Molten Salt Power Tower Plant

Tower concentrating solar power class based on SSC’s MSPT (molten salt power tower) model

class hopp.simulation.technologies.csp.tower_plant.TowerPlant(site: SiteInfo, config: TowerConfig)

Bases: CspPlant

Tower concentrating solar power class based on SSC’s MSPT (molten salt power tower) model

Parameters:
  • site – Power source site information

  • config – Tower CSP configuration

site: SiteInfo
config: TowerConfig
optimize_field_before_sim: bool
set_params_from_files()

Loads default case parameters from files

scale_params(params_names: list = ['tank_heaters', 'tank_height'])

Scales SSC MSPT input parameters that don’t automatically scale with plant capacity.

Parameters:
  • params_names – list of parameters to be scaled. The following variable scaling is supported:

  • ========================================= (==================== =====================================)

  • Method (Parameter Names Definition)

  • =========================================

  • capacity (tank_heaters Rated heater capacity for TES tanks linearly with respect to TES)

  • ratio (tank_height Height of HTF when tank is full constant aspect)

  • receiver (helio_size Heliostat height and width approximating based on a approx.)

  • area (helio_parasitics Heliostat parasitic power linearly with respect to heliostat)

  • velocity (tube_size Receiver tube diameter scaled for specified target)

  • =========================================

create_field_layout_and_simulate_flux_eta_maps(optimize_tower_field: bool = False)

Creates heliostats field layout and simulates receiver flux efficiency maps to be stored.

Parameters:

optimize_tower_field – If True, SolarPilot’s field and tower height optimization will before system simulation, o.w., SolarPilot will just generate field based on inputs.

optimize_field_and_tower()

Optimizes heliostat field, tower height, and receiver geometry (diameter and height). This method uses SolarPILOT’s internal optimization methods.

Note

We believe there is a memory leak when calling SolarPILOT’s optimization routine. This is not problematic when running a single hybrid simulation. However, this can be a problem when iterating HOPP for optimization.

generate_field()

Generates heliostat field based on current parameter values using SolarPilot.

setup_performance_model()

Sets up tower heliostat field then runs CSP setup function.

Note

Set-up functions musted be called before calculate_installed_cost()

calculate_total_installed_cost() float

Calculates CSP plant’s total installed costs using SAM’s technology specific cost calculators

Returns:

Total installed cost [$]

Note

This must be called after heliostat field layout is created

estimate_receiver_pumping_parasitic(nonheated_length=0.2)

Estimates receiver pumping parasitic power for dispatch parameter

Parameters:

nonheated_length – percentage of non-heated length for the receiver

Returns:

Receiver pumping power per thermal rating [MWe/MWt]

get_receiver_design_mass_flow()

Calculates receiver mass flow rate based on design temperature conditions.

Returns:

Receiver design mass flow rate [kg/s]

get_density_htf(TC: float)

Calculates HTF density based on temperature.

Note

Currently, only Salt (60% NaNO3, 40% KNO3) is supported by this function.

Parameters:

TC – HTF temperature [C]

Returns:

HTF density [kg/m^3]

get_visc_htf(TC: float)

Calculates HTF viscosity based on temperature.

Note

Currently, only Salt (60% NaNO3, 40% KNO3) is supported by this function.

Parameters:

TC – HTF temperature [C]

Returns:

HTF viscosity [kg/m-s]

static get_plant_state_io_map() dict

Gets CSP plant state inputs (initial state) and outputs (last state) variables

Returns:

Dictionary with the key-value pairs correspond to inputs and outputs, respectively

set_initial_plant_state() dict

Sets CSP plant initial state based on SSC initial conditions.

Note

This assumes the receiver and the power cycle are initially off

Returns:

Dictionary containing plant state variables to be set in SSC

set_tes_soc(charge_percent)

Sets CSP plant TES state-of-charge

Parameters:

charge_percent – Initial fraction of available volume that is hot [%]

property solar_multiple: float

Solar field thermal rating over the cycle thermal rating (design conditions) [-]

property cycle_thermal_rating: float

Design cycle thermal rating [MWt]

property field_thermal_rating: float

Design solar field thermal rating [MWt]

property cycle_nominal_efficiency: float

Cycle design gross efficiency [-]

property number_of_reflector_units: float

Returns number of heliostats within the field

property minimum_receiver_power_fraction: float

Returns minimum receiver mass flow rate turn down fraction.

property field_tracking_power: float

Returns power load for field to track sun position in MWe

property htf_cold_design_temperature: float

Returns cold design temperature for HTF [C]

property htf_hot_design_temperature: float

Returns hot design temperature for HTF [C]

__init__(site: SiteInfo, config: TowerConfig) None

Method generated by attrs for class TowerPlant.

_get_model_dict() dict

Convenience method that wraps the attrs.asdict method. Returns the object’s parameters as a dictionary.

Returns:

The provided or default, if no input provided, model settings as a dictionary.

Return type:

dict

property _system_model

Used for dispatch to mimic other dispatch class building in hybrid dispatch builder

property annual_energy_kwh: float

Annual energy [kWh]

as_dict() dict

Creates a JSON and YAML friendly dictionary that can be save for future reloading. This dictionary will contain only Python types that can later be converted to their proper Turbine formats.

Returns:

All key, vaue pais required for class recreation.

Return type:

dict

assign(input_dict: dict)

Sets input variables in the PowerSource class or any of its subclasses (system or financial models)

property benefit_cost_ratio: float

Benefit cost ratio [-] = Benefits / Costs

Benefits include (using present values):

  1. PPA, capacity payment, and curtailment revenues

  2. Federal, state, utility, and other production-based incentive income

  3. Salvage value

Costs: uses the present value of annual costs

calc_capacity_credit_percent(interconnect_kw: float) float

Calculates the capacity credit (value) using the last simulated year’s max feasible generation profile.

Parameters:

interconnect_kw – Interconnection limit [kW]

Returns:

capacity value [%]

calc_gen_max_feasible_kwh(interconnect_kw, cap_cred_avail_storage: bool = True) List[float]

Calculates the maximum feasible generation profile that could have occurred.

Timesteps that include startup (or could include startup if off and counting the potential of any stored energy) are a complication because three operating modes could exist in the same timestep (off, startup, on). This makes determining how long the power block (pb) is on, and thus its precise max generating potential, currently undetermined.

Parameters:
  • interconnect_kw – Interconnection limit [kW]

  • cap_cred_avail_storage – bool if capacity credit should be based on available storage (true), o.w. based on generation profile only (false)

Returns:

list of floats, maximum feasible generation [kWh]

calc_nominal_capacity(interconnect_kw: float)

Calculates the nominal AC net system capacity based on specific technology.

Parameters:

interconnect_kw – Interconnection limit [kW]

Returns:

system’s nominal AC net capacity [kW]

property capacity_credit_percent: float

Capacity credit (eligible portion of nameplate) [%]

property capacity_factor: float

System capacity factor [%]

property capacity_payment: list

Capacity payment revenue [$]

property capacity_price: list

Capacity payment price [$/MW]

property construction_financing_cost: float
copy()
Returns:

new instance

property cost_installed: float

Net capital cost [$]

property cycle_capacity_kw: float

Gross power cycle design rating [kWe]

cycle_efficiency_tables: dict
property debt_payment: tuple

Debt total payment [$]

property degradation: tuple

Annual energy degradation [%/year]

property dispatch

Dispatch object

property dispatch_factors: tuple

Time-series dispatch factors normalized by PPA price [-]

property energy_purchases: tuple

Energy purchases from grid [$]

property energy_sales: tuple

PPA revenue gross [$]

property energy_value: tuple

PPA revenue net [$]

export()
Returns:

dictionary of variables for system and financial

property federal_depreciation_total: tuple

Total federal tax depreciation [$]

property federal_taxes: tuple

Federal tax benefit (liability) [$]

classmethod from_dict(data: dict)

Maps a data dictionary to an attr-defined class.

TODO: Add an error to ensure that either none or all the parameters are passed in

Parameters:

data – dict The data dictionary to be mapped.

Returns:

cls

The attr-defined class.

property gen_max_feasible: list

Maximum feasible generation profile that could have occurred (year 1)

property generation_profile: list

System power generated [kW]

get_construction_financing_cost() float

Calculates construction financing costs based on default SAM assumptions.

Returns:

Construction financing cost [$]

get_cp_htf(tc, is_tes=True) float

Gets fluid’s specific heat at temperature

Note

Currently, this function only supports the following fluids:

  1. Salt (60% NaNO3, 40% KNO3)

  2. Nitrate_Salt

  3. Therminol_VP1

Parameters:
  • tc – fluid temperature in celsius

  • is_tes – is this the TES fluid (true) or the field fluid (false)

Returns:

HTF specific heat at temperature TC in [J/kg/K]

get_cycle_design_mass_flow() float

Returns CSP cycle design HTF mass flow rate

get_cycle_load(time_hr: int) float

Gets cycle thermal loading at a specified time.

Parameters:

time_hr – Hour in SSC simulation to get cycle thermal loading

Returns:

Cycle thermal loading normalized by cycle thermal rating [-]

get_design_storage_mass() float

Returns active storage mass [kg]

classmethod get_model_defaults() Dict[str, Any]

Produces a dictionary of the keyword arguments and their defaults.

Returns:

Dictionary of keyword argument: default.

Return type:

Dict[str, Any]

get_tes_soc(time_hr: int) float

Gets TES state-of-charge percentage at a specified time.

Parameters:

time_hr – Hour in SSC simulation to get TES state-of-charge

Returns:

TES state-of-charge percentage [%]

static import_financial_model(financial_model, system_model, config_name)
property initial_tes_hot_mass_fraction: float

Returns initial thermal energy storage fraction of mass in hot tank [-]

initialize_financial_values()

These values are provided as default values from PySAM but should be customized by user

Debt, Reserve Account and Construction Financing Costs are initialized to 0 Federal Bonus Depreciation also initialized to 0

initialize_params()

Initializes SSC parameters using default values stored in files.

property insurance_expense: tuple

Insurance expense [$]

property internal_rate_of_return: float

Internal rate of return (after-tax) [%]

property levelized_cost_of_energy_nominal: float

Levelized cost (nominal) [cents/kWh]

property levelized_cost_of_energy_real: float

Levelized cost (real) [cents/kWh]

property logger
property net_present_value: float

After-tax cumulative NPV [$]

property om_capacity

Capacity-based O&M amount [$/kWcap]

property om_capacity_expense

O&M capacity-based expense [$]

property om_fixed

Fixed O&M annual amount [$/year]

property om_fixed_expense

O&M fixed expense [$]

property om_production

Production-based O&M amount [$/Mwh]

property om_total_expense

Total operating expenses [$]

property om_variable

Production-based O&M amount [$/kWh] For battery: production-based System Costs amount [$/kWh-discharged]

Type:

For non-battery technologies

property om_variable_expense

O&M production-based expense [$]

outputs: CspOutputs
param_file_paths(relative_path: str)

Converts relative paths to absolute for files containing SSC default parameters.

Parameters:

relative_path – Relative path to data files

param_files: Dict[str, str]
plant_state: dict
plot(figure=None, axes=None, color='b', site_border_color='k', site_alpha=0.95, linewidth=4.0)
property ppa_price: tuple

PPA price [$/kWh]

run_year_for_max_thermal_gen() dict

Call PySSC to estimate solar thermal resource for the whole year for dispatch model

Note

Solar field production is “forecasted” by setting TES hours to 100 and receiver start-up time and energy to very small values.

Returns:

SSC’s output dictionary containing the previous simulation results

Return type:

ssc_outputs

set_cycle_efficiency_tables(ssc_outputs: dict)

Sets cycle off-design performance tables from PySSC outputs.

Parameters:

ssc_outputs – SSC’s output dictionary containing simulation results

set_cycle_load(load_fraction: float)

Sets cycle initial thermal loading

Parameters:

load_fraction – Thermal loading normalized by cycle thermal rating [-]

set_cycle_state(is_on: bool = True)

Sets cycle initial state

Parameters:

is_on – True if cycle is initially on, False otherwise

set_dispatch_targets(n_periods: int)

Set PySSC targets using dispatch model solution.

Parameters:

n_periods – Number of hours to simulate [hrs]

set_overnight_capital_cost(overnight_capital_cost)

Set overnight capital costs [$/kW].

set_plant_state_from_ssc_outputs(ssc_outputs: dict, seconds_relative_to_start: int)

Sets CSP plant state variables based on SSC outputs dictionary

Parameters:
  • ssc_outputs – SSC’s output dictionary containing the previous simulation results

  • seconds_relative_to_start – Seconds relative to SSC simulation start to get CSP plant states

set_solar_thermal_resource(ssc_outputs: dict)

Sets receiver estimated thermal resource using ssc outputs

Parameters:

ssc_outputs – SSC’s output dictionary containing simulation results

set_weather(weather_df: DataFrame, start_datetime: datetime | None = None, end_datetime: datetime | None = None)

Sets ‘solar_resource_data’ for pySSC simulation. If start and end (datetime) are not provided, full year is assumed.

Parameters:
  • weather_df – weather information

  • start_datetime – start of pySSC simulation

  • end_datetime – end of pySSC simulation

simulate(interconnect_kw: float, project_life: int = 25, skip_fin=False)

Overrides PowerSource function to ensure it cannot be called

simulate_financials(interconnect_kw: float, project_life: int = 25, cap_cred_avail_storage: bool = True)

Sets-up and simulates financial model for CSP plants

Parameters:
  • interconnect_kw – Interconnection limit [kW]

  • project_life – (optional) Analysis period [years]

  • cap_cred_avail_storage – Base capacity credit on available storage (True), otherwise use only dispatched generation (False)

simulate_power() dict

Runs CSP system model simulate

Returns:

SSC results dictionary

simulate_with_dispatch(n_periods: int, sim_start_time: int, store_outputs: bool = True)

Simulate CSP system using dispatch solution as targets

Parameters:
  • n_periods – Number of hours to simulate [hrs]

  • sim_start_time – Start hour of simulation horizon

  • store_outputs – When True SSC and dispatch results are stored in CspOutputs, o.w. they are not stored

solar_thermal_resource: list
ssc: PysscWrap | PysamWrap | None
property system_capacity_kw: float

Gross power cycle design rating [kWe]

property system_nameplate_mw: float

System nameplate [MW]

property tax_incentives: list

The sum of Federal and State PTC and ITC tax incentives [$]

property tes_capacity: float

TES energy capacity [MWt-hr]

property tes_hours: float

Equivalent full-load thermal storage hours [hr]

tmy3_to_df()

Parses TMY3 solar resource file (from SiteInfo) and coverts data to a Pandas DataFrame

Note

Be careful of leading spaces in the column names, they are hard to catch and break the parser

Returns:

Weather file data (DataFrame)

property total_installed_cost: float

Installed cost [$]

property total_revenue: list

Total revenue [$]

update_ssc_inputs_from_plant_state()

Updates SSC inputs from CSP plant state attribute

value(var_name, var_value=None)

Overrides PowerSource.value to enable the use of PySSC rather than PySAM. Method looks in system model (PySSC) first. If unsuccessful, then it looks in the financial model (PySAM).

Note

If system and financial models contain a variable with the same name, only the system model variable will be set.

value(var_name) Gets variable value

value(var_name, var_value) Sets variable value

Parameters:
  • var_name – PySSC or PySAM variable name

  • var_value – (optional) PySAM variable value

Returns:

Variable value (when getter)

class hopp.simulation.technologies.csp.tower_plant.TowerConfig(cycle_capacity_kw: float, solar_multiple: float, tes_hours: float, fin_model: dict | Singleowner | CustomFinancialModel | None = None, tech_name: str = 'tcsmolten_salt', optimize_field_before_sim: bool = True, scale_input_params: bool = False, name: str = 'TowerPlant')

Bases: CspConfig

Configuration class for TowerPlant.

Parameters:
  • cycle_capacity_kw – Power cycle design turbine gross output [kWe]

  • solar_multiple – Solar multiple [-]

  • tes_hours – Full load hours of thermal energy storage [hrs]

  • fin_model – Financial model for the specific technology

  • optimize_field_before_sim – If True, SolarPilot’s field and tower height optimization will before system simulation, o.w., SolarPilot will just generate field based on inputs.

  • scale_input_params – If True, HOPP will run hopp.simulation.technologies.csp.tower_plant.scale_params() before system simulation.

tech_name: str
optimize_field_before_sim: bool
scale_input_params: bool
name: str
__init__(cycle_capacity_kw: float, solar_multiple: float, tes_hours: float, fin_model: dict | Singleowner | CustomFinancialModel | None = None, tech_name: str = 'tcsmolten_salt', optimize_field_before_sim: bool = True, scale_input_params: bool = False, name: str = 'TowerPlant') None

Method generated by attrs for class TowerConfig.

_get_model_dict() dict

Convenience method that wraps the attrs.asdict method. Returns the object’s parameters as a dictionary.

Returns:

The provided or default, if no input provided, model settings as a dictionary.

Return type:

dict

as_dict() dict

Creates a JSON and YAML friendly dictionary that can be save for future reloading. This dictionary will contain only Python types that can later be converted to their proper Turbine formats.

Returns:

All key, vaue pais required for class recreation.

Return type:

dict

cycle_capacity_kw: float
fin_model: dict | FinancialModelType | None
classmethod from_dict(data: dict)

Maps a data dictionary to an attr-defined class.

TODO: Add an error to ensure that either none or all the parameters are passed in

Parameters:

data – dict The data dictionary to be mapped.

Returns:

cls

The attr-defined class.

classmethod get_model_defaults() Dict[str, Any]

Produces a dictionary of the keyword arguments and their defaults.

Returns:

Dictionary of keyword argument: default.

Return type:

Dict[str, Any]

property logger
solar_multiple: float
tes_hours: float