Source code for svcco.sv_interface.options

import os
import sys
import platform
import glob

[docs]class file_options: def __init__(self,num_caps,time=[0,1],flow=[1,1],gui=True,distal_resistance=0): """ Set the parameters for vascular construction and simulation for SimVascular python interface. """ self.set_geometry_options() self.set_loft_options() self.set_solid_options(num_caps) self.set_mesh_options() self.set_pipeline_steps(gui=gui) self.set_directories() if len(time) > 2: self.simulation_parameters(fourier_mode=10,period=time[-1],bct_point_number=2*len(time),distal_resistance=distal_resistance) else: self.simulation_parameters(distal_resistance=distal_resistance) self.flow_parameters(time=time,flow=flow) self.rom_parameters()
[docs] def set_geometry_options(self,number_samples=50,use_distance_alignment_method=True): geometry_options = {'number_samples': number_samples, 'use_distance_alignment_method': use_distance_alignment_method} self.geometry_options = geometry_options return
[docs] def set_loft_options(self,u_knot_span_type=None,v_parametric_span_type=None, u_parametric_span_type=None,v_knot_span_type=None, v_degree=None,u_degree=None,boundary_face_angle=45): loft_param = [u_knot_span_type,v_parametric_span_type, u_parametric_span_type,v_knot_span_type, v_degree,u_degree] loft_param = [param is None for param in loft_param] if all(loft_param): loft_options = {'default': True, 'changes': '', 'angle':boundary_face_angle} else: loft_options = {'default': False, 'changes': '', 'angle':boundary_face_angle} # Check Knot Span Values if u_knot_span_type is not None: if u_knot_span_type not in ['derivative','equal','average']: print('Invalid knot span type\n\nMust be one of:\n "derivative"\n "equal"\n "average"\n') print('Will default to "derivative" type.') else: loft_options['changes'] += 'options.u_knot_span_type = {}\n'.format(u_knot_span_type) if v_knot_span_type is not None: if v_knot_span_type not in ['derivative','equal','average']: print('Invalid knot span type\n\nMust be one of:\n "derivative"\n "equal"\n "average"\n') print('Will default to "average" type.') else: loft_options['changes'] += 'options.v_knot_span_type = {}\n'.format(v_knot_span_type) # Check Parametric Span Values if v_parametric_span_type is not None: if v_parametric_span_type not in ['centripetal','equal','chord']: print('Invalid knot span type\n\nMust be one of:\n "centripetal"\n "equal"\n "chord"\n') print('Will default to "chord" type.') else: loft_options['changes'] += 'options.v_parametric_span_type = {}\n'.format(v_parametric_span_type) if u_parametric_span_type is not None: if u_parametric_span_type not in ['centripetal','equal','chord']: print('Invalid knot span type\n\nMust be one of:\n "centripetal"\n "equal"\n "chord"\n') print('Will default to "centripetal" type.') else: loft_options['changes'] += 'options.u_parametric_span_type = {}\n'.format(u_parametric_span_type) if v_degree is not None: if not isinstance(v_degree,int): print('v_degree must be an integer') print('Will default to v_degree = 2') else: loft_options['changes'] += 'options.v_degree = {}\n'.format(v_degree) if u_degree is not None: if not isinstance(u_degree,int): print('v_degree must be an integer') print('Will default to u_degree = 2') else: loft_options['changes'] += 'options.u_degree = {}\n'.format(u_degree) self.loft_options = loft_options return
[docs] def set_solid_options(self,num_caps,minimum_face_cells=200,hmin=0.02,hmax=0.02, face_edge_size=0.02,boundary_face_angle=45): #Check input types if not isinstance(minimum_face_cells,int): print('minimum_face_cells must be a positive int > 0') print('Using default value') minimum_face_cells=200 if not isinstance(hmin,float): print('hmin must be a float < 1') print('Using default value') hmin=0.02 if not isinstance(hmax,float): print('hmax must be a float hmin =< hmax < 1') print('Using default value') hmax=0.02 if not isinstance(face_edge_size,float): print('face_edge_size must be a float < 1') print('Using default value') face_edge_size=0.02 if boundary_face_angle > 90 or boundary_face_angle < 0: print('boundary_face_angle must be greater than 0 and less than 90') print('Using default value') boundary_face_angle = 45 solid_options = {'minimum_face_cells': minimum_face_cells, 'hmin': hmin, 'hmax': hmax, 'face_edge_size': face_edge_size, 'angle': boundary_face_angle, 'num_caps': num_caps} self.solid_options = solid_options return
[docs] def set_mesh_options(self,global_edge_size=0.01,surface_mesh_flag=True, volume_mesh_flag=True,no_merge=False,optimization_level=5, minimum_dihedral_angle=18.0): if not isinstance(global_edge_size,float): print('global_edge_size must be a float less than 1') print('Using default: global_edge_size = 0.01') global_edge_size=0.01 if not isinstance(surface_mesh_flag,bool): print('surface_mesh_flag must be boolean logic') print('Using default: surface_mesh_flag = True') surface_mesh_flag = True if not isinstance(volume_mesh_flag,bool): print('volume_mesh_flag must be boolean logic') print('Using default: volume_mesh_flag = True') volume_mesh_flag = True if not isinstance(no_merge,bool): print('no_merge must be boolean logic') print('Using default: no_merge = False') no_merge = False if not isinstance(optimization_level,int): print('optimization_level must be an integer between 0 and 7, inclusive') print('Using default: optimization_level = 5') optimization_level = 5 elif optimization_level > 7 or optimization_level < 0: print('optimization_level must be an integer between 0 and 7, inclusive') print('Using default: optimization_level = 5') optimization_level = 5 if not isinstance(minimum_dihedral_angle,float): print('minimum_dihedral_angle must be a float') print('Using default: minimum_dihedral_angle = 18') minimum_dihedral_angle = 18 mesh_options = {'global_edge_size': global_edge_size, 'surface_mesh_flag': surface_mesh_flag, 'volume_mesh_flag': volume_mesh_flag, 'no_merge': no_merge, 'optimization_level': optimization_level, 'minimum_dihedral_angle':minimum_dihedral_angle} self.mesh_options = mesh_options return
[docs] def set_pipeline_steps(self,files='all',gui=False): file_types = ['path','contour','solid', 'mesh','simulation','rom'] # Check parameter values if not isinstance(files,str): print('{files} parameter must be a str') return if not isinstance(gui,bool): print('{gui} parameter must be True or False') return # Assign Model Constructor Values file_constructor = {'path': True, 'contour': True, 'solid': True, 'mesh': True, 'simulation': True, 'rom': True, 'gui': gui} if files == 'all': pass else: if files in file_types: file_index = file_types.index(files) for i,f in enumerate(file_types): if i <= file_index: pass else: file_constructor[f] = False self.file_constructor = file_constructor return
[docs] def set_directories(self,outdir=None): if isinstance(outdir,type(None)): outdir = os.getcwd() if isinstance(outdir,str): if not os.path.isdir(outdir): print('{} either does not exist or is not accessible'.format(outdir)) return else: pass else: print('{outdir} should be a str argument if provided') return # Assigning Directory Constructor Values directory_constructor = {'main_folder': None, 'create_main_folder': False, 'data_folder': None, 'mesh_complete_folder': None, 'mesh_surfaces_folder': None, 'postprocessing_folder':None} if not os.path.isdir(outdir+'/CCO_DATA'): directory_constructor['create_main_folder'] = True else: directory_constructor['create_main_folder'] = False directory_constructor['main_folder'] = outdir+os.sep+'CCO_DATA' number = len(glob.glob(directory_constructor['main_folder']+os.sep+'CCO_*')) directory_constructor['data_folder'] = directory_constructor['main_folder']+os.sep+'simulation_data{}'.format(number) directory_constructor['mesh_complete_folder'] = directory_constructor['data_folder']+os.sep+'mesh-complete' directory_constructor['mesh_surfaces_folder'] = directory_constructor['mesh_complete_folder']+os.sep+'mesh-surfaces' directory_constructor['centerline_folder'] = directory_constructor['data_folder']+os.sep+'centerlines' directory_constructor['postprocessing_folder'] = directory_constructor['data_folder']+os.sep+'post' directory_constructor['rom_folder'] = directory_constructor['data_folder']+os.sep+'rom' directory_constructor['rom_0D_folder'] = directory_constructor['rom_folder']+os.sep+'zeroD' directory_constructor['rom_1D_folder'] = directory_constructor['rom_folder']+os.sep+'oneD' directory_constructor['main_folder'] = directory_constructor['main_folder'].replace('\\','\\\\') directory_constructor['data_folder'] = directory_constructor['data_folder'].replace('\\','\\\\') directory_constructor['mesh_complete_folder'] = directory_constructor['mesh_complete_folder'].replace('\\','\\\\') directory_constructor['mesh_surfaces_folder'] = directory_constructor['mesh_surfaces_folder'].replace('\\','\\\\') directory_constructor['centerline_folder'] = directory_constructor['centerline_folder'].replace('\\','\\\\') directory_constructor['postprocessing_folder'] = directory_constructor['postprocessing_folder'].replace('\\','\\\\') directory_constructor['rom_folder'] = directory_constructor['rom_folder'].replace('\\','\\\\') directory_constructor['rom_0D_folder'] = directory_constructor['rom_0D_folder'].replace('\\','\\\\') directory_constructor['rom_1D_folder'] = directory_constructor['rom_1D_folder'].replace('\\','\\\\') self.directory_constructor = directory_constructor self.number = number self.filename = directory_constructor['main_folder']+os.sep+'CCO_{}.py'.format(number) self.filename = self.filename.replace('\\','\\\\') self.name = 'CCO_{}'.format(number) return
[docs] def simulation_parameters(self,svpre_name='cco',fluid_density=1.06, fluid_viscosity=0.04, initial_pressure=0, initial_velocity=[0.0001,0.0001,0.0001], bct_analytical_shape='parabolic', inflow_file='inflow', period=1,bct_point_number=2, fourier_mode=1,pressures=0, svsolver='solver',number_timesteps=200, timestep_size=0.02,number_restarts=50, number_force_surfaces=1, surface_id_force_calc=1, force_calc_method='Velocity Based', print_avg_solution=True, print_error_indicators=False, varying_time_from_file=True, step_construction='0 1 0 1', pressure_coupling='Implicit', backflow_stabilization=0.2, residual_control=True, residual_criteria=0.01, minimum_req_iter=2, svLS_type='NS',num_krylov=100, num_solves_per_left=1, tolerance_momentum=0.05, tolerance_continuity=0.4, tolerance_svLS_NS=0.4, max_iter_NS=2,max_iter_momentum=4, max_iter_continuity=400, time_integration_rule='Second Order', time_integration_rho=0.5, flow_advection_form='Convective', quadrature_interior=2, quadrature_boundary=3,procs=24, svpost='cco',start=0,vtu=True, vtp=False,vtkcombo=False, all_arg=True,wss=False, sim_units_mm=False, sim_units_cm=True, global_edge_size=0.01, distal_resistance=0): # Assign PreSolver Constructor Values presolver_constructor = {'name': svpre_name, 'fluid_density': fluid_density, 'fluid_viscosity': fluid_viscosity, 'initial_pressure': initial_pressure, 'initial_velocity': initial_velocity, 'bct_analytical_shape': bct_analytical_shape, 'inflow_file': inflow_file+'_3d.flow', 'period': period, 'bct_point_number': bct_point_number, 'fourier_mode': fourier_mode, 'pressures': pressures} # Assign Solver Constructor Values solver_constructor = {'name': svsolver, 'fluid_density': fluid_density, 'fluid_viscosity': fluid_viscosity, 'number_timesteps': number_timesteps, 'timestep_size': timestep_size, 'number_restarts': number_restarts, 'number_force_surfaces': number_force_surfaces, 'surface_id_force_calc': surface_id_force_calc, 'force_calc_method': force_calc_method, 'print_avg_solution': print_avg_solution, 'print_error_indicators':print_error_indicators, 'varying_time_from_file':varying_time_from_file, 'step_construction': step_construction, 'pressure_coupling': pressure_coupling, 'backflow_stabilization':backflow_stabilization, 'residual_control': residual_control, 'residual_criteria': residual_criteria, 'minimum_req_iter': minimum_req_iter, 'svLS_type': svLS_type, 'num_krylov': num_krylov, 'num_solves_per_left': num_solves_per_left, 'tolerance_momentum': tolerance_momentum, 'tolerance_continuity': tolerance_continuity, 'tolerance_svLS_NS': tolerance_svLS_NS, 'max_iter_NS': max_iter_NS, 'max_iter_momentum': max_iter_momentum, 'max_iter_continuity': max_iter_continuity, 'time_integration_rule': time_integration_rule, 'time_integration_rho': time_integration_rho, 'flow_advection_form': flow_advection_form, 'quadrature_interior': quadrature_interior, 'quadrature_boundary': quadrature_boundary, 'global_edge_size': global_edge_size, 'distal_resistance': distal_resistance} indir = self.directory_constructor['data_folder']+'/{}-procs_case'.format(procs) outdir = self.directory_constructor['postprocessing_folder'] if sim_units_mm and sim_units_cm: print('Must pick one unit scale. Not both.') print('Exiting without assigning postprocessing parameters.') return postsolver_constructor = {'name': svpost, 'start': start, 'stop': number_timesteps, 'incr': number_restarts, 'vtu': vtu, 'vtp': vtp, 'vtkcombo': vtkcombo, 'all': all_arg, 'wss': wss, 'indir': indir, 'sim_units_mm': sim_units_mm, 'sim_units_cm': sim_units_cm, 'outdir': outdir} self.presolver_constructor = presolver_constructor self.solver_constructor = solver_constructor self.postsolver_constructor = postsolver_constructor return
[docs] def flow_parameters(self,inflow_file='inflow',time=[0,1],flow=[1,1]): flow_constructor = {'inflow_file': inflow_file, 'time': time, 'flow': flow} self.flow_constructor = flow_constructor
[docs] def rom_parameters(self,inflow='inflow_rom.flow',zeroD=True,oneD=True,time_step=0.001, number_time_steps=1000): rom0D_constructor = {'create': zeroD, 'model_order': 0, 'time_step': time_step, 'number_time_steps': number_time_steps, 'inflow_file': inflow} rom1D_constructor = {'create': oneD, 'model_order': 1, 'time_step': time_step, 'number_time_steps': number_time_steps, 'inflow_file': inflow} self.rom_constructor = {'0D': rom0D_constructor, '1D': rom1D_constructor} return