Source code for Muscat.Containers.MmgRemeshing

# -*- 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 Union, Optional
from pathlib import Path
from Muscat.IO.MeshWriter import WriteMesh
from Muscat.IO.MeshReader import ReadMesh
from Muscat.Containers.Mesh import Mesh
from Muscat.Helpers.IO.Which import Which
from Muscat.Helpers.IO.TemporaryDirectory import TemporaryDirectory

[docs]class MmgRemeshing(): def __init__(self, mesh: Mesh, solution = None, metric = None): self.mesh = mesh self.solution = solution self.metric = metric
[docs] def WriteMeshAndSolution(self, temp_path:Union[str,Path] = None, binary:bool = True, offset:int = 0): """Write mesh and solution in a mesh file Parameters ---------- temp_path : Union[str,Path] path of the output mesh file (without extension) binary : bool """ from Muscat.Containers.MeshTools import TagsToRefs if temp_path is None: temp_path = Path("temp_file") solutionOnOwnFile = True self.binary = binary if self.binary: self.temp_mesh_path = Path(str(temp_path)+".meshb") self.temp_sol_path = Path(str(temp_path)+".solb") self.temp_out_path = Path(str(temp_path)+".o.meshb") else: self.temp_mesh_path = Path(str(temp_path)+".mesh") self.temp_sol_path = Path(str(temp_path)+".sol") self.temp_out_path = Path(str(temp_path)+".o.mesh") if self.solution is not None: solution = [self.solution] elif self.metric is not None: solution = [self.metric] else: solution = None solutionOnOwnFile = False RefByNode, self.dictNodesRefsToTags, RefByElement, self.dictElemRefsToTags = TagsToRefs(self.mesh, offset) WriteMesh(str(self.temp_mesh_path), self.mesh, PointFields = solution, solutionOnOwnFile = solutionOnOwnFile, binary = self.binary, nodalRefNumber = RefByNode, elemRefNumber = RefByElement)
[docs] def BuildMmgCommandLine(self, options:dict): """Build command line for mmg execution Parameters ---------- options : dict keys corresponding to mmg option name and value corresponding to value if applicable Returns ------- CommandLine : str the command line for mmg execution """ CommandLine = [] isElem3d = self.mesh.GetNumberOfElements(dim = 3) > 0 if isElem3d: CommandLine.append(Which("mmg3d_O3")) else: if self.mesh.GetPointsDimensionality() == 3: CommandLine.append(Which("mmgs")) else: CommandLine.append(Which("mmg2d_O3")) CommandLine.append("-in") CommandLine.append(str(self.temp_mesh_path)) if self.solution is not None: CommandLine.append("-sol") CommandLine.append(str(self.temp_sol_path)) elif self.metric is not None: CommandLine.append("-met") CommandLine.append(str(self.temp_sol_path)) for key, value in options.items(): CommandLine.append("-"+key) if value: CommandLine.append(str(value)) return " ".join(CommandLine)
[docs] def LaunchMmg(self, CommandLine:str): """Launch mmg with a subprocess using command line Parameters ---------- CommandLine : str the command line for mmg execution """ import subprocess return subprocess.check_output(CommandLine, shell = True).decode("utf-8", errors = "ignore")
[docs] def ReadMesh(self, prefix = "mmg"): """Read mesh file produced by mmg Returns ------- mesh : Mesh mmg resulting mesh from adaption """ from Muscat.Containers.MeshTools import RefsToTags print(self.temp_out_path) mesh = ReadMesh(str(self.temp_out_path), ReadRefsAsField = True) mesh = RefsToTags(mesh, self.dictNodesRefsToTags, self.dictElemRefsToTags, prefix) return mesh
[docs] def Runner(self, options:dict, temp_name:Optional[str] = "temp_file", binary:bool = True, offset:int = 1, prefix:str = "mmg", keep_temp_files:bool = False, temp_dir: Optional[str] = None): """Run the process to write mesh in an inria mesh file, launch mmg and read the resulting mesh Notes ----- The inria mesh file (called `temp_name`) will be writen in a temporary directory Parameters ---------- options : dict keys corresponding to mmg option name and value corresponding to value if applicable temp_name : str name of the output mesh file (without extension) default : "temp_file" binary : bool defaults to `True` prefix : str defaults to "mmg" keep_temp_files : bool defaults to `False` temp_dir : str directory to store temporary files if none a Temporary Directory is used for temporary file, default None Returns ------- mesh : Mesh mmg resulting mesh from adaption """ import os if not temp_dir: temp_dir = Path(TemporaryDirectory.GetTempPath()) temp_path = Path(temp_dir) / Path(temp_name) self.WriteMeshAndSolution(temp_path, binary, offset) CommandLine = self.BuildMmgCommandLine(options) self.mmg_out = self.LaunchMmg(CommandLine) mesh = self.ReadMesh(prefix) if not(keep_temp_files): self.temp_mesh_path.unlink(missing_ok=True) self.temp_sol_path.unlink(missing_ok=True) self.temp_out_path.unlink(missing_ok=True) return mesh
[docs]def CheckIntegrity(GUI = False): import time import numpy as np from Muscat.IO.GmshReader import ReadGmsh from Muscat.TestData import GetTestDataPath from Muscat.Helpers.IO.TemporaryDirectory import TemporaryDirectory tic = time.time() mmgExec = Which("mmg3d_O3") if mmgExec == '' or mmgExec == None: return "skip" print("Reading mesh") filename = GetTestDataPath()+"dent3D.msh" mesh = ReadGmsh(filename) mesh.ConvertDataForNativeTreatment() print(mesh) print("Execution time:",int(time.time()-tic),"seconds") tic = time.time() print("Executing mmg3d") obj = MmgRemeshing(mesh = mesh, solution = None) mesh = obj.Runner({"hmin":0.1}, binary = False) mesh = obj.Runner({"hmin":0.1}, binary = False, temp_name = "test_mmg") mesh = obj.Runner({"hmin":0.1}, binary = False, temp_name = "test_mmg", temp_dir=TemporaryDirectory.GetTempPath()) mesh = obj.Runner({"hmin":0.1}, binary = False, temp_dir=TemporaryDirectory.GetTempPath()) obj = MmgRemeshing(mesh = mesh, solution = np.ones(mesh.GetNumberOfNodes())) mesh = obj.Runner({"hmin":0.1}, binary = True) print(mesh) print("Execution time:",int(time.time()-tic),"seconds") return "ok"
if __name__ == '__main__': print(CheckIntegrity())