Source code for IDSimPy.preprocessing.comsol_import

# -*- coding: utf-8 -*-

import numpy as np
import gzip
import io


[docs] def import_comsol_3d_csv_grid(filename): """ Imports a csv file with multiple 3d scalar fields exported from comsol. Result dictionary contains: * grid_points: Array of vectors with the positions of the grid points in the x,y,z directions * meshgrid: Array of meshgrid matrices as defined by numpy meshgrid * fields: Array of scalar fields, which are dictionaries with a name and the scalar data in 'data' :param str filename: the file name to import :return: Result dictionary as defined above """ if filename[-3:] == ".gz": with gzip.open(filename, 'rt') as f: raw_dat_str = f.read() else: with open(filename, 'rt') as f: raw_dat_str = f.read() raw_dat_tokenized = raw_dat_str.split("% Data\n") raw_dat_header = raw_dat_tokenized[0] raw_dat_fields = raw_dat_tokenized[1:] grid_points = parse_spatial_dimensions(raw_dat_header) grid_dims = [len(x) for x in grid_points] fields = [parse_comsol_csv_data_chunk(raw_field, grid_dims) for raw_field in raw_dat_fields] meshgrid = np.meshgrid(grid_points[0], grid_points[1], grid_points[2], indexing='ij') return {"grid_points": grid_points, "meshgrid": meshgrid, "fields": fields}
# ---------------- utlilty functions / methods ----------------------
[docs] def parse_grid_vector(vec_str, delimiter=','): """ Parses a vector with spatial grid positions from a grid vector line from a comsol csv header. :param str vec_str: A string containing the header line :param str delimiter: the delimiter in the vector line :return: numpy array with the vector values """ vec_str_spl = vec_str.split(delimiter) vec_len = len(vec_str_spl) vec = np.zeros([vec_len]) for i in range(vec_len): vec[i] = float(vec_str_spl[i]) return (vec)
[docs] def parse_comsol_csv_data_chunk(raw_chunk, dims): """ Parses a raw data chunk (given as string) and returns a numpy array with the data values. :param str raw_chunk: The string containing the data chunk :param dims: 3 dim array with the number of points in the spatial (x,y,z) dimensions :type dims: tuple or numpy.Array :return: Dictionary with the field_name and the data of the field """ (field_name, raw_field) = raw_chunk.split('\n', 1) field_raw_dat = np.genfromtxt(io.BytesIO(raw_field.encode()), delimiter=',') x_len, y_len, z_len = dims field_dat = np.zeros([x_len, y_len, z_len]) for k in range(z_len): for j in range(y_len): l_pos = j + k * y_len field_dat[:, j, k] = field_raw_dat[l_pos, :] return {"name": field_name, 'data': field_dat}
[docs] def parse_spatial_dimensions(header): """ Parses and returns the spatial dimensions of a comsol csv field file from the header of the comsol csv file. :param str header: The header (given as string) :return: Tuple of three vectors with the spatial point grid positions in x,y,z direction """ header_lines = header.split("\n") x_grid_str = header_lines[-4] y_grid_str = header_lines[-3] z_grid_str = header_lines[-2] x_grid_vec = parse_grid_vector(x_grid_str) y_grid_vec = parse_grid_vector(y_grid_str) z_grid_vec = parse_grid_vector(z_grid_str) return (x_grid_vec, y_grid_vec, z_grid_vec)