From b2145d01acf96a266bbb82c950e45cb7f47d7cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Fri, 19 Dec 2025 11:05:11 +0100 Subject: [PATCH 01/17] Bump tags for Tecnalia models and fix incorrect scaling --- src/datastructures.jl | 2 +- submodules/Tecnalia_Building-Stock-Energy-Model | 2 +- submodules/Tecnalia_Solar-Energy-Model | 2 +- test/test_buildings.jl | 2 +- test/utils.jl | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/datastructures.jl b/src/datastructures.jl index 3229d32..7139c73 100644 --- a/src/datastructures.jl +++ b/src/datastructures.jl @@ -510,7 +510,7 @@ function MultipleBuildingTypes( if time_start <= date && date <= time_end for (res, res_val) ∈ v if !(res ∈ ["Datetime", "Variable cost [€]", "Emissions [KgCO2]"]) - push!(temp[res], res_val/1e6) # Scale power_outputs to MW + push!(temp[res], res_val) # Scale power_outputs to MW end end end diff --git a/submodules/Tecnalia_Building-Stock-Energy-Model b/submodules/Tecnalia_Building-Stock-Energy-Model index 76ee2e3..4bd8989 160000 --- a/submodules/Tecnalia_Building-Stock-Energy-Model +++ b/submodules/Tecnalia_Building-Stock-Energy-Model @@ -1 +1 @@ -Subproject commit 76ee2e31db400f4bf66deaa84285826fe363f0c7 +Subproject commit 4bd8989caa2767ce66b466945e0d366cc4bba2d7 diff --git a/submodules/Tecnalia_Solar-Energy-Model b/submodules/Tecnalia_Solar-Energy-Model index 636932d..bfecb8b 160000 --- a/submodules/Tecnalia_Solar-Energy-Model +++ b/submodules/Tecnalia_Solar-Energy-Model @@ -1 +1 @@ -Subproject commit 636932ddae1fecd3ae3bcfd10998b173f4e75229 +Subproject commit bfecb8b2e89ff9022f487b0769e66d5b061ffc3d diff --git a/test/test_buildings.jl b/test/test_buildings.jl index 2f8ec37..dcf2a9f 100644 --- a/test/test_buildings.jl +++ b/test/test_buildings.jl @@ -24,7 +24,7 @@ value.(m[:buildings_deficit][buildings, t, p]) == 0.0 for t ∈ 𝒯, p ∈ building_res ) - @test all(value.(m[:emissions_total][t, CO2]) > 0.001 for t ∈ 𝒯) + @test all(value.(m[:emissions_total][t, CO2]) > 1e3 for t ∈ 𝒯) # Test that the EMB function has_capacity is false for the MultipleBuildingTypes node. @test !EMB.has_capacity(buildings) diff --git a/test/utils.jl b/test/utils.jl index b7c60b1..7860ee0 100644 --- a/test/utils.jl +++ b/test/utils.jl @@ -170,7 +170,7 @@ function simple_graph_buildings(; cap_p = nothing, sources = [ RefSource( "Source for " * resource.id, - FixedProfile(150), + FixedProfile(150e6), FixedProfile(120), FixedProfile(0), Dict(resource => 1.0), @@ -212,7 +212,7 @@ function simple_graph_buildings(; cap_p = nothing, case = Case(T, products, [nodes, links], [[get_nodes, get_links]]) - em_limits = Dict(CO2 => FixedProfile(1e4)) # Emission cap for CO₂ in t/year + em_limits = Dict(CO2 => FixedProfile(1e10)) # Emission cap for CO₂ in t/year em_cost = Dict(CO2 => FixedProfile(71.0)) # Emission price for CO₂ in €/t modeltype = OperationalModel(em_limits, em_cost, CO2) return case, modeltype, create_model(case, modeltype) From d620e262fff5374f62dfc8374016709ca0975f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Fri, 19 Dec 2025 11:10:16 +0100 Subject: [PATCH 02/17] Remove old comment --- src/datastructures.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datastructures.jl b/src/datastructures.jl index 7139c73..309ddfb 100644 --- a/src/datastructures.jl +++ b/src/datastructures.jl @@ -510,7 +510,7 @@ function MultipleBuildingTypes( if time_start <= date && date <= time_end for (res, res_val) ∈ v if !(res ∈ ["Datetime", "Variable cost [€]", "Emissions [KgCO2]"]) - push!(temp[res], res_val) # Scale power_outputs to MW + push!(temp[res], res_val) end end end From 498717d0b7ba2556ab7c7dba6bcda7a8c6639a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sat, 27 Dec 2025 19:52:18 +0100 Subject: [PATCH 03/17] Improve documentation --- docs/make.jl | 9 +- docs/src/how-to/utilize.md | 206 +++++++++++++++++- docs/src/nodes/biochp.md | 166 ++++++++++++++ docs/src/nodes/multiplebuildingtypes.md | 149 +++++++++++++ docs/src/nodes/pvandcsp.md | 154 +++++++++++++ docs/src/nodes/windpower.md | 161 ++++++++++++++ docs/src/resources/resourcebio.md | 28 +++ docs/src/types/reference.md | 1 - src/datastructures.jl | 5 +- .../Tecnalia_Building-Stock-Energy-Model | 2 +- submodules/Tecnalia_Solar-Energy-Model | 2 +- .../optimization_module.py | 2 +- test/utils.jl | 27 ++- 13 files changed, 897 insertions(+), 15 deletions(-) create mode 100644 docs/src/nodes/biochp.md create mode 100644 docs/src/nodes/multiplebuildingtypes.md create mode 100644 docs/src/nodes/pvandcsp.md create mode 100644 docs/src/nodes/windpower.md create mode 100644 docs/src/resources/resourcebio.md delete mode 100644 docs/src/types/reference.md diff --git a/docs/make.jl b/docs/make.jl index fb807c4..53a5183 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -20,6 +20,7 @@ Literate.markdown(inputfile, joinpath(@__DIR__, "src", "examples")) links = InterLinks( "TimeStruct" => "https://sintefore.github.io/TimeStruct.jl/stable/", "EnergyModelsBase" => "https://energymodelsx.github.io/EnergyModelsBase.jl/stable/", + "EnergyModelsRenewableProducers" => "https://energymodelsx.github.io/EnergyModelsRenewableProducers.jl/stable/", ) makedocs( @@ -37,7 +38,13 @@ makedocs( "Quick Start"=>"manual/quick-start.md", "Release notes"=>"manual/NEWS.md", ], - "Types for EMX elements" => Any["Reference"=>"types/reference.md"], + "Nodes" => Any[ + "BioCHP"=>"nodes/biochp.md", + "WindPower"=>"nodes/windpower.md", + "PVandCSP"=>"nodes/pvandcsp.md", + "MultipleBuildingTypes"=>"nodes/multiplebuildingtypes.md", + ], + "Resources" => Any["ResourceBio"=>"resources/resourcebio.md"], "Utility functions" => Any["Reference"=>"util-fun/reference.md"], "How-to" => Any["Contribute"=>"how-to/contribute.md", "Utilize"=>"how-to/utilize.md"], diff --git a/docs/src/how-to/utilize.md b/docs/src/how-to/utilize.md index 8947096..4554139 100644 --- a/docs/src/how-to/utilize.md +++ b/docs/src/how-to/utilize.md @@ -18,6 +18,7 @@ output = EMLI.call_python_function("my_python_package", "my_func"; input) a local package you must create a conda environment (using a conda installation), or an other environment management system (not tested yet), and install required packages there. E.g., + ```bash conda create --name testenv python=3.10 conda activate testenv @@ -25,13 +26,16 @@ output = EMLI.call_python_function("my_python_package", "my_func"; input) cd path_to_your_python_project poetry install ``` + You must then (in Julia) set (it is here assumed you use miniconda on Windows) + ```julia using Pkg Pkg.add("PyCall") ENV["PYTHON"] = joinpath(homedir(), "AppData", "Local", "miniconda3", "envs", "testenv", "python.exe") Pkg.build("PyCall") ``` + and restart Julia. ### [Call C/C++ functions](@id how_to-utilize-ext_fun-Cpp) @@ -96,7 +100,7 @@ CxxWrap.prefix_path() which should return `"/home/user/.julia/dev/libcxxwrap_julia_jll/override"`. !!! note - If this instead returns `"/home/user/.julia/artifacts/5016ccec96368c99a5a678ab3319d1da7bb9a2c7"`, create a n`Overrides.toml` file at `/home/user/.julia/artifacts` with the following content + If this instead returns `"/home/user/.julia/artifacts/5016ccec96368c99a5a678ab3319d1da7bb9a2c7"`, create an `Overrides.toml` file at `/home/user/.julia/artifacts` with the following content ```toml [3eaa8342-bff7-56a5-9981-c04077f7cee7] @@ -110,3 +114,203 @@ which should return `"/home/user/.julia/dev/libcxxwrap_julia_jll/override"`. You can try to clone `CxxWrap`, change the toml file to `libcxxwrap_julia_jll = "0.13.4"` (instead of `0.14.0` which is not available yet), and `develop` `CxxWrap` in your environment. An example is given by the *[trippling_module example](https://github.com/EnergyModelsX/EnergyModelsLanguageInterfaces.jl/tree/main/test/trippling_module/)*. + +## [Use implemented nodes](@id how_to-utilize-use_nodes) + +The nodes [`WindPower`](@ref WindPower), [`CSPandPV`](@ref CSPandPV) and [`MultipleBuildingTypes`](@ref MultipleBuildingTypes) have constructors that samples [wind_power_timeseries](https://gitlab.sintef.no/harald.svendsen/wind_power_timeseries), [Tecnalia_Solar-Energy-Model](https://github.com/iDesignRES/Tecnalia_Solar-Energy-Model) and [Tecnalia_Building-Stock-Energy-Model](https://github.com/iDesignRES/Tecnalia_Building-Stock-Energy-Model), respectively. These modules are python based and the usage of these constructors requires installation of these as documented [below](@ref how_to-utilize-use_nodes-python_modules). + +Additionally, the node [`BioCHP`](@ref BioCHP) have a constructor that samples the [CHP_modelling](https://github.com/iDesignRES/CHP_modelling) module. This module is `C++` based and the constructor then requires compilation and build before usage as described further [below](@ref how_to-utilize-use_nodes-cpp_modules). + +The following installation guides will show how to install the modules to enable usage of these constructors for Windows. + +### [Clone repositories](@id how_to-utilize-use_nodes-clone_repos) + +Navigate to a folder in which you want to download required repositories and run + +```PowerShell +git clone --recurse-submodules git@github.com:EnergyModelsX/EnergyModelsLanguageInterfaces.jl.git +``` + +You should now be enabled to enter the main folder in which the other modules are located (under the submodules folder) + +```PowerShell +cd EnergyModelsLanguageInterfaces.jl +``` + +!!! note "Install git" + If you do not have git available in your PowerShell, make sure to [download](https://git-scm.com/install/windows) and install it properly (make sure to enable adjustment of the PATH environment). + + +### [Install python modules](@id how_to-utilize-use_nodes-python_modules) + +The following installs the modules using [`poetry`](https://pypi.org/project/poetry/) in a PowerShell in [VS code](https://code.visualstudio.com/). + +!!! note "Python installation" + You must have a python installation available in the terminal in VS code. + Python can be downloaded from [here](https://www.python.org/downloads/windows/) and installed by launching the downloaded installer (remember to "Add Python to PATH"). You must restart VS Code (and possibly any other open PowerShell windows) to have python available in the embedded VS code terminal. Check that you have python installed correctly with + + ```PowerShell + python --version + ``` + + which should return something like `Python 3.11.9`. + +Start by installing `poetry` using `pip` (which should be included in the python installation) + +```PowerShell +pip install poetry +``` + +Navigate to the submodule you want to install and run `poetry install`. If you want all python modules installed run the following + +```PowerShell +cd submodules/wind_power_timeseries +poetry install +cd ../.. +cd submodules/Tecnalia_Solar-Energy-Model +poetry install +cd ../.. +cd submodules/Tecnalia_Building-Stock-Energy-Model +poetry install +cd ../.. +``` + +If you want to be able to run the tests of the main repository later (see [Test modules](@ref how_to-utilize-use_nodes-test)), make sure to install the `python_module` (located in the `test/python_module` folder) + +```PowerShell +pip install highspy +cd test/python_module +poetry install +cd ../.. +``` + +!!! note "Environments" + If you are a developer, you probably want to install the python modules in a separate environment which can be done with, e.g., [miniconda](https://www.anaconda.com/docs/getting-started/miniconda/install). + +### [Install C++ modules](@id how_to-utilize-use_nodes-cpp_modules) + +Start by installing [`conan`](https://pypi.org/project/conan/) + +```PowerShell +pip install conan +``` + +Navigate to the `CHP_modelling` folder, build and install the module with the following + +```PowerShell +cd submodules/CHP_modelling +mkdir build +cd build +conan install .. --output-folder=. --build=missing -s compiler.cppstd=17 -s arch=x86_64 +cmake .. -DCMAKE_TOOLCHAIN_FILE="${PWD}/conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Release +cmake --build . --config Release +cd ../../.. +``` + +Enable these by starting a julia session in the main folder + +```PowerShell +julia --project=. +``` + +and run the following + +```julia +using Pkg +Pkg.instantiate() +ENV["PYTHON"] = joinpath(homedir(), "AppData", "Local", "Programs", "Python", "Python311", "python.exe") +Pkg.build("PyCall") +``` + +followed by restarting Julia. + +!!! note "Path to Python executable" + The path in the previous commands must be adjusted to the path of your python executable which can be found with + + ```PowerShell + (Get-Command python).Source + ``` + +### [Install modules on linux](@id how_to-utilize-use_nodes-linux) + +To perform the same installation above on linux you can navigate to a folder in which you want to download required repositories and run + +```bash +sudo apt-get update -qq +sudo apt-get install -y git glpk-utils g++ cmake wget curl python3-pip +pip install conan +conan profile detect +wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh +bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda +echo "$HOME/miniconda/bin" >> $GITHUB_PATH +source "$HOME/miniconda/etc/profile.d/conda.sh" + +conda create --name testenv python=3.11 -y +conda activate testenv +conda install -c conda-forge poetry -y + +git clone --recurse-submodules git@github.com:EnergyModelsX/EnergyModelsLanguageInterfaces.jl.git +cd "test/python_module" +poetry install +cd "../.." + +cd "submodules/wind_power_timeseries" +poetry install +cd "../.." + +cd "submodules/Tecnalia_Solar-Energy-Model" +poetry install +cd "../.." +cd "submodules/Tecnalia_Building-Stock-Energy-Model" +poetry install +cd "../.." + +cd "submodules/CHP_modelling" +mkdir build +cd build +conan install .. --output-folder=. --build=missing -s compiler.cppstd=17 -s arch=x86_64 +cmake .. -DCMAKE_TOOLCHAIN_FILE="${PWD}/conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Release +cmake --build . --config Release +cd "../../.." +``` + +Enable the python modules by starting a julia session in the main folder + +```PowerShell +julia --project=. +``` + +and run the following + +```julia +using Pkg; +Pkg.instantiate() +ENV["PYTHON"] = joinpath(ENV["HOME"], "miniconda", "envs", "testenv", "bin", "python"); +Pkg.build("PyCall"); +``` + +followed by restarting Julia. + +### [Test modules](@id how_to-utilize-use_nodes-test) + +All the mentioned constructors have been included in the tests of the repository and you may therefore check if everyting is properly setup by running these in julia. + +!!! note "Requirements" + The tests assumes that all modules listed in the [Install python modules](@ref how_to-utilize-use_nodes-python_modules) section and the [Install C++ modules](@ref how_to-utilize-use_nodes-cpp_modules) section has been installed. + +Start a new Julia session with + +```PowerShell +julia --project=. +``` + +and run the tests + +```julia +using Pkg +Pkg.test() +``` + +### [Utilize constructors](@id how_to-utilize-constructors) + +For detailed information on how to use the constructors, refer to the [test/utils.jl](https://github.com/EnergyModelsX/EnergyModelsLanguageInterfaces.jl/blob/main/test/utils.jl) file, which contains minimum working examples for both sampling the models and using saved sampled data. \ No newline at end of file diff --git a/docs/src/nodes/biochp.md b/docs/src/nodes/biochp.md new file mode 100644 index 0000000..6816d20 --- /dev/null +++ b/docs/src/nodes/biochp.md @@ -0,0 +1,166 @@ +# [BioCHP](@id nodes-BioCHP) + +The [`BioCHP`](@ref) node represents a biomass-fired combined heat and power (CHP) plant. + +!!! note "Sampling CHP_modelling module" + To use the constructor that samples the [CHP_modelling](https://github.com/iDesignRES/CHP_modelling) module, follow the installation in the [Use nodes](@ref how_to-utilize-use_nodes) section. + +The `BioCHP` utilizes linear, time-independent conversion rates from the `input` [`Resource`](@extref EnergyModelsBase.Resource)s to the `output` [`Resource`](@extref EnergyModelsBase.Resource)s, subject to the available capacity. +The capacity is normalized such that a conversion value of 1 corresponds to the nominal capacity in the fields `input` and `output`. + +Compared to a standard [`NetworkNode`](@extref EnergyModelsBase.NetworkNode), `BioCHP` differs in its outlet-flow constraints: +the produced heat does not have to be used (e.g., heat outputs are allowed to be zero), while electric output is enforced according to the given conversion factor. + +## [Introduced types and their fields](@id nodes-BioCHP-fields) + +The [`BioCHP`](@ref) is a subtype of the [`NetworkNode`](@extref EnergyModelsBase.NetworkNode). +It uses the standard `NetworkNode` functions from `EnergyModelsBase`. + +### [Standard fields](@id nodes-BioCHP-fields-stand) + +- **`id`**:\ + The field `id` is only used for providing a name to the node. + This is similar to the approach utilized in `EnergyModelsBase`. + +- **`cap::TimeProfile`**:\ + Specifies the installed capacity, that is the heat the heat pump can deliver.\ + If the node should contain investments through the application of [`EnergyModelsInvestments`](https://energymodelsx.github.io/EnergyModelsInvestments.jl/stable/), it is important to note that you can only use `FixedProfile` or `StrategicProfile` for the capacity, but not `RepresentativeProfile` or `OperationalProfile`.\ + In addition, all values have to be non-negative. + +- **`opex_var::TimeProfile`**:\ + The variable operational expenses are based on the capacity utilization through the variable [`:cap_use`](@extref EnergyModelsBase man-opt_var-cap). + Hence, it is directly related to the specified `output` ratios. + The variable operating expenses can be provided as `OperationalProfile` as well. + +- **`opex_fixed::TimeProfile`**:\ + The fixed operating expenses are relative to the installed capacity (through the field `cap`) and the chosen duration of a strategic period as outlined on *[Utilize `TimeStruct`](@extref EnergyModelsBase how_to-utilize_TS)*.\ + It is important to note that you can only use `FixedProfile` or `StrategicProfile` for the fixed OPEX, but not `RepresentativeProfile` or `OperationalProfile`. + In addition, all values have to be non-negative. + +- **`output::Dict{<:Resource, <:Real}`**:\ + The field `output` includes the output [`Resource`](@extref EnergyModelsBase.Resource)s with their corresponding conversion factors as dictionaries. + It is also possible to include other resources which are produced with a given correlation with the heat.\ + All values have to be non-negative. + +- **`data::Vector{<:ExtensionData}`**:\ + An entry for providing additional data to the model. + In the current version, it is only relevant for additional investment data when [`EnergyModelsInvestments`](https://energymodelsx.github.io/EnergyModelsInvestments.jl/) is used or for additional emission data through [`EmissionsProcess`](@extref EnergyModelsBase.EmissionsProcess). + The latter would correspond to uncaptured CO₂ that should be included in the analyses. + !!! note + The field `data` is not required as we include a constructor when the value is excluded. + +### [New fields](@id nodes-BioCHP-fields-new) + +- **`electricity_resource::Resource`**:\ + The electric power resource produced by the CHP plant. + This field is used to distinguish electricity from (potential) heat outputs in the outlet-flow constraints. + +- **`input::Dict{<:ResourceBio, <:Real}`**:\ + The biomass input resources (of type [`ResourceBio`](@ref)) and their conversion factors. + These conversion factors are normalized to the capacity definition of the node. + +!!! note "Default `data` constructor" + The provided constructor assigns `data = [EmissionsEnergy()]` by default. + This means the node includes energy-based emission accounting unless overwritten by explicitly constructing `BioCHP` with a custom `data` vector. + +## [Mathematical description](@id nodes-BioCHP-math) + +In the following mathematical equations, we use the names for variables and functions used in the model. +Variables are in general represented as + +``\texttt{var\_example}[index_1, index_2]`` + +with square brackets, while functions are represented as + +``func\_example(index_1, index_2)`` + +with paranthesis. + +### [Variables](@id nodes-BioCHP-math-var) + +The [`BioCHP`](@ref) node uses standard `NetworkNode` variables, as described on the page *[Optimization variables](@extref EnergyModelsBase man-opt_var)*. +The variables include: + +- [``\texttt{opex\_var}``](@extref EnergyModelsBase man-opt_var-opex) +- [``\texttt{opex\_fixed}``](@extref EnergyModelsBase man-opt_var-opex) +- [``\texttt{cap\_use}``](@extref EnergyModelsBase man-opt_var-cap) +- [``\texttt{cap\_inst}``](@extref EnergyModelsBase man-opt_var-cap) +- [``\texttt{flow\_in}``](@extref EnergyModelsBase man-opt_var-flow) +- [``\texttt{flow\_out}``](@extref EnergyModelsBase man-opt_var-flow) + +### [Constraints](@id nodes-BioCHP-math-con) + +The following sections omit the direct inclusion of the vector of heat pump nodes. +Instead, it is implicitly assumed that the constraints are valid ``\forall n ∈ N^{BioCHP}`` for all [`BioCHP`](@ref) types if not stated differently. +In addition, all constraints are valid ``\forall t \in T`` (that is in all operational periods) or ``\forall t_{inv} \in T^{Inv}`` (that is in all strategic periods). + +#### [Standard constraints](@id nodes-BioCHP-math-con-stand) + +`BioCHP` nodes utilize in general the standard constraints described on +*[Constraint functions](@extref EnergyModelsBase man-con)* for `NetworkNode`s. +These standard constraints are: + +- `constraints_capacity`: + + ```math + \texttt{cap\_use}[n, t] \leq \texttt{cap\_inst}[n, t] + ``` + +- `constraints_capacity_installed`: + + ```math + \texttt{cap\_inst}[n, t] = capacity(n, t) + ``` + + !!! tip "Using investments" + The function `constraints_capacity_installed` is also used in [`EnergyModelsInvestments`](https://energymodelsx.github.io/EnergyModelsInvestments.jl/) to incorporate the potential for investment. + Nodes with investments are then no longer constrained by the parameter capacity. + +- `constraints_flow_out`: + + ```math + \texttt{flow\_out}[n, t, p] = + outputs(n, p) \times \texttt{cap\_use}[n, t] + \qquad \forall p \in outputs(n) \setminus \{\text{CO}_2\} + ``` + +- `constraints_opex_fixed`: + + ```math + \texttt{opex\_fixed}[n, t_{inv}] = opex\_fixed(n, t_{inv}) \times \texttt{cap\_inst}[n, first(t_{inv})] + ``` + + !!! tip "Why do we use `first()`" + The variable ``\texttt{cap\_inst}`` is declared over all operational periods (see the section on *[Capacity variables](@extref EnergyModelsBase man-opt_var-cap)* for further explanations). + Hence, we use the function ``first(t_{inv})`` to retrieve the installed capacity in the first operational period of a given strategic period ``t_{inv}`` in the function `constraints_opex_fixed`. + +- `constraints_opex_var`: + + ```math + \texttt{opex\_var}[n, t_{inv}] = \sum_{t \in t_{inv}} opex\_var(n, t) \times \texttt{cap\_use}[n, t] \times scale\_op\_sp(t_{inv}, t) + ``` + + !!! tip "The function `scale_op_sp`" + The function [``scale\_op\_sp(t_{inv}, t)``](@extref EnergyModelsBase.scale_op_sp) calculates the scaling factor between operational and strategic periods. + It also takes into account potential operational scenarios and their probability as well as representative periods. + +- `constraints_ext_data`:\ + This function is only called for specified data of the storage node, see above. + +The function `constraints_flow_out` is extended with a new method for BioCHP nodes such that the outputs are flexible with respect to output resources not being the `electricity_resource`. + +Let ``\mathcal{P}^{out}(n)`` denote the set of output resources of node ``n`` excluding CO₂ and `electricity_resource`. The implemented constraint is + +```math +\texttt{flow\_out}[n, t, p] = outputs(n, p) \times \texttt{cap\_use}[n, t] \qquad \forall p \in \mathcal{P}^{out}(n) +``` + +For the `electricity_resource` we still have + +```math +\texttt{flow\_out}[n, t, electricity_resource(n)] = outputs(n, electricity_resource(n)) \times \texttt{cap\_use}[n, t] +``` + +#### [Additional constraints](@id nodes-BioCHP-math-con-add) + +[`BioCHP`](@ref) nodes do not add additional constraint functions or constraints in the `create_node` function. diff --git a/docs/src/nodes/multiplebuildingtypes.md b/docs/src/nodes/multiplebuildingtypes.md new file mode 100644 index 0000000..c8cf912 --- /dev/null +++ b/docs/src/nodes/multiplebuildingtypes.md @@ -0,0 +1,149 @@ +# [Multiple building types sink node](@id nodes-MultipleBuildingTypes) + +The [`MultipleBuildingTypes`](@ref) node creates sinks for all demand resources with penalties for both surplus and deficit. +The implementation uses `Dict` structures for the fields `cap`, `penalty_surplus`, and `penalty_deficit` to facilitate multiple [Resource](@extref EnergyModelsBase.Resource)s. +This approach allows modeling building demands with flexible penalty mechanisms for over- and under-supply. + +!!! danger + Investments are currently not available for this node. + +## [Introduced type and its field](@id nodes-MultipleBuildingTypes-fields) + +The [`MultipleBuildingTypes`](@ref) is a subtype of [`Sink`](@extref EnergyModelsBase.Sink) and is implemented as a specialized sink node. +Hence, it utilizes the same functions declared in `EnergyModelsBase`. + +### [Standard fields](@id nodes-MultipleBuildingTypes-fields-stand) + +Standard fields of a [`MultipleBuildingTypes`](@ref) node are given as: + +- **`id`**:\ + The field `id` is only used for providing a name to the node. + This is similar to the approach utilized in `EnergyModelsBase`. +- **`input::Dict{<:Resource, <:Real}`**:\ + The field `input` includes [`Resource`](@extref EnergyModelsBase.Resource)s with their corresponding conversion factors as dictionaries. + All values have to be non-negative. +- **`data::Vector{Data}`**:\ + An entry for providing additional data to the model. + In the current version, it is not applicable. We intend to change this in future releases to enable investments. + + !!! note "Constructor for `MultipleBuildingTypes`" + The field `data` is not required as we include a constructor when the value is excluded. + + !!! danger "Using `CaptureData`" + As a `Sink` node does not have any output, it is not possible to utilize `CaptureData`. + If you still plan to specify it, you will receive an error in the model building. + +### [Additional fields](@id nodes-MultipleBuildingTypes-fields-new) + +[`MultipleBuildingTypes`](@ref) nodes introduce additional fields for demand and penalty specifications: + +- **`cap::Dict{<:Resource,<:TimeProfile}`**:\ + The demand capacity for each of the input resources. + All values have to be non-negative. +- **`penalty_surplus::Dict{<:Resource,<:TimeProfile}`**:\ + The penalties applied for surplus (over-supply) for each of the input resources. + These penalties affect the variable operational expenses. + All values have to be non-negative. +- **`penalty_deficit::Dict{<:Resource,<:TimeProfile}`**:\ + The penalties applied for deficit (under-supply) for each of the input resources. + These penalties affect the variable operational expenses. + All values have to be non-negative. + +## [Mathematical description](@id nodes-MultipleBuildingTypes-math) + +In the following mathematical equations, we use the name for variables and functions used in the model. +Variables are in general represented as + +``\texttt{var\_example}[index_1, index_2]`` + +with square brackets, while functions are represented as + +``func\_example(index_1, index_2)`` + +with paranthesis. + +### [Variables](@id nodes-MultipleBuildingTypes-math-var) + +#### [Standard variables](@id nodes-MultipleBuildingTypes-math-var-stand) + +The [`MultipleBuildingTypes`](@ref) node type utilizes standard variables from the [`Sink`](@extref EnergyModelsBase.Sink) node type and includes: + +- [``\texttt{opex\_var}``](@extref EnergyModelsBase man-opt_var-opex) +- [``\texttt{opex\_fixed}``](@extref EnergyModelsBase man-opt_var-opex) +- [``\texttt{flow\_in}``](@extref EnergyModelsBase man-opt_var-flow) +- [``\texttt{sink\_surplus}``](@extref EnergyModelsBase man-opt_var-sink) +- [``\texttt{sink\_deficit}``](@extref EnergyModelsBase man-opt_var-sink) +- [``\texttt{emissions\_node}``](@extref EnergyModelsBase man-opt_var-emissions) if `EmissionsData` is added to the field `data` + +!!! note "cap\_use" + The standard variable [``\texttt{cap\_use}``](@extref EnergyModelsBase man-opt_var-opex) is not used. A MultipleBuildingTypes has capacity for all its resources but not in a EnergyModelsBase sense. + +#### [Additional variables](@id nodes-MultipleBuildingTypes-math-add) + +[`MultipleBuildingTypes`](@ref) introduces the following variables: + +- ``\texttt{buildings\_surplus}[n, t, p]``: Surplus (over-supply) for node ``n`` in operational period ``t`` for resource ``p``. +- ``\texttt{buildings\_deficit}[n, t, p]``: Deficit (under-supply) for node ``n`` in operational period ``t`` for resource ``p``. +- ``\texttt{sink\_surplus}[n, t]``: Total surplus aggregated across all resources. +- ``\texttt{sink\_deficit}[n, t]``: Total deficit aggregated across all resources. + +### [Constraints](@id nodes-MultipleBuildingTypes-math-con) + +The following sections omit the direct inclusion of the vector of [`MultipleBuildingTypes`](@ref) nodes. +Instead, it is implicitly assumed that the constraints are valid ``\forall n ∈ N^{\text{MultipleBuildingTypes}}`` if not stated differently. +In addition, all constraints are valid ``\forall t \in T`` (that is in all operational periods) or ``\forall t_{inv} \in T^{Inv}`` (that is in all strategic periods). +Finally, all constraints are valid ``\forall p \in inputs(n)`` (that is in all input resources). + +#### [Standard constraints](@id nodes-MultipleBuildingTypes-math-con-stand) + +[`MultipleBuildingTypes`](@ref) nodes utilize the following constraint functions: + +- `constraints_capacity`: + + ```math + \frac{\texttt{flow\_in}[n, t, p]}{inputs(n, p)} + \texttt{buildings\_deficit}[n, t, p] = + capacity(n, t, p) + \texttt{buildings\_surplus}[n, t, p] + \qquad \forall p \in inputs(n) + ``` + + ```math + \texttt{sink\_deficit}[n, t] = \sum_{p \in inputs(n)} \texttt{buildings\_deficit}[n, t, p] + ``` + + ```math + \texttt{sink\_surplus}[n, t] = \sum_{p \in inputs(n)} \texttt{buildings\_surplus}[n, t, p] + ``` + + !!! note "constraints_capacity_installed" + The function `constraints_capacity_installed` is not used and the node thus currently does not support investments. + +- `constraints_flow_in`:\ + This function is not used; inlet flow constraints are implemented directly in `constraints_capacity`. + +- `constraints_opex_fixed`:\ + The current implementation fixes the fixed operating expenses of a sink to 0. + + ```math + \texttt{opex\_fixed}[n, t_{inv}] = 0 + ``` + +- `constraints_opex_var`: + + ```math + \texttt{opex\_var}[n, t_{inv}] = \sum_{t \in t_{inv},\, p \in inputs(n)} + \left( + \texttt{buildings\_surplus}[n, t, p] \times penalty\_surplus(n, t, p) + + \texttt{buildings\_deficit}[n, t, p] \times penalty\_deficit(n, t, p) + \right) \times scale\_op\_sp(t_{inv}, t) + ``` + + !!! tip "The function `scale_op_sp`" + The function [``scale\_op\_sp(t_{inv}, t)``](@extref EnergyModelsBase.scale_op_sp) calculates the scaling factor between operational and strategic periods. + It also takes into account potential operational scenarios and their probability as well as representative periods. + +- `constraints_ext_data`:\ + This function is only called for specified additional data, see above. + +#### [Additional constraints](@id nodes-MultipleBuildingTypes-math-con-add) + +[`MultipleBuildingTypes`](@ref) nodes do not add additional constraints. diff --git a/docs/src/nodes/pvandcsp.md b/docs/src/nodes/pvandcsp.md new file mode 100644 index 0000000..5f4c3ba --- /dev/null +++ b/docs/src/nodes/pvandcsp.md @@ -0,0 +1,154 @@ +# [PV and CSV source node](@id nodes-CSPandPV) + +PV and CSP source generate, respectively, electricity and heat from solar power. +The implementation of the node is similar to that of [NonDisRES](@extref EnergyModelsRenewableProducers nodes-nondisres) but uses `Dict` structures for the fields `cap`, `profile`, `opex_var` and `opex_fixed` to facilitate multiple [Resource](@extref EnergyModelsBase.Resource)s (both electricity and heat outputs). +The type is also used to enable specialized constructors that samples the [Tecnalia_Solar-Energy-Model](https://github.com/iDesignRES/Tecnalia_Solar-Energy-Model) module. + +!!! note "Sampling Tecnalia_Solar-Energy-Model module" + To use the constructor that samples the [Tecnalia_Solar-Energy-Model](https://github.com/iDesignRES/Tecnalia_Solar-Energy-Model) module, follow the installation in the [Use nodes](@ref how_to-utilize-use_nodes) section. + +!!! danger + Investments are currently not available for this node. + +## [Introduced type and its field](@id nodes-CSPandPV-fields) + +The [`CSPandPV`](@ref) is a subtype of [`AbstractNonDisRES`](@extref EnergyModelsRenewableProducers.AbstractNonDisRES) (the same is the case for [NonDisRES](@extref EnergyModelsRenewableProducers nodes-nondisres)) and is thus implemented as equivalent to a [`RefSource`](@extref EnergyModelsBase.RefSource). +Hence, it utilizes the same functions declared in `EnergyModelsBase`. + +### [Standard fields](@id nodes-CSPandPV-fields-stand) + +Standard fields (of a [`AbstractNonDisRES`](@extref EnergyModelsRenewableProducers.AbstractNonDisRES)) being reused are given as: + +- **`id`**:\ + The field `id` is only used for providing a name to the node. + This is similar to the approach utilized in `EnergyModelsBase`. +- **`output::Dict{<:Resource, <:Real}`**:\ + The field `output` includes [`Resource`](@extref EnergyModelsBase.Resource)s with their corresponding conversion factors as dictionaries. + In the case of a PV and CSP energy source, `output` should always include your *electricity* resource and a *heat* resource. In practice, you should use a value of 1.\ + All values have to be non-negative. +- **`data::Vector{Data}`**:\ + An entry for providing additional data to the model. + In the current version, it is not applicable. We intend to change this in future releases to enable investments. + + !!! note "Constructor for `CSPandPV`" + The field `data` is not required as we include a constructor when the value is excluded. + +### [Additional fields](@id nodes-CSPandPV-fields-new) + +[`CSPandPV`](@ref) nodes alter the types of some fields compared to a [`AbstractNonDisRES`](@extref EnergyModelsRenewableProducers.AbstractNonDisRES): + +- **`cap::Dict{<:Resource,<:TimeProfile}`**:\ + The installed capacity corresponds to the nominal capacity of the node for each of the produced resources.\ + If the node should contain investments through the application of [`EnergyModelsInvestments`](https://energymodelsx.github.io/EnergyModelsInvestments.jl/stable/), it is important to note that you can only use `FixedProfile` or `StrategicProfile` for the capacity, but not `RepresentativeProfile` or `OperationalProfile`. + In addition, all values have to be non-negative. +- **`profile::Dict{<:Resource,<:TimeProfile}`**:\ + The profiles are used as a multiplier to the installed capacity to represent the maximum actual capacity in each operational period for each of the produced resources. + The profiles should be provided as `OperationalProfile` or at least as `RepresentativeProfile`. + In addition, all values should be in the range ``[0, 1]``. +- **`opex_var::Dict{<:Resource,<:TimeProfile}`**:\ + The variable operational expenses are based on the capacity utilization through the variable [`:cap_use`](@extref EnergyModelsBase man-opt_var-cap) for each of the produced resources. + Hence, it is directly related to the specified `output` ratios. + The variable operating expenses can be provided as `OperationalProfile` as well. +- **`opex_fixed::Dict{<:Resource,<:TimeProfile}`**:\ + The fixed operating expenses are relative to the installed capacity (through the field `cap`) for each of the produced resources and the chosen duration of a strategic period as outlined on *[Utilize `TimeStruct`](@extref EnergyModelsBase how_to-utilize_TS)*.\ + It is important to note that you can only use `FixedProfile` or `StrategicProfile` for the fixed OPEX, but not `RepresentativeProfile` or `OperationalProfile`. + In addition, all values have to be non-negative. + +## [Mathematical description](@id nodes-CSPandPV-math) + +In the following mathematical equations, we use the name for variables and functions used in the model. +Variables are in general represented as + +``\texttt{var\_example}[index_1, index_2]`` + +with square brackets, while functions are represented as + +``func\_example(index_1, index_2)`` + +with paranthesis. + +### [Variables](@id nodes-CSPandPV-math-var) + +#### [Standard variables](@id nodes-CSPandPV-math-var-stand) + +The PV and CSP source node types utilize all standard variables from the [`AbstractNonDisRES`](@extref EnergyModelsRenewableProducers.AbstractNonDisRES) node type. +The variables include: + +- [``\texttt{opex\_var}``](@extref EnergyModelsBase man-opt_var-opex) +- [``\texttt{opex\_fixed}``](@extref EnergyModelsBase man-opt_var-opex) +- [``\texttt{cap\_inst}``](@extref EnergyModelsBase man-opt_var-cap) +- [``\texttt{flow\_out}``](@extref EnergyModelsBase man-opt_var-flow) +- [``\texttt{emissions\_node}``](@extref EnergyModelsBase man-opt_var-emissions) if `EmissionsData` is added to the field `data`. +- [``\texttt{curtailment}[n, t]``](@extref EnergyModelsRenewableProducers nodes-nondisres-math-add): For [`CSPandPV`](@ref), this variable is the sum of curtailed capacity of source ``n`` in operational period ``t``.\ + +!!! note + Non-dispatchable renewable energy source nodes are not compatible with `CaptureData`. + Hence, you can only provide [`EmissionsProcess`](@extref EnergyModelsBase.EmissionsProcess) to the node. + It is our aim to include the potential for construction emissions in a latter stage + +#### [Additional variables](@id nodes-CSPandPV-math-add) + +[`CSPandPV`](@ref) replaces the variables [``\texttt{cap\_use}``](@extref EnergyModelsBase man-opt_var-cap) and [``\texttt{curtailment}``](@extref EnergyModelsRenewableProducers nodes-nondisres-math-add) variables with the following variables + +- ``\texttt{solar\_cap\_use}[n, t, p]``: The capacity usage of source ``n`` in operational period ``t`` for resource ``p``. +- ``\texttt{solar\_curtailment}[n, t, p]``: Curtailed capacity of source ``n`` in operational period ``t`` for resource ``p`` with a typical unit of MW.\ + The curtailed resources specifies the unused generation capacity of sources. + It is currently only used in the calculation, but not with a cost. + +### [Constraints](@id nodes-CSPandPV-math-con) + +The following sections omit the direct inclusion of the vector of PV and CSP source nodes. +Instead, it is implicitly assumed that the constraints are valid ``\forall n ∈ N^{\text{CSPandPV}\_source}`` for all [`CSPandPV`](@ref) types if not stated differently. +In addition, all constraints are valid ``\forall t \in T`` (that is in all operational periods) or ``\forall t_{inv} \in T^{Inv}`` (that is in all strategic periods). +Finally, all constraints are valid ``\forall p \in outputs(n)`` (that is in all output resources). + +#### [Standard constraints](@id nodes-CSPandPV-math-con-stand) + +[`CSPandPV`](@ref) nodes utilize specialized constraint functions that extend the standard approach to accommodate multiple resources with per-resource tracking. +These constraints are: + +- `constraints_capacity`: + + ```math + \texttt{solar\_cap\_use}[n, t, p] \leq capacity(n, t, p) + ``` + + ```math + \texttt{solar\_cap\_use}[n, t, p] + \texttt{solar\_curtailment}[n, t, p] = + profile(n, t, p) \times capacity(n, t, p) + \qquad \forall p \in outputs(n) + ``` + + ```math + \sum_{p \in outputs(n)} \texttt{solar\_curtailment}[n, t, p] = \texttt{curtailment}[n, t] + ``` + + !!! note "constraints_capacity_installed" + The function `constraints_capacity_installed` is not used and the node thus currently does not support investments. + +- `constraints_flow_out`: + + ```math + \texttt{flow\_out}[n, t, p] = + \texttt{solar\_cap\_use}[n, t, p] \times outputs(n, p) + \qquad \forall p \in outputs(n) \setminus \{\text{CO}_2\} + ``` + +- `constraints_opex_fixed`: + + ```math + \texttt{opex\_fixed}[n, t_{inv}] = \sum_{p \in outputs(n)} opex\_fixed(n, t_{inv}, p) \times capacity(n, first(t_{inv}), p) + ``` + +- `constraints_opex_var`: + + ```math + \texttt{opex\_var}[n, t_{inv}] = \sum_{t \in t_{inv},\, p \in outputs(n)} \texttt{solar\_cap\_use}[n, t, p] \times opex\_var(n, t, p) \times scale\_op\_sp(t_{inv}, t) + ``` + +- `constraints_data`:\ + This function is only called for specified data of the node, see above. + +#### [Additional constraints](@id nodes-CSPandPV-math-con-add) + +[`CSPandPV`](@ref) nodes do not add additional constraints. \ No newline at end of file diff --git a/docs/src/nodes/windpower.md b/docs/src/nodes/windpower.md new file mode 100644 index 0000000..45be75c --- /dev/null +++ b/docs/src/nodes/windpower.md @@ -0,0 +1,161 @@ +# [Wind power source node](@id nodes-WindPower) + +Wind power source generate electricity from wind sources. +The implementation of the node is identical to that of [NonDisRES](@extref EnergyModelsRenewableProducers nodes-nondisres) and is here used to enable specialized constructors that samples the [`wind_power_timeseries`](https://gitlab.sintef.no/harald.svendsen/wind_power_timeseries) module. + +!!! note "Sampling wind\_power\_timeseries module" + To use the constructor that samples the [`wind_power_timeseries`](https://gitlab.sintef.no/harald.svendsen/wind_power_timeseries) module, follow the installation in the [Use nodes](@ref how_to-utilize-use_nodes) section. + +## [Introduced type and its field](@id nodes-WindPower-fields) + +The [`WindPower`](@ref) is a subtype of [`AbstractNonDisRES`](@extref EnergyModelsRenewableProducers.AbstractNonDisRES) (the same is the case for [NonDisRES](@extref EnergyModelsRenewableProducers nodes-nondisres)) and is thus implemented as equivalent to a [`RefSource`](@extref EnergyModelsBase.RefSource). +Hence, it utilizes the same functions declared in `EnergyModelsBase`. + +### [Standard fields](@id nodes-WindPower-fields-stand) + +The standard fields (of a [`AbstractNonDisRES`](@extref EnergyModelsRenewableProducers.AbstractNonDisRES)) are given as: + +- **`id`**:\ + The field `id` is only used for providing a name to the node. + This is similar to the approach utilized in `EnergyModelsBase`. +- **`cap::TimeProfile`**:\ + The installed capacity corresponds to the nominal capacity of the node.\ + If the node should contain investments through the application of [`EnergyModelsInvestments`](https://energymodelsx.github.io/EnergyModelsInvestments.jl/stable/), it is important to note that you can only use `FixedProfile` or `StrategicProfile` for the capacity, but not `RepresentativeProfile` or `OperationalProfile`. + In addition, all values have to be non-negative. +- **`profile::TimeProfile`**:\ + The profile is used as a multiplier to the installed capacity to represent the maximum actual capacity in each operational period. + The profile should be provided as `OperationalProfile` or at least as `RepresentativeProfile`. + In addition, all values should be in the range ``[0, 1]``. +- **`opex_var::TimeProfile`**:\ + The variable operational expenses are based on the capacity utilization through the variable [`:cap_use`](@extref EnergyModelsBase man-opt_var-cap). + Hence, it is directly related to the specified `output` ratios. + The variable operating expenses can be provided as `OperationalProfile` as well. +- **`opex_fixed::TimeProfile`**:\ + The fixed operating expenses are relative to the installed capacity (through the field `cap`) and the chosen duration of a strategic period as outlined on *[Utilize `TimeStruct`](@extref EnergyModelsBase how_to-utilize_TS)*.\ + It is important to note that you can only use `FixedProfile` or `StrategicProfile` for the fixed OPEX, but not `RepresentativeProfile` or `OperationalProfile`. + In addition, all values have to be non-negative. +- **`output::Dict{<:Resource, <:Real}`**:\ + The field `output` includes [`Resource`](@extref EnergyModelsBase.Resource)s with their corresponding conversion factors as dictionaries. + In the case of a non-dispatchable renewable energy source, `output` should always include your *electricity* resource.In practice, you should use a value of 1.\ + All values have to be non-negative. +- **`data::Vector{Data}`**:\ + An entry for providing additional data to the model. + In the current version, it is only relevant for additional investment data when [`EnergyModelsInvestments`](https://energymodelsx.github.io/EnergyModelsInvestments.jl/stable/) is used. + + !!! note "Constructor for `WindPower`" + The field `data` is not required as we include a constructor when the value is excluded. + +### [Additional fields](@id nodes-WindPower-fields-new) + +[`WindPower`](@ref) adds no additional fields to that of [`AbstractNonDisRES`](@extref EnergyModelsRenewableProducers.AbstractNonDisRES). + +## [Mathematical description](@id nodes-WindPower-math) + +In the following mathematical equations, we use the name for variables and functions used in the model. +Variables are in general represented as + +``\texttt{var\_example}[index_1, index_2]`` + +with square brackets, while functions are represented as + +``func\_example(index_1, index_2)`` + +with paranthesis. + +### [Variables](@id nodes-WindPower-math-var) + +#### [Standard variables](@id nodes-WindPower-math-var-stand) + +The wind power source node types utilize all standard variables from the [`AbstractNonDisRES`](@extref EnergyModelsRenewableProducers.AbstractNonDisRES) node type. +The variables include: + +- [``\texttt{opex\_var}``](@extref EnergyModelsBase man-opt_var-opex) +- [``\texttt{opex\_fixed}``](@extref EnergyModelsBase man-opt_var-opex) +- [``\texttt{cap\_use}``](@extref EnergyModelsBase man-opt_var-cap) +- [``\texttt{cap\_inst}``](@extref EnergyModelsBase man-opt_var-cap) +- [``\texttt{flow\_out}``](@extref EnergyModelsBase man-opt_var-flow) +- [``\texttt{emissions\_node}``](@extref EnergyModelsBase man-opt_var-emissions) if `EmissionsData` is added to the field `data`. +- [``\texttt{curtailment}[n, t]``](@extref EnergyModelsRenewableProducers nodes-nondisres-math-add): Curtailed capacity of source ``n`` in operational period ``t`` with a typical unit of MW.\ + The curtailed electricity specifies the unused generation capacity of the wind power source. + It is currently only used in the calculation, but not with a cost. + +!!! note + Non-dispatchable renewable energy source nodes are not compatible with `CaptureData`. + Hence, you can only provide [`EmissionsProcess`](@extref EnergyModelsBase.EmissionsProcess) to the node. + It is our aim to include the potential for construction emissions in a latter stage + +#### [Additional variables](@id nodes-WindPower-math-add) + +[`WindPower`](@ref) adds no additional variables to that of [`AbstractNonDisRES`](@extref EnergyModelsRenewableProducers.AbstractNonDisRES). + +### [Constraints](@id nodes-WindPower-math-con) + +The following sections omit the direct inclusion of the vector of wind power nodes. +Instead, it is implicitly assumed that the constraints are valid ``\forall n ∈ N^{\text{WindPower}\_source}`` for all [`WindPower`](@ref) types if not stated differently. +In addition, all constraints are valid ``\forall t \in T`` (that is in all operational periods) or ``\forall t_{inv} \in T^{Inv}`` (that is in all strategic periods). + +#### [Standard constraints](@id nodes-WindPower-math-con-stand) + +Wind power source nodes utilize in general the standard constraints described on *[Constraint functions](@extref EnergyModelsRenewableProducers nodes-nondisres-math-con)*. +These standard constraints are: + +- `constraints_capacity_installed`: + + ```math + \texttt{cap\_inst}[n, t] = capacity(n, t) + ``` + + !!! tip "Using investments" + The function `constraints_capacity_installed` is also used in [`EnergyModelsInvestments`](https://energymodelsx.github.io/EnergyModelsInvestments.jl/stable/) to incorporate the potential for investment. + Nodes with investments are then no longer constrained by the parameter capacity. + +- `constraints_flow_out`: + + ```math + \texttt{flow\_out}[n, t, p] = + outputs(n, p) \times \texttt{cap\_use}[n, t] + \qquad \forall p \in outputs(n) \setminus \{\text{CO}_2\} + ``` + +- `constraints_opex_fixed`: + + ```math + \texttt{opex\_fixed}[n, t_{inv}] = opex\_fixed(n, t_{inv}) \times \texttt{cap\_inst}[n, first(t_{inv})] + ``` + + !!! tip "Why do we use `first()`" + The variables ``\texttt{cap\_inst}`` are declared over all operational periods (see the section on *[Capacity variables](@extref EnergyModelsBase man-opt_var-cap)* for further explanations). + Hence, we use the function ``first(t_{inv})`` to retrieve the installed capacities in the first operational period of a given strategic period ``t_{inv}`` in the function `constraints_opex_fixed`. + +- `constraints_opex_var`: + + ```math + \texttt{opex\_var}[n, t_{inv}] = \sum_{t \in t_{inv}} opex\_var(n, t) \times \texttt{cap\_use}[n, t] \times scale\_op\_sp(t_{inv}, t) + ``` + + !!! tip "The function `scale_op_sp`" + The function [``scale\_op\_sp(t_{inv}, t)``](@extref EnergyModelsBase.scale_op_sp) calculates the scaling factor between operational and strategic periods. + It also takes into account potential operational scenarios and their probability as well as representative periods. + +- `constraints_data`:\ + This function is only called for specified data of the non-dispatchable renewable energy source, see above. + +The function `constraints_capacity` is extended by [`AbstractNonDisRES`](@extref EnergyModelsRenewableProducers.AbstractNonDisRES) with a method for non-dispatchable renewable energy source nodes to allow the inclusion of the production profile and the variable ``\texttt{curtailment}[n, t]``. +It includes two individual constraints: + +```math +\texttt{cap\_use}[n, t] \leq \texttt{cap\_inst}[n, t] +``` + +and + +```math +\texttt{cap\_use}[n, t] + \texttt{curtailment}[n, t] = +profile(n, t) \times \texttt{cap\_inst}[n, t] +``` + +This function still calls the subfunction `constraints_capacity_installed` to limit the variable ``\texttt{cap\_inst}[n, t]`` or provide capacity investment options. + +#### [Additional constraints](@id nodes-WindPower-math-con-add) + +[`WindPower`](@ref) nodes do not add additional constraints. \ No newline at end of file diff --git a/docs/src/resources/resourcebio.md b/docs/src/resources/resourcebio.md new file mode 100644 index 0000000..af2d99a --- /dev/null +++ b/docs/src/resources/resourcebio.md @@ -0,0 +1,28 @@ +# [ResourceBio](@id resources-ResourceBio) + +Biomass fuels have characteristics that go beyond a pure energy carrier, such as the specific fuel type and the moisture content of the material. +[`ResourceBio`](@ref), which is a [`Resource`](@extref EnergyModelsBase.Resource) for transporting and converting biomass fuels, is introduced to enable consistent modeling of biomass-based energy technologies in [EnergyModelsX](https://github.com/EnergyModelsX). + +Compared to a [`ResourceCarrier`](@extref EnergyModelsBase.ResourceCarrier), [`ResourceBio`](@ref) includes additional information on the biomass fuel definition and its moisture content. +Resources of type [`ResourceBio`](@ref) are intended to be *consumed* by technologies (e.g. biomass boilers or CHP plants). + +## [Introduced type and its fields](@id resources-ResourceBio-fields) + +[`ResourceBio`](@ref) extends the abstract type +[`Resource`](https://github.com/EnergyModelsX/EnergyModelsBase.jl/blob/main/src/structures/resource.jl) +from [EnergyModelsBase](https://github.com/EnergyModelsX/EnergyModelsBase.jl/tree/main), +with additional fields describing biomass-specific properties. + +- **`id`** :\ + The field `id` is only used for providing a name to the resource. + +- **`bio_type::String`** :\ + The type of biomass fuel, e.g. `"spruce_stem"`, `"spruce_bark"`, `"spruce_T&B"`, or `"birch_stem"`. + +- **`moisture::Float64`** :\ + Moisture content of the biomass resource as a mass fraction. + Typical values range from around 0.1 for dry pellets to more than 0.5 for wet wood chips. + +- **`co2_int::T`** :\ + CO₂ intensity of the biomass resource (with `T <: Real`), e.g. in t/MWh. + This value can be used by emissions-accounting extensions when biomass is converted or consumed. \ No newline at end of file diff --git a/docs/src/types/reference.md b/docs/src/types/reference.md deleted file mode 100644 index f74c562..0000000 --- a/docs/src/types/reference.md +++ /dev/null @@ -1 +0,0 @@ -# [Reference](@id types-ref) diff --git a/src/datastructures.jl b/src/datastructures.jl index 309ddfb..de654e3 100644 --- a/src/datastructures.jl +++ b/src/datastructures.jl @@ -715,8 +715,11 @@ library file located at `libpath`. The BioCHP has electricity production of the - **`data::Vector{<:Data}`** is the additional data (*e.g.*, for investments). - **`libpath`** is the absolute path of the `CHP_modelling` library file. -!!! note ""EmissionsEnergy" +!!! note "EmissionsEnergy" If `EmissionsEnergy` is not included in the `data` field, it is automatically added. + +!!! note "Running on windows" + Adjust the `libpath` to point to the correct `.dll` file when running on Windows. """ function BioCHP( id::Any, diff --git a/submodules/Tecnalia_Building-Stock-Energy-Model b/submodules/Tecnalia_Building-Stock-Energy-Model index 4bd8989..76ee2e3 160000 --- a/submodules/Tecnalia_Building-Stock-Energy-Model +++ b/submodules/Tecnalia_Building-Stock-Energy-Model @@ -1 +1 @@ -Subproject commit 4bd8989caa2767ce66b466945e0d366cc4bba2d7 +Subproject commit 76ee2e31db400f4bf66deaa84285826fe363f0c7 diff --git a/submodules/Tecnalia_Solar-Energy-Model b/submodules/Tecnalia_Solar-Energy-Model index bfecb8b..636932d 160000 --- a/submodules/Tecnalia_Solar-Energy-Model +++ b/submodules/Tecnalia_Solar-Energy-Model @@ -1 +1 @@ -Subproject commit bfecb8b2e89ff9022f487b0769e66d5b061ffc3d +Subproject commit 636932ddae1fecd3ae3bcfd10998b173f4e75229 diff --git a/test/python_module/src/test_python_sampling/optimization_module.py b/test/python_module/src/test_python_sampling/optimization_module.py index 8b770a1..2647777 100644 --- a/test/python_module/src/test_python_sampling/optimization_module.py +++ b/test/python_module/src/test_python_sampling/optimization_module.py @@ -20,7 +20,7 @@ def solve_optimization_problem(input_data): # Define constraints model.constraint = pyo.Constraint(expr=model.x + 2 * model.y + model.z <= 1) # Solve the optimization problem - solver = pyo.SolverFactory("glpk") + solver = pyo.SolverFactory("highs") solver.solve(model, tee=False) # Extract results x_value = model.x.value diff --git a/test/utils.jl b/test/utils.jl index 7860ee0..c2f1c7c 100644 --- a/test/utils.jl +++ b/test/utils.jl @@ -324,14 +324,25 @@ function simple_graph_biochp(; output = nothing) BioBirchStem => 0.3, BioSpruceTB => 0.4, ) - libpath = joinpath( - pkgdir(EMLI), - "submodules", - "CHP_modelling", - "build", - "lib", - "libbioCHP_wrapper.so", - ) + libpath::String = if Sys.iswindows() + joinpath( + pkgdir(EMLI), + "submodules", + "CHP_modelling", + "build", + "Release", + "bioCHP_wrapper.dll", + ) + else + joinpath( + pkgdir(EMLI), + "submodules", + "CHP_modelling", + "build", + "lib", + "libbioCHP_wrapper.so", + ) + end if isnothing(output) bio_chp = BioCHP( From 4c8313a6109345ed4318efa7e41ecded57483cc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sat, 27 Dec 2025 20:01:20 +0100 Subject: [PATCH 04/17] Add CI windows run --- .github/actions/before-script/action.yml | 59 +++++++++++++++++++++++- .github/workflows/ci.yml | 18 +++++++- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/.github/actions/before-script/action.yml b/.github/actions/before-script/action.yml index 3be9c2b..fe8b385 100644 --- a/.github/actions/before-script/action.yml +++ b/.github/actions/before-script/action.yml @@ -7,7 +7,7 @@ runs: if: runner.os == 'Linux' run: | sudo apt-get update -qq - sudo apt-get install -y git glpk-utils g++ cmake wget curl python3-pip + sudo apt-get install -y git g++ cmake wget curl python3-pip pip install conan conan profile detect wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh @@ -41,3 +41,60 @@ runs: cmake --build . --config Release cd "$GITHUB_WORKSPACE" shell: bash + - name: Install Windows dependencies + Miniconda + python/cpp modules + if: runner.os == 'Windows' + run: | + # Install conan (use py -m pip to be explicit on Windows) + py -m pip install --upgrade pip + py -m pip install conan + + # Download & install Miniconda silently into %USERPROFILE%\miniconda + $installer = Join-Path $env:RUNNER_TEMP "Miniconda3-latest-Windows-x86_64.exe" + Invoke-WebRequest -Uri "https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe" -OutFile $installer + + $target = Join-Path $env:USERPROFILE "miniconda" + Start-Process -FilePath $installer -ArgumentList "/InstallationType=JustMe", "/S", "/D=$target" -Wait + + # Initialize conda in this PowerShell session + $conda = Join-Path $env:USERPROFILE "miniconda\Scripts\conda.exe" + & $conda "shell.powershell" "hook" | Out-String | Invoke-Expression + + conda --version + + # Create env + install poetry + conda create --name testenv python=3.11 -y + conda activate testenv + conda install -c conda-forge poetry -y + + # Some Python deps in your docs mention highspy on Windows for the test module + # Keep it here to match your documented Windows setup. + pip install highspy + + # Poetry installs + Set-Location (Join-Path $env:GITHUB_WORKSPACE "test\python_module") + poetry install + Set-Location $env:GITHUB_WORKSPACE + + Set-Location (Join-Path $env:GITHUB_WORKSPACE "submodules\wind_power_timeseries") + poetry install + Set-Location $env:GITHUB_WORKSPACE + + Set-Location (Join-Path $env:GITHUB_WORKSPACE "submodules\Tecnalia_Solar-Energy-Model") + poetry install + Set-Location (Join-Path $env:GITHUB_WORKSPACE "submodules\Tecnalia_Building-Stock-Energy-Model") + poetry install + Set-Location $env:GITHUB_WORKSPACE + + # Build C++ module (MSVC toolchain is available on windows-latest) + Set-Location (Join-Path $env:GITHUB_WORKSPACE "submodules\CHP_modelling") + New-Item -ItemType Directory -Force -Path "build" | Out-Null + Set-Location "build" + + conan profile detect + + conan install .. --output-folder=. --build=missing -s compiler.cppstd=17 -s arch=x86_64 + cmake .. -DCMAKE_TOOLCHAIN_FILE="$PWD\conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Release + cmake --build . --config Release + + Set-Location $env:GITHUB_WORKSPACE + shell: pwsh \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 97a135d..b4fe5c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,12 @@ jobs: - version: 'lts' # The long term stable version (Linux) os: ubuntu-latest arch: x64 + - version: '1' + os: windows-latest + arch: x64 + - version: 'lts' + os: windows-latest + arch: x64 steps: - uses: actions/checkout@v4 with: @@ -41,7 +47,8 @@ jobs: ${{ runner.os }}-test- ${{ runner.os }}- - uses: julia-actions/julia-buildpkg@v1 - - name: Run Julia tests inside the testenv-enviornment in Miniconda + - name: Run Julia tests inside the testenv-enviornment in Miniconda (Linux) + if: runner.os == 'Linux' run: | source "$HOME/miniconda/etc/profile.d/conda.sh" conda init bash @@ -53,3 +60,12 @@ jobs: Pkg.test(; coverage=true) ' shell: bash + - name: Run Julia tests inside the testenv-environment in Miniconda (Windows) + if: runner.os == 'Windows' + run: | + $conda = Join-Path $env:USERPROFILE "miniconda\Scripts\conda.exe" + & $conda "shell.powershell" "hook" | Out-String | Invoke-Expression + conda activate testenv + + julia --project=. -e "using Pkg; ENV[\"PYTHON\"] = joinpath(ENV[\"USERPROFILE\"], \"miniconda\", \"envs\", \"testenv\", \"python.exe\"); Pkg.build(\"PyCall\"); Pkg.test(; coverage=true)" + shell: pwsh From bf9aa2420c5b7a5e4d303eb9a264dbe7fa6761cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sat, 27 Dec 2025 20:13:09 +0100 Subject: [PATCH 05/17] Fix CI conan error --- .github/actions/before-script/action.yml | 29 ++++++------------------ 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/.github/actions/before-script/action.yml b/.github/actions/before-script/action.yml index fe8b385..893997b 100644 --- a/.github/actions/before-script/action.yml +++ b/.github/actions/before-script/action.yml @@ -44,55 +44,40 @@ runs: - name: Install Windows dependencies + Miniconda + python/cpp modules if: runner.os == 'Windows' run: | - # Install conan (use py -m pip to be explicit on Windows) - py -m pip install --upgrade pip - py -m pip install conan - - # Download & install Miniconda silently into %USERPROFILE%\miniconda + # Download & install Miniconda into %USERPROFILE%\miniconda $installer = Join-Path $env:RUNNER_TEMP "Miniconda3-latest-Windows-x86_64.exe" Invoke-WebRequest -Uri "https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe" -OutFile $installer $target = Join-Path $env:USERPROFILE "miniconda" Start-Process -FilePath $installer -ArgumentList "/InstallationType=JustMe", "/S", "/D=$target" -Wait - # Initialize conda in this PowerShell session - $conda = Join-Path $env:USERPROFILE "miniconda\Scripts\conda.exe" + # Initialize conda for this PowerShell session + $conda = Join-Path $target "Scripts\conda.exe" & $conda "shell.powershell" "hook" | Out-String | Invoke-Expression - conda --version - - # Create env + install poetry conda create --name testenv python=3.11 -y conda activate testenv + python -m pip install --upgrade pip conda install -c conda-forge poetry -y - - # Some Python deps in your docs mention highspy on Windows for the test module - # Keep it here to match your documented Windows setup. - pip install highspy + python -m pip install conan highspy # Poetry installs Set-Location (Join-Path $env:GITHUB_WORKSPACE "test\python_module") poetry install - Set-Location $env:GITHUB_WORKSPACE - Set-Location (Join-Path $env:GITHUB_WORKSPACE "submodules\wind_power_timeseries") poetry install - Set-Location $env:GITHUB_WORKSPACE - Set-Location (Join-Path $env:GITHUB_WORKSPACE "submodules\Tecnalia_Solar-Energy-Model") poetry install Set-Location (Join-Path $env:GITHUB_WORKSPACE "submodules\Tecnalia_Building-Stock-Energy-Model") poetry install - Set-Location $env:GITHUB_WORKSPACE - # Build C++ module (MSVC toolchain is available on windows-latest) Set-Location (Join-Path $env:GITHUB_WORKSPACE "submodules\CHP_modelling") New-Item -ItemType Directory -Force -Path "build" | Out-Null Set-Location "build" - conan profile detect + python -m conan profile detect + python -m conan install .. --output-folder=. --build=missing -s compiler.cppstd=17 -s arch=x86_64 - conan install .. --output-folder=. --build=missing -s compiler.cppstd=17 -s arch=x86_64 cmake .. -DCMAKE_TOOLCHAIN_FILE="$PWD\conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Release cmake --build . --config Release From 7a16129dc458268012595dd1de008cc54d81ee04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sat, 27 Dec 2025 20:35:14 +0100 Subject: [PATCH 06/17] Try to fix CI for windows --- .github/actions/before-script/action.yml | 5 ++-- .github/workflows/ci.yml | 38 ++++++++++++++++-------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/.github/actions/before-script/action.yml b/.github/actions/before-script/action.yml index 893997b..1ac9d0d 100644 --- a/.github/actions/before-script/action.yml +++ b/.github/actions/before-script/action.yml @@ -57,6 +57,7 @@ runs: conda create --name testenv python=3.11 -y conda activate testenv + $env:PATH = "$env:CONDA_PREFIX\Scripts;$env:CONDA_PREFIX;$env:PATH" python -m pip install --upgrade pip conda install -c conda-forge poetry -y python -m pip install conan highspy @@ -75,8 +76,8 @@ runs: New-Item -ItemType Directory -Force -Path "build" | Out-Null Set-Location "build" - python -m conan profile detect - python -m conan install .. --output-folder=. --build=missing -s compiler.cppstd=17 -s arch=x86_64 + conan profile detect + conan install .. --output-folder=. --build=missing -s compiler.cppstd=17 -s arch=x86_64 cmake .. -DCMAKE_TOOLCHAIN_FILE="$PWD\conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Release cmake --build . --config Release diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4fe5c2..6cadde4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,23 +14,29 @@ jobs: fail-fast: false matrix: include: - - version: '1' # The latest point-release (Linux) - os: ubuntu-latest - arch: x64 - - version: 'lts' # The long term stable version (Linux) - os: ubuntu-latest - arch: x64 - - version: '1' - os: windows-latest - arch: x64 + #- version: '1' # The latest point-release (Linux) + # os: ubuntu-latest + # arch: x64 + #- version: 'lts' # The long term stable version (Linux) + # os: ubuntu-latest + # arch: x64 + #- version: '1' + # os: windows-latest + # arch: x64 - version: 'lts' os: windows-latest arch: x64 steps: - uses: actions/checkout@v4 with: - submodules: true # Fetch the submodules - fetch-depth: 0 # full clone + submodules: true + fetch-depth: 0 + + # Recommended: ensure MSVC environment for conan/cmake on Windows + - name: Setup MSVC Dev Cmd + if: runner.os == 'Windows' + uses: ilammy/msvc-dev-cmd@v1 + - uses: ./.github/actions/before-script - uses: julia-actions/setup-julia@v2 with: @@ -67,5 +73,13 @@ jobs: & $conda "shell.powershell" "hook" | Out-String | Invoke-Expression conda activate testenv - julia --project=. -e "using Pkg; ENV[\"PYTHON\"] = joinpath(ENV[\"USERPROFILE\"], \"miniconda\", \"envs\", \"testenv\", \"python.exe\"); Pkg.build(\"PyCall\"); Pkg.test(; coverage=true)" + # Keep env scripts on PATH + $env:PATH = "$env:CONDA_PREFIX\Scripts;$env:CONDA_PREFIX;$env:PATH" + + julia --project=. -e " + using Pkg; + ENV[\"PYTHON\"] = joinpath(ENV[\"USERPROFILE\"], \"miniconda\", \"envs\", \"testenv\", \"python.exe\"); + Pkg.build(\"PyCall\"); + Pkg.test(; coverage=true) + " shell: pwsh From 2a7d0b135c7114bfff67afa51653501d898153e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sat, 27 Dec 2025 20:49:14 +0100 Subject: [PATCH 07/17] Try to fix CI for windows --- .github/workflows/ci.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6cadde4..09649e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,14 +72,7 @@ jobs: $conda = Join-Path $env:USERPROFILE "miniconda\Scripts\conda.exe" & $conda "shell.powershell" "hook" | Out-String | Invoke-Expression conda activate testenv + $env:PATH = "$env:CONDA_PREFIX;$env:CONDA_PREFIX\Scripts;$env:PATH" - # Keep env scripts on PATH - $env:PATH = "$env:CONDA_PREFIX\Scripts;$env:CONDA_PREFIX;$env:PATH" - - julia --project=. -e " - using Pkg; - ENV[\"PYTHON\"] = joinpath(ENV[\"USERPROFILE\"], \"miniconda\", \"envs\", \"testenv\", \"python.exe\"); - Pkg.build(\"PyCall\"); - Pkg.test(; coverage=true) - " + julia --project=. -e 'using Pkg; ENV["PYTHON"] = joinpath(ENV["USERPROFILE"], "miniconda", "envs", "testenv", "python.exe"); Pkg.build("PyCall"); Pkg.test(; coverage=true)' shell: pwsh From 943961876c477fa9eba74803cb97e8727ddb17c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sat, 27 Dec 2025 21:21:16 +0100 Subject: [PATCH 08/17] Try to fix laking highs installation --- .github/actions/before-script/action.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/actions/before-script/action.yml b/.github/actions/before-script/action.yml index 1ac9d0d..a9a163a 100644 --- a/.github/actions/before-script/action.yml +++ b/.github/actions/before-script/action.yml @@ -59,8 +59,11 @@ runs: conda activate testenv $env:PATH = "$env:CONDA_PREFIX\Scripts;$env:CONDA_PREFIX;$env:PATH" python -m pip install --upgrade pip - conda install -c conda-forge poetry -y - python -m pip install conan highspy + conda install -c conda-forge -y poetry highs highspy + + # Check highs installation + where.exe highs + highs --version # Poetry installs Set-Location (Join-Path $env:GITHUB_WORKSPACE "test\python_module") From c5772a5b8ad7e537a46b557e98747f15997523ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sat, 27 Dec 2025 21:30:41 +0100 Subject: [PATCH 09/17] Reintroduce mistakenly conan removal --- .github/actions/before-script/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/before-script/action.yml b/.github/actions/before-script/action.yml index a9a163a..d69c829 100644 --- a/.github/actions/before-script/action.yml +++ b/.github/actions/before-script/action.yml @@ -59,7 +59,7 @@ runs: conda activate testenv $env:PATH = "$env:CONDA_PREFIX\Scripts;$env:CONDA_PREFIX;$env:PATH" python -m pip install --upgrade pip - conda install -c conda-forge -y poetry highs highspy + conda install -c conda-forge -y poetry highs highspy conan # Check highs installation where.exe highs From f6c0bc3ecbe97deed4fac9fe6fdd49bb103fb016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sat, 27 Dec 2025 21:48:16 +0100 Subject: [PATCH 10/17] Try to use appsi_highs --- .github/workflows/ci.yml | 6 +++--- .../src/test_python_sampling/optimization_module.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 09649e9..af03b69 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,9 +17,9 @@ jobs: #- version: '1' # The latest point-release (Linux) # os: ubuntu-latest # arch: x64 - #- version: 'lts' # The long term stable version (Linux) - # os: ubuntu-latest - # arch: x64 + - version: 'lts' # The long term stable version (Linux) + os: ubuntu-latest + arch: x64 #- version: '1' # os: windows-latest # arch: x64 diff --git a/test/python_module/src/test_python_sampling/optimization_module.py b/test/python_module/src/test_python_sampling/optimization_module.py index 2647777..556e4cd 100644 --- a/test/python_module/src/test_python_sampling/optimization_module.py +++ b/test/python_module/src/test_python_sampling/optimization_module.py @@ -20,7 +20,7 @@ def solve_optimization_problem(input_data): # Define constraints model.constraint = pyo.Constraint(expr=model.x + 2 * model.y + model.z <= 1) # Solve the optimization problem - solver = pyo.SolverFactory("highs") + solver = pyo.SolverFactory("appsi_highs") solver.solve(model, tee=False) # Extract results x_value = model.x.value From 1cdda2ef696a47dcd6bdee4d56c4c01740a2ef37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sat, 27 Dec 2025 22:10:19 +0100 Subject: [PATCH 11/17] Resolve highs issue for both Linux and Windows --- .../src/test_python_sampling/optimization_module.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/python_module/src/test_python_sampling/optimization_module.py b/test/python_module/src/test_python_sampling/optimization_module.py index 556e4cd..c7e4ae9 100644 --- a/test/python_module/src/test_python_sampling/optimization_module.py +++ b/test/python_module/src/test_python_sampling/optimization_module.py @@ -1,3 +1,4 @@ +from sys import platform import pyomo.environ as pyo def solve_optimization_problem(input_data): @@ -20,7 +21,11 @@ def solve_optimization_problem(input_data): # Define constraints model.constraint = pyo.Constraint(expr=model.x + 2 * model.y + model.z <= 1) # Solve the optimization problem - solver = pyo.SolverFactory("appsi_highs") + if platform.system() == "Windows": + solver = pyo.SolverFactory("appsi_highs") # uses highspy + else: + solver = pyo.SolverFactory("highs") # uses highs executable + solver.solve(model, tee=False) # Extract results x_value = model.x.value From 4d0109e69650fd7fbc303b988d073dcebad026df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sat, 27 Dec 2025 22:10:36 +0100 Subject: [PATCH 12/17] Run all jobs --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af03b69..30785bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,15 +14,15 @@ jobs: fail-fast: false matrix: include: - #- version: '1' # The latest point-release (Linux) - # os: ubuntu-latest - # arch: x64 + - version: '1' # The latest point-release (Linux) + os: ubuntu-latest + arch: x64 - version: 'lts' # The long term stable version (Linux) os: ubuntu-latest arch: x64 - #- version: '1' - # os: windows-latest - # arch: x64 + - version: '1' + os: windows-latest + arch: x64 - version: 'lts' os: windows-latest arch: x64 From 83e119737d625d1f7cd40521efd3eb8452e321b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sat, 27 Dec 2025 22:11:02 +0100 Subject: [PATCH 13/17] Fix miscellaneous issues --- NEWS.md | 5 +++ docs/Project.toml | 2 + docs/make.jl | 2 + docs/src/how-to/utilize.md | 50 ++++++++++----------- docs/src/library/public.md | 58 ++++++++++++++++++++++++- docs/src/nodes/biochp.md | 2 +- docs/src/nodes/multiplebuildingtypes.md | 4 ++ docs/src/nodes/pvandcsp.md | 2 +- docs/src/nodes/windpower.md | 2 +- src/datastructures.jl | 7 ++- 10 files changed, 103 insertions(+), 31 deletions(-) diff --git a/NEWS.md b/NEWS.md index 58aa221..9a24435 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,11 @@ ## Version 0.1.0 (2025-04-xx) +### Improve documentation (2026-01-06) + +* Added documentation for the node and a `how-to` section for the sampling constructors of these nodes. +* Added CI test runs for windows + ### Adjust for updates in submodules and update descriptive names for the EMGUI extension (2025-10-17) * Adjust for updates in submodules diff --git a/docs/Project.toml b/docs/Project.toml index bc5e1c2..00c5d09 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,7 +1,9 @@ [deps] +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656" EnergyModelsBase = "5d7e687e-f956-46f3-9045-6f5a5fd49f50" +EnergyModelsHeat = "ad1b8b27-e232-4da9-b498-bea9c19a30d7" EnergyModelsLanguageInterfaces = "672bb132-9406-42d0-9ef4-9203b0a61e9a" EnergyModelsRenewableProducers = "b007c34f-ba52-4995-ba37-fffe79fbde35" HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b" diff --git a/docs/make.jl b/docs/make.jl index 53a5183..ce09908 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -2,8 +2,10 @@ using Documenter using DocumenterInterLinks using EnergyModelsBase using EnergyModelsRenewableProducers +using EnergyModelsHeat using EnergyModelsLanguageInterfaces using TimeStruct +using Dates using Literate const EMB = EnergyModelsBase diff --git a/docs/src/how-to/utilize.md b/docs/src/how-to/utilize.md index 4554139..7cabe85 100644 --- a/docs/src/how-to/utilize.md +++ b/docs/src/how-to/utilize.md @@ -117,11 +117,11 @@ An example is given by the *[trippling_module example](https://github.com/Energy ## [Use implemented nodes](@id how_to-utilize-use_nodes) -The nodes [`WindPower`](@ref WindPower), [`CSPandPV`](@ref CSPandPV) and [`MultipleBuildingTypes`](@ref MultipleBuildingTypes) have constructors that samples [wind_power_timeseries](https://gitlab.sintef.no/harald.svendsen/wind_power_timeseries), [Tecnalia_Solar-Energy-Model](https://github.com/iDesignRES/Tecnalia_Solar-Energy-Model) and [Tecnalia_Building-Stock-Energy-Model](https://github.com/iDesignRES/Tecnalia_Building-Stock-Energy-Model), respectively. These modules are python based and the usage of these constructors requires installation of these as documented [below](@ref how_to-utilize-use_nodes-python_modules). +The nodes [`WindPower`](@ref WindPower), [`CSPandPV`](@ref CSPandPV) and [`MultipleBuildingTypes`](@ref MultipleBuildingTypes) have [constructors](@ref lib-pub-sampling_constructors) that samples [`wind_power_timeseries`](https://gitlab.sintef.no/harald.svendsen/wind_power_timeseries), [`Tecnalia_Solar-Energy-Model`](https://github.com/iDesignRES/Tecnalia_Solar-Energy-Model) and [`Tecnalia_Building-Stock-Energy-Model`](https://github.com/iDesignRES/Tecnalia_Building-Stock-Energy-Model), respectively. These modules are python based and the usage of these [constructors](@ref lib-pub-sampling_constructors) requires installation of these as documented [below](@ref how_to-utilize-use_nodes-python_modules). -Additionally, the node [`BioCHP`](@ref BioCHP) have a constructor that samples the [CHP_modelling](https://github.com/iDesignRES/CHP_modelling) module. This module is `C++` based and the constructor then requires compilation and build before usage as described further [below](@ref how_to-utilize-use_nodes-cpp_modules). +Additionally, the node [`BioCHP`](@ref BioCHP) have a [constructor](@ref lib-pub-sampling_constructors) that samples the [CHP_modelling](https://github.com/iDesignRES/CHP_modelling) module. This module is `C++` based and the [constructor](@ref lib-pub-sampling_constructors) then requires compilation and build before usage as described further [below](@ref how_to-utilize-use_nodes-cpp_modules). -The following installation guides will show how to install the modules to enable usage of these constructors for Windows. +The following installation guides will show how to install the modules to enable usage of these [constructors](@ref lib-pub-sampling_constructors) for both Windows and Linux. ### [Clone repositories](@id how_to-utilize-use_nodes-clone_repos) @@ -187,26 +187,6 @@ cd ../.. !!! note "Environments" If you are a developer, you probably want to install the python modules in a separate environment which can be done with, e.g., [miniconda](https://www.anaconda.com/docs/getting-started/miniconda/install). -### [Install C++ modules](@id how_to-utilize-use_nodes-cpp_modules) - -Start by installing [`conan`](https://pypi.org/project/conan/) - -```PowerShell -pip install conan -``` - -Navigate to the `CHP_modelling` folder, build and install the module with the following - -```PowerShell -cd submodules/CHP_modelling -mkdir build -cd build -conan install .. --output-folder=. --build=missing -s compiler.cppstd=17 -s arch=x86_64 -cmake .. -DCMAKE_TOOLCHAIN_FILE="${PWD}/conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Release -cmake --build . --config Release -cd ../../.. -``` - Enable these by starting a julia session in the main folder ```PowerShell @@ -231,6 +211,26 @@ followed by restarting Julia. (Get-Command python).Source ``` +### [Install C++ modules](@id how_to-utilize-use_nodes-cpp_modules) + +Start by installing [`conan`](https://pypi.org/project/conan/) + +```PowerShell +pip install conan +``` + +Navigate to the `CHP_modelling` folder, build and install the module with the following + +```PowerShell +cd submodules/CHP_modelling +mkdir build +cd build +conan install .. --output-folder=. --build=missing -s compiler.cppstd=17 -s arch=x86_64 +cmake .. -DCMAKE_TOOLCHAIN_FILE="${PWD}/conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Release +cmake --build . --config Release +cd ../../.. +``` + ### [Install modules on linux](@id how_to-utilize-use_nodes-linux) To perform the same installation above on linux you can navigate to a folder in which you want to download required repositories and run @@ -293,7 +293,7 @@ followed by restarting Julia. ### [Test modules](@id how_to-utilize-use_nodes-test) -All the mentioned constructors have been included in the tests of the repository and you may therefore check if everyting is properly setup by running these in julia. +All the mentioned [constructors](@ref lib-pub-sampling_constructors) have been included in the tests of the repository and you may therefore check if everyting is properly setup by running these in julia. !!! note "Requirements" The tests assumes that all modules listed in the [Install python modules](@ref how_to-utilize-use_nodes-python_modules) section and the [Install C++ modules](@ref how_to-utilize-use_nodes-cpp_modules) section has been installed. @@ -313,4 +313,4 @@ Pkg.test() ### [Utilize constructors](@id how_to-utilize-constructors) -For detailed information on how to use the constructors, refer to the [test/utils.jl](https://github.com/EnergyModelsX/EnergyModelsLanguageInterfaces.jl/blob/main/test/utils.jl) file, which contains minimum working examples for both sampling the models and using saved sampled data. \ No newline at end of file +For detailed information on how to use the [constructors](@ref lib-pub-sampling_constructors), refer to the [test/utils.jl](https://github.com/EnergyModelsX/EnergyModelsLanguageInterfaces.jl/blob/main/test/utils.jl) file, which contains minimum working examples for both sampling the models and using saved sampled data. \ No newline at end of file diff --git a/docs/src/library/public.md b/docs/src/library/public.md index 7424c8a..c1b6b5d 100644 --- a/docs/src/library/public.md +++ b/docs/src/library/public.md @@ -1,15 +1,69 @@ # [Public interface](@id lib-pub) -## [New nodal types](@id lib-pub-types) +## [New resource types](@id lib-pub-resource_types) + +```@docs +EnergyModelsLanguageInterfaces.ResourceBio +``` + +## [New nodal types](@id lib-pub-nodal_types) ```@docs EnergyModelsLanguageInterfaces.WindPower EnergyModelsLanguageInterfaces.CSPandPV EnergyModelsLanguageInterfaces.MultipleBuildingTypes -EnergyModelsLanguageInterfaces.ResourceBio EnergyModelsLanguageInterfaces.BioCHP ``` +## [Sampling constructors](@id lib-pub-sampling_constructors) + +```@docs +EnergyModelsLanguageInterfaces.WindPower( + ::Any, + ::TimeStruct.TimeProfile, + ::Dict, + ::String, + ::String, + ::TimeStruct.TimeProfile, + ::TimeStruct.TimeProfile, + ::Dict{<:EnergyModelsBase.Resource,<:Real}, +) +EnergyModelsLanguageInterfaces.CSPandPV( + ::Any, + ::Dict, + ::DateTime, + ::DateTime, + ::Dict{String,<:EnergyModelsBase.Resource}; + data::Vector{<:Data} = Data[], + method::String = "Ninja", + data_path::String = "", + source::String = "NORA3", +) +EnergyModelsLanguageInterfaces.MultipleBuildingTypes( + ::Any, + ::Dict, + ::DateTime, + ::DateTime, + ::Vector{String}, + ::Dict{String,<:EnergyModelsBase.Resource}, + ::TimeStruct.TimeStructure, + ::Dict{<:EnergyModelsBase.Resource,<:TimeStruct.TimeProfile}, + ::Dict{<:EnergyModelsBase.Resource,<:TimeStruct.TimeProfile}; + data::Vector{<:EnergyModelsBase.Data} = EnergyModelsBase.Data[], + data_location::String = joinpath(tempdir(), "buildings"), + overwrite_saved_data::Bool = false, +) +EnergyModelsLanguageInterfaces.BioCHP( + ::Any, + ::TimeStruct.TimeProfile, + ::Dict{<:EnergyModelsLanguageInterfaces.ResourceBio,<:Real}, + ::Dict{<:EnergyModelsHeat.ResourceHeat,<:Real}, + ::EnergyModelsBase.Resource; + data::Vector{<:EnergyModelsBase.Data} = EnergyModelsBase.Data[], + libpath::String = joinpath(@__DIR__, "..", "..", "CHP_modelling", "build", "lib", "libbioCHP_wrapper.so"), +) +``` + ## [Utility functions](@id lib-pub-util_fun) ```@docs diff --git a/docs/src/nodes/biochp.md b/docs/src/nodes/biochp.md index 6816d20..1d78b98 100644 --- a/docs/src/nodes/biochp.md +++ b/docs/src/nodes/biochp.md @@ -3,7 +3,7 @@ The [`BioCHP`](@ref) node represents a biomass-fired combined heat and power (CHP) plant. !!! note "Sampling CHP_modelling module" - To use the constructor that samples the [CHP_modelling](https://github.com/iDesignRES/CHP_modelling) module, follow the installation in the [Use nodes](@ref how_to-utilize-use_nodes) section. + To use the [constructor](@ref lib-pub-sampling_constructors) that samples the [CHP_modelling](https://github.com/iDesignRES/CHP_modelling) module, follow the installation in the [Use nodes](@ref how_to-utilize-use_nodes) section. The `BioCHP` utilizes linear, time-independent conversion rates from the `input` [`Resource`](@extref EnergyModelsBase.Resource)s to the `output` [`Resource`](@extref EnergyModelsBase.Resource)s, subject to the available capacity. The capacity is normalized such that a conversion value of 1 corresponds to the nominal capacity in the fields `input` and `output`. diff --git a/docs/src/nodes/multiplebuildingtypes.md b/docs/src/nodes/multiplebuildingtypes.md index c8cf912..e7af9b2 100644 --- a/docs/src/nodes/multiplebuildingtypes.md +++ b/docs/src/nodes/multiplebuildingtypes.md @@ -3,6 +3,10 @@ The [`MultipleBuildingTypes`](@ref) node creates sinks for all demand resources with penalties for both surplus and deficit. The implementation uses `Dict` structures for the fields `cap`, `penalty_surplus`, and `penalty_deficit` to facilitate multiple [Resource](@extref EnergyModelsBase.Resource)s. This approach allows modeling building demands with flexible penalty mechanisms for over- and under-supply. +The type is also used to enable specialized constructors that samples the [`Tecnalia_Building-Stock-Energy-Model`](https://github.com/iDesignRES/Tecnalia_Building-Stock-Energy-Model) module. + +!!! note "Sampling Tecnalia_Building-Stock-Energy-Model module" + To use the [constructor](@ref lib-pub-sampling_constructors) for [`MultipleBuildingTypes`](@ref) that samples the [`Tecnalia_Building-Stock-Energy-Model`](https://github.com/iDesignRES/Tecnalia_Building-Stock-Energy-Model) module, follow the installation in the [Use nodes](@ref how_to-utilize-use_nodes) section. !!! danger Investments are currently not available for this node. diff --git a/docs/src/nodes/pvandcsp.md b/docs/src/nodes/pvandcsp.md index 5f4c3ba..2b976d7 100644 --- a/docs/src/nodes/pvandcsp.md +++ b/docs/src/nodes/pvandcsp.md @@ -5,7 +5,7 @@ The implementation of the node is similar to that of [NonDisRES](@extref EnergyM The type is also used to enable specialized constructors that samples the [Tecnalia_Solar-Energy-Model](https://github.com/iDesignRES/Tecnalia_Solar-Energy-Model) module. !!! note "Sampling Tecnalia_Solar-Energy-Model module" - To use the constructor that samples the [Tecnalia_Solar-Energy-Model](https://github.com/iDesignRES/Tecnalia_Solar-Energy-Model) module, follow the installation in the [Use nodes](@ref how_to-utilize-use_nodes) section. + To use the [constructor](@ref lib-pub-sampling_constructors) for [`CSPandPV`](@ref) that samples the [Tecnalia_Solar-Energy-Model](https://github.com/iDesignRES/Tecnalia_Solar-Energy-Model) module, follow the installation in the [Use nodes](@ref how_to-utilize-use_nodes) section. !!! danger Investments are currently not available for this node. diff --git a/docs/src/nodes/windpower.md b/docs/src/nodes/windpower.md index 45be75c..81493dc 100644 --- a/docs/src/nodes/windpower.md +++ b/docs/src/nodes/windpower.md @@ -4,7 +4,7 @@ Wind power source generate electricity from wind sources. The implementation of the node is identical to that of [NonDisRES](@extref EnergyModelsRenewableProducers nodes-nondisres) and is here used to enable specialized constructors that samples the [`wind_power_timeseries`](https://gitlab.sintef.no/harald.svendsen/wind_power_timeseries) module. !!! note "Sampling wind\_power\_timeseries module" - To use the constructor that samples the [`wind_power_timeseries`](https://gitlab.sintef.no/harald.svendsen/wind_power_timeseries) module, follow the installation in the [Use nodes](@ref how_to-utilize-use_nodes) section. + To use the [constructor](@ref lib-pub-sampling_constructors) for [`WindPower`](@ref) that samples the [`wind_power_timeseries`](https://gitlab.sintef.no/harald.svendsen/wind_power_timeseries) module, follow the installation in the [Use nodes](@ref how_to-utilize-use_nodes) section. ## [Introduced type and its field](@id nodes-WindPower-fields) diff --git a/src/datastructures.jl b/src/datastructures.jl index de654e3..4ccadd2 100644 --- a/src/datastructures.jl +++ b/src/datastructures.jl @@ -47,7 +47,8 @@ end output::Dict{<:Resource,<:Real}; data::Vector{<:Data} = Data[], method::String = "Ninja", - data_path::String = "" + data_path::String = "", + source::String = "NORA3", ) Constructs a [`WindPower`](@ref) instance where the power production profile is sampled from @@ -86,6 +87,10 @@ a Python function. an empty datapath. - **`source`** is the data source for wind data. The user can choose between the strings "NORA3" and "ERA5". The default value is "NORA3". + +!!! note "Usage of the ERA5 data source in wind_power_timeseries" + For use of the "ERA5" data source, the user needs to register and obtain a CDS API key. + - Perform step 1: https://cds.climate.copernicus.eu/how-to-api """ function WindPower( id::Any, From 4e3f0ccaa018ebde8ba3c0004286a97f554d2173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sun, 28 Dec 2025 07:30:18 +0100 Subject: [PATCH 14/17] Fix bug --- .../src/test_python_sampling/optimization_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/python_module/src/test_python_sampling/optimization_module.py b/test/python_module/src/test_python_sampling/optimization_module.py index c7e4ae9..30ffbc0 100644 --- a/test/python_module/src/test_python_sampling/optimization_module.py +++ b/test/python_module/src/test_python_sampling/optimization_module.py @@ -1,4 +1,4 @@ -from sys import platform +import platform import pyomo.environ as pyo def solve_optimization_problem(input_data): From 908120a836a54e2583bbe77995baed9bc485f477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sun, 28 Dec 2025 07:57:06 +0100 Subject: [PATCH 15/17] Fix missing highs on linux --- .github/actions/before-script/action.yml | 4 +--- .github/workflows/ci.yml | 18 +++++++++--------- .../optimization_module.py | 6 +----- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/.github/actions/before-script/action.yml b/.github/actions/before-script/action.yml index d69c829..bd837e7 100644 --- a/.github/actions/before-script/action.yml +++ b/.github/actions/before-script/action.yml @@ -8,8 +8,6 @@ runs: run: | sudo apt-get update -qq sudo apt-get install -y git g++ cmake wget curl python3-pip - pip install conan - conan profile detect wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda echo "$HOME/miniconda/bin" >> $GITHUB_PATH @@ -17,7 +15,7 @@ runs: conda create --name testenv python=3.11 -y conda activate testenv - conda install -c conda-forge poetry -y + conda install -c conda-forge -y poetry highs highspy conan cd "$GITHUB_WORKSPACE/test/python_module" poetry install diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30785bc..d1a9603 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,18 +14,18 @@ jobs: fail-fast: false matrix: include: - - version: '1' # The latest point-release (Linux) - os: ubuntu-latest - arch: x64 + #- version: '1' # The latest point-release (Linux) + # os: ubuntu-latest + # arch: x64 - version: 'lts' # The long term stable version (Linux) os: ubuntu-latest arch: x64 - - version: '1' - os: windows-latest - arch: x64 - - version: 'lts' - os: windows-latest - arch: x64 + #- version: '1' + # os: windows-latest + # arch: x64 + #- version: 'lts' + # os: windows-latest + # arch: x64 steps: - uses: actions/checkout@v4 with: diff --git a/test/python_module/src/test_python_sampling/optimization_module.py b/test/python_module/src/test_python_sampling/optimization_module.py index 30ffbc0..7ce0d56 100644 --- a/test/python_module/src/test_python_sampling/optimization_module.py +++ b/test/python_module/src/test_python_sampling/optimization_module.py @@ -21,11 +21,7 @@ def solve_optimization_problem(input_data): # Define constraints model.constraint = pyo.Constraint(expr=model.x + 2 * model.y + model.z <= 1) # Solve the optimization problem - if platform.system() == "Windows": - solver = pyo.SolverFactory("appsi_highs") # uses highspy - else: - solver = pyo.SolverFactory("highs") # uses highs executable - + solver = pyo.SolverFactory("appsi_highs") solver.solve(model, tee=False) # Extract results x_value = model.x.value From a433a6e69b5ccd020060dec1b25e2e8a6e566c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sun, 28 Dec 2025 08:01:50 +0100 Subject: [PATCH 16/17] Add conan profile detect --- .github/actions/before-script/action.yml | 3 ++- docs/src/how-to/utilize.md | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/actions/before-script/action.yml b/.github/actions/before-script/action.yml index bd837e7..ea412e0 100644 --- a/.github/actions/before-script/action.yml +++ b/.github/actions/before-script/action.yml @@ -16,6 +16,7 @@ runs: conda create --name testenv python=3.11 -y conda activate testenv conda install -c conda-forge -y poetry highs highspy conan + conan profile detect cd "$GITHUB_WORKSPACE/test/python_module" poetry install @@ -58,6 +59,7 @@ runs: $env:PATH = "$env:CONDA_PREFIX\Scripts;$env:CONDA_PREFIX;$env:PATH" python -m pip install --upgrade pip conda install -c conda-forge -y poetry highs highspy conan + conan profile detect # Check highs installation where.exe highs @@ -77,7 +79,6 @@ runs: New-Item -ItemType Directory -Force -Path "build" | Out-Null Set-Location "build" - conan profile detect conan install .. --output-folder=. --build=missing -s compiler.cppstd=17 -s arch=x86_64 cmake .. -DCMAKE_TOOLCHAIN_FILE="$PWD\conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Release diff --git a/docs/src/how-to/utilize.md b/docs/src/how-to/utilize.md index 7cabe85..91754a2 100644 --- a/docs/src/how-to/utilize.md +++ b/docs/src/how-to/utilize.md @@ -217,6 +217,7 @@ Start by installing [`conan`](https://pypi.org/project/conan/) ```PowerShell pip install conan +conan profile detect ``` Navigate to the `CHP_modelling` folder, build and install the module with the following From a146db22721b1105db70a18451b5ef5d2544f8f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vegard=20Ven=C3=A5s?= Date: Sun, 28 Dec 2025 08:29:03 +0100 Subject: [PATCH 17/17] Run full CI --- .github/workflows/ci.yml | 18 +++++++++--------- docs/src/how-to/utilize.md | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d1a9603..30785bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,18 +14,18 @@ jobs: fail-fast: false matrix: include: - #- version: '1' # The latest point-release (Linux) - # os: ubuntu-latest - # arch: x64 + - version: '1' # The latest point-release (Linux) + os: ubuntu-latest + arch: x64 - version: 'lts' # The long term stable version (Linux) os: ubuntu-latest arch: x64 - #- version: '1' - # os: windows-latest - # arch: x64 - #- version: 'lts' - # os: windows-latest - # arch: x64 + - version: '1' + os: windows-latest + arch: x64 + - version: 'lts' + os: windows-latest + arch: x64 steps: - uses: actions/checkout@v4 with: diff --git a/docs/src/how-to/utilize.md b/docs/src/how-to/utilize.md index 91754a2..157f4b7 100644 --- a/docs/src/how-to/utilize.md +++ b/docs/src/how-to/utilize.md @@ -213,7 +213,7 @@ followed by restarting Julia. ### [Install C++ modules](@id how_to-utilize-use_nodes-cpp_modules) -Start by installing [`conan`](https://pypi.org/project/conan/) +Start by installing [`conan`](https://pypi.org/project/conan/) and create a default profile ```PowerShell pip install conan