diff --git a/wetb/prepost/Simulations.py b/wetb/prepost/Simulations.py index d0c0a984c579b8c7f1be2f39def07442c8d2d66d..5ad8ee7acd367ee16550f6200a7ad1f6a8248738 100755 --- a/wetb/prepost/Simulations.py +++ b/wetb/prepost/Simulations.py @@ -1314,9 +1314,9 @@ class HtcMaster(object): self.tags['[mooring_dir]'] = 'mooring/' self.tags['[hydro_dir]'] = 'htc_hydro/' self.tags['[pbs_out_dir]'] = 'pbs_out/' - self.tags['[turb_base_name]'] = 'turb_' - self.tags['[wake_base_name]'] = 'turb_' - self.tags['[meand_base_name]'] = 'turb_' + self.tags['[turb_base_name]'] = None + self.tags['[wake_base_name]'] = None + self.tags['[meand_base_name]'] = None self.tags['[zip_root_files]'] = [] self.tags['[fname_source]'] = [] @@ -1332,9 +1332,9 @@ class HtcMaster(object): # self.queue = Queue.Queue() - self.output_dirs = ['[res_dir]', '[log_dir]', '[turb_base_name]', - '[case_id]', '[wake_base_name]', '[animation_dir]', - '[meand_base_name]', '[eigenfreq_dir]'] + self.output_dirs = ['[res_dir]', '[log_dir]', '[turb_dir]', + '[case_id]', '[wake_dir]', '[animation_dir]', + '[meand_dir]', '[eigenfreq_dir]'] def create_run_dir(self): """ @@ -2125,26 +2125,42 @@ class PBS(object): # if there is a turbulence file data base dir, copy from there if self.TurbDb: - tmp = (self.TurbDb, self.turb_base_name, self.TurbDirName) - self.pbs += "cp -R $PBS_O_WORKDIR/%s%s*.bin %s \n" % tmp + turb_dir_src = os.path.join('$PBS_O_WORKDIR', self.TurbDb) else: - # turbulence files basenames are defined for the case - self.pbs += "cp -R $PBS_O_WORKDIR/" + self.TurbDirName + \ - self.turb_base_name + "*.bin ./"+self.TurbDirName + '\n' + turb_dir_src = os.path.join('$PBS_O_WORKDIR', self.TurbDirName) + + # the original behaviour makes assumptions on the turbulence box + # names: turb_base_name_xxx_u.bin, turb_base_name_xxx_v.bin + if self.turb_base_name is not None: + turb_src = os.path.join(turb_dir_src, self.turb_base_name) + self.pbs += "cp -R %s*.bin %s \n" % (turb_src, self.TurbDirName) + # more generally, literally define the names of the boxes for u,v,w + # components + elif '[turb_fname_u]' in tag_dict: + turb_u = os.path.join(turb_dir_src, tag_dict['[turb_fname_u]']) + turb_v = os.path.join(turb_dir_src, tag_dict['[turb_fname_v]']) + turb_w = os.path.join(turb_dir_src, tag_dict['[turb_fname_w]']) + self.pbs += "cp %s %s \n" % (turb_u, self.TurbDirName) + self.pbs += "cp %s %s \n" % (turb_v, self.TurbDirName) + self.pbs += "cp %s %s \n" % (turb_w, self.TurbDirName) + # if there is a turbulence file data base dir, copy from there if self.wakeDb and self.WakeDirName: - tmp = (self.wakeDb, self.wake_base_name, self.WakeDirName) - self.pbs += "cp -R $PBS_O_WORKDIR/%s%s*.bin %s \n" % tmp + wake_dir_src = os.path.join('$PBS_O_WORKDIR', self.wakeDb) elif self.WakeDirName: - self.pbs += "cp -R $PBS_O_WORKDIR/" + self.WakeDirName + \ - self.wake_base_name + "*.bin ./"+self.WakeDirName + '\n' + wake_dir_src = os.path.join('$PBS_O_WORKDIR', self.WakeDirName) + if self.wake_base_name is not None: + wake_src = os.path.join(wake_dir_src, self.wake_base_name) + self.pbs += "cp -R %s*.bin %s \n" % (wake_src, self.WakeDirName) + # if there is a turbulence file data base dir, copy from there if self.meandDb and self.MeanderDirName: - tmp = (self.meandDb, self.meand_base_name, self.MeanderDirName) - self.pbs += "cp -R $PBS_O_WORKDIR/%s%s*.bin %s \n" % tmp + meand_dir_src = os.path.join('$PBS_O_WORKDIR', self.meandDb) elif self.MeanderDirName: - self.pbs += "cp -R $PBS_O_WORKDIR/" + self.MeanderDirName + \ - self.meand_base_name + "*.bin ./"+self.MeanderDirName + '\n' + meand_dir_src = os.path.join('$PBS_O_WORKDIR', self.MeanderDirName) + if self.meand_base_name is not None: + meand_src = os.path.join(meand_dir_src, self.meand_base_name) + self.pbs += "cp -R %s*.bin %s \n" % (meand_src, self.MeanderDirName) # copy and rename input files with given versioned name to the # required non unique generic version @@ -3811,7 +3827,7 @@ class Cases(object): ch_fatigue={}, update=False, add_sensor=None, chs_resultant=[], i0=0, i1=-1, saveinterval=1000, csv=True, suffix=None, fatigue_cycles=False, A=None, - ch_wind=None, save_new_sigs=False): + ch_wind=None, save_new_sigs=False, xlsx=False): """ Calculate statistics and save them in a pandas dataframe. Save also every 500 cases the statistics file. @@ -3862,6 +3878,10 @@ class Cases(object): csv : boolean, default=False In addition to a h5 file, save the statistics also in csv format. + xlsx : boolean, default=False + In addition to a h5 file, save the statistics also in MS Excel xlsx + format. + Returns ------- @@ -4250,7 +4270,7 @@ class Cases(object): # TODO: test this first fname = os.path.join(post_dir, sim_id + '_statistics' + ext) dfs = misc.dict2df(df_dict2, fname, save=save, update=update, - csv=csv, check_datatypes=False) + csv=csv, xlsx=xlsx, check_datatypes=False) df_dict2 = None df_dict = None @@ -4272,7 +4292,7 @@ class Cases(object): # TODO: test this first fname = os.path.join(post_dir, sim_id + '_statistics' + ext) dfs = misc.dict2df(df_dict2, fname, save=save, update=update, - csv=csv, check_datatypes=False) + csv=csv, xlsx=xlsx, check_datatypes=False) return dfs @@ -4388,7 +4408,8 @@ class Cases(object): def fatigue_lifetime(self, dfs, neq, res_dir='res/', fh_lst=None, years=20., dlc_folder="dlc%s_iec61400-1ed3/", extra_cols=[], - save=False, update=False, csv=False, new_sim_id=False): + save=False, update=False, csv=False, new_sim_id=False, + xlsx=False): """ Cacluate the fatigue over a selection of cases and indicate how many hours each case contributes to its life time. @@ -4533,14 +4554,14 @@ class Cases(object): # make consistent data types, and convert to DataFrame fname = os.path.join(post_dir, sim_id + '_Leq') df_Leq = misc.dict2df(dict_Leq, fname, save=save, update=update, - csv=csv, check_datatypes=True) + csv=csv, check_datatypes=True, xlsx=xlsx) # 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, res_dir='res/', dlc_folder="dlc%s_iec61400-1ed3/", csv=False, - new_sim_id=False, save=False, years=20.0): + new_sim_id=False, save=False, years=20.0, xlsx=False): """ Calculate the Annual Energy Production (AEP) for DLC1.2 cases. @@ -4655,7 +4676,7 @@ class Cases(object): # make consistent data types, and convert to DataFrame fname = os.path.join(post_dir, sim_id + '_AEP') df_AEP = misc.dict2df(dict_AEP, fname, update=update, csv=csv, - save=save, check_datatypes=True) + save=save, check_datatypes=True, xlsx=xlsx) return df_AEP diff --git a/wetb/prepost/dlcdefs.py b/wetb/prepost/dlcdefs.py index 2d439c148b1fbed8854e6cc9353c1e59b280e54c..822b20e5cc8731503d6847229e7a2642f7ec3935 100644 --- a/wetb/prepost/dlcdefs.py +++ b/wetb/prepost/dlcdefs.py @@ -321,7 +321,11 @@ def excel_stabcon(proot, fext='xlsx', pignore=None, sheet=0, tags_dict['[htc_dir]'] = 'htc/%s/' % dlc_case tags_dict['[case_id]'] = tags_dict['[Case id.]'] tags_dict['[time_stop]'] = tags_dict['[time stop]'] - tags_dict['[turb_base_name]'] = tags_dict['[Turb base name]'] + try: + tags_dict['[turb_base_name]'] = tags_dict['[Turb base name]'] + except KeyError: + tags_dict['[turb_base_name]'] = None + tags_dict['[Turb base name]'] = None tags_dict['[DLC]'] = tags_dict['[Case id.]'].split('_')[0][3:] tags_dict['[pbs_out_dir]'] = 'pbs_out/%s/' % dlc_case tags_dict['[pbs_in_dir]'] = 'pbs_in/%s/' % dlc_case diff --git a/wetb/prepost/misc.py b/wetb/prepost/misc.py index c7b3a067aa917a163fd83d375b3edf9116e0f2bd..441e20c1c500c7ca879e3eb22e95ec404545e068 100644 --- a/wetb/prepost/misc.py +++ b/wetb/prepost/misc.py @@ -1012,7 +1012,7 @@ def df_dict_check_datatypes(df_dict): def dict2df(df_dict, fname, save=True, update=False, csv=False, colsort=None, - check_datatypes=False, rowsort=None, csv_index=False): + check_datatypes=False, rowsort=None, csv_index=False, xlsx=False): """ Convert the df_dict to df and save/update if required. If converting to df fails, pickle the object. Optionally save as csv too. @@ -1086,6 +1086,8 @@ def dict2df(df_dict, fname, save=True, update=False, csv=False, colsort=None, print('saving: %s ...' % (fname), end='') if csv: dfs.to_csv('%s.csv' % fname, index=csv_index) + if xlsx: + dfs.to_excel('%s.xlsx' % fname, index=csv_index) dfs.to_hdf('%s.h5' % fname, 'table', mode='w', format='table', complevel=9, complib='blosc') diff --git a/wetb/prepost/windIO.py b/wetb/prepost/windIO.py index a2aa6536c5a5071d5d0c35216f31d6b2dba43276..ebf6e7647f4102f64e38e9a7a588b0d19abb515c 100755 --- a/wetb/prepost/windIO.py +++ b/wetb/prepost/windIO.py @@ -1510,7 +1510,8 @@ class UserWind(object): return u_comp, v_comp, w_comp, v_coord, w_coord, phi_deg - def write_user_defined_shear(self, fname, u, v, w, v_coord, w_coord): + def write_user_defined_shear(self, fname, u, v, w, v_coord, w_coord, + fmt_uvw='% 08.05f', fmt_coord='% 8.02f'): """ """ nr_hor = len(v_coord) @@ -1527,22 +1528,22 @@ class UserWind(object): 'nr_vert: %i' % (str(u.shape), nr_hor, nr_vert)) # and create the input file - with opent(fname, 'w') as f: - f.write('# User defined shear file\n') - f.write('%i %i # nr_hor (v), nr_vert (w)\n' % (nr_hor, nr_vert)) - h1 = 'normalized with U_mean, nr_hor (v) rows, nr_vert (w) columns' - f.write('# v component, %s\n' % h1) - np.savetxt(f, v, fmt='% 08.05f', delimiter=' ') - f.write('# u component, %s\n' % h1) - np.savetxt(f, u, fmt='% 08.05f', delimiter=' ') - f.write('# w component, %s\n' % h1) - np.savetxt(f, w, fmt='% 08.05f', delimiter=' ') - h2 = '# v coordinates (along the horizontal, nr_hor, 0 rotor center)' - f.write('%s\n' % h2) - np.savetxt(f, v_coord.reshape((v_coord.size,1)), fmt='% 8.02f') - h3 = '# w coordinates (zero is at ground level, height, nr_hor)' - f.write('%s\n' % h3) - np.savetxt(f, w_coord.reshape((w_coord.size,1)), fmt='% 8.02f') + with open(fname, 'wb') as fid: + fid.write(b'# User defined shear file\n') + fid.write(b'%i %i # nr_hor (v), nr_vert (w)\n' % (nr_hor, nr_vert)) + h1 = b'normalized with U_mean, nr_hor (v) rows, nr_vert (w) columns' + fid.write(b'# v component, %s\n' % h1) + np.savetxt(fid, v, fmt=fmt_uvw, delimiter=' ') + fid.write(b'# u component, %s\n' % h1) + np.savetxt(fid, u, fmt=fmt_uvw, delimiter=' ') + fid.write(b'# w component, %s\n' % h1) + np.savetxt(fid, w, fmt=fmt_uvw, delimiter=' ') + h2 = b'# v coordinates (along the horizontal, nr_hor, 0 rotor center)' + fid.write(b'%s\n' % h2) + np.savetxt(fid, v_coord.reshape((v_coord.size,1)), fmt=fmt_coord) + h3 = b'# w coordinates (zero is at ground level, height, nr_hor)' + fid.write(b'%s\n' % h3) + np.savetxt(fid, w_coord.reshape((w_coord.size,1)), fmt=fmt_coord) class WindProfiles(object):