# -*- 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())