def get_floating_body(fb, simulation_dir): """ This function generate a floating body and make convert the mesh file to dat format if not already in dat format :param simulation_dir the simulation directory (str) :param fb : the raw floating body :return the updated floating body """ mesh_file = os.path.realpath(jp.search(struct.BODY_MESH_FILE, fb)) if not MeshFormat.is_dat_file(mesh_file): meshing_param = { "maxh": jp.search(struct.BODY_MESHING_MAXH, fb), "minh": jp.search(struct.BODY_MESHING_MINH, fb), "fineness": jp.search(struct.BODY_MESHING_FINENESS, fb), "grading": jp.search(struct.BODY_MESHING_GRADING, fb), "usetolerance": jp.search(struct.BODY_MESHING_USE_TOLERANCE, fb), "tolerance": jp.search(struct.BODY_MESHING_TOLERANCE, fb), "infile": mesh_file, "outfile": os.path.splitext(os.path.basename(mesh_file))[0] } meshing_dir = os.path.join(simulation_dir, 'meshing') utility.mkdir_p(meshing_dir) meshing_param = convert_dict_values(meshing_param) services.generate_mesh(meshing_dir, services.MeshingParameters(**meshing_param)) mesh_file = os.path.join(meshing_dir, meshing_param['outfile'] + '-quad.dat') with open(mesh_file, 'r') as f: n_points, n_panels = utility.determine_points_panels(f) body_param = { 'degrees_of_freedom': 6, 'additional_info_lines': 0, 'resulting_generalised_forces': 6, 'surge': update_forces(0, jp.search(struct.BODY_SURGE, fb)), 'sway': update_forces(1, jp.search(struct.BODY_SWAY, fb)), 'heave': update_forces(2, jp.search(struct.BODY_HEAVE, fb)), 'roll_about_cdg': update_forces(3, jp.search(struct.BODY_ROLL, fb)), 'pitch_about_cdg': update_forces(4, jp.search(struct.BODY_PITCH, fb)), 'yaw_about_cdg': update_forces(5, jp.search(struct.BODY_YAW, fb)), 'force_in_x_direction': update_forces(0, jp.search(struct.BODY_FORCE_X, fb)), 'force_in_y_direction': update_forces(1, jp.search(struct.BODY_FORCE_Y, fb)), 'force_in_z_direction': update_forces(2, jp.search(struct.BODY_FORCE_Z, fb)), 'moment_cdg_force_in_x_direction': update_forces(3, jp.search(struct.BODY_MOMENT_X, fb)), 'moment_cdg_force_in_y_direction': update_forces(4, jp.search(struct.BODY_MOMENT_Y, fb)), 'moment_cdg_force_in_z_direction': update_forces(5, jp.search(struct.BODY_MOMENT_Z, fb)), 'mesh_file': mesh_file, 'points': n_points, 'panels': n_panels } body_param = convert_dict_values(body_param) return body_param
def simulate(simulation_dir, params, queue): ''' Run simulation. @param simulation_dir: the simulation directory @param params: the simulation parameters @return: the simulation log content @raise TypeError: if any input parameter is not of required type @raise ValueError: if any input parameter is None/empty, or any field of SimulationParameters is not of valid value @raise ServiceError: if any other error occurred when launching the simulation ''' # The logger object for logging. logger = logging.getLogger(__name__) signature = __name__ + '.simulate()' helper.log_entrance(logger, signature, {'simulation_dir': simulation_dir, 'params': params}) # Checking parameters helper.check_not_none_nor_empty(simulation_dir, 'simulation_dir') helper.check_is_directory(simulation_dir, 'simulation_dir') helper.check_type_value(params, 'params', SimulationParameters, False) helper.check_not_none_nor_empty(params.rho, 'params.rho') helper.check_not_none_nor_empty(params.g, 'params.g') helper.check_not_none_nor_empty(params.depth, 'params.depth') helper.check_not_none_nor_empty(params.xeff, 'params.xeff') helper.check_not_none_nor_empty(params.yeff, 'params.yeff') helper.check_not_none_nor_empty(params.wave_frequencies, 'params.wave_frequencies') helper.check_not_none_nor_empty(params.min_wave_frequencies, 'params.min_wave_frequencies') helper.check_not_none_nor_empty(params.max_wave_frequencies, 'params.max_wave_frequencies') helper.check_not_none_nor_empty(params.wave_directions, 'params.wave_directions') helper.check_not_none_nor_empty(params.min_wave_directions, 'params.min_wave_directions') helper.check_not_none_nor_empty(params.max_wave_direction, 'params.max_wave_direction') helper.check_not_none_nor_empty(params.indiq_solver, 'params.indiq_solver') helper.check_not_none_nor_empty(params.ires, 'params.ires') helper.check_not_none_nor_empty(params.tol_gmres, 'params.tol_gmres') helper.check_not_none_nor_empty(params.max_iterations, 'params.max_iterations') helper.check_not_none_nor_empty(params.save_potential, 'params.save_potential') helper.check_not_none_nor_empty(params.green_tabulation_numx, 'params.green_tabulation_numx') helper.check_not_none_nor_empty(params.green_tabulation_numz, 'params.green_tabulation_numz') helper.check_not_none_nor_empty(params.green_tabulation_simpson_npoints, 'params.green_tabulation_simpson_npoints') helper.check_not_none_nor_empty(params.use_ode_influence_coefficients, 'params.use_ode_influence_coefficients') helper.check_not_none_nor_empty(params.use_higher_order, 'params.use_higher_order') helper.check_not_none_nor_empty(params.num_panel_higher_order, 'params.num_panel_higher_order') helper.check_not_none_nor_empty(params.b_spline_order, 'params.b_spline_order') helper.check_not_none_nor_empty(params.use_dipoles_implementation, 'params.use_dipoles_implementation') helper.check_not_none_nor_empty(params.thin_panels, 'params.thin_panels') helper.check_not_none_nor_empty(params.compute_drift_forces, 'params.compute_drift_forces') helper.check_not_none_nor_empty(params.remove_irregular_frequencies, 'params.remove_irregular_frequencies') helper.check_not_none_nor_empty(params.compute_yaw_moment, 'params.compute_yaw_moment') helper.check_type_value(params.floating_bodies, 'params.floating_bodies', list, True) if params.floating_bodies is not None: for body in params.floating_bodies: helper.check_type_value(body, 'params.floating_bodies item', FloatingBody, False) helper.check_not_none_nor_empty(body.mesh_file, 'body.mesh_file') helper.check_not_none_nor_empty(body.points, 'body.points') helper.check_not_none_nor_empty(body.panels, 'body.panels') helper.check_not_none_nor_empty(body.degrees_of_freedom, 'body.degrees_of_freedom') helper.check_not_none_nor_empty(body.resulting_generalised_forces, 'body.resulting_generalised_forces') helper.check_not_none_nor_empty(body.additional_info_lines, 'body.additional_info_lines') try: # Write the hdf5 inputs according to given parameters # Bug solving in old h5py version: Creating the file first hdf5_path = os.path.join(simulation_dir, 'db.hdf5') utility.touch(hdf5_path) with h5py.File(hdf5_path, "a") as hdf5_data: utility.write_calculations(params, hdf5_data) # Launch preProcessor and Solver # A prepared 'results' folder is necessary for the Nemoh software suite utility.mkdir_p(os.path.join(simulation_dir, 'results')) simulation_log_path = os.path.join(simulation_dir, 'simulation_log.txt') custom_config = { 'HDF5_FILE': hdf5_path, 'NEMOH_CALCULATIONS_FILE': None, 'NEMOH_INPUT_FILE': None, 'MESH_TEC_FILE': os.path.join(simulation_dir, 'mesh', 'mesh.tec'), 'FK_FORCE_TEC_FILE': os.path.join(simulation_dir, 'results', 'fkforce.tec'), 'RADIATION_COEFFICIENTS_TEC_FILE': os.path.join(simulation_dir, 'results', 'radiationcoefficients.tec'), 'DIFFRACTION_FORCE_TEC_FILE': os.path.join(simulation_dir, 'results', 'diffractionforce.tec'), 'EXCITATION_FORCE_TEC_FILE': os.path.join(simulation_dir, 'results', 'excitationforce.tec'), 'IRF_TEC_FILE': os.path.join(simulation_dir, 'results', 'irf.tec'), 'WAVE_FIELD_TEC_FILE': os.path.join(simulation_dir, 'results', 'WaveField.tec'), 'GREEN_TABULATION_NUMX' : int(params.green_tabulation_numx), 'GREEN_TABULATION_NUMZ' : int(params.green_tabulation_numz), 'GREEN_TABULATION_SIMPSON_NPOINTS' : int(params.green_tabulation_simpson_npoints), 'USE_ODE_INFLUENCE_COEFFICIENTS': bool(int(params.use_ode_influence_coefficients)), 'USE_HIGHER_ORDER' : bool(int(params.use_higher_order)), 'NUM_PANEL_HIGHER_ORDER' : int(params.num_panel_higher_order), 'B_SPLINE_ORDER': int(params.b_spline_order), 'USE_DIPOLES_IMPLEMENTATION': bool(int(params.use_dipoles_implementation)), 'THIN_PANELS': [int(i) for i in params.thin_panels.split()], 'COMPUTE_DRIFT_FORCES' : bool(int(params.compute_drift_forces)), 'COMPUTE_YAW_MOMENT': bool(int(params.compute_yaw_moment)), 'REMOVE_IRREGULAR_FREQUENCIES' : bool(int(params.remove_irregular_frequencies)) } logger.debug('Start preProcessor function.') ret = run_thread(preprocessor.run_as_process, (custom_config, queue), simulation_log_path) output = ret["log"] if ret["exitcode"] != 0: logger.error('An error happened when running the preprocessor. The exit code is ' + str(ret["exitcode"])) else: logger.debug('Preprocessor successfully run') logger.debug('End preProcessor function.') logger.debug('Start solver function.') ret = run_thread(solver.run_as_process, (custom_config, queue), simulation_log_path) output += ret["log"] if ret["exitcode"] != 0: logger.error('An error happened when running the solver. The exit code is ' + str(ret["exitcode"])) else: logger.debug('Solver successfully run') logger.debug('End solver function.') helper.log_exit(logger, signature, output) return output except Exception as e: helper.log_exception(logger, signature, e) raise ServiceError('Error occurs when doing simulation. Caused by:\n' + unicode(str(e)))
def run(user_config, queue): """ This method takes a user configuration parse it and fill in all default :param user_config the user configuration dictionary :param queue : the logging listener queue :return the filled in configuration dictionary """ # Get application based default configuration with open(DEFAULT_CONFIGURATION_FILE, 'rt') as f: default_config = json.load(f) # Merge default configuration with user configuration config = merge_config(copy.deepcopy(default_config), copy.deepcopy(user_config)) # Get all simulations all_simulations = jp.search(struct.SIMULATIONS, config) # Get the simulations to run simulations = all_simulations.keys() if jp.search(struct.SIMULATIONS_TO_RUN, config): simulations = jp.search(struct.SIMULATIONS_TO_RUN, config) if struct.DEFAULT in simulations: simulations.remove(struct.DEFAULT) # Get the default simulation parameter default_simulation_parameters = all_simulations[struct.DEFAULT] # Get the phase of the simulations phase = jp.search(struct.PHASE, config) if phase == 'APPLY_CONFIGURATION' or not phase: apply_configuration(config) logger = logging.getLogger(__name__) logger.info('merged configuration ' + json.dumps(config) + '\n') verbosity = jp.search(struct.VERBOSITY, config) if verbosity == 0: return False # Update configuration of each floating body for each simulation for simulation in simulations: # Merge default simulation parameter with this simulation simulation_parameter = merge_config(copy.deepcopy(default_simulation_parameters), copy.deepcopy(all_simulations[simulation])) # Get the floating bodies floating_bodies = jp.search(struct.H5_BODIES, simulation_parameter) # Merge the default floating boadies parameter with this body parameter if struct.DEFAULT in floating_bodies: default_floating_bodies = floating_bodies[struct.DEFAULT] for name, body in floating_bodies.iteritems(): if name == struct.DEFAULT: continue floating_bodies[name] = merge_config(copy.deepcopy(default_floating_bodies), copy.deepcopy(body)) logger.info('Running simulation ' + str(simulation) + ' with parameter ' + json.dumps(simulation_parameter) + '\n') # Now we have the correct parameter to run in simulation_parameter simulation_dir = os.path.realpath(jp.search(struct.SIMULATION_DIR, simulation_parameter)) # Create the simulation directory if not exists utility.mkdir_p(simulation_dir) run_phases(simulation_parameter, simulation_dir, phase, queue) return True
def run(user_config, queue): """ This method takes a user configuration parse it and fill in all default :param user_config the user configuration dictionary :param queue : the logging listener queue :return the filled in configuration dictionary """ # Get application based default configuration with open(DEFAULT_CONFIGURATION_FILE, 'rt') as f: default_config = json.load(f) # Merge default configuration with user configuration config = merge_config(copy.deepcopy(default_config), copy.deepcopy(user_config)) # Get all simulations all_simulations = jp.search(struct.SIMULATIONS, config) # Get the simulations to run simulations = all_simulations.keys() if jp.search(struct.SIMULATIONS_TO_RUN, config): simulations = jp.search(struct.SIMULATIONS_TO_RUN, config) if struct.DEFAULT in simulations: simulations.remove(struct.DEFAULT) # Get the default simulation parameter default_simulation_parameters = all_simulations[struct.DEFAULT] # Get the phase of the simulations phase = jp.search(struct.PHASE, config) if phase == 'APPLY_CONFIGURATION' or not phase: apply_configuration(config) logger = logging.getLogger(__name__) logger.info('merged configuration ' + json.dumps(config) + '\n') verbosity = jp.search(struct.VERBOSITY, config) if verbosity == 0: return False # Update configuration of each floating body for each simulation for simulation in simulations: # Merge default simulation parameter with this simulation simulation_parameter = merge_config( copy.deepcopy(default_simulation_parameters), copy.deepcopy(all_simulations[simulation])) # Get the floating bodies floating_bodies = jp.search(struct.H5_BODIES, simulation_parameter) # Merge the default floating boadies parameter with this body parameter if struct.DEFAULT in floating_bodies: default_floating_bodies = floating_bodies[struct.DEFAULT] for name, body in floating_bodies.iteritems(): if name == struct.DEFAULT: continue floating_bodies[name] = merge_config( copy.deepcopy(default_floating_bodies), copy.deepcopy(body)) logger.info('Running simulation ' + str(simulation) + ' with parameter ' + json.dumps(simulation_parameter) + '\n') # Now we have the correct parameter to run in simulation_parameter simulation_dir = os.path.realpath( jp.search(struct.SIMULATION_DIR, simulation_parameter)) # Create the simulation directory if not exists utility.mkdir_p(simulation_dir) run_phases(simulation_parameter, simulation_dir, phase, queue) return True
def simulate(simulation_dir, params, queue): ''' Run simulation. @param simulation_dir: the simulation directory @param params: the simulation parameters @return: the simulation log content @raise TypeError: if any input parameter is not of required type @raise ValueError: if any input parameter is None/empty, or any field of SimulationParameters is not of valid value @raise ServiceError: if any other error occurred when launching the simulation ''' # The logger object for logging. logger = logging.getLogger(__name__) signature = __name__ + '.simulate()' helper.log_entrance(logger, signature, { 'simulation_dir': simulation_dir, 'params': params }) # Checking parameters helper.check_not_none_nor_empty(simulation_dir, 'simulation_dir') helper.check_is_directory(simulation_dir, 'simulation_dir') helper.check_type_value(params, 'params', SimulationParameters, False) helper.check_not_none_nor_empty(params.rho, 'params.rho') helper.check_not_none_nor_empty(params.g, 'params.g') helper.check_not_none_nor_empty(params.depth, 'params.depth') helper.check_not_none_nor_empty(params.xeff, 'params.xeff') helper.check_not_none_nor_empty(params.yeff, 'params.yeff') helper.check_not_none_nor_empty(params.wave_frequencies, 'params.wave_frequencies') helper.check_not_none_nor_empty(params.min_wave_frequencies, 'params.min_wave_frequencies') helper.check_not_none_nor_empty(params.max_wave_frequencies, 'params.max_wave_frequencies') helper.check_not_none_nor_empty(params.wave_directions, 'params.wave_directions') helper.check_not_none_nor_empty(params.min_wave_directions, 'params.min_wave_directions') helper.check_not_none_nor_empty(params.max_wave_direction, 'params.max_wave_direction') helper.check_not_none_nor_empty(params.indiq_solver, 'params.indiq_solver') helper.check_not_none_nor_empty(params.ires, 'params.ires') helper.check_not_none_nor_empty(params.tol_gmres, 'params.tol_gmres') helper.check_not_none_nor_empty(params.max_iterations, 'params.max_iterations') helper.check_not_none_nor_empty(params.save_potential, 'params.save_potential') helper.check_not_none_nor_empty(params.green_tabulation_numx, 'params.green_tabulation_numx') helper.check_not_none_nor_empty(params.green_tabulation_numz, 'params.green_tabulation_numz') helper.check_not_none_nor_empty(params.green_tabulation_simpson_npoints, 'params.green_tabulation_simpson_npoints') helper.check_not_none_nor_empty(params.use_ode_influence_coefficients, 'params.use_ode_influence_coefficients') helper.check_not_none_nor_empty(params.use_higher_order, 'params.use_higher_order') helper.check_not_none_nor_empty(params.num_panel_higher_order, 'params.num_panel_higher_order') helper.check_not_none_nor_empty(params.b_spline_order, 'params.b_spline_order') helper.check_not_none_nor_empty(params.use_dipoles_implementation, 'params.use_dipoles_implementation') helper.check_not_none_nor_empty(params.thin_panels, 'params.thin_panels') helper.check_not_none_nor_empty(params.compute_drift_forces, 'params.compute_drift_forces') helper.check_not_none_nor_empty(params.remove_irregular_frequencies, 'params.remove_irregular_frequencies') helper.check_not_none_nor_empty(params.compute_yaw_moment, 'params.compute_yaw_moment') helper.check_type_value(params.floating_bodies, 'params.floating_bodies', list, True) if params.floating_bodies is not None: for body in params.floating_bodies: helper.check_type_value(body, 'params.floating_bodies item', FloatingBody, False) helper.check_not_none_nor_empty(body.mesh_file, 'body.mesh_file') helper.check_not_none_nor_empty(body.points, 'body.points') helper.check_not_none_nor_empty(body.panels, 'body.panels') helper.check_not_none_nor_empty(body.degrees_of_freedom, 'body.degrees_of_freedom') helper.check_not_none_nor_empty( body.resulting_generalised_forces, 'body.resulting_generalised_forces') helper.check_not_none_nor_empty(body.additional_info_lines, 'body.additional_info_lines') try: # Write the hdf5 inputs according to given parameters # Bug solving in old h5py version: Creating the file first hdf5_path = os.path.join(simulation_dir, 'db.hdf5') utility.touch(hdf5_path) with h5py.File(hdf5_path, "a") as hdf5_data: utility.write_calculations(params, hdf5_data) # Launch preProcessor and Solver # A prepared 'results' folder is necessary for the Nemoh software suite utility.mkdir_p(os.path.join(simulation_dir, 'results')) simulation_log_path = os.path.join(simulation_dir, 'simulation_log.txt') custom_config = { 'HDF5_FILE': hdf5_path, 'NEMOH_CALCULATIONS_FILE': None, 'NEMOH_INPUT_FILE': None, 'MESH_TEC_FILE': os.path.join(simulation_dir, 'mesh', 'mesh.tec'), 'FK_FORCE_TEC_FILE': os.path.join(simulation_dir, 'results', 'fkforce.tec'), 'RADIATION_COEFFICIENTS_TEC_FILE': os.path.join(simulation_dir, 'results', 'radiationcoefficients.tec'), 'DIFFRACTION_FORCE_TEC_FILE': os.path.join(simulation_dir, 'results', 'diffractionforce.tec'), 'EXCITATION_FORCE_TEC_FILE': os.path.join(simulation_dir, 'results', 'excitationforce.tec'), 'IRF_TEC_FILE': os.path.join(simulation_dir, 'results', 'irf.tec'), 'WAVE_FIELD_TEC_FILE': os.path.join(simulation_dir, 'results', 'WaveField.tec'), 'GREEN_TABULATION_NUMX': int(params.green_tabulation_numx), 'GREEN_TABULATION_NUMZ': int(params.green_tabulation_numz), 'GREEN_TABULATION_SIMPSON_NPOINTS': int(params.green_tabulation_simpson_npoints), 'USE_ODE_INFLUENCE_COEFFICIENTS': bool(int(params.use_ode_influence_coefficients)), 'USE_HIGHER_ORDER': bool(int(params.use_higher_order)), 'NUM_PANEL_HIGHER_ORDER': int(params.num_panel_higher_order), 'B_SPLINE_ORDER': int(params.b_spline_order), 'USE_DIPOLES_IMPLEMENTATION': bool(int(params.use_dipoles_implementation)), 'THIN_PANELS': [int(i) for i in params.thin_panels.split()], 'COMPUTE_DRIFT_FORCES': bool(int(params.compute_drift_forces)), 'COMPUTE_YAW_MOMENT': bool(int(params.compute_yaw_moment)), 'REMOVE_IRREGULAR_FREQUENCIES': bool(int(params.remove_irregular_frequencies)) } logger.debug('Start preProcessor function.') ret = run_thread(preprocessor.run_as_process, (custom_config, queue), simulation_log_path) output = ret["log"] if ret["exitcode"] != 0: logger.error( 'An error happened when running the preprocessor. The exit code is ' + str(ret["exitcode"])) else: logger.debug('Preprocessor successfully run') logger.debug('End preProcessor function.') logger.debug('Start solver function.') ret = run_thread(solver.run_as_process, (custom_config, queue), simulation_log_path) output += ret["log"] if ret["exitcode"] != 0: logger.error( 'An error happened when running the solver. The exit code is ' + str(ret["exitcode"])) else: logger.debug('Solver successfully run') logger.debug('End solver function.') helper.log_exit(logger, signature, output) return output except Exception as e: helper.log_exception(logger, signature, e) raise ServiceError('Error occurs when doing simulation. Caused by:\n' + unicode(str(e)))