@mat3ra/made 2024.12.25-1 → 2024.12.28-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": "2024.12.25-1",
3
+ "version": "2024.12.28-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",
@@ -41,15 +41,14 @@ class Basis(RoundNumericValuesMixin, BaseModel):
41
41
  "elements": self.elements.to_json(),
42
42
  "coordinates": self.coordinates.to_json(skip_rounding=skip_rounding),
43
43
  "units": self.units,
44
- "cell": self.cell.to_json(skip_rounding=skip_rounding) if self.cell else None,
45
44
  "labels": self.labels.to_json(),
46
45
  }
47
46
  return json.loads(json.dumps(json_value))
48
47
 
49
48
  def clone(self):
50
49
  return Basis(
51
- elements=self.toJSON()["elements"],
52
- coordinates=self.toJSON()["coordinates"],
50
+ elements=self.elements,
51
+ coordinates=self.coordinates,
53
52
  units=self.units,
54
53
  cell=self.cell,
55
54
  isEmpty=False,
@@ -67,7 +67,9 @@ class Material(HasDescriptionHasMetadataNamedDefaultableInMemoryEntity):
67
67
 
68
68
  @property
69
69
  def basis(self) -> Basis:
70
- return Basis.from_dict(**self.get_prop("basis"))
70
+ config = self.get_prop("basis")
71
+ config["cell"] = config.get("cell", self.lattice.vector_arrays)
72
+ return Basis.from_dict(**config)
71
73
 
72
74
  @basis.setter
73
75
  def basis(self, basis: Basis) -> None:
@@ -99,15 +101,12 @@ class Material(HasDescriptionHasMetadataNamedDefaultableInMemoryEntity):
99
101
  def set_new_lattice_vectors(
100
102
  self, lattice_vector1: List[float], lattice_vector2: List[float], lattice_vector3: List[float]
101
103
  ) -> None:
102
- new_basis = self.basis.copy()
103
- new_basis.to_cartesian()
104
- new_basis.cell.vector1 = lattice_vector1
105
- new_basis.cell.vector2 = lattice_vector2
106
- new_basis.cell.vector3 = lattice_vector3
107
- new_basis.to_crystal()
108
- self.basis = new_basis
109
104
  lattice = Lattice.from_vectors_array([lattice_vector1, lattice_vector2, lattice_vector3])
105
+ original_is_in_crystal = self.basis.is_in_crystal_units
106
+ self.to_cartesian()
110
107
  self.lattice = lattice
108
+ if original_is_in_crystal:
109
+ self.to_crystal()
111
110
 
112
111
  def add_atom(self, element: str, coordinate: List[float], use_cartesian_coordinates=False) -> None:
113
112
  new_basis = self.basis.copy()
@@ -62,7 +62,8 @@ class InterfaceBuilder(BaseBuilder):
62
62
  # Simple Interface Builder #
63
63
  ########################################################################################
64
64
  class SimpleInterfaceBuilderParameters(InterfaceBuilderParameters):
65
- scale_film: bool = True
65
+ scale_film: bool = True # Whether to scale the film to match the substrate
66
+ create_slabs: bool = True # Whether to create slabs from the configurations or use the bulk
66
67
 
67
68
 
68
69
  class SimpleInterfaceBuilder(ConvertGeneratedItemsASEAtomsMixin, InterfaceBuilder):
@@ -74,15 +75,20 @@ class SimpleInterfaceBuilder(ConvertGeneratedItemsASEAtomsMixin, InterfaceBuilde
74
75
  _DefaultBuildParameters = SimpleInterfaceBuilderParameters(scale_film=True)
75
76
  _GeneratedItemType: type(ASEAtoms) = ASEAtoms # type: ignore
76
77
 
77
- @staticmethod
78
- def __preprocess_slab_configuration(configuration: SlabConfiguration, termination: Termination):
79
- slab = create_slab(configuration, termination)
78
+ def __preprocess_slab_configuration(
79
+ self, configuration: SlabConfiguration, termination: Termination, create_slabs=False
80
+ ) -> ASEAtoms:
81
+ slab = create_slab(configuration, termination) if create_slabs else configuration.bulk
80
82
  ase_slab = to_ase(slab)
83
+
81
84
  niggli_reduce(ase_slab)
82
85
  return ase_slab
83
86
 
84
87
  @staticmethod
85
88
  def __combine_two_slabs_ase(substrate_slab_ase: ASEAtoms, film_slab_ase: ASEAtoms, distance_z: float) -> ASEAtoms:
89
+ total_z_height = substrate_slab_ase.cell[2][2] + film_slab_ase.cell[2][2] + distance_z
90
+ substrate_slab_ase.cell[2][2] = total_z_height
91
+ film_slab_ase.cell[2][2] = total_z_height
86
92
  max_z_substrate = max(substrate_slab_ase.positions[:, 2])
87
93
  min_z_film = min(film_slab_ase.positions[:, 2])
88
94
  shift_z = max_z_substrate - min_z_film + distance_z
@@ -99,14 +105,21 @@ class SimpleInterfaceBuilder(ConvertGeneratedItemsASEAtomsMixin, InterfaceBuilde
99
105
 
100
106
  def _generate(self, configuration: InterfaceBuilder._ConfigurationType) -> List[_GeneratedItemType]: # type: ignore
101
107
  film_slab_ase = self.__preprocess_slab_configuration(
102
- configuration.film_configuration, configuration.film_termination
108
+ configuration.film_configuration,
109
+ configuration.film_termination,
110
+ create_slabs=self.build_parameters.create_slabs,
103
111
  )
104
112
  substrate_slab_ase = self.__preprocess_slab_configuration(
105
- configuration.substrate_configuration, configuration.substrate_termination
113
+ configuration.substrate_configuration,
114
+ configuration.substrate_termination,
115
+ create_slabs=self.build_parameters.create_slabs,
106
116
  )
107
117
 
108
118
  if self.build_parameters.scale_film:
109
- film_slab_ase.set_cell(substrate_slab_ase.cell, scale_atoms=True)
119
+ temp_cell = [substrate_slab_ase.cell[0], substrate_slab_ase.cell[1], film_slab_ase.cell[2]]
120
+ # We scale the film in XY direction only, and use two scaling steps and a temporary cell
121
+ film_slab_ase.set_cell(temp_cell, scale_atoms=True)
122
+ film_slab_ase.set_cell(substrate_slab_ase.cell, scale_atoms=False)
110
123
  film_slab_ase.wrap()
111
124
 
112
125
  interface_ase = self.__combine_two_slabs_ase(substrate_slab_ase, film_slab_ase, configuration.distance_z)
@@ -7,7 +7,7 @@ from mat3ra.made.tools.build import BaseBuilder
7
7
  from mat3ra.made.tools.build.supercell import create_supercell
8
8
  from mat3ra.made.tools.modify import filter_by_rectangle_projection, wrap_to_unit_cell
9
9
 
10
- from ...modify import translate_to_center
10
+ from ...modify import translate_to_center, rotate
11
11
  from .configuration import NanoribbonConfiguration
12
12
  from .enums import EdgeTypes
13
13
 
@@ -73,11 +73,11 @@ class NanoribbonBuilder(BaseBuilder):
73
73
  nanoribbon_length, nanoribbon_width = nanoribbon_width, nanoribbon_length
74
74
  vacuum_width, vacuum_length = vacuum_length, vacuum_width
75
75
 
76
- length_cartesian = nanoribbon_length * np.dot(np.array(material.basis.cell.vector1), np.array([1, 0, 0]))
77
- width_cartesian = nanoribbon_width * np.dot(np.array(material.basis.cell.vector2), np.array([0, 1, 0]))
78
- height_cartesian = np.dot(np.array(material.basis.cell.vector3), np.array([0, 0, 1]))
79
- vacuum_length_cartesian = vacuum_length * np.dot(np.array(material.basis.cell.vector1), np.array([1, 0, 0]))
80
- vacuum_width_cartesian = vacuum_width * np.dot(np.array(material.basis.cell.vector2), np.array([0, 1, 0]))
76
+ length_cartesian = nanoribbon_length * np.dot(np.array(material.lattice.vectors[0]), np.array([1, 0, 0]))
77
+ width_cartesian = nanoribbon_width * np.dot(np.array(material.lattice.vectors[1]), np.array([0, 1, 0]))
78
+ height_cartesian = np.dot(np.array(material.lattice.vectors[2]), np.array([0, 0, 1]))
79
+ vacuum_length_cartesian = vacuum_length * np.dot(np.array(material.lattice.vectors[0]), np.array([1, 0, 0]))
80
+ vacuum_width_cartesian = vacuum_width * np.dot(np.array(material.lattice.vectors[1]), np.array([0, 1, 0]))
81
81
 
82
82
  return length_cartesian, width_cartesian, height_cartesian, vacuum_length_cartesian, vacuum_width_cartesian
83
83
 
@@ -134,6 +134,8 @@ class NanoribbonBuilder(BaseBuilder):
134
134
 
135
135
  def _generate(self, configuration: NanoribbonConfiguration) -> List[_GeneratedItemType]:
136
136
  nanoribbon = self.create_nanoribbon(configuration)
137
+ if configuration.edge_type == EdgeTypes.armchair:
138
+ nanoribbon = rotate(nanoribbon, [0, 0, 1], 90)
137
139
  return [nanoribbon]
138
140
 
139
141
  def _post_process(
@@ -65,7 +65,7 @@ class DistancePreservingSlabPerturbationBuilder(SlabPerturbationBuilder):
65
65
 
66
66
  class CellMatchingDistancePreservingSlabPerturbationBuilder(DistancePreservingSlabPerturbationBuilder):
67
67
  def _transform_lattice_vectors(self, configuration: PerturbationConfiguration) -> List[List[float]]:
68
- cell_vectors = configuration.material.basis.cell.vectors_as_array
68
+ cell_vectors = configuration.material.lattice.vectors
69
69
  return [configuration.perturbation_function_holder.transform_coordinates(coord) for coord in cell_vectors]
70
70
 
71
71
  def create_perturbed_slab(self, configuration: PerturbationConfiguration) -> Material:
@@ -74,10 +74,4 @@ class CellMatchingDistancePreservingSlabPerturbationBuilder(DistancePreservingSl
74
74
  new_lattice = new_material.lattice.copy()
75
75
  new_lattice = new_lattice.from_vectors_array(new_lattice_vectors)
76
76
  new_material.lattice = new_lattice
77
-
78
- new_basis = new_material.basis.copy()
79
- new_basis.to_cartesian()
80
- new_basis.cell = new_basis.cell.from_vectors_array(new_lattice_vectors)
81
- new_basis.to_crystal()
82
- new_material.basis = new_basis
83
77
  return new_material
@@ -85,7 +85,8 @@ def from_pymatgen(structure: Union[PymatgenStructure, PymatgenInterface]) -> Dic
85
85
  {"id": i, "value": __round__(list(site.frac_coords))} for i, site in enumerate(structure.sites)
86
86
  ],
87
87
  "units": "crystal",
88
- "cell": __round__(structure.lattice.matrix.tolist()),
88
+ # `cell` is assigned by the `lattice` object during Material initialization
89
+ # "cell": __round__(structure.lattice.matrix.tolist()),
89
90
  "constraints": [],
90
91
  }
91
92
 
@@ -1,4 +1,5 @@
1
1
  import copy
2
+ from functools import reduce
2
3
  from typing import Any, Dict
3
4
 
4
5
  from ase.build import bulk
@@ -56,7 +57,6 @@ INTERFACE_PROPERTIES_JSON = {
56
57
  "mean_abs_strain": 0.00105,
57
58
  }
58
59
 
59
-
60
60
  # Add properties to interface structure
61
61
  INTERFACE_STRUCTURE.interface_properties = INTERFACE_PROPERTIES_MOCK
62
62
  INTERFACE_NAME = "Cu4(001)-Si8(001), Interface, Strain 0.062pct"
@@ -86,7 +86,6 @@ SI_CONVENTIONAL_CELL: Dict[str, Any] = {
86
86
  {"id": 7, "value": [0.75, 0.75, 0.75]},
87
87
  ],
88
88
  "units": "crystal",
89
- "cell": [[5.468763846, 0.0, 0.0], [-0.0, 5.468763846, 0.0], [0.0, 0.0, 5.468763846]],
90
89
  "constraints": [],
91
90
  "labels": [],
92
91
  },
@@ -137,7 +136,6 @@ SI_SUPERCELL_2X2X1: Dict[str, Any] = {
137
136
  {"id": 7, "value": [0.625, 0.625, 0.25]},
138
137
  ],
139
138
  "units": "crystal",
140
- "cell": [[6.697840473, 0.0, 3.867], [2.232613491, 6.314784557, 3.867], [0.0, 0.0, 3.867]],
141
139
  "constraints": [],
142
140
  "labels": [],
143
141
  },
@@ -176,7 +174,6 @@ SI_SLAB_CONFIGURATION: Dict[str, Any] = {
176
174
  "make_primitive": True,
177
175
  }
178
176
 
179
-
180
177
  SI_SLAB_100: Dict[str, Any] = {
181
178
  "name": "Si8(001), termination Si_P4/mmm_1, Slab",
182
179
  "basis": {
@@ -201,7 +198,6 @@ SI_SLAB_100: Dict[str, Any] = {
201
198
  {"id": 7, "value": [0.0, 0.5, 0.643382864]},
202
199
  ],
203
200
  "units": "crystal",
204
- "cell": [[3.867, 0.0, 0.0], [-0.0, 3.867, 0.0], [0.0, 0.0, 15.937527692]],
205
201
  "constraints": [],
206
202
  "labels": [],
207
203
  },
@@ -254,7 +250,6 @@ SI_SLAB_100: Dict[str, Any] = {
254
250
  {"id": 7, "value": [0.75, 0.75, 0.75]},
255
251
  ],
256
252
  "units": "crystal",
257
- "cell": [[5.468763846, 0.0, 0.0], [-0.0, 5.468763846, 0.0], [0.0, 0.0, 5.468763846]],
258
253
  "constraints": [],
259
254
  "labels": [],
260
255
  },
@@ -293,7 +288,6 @@ SI_SLAB_100: Dict[str, Any] = {
293
288
  "isUpdated": True,
294
289
  }
295
290
 
296
-
297
291
  SI_SLAB: Dict[str, Any] = {
298
292
  "name": "Si8(001), termination Si_P4/mmm_1, Slab",
299
293
  "basis": {
@@ -303,7 +297,6 @@ SI_SLAB: Dict[str, Any] = {
303
297
  {"id": 1, "value": [0.25, 0.5, 0.145147133]},
304
298
  ],
305
299
  "units": "crystal",
306
- "cell": [[3.867, 0.0, 0.0], [1.9335, 3.348920236, 0.0], [0.0, 0.0, 8.157392279]],
307
300
  "constraints": [],
308
301
  "labels": [],
309
302
  },
@@ -333,7 +326,6 @@ SI_SLAB: Dict[str, Any] = {
333
326
  "isUpdated": True,
334
327
  }
335
328
 
336
-
337
329
  SI_SLAB_PASSIVATED = {
338
330
  "name": "Si8(001), termination Si_P4/mmm_1, Slab H-passivated",
339
331
  "basis": {
@@ -350,7 +342,6 @@ SI_SLAB_PASSIVATED = {
350
342
  {"id": 3, "value": [0.583333333, 0.833333333, 0.729812904]},
351
343
  ],
352
344
  "units": "crystal",
353
- "cell": [[3.867, 0.0, 0.0], [1.9335, 3.34892, 0.0], [0.0, 0.0, 8.157392]],
354
345
  "labels": [],
355
346
  },
356
347
  "lattice": {
@@ -377,7 +368,8 @@ SI_SLAB_PASSIVATED = {
377
368
  "build": {
378
369
  "configuration": {
379
370
  "type": "PassivationConfiguration",
380
- "slab": SI_SLAB,
371
+ # TODO: `basis` retains "cell" leading to a mismatch in the test
372
+ "slab": reduce(lambda d, key: d.get(key, {}), ["basis"], SI_SLAB).pop("cell", None),
381
373
  "passivant": "H",
382
374
  "bond_length": 1.48,
383
375
  "surface": "both",
@@ -388,17 +380,15 @@ SI_SLAB_PASSIVATED = {
388
380
  "isUpdated": True,
389
381
  }
390
382
 
391
-
392
383
  SI_SLAB_VACUUM = copy.deepcopy(SI_SLAB)
393
384
  SI_SLAB_VACUUM["basis"]["coordinates"] = [
394
385
  {"id": 0, "value": [0.583333333, 0.833333333, 0.149981861]},
395
386
  {"id": 1, "value": [0.25, 0.5, 0.089989116]},
396
387
  ]
397
- SI_SLAB_VACUUM["basis"]["cell"] = [[3.867, 0.0, 0.0], [1.9335, 3.348920236, 0.0], [0.0, 0.0, 13.157392279]]
388
+ # SI_SLAB_VACUUM["basis"]["cell"] = [[3.867, 0.0, 0.0], [1.9335, 3.348920236, 0.0], [0.0, 0.0, 13.157392279]]
398
389
  SI_SLAB_VACUUM["lattice"]["c"] = 13.157392279
399
390
  SI_SLAB_VACUUM["lattice"]["vectors"]["c"] = [0.0, 0.0, 13.157392279]
400
391
 
401
-
402
392
  clean_material = Material.create(Material.default_config)
403
393
  slab_111_config = SlabConfiguration(
404
394
  bulk=clean_material,
@@ -428,7 +418,6 @@ GRAPHENE = {
428
418
  "elements": [{"id": 0, "value": "C"}, {"id": 1, "value": "C"}],
429
419
  "coordinates": [{"id": 0, "value": [0, 0, 0]}, {"id": 1, "value": [0.333333, 0.666667, 0]}],
430
420
  "units": "crystal",
431
- "cell": [[2.467291, 0, 0], [-1.2336454999, 2.1367366845, 0], [0, 0, 20]],
432
421
  "constraints": [],
433
422
  },
434
423
  "lattice": {
@@ -451,7 +440,7 @@ GRAPHENE = {
451
440
  "isNonPeriodic": False,
452
441
  }
453
442
 
454
- GRAPHENE_ZIGZAG_NANORIBBON = {
443
+ GRAPHENE_ZIGZAG_NANORIBBON: Dict[str, Any] = {
455
444
  "name": "Graphene (Zigzag nanoribbon)",
456
445
  "basis": {
457
446
  "elements": [
@@ -491,7 +480,6 @@ GRAPHENE_ZIGZAG_NANORIBBON = {
491
480
  {"id": 15, "value": [0.812500063, 0.6333333, 0.5]},
492
481
  ],
493
482
  "units": "crystal",
494
- "cell": [[9.869164, 0.0, 0.0], [-0.0, 10.683683422, 0.0], [0.0, 0.0, 20.0]],
495
483
  "constraints": [],
496
484
  "labels": [],
497
485
  },
@@ -552,25 +540,24 @@ GRAPHENE_ARMCHAIR_NANORIBBON = {
552
540
  {"id": 15, "value": "C"},
553
541
  ],
554
542
  "coordinates": [
555
- {"id": 0, "value": [0.041666626, 0.35000005, 0.5]},
556
- {"id": 1, "value": [0.208333376, 0.34999995, 0.5]},
557
- {"id": 2, "value": [0.041666626, 0.55000005, 0.5]},
558
- {"id": 3, "value": [0.208333376, 0.54999995, 0.5]},
559
- {"id": 4, "value": [0.291666626, 0.45000005, 0.5]},
560
- {"id": 5, "value": [0.458333376, 0.44999995, 0.5]},
561
- {"id": 6, "value": [0.541666626, 0.35000005, 0.5]},
562
- {"id": 7, "value": [0.708333376, 0.34999995, 0.5]},
563
- {"id": 8, "value": [0.291666626, 0.65000005, 0.5]},
564
- {"id": 9, "value": [0.458333376, 0.64999995, 0.5]},
565
- {"id": 10, "value": [0.541666626, 0.55000005, 0.5]},
566
- {"id": 11, "value": [0.708333376, 0.54999995, 0.5]},
567
- {"id": 12, "value": [0.791666626, 0.45000005, 0.5]},
568
- {"id": 13, "value": [0.958333376, 0.44999995, 0.5]},
569
- {"id": 14, "value": [0.791666626, 0.65000005, 0.5]},
570
- {"id": 15, "value": [0.958333376, 0.64999995, 0.5]},
543
+ {"id": 0, "value": [0.958333362, 0.35000006, 0.5]},
544
+ {"id": 1, "value": [0.791666617, 0.34999996, 0.5]},
545
+ {"id": 2, "value": [0.958333362, 0.550000054, 0.5]},
546
+ {"id": 3, "value": [0.791666617, 0.549999954, 0.5]},
547
+ {"id": 4, "value": [0.708333369, 0.450000057, 0.5]},
548
+ {"id": 5, "value": [0.541666624, 0.449999957, 0.5]},
549
+ {"id": 6, "value": [0.458333376, 0.35000006, 0.5]},
550
+ {"id": 7, "value": [0.291666631, 0.34999996, 0.5]},
551
+ {"id": 8, "value": [0.708333369, 0.650000051, 0.5]},
552
+ {"id": 9, "value": [0.541666624, 0.649999951, 0.5]},
553
+ {"id": 10, "value": [0.458333376, 0.550000054, 0.5]},
554
+ {"id": 11, "value": [0.291666631, 0.549999954, 0.5]},
555
+ {"id": 12, "value": [0.208333383, 0.450000057, 0.5]},
556
+ {"id": 13, "value": [0.041666638, 0.449999957, 0.5]},
557
+ {"id": 14, "value": [0.208333383, 0.650000051, 0.5]},
558
+ {"id": 15, "value": [0.041666638, 0.649999951, 0.5]},
571
559
  ],
572
560
  "units": "crystal",
573
- "cell": [[8.546946738, 0.0, 0.0], [-0.0, 12.336455, 0.0], [0.0, 0.0, 20.0]],
574
561
  "constraints": [],
575
562
  "labels": [],
576
563
  },
@@ -665,7 +652,6 @@ GRAPHENE_ZIGZAG_NANORIBBON_PASSIVATED = {
665
652
  {"id": 23, "value": [0.812499933, 0.771862307, 0.5]},
666
653
  ],
667
654
  "units": "crystal",
668
- "cell": [[9.869164, 0.0, 0.0], [-0.0, 10.683683, 0.0], [0.0, 0.0, 20.0]],
669
655
  "labels": [],
670
656
  },
671
657
  "lattice": {
@@ -692,7 +678,8 @@ GRAPHENE_ZIGZAG_NANORIBBON_PASSIVATED = {
692
678
  "build": {
693
679
  "configuration": {
694
680
  "type": "PassivationConfiguration",
695
- "slab": GRAPHENE_ZIGZAG_NANORIBBON,
681
+ # TODO: `basis` retains "cell" leading to a mismatch in the test (as above)
682
+ "slab": reduce(lambda d, key: d.get(key, {}), ["basis"], GRAPHENE_ZIGZAG_NANORIBBON).pop("cell", None),
696
683
  "passivant": "H",
697
684
  "bond_length": 1.48,
698
685
  "surface": "both",
@@ -702,7 +689,6 @@ GRAPHENE_ZIGZAG_NANORIBBON_PASSIVATED = {
702
689
  "isUpdated": True,
703
690
  }
704
691
 
705
-
706
692
  GRAPHENE_NICKEL_INTERFACE = {
707
693
  "name": "C2(001)-Ni4(111), Interface, Strain 0.105pct",
708
694
  "basis": {
@@ -721,7 +707,6 @@ GRAPHENE_NICKEL_INTERFACE = {
721
707
  {"id": 4, "value": [0.666666667, 0.666666667, 0.611447347]},
722
708
  ],
723
709
  "units": "crystal",
724
- "cell": [[2.478974, 0.0, 0.0], [1.239487, 2.14685446, 0.0], [0.0, 0.0, 27.048147591]],
725
710
  "constraints": [],
726
711
  "labels": [
727
712
  {"id": 0, "value": 0},
@@ -799,7 +784,6 @@ GRAPHENE_NICKEL_INTERFACE = {
799
784
  {"id": 3, "value": [0.5, 0.5, 0.0]},
800
785
  ],
801
786
  "units": "crystal",
802
- "cell": [[3.505798652, 0.0, 0.0], [-0.0, 3.505798652, 0.0], [0.0, 0.0, 3.505798652]],
803
787
  "constraints": [],
804
788
  "labels": [],
805
789
  },
@@ -10,27 +10,19 @@ def test_create():
10
10
  material = Material.create(Material.default_config)
11
11
  assert isinstance(material.basis, Basis)
12
12
  assert isinstance(material.lattice, Lattice)
13
- assert material.to_json() == Material.default_config
14
13
  assert material.name == Material.default_config["name"]
15
14
 
16
15
 
17
16
  def test_material_to_json():
18
17
  material = Material.create(Material.default_config)
19
- labels_array = [{"id": 0, "value": 0}, {"id": 1, "value": 1}]
20
- config_with_labels = {
21
- **Material.default_config,
22
- "basis": {**Material.default_config["basis"], "labels": labels_array},
23
- }
24
- expected_config = {
25
- **Material.default_config,
26
- "basis": {**Material.default_config["basis"], "cell": None, "labels": labels_array},
27
- }
28
- material.basis = Basis.from_dict(**config_with_labels["basis"])
29
- assertion_utils.assert_deep_almost_equal(expected_config, material.to_json())
18
+ assertion_utils.assert_deep_almost_equal(Material.default_config, material.to_json())
30
19
 
31
20
 
32
21
  def test_basis_to_json():
33
22
  material = Material.create(Material.default_config)
34
23
  basis = material.basis
35
- expected_basis_config = {**Material.default_config["basis"], "cell": None, "labels": []}
24
+ expected_basis_config = {**Material.default_config["basis"], "labels": []}
36
25
  assertion_utils.assert_deep_almost_equal(expected_basis_config, basis.to_json())
26
+
27
+
28
+ # TODO: Add test to check if basis.cell is changed when lattice of material is changed, and vice versa
@@ -114,10 +114,17 @@ def test_create_adatom_equidistant():
114
114
  defect = create_slab_defect(configuration=configuration, builder=EquidistantAdatomSlabDefectBuilder())
115
115
 
116
116
  assert defect.basis.elements.values[-1] == "Si"
117
- # We expect adatom to shift from provided position
118
- assertion_utils.assert_deep_almost_equal(
119
- [0.383333334, 0.558333333, 0.872332562], defect.basis.coordinates.values[-1]
120
- )
117
+ assert (len(configuration.crystal.basis.coordinates.values) + 1) == len(defect.basis.coordinates.values)
118
+ defect.to_cartesian()
119
+ # TODO: resolve the problem with the test in GH pipeline
120
+ # on MacOS slab atoms have different coordinates than in GH and pyodide
121
+ # for the same versions of packages
122
+ coordinate_macosx = [6.477224996, 3.739627331, 14.234895469]
123
+ coordinate_linux_and_emscripten = [5.123775004, 3.739627331, 14.234895469]
124
+ defect_coordinate = defect.basis.coordinates.values[-1]
125
+ is_passing_on_macosx = coordinate_macosx == defect_coordinate
126
+ is_passing_on_linux_and_emscripten = coordinate_linux_and_emscripten == defect_coordinate
127
+ assert is_passing_on_macosx or is_passing_on_linux_and_emscripten
121
128
 
122
129
 
123
130
  @pytest.mark.skip(reason="This test is failing due to the difference in slab generation between GHA and local")
@@ -62,9 +62,9 @@ def test_create_twisted_nanoribbon_interface():
62
62
  builder = NanoRibbonTwistedInterfaceBuilder()
63
63
  interface = builder.get_material(configuration)
64
64
 
65
- exected_cell_vectors = [[15.102810734, 0.0, 0.0], [-0.0, 16.108175208, 0.0], [0.0, 0.0, 20.0]]
65
+ expected_cell_vectors = [[15.102811, 0.0, 0.0], [0.0, 16.108175208, 0.0], [0.0, 0.0, 20.0]]
66
66
  expected_coordinate = [0.704207885, 0.522108183, 0.65]
67
- assertion_utils.assert_deep_almost_equal(exected_cell_vectors, interface.basis.cell.vectors_as_array)
67
+ assertion_utils.assert_deep_almost_equal(expected_cell_vectors, interface.lattice.vectors)
68
68
  assertion_utils.assert_deep_almost_equal(expected_coordinate, interface.basis.coordinates.values[42])
69
69
 
70
70
 
@@ -79,7 +79,7 @@ def test_create_commensurate_supercell_twisted_interface():
79
79
  interfaces = builder.get_materials(config, post_process_parameters=config)
80
80
  assert len(interfaces) == 1
81
81
  interface = interfaces[0]
82
- expected_cell_vectors = [[-9.869164, -4.273473, 0.0], [-1.233646, -10.683683, 0.0], [0.0, 0.0, 20.0]]
82
+ expected_cell_vectors = [[10.754672133, 0.0, 0.0], [5.377336066500001, 9.313819276550575, 0.0], [0.0, 0.0, 20.0]]
83
83
  assertion_utils.assert_deep_almost_equal(expected_cell_vectors, interface.basis.cell.vectors_as_array)
84
84
  expected_angle = 13.174
85
85
  assert interface.metadata["build"]["configuration"]["actual_twist_angle"] == expected_angle
@@ -1,4 +1,3 @@
1
- from mat3ra.made.cell import Cell
2
1
  from mat3ra.made.material import Material
3
2
  from mat3ra.made.tools.build.perturbation import create_perturbation
4
3
  from mat3ra.made.tools.build.perturbation.builders import SlabPerturbationBuilder
@@ -39,12 +38,12 @@ def test_distance_preserved_sine_perturbation():
39
38
  # Check selected atoms to avoid using 100+ atoms fixture
40
39
  assertion_utils.assert_deep_almost_equal([0.0, 0.0, 0.5], perturbed_slab.basis.coordinates.values[0])
41
40
  assertion_utils.assert_deep_almost_equal(
42
- [0.197552693, 0.1, 0.546942315], perturbed_slab.basis.coordinates.values[42]
41
+ [0.194051947, 0.1, 0.546942315], perturbed_slab.basis.coordinates.values[42]
43
42
  )
44
43
  # Value taken from visually inspected notebook
45
- expected_cell = Cell(
46
- vector1=[24.087442, 0.0, 0.0],
47
- vector2=[-12.043583, 21.367367, 0.0],
48
- vector3=[0.0, 0.0, 20.0],
49
- )
50
- assertion_utils.assert_deep_almost_equal(expected_cell.vectors_as_array, perturbed_slab.basis.cell.vectors_as_array)
44
+ expected_cell = [
45
+ [24.087442, 0.0, 0.0],
46
+ [-12.043583, 21.367367, 0.0],
47
+ [0.0, 0.0, 20.0],
48
+ ]
49
+ assertion_utils.assert_deep_almost_equal(expected_cell, perturbed_slab.lattice.vectors)
@@ -22,7 +22,6 @@ from .fixtures import GRAPHENE_NICKEL_INTERFACE, SI_CONVENTIONAL_CELL, SI_SLAB,
22
22
 
23
23
  COMMON_PART = {
24
24
  "units": "crystal",
25
- "cell": [[5.468763846, 0.0, 0.0], [-0.0, 5.468763846, 0.0], [0.0, 0.0, 5.468763846]],
26
25
  "labels": [],
27
26
  }
28
27