Esempio n. 1
0
    def __GetResultGaussPoints(
            mesh,
            operator,
            U,
            list_elementType,
            list_nb_pg=None):  #return the results at GaussPoints
        res = 0
        nvar = [
            mesh._GetSpecificNumberOfVariables(idmesh)
            for idmesh in range(mesh.GetDimension())
        ]
        if list_nb_pg is None:
            list_nb_pg = [
                GetDefaultNbPG(self.__listElementType[dd],
                               self.__Mesh.GetListMesh()[dd])
                for dd in range(len(self.__listElementType))
            ]

        for ii in range(len(operator.op)):
            if isinstance(operator.coef[ii], Number):
                coef_PG = operator.coef[ii]
            else:
                coef_PG = []
            res_add = []

            for dd, subMesh in enumerate(mesh.GetListMesh()):
                var = [mesh._GetSpecificVariableRank(dd, operator.op[ii].u)]
                coef = [1]
                if 'X' in subMesh.GetCoordinateID(
                ):  #test if the subMesh is related to the spatial coordinates
                    if not (Variable.GetDerivative(operator.op[ii].u) is None):
                        var.append(
                            mesh._GetSpecificVariableRank(
                                dd,
                                Variable.GetDerivative(operator.op[ii].u)[0]))
                        coef.append(
                            Variable.GetDerivative(operator.op[ii].u)[1])
                assert operator.op_vir[
                    ii] == 1, "Operator virtual are only required to build FE operators, but not to get element results"

                if isinstance(coef_PG, list):
                    coef_PG.append(
                        AssemblyPGD._Assembly__ConvertToGaussPoints(
                            subMesh, operator.coef[ii].data[dd],
                            list_elementType[dd], list_nb_pg[dd]))

                MatrixChangeOfBasis = AssemblyPGD._Assembly__GetChangeOfBasisMatrix(
                    subMesh, list_elementType[dd], list_nb_pg[dd])
                res_add.append(
                    RowBlocMatrix(
                        AssemblyPGD._Assembly__GetElementaryOp(
                            subMesh, operator.op[ii], list_elementType[dd],
                            list_nb_pg[dd]), nvar[dd], var, coef) *
                    MatrixChangeOfBasis * U.data[dd])

            if isinstance(coef_PG, list): coef_PG = SeparatedArray(Coef_PG)
            res = res + coef_PG * SeparatedArray(res_add)

        return res
Esempio n. 2
0
    def __init__(self, Density, ID = ""):
           
        if ID == "":
            ID = "Inertia"
            
        WeakForm.__init__(self,ID)

        Variable("DispX") 
        Variable("DispY")                
        if ProblemDimension.Get() == "3D": Variable("DispZ")        
        
        self.__Density = Density        
    def __init__(self, CurrentConstitutiveLaw, ID=""):
        if isinstance(CurrentConstitutiveLaw, str):
            CurrentConstitutiveLaw = ConstitutiveLaw.GetAll(
            )[CurrentConstitutiveLaw]

        if ID == "":
            ID = CurrentConstitutiveLaw.GetID()

        WeakForm.__init__(self, ID)

        Variable("DispX")
        Variable("DispY")
        if ProblemDimension.Get() == "3D": Variable("DispZ")

        self.__ConstitutiveLaw = CurrentConstitutiveLaw
        self.__InitialStressVector = 0
Esempio n. 4
0
    def GetExternalForces(self, U, NumberOfVariable=None):
        """
        Not a static method.
        Return the nodal Forces and moments in global coordinates related to a specific assembly considering the DOF solution given in U
        The resulting forces are the sum of :
            - External forces (associated to Neumann boundary conditions)
            - Nodal reaction (associated to Dirichelet boundary conditions)
            - Inertia forces 
        
        Return a list of separated array [Fx, Fy, Fz, Mx, My, Mz].   
                    
        example : 
        S = SpecificAssembly.GetNodalForces(PGD.Problem.GetDoFSolution('all'))
        """

        ExtForce = self.GetMatrix() * U
        if NumberOfVariable == None:
            return [
                ExtForce.GetVariable(var, self.__Mesh)
                for var in range(Variable.GetNumberOfVariable())
            ]
        else:
            return [
                ExtForce.GetVariable(var, self.__Mesh)
                for var in range(NumberOfVariable)
            ]
Esempio n. 5
0
    def __init__(self, Density, ID=""):

        if ID == "":
            ID = "Inertia"

        WeakForm.__init__(self, ID)

        Variable("DispX")
        Variable("DispY")
        if ProblemDimension.Get() == "3D":
            Variable("DispZ")
            Variable.SetVector('Disp', ('DispX', 'DispY', 'DispZ'))
        else:
            Variable.SetVector('Disp', ('DispX', 'DispY'))

        self.__Density = Density
Esempio n. 6
0
 def _GetSpecificNumberOfVariables(self, idmesh):
     assert isinstance(
         idmesh, int), 'idmesh must an integer, not a ' + str(type(idmesh))
     if idmesh in self.__SpecificVariableRank:
         return max(self.__SpecificVariableRank[idmesh].values()) + 1
     else:
         return Variable.GetNumberOfVariable()
Esempio n. 7
0
    def __init__(self, u, x=0, ordre=0, decentrement=0, vir=0):

        self.mesh = None

        if isinstance(u, str):
            u = Variable.GetRank(u)
        if isinstance(x, str):
            x = Coordinate.GetRank(x)

        if isinstance(u, int):
            self.coef = [1]
            if vir == 0:
                self.op = [OpDerive(u, x, ordre, decentrement)]
                self.op_vir = [1]
            else:
                self.op_vir = [OpDerive(u, x, ordre, decentrement)]
                self.op = [1]
        elif isinstance(u, list) and isinstance(x, list) and isinstance(
                ordre, list):
            self.op = u
            self.op_vir = x
            self.coef = ordre
        else:
            raise NameError('Argument error')
Esempio n. 8
0
    def __init__(self, CurrentConstitutiveLaw, Section, Jx, Iyy, Izz, k=0, ID = ""):
        #k: shear shape factor
        
        if isinstance(CurrentConstitutiveLaw, str):
            CurrentConstitutiveLaw = ConstitutiveLaw.GetAll()[CurrentConstitutiveLaw]

        if ID == "":
            ID = CurrentConstitutiveLaw.GetID()
            
        WeakForm.__init__(self,ID)

        Variable("DispX") 
        Variable("DispY")            
        if ProblemDimension.Get() == '3D':
            Variable("DispZ")   
            Variable("RotX") #torsion rotation 
            Variable("RotY")   
            Variable("RotZ")
            Variable.SetVector('Disp' , ('DispX', 'DispY', 'DispZ') , 'global')
            Variable.SetVector('Rot' , ('RotX', 'RotY', 'RotZ') , 'global')            
        elif ProblemDimension.Get() == '2Dplane':
            Variable("RotZ")
            Variable.SetVector('Disp' , ['DispX', 'DispY'], 'global' )            
            Variable.SetVector('Rot' , ['RotZ'] ) 
        elif ProblemDimension.Get() == '2Dstress':
            assert 0, "No 2Dstress model for a beam kinematic. Choose '2Dplane' instead."
                          
        self.__ConstitutiveLaw = CurrentConstitutiveLaw
        self.__parameters = {'Section': Section, 'Jx': Jx, 'Iyy':Iyy, 'Izz':Izz, 'k':k}        
Esempio n. 9
0
    def __init__(self, CurrentConstitutiveLaw, ID="", nlgeom=False):
        if isinstance(CurrentConstitutiveLaw, str):
            CurrentConstitutiveLaw = ConstitutiveLaw.GetAll(
            )[CurrentConstitutiveLaw]

        if ID == "":
            ID = CurrentConstitutiveLaw.GetID()

        WeakForm.__init__(self, ID)

        Variable("DispX")
        Variable("DispY")
        if ProblemDimension.Get() == "3D":
            Variable("DispZ")
            Variable.SetVector('Disp', ('DispX', 'DispY', 'DispZ'))
        else:  #2D assumed
            Variable.SetVector('Disp', ('DispX', 'DispY'))

        self.__ConstitutiveLaw = CurrentConstitutiveLaw
        self.__InitialStressTensor = 0
        self.__InitialGradDispTensor = None

        self.__nlgeom = nlgeom  #geometric non linearities

        if nlgeom:
            if ProblemDimension.Get() == "3D":
                GradOperator = [[
                    OpDiff(IDvar, IDcoord, 1) for IDcoord in ['X', 'Y', 'Z']
                ] for IDvar in ['DispX', 'DispY', 'DispZ']]
                #NonLinearStrainOperatorVirtual = 0.5*(vir(duk/dxi) * duk/dxj + duk/dxi * vir(duk/dxj)) using voigt notation and with a 2 factor on non diagonal terms
                NonLinearStrainOperatorVirtual = [
                    sum([
                        GradOperator[k][i].virtual() * GradOperator[k][i]
                        for k in range(3)
                    ]) for i in range(3)
                ]
                NonLinearStrainOperatorVirtual += [
                    sum([
                        GradOperator[k][0].virtual() * GradOperator[k][1] +
                        GradOperator[k][1].virtual() * GradOperator[k][0]
                        for k in range(3)
                    ])
                ]
                NonLinearStrainOperatorVirtual += [
                    sum([
                        GradOperator[k][0].virtual() * GradOperator[k][2] +
                        GradOperator[k][2].virtual() * GradOperator[k][0]
                        for k in range(3)
                    ])
                ]
                NonLinearStrainOperatorVirtual += [
                    sum([
                        GradOperator[k][1].virtual() * GradOperator[k][2] +
                        GradOperator[k][2].virtual() * GradOperator[k][1]
                        for k in range(3)
                    ])
                ]
            else:
                GradOperator = [[
                    OpDiff(IDvar, IDcoord, 1) for IDcoord in ['X', 'Y']
                ] for IDvar in ['DispX', 'DispY']]
                NonLinearStrainOperatorVirtual = [
                    sum([
                        GradOperator[k][i].virtual() * GradOperator[k][i]
                        for k in range(2)
                    ]) for i in range(2)
                ] + [0]
                NonLinearStrainOperatorVirtual += [
                    sum([
                        GradOperator[k][0].virtual() * GradOperator[k][1] +
                        GradOperator[k][1].virtual() * GradOperator[k][0]
                        for k in range(2)
                    ])
                ] + [0, 0]

            self.__NonLinearStrainOperatorVirtual = NonLinearStrainOperatorVirtual

        else:
            self.__NonLinearStrainOperatorVirtual = 0
Esempio n. 10
0
    def __init__(self, E=None, nu = None, S=None, Jx=None, Iyy=None, Izz = None, R = None, k=0, ID = ""):
        """
        Weak formulation dedicated to treat parametric problems using Bernoulli beams for isotropic materials
        
        Arugments
        ----------
        ID: str
            ID of the weak formulation
        List of other optional parameters
            E: Young Modulus
            nu: Poisson Ratio
            S: Section area
            Jx: Torsion constant
            Iyy, Izz: Second moment of area, if Izz is not specified, Iyy = Izz is assumed
            k is a scalar. k=0 for no shear effect. For other values, k is the shear area coefficient            
        When the differntial operator is generated (using PGD.Assembly) the parameters are searched among the CoordinateID defining the associated mesh.
        If a parameter is not found , a Numeric value should be specified in argument.
        
        In the particular case of cylindrical beam, the radius R can be specified instead of S, Jx, Iyy and Izz.
            S = pi * R**2
            Jx = pi * R**4/2
            Iyy = Izz = pi * R**4/4         
        """
    
        WeakForm.__init__(self,ID)

        Variable("DispX") 
        Variable("DispY")     
        if ProblemDimension.Get() == '3D':
            Variable("DispZ")   
            Variable("RotX") #torsion rotation    
            Variable('RotY')
            Variable('RotZ')
            # Variable.SetDerivative('DispZ', 'RotY', sign = -1) #only valid with Bernoulli model
            # Variable.SetDerivative('DispY', 'RotZ') #only valid with Bernoulli model       
            Variable.SetVector('Disp' , ('DispX', 'DispY', 'DispZ') , 'global')
            Variable.SetVector('Rot' , ('RotX', 'RotY', 'RotZ') , 'global')
        elif ProblemDimension.Get() == '2Dplane':
            Variable('RotZ')
            Variable.SetVector('Disp' , ('DispX', 'DispY'), 'global' )
            Variable.SetVector('Rot' , ('RotZ'))
        elif ProblemDimension.Get() == '2Dstress':
            assert 0, "No 2Dstress model for a beam kinematic. Choose '2Dplane' instead."
        
        if R is not None:
            S = np.pi * R**2
            Jx = np.pi * R**4/2
            Iyy = Izz = np.pi * R**4/4 
        
        self.__parameters = {'E':E, 'nu':nu, 'S':S, 'Jx':Jx, 'Iyy':Iyy, 'Izz':Izz, 'k':k}
Esempio n. 11
0
    def ComputeGlobalMatrix(self):
        mesh = self.__Mesh
        dim = mesh.GetDimension()

        wf = self.__weakForm.GetDifferentialOperator(mesh)
        nvar = [
            mesh._GetSpecificNumberOfVariables(idmesh) for idmesh in range(dim)
        ]

        AA = []
        BB = 0

        for ii in range(len(wf.op)):

            if wf.op[
                    ii] == 1:  #only virtual operator -> compute a separated array
                BBadd = []
            else:  #virtual and real operators -> compute a separated operator
                if isinstance(wf.coef[ii], SeparatedArray):
                    nb_term_coef = wf.coef[ii].nbTerm()
                    AA += [[] for term in range(nb_term_coef)]
                else:
                    AA.append([])

            for dd, subMesh in enumerate(mesh.GetListMesh()):

                elmType = self.__listElementType[dd]
                nb_pg = self.__listNumberOfGaussPoints[dd]
                MatGaussianQuadrature = AssemblyPGD._Assembly__GetGaussianQuadratureMatrix(
                    subMesh, elmType, nb_pg)
                MatrixChangeOfBasis = AssemblyPGD._Assembly__GetChangeOfBasisMatrix(
                    subMesh)

                coef_vir = [1]
                var_vir = [mesh._GetSpecificVariableRank(dd, wf.op_vir[ii].u)
                           ]  #list in case there is an angular variable
                if 'X' in subMesh.GetCoordinateID(
                ):  #test if the subMesh is related to the spatial coordinates (Variable derivative are only for spatial derivative in beam or shell models)
                    if not (Variable.GetDerivative(wf.op_vir[ii].u) is None):
                        var_vir.append(
                            mesh._GetSpecificVariableRank(
                                dd,
                                Variable.GetDerivative(wf.op_vir[ii].u)[0]))
                        coef_vir.append(
                            Variable.GetDerivative(wf.op_vir[ii].u)[1])
                Matvir = (RowBlocMatrix(
                    AssemblyPGD._Assembly__GetElementaryOp(
                        subMesh, wf.op_vir[ii], elmType, nb_pg), nvar[dd],
                    var_vir, coef_vir) * MatrixChangeOfBasis).T

                if wf.op[
                        ii] == 1:  #only virtual operator -> compute a separated array
                    if isinstance(
                            wf.coef[ii],
                        (Number, np.floating)):  #and self.op_vir[ii] != 1:
                        if dd == 0:
                            BBadd.append(
                                wf.coef[ii] * Matvir *
                                MatGaussianQuadrature.data.reshape(-1, 1))
                        else:
                            BBadd.append(
                                Matvir *
                                MatGaussianQuadrature.data.reshape(-1, 1))
                    elif isinstance(wf.coef[ii], SeparatedArray):
                        coef_PG = AssemblyPGD._Assembly__ConvertToGaussPoints(
                            subMesh, wf.coef[ii].data[dd], elmType, nb_pg)
                        BBadd.append(
                            Matvir *
                            (MatGaussianQuadrature.data.reshape(-1, 1) *
                             coef_PG))

                else:  #virtual and real operators -> compute a separated operator
                    coef = [1]
                    var = [mesh._GetSpecificVariableRank(dd, wf.op[ii].u)
                           ]  #list in case there is an angular variable
                    if 'X' in subMesh.GetCoordinateID(
                    ):  #test if the subMesh is related to the spatial coordinates (Variable derivative are only for spatial derivative in beam or shell models)
                        if not (Variable.GetDerivative(wf.op[ii].u) is None):
                            var.append(
                                mesh._GetSpecificVariableRank(
                                    dd,
                                    Variable.GetDerivative(wf.op[ii].u)[0]))
                            coef.append(Variable.GetDerivative(wf.op[ii].u)[1])
                    Mat = RowBlocMatrix(
                        AssemblyPGD._Assembly__GetElementaryOp(
                            subMesh, wf.op[ii], elmType, nb_pg), nvar[dd], var,
                        coef) * MatrixChangeOfBasis

                    if isinstance(
                            wf.coef[ii],
                        (Number, np.floating)):  #and self.op_vir[ii] != 1:
                        if dd == 0:
                            AA[-1].append(wf.coef[ii] * Matvir *
                                          MatGaussianQuadrature * Mat)
                        else:
                            AA[-1].append(Matvir * MatGaussianQuadrature * Mat)
                    elif isinstance(wf.coef[ii], SeparatedArray):
                        coef_PG = AssemblyPGD._Assembly__ConvertToGaussPoints(
                            subMesh, wf.coef[ii].data[dd], elmType, nb_pg)

                        for kk in range(nb_term_coef):
                            #CoefMatrix is a diag matrix that includes the gaussian quadrature coefficients and the value of wf.coef at gauss points
                            CoefMatrix = sparse.csr_matrix(
                                (MatGaussianQuadrature.data * coef_PG[:, kk],
                                 MatGaussianQuadrature.indices,
                                 MatGaussianQuadrature.indptr),
                                shape=MatGaussianQuadrature.shape)
                            AA[-nb_term_coef + kk].append(Matvir * CoefMatrix *
                                                          Mat)

            if wf.op[ii] == 1:
                BB = BB - SeparatedArray(BBadd)

        if AA == []: self.SetMatrix(0)
        else: self.SetMatrix(SeparatedOperator(AA))
        self.SetVector(BB)
Esempio n. 12
0
    def __init__(self, InitialStressTensor=0, ID=""):
        if ID == "": ID = "InitialStress"

        WeakForm.__init__(self, ID)

        if InitialStressTensor == 0:
            InitialStressTensor = [
                0, 0, 0, 0, 0, 0
            ]  #list of the six stress component (sig_xx, sig_yy, sig_zz, sig_yz, sig_xz, sigxy)

        Variable("DispX")
        Variable("DispY")
        if ProblemDimension.Get() == "3D": Variable("DispZ")

        if ProblemDimension.Get() == "3D":
            GradOperator = [[
                OpDiff(IDvar, IDcoord, 1) for IDcoord in ['X', 'Y', 'Z']
            ] for IDvar in ['DispX', 'DispY', 'DispZ']]
            #NonLinearStrainOperatorVirtual = 0.5*(vir(duk/dxi) * duk/dxj + duk/dxi * vir(duk/dxj)) using voigt notation and with a 2 factor on non diagonal terms
            NonLinearStrainOperatorVirtual = [
                sum([
                    GradOperator[k][i].virtual() * GradOperator[k][i]
                    for k in range(3)
                ]) for i in range(3)
            ]
            NonLinearStrainOperatorVirtual += [
                sum([
                    GradOperator[k][1].virtual() * GradOperator[k][2] +
                    GradOperator[k][2].virtual() * GradOperator[k][1]
                    for k in range(3)
                ])
            ]
            NonLinearStrainOperatorVirtual += [
                sum([
                    GradOperator[k][0].virtual() * GradOperator[k][2] +
                    GradOperator[k][2].virtual() * GradOperator[k][0]
                    for k in range(3)
                ])
            ]
            NonLinearStrainOperatorVirtual += [
                sum([
                    GradOperator[k][0].virtual() * GradOperator[k][1] +
                    GradOperator[k][1].virtual() * GradOperator[k][0]
                    for k in range(3)
                ])
            ]
        else:
            GradOperator = [[
                Util.OpDiff(IDvar, IDcoord, 1) for IDcoord in ['X', 'Y']
            ] for IDvar in ['DispX', 'DispY']]
            NonLinearStrainOperatorVirtual = [
                sum([
                    GradOperator[k][i].virtual() * GradOperator[k][i]
                    for k in range(2)
                ]) for i in range(2)
            ] + [0, 0, 0]
            NonLinearStrainOperatorVirtual += [
                sum([
                    GradOperator[k][0].virtual() * GradOperator[k][1] +
                    GradOperator[k][1].virtual() * GradOperator[k][0]
                    for k in range(2)
                ])
            ]

        self.__NonLinearStrainOperatorVirtual = NonLinearStrainOperatorVirtual
        self.__InitialStressTensor = InitialStressTensor
        self.__typeOperator = 'all'