diff --git a/dataprocessing/eGo_data_processing.py b/dataprocessing/eGo_data_processing.py index a4d1c138..f107dceb 100644 --- a/dataprocessing/eGo_data_processing.py +++ b/dataprocessing/eGo_data_processing.py @@ -4,7 +4,7 @@ Also see corresponding BPML diagram. """ -__copyright__ = "Reiner Lemoine Institut" +__copyright__ = "Reiner Lemoine Institut gGmbH" __license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" __url__ = "https://github.com/openego/data_processing/blob/master/LICENSE" __author__ = "gplssm, Ludee" @@ -89,23 +89,29 @@ def data_processing(): # 'rea/ego_dp_rea_results.sql', # Results and statistics ## POWERFLOW -# 'ego_dp_powerflow_assignment_otgid.sql', # assign otg_id to pp lists -# 'ego_dp_powerflow_assignment_unid.sql', # create a unified_id over all pp (res and conv) -# 'ego_dp_powerflow_create_pp_mview.sql', # create mviews to display power plants per scenario -# 'ego_dp_powerflow_hv_setup.sql', # Set schema/tables for EHV/HV powerflow calculations up -# 'ego_dp_powerflow_osmtgmod_to_pypsa.sql', # Include data from osmTGmod into EHV/HV powerflow schema -# 'ego_dp_powerflow_electrical_neighbour.sql', # Create border crossing lines and buses in neighbouring countries -# 'ego_dp_powerflow_fix_ehv_subnetworks.sql', # Fix topological errors in eHV grid -# 'ego_dp_powerflow_grid_future_scenarios.sql', # Copy grid to future scenarios -# 'ego_dp_powerflow_assignment_generator.sql', # Assign generators to corresponding substation (SQ, NEP2035, eGo100) -# 'ego_dp_powerflow_assignment_load.sql', # Assign loads to their corresponding substation (SQ, NEP2035, eGo100) -# 'ego_dp_powerflow_assignment_storage.sql', # Assign storages to their corresponding substation (SQ, NEP 2035, eGo 100) -# 'ego_dp_powerflow_timeseries_generator.sql', # Transfer renpassG!S results into the corresponding powerflow table -# 'ego_dp_powerflow_griddistrict_demand.py', # Demand per MV Griddistrict -# 'ego_dp_powerflow_timeseries_demand.sql', # Insert demand series into corresponding powerflow table (SQ, NEP2035, eGo100) -# 'ego_dp_powerflow_lopf_data.sql', # Set marginal costs for generators and storages - - +# 'ego_dp_powerflow_assignment_otgid.sql', # assign otg_id to pp lists +# 'ego_dp_powerflow_assignment_unid.sql', # create a unified_id over all pp (res and conv) +# 'ego_dp_powerflow_create_pp_mview.sql', # create mviews to display power plants per scenario +# 'ego_dp_powerflow_hv_setup.sql', # Set schema/tables for EHV/HV powerflow calculations up +# 'ego_dp_powerflow_osmtgmod_to_pypsa.sql', # Include data from osmTGmod into EHV/HV powerflow schema +# 'ego_dp_powerflow_electrical_neighbour.sql', # Create border crossing lines and buses in neighbouring countries +# 'ego_dp_powerflow_fix_ehv_subnetworks.sql', # Fix topological errors in eHV grid +# 'ego_dp_powerflow_grid_future_scenarios.sql', # Copy grid to future scenarios +# 'ego_dp_powerflow_assignment_generator.sql', # Assign generators to corresponding substation (SQ, NEP2035, eGo100) +# 'ego_dp_powerflow_create_generator_neighbours.py', # Create generators for neighbouring countries (SQ, NEP2035, eGo100) +# 'ego_dp_powerflow_assignment_load.sql', # Assign loads to their corresponding substation (SQ, NEP2035, eGo100) +# 'ego_dp_powerflow_create_load_neighbours.sql', # Create loads for neighouring countries (SQ, NEP2035, eGo100) +# 'ego_dp_powerflow_assignment_storage.sql', # Assign storages to their corresponding substation (SQ, NEP 2035, eGo 100) +# 'ego_dp_powerflow_timeseries_generator_de_p_set.py' # Assign p_sets for Germany based on renpassG!S optimization results (SQ, NEP 2035, eGo 100) +# 'ego_dp_powerflow_timeseries_generator_other_p_set.py' # Assign p_sets for neighbouring countries based on renpassG!S optimization results (SQ, NEP 2035, eGo 100) +# 'ego_dp_powerflow_timeseries_generator_de_p_max_pu.py' # Assign p_max_pu based on feedin timeseries data (Germany) (SQ, NEP 2035, eGo 100) +# 'ego_dp_powerflow_timeseries_generator_other_p_max_pu.py' # Assign p_max_pu based on feedin timeseries data (Neighbouring Countries) (SQ, NEP 2035, eGo 100) +# 'ego_dp_powerflow_timeseries_generator_offshore_p_max_pu.py' # Assign p_max_pu based on feedin timeseries data (Neighbouring countries Offshore) (SQ, NEP 2035, eGo 100) +# 'ego_dp_powerflow_griddistrict_demand.py', # Demand per MV Griddistrict +# 'ego_dp_powerflow_timeseries_demand.sql', # Insert demand series into corresponding powerflow table (SQ, NEP2035, eGo100) +# 'ego_dp_powerflow_lopf_data.sql', # Set marginal costs for generators and storages + + ## VERSIONING # 'ego_dp_versioning.sql', # Versioning # 'ego_dp_versioning_mviews.sql' , # Versioning of mviews @@ -113,7 +119,7 @@ def data_processing(): ## POST-PROCESSING # 'post_processing/ego_pp_nep2035_grid_variations.sql' # Create extension_tables and insert NEP-data - + ## VACUUM FULL # 'ego_dp_vacuum_full.sql' ] diff --git a/dataprocessing/python_scripts/ego_dp_powerflow_create_generator_neighbours.py b/dataprocessing/python_scripts/ego_dp_powerflow_create_generator_neighbours.py new file mode 100644 index 00000000..ff97f8c0 --- /dev/null +++ b/dataprocessing/python_scripts/ego_dp_powerflow_create_generator_neighbours.py @@ -0,0 +1,124 @@ +""" Transfer scenario definition as defined in FlEnS open_eGo scenarios +of LinearTransformers and Sources to eGo powerflow generator table. +""" + +__copyright__ = "ZNES Flensburg" +__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" +__url__ = "https://github.com/openego/data_processing/blob/master/LICENSE" +__author__ = "wolfbunke" + +import pandas as pd + +from dataprocessing.tools.io import oedb_session +from dataprocessing.python_scripts.functions.ego_scenario_log import write_ego_scenario_log +from sqlalchemy.orm import sessionmaker +from ego_dp_powerflow_timeseries_generator_helper import OBJ_LABEL_TO_SOURCE, SCENARIOMAP, \ + TEMPID, NEIGHBOURSID, _flatten, map_on_partial_string, missing_orm_classes +from egoio.db_tables.model_draft import EgoGridPfHvGenerator as Generator, \ + EgoGridHvElectricalNeighboursBus as Neighbour + +conn = oedb_session(section='test') +Session = sessionmaker(bind=conn) +session = Session() + +# obligatory delete statement based on NEIGHBOURSID +session.query(Generator).filter(Generator.generator_id >= NEIGHBOURSID).\ + delete(synchronize_session='fetch') + +############################################################################### + +*_, Transformer, Source, Results = missing_orm_classes(session) + +# get DataFrame each row representing one electrical neighbour by applying +# filter on id and v_nom, not affected by scenario name +query = session.query(Neighbour) +neighbours = pd.read_sql(query.statement, query.session.bind) + +ix = (neighbours['id'] <= 27) & (neighbours['v_nom'] == 380) +neighbours = neighbours.loc[ix, :] +neighbours.set_index('cntr_id', inplace=True) + +# for each scenario +logged = 0 +for scn_name, scn_nr in SCENARIOMAP.items(): + + # get renpass_gis scenario data on linear transformers. Parameters are + # defined on those edges directed from the component to the bus. + filters = [Transformer.scenario_id == scn_nr, + ~Transformer.source.like('%powerline%'), + Transformer.label == Transformer.source] # direction + + query = session.query(Transformer).filter(*filters) + transformers = pd.read_sql(query.statement, query.session.bind) + transformers['type'] = 'linear transformer' + + # get data on sources + filters = [Source.scenario_id == scn_nr, ~Source.label.like('GL%')] + query = session.query(Source).filter(*filters) + sources = pd.read_sql(query.statement, query.session.bind) + sources['type'] = 'source' + + # sources and transformers, distinct in renpass_gis, are both seen as + # generators and can be handled together + generators = pd.concat([sources, transformers], ignore_index=True) + + # parameters in renpass_gis are not necessarily scalars and stored in lists + # lists of len one are flattened + generators = generators.applymap(_flatten) + + # 0 does not equal zero. In case a class with zero nominal value + # should be defined for the purpose of scenario definition very small + # values are used in the scenario files. + ix = generators['nominal_value'] < 1e-7 + generators = generators.loc[~ix, :] + + # source in the context of eGo has a different meaning. The column has to + # be renamed + generators.rename(columns={'source': 'renpass_gis_source'}, inplace=True) + + # rename nominal_value to p_nom + generators.rename(columns={'nominal_value': 'p_nom'}, inplace=True) + + # map from obj label string -> source + generators['source'] = map_on_partial_string( + generators['label'], {i: k for k, i in OBJ_LABEL_TO_SOURCE.items()}) + + generators['cntr_id'] = generators['label'].str[:2] + + # exclude Germany + generators = generators.loc[generators['cntr_id'] != 'DE', :] + + # exclude unmatched sources + generators = generators.loc[~generators['source'].isnull(), :] + + # assign bus_ids according to neighbours DataFrame + generators['bus'] = generators['cntr_id'].map(neighbours['bus_id']) + + # set control, and dispatch parameter + generators['control'] = 'PV' + generators['dispatch'] = generators['type'].map( + {'linear transformer': 'flexible', 'source': 'variable'}) + + # set scenario name, temporal id + generators['scn_name'] = scn_name + generators['temp_id'] = TEMPID + generators['generator_id'] = generators.index + NEIGHBOURSID + + # prepare DataFrames to be exported + generator_ex = generators[ + ['scn_name', 'generator_id', 'bus', 'dispatch', 'control', 'source', + 'p_nom']] + + # write to db + for i in generator_ex.to_dict(orient='records'): + session.add(Generator(**i)) + + session.commit() + +write_ego_scenario_log(conn=conn, + version='v0.4.0', + io='input', + schema='model_draft', + table=Generator.__tablename__, + script=__file__, + entries=logged) diff --git a/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_de_p_max_pu.py b/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_de_p_max_pu.py new file mode 100644 index 00000000..e89b4305 --- /dev/null +++ b/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_de_p_max_pu.py @@ -0,0 +1,86 @@ +""" This script assigns feedin timeseries data generated with feedinlib +as p_max_pu parameter to high-voltage powerflow generators within Germany. +""" + +__copyright__ = "ZNES Flensburg" +__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" +__url__ = "https://github.com/openego/data_processing/blob/master/LICENSE" +__author__ = "wolfbunke" + +import pandas as pd + +from dataprocessing.tools.io import oedb_session +from sqlalchemy.orm import sessionmaker +from sqlalchemy import case +from dataprocessing.python_scripts.functions.ego_scenario_log \ + import write_ego_scenario_log + +from egoio.db_tables.model_draft import EgoSupplyPfGeneratorSingle \ + as GeneratorSingle, EgoGridPfHvGeneratorPqSet as PqSet +from ego_dp_powerflow_timeseries_generator_helper import OBJ_LABEL_TO_SOURCE, SCENARIOMAP, \ + TEMPID, missing_orm_classes + +# Get database connection +conn = oedb_session(section='test') +Session = sessionmaker(bind=conn) +session = Session() + +_, PowerClass, Feedin, *_, Results = missing_orm_classes(session) + +logged = 0 +for scn_name, scn_nr in SCENARIOMAP.items(): + + # Select the correct sources + # Map source_id to feedin source name + sources = ['wind_onshore', 'wind_offshore', 'solar'] + sources_dict = { + k: v for k, v in OBJ_LABEL_TO_SOURCE.items() if k in sources} + + # Wrap case around feedin source to return source_id instead of name + casestr = case(sources_dict, value=Feedin.source, else_=None) + + # Get a unique represenation of PfGeneratorSingle with regard to aggr_id, + # source, w_id, power_class + filters = ( + GeneratorSingle.scn_name == scn_name, GeneratorSingle.aggr_id != None) + fields = [GeneratorSingle.aggr_id, GeneratorSingle.source, + GeneratorSingle.w_id, GeneratorSingle.power_class] + grouper = GeneratorSingle.aggr_id, GeneratorSingle.source,\ + GeneratorSingle.w_id, GeneratorSingle.power_class + + # Construct a subquery with filters, fields and grouper + t = session.query(*fields).group_by(*grouper).filter(*filters).subquery() + + # Use subquery and Feedin table to get the correct feedin for each + # generator + query = session.query(t, Feedin.feedin.label('p_max_pu')).filter( + t.c.w_id == Feedin.w_id, t.c.power_class == Feedin.power_class, + t.c.source == casestr) + + generators = pd.read_sql(query.statement, query.session.bind) + + # Substation's aggr_id are the basis for generators in high-voltage + # powerflow + # Rename column aggr_id to generator_id + generators.rename(columns={'aggr_id': 'generator_id'}, inplace=True) + + generators['temp_id'] = TEMPID + generators['scn_name'] = scn_name + + # Select fields for PqSets + # Write PqSets to database + fields = ['generator_id', 'p_max_pu', 'scn_name', 'temp_id'] + for i in generators[fields].to_dict(orient='records'): + session.add(PqSet(**i)) + + session.commit() + + logged += len(generators) + +write_ego_scenario_log(conn=conn, + version='v0.4.0', + io='input', + schema='model_draft', + table=PqSet.__tablename__, + script=__file__, + entries=logged) diff --git a/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_de_p_set.py b/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_de_p_set.py new file mode 100644 index 00000000..8ab94175 --- /dev/null +++ b/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_de_p_set.py @@ -0,0 +1,129 @@ +""" +This script assign optimized dispatch timeseries data based on renpassG!S +results to generators in the high-voltage powerflow tables. +""" + +__copyright__ = "ZNES Flensburg" +__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" +__url__ = "https://github.com/openego/data_processing/blob/master/LICENSE" +__author__ = "wolfbunke" + +import pandas as pd +import numpy as np +import logging + +from dataprocessing.tools.io import oedb_session +from dataprocessing.python_scripts.functions.ego_scenario_log import write_ego_scenario_log +from sqlalchemy.orm import sessionmaker + +from egoio.db_tables.model_draft import EgoGridPfHvGenerator as Generator, \ + EgoGridPfHvGeneratorPqSet as PqSet +from ego_dp_powerflow_timeseries_generator_helper import OBJ_LABEL_TO_SOURCE, SCENARIOMAP, \ + TEMPID, missing_orm_classes, NEIGHBOURSID + +# get database connection +conn = oedb_session(section='test') +Session = sessionmaker(bind=conn) +session = Session() + +_, PowerClass, Feedin, *_, Results = missing_orm_classes(session) + +############################################################################### + +def _norm(x): + return x / x.sum() + +# delete all from model_draft.ego_grid_pf_hv_generator_pq_set +session.query(PqSet).delete() +session.commit() + +# Assigning p_set for each scenario +logged = 0 +for scn_name, scn_nr in SCENARIOMAP.items(): + + # model_draft.ego_grid_pf_hv_generator -> pd.DataFrame + query = session.query(Generator).filter( + Generator.scn_name == scn_name, Generator.generator_id < NEIGHBOURSID) + generators = pd.read_sql(query.statement, query.session.bind) + + assert set(generators['source'].isnull()) == {False}, "Source field empty in generators table." + + # create fraction of nominal power to total nominal power for each source + generators['p_nom_fraction'] = generators.groupby('source')['p_nom'].\ + apply(_norm) + + # calc_renpass_gis.renpass_gis_results -> pd.DataFrame + # contains inflows to buses in Germany excluding powerlines + filters = (Results.obj_label.like('%DE%'), + ~Results.obj_label.like('%powerline%'), + Results.type == 'to_bus', + Results.scenario_id == scn_nr) + fields = Results.obj_label, Results.datetime, Results.val + query = session.query(*fields).filter(*filters) + + results = pd.read_sql(query.statement, query.session.bind) + + # map obj_label to corresponding source + results['source'] = None + for k, v in OBJ_LABEL_TO_SOURCE.items(): + idx = results['obj_label'].str.contains(k) + results.loc[idx, 'source'] = v + + # aggregate by source and datetime + # in this step generation from mixed fuels and waste is summed up + # assuming these sources have identical input parameters + results = results.groupby(['source', 'datetime'], as_index=False).sum() + + # timeseries for each component in list format + # contains excess, shortage, load, mixed fuels + results_s = results.groupby('source')['val'].apply(np.array) + + # map corresponding timeseries with each generator multiplied by fraction + # of nominal power + generators['p_set'] = generators['source'].map(results_s) * \ + generators['p_nom_fraction'] + + # https://github.com/znes/FlEnS/issues/3 + # inform the user about possible discrepancies + # dataprocessing has no logging + #for i, k in OBJ_LABEL_TO_SOURCE.items(): + # if k not in generators['source'].values: + # logging.info("%s: %s: Object label %s is not matched in powerflow." % ( + # __file__, scn_name, i)) + + #for k in generators.source.unique(): + # if k not in results_s.index: + # logging.info("%s: %s: Source %s is not matched in renpass_gis." % ( + # __file__, scn_name, int(k))) + + # test for missing values for debugging + assert set(generators['p_set'].isnull()) == {False}, "P_set field empty in generators table." + + # OR just get rid of generators with missing p_set + generators = generators[~generators['p_set'].isnull()].copy() + + # remove solar and wind + sources = [v for k, v in OBJ_LABEL_TO_SOURCE.items() if k in + ['wind_offshore', 'wind_onshore', 'solar']] + + ix = generators['source'].isin(sources) + generators = generators[~ix].copy() + + generators['temp_id'] = TEMPID + + # write PqSets to the database + fields = ['generator_id', 'p_set', 'scn_name', 'temp_id'] + for i in generators[fields].to_dict(orient='records'): + session.add(PqSet(**i)) + + session.commit() + + logged += len(generators) + +write_ego_scenario_log(conn=conn, + version='v0.4.0', + io='input', + schema='model_draft', + table=PqSet.__tablename__, + script=__file__, + entries=logged) diff --git a/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_helper.py b/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_helper.py new file mode 100644 index 00000000..d65318f0 --- /dev/null +++ b/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_helper.py @@ -0,0 +1,126 @@ +""" Helper functions and constants to handle renpass_gis tables. +""" + +__copyright__ = "ZNES Flensburg" +__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" +__url__ = "https://github.com/openego/data_processing/blob/master/LICENSE" +__author__ = "wolfbunke" + +import pandas as pd + +from geoalchemy2.types import Geometry +from sqlalchemy import MetaData, Column, Integer, Float, Text, text, BigInteger +from sqlalchemy.ext.automap import automap_base +from sqlalchemy.dialects.postgresql import ARRAY, DOUBLE_PRECISION + + +NEIGHBOURSID = 200000 + +SCENARIOMAP = {'Status Quo': 43, 'NEP 2035': 41, 'eGo 100': 40} + +# list of available fuel types in eGo scenarios +OBJ_LABEL_TO_SOURCE = { + 'gas': 1, + 'lignite': 2, + 'waste': 3, + 'mixed_fuels': 3, + 'oil': 4, + 'uranium': 5, + 'biomass': 6, + 'chp': 7, # is this correct? + 'hard_coal': 8, + 'run_of_river': 9, + 'reservoir': 10, + 'solar': 12, + 'wind_onshore': 13, + 'geothermal': 14, + 'wind_offshore': 17, + 'storage_redox_flow': 99, + 'storage_pumped_hydro': 99, + 'storage_lithium_ion': 99, + 'storage_hydrogen': 99, + 'storage_phs': 99, + 'storage_a_caes': 99, + 'load': 99, + 'shortage': 99, + 'excess': 99} + +TEMPID = 1 + + +def missing_orm_classes(session): + """ Not yet implemented in ego.io + + Parameters + ---------- + session : sqlalchemy.orm.session.Session + Handling all conversations with the database + + Notes + ----- + Relations in schema calc_renpass_gis are still not part of egoio. If this is + changed in the future this function becomes obsolete. + """ + + meta = MetaData() + meta.reflect(bind=session.bind, schema='calc_renpass_gis', + only=['renpass_gis_linear_transformer', + 'renpass_gis_source', + 'renpass_gis_results']) + + # map to classes + Base = automap_base(metadata=meta) + + # ormclasses not part of egoio yet + class EgoPowerClass(Base): + __tablename__ = 'ego_power_class' + __table_args__ = {'schema': 'model_draft'} + + power_class_id = Column(Integer, primary_key=True, server_default=text("nextval('model_draft.ego_power_class_power_class_id_seq'::regclass)")) + lower_limit = Column(Float(53)) + upper_limit = Column(Float(53)) + wea = Column(Text) + h_hub = Column(Float(53)) + d_rotor = Column(Float(53)) + + class EgoRenewableFeedin(Base): + __tablename__ = 'ego_renewable_feedin' + __table_args__ = {'schema': 'model_draft'} + + weather_scenario_id = Column(Integer, primary_key=True, nullable=False) + w_id = Column(Integer, primary_key=True, nullable=False) + source = Column(Text, primary_key=True, nullable=False) + weather_year = Column(Integer, primary_key=True, nullable=False) + power_class = Column(Integer, primary_key=True, nullable=False) + feedin = Column(ARRAY(DOUBLE_PRECISION(precision=53))) + + class EgoNeighboursOffshorePoint(Base): + __tablename__ = 'ego_neighbours_offshore_point' + __table_args__ = {'schema': 'model_draft'} + + cntr_id = Column(Text, primary_key=True) + coastdat_id = Column(BigInteger) + geom = Column(Geometry('POINT', 4326)) + + Base.prepare() + + Transformer, Source, Results = Base.classes.renpass_gis_linear_transformer, \ + Base.classes.renpass_gis_source, Base.classes.renpass_gis_results + + return EgoNeighboursOffshorePoint, EgoPowerClass, EgoRenewableFeedin, Transformer, Source, Results + + +def _flatten(x): + if isinstance(x, list): + return x[0] if len(x) == 1 else x + else: + return x + + +def map_on_partial_string(series, mapping): + """ Map mapping values to string series. """ + s = pd.Series(index=series.index) + for k, v in mapping.items(): + ix = series.str.contains(v) + s[ix] = k + return s diff --git a/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_offshore_p_max_pu.py b/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_offshore_p_max_pu.py new file mode 100644 index 00000000..4e299e6a --- /dev/null +++ b/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_offshore_p_max_pu.py @@ -0,0 +1,98 @@ +""" This script assigns offshore timeseries data generated with feedinlib +as parameter p_max_pu to high-voltage powerflow generators +in case of neighbouring countries. +""" + +__copyright__ = "ZNES Flensburg" +__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" +__url__ = "https://github.com/openego/data_processing/blob/master/LICENSE" +__author__ = "wolfbunke" + +import pandas as pd + +from dataprocessing.tools.io import oedb_session +from sqlalchemy.orm import sessionmaker +from sqlalchemy import case +from dataprocessing.python_scripts.functions.ego_scenario_log \ + import write_ego_scenario_log + +from egoio.db_tables.model_draft import \ + EgoGridPfHvGenerator as Generator, \ + EgoGridPfHvGeneratorPqSet as PqSet, \ + EgoGridHvElectricalNeighboursBus as Neighbour +from ego_dp_powerflow_timeseries_generator_helper import OBJ_LABEL_TO_SOURCE,\ + TEMPID, missing_orm_classes + +# Get database connection +conn = oedb_session(section='test') +Session = sessionmaker(bind=conn) +session = Session() + +OffshorePoints, PowerClass, Feedin, *_, Results = missing_orm_classes(session) + +# TODO: This part is used very often and could be outsourced +# Read in a DataFrame with data of neighbouring countries +# Filtered on id, v_nom +query = session.query(Neighbour) +neighbours = pd.read_sql(query.statement, query.session.bind) + +ix = (neighbours['id'] <= 27) & (neighbours['v_nom'] == 380) +neighbours = neighbours.loc[ix, :] +neighbours.set_index('cntr_id', inplace=True) + +# logging variable +logged = 0 + +# With OffshorePoints, a representation of iso-country-code to w_id, +# assign w_id to data of neighbouring countries +# Delete countries that have no w_id assigned / have no offshore generation +neighbours['w_id'] = pd.Series(dict( + session.query(OffshorePoints.cntr_id, OffshorePoints.coastdat_id).all())) +neighbours = neighbours[~neighbours['w_id'].isna()].copy() +neighbours['w_id'] = neighbours['w_id'].astype(int) + +# Map source name to source_id +sources = ['wind_offshore'] +sources_dict = {v: k for k, v in OBJ_LABEL_TO_SOURCE.items() if k in sources} + +# Map bus to w_id +bus_to_wid = dict(neighbours[['bus_id', 'w_id']].values.tolist()) + +# Wrap mapping case around Generator.bus to return w_id instead +casestr = case(bus_to_wid, value=Generator.bus, else_=None).label('w_id') + +# Retrieve existing offshore Generators +query = session.query(Generator.scn_name, Generator.bus, Generator.generator_id, casestr).filter( + Generator.bus.in_(neighbours.bus_id)).filter(Generator.source.in_(sources_dict)) + +generators = pd.read_sql(query.statement, query.session.bind) + +# Select wind_offshore feedins that match the weather_id +query = session.query( + Feedin.w_id, Feedin.feedin.label('p_max_pu')).filter( + Feedin.source.in_(sources_dict.values()), + Feedin.w_id.in_(generators.w_id), + Feedin.power_class.in_([0, 4])) +feedins = pd.read_sql(query.statement, query.session.bind) + +# Merge DataFrames on weather_id +# This is a many_to_one relation because of multiple scenarios +generators = generators.merge(feedins, on=['w_id'], how='inner', validate='many_to_one') +generators['temp_id'] = TEMPID + +# Write PqSets to the database +fields = ['generator_id', 'p_max_pu', 'scn_name', 'temp_id'] +for i in generators[fields].to_dict(orient='records'): + session.add(PqSet(**i)) + +logged += len(generators) + +session.commit() + +write_ego_scenario_log(conn=conn, + version='v0.4.0', + io='input', + schema='model_draft', + table=PqSet.__tablename__, + script=__file__, + entries=logged) diff --git a/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_other_p_max_pu.py b/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_other_p_max_pu.py new file mode 100644 index 00000000..15078c01 --- /dev/null +++ b/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_other_p_max_pu.py @@ -0,0 +1,95 @@ +""" This script assigns solar and wind_onshore data generated with feedinlib +as p_max_pu parameter to high-voltage powerflow generators for neighbouring +countries. +""" +__copyright__ = "ZNES Flensburg" +__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" +__url__ = "https://github.com/openego/data_processing/blob/master/LICENSE" +__author__ = "wolfbunke" + +import pandas as pd + +from dataprocessing.tools.io import oedb_session +from sqlalchemy.orm import sessionmaker +from sqlalchemy import case, func +from dataprocessing.python_scripts.functions.ego_scenario_log \ + import write_ego_scenario_log + +from egoio.db_tables.climate import Cosmoclmgrid +from egoio.db_tables.model_draft import \ + EgoSupplyPfGeneratorSingle as GeneratorSingle, + EgoGridPfHvGeneratorPqSet as PqSet, \ + EgoGridPfHvGenerator as Generator, \ + EgoGridPfHvGeneratorPqSet as PqSet, \ + EgoGridHvElectricalNeighboursBus as Neighbour +from ego_dp_powerflow_timeseries_generator_helper import OBJ_LABEL_TO_SOURCE, SCENARIOMAP, \ + TEMPID, missing_orm_classes + +# There is no need for a scenario loop. This can be done in one operation. + +# Get database connection +conn = oedb_session(section='test') +Session = sessionmaker(bind=conn) +session = Session() + +_, PowerClass, Feedin, *_, Results = missing_orm_classes(session) + +# Read in a DataFrame with data of neighbouring countries +# Filtered on id, v_nom +query = session.query(Neighbour) +neighbours = pd.read_sql(query.statement, query.session.bind) + +ix = (neighbours['id'] <= 27) & (neighbours['v_nom'] == 380) +neighbours = neighbours.loc[ix, :] +neighbours.set_index('cntr_id', inplace=True) + +# logging variable +logged = 0 + +# Construct a subquery with w_id, bus_id based on intersecting geometries +t = session.query(Cosmoclmgrid.gid.label('w_id'), Neighbour.bus_id).filter( + func.ST_Intersects(Cosmoclmgrid.geom, Neighbour.geom)).subquery() + +# Make a mapping from source_id to source name +sources = ['wind_onshore', 'solar'] +sources_dict = {v: k for k, v in OBJ_LABEL_TO_SOURCE.items() if k in sources} + +# Wrap mapping case around Generator.source to retrieve source name +casestr = case(sources_dict, value=Generator.source, else_=None).label('source') + +# Get generators and include w_id based on subquery, source name based on case +query = session.query( + Generator.scn_name, Generator.generator_id, casestr, t.c.w_id).filter( + Generator.bus.in_(neighbours.bus_id), t.c.bus_id == Generator.bus, + Generator.source.in_(sources_dict)) + +generators = pd.read_sql(query.statement, query.session.bind) + +# Get feedins and name timeseries p_max_pu +query = session.query( + Feedin.w_id, Feedin.source, Feedin.feedin.label('p_max_pu')).filter( + Feedin.w_id.in_(generators.w_id), Feedin.power_class.in_([0, 4])) +feedins = pd.read_sql(query.statement, query.session.bind) + +# Merge DataFrames +# Assign p_max_pu to generator based on source, w_id +# This is many to one, because of multiple scenario values +generators = generators.merge(feedins, on=['source', 'w_id'], how='inner', validate='many_to_one') +generators['temp_id'] = TEMPID + +# Construct PqSets and write to database +fields = ['generator_id', 'p_max_pu', 'scn_name', 'temp_id'] +for i in generators[fields].to_dict(orient='records'): + session.add(PqSet(**i)) + +logged += len(generators) + +session.commit() + +write_ego_scenario_log(conn=conn, + version='v0.4.0', + io='input', + schema='model_draft', + table=PqSet.__tablename__, + script=__file__, + entries=logged) diff --git a/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_other_p_set.py b/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_other_p_set.py new file mode 100644 index 00000000..b67f8105 --- /dev/null +++ b/dataprocessing/python_scripts/ego_dp_powerflow_timeseries_generator_other_p_set.py @@ -0,0 +1,110 @@ +""" +Assigns dispatch optimization results from renpassG!S to generators connected +to neighbouring countries in high-voltage powerflow tables. +""" + +__copyright__ = "ZNES Flensburg" +__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" +__url__ = "https://github.com/openego/data_processing/blob/master/LICENSE" +__author__ = "wolfbunke" + +import pandas as pd +import numpy as np + +from dataprocessing.tools.io import oedb_session +from sqlalchemy.orm import sessionmaker +from dataprocessing.python_scripts.functions.ego_scenario_log import write_ego_scenario_log +from ego_dp_powerflow_timeseries_generator_helper import \ + OBJ_LABEL_TO_SOURCE, SCENARIOMAP, TEMPID, NEIGHBOURSID, \ + map_on_partial_string, missing_orm_classes +from egoio.db_tables.model_draft import EgoGridPfHvGenerator as Generator, \ + EgoGridPfHvGeneratorPqSet as PqSet, EgoGridHvElectricalNeighboursBus as Neighbour + +conn = oedb_session(section='test') +Session = sessionmaker(bind=conn) +session = Session() + +# obligatory delete statement based on NEIGHBOURSID +session.query(PqSet).filter(PqSet.generator_id >= NEIGHBOURSID).\ + delete(synchronize_session='fetch') + + +############################################################################### + +_, PowerClass, Feedin, *_, Results = missing_orm_classes(session) + +# get DataFrame each row representing one electrical neighbour by applying +# filter on id and v_nom, not affected by scenario name +query = session.query(Neighbour) +neighbours = pd.read_sql(query.statement, query.session.bind) + +ix = (neighbours['id'] <= 27) & (neighbours['v_nom'] == 380) +neighbours = neighbours.loc[ix, :] +neighbours.set_index('cntr_id', inplace=True) + +logged = 0 +for scn_name, scn_nr in SCENARIOMAP.items(): + + # model_draft.ego_grid_pf_hv_generator -> pd.DataFrame + query = session.query(Generator).filter( + Generator.scn_name == scn_name, Generator.generator_id >= NEIGHBOURSID) + generators = pd.read_sql(query.statement, query.session.bind) + + # get corresponding optimization results from renpass_gis + # obj_label, datetime, val + filters = (~Results.obj_label.like('%DE%'), + ~Results.obj_label.like('%GL%'), + ~Results.obj_label.like('%powerline%'), + Results.type == 'to_bus', + Results.scenario_id == scn_nr) + fields = Results.obj_label, Results.datetime, Results.val + query = session.query(*fields).filter(*filters) + results = pd.read_sql(query.statement, query.session.bind) + + # map from obj label string -> source + results['source'] = map_on_partial_string( + results['obj_label'], + {k: i for i, k in OBJ_LABEL_TO_SOURCE.items()}) + + results['cntr_id'] = results['obj_label'].str[:2] + results['bus'] = results['cntr_id'].map(neighbours['bus_id']) + + # create Series with bus_id, source and power generation / actual value + # in list format + results_s = results.groupby(['bus', 'source'])['val'].apply(np.array) + results_s.name = 'p_set' + + # check all arrays are of the same length + assert all(len(i) == len(results_s[0]) for i in results_s) + + # include timeseries data in generators DataFrame + generators = generators.join(results_s, on=['bus', 'source']) + + # remove solar and wind + sources = [v for k, v in OBJ_LABEL_TO_SOURCE.items() if k in + ['wind_offshore', 'wind_onshore', 'solar']] + + ix = generators['source'].isin(sources) + generators = generators[~ix].copy() + + # set scenario name, temporal id + generators['scn_name'] = scn_name + generators['temp_id'] = TEMPID + + pqsets = generators[['scn_name', 'generator_id', 'temp_id', 'p_set']] + + # export to db + for i in pqsets.to_dict(orient='records'): + session.add(PqSet(**i)) + + session.commit() + + logged += len(pqsets) + +write_ego_scenario_log(conn=conn, + version='v0.4.0', + io='input', + schema='model_draft', + table=PqSet.__tablename__, + script=__file__, + entries=logged) diff --git a/dataprocessing/sql_snippets/ego_dp_powerflow_create_load_neighbours.sql b/dataprocessing/sql_snippets/ego_dp_powerflow_create_load_neighbours.sql new file mode 100644 index 00000000..c9075adc --- /dev/null +++ b/dataprocessing/sql_snippets/ego_dp_powerflow_create_load_neighbours.sql @@ -0,0 +1,76 @@ +/* Create entries in hv load for all neighbouring countries and scenarios + +__copyright__ = "Europa Universitaet Flensburg, Centre for Sustainable Energy Systems" +__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" +__url__ = "https://github.com/openego/data_processing/blob/master/LICENSE" +__author__ = "wolfbunke, MarlonSchlemminger" +*/ + +-- DELETE +DELETE FROM model_draft.ego_grid_pf_hv_load WHERE bus IN ( +SELECT bus_id FROM model_draft.ego_grid_hv_electrical_neighbours_bus +WHERE central_bus = TRUE); + +-- Status quo +INSERT into model_draft.ego_grid_pf_hv_load (scn_name, load_id, bus, sign) + + SELECT + scn_name, + load_id, + bus_id AS bus, + '-1' AS sign + FROM + ( + SELECT *, + max(v_nom) OVER (PARTITION BY cntr_id) AS max_v_nom, + row_number() OVER () + (SELECT max(load_id) + FROM model_draft.ego_grid_pf_hv_load + WHERE scn_name = 'Status Quo') AS load_id + from model_draft.ego_grid_hv_electrical_neighbours_bus + where central_bus = TRUE) SQ + + WHERE v_nom = max_v_nom; + +-- NEP2035 +INSERT into model_draft.ego_grid_pf_hv_load (scn_name, load_id, bus, sign) + + SELECT + 'NEP 2035', + load_id, + bus_id AS bus, + '-1' AS sign + FROM + ( + SELECT *, + max(v_nom) OVER (PARTITION BY cntr_id) AS max_v_nom, + row_number() OVER () + (SELECT max(load_id) + FROM model_draft.ego_grid_pf_hv_load + WHERE scn_name = 'NEP 2035') AS load_id + from model_draft.ego_grid_hv_electrical_neighbours_bus + where central_bus = TRUE) NEP + + WHERE v_nom = max_v_nom; + + +-- eGo100 +INSERT into model_draft.ego_grid_pf_hv_load (scn_name, load_id, bus, sign) + + SELECT + 'eGo 100', + load_id, + bus_id AS bus, + '-1' AS sign + FROM + ( + SELECT *, + max(v_nom) OVER (PARTITION BY cntr_id) AS max_v_nom, + row_number() OVER () + (SELECT max(load_id) + FROM model_draft.ego_grid_pf_hv_load + WHERE scn_name = 'eGo 100') AS load_id + from model_draft.ego_grid_hv_electrical_neighbours_bus + where central_bus = TRUE + ) EGO + WHERE v_nom = max_v_nom; + +-- scenario log (project,version,io,schema_name,table_name,script_name,comment) +SELECT scenario_log('eGo_DP', 'v0.4.0','output','model_draft','ego_grid_pf_hv_generator_pq_set','ego_dp_powerflow_timeseries_generator.sql',' '); diff --git a/dataprocessing/sql_snippets/ego_dp_powerflow_timeseries_generator.sql b/dataprocessing/sql_snippets/ego_dp_powerflow_timeseries_generator.sql deleted file mode 100644 index 7f4d73bd..00000000 --- a/dataprocessing/sql_snippets/ego_dp_powerflow_timeseries_generator.sql +++ /dev/null @@ -1,1070 +0,0 @@ -/* -This is a quick workaround to transfer `renpassG!S results `_ on generator time series -into the corresponding powerflow table. It adds time series (p_set) for generators in Germany and the neighbouring countries to the -`respective table `_ - -__copyright__ = "Europa Universitaet Flensburg, Centre for Sustainable Energy Systems" -__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" -__url__ = "https://github.com/openego/data_processing/blob/master/LICENSE" -__author__ = "wolfbunke, MarlonSchlemminger" - -TODO: storage in storage_pqset #1069 -*/ - --- Status Quo --- aggregate nominal capacity on aggr_id FROM powerflow generators, keeping the source -DROP materialized view if EXISTS calc_renpass_gis.pf_pp_by_source_aggr_id; -CREATE materialized view calc_renpass_gis.pf_pp_by_source_aggr_id -AS -SELECT -SQ.aggr_id, SQ.source, SQ.p_nom / sum(SQ.p_nom) over (partition by SQ.source) AS fraction_of_installed -FROM - (SELECT - aggr_id, - source, - sum(p_nom) AS p_nom - FROM model_draft.ego_supply_pf_generator_single - WHERE scn_name = 'Status Quo' - AND aggr_id IS NOT NULL -GROUP BY aggr_id, source) SQ; - --- map renpassG!S power sources to pf generators, aggr on fuel types, neglect efficiency classes -DROP materialized view if EXISTS calc_renpass_gis.pp_feedin_by_pf_source; -CREATE materialized view calc_renpass_gis.pp_feedin_by_pf_source -AS -SELECT -SQ.source, SQ.datetime, sum(SQ.val) AS val -FROM - (SELECT - CASE - WHEN obj_label LIKE '%%gas%%' THEN 1 - when obj_label LIKE '%%lignite%%' THEN 2 - when obj_label LIKE '%%mixed_fuels%%' THEN 3 - when obj_label LIKE '%%oil%%' THEN 4 - when obj_label LIKE '%%uranium%%' THEN 5 - when obj_label LIKE '%%biomass%%' THEN 6 - when obj_label LIKE '%%hard_coal%%' THEN 8 - when obj_label LIKE '%%run_of_river%%' THEN 9 --- when obj_label LIKE '%%storage_phs%%' THEN 11 - when obj_label LIKE '%%solar%%' THEN 12 - when obj_label LIKE '%%wind_onshore%%' THEN 13 - when obj_label LIKE '%%wind_offshore%%' THEN 17 - END AS source, - bus_label, - obj_label, - type, - datetime, - val - FROM calc_renpass_gis.renpass_gis_results - -- conds - WHERE obj_label LIKE '%%DE%%' -- only Germany - AND obj_label not LIKE '%%powerline%%' -- without any powerlines - AND scenario_id = 43 - -- take only one flow (input), storage output flow seems to be the right one (?) - AND ((obj_label LIKE '%%storage%%' AND type = 'from_bus') or (obj_label not LIKE '%%storage%%' AND type = 'to_bus')) -) AS SQ -WHERE SQ.source IS not NULL -GROUP BY SQ.source, SQ.datetime; - --- get feedin per generator_id from ego_renewable_feedin -DROP materialized view IF EXISTS model_draft.ren_feedin_by_gen_id; -CREATE materialized view model_draft.ren_feedin_by_gen_id -AS -SELECT -gen.generator_id, feedin.feedin -FROM - (SELECT - aggr_id AS generator_id, - w_id, - power_class, - source - FROM - model_draft.ego_supply_pf_generator_single - WHERE source IN (12, 13, 17) - AND scn_name = 'Status Quo' - GROUP BY aggr_id, w_id, power_class, source) AS gen, - (SELECT - w_id, - power_class, - CASE - WHEN source LIKE '%%solar%%' THEN 12 - WHEN source LIKE '%%wind_onshore%%' THEN 13 - WHEN source LIKE '%%wind_offshore%%' THEN 17 - END AS source, - feedin - FROM model_draft.ego_renewable_feedin) AS feedin -WHERE gen.source = feedin.source -AND gen.w_id = feedin.w_id -AND gen.power_class = feedin.power_class; - - --- -DELETE FROM model_draft.ego_grid_pf_hv_generator_pq_set; - --- construct array per aggr_id according to source timeseries for conventional -INSERT into model_draft.ego_grid_pf_hv_generator_pq_set (scn_name, generator_id, temp_id, p_set) -SELECT - 'Status Quo' AS scn_name, - A.aggr_id, - 1 AS temp_id, - array_agg(A.fraction_of_installed * B.val ORDER BY B.datetime) AS p_set - FROM calc_renpass_gis.pf_pp_by_source_aggr_id A, - calc_renpass_gis.pp_feedin_by_pf_source B -WHERE A.source = B.source -GROUP BY A.aggr_id; - --- set p_max_pu as timeseries from ego_renewable_feedin -UPDATE model_draft.ego_grid_pf_hv_generator_pq_set A - SET p_max_pu = feedin.feedin - FROM model_draft.ren_feedin_by_gen_id AS feedin - WHERE A.generator_id = feedin.generator_id; --- NEP 2035 - --- aggregate nominal capacity on aggr_id FROM powerflow generators, keeping the source -DROP materialized view if EXISTS calc_renpass_gis.pf_pp_by_source_aggr_id; -CREATE materialized view calc_renpass_gis.pf_pp_by_source_aggr_id -AS -SELECT -NEP.aggr_id, NEP.source, NEP.p_nom / sum(NEP.p_nom) over (partition by NEP.source) AS fraction_of_installed -FROM - (SELECT - aggr_id, - source, - sum(p_nom) AS p_nom - FROM model_draft.ego_supply_pf_generator_single - WHERE scn_name = 'NEP 2035' - AND aggr_id IS NOT NULL - GROUP BY aggr_id, source) NEP; - --- map renpassG!S power sources to pf generators, aggr on fuel types, neglect efficiency classes -DROP materialized view if EXISTS calc_renpass_gis.pp_feedin_by_pf_source; -CREATE materialized view calc_renpass_gis.pp_feedin_by_pf_source -AS -SELECT -NEP.source, NEP.datetime, sum(NEP.val) AS val -FROM - (SELECT - CASE - WHEN obj_label LIKE '%%gas%%' THEN 1 - when obj_label LIKE '%%lignite%%' THEN 2 - when obj_label LIKE '%%mixed_fuels%%' THEN 3 - when obj_label LIKE '%%oil%%' THEN 4 - when obj_label LIKE '%%uranium%%' THEN 5 - when obj_label LIKE '%%biomass%%' THEN 6 - when obj_label LIKE '%%hard_coal%%' THEN 8 - when obj_label LIKE '%%run_of_river%%' THEN 9 --- when obj_label LIKE '%%storage_phs%%' THEN 11 - when obj_label LIKE '%%solar%%' THEN 12 - WHEN obj_label LIKE '%%wind_onshore%%' THEN 13 - WHEN obj_label LIKE '%%wind_offshore%%' THEN 17 - END AS source, - bus_label, - obj_label, - type, - datetime, - val - FROM calc_renpass_gis.renpass_gis_results - -- conds - WHERE obj_label LIKE '%%DE%%' -- only Germany - AND obj_label not LIKE '%%powerline%%' -- without any powerlines - AND scenario_id = 41 - -- take only one flow (input), storage output flow seems to be the right one (?) - AND ((obj_label LIKE '%%storage%%' AND type = 'from_bus') or (obj_label not LIKE '%%storage%%' AND type = 'to_bus')) -) AS NEP -WHERE NEP.source IS not NULL -GROUP BY NEP.source, NEP.datetime; - --- get feedin per generator_id from ego_renewable_feedin -DROP materialized view IF EXISTS model_draft.ren_feedin_by_gen_id; -CREATE materialized view model_draft.ren_feedin_by_gen_id -AS -SELECT -gen.generator_id, feedin.feedin -FROM - (SELECT - aggr_id AS generator_id, - w_id, - power_class, - source - FROM - model_draft.ego_supply_pf_generator_single - WHERE source IN (12, 13, 17) - AND scn_name = 'NEP 2035' - GROUP BY aggr_id, w_id, power_class, source) AS gen, - (SELECT - w_id, - power_class, - CASE - WHEN source LIKE '%%solar%%' THEN 12 - WHEN source LIKE '%%wind_onshore%%' THEN 13 - WHEN source LIKE '%%wind_offshore%%' THEN 17 - END AS source, - feedin - FROM model_draft.ego_renewable_feedin) AS feedin -WHERE gen.source = feedin.source -AND gen.w_id = feedin.w_id -AND gen.power_class = feedin.power_class; - --- construct array per aggr_id according to source timeseries -INSERT into model_draft.ego_grid_pf_hv_generator_pq_set (scn_name, generator_id, temp_id, p_set) -SELECT - 'NEP 2035' AS scn_name, - A.aggr_id, - 1 AS temp_id, - array_agg(A.fraction_of_installed * B.val ORDER BY B.datetime) AS p_set - FROM calc_renpass_gis.pf_pp_by_source_aggr_id A, - calc_renpass_gis.pp_feedin_by_pf_source B -WHERE A.source = B.source -GROUP BY A.aggr_id; - --- set p_max_pu as timeseries from ego_renewable_feedin -UPDATE model_draft.ego_grid_pf_hv_generator_pq_set A - SET p_max_pu = feedin.feedin - FROM model_draft.ren_feedin_by_gen_id AS feedin - WHERE A.generator_id = feedin.generator_id; - ---eGo100 --- aggregate nominal capacity on aggr_id FROM powerflow generators, keeping the source -DROP materialized view if EXISTS calc_renpass_gis.pf_pp_by_source_aggr_id; -CREATE materialized view calc_renpass_gis.pf_pp_by_source_aggr_id -AS -SELECT -eGo.aggr_id, eGo.source, eGo.p_nom / sum(eGo.p_nom) over (partition by eGo.source) AS fraction_of_installed -FROM - (SELECT - aggr_id, - source, - sum(p_nom) AS p_nom - FROM model_draft.ego_supply_pf_generator_single - WHERE scn_name = 'eGo 100' - AND aggr_id IS NOT NULL - GROUP BY aggr_id, source) eGo; - --- map renpassG!S power sources to pf generators, aggr on fuel types, neglect efficiency classes -DROP materialized view if EXISTS calc_renpass_gis.pp_feedin_by_pf_source; -CREATE materialized view calc_renpass_gis.pp_feedin_by_pf_source -AS -SELECT -eGo.source, eGo.datetime, sum(eGo.val) AS val -FROM - (SELECT - CASE - WHEN obj_label LIKE '%%gas%%' THEN 1 - when obj_label LIKE '%%lignite%%' THEN 2 - when obj_label LIKE '%%mixed_fuels%%' THEN 3 - when obj_label LIKE '%%oil%%' THEN 4 - when obj_label LIKE '%%uranium%%' THEN 5 - when obj_label LIKE '%%biomass%%' THEN 6 - when obj_label LIKE '%%hard_coal%%' THEN 8 - when obj_label LIKE '%%run_of_river%%' THEN 9 --- when obj_label LIKE '%%storage_phs%%' THEN 11 - when obj_label LIKE '%%solar%%' THEN 12 - WHEN obj_label LIKE '%%wind_onshore%%' THEN 13 - WHEN obj_label LIKE '%%wind_offshore%%' THEN 17 - END AS source, - bus_label, - obj_label, - type, - datetime, - val - FROM calc_renpass_gis.renpass_gis_results - -- conds - WHERE obj_label LIKE '%%DE%%' -- only Germany - AND obj_label not LIKE '%%powerline%%' -- without any powerlines - AND scenario_id = 41 - -- take only one flow (input), storage output flow seems to be the right one (?) - AND ((obj_label LIKE '%%storage%%' AND type = 'from_bus') or (obj_label not LIKE '%%storage%%' AND type = 'to_bus')) -) AS eGo -WHERE eGo.source IS not NULL -GROUP BY eGo.source, eGo.datetime; - --- get feedin per generator_id from ego_renewable_feedin -DROP materialized view IF EXISTS model_draft.ren_feedin_by_gen_id; -CREATE materialized view model_draft.ren_feedin_by_gen_id -AS -SELECT -gen.generator_id, feedin.feedin -FROM - (SELECT - aggr_id AS generator_id, - w_id, - power_class, - source - FROM - model_draft.ego_supply_pf_generator_single - WHERE source IN (12, 13, 17) - AND scn_name = 'eGo 100' - GROUP BY aggr_id, w_id, power_class, source) AS gen, - (SELECT - w_id, - power_class, - CASE - WHEN source LIKE '%%solar%%' THEN 12 - WHEN source LIKE '%%wind_onshore%%' THEN 13 - WHEN source LIKE '%%wind_offshore%%' THEN 17 - END AS source, - feedin - FROM model_draft.ego_renewable_feedin) AS feedin -WHERE gen.source = feedin.source -AND gen.w_id = feedin.w_id -AND gen.power_class = feedin.power_class; - --- construct array per aggr_id according to source timeseries -INSERT into model_draft.ego_grid_pf_hv_generator_pq_set (scn_name, generator_id, temp_id, p_set) -SELECT - 'eGo 100' AS scn_name, - A.aggr_id, - 1 AS temp_id, - array_agg(A.fraction_of_installed * B.val ORDER BY B.datetime) AS p_set - FROM calc_renpass_gis.pf_pp_by_source_aggr_id A, - calc_renpass_gis.pp_feedin_by_pf_source B -WHERE A.source = B.source -GROUP BY A.aggr_id; - --- set p_max_pu as timeseries from ego_renewable_feedin -UPDATE model_draft.ego_grid_pf_hv_generator_pq_set A - SET p_max_pu = feedin.feedin - FROM model_draft.ren_feedin_by_gen_id AS feedin - WHERE A.generator_id = feedin.generator_id; - -ALTER MATERIALIZED VIEW model_draft.ren_feedin_by_gen_id -OWNER TO oeuser; - - ------------------- NEIGHBOURING COUNTRIES --- 1 -DELETE FROM model_draft.ego_grid_pf_hv_generator WHERE generator_id > 200000 AND scn_name = 'Status Quo'; -DELETE FROM model_draft.ego_grid_pf_hv_generator WHERE generator_id > 200000 AND scn_name = 'NEP 2035'; -DELETE FROM model_draft.ego_grid_pf_hv_generator WHERE generator_id > 200000 AND scn_name = 'eGo 100'; - - --- INSERT params of LinearTransformers in model_draft.ego_grid_pf_hv_generator (countries besides Germany) --- starting generator_id at 200000, bus_id for neighbouring countries > 2800000 atm --- Status Quo -INSERT into model_draft.ego_grid_pf_hv_generator - - SELECT - 'Status Quo' AS scn_name, - row_number() over () + 200000 AS generator_id, - B.bus_id AS bus, - 'flexible' AS dispatch, - 'PV' AS control, - nominal_value[1] AS p_nom, - FALSE AS p_nom_extendable, - NULL AS p_nom_max, - 0 AS p_nom_min, - 0 AS p_min_pu_fixed, - 1 AS p_max_pu_fixed, - 1 AS sign, - CASE - WHEN source LIKE '%%gas%%' THEN 1 - when source LIKE '%%lignite%%' THEN 2 - when source LIKE '%%mixed_fuels%%' THEN 3 - when source LIKE '%%oil%%' THEN 4 - when source LIKE '%%uranium%%' THEN 5 - when source LIKE '%%biomass%%' THEN 6 - when source LIKE '%%hard_coal%%' THEN 8 - END AS source - FROM calc_renpass_gis.renpass_gis_linear_transformer A join - ( - SELECT - * - FROM - (SELECT *, - max(v_nom) over (partition by cntr_id) AS max_v_nom - FROM - model_draft.ego_grid_hv_electrical_neighbours_bus - where central_bus = TRUE - - ) SQ - WHERE SQ.v_nom = SQ.max_v_nom - ) B - ON (substring(A.source, 1, 2) = B.cntr_id) - WHERE substring(A.source, 1, 2) <> 'DE' - AND A.nominal_value IS not NULL - AND A.nominal_value[1] > 0.001 - AND A.source not LIKE '%%powerline%%' - AND A.scenario_id = 43; - - --- NEP 2035 - -INSERT into model_draft.ego_grid_pf_hv_generator - - SELECT - 'NEP 2035' AS scn_name, - row_number() over () + 200000 AS generator_id, - B.bus_id AS bus, - 'flexible' AS dispatch, - 'PV' AS control, - nominal_value[1] AS p_nom, - FALSE AS p_nom_extendable, - NULL AS p_nom_max, - 0 AS p_nom_min, - 0 AS p_min_pu_fixed, - 1 AS p_max_pu_fixed, - 1 AS sign, - CASE - WHEN source LIKE '%%gas%%' THEN 1 - when source LIKE '%%lignite%%' THEN 2 - when source LIKE '%%mixed_fuels%%' THEN 3 - when source LIKE '%%oil%%' THEN 4 - when source LIKE '%%uranium%%' THEN 5 - when source LIKE '%%biomass%%' THEN 6 - when source LIKE '%%hard_coal%%' THEN 8 - END AS source - FROM calc_renpass_gis.renpass_gis_linear_transformer A join - ( - SELECT - * - FROM - (SELECT *, - max(v_nom) over (partition by cntr_id) AS max_v_nom - FROM - model_draft.ego_grid_hv_electrical_neighbours_bus - where central_bus = TRUE - - ) SQ - WHERE SQ.v_nom = SQ.max_v_nom - ) B - ON (substring(A.source, 1, 2) = B.cntr_id) - WHERE substring(A.source, 1, 2) <> 'DE' - AND A.nominal_value IS not NULL - AND A.nominal_value[1] > 0.001 - AND A.source not LIKE '%%powerline%%' - AND A.scenario_id = 41; - --- eGo 100 - -INSERT into model_draft.ego_grid_pf_hv_generator - - SELECT - 'eGo 100' AS scn_name, - row_number() over () + 200000 AS generator_id, - B.bus_id AS bus, - 'flexible' AS dispatch, - 'PV' AS control, - nominal_value[1] AS p_nom, - FALSE AS p_nom_extendable, - NULL AS p_nom_max, - 0 AS p_nom_min, - 0 AS p_min_pu_fixed, - 1 AS p_max_pu_fixed, - 1 AS sign, - CASE - WHEN source LIKE '%%gas%%' THEN 1 - when source LIKE '%%lignite%%' THEN 2 - when source LIKE '%%mixed_fuels%%' THEN 3 - when source LIKE '%%oil%%' THEN 4 - when source LIKE '%%uranium%%' THEN 5 - when source LIKE '%%biomass%%' THEN 6 - when source LIKE '%%hard_coal%%' THEN 8 - END AS source - FROM calc_renpass_gis.renpass_gis_linear_transformer A join - ( - SELECT - * - FROM - (SELECT *, - max(v_nom) over (partition by cntr_id) AS max_v_nom - FROM - model_draft.ego_grid_hv_electrical_neighbours_bus - where central_bus = TRUE - ) SQ - WHERE SQ.v_nom = SQ.max_v_nom - ) B - ON (substring(A.source, 1, 2) = B.cntr_id) - WHERE substring(A.source, 1, 2) <> 'DE' - AND A.nominal_value IS not NULL - AND A.nominal_value[1] > 0.001 - AND A.source not LIKE '%%powerline%%' - AND A.scenario_id = 40; - - - - --- INSERT params of Source in model_draft.ego_grid_pf_hv_generator (countries besides Germany) --- Status Quo -INSERT into model_draft.ego_grid_pf_hv_generator - - SELECT - 'Status Quo' AS scn_name, - row_number() over () + (SELECT max(generator_id) FROM model_draft.ego_grid_pf_hv_generator) AS generator_id, - B.bus_id AS bus, - 'variable' AS dispatch, - 'PV' AS control, - nominal_value[1] AS p_nom, - FALSE AS p_nom_extendable, - NULL AS p_nom_max, - 0 AS p_nom_min, - 0 AS p_min_pu_fixed, - 1 AS p_max_pu_fixed, - 1 AS sign, - CASE - WHEN source LIKE '%%run_of_river%%' THEN 9 - WHEN source LIKE '%%solar%%' THEN 12 - WHEN source LIKE '%%wind_onshore%%' THEN 13 - WHEN source LIKE '%%wind_offshore%%' THEN 17 - when source LIKE '%%reservoir%%' THEN 10 - when source LIKE '%%geothermal%%' THEN 14 - END AS source - FROM calc_renpass_gis.renpass_gis_source A join - ( - SELECT - * - FROM - (SELECT *, - max(v_nom) over (partition by cntr_id) AS max_v_nom - FROM - model_draft.ego_grid_hv_electrical_neighbours_bus - where central_bus = TRUE - - ) SQ - WHERE SQ.v_nom = SQ.max_v_nom - ) B - ON (substring(A.source, 1, 2) = B.cntr_id) - WHERE substring(A.source, 1, 2) <> 'DE' - AND A.nominal_value[1] > 0.001 - AND A.scenario_id = 43; - --- NEP 2035 - -INSERT into model_draft.ego_grid_pf_hv_generator - - SELECT - 'NEP 2035' AS scn_name, - row_number() over () + (SELECT max(generator_id) FROM model_draft.ego_grid_pf_hv_generator) AS generator_id, - B.bus_id AS bus, - 'variable' AS dispatch, - 'PV' AS control, - nominal_value[1] AS p_nom, - FALSE AS p_nom_extendable, - NULL AS p_nom_max, - 0 AS p_nom_min, - 0 AS p_min_pu_fixed, - 1 AS p_max_pu_fixed, - 1 AS sign, - CASE - WHEN source LIKE '%%run_of_river%%' THEN 9 - WHEN source LIKE '%%solar%%' THEN 12 - WHEN source LIKE '%%wind_onshore%%' THEN 13 - WHEN source LIKE '%%wind_offshore%%' THEN 17 - when source LIKE '%%reservoir%%' THEN 10 - when source LIKE '%%geothermal%%' THEN 14 - END AS source - FROM calc_renpass_gis.renpass_gis_source A join - ( - SELECT - * - FROM - (SELECT *, - max(v_nom) over (partition by cntr_id) AS max_v_nom - FROM - model_draft.ego_grid_hv_electrical_neighbours_bus - where central_bus = TRUE - ) SQ - WHERE SQ.v_nom = SQ.max_v_nom - ) B - ON (substring(A.source, 1, 2) = B.cntr_id) - WHERE substring(A.source, 1, 2) <> 'DE' - AND A.nominal_value[1] > 0.001 - AND A.scenario_id = 41; - --- eGo 100 - -INSERT into model_draft.ego_grid_pf_hv_generator - - SELECT - 'eGo 100' AS scn_name, - row_number() over () + (SELECT max(generator_id) FROM model_draft.ego_grid_pf_hv_generator) AS generator_id, - B.bus_id AS bus, - 'variable' AS dispatch, - 'PV' AS control, - nominal_value[1] AS p_nom, - FALSE AS p_nom_extendable, - NULL AS p_nom_max, - 0 AS p_nom_min, - 0 AS p_min_pu_fixed, - 1 AS p_max_pu_fixed, - 1 AS sign, - CASE - WHEN source LIKE '%%run_of_river%%' THEN 9 - WHEN source LIKE '%%solar%%' THEN 12 - WHEN source LIKE '%%wind_onshore%%' THEN 13 - WHEN source LIKE '%%wind_offshore%%' THEN 17 - when source LIKE '%%reservoir%%' THEN 10 - when source LIKE '%%geothermal%%' THEN 14 - END AS source - FROM calc_renpass_gis.renpass_gis_source A join - ( - SELECT - * - FROM - (SELECT *, - max(v_nom) over (partition by cntr_id) AS max_v_nom - FROM - model_draft.ego_grid_hv_electrical_neighbours_bus - where central_bus = TRUE - ) SQ - WHERE SQ.v_nom = SQ.max_v_nom - ) B - ON (substring(A.source, 1, 2) = B.cntr_id) - WHERE substring(A.source, 1, 2) <> 'DE' - AND A.nominal_value[1] > 0.001 - AND A.scenario_id = 40; - - --- Copy timeseries data -DELETE FROM model_draft.ego_grid_pf_hv_generator_pq_set WHERE generator_id > 200000 AND scn_name = 'Status Quo'; -DELETE FROM model_draft.ego_grid_pf_hv_generator_pq_set WHERE generator_id > 200000 AND scn_name = 'NEP 2035'; -DELETE FROM model_draft.ego_grid_pf_hv_generator_pq_set WHERE generator_id > 200000 AND scn_name = 'eGo 100'; - --- CREATE a view containing data for generator_id's > 200000 for each timestep --- SELECT * FROM calc_renpass_gis.translate_to_pf limit 1000; --- Status Quo -DROP MATERIALIZED VIEW IF EXISTS calc_renpass_gis.translate_to_pf; - -CREATE MATERIALIZED VIEW calc_renpass_gis.translate_to_pf AS - SELECT - SQ.generator_id, - C.datetime, - C.val - FROM - (SELECT *, - CASE - WHEN A.source = 1 THEN 'gas' - WHEN A.source = 2 THEN 'lignite' - WHEN A.source = 3 THEN 'mixed_fuels' - WHEN A.source = 4 THEN 'oil' - WHEN A.source = 5 THEN 'uranium' - WHEN A.source = 6 THEN 'biomass' - WHEN A.source = 8 THEN 'hard_coal' - WHEN A.source = 9 THEN 'run_of_river' - WHEN A.source = 10 THEN 'reservoir' - WHEN A.source = 12 THEN 'solar' - WHEN A.source = 13 THEN 'wind_onshore' - WHEN A.source = 14 THEN 'geothermal' - WHEN A.source = 17 THEN 'wind_offshore' - END AS renpass_gis_source - FROM model_draft.ego_grid_pf_hv_generator A join - model_draft.ego_grid_hv_electrical_neighbours_bus B - ON (A.bus = B.bus_id) - WHERE A.generator_id > 200000 - AND A.scn_name = 'Status Quo' - ) SQ, - calc_renpass_gis.renpass_gis_results C - WHERE - (C.obj_label LIKE '%%' || SQ.cntr_id || '%%' || SQ.renpass_gis_source || '%%') - AND C.scenario_id = 43 - AND C.type = 'to_bus'; - --- create a view assigning a w_id to each foreign bus and the respective feedin -DROP MATERIALIZED VIEW IF EXISTS model_draft.ren_feedin_foreign; -CREATE MATERIALIZED VIEW model_draft.ren_feedin_foreign AS -SELECT -A.generator_id, B.feedin -FROM - (SELECT - feedin.w_id, - CASE - WHEN feedin.source LIKE '%%solar%%' THEN 12 - WHEN feedin.source LIKE '%%wind_onshore%%' THEN 13 - END AS source, - feedin.feedin - FROM - model_draft.ego_renewable_feedin AS feedin - WHERE power_class IN (0, 4) - ) AS B, - (SELECT - generators.generator_id, - generators.source, - buses.w_id - FROM - (SELECT - neighbours.bus_id AS bus_id, - weather.gid AS w_id - FROM model_draft.ego_grid_hv_electrical_neighbours_bus AS neighbours, - coastdat.cosmoclmgrid AS weather - WHERE ST_Intersects(weather.geom, neighbours.geom)) - AS buses, - model_draft.ego_grid_pf_hv_generator AS generators - WHERE generators.bus = buses.bus_id - AND generators.source IN (12, 13) - AND generators.generator_id > 200000 - AND generators.scn_name = 'Status Quo' - ) AS A -WHERE A.w_id = B.w_id -AND A.source = B.source; - --- Make an array, INSERT into generator_pq_set -INSERT into model_draft.ego_grid_pf_hv_generator_pq_set (scn_name, generator_id, temp_id, p_set) - - SELECT 'Status Quo' AS scn_name, - SQ.generator_id, - 1 AS temp_id, - array_agg(SQ.val ORDER BY SQ.datetime) AS p_set - FROM - ( - SELECT - A.generator_id, - A.datetime, - A.val AS val - FROM calc_renpass_gis.translate_to_pf A join - model_draft.ego_grid_pf_hv_generator B - USING (generator_id) - ) SQ - GROUP BY generator_id; - --- set p_max_pu as timeseries from ego_renewable_feedin -UPDATE model_draft.ego_grid_pf_hv_generator_pq_set A - SET p_max_pu = feedin.feedin - FROM model_draft.ren_feedin_foreign AS feedin - WHERE A.generator_id = feedin.generator_id; - --- NEP 2035 - -Drop MATERIALIZED VIEW IF EXISTS calc_renpass_gis.translate_to_pf; - -CREATE MATERIALIZED VIEW calc_renpass_gis.translate_to_pf AS - SELECT - NEP.generator_id, - C.datetime, - C.val - FROM - (SELECT *, - CASE - WHEN A.source = 1 THEN 'gas' - WHEN A.source = 2 THEN 'lignite' - WHEN A.source = 3 THEN 'mixed_fuels' - WHEN A.source = 4 THEN 'oil' - WHEN A.source = 5 THEN 'uranium' - WHEN A.source = 6 THEN 'biomass' - WHEN A.source = 8 THEN 'hard_coal' - WHEN A.source = 9 THEN 'run_of_river' - WHEN A.source = 10 THEN 'reservoir' - WHEN A.source = 12 THEN 'solar' - WHEN A.source = 13 THEN 'wind_onshore' - WHEN A.source = 14 THEN 'geothermal' - WHEN A.source = 17 THEN 'wind_offshore' - END AS renpass_gis_source - FROM model_draft.ego_grid_pf_hv_generator A join - model_draft.ego_grid_hv_electrical_neighbours_bus B - ON (A.bus = B.bus_id) - WHERE A.generator_id > 200000 - AND A.scn_name = 'NEP 2035' - ) NEP, - calc_renpass_gis.renpass_gis_results C - WHERE - (C.obj_label LIKE '%%' || NEP.cntr_id || '%%' || NEP.renpass_gis_source || '%%') - AND C.scenario_id = 41 - AND C.type = 'to_bus'; - --- create a view assigning a w_id to each foreign bus and the respective feedin -DROP MATERIALIZED VIEW IF EXISTS model_draft.ren_feedin_foreign; -CREATE MATERIALIZED VIEW model_draft.ren_feedin_foreign AS -SELECT -A.generator_id, B.feedin -FROM - (SELECT - feedin.w_id, - CASE - WHEN feedin.source LIKE '%%solar%%' THEN 12 - WHEN feedin.source LIKE '%%wind_onshore%%' THEN 13 - END AS source, - feedin.feedin - FROM - model_draft.ego_renewable_feedin AS feedin - WHERE power_class IN (0, 4) - ) AS B, - (SELECT - generators.generator_id, - generators.source, - buses.w_id - FROM - (SELECT - neighbours.bus_id AS bus_id, - weather.gid AS w_id - FROM model_draft.ego_grid_hv_electrical_neighbours_bus AS neighbours, - coastdat.cosmoclmgrid AS weather - WHERE ST_Intersects(weather.geom, neighbours.geom)) - AS buses, - model_draft.ego_grid_pf_hv_generator AS generators - WHERE generators.bus = buses.bus_id - AND generators.source IN (12, 13) - AND generators.generator_id > 200000 - AND generators.scn_name = 'NEP 2035' - ) AS A -WHERE A.w_id = B.w_id -AND A.source = B.source; - --- Make an array, INSERT into generator_pq_set -INSERT into model_draft.ego_grid_pf_hv_generator_pq_set (scn_name, generator_id, temp_id, p_set) - - SELECT 'NEP 2035' AS scn_name, - NEP.generator_id, - 1 AS temp_id, - array_agg(NEP.val ORDER BY NEP.datetime) AS p_set - FROM - ( - SELECT - A.generator_id, - A.datetime, - A.val AS val - FROM calc_renpass_gis.translate_to_pf A join - model_draft.ego_grid_pf_hv_generator B - USING (generator_id) - ) NEP - GROUP BY generator_id; - --- set p_max_pu as timeseries from ego_renewable_feedin -UPDATE model_draft.ego_grid_pf_hv_generator_pq_set A - SET p_max_pu = feedin.feedin - FROM model_draft.ren_feedin_foreign AS feedin - WHERE A.generator_id = feedin.generator_id; - --- eGo 100 - -Drop MATERIALIZED VIEW IF EXISTS calc_renpass_gis.translate_to_pf; - -CREATE MATERIALIZED VIEW calc_renpass_gis.translate_to_pf AS - SELECT - EGO.generator_id, - C.datetime, - C.val - FROM - (SELECT *, - CASE - WHEN A.source = 1 THEN 'gas' - WHEN A.source = 2 THEN 'lignite' - WHEN A.source = 3 THEN 'mixed_fuels' - WHEN A.source = 4 THEN 'oil' - WHEN A.source = 5 THEN 'uranium' - WHEN A.source = 6 THEN 'biomass' - WHEN A.source = 8 THEN 'hard_coal' - WHEN A.source = 9 THEN 'run_of_river' - WHEN A.source = 10 THEN 'reservoir' - WHEN A.source = 12 THEN 'solar' - WHEN A.source = 13 THEN 'wind_onshore' - WHEN A.source = 14 THEN 'geothermal' - WHEN A.source = 17 THEN 'wind_offshore' - END AS renpass_gis_source - FROM model_draft.ego_grid_pf_hv_generator A join - model_draft.ego_grid_hv_electrical_neighbours_bus B - ON (A.bus = B.bus_id) - WHERE A.generator_id > 200000 - AND A.scn_name = 'eGo 100' - ) EGO, - calc_renpass_gis.renpass_gis_results C - WHERE - (C.obj_label LIKE '%%' || EGO.cntr_id || '%%' || EGO.renpass_gis_source || '%%') - AND C.scenario_id = 41 - AND C.type = 'to_bus'; - --- create a view assigning a w_id to each foreign bus and the respective feedin -DROP MATERIALIZED VIEW IF EXISTS model_draft.ren_feedin_foreign; -CREATE MATERIALIZED VIEW model_draft.ren_feedin_foreign AS -SELECT -A.generator_id, B.feedin -FROM - (SELECT - feedin.w_id, - CASE - WHEN feedin.source LIKE '%%solar%%' THEN 12 - WHEN feedin.source LIKE '%%wind_onshore%%' THEN 13 - END AS source, - feedin.feedin - FROM - model_draft.ego_renewable_feedin AS feedin - WHERE power_class IN (0, 4) - ) AS B, - (SELECT - generators.generator_id, - generators.source, - buses.w_id - FROM - (SELECT - neighbours.bus_id AS bus_id, - weather.gid AS w_id - FROM model_draft.ego_grid_hv_electrical_neighbours_bus AS neighbours, - coastdat.cosmoclmgrid AS weather - WHERE ST_Intersects(weather.geom, neighbours.geom)) - AS buses, - model_draft.ego_grid_pf_hv_generator AS generators - WHERE generators.bus = buses.bus_id - AND generators.source IN (12, 13) - AND generators.generator_id > 200000 - AND generators.scn_name = 'eGo 100' - ) AS A -WHERE A.w_id = B.w_id -AND A.source = B.source; - --- Make an array, INSERT into generator_pq_set -INSERT into model_draft.ego_grid_pf_hv_generator_pq_set (scn_name, generator_id, temp_id, p_set) - - SELECT 'eGo 100' AS scn_name, - EGO.generator_id, - 1 AS temp_id, - array_agg(EGO.val ORDER BY EGO.datetime) AS p_set - FROM - ( - SELECT - A.generator_id, - A.datetime, - A.val AS val - FROM calc_renpass_gis.translate_to_pf A join - model_draft.ego_grid_pf_hv_generator B - USING (generator_id) - ) EGO - GROUP BY generator_id; - --- set p_max_pu as timeseries from ego_renewable_feedin -UPDATE model_draft.ego_grid_pf_hv_generator_pq_set A - SET p_max_pu = feedin.feedin - FROM model_draft.ren_feedin_foreign AS feedin - WHERE A.generator_id = feedin.generator_id; - --- set p_max_pu for foreign offshore generators -DROP MATERIALIZED VIEW IF EXISTS model_draft.offshore_feedin_foreign; -CREATE MATERIALIZED VIEW model_draft.offshore_feedin_foreign AS -SELECT -generator_id, scn_name, feedin -FROM - (SELECT generator_id, - bus, - scn_name - FROM model_draft.ego_grid_pf_hv_generator - WHERE generator_id > 200000 - AND source = 17) - AS gen - JOIN - (SELECT bus_id, - cntr_id - FROM model_draft.ego_grid_hv_electrical_neighbours_bus) - AS enb - ON (enb.bus_id = gen.bus) - JOIN - (SELECT cntr_id, - coastdat_id - FROM model_draft.ego_neighbours_offshore_point) - AS nop - ON (nop.cntr_id = enb.cntr_id) - JOIN - (SELECT w_id, - feedin - FROM model_draft.ego_renewable_feedin) - AS erf - ON (erf.w_id = nop.coastdat_id); - -UPDATE model_draft.ego_grid_pf_hv_generator_pq_set A - SET p_max_pu = feedin.feedin - FROM model_draft.offshore_feedin_foreign AS feedin - WHERE A.generator_id = feedin.generator_id; - --- DELETE -DELETE FROM model_draft.ego_grid_pf_hv_load WHERE bus IN ( -SELECT bus_id FROM model_draft.ego_grid_hv_electrical_neighbours_bus -WHERE central_bus = TRUE); - - --- INSERT neigbouring states in load table --- Status Quo -INSERT into model_draft.ego_grid_pf_hv_load (scn_name, load_id, bus, sign) - - SELECT - scn_name, - load_id, - bus_id AS bus, - '-1' AS sign - FROM - ( - SELECT *, - max(v_nom) OVER (PARTITION BY cntr_id) AS max_v_nom, - row_number() OVER () + (SELECT max(load_id) - FROM model_draft.ego_grid_pf_hv_load - WHERE scn_name = 'Status Quo') AS load_id - from model_draft.ego_grid_hv_electrical_neighbours_bus - where central_bus = TRUE) SQ - - WHERE v_nom = max_v_nom; - --- NEP 2035 - -INSERT into model_draft.ego_grid_pf_hv_load (scn_name, load_id, bus, sign) - - SELECT - 'NEP 2035', - load_id, - bus_id AS bus, - '-1' AS sign - FROM - ( - SELECT *, - max(v_nom) OVER (PARTITION BY cntr_id) AS max_v_nom, - row_number() OVER () + (SELECT max(load_id) - FROM model_draft.ego_grid_pf_hv_load - WHERE scn_name = 'NEP 2035') AS load_id - from model_draft.ego_grid_hv_electrical_neighbours_bus - where central_bus = TRUE) NEP - - WHERE v_nom = max_v_nom; - - --- eGo 100 - -INSERT into model_draft.ego_grid_pf_hv_load (scn_name, load_id, bus, sign) - - SELECT - 'eGo 100', - load_id, - bus_id AS bus, - '-1' AS sign - FROM - ( - SELECT *, - max(v_nom) OVER (PARTITION BY cntr_id) AS max_v_nom, - row_number() OVER () + (SELECT max(load_id) - FROM model_draft.ego_grid_pf_hv_load - WHERE scn_name = 'eGo 100') AS load_id - from model_draft.ego_grid_hv_electrical_neighbours_bus - where central_bus = TRUE - ) EGO - WHERE v_nom = max_v_nom; - - - - - - - --- Demand timeseries - --- NEP 2035 -/* Handled in ego_dp_powerflow_load_timeseries_NEP2035.sql - -INSERT INTO model_draft.ego_grid_pf_hv_load_pq_set (scn_name, load_id, temp_id, p_set) - - SELECT - 'NEP 2035' AS scn_name, - C.load_id AS load_id, - 1 AS temp_id, - array_agg(SQ.val ORDER BY SQ.datetime) AS p_set - FROM - ( - SELECT *, - max(B.v_nom) over (partition by B.cntr_id) AS max_v_nom - FROM calc_renpass_gis.renpass_gis_results A - join model_draft.ego_grid_hv_electrical_neighbours_bus B - ON (B.cntr_id = substring(A.obj_label, 1, 2)) - WHERE A.obj_label LIKE '%%load%%' - AND B.id <= 27 - AND A.type = 'from_bus' - AND A.scenario_id = 38 - ) SQ - JOIN model_draft.ego_grid_pf_hv_load C on (C.bus = SQ.bus_id) - WHERE SQ.v_nom = SQ.max_v_nom - AND C.scn_name = 'NEP 2035' - GROUP BY C.load_id; -*/ - --- scenario log (project,version,io,schema_name,table_name,script_name,comment) -SELECT scenario_log('eGo_DP', 'v0.4.0','output','model_draft','ego_grid_pf_hv_generator_pq_set','ego_dp_powerflow_timeseries_generator.sql',' ');