diff --git a/.github/workflows/semantic-release.yml b/.github/workflows/semantic-release.yml index 5ee89cc..e626edb 100644 --- a/.github/workflows/semantic-release.yml +++ b/.github/workflows/semantic-release.yml @@ -17,7 +17,6 @@ jobs: permissions: id-token: write contents: write - pull-requests: write steps: - name: Harden Runner @@ -40,27 +39,8 @@ jobs: run: | echo "short_sha=$(git rev-parse --short HEAD)\n" >> $GITHUB_OUTPUT - - name: Action | Check if release is needed - id: check - # Adjust tag with desired version if applicable. - uses: python-semantic-release/python-semantic-release@c1bcfdbb994243ac7cf419365d5894d6bfb2950e # v9.12.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - git_committer_name: "github-actions" - git_committer_email: "actions@users.noreply.github.com" - root_options: -vv --noop - build: false - changelog: true - commit: false - push: false - tag: false - vcs_release: false - # prerelease: true - # build_metadata: ${{ github.ref_name }}@${{ steps.vars.outputs.short_sha }} - - name: Action | Semantic Release - Update version id: release - if: steps.check.outputs.released == 'true' # Adjust tag with desired version if applicable. uses: python-semantic-release/python-semantic-release@c1bcfdbb994243ac7cf419365d5894d6bfb2950e # v9.12.0 with: @@ -73,20 +53,3 @@ jobs: push: true tag: true vcs_release: false - prerelease: true - prerelease_token: rc - build_metadata: ${{ steps.vars.outputs.short_sha }} - - - name: Action | Create Pull Request - Release - if: steps.check.outputs.released == 'true' - run: | - gh pr create -B main -H staging --title "release: Merge into main and create tag as v${{ steps.release.outputs.version }}" --body 'Created by Github action: semantic-release.yml' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Action | Create Pull Request - Chore - if: steps.check.outputs.released == 'false' - run: | - gh pr create -B main -H staging --title 'chore: Merge non-code changes into main' --body 'Created by Github action: semantic-release.yml' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/pyproject.toml b/pyproject.toml index cfe4c21..658f7b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -77,7 +77,7 @@ sansmic = "src/python/sansmic" [tool.semantic_release] assets = [] build_command_env = [] -commit_message = "release: {version}\n\nAutomatically generated by python-semantic-release" +commit_message = "chore: update version text to {version}\n\nAutomatically generated by python-semantic-release" commit_parser = "angular" logging_use_named_masks = false major_on_zero = true diff --git a/src/ext_modules/libsansmic/libsansmic.cpp b/src/ext_modules/libsansmic/libsansmic.cpp index f3d174a..75cd7f6 100644 --- a/src/ext_modules/libsansmic/libsansmic.cpp +++ b/src/ext_modules/libsansmic/libsansmic.cpp @@ -22,14 +22,12 @@ PYBIND11_MODULE(libsansmic, m) { py::enum_(m, "CRunMode", "See :py:class:`sansmic.model.SimulationMode`.") - .value("ORDINARY", sansmic::LeachMode::Ordinary, + .value("ORDINARY", sansmic::LeachMode::ORDINARY, "ordinary leaching (water in, brine out)") - .value("WITHDRAWAL", sansmic::LeachMode::Withdrawal, + .value("WITHDRAWAL", sansmic::LeachMode::WITHDRAWAL, "oil withdrawal (water in, oil out)") - .value("LEACH_FILL", sansmic::LeachMode::LeachFill, + .value("LEACH_FILL", sansmic::LeachMode::LEACH_FILL, "leach and fill (water and oil in, brine out)") - .value("OIL_FILL", sansmic::LeachMode::OilFill, - "oil fill (oil in, brine out)") .export_values(); py::enum_( diff --git a/src/ext_modules/libsansmic/libsansmic.hpp b/src/ext_modules/libsansmic/libsansmic.hpp index 5bd87f0..8b66541 100644 --- a/src/ext_modules/libsansmic/libsansmic.hpp +++ b/src/ext_modules/libsansmic/libsansmic.hpp @@ -67,10 +67,9 @@ const int UNIMPLEMENTED_GEOMETRY_IDATA = /// @brief The leaching operations mode for sansmic. enum LeachMode : int { - Ordinary = 0, //!< fill with raw water, produce brine - Withdrawal = 1, //!< fill with raw water, produce oil - LeachFill = 2, //!< fill with oil and raw water, produce brine - OilFill = -1 //!< fill with oil, produce brine + ORDINARY = 0, //!< fill with raw water, produce brine + WITHDRAWAL = 1, //!< fill with raw water, produce oil + LEACH_FILL = 2, //!< fill with oil and raw water, produce brine }; /// @brief The format of the data; will go away once python code fully handles diff --git a/src/ext_modules/libsansmic/model.cpp b/src/ext_modules/libsansmic/model.cpp index 9a906ff..345b74c 100644 --- a/src/ext_modules/libsansmic/model.cpp +++ b/src/ext_modules/libsansmic/model.cpp @@ -334,21 +334,16 @@ int sansmic::Model::init_stage(void) { z_obi_stop = -double(stopCriteria); } - // if the current depths are below zero (?) set to the - // height of the insolubles plus the absolute height given - // I.e., consider that these are relative heights above the - // level of the insoluble materials not absolute heights. + // Version 1.1.0: removed relative heights above new floor height as negatives + // Version 1.1.0: Negative values will be considered depths below surface if (h_inj < 0) { - h_inj = h_insol - h_inj; + h_inj = z_TD0 + h_inj; } if (h_prd < 0) { - h_prd = h_insol - h_prd; + h_prd = z_TD0 + h_prd; } if (h_obi < 0) { - h_obi = h_insol - h_obi; - } - if (h_uso < 0) { - h_uso = h_insol - h_uso; + h_obi = z_TD0 + h_obi; } // use previous OBI if OBI is ~0 @@ -401,7 +396,7 @@ int sansmic::Model::init_stage(void) { C_cav[n_nodes] = C_hat; C_cavAve = C_cav0; - if (runMode == Withdrawal) { + if (runMode == WITHDRAWAL) { dt_min = (_pi_ * sq(r_cavMin) * dz) / (Q_in + 1.0e-10); if (dt_min < 0.01) { dt_min = 0.01; @@ -415,7 +410,7 @@ int sansmic::Model::init_stage(void) { f_disSav[i] = f_dis[i]; } // FIXME: do we really want this next line? - if (runMode == Withdrawal && C_cav0 > 1.0) { + if (runMode == WITHDRAWAL && C_cav0 > 1.0) { std::fill(C_cav.begin(), C_cav.end(), C_cav0); C_cav[n_nodes] = C_hat; C_cavAve = C_cav0; @@ -449,7 +444,7 @@ int sansmic::Model::init_stage(void) { // End of initialization of cavern settings // set the prod and min timestep if withdrawal leach - if (runMode == Withdrawal) { + if (runMode == WITHDRAWAL) { prodCell = obiCell; dt_min = (_pi_ * sq(r_cavMin) * dz) / (Q_in + 1.0e-10); // next two lines are commented out? @@ -575,6 +570,8 @@ int sansmic::Model::leach() { throw sansmic::UNIMPLEMENTED_FLOW_TABLES; } + double t_add = 0; + // Convert back to BPD? Ugh. Q_inBPD = Q_in * cf_to_bbl * per_h_to_per_d; Q_fillBPD = Q_fill * cf_to_bbl * per_h_to_per_d; @@ -707,7 +704,7 @@ int sansmic::Model::leach() { // end of adjust the plume model (reverse) // leach fill from production to OBI - if (runMode >= LeachFill) { + if (runMode >= LEACH_FILL) { for (int i = prodCell; i <= obiCell; i++) { if (i > maxProdOrJet) { V_injSigned[i] = 0.0; @@ -782,7 +779,7 @@ int sansmic::Model::leach() { if (i < minProdOrJet || i > maxProdOrJet) { V_injSigned[i] = 0.0; } - if (i > maxProdOrJet && runMode == LeachFill) { + if (i > maxProdOrJet && runMode == LEACH_FILL) { V_injSigned[i] = -Q_fill; } r = max(r_cav[i], 1.0e-10); @@ -1086,14 +1083,14 @@ int sansmic::Model::leach() { izbs = obiCell; // move OBI if not Ordinary leaching mode - if (runMode == LeachFill) { + if (runMode == LEACH_FILL) { // move OBI if simultaneous LeachFill i_obi = int(h_obi / dz) + 1; dz_inc = Q_fill * dt / (_pi_ * sq(r_cav[i_obi])); h_obi = h_obi - min(dz_inc, dz); obiCell = int(h_obi / dz + 0.5) + 1; obiCellBelow = obiCell - 1; - } else if (runMode != Ordinary) { + } else if (runMode != ORDINARY) { // move OBI if Withdrawal or OilFill i_obiOld = obiCell; i_obi = int(h_obi / dz) + 1; @@ -1115,9 +1112,9 @@ int sansmic::Model::leach() { // CALCULATE MASS BALANCE CORRECTION FACTOR m_brineNew = m_brineNew - V_insol * C_cav[1]; - if (runMode == Ordinary) { + if (runMode == ORDINARY) { Q_fill = 0.0; - } else if (runMode == Withdrawal) { + } else if (runMode == WITHDRAWAL) { Q_fill = -ddim(Q_out, 0.0); } p5 = Q_fill; @@ -1205,11 +1202,13 @@ int sansmic::Model::leach() { if (b_is_injecting) { if (abs(z_obi - z_obi_stop) < 0.1 * dz) { t_end = t; - } else if (runMode != LeachFill && z_obi < z_obi_stop) { + } else if (runMode == WITHDRAWAL && z_obi <= z_obi_stop) { t_end = t; - } else if (z_obi > z_obi_stop) { + } else if (runMode == LEACH_FILL && z_obi >= z_obi_stop) { t_end = t; } + // dbh: there probably ought to be an exception check for ordinary + // mode, but the OBI doesn't move so it should be impossible to reach } } // stop on time - clear the handling variables diff --git a/src/ext_modules/libsansmic/stage.cpp b/src/ext_modules/libsansmic/stage.cpp index d041431..cab2c3f 100644 --- a/src/ext_modules/libsansmic/stage.cpp +++ b/src/ext_modules/libsansmic/stage.cpp @@ -22,7 +22,7 @@ */ sansmic::Stage::Stage() { title = ""; - leach_mode = Withdrawal; + leach_mode = WITHDRAWAL; print_freq = -1; is_subsequent = 0; t_rest = -1; diff --git a/src/python/sansmic/io.py b/src/python/sansmic/io.py index 2735ead..02e85aa 100644 --- a/src/python/sansmic/io.py +++ b/src/python/sansmic/io.py @@ -335,11 +335,18 @@ def read_dat(str_or_buffer: Union[str, Path], *, ignore_errors=False) -> Scenari stage.stop_value = float(stop_value) if stage.stop_value < 0: stage.stop_condition = StopCondition.DEPTH - if stage.stop_value > 0: + stage.stop_value = scenario.floor_depth + stage.stop_value + elif stage.stop_value > 0: stage.stop_condition = StopCondition.VOLUME - stage.brine_injection_depth = float(injection_height) - stage.brine_production_depth = float(production_height) - stage.brine_interface_depth = float(interface_height) + stage.brine_injection_depth = scenario.floor_depth - float(injection_height) + stage.brine_production_depth = scenario.floor_depth - float( + production_height + ) + stage.brine_interface_depth = ( + scenario.floor_depth - float(interface_height) + if float(interface_height) != 0 + else 0 + ) stage.brine_injection_rate = float(injection_rate) stage.inner_tbg_inside_diam = float(inn_tbg_inside_radius) * 2 stage.inner_tbg_outside_diam = float(inn_tbg_outside_radius) * 2 diff --git a/src/python/sansmic/model.py b/src/python/sansmic/model.py index 64e09b5..f64605b 100644 --- a/src/python/sansmic/model.py +++ b/src/python/sansmic/model.py @@ -122,9 +122,6 @@ class SimulationMode(IntEnum): LEACH_FILL = 2 """Simultaneous leaching (water/brine injection and brine production) and product injection from the top.""" - STORAGE_FILL = -1 - """Storage fill, with product injected from the top of the cavern and brine - produced from the suspended tubing/hanging string.""" class RateScheduleType(IntEnum): @@ -268,59 +265,6 @@ class StageDefinition: """The depth below surface/:term:`ZDP` where the end of the production string/casing/tubing is positioned.""" brine_injection_rate: Union[float, str] = 0 """The meaning of this field is based on the type of data that is provided (a value of 0 means off).""" - # """ - # float : constant rate - # Injection occurs at a constant rate for the duration of the - # :attr:`injection_duration`. - - # str : file path - # Injection rates should be read from a file. The file can be any type that can - # be read into a pd DataFrame. An 'index' column is optional, but if not provided, - # then all data is assumed to be pre-sorted. In addition to the - # 'index' column, files may contain exactly one set of the following columns: - - # ['rate', 'duration'] - # This style gives a list of rates and how long they should continue for. - # Durations are provided in decimal hours. If the sum of durations is greater - # than :attr:`injection_duration`, an error will be raised. If the - # sum of durations is less than :attr:`injection_duration`, the remaining - # time will be assumed to be no-flow. - - # ['time', 'rate'] - # This style gives a list of new rate values that start at the given time - # after the start of the stage. The 'time' values must be increasing and - # never duplicate. Times are in decimal hours since the start of the stage. - # The last rate will be used up until the end of the - # :attr:`injection_duration`. If a time is given that is after the - # :attr:`injection_duration`, then an error will be raised. - - # ['hourly'] - # This style specifies a new rate for each hour of the stage. There must be - # a value specified for each hour of the :attr`injection_duration`, or an - # error will be raised. - - # The optional column ['sg'] can be provided to change the injection water/brine - # specific gravity; however, if provided, it must contain a value for every row. - - # If 'duration' and 'time' occur in the same file, an error will be raised. - # If 'time', 'rate', or 'duration' occur in the same file as 'hourly', then - # an error will be raised. - - # Columns with names other than those described above will be ignored. - - # .. attention:: - - # In all cases, a no-flow, leaching-only period will occur for - # :attr:`rest_duration` hours **after** all injection data - # is processed -- this means that if an injection file finishes with 0s - # that there will be an additional :attr:`rest_duration` hours added to the - # end of the stage. - - # .. warning:: - - # The same file cnnot be used for both brine injection and product - # injection data. - # """ set_initial_conditions: bool = None """Unlink initial cavern brine gravity and interface level from previous stage. @@ -331,9 +275,6 @@ class StageDefinition: brine_interface_depth: float = None """Set the initial oil-brine interface or blanket level. By default None, which will link to the previous stage (as will a value of 0).""" - # set_cavern_temp: float = None - # """Set the initial temperature for all brine-filled cells of the cavern; by - # default None, which will link to the previous stage.""" product_injection_rate: Union[float, str] = 0.0 """Either a constant rate of product injection or a file with an injection schedule, by default 0.""" @@ -350,6 +291,10 @@ class StageDefinition: """If the :attr:`stop_condition` is not :attr:`~StopCondition.DURATION`, then the depth or volume value.""" defaults: InitVar[Dict[str, Any]] = None + blanket_depth: InitVar[float] = None + brine_injection_height: InitVar[float] = None + brine_production_height: InitVar[float] = None + brine_interface_height: InitVar[float] = None valid_default_keys = [ "solver_timestep", @@ -360,7 +305,14 @@ class StageDefinition: "outer_csg_outside_diam", ] - def __post_init__(self, defaults=None): + def __post_init__( + self, + defaults=None, + blanket_depth=None, + brine_injection_height=None, + brine_production_height=None, + brine_interface_height=None, + ): if defaults is None: return if not isinstance(defaults, dict): @@ -375,6 +327,17 @@ def __post_init__(self, defaults=None): ) elif getattr(self, k2) is None: setattr(self, k2, v) + if blanket_depth is not None: + self.brine_interface_depth = blanket_depth + if isinstance(brine_injection_height, float): + self.brine_injection_depth = -abs(brine_injection_height) + if isinstance(brine_production_height, float): + self.brine_production_depth = -abs(brine_production_height) + if isinstance(brine_interface_height, float): + self.brine_interface_depth = -abs(brine_interface_height) + self.brine_injection_height = self.__class__._brine_injection_height + self.brine_production_height = self.__class__._brine_production_height + self.brine_interface_height = self.__class__._brine_interface_height def __setattr__(self, name, value): if isinstance(value, str) and value.strip() == "": @@ -406,6 +369,60 @@ def __setattr__(self, name, value): # self.brine_interface_depth = None super().__setattr__(name, value) + @property + def _blanket_depth(self) -> float: + """Alias for :attr:`brine_interface_depth`""" + return self.brine_interface_depth + + @_blanket_depth.setter + def _blanket_depth(self, value): + self.brine_interface_depth = value + + @property + def _brine_injection_height(self) -> float: + """Height above floor where brine is injected. The :attr:`brine_injection_depth` will be a negative value if set using this property.""" + if self.brine_injection_depth is None: + return None + if self.brine_injection_depth < 0: + return abs(self.brine_injection_depth) + raise ValueError( + "Cannot calculate height above floor when a depth was used to set this value" + ) + + @_brine_injection_height.setter + def _brine_injection_height(self, value): + self.brine_injection_depth = -abs(value) + + @property + def _brine_production_height(self) -> float: + """Height above floor where brine is produced. The :attr:`brine_production_depth` will be a negative value if set using this property.""" + if self.brine_production_depth is None: + return None + if self.brine_production_depth < 0: + return abs(self.brine_production_depth) + raise ValueError( + "Cannot calculate height above floor when a depth was used to set this value" + ) + + @_brine_production_height.setter + def _brine_production_height(self, value): + self.brine_production_depth = -abs(value) + + @property + def _brine_interface_height(self) -> float: + """Height above floor where interface starts. The :attr:`brine_interface_depth` will be a negative value if set using this property.""" + if self.brine_interface_depth is None: + return None + if self.brine_interface_depth <= 0: + return abs(self.brine_interface_depth) + raise ValueError( + "Cannot calculate height above floor when a depth was used to set this value" + ) + + @_brine_interface_height.setter + def _brine_interface_height(self, value): + self.brine_interface_depth = -abs(value) + @classmethod def from_dict(cls, opts: dict, defaults=None) -> "StageDefinition": """Create a new object from a dictionary of options. @@ -510,7 +527,6 @@ def validate(self): in [ SimulationMode.ORDINARY, SimulationMode.LEACH_FILL, - SimulationMode.STORAGE_FILL, ] and self.brine_production_depth is None ): @@ -569,7 +585,6 @@ def validate(self): SimulationMode.ORDINARY, SimulationMode.LEACH_FILL, SimulationMode.WITHDRAWAL, - SimulationMode.STORAGE_FILL, ] and self.inner_tbg_inside_diam is None ): @@ -584,7 +599,6 @@ def validate(self): SimulationMode.ORDINARY, SimulationMode.LEACH_FILL, SimulationMode.WITHDRAWAL, - SimulationMode.STORAGE_FILL, ] and self.inner_tbg_outside_diam is None ): @@ -619,8 +633,7 @@ def validate(self): # ): # self.product_injection_depth = 0.0 if ( - self.simulation_mode - in [SimulationMode.LEACH_FILL, SimulationMode.STORAGE_FILL] + self.simulation_mode is SimulationMode.LEACH_FILL and self.product_injection_rate is None ): raise TypeError( @@ -667,15 +680,15 @@ def _to_cstage(self, defaults=None) -> _ext.CStage: else 0 ) stage.injection_depth = ( - self.brine_injection_depth if self.brine_injection_depth is not None else 0 + -self.brine_injection_depth if self.brine_injection_depth is not None else 0 ) stage.production_depth = ( - self.brine_production_depth + -self.brine_production_depth if self.brine_production_depth is not None else 0 ) stage.interface_depth = ( - self.brine_interface_depth if self.brine_interface_depth is not None else 0 + -self.brine_interface_depth if self.brine_interface_depth is not None else 0 ) stage.injection_rate = self.brine_injection_rate stage.inn_tbg_inside_radius = self.inner_tbg_inside_diam / 2.0 diff --git a/tests/test_io.py b/tests/test_io.py index e7554ef..bc7efe6 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -59,14 +59,14 @@ def test_read_scenario_leachfill(self): self.assertIs( scenario.geometry_format, sansmic.model.GeometryFormat.RADIUS_LIST ) - self.assertEqual(scenario.stages[0].stop_value, -200.0) + self.assertEqual(scenario.stages[0].stop_value, 3800.0) self.assertIs( scenario.stages[0].stop_condition, sansmic.model.StopCondition.DEPTH ) self.assertEqual(scenario.cavern_height, 1000.0) - self.assertEqual(scenario.stages[0].brine_injection_depth, 32.0) - self.assertEqual(scenario.stages[0].brine_production_depth, 350.0) - self.assertEqual(scenario.stages[0].brine_interface_depth, 900.0) + self.assertEqual(scenario.stages[0].brine_injection_depth, 3968.0) + self.assertEqual(scenario.stages[0].brine_production_depth, 4000 - 350.0) + self.assertEqual(scenario.stages[0].brine_interface_depth, 4000 - 900.0) self.assertEqual(scenario.ullage_standoff, 20.0) self.assertEqual(scenario.stages[0].brine_injection_rate, 240000.0) self.assertEqual(scenario.stages[0].inner_tbg_inside_diam / 2, 4.925) @@ -107,9 +107,9 @@ def test_read_scenario_withdrawal(self): scenario.stages[0].stop_condition, sansmic.model.StopCondition.DURATION ) self.assertEqual(scenario.cavern_height, 1000.0) - self.assertEqual(scenario.stages[0].brine_injection_depth, 32.0) - self.assertEqual(scenario.stages[0].brine_production_depth, 1000.0) - self.assertEqual(scenario.stages[0].brine_interface_depth, 100.0) + self.assertEqual(scenario.stages[0].brine_injection_depth, 4000 - 32.0) + self.assertEqual(scenario.stages[0].brine_production_depth, 4000 - 1000.0) + self.assertEqual(scenario.stages[0].brine_interface_depth, 4000 - 100.0) self.assertEqual(scenario.ullage_standoff, 20.0) self.assertEqual(scenario.stages[0].brine_injection_rate, 240000.0) self.assertEqual(scenario.stages[0].inner_tbg_inside_diam / 2, 4.925) @@ -150,9 +150,9 @@ def test_read_scenario_ordinary_direct(self): scenario.stages[0].stop_condition, sansmic.model.StopCondition.VOLUME ) self.assertEqual(scenario.cavern_height, 1000.0) - self.assertEqual(scenario.stages[0].brine_injection_depth, 100.0) - self.assertEqual(scenario.stages[0].brine_production_depth, 800.0) - self.assertEqual(scenario.stages[0].brine_interface_depth, 900.0) + self.assertEqual(scenario.stages[0].brine_injection_depth, 4000 - 100.0) + self.assertEqual(scenario.stages[0].brine_production_depth, 4000 - 800.0) + self.assertEqual(scenario.stages[0].brine_interface_depth, 4000 - 900.0) self.assertEqual(scenario.ullage_standoff, 20.0) self.assertEqual(scenario.stages[0].brine_injection_rate, 240000.0) self.assertEqual(scenario.stages[0].inner_tbg_inside_diam / 2, 4.925) @@ -193,9 +193,9 @@ def test_read_scenario_ordinary_reverse_multistage(self): scenario.stages[0].stop_condition, sansmic.model.StopCondition.DURATION ) self.assertEqual(scenario.cavern_height, 1000.0) - self.assertEqual(scenario.stages[0].brine_injection_depth, 800.0) - self.assertEqual(scenario.stages[0].brine_production_depth, 100.0) - self.assertEqual(scenario.stages[0].brine_interface_depth, 900.0) + self.assertEqual(scenario.stages[0].brine_injection_depth, 4000 - 800.0) + self.assertEqual(scenario.stages[0].brine_production_depth, 4000 - 100.0) + self.assertEqual(scenario.stages[0].brine_interface_depth, 4000 - 900.0) self.assertEqual(scenario.ullage_standoff, 20.0) self.assertEqual(scenario.stages[0].brine_injection_rate, 240000.0) self.assertEqual(scenario.stages[0].inner_tbg_inside_diam / 2, 4.925) @@ -225,8 +225,8 @@ def test_read_scenario_ordinary_reverse_multistage(self): self.assertIs( scenario.stages[1].stop_condition, sansmic.model.StopCondition.DURATION ) - self.assertEqual(scenario.stages[1].brine_injection_depth, 800.0) - self.assertEqual(scenario.stages[1].brine_production_depth, 100.0) + self.assertEqual(scenario.stages[1].brine_injection_depth, 4000 - 800.0) + self.assertEqual(scenario.stages[1].brine_production_depth, 4000 - 100.0) self.assertEqual(scenario.stages[1].brine_interface_depth, 0.0) self.assertEqual(scenario.stages[1].brine_injection_rate, 240000.0) self.assertEqual(scenario.stages[1].inner_tbg_inside_diam / 2, 4.925) @@ -250,8 +250,8 @@ def test_read_scenario_ordinary_reverse_multistage(self): self.assertIs( scenario.stages[2].stop_condition, sansmic.model.StopCondition.DURATION ) - self.assertEqual(scenario.stages[2].brine_injection_depth, 800.0) - self.assertEqual(scenario.stages[2].brine_production_depth, 100.0) + self.assertEqual(scenario.stages[2].brine_injection_depth, 4000 - 800.0) + self.assertEqual(scenario.stages[2].brine_production_depth, 4000 - 100.0) self.assertEqual(scenario.stages[2].brine_interface_depth, 0.0) self.assertEqual(scenario.stages[2].brine_injection_rate, 240000.0) self.assertEqual(scenario.stages[2].inner_tbg_inside_diam / 2, 4.925)