"""
Created on Mon Jul  13 12:34:56 2024

Most recently tested against PySAM 5.1.0

@author: Luke
"""
import numpy as np
import pandas as pd
import PySAM.TcsmoltenSalt as TcsmoltenSalt
import matplotlib.pyplot as plt


torre_por_defecto= TcsmoltenSalt.default("MSPTNone") 
recurso_solar= torre_por_defecto.SolarResource 
weather_data="./daggett_ca_34.865371_-116.783023_psmv3_60_tmy.csv"
setattr(recurso_solar, 'solar_resource_file', weather_data) 
weather_data_df = pd.read_csv(weather_data)
weather_data_df
glb=weather_data_df['Time Zone'][2:].values.copy()
glb.sort()

#SYSTEM DESIGN
diseño_del_sistema= torre_por_defecto.SystemDesign 
setattr(diseño_del_sistema, 'dni_des', float(glb[8321])) # percentile 95%
setattr(diseño_del_sistema, 'solarm', 2.4) #Default
setattr(diseño_del_sistema, 'T_htf_hot_des', 574.0) #Default
setattr(diseño_del_sistema, 'T_htf_cold_des', 290.0) #Default
setattr(diseño_del_sistema, 'tshours', 12.0) 
setattr(diseño_del_sistema, 'P_ref', 100.0)
setattr(diseño_del_sistema, 'design_eff', 0.412) #Default

#HELIOSTAT FIELD
campo_de_heliostato= torre_por_defecto.HeliostatField 
#Heliostat properties
setattr(campo_de_heliostato, 'helio_width', 12.2) #Default
setattr(campo_de_heliostato, 'helio_height', 12.2) #Default
setattr(campo_de_heliostato, 'dens_mirror', 0.97) #Default
setattr(campo_de_heliostato, 'helio_optical_error_mrad', 1.53) #Default
setattr(campo_de_heliostato, 'n_facet_x', 2.0) #Default
setattr(campo_de_heliostato, 'n_facet_y', 8.0) #Default
setattr(campo_de_heliostato, 'focus_type', 1.0) #Default
setattr(campo_de_heliostato, 'cant_type', 1.0) #Default
setattr(campo_de_heliostato, 'helio_reflectance', 0.9) #Default
setattr(campo_de_heliostato, 'hel_stow_deploy', 8.0) #Default
setattr(campo_de_heliostato, 'v_wind_max', 15.0) #Default
setattr(campo_de_heliostato, 'p_start', 0.025) #Default
setattr(campo_de_heliostato, 'p_track', 0.055) #Default

#Land Area
setattr(campo_de_heliostato, 'csp_pt_sf_fixed_land_area', 45.0) 
setattr(campo_de_heliostato, 'csp_pt_sf_land_overhead_factor', 1.0) 
setattr(campo_de_heliostato, 'land_max', 9.5) 
setattr(campo_de_heliostato, 'land_min', 0.75) 
setattr(campo_de_heliostato, 'water_usage_per_wash', 0.7) 
setattr(campo_de_heliostato, 'washing_frequency', 63.0) 

#Optimization setting
setattr(campo_de_heliostato, 'field_model_type', 1.0) #0=design field and tower/receiver geometry, 1=design field, 2=user specified field, 3=user flux and eta map, pass heliostat_positions to SolarPILOT for layout, 4=user flux and eta maps, no SolarPILOT, input A_sf_in, total_land_area_before_rad_cooling_in, and N_hel
setattr(campo_de_heliostato, 'opt_algorithm', 1.0) #Default
setattr(campo_de_heliostato, 'opt_conv_tol', 0.001) #Default
setattr(campo_de_heliostato, 'opt_flux_penalty', 0.25) #Default

#tOWER AND RECEIVER
Torre_y_receptor= torre_por_defecto.TowerAndReceiver 
setattr(Torre_y_receptor, 'rec_htf', 17.0) #Default
setattr(Torre_y_receptor, 'mat_tube', 2.0) #Default
setattr(Torre_y_receptor, 'd_tube_out', 40.0) #Default
setattr(Torre_y_receptor, 'th_tube', 1.25) #Default
setattr(Torre_y_receptor, 'epsilon', 0.88) #Default
setattr(Torre_y_receptor, 'rec_absorptance', 0.94) #Default
setattr(Torre_y_receptor, 'hl_ffact', 1.0) #Default
setattr(Torre_y_receptor, 'piping_loss_coefficient', 2.0) #Default
setattr(Torre_y_receptor, 'piping_length_const', 0.0) #Default
setattr(Torre_y_receptor, 'piping_length_mult', 2.6) #Default
setattr(Torre_y_receptor, 'flux_max', 1000.0) #Default
setattr(Torre_y_receptor, 'rec_hl_perm2', 30.0) #Default
setattr(Torre_y_receptor, 'n_flux_days', 8.0) #Default
setattr(Torre_y_receptor, 'delta_flux_hrs', 2.0) #Default
setattr(Torre_y_receptor, 'f_rec_min', 0.25) #Default
setattr(Torre_y_receptor, 'csp_pt_rec_max_oper_frac', 1.2) #Default
setattr(Torre_y_receptor, 'rec_su_delay', 0.5) #Default
setattr(Torre_y_receptor, 'rec_qf_delay', 0.25) #Default
setattr(Torre_y_receptor, 'eta_pump', 0.85) #Default
setattr(Torre_y_receptor, 'h_tower', 155.0) #Default
setattr(campo_de_heliostato, 'receiver_type', 0.0) #Default
if getattr(campo_de_heliostato, 'receiver_type')==0.0:
    setattr(Torre_y_receptor, 'rec_height', 14.2) 
    setattr(Torre_y_receptor, 'D_rec', 12.5) 
    setattr(Torre_y_receptor, 'N_panels', 20.0) 
    setattr(Torre_y_receptor, 'Flow_type', 1.0) 
    
elif getattr(campo_de_heliostato, 'receiver_type')==1.0:    
    setattr(Torre_y_receptor, 'cav_rec_height', 10.0)     
    setattr(Torre_y_receptor, 'cav_rec_width', 10.0)     
    setattr(Torre_y_receptor, 'cav_rec_span', 180.0)     
    setattr(Torre_y_receptor, 'cav_rec_passive_abs', 0.3)     
    setattr(Torre_y_receptor, 'cav_rec_passive_eps', 0.5)     
    setattr(Torre_y_receptor, 'n_cav_rec_panels', 6.0) 
    

Ciclo_de_poder= torre_por_defecto.PowerCycle 
setattr(Ciclo_de_poder, 'pb_pump_coef', 0.55) #Default
setattr(Ciclo_de_poder, 'cycle_cutoff_frac', 0.2) #Default
setattr(Ciclo_de_poder, 'startup_time', 0.5) #Default
setattr(Ciclo_de_poder, 'startup_frac', 0.5) #Default
setattr(Ciclo_de_poder, 'q_sby_frac', 0.2) #Default
setattr(Ciclo_de_poder, 'cycle_max_frac', 1.0) #Default
setattr(Ciclo_de_poder, 'pc_config', 0.0) #Default

Ciclo_rankine= torre_por_defecto.RankineCycle 
setattr(Ciclo_rankine, 'pb_bd_frac', 0.02) #Default
setattr(Ciclo_rankine, 'tech_type', 1.0) #Default
setattr(Ciclo_rankine, 'CT', 2.0) #Default
if getattr(Ciclo_rankine, 'CT')==2.0:
    setattr(Ciclo_rankine, 'T_amb_des', 42.0)     
    setattr(Ciclo_rankine, 'T_ITD_des', 16.0)     
    setattr(Ciclo_rankine, 'P_cond_ratio', 1.0028)     
    setattr(Ciclo_rankine, 'P_cond_min', 2.0)    
    setattr(Ciclo_rankine, 'n_pl_inc', 8.0) 
    
elif getattr(Ciclo_rankine, 'CT')==1.0:    
    setattr(Ciclo_rankine, 'T_amb_des', 42.0)     
    setattr(Ciclo_rankine, 'dT_cw_ref', 10.0)     
    setattr(Ciclo_rankine, 'T_approach', 5.0)     
    setattr(Ciclo_rankine, 'P_cond_min', 2.0)     
    setattr(Ciclo_rankine, 'n_pl_inc', 8.0) 
    
elif getattr(Ciclo_rankine, 'CT')==3.0:    
    setattr(Ciclo_rankine, 'T_amb_des', 42.0)     
    setattr(Ciclo_rankine, 'T_ITD_des', 16.0)     
    setattr(Ciclo_rankine, 'dT_cw_ref', 10.0)     
    setattr(Ciclo_rankine, 'T_approach', 5.0)     
    setattr(Ciclo_rankine, 'P_cond_ratio', 1.0028)     
    setattr(Ciclo_rankine, 'P_cond_min', 2.0)     
    setattr(Ciclo_rankine, 'n_pl_inc', 8.0) 
    
#THERMAL STORAGE
almacenamiento_termico= torre_por_defecto.ThermalStorage 
setattr(almacenamiento_termico, 'h_tank', 12.0) #Default
setattr(almacenamiento_termico, 'h_tank_min', 1.0) #Default
setattr(almacenamiento_termico, 'tank_pairs', 1.0) #Default
setattr(almacenamiento_termico, 'tes_init_hot_htf_percent', 30.0) #Default
setattr(almacenamiento_termico, 'u_tank', 0.4) #Default
setattr(almacenamiento_termico, 'cold_tank_Thtr', 280.0) #Default
setattr(almacenamiento_termico, 'cold_tank_max_heat', 15.0) #Default
setattr(almacenamiento_termico, 'hot_tank_Thtr', 500.0) #Default
setattr(almacenamiento_termico, 'hot_tank_max_heat', 30.0) #Default

#SYSTEM CONTROL
sistema_de_control= torre_por_defecto.SystemControl 
setattr(sistema_de_control, 'aux_par', 0.0023) #Default
setattr(sistema_de_control, 'is_dispatch', 0.0) #Default

#INSTALLATION COSTS
costos_de_instalacion= torre_por_defecto.SystemCosts 
setattr(costos_de_instalacion, 'site_spec_cost', 0.5) #Default
setattr(costos_de_instalacion, 'heliostat_spec_cost', 120.0) #Default
setattr(costos_de_instalacion, 'cost_sf_fixed', 0.0) #Default
setattr(costos_de_instalacion, 'tower_fixed_cost', 2250000.0) #Default
setattr(costos_de_instalacion, 'tower_exp', 0.0113) #Default
setattr(costos_de_instalacion, 'rec_ref_cost', 72100000.0) #Default
setattr(costos_de_instalacion, 'rec_ref_area', 1571.0) #Default
setattr(costos_de_instalacion, 'rec_cost_exp', 0.7) #Default
setattr(costos_de_instalacion, 'tes_spec_cost', 20.0) #Default
setattr(costos_de_instalacion, 'fossil_spec_cost', 0.0) #Default
setattr(costos_de_instalacion, 'bop_spec_cost', 200.0) #Default
setattr(costos_de_instalacion, 'plant_spec_cost', 700.0) #Default
setattr(costos_de_instalacion, 'heater_spec_cost', 104.0) #Default
setattr(costos_de_instalacion, 'contingency_rate', 7.0) #Default
setattr(costos_de_instalacion, 'csp_pt_cost_epc_per_acre', 0.0) #Default
setattr(costos_de_instalacion, 'csp_pt_cost_epc_percent', 0.0) #Default
setattr(costos_de_instalacion, 'csp_pt_cost_epc_per_watt', 0.0) #Default
setattr(costos_de_instalacion, 'csp_pt_cost_epc_fixed', 0.0) #Default
setattr(costos_de_instalacion, 'land_spec_cost', 10000.0) #Default
setattr(costos_de_instalacion, 'sales_tax_frac', 80.0) #Default


torre_por_defecto.execute()

resultados= torre_por_defecto.Outputs

x = []
y = []
for i in resultados.export()['helio_positions_calc']:
    x.append(i[0])
    y.append(i[1])
    



plt.figure(figsize=(8, 8))
plt.scatter(np.round(x,4).tolist(), np.round(y,4).tolist(), s=1, color='blue')  
plt.xlabel("Position, east-west (m)")
plt.ylabel("Position, north-south (m)")
plt.axis('equal')  
# plt.xlim(-1500, 1500)
# plt.ylim(-1500, 1500)
plt.title("Distribución de Heliostatos")
plt.grid(True)
plt.show()
plt.savefig('Heliostat_field.png')