Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • toolbox/WindEnergyToolbox
  • tlbl/WindEnergyToolbox
  • cpav/WindEnergyToolbox
  • frza/WindEnergyToolbox
  • borg/WindEnergyToolbox
  • mmpe/WindEnergyToolbox
  • ozgo/WindEnergyToolbox
  • dave/WindEnergyToolbox
  • mmir/WindEnergyToolbox
  • wluo/WindEnergyToolbox
  • welad/WindEnergyToolbox
  • chpav/WindEnergyToolbox
  • rink/WindEnergyToolbox
  • shfe/WindEnergyToolbox
  • shfe1/WindEnergyToolbox
  • acdi/WindEnergyToolbox
  • angl/WindEnergyToolbox
  • wliang/WindEnergyToolbox
  • mimc/WindEnergyToolbox
  • wtlib/WindEnergyToolbox
  • cmos/WindEnergyToolbox
  • fabpi/WindEnergyToolbox
22 results
Show changes
......@@ -464,6 +464,34 @@ tags:
* ```[high_freq_comp]```
### Tags required for hydro file generation
* ```[hydro_dir]```
* ```[hydro input name]```
* ```[wave_type]``` : see HAWC2 manual for options
* ```[wave_spectrum]``` : see HAWC2 manual for options
* ```[hydro_dir]```
* ```[wdepth]```
* ```[hs]``` : see HAWC2 manual for options
* ```[tp]``` : see HAWC2 manual for options
* ```[wave_seed]``` : see HAWC2 manual for options
And the corresponding section the htc master file:
```
begin hydro;
begin water_properties;
rho 1027 ; kg/m^3
gravity 9.81 ; m/s^2
mwl 0.0;
mudlevel [wdepth];
wave_direction [wave_dir];
water_kinematics_dll ./wkin_dll.dll ./[hydro_dir][hydro input name].inp;
end water_properties;
end hydro;
```
Launching the jobs on the cluster
---------------------------------
......
# -*- coding: utf-8 -*-
"""
Created on Fri Apr 15 18:34:15 2016
@author: shfe
Description: This script is used for writing the hydro input files for HAWC2
(the wave type det_airy is not included)
"""
import os
class hydro_input(object):
""" Basic class aiming for write the hydrodynamics input file"""
def __init__(self, wavetype, wdepth, spectrum, Hs, Tp, seed,
gamma = 3.3, stretching = 1, wn = None, coef = 200,
spreading = None):
self.wdepth = wdepth
if self.wdepth < 0:
raise ValueError('water depth must be greater than 0')
# Regular Airy Wave Input
if wavetype == 'reg_airy':
self.waveno = 0
self.argument = 'begin %s ;\n\t\tstretching %d;\n\t\twave %d %d;\n\tend;' \
%(wavetype,stretching,Hs,Tp)
# Iregular Airy Wave Input
if wavetype == 'ireg_airy':
self.waveno = 1
# jonswap spectrum
if spectrum == 'jonswap':
spectrumno = 1
self.argument = 'begin %s ;\n\t\tstretching %d;\n\t\tspectrum %d;'\
'\n\t\tjonswap %.1f %.1f %.1f;\n\t\tcoef %d %d;' \
%(wavetype,stretching,spectrumno,Hs,Tp,gamma,coef,seed)
# Pierson Moscowitz spectrum
elif spectrum == 'pm':
spectrumno = 2
self.argument = 'begin %s ;\n\t\tstretching %d;\n\t\tspectrum %d;'\
'\n\t\tpm %.1f %.1f ;\n\t\tcoef %d %d;' \
%(wavetype,stretching,spectrumno,Hs,
Tp,coef,seed)
# check the spreading function
if spreading is not None:
self.argument += '\n\t\tspreading 1 %d;'%(spreading)
self.argument += '\n\tend;';
# Stream Wave Input
if wavetype == 'strf':
self.waveno = 3
self.argument = 'begin %s ;\n\t\twave %d %d;\n\tend;' \
%(wavetype,Hs,Tp)
def execute(self, filename, folder):
cwd = os.getcwd()
folder_path = os.path.join(cwd,folder)
file_path = os.path.join(folder_path,filename)
# check if the hydro input file exists
if os.path.exists(file_path):
pass
else:
FILE = open(file_path,'w+')
line1 = 'begin wkin_input ;'
line2 = 'wavetype %d ;' %self.waveno
line3 = 'wdepth %d ;' %self.wdepth
line4 = 'end ;'
file_contents = '%s\n\t%s\n\t%s\n\t%s\n%s\n;\nexit;' \
%(line1,line2,line3,self.argument,line4)
FILE.write(file_contents)
FILE.close()
if __name__ == '__main__':
hs = 3
Tp = 11
hydro = hydro_input(Hs = hs, Tp = Tp, wdepth = 33,spectrum='jonswap',spreading = 2)
hydro.execute(filename='sss')
......@@ -54,7 +54,7 @@ from wetb.prepost import misc
from wetb.prepost import windIO
from wetb.prepost import prepost
from wetb.dlc import high_level as dlc
from wetb.prepost.GenerateHydro import hydro_input
def load_pickled_file(source):
FILE = open(source, 'rb')
......@@ -738,6 +738,25 @@ def prepare_launch(iter_dict, opt_tags, master, variable_tag_func,
if verbose:
print('created cases for: %s.htc\n' % master.tags['[case_id]'])
# shfe: flag to generate hydro input file
if master.tags['[hydro_dir]'] is not False:
if '[hydro input name]' not in master.tags:
continue
hydro_filename = master.tags['[hydro input name]']
print('creating hydro input file for: %s.inp\n' % hydro_filename)
wavetype = master.tags['[wave_type]']
wavespectrum = master.tags['[wave_spectrum]']
hydro_folder = master.tags['[hydro_dir]']
wdepth = float(master.tags['[wdepth]'])
hs = float(master.tags['[hs]'])
tp = float(master.tags['[tp]'])
wave_seed = int(float(master.tags['[wave_seed]']))
hydro_inputfile = hydro_input(wavetype=wavetype, Hs=hs, Tp=tp,
wdepth = wdepth, seed=wave_seed,
spectrum=wavespectrum,
spreading=None)
hydro_inputfile.execute(filename=hydro_filename + '.inp',
folder=hydro_folder)
# print(master.queue.get())
# only copy data and create zip after all htc files have been created.
......@@ -1537,15 +1556,16 @@ class HtcMaster(object):
extforce = self.tags['[externalforce]']
# result dirs are not required, HAWC2 will create them
dirs = [control_dir, data_dir, extforce, turb_dir, wake_dir,
meander_dir, mooring_dir, hydro_dir]
meander_dir, mooring_dir, hydro_dir]
for zipdir in dirs:
if zipdir:
zf.write('.', zipdir + '.', zipfile.ZIP_DEFLATED)
zf.write('.', os.path.join(zipdir, '.'), zipfile.ZIP_DEFLATED)
zf.write('.', 'htc/_master/.', zipfile.ZIP_DEFLATED)
# if any, add files that should be added to the root of the zip file
for file_name in self.tags['[zip_root_files]']:
zf.write(model_dir_local+file_name, file_name, zipfile.ZIP_DEFLATED)
src = os.path.join(model_dir_local, file_name)
zf.write(src, file_name, zipfile.ZIP_DEFLATED)
if '[ESYSMooring_init_fname]' in self.tags:
if self.tags['[ESYSMooring_init_fname]'] is not None:
......@@ -4714,6 +4734,16 @@ class Cases(object):
case_ids = [os.path.basename(k[0].replace('.sel', '')) for k in fh_lst]
hours = [k[1] for k in fh_lst]
# safe how many hours each case is active for AEP calculations for
# debugging and inspection reasons.
# FIXME: this should be somewhere in its own method or something,
# and duplication with what is in AEP should be removed
fname = os.path.join(post_dir, sim_id + '_Leq_hourlist')
dict_Leq_h = {'case_id':case_ids, 'hours':hours}
df_Leq_h = misc.dict2df(dict_Leq_h, fname, update=update, csv=csv,
save=save, check_datatypes=True, xlsx=xlsx,
complib=self.complib)
# ---------------------------------------------------------------------
# column definitions
# ---------------------------------------------------------------------
......@@ -4791,9 +4821,9 @@ class Cases(object):
# only keep the ones that do not have nan's (only works with index)
return df_Leq
def AEP(self, dfs, fh_lst=None, ch_powe=None, extra_cols=[], update=False,
def AEP(self, dfs, fh_lst=None, ch_powe='DLL-2-inpvec-2', extra_cols=[],
res_dir='res/', dlc_folder="dlc%s_iec61400-1ed3/", csv=False,
new_sim_id=False, save=False, years=20.0, xlsx=False):
new_sim_id=False, save=False, years=20.0, update=False, xlsx=False):
"""
Calculate the Annual Energy Production (AEP) for DLC1.2 cases.
......@@ -4813,7 +4843,7 @@ class Cases(object):
is the number of hours over the life time. When fh_lst is set,
dlc_folder and dlc_name are not used.
ch_powe : string, default=None
ch_powe : string, default='DLL-2-inpvec-2'
extra_cols : list, default=[]
The included column is just the AEP, and each row is
......@@ -4868,9 +4898,16 @@ class Cases(object):
case_ids = [k[0] for k in fh_lst_basename if k[0][:5]=='dlc12']
hours = [k[1] for k in fh_lst_basename if k[0][:5]=='dlc12']
# the default electrical power channel name from DTU Wind controller
if ch_powe is None:
ch_powe = 'DLL-2-inpvec-2'
# safe how many hours each case is active for AEP calculations for
# debugging and inspection reasons.
# FIXME: this should be somewhere in its own method or something,
# and duplication with what is in fatigue_lifetime should be removed
fname = os.path.join(post_dir, sim_id + '_AEP_hourlist')
dict_AEP_h = {'case_id':case_ids, 'hours':hours}
df_AEP_h = misc.dict2df(dict_AEP_h, fname, update=update, csv=csv,
save=save, check_datatypes=True, xlsx=xlsx,
complib=self.complib)
# and select only the power channels
dfs_powe = dfs[dfs.channel==ch_powe]
......
......@@ -404,9 +404,14 @@ def post_launch(sim_id, statistics=True, rem_failed=True, check_logs=True,
suffix=suffix, save_new_sigs=save_new_sigs,
csv=csv, m=m, neq=None, no_bins=no_bins,
chs_resultant=[], A=A, add_sigs={})
# annual energy production
if AEP:
df_AEP = cc.AEP(df_stats, csv=csv, update=update, save=True)
# annual energy production
if AEP:
# load the statistics in case they are missing
if not statistics:
df_stats, Leq_df, AEP_df = cc.load_stats()
df_AEP = cc.AEP(df_stats, csv=csv, update=update, save=True,
ch_powe='DLL-2-inpvec-2')
if envelopeblade:
ch_list = []
......@@ -435,6 +440,7 @@ def post_launch(sim_id, statistics=True, rem_failed=True, check_logs=True,
'hub1-hub1-node-001-momentvec-y',
'hub1-hub1-node-001-momentvec-z']]
cc.envelope(ch_list=ch_list, append='_turbine')
if fatigue:
# load the statistics in case they are missing
if not statistics:
......@@ -540,7 +546,8 @@ if __name__ == '__main__':
launch_dlcs_excel(sim_id, silent=False, zipchunks=opt.zipchunks,
pbs_turb=opt.pbs_turb, walltime=opt.walltime)
# post processing: check log files, calculate statistics
if opt.check_logs or opt.stats or opt.fatigue or opt.envelopeblade or opt.envelopeturbine:
if opt.check_logs or opt.stats or opt.fatigue or opt.envelopeblade \
or opt.envelopeturbine or opt.AEP:
post_launch(sim_id, check_logs=opt.check_logs, update=False,
force_dir=P_RUN, saveinterval=2500, csv=opt.csv,
statistics=opt.stats, years=opt.years, neq=opt.neq,
......