@mat3ra/made 2026.3.10-0 → 2026.4.2-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mat3ra/made",
3
- "version": "2026.3.10-0",
3
+ "version": "2026.4.2-0",
4
4
  "description": "MAterials DEsign library",
5
5
  "scripts": {
6
6
  "lint": "eslint --cache src/js tests/js && prettier --write src/js tests/js",
@@ -0,0 +1,5 @@
1
+ from .builder import StrainBuilder
2
+ from .configuration import StrainConfiguration
3
+ from .helpers import create_strain, get_isotropic_strain_matrix
4
+
5
+ __all__ = ["StrainBuilder", "StrainConfiguration", "create_strain", "get_isotropic_strain_matrix"]
@@ -0,0 +1,25 @@
1
+ from typing import Type
2
+
3
+ from mat3ra.made.tools.build_components.entities.reusable.base_builder import BaseBuilderParameters, BaseSingleBuilder
4
+
5
+ from ..... import MaterialWithBuildMetadata
6
+ from ......operations.core.unary import strain
7
+ from .configuration import StrainConfiguration
8
+
9
+
10
+ class StrainBuilder(BaseSingleBuilder):
11
+ _ConfigurationType: Type[StrainConfiguration] = StrainConfiguration
12
+ _BuildParametersType: Type[BaseBuilderParameters] = BaseBuilderParameters
13
+ _DefaultBuildParameters: BaseBuilderParameters = BaseBuilderParameters()
14
+
15
+ def _generate(self, configuration: StrainConfiguration) -> MaterialWithBuildMetadata:
16
+ strained_material = strain(configuration.material, configuration.strain_matrix)
17
+ return MaterialWithBuildMetadata.create(strained_material.to_dict())
18
+
19
+ def _update_material_name(
20
+ self, material: MaterialWithBuildMetadata, configuration: StrainConfiguration
21
+ ) -> MaterialWithBuildMetadata:
22
+ if configuration.scale_factor is not None:
23
+ base_name = configuration.material.name
24
+ material.name = f"{base_name} (scale={configuration.scale_factor:.4f})"
25
+ return material
@@ -0,0 +1,23 @@
1
+ from typing import Optional, Union
2
+
3
+ from mat3ra.esse.models.core.abstract.matrix_3x3 import Matrix3x3Schema
4
+ from mat3ra.made.material import Material
5
+ from mat3ra.made.tools.build_components.entities.reusable.base_builder import BaseConfigurationPydantic
6
+
7
+ from ..... import MaterialWithBuildMetadata
8
+
9
+
10
+ class StrainConfiguration(BaseConfigurationPydantic):
11
+ """
12
+ Configuration for a strain operation on a Material.
13
+
14
+ Args:
15
+ material (Material): The Material object to be strained.
16
+ strain_matrix (Matrix3x3Schema): The 3x3 strain matrix defining the deformation.
17
+ scale_factor (Optional[float]): An optional scale factor for isotropic scaling instead of a full strain matrix.
18
+ """
19
+
20
+ type: str = "StrainConfiguration"
21
+ material: Union[Material, MaterialWithBuildMetadata]
22
+ strain_matrix: Matrix3x3Schema
23
+ scale_factor: Optional[float] = None
@@ -0,0 +1,49 @@
1
+ from typing import Optional, Union
2
+
3
+ from mat3ra.esse.models.core.abstract.matrix_3x3 import Matrix3x3Schema
4
+ from mat3ra.made.material import Material
5
+
6
+ from ..... import MaterialWithBuildMetadata
7
+ from .builder import StrainBuilder
8
+ from .configuration import StrainConfiguration
9
+
10
+
11
+ def get_isotropic_strain_matrix(scale_factor: float) -> Matrix3x3Schema:
12
+ """
13
+ Returns a 3x3 isotropic strain matrix for uniform lattice scaling.
14
+ """
15
+ return Matrix3x3Schema(
16
+ root=[
17
+ [scale_factor, 0.0, 0.0],
18
+ [0.0, scale_factor, 0.0],
19
+ [0.0, 0.0, scale_factor],
20
+ ]
21
+ )
22
+
23
+
24
+ def create_strain(
25
+ material: Union[Material, MaterialWithBuildMetadata],
26
+ strain_matrix: Optional[Matrix3x3Schema] = None,
27
+ scale_factor: Optional[float] = None,
28
+ ) -> MaterialWithBuildMetadata:
29
+ """
30
+ Creates a strained Material based on the provided strain matrix or scale factor.
31
+
32
+ Args:
33
+ material (Union[Material, MaterialWithBuildMetadata]): The material to be strained.
34
+ strain_matrix (Optional[Matrix3x3Schema]): The 3x3 strain matrix defining the deformation.
35
+ scale_factor (Optional[float]): An optional scale factor for isotropic scaling instead of a full strain matrix.
36
+
37
+ Returns:
38
+ MaterialWithBuildMetadata: The strained material with build metadata.
39
+ """
40
+ if scale_factor is not None:
41
+ if scale_factor <= 0:
42
+ raise ValueError("scale_factor must be positive.")
43
+ strain_matrix = get_isotropic_strain_matrix(scale_factor)
44
+ if strain_matrix is None:
45
+ raise ValueError("Either strain_matrix or scale_factor must be provided.")
46
+
47
+ configuration = StrainConfiguration(material=material, strain_matrix=strain_matrix, scale_factor=scale_factor)
48
+ builder = StrainBuilder()
49
+ return builder.get_material(configuration)
@@ -0,0 +1,36 @@
1
+ import pytest
2
+ from mat3ra.esse.models.core.abstract.matrix_3x3 import Matrix3x3Schema
3
+ from mat3ra.made.material import Material
4
+ from mat3ra.made.tools.build_components.operations.core.modifications.strain.helpers import create_strain
5
+ from unit.fixtures.strain import BULK_Si_CONVENTIONAL_STRAINED
6
+ from unit.utils import assert_two_entities_deep_almost_equal
7
+
8
+ from .fixtures.bulk import BULK_Si_CONVENTIONAL
9
+
10
+
11
+ @pytest.mark.parametrize(
12
+ "material_config, strain_matrix, expected_material_config",
13
+ [
14
+ (BULK_Si_CONVENTIONAL, [[1.1, 0, 0], [0, 1.1, 0], [0, 0, 1.0]], BULK_Si_CONVENTIONAL_STRAINED),
15
+ ],
16
+ )
17
+ def test_create_strain(material_config, strain_matrix, expected_material_config):
18
+ material = Material.create(material_config)
19
+ strained_material = create_strain(material, Matrix3x3Schema(root=strain_matrix))
20
+
21
+ assert_two_entities_deep_almost_equal(strained_material, expected_material_config)
22
+
23
+ build_step = strained_material.metadata.build[-1]
24
+ assert build_step.configuration["type"] == "StrainConfiguration"
25
+ assert build_step.configuration["strain_matrix"] == strain_matrix
26
+ assert build_step.build_parameters == {}
27
+
28
+
29
+ def test_create_strain_with_scale_factor():
30
+ material = Material.create(BULK_Si_CONVENTIONAL)
31
+ strained_material = create_strain(material, scale_factor=1.1)
32
+
33
+ assert strained_material.name == f"{material.name} (scale=1.1000)"
34
+ build_step = strained_material.metadata.build[-1]
35
+ assert build_step.configuration["scale_factor"] == 1.1
36
+ assert build_step.configuration["strain_matrix"] == [[1.1, 0.0, 0.0], [0.0, 1.1, 0.0], [0.0, 0.0, 1.1]]