Source code for nrv.fmod.FEM.fenics_utils._f_materials

"""
NRV-fenics_materials class handling.
"""

import faulthandler
import os

import numpy as np

from ....backend._file_handler import json_dump, rmv_ext
from ....backend._log_interface import rise_warning
from ....utils._nrv_function import nrv_interp, nrv_function
from ..._materials import (
    is_mat,
    load_material,
    material,
    compute_effective_conductivity,
)

# enable faulthandler to ease "segmentation faults" debug
faulthandler.enable()


####################
## material class ##
####################
[docs] class f_material(material): """ a class for conductive material wh parameters ---------- mat :material generate the fenics material from mat attribute """
[docs] def __init__(self): """ initialisation of the fenics_material """ super().__init__() self._sigma_func = None
## Save and Load mehtods
[docs] def save(self, save=False, fname="Fenics_model.json", blacklist=[], **kwargs): """ Return material as dictionary and eventually save it as json file Parameters ---------- save : bool if True, save in json files fname : str Path and Name of the saving file, by default "material.json" Returns ------- mat_dic : dict dictionary containing all information """ bl = [i for i in blacklist] bl += ["sigma_func"] return super().save(save=save, fname=fname, blacklist=bl, **kwargs)
@property def is_func(self): """ Whether the material conductivity is defined by a spatial function. Returns ------- bool ``True`` when a conductivity function is available. """ return not self._sigma_func is None @property def sigma(self): """ Effective conductivity accessor. Returns ------- Any Conductivity function when defined, otherwise the scalar/tensor conductivity. """ if self.is_func: return self.sigma_func else: return super().sigma @property def sigma_func(self): """ Frequency-adjusted conductivity function. Returns ------- nrv_function Conductivity function corrected for dielectric effects. """ return compute_effective_conductivity( sigma=self._sigma_func, epsilon=self.epsilon, freq=self.freq )
[docs] def set_conductivity_function(self, sigma_func: nrv_function) -> None: """ set the conductivity space function for an anisotropic material Parameters ---------- sigma_fuction : func(X : array([3, N]))-> array([N]) conductivity function in 3D space """ self.isotrop_cond = False self._sigma_func = sigma_func
[docs] def is_function_defined(self) -> bool: """ check that the material conductivity is define as a function Returns ------- bool : True if the per """ return self.is_func
############### ## Functions ## ###############
[docs] def is_f_mat(mat: object) -> bool: """ check if an object is a fenics_material, return True if yes, else False Parameters ---------- mat : object object to test Returns ------- bool True it the type is a material object """ return isinstance(mat, f_material)
[docs] def mat_from_interp( X, Y, kind="linear", dx=0.01, interpolator=None, dxdy=None, scale=None, columns=0 ) -> f_material: """ Return a fenics material with a conductivity space function define as the :class:`~nrv.utils.nrv_function.nrv_interp` of X and Y Parameters ---------- f_material : str either material name if the material is in the NRV2 Librairy or path to the corresponding .mat material file kwargs : dict interpolation k arguments (see :class:`~nrv.utils.nrv_function.nrv_interp`) Returns ------- mat_obj : fenics_material Fenics material with conductivity function defined from the interpolation """ sigma_func = nrv_interp( X, Y, kind=kind, dx=dx, interpolator=interpolator, dxdy=dxdy, scale=scale, columns=columns, ) # creat material instance mat_obj = f_material() mat_obj.set_conductivity_function(sigma_func) return mat_obj
[docs] def mat_from_csv(fname: str, **kwargs) -> f_material: """ Return a fenics material with a conductivity space function define as the :class:`~nrv.utils.nrv_function.nrv_interp` from the value of a .csv file Parameters ---------- f_material : str name of the .csv file Returns ------- mat_obj : fenics_material Fenics material with conductivity function defined from the interpolation from the value of f_material file """ fname = rmv_ext(fname) + ".csv" data = np.loadtxt(fname, delimiter=",") X = data[0] Y = data[1] return mat_from_interp(X, Y, **kwargs)
[docs] def load_f_material(X: any = None, **kwargs) -> f_material: """ Return fenics material from an object X Parameters ---------- X : objects if material or fenics material returning the corresponding fenics material if float returns an isotropic fenics material with X as conductivity value if str finishing with .csv use mat_from_csv with kwargs else return None """ mat = None if X is None: mat = f_material() elif is_f_mat(X): mat = X elif is_mat(X): mat = f_material() mat.load(X.save(save=False)) elif isinstance(X, str): if ".csv" in X: mat = mat_from_csv(X, **kwargs) else: mat = f_material() mat.load(load_material(X).save(save=False)) elif isinstance(X, (complex, float, int)): mat = f_material() mat.set_isotropic_conductivity(X) elif np.iterable(X): if len(X) == 2: mat = mat_from_interp(X[0, :], X[1, :], **kwargs) elif len(X) == 3: mat = f_material() mat.set_anisotropic_conductivity(X[0], X[1], X[2]) elif hasattr(X, "mat"): mat = load_f_material(X.mat) if mat is None: rise_warning( TypeError(), f"{type(X)} not convertible in f_material\n", "empty material generated", ) mat = f_material() return mat