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}
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}
def __init__(self, NodeCoordinates, ElementTable=None, ElementShape=None, LocalFrame=None, ID=""): MeshBase.__init__(self, ID) self.__NodeCoordinates = NodeCoordinates #node coordinates self.__ElementTable = ElementTable #element self.__ElementShape = ElementShape self.__SetOfNodes = {} #node on the boundary for instance self.__SetOfElements = {} self.__LocalFrame = LocalFrame #contient le repere locale (3 vecteurs unitaires) en chaque noeud. Vaut 0 si pas de rep locaux definis n = ProblemDimension.Get() N = self.__NodeCoordinates.shape[0] if self.__NodeCoordinates.shape[1] == 1: self.__CoordinateID = ('X') elif self.__NodeCoordinates.shape[1] == 2: self.__CoordinateID = ('X', 'Y') elif n == '2Dplane' or n == '2Dstress': self.__CoordinateID = ('X', 'Y') else: self.__CoordinateID = ('X', 'Y', 'Z') if n == '3D' and self.__NodeCoordinates.shape[1] == 2: self.__NodeCoordinates = np.c_[self.__NodeCoordinates, np.zeros(N)] if LocalFrame != None: LocalFrameTemp = np.zeros((N, 3, 3)) LocalFrameTemp[:, :2, :2] = self.__LocalFrame LocalFrameTemp[:, 2, 2] = 1 self.__LocalFrame = LocalFrameTemp
def GetGradOperator(): if ProblemDimension.Get() == "3D": GradOperator = [[OpDiff(IDvar, IDcoord,1) for IDcoord in ['X','Y','Z']] for IDvar in ['DispX','DispY','DispZ']] else: GradOperator = [[OpDiff(IDvar, IDcoord,1) for IDcoord in ['X','Y']] + [0] for IDvar in ['DispX','DispY']] GradOperator += [[0,0,0]] return GradOperator
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
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
def LineMesh(N=11, x_min=0, x_max=1, ElementShape='lin2', ID=""): """ Define the mesh of a line Parameters ---------- N : int Numbers of nodes (default = 11). x_min, x_max : int,float,list The boundary of the line as scalar (1D) or list (default : 0, 1). ElementShape : {'lin2', 'lin3', 'lin4'} The shape of the elements (default='lin2') * 'lin2' -- 2 node line * 'lin3' -- 3 node line * 'lin4' -- 4 node line Returns ------- Mesh The generated geometry in Mesh format. See the Mesh class for more details. See Also -------- RectangleMesh : Surface mesh of a rectangle BoxMesh : Volume mesh of a box GridMeshCylindric : Surface mesh of a grid in cylindrical coodrinate LineMeshCylindric : Line mesh in cylindrical coordinate """ if np.isscalar(x_min): m = LineMesh1D(N, x_min, x_max, ElementShape, ID) if ProblemDimension.Get() in ['2Dplane', '2Dstress']: dim = 2 else: dim = 3 crd = np.c_[m.GetNodeCoordinates(), np.zeros((N, dim - 1))] elm = m.GetElementTable() ReturnedMesh = Mesh(crd, elm, ElementShape, None, ID) ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("left"), "left") ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("right"), "right") else: m = LineMesh1D(N, 0., 1., ElementShape, ID) crd = m.GetNodeCoordinates() crd = (np.array(x_max) - np.array(x_min)) * crd + np.array(x_min) elm = m.GetElementTable() ReturnedMesh = Mesh(crd, elm, ElementShape, None, ID) ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("left"), "left") ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("right"), "right") return ReturnedMesh
def GetBernoulliBeamStrainOperator(): n = ProblemDimension.Get() epsX = OpDiff('DispX', 'X', 1) # dérivée en repère locale xsiZ = OpDiff('RotZ', 'X', 1) # flexion autour de Z if n == "2Dplane": eps = [epsX, 0, 0, 0, 0, xsiZ] elif n == "2Dstress": assert 0, "no 2Dstress for a beam kinematic, use '2Dplane' instead" elif n == "3D": xsiX = OpDiff('RotX', 'X', 1) # torsion autour de X xsiY = OpDiff('RotY', 'X', 1) # flexion autour de Y eps = [epsX, 0, 0, xsiX, xsiY, xsiZ] eps_vir = [e.virtual() if e != 0 else 0 for e in eps] return eps, eps_vir
def GetBeamStrainOperator(): n = ProblemDimension.Get() epsX = OpDiff('DispX', 'X', 1) # dérivée en repère locale xsiZ = OpDiff('RotZ', 'X', 1) # flexion autour de Z gammaY = OpDiff('DispY', 'X', 1) - OpDiff('RotZ') #shear/Y if n == "2Dplane": eps = [epsX, gammaY, 0, 0, 0, xsiZ] elif n == "2Dstress": assert 0, "no 2Dstress for a beam kinematic" elif n == "3D": xsiX = OpDiff('RotX', 'X', 1) # torsion autour de X xsiY = OpDiff('RotY', 'X', 1) # flexion autour de Y gammaZ = OpDiff('DispZ', 'X', 1) + OpDiff('RotY') #shear/Z eps = [epsX, gammaY, gammaZ, xsiX, xsiY, xsiZ] eps_vir = [e.virtual() if e != 0 else 0 for e in eps] return eps, eps_vir
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
def Get(InitialGradDisp=None): n = ProblemDimension.Get() # InitialGradDisp = StrainOperator.__InitialGradDisp if (InitialGradDisp is None) or (InitialGradDisp is 0): du_dx = OpDiff('DispX', 'X', 1) dv_dy = OpDiff('DispY', 'Y', 1) du_dy = OpDiff('DispX', 'Y', 1) dv_dx = OpDiff('DispY', 'X', 1) if n == "2Dplane" or n == "2Dstress": eps = [du_dx, dv_dy, 0, du_dy + dv_dx, 0, 0] # elif n == "2Dstress": # dw_dx = OpDiff('DispZ', 'X', 1) # dw_dy = OpDiff('DispZ', 'Y', 1) # eps = [du_dx, dv_dy, 0, dw_dy, dw_dx, du_dy+dv_dx] elif n == "3D": dw_dz = OpDiff('DispZ', 'Z', 1) du_dz = OpDiff('DispX', 'Z', 1) dv_dz = OpDiff('DispY', 'Z', 1) dw_dx = OpDiff('DispZ', 'X', 1) dw_dy = OpDiff('DispZ', 'Y', 1) eps = [ du_dx, dv_dy, dw_dz, du_dy + dv_dx, du_dz + dw_dx, dv_dz + dw_dy ] else: if n == "2Dplane" or n == "2Dstress": GradOperator = [[ OpDiff(IDvar, IDcoord, 1) for IDcoord in ['X', 'Y'] ] for IDvar in ['DispX', 'DispY']] eps = [ GradOperator[i][i] + sum([ GradOperator[k][i] * InitialGradDisp[k][i] for k in range(2) ]) for i in range(2) ] eps += [0] eps += [ GradOperator[0][1] + GradOperator[1][0] + sum([ GradOperator[k][0] * InitialGradDisp[k][1] + GradOperator[k][1] * InitialGradDisp[k][0] for k in range(2) ]) ] eps += [0, 0] elif n == "3D": GradOperator = [[ OpDiff(IDvar, IDcoord, 1) for IDcoord in ['X', 'Y', 'Z'] ] for IDvar in ['DispX', 'DispY', 'DispZ']] eps = [ GradOperator[i][i] + sum([ GradOperator[k][i] * InitialGradDisp[k][i] for k in range(3) ]) for i in range(3) ] eps += [ GradOperator[0][1] + GradOperator[1][0] + sum([ GradOperator[k][0] * InitialGradDisp[k][1] + GradOperator[k][1] * InitialGradDisp[k][0] for k in range(3) ]) ] eps += [ GradOperator[0][2] + GradOperator[2][0] + sum([ GradOperator[k][0] * InitialGradDisp[k][2] + GradOperator[k][2] * InitialGradDisp[k][0] for k in range(3) ]) ] eps += [ GradOperator[1][2] + GradOperator[2][1] + sum([ GradOperator[k][1] * InitialGradDisp[k][2] + GradOperator[k][2] * InitialGradDisp[k][1] for k in range(3) ]) ] eps_vir = [e.virtual() if e != 0 else 0 for e in eps] return eps, eps_vir
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'