diff --git a/hopp/simulation/technologies/grid.py b/hopp/simulation/technologies/grid.py index a080061ab..965724f07 100644 --- a/hopp/simulation/technologies/grid.py +++ b/hopp/simulation/technologies/grid.py @@ -118,10 +118,15 @@ def simulate_grid_connection( """ if self.site.follow_desired_schedule: # Desired schedule sets the upper bound of the system output, any over generation is curtailed - lifetime_schedule: NDArrayFloat = np.tile([ - x * 1e3 for x in self.site.desired_schedule], - int(project_life / (len(self.site.desired_schedule) // self.site.n_timesteps)) - ) + if self.site.curtailment_value_type == "grid": + lifetime_schedule: NDArrayFloat = np.tile([self.interconnect_kw], + len(total_gen)) + elif self.site.curtailment_value_type == "desired_schedule": + lifetime_schedule: NDArrayFloat = np.tile([ + x * 1e3 for x in self.site.desired_schedule], + int(project_life / (len(self.site.desired_schedule) // self.site.n_timesteps)) + ) + self.generation_profile = list(np.minimum(total_gen, lifetime_schedule)) # TODO: remove list() cast once parent class uses numpy self.missed_load = np.array([schedule - gen if gen > 0 else schedule for (schedule, gen) in @@ -189,7 +194,7 @@ def simulate_grid_connection( logger.info('Total number of hours available for ERS: ', np.round(self.total_number_hours,2)) else: - self.generation_profile = total_gen + self.generation_profile = total_gen #actual self.total_gen_max_feasible_year1 = np.array(total_gen_max_feasible_year1) self.system_capacity_kw = hybrid_size_kw # TODO: Should this be interconnection limit? diff --git a/hopp/simulation/technologies/sites/site_info.py b/hopp/simulation/technologies/sites/site_info.py index 026c383c0..07c1649dd 100644 --- a/hopp/simulation/technologies/sites/site_info.py +++ b/hopp/simulation/technologies/sites/site_info.py @@ -55,7 +55,9 @@ class SiteInfo(BaseClass): solar: Whether to set solar data for this site. Defaults to True. wind: Whether to set wind data for this site. Defaults to True. wave: Whether to set wave data for this site. Defaults to True. + renewable_resource_origin: Whether to use API to download resource or pull from databases hosted on HPC, defaults to API wind_resource_origin: Which wind resource API to use, defaults to WIND Toolkit + curtailment_value_type: whether to curtail power above grid interconnection limit or desired schedule """ # User provided data: dict @@ -66,6 +68,8 @@ class SiteInfo(BaseClass): hub_height: hopp_float_type = field(default=97., converter=hopp_float_type) capacity_hours: NDArray = field(default=[], converter=converter(bool)) desired_schedule: NDArrayFloat = field(default=[], converter=converter()) + curtailment_value_type: str = field(default="desired_schedule", validator=contains(["grid", "desired_schedule"])) + solar: bool = field(default=True) wind: bool = field(default=True) wave: bool = field(default=False) @@ -131,7 +135,11 @@ def __attrs_post_init__(self): self.tz = data['tz'] if self.solar: - self.solar_resource = SolarResource(data['lat'], data['lon'], data['year'], filepath=self.solar_resource_file) + if self.renewable_resource_origin=="API": + self.solar_resource = SolarResource(data['lat'], data['lon'], data['year'], filepath=self.solar_resource_file) + else: + from hopp.simulation.technologies.resource.nsrdb_data import HPCSolarData + self.solar_resource = HPCSolarData(data['lat'], data['lon'], data['year'],filepath=self.solar_resource_file) self.n_timesteps = len(self.solar_resource.data['gh']) // 8760 * 8760 if self.wave: self.wave_resource = WaveResource(data['lat'], data['lon'], data['year'], filepath = self.wave_resource_file) @@ -139,8 +147,13 @@ def __attrs_post_init__(self): if self.wind: # TODO: allow hub height to be used as an optimization variable - self.wind_resource = WindResource(data['lat'], data['lon'], data['year'], wind_turbine_hub_ht=self.hub_height, - filepath=self.wind_resource_file, source=self.wind_resource_origin) + if self.renewable_resource_origin=="API": + self.wind_resource = WindResource(data['lat'], data['lon'], data['year'], wind_turbine_hub_ht=self.hub_height, + filepath=self.wind_resource_file, source=self.wind_resource_origin) + else: + from hopp.simulation.technologies.resource.wind_toolkit_data import HPCWindData + self.wind_resource = HPCWindData(data['lat'], data['lon'], data['year'], wind_turbine_hub_ht=self.hub_height, + filepath=self.wind_resource_file) n_timesteps = len(self.wind_resource.data['data']) // 8760 * 8760 if self.n_timesteps is None: self.n_timesteps = n_timesteps