@@ -106,6 +106,8 @@ class Parent:
106106 :param unit_cell: Required only if GB is specified using a LAMMPS dump file. Gives
107107 the nominal unit cell of the system.
108108 :param gb_thickness: Thickness of the GB region, optional, defaults to 10.
109+ :param type_dict: The map from integer to element string. The default mapping is
110+ 1 -> 'H', 2 -> 'He', etc.
109111 """
110112 __num_to_name = {val : key for key , val in Atom ._numbers .items ()}
111113
@@ -115,7 +117,7 @@ def __init__(
115117 * ,
116118 unit_cell : UnitCell = None ,
117119 gb_thickness : float = 10 ,
118- type_dict : dict = {}
120+ type_dict : dict = {},
119121 ) -> None :
120122 if isinstance (system , GBMaker ):
121123 self .__init_by_gbmaker (system )
@@ -139,10 +141,10 @@ def __init__(
139141 self .__GBpos = self .__whole_system [
140142 np .where (
141143 np .logical_and (
142- self .__whole_system ["x" ] >= self . __box_dims [ 0 , 1 ] /
143- 2 - self .__gb_thickness / 2 ,
144- self .__whole_system ["x" ] <= self . __box_dims [ 0 , 1 ] /
145- 2 + self .__gb_thickness / 2
144+ self .__whole_system ["x" ]
145+ >= self . __box_dims [ 0 , 1 ] / 2 - self .__gb_thickness / 2 ,
146+ self .__whole_system ["x" ]
147+ <= self . __box_dims [ 0 , 1 ] / 2 + self .__gb_thickness / 2
146148 )
147149 )
148150 ]
@@ -171,7 +173,7 @@ def __init_by_file(
171173 system_file : str ,
172174 unit_cell : UnitCell ,
173175 gb_thickness : float ,
174- type_dict : dict
176+ type_dict : dict ,
175177 ) -> None :
176178 """
177179 Method for initializing the Parent using a file.
@@ -211,7 +213,7 @@ def __init_by_file(
211213 "ITEM: TIMESTEP" ,
212214 "ITEM: NUMBER OF ATOMS" ,
213215 "ITEM: BOX BOUNDS" ,
214- "ITEM: ATOMS"
216+ "ITEM: ATOMS" ,
215217 ],
216218 self .__init_from_lammps_input : [
217219 "atoms" ,
@@ -231,7 +233,7 @@ def __init_by_file(
231233 "avec" ,
232234 "bvec" ,
233235 "cvec" ,
234- "abc origin"
236+ "abc origin" ,
235237 ]
236238 }
237239
@@ -354,7 +356,10 @@ def convert_type(value):
354356 if typelabel_in_attrs :
355357 return value
356358 else :
357- return self .__num_to_name [int (value )]
359+ if not type_dict :
360+ return self .__num_to_name [int (value )]
361+ else :
362+ return type_dict [int (value )]
358363 max_rows = 0
359364 line = f .readline () # read the next line to move the file pointer ahead.
360365 while not line .startswith ("ITEM" ):
@@ -466,7 +471,7 @@ def convert_type(value):
466471 max_rows = n_atoms ,
467472 converters = {1 : convert_type },
468473 usecols = [1 , 2 , 3 , 4 ],
469- dtype = Atom .atom_dtype
474+ dtype = Atom .atom_dtype ,
470475 )
471476 mask = self .__whole_system ["x" ] < grain_cutoff
472477 self .__left_grain = self .__whole_system [mask ]
@@ -605,7 +610,7 @@ def _calculate_fingerprint_vector(atom, neighs, NB, V, Btype, Delta, Rmax):
605610 calculate the fingerprint.
606611 :return: The vector containing the fingerprint for *atom*.
607612 """
608- Rs = np .arange (0 , Rmax + Delta , Delta )
613+ Rs = np .arange (0 , Rmax + Delta , Delta )
609614
610615 fingerprint_vector = np .zeros_like (Rs )
611616 for idx , R in enumerate (Rs ):
@@ -615,10 +620,9 @@ def _calculate_fingerprint_vector(atom, neighs, NB, V, Btype, Delta, Rmax):
615620 diff = atom [1 :] - neigh [1 :]
616621 # Rij = np.linalg.norm(atom[1:] - neigh[1:])
617622 distance = np .sqrt (np .dot (diff , diff ))
618- delta = _gaussian (R - distance , 0.02 )
623+ delta = _gaussian (R - distance , 0.02 )
619624 local_sum += delta / \
620625 (4 * np .pi * distance * distance * (NB / V ) * Delta )
621- # pdb.set_trace()
622626 fingerprint_vector [idx ] = local_sum - 1
623627
624628 return fingerprint_vector
@@ -642,8 +646,8 @@ def _calculate_local_order(atom, neighs, unit_cell_types, unit_cell_a0, N, Delta
642646 """
643647 local_sum = 0
644648 atom_types = np .unique (neighs [:, 0 ])
645- V = unit_cell_a0 ** 3
646- prefactor = Delta / (N * (V / N ) ** ( 1 / 3 ))
649+ V = unit_cell_a0 ** 3
650+ prefactor = Delta / (N * (V / N ) ** ( 1 / 3 ))
647651 for Btype in atom_types :
648652 NB = np .sum (unit_cell_types == Btype )
649653 fingerprint = _calculate_fingerprint_vector (
@@ -793,6 +797,8 @@ class GBManipulator:
793797 :param gb_thickness: Thickness of the GB region, optional, defaults to 10.
794798 :param seed: The seed for random number generation, optional, defaults to None
795799 (automatically seeded).
800+ :param type_dict: The mapping of integer to string types. If not specified, the
801+ default mapping is 1 -> 'H', 2 -> 'He', etc.
796802 """
797803
798804 def __init__ (
@@ -802,7 +808,8 @@ def __init__(
802808 * ,
803809 gb_thickness : float = None ,
804810 unit_cell : UnitCell = None ,
805- seed : int = None
811+ seed : int = None ,
812+ type_dict : dict = {},
806813 ) -> None :
807814 # initialize the random number generator
808815 if not seed :
@@ -817,21 +824,21 @@ def __init__(
817824 # not attempt to perform those in the case that only one GB is passed in.
818825 self .__one_parent = True
819826 self .__set_parents (system1 , unit_cell = unit_cell ,
820- gb_thickness = gb_thickness )
827+ gb_thickness = gb_thickness , type_dict = type_dict )
821828 else :
822829 self .__one_parent = False
823830 self .__set_parents (system1 , system2 , unit_cell = unit_cell ,
824- gb_thickness = gb_thickness )
831+ gb_thickness = gb_thickness , type_dict = type_dict )
825832 self .__num_processes = mp .cpu_count () // 2 or 1
826833
827834 def __set_parents (
828- self ,
829- system1 : Union [GBMaker , str ],
830- system2 : Union [GBMaker , str ] = None ,
831- * ,
832- unit_cell = None ,
833- gb_thickness = None
834- ) -> None :
835+ self ,
836+ system1 : Union [GBMaker , str ],
837+ system2 : Union [GBMaker , str ] = None ,
838+ * ,
839+ unit_cell : UnitCell = None ,
840+ gb_thickness : float = None ,
841+ type_dict : dict = {} ) -> None :
835842 """
836843 Method to assign the parent(s) that will create the child(ren).
837844
@@ -842,9 +849,12 @@ def __set_parents(
842849 :param gb_thickness: Keyword argument. The thickness of the GB region, optional,
843850 defaults to None. Note that if None is passed to the Parent class
844851 constructor, a value of 10 is assigned.
852+ :param type_dict: Keyword argument. Optional, defaults to an empty dict. The
853+ mapping from integer to elemental string. Default mapping is 1 -> 'H',
854+ 2 -> 'He', etc.
845855 """
846856 self .__parents [0 ] = Parent (
847- system1 , unit_cell = unit_cell , gb_thickness = gb_thickness )
857+ system1 , unit_cell = unit_cell , gb_thickness = gb_thickness , type_dict = type_dict )
848858 if system2 is not None :
849859 # If there are 2 parents, with the first one being of type GBMaker, and
850860 # unit_cell has not been passed in, we assume that the unit cell from the
@@ -855,7 +865,7 @@ def __set_parents(
855865 if gb_thickness is None :
856866 gb_thickness = system1 .gb_thickness
857867 self .__parents [1 ] = Parent (
858- system2 , unit_cell = unit_cell , gb_thickness = gb_thickness )
868+ system2 , unit_cell = unit_cell , gb_thickness = gb_thickness , type_dict = type_dict )
859869
860870 @property
861871 def rng (self ):
@@ -924,7 +934,7 @@ def remove_atoms(
924934 gb_fraction : float = None ,
925935 num_to_remove : int = None ,
926936 keep_ratio : bool = True ,
927- return_positions : bool = False
937+ return_positions : bool = False ,
928938 ) -> np .ndarray :
929939 """
930940 Removes *gb_fraction* of atoms or *num_to_remove* atom(s) in the GB region. Uses
@@ -961,11 +971,9 @@ def remove_atoms(
961971 "0 < gb_fraction <= 0.25"
962972 )
963973
964- if (num_to_remove is not None and
965- (
966- num_to_remove < 1 or num_to_remove > int (0.25 * len (gb_atoms ))
967- )
968- ):
974+ if num_to_remove is not None and (
975+ num_to_remove < 1 or num_to_remove > int (0.25 * len (gb_atoms ))
976+ ):
969977 raise GBManipulatorValueError (
970978 "Invalid num_to_remove value. Must be >= 1, and must be less than or "
971979 "equal to 25% of the total number of atoms in the GB region."
@@ -1004,12 +1012,12 @@ def remove_atoms(
10041012 parent .unit_cell .a0 ,
10051013 len (parent .unit_cell .unit_cell ),
10061014 Delta ,
1007- Rmax
1015+ Rmax ,
10081016 )
10091017 for idx , atom_idx in enumerate (gb_atom_indices )
10101018 ]
10111019 order = np .zeros (len (args_list ))
1012- for ( i , args ) in enumerate (args_list ):
1020+ for i , args in enumerate (args_list ):
10131021 order [i ] = _calculate_local_order (* args )
10141022
10151023 # We want the probabilities to be inversely proportional to the order parameter.
@@ -1047,8 +1055,10 @@ def remove_atoms(
10471055
10481056 central_num_to_remove = num_to_remove_dict [central_type ]
10491057 selected_central_indices = self .__rng .choice (
1050- central_indices , central_num_to_remove , replace = False ,
1051- p = central_probabilities
1058+ central_indices ,
1059+ central_num_to_remove ,
1060+ replace = False ,
1061+ p = central_probabilities ,
10521062 )
10531063
10541064 distances = {
@@ -1124,7 +1134,7 @@ def insert_atoms(
11241134 num_to_insert : int = None ,
11251135 method : str = "delaunay" ,
11261136 keep_ratio : bool = True ,
1127- return_positions : bool = False
1137+ return_positions : bool = False ,
11281138 ) -> np .ndarray :
11291139 """
11301140 Inserts **fraction** atoms in the GB at empty lattice sites. "Empty" sites are
@@ -1324,11 +1334,11 @@ def grid_approach(
13241334 )
13251335
13261336 if (num_to_insert is not None and
1327- (
1337+ (
13281338 num_to_insert < 1 or
13291339 num_to_insert > int (0.25 * len (gb_atoms ))
13301340 )
1331- ):
1341+ ):
13321342 raise GBManipulatorValueError (
13331343 "Invalid num_to_insert value. Must be >= 1, and must be less than or "
13341344 "equal to 25% of the total number of atoms in the GB region." )
@@ -1376,15 +1386,19 @@ def grid_approach(
13761386 if keep_ratio and len (type_map ) > 1 :
13771387 central_num_to_insert = num_to_insert_dict [central_type ]
13781388 selected_central_indices = self .__rng .choice (
1379- list (range (len (possible_sites ))), central_num_to_insert , replace = False ,
1389+ list (range (len (possible_sites ))),
1390+ central_num_to_insert ,
1391+ replace = False ,
13801392 p = probabilities
13811393 )
1382- cutoff = (parent .unit_cell .nn_distance (2 ) +
1383- parent .unit_cell .nn_distance (1 )) / 2.0
1394+ cutoff = (
1395+ parent .unit_cell .nn_distance (2 ) + parent .unit_cell .nn_distance (1 )
1396+ ) / 2.0
13841397 possible_sites_neighbor_list = _create_neighbor_list (cutoff , possible_sites )
13851398
13861399 atoms_to_add = {
1387- type_map [i ]: [] if type_map [i ] is not central_type else selected_central_indices for i in type_map .keys ()}
1400+ type_map [i ]: []
1401+ if type_map [i ] is not central_type else selected_central_indices for i in type_map .keys ()}
13881402 for atom_type , ratio in parent .unit_cell .ratio .items ():
13891403 if atom_type == central_type :
13901404 continue
@@ -1437,7 +1451,7 @@ def displace_along_soft_modes(
14371451 mesh_size : int = 4 ,
14381452 num_q : int = 1 ,
14391453 num_children : int = 1 ,
1440- subtract_displacement : bool = False
1454+ subtract_displacement : bool = False ,
14411455 ) -> np .ndarray :
14421456 """
14431457 Displace atoms along soft phonon modes.
0 commit comments