Пример #1
0
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
Пример #2
0
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

        )
Пример #3
0
 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)
Пример #4
0
    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
Пример #5
0
    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]
Пример #6
0
    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),
        )
Пример #7
0
    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),
        )
Пример #8
0
    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
Пример #9
0
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
Пример #10
0
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')
Пример #11
0
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
Пример #12
0
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
Пример #13
0
def _find_modulus_key(key: str):
    res = re.search(REGEX_MODULUS, key)
    if res:
        return c_(res.group(1))
    else:
        return key