Source code for Muscat.FE.KR.KRMasterSlaves

# -*- coding: utf-8 -*-
#
# This file is subject to the terms and conditions defined in
# file 'LICENSE.txt', which is part of this source code package.
#

import numpy as np

from Muscat.FE.KR.KRBase import KRBaseScalar, KRBaseVector
from Muscat.Containers.Filters.FilterObjects import ElementFilter


[docs]class KRMasterNodeToSlaveScalar(KRBaseScalar): def __init__(self): super().__init__() self.type = "KRMasterNodeToSlaveScalar"
[docs] def MasterNode(self,tag=None): self.master = tag
[docs] def GenerateEquations(self,mesh,fields,CH=None): CH = self._GetConstraintHolder(CH) offsets, fieldOffsets, totalNumberOfDofs = self._ComputeOffsets(fields) fieldDic = {f.name:f for f in fields } nids = mesh.nodesTags[self.master].GetIds() if len(nids) > 1 : raise Exception("master tag has more than 1 nodes") if len(self.args) > 1: raise(Exception("Cant treat only cases with one arg")) fieldname = self.args[0] field = fieldDic[fieldname] masterDofs = np.array([ field.numbering.GetDofOfPoint(x) for x in nids])+fieldOffsets[fieldname] ef = ElementFilter(eTag=self.on ) for selection in ef(mesh): numbering = np.unique(field.numbering[selection.elementType][selection.indices,:].flatten()) dofs = numbering+fieldOffsets[fieldname] for dof in dofs : if dof == masterDofs : continue CH.AddFactor(dof,1) CH.AddFactor(masterDofs[0],-1) CH.NextEquation() return CH
[docs]class KRMasterNodeToSlaveVector(KRBaseVector): def __init__(self): super().__init__() self.type = "KRMasterNodeToSlaveVector"
[docs] def MasterNode(self,tag=None): self.master = tag
[docs] def GenerateEquations(self,mesh,fields,CH=None): CH = self._GetConstraintHolder(CH) offsets, fieldOffsets, totalNumberOfDofs = self._ComputeOffsets(fields) fieldDic = {f.name:f for f in fields } nids = mesh.nodesTags[self.master].GetIds() if len(nids) > 1 : raise Exception("master tag has more than 1 nodes") if len(self.args) > 1: raise(Exception("Cant treat only cases with one arg")) fieldname = self.args[0] masterDofs = [] usedFields = [] for sufix in range(3): cfieldname = fieldname + "_"+ str(sufix) masterDofs.append( fieldDic[cfieldname].numbering.GetDofOfPoint(nids[0]) + fieldOffsets[cfieldname] ) usedFields.append(fieldDic[cfieldname]) initPos = mesh.nodes[nids[0],:] ef = ElementFilter(eTag=self.on ) field = usedFields[0] print(masterDofs) for selection in ef(mesh): print(selection.elementType) sp = field.space[selection.elementType] sp.Create() nbsf = sp.GetNumberOfShapeFunctions() nu = [x.numbering[selection.elementType] for x in usedFields] for elid in selection.indices: print(elid) for i in range(nbsf): dofids = [x[elid,i] for x in nu] # the posicion of pos = sp.GetPosOfShapeFunction(i,mesh.nodes[selection.elements.connectivity[elid,:],:] ) # vector from the master to the final point disp = pos - initPos dirToBlock = self.GetConstrainedDirections(pos,disp) for dtb in dirToBlock: for d in range(3): CH.AddFactor(dofids[d]+offsets[d],dtb[d]) CH.AddFactor(masterDofs[d],-dtb[d]) CH.NextEquation() return CH
def __str__(self): res = self.type + " " if len(self.arg) > 1: res += "(" res += " and ".join(str(x)+"."+str(y) for x,y in self.arg) if len(self.arg) > 1: res += ")" res += "_On(" + ",".join(self.on) + ")" res += "_To(" + ",".join(self.to) + ")" return res
[docs]def CheckIntegrityKRMasterNodeToSlaveScalar(GUI:bool=False): from Muscat.Containers.MeshCreationTools import CreateSquare from Muscat.FE.FETools import PrepareFEComputation mesh = CreateSquare() space, numberings, offset, _ = PrepareFEComputation(mesh, numberOfComponents=1) obj = KRMasterNodeToSlaveScalar() obj.MasterNode("x0y0") obj.AddArg("temp") obj.On("X1") from Muscat.FE.Fields.FEField import FEField temp = FEField("temp",mesh=mesh,space=space, numbering=numberings[0]) CH = obj.GenerateEquations(mesh,[temp]) CH.SetNumberOfDofs(numberings[0].size) mat, dofs = CH.ToSparse() print(dofs) print(mat.toarray()) #obj.AddArg("u").On("Z0").Fix0().Fix1(False).Fix2(True) return "ok"
[docs]def CheckIntegrityKRMasterNodeToSlaveVector(GUI:bool=False): from Muscat.Containers.MeshCreationTools import CreateSquare from Muscat.FE.FETools import PrepareFEComputation mesh = CreateSquare() space, numberings, offset, _ = PrepareFEComputation(mesh, numberOfComponents=3) obj = KRMasterNodeToSlaveVector() obj.MasterNode("x0y0") obj.AddArg("temp") obj.On("X1").Fix0() from Muscat.FE.Fields.FEField import FEField fields = [] for x in range(3): fields.append(FEField("temp_"+str(x),mesh=mesh,space=space, numbering=numberings[x]) ) CH = obj.GenerateEquations(mesh,fields) CH.SetNumberOfDofs(numberings[0].size*3) mat, dofs = CH.ToSparse() #print(CH.cols) #print(CH.rows) #print(CH.vals) print(dofs) print(mat.toarray()) return "ok"
[docs]def CheckIntegrity(GUI:bool=False): totest = [CheckIntegrityKRMasterNodeToSlaveScalar, CheckIntegrityKRMasterNodeToSlaveVector] for f in totest: print(str(f)) res = f(GUI) if res.lower() != "ok": return res return "ok"
if __name__ == '__main__': print(CheckIntegrity(GUI=True))