Source code for solsticepy.process_raw

import numpy as np
import re
import sys
import os
from uncertainties import ufloat
from uncertainties.umath import *
from .output_motab import output_motab 

[docs]def process_raw_results(rawfile, savedir,rho_mirror,dni,verbose=False): """Process the raw Solstice `simul` output into readable CSV files for central receiver systems ``Arguments`` * rawfile (str): the directory of the `simul` file that generated by Solstice * savedir (str): the directory for saving the organised results * rho_mirror (float): mirror reflectivity (needed for reporting energy sums) * dni (float): the direct normal irradiance (W/m2), required to obtain performance of individual heliostat * verbose (bool), write results to disk or not ``Returns`` * efficiency_total (float): the total optical efficiency * performance_hst (numpy array): the breakdown of losses of each individual heliostat * The simulation results are created and written in the `savedir` """ # FIXME this approach seems fundamentally a bit messy... we are carefully # load the text output from 'solppraw' and then assuming that we can # correctly find the right bits of data in the right place. Wouldn't it # be easier and more robust to modify solppraw to create output that can # be directly loaded, along with data labels, eg a YAML file? Or to # create 'result-raw.csv' directly? rows = [] index = 0 with open(rawfile) as f: for r in f.readlines(): if index<20: pass #sys.stderr.write("Line %d: %s"%(index,r)) if r[0] == "#": #sys.stderr.write("^------Comment\n") #comment line rows.append([r]) else: rows.append(r.split()) index+=1 # sun direction #sys.stderr.write("SUN DIRECTION?\n") #sys.stderr.write(rows[0][0]+"\n") sun=re.findall("[-+]?\d*\.\d+|\d+", rows[0][0]) #sys.stderr.write("SUN = %s\n"%(repr(sun),)) azimuth=sun[0] elevation=sun[1] def get_rc(row,col): return float(rows[row][col]) # Global results num_res=int(get_rc(1,0)) # number of global results num_rec=int(get_rc(1,1)) num_hst=get_rc(1,2) num_rays=get_rc(1,3) potential=get_rc(2,0) #W potential_err=get_rc(2,1) absorbed=get_rc(3,0) absorbed_err=get_rc(3,1) Fcos=get_rc(4,0) Fcos_err=get_rc(4,1) shadow_loss=get_rc(5,0) shadow_err=get_rc(5,1) missing_loss=get_rc(6,0) missing_err=get_rc(6,1) material_loss=get_rc(7,0) material_err=get_rc(7,1) atmospheric_loss=get_rc(8,0) atmospheric_err=get_rc(8,1) # Target (receiver) # 0 receiver name # 1 - 2 id and area # 3 - 24 (total 22) front # 25- 46 (total 22) back rec_area=0. # m2 rec_front_income=0. rec_front_income_err=0. #rec_no_material_loss=get_rc(num_res+2,5) #rec_no_material_loss_err=get_rc(num_res+2,6) #rec_no_atmo_loss=get_rc(num_res+2,7) #rec_no_atmo_loss_err=get_rc(num_res+2,8) #rec_material_loss=get_rc(num_res+2,9) #rec_material_loss_err=get_rc(num_res+2,10) rec_front_absorbed=0. rec_front_absorbed_err=0. rec_front_eff=0. rec_front_eff_err=0. rec_back_income=0. rec_back_income_err=0. rec_back_absorbed=0. rec_back_absorbed_err=0. rec_back_eff=0. rec_back_eff_err=0. rec_id={} for i in range(num_rec-1): # -1 the virtual target rec_id[i]=get_rc(num_res+2+i,1) # the id number of the receiver rec_area+=get_rc(num_res+2+i,2) # m2 rec_front_income+=get_rc(num_res+2+i,3) rec_front_income_err+=get_rc(num_res+2+i,4) #rec_no_material_loss=get_rc(num_res+2,5) #rec_no_material_loss_err=get_rc(num_res+2,6) #rec_no_atmo_loss=get_rc(num_res+2,7) #rec_no_atmo_loss_err=get_rc(num_res+2,8) #rec_material_loss=get_rc(num_res+2,9) #rec_material_loss_err=get_rc(num_res+2,10) rec_front_absorbed+=get_rc(num_res+2+i,13) rec_front_absorbed_err+=get_rc(num_res+2+i,14) rec_front_eff+=get_rc(num_res+2+i,23) rec_front_eff_err+=get_rc(num_res+2+i,24) rec_back_income+=get_rc(num_res+2+i,25) rec_back_income_err+=get_rc(num_res+2+i,26) rec_back_absorbed+=get_rc(num_res+2+i,35) rec_back_absorbed_err+=get_rc(num_res+2+i,36) rec_back_eff+=get_rc(num_res+2+i,-2) rec_back_eff_err+=get_rc(num_res+2+i,-1) #Virtual target vir_area=get_rc(num_res+2+num_rec-1,2) vir_income=get_rc(num_res+2+num_rec-1,3) vir_income_err=get_rc(num_res+2+num_rec-1,4) raw_res=np.array([ ['name','value', 'error'] ,['sun_azimuth', azimuth,''] ,['sun_elevation', elevation, ''] ,['num hst', num_hst,''] ,['num rays',num_rays, ''] ,['potential flux', potential, potential_err] ,['absorbed flux', absorbed, absorbed_err] ,['Cosine factor', Fcos, Fcos_err] ,['shadow loss', shadow_loss, shadow_err] ,['Mising loss', missing_loss, missing_err] ,['materials loss', material_loss, material_err] ,['atomospheric loss', atmospheric_loss, atmospheric_err] ,['','',''] ,['Target', '',''] ,['area', rec_area, ''] ,['front income flux', rec_front_income, rec_front_income_err] ,['back income flux', rec_back_income, rec_back_income_err] ,['front absorbed flux', rec_front_absorbed, rec_front_absorbed_err] ,['back absorbed flux', rec_back_absorbed, rec_back_absorbed_err] ,['front efficiency', rec_front_eff, rec_front_eff_err] ,['back efficiency', rec_back_eff, rec_back_eff_err] ,['','',''] ,['Virtual plane','',''] ,['area', vir_area, ''] ,['income flux', vir_income,vir_income_err] ]) #sys.stderr.write(repr(raw_res)) #sys.stderr.write("SHAPE = %s" % (repr(raw_res.shape))) Qtotal=ufloat(potential, 0) Fcos=ufloat(Fcos,Fcos_err) Qcos=Qtotal*(1.-Fcos) Qshade=ufloat(shadow_loss,shadow_err) Qfield_abs=(Qtotal-Qcos-Qshade)*(1.-float(rho_mirror)) Qattn=ufloat(atmospheric_loss, atmospheric_err) Qabs=ufloat(absorbed, absorbed_err) Qspil=ufloat(vir_income,vir_income_err)-Qabs Qrefl=ufloat(rec_front_income,rec_front_income_err)+ufloat(rec_back_income,rec_back_income_err)-Qabs Qblock=Qtotal-Qcos-Qshade-Qfield_abs-Qspil-Qabs-Qrefl-Qattn organised=np.array([ ['Name', 'Value', '+/-Error'] ,['Qall (kW)', Qtotal.n/1000., Qtotal.s/1000.] ,['Qcos (kW)', Qcos.n/1000.,Qcos.s/1000.] ,['Qshad (kW)', Qshade.n/1000., Qshade.s/1000.] ,['Qfield_abs (kW)', Qfield_abs.n/1000., Qfield_abs.s/1000.] ,['Qblcok (kW)', Qblock.n/1000., Qblock.s/1000.] ,['Qattn (kW)',Qattn.n/1000., Qattn.s/1000.] ,['Qspil (kW)', Qspil.n/1000., Qspil.s/1000.] ,['Qrefl (kW)', Qrefl.n/1000.,Qrefl.s/1000.] ,['Qabs (kW)', Qabs.n/1000., Qabs.s/1000.] ,['rays', num_rays,'-'] ]) efficiency_total=Qabs/Qtotal # per heliostat results, and # per receiver per heliostat results num_hst=int(num_hst) heliostats=np.zeros((num_hst,28)) for i in range(num_hst): l1=2+num_res+num_rec+i # the line number of the per heliostat result per_hst=rows[l1] hst_idx=re.findall("[-+]?\d*\.\d+|\d+", per_hst[0] ) hst_area=per_hst[2] hst_sample=per_hst[3] hst_cos=per_hst[4] hst_shad=per_hst[6] heliostats[i,0]=hst_idx[0] heliostats[i,1]=hst_area heliostats[i,2]=hst_sample heliostats[i,3]=hst_cos heliostats[i,4]=hst_shad # per heliostat per receiver for j in range(num_rec-1): l2=2+num_res+num_rec+num_hst*(j+1)+i per_hst=rows[l2] hst_in=float(per_hst[2])+float(per_hst[22]) # front+back hst_in_mat=float(per_hst[8])+float(per_hst[28]) hst_in_atm=float(per_hst[10])+float(per_hst[30]) hst_abs=float(per_hst[12])+float(per_hst[32]) hst_abs_mat=float(per_hst[18])+float(per_hst[38]) hst_abs_atm=float(per_hst[20])+float(per_hst[40]) heliostats[i,5]+=hst_in heliostats[i,6]+=hst_in_mat heliostats[i,7]+=hst_in_atm heliostats[i,8]+=hst_abs heliostats[i,9]+=hst_abs_mat heliostats[i,10]+=hst_abs_atm # per heliostat per virtual target l3=2+num_res+num_rec+(num_rec)*num_hst+i per_hst=rows[l3] hst_in=float(per_hst[2])+float(per_hst[22]) # front+back hst_in_mat=float(per_hst[8])+float(per_hst[28]) hst_in_atm=float(per_hst[10])+float(per_hst[30]) hst_abs=float(per_hst[12])+float(per_hst[32]) hst_abs_mat=float(per_hst[18])+float(per_hst[38]) hst_abs_atm=float(per_hst[20])+float(per_hst[40]) heliostats[i,11]=hst_in heliostats[i,12]=hst_in_mat heliostats[i,13]=hst_in_atm heliostats[i,14]=hst_abs heliostats[i,15]=hst_abs_mat heliostats[i,16]=hst_abs_atm hst_tot=float(hst_area)*1000. hst_cos=hst_tot*(1.-float(hst_cos)) hst_shad=float(hst_shad) hst_abs=(hst_tot-hst_cos-hst_shad)*(1.-rho_mirror) hst_atm=float(heliostats[i,10]) hst_rec_abs=float(heliostats[i,8]) hst_spil=float(heliostats[i,11])-hst_rec_abs hst_rec_refl=float(heliostats[i,5])-float(heliostats[i,8]) hst_block=hst_tot-hst_cos-hst_shad-hst_abs-hst_atm-hst_spil-hst_rec_abs-hst_rec_refl heliostats[i,19]=hst_tot heliostats[i,20]=hst_cos heliostats[i,21]=hst_shad heliostats[i,22]=hst_abs heliostats[i,23]=hst_block heliostats[i,24]=hst_atm heliostats[i,25]=hst_spil heliostats[i,26]=hst_rec_refl heliostats[i,27]=hst_rec_abs idx=heliostats[:, 0].argsort() heliostats=heliostats[idx] performance_hst=heliostats[:, 19:] heliostats_title=np.array(['hst_idx', 'area', 'sample', 'cos', 'shade', 'incoming', 'in-mat-loss','in-atm-loss', 'absorbed', 'abs-mat-loss', 'abs-atm-loss', 'vir_incoming', 'vir_in-mat-loss','vir_in-atm-loss', 'vir_absorbed', 'vir_abs-mat-loss', 'vir_abs-atm-loss', '', '', 'total', 'cos', 'shad', 'hst_abs', 'block', 'atm', 'spil', 'rec_refl', 'rec_abs' ]) heliostats_details=np.vstack((heliostats_title, heliostats)) if verbose: np.savetxt(savedir+'/result-formatted.csv', organised, fmt='%s', delimiter=',') np.savetxt(savedir+'/heliostats-raw.csv', heliostats_details, fmt='%s', delimiter=',') np.savetxt(savedir+'/result-raw.csv', raw_res, fmt='%s', delimiter=',') else: os.system('rm -rf %s'%savedir) return efficiency_total, performance_hst
def process_raw_results_multi_aperture(rawfile, savedir,rho_mirror,dni,verbose=False): """Process the raw Solstice `simul` output into readable CSV files for multi-aperture central receiver systems ``Arguments`` * rawfile (str): the directory of the `simul` file that generated by Solstice * savedir (str): the directory for saving the organised results * rho_mirror (float): mirror reflectivity (needed for reporting energy sums) * dni (float): the direct normal irradiance (W/m2), required to obtain performance of individual heliostat * verbose (bool), write results to disk or not ``Returns`` * efficiency_total (float): the total optical efficiency * performance_hst (numpy array): the breakdown of losses of each individual heliostat * The simulation results are created and written in the `savedir` """ # FIXME this approach seems fundamentally a bit messy... we are carefully # load the text output from 'solppraw' and then assuming that we can # correctly find the right bits of data in the right place. Wouldn't it # be easier and more robust to modify solppraw to create output that can # be directly loaded, along with data labels, eg a YAML file? Or to # create 'result-raw.csv' directly? rows = [] index = 0 with open(rawfile) as f: for r in f.readlines(): if index<20: pass #sys.stderr.write("Line %d: %s"%(index,r)) if r[0] == "#": #sys.stderr.write("^------Comment\n") #comment line rows.append([r]) else: rows.append(r.split()) index+=1 # sun direction #sys.stderr.write("SUN DIRECTION?\n") #sys.stderr.write(rows[0][0]+"\n") sun=re.findall("[-+]?\d*\.\d+|\d+", rows[0][0]) #sys.stderr.write("SUN = %s\n"%(repr(sun),)) azimuth=sun[0] elevation=sun[1] def get_rc(row,col): return float(rows[row][col]) # Global results num_res=int(get_rc(1,0)) # number of global results num_rec=int(get_rc(1,1)) num_hst=get_rc(1,2) num_rays=get_rc(1,3) potential=get_rc(2,0) #W potential_err=get_rc(2,1) absorbed=get_rc(3,0) absorbed_err=get_rc(3,1) Fcos=get_rc(4,0) Fcos_err=get_rc(4,1) shadow_loss=get_rc(5,0) shadow_err=get_rc(5,1) missing_loss=get_rc(6,0) missing_err=get_rc(6,1) material_loss=get_rc(7,0) material_err=get_rc(7,1) atmospheric_loss=get_rc(8,0) atmospheric_err=get_rc(8,1) # Target (receiver) # 0 receiver name # 1 - 2 id and area # 3 - 24 (total 22) front # 25- 46 (total 22) back num_apertures=num_rec-1 # -1 the virtual target rec_id={} rec_area=[] # m2 rec_front_income=[] rec_front_income_err=[] rec_front_absorbed=[] rec_front_absorbed_err=[] rec_front_eff=[] rec_front_eff_err=[] rec_back_income=[] rec_back_income_err=[] rec_back_absorbed=[] rec_back_absorbed_err=[] rec_back_eff=[] rec_back_eff_err=[] for i in range(num_apertures): rec_id[i]=get_rc(num_res+2+i,1) # the id number of the receiver rec_area.append(get_rc(num_res+2+i,2)) # m2 rec_front_income.append(get_rc(num_res+2+i,3)) rec_front_income_err.append(get_rc(num_res+2+i,4)) rec_front_absorbed.append(get_rc(num_res+2+i,13)) rec_front_absorbed_err.append(get_rc(num_res+2+i,14)) rec_front_eff.append(get_rc(num_res+2+i,23)) rec_front_eff_err.append(get_rc(num_res+2+i,24)) rec_back_income.append(get_rc(num_res+2+i,25)) rec_back_income_err.append(get_rc(num_res+2+i,26)) rec_back_absorbed.append(get_rc(num_res+2+i,35)) rec_back_absorbed_err.append(get_rc(num_res+2+i,36)) rec_back_eff.append(get_rc(num_res+2+i,-2)) rec_back_eff_err.append(get_rc(num_res+2+i,-1)) #Virtual target vir_area=get_rc(num_res+2+num_rec-1,2) vir_income=get_rc(num_res+2+num_rec-1,3) vir_income_err=get_rc(num_res+2+num_rec-1,4) raw_res=np.array([ ['name','value', 'error'] ,['sun_azimuth', azimuth,''] ,['sun_elevation', elevation, ''] ,['num hst', num_hst,''] ,['num rays',num_rays, ''] ,['potential flux', potential, potential_err] ,['absorbed flux', absorbed, absorbed_err] ,['Cosine factor', Fcos, Fcos_err] ,['shadow loss', shadow_loss, shadow_err] ,['Mising loss', missing_loss, missing_err] ,['materials loss', material_loss, material_err] ,['atomospheric loss', atmospheric_loss, atmospheric_err] ,['','',''] ,['','',''] ,['Virtual plane','',''] ,['area', vir_area, ''] ,['income flux', vir_income,vir_income_err]]) for i in range(num_apertures): aperture_i = np.array([ ['','',''] ,['Aperture', i,''] ,['area', rec_area[i], ''] ,['front income flux', rec_front_income[i], rec_front_income_err[i]] ,['back income flux', rec_back_income[i], rec_back_income_err[i]] ,['front absorbed flux', rec_front_absorbed[i], rec_front_absorbed_err[i]] ,['back absorbed flux', rec_back_absorbed[i], rec_back_absorbed_err[i]] ,['front efficiency', rec_front_eff[i], rec_front_eff_err[i]] ,['back efficiency', rec_back_eff[i], rec_back_eff_err[i]]]) raw_res=np.vstack((raw_res, aperture_i)) #sys.stderr.write(repr(raw_res)) #sys.stderr.write("SHAPE = %s" % (repr(raw_res.shape))) Qtotal=ufloat(potential, 0) Fcos=ufloat(Fcos,Fcos_err) Qcos=Qtotal*(1.-Fcos) Qshade=ufloat(shadow_loss,shadow_err) Qfield_abs=(Qtotal-Qcos-Qshade)*(1.-float(rho_mirror)) Qattn=ufloat(atmospheric_loss, atmospheric_err) Qabs=ufloat(absorbed, absorbed_err) Qspil=ufloat(vir_income,vir_income_err)-Qabs Qrefl=ufloat(sum(rec_front_income),sum(rec_front_income_err))+ufloat(sum(rec_back_income),sum(rec_back_income_err))-Qabs Qblock=Qtotal-Qcos-Qshade-Qfield_abs-Qspil-Qabs-Qrefl-Qattn organised=np.array([ ['Name', 'Value', '+/-Error'] ,['Qall (kW)', Qtotal.n/1000., Qtotal.s/1000.] ,['Qcos (kW)', Qcos.n/1000.,Qcos.s/1000.] ,['Qshad (kW)', Qshade.n/1000., Qshade.s/1000.] ,['Qfield_abs (kW)', Qfield_abs.n/1000., Qfield_abs.s/1000.] ,['Qblcok (kW)', Qblock.n/1000., Qblock.s/1000.] ,['Qattn (kW)',Qattn.n/1000., Qattn.s/1000.] ,['Qspil (kW)', Qspil.n/1000., Qspil.s/1000.] ,['Qrefl (kW)', Qrefl.n/1000.,Qrefl.s/1000.] ,['Qabs (kW)', Qabs.n/1000., Qabs.s/1000.] ,['rays', num_rays,'-'] ]) efficiency_total=Qabs/Qtotal # per heliostat results, and # per receiver per heliostat results num_hst=int(num_hst) heliostats=np.zeros((num_hst,28)) for i in range(num_hst): l1=2+num_res+num_rec+i # the line number of the per heliostat result per_hst=rows[l1] hst_idx=re.findall("[-+]?\d*\.\d+|\d+", per_hst[0] ) hst_area=per_hst[2] hst_sample=per_hst[3] hst_cos=per_hst[4] hst_shad=per_hst[6] heliostats[i,0]=hst_idx[0] heliostats[i,1]=hst_area heliostats[i,2]=hst_sample heliostats[i,3]=hst_cos heliostats[i,4]=hst_shad # per heliostat per receiver for j in range(num_rec-1): l2=2+num_res+num_rec+num_hst*(j+1)+i per_hst=rows[l2] hst_in=float(per_hst[2])+float(per_hst[22]) # front+back hst_in_mat=float(per_hst[8])+float(per_hst[28]) hst_in_atm=float(per_hst[10])+float(per_hst[30]) hst_abs=float(per_hst[12])+float(per_hst[32]) hst_abs_mat=float(per_hst[18])+float(per_hst[38]) hst_abs_atm=float(per_hst[20])+float(per_hst[40]) heliostats[i,5]+=hst_in heliostats[i,6]+=hst_in_mat heliostats[i,7]+=hst_in_atm heliostats[i,8]+=hst_abs heliostats[i,9]+=hst_abs_mat heliostats[i,10]+=hst_abs_atm # per heliostat per virtual target l3=2+num_res+num_rec+(num_rec)*num_hst+i per_hst=rows[l3] hst_in=float(per_hst[2])+float(per_hst[22]) # front+back hst_in_mat=float(per_hst[8])+float(per_hst[28]) hst_in_atm=float(per_hst[10])+float(per_hst[30]) hst_abs=float(per_hst[12])+float(per_hst[32]) hst_abs_mat=float(per_hst[18])+float(per_hst[38]) hst_abs_atm=float(per_hst[20])+float(per_hst[40]) heliostats[i,11]=hst_in heliostats[i,12]=hst_in_mat heliostats[i,13]=hst_in_atm heliostats[i,14]=hst_abs heliostats[i,15]=hst_abs_mat heliostats[i,16]=hst_abs_atm hst_tot=float(hst_area)*1000. hst_cos=hst_tot*(1.-float(hst_cos)) hst_shad=float(hst_shad) hst_abs=(hst_tot-hst_cos-hst_shad)*(1.-rho_mirror) hst_atm=float(heliostats[i,10]) hst_rec_abs=float(heliostats[i,8]) hst_spil=float(heliostats[i,11])-hst_rec_abs hst_rec_refl=float(heliostats[i,5])-float(heliostats[i,8]) hst_block=hst_tot-hst_cos-hst_shad-hst_abs-hst_atm-hst_spil-hst_rec_abs-hst_rec_refl heliostats[i,19]=hst_tot heliostats[i,20]=hst_cos heliostats[i,21]=hst_shad heliostats[i,22]=hst_abs heliostats[i,23]=hst_block heliostats[i,24]=hst_atm heliostats[i,25]=hst_spil heliostats[i,26]=hst_rec_refl heliostats[i,27]=hst_rec_abs idx=heliostats[:, 0].argsort() heliostats=heliostats[idx] performance_hst=heliostats[:, 19:] heliostats_title=np.array(['hst_idx', 'area', 'sample', 'cos', 'shade', 'incoming', 'in-mat-loss','in-atm-loss', 'absorbed', 'abs-mat-loss', 'abs-atm-loss', 'vir_incoming', 'vir_in-mat-loss','vir_in-atm-loss', 'vir_absorbed', 'vir_abs-mat-loss', 'vir_abs-atm-loss', '', '', 'total', 'cos', 'shad', 'hst_abs', 'block', 'atm', 'spil', 'rec_refl', 'rec_abs' ]) heliostats_details=np.vstack((heliostats_title, heliostats)) if verbose: np.savetxt(savedir+'/result-formatted.csv', organised, fmt='%s', delimiter=',') np.savetxt(savedir+'/heliostats-raw.csv', heliostats_details, fmt='%s', delimiter=',') np.savetxt(savedir+'/result-raw.csv', raw_res, fmt='%s', delimiter=',') else: os.system('rm -rf %s'%savedir) return efficiency_total, performance_hst
[docs]def get_breakdown(casedir): """Postprocess the .csv output files (heliostats-raw.csv, before trimming), to obtain the breakdown of total energy losses of the designed field (after trimming) for central receiver systems ``Argument`` * casedir (str): the directory of the case that contains the folder of sunpos_1, sunpos_2, ..., and all the other case-related details * verbose (bool), write results to disk or not ``Outputs`` * output file: OELT_Solstice_breakdown.motab, it contains the annual lookup tables of each breakdown of energy * output files: result-formatted-designed.csv file in each sunpos folder, each of them is a list of the breakdown of energy at this sun position """ table=np.loadtxt(casedir+'/table_view.csv', dtype=str, delimiter=',') idx=np.loadtxt(casedir+'/selected_hst.csv', dtype=int, delimiter=',') #index of the selected heliostats cosn=table shad=table hsta=table blck=table attn=table spil=table refl=table absr=table breakdown=np.array([absr, cosn, shad, hsta, blck, attn, spil, refl]) title_breakdown=['eta_rcv_absorption','eta_cosine', 'eta_shading', 'eta_helios_absorption', 'eta_blocking', 'eta_attenuation', 'eta_spillage', 'eta_rcv_reflection'] tot=len(title_breakdown) for a in range(len(table[3:])): for b in range(len(table[0,3:])): val=re.findall(r'\d+',table[a+3,b+3]) if len(val)==0: for i in range(tot): breakdown[i][a+3,b+3]=0 else: c=val[0] resfile=casedir+'/sunpos_%s/result-formatted-designed.csv'%c if os.path.exists(resfile): res=np.loadtxt(resfile, dtype=str, delimiter=',') eta_cos=res[2,2].astype(float) eta_shad=res[3,2].astype(float) eta_hst=res[4,2].astype(float) eta_block=res[5,2].astype(float) eta_attn=res[6,2].astype(float) eta_spil=res[7,2].astype(float) eta_refl=res[8,2].astype(float) eta_abs=res[9,2].astype(float) else: raw=np.loadtxt(casedir+'/sunpos_%s/heliostats-raw.csv'%c, delimiter=',', skiprows=1) data=raw[:, -9:] res_selected=data[idx] Qtot=np.sum(res_selected[:,0]) Qcos=np.sum(res_selected[:,1]) Qshad=np.sum(res_selected[:,2]) Qhst=np.sum(res_selected[:,3]) Qblock=np.sum(res_selected[:,4]) Qattn=np.sum(res_selected[:,5]) Qspil=np.sum(res_selected[:,6]) Qrefl=np.sum(res_selected[:,7]) Qabs=np.sum(res_selected[:,8]) eta_cos=Qcos/Qtot eta_shad=Qshad/Qtot eta_hst=Qhst/Qtot eta_block=Qblock/Qtot eta_attn=Qattn/Qtot eta_spil=Qspil/Qtot eta_refl=Qrefl/Qtot eta_abs=Qabs/Qtot res=np.array([ ['Name', 'Value (kW)', 'eta Ratio'] ,['Qall', Qtot, 1] ,['Qcos', Qcos, eta_cos] ,['Qshad', Qshad, eta_shad] ,['Qfield_abs', Qhst, eta_hst] ,['Qblcok', Qblock, eta_block] ,['Qattn',Qattn, eta_attn] ,['Qspil ', Qspil,eta_spil] ,['Qrefl', Qrefl, eta_refl] ,['Qabs ', Qabs, eta_abs] ,['After trimming', 'postprocessed results','-'] ]) np.savetxt(casedir+'/sunpos_%s/result-formatted-designed.csv'%c, res, fmt='%s', delimiter=',') eta_all=[eta_abs, eta_cos, eta_shad, eta_hst, eta_block, eta_attn, eta_spil, eta_refl] for i in range(tot): if eta_all[i]<1e-8: breakdown[i][a+3,b+3]=0. else: breakdown[i][a+3,b+3]=eta_all[i] output_motab(table=breakdown, savedir=casedir+'/OELT_Solstice_breakdown.motab', title=title_breakdown) # at design point raw=np.loadtxt(casedir+'/des_point/heliostats-raw.csv', delimiter=',', skiprows=1) data=raw[:, -9:] res_selected=data[idx] Qtot=np.sum(res_selected[:,0]) Qcos=np.sum(res_selected[:,1]) Qshad=np.sum(res_selected[:,2]) Qhst=np.sum(res_selected[:,3]) Qblock=np.sum(res_selected[:,4]) Qattn=np.sum(res_selected[:,5]) Qspil=np.sum(res_selected[:,6]) Qrefl=np.sum(res_selected[:,7]) Qabs=np.sum(res_selected[:,8]) eta_cos=Qcos/Qtot eta_shad=Qshad/Qtot eta_hst=Qhst/Qtot eta_block=Qblock/Qtot eta_attn=Qattn/Qtot eta_spil=Qspil/Qtot eta_refl=Qrefl/Qtot eta_abs=Qabs/Qtot res=np.array([ ['Name', 'Value (kW)', 'eta Ratio'] ,['Qall', Qtot, 1] ,['Qcos', Qcos, eta_cos] ,['Qshad', Qshad, eta_shad] ,['Qfield_abs', Qhst, eta_hst] ,['Qblcok', Qblock, eta_block] ,['Qattn',Qattn, eta_attn] ,['Qspil ', Qspil,eta_spil] ,['Qrefl', Qrefl, eta_refl] ,['Qabs ', Qabs, eta_abs] ,['After trimming', 'postprocessed results','-'] ]) np.savetxt(casedir+'/des_point/result-formatted-designed.csv', res, fmt='%s', delimiter=',')
[docs]def process_raw_results_dish(rawfile, savedir,rho_mirror,dni,verbose=False): """Process the raw Solstice `simul` output into readable CSV files for dish systems ``Arguments`` * rawfile (str): the directory of the `simul` file that generated by Solstice * savedir (str): the directory for saving the organised results * rho_mirror (float): mirror reflectivity (needed for reporting energy sums) * dni (float): the direct normal irradiance (W/m2), required to obtain performance of individual heliostat ``Returns`` * efficiency_total (float): the total optical efficiency * The simulation results are created and written in the `savedir` """ # FIXME this approach seems fundamentally a bit messy... we are carefully # load the text output from 'solppraw' and then assuming that we can # correctly find the right bits of data in the right place. Wouldn't it # be easier and more robust to modify solppraw to create output that can # be directly loaded, along with data labels, eg a YAML file? Or to # create 'result-raw.csv' directly? rows = [] index = 0 with open(rawfile) as f: for r in f.readlines(): if index<20: pass #sys.stderr.write("Line %d: %s"%(index,r)) if r[0] == "#": #sys.stderr.write("^------Comment\n") #comment line rows.append([r]) else: rows.append(r.split()) index+=1 results=np.array([]) # sun direction #sys.stderr.write("SUN DIRECTION?\n") #sys.stderr.write(rows[0][0]+"\n") sun=re.findall("[-+]?\d*\.\d+|\d+", rows[0][0]) #sys.stderr.write("SUN = %s\n"%(repr(sun),)) azimuth=sun[0] elevation=sun[1] def get_rc(row,col): return float(rows[row][col]) # Global results num_res=int(get_rc(1,0)) # number of global results num_rec=int(get_rc(1,1)) num_hst=get_rc(1,2) num_rays=get_rc(1,3) potential=get_rc(2,0) #W potential_err=get_rc(2,1) absorbed=get_rc(3,0) absorbed_err=get_rc(3,1) Fcos=get_rc(4,0) Fcos_err=get_rc(4,1) shadow_loss=get_rc(5,0) shadow_err=get_rc(5,1) missing_loss=get_rc(6,0) missing_err=get_rc(6,1) material_loss=get_rc(7,0) material_err=get_rc(7,1) atmospheric_loss=get_rc(8,0) atmospheric_err=get_rc(8,1) # Target (receiver) # 0 receiver name # 1 - 2 id and area # 3 - 24 (total 22) front # 25- 46 (total 22) back rec_area=get_rc(num_res+2,2) # m2 rec_front_income=get_rc(num_res+2,3) rec_front_income_err=get_rc(num_res+2,4) rec_front_absorbed=get_rc(num_res+2,5) rec_front_absorbed_err=get_rc(num_res+2,6) rec_front_eff=get_rc(num_res+2,23) rec_front_eff_err=get_rc(num_res+2,24) rec_back_income=get_rc(num_res+2,25) rec_back_income_err=get_rc(num_res+2,26) rec_back_absorbed=get_rc(num_res+2,35) rec_back_absorbed_err=get_rc(num_res+2,36) rec_back_eff=get_rc(num_res+2,-2) rec_back_eff_err=get_rc(num_res+2,-1) raw_res=np.array([ ['name','value', 'error'] ,['sun_azimuth', azimuth,''] ,['sun_elevation', elevation, ''] ,['num hst', num_hst,''] ,['num rays',num_rays, ''] ,['potential flux', potential, potential_err] ,['absorbed flux', absorbed, absorbed_err] ,['Cosine factor', Fcos, Fcos_err] ,['shadow loss', shadow_loss, shadow_err] ,['Mising loss', missing_loss, missing_err] ,['materials loss', material_loss, material_err] ,['atomospheric loss', atmospheric_loss, atmospheric_err] ,['','',''] ,['Target', '',''] ,['area', rec_area, ''] ,['front income flux', rec_front_income, rec_front_income_err] ,['back income flux', rec_back_income, rec_back_income_err] ,['front absorbed flux', rec_front_absorbed, rec_front_absorbed_err] ,['back absorbed flux', rec_back_absorbed, rec_back_absorbed_err] ,['front efficiency', rec_front_eff, rec_front_eff_err] ,['back efficiency', rec_back_eff, rec_back_eff_err] ]) #sys.stderr.write(repr(raw_res)) #sys.stderr.write("SHAPE = %s" % (repr(raw_res.shape))) Qtotal=ufloat(potential, 0) Qshad=ufloat(shadow_loss, shadow_err) Qdish=(Qtotal-Qshad)*(1.-rho_mirror) Qabs=ufloat(absorbed, absorbed_err) Qrefl=ufloat(rec_front_income,rec_front_income_err)+ufloat(rec_back_income,rec_back_income_err)-Qabs Qspil=Qtotal-Qshad-Qdish-Qabs-Qrefl organised=np.array([ ['Name', 'Value', '+/-Error'] ,['Qall (kW)', Qtotal.n/1000., Qtotal.s/1000.] ,['Qshad (kW)', Qshad.n/1000., Qshad.s/1000.] ,['Qdish_abs (kW)', Qdish.n/1000., Qdish.s/1000.] ,['Qspil (kW)', Qspil.n/1000., Qspil.s/1000.] ,['Qrefl (kW)', Qrefl.n/1000.,Qrefl.s/1000.] ,['Qabs (kW)', Qabs.n/1000., Qabs.s/1000.] ,['rays', num_rays,'-'] ]) efficiency_total=Qabs/Qtotal if verbose: np.savetxt(savedir+'/result-formatted.csv', organised, fmt='%s', delimiter=',') np.savetxt(savedir+'/result-raw.csv', raw_res, fmt='%s', delimiter=',') return efficiency_total
if __name__=='__main__': eta,pf_hst = proces_raw_results(sys.argv[1], sys.argv[2], sys.argv[3]) sys.stderr.write('\nTotal efficiency: %s\n'%(repr(eta),))