Source code for Muscat.Containers.TagsTools
# -*- 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 Optional
import numpy as np
from typing import Optional, List, Union
from Muscat.Types import ArrayLike, MuscatFloat
import Muscat.Containers.ElementsDescription as ED
from Muscat.Containers.Mesh import Mesh
from Muscat.Containers.MeshTools import GetElementsCenters
from Muscat.Containers.ElementsContainers import ElementsContainer
from Muscat.Containers.Filters.FilterObjects import ElementFilter
from Muscat.ImplicitGeometry.ImplicitGeometryObjects import CreateImplicitGeometryByETag
[docs]def TransportETagsToNewMesh(oldMesh: Mesh, newMesh: Mesh, globalOriginalEIds: Optional[ArrayLike] = None, tagNames: Optional[Union[str, List[str]]] = None):
"""Function to port all eTags from the oldmesh on the new mesh, the new mesh must be a
transformation of the oldMesh. This means the new mesh originalIds
(for elements) must be with respect to the oldMesh.
The tags will be created on the newMesh
Parameters
----------
oldMesh : Mesh
the mesh with the eTags to be transported
newMesh : Mesh
the target mesh
globalOriginalEIds : Optional[ArrayLike] = None
the user can pass the global original ids in the case the newMesh is a complex transformation.
(in the case the local originalIds are not sufficient for the task )
tagNames: Optional[Union[str, List[str]]], optional
tagnames to transport, by default value is oldMesh.GetNamesOfElementTags()
"""
if tagNames is None:
tagNames = oldMesh.GetNamesOfElementTags()
if globalOriginalEIds is None:
for tagname in tagNames:
for selection in ElementFilter(eTag=tagname)(oldMesh):
mask = np.zeros(selection.elements.GetNumberOfElements(), dtype=bool)
mask[selection.indices] = True
newMesh.AddElementsToTag(np.where(mask[newMesh.GetElementsOfType(selection.elementType).originalIds])[0], tagname)
else:
mask = np.zeros(oldMesh.GetNumberOfElements(), dtype=bool)
for tagname in tagNames:
mask.fill(False)
mask[oldMesh.GetElementsInTag(tagname)] = True
newMesh.AddElementsToTag(np.where(mask[globalOriginalEIds])[0], tagname)
return
[docs]def TransportETagsToNewMeshUsingImplicitGeometries(originMesh: Mesh, targetMesh: Mesh, tagNames: Optional[Union[str, List[str]]] = None, dim:Optional[int] = None, tol: Optional[MuscatFloat] = None):
"""Function to transport eTags of a given dimensionality from the originMesh on the new mesh, when the new mesh is not necessarily a
transformation of the originMesh.
The tags will be created on the targetMesh
Parameters
----------
originMesh : Mesh
the mesh with the eTags to be transported
targetMesh : Mesh
the target mesh
tagNames: Optional[Union[str, List[str]]], optional
tagnames to transport, by default value is originMesh.GetNamesOfElementTags()
dim : Optional[int], optional
dimensionality filter, by default value is mesh dimensionality
tol : Optional[MuscatFloat], optional
tolerance over the distance, by default value is = np.linalg.norm(boundingMax - boundingMin)*1e-7
"""
if tagNames is None:
tagNames = originMesh.GetNamesOfElementTags()
if dim is None:
dim = originMesh.GetPointsDimensionality()
if tol is None:
boundingMin,boundingMax = originMesh.ComputeBoundingBox()
tol = np.linalg.norm(boundingMax -boundingMin)*1e-7
EF = ElementFilter(dimensionality=dim)
for selectionoriginMesh in EF(originMesh):
elements = selectionoriginMesh.elements
tagsToTreat = [tag for tag in tagNames if tag in elements.tags]
for tagname in tagsToTreat:
IGByETag = CreateImplicitGeometryByETag({"support": originMesh,"eTags":[tagname]})
for selection in EF(targetMesh):
elementsCenters = GetElementsCenters(nodes=targetMesh.nodes,elements=selection.elements)
distance = IGByETag(elementsCenters)
selection.elements.tags.CreateTag(tagname,False).SetIds(np.where(distance < tol)[0])
return
[docs]def TransportETagsToNewElementContainer(oldElementsContainer: ElementsContainer, newElementsContainer: ElementsContainer, errorIfAlreadyCreated=True):
"""Transport ETags To a new ElementContainer.
The ids will be appended if the tag already exist
the newElementsContainer must be a transformation of theoldElementsContainer
Parameters
----------
oldElementsContainer : ElementsContainer
ElementsContainer with the etags to be transported
newElementsContainer : ElementsContainer
ElementsContainer to hold the new etags
errorIfAlreadyCreated : bool, default True
if True (default) un error is raised if the tag already exist in the newElementsContainer
if False the ids will be appended to the already created tags
"""
# copy tags from the old container to the new
tagmask = np.zeros(oldElementsContainer.GetNumberOfElements(), dtype=bool)
for tag in oldElementsContainer.tags:
tagmask.fill(False)
tagmask[tag.GetIds()] = True
newElementsContainer.tags.CreateTag(tag.name, errorIfAlreadyCreated).AddToTag(np.where(tagmask[newElementsContainer.originalIds])[0])
[docs]def CheckIntegrityCheckTags(GUI=False):
from Muscat.Containers.MeshCreationTools import CreateSquare
from Muscat.Containers.MeshInspectionTools import ExtractElementsByElementFilter
from Muscat.Containers.Filters.FilterObjects import ElementFilter
import Muscat.Containers.ElementsDescription as ED
mesh1 = CreateSquare([5, 5], [0, 0])
mesh2 = ExtractElementsByElementFilter(mesh1, ElementFilter(dimensionality=2))
mesh2.DeleteElemTags(mesh2.GetNamesOfElementTags())
quads = mesh1.GetElementsOfType(ED.Quadrangle_4)
quads.tags.CreateTag("allQuads").SetIds(np.arange(quads.GetNumberOfElements()))
quads.tags.CreateTag("SecondQuad").SetIds(1)
TransportETagsToNewMesh(mesh1, mesh2)
np.testing.assert_equal((mesh2.GetElementsInTag("SecondQuad")), 1)
np.testing.assert_equal(len(mesh2.GetElementsInTag("allQuads")), quads.GetNumberOfElements())
np.testing.assert_equal(mesh2.GetElementsOfType(ED.Quadrangle_4).tags["SecondQuad"].GetIds()[0], 1)
mesh3 = mesh1.View()
mesh3.DeleteElemTags(mesh3.GetNamesOfElementTags())
TransportETagsToNewMesh(mesh1, mesh3, globalOriginalEIds=np.arange(mesh3.GetNumberOfElements()))
from Muscat.Containers.MeshTools import IsClose
IsClose(mesh1, mesh3)
mesh3.DeleteElemTags(mesh3.GetNamesOfElementTags())
TransportETagsToNewMeshUsingImplicitGeometries(mesh1, mesh3)
oldQuads = mesh1.GetElementsOfType(ED.Quadrangle_4)
newQuads = mesh3.GetElementsOfType(ED.Quadrangle_4)
for name in ["2D","allQuads","SecondQuad"]:
np.testing.assert_equal(oldQuads.tags[name].GetIds(), newQuads.tags[name].GetIds())
return "ok"
[docs]def CheckIntegrity_TransportETagsToNewElementContainer(GUI=False) -> str:
from Muscat.Containers.MeshCreationTools import CreateCube
mesh = CreateCube(dimensions=[2, 3, 4])
print(mesh)
from Muscat.Containers.MeshInspectionTools import ExtractElementsByElementFilter
mesh2 = ExtractElementsByElementFilter(mesh, ElementFilter(eTag="Skin"))
for selection in ElementFilter(eTag="Skin")(mesh):
selection.elements.tags.CreateTag("newSkin").SetIds(selection.indices)
oldQuads = mesh.GetElementsOfType(ED.Quadrangle_4)
newQuads = mesh2.GetElementsOfType(ED.Quadrangle_4)
TransportETagsToNewElementContainer(oldQuads, newQuads, False)
np.testing.assert_equal(oldQuads.tags["newSkin"].GetIds(), newQuads.tags["newSkin"].GetIds())
return "ok"
[docs]def CheckIntegrity(GUI: bool = False):
from Muscat.Helpers.IO.TemporaryDirectory import TemporaryDirectory
from Muscat.Helpers.CheckTools import RunListOfCheckIntegrities
func = [CheckIntegrityCheckTags, CheckIntegrity_TransportETagsToNewElementContainer]
return RunListOfCheckIntegrities(func, GUI=GUI)
if __name__ == "__main__": # pragma: no cover
print(CheckIntegrity(GUI=True))