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