Skip to content
Closed
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
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ dependencies = [
"fans" = "aiida_fans.calculations:FansCalculation"
[project.entry-points."aiida.parsers"]
"fans" = "aiida_fans.parsers:FansParser"
[project.entry-points."aiida.data"]
"fans" = "aiida_fans.data:MaterialData"

# Build System
[build-system]
Expand Down
6 changes: 4 additions & 2 deletions src/aiida_fans/calculations.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""CalcJob subclasses for aiida-fans calculations."""
"""Subclasses of CalcJob for aiida-fans calculations."""

from json import dump
from pathlib import Path
Expand All @@ -11,6 +11,7 @@
from aiida.orm import Dict, Float, Int, List, SinglefileData, Str
from h5py import File as h5File

from aiida_fans.data import MaterialData
from aiida_fans.helpers import make_input_dict


Expand Down Expand Up @@ -47,7 +48,8 @@ def define(cls, spec: CalcJobProcessSpec) -> None:
## Problem Type and Material Model
spec.input("problem_type", valid_type=Str)
spec.input("matmodel", valid_type=Str)
spec.input("material_properties", valid_type=Dict)
spec.input("material_phases", valid_type=Dict)
spec.input_namespace("material_properties", valid_type=MaterialData, dynamic=True)
## Solver Settings
spec.input("method", valid_type=Str)
spec.input("n_it", valid_type=Int)
Expand Down
17 changes: 17 additions & 0 deletions src/aiida_fans/data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Subclasses of Data for aiida-fans."""

from aiida.orm import Data


class MaterialData(Data):
"""Data class to represent material properties."""

def __init__(self, **kwargs):
"""Initialize the MaterialData instance."""
bulk = kwargs.pop("bulk_modulus", None)
shear = kwargs.pop("shear_modulus", None)
super().__init__(**kwargs)
if bulk is not None:
self.base.attributes.set("bulk_modulus", bulk)
if shear is not None:
self.base.attributes.set("shear_modulus", shear)
5 changes: 4 additions & 1 deletion src/aiida_fans/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ def make_input_dict(job: CalcJob) -> dict[str, Any]:
## Problem Type and Material Model
"problem_type": job.inputs.problem_type.value,
"matmodel": job.inputs.matmodel.value,
"material_properties": job.inputs.material_properties.get_dict(),
"material_properties": {
"bulk_modulus": [mat.base.attributes.get("bulk_modulus") for mat in job.inputs.material_properties],
"shear_modulus": [mat.base.attributes.get("shear_modulus") for mat in job.inputs.material_properties],
},
## Solver Settings
"method": job.inputs.method.value,
"n_it": job.inputs.n_it.value,
Expand Down
2 changes: 1 addition & 1 deletion src/aiida_fans/parsers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Parser subclass for aiida-fans calculations."""
"""Subclass of Parser for aiida-fans calculations."""

from pathlib import Path

Expand Down
83 changes: 83 additions & 0 deletions src/aiida_fans/readme_submit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"""This is an example submit script. It should **not** be committed to dev."""

from aiida import load_profile # type: ignore
from aiida.orm import load_code, load_node
from aiida.tools import delete_nodes

from aiida_fans.utils import run_fans

load_profile()


################################################################################

inputs = {
"code": load_code("FANS"), #! Code node goes here.
"microstructure": {
"file": load_node(label="microstructure.file"), #! Microstructure node goes here.
"datasetname": "/dset_0/image",
"L": [1.0, 1.0, 1.0]
},
"results_prefix": "my_results", #? Optional
"problem_type": "mechanical",
"matmodel": "LinearElasticIsotropic",

######################################
# Proposed material properties format:
"material_phases": {
"copper": [0, 2],
"aluminium": [1]
},
# translates to: phase 0 = copper, phase 1 = aluminium, phase 2 = copper
#
# Under this format, each material would be its own node labelled "copper",
# "aluminium", etc., and they would be of various MaterialData types that
# the plugin defines for each supported matmodel.
#
# Additionally, each job would have a material_phases input which defines
# what materials occupy which phases of the microstructure. If the user were
# to provide materials inconsistent with the provided "matmodel", utils
# could reject the input without ever calling AiiDA or FANS.
#
# If an advanced user wishes to use a custom material, they must create the
# node themselves and provide it a unique label. That label can then simply
# be used in place of "copper" or "alumininum" above.
######################################

"method": "cg",
"error_parameters": {
"measure": "Linfinity",
"type": "absolute",
"tolerance": 1e-10
},
"n_it": 100,
"macroscale_loading": [
{
"strain_indices": [ 2, 3, 4, 5],
"stress_indices": [0, 1 ],
"strain": [[0.005, 0.0, 0.0, 0.0],[0.010, 0.0, 0.0, 0.0]],
"stress": [[0.0, 0.0],[0.0, 0.0]]
},
{
"strain_indices": [ 4, 5],
"stress_indices": [0, 1, 2, 3 ],
"strain": [[0.001, 0.005],[0.005, 0.001]],
"stress": [[0.01, 0.0, 0.0, 0.0],[0.0, 0.01, 0.0, 0.0]]
}
],
"results": [ # Optional
"stress", "strain",
"stress_average", "strain_average",
"phase_stress_average", "phase_strain_average",
"microstructure", "displacement", "absolute_error",
],

"metadata": { # Optional
# "label": "test calculation 1",
# "dry_run": True
}
}

################################################################################

run_fans(inputs)