Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
merging. index is a single index for the Wyckoff position within
the sg. If no matching WP is found, returns False. point is a 3-vector;
when plugged into the Wyckoff position, it will generate all the other
points.
"""
coor = np.array(coor)
# Get index of current Wyckoff position. If not one, return False
index, point = check_wyckoff_position(coor, group)
if index is False:
return coor, False, None
if point is None:
printx("Error: Could not find generating point.", priority=1)
printx("coordinates:")
printx(str(coor))
printx("Lattice: ")
printx(str(lattice))
printx("group: ")
group.print_all()
return coor, False, None
PBC = group.PBC
# Main loop for merging multiple times
while True:
# Check distances of current WP. If too small, merge
dm = distance_matrix([coor[0]], coor, lattice, PBC=PBC)
passed_distance_check = True
x = np.argwhere(dm < tol)
for y in x:
# Ignore distance from atom to itself
if y[0] == 0 and y[1] == 0:
pass
else:
passed_distance_check = False
coor, index, point: (coor) is the new list of fractional coordinates after
merging. index is a single index for the Wyckoff position within
the sg. If no matching WP is found, returns False. point is a 3-vector;
when plugged into the Wyckoff position, it will generate all the other
points.
"""
coor = np.array(coor)
# Get index of current Wyckoff position. If not one, return False
index, point = check_wyckoff_position(coor, group)
if index is False:
return coor, False, None
if point is None:
printx("Error: Could not find generating point.", priority=1)
printx("coordinates:")
printx(str(coor))
printx("Lattice: ")
printx(str(lattice))
printx("group: ")
group.print_all()
return coor, False, None
PBC = group.PBC
# Main loop for merging multiple times
while True:
# Check distances of current WP. If too small, merge
dm = distance_matrix([coor[0]], coor, lattice, PBC=PBC)
passed_distance_check = True
x = np.argwhere(dm < tol)
for y in x:
# Ignore distance from atom to itself
if y[0] == 0 and y[1] == 0:
pass
else:
than this.
'mid_l': the second smallest allowed cell vector. The second smallest vector
must be larger than this.
'max_l': the third smallest allowed cell vector. The largest cell vector must
be larger than this.
Returns:
a 3x3 matrix representing the lattice vectors of the unit cell. If
generation fails, outputs a warning message and returns empty
"""
if ltype == "spherical":
# Use a cubic lattice with altered volume
a = b = c = np.cbrt((3 * volume) / (4 * np.pi))
alpha = beta = gamma = 0.5 * np.pi
if a < minvec:
printx(
"Could not generate spherical lattice; volume too small compared to minvec",
priority=2,
)
return
return np.array([a, b, c, alpha, beta, gamma])
if ltype == "ellipsoidal":
# Use a matrix with only on-diagonal elements, with a = b
alpha, beta, gamma = np.pi / 2, np.pi / 2, np.pi / 2
x = (4.0 / 3.0) * np.pi
for numattempts in range(maxattempts):
vec = random_vector()
c = vec[2] / (vec[0] * vec[1]) * np.cbrt(volume / x)
a = b = np.sqrt((volume / x) / c)
if (a / c < 10.0) and (c / a < 10.0):
return np.array([a, b, c, alpha, beta, gamma])
return
def __init__(self, matrix, degrees=0, axis=None):
if (degrees == 1) and (axis is None):
printx("Error: Constraint vector required for orientation", priority=1)
self.matrix = np.array(matrix)
self.r = Rotation.from_matrix(matrix) # scipy transform.Rotation class
self.degrees = degrees # The number of degrees of freedom.
self.axis = axis # The rotational axis (optional)
self.angle = None
Returns:
coor, index, point: (coor) is the new list of fractional coordinates after
merging. index is a single index for the Wyckoff position within
the sg. If no matching WP is found, returns False. point is a 3-vector;
when plugged into the Wyckoff position, it will generate all the other
points.
"""
coor = np.array(coor)
# Get index of current Wyckoff position. If not one, return False
index, point = check_wyckoff_position(coor, group)
if index is False:
return coor, False, None
if point is None:
printx("Error: Could not find generating point.", priority=1)
printx("coordinates:")
printx(str(coor))
printx("Lattice: ")
printx(str(lattice))
printx("group: ")
group.print_all()
return coor, False, None
PBC = group.PBC
# Main loop for merging multiple times
while True:
# Check distances of current WP. If too small, merge
dm = distance_matrix([coor[0]], coor, lattice, PBC=PBC)
passed_distance_check = True
x = np.argwhere(dm < tol)
for y in x:
# Ignore distance from atom to itself
if y[0] == 0 and y[1] == 0:
# 1st symbol: x, y, and/or z axes (whichever have highest symmetry)
s1 = combine_axes([0, 1, 2])
# 2nd symbol: body-diagonal axes (whichever has highest symmetry)
s2 = combine_axes([9, 10, 11, 12])
# 3rd symbol: face-diagonal axes (whichever have highest symmetry)
s3 = combine_axes([3, 4, 5, 6, 7, 8])
symbol = s1 + " " + s2 + " " + s3
if symbol != ". . .":
return symbol
elif symbol == ". . .":
if has_inversion is True:
return "-1"
else:
return "1"
else:
printx("Error: invalid spacegroup number", priority=1)
return
self.volume = self.estimate_volume()
self.lattice.volume = self.volume
self.lattice.reset_matrix()
try:
cell_matrix = self.lattice.get_matrix()
if cell_matrix is None:
continue
# TODO remove bare except
except:
continue
# Check that the correct volume was generated
if self.lattice.random is True:
if self.dim != 0 and abs(self.volume - self.lattice.volume) > 1.0:
printx(
(
"Error, volume is not equal to the estimated value: "
"{} -> {} cell_para: {}"
).format(self.volume, self.lattice.volume, self.lattice.get_para),
priority=0,
)
self.valid = False
self.struct = None
return
# to try to generate atomic coordinates
for cycle2 in range(self.coord_attempts):
self.cycle2 = cycle2
output = self._generate_coords(cell_matrix)
if output:
[coordinates_tmp, coords_toadd]
)
species_tmp += species_toadd
numMol_added += len(coords_toadd) / len(symbols)
if numMol_added == numMol:
# We have enough molecules of the current type
mol_sites_total = deepcopy(mol_sites_tmp)
coordinates_total = deepcopy(coordinates_tmp)
species_total = deepcopy(species_tmp)
break
if numMol_added != numMol:
break # need to repeat from the 1st species
if numMol_added == numMol:
printx(self.Msg6, priority=3)
good_structure = True
break
else: # reset the coordinates and sites
molecular_coordinates_total = []
molecular_sites_total = []
wps_total = []
# placing molecules here
if good_structure:
final_lattice = cell_matrix
final_coor = []
final_site = []
final_number = []
self.mol_sites = [] # to regenerate the crystal
final_coor = deepcopy(coordinates_total)
final_site = deepcopy(species_total)