Source code for pytheas.tools.utils

"""Shared utility functions used in pytheas."""


import numpy as np
from ..tools import femio
from ..material import genmat


[docs]def normalize(x): """Normalize an array between 0 and 1 Parameters ---------- x : array-like the quantity to be normalized Returns ------- x_norm : array-like normalized array """ return (x - x.min()) / (x.max() - x.min())
def between_range(x, xmin, xmax): return (xmax - xmin) * x + xmin def refine_mesh( fem, mat, lc_des=None, par=None, nmax=5, periodic_x=False, periodic_y=False, lc_bnd=None, ): mat_tmp = mat mat_tmp.ratio_filter = [20, 20, 20] pattern = mat_tmp.pattern nodes, els, des = fem.get_mesh_info() if not lc_des: lc_des = 1 * fem.lambda_mesh / (fem.parmesh_des * np.sqrt(fem.eps_des.real)) if not par: par = [[1, 0.8, 0.7], [0.2, 0.15, 0.1], [0.6, 0.8, 1]] it = 0 for smooth_factor, fc_min, fc_max in zip(*par): lc_min, lc_max = lc_des * fc_min, lc_des * fc_max if fem.dim is 2: grad_pat = np.gradient(pattern[:, :, 0]) grad_pat_norm = np.sqrt(grad_pat[0] ** 2 + grad_pat[1] ** 2).reshape( pattern.shape ) else: grad_pat = np.gradient(pattern) grad_pat_norm = np.sqrt( grad_pat[0] ** 2 + grad_pat[1] ** 2 + grad_pat[2] ** 2 ) grad_pat_norm = genmat.filter_pattern( grad_pat_norm, smooth_factor * mat_tmp.sigma ) grad_pat_norm = normalize(grad_pat_norm) thres_grad = 1e-1 grad_pat_norm[grad_pat_norm > thres_grad] = 1 grad_pat_norm[grad_pat_norm <= thres_grad] = 0 grad_pat_norm = genmat.filter_pattern( grad_pat_norm, smooth_factor * mat_tmp.sigma ) grad_pat_norm = 1 - normalize(grad_pat_norm) grad_pat_norm = between_range(grad_pat_norm, lc_min, lc_max) if not lc_bnd: lc_bnd = lc_min # (lc_max + lc_min) / 2 if periodic_y: grad_pat_norm[:, :nmax] = lc_bnd grad_pat_norm[:, -nmax:] = lc_bnd if periodic_x: grad_pat_norm[:nmax, :] = lc_bnd grad_pat_norm[-nmax:, :] = lc_bnd fdens_grad = fem.make_fdens(grad_pat_norm) density_grad = fdens_grad(nodes[1]) fem.type_des = "nodes" path_size_mesh = fem.make_pos(nodes[0], density_grad, "size_mesh") fem.type_des = "elements" # if it == 0: if fem.dim is 3: dim = [1, 2, 3] else: dim = [1, 2] femio.mesh_model( fem.path_mesh, fem.path_bg_mesh, verbose=fem.gmsh_verbose, dim=dim ) bgm = " -bgm {}".format(path_size_mesh) bgm += " -merge {}".format(fem.path_bg_mesh) femio.mesh_model( fem.path_mesh, fem.path_geo, other_option=bgm, verbose=fem.gmsh_verbose, dim=dim, ) nodes, els, des = fem.get_mesh_info() # fem.content_mesh = fem.make_mesh_pos(els, nodes) fem.content_mesh = femio.get_content(fem.path_mesh) it += 1 if fem.gmsh_verbose: print("mesh refinement iteration :", it) fem.nodes, fem.els, fem.des = nodes, els, des return fem