Source code for coilpy.pm4stell

"""
Some useful functions used for the PM4STELL project
"""
import numpy as np
import pandas as pd
from .dipole import Dipole


[docs]def blocks2vtk( block_file, vtk_file, moment_file=None, dipole_file=None, clip=0, **kwargs ): """Write a VTK file from the blocks file Args: block_file (str): File name and path to the `blocks` file. vtk_file (str): VTK file name to be saved. moment_file (str, optional): File name and path to the `moments` file. Defaults to None. dipole_file (str, optional): File name and path to the FAMUS dipole file (`*.focus`). Defaults to None. clip (int, optional): The threshold value to clip magents with rho>=clip. Defaults to 0. Returns: meshio.Mesh: The constructed `meshio.Mesh` object. """ import meshio assert ".vtk" in vtk_file, ".vtk must be in the filename." assert clip >= 0, "the clip value should be >=0." blocks = pd.read_csv(block_file, skiprows=1) # remove space in headers blocks.rename(columns=lambda x: x.strip(), inplace=True) nmag = len( blocks["xb1"], ) cond = np.full((nmag), True) # parse moment data kwargs.setdefault("cell_data", {}) if moment_file is not None: moments = pd.read_csv(moment_file, skiprows=1) moments.rename(columns=lambda x: x.strip(), inplace=True) cond = moments["rho"] > clip kwargs["cell_data"].setdefault( "m", [ np.ascontiguousarray( np.transpose( [moments["Mx"][cond], moments["My"][cond], moments["Mz"][cond]] ) ) ], ) kwargs["cell_data"].setdefault("rho", [moments["rho"][cond]]) kwargs["cell_data"].setdefault("type", [moments["type"][cond]]) if dipole_file is not None: dipoles = Dipole.open(dipole_file) dipoles.sp2xyz() cond = dipoles.rho >= clip kwargs["cell_data"].setdefault( "m", [ np.ascontiguousarray( np.transpose([dipoles.mx[cond], dipoles.my[cond], dipoles.mz[cond]]) ) ], ) kwargs["cell_data"].setdefault("rho", [dipoles.rho[cond]]) kwargs["cell_data"].setdefault("Lc", [dipoles.Lc[cond]]) # update blocks based on cond blocks = blocks.loc[cond] x = np.concatenate( [ blocks["xb1"], blocks["xb2"], blocks["xb3"], blocks["xb4"], blocks["xt1"], blocks["xt2"], blocks["xt3"], blocks["xt4"], ] ) y = np.concatenate( [ blocks["yb1"], blocks["yb2"], blocks["yb3"], blocks["yb4"], blocks["yt1"], blocks["yt2"], blocks["yt3"], blocks["yt4"], ] ) z = np.concatenate( [ blocks["zb1"], blocks["zb2"], blocks["zb3"], blocks["zb4"], blocks["zt1"], blocks["zt2"], blocks["zt3"], blocks["zt4"], ] ) # write VTK nmag = np.count_nonzero(cond) ind = np.reshape(np.arange(len(x)), (8, nmag)) points = np.ascontiguousarray(np.transpose([x, y, z])) hedrs = [ind[:, i] for i in range(nmag)] data = meshio.Mesh(points=points, cells=[("hexahedron", hedrs)], **kwargs) data.write(vtk_file) return data
[docs]def blocks2ficus( block_file, ficus_file, moment_file=None, dipole_file=None, magnitization=1.1e6, clip=None, **kwargs ): """Convert PM4STELL blocks file to FICUS inputs Args: block_file (str): Path and file name to the blocks file (usually contains `_blocks.csv`). ficus_file (str): FICUS input CSV filename. moment_file (str, optional): Moments file to assign the magnetic moment. Defaults to None. dipole_file (str, optional): FAMUS dipole file to assign the magnetic moment. Defaults to None. magnitization (float, optional): The magnetization of the material. Defaults to 1.1e6. clip (float, optional): The minimum rho value to preserve. Defaults to None. Returns: pandas.DataFrame: Data in the format of pandas.DataFrame Note: This requires to load the MUSE package (https://github.com/tmqian/MUSE) to the sys.path. Example: magnets = blocks2ficus("magpie_trial104b_blocks.csv", "trial104b_ficus.csv", dipole_file="disc_ftri_wp0_c9a_tr104b.focus") """ import pandas as pd import FICUS.Magnet3D as m3 blocks = pd.read_csv(block_file, skiprows=1) blocks.to_csv("tmp.csv", columns=blocks.columns[7:], index=False) corner = m3.Magnet_3D("tmp.csv") muse_data = corner.export_source() muse_data[:, -1] = magnitization # read dipole moment if moment_file is not None: moments = pd.read_csv(moment_file, skiprows=1) moments.rename(columns=lambda x: x.strip(), inplace=True) mx = moments["Mx"].to_numpy() my = moments["My"].to_numpy() mz = moments["Mz"].to_numpy() rho = moments["rho"].to_numpy() if dipole_file is not None: dipoles = Dipole.open(dipole_file) dipoles.sp2xyz() mx = dipoles.mx my = dipoles.my mz = dipoles.mz rho = dipoles.rho # filter if clip is None: cond = np.full(np.shape(rho), True) else: cond = rho > clip muse_data = np.concatenate( [muse_data, mx[:, np.newaxis], my[:, np.newaxis], mz[:, np.newaxis]], axis=1 ) dt = pd.DataFrame( muse_data[cond], columns=[ "ox", "oy", "oz", "nx", "ny", "nz", "ux", "uy", "uz", "H", "L", "M", "mx", "my", "mz", ], ) dt.to_csv(ficus_file, index=False) return dt
[docs]def read_ansys_bfield(filename): ansys = pd.read_csv(filename, skiprows=[0], delim_whitespace=True, header=None) ansys.columns = ["x", "y", "z", "Bx", "By", "Bz"] return ansys