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))