def calculate_fictitious_strain_energy( fictitious_strain: numpy.ndarray, resolve_elastic_modulus: callable, target: Union[C_, None] = None) -> numpy.ndarray: '''Calculate the strain energy for under given coordinate system, ignore the unknown. :param fictitious_strain: the fictitious strain where strain energy is calculated :param resolve_elastic_modulus: the function used to get elastic modulus :param target: the key for the elastic modulus ''' _energy = 0 nz = numpy.argwhere(numpy.logical_not(numpy.isclose(fictitious_strain, 0))) for (i, j), (k, l) in itertools.product(nz, nz): key = c_(i + 1, j + 1, k + 1, l + 1) if target and key == target: continue _moduli = resolve_elastic_modulus(key) _energy += _moduli * fictitious_strain[i, j] * fictitious_strain[k, l] / 2 return _energy
def apply_symetry_on_elast_data(input: ElastData, system: str) -> None: from cij.util.fill import fill_cij import pandas df = pandas.DataFrame([ dict( ("c%s%s" % key.v, val) for key, val in volume.static_elastic_modulus.items() ) for volume in input.volumes ]) df = fill_cij(df, system=system) for i in range(len(input.volumes)): static_elastic_modulus = dict([ (c_(key[1:]), val) for key, val in df.iloc[i, :].items() ]) input.volumes[i] = ElastVolumeData( input.volumes[i].volume, static_elastic_modulus )
def __getattr__(self, name): res = re.search(REGEX_CIJ, name) if res: if res.group(1) == "c": key = c_(res.group(2)) if key not in self.calculator.modulus_keys: raise AttributeError() if res.group(3) == 't': return self.calculator.modulus_isothermal[key] else: return self.calculator.modulus_adiabatic[key] if res.group(1) == "s": key = c_(res.group(2)) if key not in self.calculator._compliances.keys(): raise AttributeError() if res.group(1) == 't': raise AttributeError() return self.calculator._compliances[key] raise AttributeError(name)
def get_shear_phonon_modulus(self, key: C_, flag: str): if self.calculator.config["settings"]["disable_phonon_contribution"]: return numpy.zeros( self.calculator.qha_calculator.volume_base.pressures.shape) logger.debug(f"Start calculating {key}.") dims = (self.calculator.qha_calculator.t_array.shape[0], self.calculator.qha_calculator.v_array.shape[0]) if key.i != key.j: raise NotImplementedError() e = numpy.zeros((3, 3)) e[key.i[0] - 1, key.i[1] - 1] = 1 e[key.i[1] - 1, key.i[0] - 1] = 1 eig, t = numpy.linalg.eig(e) eig_new = numpy.diag(t @ numpy.eye(3) @ t.T) nz, = numpy.nonzero(eig) rhs = numpy.zeros(dims) for i, j in itertools.product(nz, nz): if i > j: continue _key: C_ = c_(i + 1, j + 1) #if not in allowed_keys: if _key.is_longitudinal: modulus = self.find_or_create_elastic_modulus_phonon_contribution( LongitudinalElasticModulusPhononContribution, (eig_new[i] / 3, eig_new[j] / 3)) elif _key.is_off_diagonal: modulus = self.find_or_create_elastic_modulus_phonon_contribution( OffDiagonalElasticModulusPhononContribution, (eig_new[i] / 3, eig_new[j] / 3)) #else: #c_shear() #value = getattr(modulus, f"value_{flag}") value = modulus.value_isothermal logger.debug(f"{_key.multiplicity * eig[i] * eig[j]} * c_{_key}") rhs += _key.multiplicity * eig[i] * eig[j] * value logger.debug(f"Dividing by {key.multiplicity}") return (rhs - 0) / key.multiplicity
def _calculate_compliances(self): elastic_moduli = numpy.zeros((*self.dims, 6, 6)) self._compliances = {} for key in self.modulus_keys: for i, j in set(itertools.permutations(key.voigt, 2)): elastic_moduli[:, :, i - 1, j - 1] = self.modulus_adiabatic[key] compliances = numpy.linalg.inv(elastic_moduli) for i, j in itertools.product(range(6), range(6)): if i > j: continue if numpy.allclose(compliances[:, :, i, j], 0): continue self._compliances[c_(i + 1, j + 1)] = compliances[:, :, i, j]
def plot_cij_t_with(self, handler: callable, cij_key: int, p: float): key = c_(cij_key) p_index = self.index_p(_from_gpa(p)) # p_array = self.calculator.pressure_base.p_array[p_indices[t_index]] # c_array = self.calculator.modulus_adiabatic[key][t_index, p_indices[t_index]] t_array = self.calculator.pressure_base.t_array c_array = self.calculator.pressure_base.modulus_adiabatic[key][:, p_index] return handler( t_array, _to_gpa(c_array), )
def plot_cij_p_with(self, handler: callable, cij_key: int, t: float): key = c_(cij_key) t_index = self.index_t(t) # p_array = self.calculator.pressure_base.p_array[p_indices[t_index]] # c_array = self.calculator.modulus_adiabatic[key][t_index, p_indices[t_index]] p_array = self.calculator.pressure_base.p_array c_array = self.calculator.pressure_base.modulus_adiabatic[key][ t_index, :] return handler( _to_gpa(p_array), _to_gpa(c_array), )
def plot_cij_p(self, ax: matplotlib.axes.Axes, cij_key: int, t: float, *argv, **kwargs): key = c_(cij_key) t_index = self.index_t(t) # p_array = self.calculator.pressure_base.p_array[p_indices[t_index]] # c_array = self.calculator.modulus_adiabatic[key][t_index, p_indices[t_index]] p_array = self.calculator.pressure_base.p_array c_array = self.calculator.pressure_base.modulus_adiabatic[key][ t_index, :] line, = ax.plot(_to_gpa(p_array), _to_gpa(c_array), *argv, **kwargs) return line
def get_fictitious_strain_energy_keys( fictitious_strain: numpy.ndarray, target: Union[C_, None] = None) -> numpy.ndarray: nz = numpy.argwhere(numpy.logical_not(numpy.isclose(fictitious_strain, 0))) _keys = [] for (i, j), (k, l) in itertools.product(nz, nz): key = c_(i + 1, j + 1, k + 1, l + 1) if target and key == target: continue _keys.append(key) return _keys
def _guess_unit(fname: str): import re from cij.io.output.results_writer import DEFAULT_WRITER_RULES for rule in DEFAULT_WRITER_RULES: fname_pattern = rule["fname_pattern"] regex_pattern = re.compile( fname_pattern.format(ij=r"(?P<ij>\d+)", base=r"(?P<base>[vpt]{2,2})")) res = regex_pattern.search(fname) if res: break if res is None: raise RuntimeError(f"File name '{fname}' has no match in rules!") key = None if 'ij' in dict(res.groups()).keys(): key = c_(res.group('ij')) return rule, key, res.group('base')
def reverse_moduli(stiffness: Dict[c_, numpy.array]) -> numpy.ndarray: ''' Calculate compliance from stiffness or stiffness from compliance .. math:: S_{ij}(T, V) = C{ij}^{-1}(T, V) :param `modulus_keys`: array of modulus :param `stiffness`: ''' # Flatten C[ij](T, V) to C[T, V, i, j] form dims = stiffness.values()[0].shape _stiffness = numpy.zeros((*dims, 6, 6)) for key in stiffness.keys(): for i, j in set(itertools.permutations(key.voigt, 2)): _stiffness[:, :, i - 1, j - 1] = stiffness[key][:, :] # Matrix inverse _compliance = numpy.linalg.inv(_stiffness) # Reconstruct with S[ij](T, V) from S[T, V, i, j] form compliance = {} for i, j in itertools.product(range(6), range(6)): if i > j: continue if numpy.allclose(_compliance[:, :, i, j], 0): continue compliance[c_(i + 1, j + 1)][:, :] = _compliance[:, :, i, j] return compliance
import pytest from cij.util import c_ @pytest.mark.parametrize( "a, b, result", [ (c_(11), c_(11), True ), (c_(11), c_(1111), True ), (c_("11"), c_(11), True ), (c_("1111") , c_(11), True ), (c_(11), c_(22), False), (c_(34), c_(43), True ), (c_(1112), c_(16), True ), (c_(1121), c_(16), True ), (c_(1211), c_(16), True ), (c_(56), c_(65), True ), ]) def test_expression(a, b, result): assert (a == b) == result
def _find_modulus_key(key: str): res = re.search(REGEX_MODULUS, key) if res: return c_(res.group(1)) else: return key