Source code for BasicTools.FE.DofNumbering

# -*- 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.
#

from BasicTools.Containers import Filters
import BasicTools.Containers.ElementNames as EN


__cache__ = {}
__cacheSize__ = 1
numberingAlgorithm = "CppBase"
#numberingAlgorithm = "NumpyBase"
#numberingAlgorithm = "DictBase"

[docs]def GetNumberingFromCache(mesh,space,elementFilter=None,discontinuous=False,fromConnectivity=False): return None key = (id(mesh),id(space),id(elementFilter),discontinuous,fromConnectivity) return __cache__.get(key,None)
[docs]def SetNumberingToCache(obj, mesh,space,elementFilter=None,discontinuous=False,fromConnectivity=False): if len(__cache__) >= __cacheSize__: for k in __cache__: del __cache__[k] break key = (id(mesh),id(space),id(elementFilter),discontinuous,fromConnectivity) __cache__[key] = obj
[docs]def ComputeDofNumbering(mesh,Space,dofs=None,fromConnectivity=False,elementFilter=None,discontinuous=False): if dofs is None: cachedData = GetNumberingFromCache(mesh=mesh, space=Space, fromConnectivity=fromConnectivity, elementFilter=elementFilter, discontinuous=discontinuous ) if cachedData is not None: return cachedData global numberingAlgorithm res = None if numberingAlgorithm == "CppBase": try: from BasicTools.FE.Numberings.NativeDofNumbering import NativeDofNumbering res = NativeDofNumbering() except: numberingAlgorithm = "NumpyBase" print("Warning CppBase Numbering non available (missing compilation) Using NumpyBase") if numberingAlgorithm == "NumpyBase": from BasicTools.FE.Numberings.DofNumberingNumpy import DofNumberingNumpy res = DofNumberingNumpy() elif numberingAlgorithm == "DictBase": from BasicTools.FE.Numberings.DofNumberingDict import DofNumberingDict res = DofNumberingDict() elif res == None: raise(Exception(f"Numbering algorithm of type {numberingAlgorithm} not available ")) if fromConnectivity: if dofs is not None or elementFilter is not None or discontinuous: raise(Exception("cant take dofs, sign, discontinuous or elementFilter different from the default values")) from BasicTools.FE.Spaces.FESpaces import LagrangeSpaceGeo #check the compatibility of the spaces, this is not perfect, the user is responsible of putting the shape function in the same order # as the nodes of the reference element for k in mesh.elements.keys(): Space[k].Create() if Space[k].fromConnectivityCompatible == True or Space[k].GetNumberOfShapeFunctions() == EN.numberOfNodes[k] : continue raise Exception(f"Incompatible case! Can't use a non compatible space {(type(Space[k]))} and fromConnectivity at the same time") res.ComputeNumberingFromConnectivity(mesh, Space) SetNumberingToCache(res,mesh=mesh, space=Space, fromConnectivity=fromConnectivity, elementFilter=elementFilter, discontinuous=discontinuous ) return res else: if dofs is not None: res = dofs res.ComputeNumberingGeneral(mesh=mesh, space=Space, elementFilter=elementFilter, discontinuous=discontinuous ) SetNumberingToCache(res,mesh=mesh, space=Space, fromConnectivity=fromConnectivity, elementFilter=elementFilter, discontinuous=discontinuous ) return res
[docs]def CheckIntegrity(GUI=False): import BasicTools.FE.DofNumbering as DN from BasicTools.Containers.UnstructuredMeshCreationTools import CreateCube res2 = CreateCube([2,2,2],[-1.0,-1.0,-1.0],[2./46, 2./46,2./46]) from BasicTools.FE.Spaces.FESpaces import LagrangeSpaceGeo, LagrangeSpaceP0, LagrangeSpaceP1, LagrangeSpaceP2, ConstantSpaceGlobal spacesToTest = { "ConstantSpaceGlobal":ConstantSpaceGlobal,"LagrangeSpaceGeo":LagrangeSpaceGeo, "LagrangeSpaceP0":LagrangeSpaceP0, "LagrangeSpaceP1":LagrangeSpaceP1, "LagrangeSpaceP2":LagrangeSpaceP2 } from BasicTools.FE.Spaces.IPSpaces import GenerateSpaceForIntegrationPointInterpolation from BasicTools.FE.IntegrationsRules import GetRule irule = GetRule(ruleName="LagrangeP1") gaussSpace = GenerateSpaceForIntegrationPointInterpolation(irule) spacesToTest["gaussSpace"] =gaussSpace import time def printData(numbering,st): for k,v in res2.elements.items(): print(k,numbering.get(k,None)) print(f"numbering.size = {numbering.size}") print(f" time : {time.time()-st}" ) for spaceName, space in spacesToTest.items(): print("*************************** {} {}*******************************************".format(DN.numberingAlgorithm, spaceName)) # on a tag print(f"vvvvvvvvvvv {spaceName} tag vvvvvvvvvvvvvvv") st = time.time() numbering = DN.ComputeDofNumbering(res2,space,elementFilter= Filters.ElementFilter(mesh=res2,tag="X0") ) printData(numbering,st) # all print("----------------------{} all -----------------------------".format(spaceName)) st = time.time() numbering = DN.ComputeDofNumbering(res2,space) printData(numbering,st) if space is LagrangeSpaceGeo: # from connectivity print("----------------------{} from connectivity -----------------------------".format(spaceName)) st = time.time() numbering = DN.ComputeDofNumbering(res2, space,fromConnectivity=True) printData(numbering,st) # 3D using filter print("----------------------{} 3D filter-----------------------------".format(spaceName)) st = time.time() numbering = DN.ComputeDofNumbering(res2,space,elementFilter=Filters.ElementFilter(mesh=res2,dimensionality=3) ) printData(numbering,st) return "ok"
[docs]def CheckIntegrityUsingAlgo(algo,GUI=False): import BasicTools.FE.DofNumbering as DN tmpAlgo = DN.numberingAlgorithm DN.numberingAlgorithm = algo try: res = DN.CheckIntegrity(GUI) DN.numberingAlgorithm = tmpAlgo return res except: DN.numberingAlgorithm = tmpAlgo raise
if __name__ == '__main__': print(CheckIntegrity(True))# pragma: no cover