Source code for g3d.flow.io.g3dio

"""I/O functionality - geometry and flow import/export (G3DIO class definition)"""
from typing import Any, TextIO, TYPE_CHECKING

import sys
import os

if TYPE_CHECKING:
    from g3d.flow.domain import Domain

from g3d.flow.placeholders import ConsField, AuxvField, PostField, VGradField, FlowDataPlaceHolder

if os.environ.get('__USE_CUDA', '0') == '1':
    import cupy as np
    from cupy import ndarray
else:
    import numpy as np
    from numpy import ndarray

import matplotlib.pyplot as plt

from g3d.defs import G3DWorld
from g3d.defs import G3DEntity
from g3d.defs import DIMMode
from g3d.defs import assure_path_exists
from g3d.defs import clean_path


[docs] class G3DIO(G3DEntity): """Definition of class G3DIO: I/O functionality - geometry and flow import/export""" def __init__(self, *args: Any, **kwargs: Any) -> None: self._id = [0, 1, -1, 0, 0, 0, 0] self._jd = [0, 0, 0, 1, -1, 0, 0] self._kd = [0, 0, 0, 0, 0, 1, -1] self._export_name = 'g3d.xml' super().__init__(*args, **kwargs) def _set_default(self) -> None: super()._set_default() self._tag = 'g3d_io' self.__name_tags = ['name', 'export_name', 'xml_name', 'sol_dir', 'export_dir', 'xml_dir', 'remove_sub_path', 'label', 'subdir', 'variable_name', 'variable_names'] self.__reset_names() def __reset_names(self) -> None: self.__names = {} for x in self.__name_tags: if x == 'variable_name': self.__names[x] = 'var' elif x == 'variable_names': self.__names[x] = [] else: self.__names[x] = ''
[docs] def set_from_key_value(self, key: str, value: Any) -> bool: """Sets data from key-value pair input Parameters ---------- key: str : keyword value: Any : value corresponding to keyword Returns ------- bool status - True if key is found in list of valid keywords """ if super().set_from_key_value(key, value): return True elif key == 'export_name': self._export_name = value return True return False
[docs] @staticmethod def get_solution(cons: ConsField, filename: str) -> None: """Reads flow field data (solver variables) from file Parameters ---------- cons : ConsField : conservative variable container filename : str : file name """ cons.import_data(filename)
def __get_names(self, **kwargs: Any) -> None: g3d_world = G3DWorld() self.__reset_names() xml_export = False for key, value in kwargs.items(): if key in self.__name_tags: self.__names[key] = value elif key == 'no_xml': xml_export = False elif key == 'export_xml': xml_export = value name = self.__names['name'] subdir = self.__names['subdir'] if name == '': name = g3d_world.io.wd + '/' + subdir + '/' + g3d_world.io.jobname name = clean_path(name) assure_path_exists(name) self.__names['name'] = name self.__names['sol_dir'] = os.path.dirname(name) self.__names['export_dir'] = self.__names['sol_dir'] if xml_export: name = self.__names['xml_name'] if name == '': name = g3d_world.io.wd + '/' + subdir + '/' + g3d_world.io.jobname name = clean_path(name) assure_path_exists(name) self.__names['xml_name'] = name self.__names['xml_dir'] = os.path.dirname(name) xml_dir = self.__names['xml_dir'] sol_dir = self.__names['sol_dir'] if len(sol_dir) and len(xml_dir): if xml_dir in sol_dir: if sol_dir.index(xml_dir) == 0: self.__names['remove_sub_path'] = xml_dir else: self.__names['xml_name'] = ''
[docs] @staticmethod def add_xdmf_header(f: TextIO) -> None: """Add header to xdmf file Parameters ---------- f : TextIO : file handle """ f.write('<?xml version=\"1.0\" ?>\n') f.write('<!DOCTYPE Xdmf SYSTEM \"Xdmf.dtd\" []>\n') f.write('<Xdmf Version=\"2.0\">\n')
[docs] @staticmethod def add_geo_data_item(ni: int, nj: int, nk: int, filename: str, f: TextIO, pos: int = 0, dim_mode: Any = DIMMode.G3D, bo: str = 'little') -> None: """Add geometric data item to xdmf file Parameters ---------- ni : int : number of nodes in i-direction nj : int : number of nodes in j-direction nk : int : number of nodes in k-direction filename : str : file name f : TextIO : file handle pos : int : file position (Default value = 0) dim_mode : DIMMode dimension mode (Default value = DIMMode.G3D) bo : str : byte order 'little' or 'big' (Default value = 'little') """ if dim_mode == DIMMode.G3D or dim_mode == DIMMode.Q3D: f.write(' <DataItem Dimensions=\"%d %d %d 3\" NumberType=\"Float\"' % (nk, nj, ni)) f.write(' Precision=\"8\" Format=\"Binary\" Endian=\"%s\" Seek=\"%d\">\n' % (bo, pos)) elif dim_mode == DIMMode.G2D or dim_mode == DIMMode.G2D_AXISYMM: f.write(' <DataItem Dimensions=\"1 %d %d 2\" NumberType=\"Float\"' % (nj, ni)) f.write(' Precision=\"8\" Format=\"Binary\" Endian=\"%s\" Seek=\"%d\">\n' % (bo, pos)) f.write(' %s\n' % filename) f.write(' </DataItem>\n')
[docs] @staticmethod def add_cell_data_item(ni: int, nj: int, nk: int, filename: str, f: TextIO, pos: int = 0, dim_mode: Any = DIMMode.G3D, bo: str = 'little') -> None: """Add cell data item to xdmf file Parameters ---------- ni : int : number of nodes in i-direction nj : int : number of nodes in j-direction nk : int : number of nodes in k-direction filename : str : file name f : TextIO : file handle pos : int : file position (Default value = 0) dim_mode : DIMMode : dimension mode (Default value = DIMMode.G3D) bo : str : byte order 'little' or 'big' (Default value = 'little') """ if dim_mode == DIMMode.G3D or dim_mode == DIMMode.Q3D: f.write(' <DataItem Dimensions=\"%d %d %d 1\" NumberType=\"Float\"' % (nk - 1, nj - 1, ni - 1)) f.write(' Precision=\"8\" Format=\"Binary\" Endian=\"%s\" Seek=\"%d\">\n' % (bo, pos)) elif dim_mode == DIMMode.G2D or dim_mode == DIMMode.G2D_AXISYMM: f.write(' <DataItem Dimensions=\"%d %d\" NumberType=\"Float\"' % (nj - 1, ni - 1)) f.write(' Precision=\"8\" Format=\"Binary\" Endian=\"%s\" Seek=\"%d\">\n' % (bo, pos)) f.write(' %s\n' % filename) f.write(' </DataItem>\n')
[docs] @staticmethod def add_geo_attribute(im: int, ni: int, nj: int, nk: int, f: TextIO, dim_mode: Any = DIMMode.G3D): """Adds geometric attribute to xdmf file Parameters ---------- im : int : block number ni : int : number of nodes in i-direction nj : int : number of nodes in j-direction nk : int : number of nodes in k-direction f : TextIO : file handle dim_mode : DIMMode : dimension mode (Default value = DIMMode.G3D) """ if dim_mode == DIMMode.G3D or dim_mode == DIMMode.Q3D: f.write(' <Topology TopologyType=\"3DSMesh\" Dimensions=\"%d %d %d\"/>\n' % (nk, nj, ni)) f.write(' <Geometry GeometryType=\"XYZ\">\n') elif dim_mode == DIMMode.G2D or dim_mode == DIMMode.G2D_AXISYMM: f.write(' <Topology TopologyType=\"2DSMesh\" Dimensions=\"%d %d\"/>\n' % (nj, ni)) f.write(' <Geometry GeometryType=\"XY\">\n') f.write(' <DataItem Reference=\"/Xdmf/DataItem[%d]/DataItem[1]\" />\n' % (im + 1)) f.write(' </Geometry>\n')
[docs] @staticmethod def add_cell_attribute(variable: str, im: int, f: TextIO, item_counter: int = 2): """Adds cell attribute (flow data) to xdmf file Parameters ---------- variable : str : variable name im : int : block number f : TextIO : file handle item_counter : int : accumulated data-item count (Default value = 2) """ f.write(' <Attribute Name=\"%s\" Center=\"Cell\">\n' % variable) f.write(' <DataItem Reference=\"/Xdmf/DataItem[%d]/DataItem[%d]\" />\n' % (im + 1, item_counter)) f.write(' </Attribute>\n')
[docs] def export_flow(self, dom: 'Domain', cons: ConsField, auxv: AuxvField, post: PostField, **kwargs: Any) -> None: """Exports flow data to file Parameters ---------- dom : Domain : flow domain cons : ConsField : instance of conservative variables auxv : AuxvField : instance of primitive variables post : PostField : instance of postprocessing variables **kwargs : Any : keyword-value pairs valid keyword: 'name', 'export_name', 'xml_name', 'sol_dir', 'export_dir', 'xml_dir', 'remove_sub_path', 'label', 'subdir', 'variable_name', 'variable_names', 'no_xml', 'export_xml' """ g3d_world = G3DWorld() self.__get_names(**kwargs, export_xml=True) name = self.__names['name'] xml_name = self.__names['xml_name'] remove_sub_path = self.__names['remove_sub_path'] mesh = dom.mesh msh = xml_name + '.geo' if not os.path.isfile(msh): mesh.export(filename=xml_name) auxv_variable_list = ['u', 'v', 'w', 'p', 't'] c_variables = cons.export(name) a_variables = auxv.export(name) p_variables = post.export(name) if len(remove_sub_path) != 0: msh = msh.replace(remove_sub_path, '').strip('/') for var in c_variables.keys(): c_variables[var]['filename'] = c_variables[var]['filename'].replace(remove_sub_path, '').strip('/') for var in a_variables.keys(): a_variables[var]['filename'] = a_variables[var]['filename'].replace(remove_sub_path, '').strip('/') for var in p_variables.keys(): p_variables[var]['filename'] = p_variables[var]['filename'].replace(remove_sub_path, '').strip('/') if g3d_world.options.dim_mode.value > DIMMode.Q1D.value: nb = mesh.n_blocks bo = sys.byteorder xmf = xml_name + '.xmf' xmf = clean_path(xmf) print('generating xml meta data: %s' % xmf) f = open(xmf, 'w') self.add_xdmf_header(f) node_pos = 0 cell_pos = 0 for im in range(nb): ni, nj, nk = mesh.blocks[im].get_block_sizes() f.write(' <DataItem Name=\"Collection %d\" ItemType=\"Collection\">\n' % (im + 1)) self.add_geo_data_item(ni, nj, nk, msh, f, node_pos, g3d_world.options.dim_mode, bo) self.add_cell_data_item(ni, nj, nk, c_variables['ro']['filename'], f, cell_pos, g3d_world.options.dim_mode, bo) for var in auxv_variable_list: self.add_cell_data_item(ni, nj, nk, a_variables[var]['filename'], f, cell_pos, g3d_world.options.dim_mode, bo) for var in p_variables.keys(): self.add_cell_data_item(ni, nj, nk, p_variables[var]['filename'], f, cell_pos, g3d_world.options.dim_mode, bo) f.write(' </DataItem>\n') if g3d_world.options.dim_mode == DIMMode.G3D or g3d_world.options.dim_mode == DIMMode.Q3D: node_pos += ni * nj * nk * 3 * 8 cell_pos += (ni - 1) * (nj - 1) * (nk - 1) * 8 elif g3d_world.options.dim_mode == DIMMode.G2D or g3d_world.options.dim_mode == DIMMode.G2D_AXISYMM: node_pos += ni * nj * 2 * 8 cell_pos += (ni - 1) * (nj - 1) * 8 f.write(' <Domain>\n') for im in range(nb): ni, nj, nk = mesh.blocks[im].get_block_sizes() f.write(' <Grid Name=\"Block %d\" GridType=\"Uniform\">\n' % (im + 1)) self.add_geo_attribute(im, ni, nj, nk, f, g3d_world.options.dim_mode) item_counter = 2 self.add_cell_attribute(c_variables['ro']['longname'], im, f, item_counter) for var in auxv_variable_list: item_counter += 1 self.add_cell_attribute(a_variables[var]['longname'], im, f, item_counter) for var in p_variables.keys(): item_counter += 1 self.add_cell_attribute(p_variables[var]['longname'], im, f, item_counter) f.write(' </Grid>\n') f.write(' </Domain>\n') self.add_xdmf_footer(f) f.close()
[docs] def export_velocity_gradients(self, dom: 'Domain', vgrad: VGradField, **kwargs: Any) -> None: """Exports velocity gradient data Parameters ---------- dom : Domain : flow domain vgrad : VGradField : instance of velocity gradients **kwargs : Any : keyword-value pairs valid keyword: 'name', 'export_name', 'xml_name', 'sol_dir', 'export_dir', 'xml_dir', 'remove_sub_path', 'label', 'subdir', 'variable_name', 'variable_names', 'no_xml', 'export_xml' """ g3d_world = G3DWorld() self.__get_names(**kwargs, export_xml=True) name = self.__names['name'] xml_name = self.__names['xml_name'] remove_sub_path = self.__names['remove_sub_path'] mesh = dom.mesh msh = xml_name + '.geo' if not os.path.isfile(msh): mesh.export(name=xml_name) v_variables = vgrad.export(name) if len(remove_sub_path) != 0: msh = msh.replace(remove_sub_path, '').strip('/') for var in v_variables.keys(): v_variables[var]['filename'] = v_variables[var]['filename'].replace(remove_sub_path, '').strip('/') if g3d_world.options.dim_mode.value > DIMMode.Q1D.value: nb = mesh.n_blocks bo = sys.byteorder xmf = xml_name + '_vgrad.xmf' xmf = clean_path(xmf) print('generating xml meta data: %s' % xmf) f = open(xmf, 'w') self.add_xdmf_header(f) node_pos = 0 cell_pos = 0 for im in range(nb): ni, nj, nk = mesh.blocks[im].get_block_sizes() f.write(' <DataItem Name=\"Collection %d\" ItemType=\"Collection\">\n' % (im + 1)) self.add_geo_data_item(ni, nj, nk, msh, f, node_pos, g3d_world.options.dim_mode, bo) for var in v_variables.keys(): self.add_cell_data_item(ni, nj, nk, v_variables[var]['filename'], f, cell_pos, g3d_world.options.dim_mode, bo) f.write(' </DataItem>\n') if g3d_world.options.dim_mode == DIMMode.G3D or g3d_world.options.dim_mode == DIMMode.Q3D: node_pos += ni * nj * nk * 3 * 8 cell_pos += (ni - 1) * (nj - 1) * (nk - 1) * 8 elif g3d_world.options.dim_mode == DIMMode.G2D or g3d_world.options.dim_mode == DIMMode.G2D_AXISYMM: node_pos += ni * nj * 2 * 8 cell_pos += (ni - 1) * (nj - 1) * 8 f.write(' <Domain>\n') for im in range(nb): ni, nj, nk = mesh.blocks[im].get_block_sizes() f.write(' <Grid Name=\"Block %d\" GridType=\"Uniform\">\n' % (im + 1)) self.add_geo_attribute(im, ni, nj, nk, f, g3d_world.options.dim_mode) item_counter = 1 for var in v_variables.keys(): item_counter += 1 self.add_cell_attribute(v_variables[var]['longname'], im, f, item_counter) f.write(' </Grid>\n') f.write(' </Domain>\n') self.add_xdmf_footer(f) f.close()
[docs] def export_field(self, dom: 'Domain', field: FlowDataPlaceHolder, **kwargs: Any) -> None: """Exports field data to file Parameters ---------- dom : Domain : flow domain field : FlowDataPlaceHolder : instance of flow data placeholder **kwargs : Any : keyword-value pairs valid keyword: 'name', 'export_name', 'xml_name', 'sol_dir', 'export_dir', 'xml_dir', 'remove_sub_path', 'label', 'subdir', 'variable_name', 'variable_names', 'no_xml', 'export_xml' """ g3d_world = G3DWorld() self.__get_names(**kwargs, export_xml=False) name = self.__names['name'] export_dir = self.__names['export_dir'] mesh = dom.mesh msh = name + '.geo' if not os.path.isfile(msh): mesh.export(name=name) variables = field.export(name) if g3d_world.options.dim_mode.value > DIMMode.Q1D.value: nb = mesh.n_blocks bo = sys.byteorder xmf = name + '.xmf' msh = msh.strip(export_dir).strip('/') for var in variables.keys(): variables[var]['filename'] = variables[var]['filename'].strip(export_dir).strip('/') xmf = clean_path(xmf) print('generating xml meta data: %s' % xmf) f = open(xmf, 'w') self.add_xdmf_header(f) node_pos = 0 cell_pos = 0 for im in range(nb): ni, nj, nk = mesh.blocks[im].get_block_sizes() f.write(' <DataItem Name=\"Collection %d\" ItemType=\"Collection\">\n' % (im + 1)) self.add_geo_data_item(ni, nj, nk, msh, f, node_pos, g3d_world.options.dim_mode, bo) for var in variables.keys(): self.add_cell_data_item(ni, nj, nk, variables[var]['filename'], f, cell_pos, g3d_world.options.dim_mode, bo) f.write(' </DataItem>\n') if g3d_world.options.dim_mode == DIMMode.G3D or g3d_world.options.dim_mode == DIMMode.Q3D: node_pos += ni * nj * nk * 3 * 8 cell_pos += (ni - 1) * (nj - 1) * (nk - 1) * 8 elif g3d_world.options.dim_mode == DIMMode.G2D or g3d_world.options.dim_mode == DIMMode.G2D_AXISYMM: node_pos += ni * nj * 2 * 8 cell_pos += (ni - 1) * (nj - 1) * 8 f.write(' <Domain>\n') for im in range(nb): ni, nj, nk = mesh.blocks[im].get_block_sizes() f.write(' <Grid Name=\"Block %d\" GridType=\"Uniform\">\n' % (im + 1)) self.add_geo_attribute(im, ni, nj, nk, f, g3d_world.options.dim_mode) item_counter = 1 for var in variables.keys(): item_counter += 1 self.add_cell_attribute(variables[var]['longname'], im, f, item_counter) f.write(' </Grid>\n') f.write(' </Domain>\n') self.add_xdmf_footer(f) f.close()
[docs] def export_scalar(self, dom: 'Domain', var: ndarray, **kwargs: Any) -> None: """Export scalar variable to file Parameters ---------- dom : Domain : flow domain var : ndarray : scalar variable array (cell values) **kwargs : Any : keyword-value pairs valid keyword: 'name', 'export_name', 'xml_name', 'sol_dir', 'export_dir', 'xml_dir', 'remove_sub_path', 'label', 'subdir', 'variable_name', 'variable_names', 'no_xml', 'export_xml' """ g3d_world = G3DWorld() self.__get_names(**kwargs, export_xml=False) name = self.__names['name'] export_dir = self.__names['export_dir'] variable_name = self.__names['variable_name'] mesh = dom.mesh msh = name + '.geo' if not os.path.isfile(msh): mesh.export(name=name) n_cells = g3d_world.sizes.n_cells nb = mesh.n_blocks bo = sys.byteorder xmf = name + '.xmf' csv = name + '_' + variable_name + '.csv' print('exporting scalar field to file: %s' % csv) with open(csv, 'w+b') as f: f.write(var[0:n_cells].tobytes()) if g3d_world.options.dim_mode.value > DIMMode.Q1D.value: csv = csv.strip(export_dir).strip('/') msh = msh.strip(export_dir).strip('/') xmf = clean_path(xmf) print('generating xml meta data: %s' % xmf) f = open(xmf, 'w') self.add_xdmf_header(f) node_pos = 0 cell_pos = 0 for im in range(nb): ni, nj, nk = mesh.blocks[im].get_block_sizes() f.write(' <DataItem Name=\"Collection %d\" ItemType=\"Collection\">\n' % (im + 1)) self.add_geo_data_item(ni, nj, nk, msh, f, node_pos, g3d_world.options.dim_mode, bo) self.add_cell_data_item(ni, nj, nk, csv, f, cell_pos, g3d_world.options.dim_mode, bo) f.write(' </DataItem>\n') if g3d_world.options.dim_mode == DIMMode.G3D or g3d_world.options.dim_mode == DIMMode.Q3D: node_pos += ni * nj * nk * 3 * 8 cell_pos += (ni - 1) * (nj - 1) * (nk - 1) * 8 elif g3d_world.options.dim_mode == DIMMode.G2D or g3d_world.options.dim_mode == DIMMode.G2D_AXISYMM: node_pos += ni * nj * 2 * 8 cell_pos += (ni - 1) * (nj - 1) * 8 f.write(' <Domain>\n') for im in range(nb): ni, nj, nk = mesh.blocks[im].get_block_sizes() f.write(' <Grid Name=\"Block %d\" GridType=\"Uniform\">\n' % (im + 1)) self.add_geo_attribute(im, ni, nj, nk, f, g3d_world.options.dim_mode) self.add_cell_attribute(variable_name, im, f) f.write(' </Grid>\n') f.write(' </Domain>\n') self.add_xdmf_footer(f) f.close()
[docs] def export_scalars(self, dom: 'Domain', variables: list[ndarray], **kwargs: Any) -> None: """Export multiple scalar variables (arrays) to file (cell values) Parameters ---------- dom : Domain : flow domain variables : list : multiple arrays with cell values (list of arrays) **kwargs : Any : keyword-value pairs valid keyword: 'name', 'export_name', 'xml_name', 'sol_dir', 'export_dir', 'xml_dir', 'remove_sub_path', 'label', 'subdir', 'variable_name', 'variable_names', 'no_xml', 'export_xml' """ g3d_world = G3DWorld() n_var = len(variables) self.__get_names(**kwargs, export_xml=False) name = self.__names['name'] export_dir = self.__names['export_dir'] variable_names = self.__names['variable_names'] if len(variable_names) == 0: for i in range(n_var): variable_names.append('var_' + str(i)) mesh = dom.mesh msh = name + '.geo' if not os.path.isfile(msh): mesh.export(name=name) csv_files = [] for i in range(n_var): csv_files.append(name + '_' + variable_names[i] + '.csv') n_cells = g3d_world.sizes.n_cells nb = mesh.n_blocks bo = sys.byteorder xmf = name + '.xmf' for i in range(n_var): print('exporting scalar field to file: %s' % csv_files[i]) with open(csv_files[i], 'w+b') as f: f.write(variables[i][0:n_cells].tobytes()) csv_files[i] = csv_files[i].strip(export_dir).strip('/') msh = msh.strip(export_dir).strip('/') xmf = clean_path(xmf) print('generating xml meta data: %s' % xmf) f = open(xmf, 'w') self.add_xdmf_header(f) node_pos = 0 cell_pos = 0 for im in range(nb): ni, nj, nk = mesh.blocks[im].get_block_sizes() f.write(' <DataItem Name=\"Collection %d\" ItemType=\"Collection\">\n' % (im + 1)) self.add_geo_data_item(ni, nj, nk, msh, f, node_pos, g3d_world.options.dim_mode, bo) for i in range(n_var): self.add_cell_data_item(ni, nj, nk, csv_files[i], f, cell_pos, g3d_world.options.dim_mode, bo) f.write(' </DataItem>\n') if g3d_world.options.dim_mode == DIMMode.G3D or g3d_world.options.dim_mode == DIMMode.Q3D: node_pos += ni * nj * nk * 3 * 8 cell_pos += (ni - 1) * (nj - 1) * (nk - 1) * 8 elif g3d_world.options.dim_mode == DIMMode.G2D or g3d_world.options.dim_mode == DIMMode.G2D_AXISYMM: node_pos += ni * nj * 2 * 8 cell_pos += (ni - 1) * (nj - 1) * 8 f.write(' <Domain>\n') for im in range(nb): ni, nj, nk = mesh.blocks[im].get_block_sizes() f.write(' <Grid Name=\"Block %d\" GridType=\"Uniform\">\n' % (im + 1)) self.add_geo_attribute(im, ni, nj, nk, f, g3d_world.options.dim_mode) item_counter = 1 for i in range(n_var): item_counter += 1 self.add_cell_attribute(variable_names[i], im, f, item_counter) f.write(' </Grid>\n') f.write(' </Domain>\n') self.add_xdmf_footer(f) f.close()
def __generate_2D_plot(self, X: ndarray, Y: ndarray, Z: ndarray, **kwargs: Any) -> None: self.__get_names(**kwargs, export_xml=False, subdir='/images/2D/') name = self.__names['name'] variable_name = self.__names['variable_name'] label = self.__names['label'] if label == '': label = variable_name fig = plt.figure() plt.contourf(X, Y, Z, levels=100, cmap='jet') color_bar = plt.colorbar(location='bottom') color_bar.set_label(label) plt.ylabel(r'$y\ [m]$') plt.xlabel(r'$x\ [m]$') plt.savefig(name + '_' + variable_name + '.png') # plt.show() plt.close(fig)
[docs] def plot_scalar_2D(self, dom: 'Domain', var: ndarray, im: int = 0, k: int = 0, **kwargs: Any) -> None: """Plots scalar data in two dimensions Parameters ---------- dom : Domain : flow domain var : ndarray : scalar variable array (cell values) im : int : block number (Default value = 0) k : int : k-plane index (Default value = 0) **kwargs : Any : keyword-value pairs valid keyword: 'name', 'export_name', 'xml_name', 'sol_dir', 'export_dir', 'xml_dir', 'remove_sub_path', 'label', 'subdir', 'variable_name', 'variable_names', 'no_xml', 'export_xml' """ mesh = dom.mesh ni, nj, nk = mesh.blocks[im].get_block_sizes() xc, yc, zc = dom.get_cell_centers() X2D = np.zeros((ni - 1, nj - 1)) Y2D = np.zeros((ni - 1, nj - 1)) VAR2D = np.zeros((ni - 1, nj - 1)) for j in range(nj - 1): for i in range(ni - 1): kp = dom.get_cell(im, i, j, k) X2D[i, j] = xc[kp] Y2D[i, j] = yc[kp] VAR2D[i, j] = var[kp] self.__generate_2D_plot(X2D, Y2D, VAR2D, **kwargs)
[docs] def plot_scalars_2D(self, dom: 'Domain', variables: ndarray, im: int = 0, k: int = 0, **kwargs: Any) -> None: """Plots scalar data in two dimensions (multiple scalar variables) Parameters ---------- dom : Domain : flow domain variables : ndarray : multiple arrays with cell values (list of arrays) im : int : block number (Default value = 0) k : int : k-plane index (Default value = 0) **kwargs : Any : keyword-value pairs valid keyword: 'name', 'export_name', 'xml_name', 'sol_dir', 'export_dir', 'xml_dir', 'remove_sub_path', 'label', 'subdir', 'variable_name', 'variable_names', 'no_xml', 'export_xml' """ n_var = len(variables) self.__get_names(**kwargs, export_xml=False) variable_names = self.__names['variable_names'] if len(variable_names) == 0: for i in range(n_var): variable_names.append('var_' + str(i)) mesh = dom.mesh ni, nj, nk = mesh.blocks[im].get_block_sizes() xc, yc, zc = dom.get_cell_centers() X2D = np.zeros((ni - 1, nj - 1)) Y2D = np.zeros((ni - 1, nj - 1)) VAR2D = np.zeros((ni - 1, nj - 1)) for j in range(nj - 1): for i in range(ni - 1): kp = dom.get_cell(im, i, j, k) X2D[i, j] = xc[kp] Y2D[i, j] = yc[kp] for ivar in range(n_var): for j in range(nj - 1): for i in range(ni - 1): kp = dom.get_cell(im, i, j, k) VAR2D[i, j] = variables[ivar, kp] self.__generate_2D_plot(X2D, Y2D, VAR2D, variable_name=variable_names[ivar], **kwargs)
[docs] def plot_field_2D(self, dom: 'Domain', field: FlowDataPlaceHolder, im: int = 0, k: int = 0, **kwargs: Any) -> None: """Plots field data in two dimensions (multiple variables) Parameters ---------- dom : Domain : flow domain field : FlowDataPlaceHolder : instance of flow data placeholder im : int : block number (Default value = 0) k : int : k-plane index (Default value = 0) **kwargs : Any : keyword-value pairs valid keyword: 'name', 'export_name', 'xml_name', 'sol_dir', 'export_dir', 'xml_dir', 'remove_sub_path', 'label', 'subdir', 'variable_name', 'variable_names', 'no_xml', 'export_xml' """ variables = field.variables mesh = dom.mesh ni, nj, nk = mesh.blocks[im].get_block_sizes() xc, yc, zc = dom.get_cell_centers() X2D = np.zeros((ni - 1, nj - 1)) Y2D = np.zeros((ni - 1, nj - 1)) VAR2D = np.zeros((ni - 1, nj - 1)) for j in range(nj - 1): for i in range(ni - 1): kp = dom.get_cell(im, i, j, k) X2D[i, j] = xc[kp] Y2D[i, j] = yc[kp] for var in variables.keys(): for j in range(nj - 1): for i in range(ni - 1): kp = dom.get_cell(im, i, j, k) VAR2D[i, j] = variables[var]['ref'][kp] self.__generate_2D_plot(X2D, Y2D, VAR2D, variable_name=variables[var]['longname'], **kwargs)
[docs] def plot_flow_2D(self, dom: 'Domain', cons: ConsField, auxv: AuxvField, post: PostField, im: int = 0, k: int = 0, **kwargs: Any) -> None: """Plots flow data in two dimensions (multiple variables) Parameters ---------- dom : Domain : flow domain cons : ConsField : instance of conservative variables auxv : AuxvField : instance of primitive variables post : PostField : instance of postprocessing variables im : int : block number (Default value = 0) k : int : k-plane index (Default value = 0) **kwargs : Any : keyword-value pairs valid keyword: 'name', 'export_name', 'xml_name', 'sol_dir', 'export_dir', 'xml_dir', 'remove_sub_path', 'label', 'subdir', 'variable_name', 'variable_names', 'no_xml', 'export_xml' """ mesh = dom.mesh ni, nj, nk = mesh.blocks[im].get_block_sizes() xc, yc, zc = dom.get_cell_centers() X2D = np.zeros((ni - 1, nj - 1)) Y2D = np.zeros((ni - 1, nj - 1)) VAR2D = np.zeros((ni - 1, nj - 1)) for j in range(nj - 1): for i in range(ni - 1): kp = dom.get_cell(im, i, j, k) X2D[i, j] = xc[kp] Y2D[i, j] = yc[kp] for var in auxv.variables.keys(): V = auxv.get_array(var) for j in range(nj - 1): for i in range(ni - 1): kp = dom.get_cell(im, i, j, k) VAR2D[i, j] = V[kp] self.__generate_2D_plot(X2D, Y2D, VAR2D, variable_name=auxv.variables[var]['longname'], **kwargs) for var in post.variables.keys(): V = post.get_array(var) for j in range(nj - 1): for i in range(ni - 1): kp = dom.get_cell(im, i, j, k) VAR2D[i, j] = V[kp] self.__generate_2D_plot(X2D, Y2D, VAR2D, variable_name=post.variables[var]['longname'], **kwargs) var = 'ro' V = cons.get_array(var) for j in range(nj - 1): for i in range(ni - 1): kp = dom.get_cell(im, i, j, k) VAR2D[i, j] = V[kp] self.__generate_2D_plot(X2D, Y2D, VAR2D, variable_name=cons.variables[var]['longname'], **kwargs)
def __plot_probe_array(self, dom: 'Domain', var: ndarray, lc: ndarray, **kwargs: Any) -> None: self.__get_names(**kwargs, export_xml=False, subdir='/images/1D/') name = self.__names['name'] variable_name = self.__names['variable_name'] xc, yc, zc = dom.get_cell_centers() DX = xc[lc[1::]] - xc[lc[0:-1:]] DY = yc[lc[1::]] - yc[lc[0:-1:]] DZ = zc[lc[1::]] - zc[lc[0:-1:]] DR = np.sqrt(DX ** 2 + DY ** 2 + DZ ** 2) RC = np.zeros(len(lc)) for i in range(1, len(lc)): RC[i] = RC[i - 1] + DR[i - 1] RC = RC / max(RC) fig = plt.figure() plt.plot(RC, var[lc]) plt.xlabel('non-dimensional coordinate') plt.ylabel(variable_name) plt.xlim([0, max(RC)]) plt.savefig(name + '_' + variable_name + '.png') # plt.show() plt.close(fig)
[docs] def plot_probe_array(self, dom: 'Domain', var: ndarray, im: int, i0: int, j0: int, k0: int, idir: int, nci: int, **kwargs: Any) -> None: """Plots probe array data Parameters ---------- dom : Domain : flow domain var : ndarray : scalar variable array (cell values) im : int : block number i0 : int : start index i-direction j0 : int : start index j-direction k0 : int : start index k-direction idir : int : probe direction (1 -> +i, 2 -> -i, 3 -> +j, 4 -> -j, 5 -> +k, 6 -> -k) nci : int : number of cells in specified direction **kwargs : Any : keyword-value pairs valid keyword: 'name', 'export_name', 'xml_name', 'sol_dir', 'export_dir', 'xml_dir', 'remove_sub_path', 'label', 'subdir', 'variable_name', 'variable_names', 'no_xml', 'export_xml' """ mesh = dom.mesh ni, nj, nk = mesh.blocks[im].get_block_sizes() lc = np.zeros(nci, dtype=int) l0c = dom.get_cell(im, i0, j0, k0) ldic = self._id[idir] + (ni - 1) * self._jd[idir] + (ni - 1) * (nj - 1) * self._kd[idir] for i in range(nci): lc[i] = l0c + i * ldic self.__plot_probe_array(dom, var, lc, **kwargs)