# This file was automatically generated by SWIG (https://www.swig.org).
# Version 4.1.1
#
# Do not make changes to this file unless you know what you are doing - modify
# the SWIG interface file instead.

from sys import version_info as _swig_python_version_info
# Import the low-level C/C++ module
if __package__ or "." in __name__:
    from . import _material
else:
    import _material

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__

def _swig_repr(self):
    try:
        strthis = "proxy of " + self.this.__repr__()
    except __builtin__.Exception:
        strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)


def _swig_setattr_nondynamic_instance_variable(set):
    def set_instance_attr(self, name, value):
        if name == "this":
            set(self, name, value)
        elif name == "thisown":
            self.this.own(value)
        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
            set(self, name, value)
        else:
            raise AttributeError("You cannot add instance attributes to %s" % self)
    return set_instance_attr


def _swig_setattr_nondynamic_class_variable(set):
    def set_class_attr(cls, name, value):
        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
            set(cls, name, value)
        else:
            raise AttributeError("You cannot add class attributes to %s" % cls)
    return set_class_attr


def _swig_add_metaclass(metaclass):
    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
    def wrapper(cls):
        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
    return wrapper


class _SwigNonDynamicMeta(type):
    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)


import ooflib.SWIG.common.abstractimage
import ooflib.SWIG.common.ccolor
import ooflib.SWIG.common.coord
import ooflib.SWIG.common.pixelattribute
import ooflib.SWIG.common.timestamp
import ooflib.SWIG.engine.property
class Material(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, arg2, MaterialType):
        _material.Material_swiginit(self, _material.new_Material(arg2, MaterialType))
    __swig_destroy__ = _material.delete_Material

    def name(self):
        return _material.Material_name(self)

    def rename(self, newname):
        return _material.Material_rename(self, newname)

    def type(self):
        return _material.Material_type(self)

    def add1Property(self, newprop):
        return _material.Material_add1Property(self, newprop)

    def remove1Property(self, oldprop):
        return _material.Material_remove1Property(self, oldprop)

    def fetchProperty(self, name):
        return _material.Material_fetchProperty(self, name)

    def getProperty(self, arg2):
        return _material.Material_getProperty(self, arg2)

    def nProperties(self):
        return _material.Material_nProperties(self)

    def registerPropertyType(self, p, name):
        return _material.Material_registerPropertyType(self, p, name)

    def registerFlux(self, arg2, arg3):
        return _material.Material_registerFlux(self, arg2, arg3)

    def registerEqn(self, arg2, arg3):
        return _material.Material_registerEqn(self, arg2, arg3)

    def registerOutput(self, arg2, arg3):
        return _material.Material_registerOutput(self, arg2, arg3)

    def clear_xref(self):
        return _material.Material_clear_xref(self)

    def self_consistent(self):
        return _material.Material_self_consistent(self)

    def set_consistency(self, arg2):
        return _material.Material_set_consistency(self, arg2)

    def cprecompute(self, arg2):
        return _material.Material_cprecompute(self, arg2)

    def begin_element(self, arg2, arg3):
        return _material.Material_begin_element(self, arg2, arg3)

    def end_element(self, arg2, arg3):
        return _material.Material_end_element(self, arg2, arg3)

    def contributes_to_flux(self, arg2):
        return _material.Material_contributes_to_flux(self, arg2)

    def cleanAttributes(self, arg2):
        return _material.Material_cleanAttributes(self, arg2)

    def replaceAttributes(self, arg2, arg3):
        return _material.Material_replaceAttributes(self, arg2, arg3)

    def assignToPixels(self, arg2, iPointList):
        return _material.Material_assignToPixels(self, arg2, iPointList)

    def assignToPixelGroup(self, arg2, arg3):
        return _material.Material_assignToPixelGroup(self, arg2, arg3)

    def assignToAllPixels(self, arg2):
        return _material.Material_assignToAllPixels(self, arg2)

    def nPixelsInMicrostructure(self, arg2):
        return _material.Material_nPixelsInMicrostructure(self, arg2)

# Register Material in _material:
_material.Material_swigregister(Material)
class MaterialAttributeRegistration(ooflib.SWIG.common.pixelattribute.PxlAttributeRegistration):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self):
        _material.MaterialAttributeRegistration_swiginit(self, _material.new_MaterialAttributeRegistration())
    __swig_destroy__ = _material.delete_MaterialAttributeRegistration

# Register MaterialAttributeRegistration in _material:
_material.MaterialAttributeRegistration_swigregister(MaterialAttributeRegistration)

def getMaterials(arg1):
    return _material.getMaterials(arg1)

def getMaterialFromCategory(arg1, arg2):
    return _material.getMaterialFromCategory(arg1, arg2)

def getMaterialFromPoint(arg1, iPoint):
    return _material.getMaterialFromPoint(arg1, iPoint)

def removeMaterialFromPixels(arg1, arg2):
    return _material.removeMaterialFromPixels(arg1, arg2)

def removeAllMaterials(arg1):
    return _material.removeAllMaterials(arg1)

def getMaterialTimeStamp(arg1):
    return _material.getMaterialTimeStamp(arg1)
class MaterialImage(ooflib.SWIG.common.abstractimage.AbstractImage):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, arg2, arg3, arg4):
        _material.MaterialImage_swiginit(self, _material.new_MaterialImage(arg2, arg3, arg4))

    def makeCanvasImage(self, arg2, arg3):
        return _material.MaterialImage_makeCanvasImage(self, arg2, arg3)
    __swig_destroy__ = _material.delete_MaterialImage

# Register MaterialImage in _material:
_material.MaterialImage_swigregister(MaterialImage)
# -*- python -*-


# This software was produced by NIST, an agency of the U.S. government,
# and by statute is not subject to copyright in the United States.
# Recipients of this software assume all responsibilities associated
# with its operation, modification and maintenance. However, to
# facilitate maintenance we ask that before distributing modified
# versions of this software, you first contact the authors at
# oof_manager@nist.gov.

from ooflib.SWIG.common import switchboard
from ooflib.SWIG.engine import ooferror
from ooflib.SWIG.engine import property
from ooflib.common import debug
from ooflib.common import utils
from ooflib.common.IO import oofmenu
import copy

from ooflib.engine import materialtype


oldMaterial__init__ = Material.__init__

def _Material___init__(self, name, mattype=materialtype.MATERIALTYPE_BULK):
    oldMaterial__init__(self, name, mattype)
    self.consistency_state = [] # empty if material is consistent

# addProperty and removeProperty maintain a Python list of
# property instances, which ensures that there exists a Python
# reference to each property in a material.  Reference-count
# manipulations are not required in the C++ code.
# Don't change self.properties to a set.  Preserving order is
# important for tests.
    self.properties = []

Material.__init__ = _Material___init__

def _Material_addProperty(self, prop):
    self.add1Property(prop)
    self.properties.append(prop)
    self.cross_reference()

Material.addProperty = _Material_addProperty

def _Material_removeProperty_(self, *properties):
    for prop in properties:
# Exception thrown by C++ code if the property is not present.
        self.remove1Property(prop)  # remove from C++ list
        self.properties.remove(prop)
    self.cross_reference()

Material.removeProperty = _Material_removeProperty_

# def _Material_properties(self):
#     return [self.getProperty(i) for i in range(self.nProperties())]

# Material.properties = _Material_properties

###########

# Call cross_reference() whenever properties have been added to or
# removed from the material, so the "consistency_state" flag/object is
# always correct.

# Cross-referencing relies on properties not being shared between
# materials -- otherwise, the material is ambiguous in precompute(),
# and in one of the contexts, the property can retrieve the wrong
# companion property.  Each material should have a unique copy of each
# of its properties.

def _Material_cross_reference(self):
    self.clear_xref()
    self.consistency_state = []
    for prop in self.properties: 
        try:
            prop.bookkeeping(self)
        except ooferror.PyErrRedundantProperty as exc:
            self.consistency_state.append(
                "Property '%s' is a redundant property of type '%s'."
                % (prop.name(), exc.get_tag()))
    for prop in self.properties: 
        try:
            prop.c_cross_reference(self)
        except ooferror.PyErrNoSuchProperty as exc:
            self.consistency_state.append(exc.summary())
    self.set_consistency(self.self_consistent()) # sets C++ flag

Material.cross_reference = _Material_cross_reference

def _Material_selfconsistent(self):
    return self.consistency_state == []
Material.self_consistent = _Material_selfconsistent

def _Material_consistency_messages(self):
    return self.consistency_state
Material.consistency_messages = _Material_consistency_messages

###########

def _Material_precompute(self, subproblem, fields):
# subproblem is a CSubProblem subclass instance, not a SubProblemContext.
    for prop in self.properties:
        prop.cache_active(subproblem, prop.is_active(subproblem))
        if prop.currently_active(subproblem):
            prop.c_precompute(subproblem.mesh)
            prop.cache_nonlinearity(subproblem, prop.is_nonlinear(fields))
    self.cprecompute(subproblem)

Material.precompute = _Material_precompute

# def _Material_precompute_all_properties(self, mesh):
#     for prop in self.properties():
#         try:
#             prop.precompute(mesh)
#         except ooferror.PyErrNoSuchField:
#             pass
#
# Material.precompute_all_properties = _Material_precompute_all_properties

###########

# Return true if we have any active nonlinear property.

def _Material_nonlinear(self, subproblem, fields):
## TODO: Remove the 'fields' arg.  This is called in
## SubProblemContext.nonlinear(), and possibly elsewhere.
    for p in self.properties:
        if p.currently_active(subproblem):
            if p.currently_nonlinear(subproblem):
                return True
    return False

Material.nonlinear = _Material_nonlinear

def _Material_second_order_field(self, subproblem, field, eqns):
    for p in self.properties:
        if p.currently_active(subproblem):
            r = p.registration()
            if field in r.second_order_fields(*eqns):
                return True
    return False

Material.is_second_order_field = _Material_second_order_field


def _Material_timeDependent(self, subproblem, fields):
    for p in self.properties:
        if p.currently_active(subproblem):
            r = p.registration()
            if r.timeDependent(fields):
                return True
    return False

Material.timeDependent = _Material_timeDependent


def _Material__symmetric(self, subprobctxt, fn):
    subprobctxt.solver_precompute()
    subproblem = subprobctxt.getObject()
    for p in self.properties:
        if p.currently_active(subproblem):
            if not fn(p, subproblem):
                return False
    return True
Material._is_symmetric = _Material__symmetric

def _Material_symmetric_K(self, subproblem):
    return self._is_symmetric(subproblem,
                              property.Property.c_is_symmetric_K)
Material.is_symmetric_K = _Material_symmetric_K

def _Material_symmetric_C(self, subproblem):
    return self._is_symmetric(subproblem, 
                              property.Property.c_is_symmetric_C)
Material.is_symmetric_C = _Material_symmetric_C

def _Material_symmetric_M(self, subproblem):
    return self._is_symmetric(subproblem,
                              property.Property.c_is_symmetric_M)
Material.is_symmetric_M = _Material_symmetric_M


######

# A Material's identity is tied to its name.  Python object identity
# doesn't work, because the same Material returned to Python via SWIG
# gets wrapped in different objects each time it's returned.

def _Material__eq__(self, other):
    return isinstance(other, Material) and other.name() == self.name()
Material.__eq__ = _Material__eq__

def _Material__ne__(self, other):
    return not self.__eq__(other)
Material.__ne__ = _Material__ne__

def _Material__hash__(self):
    return hash(self.name())
Material.__hash__ = _Material__hash__

######

def _Material___repr_(self):
    out = ["Material('" + self.name() + "'"]
    for prop in self.properties:
        out.append(repr(prop))
    out = utils.stringjoin(out, ",\n\t")
    return out + ")"

Material.__repr__ = _Material___repr_

def _Material_copy_(self, newname):
    m = Material(newname)
    for p in [copy.deepcopy(p) for p in self.properties]:
        m.addProperty(p)

    return m

Material.copy = _Material_copy_

##############################

# Create the singleton material attribute registration object.
# The (swig'd) constructor adds it to the global list of attributes.
attributeReg = MaterialAttributeRegistration()



