Package: grim-opt
Installation stepsOPTIONAL, only if plotting is necessary:Install thelibgeoslibrary and development headersIn Ubuntu:sudo apt install libgeos-devUsepipto install thegrim-optlibrary and executable normally.Recommended: do it in a fresh virtual environmentCreate env:python3 -m venv <chosen_venv_directory>Activate env:source <chosen_venv_directory>/bin/activateTBD: Conda environment file (handles geos dependency also)Instructions for contributing to the projectOne-time setupThis project usespoetryas its dependency management, virtualenv management and release (build) toolInstall following the steps described inhttps://python-poetry.org/docs/#installationSetup PyPI credentials to be able to publish packagesMake an account onhttps://pypi.org. Ask (optional) for invitation to become project contributor on PyPI.Add API token on the "account settings" page of PyPI (global scope)Register the API token to be the one used by Poetry:poetry config pypi-token.pypi "<your_api_token>"Sometimes: update package dependenciesIt is advisable to sometimes (every couple of months) update the package's dependenciesUsing newer versions (if possible) of dependencies gives you above all security fixesSometimes also performance improvementsSteps:First make a backup of the lock file (in case you need to rollback the update):mv poetry.lock bkp-poetry.lockThen create a new lock file with updated versions of dependencies, and install all fresh:poetry update --lockpoetry env remove python && poetry installTest that the program still works as expectedIf the program breaks after the update, revert to the previous state by restoring the old lock file:mv bkp-poetry.lock poetry.lockpoetry env remove python && poetry installBuilding a new version and releasing/uploading to PyPIBuilding a (new) release and publishing it to PyPI:Do the actual contribution to the project 🙂Increment the package's version number inpyproject.tomlBuild the package (wheel and source):poetry build. The built artifacts will be placed in thedistfolderPublish to PyPI:poetry publishContributing to documentation and build the docsTODOProcessing stepsArea per land cover per regionModule/function name:land_cover.pyInput data:corine_land_coverpolygonsOutputs:region_area_land_cover_classesFromregion_area_land_cover_classes, we aggregate (manually) into:region_area_generationOptimize investmentModule/function name:optimization.pyInput dataregion_area_generationelectricity_demandelectricity_gencap_factors_new_solarelectricity_gencap_factors_new_windelectricity_gencap_existingelectricity_transcap_connectionsInput parameters:Techno-economic:parameters_techno_econ.xlsxOutputs ({pct}is the proportion of the overall generation capacity required to be renewable):One file for each value of{pct}: 0%, 20%, 50%, 80%, 100%optimized_gencap_{pct}_renewoptimized_transcap_{pct}_renewPost-processing / plottingModule/function name:plot_capacities_totals.pyInput data:One file for each value of{pct}: 0%, 20%, 50%, 80%, 100%optimized_gencap_{pct}_renewoptimized_transcap_{pct}_renewOutput:plot_capacities_totalsModule/function name:plot_capacities_regions.pyInput data:One file for each value of{pct}: 0%, 20%, 50%, 80%, 100%optimized_transcap_{pct}_renewOutput:plot_capacities_regionsFile meaning, format and data descriptioncorine_land_covernetcdf file: Corine land cover dataout_shp: the size of the Corine land cover data. For example, (4721, 4412) means 4721 points in y dimension and 4412 points in x dimension.r: radius of circles where the circle area will be excluded from the available points/land cover. It should be used in combination with "class_artificial_indices".class_artificial_indices: a list contains grid codes from Corine land cover data which present centers of the cirlces. The grid codes could be found in file "clc_legend_new.xls". The default values are artificial surfaces. Detailed description of the Corine land cover classes could be found in:https://land.copernicus.eu/user-corner/technical-library/corine-land-cover-nomenclature-guidelines/html.EPSG3035/EPSG4326 are parameters for EPSG coordinate systems. For example, the EPSG 3035 system is constructed as: EPSG3035 = pyproj.Proj("+init=EPSG:3035").polygonsgeojson files: polygon data (in my case, I created the polygon data myself)Optimization inputselectricity_demandDemand data (for countries: can be obtained fromENTSO-E, but need to be cleaned). The data is in MWh, per node, per time step.Wind and solar dataCan be obtained fromrenewable.ninja, but need to be cleanedelectricity_gencap_factors_new_solar.  The data is unitless between 0 - 1, per node, per time step.electricity_gencap_factors_new_wind.  The data is unitless between 0 - 1, per node, per time step.electricity_gencap_existingexisting generation data. The data is in MW, per node, per technology.electricity_transcap_connectionsline data (transmission capacities of inter-region connections). The data shows the details of the lines. In my case, both ends of the lines are represented by region numbers. The regions numbers can be found in file "region_numbered.csv"techno_economic_parameters.xlsxtechno-economic dataregion_area_land_cover_classescsv file (matrix): for each land cover class, for each region, the area (m2).region_area_generationSome manual calculations are done, for summation and suitability factors.Per column, the area in km2optimizationsetsN: number of nodes.FL: number of lines.G: all generation technologies.SC: storage conversion. S = SCS: storage technologies. S = SCRES: renewable energy technologies. Subset of GVRES: variable renewable energy technologies. Subset of RES.Non-VRES: non-variable renewable energy technologies. G-VRES.T = time stepsT2 =time steps excluding the first time stepparameters.capacity_density_onshore: capacity density for onshore wind turbines (MW/km2)capacity_density_solar: capacity density for solar PV (MW/km2)lol: value of lost load (euros/MWh)R: number of time steps. Used in combination with T, T2.CT: cost transmission line (euros/km/MW)r: discount rate (0 - 1)LT: lifetime transmission linereserve_margin: reserve capacity in percentage (0 - 1), i.e., extra capacity to be built but will now be used.omega: renewable energy target, 0 - 1.im = np.zeros([len(df.index), 32]): 32 is number of nodesarr_demand = np.empty([32, 8760]): 32 is number of nodes, 8760 is number of time steps (in my case, hours). Same for other arrays.e_l: percentage of extra length of the lines (0 - 1), accounting for routing due to non-straight lines.solver optionssolver_name: name of the solversolver_crossover: crossover. Default is 0 (disabled)solver_method: method to solve the problem. Default is 2 (barrier method)solver_threads: number of threads to use.Optimized capacitiesoptimized_gencap_{pct}_renewMW, per technology, per nodeoptimized_transcap_{pct}_renewMW, between nodesPlotsplots_capacities_totalsFor each scenario (pct. of renewables in generation mix), for each energy source the installed capacityplots_capacities_regionsFor each scenario (pcr. of renewables in generation mix), for each energy source, for each region the installed capacity