#
# Copyright © 2020 MSC.Software Corporation
#  
# Permission to use Scripts
#  
# Permission is granted to MSC.Software customers with valid licenses of the MSC Apex™ software 
# to use script files posted on this page (collectively “Scripts”) solely for customers’ own authorized 
# internal use in conjunction with licensed use of the MSC Apex software.  
# No other use is permitted.  No license to MSC Apex or other software is granted under this Permission.
#  
# SCRIPTS ARE PROVIDED ON AN "AS-IS" BASIS, WITH NO WARRANTIES OF ANY KIND.  USE OF THE SCRIPTS IS AT CUSTOMER'S SOLE RISK.
#  
# IN NO EVENT SHALL MSC.SOFTWARE CORPORATION, ITS AFFILIATES, SUBSIDIARIES, SUPPLIERS, AGENTS, REPRESENTATIVES OR EMPLOYEES BE LIABLE FOR ANY 
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, TORT, 
# STRICT LIABILITY, OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION USE OF THE SCRIPTS, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
#  
# Customer shall indemnify, defend and hold MSC.Software Corporation, its affiliates, subsidiaries, suppliers, agents, 
# employees or representatives (collectively, “Indemnified Parties”) harmless from and against any third-party claims 
# brought against Indemnified Parties rising out of or in connection with Customer’s use of the Scripts.
#
"""
Created on Thu Apr 21 13:55:25 2016
material classes and material related routines
@author: e1851
"""


import apex
from apex.construct import Point3D, Point2D


import numpy


############################
class matOrth:
    ########################
    def __init__(self, id, e1, e2, nu12, g12, g1z=0.0, g2z=0.0, xt=0.0, xc=0.0,
                 yt=0.0, yc=0.0, s=0.0, ixy=-0.5, q=numpy.empty([3, 3])):
        self.id = id
        self.e1 = e1
        self.e2 = e2
        self.nu12 = nu12
        self.g12 = g12
        self.g1z = g1z
        self.g2z = g2z
        self.xt = xt
        self.xc = xc
        self.yt = yt
        self.yc = yc
        self.s = s
        self.ixy = ixy
        self.q = q
        return

    def __str__(self):

        if not(self.e1 > 0.0 and self.e2 > 0.0 and self.g12 > 0.0):
            return "Mat " + str(self.id) + " Material stiffness invalid"
        else:
            if not(self.g1z > 0.0 and self.g2z > 0.0):
                return "Mat " + str(self.id) + " No out-of-plane shear stiffness"
            else:
                if not (self.xt > 0.0 and
                        self.xc > 0.0 and
                        self.yt > 0.0 and
                        self.yc > 0.0 and
                        self.s > 0.0):
                    print("Mat " + str(self.id) + " Invalid strength allowables")
                    print("xt =" + str(self.xt))
                    print("xc =" + str(self.xc))
                    print("yt =" + str(self.yt))
                    print("yc =" + str(self.yc))
                    print("s =" + str(self.s))
        return f"Mat ID {self.id}, E1= {self.e1}, E2= {self.e2}, Nu12= \
            {self.nu12}, g12= {self.g12}, ixy= {self.ixy}, Xt= {self.xt}, \
            Xc= {self.xc},. Yt= {self.yt} Yc= {self.yc} SS= {self.s}"


############################
class matIso:
    #########################
    def __init__(self, id, e, g, nu, rho=0.0, a=0.0, tref=0.0, ge=0.0, st=0.0,
                 sc=0.0, ss=0.0, q=numpy.empty([3, 3])):
        self.id = id
        self.e = e
        self.g = g
        self.nu = nu
        self.rho = rho
        self.a = a
        self.tref = tref
        self.ge = ge
        self.st = st
        self.sc = sc
        self.ss = ss
        self.q = q
        return

    def __str__(self):
        if not(self.e > 0.0):
            return "Mat " + str(self.id) + " Material stiffness invalid"
        else:
            if not (self.st > 0.0 and self.sc > 0.0 and self.ss > 0.0):
                return "Mat " + str(self.id) + " Invalid strength allowables"
            return ("Mat ID: " + str(self.id) + ", E= " + str(self.e) + ", Nu= " +
                    str(self.nu))


def find_all_mat_properties():

    model = apex.currentModel()
    allMatls = apex.catalog.getMaterials([{"path":"/CatalogMaterial" }])
    mat1_dict = {}
    mat8_dict = {}

    for material in allMatls:
        matName = material.getName()
        matType = material.getMaterialType()
        if matType == 1:

            modulii = material.getElasticityOrthotropic2D()
            e1 = modulii['elasticModulusX']
            e2 = modulii['elasticModulusY']
            g12 = modulii['shearModulusXY']
            g2z = modulii['shearModulusYZ']
            g1z = modulii['shearModulusXZ']
            nu12 = material.getPoissonRatio()
            failure = material.getFailureLimitsOrthotropic2D()
            xt = failure['stressLimitTensionX']
            yt = failure['stressLimitTensionY']
            xc = failure['stressLimitCompressionX']
            yc = failure['stressLimitCompressionY']
            s = failure['stressLimitInplaneShear']
            Ixy = -0.5
            mat = matOrth(matName,
                          e1, e2, nu12, g12, g1z, g2z,
                          xt, xc, yt, yc, s, Ixy)
            mat8_dict[matName] = mat

        if matType == 0:

            e = material.getElasticModulus()
            nu = material.getPoissonRatio()
            g = (e/(1 + nu)) / 2
            failure = material.getFailureLimitsIsotropic()
            St = failure['stressLimitTension']
            Sc = failure['stressLimitCompression']
            Ss = failure['stressLimitShear']
            mat = matIso(matName, e, g, nu, st=St, sc=Sc, ss=Ss)
            mat1_dict[matName] = mat
    return (mat1_dict, mat8_dict)


def createQ(mat1_dict, mat8_dict):
    for item, material in mat8_dict.items():
        nu21 = material.nu12 * material.e2 / material.e1
        q11 = material.e1 / (1 - material.nu12 * nu21)
        q12 = material.e1 * nu21 / (1 - material.nu12 * nu21)
        q13 = 0.0
        q22 = material.e2 / (1 - material.nu12 * nu21)
        q23 = 0.0
        q33 = material.g12
        q = numpy.array([[q11, q12, q13], [q12, q22, q23], [q13, q23, q33]])
        material.q = q
    for item, material in mat1_dict.items():
        q11 = material.e / (1 - material.nu * material.nu)
        q12 = material.e * material.nu / (1 - material.nu * material.nu)
        q13 = 0.0
        q22 = q11
        q23 = 0.0
        q33 = material.g
        q = numpy.array([[q11, q12, q13], [q12, q22, q23], [q13, q23, q33]])
        material.q = q
