from abaqusConstants import *
from .CombinedTestData import CombinedTestData
from ....Others.Mechanical.Viscosity.Trs import Trs
from ....TestData.ShearTestData import ShearTestData
from ....TestData.VolumetricTestData import VolumetricTestData


class Viscoelastic:
    r"""The Viscoelastic object specifies dissipative behavior for use with elasticity.

    Notes
    -----
    This object can be accessed by:

    .. code-block:: python

        import material
        mdb.models[name].materials[name].viscoelastic
        import odbMaterial
        session.odbs[name].materials[name].viscoelastic

    The table data for this object are:

    - If **frequency** = FORMULA, the table data for **table** specify the following:
    
        - Real part of :math:`g_{1}^{*}\left(g^{*}(\omega)=g_{1}^{*} f^{-a}\right)`
        - Imaginary part of :math:`g_{1}^{*}`.
        - Value of :math:`a`.
        - Real part of :math:`k_{1}^{*}\left(k^{*}(\omega)=k_{1}^{*} f^{-b}\right)`. If 
          the material is incompressible, this value is ignored.
        - Imaginary part of :math:`k_{1}^{*}`. If the material is incompressible, this 
          value is ignored.
        - Value of :math:`b`. If the material is incompressible, this value is ignored.
        
    - If **frequency** = TABULAR and **type** = ISOTROPIC and **preload** = NONE, or **time** = FREQUENCY_DATA 
      the table data for **table** specify the following:
      
        - Real part of :math:`\omega g^{*}\left(\omega \Re\left(g^{*}\right)=G_{\ell} / G_{\infty}\right)`.
        - Imaginary part of :math:`\omega g^{*}\left(\omega \mathfrak{J}\left(g^{*}\right)=1-G_{s} / G_{\infty}\right)`
        - Real part of :math:`\omega k^{*}\left(\omega \mathfrak{R}\left(k^{*}\right)=\mathrm{K}_{\ell} / \mathrm{K}_{\infty}\right)`. If the material is incompressible, this value is ignored.
        - Imaginary part of :math:`\omega k^{*}\left(\omega \mathfrak{I}\left(k^{*}\right)=1-\mathrm{K}_{s} / \mathrm{K}_{\infty}\right)`. If the material is incompressible, this value is ignored.
        - Frequency :math:`f` in cycles per time.
        
    - If **frequency** = TABULAR and **type** = ISOTROPIC and **preload** = UNIAXIAL the table data for **table** 
      specify the following:
    
        - Loss modulus.
        - Storage modulus.
        - Frequency.
        - Uniaxial strain.
        
    - If **frequency** = TABULAR and **type** = TRACTION and **preload** = NONE the table data for **table** 
      specify the following:
    
        - Normalized loss modulus.
        - Normalized shear modulus.
        - Frequency.
        
    - If **frequency** = TABULAR and **type** = TRACTION and **preload** = UNIAXIAL or 
      **preload** = UNIAXIAL_VOLUMETRIC the table data for **table** specify the following:
    
        - Loss modulus.
        - Storage modulus.
        - Frequency.
        - Closure.
        
    - If **time** = PRONY or **frequency** = PRONY, the table data for **table** specify the following:
    
        - :math:`\bar{g}_{1}^{P}`, the modulus ratio in the first term in the Prony series
          expansion of the shear relaxation modulus.
        - :math:`\bar{k}_{1}^{P}`, the modulus ratio in the first term in the Prony series 
          expansion of the bulk relaxation modulus.
        - :math:`\tau_{1}`, the relaxation time for the first term in the Prony series expansion.
        
    - If **frequency** = TABULAR and **type** = ISOTROPIC and **preload** = VOLUMETRIC or 
      **preload** = UNIAXIAL_VOLUMETRIC the table data for **volumetricTable** specify the following:
    
        - Loss modulus.
        - Storage modulus.
        - Frequency.
        - Volume ratio.

    The corresponding analysis keywords are:

    - VISCOELASTIC
    """

    # A :py:class:`~abaqus.Material.Elastic.HyperElastic.ViscoElastic.CombinedTestData.CombinedTestData` object.
    combinedTestData: CombinedTestData = CombinedTestData(((),))

    # A :py:class:`~abaqus.Material.TestData.ShearTestData.ShearTestData` object.
    shearTestData: ShearTestData = ShearTestData(((),))

    # A :py:class:`~abaqus.Material.Others.Mechanical.Viscosity.Trs.Trs` object.
    trs: Trs = Trs()

    # A :py:class:`~abaqus.Material.TestData.VolumetricTestData.VolumetricTestData` object.
    volumetricTestData: VolumetricTestData = VolumetricTestData(((),))

    def __init__(
        self,
        domain: SymbolicConstant,
        table: tuple,
        frequency: SymbolicConstant = FORMULA,
        type: SymbolicConstant = ISOTROPIC,
        preload: SymbolicConstant = NONE,
        time: SymbolicConstant = PRONY,
        errtol: float = 0,
        nmax: int = 13,
        volumetricTable: tuple = (),
    ):
        """This method creates a Viscoelastic object.

        Notes
        -----
        This function can be accessed by:

        .. code-block:: python

            mdb.models[name].materials[name].Viscoelastic
            session.odbs[name].materials[name].Viscoelastic

        Parameters
        ----------
        domain
            A SymbolicConstant specifying the domain definition. Possible values are:
            - FREQUENCY, specifying a frequency domain. This domain is only available for an Abaqus/Standard analysis.
            - TIME, specifying a time domain.
        table
            A sequence of sequences of Floats specifying the items described below.
        frequency
            A SymbolicConstant specifying the frequency domain definition. This argument is required
            only when **domain** = FREQUENCY. Possible values are FORMULA, TABULAR, PRONY,
            CREEP_TEST_DATA, and RELAXATION_TEST_DATA. The default value is FORMULA.
        type
            A SymbolicConstant specifying the type. This argument is required only when
            **domain** = FREQUENCY and **frequency** = TABULAR. Possible values are ISOTROPIC and TRACTION.
            The default value is ISOTROPIC.
        preload
            A SymbolicConstant specifying the preload. This argument is required only when
            **domain** = FREQUENCY and **frequency** = TABULAR. Possible values are NONE, UNIAXIAL,
            VOLUMETRIC, and UNIAXIAL_VOLUMETRIC. The default value is NONE.
        time
            A SymbolicConstant specifying the time domain definition. This argument is required only
            when **domain** = TIME. Possible values are PRONY, CREEP_TEST_DATA, RELAXATION_TEST_DATA,
            and FREQUENCY_DATA. The default value is PRONY.
        errtol
            A Float specifying the allowable average root-mean-square error of the data points in
            the least-squares fit. The Float values correspond to percentages; for example, 0.01 is
            1%. The default value is 0.01.This argument is valid only when **time** = CREEP_TEST_DATA,
            RELAXATION_TEST_DATA or FREQUENCY_DATA; or only when **frequency** = CREEP_TEST_DATA or
            RELAXATION_TEST_DATA.
        nmax
            An Int specifying the maximum number of terms NN in the Prony series. The maximum value
            is 13. The default value is 13.This argument is valid only when **time** = CREEP_TEST_DATA,
            RELAXATION_TEST_DATA or FREQUENCY_DATA; or only when **frequency** = CREEP_TEST_DATA or
            RELAXATION_TEST_DATA.
        volumetricTable
            A sequence of sequences of Floats specifying the items described below. The default
            value is an empty sequence.

        Returns
        -------
        Viscoelastic
            A :py:class:`~abaqus.Material.Elastic.HyperElastic.ViscoElastic.Viscoelastic.Viscoelastic` object.

        Raises
        ------
        RangeError
        """
        pass

    def setValues(self, *args, **kwargs):
        """This method modifies the Viscoelastic object.

        Raises
        ------
        RangeError
        """
        pass
