diff --git a/src/muse/constraints.py b/src/muse/constraints.py index 01bc717d3..6ac3c7255 100644 --- a/src/muse/constraints.py +++ b/src/muse/constraints.py @@ -1,6 +1,6 @@ r"""Investment constraints. -Constraints on investments ensure that investments match some given criteria. For +Constraints on investements ensure that investements match some given criteria. For instance, the constraints could ensure that only so much of a new asset can be built every year. @@ -8,7 +8,7 @@ :py:meth:`~muse.constraints.register_constraints`. This registration step makes it possible for constraints to be declared in the TOML file. -Generally, LP solvers accept linear constraints defined as: +Generally, LP solvers accept linear constraint defined as: .. math:: @@ -16,8 +16,8 @@ with :math:`A` a matrix, :math:`x` the decision variables, and :math:`b` a vector. However, these quantities are dimensionless. They do no have timeslices, assets, or -replacement technologies, or any other dimensions that users have set up in their model. -The crux is to translate from MUSE's data-structures to a consistent dimensionless +replacement technologies, or any other dimensions that users have set-up in their model. +The crux is to translates from MUSE's data-structures to a consistent dimensionless format. In MUSE, users can register constraints functions that return fully dimensional @@ -44,8 +44,8 @@ - Any dimension in :math:`A_c .* x_c` (:math:`A_p .* x_p`) that is also in :math:`b` defines diagonal entries into the left (right) submatrix of :math:`A`. - Any dimension in :math:`A_c .* x_c` (:math:`A_p .* x_b`) and missing from - :math:`b` is reduced by summation over a row in the left (right) submatrix of - :math:`A`. In other words, those dimensions become part of a standard tensor + :math:`b` is reduce by summation over a row in the left (right) submatrix of + :math:`A`. In other words, those dimension do become part of a standard tensor reduction or matrix multiplication. There are two additional rules. However, they are likely to be the result of an @@ -288,7 +288,7 @@ def max_capacity_expansion( :math:`y=y_1` is the year marking the end of the investment period. Let :math:`\mathcal{A}^{i, r}_{t, \iota}(y)` be the current assets, before - investment, and let :math:`\Delta\mathcal{A}^{i,r}_t` be the future investments. + invesment, and let :math:`\Delta\mathcal{A}^{i,r}_t` be the future investements. The the constraint on agent :math:`i` are given as: .. math:: diff --git a/src/muse/readers/csv.py b/src/muse/readers/csv.py index 2f8608c4c..a7bc5ba71 100644 --- a/src/muse/readers/csv.py +++ b/src/muse/readers/csv.py @@ -114,9 +114,6 @@ def to_agent_share(name): if "year" in result.dims and len(result.year) == 1: result = result.isel(year=0, drop=True) - - check_minimum_service_factors_in_range(data, filename) - return result @@ -132,7 +129,7 @@ def read_technodata_timeslices(filename: Union[Text, Path]) -> xr.Dataset: data = csv[csv.technology != "Unit"] data = data.apply(lambda x: pd.to_numeric(x, errors="ignore")) - check_utilization_not_all_zero(data, filename) + data = check_utilization_not_all_zero(data, filename) ts = pd.MultiIndex.from_frame( data.drop( @@ -924,12 +921,4 @@ def check_utilization_not_all_zero(data, filename): """A technology can not have a utilization factor of 0 for every timeslice. Please check file {}.""".format(filename) ) - - -def check_minimum_service_factors_in_range(data, filename): - min_service_factor = data["minimum_service_factor"] - if not np.all((0 <= min_service_factor) & (min_service_factor <= 1)): - raise ValueError( - f"""Minimum service factor values must all be between 0 and 1 inclusive. - Please check file {filename}.""" - ) + return data diff --git a/tests/test_minimum_service.py b/tests/test_minimum_service.py index 2064cf869..ded2b50d1 100644 --- a/tests/test_minimum_service.py +++ b/tests/test_minimum_service.py @@ -1,11 +1,8 @@ -from itertools import permutations - -import numpy as np from pytest import mark def modify_minimum_service_factors( - model_path, sector, processes, minimum_service_factors + model_path, sector, process_name, minimum_service_factor ): import pandas as pd @@ -13,25 +10,27 @@ def modify_minimum_service_factors( model_path / "technodata" / sector / "TechnodataTimeslices.csv" ) - for process, minimum in zip(processes, minimum_service_factors): - technodata_timeslices.loc[ - technodata_timeslices["ProcessName"] == process, "MinimumServiceFactor" - ] = minimum + technodata_timeslices.loc[ + technodata_timeslices["ProcessName"] == process_name[0], "MinimumServiceFactor" + ] = minimum_service_factor[0] + + technodata_timeslices.loc[ + technodata_timeslices["ProcessName"] == process_name[1], "MinimumServiceFactor" + ] = minimum_service_factor[1] return technodata_timeslices +@mark.parametrize("process_name", [("gasCCGT", "windturbine")]) @mark.parametrize( - "minimum_service_factors", - permutations((np.linspace(0, 1, 6), [0] * 6)), + "minimum_service_factor", [([1, 2, 3, 4, 5, 6], [0] * 6), ([0], [1, 2, 3, 4, 5, 6])] ) -def test_minimum_service_factor(tmpdir, minimum_service_factors): +def test_minimum_service_factor(tmpdir, minimum_service_factor, process_name): import pandas as pd from muse import examples from muse.mca import MCA sector = "power" - processes = ("gasCCGT", "windturbine") # Copy the model inputs to tmpdir model_path = examples.copy_model( @@ -41,8 +40,8 @@ def test_minimum_service_factor(tmpdir, minimum_service_factors): technodata_timeslices = modify_minimum_service_factors( model_path=model_path, sector=sector, - processes=processes, - minimum_service_factors=minimum_service_factors, + process_name=process_name, + minimum_service_factor=minimum_service_factor, ) technodata_timeslices.to_csv( @@ -54,7 +53,7 @@ def test_minimum_service_factor(tmpdir, minimum_service_factors): supply_timeslice = pd.read_csv(tmpdir / "Results/MCAMetric_Supply.csv") - for process, service_factor in zip(processes, minimum_service_factors): + for process, service_factor in zip(process_name, minimum_service_factor): for i, factor in enumerate(service_factor): assert ( supply_timeslice[