sensotwin.lifetime_extrapolation.simulation.remainingLifeTimePrediction
1import os 2import shutil 3import time 4import subprocess 5from datetime import datetime 6 7from .lib import staticAnalysisAerodynamicsCentrifugalCCX 8from .lib import staticAnalysisGravityCCX 9from .lib import convertFRDtoVTK 10from .lib import createElementStackingTable 11from .lib import extractStresses 12from .lib import fatigueAnalysisCCX 13 14CCX_TEMPLATE_NAME = "CCX_TEMPLATE" 15 16def f_calculateRemainingLifeTime(wind_speed=None, simulation_time=None, working_dir = './', num_cpus=1, ccx_input_files=None): 17 ''' 18 Top level script to set up the simulations, run them and 19 create the results in form of a .vtu file. 20 21 Parameters: 22 - wind_speed (float): 23 Average wind speed acting on the entire rotor disc in m/s. 24 - simulation_time (float): 25 Total time the rotor blade is exposed to wind_speed in years. 26 - num_cpus (int): 27 Number of CPUs to run the CCX solver on. Defaults to 1. 28 - working_dir (string): 29 Working directory to execute file in. 30 31 Returns: 32 - None 33 ''' 34 35 # change number of processors to run CCX with 36 os.environ['OMP_NUM_THREADS'] = str(num_cpus) 37 38 current_dir = working_dir 39 40 shutil.copytree(os.path.dirname(os.path.realpath(__file__)) + "/IN", current_dir + "/IN") 41 42 # create folder structure 43 # |- IN 44 # |- OUT 45 # | 46 # |- lib 47 # |- 02_convertFRDtoVTK_PyModule.py 48 # |- 03_createElementStackingTable.py 49 # |- 04_extractStresses.py 50 # |- readVTT.py 51 # | 52 # |- main 53 # |- Static 54 # |- IN 55 # |- OUT 56 # |- Fatigue 57 # |- IN 58 # |- OUT 59 60 root_directories = ['IN','OUT','main'] 61 main_directories = ['Static','Fatigue'] 62 analysis_directories = ['IN','OUT'] 63 64 for directory in root_directories: 65 if not os.path.exists(os.path.join(current_dir,directory)): 66 os.mkdir(os.path.join(current_dir,directory)) 67 68 for directory in main_directories: 69 if not os.path.exists(os.path.join(current_dir,'main',directory)): 70 os.mkdir(os.path.join(current_dir,'main',directory)) 71 72 for analysis_directory in main_directories: 73 for directory in analysis_directories: 74 if not os.path.exists(os.path.join(current_dir,'main',analysis_directory,directory)): 75 os.mkdir(os.path.join(current_dir,'main',analysis_directory,directory)) 76 77 # copy necessary files to folder structure 78 shutil.copy(os.path.join(current_dir,'IN','aero_loads_N_transformed.vtt'), 79 os.path.join(current_dir,'main','Static','IN','aero_loads_N_transformed.vtt')) 80 shutil.copy(os.path.join(current_dir,'IN','gravity_loads_transformed.vtt'), 81 os.path.join(current_dir,'main','Static','IN','gravity_loads_transformed.vtt')) 82 shutil.copy(os.path.join(current_dir,'IN','coords_N_web_1.vtt'), 83 os.path.join(current_dir,'main','Static','IN','coords_N_web_1.vtt')) 84 shutil.copy(os.path.join(current_dir,'IN','coords_N_web_2.vtt'), 85 os.path.join(current_dir,'main','Static','IN','coords_N_web_2.vtt')) 86 shutil.copy(os.path.join(current_dir,'IN','composite_layup_db.vtt'), 87 os.path.join(current_dir,'main','Static','IN','composite_layup_db.vtt')) 88 shutil.copy(os.path.join(current_dir,'IN','material_fatigue_data.vtt'), 89 os.path.join(current_dir,'main','Fatigue','IN','material_fatigue_data.vtt')) 90 shutil.copy(os.path.join(current_dir,'IN','rpm_windspeed_0p01.vtt'), 91 os.path.join(current_dir,'main','Fatigue','IN','rpm_windspeed_0p01.vtt')) 92 for ccx_input_file in ccx_input_files: 93 if ".inp" in ccx_input_file: 94 shutil.copy(os.path.join(ccx_input_file), 95 os.path.join(current_dir,'main','Static','IN','{}.inp'.format(CCX_TEMPLATE_NAME))) 96 else: 97 shutil.copy(os.path.join(ccx_input_file), 98 os.path.join(current_dir,'main','Static','IN',ccx_input_file)) 99 # set up static analysis 100 static_dir = os.path.join(current_dir,'main','Static') 101 102 103 staticAnalysisAerodynamicsCentrifugalCCX.f_setupStaticAerodynamicsCentrifugalSimulations(CCX_TEMPLATE_NAME, wind_speed, working_dir=static_dir) 104 staticAnalysisGravityCCX.f_setupStaticGravitySimulations(CCX_TEMPLATE_NAME, wind_speed, working_dir=static_dir) 105 106 # run static simulations 107 all_files = os.listdir(os.path.join(static_dir,'OUT')) 108 all_dirs = [x for x in all_files if os.path.isdir(os.path.join(static_dir,'OUT',x))] 109 110 all_dirs.sort() 111 112 for i,direc in enumerate(all_dirs): 113 current_working_dir = os.path.join(static_dir,'OUT',direc) 114 115 all_current_files = os.listdir(current_working_dir) 116 all_current_inp_files = [x for x in all_current_files if x.endswith('.inp')] 117 for file in all_current_inp_files: 118 subprocess.run(["ccx", current_working_dir + "/" + file.strip('.inp')], capture_output=True) 119 120 121 convertFRDtoVTK.f_convertFRD2VTU(current_working_dir) 122 if i == 0: 123 124 createElementStackingTable.f_createElementStackingTable(current_working_dir) 125 else: 126 shutil.copy(os.path.join(static_dir,'OUT',all_dirs[0],'element_layer_assignment.out.txt'), 127 os.path.join(current_working_dir,'element_layer_assignment.out.txt')) 128 129 extractStresses.f_extractStresses(current_working_dir) 130 131 # run fatigue calculation 132 fatigue_dir = os.path.join(current_dir,'main','Fatigue') 133 134 135 136 fatigueAnalysisCCX.f_calculateDamageAndFatigueLife(wind_speed,simulation_time,fatigue_dir) 137 138 139 # copy final result file to ./OUT 140 fatigue_output_dir = os.path.join(current_dir,'main','Fatigue','OUT') 141 all_files = os.listdir(fatigue_output_dir) 142 all_result_files = [x for x in all_files if x.endswith('.vtu')] 143 result_paths = [] 144 for result_file in all_result_files: 145 shutil.copy(os.path.join(fatigue_output_dir,result_file),os.path.join(current_dir,'OUT',result_file)) 146 result_paths.append(os.path.join(current_dir,'OUT',result_file)) 147 148 return result_paths
CCX_TEMPLATE_NAME =
'CCX_TEMPLATE'
def
f_calculateRemainingLifeTime( wind_speed=None, simulation_time=None, working_dir='./', num_cpus=1, ccx_input_files=None):
17def f_calculateRemainingLifeTime(wind_speed=None, simulation_time=None, working_dir = './', num_cpus=1, ccx_input_files=None): 18 ''' 19 Top level script to set up the simulations, run them and 20 create the results in form of a .vtu file. 21 22 Parameters: 23 - wind_speed (float): 24 Average wind speed acting on the entire rotor disc in m/s. 25 - simulation_time (float): 26 Total time the rotor blade is exposed to wind_speed in years. 27 - num_cpus (int): 28 Number of CPUs to run the CCX solver on. Defaults to 1. 29 - working_dir (string): 30 Working directory to execute file in. 31 32 Returns: 33 - None 34 ''' 35 36 # change number of processors to run CCX with 37 os.environ['OMP_NUM_THREADS'] = str(num_cpus) 38 39 current_dir = working_dir 40 41 shutil.copytree(os.path.dirname(os.path.realpath(__file__)) + "/IN", current_dir + "/IN") 42 43 # create folder structure 44 # |- IN 45 # |- OUT 46 # | 47 # |- lib 48 # |- 02_convertFRDtoVTK_PyModule.py 49 # |- 03_createElementStackingTable.py 50 # |- 04_extractStresses.py 51 # |- readVTT.py 52 # | 53 # |- main 54 # |- Static 55 # |- IN 56 # |- OUT 57 # |- Fatigue 58 # |- IN 59 # |- OUT 60 61 root_directories = ['IN','OUT','main'] 62 main_directories = ['Static','Fatigue'] 63 analysis_directories = ['IN','OUT'] 64 65 for directory in root_directories: 66 if not os.path.exists(os.path.join(current_dir,directory)): 67 os.mkdir(os.path.join(current_dir,directory)) 68 69 for directory in main_directories: 70 if not os.path.exists(os.path.join(current_dir,'main',directory)): 71 os.mkdir(os.path.join(current_dir,'main',directory)) 72 73 for analysis_directory in main_directories: 74 for directory in analysis_directories: 75 if not os.path.exists(os.path.join(current_dir,'main',analysis_directory,directory)): 76 os.mkdir(os.path.join(current_dir,'main',analysis_directory,directory)) 77 78 # copy necessary files to folder structure 79 shutil.copy(os.path.join(current_dir,'IN','aero_loads_N_transformed.vtt'), 80 os.path.join(current_dir,'main','Static','IN','aero_loads_N_transformed.vtt')) 81 shutil.copy(os.path.join(current_dir,'IN','gravity_loads_transformed.vtt'), 82 os.path.join(current_dir,'main','Static','IN','gravity_loads_transformed.vtt')) 83 shutil.copy(os.path.join(current_dir,'IN','coords_N_web_1.vtt'), 84 os.path.join(current_dir,'main','Static','IN','coords_N_web_1.vtt')) 85 shutil.copy(os.path.join(current_dir,'IN','coords_N_web_2.vtt'), 86 os.path.join(current_dir,'main','Static','IN','coords_N_web_2.vtt')) 87 shutil.copy(os.path.join(current_dir,'IN','composite_layup_db.vtt'), 88 os.path.join(current_dir,'main','Static','IN','composite_layup_db.vtt')) 89 shutil.copy(os.path.join(current_dir,'IN','material_fatigue_data.vtt'), 90 os.path.join(current_dir,'main','Fatigue','IN','material_fatigue_data.vtt')) 91 shutil.copy(os.path.join(current_dir,'IN','rpm_windspeed_0p01.vtt'), 92 os.path.join(current_dir,'main','Fatigue','IN','rpm_windspeed_0p01.vtt')) 93 for ccx_input_file in ccx_input_files: 94 if ".inp" in ccx_input_file: 95 shutil.copy(os.path.join(ccx_input_file), 96 os.path.join(current_dir,'main','Static','IN','{}.inp'.format(CCX_TEMPLATE_NAME))) 97 else: 98 shutil.copy(os.path.join(ccx_input_file), 99 os.path.join(current_dir,'main','Static','IN',ccx_input_file)) 100 # set up static analysis 101 static_dir = os.path.join(current_dir,'main','Static') 102 103 104 staticAnalysisAerodynamicsCentrifugalCCX.f_setupStaticAerodynamicsCentrifugalSimulations(CCX_TEMPLATE_NAME, wind_speed, working_dir=static_dir) 105 staticAnalysisGravityCCX.f_setupStaticGravitySimulations(CCX_TEMPLATE_NAME, wind_speed, working_dir=static_dir) 106 107 # run static simulations 108 all_files = os.listdir(os.path.join(static_dir,'OUT')) 109 all_dirs = [x for x in all_files if os.path.isdir(os.path.join(static_dir,'OUT',x))] 110 111 all_dirs.sort() 112 113 for i,direc in enumerate(all_dirs): 114 current_working_dir = os.path.join(static_dir,'OUT',direc) 115 116 all_current_files = os.listdir(current_working_dir) 117 all_current_inp_files = [x for x in all_current_files if x.endswith('.inp')] 118 for file in all_current_inp_files: 119 subprocess.run(["ccx", current_working_dir + "/" + file.strip('.inp')], capture_output=True) 120 121 122 convertFRDtoVTK.f_convertFRD2VTU(current_working_dir) 123 if i == 0: 124 125 createElementStackingTable.f_createElementStackingTable(current_working_dir) 126 else: 127 shutil.copy(os.path.join(static_dir,'OUT',all_dirs[0],'element_layer_assignment.out.txt'), 128 os.path.join(current_working_dir,'element_layer_assignment.out.txt')) 129 130 extractStresses.f_extractStresses(current_working_dir) 131 132 # run fatigue calculation 133 fatigue_dir = os.path.join(current_dir,'main','Fatigue') 134 135 136 137 fatigueAnalysisCCX.f_calculateDamageAndFatigueLife(wind_speed,simulation_time,fatigue_dir) 138 139 140 # copy final result file to ./OUT 141 fatigue_output_dir = os.path.join(current_dir,'main','Fatigue','OUT') 142 all_files = os.listdir(fatigue_output_dir) 143 all_result_files = [x for x in all_files if x.endswith('.vtu')] 144 result_paths = [] 145 for result_file in all_result_files: 146 shutil.copy(os.path.join(fatigue_output_dir,result_file),os.path.join(current_dir,'OUT',result_file)) 147 result_paths.append(os.path.join(current_dir,'OUT',result_file)) 148 149 return result_paths
Top level script to set up the simulations, run them and create the results in form of a .vtu file.
Parameters:
- wind_speed (float): Average wind speed acting on the entire rotor disc in m/s.
- simulation_time (float): Total time the rotor blade is exposed to wind_speed in years.
- num_cpus (int): Number of CPUs to run the CCX solver on. Defaults to 1.
- working_dir (string): Working directory to execute file in.
Returns:
- None