Source code for Muscat.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 typing import Dict

from Muscat.Containers.Filters.FilterObjects import ElementFilter
import Muscat.Containers.ElementsDescription as ED


__cache__:Dict = {}
__cacheSize__:int = 1
numberingAlgorithm:str = "CppBase"          # option are "CppBase" or  "NumpyBase" or "DictBase"
numberingAlgorithmBackUp:str = "NumpyBase"  # option are "NumpyBase" or "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 Muscat.FE.Numberings.NativeDofNumbering import NativeDofNumbering res = NativeDofNumbering() except: numberingAlgorithm = "NumpyBase" print("Warning CppBase Numbering non available (missing compilation) Using NumpyBase") if numberingAlgorithm == "NumpyBase": from Muscat.FE.Numberings.DofNumberingNumpy import DofNumberingNumpy res = DofNumberingNumpy() elif numberingAlgorithm == "DictBase": from Muscat.FE.Numberings.DofNumberingDict import DofNumberingDict res = DofNumberingDict() elif res == None: raise (Exception(f"Numbering algorithm of type {numberingAlgorithm} not available ")) discontinuous = discontinuous or not Space.hasSharedShapeFunctions 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")) # 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() == ED.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 elif discontinuous: if dofs is not None: res = dofs res.ComputeNumberingNoSharedDof(mesh=mesh, space=Space, elementFilter=elementFilter) 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) SetNumberingToCache(res, mesh=mesh, space=Space, fromConnectivity=fromConnectivity, elementFilter=elementFilter, discontinuous=discontinuous) return res
[docs]def CheckIntegrity(GUI: bool = False): import Muscat.FE.DofNumbering as DN from Muscat.Containers.MeshCreationTools import CreateCube res2 = CreateCube([2, 2, 2], [-1.0, -1.0, -1.0], [2./46, 2./46, 2./46]) from Muscat.FE.Spaces.FESpaces import LagrangeSpaceGeo, LagrangeSpaceP0, LagrangeSpaceP1, LagrangeSpaceP2, ConstantSpaceGlobal, FESpace from Muscat.FE.Spaces.FESpaces import GetListOfAvailableFESpaces, GetFESpaceByName spacesToTest:Dict[str,FESpace] = {"ConstantSpaceGlobal": ConstantSpaceGlobal, "LagrangeSpaceGeo": LagrangeSpaceGeo, "LagrangeSpaceP0": LagrangeSpaceP0, "LagrangeSpaceP1": LagrangeSpaceP1, "LagrangeSpaceP2": LagrangeSpaceP2} spacesToTest:Dict[str,FESpace] = {k.name:k for k in GetListOfAvailableFESpaces()} from Muscat.FE.Spaces.IPSpaces import GenerateSpaceForIntegrationPointInterpolation from Muscat.FE.IntegrationRules import GetIntegrationRuleByName irule = GetIntegrationRuleByName(ruleName="LagrangeIsoParamQuadrature") 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=ElementFilter(eTag="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=ElementFilter(dimensionality=3)) printData(numbering, st) return "ok"
[docs]def CheckIntegrityUsingAlgo(algo, GUI=False): import Muscat.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