from __future__ import annotations

from typing_extensions import Literal

from abqpy.decorators import abaqus_class_doc, abaqus_method_doc

from .....UtilityAndView.abaqusConstants import (
    COMPRESSION,
    LINEAR,
    OFF,
    POWER_LAW,
    STRAIN,
    Boolean,
)
from .....UtilityAndView.abaqusConstants import abaqusConstants as C
from ...Metal.RateDependent.RateDependent import RateDependent
from .DruckerPragerCreep import DruckerPragerCreep
from .DruckerPragerHardening import DruckerPragerHardening
from .TriaxialTestData import TriaxialTestData


@abaqus_class_doc
class DruckerPrager:
    r"""The DruckerPrager object specifies the extended Drucker-Prager plasticity model.

    .. note::
        This object can be accessed by::

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

        The table data for this object are:

        - If **shearCriterion** = LINEAR (the only option allowed in an Abaqus/Explicit analysis), the table data specify the following:

            - Material angle of friction, :math:`\beta`, in the :math:`p-t` plane. Give the value in degrees.
            - :math:`K`, the ratio of the flow stress in triaxial tension to the flow stress in triaxial
              compression. :math:`0.778 \leq K \leq 1.0`. If the default value of :math:`0.0` is accepted, a
              value of :math:`1.0` is assumed.
            - Dilation angle, :math:`\psi`, in the :math:`p-t` plane. Give the value in degrees.
            - Temperature, if the data depend on temperature.
            - Value of the first field variable, if the data depend on field variables.
            - Value of the second field variable.
            - Etc.
        - If **shearCriterion** = HYPERBOLIC, the table data specify the following:

            - Material angle of friction, :math:`\beta`, at high confining pressure in the :math:`p-q` plane.
              Give the value in degrees.
            - Initial hydrostatic tension strength, :math:`\left.p_{t}\right|_{0}`.
            - Dilation angle, :math:`\psi`, at high confining pressure in the :math:`p-q` plane. Give the value
              in degrees.
            - Temperature, if the data depend on temperature.
            - Value of the first field variable, if the data depend on field variables.
            - Value of the second field variable.
            - Etc.
        - If **shearCriterion** = EXPONENTIAL, the table data specify the following:

            - Dilation angle, :math:`\psi`, at high confining pressure in the :math:`p-q` plane. Give
              the value in degrees.
            - Temperature, if the data depend on temperature.
            - Value of the first field variable, if the data depend on field variables.
            - Value of the second field variable.
            - Etc.

        The corresponding analysis keywords are:

        - DRUCKER PRAGER
    """

    #: A DruckerPragerCreep object.
    druckerPragerCreep: DruckerPragerCreep = DruckerPragerCreep(((),))

    #: A DruckerPragerHardening object.
    druckerPragerHardening: DruckerPragerHardening = DruckerPragerHardening(((),))

    #: A RateDependent object.
    rateDependent: RateDependent = RateDependent(((),))

    #: A TriaxialTestData object.
    triaxialTestData: TriaxialTestData = TriaxialTestData(((),))

    @abaqus_method_doc
    def __init__(
        self,
        table: tuple,
        shearCriterion: Literal[C.EXPONENTIAL, C.HYPERBOLIC, C.LINEAR] = LINEAR,
        eccentricity: float = 0,
        testData: Boolean = OFF,
        temperatureDependency: Boolean = OFF,
        dependencies: int = 0,
    ):
        r"""This method creates a DruckerPrager object.

        .. note::
            This function can be accessed by::

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

        Parameters
        ----------
        table
            A sequence of sequences of Floats specifying the items described below.
        shearCriterion
            A SymbolicConstant specifying the yield criterion. Possible values are LINEAR,
            HYPERBOLIC, and EXPONENTIAL. The default value is LINEAR.This argument applies only to
            Abaqus/Standard analyses. Only the linear Drucker-Prager model is available in
            Abaqus/Explicit analyses.
        eccentricity
            A Float specifying the flow potential eccentricity, :math:`\epsilon`, a small positive number that
            defines the rate at which the hyperbolic flow potential approaches its asymptote. The
            default value is 0.1.This argument applies only to Abaqus/Standard analyses.
        testData
            A Boolean specifying whether the material constants for the exponent model are to be
            computed by Abaqus/Standard from triaxial test data at different levels of confining
            pressure. The default value is OFF.This argument is valid only if
            **shearCriterion** = EXPONENTIAL.
        temperatureDependency
            A Boolean specifying whether the data depend on temperature. The default value is OFF.
        dependencies
            An Int specifying the number of field variable dependencies. The default value is 0.

        Returns
        -------
        DruckerPrager
            A DruckerPrager object.

        Raises
        ------
        RangeError
        """
        ...

    @abaqus_method_doc
    def DruckerPragerCreep(
        self,
        table: tuple,
        law: Literal[C.STRAIN] = STRAIN,
        temperatureDependency: Boolean = OFF,
        dependencies: int = 0,
    ):
        """This method creates a DruckerPragerCreep object.

        .. note::
            This function can be accessed by::

                mdb.models[name].materials[name].druckerPrager.DruckerPragerCreep
                session.odbs[name].materials[name].druckerPrager.DruckerPragerCreep

        Parameters
        ----------
        table
            A sequence of sequences of Floats specifying the items described below.
        law
            A SymbolicConstant specifying the type of data defining the creep law. Possible values
            are:STRAIN, specifying a strain-hardening power law.TIME, specifying a time-hardening
            power law.SINGHM, specifying a Singh-Mitchell type law.USER, specifying the creep law is
            input from user subroutine CREEP.The default value is STRAIN.
        temperatureDependency
            A Boolean specifying whether the data depend on temperature. The default value is OFF.
        dependencies
            An Int specifying the number of field variable dependencies. The default value is 0.

        Returns
        -------
        DruckerPragerCreep
            A DruckerPragerCreep object.

        Raises
        ------
        RangeError
        """
        ...

    @abaqus_method_doc
    def DruckerPragerHardening(
        self,
        table: tuple,
        type: Literal[C.SHEAR, C.TENSION, C.COMPRESSION] = COMPRESSION,
        rate: Boolean = OFF,
        temperatureDependency: Boolean = OFF,
        dependencies: int = 0,
    ):
        """This method creates a DruckerPragerHardening object.

        .. note::
            This function can be accessed by::

                mdb.models[name].materials[name].druckerPrager.DruckerPragerHardening
                    session.odbs[name].materials[name].druckerPrager.DruckerPragerHardening

        Parameters
        ----------
        table
            A sequence of sequences of Floats specifying the items described below.
        type
            A SymbolicConstant specifying the type of data defining the hardening behavior. Possible
            values are COMPRESSION, TENSION, and SHEAR. The default value is COMPRESSION.
        rate
            A Boolean specifying whether the data depend on rate. The default value is OFF.
        temperatureDependency
            A Boolean specifying whether the data depend on temperature. The default value is OFF.
        dependencies
            An Int specifying the number of field variable dependencies. The default value is 0.

        Returns
        -------
        DruckerPragerHardening
            A DruckerPragerHardening object.

        Raises
        ------
        RangeError
        """
        ...

    @abaqus_method_doc
    def RateDependent(
        self,
        table: tuple,
        type: Literal[C.JOHNSON_COOK, C.POWER_LAW, C.YIELD_RATIO] = POWER_LAW,
        temperatureDependency: Boolean = OFF,
        dependencies: int = 0,
    ):
        """This method creates a RateDependent object.

        .. note::
            This function can be accessed by::

                mdb.models[name].materials[name].crushableFoam.RateDependent
                mdb.models[name].materials[name].druckerPrager.RateDependent
                mdb.models[name].materials[name].Plastic.RateDependent
                session.odbs[name].materials[name].crushableFoam.RateDependent
                session.odbs[name].materials[name].druckerPrager.RateDependent
                session.odbs[name].materials[name].Plastic.RateDependent

        Parameters
        ----------
        table
            A sequence of sequences of Floats specifying the items described below.
        type
            A SymbolicConstant specifying the type of rate-dependent data. Possible values are
            POWER_LAW, YIELD_RATIO, and JOHNSON_COOK. The default value is POWER_LAW.
        temperatureDependency
            A Boolean specifying whether the data depend on temperature. The default value is OFF.
        dependencies
            An Int specifying the number of field variable dependencies. The default value is 0.

        Returns
        -------
        RateDependent
            A RateDependent object.

        Raises
        ------
        RangeError
        """
        ...

    @abaqus_method_doc
    def TriaxialTestData(self, table: tuple, a: float | None = None, b: float | None = None, pt: float | None = None):
        """This method creates a TriaxialTestData object.

        .. note::
            This function can be accessed by::

                mdb.models[name].materials[name].druckerPrager.TriaxialTestData
                session.odbs[name].materials[name].druckerPrager.TriaxialTestData

        Parameters
        ----------
        table
            A sequence of sequences of Floats specifying the items described below.
        a
            None or a Float specifying the value of the material constant aa. None is used when the
            value is unknown or it is not held fixed at the input value. The default value is None.
        b
            None or a Float specifying the value of the material constant bb. None is used when the
            value is unknown or it is not held fixed at the input value. The default value is None.
        pt
            None or a Float specifying the value of the material constant pt. None is used when the
            value is unknown or it is not held fixed at the input value. The default value is None.

        Returns
        -------
        TriaxialTestData
            A TriaxialTestData object.

        Raises
        ------
        RangeError
        """
        ...

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

        Raises
        ------
        RangeError
        """
        ...
