Source code for kokiy.shell_utils

"""Defines cut plane tools.
"""

import numpy as np

from arnica.utils.vector_actions import yz_to_theta
from cloud2cloud import CloudInterpolator

from kokiy import AxiShell
from kokiy import CartShell

# TODO: need to review how general this functions are


__all__ = ["infer_shell_from_xyz", "axishell_create_structured_base",
           "cartshell_create_structured_base",
           "interpolate_solutions_on_shell",
           "shell_geom_type", "shell_repr"]


[docs]def infer_shell_from_xyz(mesh_xyz, geom_type, shape, bnd_uv=None, bnd_angles=None): """Build a shell from an AVBP Cut. Args: geom_type (str): Geometry type. Either "cart" or "axicyl". shape (array-like): Discretization of the shell. Shape (nu, nv). bnd_uv (array-like): Limits shell umin, umax, vmin, vmax. Shape (4,). """ if bnd_angles is not None: raise DeprecationWarning("BNd_angle is not used anymore, Use bnd_uv") # Build shell if geom_type == "axicyl": shell = axishell_create_structured_base( shape[0], shape[1], mesh_xyz, bnd_uv) elif geom_type == "cart": shell = cartshell_create_structured_base( shape[0], shape[1], mesh_xyz) return shell
[docs]def axishell_create_structured_base(n_longi, n_azi, mesh, bnd_uv=None): """Obtain the base in a structured mesh. Assumes the mesh is the x_axis rotated extrusion of an (x,r) curve. Args: n_longi (int): Number of radial points of the shell. n_azi (int): Number of azimuthal points of the shell. mesh (array-like): Coordinates of the cut mesh of shape (n, 3). bnd_uv (array-like): Limits shell umin, umax, vmin, vmax. Shape (4,). Returns: AxiShell: An axysymmetric computational shell. """ x_pos = mesh[:, 0].mean() r_vals = np.hypot(mesh[:, 1], mesh[:, 2]) theta = np.rad2deg(yz_to_theta(mesh[:, :])) if bnd_uv is None: bnd_uv = [None, None, None, None] if bnd_uv[0] is None: bnd_uv[0] = r_vals.min() if bnd_uv[1] is None: bnd_uv[1] = r_vals.max() if bnd_uv[2] is None: bnd_uv[2] = theta.min() if bnd_uv[3] is None: bnd_uv[3] = theta.max() x_ctrl_pts = [x_pos, x_pos] r_ctrl_pts = [bnd_uv[0], bnd_uv[1]] tmin = bnd_uv[2] tmax = bnd_uv[3] shell = AxiShell( n_azi, n_longi, tmax - tmin, # angle_range, x_ctrl_pts, # x_vals[corners_idx], r_ctrl_pts, # r_vals[corners_idx], tmin # angle_min, ) return shell
[docs]def cartshell_create_structured_base(n_longi, n_trans, mesh): """Obtain the base in a structured mesh. Assumes the path is square, aligned with y and z, with x = constant. Args: n_longi (int): Number of longitudinal points of the shell. n_trans (int): Number of transversal points of the shell. mesh (array-like): Coordinates of the cut mesh of shape (n, 3). Returns: CartShell: A cartesian computational shell. """ x_vals, y_vals, z_vals = mesh.T zero = (x_vals.mean(), y_vals.min(), z_vals.min()) v_max = (x_vals.mean(), y_vals.max(), z_vals.min()) u_max = (x_vals.mean(), y_vals.min(), z_vals.max()) shell = CartShell( n_trans, n_longi, zero, u_max, v_max, ) return shell
[docs]def interpolate_solutions_on_shell(shell, mesh, raw_data, stencil=4, function=None, limitsource=None): """Interpolates solutions on a shell. Args: shell (Shell): A `Shell` object. mesh (np.array): Mesh with shape (n_pts, 3). data_dict (dict or np.array): Arrays shape = (n_steps, n_pts) or (n_pts,). Must contain keys if `np.array` (prefer `dict` for this case). Notes: Check cloud2cloud.CloudInterpolator for meaning of other arguments. """ if function is None: function = lambda x: np.power(x, 4) # manipulate input is_dict = type(raw_data) == dict data_dict = raw_data if is_dict else _from_np_struct_to_dict(raw_data) # create interpolator interpolator = CloudInterpolator(mesh.reshape(-1, 3).T, shell.xyz.reshape(-1, 3).T, stencil=stencil, function=function, limitsource=limitsource) n = mesh.shape[0] results_dict = {} for key, array in data_dict.items(): if array.shape[0] == n: results_dict[key] = interpolator.interp(array).reshape(*shell.shape) else: results_dict[key] = interpolator.interp(array.T).T.reshape(-1, *shell.shape) # manipulate output results = results_dict if is_dict else _from_dict_to_np_struct(results_dict) return results
[docs]def interpolate_solution_on_shell(shell, mesh, array, **kwargs): """Interpolates a solution on a shell. Args: shell (Shell): A `Shell` object. mesh (np.array): Mesh with shape (n_pts, 3). array (np.array): Shape = (n_steps, pts) or (n_pts,). kwargs : cloud2cloud.CloudInterpolator parameters. """ return interpolate_solutions_on_shell(shell, mesh, {'data': array}, **kwargs)['data']
[docs]def shell_geom_type(shell): """Return the shell geom_type. .. deprecated:: 0.2.0 Use `shell.geom_type` instead. """ return shell.geom_type
[docs]def shell_repr(shell): """Return a shell description. .. deprecated:: 0.2.0 Use `repr(shell)` instead. """ return repr(shell)
def _from_np_struct_to_dict(array): return {key: array[key] for key in array.dtype.names} def _from_dict_to_np_struct(my_dict, type_=np.float32): keys = list(my_dict.keys()) dtype = dict(names=keys, formats=[type_] * len(keys)) shape = my_dict[keys[0]].shape array = np.empty(shape, dtype=dtype) for key, value in my_dict.items(): array[key] = value return array