# -*- 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 BasicTools.FE.KR.KRBase import KRBaseScalar, KRBaseVector
from BasicTools.Containers.Filters import ElementFilter
[docs]class KRMasterNodeToSlaveScalar(KRBaseScalar):
def __init__(self):
super(KRMasterNodeToSlaveScalar,self).__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(mesh=mesh, tags=self.on )
for name, data, elids in ef:
numbering = np.unique(field.numbering[name][elids,:].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(KRMasterNodeToSlaveVector,self).__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(mesh=mesh, tags=self.on )
field = usedFields[0]
print(masterDofs)
for name, data, elids in ef:
print(name)
sp = field.space[name]
sp.Create()
nbsf = sp.GetNumberOfShapeFunctions()
nu = [x.numbering[name] for x in usedFields]
for elid in elids:
print(elid)
for i in range(nbsf):
dofids = [x[elid,i] for x in nu]
# the posicion of
pos = sp.GetPosOfShapeFunction(i,mesh.nodes[data.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=False):
from BasicTools.Containers.UnstructuredMeshCreationTools import CreateSquare
from BasicTools.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 BasicTools.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=False):
from BasicTools.Containers.UnstructuredMeshCreationTools import CreateSquare
from BasicTools.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 BasicTools.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=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))