Source code for sharpy.postproc.writevariablestime

import os
import numpy as np
from sharpy.utils.solver_interface import solver, BaseSolver
import sharpy.utils.settings as settings_utils


[docs]@solver class WriteVariablesTime(BaseSolver): r""" Write variables with time ``WriteVariablesTime`` is a class inherited from ``BaseSolver`` It is a postprocessor that outputs the value of variables with time onto a text file. Attributes: settings_types (dict): Acceptable data types of the input data settings_default (dict): Default values for input data should the user not provide them See the list of arguments dir (str): directory to output the information """ solver_id = 'WriteVariablesTime' solver_classification = 'post-processor' settings_types = dict() settings_default = dict() settings_description = dict() settings_types['delimiter'] = 'str' settings_default['delimiter'] = ' ' settings_description['delimiter'] = 'Delimiter to be used in the output file' settings_types['FoR_variables'] = 'list(str)' settings_default['FoR_variables'] = [''] settings_description['FoR_variables'] = 'Variables of :class:`~sharpy.utils.datastructures.StructTimeStepInfo` associated to the frame of reference to be writen' settings_types['FoR_number'] = 'list(int)' settings_default['FoR_number'] = np.array([0], dtype=int) settings_description['FoR_number'] = 'Number of the A frame of reference to output (for multibody configurations)' settings_types['structure_variables'] = 'list(str)' settings_default['structure_variables'] = [''] settings_description['structure_variables'] = 'Variables of :class:`~sharpy.utils.datastructures.StructTimeStepInfo` associated to the frame of reference to be writen' settings_types['structure_nodes'] = 'list(int)' settings_default['structure_nodes'] = np.array([-1]) settings_description['structure_nodes'] = 'Number of the nodes to be writen' settings_types['nonlifting_nodes_variables'] = 'list(str)' settings_default['nonlifting_nodes_variables'] = [''] settings_description['nonlifting_nodes_variables'] = 'Variables of :class:`~sharpy.utils.datastructures.NonliftingBodyTimeStepInfo` associated to panels to be writen' settings_types['nonlifting_nodes_im'] = 'list(int)' settings_default['nonlifting_nodes_im'] = np.array([0]) settings_description['nonlifting_nodes_im'] = 'Chordwise index of the nonlifting panels to be output' settings_types['nonlifting_nodes_in'] = 'list(int)' settings_default['nonlifting_nodes_in'] = np.array([0]) settings_description['nonlifting_nodes_in'] = 'Spanwise index of the nonlifting panels to be output' settings_types['nonlifting_nodes_isurf'] = 'list(int)' settings_default['nonlifting_nodes_isurf'] = np.array([0]) settings_description['nonlifting_nodes_isurf'] = "Number of the panels' surface to be output" settings_types['aero_panels_variables'] = 'list(str)' settings_default['aero_panels_variables'] = [''] settings_description['aero_panels_variables'] = 'Variables of :class:`~sharpy.utils.datastructures.AeroTimeStepInfo` associated to panels to be writen' settings_types['aero_panels_isurf'] = 'list(int)' settings_default['aero_panels_isurf'] = np.array([0]) settings_description['aero_panels_isurf'] = "Number of the panels' surface to be output" settings_types['aero_panels_im'] = 'list(int)' settings_default['aero_panels_im'] = np.array([0]) settings_description['aero_panels_im'] = 'Chordwise index of the panels to be output' settings_types['aero_panels_in'] = 'list(int)' settings_default['aero_panels_in'] = np.array([0]) settings_description['aero_panels_in'] = 'Spanwise index of the panels to be output' settings_types['aero_nodes_variables'] = 'list(str)' settings_default['aero_nodes_variables'] = [''] settings_description['aero_nodes_variables'] = 'Variables of :class:`~sharpy.utils.datastructures.AeroTimeStepInfo` associated to nodes to be writen' settings_types['aero_nodes_isurf'] = 'list(int)' settings_default['aero_nodes_isurf'] = np.array([0]) settings_description['aero_nodes_isurf'] = "Number of the nodes' surface to be output" settings_types['aero_nodes_im'] = 'list(int)' settings_default['aero_nodes_im'] = np.array([0]) settings_description['aero_nodes_im'] = 'Chordwise index of the nodes to be output' settings_types['aero_nodes_in'] = 'list(int)' settings_default['aero_nodes_in'] = np.array([0]) settings_description['aero_nodes_in'] = 'Spanwise index of the nodes to be output' settings_types['cleanup_old_solution'] = 'bool' settings_default['cleanup_old_solution'] = False settings_description['cleanup_old_solution'] = 'Remove the existing files' settings_types['vel_field_variables'] = 'list(str)' settings_default['vel_field_variables'] = list() settings_description['vel_field_variables'] = 'Variables associated to the velocity field. Only ``uext`` implemented so far' settings_types['vel_field_points'] = 'list(float)' settings_default['vel_field_points'] = np.array([0., 0., 0.]) settings_description['vel_field_points'] = 'List of coordinates of the control points as x1, y1, z1, x2, y2, z2 ...' settings_table = settings_utils.SettingsTable() __doc__ += settings_table.generate(settings_types, settings_default, settings_description) def __init__(self): self.settings = None self.data = None self.folder = None self.n_velocity_field_points = None self.velocity_field_points = None self.caller = None self.velocity_generator = None def initialise(self, data, custom_settings=None, caller=None, restart=False): self.data = data if custom_settings is None: self.settings = data.settings[self.solver_id] else: self.settings = custom_settings settings_utils.to_custom_types(self.settings, self.settings_types, self.settings_default) self.folder = data.output_folder + '/WriteVariablesTime/' if not os.path.isdir(self.folder): os.makedirs(self.folder) # Check inputs if not ((len(self.settings['aero_panels_isurf']) == len(self.settings['aero_panels_im'])) and (len(self.settings['aero_panels_isurf']) == len(self.settings['aero_panels_in']))): raise RuntimeError("aero_panels should be defined as [i_surf,i_m,i_n]") if not ((len(self.settings['aero_nodes_isurf']) == len(self.settings['aero_nodes_im'])) and (len(self.settings['aero_nodes_isurf']) == len(self.settings['aero_nodes_in']))): raise RuntimeError("aero_nodes should be defined as [i_surf,i_m,i_n]") if len(self.settings['vel_field_variables']) > 0: if not (len(self.settings['vel_field_points']) % 3 == 0): raise RuntimeError('Number of entries in ``vel_field_points`` has to be a multiple of 3') else: self.n_vel_field_points = len(self.settings['vel_field_points']) // 3 self.vel_field_points = [np.zeros((3, self.n_vel_field_points, 1))] for ipoint in range(self.n_vel_field_points): self.vel_field_points[0][:, ipoint, 0] = self.settings['vel_field_points'][ipoint*3:(ipoint + 1)*3] # Initialise files with headers and clean them if required for ivariable in range(len(self.settings['FoR_variables'])): for ifor in range(len(self.settings['FoR_number'])): filename = self.folder + "FoR_" + '%02d' % self.settings['FoR_number'][ifor] + "_" + self.settings['FoR_variables'][ivariable] + ".dat" if self.settings['cleanup_old_solution']: if os.path.isfile(filename): os.remove(filename) # Structure variables at nodes for ivariable in range(len(self.settings['structure_variables'])): for inode in range(len(self.settings['structure_nodes'])): node = self.settings['structure_nodes'][inode] filename = self.folder + "struct_" + self.settings['structure_variables'][ivariable] + "_node" + str(node) + ".dat" if self.settings['cleanup_old_solution']: if os.path.isfile(filename): os.remove(filename) # Nonlifting variables at panels for ivariable in range(len(self.settings['nonlifting_nodes_variables'])): for ipanel in range(len(self.settings['nonlifting_nodes_isurf'])): i_surf = self.settings['nonlifting_nodes_isurf'][ipanel] i_m = self.settings['nonlifting_nodes_im'][ipanel] i_n = self.settings['nonlifting_nodes_in'][ipanel] filename = self.folder + "nonlifting_" + self.settings['nonlifting_nodes_variables'][ivariable] + "_panel" + "_isurf" + str(i_surf) + "_im"+ str(i_m) + "_in"+ str(i_n) + ".dat" if self.settings['cleanup_old_solution']: if os.path.isfile(filename): os.remove(filename) # Aerodynamic variables at panels for ivariable in range(len(self.settings['aero_panels_variables'])): for ipanel in range(len(self.settings['aero_panels_isurf'])): i_surf = self.settings['aero_panels_isurf'][ipanel] i_m = self.settings['aero_panels_im'][ipanel] i_n = self.settings['aero_panels_in'][ipanel] filename = self.folder + "aero_" + self.settings['aero_panels_variables'][ivariable] + "_panel" + "_isurf" + str(i_surf) + "_im"+ str(i_m) + "_in"+ str(i_n) + ".dat" if self.settings['cleanup_old_solution']: if os.path.isfile(filename): os.remove(filename) # Aerodynamic variables at nodes for ivariable in range(len(self.settings['aero_nodes_variables'])): for inode in range(len(self.settings['aero_nodes_isurf'])): i_surf = self.settings['aero_nodes_isurf'][inode] i_m = self.settings['aero_nodes_im'][inode] i_n = self.settings['aero_nodes_in'][inode] filename = self.folder + "aero_" + self.settings['aero_nodes_variables'][ivariable] + "_node" + "_isurf" + str(i_surf) + "_im"+ str(i_m) + "_in"+ str(i_n) + ".dat" if self.settings['cleanup_old_solution']: if os.path.isfile(filename): os.remove(filename) # Velocity field variables at points for ivariable in range(len(self.settings['vel_field_variables'])): for ipoint in range(self.n_vel_field_points): filename = self.folder + "vel_field_" + self.settings['vel_field_variables'][ivariable] + "_point" + str(ipoint) + ".dat" if self.settings['cleanup_old_solution']: if os.path.isfile(filename): os.remove(filename) if not os.path.isfile(filename): fid = open(filename, 'w') fid.write(("#t[s]%suext_x[m/s]%suext_y[m/s]%suext_z[m/s]\n" % ((self.settings['delimiter'],)*3))) fid.close() # Initialise velocity generator self.caller = caller if ((not self.caller is None) and (not len(self.settings['vel_field_variables']) == 0)): if self.caller.solver_classification.lower() == 'aero': # For aerodynamic solvers self.velocity_generator = self.caller.velocity_generator elif self.caller.solver_classification.lower() == 'coupled': # For coupled solvers self.velocity_generator = self.caller.aero_solver.velocity_generator def run(self, **kwargs): online = settings_utils.set_value_or_default(kwargs, 'online', False) if online: self.data = self.write(-1) else: for it in range(len(self.data.structure.timestep_info)): if self.data.structure.timestep_info[it] is not None: self.data = self.write(it) return self.data def write(self, it): # FoR variables if 'FoR_number' in self.settings: pass else: self.settings['FoR_number'] = np.array([0], dtype=int) tstep = self.data.structure.timestep_info[it] for ivariable in range(len(self.settings['FoR_variables'])): if self.settings['FoR_variables'][ivariable] == '': continue for ifor in range(len(self.settings['FoR_number'])): filename = self.folder + "FoR_" + '%02d' % self.settings['FoR_number'][ifor] + "_" + self.settings['FoR_variables'][ivariable] + ".dat" with open(filename, 'a') as fid: var = np.atleast_2d(getattr(tstep, self.settings['FoR_variables'][ivariable])) rows, cols = var.shape if ((cols == 1) and (rows == 1)): self.write_value_to_file(fid, self.data.ts, var, self.settings['delimiter']) elif ((cols > 1) and (rows == 1)): self.write_nparray_to_file(fid, self.data.ts, var, self.settings['delimiter']) elif ((cols == 1) and (rows >= 1)): self.write_value_to_file(fid, self.data.ts, var[ifor], self.settings['delimiter']) else: self.write_nparray_to_file(fid, self.data.ts, var[ifor,:], self.settings['delimiter']) # Structure variables at nodes for ivariable in range(len(self.settings['structure_variables'])): if self.settings['structure_variables'][ivariable] == '': continue var = getattr(tstep, self.settings['structure_variables'][ivariable]) num_indices = len(var.shape) if num_indices == 1: # Beam global variables (i.e. not node dependant) filename = self.folder + "struct_" + self.settings['structure_variables'][ivariable] + ".dat" with open(filename, 'a') as fid: self.write_nparray_to_file(fid, self.data.ts, var, self.settings['delimiter']) else: # These variables have nodal values (i.e the number of indices is either 2 or 3) for inode in range(len(self.settings['structure_nodes'])): node = self.settings['structure_nodes'][inode] filename = self.folder + "struct_" + self.settings['structure_variables'][ivariable] + "_node" + str(node) + ".dat" with open(filename, 'a') as fid: if num_indices == 2: self.write_nparray_to_file(fid, self.data.ts, var[node,:], self.settings['delimiter']) elif num_indices == 3: ielem, inode_in_elem = self.data.structure.node_master_elem[node] self.write_nparray_to_file(fid, self.data.ts, var[ielem,inode_in_elem,:], self.settings['delimiter']) # Aerodynamic variables at nonlifting panels for ivariable in range(len(self.settings['nonlifting_nodes_variables'])): if self.settings['nonlifting_nodes_variables'][ivariable] == '': continue for ipanel in range(len(self.settings['nonlifting_nodes_isurf'])): i_surf = self.settings['nonlifting_nodes_isurf'][ipanel] i_m = self.settings['nonlifting_nodes_im'][ipanel] i_n = self.settings['nonlifting_nodes_in'][ipanel] filename = self.folder + "nonlifting_" + self.settings['nonlifting_nodes_variables'][ivariable] + "_panel" + "_isurf" + str(i_surf) + "_im"+ str(i_m) + "_in"+ str(i_n) + ".dat" with open(filename, 'a') as fid: var = getattr(self.data.nonlifting_body.timestep_info[it], self.settings['nonlifting_nodes_variables'][ivariable]) self.write_value_to_file(fid, self.data.ts, var[i_surf][i_m,i_n], self.settings['delimiter']) # Aerodynamic variables at panels for ivariable in range(len(self.settings['aero_panels_variables'])): if self.settings['aero_panels_variables'][ivariable] == '': continue for ipanel in range(len(self.settings['aero_panels_isurf'])): i_surf = self.settings['aero_panels_isurf'][ipanel] i_m = self.settings['aero_panels_im'][ipanel] i_n = self.settings['aero_panels_in'][ipanel] filename = self.folder + "aero_" + self.settings['aero_panels_variables'][ivariable] + "_panel" + "_isurf" + str(i_surf) + "_im"+ str(i_m) + "_in"+ str(i_n) + ".dat" with open(filename, 'a') as fid: var = getattr(self.data.aero.timestep_info[it], self.settings['aero_panels_variables'][ivariable]) self.write_value_to_file(fid, self.data.ts, var[i_surf][i_m,i_n], self.settings['delimiter']) # Aerodynamic variables at nodes for ivariable in range(len(self.settings['aero_nodes_variables'])): if self.settings['aero_nodes_variables'][ivariable] == '': continue for inode in range(len(self.settings['aero_nodes_isurf'])): i_surf = self.settings['aero_nodes_isurf'][inode] i_m = self.settings['aero_nodes_im'][inode] i_n = self.settings['aero_nodes_in'][inode] filename = self.folder + "aero_" + self.settings['aero_nodes_variables'][ivariable] + "_node" + "_isurf" + str(i_surf) + "_im"+ str(i_m) + "_in"+ str(i_n) + ".dat" with open(filename, 'a') as fid: var = getattr(self.data.aero.timestep_info[it], self.settings['aero_nodes_variables'][ivariable]) self.write_nparray_to_file(fid, self.data.ts, var[i_surf][:,i_m,i_n], self.settings['delimiter']) # Velocity field variables at points for ivariable in range(len(self.settings['vel_field_variables'])): if self.settings['vel_field_variables'][ivariable] == 'uext': uext = [np.zeros((3, self.n_vel_field_points, 1))] self.velocity_generator.generate({'zeta': self.vel_field_points, 'for_pos': tstep.for_pos[0:3], 't': self.data.ts*self.caller.settings['dt'], 'is_wake': False, 'override': True}, uext) for ipoint in range(self.n_vel_field_points): filename = self.folder + "vel_field_" + self.settings['vel_field_variables'][ivariable] + "_point" + str(ipoint) + ".dat" with open(filename, 'a') as fid: self.write_nparray_to_file(fid, self.data.ts, uext[0][:,ipoint,0], self.settings['delimiter']) return self.data def write_nparray_to_file(self, fid, ts, nparray, delimiter): fid.write("%d%s" % (ts,delimiter)) for idim in range(nparray.shape[0]): try: for jdim in range(nparray.shape[1] - 1): fid.write("%e%s" % (nparray[idim, jdim],delimiter)) fid.write("%e" % (nparray[idim, -1])) except IndexError: fid.write("%e%s" % (nparray[idim],delimiter)) fid.write("\n") def write_value_to_file(self, fid, ts, value, delimiter): fid.write("%d%s%e\n" % (ts,delimiter,value))