Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,6 @@ on:

jobs:

static-analysis:
name: Perform static analysis
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Pixi
uses: prefix-dev/setup-pixi@v0.8.1
with:
pixi-version: v0.40.2
cache: false
environments: fmt
activate-environment: true
- name: Run formatter and linter
run: pixi run fmt

docs:
name: Generate documentation
runs-on: ubuntu-latest
Expand Down
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.12.0
hooks:
# Run the linter.
- id: ruff-check
args: [ --fix ]
# Run the formatter.
- id: ruff-format
5 changes: 1 addition & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ platforms = ["linux-64"]
### pixi: features
[tool.pixi.feature.py3]
dependencies = {python = "3.*"}
[tool.pixi.feature.ruff]
dependencies = {ruff = "*"}
tasks = {fmt = "ruff check"}
[tool.pixi.feature.build]
pypi-dependencies = {build = "*"}
tasks = {build-dist = "python -m build"}
Expand All @@ -63,12 +60,12 @@ dependencies = {fans = "0.4.*"}
[tool.pixi.dependencies]
aiida-core = "2.6.*"
h5py = "*"
pre-commit = "*"
[tool.pixi.pypi-dependencies]
aiida-fans = { path = ".", editable = true }

### pixi: environments
[tool.pixi.environments]
fmt = { no-default-feature = true, features = ["py3", "ruff"] } # CI env
dist = { no-default-feature = true, features = ["py3", "build"] } # CI env
docs = { no-default-feature = true, features = ["py3", "sphinx"] } # CI env
tutorial = { features = ["marimo", "fans"] }
Expand Down
29 changes: 13 additions & 16 deletions src/aiida_fans/calculations.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ def define(cls, spec: CalcJobProcessSpec) -> None:
spec.inputs["metadata"]["label"].default = "FANS"
## Processing Power
spec.inputs["metadata"]["options"]["withmpi"].default = True
spec.inputs["metadata"]["options"]["resources"].default = {
"num_machines": 1,
"num_mpiprocs_per_machine": 4
}
spec.inputs["metadata"]["options"]["resources"].default = {"num_machines": 1, "num_mpiprocs_per_machine": 4}
## Filenames
spec.inputs["metadata"]["options"]["input_filename"].default = "input.json"
spec.inputs["metadata"]["options"]["output_filename"].default = "output.h5"
Expand Down Expand Up @@ -72,14 +69,16 @@ def prepare_for_submission(self, folder: Folder) -> CalcInfo:
"""Prepare the calculation for submission."""
# Stashed Strategy:
if self.options.stashed_microstructure:
ms_filepath: Path = Path(self.inputs.code.computer.get_workdir()) / \
"stash/microstructures" / \
self.inputs.microstructure.file.filename
ms_filepath: Path = (
Path(self.inputs.code.computer.get_workdir())
/ "stash/microstructures"
/ self.inputs.microstructure.file.filename
)
# if microstructure does not exist in stash, make it
if not ms_filepath.is_file():
ms_filepath.parent.mkdir(parents=True, exist_ok=True)
with self.inputs.microstructure.file.open(mode='rb') as source:
with ms_filepath.open(mode='wb') as target:
with self.inputs.microstructure.file.open(mode="rb") as source:
with ms_filepath.open(mode="wb") as target:
copyfileobj(source, target)

# input.json as dict
Expand All @@ -90,11 +89,11 @@ def prepare_for_submission(self, folder: Folder) -> CalcInfo:
dump(input_dict, json, indent=4)
# Fragmented Strategy:
else:
datasetname : str = self.inputs.microstructure.datasetname.value
with folder.open("microstructure.h5","bw") as f_dest:
with h5File(f_dest,"w") as h5_dest:
datasetname: str = self.inputs.microstructure.datasetname.value
with folder.open("microstructure.h5", "bw") as f_dest:
with h5File(f_dest, "w") as h5_dest:
with self.inputs.microstructure.file.open(mode="rb") as f_src:
with h5File(f_src,'r') as h5_src:
with h5File(f_src, "r") as h5_src:
h5_src.copy(datasetname, h5_dest, name=datasetname)

# input.json as dict
Expand All @@ -117,8 +116,6 @@ def prepare_for_submission(self, folder: Folder) -> CalcInfo:
calcinfo.local_copy_list = []
calcinfo.remote_copy_list = []
calcinfo.retrieve_list = [codeinfo.stdout_name, codeinfo.stderr_name]
calcinfo.retrieve_temporary_list = [
self.options.output_filename
]
calcinfo.retrieve_temporary_list = [self.options.output_filename]

return calcinfo
9 changes: 5 additions & 4 deletions src/aiida_fans/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ def make_input_dict(job: CalcJob) -> dict[str, Any]:
return {
## Microstructure Definition
"microstructure": {
"filepath": None, # path to stashed microstructure, must be overwritten by impl
"filepath": None, # path to stashed microstructure, must be overwritten by impl
"datasetname": job.inputs.microstructure.datasetname.value,
"L": job.inputs.microstructure.L.get_list()
"L": job.inputs.microstructure.L.get_list(),
},
"results_prefix": job.inputs.metadata.options.results_prefix,
## Problem Type and Material Model
Expand All @@ -26,14 +26,15 @@ def make_input_dict(job: CalcJob) -> dict[str, Any]:
"error_parameters": {
"measure": job.inputs.error_parameters.measure.value,
"type": job.inputs.error_parameters.type.value,
"tolerance": job.inputs.error_parameters.tolerance.value
"tolerance": job.inputs.error_parameters.tolerance.value,
},
## Macroscale Loading Conditions
"macroscale_loading": job.inputs.macroscale_loading.get_list(),
## Results Specification
"results": job.inputs.metadata.options.results
"results": job.inputs.metadata.options.results,
}


def arraydata_equal(first: dict[str, ndarray], second: dict[str, ndarray]) -> bool:
"""Return whether two dicts of arrays are roughly equal."""
if first.keys() != second.keys():
Expand Down
6 changes: 2 additions & 4 deletions src/aiida_fans/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,15 @@ def __init__(self, node: CalcJobNode):

def parse(self, **kwargs) -> ExitCode | None:
"""Parse outputs and store results as nodes."""
output_path: Path = Path(kwargs["retrieved_temporary_folder"]) / self.node.get_option("output_filename") # type: ignore
output_path: Path = Path(kwargs["retrieved_temporary_folder"]) / self.node.get_option("output_filename") # type: ignore
if output_path.is_file():
self.out("output", node=SinglefileData(output_path))
else:
return self.exit_codes.ERROR_MISSING_OUTPUT

with h5File(output_path) as h5:
results = h5[
self.node.inputs.microstructure.datasetname.value + \
"_results/" + \
self.node.get_option('results_prefix')
self.node.inputs.microstructure.datasetname.value + "_results/" + self.node.get_option("results_prefix")
]
results.visititems(self.parse_h5)

Expand Down
13 changes: 3 additions & 10 deletions src/aiida_fans/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,7 @@ def compile_query(ins: dict[str, Any], qb: QueryBuilder) -> None:
qb.append(cls=type(v), with_outgoing="calc", filters={"pk": v.pk})


def execute_fans(
mode: Literal["Submit", "Run"],
inputs: dict[str, Any]
):
def execute_fans(mode: Literal["Submit", "Run"], inputs: dict[str, Any]):
"""This utility function simplifies the process of executing aiida-fans jobs.

The only nodes you must provide are the `code` and `microstructure` inputs.
Expand Down Expand Up @@ -199,15 +196,11 @@ def execute_fans(
submit(calcjob, inputs) # type: ignore


def submit_fans(
inputs: dict[str, Any]
):
def submit_fans(inputs: dict[str, Any]):
"""See `execute_fans` for implementation and usage details."""
execute_fans("Submit", inputs)


def run_fans(
inputs: dict[str, Any]
):
def run_fans(inputs: dict[str, Any]):
"""See `execute_fans` for implementation and usage details."""
execute_fans("Run", inputs)