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 AddArgII(self,name): self.argsII.append(name) return self
[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 SideI(self,zone): return self.On(zone)
[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] class KRConformalTieScalar(KRConformalTieVector): def __init__(self): super().__init__()
[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))