Source code for Muscat.FE.KR.KRConformalTie
# -*- 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 scipy.spatial import KDTree
from Muscat.Containers.Filters.FilterObjects import ElementFilter
from Muscat.FE.KR.KRBase import KRBaseVector
import Muscat.Helpers.CPU as CPU
[docs]
class KRConformalTieVector(KRBaseVector):
def __init__(self):
super().__init__()
self.tol = 0.000001
self.onII =[]
self.argsII = []
[docs]
def From(self,offset=None,first=None,second=None):
if offset is not None:
self.originSystem.SetOffset(offset)
if first is not None:
self.originSystem.SetFirst(first)
if second is not None:
self.originSystem.SetSecond(second)
return self
[docs]
def To(self,offset=None,first=None,second=None):
if offset is not None:
self.targetSystem.SetOffset(offset)
if first is not None:
self.targetSystem.SetFirst(first)
if second is not None:
self.targetSystem.SetSecond(second)
return self
[docs]
def SideII(self,zone):
if type(zone) is list:
self.onII.extend(zone)
else:
self.onII.append(zone)
self.onII = list(set(self.onII))
return self
[docs]
def GenerateEquations(self,meshI=None,fields=None,CH=None,meshII=None,fieldsII=None):
CH = self._GetConstraintHolder(CH)
if meshII is None:
meshII = meshI
fieldsII = fields
if len(self.argsII) == 0:
argsII = self.args
else:
argsII = self.argsII
#submesh1 = ExtractElementByTags(meshI,self.on,cleanLonelyNodes=False)
#submesh2 = ExtractElementByTags(meshII,self.onII,cleanLonelyNodes=False)
bmin1, bmax1 = meshI.ComputeBoundingBox()
bmin2, bmax2 = meshII.ComputeBoundingBox()
fieldDicI = {f.name:f for f in fields }
fieldDicII = {f.name:f for f in fields }
offsets , fieldOffsetsI, totalNumberOfDofsI = self._ComputeOffsets(fields)
offsetsII, fieldOffsetsII, totalNumberOfDofsII = self._ComputeOffsets(fieldsII)
def FillOctree(mesh, tags, base ):
usedNodes = ElementFilter(eTag=tags).GetNodesIndices(mesh)
nodes = base.ApplyTransform(mesh.nodes[usedNodes,:])
return ( KDTree(nodes), usedNodes, nodes)
kdTree1, usedNodesMeshI, nodesI = FillOctree(meshI, self.on, self.originSystem.GetOrthoNormalBase())
kdTree2, usedNodesMeshII, nodesII = FillOctree(meshII, self.onII, self.targetSystem.GetOrthoNormalBase())
ffI = []
usedOffsetsI = []
ffII = []
usedOffsetsII = []
for arg, argII in zip(self.args,argsII):
if arg in fieldDicI.keys():
dim = 1
ffI.append(fieldDicI[arg])
usedOffsetsI.append(fieldOffsetsI[arg])
ffII.append(fieldDicII[argII])
usedOffsetsII.append(fieldOffsetsII[argII])
else:
dim =0
#field = fieldDic[arg+"_0"]
for i in range(3):
if arg+"_"+str(i) in fieldDicI:
dim += 1
ffI.append(fieldDicI[arg+"_"+str(i)])
usedOffsetsI.append(fieldOffsetsI[arg+"_"+str(i)])
ffII.append(fieldDicII[argII+"_"+str(i)])
usedOffsetsII.append(fieldOffsetsI[argII+"_"+str(i)])
else:
break
neighboors = kdTree2.query_ball_point(x=nodesI[:len(usedNodesMeshI)], r=self.tol, workers=CPU.GetNumberOfAvailableCores())
for cpt,nidI in enumerate(usedNodesMeshI):
posI = nodesI[cpt,:]
entries = neighboors[cpt]
for entry in entries:
nidII = entry
posII = usedNodesMeshII[entry]
dist = np.linalg.norm(posII - posI)
if dist > self.tol:
continue
for i in range(len(ffI)):
firstOff = usedOffsetsI[i]
firstNumbering = ffI[i].numbering.GetDofOfPoint(nidI)+firstOff
secondOff = usedOffsetsII[i]
secondNumbering = ffII[i].numbering.GetDofOfPoint(nidII) + secondOff
CH.AddFactor(firstNumbering,1)
CH.AddFactor(secondNumbering,-1)
CH.NextEquation()
break
return CH
[docs]
def CheckIntegrityKRConformalTieScalar(GUI:bool=False):
from Muscat.Containers.MeshCreationTools import CreateCube
from Muscat.FE.FETools import PrepareFEComputation
mesh = CreateCube()
space, numberings, offset, _ = PrepareFEComputation(mesh, numberOfComponents=3)
print(mesh)
obj = KRConformalTieVector()
obj.From([-1,0,0])
obj.To([0,0,0])
obj.AddArg("temp")
obj.SideI("X0")
obj.SideII("X1")
from Muscat.FE.Fields.FEField import FEField
fields = []
fields.append(FEField("temp",mesh=mesh,space=space, numbering=numberings[0]) )
CH = obj.GenerateEquations(mesh,fields)
CH.SetNumberOfDofs(numberings[0].size)
mat, dofs = CH.ToSparse()
#print(CH.cols)
#print(CH.rows)
#print(CH.vals)
return 'ok'
[docs]
def CheckIntegrityKRConformalTieVector(GUI:bool=False):
from Muscat.Containers.MeshCreationTools import CreateCube
from Muscat.FE.FETools import PrepareFEComputation
mesh = CreateCube()
space, numberings, offset, _ = PrepareFEComputation(mesh, numberOfComponents=3)
print(mesh)
obj = KRConformalTieVector()
obj.From([-1,0,0])
obj.To([0,0,0])
obj.AddArg("temp")
obj.SideI("X0")
obj.SideII("X1")
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 = [CheckIntegrityKRConformalTieScalar,
CheckIntegrityKRConformalTieVector]
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))