Source code for OpenPisco.ExternalTools.FreeFem.FreeFemInterface

# -*- coding: utf-8 -*-
#
# This file is subject to the terms and conditions defined in
# file 'LICENSE', which is part of this source code package.
#
"""FreefemInterface

This is the dedicated interface for the external physical solver Code\_Aster. 
Its main responsability is to facilitate the interactions with Code\_Aster, either by providing features to build the command line required to run the solver or to retrieve field computed by said solver.
"""

import numpy as np
import os
import shutil

from OpenPisco.ExternalTools.FreeFem import GetScriptsPath as GetScriptsPath
from OpenPisco.Unstructured.AppExecutableTools import AppExecutableBase, CommandLineBuilder
import OpenPisco.PhysicalSolvers.FieldsNames as FN
import OpenPisco.Unstructured.MetricFieldsNames as MFN

#outputs that the solver can generate
FileNamebyFieldName={}
FileNamebyFieldName[FN.potential_energy]="freefeminput.elasticenergy.sol"
FileNamebyFieldName[FN.von_mises]="freefeminput.vonmises.sol"
FileNamebyFieldName[FN.stress]="freefeminput.stress.sol"
FileNamebyFieldName[MFN.metric]="mshmetdata.sol"

FileNamebyScalarName={}
FileNamebyScalarName[FN.int_potential_energy]="intelasticenergy.txt"

freefemExec = "FreeFem++"

[docs]class FreeFemInterface(AppExecutableBase): """ .. py:class:: FreeFemInterface Interface for the finite element solver Freefem++ """ def __init__(self): super(FreeFemInterface, self).__init__(freefemExec)
[docs] def DeleteGeneratedFiles(self): """Delete specific generated files after run""" filesToDelete = ["freefeminput.depl.sol","freefeminput.sol"] self.DeleteFiles(filesToDelete)
[docs] def ExecuteFreefem(self): """Run Freefem++ executable""" source = GetScriptsPath() assert len(self.filename),"No freefem filename given" filesFound = [f for f in os.listdir(source) if f.startswith(self.filename)] assert len(filesFound)<=1,"Ambiguity: Only one file at most should match "+self.filename if len(filesFound)==1: freefemFile=filesFound[0] shutil.copy(os.path.join(source,freefemFile), self.workingDirectory ) cmdBuilder = CommandLineBuilder(self.GetAppName()) cmdBuilder.optionAdd("nw") cmdBuilder.argumentAdd(self._fileName(self.filename)) cmd = cmdBuilder.result() self._runCommand(cmd)
[docs] def GetSolution(self, i:int=0)->np.ndarray: """Retrieve solution Parameters ---------- i : int, optional solution index, by default 0 Returns ------- np.ndarray solution at index i """ self.fileoutname = self._filePath("freefeminput.depl.sol") self.reader.SetFileName(self.fileoutname) res = self.reader.Read() return res.nodeFields["SolAtVertices"+str(i)]
[docs] def GetNodalField(self,name:str)->np.ndarray: """Retrieve nodal field Parameters ---------- name : str field name Returns ------- np.ndarray nodal field value """ self.fileoutname = self._filePath(FileNamebyFieldName[name]) self.reader.SetFileName(self.fileoutname) res = self.reader.Read() if name == FN.stress: np.hstack((res.nodeFields["SolAtVertices0"], res.nodeFields["SolAtVertices1"])) if name=='metric' and "SolAtVertices1" in res.nodeFields and "SolAtVertices2" in res.nodeFields: return np.vstack([res.nodeFields["SolAtVertices0"][:,0],res.nodeFields["SolAtVertices1"][:,0],res.nodeFields["SolAtVertices2"][:,0]]).T return res.nodeFields["SolAtVertices0"][:,0]
[docs] def GetScalar(self,name:str)->float: """Retrieve scalar Parameters ---------- name : str scalar name Returns ------- float scalar value """ return float(np.loadtxt(self._filePath(FileNamebyScalarName[name])))
[docs]def CheckIntegrity(GUI=False): return "ok"