# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""Module providing the MatTabulatedJohnsonCookGysLogInterpolation class."""
import typing
from ansys.dyna.core.lib.card import Card, Field, Flag
from ansys.dyna.core.lib.field_schema import FieldSchema
from ansys.dyna.core.lib.option_card import OptionCardSet, OptionSpec
from ansys.dyna.core.lib.keyword_base import KeywordBase
from ansys.dyna.core.lib.keyword_base import LinkType
from ansys.dyna.core.keywords.keyword_classes.auto.define.define_curve import DefineCurve

_MATTABULATEDJOHNSONCOOKGYSLOGINTERPOLATION_CARD0 = (
    FieldSchema("mid", int, 0, 10, None),
    FieldSchema("ro", float, 10, 10, None),
    FieldSchema("e", float, 20, 10, None),
    FieldSchema("pr", float, 30, 10, None),
    FieldSchema("cp", float, 40, 10, None),
    FieldSchema("tr", float, 50, 10, 0.0),
    FieldSchema("beta", float, 60, 10, 1.0),
    FieldSchema("numint", float, 70, 10, 1.0),
)

_MATTABULATEDJOHNSONCOOKGYSLOGINTERPOLATION_CARD1 = (
    FieldSchema("lck1", int, 0, 10, 0),
    FieldSchema("lckt", int, 10, 10, 0),
    FieldSchema("lcf", int, 20, 10, 0),
    FieldSchema("lcg", int, 30, 10, 0),
    FieldSchema("lch", int, 40, 10, 0),
    FieldSchema("lci", int, 50, 10, 0),
)

_MATTABULATEDJOHNSONCOOKGYSLOGINTERPOLATION_CARD2 = (
    FieldSchema("lccr", int, 0, 10, None),
    FieldSchema("lcct", int, 10, 10, None),
    FieldSchema("lcsr", int, 20, 10, None),
    FieldSchema("lcst", int, 30, 10, None),
    FieldSchema("iflag", int, 40, 10, 0),
    FieldSchema("sfiepm", float, 50, 10, 1.0),
    FieldSchema("niter", int, 60, 10, 100),
)

_MATTABULATEDJOHNSONCOOKGYSLOGINTERPOLATION_OPTION0_CARD0 = (
    FieldSchema("title", str, 0, 80, None),
)

class MatTabulatedJohnsonCookGysLogInterpolation(KeywordBase):
    """DYNA MAT_TABULATED_JOHNSON_COOK_GYS_LOG_INTERPOLATION keyword"""

    keyword = "MAT"
    subkeyword = "TABULATED_JOHNSON_COOK_GYS_LOG_INTERPOLATION"
    option_specs = [
        OptionSpec("TITLE", -1, 1),
    ]
    _link_fields = {
        "lcg": LinkType.DEFINE_CURVE,
        "lch": LinkType.DEFINE_CURVE,
        "lci": LinkType.DEFINE_CURVE,
        "lck1": LinkType.DEFINE_CURVE_OR_TABLE,
        "lckt": LinkType.DEFINE_CURVE_OR_TABLE,
        "lcf": LinkType.DEFINE_CURVE_OR_TABLE,
    }

    def __init__(self, **kwargs):
        """Initialize the MatTabulatedJohnsonCookGysLogInterpolation class."""
        super().__init__(**kwargs)
        kwargs["parent"] = self
        self._cards = [
            Card.from_field_schemas_with_defaults(
                _MATTABULATEDJOHNSONCOOKGYSLOGINTERPOLATION_CARD0,
                **kwargs,
            ),            Card.from_field_schemas_with_defaults(
                _MATTABULATEDJOHNSONCOOKGYSLOGINTERPOLATION_CARD1,
                **kwargs,
            ),            Card.from_field_schemas_with_defaults(
                _MATTABULATEDJOHNSONCOOKGYSLOGINTERPOLATION_CARD2,
                **kwargs,
            ),            OptionCardSet(
                option_spec = MatTabulatedJohnsonCookGysLogInterpolation.option_specs[0],
                cards = [
                    Card.from_field_schemas_with_defaults(
                        _MATTABULATEDJOHNSONCOOKGYSLOGINTERPOLATION_OPTION0_CARD0,
                        **kwargs,
                    ),
                ],
                **kwargs
            ),
        ]
    @property
    def mid(self) -> typing.Optional[int]:
        """Get or set the Material identification. A unique number or label must be specified.
        """ # nopep8
        return self._cards[0].get_value("mid")

    @mid.setter
    def mid(self, value: int) -> None:
        """Set the mid property."""
        self._cards[0].set_value("mid", value)

    @property
    def ro(self) -> typing.Optional[float]:
        """Get or set the Mass density.
        """ # nopep8
        return self._cards[0].get_value("ro")

    @ro.setter
    def ro(self, value: float) -> None:
        """Set the ro property."""
        self._cards[0].set_value("ro", value)

    @property
    def e(self) -> typing.Optional[float]:
        """Get or set the Young's modulus.
        GT.0.0:	Constant value is used.
        LT.0.0:	Temperature dependent Young’s modulus given by load curve ID = -E
        """ # nopep8
        return self._cards[0].get_value("e")

    @e.setter
    def e(self, value: float) -> None:
        """Set the e property."""
        self._cards[0].set_value("e", value)

    @property
    def pr(self) -> typing.Optional[float]:
        """Get or set the Poisson's ratio.
        """ # nopep8
        return self._cards[0].get_value("pr")

    @pr.setter
    def pr(self, value: float) -> None:
        """Set the pr property."""
        self._cards[0].set_value("pr", value)

    @property
    def cp(self) -> typing.Optional[float]:
        """Get or set the Specific heat.
        """ # nopep8
        return self._cards[0].get_value("cp")

    @cp.setter
    def cp(self, value: float) -> None:
        """Set the cp property."""
        self._cards[0].set_value("cp", value)

    @property
    def tr(self) -> float:
        """Get or set the Room temperature.
        """ # nopep8
        return self._cards[0].get_value("tr")

    @tr.setter
    def tr(self, value: float) -> None:
        """Set the tr property."""
        self._cards[0].set_value("tr", value)

    @property
    def beta(self) -> float:
        """Get or set the Fraction of plastic work converted into heat (superseded by FWORK in *CONTROL_THERMAL_SOLVER if a coupled thermal/structural analysis):
        GT.0.0:	Constant value is used
        LT.0.0 : -BETA gives a load curve ID for strain rate dependence, a table ID for strain rateand temperature dependence, or a 3 - dimensional table ID for temperature(TABLE_3D), strain rate(TABLE) and plastic strain(CURVE) dependence, or a 4 - dimensional table ID for triaxiality(TABLE_4D), temperature(TABLE_3D), strain rate(TABLE) and plastic strain(CURVE) dependence.
        """ # nopep8
        return self._cards[0].get_value("beta")

    @beta.setter
    def beta(self, value: float) -> None:
        """Set the beta property."""
        self._cards[0].set_value("beta", value)

    @property
    def numint(self) -> float:
        """Get or set the Number of integration points which must fail before the element is deleted. Available for shells and solids.
        LT.0.0: |NUMINT| is percentage of integration points/layers which must fail before element fails. For fully integrated shells, a methodology is used where a layer fails if one integrationpoint fails and then the given percentage of layers must fail before the element fails.
        """ # nopep8
        return self._cards[0].get_value("numint")

    @numint.setter
    def numint(self, value: float) -> None:
        """Set the numint property."""
        self._cards[0].set_value("numint", value)

    @property
    def lck1(self) -> int:
        """Get or set the Table ID defining for each plastic strain rate value a load curve ID giving the (isothermal) effective stress as a function of effective plastic strain for that rate.
        """ # nopep8
        return self._cards[1].get_value("lck1")

    @lck1.setter
    def lck1(self, value: int) -> None:
        """Set the lck1 property."""
        self._cards[1].set_value("lck1", value)

    @property
    def lckt(self) -> int:
        """Get or set the Table ID defining for each temperature value a load curve ID giving the (qu asi-static) effective stress as a function of effective plastic strain for that temperature.
        """ # nopep8
        return self._cards[1].get_value("lckt")

    @lckt.setter
    def lckt(self, value: int) -> None:
        """Set the lckt property."""
        self._cards[1].set_value("lckt", value)

    @property
    def lcf(self) -> int:
        """Get or set the Load curve ID or table ID. The load curve specifies plastic failure strain as a function of triaxiality. The table specifies for each Lode parameter a load curve ID giving the plastic failure strain versus triaxiality for that Lode parameter. (Table option not yet generally supported).
        """ # nopep8
        return self._cards[1].get_value("lcf")

    @lcf.setter
    def lcf(self, value: int) -> None:
        """Set the lcf property."""
        self._cards[1].set_value("lcf", value)

    @property
    def lcg(self) -> int:
        """Get or set the Load curve ID for specifying plastic failure strain as a function of plastic strain rate.
        """ # nopep8
        return self._cards[1].get_value("lcg")

    @lcg.setter
    def lcg(self, value: int) -> None:
        """Set the lcg property."""
        self._cards[1].set_value("lcg", value)

    @property
    def lch(self) -> int:
        """Get or set the Load curve ID for specifying plastic failure strain as a function of temperature
        """ # nopep8
        return self._cards[1].get_value("lch")

    @lch.setter
    def lch(self, value: int) -> None:
        """Set the lch property."""
        self._cards[1].set_value("lch", value)

    @property
    def lci(self) -> int:
        """Get or set the Load curve ID or table ID. The load curve ID defines plastic failure strain as a function of element size. The table ID defines for each triaxiality a load curve ID giving the plastic failure strain versus element size for that triaxiality.
        """ # nopep8
        return self._cards[1].get_value("lci")

    @lci.setter
    def lci(self, value: int) -> None:
        """Set the lci property."""
        self._cards[1].set_value("lci", value)

    @property
    def lccr(self) -> typing.Optional[int]:
        """Get or set the Table ID. The curves in this table define compressive yield stress as a function of plastic strain or effective plastic strain (see IFLAG). The table ID defines for each plastic strain rate value or effective plastic strain rate value a load curve ID giving the (isothermal) compressive yield stress as a function of plastic strain or effective plastic strain for that rate.
        """ # nopep8
        return self._cards[2].get_value("lccr")

    @lccr.setter
    def lccr(self, value: int) -> None:
        """Set the lccr property."""
        self._cards[2].set_value("lccr", value)

    @property
    def lcct(self) -> typing.Optional[int]:
        """Get or set the Table ID defining for each temperature value a load curve ID giving the (quasi-static) compressive yield stress as a function of strain for that temperature. The curves in this table define compressive yield stress as a function of plastic strain or effective plastic strain (see IFLAG).
        """ # nopep8
        return self._cards[2].get_value("lcct")

    @lcct.setter
    def lcct(self, value: int) -> None:
        """Set the lcct property."""
        self._cards[2].set_value("lcct", value)

    @property
    def lcsr(self) -> typing.Optional[int]:
        """Get or set the Table ID. The load curves define shear yield stress in function of plastic strain or effective plastic strain (see IFLAG). The table ID defines for each plastic strain rate value or effective plastic strain rate value a load curve ID giving the (isothermal) shear yield stress as a function of plastic strain or effective plastic strain for that rate.
        """ # nopep8
        return self._cards[2].get_value("lcsr")

    @lcsr.setter
    def lcsr(self, value: int) -> None:
        """Set the lcsr property."""
        self._cards[2].set_value("lcsr", value)

    @property
    def lcst(self) -> typing.Optional[int]:
        """Get or set the Table ID defining for each temperature value a load curve ID giving the (quasi-static) shear yield stress as a function of strain for that temperature. The load curves define shear yield stress as a function of plastic strain or effective plastic strain (see IFLAG).
        """ # nopep8
        return self._cards[2].get_value("lcst")

    @lcst.setter
    def lcst(self, value: int) -> None:
        """Set the lcst property."""
        self._cards[2].set_value("lcst", value)

    @property
    def iflag(self) -> int:
        """Get or set the Flag to specify abscissa for LCCR, LCCT, LCSR, LCST:
        EQ.0:	Compressive and shear yields are given as functions of plastic strain as defined in Remark 1 (default).
        EQ.1 : Compressive and shear yields are given as functions of effective plastic strain
        """ # nopep8
        return self._cards[2].get_value("iflag")

    @iflag.setter
    def iflag(self, value: int) -> None:
        """Set the iflag property."""
        if value not in [0, 1, None]:
            raise Exception("""iflag must be `None` or one of {0,1}.""")
        self._cards[2].set_value("iflag", value)

    @property
    def sfiepm(self) -> float:
        """Get or set the Scale factor on the initial estimate of the plastic multiplier.
        """ # nopep8
        return self._cards[2].get_value("sfiepm")

    @sfiepm.setter
    def sfiepm(self, value: float) -> None:
        """Set the sfiepm property."""
        self._cards[2].set_value("sfiepm", value)

    @property
    def niter(self) -> int:
        """Get or set the Number of secant iterations to be performed.
        """ # nopep8
        return self._cards[2].get_value("niter")

    @niter.setter
    def niter(self, value: int) -> None:
        """Set the niter property."""
        self._cards[2].set_value("niter", value)

    @property
    def title(self) -> typing.Optional[str]:
        """Get or set the Additional title line
        """ # nopep8
        return self._cards[3].cards[0].get_value("title")

    @title.setter
    def title(self, value: str) -> None:
        """Set the title property."""
        self._cards[3].cards[0].set_value("title", value)

        if value:
            self.activate_option("TITLE")

    @property
    def lcg_link(self) -> typing.Optional[DefineCurve]:
        """Get the DefineCurve object for lcg."""
        if self.deck is None:
            return None
        for kwd in self.deck.get_kwds_by_full_type("DEFINE", "CURVE"):
            if kwd.lcid == self.lcg:
                return kwd
        return None

    @lcg_link.setter
    def lcg_link(self, value: DefineCurve) -> None:
        """Set the DefineCurve object for lcg."""
        self.lcg = value.lcid

    @property
    def lch_link(self) -> typing.Optional[DefineCurve]:
        """Get the DefineCurve object for lch."""
        if self.deck is None:
            return None
        for kwd in self.deck.get_kwds_by_full_type("DEFINE", "CURVE"):
            if kwd.lcid == self.lch:
                return kwd
        return None

    @lch_link.setter
    def lch_link(self, value: DefineCurve) -> None:
        """Set the DefineCurve object for lch."""
        self.lch = value.lcid

    @property
    def lci_link(self) -> typing.Optional[DefineCurve]:
        """Get the DefineCurve object for lci."""
        if self.deck is None:
            return None
        for kwd in self.deck.get_kwds_by_full_type("DEFINE", "CURVE"):
            if kwd.lcid == self.lci:
                return kwd
        return None

    @lci_link.setter
    def lci_link(self, value: DefineCurve) -> None:
        """Set the DefineCurve object for lci."""
        self.lci = value.lcid

    @property
    def lck1_link(self) -> typing.Optional[KeywordBase]:
        """Get the linked DEFINE_CURVE or DEFINE_TABLE for lck1."""
        if self.deck is None:
            return None
        field_value = self.lck1
        if field_value is None or field_value == 0:
            return None
        for kwd in self.deck.get_kwds_by_full_type("DEFINE", "CURVE"):
            if kwd.lcid == field_value:
                return kwd
        for kwd in self.deck.get_kwds_by_full_type("DEFINE", "TABLE"):
            if kwd.tbid == field_value:
                return kwd
        return None

    @lck1_link.setter
    def lck1_link(self, value: KeywordBase) -> None:
        """Set the linked keyword for lck1."""
        if hasattr(value, "lcid"):
            self.lck1 = value.lcid
        elif hasattr(value, "tbid"):
            self.lck1 = value.tbid

    @property
    def lckt_link(self) -> typing.Optional[KeywordBase]:
        """Get the linked DEFINE_CURVE or DEFINE_TABLE for lckt."""
        if self.deck is None:
            return None
        field_value = self.lckt
        if field_value is None or field_value == 0:
            return None
        for kwd in self.deck.get_kwds_by_full_type("DEFINE", "CURVE"):
            if kwd.lcid == field_value:
                return kwd
        for kwd in self.deck.get_kwds_by_full_type("DEFINE", "TABLE"):
            if kwd.tbid == field_value:
                return kwd
        return None

    @lckt_link.setter
    def lckt_link(self, value: KeywordBase) -> None:
        """Set the linked keyword for lckt."""
        if hasattr(value, "lcid"):
            self.lckt = value.lcid
        elif hasattr(value, "tbid"):
            self.lckt = value.tbid

    @property
    def lcf_link(self) -> typing.Optional[KeywordBase]:
        """Get the linked DEFINE_CURVE or DEFINE_TABLE for lcf."""
        if self.deck is None:
            return None
        field_value = self.lcf
        if field_value is None or field_value == 0:
            return None
        for kwd in self.deck.get_kwds_by_full_type("DEFINE", "CURVE"):
            if kwd.lcid == field_value:
                return kwd
        for kwd in self.deck.get_kwds_by_full_type("DEFINE", "TABLE"):
            if kwd.tbid == field_value:
                return kwd
        return None

    @lcf_link.setter
    def lcf_link(self, value: KeywordBase) -> None:
        """Set the linked keyword for lcf."""
        if hasattr(value, "lcid"):
            self.lcf = value.lcid
        elif hasattr(value, "tbid"):
            self.lcf = value.tbid

