From 541dab677ad57c97c3af058901f60a755246fbc2 Mon Sep 17 00:00:00 2001 From: hommel <johannes.hommel@iws.uni-stuttgart.de> Date: Wed, 31 Jul 2019 14:14:27 +0200 Subject: [PATCH] [examples][biomin] added new biomineralization example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit with contributions by Felix Weinhardt and some proof reading by Timo Koch and Dennis Gläser --- examples/CMakeLists.txt | 1 + examples/README.md | 21 + examples/biomineralization/.doc_config | 53 + examples/biomineralization/CMakeLists.txt | 11 + examples/biomineralization/README.md | 190 ++++ examples/biomineralization/doc/_intro.md | 159 +++ .../biomineralization/doc/fluidmaterial.md | 784 ++++++++++++++ .../doc/fluidmaterial_intro.md | 42 + examples/biomineralization/doc/mainfile.md | 330 ++++++ .../biomineralization/doc/mainfile_intro.md | 14 + examples/biomineralization/doc/material.md | 990 ++++++++++++++++++ .../biomineralization/doc/modelconcept.md | 271 +++++ .../doc/modelconcept_intro.md | 261 +++++ examples/biomineralization/doc/setup.md | 938 +++++++++++++++++ examples/biomineralization/doc/setup_intro.md | 17 + .../biomineralization/doc/solidmaterial.md | 258 +++++ .../doc/solidmaterial_intro.md | 38 + .../img/pore_scale_w_processes_named.png | Bin 0 -> 154841 bytes .../results_volfracs_over_length_100000s.png | Bin 0 -> 17950 bytes .../injection_checkpoints.dat | 212 ++++ examples/biomineralization/injection_type.dat | 212 ++++ examples/biomineralization/main.cc | 278 +++++ .../material/co2tableslaboratory.hh | 38 + .../material/co2valueslaboratory.inc | 424 ++++++++ .../material/components/biofilm.hh | 74 ++ .../material/components/suspendedbiomass.hh | 65 ++ .../material/fluidsystems/CMakeLists.txt | 5 + .../fluidsystems/biominsimplechemistry.hh | 582 ++++++++++ .../fluidsystems/icpcomplexsalinitybrine.hh | 391 +++++++ .../material/solidsystems/biominsolids.hh | 197 ++++ examples/biomineralization/params.input | 63 ++ examples/biomineralization/problem.hh | 590 +++++++++++ examples/biomineralization/properties.hh | 125 +++ examples/biomineralization/spatialparams.hh | 149 +++ .../example_biomineralization-reference.vtp | 296 ++++++ 35 files changed, 8079 insertions(+) create mode 100644 examples/biomineralization/.doc_config create mode 100644 examples/biomineralization/CMakeLists.txt create mode 100644 examples/biomineralization/README.md create mode 100644 examples/biomineralization/doc/_intro.md create mode 100644 examples/biomineralization/doc/fluidmaterial.md create mode 100644 examples/biomineralization/doc/fluidmaterial_intro.md create mode 100644 examples/biomineralization/doc/mainfile.md create mode 100644 examples/biomineralization/doc/mainfile_intro.md create mode 100644 examples/biomineralization/doc/material.md create mode 100644 examples/biomineralization/doc/modelconcept.md create mode 100644 examples/biomineralization/doc/modelconcept_intro.md create mode 100644 examples/biomineralization/doc/setup.md create mode 100644 examples/biomineralization/doc/setup_intro.md create mode 100644 examples/biomineralization/doc/solidmaterial.md create mode 100644 examples/biomineralization/doc/solidmaterial_intro.md create mode 100644 examples/biomineralization/img/pore_scale_w_processes_named.png create mode 100644 examples/biomineralization/img/results_volfracs_over_length_100000s.png create mode 100644 examples/biomineralization/injection_checkpoints.dat create mode 100644 examples/biomineralization/injection_type.dat create mode 100644 examples/biomineralization/main.cc create mode 100644 examples/biomineralization/material/co2tableslaboratory.hh create mode 100644 examples/biomineralization/material/co2valueslaboratory.inc create mode 100644 examples/biomineralization/material/components/biofilm.hh create mode 100644 examples/biomineralization/material/components/suspendedbiomass.hh create mode 100644 examples/biomineralization/material/fluidsystems/CMakeLists.txt create mode 100644 examples/biomineralization/material/fluidsystems/biominsimplechemistry.hh create mode 100644 examples/biomineralization/material/fluidsystems/icpcomplexsalinitybrine.hh create mode 100644 examples/biomineralization/material/solidsystems/biominsolids.hh create mode 100644 examples/biomineralization/params.input create mode 100644 examples/biomineralization/problem.hh create mode 100644 examples/biomineralization/properties.hh create mode 100644 examples/biomineralization/spatialparams.hh create mode 100644 test/references/example_biomineralization-reference.vtp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 058cc9e278..d839bb9070 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(2pinfiltration) add_subdirectory(1ptracer) +add_subdirectory(biomineralization) add_subdirectory(shallowwaterfriction) add_subdirectory(freeflowchannel) add_subdirectory(1protationsymmetry) diff --git a/examples/README.md b/examples/README.md index e4e0e646c5..8f3fc62a4f 100644 --- a/examples/README.md +++ b/examples/README.md @@ -91,3 +91,24 @@ You learn how to <figure><img src="1protationsymmetry/img/setup.svg" alt="Rotation-symmetric setup"/></figure></td> </a></td> </tr></table> + +### [:open_file_folder: Example 6: Biomineralization](biomineralization/README.md) + +<table><tr><td> + +In this example, we simulate microbially-induced calcite precipitation +You learn how to + +* solve a reactive transport model including + * biofilm growth + * mineral precipitation and dissolution + * changing porosity and permeability +* use complex fluid and solid systems +* set a complex time loop with checkpoints, reading the check points from a file +* set complex injection boundary conditions, reading the injection types from a file + +</td> +<td width="20%"><a href="biomineralization/README.md"> +<figure><img src="biomineralization/img/pore_scale_w_processes_named.png" alt="biomin result"/></figure></td> +</a></td> +</tr></table> diff --git a/examples/biomineralization/.doc_config b/examples/biomineralization/.doc_config new file mode 100644 index 0000000000..4481d351ff --- /dev/null +++ b/examples/biomineralization/.doc_config @@ -0,0 +1,53 @@ +{ + "README.md" : [ + "doc/_intro.md" + ], + + "doc/modelconcept.md" : [ + "doc/modelconcept_intro.md" + ], + + "doc/mainfile.md" : [ + "doc/mainfile_intro.md", + "main.cc" + ], + + "doc/setup.md" : [ + "doc/setup_intro.md", + "problem.hh", + "spatialparams.hh", + "properties.hh" + ], + + "doc/fluidmaterial.md" : [ + "doc/fluidmaterial_intro.md", + "material/co2tableslaboratory.hh", + "material/components/suspendedbiomass.hh", + "material/fluidsystems/biominsimplechemistry.hh", + "material/fluidsystems/icpcomplexsalinitybrine.hh" + ], + + "doc/solidmaterial.md" : [ + "doc/solidmaterial_intro.md", + "material/components/biofilm.hh", + "material/solidsystems/biominsolids.hh" + ], + + "navigation" : { + "mainpage" : "README.md", + "subpages" : [ + "doc/modelconcept.md", + "doc/mainfile.md", + "doc/setup.md", + "doc/fluidmaterial.md", + "doc/solidmaterial.md" + ], + "subtitles" : [ + "Model concept", + "Main file", + "Simulation setup", + "Specific fluid material files", + "Specific solid material files" + ] + } +} diff --git a/examples/biomineralization/CMakeLists.txt b/examples/biomineralization/CMakeLists.txt new file mode 100644 index 0000000000..9820938673 --- /dev/null +++ b/examples/biomineralization/CMakeLists.txt @@ -0,0 +1,11 @@ +dune_symlink_to_source_files(FILES injection_checkpoints.dat injection_type.dat params.input) + +# compile MICP simplified chemistry column setup +dumux_add_test(NAME example_biomineralization + LABELS porousmediumflow + SOURCES main.cc + COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/test/references/example_biomineralization-reference.vtp + ${CMAKE_CURRENT_BINARY_DIR}/example_biomineralization-00018.vtp + --command "${CMAKE_CURRENT_BINARY_DIR}/example_biomineralization params.input -Problem.Name example_biomineralization") diff --git a/examples/biomineralization/README.md b/examples/biomineralization/README.md new file mode 100644 index 0000000000..42529a0986 --- /dev/null +++ b/examples/biomineralization/README.md @@ -0,0 +1,190 @@ +<!-- Important: This file has been automatically generated by generate_example_docs.py. Do not edit this file directly! --> + +# Biomineralization + +We simulate microbially-induced calcite precipitation in a vertical sand-column. +The problem is considered radially-symmetric so that a one-dimensional problem can be simulated. + +__The main points illustrated in this example are__ +* solving a reactive transport model including + * biofilm growth + * mineral precipitation and dissolution + * changing porosity and permeability +* using complex fluid and solid systems +* setting a complex time loop with checkpoints, reading the check points from a file +* set complex injection boundary conditions, reading the injection types from a file + +__Table of contents__. This description is structured as follows: + +[[_TOC_]] + +__Result__. The result will look like below. +You see the volume fractions of the solid components after 100000s over the column. + +<figure> + <center> + <img src="img/results_volfracs_over_length_100000s.png" alt="Biofilm and calcite volume fractions" width="50%"/> + <figcaption> <b> Fig.1 </b> - Biofilm and calcite volume fractions.</figcaption> + </center> +</figure> + +## Problem set-up +A vertical, sand-filled column is biomineralized by repeated injections of various aqueous solutions +from its bottom end. The setup will be explained in more detail in [Part 3: Example Setup](doc/setup.md). +For more information, see the description of _column experiment D1_ in Section 4.2 of [@Hommel2016]. + +## What is microbially-induced calcite precipitation? +Microbially-induced calcite precipitation (MICP) is an engineering technology for targeted biomineralization. +It can be used in the context of sealing possible leakage pathways of subsurface gas or oil reservoirs as well as other applications. +The governing processes are two-phase multi-component reactive transport including precipitation and dissolution +of calcite, as well as biomass-related processes: +* attachment of biomass to surfaces, +* detachment of biomass from a biofilm, +* growth and decay of biomass. + +Additionally, the reduction in porosity and permeability has to be considered. +This results from the presence of the solid phases biofilm and calcite in the pore space. + +In subsurface applications, MICP is typically +associated with a reduction of porosity, which, even more importantly, corresponds to a +reduction of permeability. +MICP can be used to alter hydraulic flow conditions, for example, by filling highly permeable pathways such as +fractures, faults, or behind-casing defects in boreholes within a geological +formation, e.g. [@Phillips2013a]. + +The bacterium _Sporosarcina pasteurii_ +expresses the enzyme urease that catalyzes the hydrolysis reaction of +urea (CO(NH<sub>2</sub>)<sub>2</sub>) into ammonia (NH<sub>3</sub>) and carbon +dioxide (CO<sub>2</sub>): + +```math +\mathrm{CO(NH_2)_2} + 2\mathrm{H_2O} \xrightarrow{urease} +2\mathrm{NH_{3}} + \mathrm{H_2CO_{3}}. +\tag{1} +``` + +Aqueous solutions of ammonia become alkaline until the equilibrium of ammonium and ammonia is reached. +Thus, the ureolysis reaction leads to an increase in pH until the pH is equal to the pKa of ammonia. +This shifts the +carbonate balance in an aqueous solution toward higher concentrations of +dissolved carbonate. +Adding calcium to the system results then in the precipitation of calcium carbonate: + +```math +\mathrm{CO_{3}^{2-}} + \mathrm{Ca^{2+}} \longrightarrow \mathrm{CaCO_3 \downarrow}. +``` + +The resulting overall MICP reaction equation is: + +```math +\mathrm{CO(NH_2)_2} + 2\mathrm{H_2O} + \mathrm{Ca^{2+}} \xrightarrow{urease} +2\mathrm{NH_{4}^{+}} + \mathrm{CaCO_{3}} \downarrow. +``` + +In a porous medium, biofilm growth, fluid dynamics, +and reaction rates are strongly interacting. +A pore-scale sketch of the most important processes of MICP is shown +in Fig.2. + +<figure> + <center> + <img src="img/pore_scale_w_processes_named.png" alt="Schematic pore-scale sketch of the processes during biomineralization." width="50%"/> + <figcaption> <b> Fig.2 </b> - Schematic pore-scale sketch of the processes during biomineralization.</figcaption> + </center> +</figure> + +A major difficulty for practical engineering applications of MICP is the predictive planning of a scenario and its impact. +While the basic chemistry and the flow processes are known, it is mainly the quantitative description +of the influence of the biofilm and the developing precipitates on hydraulic parameters that poses challenges to achieving predictability. +More details on modeling biomineralization are given in [Part 1: Model Concept](doc/modelconcept.md). + +# The code documentation + +In the following, we take a closer look at the source files for this example. +The setup is rather complex in comparison to the other examples. +We will discuss the different parts of the code in detail subsequently. + +``` +└── biomineralization/ + ├── CMakeLists.txt -> build system file + ├── main.cc -> main program flow + ├── params.input -> runtime parameters + ├── injections.dat -> runtime injection strategy input file + ├── properties.hh -> compile time settings for the simulation + ├── problem.hh -> boundary & initial conditions for the simulation + ├── spatialparams.hh -> parameter distributions for the simulation + └── material/ -> components, fluid- and solidsystems + ├── components/ + │ ├── biofilm.hh + │ └── suspendedbiomass.hh + ├── fluidsystems/ + │ ├── biominsimplechemistry.hh + │ └── icpcomplexsalinitybrine.hh + ├── solidsystems/ + │ └── biominsolids.hh + └── co2tableslaboratory.hh +``` + +In order to define a simulation setup in DuMu<sup>x</sup>, you need to implement compile-time settings, +where you specify the classes and compile-time options that DuMu<sup>x</sup> should use for the simulation. +Moreover, a `Problem` class needs to be implemented, in which the initial and boundary conditions +are specified. Finally, spatially-distributed values for the parameters required by the used model +are implemented in a `SpatialParams` class. + +__Part 1__ discusses the mathematical model in more detail. + +__Part 2__ takes a close look at the main file. +`main.cc` controlling the simulation, and containing the time loop management, +A special feature of this example, which might be interesting also for non-biomineralization modelers, +is that it uses the class `CheckPointTimeLoop` extensively to set the injections of the various consecutive +biomineralization solution injections based on a separate input file `injections_checkpoints.dat`. +Similar strategies might be useful when simulating experimental setups with boundary conditions changing over time. + +__Part 3__ takes a close look at the problem set-up. +`problem.hh` featuring the reactive source and sink terms discussed in the model concept and the time-dependent injection boundary conditions, and +`spatialparams.hh` with the spatially distributed parameters, most importantly the porosity and permeability changing due to the reactions. +A special feature of this example, which might be interesting also for non-biomineralization modelers, +is that `problem.hh`, determines the Neumann boundary condition, more specifically which type of solution is currently injected, (the `injectionType_`) based on a separate input file `injections_type.dat`. +Similar strategies might be useful when simulating experimental setups with boundary conditions changing over time. + +__Part 4__ discusses the code concerned with the fluid (files in the folder `material/`), +especially the multi-component fluidsystems. +The CO<sub>2</sub> properties are stored in the CO<sub>2</sub> tables in the subfolder `material` (`co2tableslaboratory.hh`,`co2valueslaboratory.inc`). + +__Part 5__ discusses the code concerned with the solid properties (files in the folder `material/`), +especially the multi-component solidsystems and variable solid volume fractions. + + +[@Ebigbo2012]: https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2011WR011714 "Darcy-scale modeling of microbially induced carbonate mineral precipitation in sand columns" +[@Hommel2015]: https://agupubs.onlinelibrary.wiley.com/doi/full/10.1002/2014WR016503 "A revised model for microbially induced calcite precipitation: Improvements and new insights based on recent experiments" +[@Hommel2016]: https://elib.uni-stuttgart.de/handle/11682/8787 "Modelling biogeochemical and mass transport processes in the subsurface: investigation of microbially induced calcite precipitation" +[@Phillips2013a]: https://pubs.acs.org/doi/abs/10.1021/es301294q "Potential CO<sub>2</sub> leakage reduction through biofilm-induced calcium carbonate precipitation" + +## Part 1: Model concept + +| [:arrow_right: Click to continue with part 1 of the documentation](doc/modelconcept.md) | +|---:| + + +## Part 2: Main file + +| [:arrow_right: Click to continue with part 2 of the documentation](doc/mainfile.md) | +|---:| + + +## Part 3: Simulation setup + +| [:arrow_right: Click to continue with part 3 of the documentation](doc/setup.md) | +|---:| + + +## Part 4: Specific fluid material files + +| [:arrow_right: Click to continue with part 4 of the documentation](doc/fluidmaterial.md) | +|---:| + + +## Part 5: Specific solid material files + +| [:arrow_right: Click to continue with part 5 of the documentation](doc/solidmaterial.md) | +|---:| \ No newline at end of file diff --git a/examples/biomineralization/doc/_intro.md b/examples/biomineralization/doc/_intro.md new file mode 100644 index 0000000000..34d532bb0a --- /dev/null +++ b/examples/biomineralization/doc/_intro.md @@ -0,0 +1,159 @@ +# Biomineralization + +We simulate microbially-induced calcite precipitation in a vertical sand-column. +The problem is considered radially-symmetric so that a one-dimensional problem can be simulated. + +__The main points illustrated in this example are__ +* solving a reactive transport model including + * biofilm growth + * mineral precipitation and dissolution + * changing porosity and permeability +* using complex fluid and solid systems +* setting a complex time loop with checkpoints, reading the check points from a file +* set complex injection boundary conditions, reading the injection types from a file + +__Table of contents__. This description is structured as follows: + +[[_TOC_]] + +__Result__. The result will look like below. +You see the volume fractions of the solid components after 100000s over the column. + +<figure> + <center> + <img src="img/results_volfracs_over_length_100000s.png" alt="Biofilm and calcite volume fractions" width="50%"/> + <figcaption> <b> Fig.1 </b> - Biofilm and calcite volume fractions.</figcaption> + </center> +</figure> + +## Problem set-up +A vertical, sand-filled column is biomineralized by repeated injections of various aqueous solutions +from its bottom end. The setup will be explained in more detail in [Part 3: Example Setup](doc/setup.md). +For more information, see the description of _column experiment D1_ in Section 4.2 of [@Hommel2016]. + +## What is microbially-induced calcite precipitation? +Microbially-induced calcite precipitation (MICP) is an engineering technology for targeted biomineralization. +It can be used in the context of sealing possible leakage pathways of subsurface gas or oil reservoirs as well as other applications. +The governing processes are two-phase multi-component reactive transport including precipitation and dissolution +of calcite, as well as biomass-related processes: +* attachment of biomass to surfaces, +* detachment of biomass from a biofilm, +* growth and decay of biomass. + +Additionally, the reduction in porosity and permeability has to be considered. +This results from the presence of the solid phases biofilm and calcite in the pore space. + +In subsurface applications, MICP is typically +associated with a reduction of porosity, which, even more importantly, corresponds to a +reduction of permeability. +MICP can be used to alter hydraulic flow conditions, for example, by filling highly permeable pathways such as +fractures, faults, or behind-casing defects in boreholes within a geological +formation, e.g. [@Phillips2013a]. + +The bacterium _Sporosarcina pasteurii_ +expresses the enzyme urease that catalyzes the hydrolysis reaction of +urea (CO(NH<sub>2</sub>)<sub>2</sub>) into ammonia (NH<sub>3</sub>) and carbon +dioxide (CO<sub>2</sub>): + +```math +\mathrm{CO(NH_2)_2} + 2\mathrm{H_2O} \xrightarrow{urease} +2\mathrm{NH_{3}} + \mathrm{H_2CO_{3}}. +\tag{1} +``` + +Aqueous solutions of ammonia become alkaline until the equilibrium of ammonium and ammonia is reached. +Thus, the ureolysis reaction leads to an increase in pH until the pH is equal to the pKa of ammonia. +This shifts the +carbonate balance in an aqueous solution toward higher concentrations of +dissolved carbonate. +Adding calcium to the system results then in the precipitation of calcium carbonate: + +```math +\mathrm{CO_{3}^{2-}} + \mathrm{Ca^{2+}} \longrightarrow \mathrm{CaCO_3 \downarrow}. +``` + +The resulting overall MICP reaction equation is: + +```math +\mathrm{CO(NH_2)_2} + 2\mathrm{H_2O} + \mathrm{Ca^{2+}} \xrightarrow{urease} +2\mathrm{NH_{4}^{+}} + \mathrm{CaCO_{3}} \downarrow. +``` + +In a porous medium, biofilm growth, fluid dynamics, +and reaction rates are strongly interacting. +A pore-scale sketch of the most important processes of MICP is shown +in Fig.2. + +<figure> + <center> + <img src="img/pore_scale_w_processes_named.png" alt="Schematic pore-scale sketch of the processes during biomineralization." width="50%"/> + <figcaption> <b> Fig.2 </b> - Schematic pore-scale sketch of the processes during biomineralization.</figcaption> + </center> +</figure> + +A major difficulty for practical engineering applications of MICP is the predictive planning of a scenario and its impact. +While the basic chemistry and the flow processes are known, it is mainly the quantitative description +of the influence of the biofilm and the developing precipitates on hydraulic parameters that poses challenges to achieving predictability. +More details on modeling biomineralization are given in [Part 1: Model Concept](doc/modelconcept.md). + +# The code documentation + +In the following, we take a closer look at the source files for this example. +The setup is rather complex in comparison to the other examples. +We will discuss the different parts of the code in detail subsequently. + +``` +└── biomineralization/ + ├── CMakeLists.txt -> build system file + ├── main.cc -> main program flow + ├── params.input -> runtime parameters + ├── injections.dat -> runtime injection strategy input file + ├── properties.hh -> compile time settings for the simulation + ├── problem.hh -> boundary & initial conditions for the simulation + ├── spatialparams.hh -> parameter distributions for the simulation + └── material/ -> components, fluid- and solidsystems + ├── components/ + │ ├── biofilm.hh + │ └── suspendedbiomass.hh + ├── fluidsystems/ + │ ├── biominsimplechemistry.hh + │ └── icpcomplexsalinitybrine.hh + ├── solidsystems/ + │ └── biominsolids.hh + └── co2tableslaboratory.hh +``` + +In order to define a simulation setup in DuMu<sup>x</sup>, you need to implement compile-time settings, +where you specify the classes and compile-time options that DuMu<sup>x</sup> should use for the simulation. +Moreover, a `Problem` class needs to be implemented, in which the initial and boundary conditions +are specified. Finally, spatially-distributed values for the parameters required by the used model +are implemented in a `SpatialParams` class. + +__Part 1__ discusses the mathematical model in more detail. + +__Part 2__ takes a close look at the main file. +`main.cc` controlling the simulation, and containing the time loop management, +A special feature of this example, which might be interesting also for non-biomineralization modelers, +is that it uses the class `CheckPointTimeLoop` extensively to set the injections of the various consecutive +biomineralization solution injections based on a separate input file `injections_checkpoints.dat`. +Similar strategies might be useful when simulating experimental setups with boundary conditions changing over time. + +__Part 3__ takes a close look at the problem set-up. +`problem.hh` featuring the reactive source and sink terms discussed in the model concept and the time-dependent injection boundary conditions, and +`spatialparams.hh` with the spatially distributed parameters, most importantly the porosity and permeability changing due to the reactions. +A special feature of this example, which might be interesting also for non-biomineralization modelers, +is that `problem.hh`, determines the Neumann boundary condition, more specifically which type of solution is currently injected, (the `injectionType_`) based on a separate input file `injections_type.dat`. +Similar strategies might be useful when simulating experimental setups with boundary conditions changing over time. + +__Part 4__ discusses the code concerned with the fluid (files in the folder `material/`), +especially the multi-component fluidsystems. +The CO<sub>2</sub> properties are stored in the CO<sub>2</sub> tables in the subfolder `material` (`co2tableslaboratory.hh`,`co2valueslaboratory.inc`). + +__Part 5__ discusses the code concerned with the solid properties (files in the folder `material/`), +especially the multi-component solidsystems and variable solid volume fractions. + + +[@Ebigbo2012]: https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2011WR011714 "Darcy-scale modeling of microbially induced carbonate mineral precipitation in sand columns" +[@Hommel2015]: https://agupubs.onlinelibrary.wiley.com/doi/full/10.1002/2014WR016503 "A revised model for microbially induced calcite precipitation: Improvements and new insights based on recent experiments" +[@Hommel2016]: https://elib.uni-stuttgart.de/handle/11682/8787 "Modelling biogeochemical and mass transport processes in the subsurface: investigation of microbially induced calcite precipitation" +[@Phillips2013a]: https://pubs.acs.org/doi/abs/10.1021/es301294q "Potential CO<sub>2</sub> leakage reduction through biofilm-induced calcium carbonate precipitation" diff --git a/examples/biomineralization/doc/fluidmaterial.md b/examples/biomineralization/doc/fluidmaterial.md new file mode 100644 index 0000000000..f02af395a6 --- /dev/null +++ b/examples/biomineralization/doc/fluidmaterial.md @@ -0,0 +1,784 @@ +<!-- Important: This file has been automatically generated by generate_example_docs.py. Do not edit this file directly! --> + + +| [:arrow_left: Back to the main documentation](../README.md) | [:arrow_left: Go back to part 3](setup.md) | [:arrow_right: Continue with part 5](solidmaterial.md) | +|---|---|---:| + +# Biomineralization - Fluids + +The main idea of biomineralization revolves around +biologically-induced mineral precipitation. +I our example, it is about precipitation of calcite +due to urea hydrolysis. +The resulting overall reaction equation is: + +```math +\mathrm{CO(NH_2)_2} + 2\mathrm{H_2O} + \mathrm{Ca^{2+}} \xrightarrow{urease} +2\mathrm{NH_{4}^{+}} + \mathrm{CaCO_{3}} \downarrow. +``` + +To describe the processes, the minimum set of components is: +water (w), dissolved inorganic carbon (C<sub>tot</sub>), +sodium (Na), chloride (Cl), calcium (Ca), urea (u), glucose as a substrate (s), oxygen (O<sub>2</sub>), and suspended biomass (b), +as well as the solid components biofilm and calcite. +Thus, there are many components involved and keeping track of the components and their interactions, +necessitates a sophisticated handling. +This is why the material folder in this example is both separated from the regular material folder in dumux/dumux/material +and also documented separately. +For further specialization, the overview over the material subfolder is split into solid and fluid, this description considering the fluids. + +## Fluids in the folder `material` + +As this example is about biomineralization involving many components with complex inteactions, some specific fluid material files are necessary. +A CO_2-Table file provides tabulated CO_2 properties according to @Span1996 in `material/co2tableslaboratory.hh` +In the component subfolder, `material/components/suspendedbiomass.hh` defines the component suspended biomass, which is the mobile form of biomass being transported suspended in the aqueous fluid phase. +In the fluidsystem subfolder, the biomineralization fluidsystem `material/fluidsystems/biominsimplechemistry.hh` as well as +the complex salinity brine adapter `material/fluidsystems/icpcomplexsalinitybrine.hh` can be found. +The biomineralization fluidsystem `material/fluidsystems/biominsimplechemistry.hh` +contains the fluid related properties and the interactions of the components in the fluids. +The complex salinity brine adapter `material/fluidsystems/icpcomplexsalinitybrine.hh` +adapts the brine fluidsystem (dumux/dumux/material/fluidsystems/brine.hh) expecting a single non-aqueous component defining salinity to be reused for biomineralization with three ions (calcium, sodium, chloride) being assumed to contribute to salinity. + + +The subsequent documentation is structured as follows: + +[[_TOC_]] + + +[@Span1996]: https://aip.scitation.org/doi/abs/10.1063/1.555991 "A new equation of state for carbon dioxide covering the fluid region from the triple-point temperature to 1100 K at pressures up to 800 MPa" + + +## The CO2 tables (`co2tableslaboratory.hh`) + +This file contains the __co2table class__ which forwards to tabulated properties of CO2 according to Span and Wagner 1996. +The real work (creating the tables) is done by some external program by Span and Wagner 1996 which provides the ready-to-use tables. + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../material/co2tableslaboratory.hh))</summary> + + + +```cpp + +#include <assert.h> +namespace Dumux::ICP { +#include "co2valueslaboratory.inc" +}// end namespace Dumux::ICP +``` + + +</details> + + + +## The suspended biomass component (`suspendedbiomass.hh`) + +This file contains the __ component class__ which defines the name and molar mass of suspended biomass + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../material/components/suspendedbiomass.hh))</summary> + + +### Include files + +```cpp +// including the base component +#include <dumux/material/components/base.hh> +``` + +### The suspended biomass component + +```cpp +namespace Dumux::Components { + +// In SuspendedBiomass, we define the properties of the component suspended biomass +template <class Scalar> +class SuspendedBiomass +: public Components::Base<Scalar, SuspendedBiomass<Scalar> > +{ +public: + // the name + static std::string name() + { return "Suspended_Biomass"; } +``` + +### The suspended biomass component's properties + +```cpp + // The molar mass, which is not really defined for suspended biomass. Thus, we read it from params.input or use a default of 1. + // Based on a cell mass of 2.5e-16, the molar mass of cells would be 1.5e8 kg/mol, but such high molar masses would lead to numerical problems. + static Scalar molarMass() + { + Scalar molarMass = getParam<Scalar>("BioCoefficients.SuspendedBiomassMolarMass", 1); + return molarMass; + } +}; + + +} // end namespace Dumux::Components +``` + + +</details> + + + +## The fluid system (`biominsimplechemistry.hh`) + +This file contains the __fluidsystem class__ which defines all functions needed to describe the fluids and their properties, +which are needed to model biomineralization. + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../material/fluidsystems/biominsimplechemistry.hh))</summary> + + +### Include files +<details><summary> Click to show </summary> + +```cpp +#include <dumux/material/idealgas.hh> + +// we include the base fluid system +#include <dumux/material/fluidsystems/base.hh> +// we include the brine adapter adapting component indices to use the brine fluidsystem +#include "icpcomplexsalinitybrine.hh" + +// we include all necessary fluid components +#include <dumux/material/fluidstates/adapter.hh> +#include <dumux/material/components/co2.hh> +#include <dumux/material/components/h2o.hh> +#include <dumux/material/components/tabulatedcomponent.hh> +#include <dumux/material/components/co2tablereader.hh> +#include <dumux/material/components/sodiumion.hh> +#include <dumux/material/components/chlorideion.hh> +#include <dumux/material/components/calciumion.hh> +#include <dumux/material/components/urea.hh> +#include <dumux/material/components/o2.hh> +#include <dumux/material/components/glucose.hh> +#include <examples/biomineralization/material/components/suspendedbiomass.hh> + +// we include brine-co2 and h2o-co2 binary coefficients +#include <dumux/material/binarycoefficients/brine_co2.hh> +#include <dumux/material/binarycoefficients/h2o_o2.hh> +``` + + +```cpp + +#include <dumux/material/fluidsystems/nullparametercache.hh> +#include <dumux/common/valgrind.hh> +#include <dumux/common/exceptions.hh> + +#include <assert.h> +``` + +</details> + +### The fluidsystem class +In the BioMinSimpleChemistryFluid fluid system, we define all functions needed to describe the fluids and their properties accounted for in our simulation. +The simplified biogeochemistry biomineralization fluid system requires the CO2 tables and the H2OType as template parameters. +We enter the namespace Dumux. All Dumux functions and classes are in a namespace Dumux, to make sure they don`t clash with symbols from other libraries you may want to use in conjunction with Dumux. + +```cpp +namespace Dumux::FluidSystems { + +template <class Scalar, + class CO2Table, + class H2OType = Components::TabulatedComponent<Components::H2O<Scalar>> > +class BioMinSimpleChemistryFluid +: public Base<Scalar, BioMinSimpleChemistryFluid<Scalar, CO2Table, H2OType> > +{ + using ThisType = BioMinSimpleChemistryFluid<Scalar, CO2Table, H2OType>; + using Base = Dumux::FluidSystems::Base<Scalar, ThisType>; + using IdealGas = Dumux::IdealGas<Scalar>; +``` + + +#### Component and phase definitions +With the following function we define what phases and components will be used by the fluid system and define the indices used to distinguish phases and components in the course of the simulation. + +```cpp +public: + // We use convenient declarations that we derive from the property system + typedef Components::CO2<Scalar, CO2Table> CO2; + using H2O = H2OType; + // export the underlying brine fluid system for the liquid phase, as brine is used as a "pseudo component" + using Brine = Dumux::FluidSystems::ICPComplexSalinityBrine<Scalar, H2OType>; + using Na = Components::SodiumIon<Scalar>; + using Cl = Components::ChlorideIon<Scalar>; + using Ca = Components::CalciumIon<Scalar>; + using Urea = Components::Urea<Scalar>; + using O2 = Components::O2<Scalar>; + using Glucose = Components::Glucose<Scalar>; + using SuspendedBiomass = Components::SuspendedBiomass<Scalar>; + + // We define the binary coefficents file, which accounts for the interactions of the main fluids in our setup, water/brine and CO2 + using Brine_CO2 = BinaryCoeff::Brine_CO2<Scalar, CO2Table, true>; + + // the type of parameter cache objects. this fluid system does not + // cache anything, so it uses Dumux::NullParameterCache + typedef Dumux::NullParameterCache ParameterCache; + + // We define phase-related indices and properties + static constexpr int numPhases = 2; // liquid and gas phases + static constexpr int wPhaseIdx = 0; // index of the liquid phase + static constexpr int nPhaseIdx = 1; // index of the gas phase + static constexpr int phase0Idx = wPhaseIdx; + static constexpr int phase1Idx = nPhaseIdx; + + // the phase names + static std::string phaseName(int phaseIdx) + { + static std::string name[] = { + "w", + "n" + }; + + assert(0 <= phaseIdx && phaseIdx < numPhases); + return name[phaseIdx]; + } + + // We define component-related indices and properties + static constexpr int numComponents = 9; // H2O, TotalC, Na, Cl, Ca,... + static constexpr int numSecComponents = 6; + + static constexpr int H2OIdx = 0; + static constexpr int BrineIdx = 0; + static constexpr int TCIdx = 1; + static constexpr int wCompIdx = BrineIdx; + static constexpr int nCompIdx = TCIdx; + static constexpr int comp0Idx = wCompIdx; + static constexpr int comp1Idx = nCompIdx; + + static constexpr int NaIdx = 2; + static constexpr int ClIdx = 3; + static constexpr int CaIdx = 4; + static constexpr int UreaIdx = 5; + static constexpr int O2Idx = 6; + static constexpr int GlucoseIdx = 7; + static constexpr int SuspendedBiomassIdx = 8; +``` + + +#### The Brine Adapter +With the brine adapter, we link water and the components sodium, chloride, and calcium to form brine, to be able to use the "brine.hh" fluidsystem expecting only water and a single salt. +Here, we define that the components water, sodium, chloride, and calcium contribute to brine. +The real work is done by the adapter "icpcomplexsalinitybrine.hh". + +```cpp +private: + struct BrineAdapterPolicy + { + using FluidSystem = Brine; + + static constexpr int phaseIdx(int brinePhaseIdx) { return wPhaseIdx; } + static constexpr int compIdx(int brineCompIdx) + { + switch (brineCompIdx) + { + assert(brineCompIdx == Brine::H2OIdx + || brineCompIdx == Brine::NaIdx + || brineCompIdx == Brine::ClIdx + || brineCompIdx == Brine::CaIdx + ); + case Brine::H2OIdx: return H2OIdx; + case Brine::NaIdx: return NaIdx; + case Brine::ClIdx: return ClIdx; + case Brine::CaIdx: return CaIdx; + default: return 0; // this will never be reached, only needed to suppress compiler warning + } + } + }; + + template<class FluidState> + using BrineAdapter = FluidStateAdapter<FluidState, BrineAdapterPolicy>; +``` + +#### Initializing the fluid system + +```cpp +public: + static void init() + { + init(/*startTemp=*/275.15, /*endTemp=*/455.15, /*tempSteps=*/30, + /*startPressure=*/1e4, /*endPressure=*/99e6, /*pressureSteps=*/500); + } + static void init(Scalar startTemp, Scalar endTemp, int tempSteps, + Scalar startPressure, Scalar endPressure, int pressureSteps) + { + std::cout << "Initializing tables for the pure-water properties.\n"; + H2O::init(startTemp, endTemp, tempSteps, + startPressure, endPressure, pressureSteps); + } +``` + +#### The Component-Phase Interactions +In the following, we define the component-phase interactions such as // each component's fugacity coefficient in each phase +and each component's and the phases' main components binary diffusion coefficient in the respective phase. + +```cpp + // The component fugacity coefficients + template <class FluidState> + static Scalar fugacityCoefficient(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx, + int compIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + assert(0 <= compIdx && compIdx < numComponents); + + if (phaseIdx == nPhaseIdx) + // use the fugacity coefficients of an ideal gas. the + // actual value of the fugacity is not relevant, as long + // as the relative fluid compositions are observed, + return 1.0; + + Scalar temperature = fluidState.temperature(phaseIdx); + Scalar pressure = fluidState.pressure(phaseIdx); + if (pressure<0) + { + typedef Dune::FieldVector<Scalar, numComponents> ComponentVector; + ComponentVector moleFractionsw; + ComponentVector massFractionsw; + + for (int compIdx = 0; compIdx<numComponents;++compIdx) + { + moleFractionsw[compIdx] = fluidState.moleFraction(wPhaseIdx,compIdx); + massFractionsw[compIdx] = fluidState.massFraction(wPhaseIdx,compIdx); + } + } + + assert(temperature > 0); + assert(pressure > 0); + + // calulate the equilibrium composition for the given + // temperature and pressure. + Scalar xgH2O, xlH2O; + Scalar xlCO2, xgCO2; + Scalar Xl_Sal = fluidState.massFraction(wPhaseIdx, NaIdx) //Salinity= XNa+XCl+XCa + + fluidState.massFraction(wPhaseIdx, ClIdx) + + fluidState.massFraction(wPhaseIdx, CaIdx); + Brine_CO2::calculateMoleFractions(temperature, + pressure, + Xl_Sal, + /*knownPhaseIdx=*/ -1, + xlCO2, + xgH2O); + + xlCO2 = std::max(0.0, std::min(1.0, xlCO2)); + xgH2O = std::max(0.0, std::min(1.0, xgH2O)); + xlH2O = 1.0 - xlCO2; + xgCO2 = 1.0 - xgH2O; + + // Only H2O, CO2, and O2 in the gas phase + if (compIdx == BrineIdx) { + Scalar phigH2O = 1.0; + return phigH2O * xgH2O / xlH2O; + } + else if (compIdx == TCIdx) + { + Scalar phigCO2 = 1.0; + return phigCO2 * xgCO2 / xlCO2; + } + else if (compIdx == O2Idx) + { + return Dumux::BinaryCoeff::H2O_O2::henry(temperature)/pressure; + } + // All other components are assumed not be present in the gas phase + else + { + return 1e-20; + } + } + + template <class FluidState> + static Scalar diffusionCoefficient(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx, + int compIdx) + { + DUNE_THROW(Dune::NotImplemented, "Diffusion coefficients"); + }; + + // The binary diffusion coefficients of the components and the phases main component + template <class FluidState> + static Scalar binaryDiffusionCoefficient(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx, + int compIIdx, + int compJIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + assert(0 <= compIIdx && compIIdx < numComponents); + assert(0 <= compJIdx && compJIdx < numComponents); + + Scalar temperature = fluidState.temperature(phaseIdx); + Scalar pressure = fluidState.pressure(phaseIdx); + + if (phaseIdx == wPhaseIdx) { + assert(compIIdx == H2OIdx); + Scalar result = 0.0; + if(compJIdx == TCIdx) + result = Brine_CO2::liquidDiffCoeff(temperature, pressure); + else if(compJIdx == O2Idx) + result = Dumux::BinaryCoeff::H2O_O2::liquidDiffCoeff(temperature, pressure); + else //all other components + result = 1.587e-9; //[m²/s] //J. Phys. D: Appl. Phys. 40 (2007) 2769-2776 //old Value from Anozie 1e-9 + + Valgrind::CheckDefined(result); + return result; + } + else { + assert(phaseIdx == nPhaseIdx); + assert(compIIdx == TCIdx); + Scalar result = 0.0; + if(compJIdx == H2OIdx) + result = Brine_CO2::gasDiffCoeff(temperature, pressure); + else if(compJIdx == O2Idx) + result = Dumux::BinaryCoeff::H2O_O2::gasDiffCoeff(temperature, pressure); + else //all other components + result = 0.0; + + Valgrind::CheckDefined(result); + return result; + } + }; +``` + +#### The Fluid Properties +In the following, all functions defining the phase properties are given: +the density, viscosity, enthalpy, thermal conductivities, and heat capacities +of each phase depending on temperature, pressure, and phase composition + +```cpp + // The phase density of the liquid phase is calculated accounting for the impact of solutes in the brine as well as the contribution of CO2. + // For the gas phase, a mixture of water and CO2 is considered, as solutes do not partition into the gas phase. + template <class FluidState> + static Scalar density(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + + const Scalar T = fluidState.temperature(phaseIdx); + + if (phaseIdx == wPhaseIdx) + { + const Scalar pl = fluidState.pressure(phaseIdx); + const Scalar xlCO2 = fluidState.moleFraction(wPhaseIdx, TCIdx); + const Scalar xlH2O = fluidState.moleFraction(wPhaseIdx, H2OIdx); + if(T < 273.15) { + DUNE_THROW(NumericalProblem, + "Liquid density for Brine and CO2 is only " + "defined above 273.15K (is" << T << ")"); + } + if(pl >= 2.5e8) { + DUNE_THROW(NumericalProblem, + "Liquid density for Brine and CO2 is only " + "defined below 250MPa (is" << pl << ")"); + } + + // calling the brine adapter for brine density + Scalar rho_brine = Brine::molarDensity(BrineAdapter<FluidState>(fluidState), Brine::liquidPhaseIdx) + *(H2O::molarMass()*fluidState.moleFraction(wPhaseIdx, H2OIdx) + + Na::molarMass()*fluidState.moleFraction(wPhaseIdx, NaIdx) + + Cl::molarMass()*fluidState.moleFraction(wPhaseIdx, ClIdx) + + Ca::molarMass()*fluidState.moleFraction(wPhaseIdx, CaIdx) + ); + // the density of pure water + Scalar rho_pure = H2O::liquidDensity(T, pl); + //we also use a private helper function to calculate the liquid density of the same amount of CO2 in pure water + Scalar rho_lCO2 = liquidDensityWaterCO2_(T, pl, xlH2O, xlCO2); + // calculating the density contribution of CO2 in pure water + Scalar contribCO2 = rho_lCO2 - rho_pure; + // assuming CO2 increases the density for brine by the same amount as for pure water + return rho_brine + contribCO2; + } + + else if (phaseIdx == nPhaseIdx) + return H2O::gasDensity(T, fluidState.partialPressure(nPhaseIdx, H2OIdx)) + + CO2::gasDensity(T, fluidState.partialPressure(nPhaseIdx, TCIdx)); + else + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + } + + // The phase molar density of the liquid phase is assumed to not change significantly from the molar density of the pure brine. + // For the gas phase, a mixture of water and CO2 is considered, as solutes do not partition into the gas phase. + using Base::molarDensity; + template <class FluidState> + static Scalar molarDensity(const FluidState& fluidState, int phaseIdx) + { + if (phaseIdx == wPhaseIdx) + return Brine::molarDensity(BrineAdapter<FluidState>(fluidState), Brine::liquidPhaseIdx); + else if (phaseIdx == nPhaseIdx) + return H2O::gasMolarDensity(fluidState.temperature(phaseIdx), + fluidState.partialPressure(phaseIdx, H2OIdx)) + + CO2::gasMolarDensity(fluidState.temperature(phaseIdx), + fluidState.partialPressure(phaseIdx, TCIdx)); + else + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + } + + // The phase viscosities are assumed to not change significantly from those of the pure brine for the liquid and pure CO2 for the gas phase + using Base::viscosity; + template <class FluidState> + static Scalar viscosity(const FluidState& fluidState, int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + + if (phaseIdx == wPhaseIdx) + return Brine::viscosity(BrineAdapter<FluidState>(fluidState), Brine::liquidPhaseIdx); + else if (phaseIdx == nPhaseIdx) + { + return CO2::gasViscosity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); + } + else + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + + } +``` + + +</details> + + + +## The brine adapter (`icpcomplexsalinitybrine.hh`) + +This file contains the brineadapter class__ which defines +how to adapt values for communication between +the "full" fluidsystem accounting for 4 components influencing the brine properties +and the "brine" fluidsystem assuming water and a single salt determining the brine properties. + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../material/fluidsystems/icpcomplexsalinitybrine.hh))</summary> + + +### Include files +<details><summary> Click to show includes</summary> +we include all necessary components + +```cpp +#include <dumux/material/fluidsystems/base.hh> +#include <dumux/material/constants.hh> +#include <dumux/material/components/h2o.hh> +#include <dumux/material/components/sodiumion.hh> +#include <dumux/material/components/chlorideion.hh> +#include <dumux/material/components/calciumion.hh> +#include <dumux/material/components/tabulatedcomponent.hh> + +#include <dumux/common/exceptions.hh> + +#include <dumux/io/name.hh> +``` + +</details> + +### The brine adapter class +In ICPComplexSalinityBrine we make the transition from 3 components additional to water contributing to salinity to the single component that is assumed in the brine fluid system. +We enter the namespace Dumux. All Dumux functions and classes are in a namespace Dumux, to make sure they don`t clash with symbols from other libraries you may want to use in conjunction with Dumux. + +```cpp +namespace Dumux::FluidSystems { + +template< class Scalar, class H2OType = Components::TabulatedComponent<Dumux::Components::H2O<Scalar>> > +class ICPComplexSalinityBrine : public Base< Scalar, ICPComplexSalinityBrine<Scalar, H2OType>> +{ + using ThisType = ICPComplexSalinityBrine<Scalar, H2OType>; + using Base = Dumux::FluidSystems::Base<Scalar, ThisType>; + +public: + //! export the involved components + using H2O = H2OType; + using Na = Components::SodiumIon<Scalar>; + using Cl = Components::ChlorideIon<Scalar>; + using Ca = Components::CalciumIon<Scalar>; +``` + + +#### Component and phase definitions +With the following function we define what phases and components will be used by the fluid system and define the indices used to distinguish phases and components in the course of the simulation. + +```cpp + // We use convenient declarations that we derive from the property system. + static constexpr int numPhases = 1; //!< Number of phases in the fluid system + static constexpr int numComponents = 4; //!< Number of components in the fluid system (H2O, Na, Cl, Ca) + + static constexpr int phase0Idx = 0; //!< Index of the first (and only) phase + static constexpr int liquidPhaseIdx = phase0Idx; //!< The one considered phase is liquid + + static constexpr int H2OIdx = 0; //!< index of the water component + static constexpr int NaIdx = 1; //!< index of the Na component + static constexpr int ClIdx = 2; //!< index of the Cl component + static constexpr int CaIdx = 3; //!< index of the Ca component + static constexpr int comp0Idx = H2OIdx; //!< index of the first component + static constexpr int comp1Idx = NaIdx; //!< index of the second component + static constexpr int comp2Idx = ClIdx; //!< index of the third component + static constexpr int comp3Idx = CaIdx; //!< index of the fourth component + + // the fluid phase index + static std::string phaseName(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return IOName::liquidPhase(); + } + + // the miscibility + static constexpr bool isMiscible() + { + return false; + } + + // we do not have a gas phase + static constexpr bool isGas(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return false; + } + + // We need a ideal mixture + static constexpr bool isIdealMixture(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return true; + } + + // phase compressibility + static constexpr bool isCompressible(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return H2O::liquidIsCompressible(); + } + + // no gas, thus no ideal gas + static constexpr bool isIdealGas(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return false; /*we're a liquid!*/ + } +``` + + +#### The Component-Phase Interactions +In the following, we define the component-phase interactions such as // each component's fugacity coefficient in brine +and each component's binary diffusion coefficient with water in brine + +```cpp + // The component fugacity coefficients + template <class FluidState> + static Scalar fugacityCoefficient(const FluidState &fluidState, + int phaseIdx, + int compIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + assert(0 <= compIdx && compIdx < numComponents); + + if (phaseIdx == compIdx) + // We could calculate the real fugacity coefficient of + // the component in the fluid. Probably that's not worth + // the effort, since the fugacity coefficient of the other + // component is infinite anyway... + return 1.0; + return std::numeric_limits<Scalar>::infinity(); + } + + // The binary diffusion coefficients of the components and the phases main component + template <class FluidState> + static Scalar binaryDiffusionCoefficient(const FluidState& fluidState, + int phaseIdx, + int compIIdx, + int compJIdx) + { + if (phaseIdx == liquidPhaseIdx) + { + if (compIIdx > compJIdx) + { + using std::swap; + swap(compIIdx, compJIdx); + } + if (compJIdx == NaIdx || compJIdx == ClIdx || compJIdx == CaIdx) + return 1.587e-9; //[m²/s] //J. Phys. D: Appl. Phys. 40 (2007) 2769-2776 + else + DUNE_THROW(Dune::NotImplemented, "Binary diffusion coefficient of components " + << compIIdx << " and " << compJIdx + << " in phase " << phaseIdx); + } + + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index: " << phaseIdx); + } +``` + + +#### The Fluid (Brine) Properties +In the following, all functions defining the phase properties are given: +the density, viscosity, enthalpy, thermal conductivities, and heat capacities +of each phase depending on temperature, pressure, and phase composition + +```cpp + // The phase density + template <class FluidState> + static Scalar density(const FluidState& fluidState, int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + const Scalar temperature = fluidState.temperature(phaseIdx); + const Scalar pressure = fluidState.pressure(phaseIdx); + const Scalar xNaCl = fluidState.massFraction(phaseIdx, NaIdx) + + fluidState.massFraction(phaseIdx, ClIdx) + + fluidState.massFraction(phaseIdx, CaIdx); + + using std::max; + const Scalar TempC = temperature - 273.15; + const Scalar pMPa = pressure/1.0E6; + const Scalar salinity = max(0.0, xNaCl); + + const Scalar rhow = H2O::liquidDensity(temperature, pressure); + const Scalar density = rhow + 1000*salinity*(0.668 + + 0.44*salinity + + 1.0E-6*(300*pMPa - + 2400*pMPa*salinity + + TempC*(80.0 + + 3*TempC - + 3300*salinity - + 13*pMPa + + 47*pMPa*salinity))); + assert(density > 0.0); + return density; + } + + + + // The phase viscosity + template <class FluidState> + static Scalar viscosity(const FluidState& fluidState, int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + const Scalar temperature = fluidState.temperature(phaseIdx); + const Scalar xNaCl = fluidState.massFraction(phaseIdx, NaIdx) + + fluidState.massFraction(phaseIdx, ClIdx) + + fluidState.massFraction(phaseIdx, CaIdx); + + using std::pow; + using std::exp; + using std::max; + const Scalar T = max(temperature, 275.0); + const Scalar salinity = max(0.0, xNaCl); + + const Scalar T_C = T - 273.15; + const Scalar A = ((0.42*pow((pow(salinity, 0.8)-0.17), 2)) + 0.045)*pow(T_C, 0.8); + const Scalar mu_brine = 0.1 + (0.333*salinity) + (1.65+(91.9*salinity*salinity*salinity))*exp(-A); // [cP] + assert(mu_brine > 0.0); + return mu_brine/1000.0; // [Pa·s] + } +``` + + +</details> + + +| [:arrow_left: Back to the main documentation](../README.md) | [:arrow_left: Go back to part 3](setup.md) | [:arrow_right: Continue with part 5](solidmaterial.md) | +|---|---|---:| + diff --git a/examples/biomineralization/doc/fluidmaterial_intro.md b/examples/biomineralization/doc/fluidmaterial_intro.md new file mode 100644 index 0000000000..84c360cd39 --- /dev/null +++ b/examples/biomineralization/doc/fluidmaterial_intro.md @@ -0,0 +1,42 @@ +# Biomineralization - Fluids + +The main idea of biomineralization revolves around +biologically-induced mineral precipitation. +I our example, it is about precipitation of calcite +due to urea hydrolysis. +The resulting overall reaction equation is: + +```math +\mathrm{CO(NH_2)_2} + 2\mathrm{H_2O} + \mathrm{Ca^{2+}} \xrightarrow{urease} +2\mathrm{NH_{4}^{+}} + \mathrm{CaCO_{3}} \downarrow. +``` + +To describe the processes, the minimum set of components is: +water (w), dissolved inorganic carbon (C<sub>tot</sub>), +sodium (Na), chloride (Cl), calcium (Ca), urea (u), glucose as a substrate (s), oxygen (O<sub>2</sub>), and suspended biomass (b), +as well as the solid components biofilm and calcite. +Thus, there are many components involved and keeping track of the components and their interactions, +necessitates a sophisticated handling. +This is why the material folder in this example is both separated from the regular material folder in dumux/dumux/material +and also documented separately. +For further specialization, the overview over the material subfolder is split into solid and fluid, this description considering the fluids. + +## Fluids in the folder `material` + +As this example is about biomineralization involving many components with complex inteactions, some specific fluid material files are necessary. +A CO_2-Table file provides tabulated CO_2 properties according to @Span1996 in `material/co2tableslaboratory.hh` +In the component subfolder, `material/components/suspendedbiomass.hh` defines the component suspended biomass, which is the mobile form of biomass being transported suspended in the aqueous fluid phase. +In the fluidsystem subfolder, the biomineralization fluidsystem `material/fluidsystems/biominsimplechemistry.hh` as well as +the complex salinity brine adapter `material/fluidsystems/icpcomplexsalinitybrine.hh` can be found. +The biomineralization fluidsystem `material/fluidsystems/biominsimplechemistry.hh` +contains the fluid related properties and the interactions of the components in the fluids. +The complex salinity brine adapter `material/fluidsystems/icpcomplexsalinitybrine.hh` +adapts the brine fluidsystem (dumux/dumux/material/fluidsystems/brine.hh) expecting a single non-aqueous component defining salinity to be reused for biomineralization with three ions (calcium, sodium, chloride) being assumed to contribute to salinity. + + +The subsequent documentation is structured as follows: + +[[_TOC_]] + + +[@Span1996]: https://aip.scitation.org/doi/abs/10.1063/1.555991 "A new equation of state for carbon dioxide covering the fluid region from the triple-point temperature to 1100 K at pressures up to 800 MPa" diff --git a/examples/biomineralization/doc/mainfile.md b/examples/biomineralization/doc/mainfile.md new file mode 100644 index 0000000000..3fbcc53d68 --- /dev/null +++ b/examples/biomineralization/doc/mainfile.md @@ -0,0 +1,330 @@ +<!-- Important: This file has been automatically generated by generate_example_docs.py. Do not edit this file directly! --> + + +| [:arrow_left: Back to the main documentation](../README.md) | [:arrow_left: Go back to part 1](modelconcept.md) | [:arrow_right: Continue with part 3](setup.md) | +|---|---|---:| + +# Main file + +The main file features a time loo with check points to assure the correct timing of the injections matching an experimental setup (see [@Hommel2016], Section 4.2 under the name _column experiment D1_) +The timing of the injections is stored in an additional input file `injections_checkpoints.dat`, +which is read by `main.cc` to set the check points in the time loop. +The number of check points reached is counted and passed on to `problem.hh`, so that `problem.hh` can determine the appropriate injection type. + +Additionally, there is an output of the porosity-dependent permeability. + +The subsequent file documentation is structured as follows: + +[[_TOC_]] + +[@Hommel2016]: https://elib.uni-stuttgart.de/handle/11682/8787 "Modelling biogeochemical and mass transport processes in the subsurface: investigation of microbially induced calcite precipitation" + + +## The main file +This files contains the main program flow for the biomineralization example. Here we can see the programme sequence and how the system is solved using newton's method. + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../main.cc))</summary> + + +### Included header files +<details> +These are DUNE helper classes related to parallel computations + +```cpp +#include <dune/common/parallel/mpihelper.hh> +``` + +The following headers include functionality related to property definition or retrieval, as well as +the retrieval of input parameters specified in the input file or via the command line. + +```cpp +#include <dumux/common/properties.hh> +#include <dumux/common/parameters.hh> +``` + +The follwoing files contain the nonlinear Newtown method, the linear solver and the assembler + +```cpp +#include <dumux/nonlinear/newtonsolver.hh> +#include <dumux/linear/amgbackend.hh> +#include <dumux/assembly/fvassembler.hh> +#include <dumux/assembly/diffmethod.hh> +``` + +The following class provides a convenient way of writing of dumux simulation results to VTK format. + +```cpp +#include <dumux/io/vtkoutputmodule.hh> +``` + +The gridmanager constructs a grid from the information in the input or grid file. There is a specification for the different supported grid managers. +Many different Dune grid implementations are supported, of which a list can be found +in `gridmanager.hh`. + +```cpp +#include <dumux/io/grid/gridmanager_yasp.hh> +``` + +We include the problem file which defines initial and boundary conditions to describe our example problem +remove #include "problem.hh" + +```cpp +#include "properties.hh" +``` + +</details> + +### The main function +We will now discuss the main program flow implemented within the `main` function. +At the beginning of each program using Dune, an instance `Dune::MPIHelper` has to +be created. Moreover, we parse the run-time arguments from the command line and the +input file: + +```cpp +int main(int argc, char** argv) try +{ + using namespace Dumux; + + // initialize MPI, finalize is done automatically on exit + const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); + + // parse command line arguments and input file + Parameters::init(argc, argv); +``` + +For convenience we define the type tag for this problem. +The type tags contain all the properties that are needed to run the simulations. + +```cpp + using TypeTag = Properties::TTag::MICPColumnSimpleChemistry; +``` + +### Step 1: Create the grid +The `GridManager` class creates the grid from information given in the input file. +This can either be a grid file, or in the case of structured grids, one can specify the coordinates +of the corners of the grid and the number of cells to be used to discretize each spatial direction. The latter is the case for this example. + +```cpp + GridManager<GetPropType<TypeTag, Properties::Grid>> gridManager; + gridManager.init(); + + // we compute on the leaf grid view + const auto& leafGridView = gridManager.grid().leafGridView(); +``` + +### Step 2: Setting up the problem +We create and initialize the finite volume grid geometry, the problem, the linear system, including the jacobian matrix, the residual and the solution vector and the gridvariables. +We need the finite volume geometry to build up the subcontrolvolumes (scv) and subcontrolvolume faces (scvf) for each element of the grid partition. + +```cpp + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + auto gridGeometry = std::make_shared<GridGeometry>(leafGridView); + gridGeometry->update(); +``` + +We now instantiate the problem, in which we define the boundary and initial conditions. + +```cpp + using Problem = GetPropType<TypeTag, Properties::Problem>; + auto problem = std::make_shared<Problem>(gridGeometry); +``` + +get some time loop parameters + +```cpp + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); + const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); + const auto dt = getParam<Scalar>("TimeLoop.DtInitial"); +``` + +We initialize the solution vector + +```cpp + using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + SolutionVector x; + problem->applyInitialSolution(x); + auto xOld = x; +``` + +on the basis of this solution, we initialize the grid variables + +```cpp + using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; + auto gridVariables = std::make_shared<GridVariables>(problem, gridGeometry); + gridVariables->init(x); +``` + +We intialize the vtk output module. Each model has a predefined model specific output with relevant parameters for that model. + +```cpp + VtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name()); + using VelocityOutput = GetPropType<TypeTag, Properties::VelocityOutput>; + vtkWriter.addVelocityOutput(std::make_shared<VelocityOutput>(*gridVariables)); + GetPropType<TypeTag, Properties::IOFields>::initOutputModule(vtkWriter); //!< Add model specific output fields + //we add permeability as a specific output + vtkWriter.addField(problem->getPermeability(), "Permeability"); + //We update the output fields before write + problem->updateVtkOutput(x); + vtkWriter.write(0.0); +``` + +We instantiate the time loop and define an episode index to keep track of the the actual episode number + +```cpp + int episodeIdx = 0; + //We set the initial episodeIdx in the problem to zero + problem->setEpisodeIdx(episodeIdx); + //We set the time loop with episodes (check points) + auto timeLoop = std::make_shared<CheckPointTimeLoop<Scalar>>(0.0, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); +``` + +### Step 3 Setting episodes specified from file +In this example we want to specify the injected reactant solutions at certain times. +This is specified in an external file injections_checkpoints.dat. +Within the following code block, the parameter file read and the time for the injection are extracted. +Based on that, the checkpoints for the simulation are set. + +```cpp + //We use a time loop with episodes if an injection parameter file is specified in the input + if (hasParam("Injection.NumInjections")) + { + //We first read the times of the checkpoints from the injection file + const auto injectionCheckPoints = readFileToContainer<std::vector<double>>("injection_checkpoints.dat"); + + // We set the time loop with episodes of various lengths as specified in the injection file + // set the episode ends /check points: + timeLoop->setCheckPoint(injectionCheckPoints); + + // We also set the initial episodeIdx in the problem to zero, as in the problem the boundary conditions depend on the episode. + problem->setEpisodeIdx(episodeIdx); + } + + // If nothing specified, we do not need to use episodes + else + { + // In this case, we set the time loop with one big episodes + timeLoop->setCheckPoint(tEnd); + } +``` + +### Step 4 solving the instationary problem +We create and initialize the assembler with a time loop for the transient problem. +Within the time loop, we will use this assembler in each time step to assemble the linear system. +Additionally the linear and non-linear solvers are set + +```cpp + using Assembler = FVAssembler<TypeTag, DiffMethod::numeric>; + auto assembler = std::make_shared<Assembler>(problem, gridGeometry, gridVariables, timeLoop, xOld); + + //We set the linear solver + using LinearSolver = Dumux::ILU0BiCGSTABBackend; + auto linearSolver = std::make_shared<LinearSolver>(); + + //We set the non-linear solver + using NewtonSolver = NewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); +``` + +#### The time loop +We start the time loop and solve a new time step as long as `tEnd` is not reached. In every time step, +the problem is assembled and solved, the solution is updated, and when a checkpoint is reached the solution +is written to a new vtk file. In addition, statistics related to CPU time, the current simulation time +and the time step sizes used is printed to the terminal. + +```cpp + timeLoop->start(); do + { + // We set the time and time step size to be used in the problem + problem->setTime( timeLoop->time() + timeLoop->timeStepSize() ); + problem->setTimeStepSize( timeLoop->timeStepSize() ); + + // Solve the linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + // Update the old solution with the one computed in this time step and move to the next one + xOld = x; + gridVariables->advanceTimeStep(); + timeLoop->advanceTimeStep(); + + // We update the output fields before write + problem->updateVtkOutput(x); + + // We write vtk output on checkpoints or every 20th timestep + if (timeLoop->timeStepIndex() % 20 == 0 || timeLoop->isCheckPoint()) + { + // update the output fields before write + problem->updateVtkOutput(x); + + // write vtk output + vtkWriter.write(timeLoop->time()); + } + // We report statistics of this time step + timeLoop->reportTimeStep(); + + //If episodes/check points are used, we count episodes and update the episode indices in the main file and the problem. + if (hasParam("Injection.NumInjections") || hasParam("TimeLoop.EpisodeLength")) + { + if (timeLoop->isCheckPoint()) + { + episodeIdx++; + problem->setEpisodeIdx(episodeIdx); + } + } + + // set the new time step size that is suggested by the newton solver + timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); + + } while (!timeLoop->finished()); + timeLoop->finalize(leafGridView.comm()); +``` + + +```cpp + + if (mpiHelper.rank() == 0) + Parameters::print(); + + return 0; +} +``` + +### Exception handling +In this part of the main file we catch and print possible exceptions that could +occur during the simulation. +<details><summary> Click to show error handler</summary> + +```cpp +// errors related to run-time parameters +catch (const Dumux::ParameterException &e) +{ + std::cerr << std::endl << e << " ---> Abort!" << std::endl; + return 1; +} +catch (const Dune::DGFException & e) +{ + std::cerr << "DGF exception thrown (" << e << + "). Most likely, the DGF file name is wrong " + "or the DGF file is corrupted, " + "e.g. missing hash at end of file or wrong number (dimensions) of entries." + << " ---> Abort!" << std::endl; + return 2; +} +catch (const Dune::Exception &e) +{ + std::cerr << "Dune reported error: " << e << " ---> Abort!" << std::endl; + return 3; +} +``` + +</details> + +</details> + + +| [:arrow_left: Back to the main documentation](../README.md) | [:arrow_left: Go back to part 1](modelconcept.md) | [:arrow_right: Continue with part 3](setup.md) | +|---|---|---:| + diff --git a/examples/biomineralization/doc/mainfile_intro.md b/examples/biomineralization/doc/mainfile_intro.md new file mode 100644 index 0000000000..c1435eb899 --- /dev/null +++ b/examples/biomineralization/doc/mainfile_intro.md @@ -0,0 +1,14 @@ +# Main file + +The main file features a time loo with check points to assure the correct timing of the injections matching an experimental setup (see [@Hommel2016], Section 4.2 under the name _column experiment D1_) +The timing of the injections is stored in an additional input file `injections_checkpoints.dat`, +which is read by `main.cc` to set the check points in the time loop. +The number of check points reached is counted and passed on to `problem.hh`, so that `problem.hh` can determine the appropriate injection type. + +Additionally, there is an output of the porosity-dependent permeability. + +The subsequent file documentation is structured as follows: + +[[_TOC_]] + +[@Hommel2016]: https://elib.uni-stuttgart.de/handle/11682/8787 "Modelling biogeochemical and mass transport processes in the subsurface: investigation of microbially induced calcite precipitation" diff --git a/examples/biomineralization/doc/material.md b/examples/biomineralization/doc/material.md new file mode 100644 index 0000000000..cf9a24e811 --- /dev/null +++ b/examples/biomineralization/doc/material.md @@ -0,0 +1,990 @@ +<!-- Important: This file has been automatically generated by generate_example_docs.py. Do not edit this file directly! --> + + +| [:arrow_left: Back to the main documentation](../README.md) | [:arrow_left: Go back to part 2](setup.md) | +|---|---:| + +# Biomineralization + +The main idea of biomineralization revolves around +biologically-induced mineral precipitation. +I our example, it is about precipitation of calcite +due to urea hydrolysis. +The resulting overall reaction equation is: + +```math +\mathrm{CO(NH_2)_2} + 2\mathrm{H_2O} + \mathrm{Ca^{2+}} \xrightarrow{urease} +2\mathrm{NH_{4}^{+}} + \mathrm{CaCO_{3}} \downarrow. +``` + +To describe the processes, the minimum set of components is: +water (w), dissolved inorganic carbon (C<sub>tot</sub>), +sodium (Na), chloride (Cl), calcium (Ca), urea (u), glucose as a substrate (s), oxygen (O<sub>2</sub>), and suspended biomass (b), +as well as the solid components biofilm and calcite. +Thus, there are many components involved and keeping track of the components and their interactions, +necessitates a sophisticated handling. +This is why the material folder in this example is both separated from the regular material folder in dumux/dumux/material +and also documented separately. + +## The folder `material` (fluid- and solidsystems) + +This material folder of the biomineralization example contains: +A CO<sub>2</sub>-Tables file providing tabulated CO<sub>2</sub> properties according to [@Span1996] `material/co2tableslaboratory.hh`; +a component subfolder, containing the special components biofilm `material/components/biofilm.hh` and suspended biomass `material/components/suspendedbiomass.hh`; +a fluidsystems subfolder, containing the (simplified) biomineralization fluidsystem `material/fluidsystems/biominsimplechemistry.hh` and a brine adapter to be able to use the generic brine fluidsystem with several salts while it assumes a single salt `material/fluidsystems/icpcomplexsalinitybrine.hh`; +a solidsystem subfolder, containing the biomineralization solid system `material/solidsystems/biominsolids.hh`. + +The subsequent documentation is structured as follows: + +[[_TOC_]] + + +[@Span1996]: https://aip.scitation.org/doi/abs/10.1063/1.555991 "A new equation of state for carbon dioxide covering the fluid region from the triple-point temperature to 1100 K at pressures up to 800 MPa" + + +## The CO2 tables (`co2tableslaboratory.hh`) + +This file contains the __ co2table class__ which forwards to tabulated properties of CO2 according to Span and Wagner 1996. +The real work (creating the tables) is done by some external program by Span and Wagner 1996 which provides the ready-to-use tables. + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../material/co2tableslaboratory.hh))</summary> + + + +```cpp + +#include <assert.h> +namespace Dumux::ICP { +#include "co2valueslaboratory.inc" +}// end namespace Dumux::ICP +``` + + +</details> + + + +## The biofilm component (`biofilm.hh`) + +This file contains the __solid component class__ which defines the name, molar mass and density of biofilm + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../material/components/biofilm.hh))</summary> + + +### Include files + +```cpp +// including the base and the generic solid component +#include <dumux/material/components/base.hh> +#include <dumux/material/components/solid.hh> +``` + +### The biofilm component + +```cpp +namespace Dumux::Components { + +// In Biofilm, we define the properties of the solid component biofilm +template <class Scalar> +class Biofilm +: public Components::Base<Scalar, Biofilm<Scalar> > +, public Components::Solid<Scalar, Biofilm<Scalar> > +{ +public: + // the name + static std::string name() + { return "Biofilm"; } +``` + +### The biofilm component's properties + +```cpp + // The molar mass, which is not really defined for biofilm. Thus, we read it from params.input or use a default of 1. + // Based on a cell mass of 2.5e-16, the molar mass of cells would be 1.5e8 kg/mol, but biofilms are more than just cells and such high molar masses would lead to numerical problems. + static Scalar molarMass() + { + Scalar molarMass = getParam<Scalar>("BioCoefficients.BiofilmMolarMass", 1); + return molarMass; + } + + // The density, or rather the dry density (dry biomass/wet volume), most of biofilm is water. + // It is typically highly variable for different biofilms, thus we read it from params.input or use the default value of 10 kg/m^3 + static Scalar solidDensity(Scalar temperature) + { + Scalar rho = getParam<Scalar>("BioCoefficients.BiofilmDensity", 10); + return rho; + } +}; + +} // end namespace Dumux::Components +``` + + +</details> + + + +## The suspended biomass component (`suspendedbiomass.hh`) + +This file contains the __ component class__ which defines the name and molar mass of suspended biomass + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../material/components/suspendedbiomass.hh))</summary> + + +### Include files + +```cpp +// including the base component +#include <dumux/material/components/base.hh> +``` + +### The suspended biomass component + +```cpp +namespace Dumux::Components { + +// In SuspendedBiomass, we define the properties of the component suspended biomass +template <class Scalar> +class SuspendedBiomass +: public Components::Base<Scalar, SuspendedBiomass<Scalar> > +{ +public: + // the name + static std::string name() + { return "Suspended_Biomass"; } +``` + +### The suspended biomass component's properties + +```cpp + // The molar mass, which is not really defined for suspended biomass. Thus, we read it from params.input or use a default of 1. + // Based on a cell mass of 2.5e-16, the molar mass of cells would be 1.5e8 kg/mol, but such high molar masses would lead to numerical problems. + static Scalar molarMass() + { + Scalar molarMass = getParam<Scalar>("BioCoefficients.SuspendedBiomassMolarMass", 1); + return molarMass; + } +}; + + +} // end namespace Dumux::Components +``` + + +</details> + + + +## The fluid system (`biominsimplechemistry.hh`) + +This file contains the __fluidsystem class__ which defines all functions needed to describe the fluids and their properties, +which are needed to model biomineralization. + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../material/fluidsystems/biominsimplechemistry.hh))</summary> + + +### Include files +<details><summary> Click to show </summary> + +```cpp +#include <dumux/material/idealgas.hh> + +// we include the base fluid system +#include <dumux/material/fluidsystems/base.hh> +// we include the brine adapter adapting component indices to use the brine fluidsystem +#include "icpcomplexsalinitybrine.hh" + +// we include all necessary fluid components +#include <dumux/material/fluidstates/adapter.hh> +#include <dumux/material/components/co2.hh> +#include <dumux/material/components/h2o.hh> +#include <dumux/material/components/tabulatedcomponent.hh> +#include <dumux/material/components/co2tablereader.hh> +#include <dumux/material/components/sodiumion.hh> +#include <dumux/material/components/chlorideion.hh> +#include <dumux/material/components/calciumion.hh> +#include <dumux/material/components/urea.hh> +#include <dumux/material/components/o2.hh> +#include <dumux/material/components/glucose.hh> +#include <examples/biomineralization/material/components/suspendedbiomass.hh> + +// we include brine-co2 and h2o-co2 binary coefficients +#include <dumux/material/binarycoefficients/brine_co2.hh> +#include <dumux/material/binarycoefficients/h2o_o2.hh> +``` + + +```cpp + +#include <dumux/material/fluidsystems/nullparametercache.hh> +#include <dumux/common/valgrind.hh> +#include <dumux/common/exceptions.hh> + +#include <assert.h> +``` + +</details> + +### The fluidsystem class +In the BioMinSimpleChemistryFluid fluid system, we define all functions needed to describe the fluids and their properties accounted for in our simulation. +The simplified biogeochemistry biomineralization fluid system requires the CO2 tables and the H2OType as template parameters. +We enter the namespace Dumux. All Dumux functions and classes are in a namespace Dumux, to make sure they don`t clash with symbols from other libraries you may want to use in conjunction with Dumux. + +```cpp +namespace Dumux::FluidSystems { + +template <class Scalar, + class CO2Table, + class H2OType = Components::TabulatedComponent<Components::H2O<Scalar>> > +class BioMinSimpleChemistryFluid +: public Base<Scalar, BioMinSimpleChemistryFluid<Scalar, CO2Table, H2OType> > +{ + using ThisType = BioMinSimpleChemistryFluid<Scalar, CO2Table, H2OType>; + using Base = Dumux::FluidSystems::Base<Scalar, ThisType>; + using IdealGas = Dumux::IdealGas<Scalar>; +``` + + +#### Component and phase definitions +With the following function we define what phases and components will be used by the fluid system and define the indices used to distinguish phases and components in the course of the simulation. + +```cpp +public: + // We use convenient declarations that we derive from the property system + typedef Components::CO2<Scalar, CO2Table> CO2; + using H2O = H2OType; + // export the underlying brine fluid system for the liquid phase, as brine is used as a "pseudo component" + using Brine = Dumux::FluidSystems::ICPComplexSalinityBrine<Scalar, H2OType>; + using Na = Components::SodiumIon<Scalar>; + using Cl = Components::ChlorideIon<Scalar>; + using Ca = Components::CalciumIon<Scalar>; + using Urea = Components::Urea<Scalar>; + using O2 = Components::O2<Scalar>; + using Glucose = Components::Glucose<Scalar>; + using SuspendedBiomass = Components::SuspendedBiomass<Scalar>; + + // We define the binary coefficents file, which accounts for the interactions of the main fluids in our setup, water/brine and CO2 + using Brine_CO2 = BinaryCoeff::Brine_CO2<Scalar, CO2Table, true>; + + // the type of parameter cache objects. this fluid system does not + // cache anything, so it uses Dumux::NullParameterCache + typedef Dumux::NullParameterCache ParameterCache; + + // We define phase-related indices and properties + static constexpr int numPhases = 2; // liquid and gas phases + static constexpr int wPhaseIdx = 0; // index of the liquid phase + static constexpr int nPhaseIdx = 1; // index of the gas phase + static constexpr int phase0Idx = wPhaseIdx; + static constexpr int phase1Idx = nPhaseIdx; + + // the phase names + static std::string phaseName(int phaseIdx) + { + static std::string name[] = { + "w", + "n" + }; + + assert(0 <= phaseIdx && phaseIdx < numPhases); + return name[phaseIdx]; + } + + // We define component-related indices and properties + static constexpr int numComponents = 9; // H2O, TotalC, Na, Cl, Ca,... + static constexpr int numSecComponents = 6; + + static constexpr int H2OIdx = 0; + static constexpr int BrineIdx = 0; + static constexpr int TCIdx = 1; + static constexpr int wCompIdx = BrineIdx; + static constexpr int nCompIdx = TCIdx; + static constexpr int comp0Idx = wCompIdx; + static constexpr int comp1Idx = nCompIdx; + + static constexpr int NaIdx = 2; + static constexpr int ClIdx = 3; + static constexpr int CaIdx = 4; + static constexpr int UreaIdx = 5; + static constexpr int O2Idx = 6; + static constexpr int GlucoseIdx = 7; + static constexpr int SuspendedBiomassIdx = 8; +``` + + +#### The Brine Adapter +With the brine adapter, we link water and the components sodium, chloride, and calcium to form brine, to be able to use the "brine.hh" fluidsystem expecting only water and a single salt. +Here, we define that the components water, sodium, chloride, and calcium contribute to brine. +The real work is done by the adapter "icpcomplexsalinitybrine.hh". + +```cpp +private: + struct BrineAdapterPolicy + { + using FluidSystem = Brine; + + static constexpr int phaseIdx(int brinePhaseIdx) { return wPhaseIdx; } + static constexpr int compIdx(int brineCompIdx) + { + switch (brineCompIdx) + { + assert(brineCompIdx == Brine::H2OIdx + || brineCompIdx == Brine::NaIdx + || brineCompIdx == Brine::ClIdx + || brineCompIdx == Brine::CaIdx + ); + case Brine::H2OIdx: return H2OIdx; + case Brine::NaIdx: return NaIdx; + case Brine::ClIdx: return ClIdx; + case Brine::CaIdx: return CaIdx; + default: return 0; // this will never be reached, only needed to suppress compiler warning + } + } + }; + + template<class FluidState> + using BrineAdapter = FluidStateAdapter<FluidState, BrineAdapterPolicy>; +``` + +#### Initializing the fluid system + +```cpp +public: + static void init() + { + init(/*startTemp=*/275.15, /*endTemp=*/455.15, /*tempSteps=*/30, + /*startPressure=*/1e4, /*endPressure=*/99e6, /*pressureSteps=*/500); + } + static void init(Scalar startTemp, Scalar endTemp, int tempSteps, + Scalar startPressure, Scalar endPressure, int pressureSteps) + { + std::cout << "Initializing tables for the pure-water properties.\n"; + H2O::init(startTemp, endTemp, tempSteps, + startPressure, endPressure, pressureSteps); + } +``` + +#### The Component-Phase Interactions +In the following, we define the component-phase interactions such as // each component's fugacity coefficient in each phase +and each component's and the phases' main components binary diffusion coefficient in the respective phase. + +```cpp + // The component fugacity coefficients + template <class FluidState> + static Scalar fugacityCoefficient(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx, + int compIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + assert(0 <= compIdx && compIdx < numComponents); + + if (phaseIdx == nPhaseIdx) + // use the fugacity coefficients of an ideal gas. the + // actual value of the fugacity is not relevant, as long + // as the relative fluid compositions are observed, + return 1.0; + + Scalar temperature = fluidState.temperature(phaseIdx); + Scalar pressure = fluidState.pressure(phaseIdx); + if (pressure<0) + { + typedef Dune::FieldVector<Scalar, numComponents> ComponentVector; + ComponentVector moleFractionsw; + ComponentVector massFractionsw; + + for (int compIdx = 0; compIdx<numComponents;++compIdx) + { + moleFractionsw[compIdx] = fluidState.moleFraction(wPhaseIdx,compIdx); + massFractionsw[compIdx] = fluidState.massFraction(wPhaseIdx,compIdx); + } + } + + assert(temperature > 0); + assert(pressure > 0); + + // calulate the equilibrium composition for the given + // temperature and pressure. TODO: calculateMoleFractions() + // could use some cleanup. + Scalar xgH2O, xlH2O; + Scalar xlCO2, xgCO2; + Scalar Xl_Sal = fluidState.massFraction(wPhaseIdx, NaIdx) //Salinity= XNa+XCl+XCa + + fluidState.massFraction(wPhaseIdx, ClIdx) + + fluidState.massFraction(wPhaseIdx, CaIdx); + Brine_CO2::calculateMoleFractions(temperature, + pressure, + Xl_Sal, + /*knownPhaseIdx=*/ -1, + xlCO2, + xgH2O); + + xlCO2 = std::max(0.0, std::min(1.0, xlCO2)); + xgH2O = std::max(0.0, std::min(1.0, xgH2O)); + xlH2O = 1.0 - xlCO2; + xgCO2 = 1.0 - xgH2O; + + // Only H2O, CO2, and O2 in the gas phase + if (compIdx == BrineIdx) { + Scalar phigH2O = 1.0; + return phigH2O * xgH2O / xlH2O; + } + else if (compIdx == TCIdx) + { + Scalar phigCO2 = 1.0; + return phigCO2 * xgCO2 / xlCO2; + } + else if (compIdx == O2Idx) + { + return Dumux::BinaryCoeff::H2O_O2::henry(temperature)/pressure; + } + // All other components are assumed not be present in the gas phase + else + { + return 1e-20; + } + } + + template <class FluidState> + static Scalar diffusionCoefficient(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx, + int compIdx) + { + DUNE_THROW(Dune::NotImplemented, "Diffusion coefficients"); + }; + + // The binary diffusion coefficients of the components and the phases main component + template <class FluidState> + static Scalar binaryDiffusionCoefficient(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx, + int compIIdx, + int compJIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + assert(0 <= compIIdx && compIIdx < numComponents); + assert(0 <= compJIdx && compJIdx < numComponents); + + Scalar temperature = fluidState.temperature(phaseIdx); + Scalar pressure = fluidState.pressure(phaseIdx); + + if (phaseIdx == wPhaseIdx) { + assert(compIIdx == H2OIdx); + Scalar result = 0.0; + if(compJIdx == TCIdx) + result = Brine_CO2::liquidDiffCoeff(temperature, pressure); + else if(compJIdx == O2Idx) //TODO Test O2 diffusion coeff from binarycoeff. + result = Dumux::BinaryCoeff::H2O_O2::liquidDiffCoeff(temperature, pressure); + else //all other components + result = 1.587e-9; //[m²/s] //J. Phys. D: Appl. Phys. 40 (2007) 2769-2776 //old Value from Anozie 1e-9 + + Valgrind::CheckDefined(result); + return result; + } + else { + assert(phaseIdx == nPhaseIdx); + assert(compIIdx == TCIdx); + Scalar result = 0.0; + if(compJIdx == H2OIdx) //TODO Test H2O diffusion coeff from binarycoeff. + result = Brine_CO2::gasDiffCoeff(temperature, pressure); +// result = 1e-5; + else if(compJIdx == O2Idx) //TODO Test O2 diffusion coeff from binarycoeff. + result = Dumux::BinaryCoeff::H2O_O2::gasDiffCoeff(temperature, pressure); + else //all other components + result = 0.0; + + Valgrind::CheckDefined(result); + return result; + } + }; +``` + +#### The Fluid Properties +In the following, all functions defining the phase properties are given: +the density, viscosity, enthalpy, thermal conductivities, and heat capacities +of each phase depending on temperature, pressure, and phase composition + +```cpp + // The phase density of the liquid phase is calculated accounting for the impact of solutes in the brine as well as the contribution of CO2. + // For the gas phase, a mixture of water and CO2 is considered, as solutes do not partition into the gas phase. + template <class FluidState> + static Scalar density(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + + const Scalar T = fluidState.temperature(phaseIdx); + + if (phaseIdx == wPhaseIdx) + { + const Scalar pl = fluidState.pressure(phaseIdx); + const Scalar xlCO2 = fluidState.moleFraction(wPhaseIdx, TCIdx); + const Scalar xlH2O = fluidState.moleFraction(wPhaseIdx, H2OIdx); + if(T < 273.15) { + DUNE_THROW(NumericalProblem, + "Liquid density for Brine and CO2 is only " + "defined above 273.15K (is" << T << ")"); + } + if(pl >= 2.5e8) { + DUNE_THROW(NumericalProblem, + "Liquid density for Brine and CO2 is only " + "defined below 250MPa (is" << pl << ")"); + } + + // calling the brine adapter for brine density + Scalar rho_brine = Brine::molarDensity(BrineAdapter<FluidState>(fluidState), Brine::liquidPhaseIdx) + *(H2O::molarMass()*fluidState.moleFraction(wPhaseIdx, H2OIdx) + + Na::molarMass()*fluidState.moleFraction(wPhaseIdx, NaIdx) + + Cl::molarMass()*fluidState.moleFraction(wPhaseIdx, ClIdx) + + Ca::molarMass()*fluidState.moleFraction(wPhaseIdx, CaIdx) + ); + // the density of pure water + Scalar rho_pure = H2O::liquidDensity(T, pl); + //we also use a private helper function to calculate the liquid density of the same amount of CO2 in pure water + Scalar rho_lCO2 = liquidDensityWaterCO2_(T, pl, xlH2O, xlCO2); + // calculating the density contribution of CO2 in pure water + Scalar contribCO2 = rho_lCO2 - rho_pure; + // assuming CO2 increases the density for brine by the same amount as for pure water + return rho_brine + contribCO2; + } + + else if (phaseIdx == nPhaseIdx) + return H2O::gasDensity(T, fluidState.partialPressure(nPhaseIdx, H2OIdx)) + + CO2::gasDensity(T, fluidState.partialPressure(nPhaseIdx, TCIdx)); + else + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + } + + // The phase molar density of the liquid phase is assumed to not change significantly from the molar density of the pure brine. + // For the gas phase, a mixture of water and CO2 is considered, as solutes do not partition into the gas phase. + using Base::molarDensity; + template <class FluidState> + static Scalar molarDensity(const FluidState& fluidState, int phaseIdx) + { + if (phaseIdx == wPhaseIdx) + return Brine::molarDensity(BrineAdapter<FluidState>(fluidState), Brine::liquidPhaseIdx); + else if (phaseIdx == nPhaseIdx) + return H2O::gasMolarDensity(fluidState.temperature(phaseIdx), + fluidState.partialPressure(phaseIdx, H2OIdx)) + + CO2::gasMolarDensity(fluidState.temperature(phaseIdx), + fluidState.partialPressure(phaseIdx, TCIdx)); + else + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + } + + // The phase viscosities are assumed to not change significantly from those of the pure brine for the liquid and pure CO2 for the gas phase + using Base::viscosity; + template <class FluidState> + static Scalar viscosity(const FluidState& fluidState, int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + + if (phaseIdx == wPhaseIdx) + return Brine::viscosity(BrineAdapter<FluidState>(fluidState), Brine::liquidPhaseIdx); + else if (phaseIdx == nPhaseIdx) + { + return CO2::gasViscosity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); + } + else + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + + } +``` + + +</details> + + + +## The brine adapter (`icpcomplexsalinitybrine.hh`) + +This file contains the brineadapter class__ which defines +how to adapt values for communication between +the "full" fluidsystem accounting for 4 components influencing the brine properties +and the "brine" fluidsystem assuming water and a single salt determining the brine properties. + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../material/fluidsystems/icpcomplexsalinitybrine.hh))</summary> + + +### Include files +<details><summary> Click to show includes</summary> +we include all necessary components + +```cpp +#include <dumux/material/fluidsystems/base.hh> +#include <dumux/material/constants.hh> +#include <dumux/material/components/h2o.hh> +#include <dumux/material/components/sodiumion.hh> +#include <dumux/material/components/chlorideion.hh> +#include <dumux/material/components/calciumion.hh> +#include <dumux/material/components/tabulatedcomponent.hh> + +#include <dumux/common/exceptions.hh> + +#include <dumux/io/name.hh> +``` + +</details> + +### The brine adapter class +In ICPComplexSalinityBrine we make the transition from 3 components additional to water contributing to salinity to the single component that is assumed in the brine fluid system. +We enter the namespace Dumux. All Dumux functions and classes are in a namespace Dumux, to make sure they don`t clash with symbols from other libraries you may want to use in conjunction with Dumux. + +```cpp +namespace Dumux::FluidSystems { + +template< class Scalar, class H2OType = Components::TabulatedComponent<Dumux::Components::H2O<Scalar>> > +class ICPComplexSalinityBrine : public Base< Scalar, ICPComplexSalinityBrine<Scalar, H2OType>> +{ + using ThisType = ICPComplexSalinityBrine<Scalar, H2OType>; + using Base = Dumux::FluidSystems::Base<Scalar, ThisType>; + +public: + //! export the involved components + using H2O = H2OType; + using Na = Components::SodiumIon<Scalar>; + using Cl = Components::ChlorideIon<Scalar>; + using Ca = Components::CalciumIon<Scalar>; +``` + + +#### Component and phase definitions +With the following function we define what phases and components will be used by the fluid system and define the indices used to distinguish phases and components in the course of the simulation. + +```cpp + // We use convenient declarations that we derive from the property system. + static constexpr int numPhases = 1; //!< Number of phases in the fluid system + static constexpr int numComponents = 4; //!< Number of components in the fluid system (H2O, Na, Cl, Ca) + + static constexpr int phase0Idx = 0; //!< Index of the first (and only) phase + static constexpr int liquidPhaseIdx = phase0Idx; //!< The one considered phase is liquid + + static constexpr int H2OIdx = 0; //!< index of the water component + static constexpr int NaIdx = 1; //!< index of the Na component + static constexpr int ClIdx = 2; //!< index of the Cl component + static constexpr int CaIdx = 3; //!< index of the Ca component + static constexpr int comp0Idx = H2OIdx; //!< index of the first component + static constexpr int comp1Idx = NaIdx; //!< index of the second component + static constexpr int comp2Idx = ClIdx; //!< index of the third component + static constexpr int comp3Idx = CaIdx; //!< index of the fourth component + + // the fluid phase index + static std::string phaseName(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return IOName::liquidPhase(); + } + + // the miscibility + static constexpr bool isMiscible() + { + return false; + } + + // we do not have a gas phase + static constexpr bool isGas(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return false; + } + + // We need a ideal mixture + static constexpr bool isIdealMixture(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return true; + } + + // phase compressibility + static constexpr bool isCompressible(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return H2O::liquidIsCompressible(); + } + + // no gas, thus no ideal gas + static constexpr bool isIdealGas(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return false; /*we're a liquid!*/ + } +``` + + +#### The Component-Phase Interactions +In the following, we define the component-phase interactions such as // each component's fugacity coefficient in brine +and each component's binary diffusion coefficient with water in brine + +```cpp + // The component fugacity coefficients + template <class FluidState> + static Scalar fugacityCoefficient(const FluidState &fluidState, + int phaseIdx, + int compIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + assert(0 <= compIdx && compIdx < numComponents); + + if (phaseIdx == compIdx) + // We could calculate the real fugacity coefficient of + // the component in the fluid. Probably that's not worth + // the effort, since the fugacity coefficient of the other + // component is infinite anyway... + return 1.0; + return std::numeric_limits<Scalar>::infinity(); + } + + // The binary diffusion coefficients of the components and the phases main component + template <class FluidState> + static Scalar binaryDiffusionCoefficient(const FluidState& fluidState, + int phaseIdx, + int compIIdx, + int compJIdx) + { + if (phaseIdx == liquidPhaseIdx) + { + if (compIIdx > compJIdx) + { + using std::swap; + swap(compIIdx, compJIdx); + } + if (compJIdx == NaIdx || compJIdx == ClIdx || compJIdx == CaIdx) + return 1.587e-9; //[m²/s] //J. Phys. D: Appl. Phys. 40 (2007) 2769-2776 + else + DUNE_THROW(Dune::NotImplemented, "Binary diffusion coefficient of components " + << compIIdx << " and " << compJIdx + << " in phase " << phaseIdx); + } + + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index: " << phaseIdx); + } +``` + + +#### The Fluid (Brine) Properties +In the following, all functions defining the phase properties are given: +the density, viscosity, enthalpy, thermal conductivities, and heat capacities +of each phase depending on temperature, pressure, and phase composition + +```cpp + // The phase density + template <class FluidState> + static Scalar density(const FluidState& fluidState, int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + const Scalar temperature = fluidState.temperature(phaseIdx); + const Scalar pressure = fluidState.pressure(phaseIdx); + const Scalar xNaCl = fluidState.massFraction(phaseIdx, NaIdx) + + fluidState.massFraction(phaseIdx, ClIdx) + + fluidState.massFraction(phaseIdx, CaIdx); + + using std::max; + const Scalar TempC = temperature - 273.15; + const Scalar pMPa = pressure/1.0E6; + const Scalar salinity = max(0.0, xNaCl); + + const Scalar rhow = H2O::liquidDensity(temperature, pressure); + const Scalar density = rhow + 1000*salinity*(0.668 + + 0.44*salinity + + 1.0E-6*(300*pMPa - + 2400*pMPa*salinity + + TempC*(80.0 + + 3*TempC - + 3300*salinity - + 13*pMPa + + 47*pMPa*salinity))); + assert(density > 0.0); + return density; + } + + + + // The phase viscosity + template <class FluidState> + static Scalar viscosity(const FluidState& fluidState, int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + const Scalar temperature = fluidState.temperature(phaseIdx); + const Scalar xNaCl = fluidState.massFraction(phaseIdx, NaIdx) + + fluidState.massFraction(phaseIdx, ClIdx) + + fluidState.massFraction(phaseIdx, CaIdx); + + using std::pow; + using std::exp; + using std::max; + const Scalar T = max(temperature, 275.0); + const Scalar salinity = max(0.0, xNaCl); + + const Scalar T_C = T - 273.15; + const Scalar A = ((0.42*pow((pow(salinity, 0.8)-0.17), 2)) + 0.045)*pow(T_C, 0.8); + const Scalar mu_brine = 0.1 + (0.333*salinity) + (1.65+(91.9*salinity*salinity*salinity))*exp(-A); // [cP] + assert(mu_brine > 0.0); + return mu_brine/1000.0; // [Pa·s] + } +``` + + +</details> + + + +## The solid system (`biominsolids.hh`) + +This file contains the __solidystem class__ which defines all functions needed to describe the solid and their properties, +which are needed to model biomineralization. + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../material/solidsystems/biominsolids.hh))</summary> + + +### Include files + +```cpp +#include <string> +#include <dune/common/exceptions.hh> + +// we include all necessary solid components +#include <examples/biomineralization/material/components/biofilm.hh> +#include <dumux/material/components/calcite.hh> +#include <dumux/material/components/granite.hh> +``` + +### The solidsystem class +In the BioMinSolidPhase solid system, we define all functions needed to describe the solids and their properties accounted for in our simulation. +We enter the namespace Dumux. All Dumux functions and classes are in a namespace Dumux, to make sure they don`t clash with symbols from other libraries you may want to use in conjunction with Dumux. + +```cpp +namespace Dumux::SolidSystems { + +template <class Scalar> +class BioMinSolidPhase +{ +public: +``` + +#### Component definitions +With the following function we define what solid components will be used by the solid system and define the indices used to distinguish solid components in the course of the simulation. + +```cpp + // We use convenient declarations that we derive from the property system. + using Biofilm = Components::Biofilm<Scalar>; + using Calcite = Components::Calcite<Scalar>; + using Granite = Components::Granite<Scalar>; + + /**************************************** + * Solid phase related static parameters + ****************************************/ + static constexpr int numComponents = 3; + static constexpr int numInertComponents = 1; + static constexpr int BiofilmIdx = 0; + static constexpr int CalciteIdx = 1; + static constexpr int GraniteIdx = 2; + + // The component names + const static std::string componentName(int compIdx) + { + switch (compIdx) + { + case BiofilmIdx: return Biofilm::name(); + case CalciteIdx: return Calcite::name(); + case GraniteIdx: return Granite::name(); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + } + + // The solid system's name + static std::string name() + { return "BiomineralizationMinSolidPhase"; } + + // We assume incompressible solids + static constexpr bool isCompressible(int compIdx) + { return false; } + + // we have one inert component, the others may change + static constexpr bool isInert() + { return (numComponents == numInertComponents); } +``` + +#### Component properties +This simply forwards the component properties (name, molar mass, density). + +```cpp + // The component molar masses + static Scalar molarMass(int compIdx) + { + switch (compIdx) + { + case BiofilmIdx: return Biofilm::molarMass(); + case CalciteIdx: return Calcite::molarMass(); + case GraniteIdx: return Granite::molarMass(); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + } + + // The component densities + template <class SolidState> + static Scalar density(const SolidState& solidState, const int compIdx) + { + switch (compIdx) + { + case BiofilmIdx: return Biofilm::solidDensity(solidState.temperature()); + case CalciteIdx: return Calcite::solidDensity(solidState.temperature()); + case GraniteIdx: return Granite::solidDensity(solidState.temperature()); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + } + + // The component molar densities + template <class SolidState> + static Scalar molarDensity(const SolidState& solidState, const int compIdx) + { + switch (compIdx) + { + case BiofilmIdx: return Biofilm::solidDensity(solidState.temperature())/Biofilm::molarMass(); + case CalciteIdx: return Calcite::solidDensity(solidState.temperature())/Calcite::molarMass(); + case GraniteIdx: return Granite::solidDensity(solidState.temperature())/Calcite::molarMass(); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + } +``` + +#### Averaged solid properties +The overall solid properties are calculated by a volume-weigthed average of the pure component's properties. + +```cpp + // The average density + template <class SolidState> + static Scalar density(const SolidState& solidState) + { + const Scalar rho1 = Biofilm::solidDensity(solidState.temperature()); + const Scalar rho2 = Calcite::solidDensity(solidState.temperature()); + const Scalar rho3 = Granite::solidDensity(solidState.temperature()); + const Scalar volFrac1 = solidState.volumeFraction(BiofilmIdx); + const Scalar volFrac2 = solidState.volumeFraction(CalciteIdx); + const Scalar volFrac3 = solidState.volumeFraction(GraniteIdx); + + return (rho1*volFrac1+ + rho2*volFrac2+ + rho3*volFrac3) + /(volFrac1+volFrac2+volFrac3); + } +``` + + +</details> + + +| [:arrow_left: Back to the main documentation](../README.md) | [:arrow_left: Go back to part 2](setup.md) | +|---|---:| + diff --git a/examples/biomineralization/doc/modelconcept.md b/examples/biomineralization/doc/modelconcept.md new file mode 100644 index 0000000000..e918be0508 --- /dev/null +++ b/examples/biomineralization/doc/modelconcept.md @@ -0,0 +1,271 @@ +<!-- Important: This file has been automatically generated by generate_example_docs.py. Do not edit this file directly! --> + + +| [:arrow_left: Back to the main documentation](../README.md) | [:arrow_right: Continue with part 2](mainfile.md) | +|---|---:| + +# Model Concept for Biomineralization + +The conceptual model for biomineralization follows the one presented by [@Ebigbo2012] and [@Hommel2015]. +It accounts for two-phase multi-component reactive transport on the continuum scale, including biofilm and calcite as solid phases. +The reactions considered are pH-dependent dissociation reactions, microbial growth, and decay as well as microbially-catalyzed ureolysis and mass-transfer reactions between the different phases. +A mass transfer may occur between both fluid phases by the mutual dissolution of water and CO<sub>2</sub> in the gas or the aqueous phase. It may also occur between +the aqueous phase and the two *solid* phases, biofilm and calcite, denoted by subscripts (f) and (c) respectively, by attachment or +detachment of biomass and precipitation or dissolution of calcite. + +The mobile components, denoted by superscripts k, are water (w), dissolved inorganic carbon (C<sub>tot</sub>), +sodium (Na), chloride (Cl), calcium (Ca), urea (u), substrate (s), oxygen (O<sub>2</sub>), and suspended biomass (b). +A substrate is the carbon and energy source of the bacteria and O<sub>2</sub> is the electron acceptor. + +Contrary to [@Ebigbo2012] and [@Hommel2015], for the sake of simplicity, +the dissociation processes are not modeled in this example. +It is assumed that the system has reached a steady state were the calcite precipitation rate is equal to the rate of ureolysis. +Thus, in this example, we consider only the "simplified chemistry case" in which it is assumed that the precipitation rate is equal to the ureolysis rate to simplify the chemical processes considered ($`r_\mathrm{prec} = r_\mathrm{urea}`$), +described in detail in Chapter 6 of [@Hommel2016]. + +The documentation provided for the model concept is structured as follows: + +[[_TOC_]] + + +## Primary variables and mass balance equations + +The primary variables of this system of equations are chosen as the aqueous-phase pressure, mole fractions of the components in the water phase, and +for the solid phases biofilm and calcite, volume fractions. +However, the CO<sub>2</sub>-phase saturation is used as the primary variable instead of the mole fraction of total inorganic carbon in water +whenever both fluid phases are present within the same control volume ([@Class2002]). +All reactive and mass-transfer processes are incorporated in the mass balance equations for the components by component-specific source and sink terms: + +```math +\sum\limits_{\alpha} \left[\frac{\partial}{\partial t}\left(\phi \rho_\mathrm{\alpha,\,mol} x^\kappa_\alpha S_\alpha \right) + \nabla\cdotp \left(\rho_\mathrm{\alpha,\,mol} x^\kappa_\alpha \mathbf{v}_\alpha \right) - \nabla\cdotp \left(\rho_\mathrm{\alpha,\,mol} \mathbf{D}^\kappa_\mathrm{pm,\alpha} \nabla x^\kappa_\alpha \right) \right] = q^\kappa,\:\alpha\in \mathrm{\{n;w\}} . +\tag{2} +``` + +However, all components except water, CO<sub>2</sub> , and O<sub>2</sub> are assumed to be restricted to the water phase. + +The mass balances for the solid phases calcite and biofilm contain +only a storage and source term since they are immobile: + +```math +\frac{\partial}{\partial t} \left(\phi_\lambda \rho_\lambda \right) = q^\lambda,\:\lambda\in \mathrm{\{c;f\}}. +\tag{3} +``` + +Here, $`\phi_\lambda`$ and $`\rho_\lambda`$ are volume fraction and mass density of +the solid phase $`\lambda`$, and $`q^\lambda`$ is the source term of phase $`\lambda`$ due to biochemical reactions. +The sources and sinks due to reactions $`q^\kappa$ and $q^\lambda`$ are specific to the components and are discussed in details in the subsequent section. + +## Component-specific reactive source and sink terms + +The source and sink terms account for the biogeochemical reactions occurring during MICP and the presence of CO<sub>2</sub>: +ureolysis, calcite precipitation, and dissolution, biomass growth under consumption of oxygen and substrate, biomass decay, as well as attachment and detachment of biomass. + +## Water, sodium and chloride +Sodium and chloride do not participate in the reactions and water is the solvent and, thus, abundant, which is why its consumption by the hydrolysis of urea (Eq. [1](#mjx-eqn-eq:q_w_na_cl)) is considered negligible. +Thus, the reactive source terms for water, sodium, and chloride are zero. + +## Urea and total nitrogen +The source term for ammonia/ammonium, $`q^\mathrm{N_{tot}}`$, and the sink term for urea $`q^\mathrm{u}`$ result from ureolysis (Eq. [1](#mjx-eqn-eq:q_ntot)). +For each mole of urea hydrolyzed, 2 moles of ammonia/ammonium are generated. The source terms are thus: + +```math +q^\mathrm{u}=-r_\mathrm{urea}; \\ +q^\mathrm{N_{tot}}=2r_\mathrm{urea}, +``` + +where $`r_\mathrm{urea}`$ is the ureolysis rate calculated according to [@Lauchnor2015], +who investigated the influences of urea, +NH<sup>4+</sup>, and cell concentration, and pH of the medium on the ureolysis of whole cells of _S. pasteurii_: + +```math +r_\mathrm{urea} = k_\mathrm{urease} +\:k_\mathrm{ub}\:\rho_\mathrm{f}\:\phi_\mathrm{f} +\:\frac{m^\mathrm{u}}{m^\mathrm{u}+K_\mathrm{u}}. +``` + +$`r_\mathrm{urea}`$ represents the revised rate of ureolysis according to [@Lauchnor2015], +$`k_\mathrm{urease}`$ the revised maximum activity of urease adapted from [@Lauchnor2015], +$`\rho_\mathrm{f}`$ and $`\phi_\mathrm{f}`$ the density and volume fraction of biofilm respectively, +$`k_\mathrm{ub}`$ the mass ratio of urease to biofilm, +$`m^\mathrm{u}`$ the molality of urea calculated from the water phase composition, +and $`K_\mathrm{u}`$ is the half saturation constant for urea adapted from [@Lauchnor2015]. + +## Calcium and calcite +The source terms of calcium $`q^\mathrm{Ca}`$ and calcite $`q^\mathrm{c}`$ +are determined by the rates of precipitation and dissolution. +When the aqueous phase is oversaturated with respect to calcite, it precipitates. +In the opposite case, calcite dissolves until the solution is saturated or all calcite is already dissolved: + +```math +q^\mathrm{Ca} = r_\mathrm{diss} - r_\mathrm{prec}; \\ +q^\mathrm{c} = - r_\mathrm{diss} + r_\mathrm{prec}. +``` + +In the presented simplified chemistry system, dissolution is neglected +and instead of calculating the complex geochemistry, e.g. dissociation of inorganic carbon into carbonate and bicarbonate, +it is assumed that the system has reached a steady state, were the precipitation rate is equal to the ureolysis rate and, thus, it yields: + +```math +r_\mathrm{prec} = r_\mathrm{urea}, +``` +as long as there is calcium to form calcite. +Note: The "simplified chemistry case" ($`r_\mathrm{prec} = r_\mathrm{urea}`$), +is a simplifying assumption, its effects and validity are discussed in more detail in Chapter 6 of [@Hommel2016]. + +## Dissolved inorganic carbon +Dissolved inorganic carbon is generated by the hydrolysis of urea +as well as by the dissolution of calcite while it is consumed by the precipitation of calcite. +Thus, the source term of dissolved inorganic carbon $`q^\mathrm{C_{tot}}`$ results in: + +```math +q^\mathrm{C_{tot}} = r_\mathrm{urea} + r_\mathrm{diss} - r_\mathrm{prec}, +``` + + +## Suspended and attached biomass + +The source and sink terms of suspended and attached biomass (biofilm), $`q^\mathrm{b}`$ and $`q^\mathrm{f}`$, +include four reaction rates each, corresponding to the biomass-related processes the model accounts for. +These processes are growth and decay increasing and decreasing the suspended or attached biomass as well as +attachment and detachment describing the transfer of biomass from the suspended to the attached state and vice versa: + +```math +q^\mathrm{b} = \frac{r^\mathrm{b}_\mathrm{g} - r^\mathrm{b}_\mathrm{b} - r_\mathrm{a} + r_\mathrm{d}}{M^\mathrm{b}}; \\ +q^\mathrm{f} = \frac{r^\mathrm{f}_\mathrm{g} - r^\mathrm{f}_\mathrm{b} + r_\mathrm{a} - r_\mathrm{d}}{M^\mathrm{f}} +``` + +where $`r^\mathrm{b}_\mathrm{g}`$ is the growth rate and $`r^\mathrm{b}_\mathrm{b}`$ the decay rate of suspended biomass, $`r_\mathrm{a}`$ the attachment rate, $`r_\mathrm{d}`$ the detachment rate. +Accordingly, $`r^\mathrm{f}_\mathrm{g}`$ and $`r^\mathrm{f}_\mathrm{b}`$ are the growth and decay of biofilm. +All rates influencing both attached and suspended biomass are assumed to be of a first-order type. + +The growth rates of suspended and attached biomass are as given below, +with the specific growth rate calculated using double Monod kinetics to reproduce the dependence of +the microbial growth on both substrate and oxygen. + +```math +r_\mathrm{g}^\mathrm{b} = \mu_\mathrm{g} C_\mathrm{w}^\mathrm{b}S_\mathrm{w}\phi; \\ + r_\mathrm{g}^\mathrm{f} = \mu_\mathrm{g} \phi_\mathrm{f}\rho_\mathrm{f}; \\ + \mu_\mathrm{g} = k_\mathrm{\mu} + \frac{C_\mathrm{w}^\mathrm{s}}{K_\mathrm{s} + C_\mathrm{w}^\mathrm{s}} + \frac{C_\mathrm{w}^\mathrm{O_2}}{K_\mathrm{O_2} + C_\mathrm{w}^\mathrm{O_2}}. +``` + +Here, $`k_\mathrm{\mu}`$ is the maximum specific growth rate, according to [@Connolly2014], +$`C_\mathrm{w}^\mathrm{s}`$ and $`C_\mathrm{w}^\mathrm{O_2}`$ are the mass concentrations of substrate and oxygen in the water phase and +K<sub>s</sub> and K<sub>O<sub>2</sub></sub> are the half-saturation coefficients for substrate and oxygen respectively. + +The decay rates are calculated similarly to the growth rates, +except that the specific decay rates of suspended and attached biomass +take different processes into account, increasing inactivation. +For suspended biomass, non-optimal acidic pH is assumed to increase inactivation. +As calcite precipitates mainly in or close to the biofilm, cells may be covered with calcite precipitates +or disrupted by crystals inactivating the affected cells ([@Dupraz2009a] and [@Whiffin2007]). +Consequently, the precipitation rate is assumed to increase the specific decay rate of attached biomass. + + +```math +r_\mathrm{b}^\mathrm{b} = k_\mathrm{b}^\mathrm{b} C_\mathrm{w}^\mathrm{b}S_\mathrm{w}\phi; \\ + r_\mathrm{b}^\mathrm{f} = k_\mathrm{b}^\mathrm{f}\phi_\mathrm{f}\rho_\mathrm{f}; \\ +k_\mathrm{b}^\mathrm{b}=b_0\left(1+\frac{K_\mathrm{pH}}{m_\mathrm{H^{+}}^2}\right); \\ + k_\mathrm{b}^\mathrm{f} = b_0 + \frac{r_\mathrm{prec} M^\mathrm{c}}{\rho_\mathrm{c}\left(\phi_0 - \phi_\mathrm{c}\right)} +``` + +The attachment rate quantifies the biomass transfer from +the suspended to the attached state. +As attachment is modeled assuming a first-order kinetic rather than a +sorption-type behavior, with preferential attachment to previously attached biomass: + +```math +r_\mathrm{a}= k_\mathrm{a} C^\mathrm{b}_\mathrm{w} \phi S_\mathrm{w};\\ +k_\mathrm{a}=c_\mathrm{a,1} \phi_\mathrm{f} + c_\mathrm{a,2}, +``` + +Detachment of biomass from biofilm is assumed to be proportional to the shear stress. +Additionally, the growth contributes to the detachment rate, as vigorously growing +biofilm is typically weaker and as such more susceptible to detachment. +As the model of [@Ebigbo2012] is defined on the Darcy scale but the shear stress is a micro-scale property, +it is approximated using the absolute value of the water-phase potential gradient: + +```math +r_\mathrm{d}=k_\mathrm{d} \phi_\mathrm{f} \rho_\mathrm{f};\\ +k_\mathrm{d}=c_\mathrm{d} +\left( \phi S_\mathrm{w} \left|\nabla p_\mathrm{w} - \rho_\mathrm{w} \mathbf{g} \right| \right)^{0.58} ++ \frac{\phi_\mathrm{f}}{\phi_0-\phi_\mathrm{c}} \mu_\mathrm{g}. +``` + +Here, $`c_\mathrm{d}`$ is a coefficient for the shear-stress-dependent detachment, +$`\left|\nabla p_\mathrm{w} - \rho_\mathrm{w} \mathbf{g} \right|`$ the absolute value of +the water-phase potential gradient, and $`\phi_0`$ the initial porosity. + + +## Substrate and oxygen +The consumption of substrate and oxygen is linked to the growth of both suspended and attached biomass +by the yield coefficient Y of substrate. In the case of oxygen, the coefficient F, which is the ration of oxygen consumed per substrate consumed, +is used to express the biomass yield per oxygen consumed: + +```math +q^\mathrm{s} = - \frac{r^\mathrm{b}_\mathrm{g} + r^\mathrm{f}_\mathrm{g}}{M^\mathrm{s}Y}; \\ + q^\mathrm{O_2} = F q^\mathrm{s} = - F \frac{ r^\mathrm{b}_\mathrm{g} + r^\mathrm{f}_\mathrm{g}} {M^\mathrm{O_2}Y}. +``` + +## Supplementary equations +\subsubsection{Permeability and porosity}\label{sec:perm_poro_pw} +The permeability decreases due to biofilm growth and calcite precipitation. +In the model, the reduction of permeability is calculated based on the +reduction of porosity using a Kozenzy-Carman-type relationship: + +```math +\frac{K}{K_\mathrm{0}}=\left(\frac{\phi}{\phi_\mathrm{0}}\right)^3 \left(\frac{1-\phi_0}{1-\phi}\right)^2. +``` + +Here, $`K_\mathrm{0}`$ is the initial permeability, +and $`\phi_0`$ is the initial porosity. The porosity decreases as +the volume fractions of biofilm and calcite increase: + +```math +\phi=\phi_\mathrm{0}-\phi_\mathrm{c}-\phi_\mathrm{f}. +``` + + +## Fluid properties +The density and the viscosity of the CO<sub>2</sub> phase are calculated using +the relation given by [@Span1996] and [@Fenghour1998] respectively. +In these calculations, the effects of the small amounts of water and oxygen are neglected. +The density and the viscosity of the aqueous phase are calculated +according to [@Batzle1992] as a function of salinity. +Sodium, chloride and calcium are considered to contribute to the salinity. + + +## Phase partitioning of components +The dissolution of CO<sub>2</sub> in the aqueous phase is calculated according +to [@Duan2003] as a function of temperature, pressure and salinity. +In the two-phase case, the concentration of carbonic acid is assumed to be +equal to the solubility while, in the case of the exclusive presence of the aqueous phase, +the concentration of inorganic carbon +is exclusively dependent on the precipitation, dissolution and ureolysis reactions. +In this case, the solubility represents the maximum possible concentration. +For the solubility of oxygen in the aqueous phase, Henry's law is used. + + + + + +[@Batzle1992]: https://library.seg.org/doi/10.1190/1.1443207 "Seismic Properties of Pore Fluids" +[@Class2002]: https://www.sciencedirect.com/science/article/pii/S0309170802000155 "Numerical simulation of non-isothermal multiphase multicomponent processes in porous media. 2. Applications for the injection of steam and air" +[@Connolly2014]: http://www.ncbi.nlm.nih.gov/pubmed/23835134 "Construction of two ureolytic model organisms for the study of microbially induced calcium carbonate precipitation" +[@Duan2003]: https://www.sciencedirect.com/science/article/pii/S0009254102002632 "An improved model calculating CO<sub>2</sub> solubility in pure water and aqueous NaCl solutions from 273 to 533 K and from 0 to 2000 bar" +[@Chou1989]: https://www.sciencedirect.com/science/article/pii/0009254189900636 "Comparative study of the kinetics and mechanisms of dissolution of carbonate minerals" +[@Compton1989]: https://onlinelibrary.wiley.com/doi/abs/10.1111/j.1365-2427.1989.tb01101.x "The dissolution of calcite in acid waters: Mass transport versus surface control" +[@Dupraz2009a]: http://linkinghub.elsevier.com/retrieve/pii/S0009254109002265 "Experimental and numerical modeling of bacterially induced pH increase and calcite precipitation in saline aquifers" +[@Whiffin2007]: https://www.tandfonline.com/doi/full/10.1080/01490450701436505 "Microbial Carbonate Precipitation as a Soil Improvement Technique" +[@Ebigbo2012]: https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2011WR011714 "Darcy-scale modeling of microbially induced carbonate mineral precipitation in sand columns" +[@Fenghour1998]: https://aip.scitation.org/doi/10.1063/1.556013 "The Viscosity of Carbon Dioxide" +[@Hommel2015]: https://agupubs.onlinelibrary.wiley.com/doi/full/10.1002/2014WR016503 "A revised model for microbially induced calcite precipitation: Improvements and new insights based on recent experiments" +[@Hommel2016]: https://elib.uni-stuttgart.de/handle/11682/8787 "Modelling biogeochemical and mass transport processes in the subsurface: investigation of microbially induced calcite precipitation" +[@Lauchnor2015]: http://dx.doi.org/10.1111/jam.12804 "Whole cell kinetics of ureolysis by Sporosarcina pasteurii" +[@Mitchell2008]: https://www.sciencedirect.com/science/article/pii/S0896844608002040 "Resilience of planktonic and biofilm cultures to supercritical CO<sub>2</sub>" +[@Span1996]: https://aip.scitation.org/doi/abs/10.1063/1.555991 "A new equation of state for carbon dioxide covering the fluid region from the triple-point temperature to 1100 K at pressures up to 800 MPa" + +| [:arrow_left: Back to the main documentation](../README.md) | [:arrow_right: Continue with part 2](mainfile.md) | +|---|---:| + diff --git a/examples/biomineralization/doc/modelconcept_intro.md b/examples/biomineralization/doc/modelconcept_intro.md new file mode 100644 index 0000000000..68d6ca11b4 --- /dev/null +++ b/examples/biomineralization/doc/modelconcept_intro.md @@ -0,0 +1,261 @@ +# Model Concept for Biomineralization + +The conceptual model for biomineralization follows the one presented by [@Ebigbo2012] and [@Hommel2015]. +It accounts for two-phase multi-component reactive transport on the continuum scale, including biofilm and calcite as solid phases. +The reactions considered are pH-dependent dissociation reactions, microbial growth, and decay as well as microbially-catalyzed ureolysis and mass-transfer reactions between the different phases. +A mass transfer may occur between both fluid phases by the mutual dissolution of water and CO<sub>2</sub> in the gas or the aqueous phase. It may also occur between +the aqueous phase and the two *solid* phases, biofilm and calcite, denoted by subscripts (f) and (c) respectively, by attachment or +detachment of biomass and precipitation or dissolution of calcite. + +The mobile components, denoted by superscripts k, are water (w), dissolved inorganic carbon (C<sub>tot</sub>), +sodium (Na), chloride (Cl), calcium (Ca), urea (u), substrate (s), oxygen (O<sub>2</sub>), and suspended biomass (b). +A substrate is the carbon and energy source of the bacteria and O<sub>2</sub> is the electron acceptor. + +Contrary to [@Ebigbo2012] and [@Hommel2015], for the sake of simplicity, +the dissociation processes are not modeled in this example. +It is assumed that the system has reached a steady state were the calcite precipitation rate is equal to the rate of ureolysis. +Thus, in this example, we consider only the "simplified chemistry case" in which it is assumed that the precipitation rate is equal to the ureolysis rate to simplify the chemical processes considered ($`r_\mathrm{prec} = r_\mathrm{urea}`$), +described in detail in Chapter 6 of [@Hommel2016]. + +The documentation provided for the model concept is structured as follows: + +[[_TOC_]] + + +## Primary variables and mass balance equations + +The primary variables of this system of equations are chosen as the aqueous-phase pressure, mole fractions of the components in the water phase, and +for the solid phases biofilm and calcite, volume fractions. +However, the CO<sub>2</sub>-phase saturation is used as the primary variable instead of the mole fraction of total inorganic carbon in water +whenever both fluid phases are present within the same control volume ([@Class2002]). +All reactive and mass-transfer processes are incorporated in the mass balance equations for the components by component-specific source and sink terms: + +```math +\sum\limits_{\alpha} \left[\frac{\partial}{\partial t}\left(\phi \rho_\mathrm{\alpha,\,mol} x^\kappa_\alpha S_\alpha \right) + \nabla\cdotp \left(\rho_\mathrm{\alpha,\,mol} x^\kappa_\alpha \mathbf{v}_\alpha \right) - \nabla\cdotp \left(\rho_\mathrm{\alpha,\,mol} \mathbf{D}^\kappa_\mathrm{pm,\alpha} \nabla x^\kappa_\alpha \right) \right] = q^\kappa,\:\alpha\in \mathrm{\{n;w\}} . +\tag{2} +``` + +However, all components except water, CO<sub>2</sub> , and O<sub>2</sub> are assumed to be restricted to the water phase. + +The mass balances for the solid phases calcite and biofilm contain +only a storage and source term since they are immobile: + +```math +\frac{\partial}{\partial t} \left(\phi_\lambda \rho_\lambda \right) = q^\lambda,\:\lambda\in \mathrm{\{c;f\}}. +\tag{3} +``` + +Here, $`\phi_\lambda`$ and $`\rho_\lambda`$ are volume fraction and mass density of +the solid phase $`\lambda`$, and $`q^\lambda`$ is the source term of phase $`\lambda`$ due to biochemical reactions. +The sources and sinks due to reactions $`q^\kappa$ and $q^\lambda`$ are specific to the components and are discussed in details in the subsequent section. + +## Component-specific reactive source and sink terms + +The source and sink terms account for the biogeochemical reactions occurring during MICP and the presence of CO<sub>2</sub>: +ureolysis, calcite precipitation, and dissolution, biomass growth under consumption of oxygen and substrate, biomass decay, as well as attachment and detachment of biomass. + +## Water, sodium and chloride +Sodium and chloride do not participate in the reactions and water is the solvent and, thus, abundant, which is why its consumption by the hydrolysis of urea (Eq. [1](#mjx-eqn-eq:q_w_na_cl)) is considered negligible. +Thus, the reactive source terms for water, sodium, and chloride are zero. + +## Urea and total nitrogen +The source term for ammonia/ammonium, $`q^\mathrm{N_{tot}}`$, and the sink term for urea $`q^\mathrm{u}`$ result from ureolysis (Eq. [1](#mjx-eqn-eq:q_ntot)). +For each mole of urea hydrolyzed, 2 moles of ammonia/ammonium are generated. The source terms are thus: + +```math +q^\mathrm{u}=-r_\mathrm{urea}; \\ +q^\mathrm{N_{tot}}=2r_\mathrm{urea}, +``` + +where $`r_\mathrm{urea}`$ is the ureolysis rate calculated according to [@Lauchnor2015], +who investigated the influences of urea, +NH<sup>4+</sup>, and cell concentration, and pH of the medium on the ureolysis of whole cells of _S. pasteurii_: + +```math +r_\mathrm{urea} = k_\mathrm{urease} +\:k_\mathrm{ub}\:\rho_\mathrm{f}\:\phi_\mathrm{f} +\:\frac{m^\mathrm{u}}{m^\mathrm{u}+K_\mathrm{u}}. +``` + +$`r_\mathrm{urea}`$ represents the revised rate of ureolysis according to [@Lauchnor2015], +$`k_\mathrm{urease}`$ the revised maximum activity of urease adapted from [@Lauchnor2015], +$`\rho_\mathrm{f}`$ and $`\phi_\mathrm{f}`$ the density and volume fraction of biofilm respectively, +$`k_\mathrm{ub}`$ the mass ratio of urease to biofilm, +$`m^\mathrm{u}`$ the molality of urea calculated from the water phase composition, +and $`K_\mathrm{u}`$ is the half saturation constant for urea adapted from [@Lauchnor2015]. + +## Calcium and calcite +The source terms of calcium $`q^\mathrm{Ca}`$ and calcite $`q^\mathrm{c}`$ +are determined by the rates of precipitation and dissolution. +When the aqueous phase is oversaturated with respect to calcite, it precipitates. +In the opposite case, calcite dissolves until the solution is saturated or all calcite is already dissolved: + +```math +q^\mathrm{Ca} = r_\mathrm{diss} - r_\mathrm{prec}; \\ +q^\mathrm{c} = - r_\mathrm{diss} + r_\mathrm{prec}. +``` + +In the presented simplified chemistry system, dissolution is neglected +and instead of calculating the complex geochemistry, e.g. dissociation of inorganic carbon into carbonate and bicarbonate, +it is assumed that the system has reached a steady state, were the precipitation rate is equal to the ureolysis rate and, thus, it yields: + +```math +r_\mathrm{prec} = r_\mathrm{urea}, +``` +as long as there is calcium to form calcite. +Note: The "simplified chemistry case" ($`r_\mathrm{prec} = r_\mathrm{urea}`$), +is a simplifying assumption, its effects and validity are discussed in more detail in Chapter 6 of [@Hommel2016]. + +## Dissolved inorganic carbon +Dissolved inorganic carbon is generated by the hydrolysis of urea +as well as by the dissolution of calcite while it is consumed by the precipitation of calcite. +Thus, the source term of dissolved inorganic carbon $`q^\mathrm{C_{tot}}`$ results in: + +```math +q^\mathrm{C_{tot}} = r_\mathrm{urea} + r_\mathrm{diss} - r_\mathrm{prec}, +``` + + +## Suspended and attached biomass + +The source and sink terms of suspended and attached biomass (biofilm), $`q^\mathrm{b}`$ and $`q^\mathrm{f}`$, +include four reaction rates each, corresponding to the biomass-related processes the model accounts for. +These processes are growth and decay increasing and decreasing the suspended or attached biomass as well as +attachment and detachment describing the transfer of biomass from the suspended to the attached state and vice versa: + +```math +q^\mathrm{b} = \frac{r^\mathrm{b}_\mathrm{g} - r^\mathrm{b}_\mathrm{b} - r_\mathrm{a} + r_\mathrm{d}}{M^\mathrm{b}}; \\ +q^\mathrm{f} = \frac{r^\mathrm{f}_\mathrm{g} - r^\mathrm{f}_\mathrm{b} + r_\mathrm{a} - r_\mathrm{d}}{M^\mathrm{f}} +``` + +where $`r^\mathrm{b}_\mathrm{g}`$ is the growth rate and $`r^\mathrm{b}_\mathrm{b}`$ the decay rate of suspended biomass, $`r_\mathrm{a}`$ the attachment rate, $`r_\mathrm{d}`$ the detachment rate. +Accordingly, $`r^\mathrm{f}_\mathrm{g}`$ and $`r^\mathrm{f}_\mathrm{b}`$ are the growth and decay of biofilm. +All rates influencing both attached and suspended biomass are assumed to be of a first-order type. + +The growth rates of suspended and attached biomass are as given below, +with the specific growth rate calculated using double Monod kinetics to reproduce the dependence of +the microbial growth on both substrate and oxygen. + +```math +r_\mathrm{g}^\mathrm{b} = \mu_\mathrm{g} C_\mathrm{w}^\mathrm{b}S_\mathrm{w}\phi; \\ + r_\mathrm{g}^\mathrm{f} = \mu_\mathrm{g} \phi_\mathrm{f}\rho_\mathrm{f}; \\ + \mu_\mathrm{g} = k_\mathrm{\mu} + \frac{C_\mathrm{w}^\mathrm{s}}{K_\mathrm{s} + C_\mathrm{w}^\mathrm{s}} + \frac{C_\mathrm{w}^\mathrm{O_2}}{K_\mathrm{O_2} + C_\mathrm{w}^\mathrm{O_2}}. +``` + +Here, $`k_\mathrm{\mu}`$ is the maximum specific growth rate, according to [@Connolly2014], +$`C_\mathrm{w}^\mathrm{s}`$ and $`C_\mathrm{w}^\mathrm{O_2}`$ are the mass concentrations of substrate and oxygen in the water phase and +K<sub>s</sub> and K<sub>O<sub>2</sub></sub> are the half-saturation coefficients for substrate and oxygen respectively. + +The decay rates are calculated similarly to the growth rates, +except that the specific decay rates of suspended and attached biomass +take different processes into account, increasing inactivation. +For suspended biomass, non-optimal acidic pH is assumed to increase inactivation. +As calcite precipitates mainly in or close to the biofilm, cells may be covered with calcite precipitates +or disrupted by crystals inactivating the affected cells ([@Dupraz2009a] and [@Whiffin2007]). +Consequently, the precipitation rate is assumed to increase the specific decay rate of attached biomass. + + +```math +r_\mathrm{b}^\mathrm{b} = k_\mathrm{b}^\mathrm{b} C_\mathrm{w}^\mathrm{b}S_\mathrm{w}\phi; \\ + r_\mathrm{b}^\mathrm{f} = k_\mathrm{b}^\mathrm{f}\phi_\mathrm{f}\rho_\mathrm{f}; \\ +k_\mathrm{b}^\mathrm{b}=b_0\left(1+\frac{K_\mathrm{pH}}{m_\mathrm{H^{+}}^2}\right); \\ + k_\mathrm{b}^\mathrm{f} = b_0 + \frac{r_\mathrm{prec} M^\mathrm{c}}{\rho_\mathrm{c}\left(\phi_0 - \phi_\mathrm{c}\right)} +``` + +The attachment rate quantifies the biomass transfer from +the suspended to the attached state. +As attachment is modeled assuming a first-order kinetic rather than a +sorption-type behavior, with preferential attachment to previously attached biomass: + +```math +r_\mathrm{a}= k_\mathrm{a} C^\mathrm{b}_\mathrm{w} \phi S_\mathrm{w};\\ +k_\mathrm{a}=c_\mathrm{a,1} \phi_\mathrm{f} + c_\mathrm{a,2}, +``` + +Detachment of biomass from biofilm is assumed to be proportional to the shear stress. +Additionally, the growth contributes to the detachment rate, as vigorously growing +biofilm is typically weaker and as such more susceptible to detachment. +As the model of [@Ebigbo2012] is defined on the Darcy scale but the shear stress is a micro-scale property, +it is approximated using the absolute value of the water-phase potential gradient: + +```math +r_\mathrm{d}=k_\mathrm{d} \phi_\mathrm{f} \rho_\mathrm{f};\\ +k_\mathrm{d}=c_\mathrm{d} +\left( \phi S_\mathrm{w} \left|\nabla p_\mathrm{w} - \rho_\mathrm{w} \mathbf{g} \right| \right)^{0.58} ++ \frac{\phi_\mathrm{f}}{\phi_0-\phi_\mathrm{c}} \mu_\mathrm{g}. +``` + +Here, $`c_\mathrm{d}`$ is a coefficient for the shear-stress-dependent detachment, +$`\left|\nabla p_\mathrm{w} - \rho_\mathrm{w} \mathbf{g} \right|`$ the absolute value of +the water-phase potential gradient, and $`\phi_0`$ the initial porosity. + + +## Substrate and oxygen +The consumption of substrate and oxygen is linked to the growth of both suspended and attached biomass +by the yield coefficient Y of substrate. In the case of oxygen, the coefficient F, which is the ration of oxygen consumed per substrate consumed, +is used to express the biomass yield per oxygen consumed: + +```math +q^\mathrm{s} = - \frac{r^\mathrm{b}_\mathrm{g} + r^\mathrm{f}_\mathrm{g}}{M^\mathrm{s}Y}; \\ + q^\mathrm{O_2} = F q^\mathrm{s} = - F \frac{ r^\mathrm{b}_\mathrm{g} + r^\mathrm{f}_\mathrm{g}} {M^\mathrm{O_2}Y}. +``` + +## Supplementary equations +\subsubsection{Permeability and porosity}\label{sec:perm_poro_pw} +The permeability decreases due to biofilm growth and calcite precipitation. +In the model, the reduction of permeability is calculated based on the +reduction of porosity using a Kozenzy-Carman-type relationship: + +```math +\frac{K}{K_\mathrm{0}}=\left(\frac{\phi}{\phi_\mathrm{0}}\right)^3 \left(\frac{1-\phi_0}{1-\phi}\right)^2. +``` + +Here, $`K_\mathrm{0}`$ is the initial permeability, +and $`\phi_0`$ is the initial porosity. The porosity decreases as +the volume fractions of biofilm and calcite increase: + +```math +\phi=\phi_\mathrm{0}-\phi_\mathrm{c}-\phi_\mathrm{f}. +``` + + +## Fluid properties +The density and the viscosity of the CO<sub>2</sub> phase are calculated using +the relation given by [@Span1996] and [@Fenghour1998] respectively. +In these calculations, the effects of the small amounts of water and oxygen are neglected. +The density and the viscosity of the aqueous phase are calculated +according to [@Batzle1992] as a function of salinity. +Sodium, chloride and calcium are considered to contribute to the salinity. + + +## Phase partitioning of components +The dissolution of CO<sub>2</sub> in the aqueous phase is calculated according +to [@Duan2003] as a function of temperature, pressure and salinity. +In the two-phase case, the concentration of carbonic acid is assumed to be +equal to the solubility while, in the case of the exclusive presence of the aqueous phase, +the concentration of inorganic carbon +is exclusively dependent on the precipitation, dissolution and ureolysis reactions. +In this case, the solubility represents the maximum possible concentration. +For the solubility of oxygen in the aqueous phase, Henry's law is used. + + + + + +[@Batzle1992]: https://library.seg.org/doi/10.1190/1.1443207 "Seismic Properties of Pore Fluids" +[@Class2002]: https://www.sciencedirect.com/science/article/pii/S0309170802000155 "Numerical simulation of non-isothermal multiphase multicomponent processes in porous media. 2. Applications for the injection of steam and air" +[@Connolly2014]: http://www.ncbi.nlm.nih.gov/pubmed/23835134 "Construction of two ureolytic model organisms for the study of microbially induced calcium carbonate precipitation" +[@Duan2003]: https://www.sciencedirect.com/science/article/pii/S0009254102002632 "An improved model calculating CO<sub>2</sub> solubility in pure water and aqueous NaCl solutions from 273 to 533 K and from 0 to 2000 bar" +[@Chou1989]: https://www.sciencedirect.com/science/article/pii/0009254189900636 "Comparative study of the kinetics and mechanisms of dissolution of carbonate minerals" +[@Compton1989]: https://onlinelibrary.wiley.com/doi/abs/10.1111/j.1365-2427.1989.tb01101.x "The dissolution of calcite in acid waters: Mass transport versus surface control" +[@Dupraz2009a]: http://linkinghub.elsevier.com/retrieve/pii/S0009254109002265 "Experimental and numerical modeling of bacterially induced pH increase and calcite precipitation in saline aquifers" +[@Whiffin2007]: https://www.tandfonline.com/doi/full/10.1080/01490450701436505 "Microbial Carbonate Precipitation as a Soil Improvement Technique" +[@Ebigbo2012]: https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2011WR011714 "Darcy-scale modeling of microbially induced carbonate mineral precipitation in sand columns" +[@Fenghour1998]: https://aip.scitation.org/doi/10.1063/1.556013 "The Viscosity of Carbon Dioxide" +[@Hommel2015]: https://agupubs.onlinelibrary.wiley.com/doi/full/10.1002/2014WR016503 "A revised model for microbially induced calcite precipitation: Improvements and new insights based on recent experiments" +[@Hommel2016]: https://elib.uni-stuttgart.de/handle/11682/8787 "Modelling biogeochemical and mass transport processes in the subsurface: investigation of microbially induced calcite precipitation" +[@Lauchnor2015]: http://dx.doi.org/10.1111/jam.12804 "Whole cell kinetics of ureolysis by Sporosarcina pasteurii" +[@Mitchell2008]: https://www.sciencedirect.com/science/article/pii/S0896844608002040 "Resilience of planktonic and biofilm cultures to supercritical CO<sub>2</sub>" +[@Span1996]: https://aip.scitation.org/doi/abs/10.1063/1.555991 "A new equation of state for carbon dioxide covering the fluid region from the triple-point temperature to 1100 K at pressures up to 800 MPa" diff --git a/examples/biomineralization/doc/setup.md b/examples/biomineralization/doc/setup.md new file mode 100644 index 0000000000..8debae39a9 --- /dev/null +++ b/examples/biomineralization/doc/setup.md @@ -0,0 +1,938 @@ +<!-- Important: This file has been automatically generated by generate_example_docs.py. Do not edit this file directly! --> + + +| [:arrow_left: Back to the main documentation](../README.md) | [:arrow_left: Go back to part 2](mainfile.md) | [:arrow_right: Continue with part 4](fluidmaterial.md) | +|---|---|---:| + +# Simulation Setup + +The setup for this example is based on the initial 100000s of the _column experiment D1_ described in [@Hommel2015] and can also be found in Section 4.2 of [@Hommel2016] under the name _column experiment D1_. +We here only consider the "simplified chemistry case" in which it is assumed that the precipitation rate is equal to the ureolysis rate to simplify the chemical processes considered ($`r_\mathrm{prec} = r_\mathrm{urea}`$) (see Chapter 6 [@Hommel2016]). + +The column is considered as a 1D domain with injections of various aqueous solutions at the bottom (Neumann boundary condition) +and a fixed pressure at the top (Dirichlet boundary condition). +The various types of injected fluid compositions are read from an additional input file `injections_type.dat`. +Depending on the injection type, the `problem.hh` adapts the composition of the injected aqueous solution for the bottom Neumann boundary condition. +Further, `spatialparams.hh` is an example for spatial parameters dealing with changing porosity and permeability. + +The subsequent file documentation is structured as follows: + +[[_TOC_]] + +[@Hommel2015]: https://agupubs.onlinelibrary.wiley.com/doi/full/10.1002/2014WR016503 "A revised model for microbially induced calcite precipitation: Improvements and new insights based on recent experiments" +[@Hommel2016]: https://elib.uni-stuttgart.de/handle/11682/8787 "Modelling biogeochemical and mass transport processes in the subsurface: investigation of microbially induced calcite precipitation" + + +## Initial and boundary conditions (`problem.hh`) + +This file contains the __problem class__ which defines the initial and boundary +conditions for the biominearalization example. + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../problem.hh))</summary> + + +### Include files + +```cpp +// This header contains the PorousMediumFlowProblem class +#include <dumux/porousmediumflow/problem.hh> +#include <dumux/common/properties.hh> // GetPropType +#include <dumux/material/components/ammonia.hh> +#include <dumux/discretization/evalgradients.hh> +#include <dumux/io/container.hh> +#include <algorithm> // for std::transform +``` + +### The problem class +The problem class defines the boundary and initial conditions. +As this is a biomineralization problem in porous media, we inherit from the porous-media-flow problem + +```cpp +namespace Dumux { + +template <class TypeTag> +class MICPColumnProblemSimpleChemistry : public PorousMediumFlowProblem<TypeTag> +{ + using ParentType = PorousMediumFlowProblem<TypeTag>; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using NH3 = Components::Ammonia<Scalar>; // for molar mass of Ammonia + using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>; + using SolidSystem = GetPropType<TypeTag, Properties::SolidSystem>; + using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; + using FluxVariables = GetPropType<TypeTag, Properties::FluxVariables>; + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + + // We define some indices for convenience to be used later when defining the initial and boundary conditions + enum { + numComponents = FluidSystem::numComponents, + + pressureIdx = Indices::pressureIdx, + switchIdx = Indices::switchIdx, //Saturation + xwNaIdx = FluidSystem::NaIdx, + xwClIdx = FluidSystem::ClIdx, + xwCaIdx = FluidSystem::CaIdx, + xwUreaIdx = FluidSystem::UreaIdx, + xwO2Idx = FluidSystem::O2Idx, + xwBiosubIdx = FluidSystem::GlucoseIdx, + xwSuspendedBiomassIdx = FluidSystem::SuspendedBiomassIdx, + phiBiofilmIdx = numComponents, + phiCalciteIdx = numComponents + 1, + + //Indices of the components + wCompIdx = FluidSystem::wCompIdx, + nCompIdx = FluidSystem::nCompIdx, + NaIdx = FluidSystem::NaIdx, + ClIdx = FluidSystem::ClIdx, + CaIdx = FluidSystem::CaIdx, + UreaIdx = FluidSystem::UreaIdx, + O2Idx = FluidSystem::O2Idx, + BiosubIdx = FluidSystem::GlucoseIdx, + SuspendedBiomassIdx = FluidSystem::SuspendedBiomassIdx, + + wPhaseIdx = FluidSystem::wPhaseIdx, + conti0EqIdx = Indices::conti0EqIdx, + + // Phase State + wPhaseOnly = Indices::firstPhaseOnly, + bothPhases = Indices::bothPhases + }; + + using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; + using NumEqVector = GetPropType<TypeTag, Properties::NumEqVector>; + using BoundaryTypes = GetPropType<TypeTag, Properties::BoundaryTypes>; + using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView; + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Element = typename GridView::template Codim<0>::Entity; + using FVElementGeometry = typename GridGeometry::LocalView; + using SubControlVolume = typename GridGeometry::SubControlVolume; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + static constexpr int dim = GridView::dimension; +``` + + +We define an enum class to distinguish between different injection processes. +We will use these later in the definition of the Neumann boundary conditions. + +```cpp + enum class InjectionProcess : int + { + noInjection = -99, + noFlow = -9, + rinse = -1, + resuscitation = 3, + inoculation = 2, + mineralization = 1 + }; +``` + + +### Reading of parameters specified in the params.input file +<details><summary> Click to show parameters</summary> + +```cpp +public: + // This is the constructor of our problem class. + MICPColumnProblemSimpleChemistry(std::shared_ptr<const GridGeometry> gridGeometry) + : ParentType(gridGeometry) + { + // We read the parameters from the params.input file. + name_ = getParam<std::string>("Problem.Name"); + temperature_ = getParam<Scalar>("Problem.Temperature"); + + // biomass parameters + ca1_ = getParam<Scalar>("BioCoefficients.Ca1"); + ca2_ = getParam<Scalar>("BioCoefficients.Ca2"); + cd1_ = getParam<Scalar>("BioCoefficients.Cd1"); + dc0_ = getParam<Scalar>("BioCoefficients.Dc0"); + kmue_ = getParam<Scalar>("BioCoefficients.Kmue"); + f_ = getParam<Scalar>("BioCoefficients.F"); + ke_ = getParam<Scalar>("BioCoefficients.Ke"); + ks_ = getParam<Scalar>("BioCoefficients.Ks"); + yield_ = getParam<Scalar>("BioCoefficients.Yield"); + + // ureolysis kinetic parameters + kub_ = getParam<Scalar>("UreolysisCoefficients.Kub"); + kurease_ = getParam<Scalar>("UreolysisCoefficients.Kurease"); + ku_ = getParam<Scalar>("UreolysisCoefficients.Ku"); + + // initial values + densityW_ = getParam<Scalar>("Initial.DensityW"); + initPressure_ = getParam<Scalar>("Initial.Pressure"); + + initxwTC_ = getParam<Scalar>("Initial.XwTC"); + initxwNa_ = getParam<Scalar>("Initial.XwNa"); + initxwCl_ = getParam<Scalar>("Initial.XwCl"); + initxwCa_ = getParam<Scalar>("Initial.XwCa"); + initxwUrea_ = getParam<Scalar>("Initial.XwUrea"); + initxwTNH_ = getParam<Scalar>("Initial.XwTNH"); + initxwO2_ = getParam<Scalar>("Initial.XwO2"); + initxwBiosub_ = getParam<Scalar>("Initial.XwSubstrate"); + initxwBiosusp_ = getParam<Scalar>("Initial.XwSuspendedBiomass"); + initCalcite_ = getParam<Scalar>("Initial.Calcite"); + initBiofilm_ = getParam<Scalar>("Initial.Biofilm"); + + xwNaCorr_ = getParam<Scalar>("Initial.XwNaCorr"); + xwClCorr_ = getParam<Scalar>("Initial.XwClCorr"); + + // injection values + injQ_ = getParam<Scalar>("Injection.FlowRate"); + + injTC_ = getParam<Scalar>("Injection.MassFracTC"); + injNa_ = getParam<Scalar>("Injection.ConcentrationNa"); + injCa_ = getParam<Scalar>("Injection.ConcentrationCa"); + injUrea_ = getParam<Scalar>("Injection.ConcentrationUrea"); + injTNH_ = getParam<Scalar>("Injection.ConcentrationTNH"); + injO2_ = getParam<Scalar>("Injection.ConcentrationO2"); + injSub_ = getParam<Scalar>("Injection.ConcentrationSubstrate"); + injBiosusp_= getParam<Scalar>("Injection.ConcentrationSuspendedBiomass"); + injNaCorr_ = getParam<Scalar>("Injection.ConcentrationNaCorr"); +``` + +</details> + +### Reading of the temporal sequence of the different types of injection +Here, the number of injections and the corresponding parameters are defined based on what is specified in the input files. + +```cpp + // We get the number of injections and the injection data file name from params.input + numInjections_ = getParam<int>("Injection.NumInjections"); + + // We resize the permeability vector contaning the permeabilities for the additional output + permeability_.resize(gridGeometry->numDofs()); + + // We read from the injection data file which injection type we have in each episode. + // We will use this in the Neumann boundary condition to set time dependend, changing boundary conditions. + // We do this similarly to the episode ends in the main file. + const auto injType = readFileToContainer<std::vector<int>>("injection_type.dat"); + // translate integer to InjectionProcess type + std::transform(injType.begin(), injType.end(), std::back_inserter(injectionType_), + [](int n){ return static_cast<InjectionProcess>(n); }); +``` + +We check the injection data against the number of injections specified in the parameter file +and print an error message if the test fails + +```cpp + if (injectionType_.size() != numInjections_) + DUNE_THROW(Dune::IOError, "numInjections from the parameterfile and the number of injection types " + << "specified in the injection data file do not match!\n" + << "numInjections from parameter file: " << numInjections_ << "\n" + << "numInjTypes from injection data file: "<< injectionType_.size()); + + // Initialize the fluidsystem + FluidSystem::init(/*startTemp=*/temperature_ -5.0, /*endTemp=*/temperature_ +5.0, /*tempSteps=*/5, + /*startPressure=*/1e4, /*endPressure=*/1e6, /*pressureSteps=*/500); + } +``` + +In the follwing, functions to set the time, time step size and the index of the episode +are declared which are used the time loop in main.cc + +```cpp + void setTime(const Scalar t) + { time_ = t; } + + // We need the time step size to regularize the reactive source terms. + void setTimeStepSize(const Scalar dt) + { timeStepSize_ = dt; } + + // We need the episode index to choose the right Neumann boundary condition for each episode based on the injection data. + void setEpisodeIdx(const Scalar epIdx) + { episodeIdx_ = epIdx; } +``` + +Here, functions to return the injectionType, the name of the problem and the temperature +are defined + +```cpp + int injectionType(int episodeIdx) const + { return injectionType_[episodeIdx]; } + + // Get the problem name. It is used as a prefix for files generated by the simulation. + const std::string& name() const + { return name_; } + + // Return the temperature + Scalar temperature() const + { return temperature_; } +``` + +#### Boundary conditions +With the following function we define the type of boundary conditions depending on the location. Two types of boundary conditions +can be specified: Dirichlet or Neumann boundary condition. On a Dirichlet boundary, the values of the +primary variables need to be fixed. On a Neumann boundary condition, values for derivatives need to be fixed. + +```cpp + BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const + { + BoundaryTypes bcTypes; + // We set all to Neumann, except for the top boundary, which is set to Dirichlet. + const Scalar zmax = this->gridGeometry().bBoxMax()[dim - 1]; + bcTypes.setAllNeumann(); + if (globalPos[dim - 1] > zmax - eps_) + bcTypes.setAllDirichlet(); + + return bcTypes; + } +``` + +We define the Dirichlet boundary conditions + +```cpp + PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const + { + PrimaryVariables priVars(0.0); + priVars.setState(wPhaseOnly); + // We recycle the initial conditions, but additionally enforce that substrate and oxygen necessary for biomass growth are zero. + priVars = initial_(globalPos); + priVars[xwBiosubIdx] = 0.0; + priVars[xwO2Idx] = 0.0; + return priVars; + } +``` + +The injections can be described with a Neumann boundary condition. +Since we have multiple injections durng the whole simulation period, the Neumann boundary conditions in this case are time or rather episode depended. + +```cpp + NumEqVector neumannAtPos(const GlobalPosition& globalPos) const + { + // We only have injection at the bottom, negative values for injection + if (globalPos[dim - 1] > eps_) + return NumEqVector(0.0); + + // We calculate the injected water velocity based on the volume flux injected into a 1 inch diameter column. + const Scalar diameter = 0.0254; + const Scalar waterFlux = injQ_/(3.14*diameter*diameter/4.); //[m/s] + const auto injProcess = injectionType_[episodeIdx_]; + + // We also have no-injection, no-flow periods, which are coded for by -99 or 9. + // Thus, for no flow, we set the Neumann BC to zero for all components. + if (injProcess == InjectionProcess::noInjection || injProcess == InjectionProcess::noFlow) + return NumEqVector(0.0); + + // We set the injection BC to the basic rinse injection and later only change the BC for those components that are different. + NumEqVector values(0.0); + + values[conti0EqIdx + wCompIdx] = -waterFlux * 996/FluidSystem::molarMass(wCompIdx); + values[conti0EqIdx + nCompIdx] = -waterFlux * injTC_*996 /FluidSystem::molarMass(nCompIdx); + values[conti0EqIdx + xwCaIdx] = 0; + values[conti0EqIdx + xwSuspendedBiomassIdx] = 0; + values[conti0EqIdx + xwBiosubIdx] = -waterFlux * injSub_ /FluidSystem::molarMass(xwBiosubIdx); + values[conti0EqIdx + xwO2Idx] = -waterFlux * injO2_ /FluidSystem::molarMass(O2Idx); + values[conti0EqIdx + xwUreaIdx] = 0; + values[conti0EqIdx + phiCalciteIdx] = 0; + values[conti0EqIdx + phiBiofilmIdx] = 0; + values[conti0EqIdx + xwNaIdx] = -waterFlux * (injNa_ + injNaCorr_) /FluidSystem::molarMass(NaIdx); + values[conti0EqIdx + xwClIdx] = -waterFlux *injTNH_ /NH3::molarMass() //NH4Cl ---> mol Cl = mol NH4 + -waterFlux *injNa_ /FluidSystem::molarMass(NaIdx); //NaCl ---> mol Cl = mol Na + // rinse, used as standard injection fluid + if (injProcess == InjectionProcess::rinse) + { + return values; // do not change anything. + } + + // injProcess == 1 codes for an injection of mineralization medium containing urea and calcium chloride. + // Thus, we add BC terms for those components. + // Additionally, we need to adjust the amount of water injected due to the high concentration of other components injected. + // Finally, we need to adapt the injected NaCorr concentration to account fo the lower pH. + else if (injProcess == InjectionProcess::mineralization) + { + values[conti0EqIdx + wCompIdx] = - waterFlux * 0.8716 * densityW_ /FluidSystem::molarMass(wCompIdx); //0.8716 factor accounts for less water per volume due to relatively high solute concentrations! + values[conti0EqIdx + nCompIdx] = - waterFlux * injTC_ * densityW_ /FluidSystem::molarMass(nCompIdx); + values[conti0EqIdx + xwCaIdx] = - waterFlux * injCa_/FluidSystem::molarMass(CaIdx); + values[conti0EqIdx + xwUreaIdx] = - waterFlux * injUrea_ /FluidSystem::molarMass(UreaIdx); + values[conti0EqIdx + xwNaIdx] = - waterFlux * injNa_ /FluidSystem::molarMass(NaIdx) + - waterFlux * injNaCorr_ /FluidSystem::molarMass(NaIdx)* 0.032; + values[conti0EqIdx + xwClIdx] = - waterFlux * injTNH_ /NH3::molarMass() //NH4Cl ---> mol Cl = mol NH4 + - waterFlux * 2 * injCa_/FluidSystem::molarMass(CaIdx) //+CaCl2 ---> mol Cl = mol Ca*2 + -waterFlux *injNa_ /FluidSystem::molarMass(NaIdx); //NaCl ---> mol Cl = mol Na + return values; + } + + // injProcess == 3 codes for a resuscitation injection to regrow biomass. + // It is similar to a rinse injection, but with added urea, which is what we add to the basic rinse + else if (injProcess == InjectionProcess::resuscitation ) + { + values[conti0EqIdx + xwUreaIdx] = - waterFlux * injUrea_ /FluidSystem::molarMass(UreaIdx); + return values; + } + + // injProcess == 2 codes for a inoculation or biomass injection. + // It is similar to a rinse injection, but with added suspended biomass, which is what we add to the basic rinse + else if (injProcess == InjectionProcess::inoculation) + { + values[conti0EqIdx + xwSuspendedBiomassIdx] = -waterFlux * injBiosusp_ /FluidSystem::molarMass(xwSuspendedBiomassIdx); + return values; + } + else + DUNE_THROW(Dune::InvalidStateException, "Invalid injection process " << static_cast<int>(injProcess)); + } +``` + +#### Initial conditions +We specify the initial conditions for the primary variable depending +on the location. Here, we set zero model fractions everywhere in the domain except for a strip +at the bottom of the domain where we set an initial mole fraction of $`1e-9`$. + +```cpp + PrimaryVariables initialAtPos(const GlobalPosition& globalPos) const + { return initial_(globalPos); } +``` + +#### Reactive source and sink terms +We calculate the reactive source and sink terms. +For the details, see the "simplified chemistry case" in the dissertation of Hommel available at https://elib.uni-stuttgart.de/handle/11682/8787 + +```cpp + NumEqVector source(const Element &element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolume &scv) const + { + const auto elemSol = elementSolution(element, elemVolVars, fvGeometry); + const auto gradPw = evalGradients(element, + element.geometry(), + this->gridGeometry(), + elemSol, + scv.center())[pressureIdx]; + const Scalar scvPotGradNorm = gradPw.two_norm(); + + //define and compute some parameters for siplicity: + const Scalar porosity = elemVolVars[scv].porosity(); + Scalar initialPorosity = 1.0; + constexpr int numActiveComps = SolidSystem::numComponents-SolidSystem::numInertComponents; + for (int i = numActiveComps; i<SolidSystem::numComponents; ++i) + initialPorosity -= elemVolVars[scv].solidVolumeFraction(i); + + const Scalar Sw = elemVolVars[scv].saturation(wPhaseIdx); + const Scalar xlSalinity = elemVolVars[scv].moleFraction(wPhaseIdx,NaIdx) + + elemVolVars[scv].moleFraction(wPhaseIdx,CaIdx) + + elemVolVars[scv].moleFraction(wPhaseIdx,ClIdx); + const Scalar densityBiofilm = elemVolVars[scv].solidComponentDensity(SolidSystem::BiofilmIdx); + const Scalar densityCalcite = elemVolVars[scv].solidComponentDensity(SolidSystem::CalciteIdx); + const Scalar cBio = std::max(0.0, elemVolVars[scv].moleFraction(wPhaseIdx, SuspendedBiomassIdx) + * elemVolVars[scv].molarDensity(wPhaseIdx) + * FluidSystem::molarMass(SuspendedBiomassIdx)); //[kg_suspended_Biomass/m³_waterphase] + const Scalar volFracCalcite = std::max(0.0, elemVolVars[scv].solidVolumeFraction(SolidSystem::CalciteIdx)); + const Scalar volFracBiofilm = std::max(0.0, elemVolVars[scv].solidVolumeFraction(SolidSystem::BiofilmIdx)); + const Scalar massBiofilm = densityBiofilm * volFracBiofilm; + const Scalar cSubstrate = std::max(0.0, elemVolVars[scv].moleFraction(wPhaseIdx, BiosubIdx) + * elemVolVars[scv].molarDensity(wPhaseIdx) + * FluidSystem::molarMass(BiosubIdx)); //[kg_substrate/m³_waterphase] + const Scalar cO2 = std::max(0.0, elemVolVars[scv].moleFraction(wPhaseIdx, O2Idx) + * elemVolVars[scv].molarDensity(wPhaseIdx) + * FluidSystem::molarMass(O2Idx)); //[kg_oxygen/m³_waterphase] + const Scalar mUrea = std::max(0.0, moleFracToMolality(elemVolVars[scv].moleFraction(wPhaseIdx,UreaIdx), + xlSalinity, + elemVolVars[scv].moleFraction(wPhaseIdx,nCompIdx))); //[mol_urea/kg_H2O] + // compute rate of ureolysis: + const Scalar vmax = kurease_; + const Scalar Zub = kub_ * massBiofilm; // [kgurease/m³] + const Scalar rurea = vmax * Zub * mUrea / (ku_ + mUrea); //[mol/m³s] + + // compute precipitation rate of calcite, no dissolution! Simplification: rprec = rurea + // additionally regularize the precipitation rate that we do not precipitate more calcium than available. + const Scalar maxPrecipitationRate = elemVolVars[scv].moleFraction(wPhaseIdx,CaIdx) * Sw * porosity + * elemVolVars[scv].molarDensity(wPhaseIdx) / timeStepSize_; + const Scalar rprec = std::min(rurea, maxPrecipitationRate); + + //compute biomass growth coefficient and rate + const Scalar mue = kmue_ * cSubstrate / (ks_ + cSubstrate) * cO2 / (ke_ + cO2);// [1/s] + const Scalar rgf = mue * massBiofilm; //[kg/m³s] + const Scalar rgb = mue * porosity * Sw * cBio; //[kg/m³s] + + // compute biomass decay coefficient and rate: + const Scalar dcf = dc0_ + (rprec * SolidSystem::molarMass(SolidSystem::CalciteIdx) + /(densityCalcite * (initialPorosity - volFracCalcite))); + const Scalar dcb = dc0_; //[1/s] + const Scalar rdcf = dcf * massBiofilm; //[kg/m³s] + const Scalar rdcb = dcb * porosity * Sw * cBio; //[kg/m³s] + + // compute attachment coefficient and rate: + const Scalar ka = ca1_ * volFracBiofilm + ca2_; //[1/s] + const Scalar ra = ka * porosity * Sw * cBio; //[kg/m³s] + + // compute detachment coefficient and rate: + const Scalar cd2 = volFracBiofilm / (initialPorosity - volFracCalcite); //[-] + const Scalar kd = cd1_ * std::pow((porosity * Sw * scvPotGradNorm),0.58) + cd2 * mue; //[1/s] + const Scalar rd = kd * massBiofilm; //[kg/m³s] + + // rprec[mol/m³s] + // rurea[mol/m³s] + // rgb + rdcb + ra + rd [kg/m³s] + // source[kg/m³s] + NumEqVector source(0.0); + source[wCompIdx] += 0; + source[nCompIdx] += rurea - rprec; + source[NaIdx] += 0; + source[ClIdx] += 0; + source[CaIdx] += - rprec; + source[UreaIdx] += - rurea; + source[O2Idx] += -(rgf + rgb) *f_/yield_ / FluidSystem::molarMass(O2Idx); + source[BiosubIdx] += -(rgf + rgb) / yield_ / FluidSystem::molarMass(BiosubIdx); + source[SuspendedBiomassIdx] += (rgb - rdcb - ra + rd) / FluidSystem::molarMass(SuspendedBiomassIdx); + source[phiBiofilmIdx] += (rgf - rdcf + ra - rd) / SolidSystem::molarMass(SolidSystem::BiofilmIdx); + source[phiCalciteIdx] += + rprec; + + return source; + } +``` + +The permeability is added to the vtk output + +```cpp + // Function to return the permeability for additional vtk output + const std::vector<Scalar>& getPermeability() + { return permeability_; } + + // Function to update the permeability for additional vtk output + template<class SolutionVector> + void updateVtkOutput(const SolutionVector& curSol) + { + for (const auto& element : elements(this->gridGeometry().gridView())) + { + const auto elemSol = elementSolution(element, curSol, this->gridGeometry()); + auto fvGeometry = localView(this->gridGeometry()); + fvGeometry.bindElement(element); + for (const auto& scv : scvs(fvGeometry)) + { + VolumeVariables volVars; + volVars.update(elemSol, *this, element, scv); + const auto dofIdxGlobal = scv.dofIndex(); + permeability_[dofIdxGlobal] = volVars.permeability(); + } + } + } +``` + +### Declaring all necessary variables and private fuctions +The internal methods are defined here + +```cpp +private: + // Internal method for the initial condition reused for the dirichlet conditions. + PrimaryVariables initial_(const GlobalPosition &globalPos) const + { + PrimaryVariables priVars(0.0); + priVars.setState(wPhaseOnly); + priVars[pressureIdx] = initPressure_ ; //70e5; // - (maxHeight - globalPos[1])*densityW_*9.81; //p_atm + rho*g*h + priVars[switchIdx] = initxwTC_; + priVars[xwNaIdx] = initxwNa_ + xwNaCorr_; + priVars[xwClIdx] = initxwCl_ + initxwTNH_ + 2*initxwCa_ + xwClCorr_; + priVars[xwCaIdx] = initxwCa_; + priVars[xwUreaIdx] = initxwUrea_; + priVars[xwO2Idx] = initxwO2_; + priVars[xwBiosubIdx] = initxwBiosub_; + priVars[xwSuspendedBiomassIdx] = initxwBiosusp_; + priVars[phiBiofilmIdx] = initBiofilm_; // [m^3/m^3] + priVars[phiCalciteIdx] = initCalcite_; // [m^3/m^3] + return priVars; + } + + // Internal method to calculate the molality of a component based on its mole fraction. + static Scalar moleFracToMolality(Scalar moleFracX, Scalar moleFracSalinity, Scalar moleFracCTot) + { + const Scalar molalityX = moleFracX / (1 - moleFracSalinity - moleFracCTot) + / FluidSystem::molarMass(FluidSystem::H2OIdx); + return molalityX; + } +``` + +The remainder of the class contains an epsilon value used for floating point comparisons +and parameters needed to describe the chemical processess. +Additionally the problem name, the peremability vector as well as some time-parameters are declared +<details><summary> Click to show private members</summary> +eps is used as a small value for the definition of the boundary conditions + +```cpp + static constexpr Scalar eps_ = 1e-6; +``` + +initial condition parameters + +```cpp + Scalar initPressure_; + Scalar densityW_;//1087; // rhow=1087; + Scalar initxwTC_;//2.3864e-7; // [mol/mol] + Scalar initxwNa_;//0; + Scalar initxwCl_;//0; + Scalar initxwCa_;//0; + Scalar initxwUrea_;//0; + Scalar initxwTNH_;//3.341641e-3; + Scalar initxwO2_;//4.4686e-6; + Scalar initxwBiosub_;//2.97638e-4; + Scalar initxwBiosusp_;//0; + Scalar xwNaCorr_;//2.9466e-6; + Scalar xwClCorr_;//0; + Scalar initBiofilm_; + Scalar initCalcite_; + Scalar temperature_; +``` + +biomass parameters for source/sink calculations + +```cpp + Scalar ca1_; + Scalar ca2_; + Scalar cd1_; + Scalar dc0_; + Scalar kmue_ ; + Scalar f_; + Scalar ke_; + Scalar ks_; + Scalar yield_; +``` + +urease parameters for source/sink calculations + +```cpp + Scalar kub_; + Scalar kurease_; + Scalar ku_; +``` + +injection parameters + +```cpp + Scalar injQ_; + Scalar injTC_; // [kg/kg] + Scalar injNa_; // [kg/m³] + Scalar injCa_; // [kg/m³] //computed from CaCl2 + Scalar injUrea_; // [kg/m³] + Scalar injTNH_; // [kg/m³] //computed from NH4Cl + Scalar injO2_; // [kg/m³] + Scalar injSub_; // [kg/m³] + Scalar injBiosusp_; // [kg/m³] + Scalar injNaCorr_; // [kg/m³] + int numInjections_; + std::vector<InjectionProcess> injectionType_; +``` + +the problem name + +```cpp + std::string name_; +``` + +the permeability for output + +```cpp + std::vector<Scalar> permeability_; +``` + +timing parameters + +```cpp + Scalar time_ = 0.0; + Scalar timeStepSize_ = 0.0; + int episodeIdx_ = 0; +}; +} // end namespace Dumux +``` + +</details> + +</details> + + + +## Parameter distributions (`spatialparams_1p.hh`) + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../spatialparams.hh))</summary> + + +This file contains the __spatial parameters class__ which defines the +distributions for the porous medium parameters permeability and porosity +over the computational grid + +### Include files +<details><summary> Click to show includes</summary> +We include the basic spatial parameters for finite volumes file from which we will inherit + +```cpp +#include <dumux/material/spatialparams/fv.hh> +``` + +We include the files for the two-phase laws: the linear material law + +```cpp +#include <dumux/material/fluidmatrixinteractions/2p/linearmaterial.hh> +``` + +We include the files for the two-phase laws: the regularized Brooks-Corey pc-Sw and relative permeability laws + +```cpp +#include <dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh> +``` + +We include the files for the two-phase laws: the scaling from effective to absolute saturations + +```cpp +#include <dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh> +``` + +We include the laws for changing porosity due to precipitation + +```cpp +#include <dumux/material/fluidmatrixinteractions/porosityprecipitation.hh> +``` + +We include the laws for changing permeability based on porosity change according to Kozeny-Carman + +```cpp +#include <dumux/material/fluidmatrixinteractions/permeabilitykozenycarman.hh> +``` + +</details> + +### The spatial parameters class +In the `ICPSpatialParams` class, we define all functions needed to describe +the porous medium, e.g. porosity and permeability. +We inherit from the `FVSpatialParams` class which is the base class for spatial paramters using finite volume discretization schemes. + +```cpp +namespace Dumux { + +// In the ICPSpatialParams class we define all functions needed to describe the spatial distributed parameters. +template<class GridGeometry, class Scalar> +class ICPSpatialParams +: public FVSpatialParams<GridGeometry, Scalar, ICPSpatialParams<GridGeometry, Scalar>> +{ + // We introduce using declarations that are derived from the property system which we need in this class + using ThisType = ICPSpatialParams<GridGeometry, Scalar>; + using ParentType = FVSpatialParams<GridGeometry, Scalar, ThisType>; + using GridView = typename GridGeometry::GridView; + using EffectiveLaw = RegularizedBrooksCorey<Scalar>; + using SubControlVolume = typename GridGeometry::SubControlVolume; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + +public: + // type used for the permeability (i.e. tensor or scalar) + using PermeabilityType = Scalar; + using MaterialLaw = EffToAbsLaw<EffectiveLaw>; + using MaterialLawParams = typename MaterialLaw::Params; +``` + +#### Using porosity and permeability laws to return the updated values +Due due calcium carbonate precipitation the porosity and the permeability change with time. At first, the initial values for the porosity and permeability are defined. Moreover, the functions that return the updated values, based on the chosen laws are defined. + +```cpp + ICPSpatialParams(std::shared_ptr<const GridGeometry> gridGeometry) + : ParentType(gridGeometry) + { + // We read reference values for porosity and permeability from the input + referencePorosity_ = getParam<Scalar>("SpatialParams.ReferencePorosity", 0.4); + referencePermeability_ = getParam<Scalar>("SpatialParams.ReferencePermeability", 2.e-10); + + // Setting residual saturations + materialParams_.setSwr(0.2); + materialParams_.setSnr(0.05); + + // Setting parameters for the Brooks-Corey law + materialParams_.setPe(1e4); + materialParams_.setLambda(2.0); + } + + // We return the reference or initial porosity. + //This reference porosity is the porosity, for which the permeability is know and set as reference permeability + Scalar referencePorosity(const Element& element, const SubControlVolume &scv) const + { return referencePorosity_; } + + // We return the volume fraction of the inert (unreactive) component + template<class SolidSystem> + Scalar inertVolumeFractionAtPos(const GlobalPosition& globalPos, int compIdx) const + { return 1.0-referencePorosity_; } + + // [[codeblock]] + // We return the updated porosity using the specified porosity law + template<class ElementSolution> + Scalar porosity(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const + { return poroLaw_.evaluatePorosity(element, scv, elemSol, referencePorosity_); } + + // We return the updated permeability using the specified permeability law + template<class ElementSolution> + PermeabilityType permeability(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const + { + const auto poro = porosity(element, scv, elemSol); + return permLaw_.evaluatePermeability(referencePermeability_, referencePorosity_, poro); + } +``` + +Return the brooks-corey context depending on the position + +```cpp + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + { return materialParams_; } +``` + +Define the wetting phase + +```cpp + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::H2OIdx; } +``` + +The remainder of this class contains the data members and defines the porosity law which describes the change of porosity due to calcium carbonate precipitation. +Additionally the change of porosity results in a change of permeability. This relation is described in the permeability law, in this case the Kozeny-Carman porosity-permeability relation + +```cpp +private: + + MaterialLawParams materialParams_; + // Setting porosity precipitation as the porosity law + PorosityPrecipitation<Scalar, /*numFluidComponents*/9, /*activeComponents*/2> poroLaw_; + // Setting the Kozeny-Carman porosity-permeability relation as the permeability law + PermeabilityKozenyCarman<PermeabilityType> permLaw_; + //The reference porosity is the porosity, for which the permeability is know and set as reference permeability + Scalar referencePorosity_; + //The reference permeability is the known (measured) permeability, of the porous medium in the initial condition, before the solid phases change during the simulation + PermeabilityType referencePermeability_ = 0.0; +};// end class definition of ICPSpatialParams +} //end namespace Dumux +``` + + +</details> + + + +## `TypeTag` and compile-time settings (`properties.hh`) + +This file defines the `TypeTag` used for the biomineralization example, +for which we then specialize `properties` to the needs of this setup. + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../properties.hh))</summary> + + +### Include files +<details> + +This type tag specializes most of the `properties` required for two phase flow with +multiple components including mineralisation simulations (2pncmin) in DuMuX +We will use this in the following to inherit the respective properties and +subsequently specialize those `properties` for our `TypeTag`, which we want to +modify or for which no meaningful default can be set. + +```cpp +#include <dumux/common/properties.hh> +#include <dumux/porousmediumflow/2pncmin/model.hh> +``` + +We want to use `YaspGrid`, an implementation of the dune grid interface for structured grids: + +```cpp +#include <dune/grid/yaspgrid.hh> +``` + +In this example, we want to discretize the equations with the box scheme + +```cpp +#include <dumux/discretization/box.hh> +``` + +We include the necessary material files + +```cpp +#include <examples/biomineralization/material/fluidsystems/biominsimplechemistry.hh> +#include <examples/biomineralization/material/solidsystems/biominsolids.hh> +#include <examples/biomineralization/material/co2tableslaboratory.hh> +``` + +We include the problem and spatial parameters headers used for this simulation. + +```cpp +#include "problem.hh" +#include "spatialparams.hh" +``` + +</details> + +### Definition of the `TypeTag` used for the biomineralization problem + +We define a `TypeTag` for our simulation with the name `MICPColumnSimpleChemistry` +and inherit the `properties` specialized for the type tags `TwoPNCMin` and `BoxModel` respectively. +This way, most of the `properties` required for this simulations +using the box scheme are conveniently specialized for our new `TypeTag`. +However, some properties depend on user choices and no meaningful default value can be set. +Those properties will be adressed later in this file. + +```cpp +namespace Dumux::Properties { + +// We create new type tag for our simulation which inherits from the 2pncmin model and the box discretization +namespace TTag { +struct MICPColumnSimpleChemistry { using InheritsFrom = std::tuple<TwoPNCMin, BoxModel>; }; +} // end namespace TTag +``` + +### Property specializations + +In the following piece of code, mandatory `properties` for which no meaningful +dafault can be set, are specialized for our type tag `MICPColumnSimpleChemistry`. + +```cpp +// We set the grid to a 1D Yasp Grid +template<class TypeTag> +struct Grid<TypeTag, TTag::MICPColumnSimpleChemistry> +{ using type = Dune::YaspGrid<1>; }; + +// We set the problem used for our simulation, defining boundary and initial conditions (see below) +template<class TypeTag> +struct Problem<TypeTag, TTag::MICPColumnSimpleChemistry> +{ using type = MICPColumnProblemSimpleChemistry<TypeTag>; }; + +// We set the fluidSystem used for our simulation +template<class TypeTag> +struct FluidSystem<TypeTag, TTag::MICPColumnSimpleChemistry> +{ + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using CO2Tables = Dumux::ICP::CO2Tables; + using H2OTabulated = Components::TabulatedComponent<Components::H2O<Scalar>>; + using type = Dumux::FluidSystems::BioMinSimpleChemistryFluid<Scalar, CO2Tables, H2OTabulated>; +}; + +// We set the solidSystem used for our simulation +template<class TypeTag> +struct SolidSystem<TypeTag, TTag::MICPColumnSimpleChemistry> +{ + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using type = SolidSystems::BioMinSolidPhase<Scalar>; +}; + +// We define the spatial parameters for our simulation. The values are specified in the corresponding spatialparameters header file, which is included above. +template<class TypeTag> +struct SpatialParams<TypeTag, TTag::MICPColumnSimpleChemistry> +{ + using type = ICPSpatialParams<GetPropType<TypeTag, Properties::GridGeometry>, + GetPropType<TypeTag, Properties::Scalar>>; +}; + +// We set the two-phase primary variable formulation used for our simulation +template<class TypeTag> +struct Formulation<TypeTag, TTag::MICPColumnSimpleChemistry> +{ static constexpr auto value = TwoPFormulation::p0s1; }; + +}// We leave the namespace Dumux::Properties. +``` + + +</details> + + +| [:arrow_left: Back to the main documentation](../README.md) | [:arrow_left: Go back to part 2](mainfile.md) | [:arrow_right: Continue with part 4](fluidmaterial.md) | +|---|---|---:| + diff --git a/examples/biomineralization/doc/setup_intro.md b/examples/biomineralization/doc/setup_intro.md new file mode 100644 index 0000000000..e17456cd4f --- /dev/null +++ b/examples/biomineralization/doc/setup_intro.md @@ -0,0 +1,17 @@ +# Simulation Setup + +The setup for this example is based on the initial 100000s of the _column experiment D1_ described in [@Hommel2015] and can also be found in Section 4.2 of [@Hommel2016] under the name _column experiment D1_. +We here only consider the "simplified chemistry case" in which it is assumed that the precipitation rate is equal to the ureolysis rate to simplify the chemical processes considered ($`r_\mathrm{prec} = r_\mathrm{urea}`$) (see Chapter 6 [@Hommel2016]). + +The column is considered as a 1D domain with injections of various aqueous solutions at the bottom (Neumann boundary condition) +and a fixed pressure at the top (Dirichlet boundary condition). +The various types of injected fluid compositions are read from an additional input file `injections_type.dat`. +Depending on the injection type, the `problem.hh` adapts the composition of the injected aqueous solution for the bottom Neumann boundary condition. +Further, `spatialparams.hh` is an example for spatial parameters dealing with changing porosity and permeability. + +The subsequent file documentation is structured as follows: + +[[_TOC_]] + +[@Hommel2015]: https://agupubs.onlinelibrary.wiley.com/doi/full/10.1002/2014WR016503 "A revised model for microbially induced calcite precipitation: Improvements and new insights based on recent experiments" +[@Hommel2016]: https://elib.uni-stuttgart.de/handle/11682/8787 "Modelling biogeochemical and mass transport processes in the subsurface: investigation of microbially induced calcite precipitation" diff --git a/examples/biomineralization/doc/solidmaterial.md b/examples/biomineralization/doc/solidmaterial.md new file mode 100644 index 0000000000..95e72dc28d --- /dev/null +++ b/examples/biomineralization/doc/solidmaterial.md @@ -0,0 +1,258 @@ +<!-- Important: This file has been automatically generated by generate_example_docs.py. Do not edit this file directly! --> + + +| [:arrow_left: Back to the main documentation](../README.md) | [:arrow_left: Go back to part 4](fluidmaterial.md) | +|---|---:| + +# Biomineralization - Solids + +The main idea of biomineralization revolves around +biologically-induced mineral precipitation. +I our example, it is about precipitation of calcite +due to urea hydrolysis. +The resulting overall reaction equation is: + +```math +\mathrm{CO(NH_2)_2} + 2\mathrm{H_2O} + \mathrm{Ca^{2+}} \xrightarrow{urease} +2\mathrm{NH_{4}^{+}} + \mathrm{CaCO_{3}} \downarrow. +``` + +To describe the processes, the minimum set of components is: +water (w), dissolved inorganic carbon (C<sub>tot</sub>), +sodium (Na), chloride (Cl), calcium (Ca), urea (u), glucose as a substrate (s), oxygen (O<sub>2</sub>), and suspended biomass (b), +as well as the solid components biofilm and calcite. +Thus, there are many components involved and keeping track of the components and their interactions, +necessitates a sophisticated handling. +This is why the material folder in this example is both separated from the regular material folder in dumux/dumux/material +and also documented separately. +For further specialization, the overview over the material subfolder is split into solid and fluid, this description considering the solids. + +## Solids in the folder `material` + +As this example is about biomineralization involving many components with complex inteactions, some specific solid material files are necessary. +First, `material/components/biofilm.hh` defines the solid component biofilm, which plays an essential role in biomineralization by providing the essential catalytic activity for biomineralization. +Second, as biofilm grows or calcite precipitates, the volume fractions of those non-inert solids change, influencing the overall properties of the solids in the system. +The specific solidsystem `material/solidsystems/biominsolids.hh` gives the relations on how to +calculate the resulting average solid properties based on the solids volume fractions. + + +The subsequent documentation is structured as follows: + +[[_TOC_]] + + +[@Span1996]: https://aip.scitation.org/doi/abs/10.1063/1.555991 "A new equation of state for carbon dioxide covering the fluid region from the triple-point temperature to 1100 K at pressures up to 800 MPa" + + +## The biofilm component (`biofilm.hh`) + +This file contains the __solid component class__ which defines the name, molar mass and density of biofilm + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../material/components/biofilm.hh))</summary> + + +### Include files + +```cpp +// including the base and the generic solid component +#include <dumux/material/components/base.hh> +#include <dumux/material/components/solid.hh> +``` + +### The biofilm component + +```cpp +namespace Dumux::Components { + +// In Biofilm, we define the properties of the solid component biofilm +template <class Scalar> +class Biofilm +: public Components::Base<Scalar, Biofilm<Scalar> > +, public Components::Solid<Scalar, Biofilm<Scalar> > +{ +public: + // the name + static std::string name() + { return "Biofilm"; } +``` + +### The biofilm component's properties + +```cpp + // The molar mass, which is not really defined for biofilm. Thus, we read it from params.input or use a default of 1. + // Based on a cell mass of 2.5e-16, the molar mass of cells would be 1.5e8 kg/mol, but biofilms are more than just cells and such high molar masses would lead to numerical problems. + static Scalar molarMass() + { + Scalar molarMass = getParam<Scalar>("BioCoefficients.BiofilmMolarMass", 1); + return molarMass; + } + + // The density, or rather the dry density (dry biomass/wet volume), most of biofilm is water. + // It is typically highly variable for different biofilms, thus we read it from params.input or use the default value of 10 kg/m^3 + static Scalar solidDensity(Scalar temperature) + { + Scalar rho = getParam<Scalar>("BioCoefficients.BiofilmDensity", 10); + return rho; + } +}; + +} // end namespace Dumux::Components +``` + + +</details> + + + +## The solid system (`biominsolids.hh`) + +This file contains the __solidystem class__ which defines all functions needed to describe the solid and their properties, +which are needed to model biomineralization. + + +<details open> +<summary><b>Click to hide/show the file documentation</b> (or inspect the [source code](../material/solidsystems/biominsolids.hh))</summary> + + +### Include files + +```cpp +#include <string> +#include <dune/common/exceptions.hh> + +// we include all necessary solid components +#include <examples/biomineralization/material/components/biofilm.hh> +#include <dumux/material/components/calcite.hh> +#include <dumux/material/components/granite.hh> +``` + +### The solidsystem class +In the BioMinSolidPhase solid system, we define all functions needed to describe the solids and their properties accounted for in our simulation. +We enter the namespace Dumux. All Dumux functions and classes are in a namespace Dumux, to make sure they don`t clash with symbols from other libraries you may want to use in conjunction with Dumux. + +```cpp +namespace Dumux::SolidSystems { + +template <class Scalar> +class BioMinSolidPhase +{ +public: +``` + +#### Component definitions +With the following function we define what solid components will be used by the solid system and define the indices used to distinguish solid components in the course of the simulation. + +```cpp + // We use convenient declarations that we derive from the property system. + using Biofilm = Components::Biofilm<Scalar>; + using Calcite = Components::Calcite<Scalar>; + using Granite = Components::Granite<Scalar>; + + /**************************************** + * Solid phase related static parameters + ****************************************/ + static constexpr int numComponents = 3; + static constexpr int numInertComponents = 1; + static constexpr int BiofilmIdx = 0; + static constexpr int CalciteIdx = 1; + static constexpr int GraniteIdx = 2; + + // The component names + const static std::string componentName(int compIdx) + { + switch (compIdx) + { + case BiofilmIdx: return Biofilm::name(); + case CalciteIdx: return Calcite::name(); + case GraniteIdx: return Granite::name(); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + } + + // The solid system's name + static std::string name() + { return "BiomineralizationMinSolidPhase"; } + + // We assume incompressible solids + static constexpr bool isCompressible(int compIdx) + { return false; } + + // we have one inert component, the others may change + static constexpr bool isInert() + { return (numComponents == numInertComponents); } +``` + +#### Component properties +This simply forwards the component properties (name, molar mass, density). + +```cpp + // The component molar masses + static Scalar molarMass(int compIdx) + { + switch (compIdx) + { + case BiofilmIdx: return Biofilm::molarMass(); + case CalciteIdx: return Calcite::molarMass(); + case GraniteIdx: return Granite::molarMass(); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + } + + // The component densities + template <class SolidState> + static Scalar density(const SolidState& solidState, const int compIdx) + { + switch (compIdx) + { + case BiofilmIdx: return Biofilm::solidDensity(solidState.temperature()); + case CalciteIdx: return Calcite::solidDensity(solidState.temperature()); + case GraniteIdx: return Granite::solidDensity(solidState.temperature()); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + } + + // The component molar densities + template <class SolidState> + static Scalar molarDensity(const SolidState& solidState, const int compIdx) + { + switch (compIdx) + { + case BiofilmIdx: return Biofilm::solidDensity(solidState.temperature())/Biofilm::molarMass(); + case CalciteIdx: return Calcite::solidDensity(solidState.temperature())/Calcite::molarMass(); + case GraniteIdx: return Granite::solidDensity(solidState.temperature())/Calcite::molarMass(); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + } +``` + +#### Averaged solid properties +The overall solid properties are calculated by a volume-weigthed average of the pure component's properties. + +```cpp + // The average density + template <class SolidState> + static Scalar density(const SolidState& solidState) + { + const Scalar rho1 = Biofilm::solidDensity(solidState.temperature()); + const Scalar rho2 = Calcite::solidDensity(solidState.temperature()); + const Scalar rho3 = Granite::solidDensity(solidState.temperature()); + const Scalar volFrac1 = solidState.volumeFraction(BiofilmIdx); + const Scalar volFrac2 = solidState.volumeFraction(CalciteIdx); + const Scalar volFrac3 = solidState.volumeFraction(GraniteIdx); + + return (rho1*volFrac1+ + rho2*volFrac2+ + rho3*volFrac3) + /(volFrac1+volFrac2+volFrac3); + } +``` + + +</details> + + +| [:arrow_left: Back to the main documentation](../README.md) | [:arrow_left: Go back to part 4](fluidmaterial.md) | +|---|---:| + diff --git a/examples/biomineralization/doc/solidmaterial_intro.md b/examples/biomineralization/doc/solidmaterial_intro.md new file mode 100644 index 0000000000..8e223b463d --- /dev/null +++ b/examples/biomineralization/doc/solidmaterial_intro.md @@ -0,0 +1,38 @@ +# Biomineralization - Solids + +The main idea of biomineralization revolves around +biologically-induced mineral precipitation. +I our example, it is about precipitation of calcite +due to urea hydrolysis. +The resulting overall reaction equation is: + +```math +\mathrm{CO(NH_2)_2} + 2\mathrm{H_2O} + \mathrm{Ca^{2+}} \xrightarrow{urease} +2\mathrm{NH_{4}^{+}} + \mathrm{CaCO_{3}} \downarrow. +``` + +To describe the processes, the minimum set of components is: +water (w), dissolved inorganic carbon (C<sub>tot</sub>), +sodium (Na), chloride (Cl), calcium (Ca), urea (u), glucose as a substrate (s), oxygen (O<sub>2</sub>), and suspended biomass (b), +as well as the solid components biofilm and calcite. +Thus, there are many components involved and keeping track of the components and their interactions, +necessitates a sophisticated handling. +This is why the material folder in this example is both separated from the regular material folder in dumux/dumux/material +and also documented separately. +For further specialization, the overview over the material subfolder is split into solid and fluid, this description considering the solids. + +## Solids in the folder `material` + +As this example is about biomineralization involving many components with complex inteactions, some specific solid material files are necessary. +First, `material/components/biofilm.hh` defines the solid component biofilm, which plays an essential role in biomineralization by providing the essential catalytic activity for biomineralization. +Second, as biofilm grows or calcite precipitates, the volume fractions of those non-inert solids change, influencing the overall properties of the solids in the system. +The specific solidsystem `material/solidsystems/biominsolids.hh` gives the relations on how to +calculate the resulting average solid properties based on the solids volume fractions. + + +The subsequent documentation is structured as follows: + +[[_TOC_]] + + +[@Span1996]: https://aip.scitation.org/doi/abs/10.1063/1.555991 "A new equation of state for carbon dioxide covering the fluid region from the triple-point temperature to 1100 K at pressures up to 800 MPa" diff --git a/examples/biomineralization/img/pore_scale_w_processes_named.png b/examples/biomineralization/img/pore_scale_w_processes_named.png new file mode 100644 index 0000000000000000000000000000000000000000..3d68ec017c4429881930d9de374f1156e0ba7985 GIT binary patch literal 154841 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%0D!8g<ACyQW*nAD0&?|s$I3U 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%0Am731ene zsHIBQo=w%%i5Y$9F$5VDgf%rjIcDGh3{!+z6*xg-h{-sajX5&eZN1_=jywo6^c`yk zm#RVw+8d>B{^2WL%xit%sKf2jR%IFB$iDqSH|C~J@!D~)CHI~V8fq??LW^+)u86XO zVVwa~1fy#wquZaF>H}db=#cw^hYMc3{W8RzyA|YS#<mK3D=K}HpjW4Z)wPfD({5+u z)UNvKuyGmnzWyNWs$;h(<Ef3NG|`k?h7gD(%xD9z=iSncj&8{iBIN(QUq&|L4madw z*Y`zD#b3DHXQRD*O(8Gy_1Wslr@Z#)*<fd$-534Wxd!6H@krvPr7VxVA)emGa#>dH zxDNlGQq)Wd^~>^fj5);hluVV2dfF2G@BHo!i97W=!Zoz;Re#)ZwCI&c){D2rxX483 z`#V1pFGsK4zZ#vsDgQB6RF41({we*e2d^$(Ij--3MEx^Pg8UTS{AU!yFM-iyx(fT1 zc+SFGT4VQ9INw=r^j%0#-5Dv6hf@};6XLn&jCDU(UBFsS=)8KX`T=d{0nZPF=VwbP z7}kDJhAHX?Y{$8Eu#X6dEIX%!%OCE<EH8YjLs<bLMWX%E7{N*XG6MMtq+e;#x{N*N z|6W!^Sw1+vY}$W=#=CLRnPjYY@jAO#i%?YMyoF)8<y4u3XiUB!+VM*&n_;o%R(^AC zn`6Z`C5jy|Ih)?i03?3SOPlbFq5OvuQ-!?8!;Bj<x^CHOp_w(=g)+jnHG7F}S;(6( z$wjtg81*4mxl<u3?Fma={GVy<rv<Lc^aeK>1)47@M$lVCwS9-rsZyloN)b5if^}xg zf5qZ7Q?mSA@#<J4D;GryC1wpiMfP4z?G;#yI~_Br?d-XXSA9(n$_dW1J&;33wLCZ= zP@ypF=1JPmw3|5TQU;8zLd4eK6b<m?bkhpi6kh`2hC)cwBp@Hs&>CACsfG1CyM9w* zC36h7sT37lmyaX`QNt#bm}=ypzWfrBUDUKMCXgO<aEl7uk4;UQbBM&xbDxmC_p7Bb z*(|YBqT4@q^;H4lUg94-XU%!|<pTr&K@t@Z3Fuy@(VG477@gkxe*5g3dR!XW?n*aD z4P^DgCfm`DrgJepi>U|wQr^h}o`6$ACJyyg3tq0M$QEW+&-+@zn?=bhaQ5))<&l|% zkS%C0nQXmp{sl1s8+s2496i$cp+(ha_dSjj%==8Pw0bhF4>##x#l*evo^3&O{omSl z-D6I?L;cM+Q9pCwv=|f0V0Q>+GY*=NktD)NvhZfM->w7ogdR^}$iCNH-Btc_89cBj zuzo|?thV3yW%8m;`$}X7F5a?X?x$ZLi_%0~A)t$IetS`|)pci1jhEw$QN#zF6ei-o zNdnxt0@Vr7uBp5<&h6KNvWd46S0<k9Xxs-4v!n`FN$%L86rmU(1n}4rK70i1>8JZ^ zO3PRwZ-<x6cjE}bQ;<odg35Pie`tIEUB#l9)0(e^0@G1`=Fh8VN$FmXdPIqaeCg32 z6FV<)zx7{i)EfG`_OPY5_lef>*{0ENKj1DxyKGM}|JTjzGaPyjQhWlx+;jPPD{)s< zH*^GglKfi#75yn9%HGx+|H;S5Bk<n)H!@~zQu+<lclozZ+#->14e?7#Tk7iC)|r|U z3=a{XW@_v9O756`6{z;gvN7A!wDQc0u`|s4yvMcgz}I8_(Wmb{?`n8jP!fL(;HoV8 z5dV8k{(Qr?1^x1<SKKi#Uc5NzE?6IO{1|Ttjj`m(h*Tx!r#CT5*>@6V`1vbpSvb2s zNU?uC(*K#%QP|;hAqPq0H6gisqm(u|d`}*2#hoILE->=jb9JNBed{nn!COE+x1(0T z9^kGR618*mt*}~72^Vv!=SB5%@KvBC=uX_^KXN9*$#B_^y5rjQw;Gh>>&)N3hh&5> zbY+}}pCQsG%{7%iDjoYt?D@aVCkL`q%V^jV6?Hh$jt6Id7YucB+)tX}f6?;q;Um!* zmhb3B0)4c+m8BjL!9VW*QN35ZpF3m1#LUbb#4bxu_AiCqBL*VhXJ@aRtG_9lca7a@ z@bOv3ca(0aN|%XDdFV0aOsv?`%=|YGXH1_CG-Ef*-!=&Zb-(R7>1IY<!->o!UF>~1 zV%2v?uA&m<juAcMeaUNe?(_Wf?dN<?Pf}ZKr0jfp#8J1vSsj25sJs&+b;k=s6ou*z ztVW3s|8@~*RSyyw>|(;+VP;OP);w!0`9;#>^GGrFMDh2*CscY7GbS)x=I{s4Z_m1r z-~Y<|Ou^l3>Wyaa1d}+1#=R>ejHxJw>;?BfFIJ8n&Aq;2am-~#X|B;221H`*nL%>y zoCY<_WGd5#cdZrqi&6)#VtG+lyD@0)%&4B<>-x}h$9TE1Vwwh2?eC6H%f?6@q37H> z5t;A{{&~mCJYnX@iqyr@55W<?e-xw_3Bo5-c0Qvq{#QB^-krA8^RCW_Zr31H7fuHL zJDo;gKKl+G*^i@_KC5U?oECLBU4Po=VGVz)S^tx>wN<+wsclTDVhtEYi`9z_DwkBZ zb5n1vO<Xa4m~xewxjSq~GzGta?1<SnRDIbWy)Hcul+q!~gC{mVRV;hS9dK+r;)hv- z;aLik<L9Q%9oMEMxlf^WGhx}C`DFd8%0UI$J9i>kdTB4n!(bvwzrJ@mnR`uGKIzek zM=vLsQ(&7&u<uE_(%gx(zNl`?`UJx<5y|@6;A@K6nj?HFO?PgAao@u25fe^t<OIAZ zQ6<SWZMZgXbJm2cNh3%EUWsh-3hW$zHA<KKpNw~6B=2~&T*so);$`aQEVh1i25R=A z%X!)1VL4N?Z?5$9hXje(opa-T2dkL6qZ1@@>C=f=8OC3o9WQy040T~Ndp`!*4R)b8 zb7f=hh?EumrZ&BX<%Vt7Dswtp@JDlz(2yf)@^m%~M!VvNCeJ&=$3id1=#foflHEWv z*o9$FoEjdcg$@1nJuK?rzM%&F_AL$mJ<Dw#S!8%YL{Z0?PcpqWP^tJv?h5lVM=D&| zILGj8Nc2sYyRO5O{@l#D8d3Nkcd(b;w7&g&<QE?+HZjpc?&#NRPpO28e=882n1!m< zUFo+;oL+K2eX&A$l;eyI4Kp9|Qr&m6xA|K|LerQ&gmvBMHSGw3p<Ww^yWdP?EX_X0 z`;_$3R^>|?_sG=6yuz#!w|$2TCbUyTg|}tzzyrD^QH-|LyN|ie6=3(2yeMUOwX1hu zbmNM0?QA3i&W=+Ko*qqSbZ6=KxmoR#5hw3mI(OZ1vx>fGg_ZT(RIp-M3Z)xtPA@u5 z1-z7j#!*qz2f~!6)>ZIJ>W=XjkX^zDyX5_(&es&R#sz^yWW>^+3_|ODgf+x^N%MSo za~yLYxrn|kbH6;7O=Ti}ZdUnXY3xU{#?W&^+w$Xd`Pp~jWKcMywq0TF)@GmkO>uXk z$>@191&f=sg1z*zFWKxje`o}#b%&K2rX@0!`)Z{M%%xcoOL=eC)6`;4UZ1NK`6^V8 z`&oYEH}|lpT$+`;V|3?i{Uw4H)`sh~f%3%lor_Xu+E-m9-n7U1_6)lF(*_9NwUBs) z?3`Znrao3|b)to=5FD%TpA{OPY2!iFCmQWcgv)v%PYxTo{<J6z^I~bPQ-YcHOW3y7 zRmA}o+b^!MT~=;*RoT7AeYXCl<NZrIH~$Y+?*UJB|Nf67l#!4bk|SkgX3xfvQRJ9e zNl5mV?95|lm1NYh_sEtJp_D}S9x2I4gv|f-KDs~O-~T*3?#F%KocDRZU$1LCujlo= zUMKKW3M1_G!*1CBez}^tyNQ1g3$V8}RdNgeSUSrUd6(Q$IEJHVF7qQ|m(&zl9*rT+ zVU=gzF7u#zNnkDWnybZ_*E-xC5gSD9CAaA72xvdQ%D(84n0^pOEbMh&W5mTkI4O>f znDOrAf%pM|3vTOJ0fijaX0BV9C}tyS<8YJ}I=zphZJE2%!cTMeIvkP_D<JfuSD9XV zx}!vA376kYracujZ_J5&1Wxjv<K=#gj+SJ^Q=!iI7ij%^8|p6#*E}?BF!ohGHH@Rn zH#t34eR}F+welTFvvLC&Cm|B|%n=L?aabrFDa>Usrj6w-B;oLO*;zqCFfkC);IksF z(MM`BM>Yy`b=|xW`$uP{5wz>1zo2d}T$UlnMrMOeyGwF`k|rSTk$q2noXg_<W>b$K z<0KnJG2Wh#BQ-&-HDT}r|DswUoPxUg_y58Z4FRcka(Tw(#M)KOp*FtrurFBbI*)&h z=x{MRC+<NMcL_vh`1&)IsuP<nU!OBH$Vhci%A|NOs=qGyD@9GJnGiDsUgFtG<9Dh6 z@9L0<31)c|8fonyHil^7Z&^C~+x@0Lcn43rz|~1x;H6P%M}NCM;CzuW?g7tvohjl) z4|<n*y&@T%Q-kOCrgwPfG9X#9A;zP}q+xNHXTg!0{SK8+(p5jrwS=Ynm*}NyxkZpD zjG_9>`y#HY>tr5!1c~%N(&FeQm@F<O5<-}N^H3Xi+-1I1HYCn>ahqDz;A%M5|KR>! z3GVtC)QCT!4uj4#CF}>1wB8S~zaI(B)`Jl0egnBO&D>*ifh*Vbj>WeOm~-IP^O)V| zE?TKApGxVF4WVv1OSE;2hWL)6SYhtp1zA<*R&Er@WW_$!T=v5r3u+p>W`9-x$`cy> zyKxXU&}eh&dqZLrdB|#2Y{(l1UxX~vseh2S^%Q?END@O9AB%N1=2>ud9z|!S>KN9} z(_*m%rC#CK^$0?G{7qp(D#&9$mR@{;>WqWjoBy&G+!gmA410{=7kjnK5_rJ*Lok3w zGndcms8xL^n?euM+uQ3|$P`pL%gPO)JRe}Or4Yse;vlh-Tj1XtcrSXLzq1+{E)ZD$ zE}FD|@S1RIG~$dl=!bJohEI8owWq(iquDBP4??lWCM(L3`}zQx1@8eymTo6n7E>=l zq6M$28fye_0I?F@QLJ+Jj?O%qVD^})X5y06s#cOIV}l|3p+&!LblZLb_fOf=n|rd% z@Rx`ePSB%JklI(T^td7G`2Oxu{DWhX!`q8r?8@w5MqEzmZoXK2{}JLAH}ibEi^HPQ z`%BgH<tm(jjtHJ=lO@8Ix{G2bxNxuOoCeIw4tP<YwiDQQGAk)wE`Pv1c!Xc9Vb}`k z4u2#UV7ZTT9T_i8^*VWO(zQ2+=a|5q9Y;ai?-O*!@>ZF2ZjzKYM`rg`F`<E5{uz5% z;t0u~G#)GGu8cn|o3Yk>y^>$ViroF~Zx?rUn%Lq)AHIan#B%N<SI26ayPdeZ<LEFF zBM5$~Gir6)!a<{V1Vb<R2=6Z{a@pjm`6XtG=x1aS)trDS1Ez>RPLM&QEu%P@cG{{X zzeu)7oeza7^7*nYbBp2%SPx3`?Z2BRA$dch)4r}h9tcrV#lu2=P9TqkoPdZ)iGZCW zk{MmfR6qW|41OI=j)YSuG1E4#I$9L&>mr}FrP>V?iXWdVQ7F~Rs~RPX23mRLbw`;s z=E!7D)nwCw?O6m@o(W<MFOEP=hNJj0;1~cfL=l$S;LK6R|MIiB&;frd52}*}j|bq< z?`){&*2#$-5yV@G>WA-$y{nQR;YI%Y@D(^@S<6*NjKXE&F$mnk8+hKOj!#Fn%)fM} zEfv!@TtD<7aISx_FM;mWKaX*K4<4XW!bVRZ6j*tulj6*7e|IXu;w_4L9Mz#=XHr4* z#t4}Hvm|m|BQ=%r?&DJ{gu7JD{N8Npgf=hXY)FYJ>>+9qp)OWXMArtf;mZ&-&oPN= zGq8snjaF?t;7QL3H7xl$G~sOTaSl}CE!hl~eZRN*={?FCkO*8$1H-Y-WQUK3qazV) zi~&ZM`<TGHi5$)8)r$mAq&+=;Cv%6=6Eog%JAu2uNd9pmtY$Mz+8S)B1yWJ;+F2B; z%V`f5QH*s}3BSs?L)1ZkQ&NWhG&`x#_d>=77Ieb70x#<BhB9_A-tuWW0x*}-x}%u= z)IIJcsUjw8s7Wls$F<N2HircVO%}&Yq0&^tbC2E;u2C|bj9*(aW_suqBATq172jPA zOym3Il1kU&z#mQ;`N3lx|MwW8MZT5MeXRv1D9B;5R!c461w0#;H~R^PJJe0gE-5D1 zAo*e8^o^a>dn?3%v?8F4Ly2&^YtUedr%xR&BQF@|8)vf*A?ZsSYDXrA**EtuPl^UK zS`F0*9LK1`620)qm6%;hYB&i`L1S;vi0r!g8T_5l$mHTZN%XEuAMT225sy2DW{wI; zB&*)fTus3|+gc&}cPjofJJGL>V(%x~-Ey(cO4Cu8{wj+N^=2f2{XdudXM)F<MnyLq z<eDB3T~5n9*GYD7B`AM%)IHsAGYqRNxA+2uGy3Of%2(+>dA7M_d!PPOCxTU$ah}~H z!clNSRn+k(2g|MZ&w+ZAdXp5u@@h>jzD&+C6RbQ!Vs}^va(_Di-QSb@Z21<?K2f52 zW9Icz9}^NZZ7syGT~a$WYEYTzK=vA*wzuv7ch#ZBb_TlPP78-7zd&PcwCCo$LPN+T z;g(mS+fBme^z7Oq@X#Mfv}vQ_{l8Btzq3gb{g<;-@xvPu57N3-g}tr=`s#tbU5i3D zjVx=3!ASjD58h1r2Kl_F|DK{V0ByF9RrY(me7WW(Tl-hXl@LsdE@*pxc&vYd6ISPQ z!Aw<2AVvQ_Z}B1LY<Ln#L79hjefym`c&E?QXhkaOg@fmZrO>pJM`CSu#Uq_%Lw<=i zH)&{M^K16$Xy!!zWgmSFb3VOA+)R=JY89+vcf07|qWq#PRnr61vX5=F0qb`9%9%bN zW{i?u3v!uN2<ImI3-I+!0E(m$QxmutA>fag3Af3jeD7Hn^f+^UK*sn}#iz;%Pcz-J zUoXE2+AOkJA|eQSJ_-gF`d;FAgeBd%Nm23u3ZcK*G)@C0cGYEE8<XI4*0bB-IY0k- zj)lrn83Qce>_io-k^i9FF-w>Fd6BT+?aq#b=~RDOex4pHZBJkgEwK79*^`^WfH`_F zK}&<#D1#j7%%-%9&)pVbU6_Iz2KtU&8jBdX#%5k?66>-WZwitBRXbw@y`#dX|9_tv z+bga8puPC44=x4UJG&Oy;<F%ByqR+Cvqb9p?1oqs_x>Ii3e{Ql+m3Zb30)g?2of+1 zOE$KbV~dP7HW2@YL*|vi(_k&5PsqfyuB0meT~+e!<Md>Nr4k>~^SJIx24KPT(qTkb zRIGAt6ZX5k`C^_njM74?#{Z{W&g#v{;q(oruDSt%AyxnY!LZ2fNR3NGgK7V7jh^); z3Bhh<m6@UGCShUH9@)P>Xy1<vm_!*$4W>b`AAdL@f{*l(cq`L<bhrZ~MlvDTxX1TD zve)NgMP>m=z;m7p^}2X_uxog%cxy8ei&Z8@g7URH48{b2`UJ`kiJ{=Z;%2&>FA&!{ z!VAa{cp?RmX~t2!+RV8|V%hEs{J#IqAA79k9IW2O*av{vB>cI%=1t}~a|yNrK! zGbA-&$RWZfxSdwg|L$bVz8uA(PUt@@^JuBHf&1W-Z^A~(Jxh8TyO$MII-ezqM#$W8 z-qh=Av#p<Iw@TM)^8Fqx7)Xu80DjIJdy6=r4}=czkT|#mWB{H}HQmiKKpGK4M!>$h zy>3q(tFA5i)6}J}vltF7KQVKE)1t?M_D6EXrvwHwVYcFPlFvsKS5Rbh?H8^jp^wG0 z_}VLqE#CL1@5fy~i<7;_e=H0*6>c+pM2UNBFUckRHyc4mP@a}`x?RA|^L_f}j<;EN z%S9yNGD8UPmhPh{@e-O9%l^u0ZMLZ`AAZJPYP~hagfmjVZ711OiEBh7SRD|Wu`~@F z_k-|3m(U5q(OXdGs9r&sAG2*hCP-OO0aV?S5wqWB`{4357u^+I!_amAw|Qa|Ibfm9 z)7G>N1ql|uky8xGLZOX8({yKo^?ho{7?Bd*8`a6V2!@ey2Qj_`SZ+eV6Nz?q?8|eW z+Gsj6mp<M!;?2DEiL2(s^4;8HIaITr-B!arN!C)oGazhT*LP<*55=wuiPm#P>Snr6 zGvex~0RMSo4xH?-*A}YC?&cp}{8DTu8)dMBN6Ry8V^s;JF+%mjss*|hHUGRlG__;Z z^t;nm!^va?6Jr}jh&Da-YWkvq6vyt!&MpDJD778|*r4;s+$fMvfb7WeL5s|`zGPWv z<lBW5BTn4dOF9ig8xDGmyaAQK6x`+Rmj@e`MbAs$>3*ur`F-P9eA3l)>(S>|(|Ju9 zX<}*Xf1E&|kR}O|hj7GIa(6e0XsmMH>86!Ngmb4~ILbH$=yu0pv3vXH<nUND3d(`2 zm-N538J@CT+hP5qgihv_C<C++iO(+>B24sO4pdbC>G%`55I;k-6D0l@yB!8P3`bZi z9o-z4^1NwV%nfYRxo9sFaNG!=kORKe=CbntyHIcSOBObsoQzxpI_OnNnW9tIa~a-} zV5Lln|Jwp$pM~fFHC<yqrJXqz{;Qb;^0W<JX!ARG{^b!?nI3PJw16}7s)}+mbpJF* zU?VU8_*&C_kz8T0g!2gbb~du+-a`+K=55BNtpi@w8m~{kxbOw%weZuf8;jf+H&S)S z;z6P6nT6c8lZnOox;8RsbJ?9!hIE6C(@6><adT5d5E9!Jd@L2b(=a`AQyMG>KA)5f z+%*(Sxji?r?_Q);-#}bNS?thNe$^E5&3?)OMy2Jo^mD8^BvpDDNk|TbCGW3hR>AdT zkBoa9MD5j)8E=9Gzr0&5I!DEqFE(1mY=L_agQd*(9(|3JX4+=|q7e|%NSUGPrJlhZ zRe1-P8q+X}l9L!B@W2~Xo1GK;KQsi5yaivfx*xO~RBNA`T}Rz)O**}IUiM+`C$c(D zg_+4b?<|W;7K%~x<D96#^5^?!01>154<8;#Kh`%9D`stCSO`Z#TxHlD2zN1~b=t-q zU;rP!<+cGj7>gxqX+Q|ngfHNEcTCK#kHnaOEkcOO57u%kGA@;}R%B<Og^DKGZZuj? zapg1(vvzG5;9PT7SexHiy#LVwhO3erkwkF=S_B>{M=7~9zjU93#z!vy=JJYmA0`4a z+|8KEGoA6b(FrI>g|?R}@o6y$vq^?2j%(p*dT=FiiGH}Vc0)VuRR*E1HiQ?QYMT(_ zFTWzNzn>$t^}na<JOX5Tc&Mi-=9a%fogLs2*qGDRZo;`J)l1~=Vc0%^a&NxnDr#h3 zk0+#`;{>3_?tWU&jZNIrMJ9afp~MPXGZ&Cf{nb_>#_Pp2v6q3#Mv@Gw-}WRV3#$U4 z*)38#=v(vtK%O6xAB%u^EL7m?#tT_FE4x^yu>g{yzu<en!LZ0P!;YPrM#<~qcF_jW zAI=ik7;EcDW{hkAl|r6E4P~pj20maxwlu#3oPC+G=}R}RL)4pbsjUFvwz#Fjq-DNd zBcNrD>b{t)EvaM9*AW|?ezw6li#qA|&Eub1qeCLAwZf(Qrd}g8#1XH<tccQqtSG__ zkOTldvmMZt{%j6SJf3=xr+>%wGAWdJX}A-giN$z~2dac>mHaVji*A@ywyvkrJK160 z%W!n{@<_(tkEI!;-&bj`A<0Nor_t^<-nH+-{c1qn%sX1<aV`Gz350!KP;n*l5$O`J z!Wm6L0`lzs5wuz0I568~;u9TCHxMM-*S^dXUP5aJ^{*=DLGMFK8cf|{wgSTCE9>0r zA)$`lh85-3bXva&Wq)B!GJ1sp^62d{DeGxl`%t}axRWJb)c*|cscL3EAPEbT&7V4w zKUWP7blRMfo&!>O6qs(K@~H2)PT<-xQ(D4EFqI(To&F^YZbdd#Oit&mODLRn!t)`h zINMwN!{7Ns{?VznoH@n;`IQ4fL20?^tjldZP}_evs~PnKN+H(2n3#FvOjZ;L295SK zJ<OHLI!HZ5mdEA+8;@~jEk4&~e*$jMcV9-0w3OAT8S+3pc}_~#l2x$QqU2dX{?#SF zp5Q&b4Qg%L@JyjE>984niT4{=yMc3{4HH2HYc-x7kaH8Sp1r?0m(ZH`59{DkVDV5Q zC`c5f>$cT(dLi<ou_I&%S)v)!+D{B#v$!PReP8qZM%enhmDFa4^f&WQmKIm?EyX_h z^lc;IDnI<K+&{#G>PKwj1w_*R;v9N`v%ue;)iy40{@#&uwE+Nu>Tqfq9{>?a$i-wU zUKKkcMr=Qd*ezW8viEMmbsD%Q#Rc(Bfm|oIv?XyM4=Zi0GYT6<lhyGp*MgCrIebtK zTjt_$jxs0QcJBV`t;U(33bANHK?HD>{uhz(?*|_R%3EYYox4kz7fdNrz#Rj2Nm}RB z@ZGg#2Rt9y;KdJ97wvE~&)^Sgad=cDavE6=hK0tI9*@Qw>^JdNm>se33EDFjwD13A z&Kp$cskFcWUk~`v(=$gG$s>jc1tsZ!i3(~?^E<$1UDz;bgOa&0yA;&*1!Rvl?VT&w zp|beYSLyyzd3ti4#c!0q4vnjURY4Z#umW%#$oSjvoH<krvdGj_n=Zo6{g=1gkT}?^ zsdS=oxBok|9iU>pK32*L_!41>;p6Te=%7VpIW8f0e!WkTeqHT6Jpr{v{G`mI&B>t? zfPbfbQoEKsiVpJcQa>-`R9K*C_=!e8%sNv;0G|Er?8FLupEQDbM38Ew+zcY#d80GQ z5H`NES^o@xEts3SGB$c1VhiNn#FM+|XTR%?PBYIx@o6a58yq3g3zdGU`5#KTi8jBF z6fh;mm!ZxDGQ!Y422UkG2cescpV{+YXi+<)R&be$)X>l12vUJAAVIrXbt2CG1G}b4 zY!NG@s$n;8Kn?&A3r50xajp+Z>*5U@$O)p|O>`HjZYahUr66^iRUy*1Jo&ogx%U^L zzXQ_s)h9NcQ-4w>I6P;BdLZ`PVLgD+yyr-`#&m`FQBC#rmx*tqN%8DDf1PWqN>v2! z7cp;aZy7k<pR_Lk9=WD{B5da*M|_xJQ?$K&A-2mL3&V;c{YL%os|g)j&%D0?RT!<Y zY2mJw^~QcX5b;aVH)6TqkXU65!7R|+fUs;Ov({^X!Ec}l;dI0B)K0h<xIRk=MV@Qu zq3jRGh06Vc{17d1CI0%OaQ%weC5ej$X89H0MZ@E^Bm%_$VXCmhQtEwj2etj|*_I?V zFBTw@?NaC(_(EnE<}r(pe|wz=fW}~aZjL71l5SZmbo%DZTZ`aVryZau?XTZmsQJcA z6ML_4`Av<DT2}s+Lp|p4+mWDkv42LKjEAMr<_;DvFxb>0m|e{5ZH5>YUhOp=cx*dc z@u|wgJI*zXknEna$<(I3s%7h18Q1oqOmFSa9FYdAt<b@V<-}S1R(ln}tN5P*pTvV4 zEO#+aikelX3Cd-DwDcOiMRALM$&fIrhy<OP2neVBQ^PaY>a>E4^QNV$X!N$(Z?)FU z8AU;B*Sm8Rc+>@M4lf-4H{l>?I7|xE=k`6wEus)tDmn~XKM85FI-!=dYRGGkSaBg{ zr@=&zxSNbeFWSXO&Isyv8)hS=LniY-o=(|MMBha<jNzqTBVT#q?7J9GA@^mq;T?n^ z7*|TxX3Jx^d}e@#vE6o23{qnfrfRuq33r0Vs`=;XAj=mrd9l90zOXJe7H)e&#h*~$ zNA)_g@E;HpZ9Swyt3Hb;liy)Q$X~^)!-GQsK7$74GWy{CzbIWTWexcKowkGn2->yC zg|lAd)47%6PG#j@<yk<pi>t<4zF>)0DZV=6C^kJLvr^DF0j%d-m1Vun#YyF~|H5C_ zKR@EHFyiA4Qh{a@VzZkLk)7@pkd}uAhloN8c;@VOgaep&-9}Q~dVgBE{IXKIdZ7^5 zcz44eV^A2wmWEEs#P;p|G^n3~)~2yI^kUE8oEZy8MlY5-p9He&T}=%sp7^$-zI<tR zNiZB9h!@sP<N5Dx`N0X_i+QoOamR>$&G37yJ~?N`euSxmb$hDKaEo}dnP1ct-y!R2 zzoF^59BKRpNiDo7aRblqN-6@>LjtEnRc=*7j*@26opUDoz$Zf`(o1>Bh>hTTbpy6L z?yq@08IKnfS6(l>Y7IPqjYHG3zADtQDRK3dnApO8_Lj3?9Xu&*YOL+>nWT(U9oTPg zc;2s3x|%H-IZxjMXFx!TJpIkPv^25uviq^pjHdx6l*V0CdeAuXk9kP`$2=I`ua&1B zJl(5{1BxvTNhb6woWWWK(VjQ1LHR3P2#yGCHV@;!P_u>X^i5|DK6i$+3l5z-H3a0z zRiuyI=_vOB;AzanLz8tFDUVhEZ^H_6d+yiw8(Auwf$uLEBr5HxQEkpZ;u#)o*lHBG zddBMP6u;>7NpDVZs>kCx3u_Q`<=rHI{K+<AlS4Kcco9VB5gURiP*h!lYycZ8`9Q7h z#}|js_0oq-R)r$hh$vYcZ_hc;!QTOhi!pwHAO|j8z3WZNNZnjBZ>-E6aLJbSMTIYY zeSt{zzbH82A`Mm!A0yiI;G!uv_+>jnazR!DnMqpTUPkoDkQokY(>b_{XgY#hiTmB` zd#fKLSC^Z@it)`mR}f2pL0FFh=svpoXnwqt1&V%PVSL*jUp5d_UhpI{rLBIvV{_#e z=D5tMJ4#1*9j~}bNdW*x0<p>iH7O%C$&F7ti^;$%nL%a&$^v+0p^}}=+2Lqs*-_(& z9Hp8G?Q@7mW<N72Jw5E5r1i$Z^~EL=-@g_~ij0sLA)shKI+@!{wj~_5S_M5@0)eoJ ztk;@=gUcRFbO6k<See~aZ@&1M&9K^<lo9>3C|u|s^mIR(9cv!3(I+oN8lq_eNCLWT zLr$;&Zldb)7WiytC8YY`tW`&9=B~p;6MKP2yYp;jIqsDD>koG>5rh_y0ptvS69}o4 z+)|D=na|~Jg^BboQ&>aDbqwRrLSDtx`QD)Gl{TGFR?N0-o{WABTqf?LoI@HyXvJp# zcioGNjx)wk{qv+KGQHxFYb3V>ZbWV174B<|wCAt+eNk|(*oGJg9Q~hEZC%2Pb-g%l zfd1v<%M-fV8AOxUcou#;)7{B8Mv#UhU^1m`KwB1JZie`JI~hPZvRGswvVab))H;WM z3^W!|$KE!S^u5#!6L(kp@fI?|FR$~!G<7uifDd-d92xpzLRxUquMrg_93iz1q9e1c z;(YQHA=lhfz()b`uqB(JGT!t~HyT*QT$?3YpmG3|Bkd1nV?uwO9|yZV>`jp;SN5OJ z1MC3caTKm3bWeQuV>D@xMJ(lEh1KEgczHvfA(TvPW!SWw9xI?%Q_`C6z`}b!6~H#2 z&hV1J;~j7GV}N0m>ILFU*}rM*j|o2L=O^zS(C(}}HSv9R*hEP<&6j`NZDwMgH|39` z+d4vz4DS?f;c5nJv2uGB57|K*q1!bTz%fvCm{-;74)@(Lw<v;h4{nn9KcX@jz#p<| z3FiT*!_q+M(m8Q{F-j<N<m}VIA_PKyc{!0VkX$Zh?F4HMFduOkc!Ag!pVWYKDvmx4 zY!AHKe5LiV>cls<f<+Ip0pqM{w*m+~kdyf9H*U!yPJrqS{cX2~kB?*GQ1T!b!fXI% z006f?$c9{nLr1hG`RkLlo5X~WTOb;q-y*etN#-(t^;rCspKv>O7RR0g`1I(VPFSyl zhZn*tJP7~sKfSDnQ5Pr68B8;psu;c*e}z|79oV8bBx6@j+Rq4OJ2Lo2npcLrpT3Pa z@)&b{+`1W*JyTGpeTwx()&iY?FKv*231zT7h|J&D{FoAcr;RbO!DNW#jrYxC_0p=6 z%Yr1PAMc*Nn$$r}0AjF4gX)FRQk=n`?`sdQtpY*eoz|1dt_4mCHV26ewe1Mc+H<b^ zc@BP4r4GXzsEJ}|l59yFjVicU=NKJBX*RCaoYNuQWqQQU2{#P_3UcqAg60MEwbA3- z*-o<#^;!!_L<E57I{qT7M-!`Yh*7Y=LB|4e8G<`*$z?fB7fhAuH?9fowLisMc)SUx z2u=HiZ=V@=4t}`m@gHUU1@{Q7u$HI&^9%;1dO?>IJl6lO-0yNaj&CaBWM9d%5;juh z(Yh%q1{NSD<}Y)>laW$!p|B2-LbSqNwpA7YJBHBHP_hB5y*n&eJAkw~LD+Rf&<ElH z#6M0N;+YWk_wJf-nWPmm(>BJo;%M5QdNWDqaUFNjJ3VUzgI?;K^Uu}cdo1)$0!|L; z!tep-1U^NE2m!dLX)N&k9)uU!nT}(KYx563CMP&erSRs<PPfLeai?3J=+};8_vD)1 zKD`=K_ElfyM;W952ryH&&;nyIKLhH7NM?ZR#~28KvFn^r@OJ_|AI}0^b^TxWi=E=T z7oOQs(=Z380%V;d`)`xX*F2iKG9Pz75Wv!#Xs<TDDYF27gH3xgBNR3v)~f%zFq8fU zq0Q_rRi)d@ce(<e67Qg89LmlKJ7W4Vdw1&?QJLFHLK-JM$W@p(hWs3MA2Jhw-13c5 zG!iuu4ihV?^Q3R&SvTk51<{Oeax%+q0;t6(?g@#-s5{@Z3A!uk%`AVq_tf7%_Ka97 zF-maySIj<XVzfip#BmWUIE!ou`e|9)c5xAUdSH8*k1yXe#OG@0z;<Z_=!QD05q|Uc zk^ej-wo~O^d=UWzB;m=ESDM*$Upt7_gdaU}-NSp9$K5TVdEx6|q^mjY4gJ)6iwoSB z!)&OuB!iiUBnnL|6f5V)Gg#@GYXn;Jw7I^#A+e<_7Z1_1D8+^N#bCK@{_z^zd|O?y z$m4OJAQnpdeT<(VcTpg?&9o)(QC85V@$bSrKeP#C46A2rtL_%7B?jGhq=%K2W%Z47 z%)BcL(Gq^wI$=BhYwZ{jO8^NxkJ6DNe5xvqZuCVb%D+wsCSJKv9FGLBgj4@*RdY;i z1$+G~HyQE=4z1v;JyX^#I|{760ZM~uxbk{BE`f-7<H0O?6FR~NOoR_4^UUg=z1Jo1 zdL{Pbj8Noo&7=O2biFkJ?2E4nI4WK3oXX_{4A;rKgsX$^%5l;RR4#>QXn4x(De(OQ zzJJ{s=CN;%D7LD0)GgL?Tc1ec7uNMx6`e|4Xg2QgxmVeTwwcoUFu8I_Rz>>Dqzo`A zocVJ{HF`by@oh#;%l?rAky2a<h-b1LbzPaI&JT-~&lJUQmCg1K`MJD3gYiY0z6pZ= z`zY3J?cwNttLUQZ^sI*J3&NUDHRO-#@HKLuHuefXy#A$zJ4n=HQO~{pD3PtCC7RT< zBl<1qD!+a15a5mChRbhGG(1e0+CC7^ux&l~K52pk=T}4oWe;in);k1e-_{?Ts{<Ga zFHIHDgN8x2l8~%QS%25`XR%9n=u`xy!uCxALtglQ?$vZJe1sAU$y0_tTPXhJ@^=CT zvB%;u`9M46fbHLhubT#cD$y2qe2!4|I=I@F-fGY+><7HF*v<j82L+pUMF68CugDuk z%XwY4QHtF1npnZm)3ejR;xpOLyJ;uZT<|C^8q&C&NT<sGP&aN_C_dxq9o3nRcX~gQ zjIl)~Ahgt;BJLpkMksSiBlu!+L%POBkT6R%i@Fu1DX*r!;fKib8q;UeVhMJh0y3>` zojjD#Yc=`jbt1Xc=Pus%QVn~r>u=1)g?#$oG!50+pHF1@ZvDQ{vLM<za4U$dgWSb= zcQRaXyT8%=v?`%L7;>~(a2;9pjDA!0Fx{ti>4HoFK9THGDM|#hEY~j6+CAYbiTQIm zdA*UVsHtO97y{SgG*$t>s)2P;@%hH|>5<@ZJZ@Tc_uP^(Gv&<#w}=b0(g%AXNP-_) zT}V)UpqAH_xmP7&sJL?X8t{=s=V27HtiJOWNTcmi&>(!vqPFS`w@$!CXQ-(p{SP*T zb#d<hXETp;#mrhJj-95wU{SG5TRNbkJyZVTt;OZl*ej;vXfPf4CH%nS9`oYNw;MI* z!v<@59{(!B6|BQba-S8%yL6vG%EbM1%lF!_rhT$fhs%KkA}O*8_}3;q4JP6=$o&2Z zS2uYht7nRn23MKn4eqgq<GMM_452&>ck(PC<U^ePwbibL4lF3^@i8csyiqD)XzEb4 z;2xRI;Nd(7(!WPPF__!&6Wsv$>*z#YK-cV-ACHV6NMuoJwp6*151*Yz5)0-uG=Dxj zk~iy(-?V_cK33BTKg@OxZH!SYr}R_59p|`-Q$Ne&9VgpxaHCS#M>W%)$IvV`|BZpb zsu{6w<Q;NL41%kx;h(q<I8jGA-p&WTJHxEoU_g`;BykfFnF_t%*)J}Fn)DW;G!14u zj=RnU`b301g%^@dW*CxPtFL_w7Yq+=y-Ce#cn$E&Us4x;I#rdQ*L!pikt=+)le0tz zNI=zUTsLoDJsZI6-Zv#HlV8s5?{s6@wwLiM<oP2t2`4YpBh~6V@dp}qCynvwh$hdH z)UW8n$##f_iQ`$hd;Km$!*%1IGnT+jAOTIY=ske2mN1<V0H8lq-aEh{(-jx{_F`*v z;1;5MuA{z807}YH$@iPWQHs?5j1F1eg{?_#b}2!O4nOuEX#XR%^+9%sJQSLgBZ{^6 zB4h?YIi&>|#HJ3!NKmfZ5al!5sJMG*rjVbulwZDVmEi9(I|jTIG&%#<7IQlZvvOMr zjqt`2tjtKn)B)8jq0wE5MAE+bv2`<Ikl#NQA_wvFil&kK7rdT2;joj0#Zq3X^OSjd zEA<}yK*D(gYYH(N1wpe^0#zrfh!~Ob@TmwU<viQdSAUrigAR`V6ILLU79{BSIRW(3 zE14|tu+-;3x`uvwm;1K2Nuq#L9>q_t$nXi+x!3<BYVQaj);`VHi?eV_DurADF}edj z4otUYLU}QU`<&tB3(D~UJQ1yDw;h>p6BB-%y0S<tSf97PL?FNssgFqL=}_Z<{or#i zdpB<i(SzQ&e=~{toNypTF5#dj3Pt;m^}<BQORGn=%m}?{<RK>a;=Hx02q5p*`u?k- z1HBL1XRJq~?aB`BJxI9a8wslIw5cva^<BE^&zU=w#@KS6AQcFvjiDCGb@wmZ0S@LG zag|ws9LxS6VlXxRXzkp4%^|b--N3Di>F?mpX%l``bC#<ud^{d;$}j1D7#@qSA$wXp zNWlSY1PD&6okVi#rNa8!AM?6!+_0{*+aJAxK1<aUg*X<?9JkeR_zpN`Tc@O|=rI?4 z^ixIN_}f2a-xN6DcQ=3$RN=wOdYO;IZBA#M2Z8IT`>}W^P<!fY9{sDv;M*Ep3GwEX zaM~*BG<5e{&f?Qs!X*-QM>R&A<ksmYjY9WCN2^XNC?y_}otT0Dp6N0K90bf<PSEj< zWU_7$%gAqG*2bwJ_Iwd4+m|<yL>ZunV8YmI|DxO+)9qljzqaI-Yo3J`#W1_V4W+3F z*42`fk*Oj_`NJkHB6>hn+eiS$v7(C1E+>?rj@_Z!!+m&h7KHk;f3MRW4czFv|5v_c zlN*I9`|rwFJUNushkGp%Djy`wS4XLOxRUpV6v5{BXo!c%Qi)_viH?fP$c16w;@M~< zqtQm3@dww7|4rm!veB_uyB1I0lf|qn(&0_z19ynKo<$5w$Rjnxf)ljH<gvw2^hmA0 zB)3FA#d*Qd1~QIQyx@KvlVi07Atww$aPU(8p6LjD83g_x?Xn?5YDt{DjsfSV!)B7M zDhSG|#GO>osbtYw_yxfGzeo7N1VX}xzLC&wiqj5U!;ke~U4t|B<19mr`-_K9rF;jm z3|hMRko!~a$aaL*Pb_6+hg@uxwPV`P25LLnX31}#&(}q!oN+U|H=?2gVe(@b*7aWo zh^4|um$Iut%9jb)0Ul}I31I`;B;TwK8wqR7s-K(*a^LGriX`fpySHRcIWkFL0@rX4 z0<qXeXhq>4%rdjg7cz5#BK4HYI4ftcHhNtwdi#15eLs)~utRX)Gr977`4F?qc3cYC zX<{3JC4v6I4~jdi95>qcl_?gJO+x|lgr6E(<wXWLcw?!dqX=pg(886aE2jLxg5cDx zFI*soTcB7<F(H}y++Y3k9f0;=Xyp9YumQ*pgpq4|7f9Si-$v^ZKjKeMRmF5ftD#V- zNVS|02w{y<;9c75$TQUS3%*o7KzzbmP29N!4@HBfAVq{PDD`SO?CefC88U)O6eLMR z&5q&9<*(f8=V_JA67OGSdS&DldOwxfsQLQtrzcM;BSfQ|7B}d@6hH}tcZN<57}p7; zNb1l~jiE4OsCJ?Snd_-t`i@hNO+lgx(!|t0AGJm+kk|zG%VB}fN0gTW>A#J@<)h+R z^{x@$(Nj|C-8??U*_x8@Q9?{I2AO}Vnb*X+LgNC+6&*>=Iy&0<PhXxgY0_XOrVxdp z6e@tgz9rEa#-G?ZYl5?fxG$kNd6?(brBe(_p!YIbD*+D~K0(rH<{JqmIPUe=w>KZI z()CEY%zyt*2-O}7Qk6OfF;42uMW_-J0*waESxp`2Y{IQ}-Dk;?%P|FY^aOq9)ioxF zD68h6UgN@ZM8zkst|uNNO1jzv-V4JGh<#zGpc|2&aTCHVr2uw<AJtEHU{@_Y%G`P3 zD@wJW?h}kLAOlQiVPXR^5h!|lqomfI7DynR!4Lx&c1}ON>u&GWYZw?kJ2zRuI|`yF zXxPO9?+XjX9A(Fa69Wl{z$0yqF!AF0s})p&cQ{Zu??a6g4~41btFoIMH=MsI%*nob zaHW6gf13LU$_qg%9;><|jAR!c>QX~&U+j4`)Eyo}hjZK%hl-%5UWxSN@nR&CLD>QM zv}cO9W#ZkF9evhwbjuSVb~05j;V<dfdC*}WP<6XVgAKYkB%m|foghQBD=}*hAa{#k ztGB__WU$J(58mC3Jtt|ThWj8<fk&H^Y+(eztr4`FDh0yULN5m)@s+<5Z7IL93l$1O z+U*f&=3%6#kYg9afL@`sXue48H<nS5p~TpYu!U1Z%dYJwayHhV+Wj5=U+!g<U?T7b zXoJs^ZV8#M6?!+a2v8F)Kw6YacOgGw3~%784F|EM611b6Ih*NF*^fK3N3_xvICPX< zF(z?45t?p$>?D@~sid{+_c%)u6Dqm(I7_a)osumai?0Oynt-5C{i3STlLQlqO=-s2 zec6f0So6QK8C$NojE!dpStz%&X^aMSWd8OWghJy2o*XEZ0CG#8kv|&V>aQaV@6XhE zqY0o#CWvRHjv$VzAAjS#2C>a~PNrmU{z&Gos;&a9uy^+}PriGe$E=aH#)@~XvRL2u zDeEz$daHAvXNSUkD@n#oi94Re7hAl46##$$$c0C3rU4DZ<X*4n&lx_t_eYM^msaBO z$PIF(0J9GsLZ!q7UswxnR#?WQwe7J9Jk-_roo4*!yWy(h>YY10%XU@mxS$xgK2l{n z+Uh5IW`16q{&iAPAy0YR={>30`&)+!C!nHmog1*>z@>qbv29a9U#Cdj0Oo*Fws`Dk zGhthUC`@VbU<-f_w22XVg6@_4C4-%nHva04lb0|3c`++w@4P;yCw_1mdp`r(E&byY z(at^fXws8N0v6Bm<I8xXGxpOcVJWHeE$qb!(kCJ#RdfNwW2U=3G2!v#@^J`nG<mW! zSKf*RfFB^S_tqVQ_crd?jQOjQ+xHdoPf<Z8>oa{aU-K7gU2+naVCdIEtJ{7)2(<@X zIgA}its@YjMrs|u9j(C4KD2Ood^dzGEBB<a?m#foFQs{dx{}oA8kOOyHhlqRoq8<h zVSo%6{d1%DjwxTG#you8`^AhO<}oPW#?SyxRz3J+&8#lRbW5|6)259vc*TfXrXjWh zCQ=z3Lt%L}iy9FGml`qDk3kha@0<~O`PL$Al!neR6f<m`zp(b6L_2K5WFbXFQ<BR~ zT{xvvO-zz~XW~jicS}+mr2u{&5?NU2J(zo}F@^h-g;g`v(rG5*sC4FonB9B03IrmD zhlmOYy))~Dcwu-55V!Vp<h*9k7ZJ3@CB<u{FsL!pR1~ZdeDX10@i{cxg1b4!7cUFU zar@&ZGM!*F#i6uRX7?PdDB!-MSVpPhlB4xn<B_ndr;4Dep4o5Aq!O%bKTA4hiVieX z`t;0}gsgsy)~#Q~M#XNljDH}EtH`o)CZc`dsA1C+{nrK+XC$bGFMd7_DxnRhUIWcw znNBks73e$=3=E`uy8201Q6-8FI7q#7BY*WiEPdvjk<{v5u=4daCXvOz<PfSID0APH z;sfj1*E0eEmoB`Hm0xG(pd&M5@ZCM-8~Jrn`l`#k5=mp~CP(-aLLGT`>NsJ!eas1% z>G<d&bDg(X3;mZbHP$!IgX0mNN}+F4A~$>Fk0vKQJ?Rk+;qATs=Kg35-4XsDQsC$p zsJ?_?9Dg1;T1!BDi$W>0GF=m4GMLn%%r7%5ZG>G^EfmjMPKP4A@Hx+Drm)}hpAn>b zG^~cY{F3n$XY8UB!#Re+1@k3OIqE5e%{aY+I#TjRbM}t1P0D*aL;h8PD-_$=({3l) z8~mVeRvevni-~?SNy-`&qC~|}3QZ7Q<-2nit5l5fV=mC^gCSsA)w*B7paw^qi^7sP ziqziKH)tM<p<!*#N|AZUewhG2K6^E?1$(9$<9F+)GfaE^nY7|rxC23VoKv&S*^Gib z;3>#PrI+l2>I4hq1s?zIX5EGaZl&P6w$+eYG`ebJSY}&uhUAFq^qas(Tp*A#=WBMc zYlEWBcw@EK1x(<Vk)beD&=+LR{d&_(3sJGM6s7W0CgrR3*xo0qVV?_5`WiFkcYp~5 zr<G;86?eSno7a`xhuy^n9h$uEtbCDPV?@iPyoCMXg1kFk>J>h<1n*~rOmF(>k92$h zg2B*?2Kc?H4=+2ISIl_75}gGG7+Q;pvHT5xNI|3rVmAtC(?Rf+DA-9T0c`mbLo@xe zGWYi$(I@ZHUxl<gXvWLv1g=q$N#fYXOcwPb#+I}8v*w>7;~o!GBVALvPp42Ral}GY z3fIt2IZ^<Sx}^j%yGyPX&yS-tb!uwaV0h@3+G^%3i19#Ui=R-SNSJ-?!I$A^{i<`h zH?pG%m>%=ivjtxwlQ$Q`r~B@mGbDujeitGOoL;AmQP*aW`4KMo^@xewQ`f=xhT(js zT%cw3PpA$IGQ{+yKH<rt%KgJ;=`8kE3;bU->3oBIxr%+oBvA5Jp;|vdSTlWh&~8Bc z<;Cv;r_c5h1&-`e`(`h1CxFbU-9MbNErzCFzEovg#*@p<Yy7RL$0`FNv_0FESy%I# zMrBs5PcvBk_Cuu*I(z$$r%l_eHx24(i@9L*(=0FJD59q?<c@rZQhk!lsJ&=AUaYDY zWn>xGZ`Gc*U!EYHDz4zWDI+s8@#KErgy;1%`r$HHctlo4JD#IwdmG=&sT&CLjb;jn z)|x%xskJ-1CLKqSi;ldi9bt57ZfeIzU32G^5T-b}<MB%YWl*lqU=>6t`H8rAe)WDy z)`sQ;l}`v&rg*$>_1}qAEucEyJpA}lA)~pN+|u<=@;S{>So-U1a-hor<#?3cW)3nk zKbk=zJBo>h5g8gwpUzZW^zdD$B<&yKu@vFG$9={5ob>NFRJ9+!25IrK#e<mwzr=uN z<135rxG#-D&}I4TBegF1lTEJK;1-?WV~S{g%Rc_|)#6F-b<ePb7cs7s)v~G+Hak0- ze&}XW&w_bN{}z@EIG4cmx0*u@|3a=Jw1MgMv|1>x^l64mM{jesjPx-@Tf?w8qG}F_ z{h{I|wZ_!j_I}r!GJD{Q*)8rXFs(~8*-p7HJ;(QF>3%b?4d3bJ5|Ob1C4QMq?i?ho z=?q6}Dyh}I>Au%nck?+($CHz!+I)?<wwnn>W!$s=ZzpWqTBpxDU9AJcft)Ni^G~h# zARQjDrMM5K^g7X%O)$(=!5o<?X&nL}Nt^=Y2}(U0_g4_%YuA##en%PUcQ{tyN)nw< z5;lnJ4p3%5is17!Uhv&|%<Njm(kF6uL8u_du4qk!XvM)){ZkA9lzCwf;2?stMrQ}Z zt+l7ni~CRkVMQ|jSQ2FkJLWw$9DIk55evk3G#ge2B;tq|xnhdt5*zpv-O3W)*;xXu z7H6qgIs2HrmYR25*iUsQ?tRib2%^0ir(A-&FNRNLtDhNpx0u=t<9(t1a@;KHKsTPi z6|PBwpr)|z9mWrB^Zgh)J?9Ltz0e>4GYX`@yi^9>H~1U?Lj`Z&wuowv3yml@G+Vpc z>qx(j%ig8a-KJx2O~-;xuHcByqn}<!C#*qb#D9M@Drex9Sgm6&FhmP%V$Nb8ifj_* z-D^Mdv8kF)&a&Lp8jAD$dWExALzt%a&W8oj^FFL|zM+jSmpOjA<z2Q<nH;K>n2kQj zsC3MSso&l=eV#Cr2O|TYRF%1+wmCa3ZBFWL1KK}DhCaXxm&!v3>6u|3I@wOfKc>7< z0k4lA60QK^`q#`3?!#v`An`IxTiM;OgEj>C07sVdVtcO%FIC>TCNQsIv-6Xlo##d# zX_(QairHHneRs?0-z~dHn?5!W%NthA673Y$SM9jJ9VPf>d6_ov%Du6ae*!g!Cv`r~ zVM}ArLF4!{k<!&czeJTnOtQPXE@AVVaOU6dw6tc^`dNs$3b{uN?MLnp3u|3w*wicJ zuvU0Z738RJ+y=7HF9rF!a|T8<oH-{ej^&a+=r~Y)+4m4Cht7%O0pZ8*+>VBwT0QzM zROwCGT!QoyqGiXio#(bBJW=7=<gajVbUtnd{aWc@zuR~|!8r;C6Au;+hKJaalHHFA znrpM4h7w`G5@r!~$etX^cb_LFOD)9wHby9}5~PAcC(!(9dPz$L?$=cprHXl4xd${? z>(jF!C&<d3Z7BtO6oyo1eggqKVW(y{69$fZ3Y7*4>YQFZuatLH<%f9Xk$gLuuO;sx zW$Um%Oro^fo%l9;rf59Tb~ApATglK2qq_5tc!My4k=2DZ%zzr#QeeN;wXhGk?G=7R zQ3g5%p*-p*NcjVKye<!#-DL{U7{t#L#ELO==UR{Q!UQPPyj?a`8HDtbgbLS0{RB`A zaApNzBycCdkANIA7;Ga1U`v(!qHv087u}~8N|`}DV1RT~QtMFd-*S7V*Vp$i4v(Uv zDz68RJc{iVJ`N;!(M}>SApSMEm;4GRYFbrD@BxGI7VqrdS)>v7{#D$%jrm%#J`l59 z0u)H`QdeE!3aT#9_3uuEWiGF5s@v9-bYUn!Ljm^<O=cL0RD<bGjGZAEG;jsjdmK{* zZ%ja`Ao(!h_XwrH6c<vfCS)*a#G2k03zRh+*P_hny%_we6enF^Y!Arf2CgpqJ|}-W z^+Ie>*)c%xRgoX!1JcnQm+g(Y^9p!$AcI&>yfOnD7)aIvE|3U*mW6J}aSS~#0<Qg4 zuRhnN6pT?sf7`T2RLT_tDKI@S{in$77X6=u*5NTKOBb)(Zn{}EqkD_Q+CX5_+IdfA zzh-Cwy%3?8q+lJLrplR4v0Uy4V-1^3={{B1(dr{xiyJ6{sqKz^{>{<)944<#2D6p4 zy9tT<zdHHq9oG}dP2B_qijhAEa=R|p=ut{p^17Tt@brbN`p=Rm#v*wY8uu`_;ed-R zVVozUj=22SV4?SpylOPW;HnTDg))J$s|W)PfnC_bW7W6jeEto?rydmEZf3h?@gQ$z zcJ4~1YhBJj!J>d-*oT0FSqFB$=m>4v<Ha*jYe7db;2-wN&Y<fm<(u$5)G~~1joK4` zF|xD*F$gFEV7dTTTuBi+QU~L6gSP3;<JJr@YV^`j9=k(R;&}%(Z%_7caD9R?1!b=C z_vHz%$jRLeirtOsO|xlrk(gSq6{p36gYmg;LW0Si<=e0Kx0efpbrg2mjJ<bPkL-S{ zHaY9&$5T<aU#6hDR(;#=bV*Yc%cSSt-@-myS3H{X1+W=pqM?O>CRWU5JQ0Ixx+`Vn zsa24ew^vp*Z;=2S9HN!r=4`6zX#4QGWxppl&+-x!ro6L%pd~PL@WENz{pr2e4N$ZT zx$vIxe*G1u8K5JtfG81|V}3qoU4~i0=}e`g-(aTv_TZ=%lw~^eA4k?`e)Nodf7ZkR zr)V&bjeEtcZq(jfT}Z!ub>*gSx~pW?SIefFh^G5H#3lPb#C8`MAC%S9#I1_YrG4** z>B;JDpJe#Pz3&oDdqixhC(Dv~F2c~(RXC_5|8p3#k%oog@O;|unVr`oH%S(e?bKFb z`}o)OQQ+E1Co|Fed{*PxT{bGv_c|8M&qsP|6_Bv@l6GAC`ZSKeN<Oh-Lx*=9>2g9- z9Jis@ZPlxi*lDR?b%R|1RV5EoWXIDjMYERkUpSlsMPSGCrtLB6RP7H@{6YnEHT)E} zN(#s=g<?2v-@o**D~4uExJ4{EOxZ0Wf^Tc*gH{<8ieGtJ51un-#pi)wo$qcy{%Dj$ z<IN(w1K8ZvPi<F+>T_<rnl&?rXKKxBVU}FAzgDyal`eEy)(k8i2?--D*M2c2(`j~@ zDZBDOkaW3N<8OGsv%ry8&z8z&y-Kd~y&L!Ys9*6!I1drFm7L7C7H>WcEI~)SZQta{ zEc9_&oO(#151sd!=af+!6bD@k*F#(TgFsLLO3g@xow@IDSUA@y!NwEdqM9$i98LxH z)V~aObg8#C`wKwi$_9|fL9&9eX%NmI5*A+erjbHsUkI8ls~J}r?b7d`QZK5msR?MR z-<7((_r-?!!Tmkh$yJlay(Vi~^`ZxRW(xZsst*PuWnTS;Zq#o80l#JkkC`zLMmp5g zeWa8Dz8Vg(iPjTix5=p_Pw{6f$$tI0mhE`%o4<vwQ^Z1_+PuZ6FQ2JO(?jqNoDw7* zf5KQxH)mIAw^Rb>QGeR{<2kv)n-&gLGjE!EpTzo@I-Ffzxh_ysF5RUsSKKRk8R`?> z`s+~b0ZXJ<C7-tezH167v`Dc?Ob^8L2>0U?#gE7cVV<)YW@88CxObTTHyxofo?~kW zLqveVfo8loq7LN-6yqE_!0df|8Dp%SFbMTN>-H;=;~^FFzPibOuVF>jUzv<4B8J{O z)R0l4{i5(AZT0i{SECU%UJqssw4L$JzP}-VTlUry_a%q)9nrj<ClKFe-jolyEDak5 zcs+P}*Uful_-;!wBctBu9;rudN}<0RR+iOP{J-<~cwaoLrbw;K)Q1Mm_-xtdv(GO_ z>Eg#rFk#|A-BF)2^Bb7#h}JVzRMQQt{lh_SWkzmks_6D9v<R#zO={gjmh{%jxFi8x zz5Y6_22cMM^ig#JGdd*FvW>1*4L>jPklZ!@(0ycC2v)Cp_l7+SO2xDvOzc-GMQ5=T zy<=!uK?b`2`@n)s1f6bwrMoF;smg8CAC3otkm|nXRdJQnn?FL3b19&Br5F$8O_|=j z(CKCK-PQS^#SBHuH|(EN_%Q(SklPO}7^55G#w1tkH&4%QclaXlO|33EuE;ol$FM{p z{a0i9`0cmde)7*9yLf&)WY*-mxm&H(+b0_W)i6)B$5EkZLnbA_?&PULtpc8Uz4sI= zm!+-XoFu*-(Q|Gjv~U7gbI}x8knO>fRrfSG&vTx7akLJ`oCM`BAEjA)dzy@!U8t6m zBX*;$^#>6`B=qgegn*iI_)$UBxO}hoNJMK8h~biaXFt?bTCbk!+rF3%6zbr1$;_U_ zhM81N>709$s*S{t%U~T)D!{l|Yr@xLBji{Q`=7|!0X=ijYwz9OziuvyKZ+*#%Xeq2 za!R+o;5kZ<&dv+-+p82-B*I>sbhBQQ<2(HZS~06@>D~F_SA?E9F2Ewh6tg!y?oGx( znrn?<JTZM#LGrPqS^)&g@N%{%nE`?`r?f-Ff!%Kzj+9U7etDwWNproJiCk&N0wzbd zOjAHN^S+2>?dXb9zO4cyob&ki7nfuetAyxhtte-<n?K@4)6$4|foYYv6ON}xqW2E| z95kdAl_~47nW{c|HsTjr-p_F+>L8-yJ9C%n@!@hf7NJE@0Zv(RzEC=13*!=V?F_Kn zvmZ=+iX$A!Z`CWSIWV554Wn+iZ8x4h%P{x?g<)XS`vswcd*VAhXGF~YQ?q<mvZZmY zNO(T~nEgMudf9F{%hxwxC(?IsugV)M_!1u3`@<8g_59~v$IGXytzUNNS2j0He3SdQ zuim|6af{<dK0`o|(EAhOywmra7KK`)d0jzW0J_9n#{u9L4UAcw2_H?o3l;>XypgrH zgOMxiRN{cJYOqlU4FT}vbUw$#hnz0>%Jr5(JJq6<t!H*`2B@c`uIPugn~WK8*Eaa! z0Ff;P{qbMlr~3tIUT?`GLgU0*p-XhWC(al^6LCuzg&eyj>~Jub6K<pKwzoy{+GUlx zv$N0mgATbb<bW$9qv{p62V@vea8W*q<6=811?hsURm7mxztg|s*yV4ZE$7?bz6#FR zD-VQ|A<%z6Fnm|_yOip$%Cq>H1)|sms`y1;U?gzYwHLQBd@tfC=+vr+bOviRe|o&# zNeynG32LAjHq)FbpU-Exf!f^GG9*zqw@d#zVWMm@q^P)Fc_U|m8sq!7%b`ib=;T6Z z&Sn9_FK)RG1*(P==g=>c#`{K2ixY5zd5r>nn~n8)!kMbBvQ}`^#1Wtc&Y9BI=ZduU z_zs&Yidj3}hVCi)tnyo@^UK{A+3Xkr8@*|cn;*X(W~8JpT0=fr`(pk#oFz<YG{h2C ze@=@R!1?>UXwIxUV3TYwWj(FT5sx=4QR|xG9kq#;_o<-X{7zZC9!f~xlZ^C7q0o9E z>P^!lPJAX@DQ{NEpqhsTqGgER{vW^gH-Q_O%S}k)X_C#lRX;MF@D+@ypk{!sK9|<) zlEozhH)#?f0nb6_Q%4#X0SMw-y96MxfEnbO-|r^Q$NT>P4$(Q=OZ7Lxp)o<D1!(Ht zuMacc^k>QpKnwqA!xC^>Ru4R3VcRevwM-gqUVFfwGOv69u24lO)#yd`z3Qh%o7$fx z;2Z^mKRz%EG&>k;nQ`C@ry`Y~x=s5-pI}y&JvOkVAPaZ>h3pz6g+$|vc@Xs;?0?e; zH~e@*|Cyrj*053i*nK#peE-wryBOKmUMs@B8xi#*rwds-5Yu37>k#()@$3!B>G}($ zxMaQSv@~-Z3fCMd)IbiXo1^bkVVrNHjOZYx=pQe=?LpKQiQ~V|O8`>${vMD|;-L9- zc%8-MoKFfrRlKb-mz!sn0ir!^_@p@8v1B`*R=Mhurz+;C$$8()^MG0Y;1dy0fcYdk zgb!|QtVAYf(9a3n0PgqH!FuXm4NUD+zUYL>kM4`7HpN2=R4RQ?e|~up_6&j?EFwBg zxu@Gtpy}-U6YA_5K3#dX{rix$`d@F9i$vTF9dPjTG8rm+PePeXc`m>|+lE!xT*a8_ z73<Pdu3cJHbb=q01-D;Un);Ar#cwpayvbDRfELP)rq#I+`!fxsEY7M%3~d5gQ$r&6 z)Ja4P)_5RT|4pOLp4_5^&QB&Qx7?uag?ffWI&m%*YIz{{DRVARolLX2ZkOg$l_gSs zvrE0yUna7<>6QO8EkZ;bI8bM&smwE&nsco~&vp_yOOJj9M&)PH8(*=*=#a3~7zIp@ z&3)IW5&%_v6wFD^PTV%<3x%QRL?4tJoRBq`#bwX|gEn&cth88NX!`wrhv1{(rM8-C zE^-re{eGEA+1k&eIVa4ssIsVU=3OINuTB=QI2+LRQ36-92Q%>>rL-jZ>VjT3w>=KS z{*I`~zVf=@(NdQ#aI(Ypk3rN0YNR2jLTXSyjk<gLbPYgD4LW2Gx_Du;qa(yWrjTPN z_7V_frDzQ=%ax)n9H?Taf${y<IHY6OH*Cs3>>vg;#15?@dNA8a6KRfigb9T{-TTve zJeh!+paa)-?JYu{Pc5uQ<#@O*S+!7|=}>%b%aqLswP~TcON*J|O!<A<B-N(Dqqiv5 z2M*+h$M()PP$le76z25xJk95IJ?CQrT6NzQV%b}Ug83V_D4^ix9>X+d?Lc)zfSl-p zZ%0C#DqwCZV6iF&2H7?lFXh9zR^%zoh+5-HCI!A;gL&DDlT23jFiLL`s~LJzT>7!d z>T1UcSB#hbGm=TqrH8{#z6u9_Z3hN^b%OebvOV1T7N$s_k^Z|!PJ0YZRgWcE2}}`m zviFiP)P7nv56Gl95&fag`yK?tI)mNsvpbhHq5l}Z!+N~9{n}cVr>%$u=#qfrtr5^Y z_b5qpSxC><4?0#YVlA3KDpd8P{ce6m2v~zI<c!mhiqkCXYH+57UZOOx45i3qpk1su zZx3+3_ftW_6Z{IV&EP<>A(8iS!_uF@2N42-meziAiN@uG{eNQi<~yy$Y6Cg<DV0A^ z^Nb4y{N)ZHsLv_KmZ-s;|6}fyIORv727tqK*mBObz-=2ppaz5nTI_63AI(r*aU!-# zC~)Xv0+Ta-mzx5Y4~BrT^YWA|GeD*i;XEV}?njz^T&yH22@c<c-&!1VCa%xrW&s#_ zLB`h}itE=Nr8iu|tom>3-h1!41V!Y-;pid&CwHBMHwVN%k&<eYnkz<~8@1Tfwgy-g zi`6&pC_tq5s3<NLb(O`gfyg7wJY(;&gf4{vl>j>6|BtM<j_PXbzK20X1ren~LP|<n zT0%OcyF^N)B&1tKI;2FA4rvesq*0Jo5TrY$yZg5e-sk=P@s4rF)q(KgoPG9Ld#$<V zoQr#m60n(JBW0+d0dm)qYBN)nUoA@N_|VA+)W{T9tiBT@p2oj<2cU<?QHT1CtX#Xh zMw3u2OM^p7v=^uZ5UHxa8o!^(x1jR)@954%e^Cm>C5JYK%(pt4$h<Pe9NqY}s#O{8 ze(lt%>nO0bjEP}#1Ri~E01Yq^ApV0qsfL;{BtQGFs|XOi*#pipVEj8=A<|S@R-}_( zQg$mW(Eds;y;#Ec2q~W+#f8+DcB<-O5bO$sy@?w~XEd)=vb(y-*7&dC9A3Z`iwQ?E za98_YvEo3bTvDXNjm8A+16%#EAc#)D{8F`Yqob}REWIWct>cl~pcB!bXNZWJkdAB} z(vNqP>RPtrHiG^L$R%>u@htKX=$SQ;^|g!(C<_1|YigBnTiaXpU9oY0?7^h63fbZH zoW-WsW))ELuh~%goQUqHCSQY1--;y&#-cT@@?|!fX*US?sNmkO)T5XYi74aY%mt{! zO_!eiE)0(vlszCYbd=vPa*Bs42=@w0rxNG6YHBkNCmp&5a00cr@+Xnk9u5M?ll>vc z@Ro88VH&rz0ZZ?P8Fa6EGU{;S(CG?G2G`||YHbQ_UMN`lnSKm9@RD7A*(AuSOZFmX z+eS+oL(@|Q*pgTgwhz#K2Zs$e8^rSd)J(ag^lwJE{Jc5+I)+tl_+Rk_6~i4c`$#|j zQ{iKRk21Nhh=Kx=2bKuXyr%=Y1X>{g>Q=0*yYp#6O3fv?0ZH7er;?CzzQA)f1j`iP zX!YIJQlOQ7E<y3R{8LmCW1sg%ih+!RTvrE<&n8C-XEtVnC_!g-PZRXOA${3loeOot zqVl!xHk&0VXx0T4TpiFTYu<xjt%Z>AK>upnr!sb#WGxw8vb%%anBRApNcCfHWS11b zd)H(X{HDwuKoyb#e#;lV4S%!WH1^TDYsvUxCO~5WKj6Ob2dY?M5IwZ}>tid#SQ7P} zX71F;z0?(+AyvPk`KB|pWoxJ#g?@bQpp;hf)|34hl&1?W-=zRBR{}#tVqU~b7}w^+ zQ_P=^*O|jmykE6<^A&&lwSiRXsJJE4WC_!IF6-?9cikzav(&45bd_~g-5+PVZ<9c- z24u|(W|YFArMShTJ4I=-zsQa>439%_XRKlZ8S26H6&xqyHrIg!<*#ANH>B;sr1jn? z0B;?#W`_h4=kR=b)o*X*k{j~qkhJA(hk=k>*_YQ$E_Oc*DM0xT-F1L(5q^~Q-CuuM zCCQa`GJyS~A;koBmdX~B-6fzE!LPV=cdF&uCE|Gu!gie=cfHM76HzCWxF<mO=WIm* zyBzSb1ZE9O`0<})HtMVY6SBCOo@&1ahQ8vcwn`(LH_7xf5&H|lC2F9-GqeQh3k0F~ zcQAvNCqMpqyBxr(?;hxd$YZ7i^(w!_d*7e~OyWgSap2{(^ITDPYsd1C3c>m#1uYbm znY4~pJuI!Dz-L^{xxD#Ji!Im0-kZ7*Eb4wEZ;qlrGwuS`efOMM?0ts>85Zygdt54- z@dz^qI1^pBF$ldinGl^mqGn0MLLM8aQX)GwCMB$GIzhaGR`H_~t0(p|?<+X4?QNmE zr96$xC2fcwPDao2nZ}QSUsZ-1+)*=Uxxut2%@f#h3`j2=NY}u9#!-m^8&<mE$sg5x z!B^qgsHcUISJM7RtFQz5KQt;wj~_sOQ}r_++($2}9IWh16NCnrR1`ln=sbQaZ)#^| zR_TEgLt$0#v0e;eBVX$#-*f~68r36c;33w8)M;4xhVxRoU)nE>g}O5%zas<=@+tb3 zaci@E{75;t3dSYArC0`ZAc$T@4L2a5t<l9qq|qd%Pmt;p4y?2e_D8F*1Fx#X7w|w2 z2wXx2w3;ZH2c18F=g$os2jGUmnt&}MeY-3Jl+RF7!|GQdM$9j<LT3zuRCyz)Kt`3- za&4mtv*jd`4{CgT1F_D&!rq6H@WxWhMI(wAeWcKk$iM-LA4=Q?=a~@CmA4FfkIFCc zu?{~$#BX$YK&Z3-n865MYH~^lIh9E8RuGm{PM&nmZJC=p+Q+rk@+F{GVG;&B+#>Lf zFUbjPL7+7;$TQhd6KeKNK2S=D{sd7R+TPfCT<3R7zJR6g-LONNv|g|-0s$?BICS)> zV^@ZlCklLyokjm0JM-^UYY#)A6GI9|q7x&0;?`RdXZ5L{{y4r8mJIef2+s-d^G1N; zfc#rUOGQkk%)@?-uKni)$BciA?Rs6H-499&dAL~HWx+YIRft#Exd&V8Q4i9v-XJPM z47W8<vH;7ev!m=9{ED6C@GI~NGbMZ{J96dbpexNvHk8BTc-<0Ms`V1Dq3#b32}pN< zAq(dL8|$5Rqkp(KI#io_&yN9FN3f?_k6_8T4|rwg03x@Jm%Au&pfQmE7%3N--R%u! z@|x4%wP`=yDOupj<Ng9;=!1HugqH|s1!wNw*=efv?`2(c=od_%QT5~jLHahmTO_th zxZsi8n-v?m)DVh=oV^GU@3)$Xhv6VIWQ0lugmR~DjpNr484{_!B;f1|jVa8Uy}%*u z+4&PU!*+Cbs-!6yCnXU>$aP^5n~L{h0SsOFj{F%UYcP{bGA~W^8xZv&y;YyW77Wty zxS0rc2k$6DdSIKeUvRCX;H-X5UjWpF-gVknz{>`p5hSjgVra2mI78sF(T)bK0(qXF zhlgF}03{rGkuPQLH8l|+05rjJ#sQG=V?ZhR>*&Rm(J5^{vl4>YIpZPNfRz##X5Itf zeWQZ-*{3`}nEvu9WP4AZV4QoOP(jI5{FZ6rkmHr!GbGZ;bHr>gv8mo&^;)m?P|<uE z<S_y$IKgY8?z-LK?W*k4bvC88i>0sIJ=zuvS7L>uBPIjRq|l*!;d!`A$l$3+^_Lln zxe0@Wv7lYU{?99}ZmtU)MbhLu+<F%3fdDT^3dm>--k_7rP}%^8Plhc#K&Xy3><(mC zJOsSJBpP7;pOdeE^Ti;EbP|R}+<mr=E0!NDK7<0)bv39ei&&8nSZ*<X*DmRt`*Kg< z4RhMo{4kS!VFkCo3EVmRbHrRuo-6d9c|6{_!^#bnOE`AFG}@CeJ@p(hVoYEGR^G`q zkR3sj<%@S@5zd=rhzcb$Q1`StQ?o$BX0`t0e%|gq)<W7^|K8+tx3X#H(!x{tsyfeQ zX67%G@SV?&PAbE{Gz3OLrj~E;iv(Z=sM9~s4jnW<Eg>NO^m^(0H`UR@CD3wZJuoz| zNW9b~$_vWFuO~IoYXR+OcL2EAzonRnL-GfaFZ`A&Q~5-y5t09#jG@XhRgh29hu1^8 zNTnZaqSyLUsZTLM?h(!s!b)Qf*s0#L22}m&WA`g{fg3+~%mR9Yc3k2_B0P?5y^qoN z)((XbK>u$U+{Pr^u<-Y8EvBd?;bG`gi9Dz^EZ)<4T$wj$5nGsiI$db|_7na|)5!XS z=K=cKm_dX2SKh~^yVKt}R~VRozz-sLZ$^0>BK)EQjI6(|6oGJ<OG0rKbADl&)H34X zm;o?PwZ>3C4BRz&u6q}p)(bJ~93NMjLc@C;gG+Nb7GTf!fPrL_wd8U?>)kRC!C2j! zj_>{`fhaTp!@nT0Ql(vnE5B6evoe7jE_1fFH9z>}t3-5)v;&~@0s{1(0Z##}n)bAU zGC|lEX+=Rx4!S{rPUAxiQR5yx9AaCWUVX7Orh^;<H<i}4M*Z>Sya23iN?8Wj7Dbe; z|57F8$)xY6`T%QSkfdEMAyFJdju)bDn;?hHC_m<vnmO|{q(NgUfG2|8m_CT{C?*1k zrLcp{5s}X2c2pp*0L*1?JMzcSA5IOdEPNmqfBpUA`inq^Zvam*I-k^dt*Pyt&F<%l ztWQs4!fy6BksP77C?L_$eEJ>vmhpLbHbLk@ALQ^A>C|qb^m=XA!=)$R73#c&f<!>T zO>+-UD*evgaT%c>0W^>kH;5vziG%lzu4;H*1g1a+^QPPDTBgkNuJ!kzG>u~q2AV}6 zV_Fg5?$@HRY#FVXHdgbCc&#tPh74h)$^(iT>Ha(vi_PEF>&QAFG~%)HZK@$d8WIw= zBxh0nIXiFt2)Wv^(K$gTCOz-B;)Og6Na-m7?4-(M&2mLBQUHsZCJdA0nBVKJFEA6h z&QDVfO-hlH9{>QVMq2yT?Y8Z?*|ccRatm9=SV0+t@Vzyb@r?u5L>r_<2;I^WPG=Q) zU{2#dn#%v%MfH{9k2_Y@td2?|bSMJ1)N3}qSCZQ6ND~4G`apL3Sm)7Y_LQ`I5bJ~S z1`^`h7;_5A6P9Q1CT4FM2qlM`T}FjK0!ebNofH@o(46F}BTo$pU)r9IGR5Na(BLR` zN<-j$<crYc;>%g37wl&xN21PXbv11@1;J;+&lf$S*MF`?6&|nEwj3a#817bqI0InQ zH!&^ivR1yQhsjzk1zF2^Fv>Q1!gk@(adk)XOstl(85w>sn7+zLfob&<{V%K1AZ-J} z04NnV>d4lKC_$KzwgUkRc(B%om5`QKmDZ>S@c<$Jt9=v|!CWm$Grx0KNiMF9P9<NY z!vILgrq62Zc(poZfQJu~8L+~ER(~WG<CDeHwsiuu56hIt_V9*Wgv>;d<uT|}yQ~Yp zGnkQMQI(EV1r`bZ3Vf%Dm6|NMhR5E!C-(N}5roOc@CRfxkE;GsCXFZCjpgjB>L@Ki z?REet_SaCR6X+De!wG$ceF{tyQhg15TT3oy<)#+oMOg%k(<AU&A@jcqm#wv>_ITUm zGI*N%8#pq?&;y4Km4Goy&j(1UL98t1pqeuJ*$|Yxb($oTRkuG@>$>@bMBr>4uL4@g z4aXA~S1hDymY4<S{^rqg^&fA~fe6EINwstsXgny4=*n{Am97kPojC~puG_T@ZQ792 zbL7VN$7eDG2Y3AA+;26dLh%o<;m;h=o+<U9j!V%6qB~UGbm87q)N&J`tl0lU!?nT} zc=N!P43=3KbO&=dTq`TXG`M$s?VTg&jV{P53=y@^us=UpK2K29QvT%a>MnA2IB?Ft z%AG)qY?G6j-yI~j^g|{wmVB{=wI1cpIb*dS`9yn}A$zm`X(AK73bbg*hgJ5L@>~an z=(@lz5A1AWqJiyv+3Sy<cju<}(VaKy4|L=XA9bjVNNgf+-(_$dM`(o^3!IK&R?3mj z%*+TK0i{3LE;|46G<_CYFb7kMrw0p$5vlM>{b*h_lf#UFWs%v%rpbBA-B9Y7G{OM6 z^s{L8r&BF~OCvWb8sUV_Jb?)>n>s4L*dpD)i3Ol7;||vnu+8~w;=+QkOX%ABEx;KW z>VIIEH;?SYJO@9l>WKTP@D;>3a;%G_a?4%yV^`y*x4SurT<kDF7%)mXm+6L;dS#w} zFR0|xC3<kPZ+K5&AlHKw)m3{4@1MDD!Jm;Fz&jwp!hevyeim>$3Md6A9(3MF5nr6F zL-uLVN(HejXi;tmd2v7<D09!^Mh4Pmn-@uLf)h<rHT^usb9r}u6Sx)k*M*P9UG}Gu z&J3JitioppsNUNnY@7nvMfG*Jk;fyBE}8cK^EZ*nW=znieQjAskGzOmGjKVO_L`rZ zKqf*lp?y5P1)P`%9y?g_NeA0nEZBG;r$+cWpcsv*;Pgqa9jLSqUq)U<=SbPE#8Bgt zuM9s}!DEbj?+X~?+E#P{G+-}y836$X6NhEzce|oP!7FKPf*4_oOYdiG?sUIe!7$26 z0;s^5(gL^tJAeq2z)%{r-}a!#?XNB>rd$0ym&MjXX>bU6=GPNzU}=B{@8otU0?IV4 zf(d7~Q2!+`e`A_z_&X3wJ8p#-knWT*BL=E_2dJXp#06#{0PxXePJAsrhi>r`engl9 zzY+i(Ft#<XId6;FGjL!1F>+3==XNipW3~)WiK#xzx-MyFr>-;!m=Y}Y>G1vW6V)H~ zcw}$mT&}oFFjoMTqhbR-(#xf6dbPT1@GLWXWGkRNUYrtKbq2RR48!Z625d)%Y2^jf z;voE!$w7ynk#d1wz)eqU-xqwc?DC*3$=j*u&P~v+hO@NPb+mg$#9Vp{Dq}8PqKll# z{={J-xlbTzGsFE}wAU#uP3%MwevDi_JwI$AWb**-EA(7beTKc<o3L-&CB>RwbL-|o z^z=<o&f&+E{_TY_s@N%Ey5Qk|hfVXiP!j{BZ4i|$`om&FA&u5QAB^~qzyoL4bfGws z>>$J)B<F#)Hsluz#syhbwr2x3tgO6tidr01v^f9Iqy}E`WvI9mD%3yv033^u&w7Xg zc7do14COsQTKA+rgAc<26$cKKlyG;zfVLmDGHUZu)@(dt7iZm2K6aZ0gsu2ym)w*D zbq~fSIIYARqW|X&4gR`ovfHLIMj?%TF{=BL0Kd-Ku?dqeX`FCUXI*5FNul8?oKCF& z=V>v129y`X-Rhtk8%#55=S!_y8MEN+1$PyV8?Si4jmX4EDc2e-fZ|#o87{kf2?co@ z2Ghgl0q4`@6Cjn}1Yr1nUR)1R^S$S(LCajq<HcYC^c~Nk?P8iw^3JgY%v`$S1EvI$ zafQs5K9r9%I8hs+27t3IW)I<UgC9lwra+6OKh-8e)P}}IkE>@;pN0R0mV|q*WgOD1 z8|fu1eI_}7*J(f4Ktt%jVSxkMZnAF24n>WP6(k;pJ;-xK<Sfe<XE0E5OwN4({`G_> zArTi_`U{l+dbGMN5jYx+IUb22Kx{_&Jfm&Y9)aOOb8sSf9qBRE9x)RDbp}59JG7Oa zma<9xg?H`0ehIkYbuuJe>K6`F0uLu>j?=HKwfceI4`RXBCF(Lfg}>p{$_)l%p@|-9 zWk-lQY5WCg(#y5dhRaV_LhX_T682`I3%0=;6?l*+c3_YU{@AQ~Gf?v&|EP&F3%?Ei zm8Aae%%+<Z;sjN|78V6m9dNY<L-hWgGVIyTWyaf|ikd|F%Ubxxm5TDS{qaNy46dm3 zqq8Te&Gbt^L3%NXN@md`l#-^nrF-B)3=i~jE7)@?eCQ~kR)MaH>4}gEGXz_%tV>9+ zCs33ffj_4n&!;`#=Ngcm7wo~v@+}*ff?k@$>)UJ<Q3B1oN8~awg3K%KpaHvJ1l1=G zZ+wC7_MNKyP|&36N*6S}he8;7R-EZK8#S}|3%WtXWjRbai)S<7!uq~nKvxQkr&<{% zRfgAqy^3tPrz0B2632g}m#mdAy}&Cm^edg$!|qq==AR6`fge~=Z_aqoF}qLOm;KkO zm+N=IQd}J@h{^mo7_{k?k<O5#)z&AK(2cME`pdrNt|tZF7f2RIBB7JDw_roFX+oQh zlL8VZpc8}JLUkImyH}AH?7jZM16Me54E%Ya8Q8aB4KgO!7P;iSy5Rry;VdcRj(zQ| zyH3aCpd-DBq)0cGy~(|xQil#gx0#tAv~vZZ@~;W=6(rl2OHl{KwFD*h&}qj`u8>^V zfKc{ukjLWds{S#i52{NNU_aM5Wf^=b`!}NsT-clgqNBjsET=+q;79<klFQkwab1VC zG%A0>Ic?Jw+_Qjj_tQ{ZwIZjf_;SBMOfR<S%TYHWv)83({ZApcy}`{_w9I@QR65xL zY}6EaV6kJGYYb^3hJLy&!IonMUgfhoK_fXp(fu}V{bnZZ1~e|FPBJb{R8-+XO9Jql z>S<yT3$ohB@X{$PMeapY#k#N6pUUtgK)V1C9%CO|jBplPzWR+;4?~xUmw?YqBg8g1 zJ)f_f$3f%+wpUt5`+FTwFuSKVPtSblL^EVd-1L?MlILJU@rbka$d-})|Ct%U>8@UU zeHn;`Kuvh${&4UYR}m%Fy{6Mwv5W2xKMt5|VmY=51?4waNwnEj#4AtbOM@r{bUI)C z@Bts77)x$Gy`2sn2FcB(LZBh82uJDvrlKEuo($&>I4*(zz8`rtud@b3NiaT}+E@Hx zsa1WwgX?!~<{wGjyzD(~`B9XIq#@b8RNITnMNC%Y1w}8mTQMxi3xOwPpWL!c@nhDm zXl32q!L^{dfqc%sg-&jnyXj-r8l0tnQXda-5F<>gfd}#3Rtv);woKte3?;EGOHhpS z_A=H!hdd4Z_)3ayLo_b`R!k~UpR}`AM@yubRpLz+1Q0P)=PgMp<4~3%deAXbcxVRn z7T8{(3XgeZlHps%$|U5pZiD?CP(Z*#$y{oUqYLg3V#D9_E2NYmM+Lqcw7_txe1P2S zha{`G$Jmxm-d;>ruz>-f^%cxNAa|~#$G@%=v$Dt*a{Pj2V6?~K*V8f(gbkNSX+e4m z{T(<K?Zvw#mV-cFbqRoGcvy|+`=k9K{*pdd!Q$jKq{zJag6R2Sdq7mxcC;XY*t!$@ zsD3iXO#|8la#l4Hh}LbT(YT~b2V^$T6#-ieh|9$*mx{NAs8-I+w&;&wY7z)dg9WrV z>L;nr40FktYwdZywul8wWJKx$*%#z97$W+HV8@8i_ACaRAs`s@&4C-DvR>SDfD5Bt z^q$gE^9C@nZ||2M&erCoUj?5vjEFfPX(EREK+Up8yOX0?_9|l6iEyYL%(omGCaS@= z5)zte|GUdy^-M!YyYgWKE{d$gLv`kf&o|rd?Jyh2y27toDPIpYkUj3usS$mCdPZrv zta>6OTeOdm=6d_zC<VBiRlfyaZdn&Dx+vzNEbGYI>*g7f8DX9O>;b;vvBZc#)6v&5 z(G4qyC*HG`f9HFUi{yF|D;QN=;FuCHKJ&KX3eeA?r&&&w5ouCFfUFfzUaV0-a0i|q zxm%}P<Us<J@W@xZ%>%4I)4s8Xn!DwbSE~Zohjon9ze3f<<|K@Il+N+i=+MYhaIO0e z?=-NN>>tg+Ny<Ki`FYlZ`1k`w9ok|O5%WdE;gXlL2M&4S?fQ=MjU8`KK<XspK4Ahn z-~RT#kIt`1)DMnI(4z!B6*+_iuAG}82mt|hOmuDhbMWvQGq<pxf^N%0Pv3M`-`59s zc;cVk-r=ufHvpq3#OZc-DNgncK4NGL*{nu+2&9yX9ybyp@x*UA0@mCVSR^v~*u@Dv zg_JM|_++{6QPuzW)OWG)`jP$@7~+<E_b0Ww)s(jl-z|GSp2;r1rY&!vxxCL9Ym&D^ zs=lPJI=vm*?l0TJp)|Lz4(tTj0bofQI`XoVOkdf{?{Q&GQYqoO*PVg-&-3Z3y--*H zJwJvUHS~*>9eF|c8`7E1u#5}#Tvg}|RgA3uFT8rt0w>)se`cpq-pF(tfRU1ypf-|% z7OuRzLqP3NFc9KOP<w%i0OmUMWh|<9YYC%;CSZnuL%n=Xhg@2~x~MzuW0qf@G*Fx& zj4p)j8xms3dkb0U?%f%17yJZPOK$gGfxQ)&WCEEFTr)?T+cM4&iwq@{8UKTx_nmwp z@W#TaQ(_>s*lv2t2whfyg~0Bn{EL&vXg3auF>2qD=n`G%wAl$_NTI=pCP=C-#N)0$ zl@ALcUDj>yRIruEu$XWQJl7dIH-(42bYi=WRq5aB;u^5fOJicqL`vc3GLAi2Q`VbK z$$<3-<J7E^VSz20!-+-+r;OGXVWZ2^N7L`0XQ@HBZ5eli{woaP$gR)QcN4N$gi52r zuoH$deeyiyeJ7KaWp9<1!x66^PMD}u*^V@4qZT-MAYG4g;G-+PaH(moWdXaRP15#7 z=(*kjCf+{J1(~BfrhY&-@oCfBB{&19jxFymUd}`T8Q-*uy89tEkgnqO`ON&BvieO# zW6e*9zr$n&!uSo0I-Kht|Ng!zB4uo(mL~FIA>=etEbk*<=<?tj`2PrB5LkL)vHp-! z&gQ2vxc+ny+Ly8uhL~BigjW^fAXFX82WTc)F^3<cia_<~yIy<aCH{PW-i)%I*67Vy zSi5t_Y^}Xu4vVC(<FK>MO7DjE42#NHF=VQlR~eYJ-COa<E?_R$khU<@%S|VqdzI!` z&(|!7?NIcvtSZ}KZa1UMwf-2f;7)EgQan+2(b~teFryH!Iv0*)(e;<n^*5}{zC;hK z+HNxx?T>a;MC^3(YYmOC|N4UNw5hsxf-+3TV<pA0`xBY7irG`7An4MGsknzBE-mB< z;TV_2uz?Xq$32FF1L)F98#gW_b{UIA5inI1>?Sz;_;<j66}lCh7<DgUVMh2c*v5m= zP2892a=#yD)cL|G4@uuMhdGVAGpD7H7CbRGQ8+P~+6-dtdK;rin&mF0U$`ts`sI^! zn<Eij$+65y;Vtg^1XJBC{V-pLc}33ID&roE>}iPKc_mW#C_|^}r1Bqvkv(E_G~7Rv zvqMUIs;3vRlm*SW_TX!m$R5U_<J=2oedq#BX(FO2Gg3uVD<W|wCl#|lh~hE<6yF&w zM{O#)TFc#KSvq4{>9U`$%gJuy9KN7{{g5H;l2nIS_P0m5PW1w+h()4^3WNZbi|z-n zJ@Jc$Kfee9K*ACcIr!}R?wHos-=#)=DS`1fCvg*8wf5v&;jnCy)aQzAa}_}vckueq zk2k42_~tXS67Es2Pih-$HCuQlH}}3HZ0Ax;wU`8S?bGB81f5%MD)qYm%C$e4wTvlG z#;BZ}>OP&_pIA?PyIQ3}vlH2Buv!6mEMG=@>_Bw?Y!w^-INSbE_gmGgd@8J9xU_)l z2=hySmD>Q7#6`&^L&b+$P!l+feRcHh=pw-6&P!j95u>hDEK+YnglQUHk9_JtcEa^o zF~#odNsi3F$1cm7a0HkdL~atGsc=II>&HC*v@C$V67G`$deH#e#<7#?&7|I`K!Zb9 zf#@yw5T;+)esq7NfUi7X=tozKbYvpo<d0zvqdd?49Q&WKRRz6R#3jWOmNwD_Z1k3n zHyKy0KD9h#jgjS^3^m`6{4s-}mf6=A4%kgk{OEer%xUODHe^dH#P_~kFFiT#+>biA zm`f+BEtC0IGE{DiIl|Vo=!?vA^}2YP_1JJdp8Y<V9`fpnq@H!Hn-ed0m}+#9{<I zRXz>PcRJ?9NkCh84_<%Rw6%_p%*1x8Faepp(K&Pb`#H`{fe!BEj>Oe9#vJ*jJHmkl zG#WwW6<TKPUdl1covA<J9_AF+^7=HQew`|6Okvy9CuFO@CJlPtq3PvNL|Nu7y==iP z#-{aHNjHQ@ll}`f>0CHk1?;4>e8emR*Y8UjXbd&4pPyx#tIA}WUHzEwNKli<R-W~a zvWJ%$odaql+{SK6kyM(LYlTg~zsJ#&_vRU*P?HfqgpKU`Uh_r|49J0~K9)Zp!&s|d zJHM}pxNhq3V|-XlSd{>uu%F{1&0G`C4>tX$ZeE$(KhtP#37D0o=>cDGNKpaDHTC?d z>Q*!A6)V*d^hwi3H-c3yT`|*U!DuI5|7sGU;mK^c<R>au<cOoKJ-2S&%?g#Q%6^KN z*NSB@TAb?QP`!K%<0iL>RZn02FzuiI<pS12^2AN}oll(<?q?QeIck%Asz6mJ7yAg& z#yKH{lw4pL7;yIcAv9+_>GzYA!fa-@%%8&yxw#j7=<F$+p%*>R8{OP=-Hm-7pwTL< zJ$<TK<=30QTsO{Th|#bn($HwN|9N&B?Ld3mtIY*6b1=1hWLQmIS}n%d+Or*G!7VjE zCzt3xu9Z1Z2tKvRPjj~K{t?ycYT?s^%9V0m%Oeyv)hA5zTi>L~UP}4%2GrH8k(MI% zFc^<(GKYC8lMJ?CY;TYYVz`mYM$dLjgT}PgPxaO(XVJ{w0+9OU4ky05*?VxBeJa>V z^m4)H7FfYp+?i;EC>aZsWoUGAtMj2ht3I&hgsTH@)x@%SHLe6EN%CON0Co{iqU35H zjM>S!Px|;56gMJd^pq-!-3hgsl!XnQv*O=($Gqjv4KOu=WSpcIyt-KKldQd<>UIaV z#f{G8=~p}|7j%$RIid)Xy&CM39@wSYydV1?#ty%X(tnm7P)J>dMw1!oXk;s~&3ISB zQpdF!tiz;A`4gD_bp$7&slaGszCLceGNyLV-KD3&m#O6qyG5%V=B<&3PPOxn{o?+Q zgo!_181-EA#!2>l-k7I+M3p22H3GlWPkw=y3?d-?GaX2#Ht9+G@=7M+@9zkhpK0K) ztePDoD??Xn9$3f69w+-S7AOZ7lP-YIk}SR&j>p}P(-WLz1v8dZM~>{|j?T#wa}4oM zpb2x4z^p6k9<cdfb4_d4?}8lj=mh{rcD3_}{cxM738P%u>-O*~F=?!Xk7RomPjVrh zV+gW0a9Hl16{L7U-NRhz)3wL#P?H>)Go<q{LkpITKw!HnM2?i3=o=qcY|LRNF(tGe zn`GZztR>=$fMD>J$v0wpTm%^&8OZ+B!Qs)9!Y2XvB>&535g!kJrdKF6t{tDJ@IUi> zV*LmZ3o-}mZMOz@*e?c2<xM$3#<x*oIj)AZuj?!jGw<Y%p;3z4t1(LiJ0e~mwm~q< zK~F6dLgX+4pr~Dc2y57VXDG|QN&BDW%N)Yd0waeJJq~pO`3(r40Aj(&RWLw38#6p+ z?e>)`Ew+*qx58uXXQkHn;Yf`_X`X6I4rWaZbo?*IQNz%Kc9lhasyM6s?6%<-hqZVY zKD;wSWQCu!CpUaNkItLV*T0^>?cUa^eEb@3_1Y89MgnKmTd~&Ky!@lg)i<HQf$}3( zeE^#-q9tLg8yrpu3_!0wexz2`GAI;#GlScVZz&?w8rusiyI*HHPyh|ZUOd<IH7>6B z;{KQEkX(Vk>qF`0X)bYFgTqbb-arJ)c=L>|T>&xtp(gm{c{UNk`Vi24{%2Q+wv0{X z%L^CeOPzlou>+Z}ek%6`NW|v4pKr>fzsumx=)u`h=qUW?1X4f%gGu_{Gg~p6sj*VR zcg0x!zC|($@Rj|9G+dYna#gIMItLtEecIf*Y$JadWb~BQMbx-cz|ak-4FS8!P$cGt z&*^RDo7Ul|Y7hw6-#)*ITptS9jd9-DOcq9lGhZ-ze(RSPu7L_~j6F$#F?9HmZV?k= zX|2Ba`9mF{Pa+Oj-p{05_I=wO;GVT_Qiv}q<n`lQB!uE~SaU3X2T^DPLakCL5^IiJ z*K-PSaI4rLi#SWZHbu$p!^S&Q!u44H=0oCdyEzgJl4DwlNm$uE#s9Ny$l&zyWJ<}9 zSyr5TZLPmK55(!kbaX&V6WBw8=K&0Wj!el{y;Xv1S8=}<<n=XC6Ftqwi9t~w9q^3p zXc=8koRqax&A?CKN@>5bd5P()wo3#CXi0tLq4r3aS#JHE<eEHbmkwPpRr|4N(>5o9 zoT1E2Ae4A`&gA5N??wdRg)d8AAP#+R|1@+}V1t!*7q~$yZ~gskd*GBs`!vSl44I(u z&$d_TP$CaB?0}0j9j}O-&CA-z7ev2tFbdM8j~sefrol?~q7o&hUP<nXp-5%NdSc*h z2QKZON<G;k)ald2@|*%dT?UhnTa>1r9Ogi^7My0&LnXK~Q49Ef)v`&OjS`!I{$U2D zIiL4^@u@ysM0k)Bj;aw3<I32ij%9aFQt3W)d&A}(Jhq$$i^fiOjpk$2tuY=L-@r5i zRw8uUVZ@J+%ZToVbESHkfvR#KVsuz4gVJH0awVnR@T%Qno@854s5ynW+Y2hnIeM6J z0a%!Z7*l09^_^;(_1R0*nMb{&hF8>w%p|#Ue=~x~+P>th@5Qv77GI{T;2nvG#cA?( z9;DH9KSLTA05Qmht#!oWy?MNUM@h>3gKmrGKF;AlDv06Sd1dEkFXckN1%Pq|d#e}) z7_Zq|#qi1@;{H-ZYc}FyahX~{mMGbjR8^?zuE-Ya$JDUV7l`_@qA~Y@G{|c2S3oH_ zP4h-)L~HsDrzM62^Tn_>@W$c4lPq<NdW4-7MY8GwxWr05UYKgG&?hg^OsP1m*P*=& zi|+;X6-vkruqYTK0dxp1qI8~GRQt_K?t(?ra*QK=8W{;4P@K!qr^xuQJ0boHITO`{ zr|PFez$FXHD&Qe&?zi-7(^g~0=%U7s)&WAGvr5?E0`sGmw;xoRB4gS}ZlN(HUN_+> zLav5<J#GaCW7DI=Dqhj#Th_RZp0%UDS(v8O1jyIY@~_s_{q*Cdq?P_7HwVaz(No)M zJ_W@*76HH&-{5g)Tl4Y6PT9fCX^Fkc<we6AXTe(R(Nw?~gh@WSzj<q^E-dj+?q}Kn zkWcOLv34ka*DLCJQ^R<maY5VKGAI>!kK>E@hLya?wxuPc8hz#Fw`@u&Qzm?whPu6% zp<`<adR~vhNBtaN%6^|@hE8i4%G6xvooA;HDjj~_EOTP)Um{u1+&yg7hU@ZP_j^h; z54Q2UcKSC<HqVIGg=AJks2N-~C2&Z9G|E}^YeE(o-rY&NI|!ECBOk!i^_ot!1#roS zM!-J?yvFVqtoqmDc=GRP?>WQP0wvJWbrEKWxiBu2Sb1>}NN3;#$63;e^kY9u=BA(0 z%8{#E8nzYo{)+CzF#YFUKVW(}Vf0AfvdAiZcYC&-gYDnM5mQ^36Qx0yvE?R3;!L6( zS@2-(_~Q>i8Ug>-@EC(r^?xJx7*_h23nt=bU)7rSOJ<xv8Cz9*2gc$W{p8G`7LOJf z9PnAo{q6=5fP)IeaSQ8S+xQu1eBPddgKP<636E%#R!CJHAom0^TD$ObxJfWpqdNX* z3oCvbXmHf&MxvQ&7mi*CXHm6xacwEy5nkU}#cR+f%r$IVvj&0CuVsoy0_>5B*wsqp z;~PydAh6J~)`8qKy0I4NX#fbC-6NDbw>{g#F##o$_BzsQT6vJv?<xlJQbbq`^A>Il zZHif~n?Xb<`8q*TeF;X7k`yE&b0Lx0c`zTO1-4x3fb^d&FIm=JwQ8$42g4hkA*?TD zz}*|jb23iL^@4IlWd-N?K#-gkX1$R6X8OGhYu$Yh1^qjN5IM|`vr@Y@@17Zg0O&J2 z>%?ahJ;DFd!N}Z_iADw44-G>#`m<UQS_2te!?xS2AC>M~7Gujm%M-b<#K#a7z<nQF zAb?H<c(X8}FVbWafm{3`#NoM;xQ|Q>>|26aTOCO<yH!`Cg}YBrm12sr|7^KAtiGpQ ztt0d3bcK(A2?&r;0Lm}+54Bb?Wsax~kAr!R;L5h60Mjm7U29p|$$`p+WNhc1aDe=4 z5Iz5gTw4_%x9ZB&o9yc{u+{qe7D*2?*4_=1>)6k9^`VE!R88TJ+m)Q}1ATghhpG|0 zQ>Y%5$iKy!gRwR|`KOC8+X5z-f_(yvzkCID3VC^?;NlL1L_m$<Fu}14AP{_;ulQx- zTQm5iB%N^r9`K{q05j)bi@jLIkB(LTUWGf@nu9}jyd7=IOqv1@7LAjAX|gk6k_O0s zU;-QeZRHQOcrZBm4veSDZBHamJLHJ^s&%%w8e&?Ne%c>Gq-^0tcbr<z3hPlq@A0~B zu~h0aIWj`WmEpqSA^I<BKz~=Xd<z-M<K=qN<==0kBVMA?&BH8GWGdnW5iD8pfL7Xm zmuKeOv1(2Ih^{{V!)C;7IJ@;Ngyazwv6v9J&nFXQ?^w<|VQWS0$(RCXgZE_^z<6dZ zj0mK+4}CrGJGNN20z&3nr}8Zv>0^s!uy6b~EFytq6Nbm9!3d`I`Y)6OY((F@m)K#7 zw8{MDyz-_4D*QDaMo!&*qZp_EnP+$%+ALI|N&U&~rlk|^AEgg1+~}%HH9<l)g-og< zyAc;;vR;!Mn|D;^nWQiH7a6DmuDbU6w<B?(OA2E2qNBks&-A9_s8I~2oaiuwrwxi` z;78{`X5z*l_9}E0R-jK<5V7@LWc$;n`v_doLB5nj@m`i(7ol%gzb67hFh_&VH<&Tq zD&t6b@hJYyiS<YPYD9G&q$9Hix7JsrWl6^{-8llhFKk$;cFNDxKf&XfuoWsOGA;TC zzLNO3MZO{`c!j&jk6^SQpjS|Gwt_J0_>&HHDT3?nmi_J>r&#<0jba!OqxNTD3H~Nt z^f99eo=kW?&^+#ry*DL8%rW7h{F!P9ga2}onL&W(lK2Rha1(-`)(6(=AOM$pYs|H5 z6z)Oy!O~|pfpxzx@S?_(jEf{f=7`cz&-~u4?@=94&qXGCPm{pdv%Un<^ZAx*h@C2y z(GGZ$H9r$+`-}H_h;Ity326WzBNl)#7sP&mS9Kc3|H0%ND{@@8cu0z%!7686lTgZ| zQ20Qpko?7y)v`nL`jZFce-)})km-&vUK!qdfHrad&30(%H;UGiXVHO&w<27^bMzdh zS&lnC%Q>vWFM8eHN=2E|c;P%W9v*jhW@~1kCU`=$;k_g=SMhn#*O1#^B;)-jttgPo zVGO%o&i4ob*Y}?0EsV)%&%^r$u9q8#d7^+?4q^s5Zmq$xkTwgfGi30L)MIU6$x2*N zMY&UM{P+JR>|mfMgOO6XQ;6>;nty}T(_H8(b#Z`6u;q^5Bv0JeM5+!+610akSCVqA zR^@U%<fet4h(VzSq!Pr?qU%VwKxC6K@kC!qSNm&&PO=uge_2dO%Y%O;kbmK+rNHCG zYL5>ds@2pPoVTtZid3RxX|3}IBLN6&+fEtO7R5WiU?X?E4aWV)-+(4-uAr|xnaPKA zum`3PzcxwZ$4;{EQ9{u7IUOvnJ4PnH>>Qq+g{fR#JGa%|8jBbMs_QqfiNEm0HtO`} zhHg7l1n{2zvwOaEqgm0UY3~oXKwp^2XM{MFZ7HBDe)eDrdCX81zP>W)UM~^z@&9-g zr&rYHCWeaI-BrOU?V7ofzUC(w*>s5*Dqwbm^09++*B$D>>Z}a==Q&8Yg?JBTjI7IJ zuy6(#cA^l(OH0%!^j_eM3%NLQPyfv^;$)Bne`PGz49Cq+rE6hHpBzj-Qqln8(`}|q z0c1ipqx)>tq>{yiej6g{CzS~CzNdsgrDu**T@I$NSss5rD`I#rZumGr&DXp6IER1O zRw#$dci9)rm<ca{kQTe(sK}z_<fu(__RawpY-CQ7J+2zx$1T&yM-*20hu(@Wf7pYV zMNNnBG0PlGDd)s8xT5|J|1Sf*F-%X(-xA=l+%oZ_(MXB#MW$sfWAs1Bvs#4{NO;ah zi*Fgup!xUUd8V3p|J@6&$M_H10`I&Xuu6&AMC>;(5LWcYbU~>2J2xzVk0sX?`@vCI z_Z6)KKpe(7{+{<KFKjWWH5NEihW8jwCHrR>Tc310v%F#d5J#EB3yK`DOf|TI@J#ew zpn6R1sZv`8Q$@s@O9pSVDhmZB!)k*;R#@~3JC!&9`?rDkQ?^enBDJ-)FC39tvr0x| z4@e3UK|*VGB~1aKgCV!69llJIGW3@ZsBo*UWtEbyetm3U6}K=3R?TQtT;<#;064TX zci`F(K12aT9Qpva?n=gqXXISF<VK`9OA7vO+-PjIddq&RL<U#pNSJdktj;3`>YgAY ziTt2xeJDd}_|48zfo|AOxc(i)#+e{7=zNORtc{abAKGHu5Fn$*enjuaxSSB<oF%@V zwb)FeMUMt=ANT$Hab3&LBZ;35R<6ZhkGdU2{eM?IoeyJTb7lO$zsf!KM}fUqq<I=l z(AO|eV0AI7TgHlPPFgM_y3{*#W1D`i01Q5x?;#NYvng`1O3h(wO2`)5OWz~7Bz#$M zu_ZB!&B$;Hwj4}#k%*%?d#9nFXI@#14*m<>)t8^FqHRGSn11b0BGJX%3DFU;?6w96 zo*LKd$&<H%{px*|Q8SOQ1Vrth5h$WI-^_;2%7qqh>k-}XU}P@MMIxR83l5jglHr~f z?c@X6rg*iF+A1uLr#aSPdw>y9xBG)}KHx1Eu7z8<?rBbZ!>Y-pSdrA%h@HuEFXW)0 zY=58@TvbE-@q_$Y{^#hhK!;>jG$xd5PKKSX_mfFSlpD#8h!vX<f!VKnduDuBqSBE$ zORXTL3Lvtbx{Gas?RD}~79X@w{_ELolDb7kCQ=_34Ac#-ML(z))j?Q<o2UbcJtQEO zl#ogp@wEhRhRLS=KiKcz3Ao>S{+y`lCS<p7zF1dBAQNv#8idfsEJWb(!mnW%kR?9? z*6En4gzV%5-f6c3`E3{x<-(abg&)*lCs*%X?+L_Tm`mSnBZ`g!ZWou<$9{mtg#>w- ztkBcSV!A!z$c&reWOO(asQT>-n-F9FIS;FP-;+LufTF^xNBPL2())U3_r`k2SxlPZ zm*{cm|4@VZvkG*|rp|;(+K3`g5q)WUAZ)@mWZWlA{)CBV_~XP)<;Q;p_ZF6)P(!GP zp<`h2*Yoh*J816!Is2+K2{bU6bGe3_0dYa;f5ij{NM_5$@KKz(H1HY&sxyjY%qK9e z23Lv+Nf`s@np|0zkCBSmT=45bf;zLvn^7>qM%h#x1&HYt9F<`Q>XfL9;dsWxkqSLB zBH`h0v-;EG{|xkB$^}Nd8fG>hGG9K>0f)_(S~Y;OUJ4l{@VXzYefsLf^;B%$M=xPz z$>2j<lHW&sST|79m`XRu;ZF_XuH2KhjN?;D3)cK%c#VwcPY1auR<GteDaev5N31E) zpYnwxJ1b2e?;*-X*z1UnmSDPOr0R%K8l+3aQ8@pj+FzS303HswtO3^?;%*cIgUoSW zQD*|THF&uY>S%DGMygsY$MqgpktZzqa)kdq2}qE6r>3j;C73WLX}al@AxS~Hrz7uh znvXePJu*T<!ftK-4S~rj)R4TSmCp4BiU`5%%?ktmDv%uIhV{G!2tyQX5C9^8gD^N^ z3f{1up7R_>`^NK$=fTEZdvqGf>1phttDhF$B~N&$M(yxW2(vUaW=YCUocr92&GF0# zWYB>Sg;@Q*ZndMncE?Xv{4%lB%nv1wfV0wx;|p_}8yv$CCI+(j|7gY(A57{3$tEG* zx9ebKbHaAk&k(?{4BJEF3E$T{=gM@tcr3Hl*ze9h_DJ78tIwPy*^9f(d$J;eFZ9xE zgsVHVV@;grfp)p^;RnXO^SHF94?K1KTDrq1nUf?G?9oa+l;p}s;{y8;A;pCG0Dh!D zyz^~Z<hqpX3Sc3;{u(@+m>fydW?mD0kCFl3_Voz<rOtMF2HsOeI3pz(XNFSmgHhc0 zL(i09BJ^Z)$Br%_t!iK)SH^I@a!)_piA*-}QFTE?abwM^G#ix_Cd?34j;tK76AH<D zuBEDh3zn!2UFH6|`$;jAvOCM7p@{~j>Hz*>npa9;M>g}t8%*S9Hv<9TLT=gc{vk~2 z@rKz7A*aAG)Km{))gyqdmjQari!&&5@qBx>zLB>8xaSP}>?v|+jXAS9LgyZ*M`}^h z`*V%-u-!N*a!j6e?PU(O3eIbZ<f*#lQ<$}2Z(};Y*D^jA=_~wPS#+sjg9}d#hwDVC zpcrgLS)FYn$I;obA@Q+Sl+gL+%fu^#s$Mtgb_F*F(;SO~f-BknCne4tQ&Ns>Hx}!L zxJlH?GtnEJdF8dhQ}bT`@h-XLnB-fx_s+Tb`uWUo)q3^R`5QV>U%#6?rX_Q|lW(OI zd#<ZpZL#udK}+CX)epG!wYrLMY2^7I5Bs*V_=2fi`LD5+h9zTr?jI_u<LNvNo_&2B zCLTCXH)Omq>Skd)ZT$6dK|$dgqK^Kj#@N?FQH<6^64JM3$Wke#kH}<;=4T?Mtx=`d zUwpfg95=qsOIPiY->99${c=tRuR_rFGP(}l3o$He$%^l@Y@WE@!m7Ss8as$JBU3jB zwk3j^aN@z|H%o?AaLK9GMSNQS{h(jOECmh{J|tXS?p}J$*KXEl)bnCJW?FSUBsb#t zK^*(kZL#u#C!I57tI{!KYd=XExAHOa+jgf4A5gwCQ@AsLf6IU{GsVM(bFHlHz#!nG z5dldvitfQST_lRPzT$^syO^2^m$wpM(jV`8@X~g^35wuMp-#(a6y(Gq{>CdA_x8SK z>cf4XjhwK3HLR-6pF`qJ-QE(-UmjRpa`_uN)tSJNUpo53)-=Mzt>15<gh7ELpPFWp z`ESsVO%q>K0t^D*(Cxv_+SjyLjXAxI96k~;p{_)CA8p5#MDbvJEXGt?bbnN^=^dPx z6>$}f3E4OP$YQk!ghuI8_7D3T&A1A4GWcu6JVR|IyRAU0jS{&kNZa#=p>v9wlteL- zT{Ff$-!OP--v>*>Z2}Kjt3lU!x<{}1n5z6Ta3ZuOU5~;8Jda!Z3?sH?Af|A{h%T+w z;CTKPz{>kza>Q`>6FZM}taQpyns(<VTZ>2ZP?~%?{&%gPcqEMsovF7*01~u#hCgpd zF@ocJuL@sIO*3Z7o9rb?)PgDlHtQp6WXz-N8&r+=e0Ty6oO@f$)SHb_V|xscbqb2M z!km2FkApmsdKPlAhj&|cRV;O)mmA~tDTOV3hz3q7U8Ns)ehxNnunP`ksJ$`Gz?v30 zg^$r_$FzGxVZ`3Z7_a|nGK}KDQPCz=enW-wffu(SWB-}R<X&r?@^O~$2n~wYz$iR^ zeDmdZ<KGhbO&B`rU#3~tFE|9^K7BKHSJ<My?Q?Kivt4kjHt{XxG`H@TA<ys)u4Hof zt1UJP>43*XVAK_~T=oqqG1q*C5c&OH<Efam_21{S&qUJrD!9zCkPm*1K48S9WOPN; ze<3aKvaz;g<TM{W^~{vFkz58dUm$8J99BKVjX678YUecBCEhpRg{mNamn^}k8pNh2 z+Kw2q4;%hgkhv7Y)0S^JS8Dw#%{gq_!0Y#LfJ9%&i;PB#?fZPCpMt`K**-yL*kNj~ zHRQJ5VMYWj{!{okD(=;RQm)-pFzLhuEGYl5-Q}5Td^dnNgqAW~Q8(H!5xw{o;#HJf z37g(i*SLpmy@|OO1h}&B@_tuR^c{O&{s=@2R*Fc}dtLFOhdukBQ=i<bj}&69B1_BQ z63jp93L;COU^3N?{Y$I}KApV&YP9j>y9`ax)_IF^Izx$&o@HOc?eLvFOvuY>Tu#C? z+j~~u)R28hMxdv>TR=%QqIu^?l~`^f^=@AazZeJqm<f3^TF)IGe5_#BHw<PcQhR*x z*yD^eNKIf^Z%o~#w^I#7cMvaqhA@cnwgZ<kiQ~)Dzs(XLPh18oyWtzT`m~?mI9trC z>NV-EaV0iVsbBN?Zq#YTzKgT^^IW+RTq$y_$P@Z2#@0W3#7<N7o?&**M%~NPdWEGs z6X)0W&rGMSd>BM^FzloC+kx$a;5Zc1gcfJ-Fc{UCbq(d{lu}${d>{6?1U@cWt|XLz zo|_e#?xFj~a}&~Mzg*S+xJ>1{iS2JwalV3pcJMP-o}o1XOSrjKRU!yJefNJ`3Wwzt zDrXZ~BO~W4)s+D9U1)-#Rj?N$bB9PM;FImn)em;Cvqy#4j2n1ke!plfCwKxMuA+LH z<0s6fLOlwrMN>cZJzhT<vYKmHd8#-UTCAq-LetAwS<lK-Ed)oSmzATOG!aL`cw%Li zS4Ezf6L%gz<cN0?Orn@MrH-^={?;-wE}HtnODs8#VH{$j_^;q|QH$|F_)M9`mCu&0 zOxL{}s5-IP8mnjA;B9BWk%F#er;Hr7v?z^?xWBM4_Ghl;GvFCul7xEXf;t<AgcL6S zGW$J<DN`+Gq0<S^MQ$x}jI-&#>D)bV9k~s6Lc7A>c5sBvowGK=l;<J9xMwpLf5~+g z`z8;Od$dCfzDkvDJbw_2q*ig}LawED?1~R>W?INIKO%BirnGB^_9TS);B-mHk8C>v zGrMW@GcT!JzP}NHq2Z_mi|rxU288zRN8$9=HOXK8VyLe?H{+9JG#l%=Jy_>}!n2K! zvi6=@PSesTmidL8qs~qpimAQ?%@uofSSoyUkt?p^amEeZg|xa<<*E3`M*g%g%q$xg zv=CjcxWQ8eS<u{ffvn#aV7@o!W5<P(kfo)?AEEoqc^;%6<Lf%?f>oR0a5;&n_I`PO zj8>23uLe^NV?JBHb_7M4-$)|Sd@-c=I4bclhdQmGK@IM}U#&FzIv(W(z<>9OdWN9T z9-IDB*tu&xyykNZv~rBerS&1Uqb~^QDuofr914%KCS7P~G+zjdCl#Jb)SsC*PBBTu zijgu;W#C0LaPd{MtY$BkMQVq5zG+(=PQ_qWszujsRKcb6aY=aH(URv?N0&Ov2~w8y zL|&yEhh)o3WaJ^+b|qI{JDwlIcjhFpr|-(5z}d4^C42YmYvuuQ--Uz;u#|tkt+=m8 zkM^v4u8B{AmI93__)7iFw=$YBuwI8R$R$mm4Tr;mVLp0%5!k?cVY=asfp)-*N?Clh z$Mk@Z#)5tX+?ZtQi`s8_;u*<G!xK&K((;gA@atAyC3F|f!%H6yvQjO`D82D)!+dPJ z=T<di-kj9gG^=VW*R-~<C2qe*Z({s1VFm{dP8c$wR?dW|`x=`7atgJFyW^*SpgCn= zTFY@_V6SBbySOxTI2FF#zSX@w!+GU5ymk=>CNtdQMG)~QZ9QHee`25;{lMj4CFt{J zqLqROq6$gOuLp0G2<N7vC2uwo9b9$~IK#8WI>+<o94|aN3p%Pa_rAq*PVfzvqQ}z^ z=cFQ(nXmPBlmuho`FOevQeFLgs~ig4Kk(g^Glr<x7{CH~V5=)!$LB%jFvk0A0#77$ zBt#^dtS&aHwdD~sy~Q#@VC!$n9#<o~oz|F3X{tNT%(XO|u<l#dZ$U@$`4*qx!YNz& zns<l1e)AD({iGjFzb`$x8i#B7q4@rR6~;%Wf)}@>sb*+xrEoLZuc+gP|KA3W@#pJ_ z*l}P{#@wG3h%rq>qGvZ5R<_vNO_OdqS|Kxg>k6vato4dD?wCHIu;8(RG&XdVpYO~S zCSSOmVOlwOfj2`M?NctL3GBSj=svE?UpKq9Zq)D}nbdHeBrNoZZOu5?89vG;Pn8>p zMbCRZruC(|<nQ_nrYQD!#=A|E0}d1tk-yht1ABb8=9787W#v&gJ52-|AK@AkB#Cjv z!!gA;`)jj>L>VV?iaiDMdjx7XU51~G7?aSxlGzBRa&a|5XFR=x;U#er$HbS_^OBHk zJ^Af)1+Ol3as)GR+2}?7%XH)GaLzn=k&k1*TDwluadthTpd$1q-B*dYs2$UxfHQ9* zcMqj5x0+l_wBQh}w2U8ART94h<mJd1*j&<TMoG3ekB<!&)?L1@?)|L1GB>9v6Q!`T zNFQc;=-v}mJ4=`wCp%bTeLJacm%;nqIlW@o-sIp0XtxNt%RUC`KUI>@y<#7ON|1xR z;P0uv2hBUJW79h*6`Bx1gjBrZOESmnGWr!~<nck!LOj+C`GZ@YnXFBP_{ZY@>cU-g zC&?}AJ#&>MHt0ymWN<7b@*4J^f`L`@0?9$o{ETIHvy?UWcU~<YoHS$g?VmU3aZQo& zSi?{1FL~hzcV#|F;V~>PK!KPGKP(O3ZhVwb-@mbuFcG0&o8ew-9nRfqNTTDqzgf;p zU1$!u#dnu8)Hg|wLk(*EQd4mf_`0)>>gedO@rjBg+$!-jG;S;F=-})+1#0@#UpFui zA||fD{5tab%zGfMtiNAVn!NmfCusqCL|e&C_!d6<G~^Ge2tC#5Zzd5MM)RGd1`Tft z^lqzDia6)nd^dUi^(tHaXh>lp#joY7C{d>3Ha6UrR(Ui>`pokaeSK&;{cAs%*<6g_ z2UkXQ@U{;F<oR9ZtfW^@=-LRe7K{&vRq)#88M_UYwyo68LUV+)>^Iv3!-dXIp4uG; zGzRIB9JFmXC2Z72_8P$;D!%?HK5?e_*HFAu8*wGLK0d%!lrx~yG2a}@T=_{uZ6CZY zKzOp-9Cn*T*<y2sbNoA6T89jOs#xxe#IBTeWwoDODiF7pyhM!myN>UAiZ7fFXPJ;D zYr~c_b5gqML%HtT-gim{r?!;FmtVzKV4qIryImS8e-$XKxm>ezYpo2~vsvq|pF3D| z+Z8sOn~y4-8(T|muC9(fvt8G$HKM?#v(CxS7qzi*8l)t8F6uNXO24<hevPE{+0d6P zY!;SklPamHUd9gLm5GU$XjcVjguP+ahKJ+DypzVB-y|i~<wjFvfgM{~#=S^-`Pabs zI60OFwT9~SwJR3I-ifylmu2&KgtF1AwiU+PzvUR+R6KaxnAgbGQb0(35we0$8Gi6| zXTC)ZohH*CY$D22ZLrUvq-&o!?0RCe#|W?=99*IVpZ?2bY3PPjB2-rlH(d9_uNqfT z-5gyz80y^_3w#}<4yVlP0aA)2u4Xn}Sd7m(i`6L8M9OYQ;pxb78eaXjnqt`)UBHlY zrankX!<j<rnD`J<H|gFfLTuTR)Pe%Wv`Kn>WObek<M)NRvy_$fEv$?Z^&hhmGQhh1 z`W5gSZct4DZkSB4pU?>fS20oVE05pG`{2xG*jV@Pmr9+wMbX|4C%5_|lpz3n5`M;5 zz*bT=2yNozZ#0M3#gaIRa!-uVoWF^#qp0CI!Ib(WJ)?OWM<q>m5KC~0L_M=uC85#H zdY(c|j)997Kb?PNY)qn<iQTO@Z<6`5>4rIs3aL3n1quo}Ni5_k@-jM)9q%2a8j?&A zUN`@Rmp#5u<FB^<hb!UIa~JMJ%TqXcR|R|hU~&5C;A=h#yDO)qtOjmDP^b0?!B-~K zi}FT7{QdhY$ke**Fj4&dr5y9@m;3$SH(s9HTM#SQv~}+zv6A^Sv95Yb_Vuevdf{{1 zN6GY=&Cdj9d++m7_RQ4~zzgQ&<k3CqDf5-IukdAeeG=~6_Y=VljTUpe>2b<w!Mu^p z>JH%$&u9%t9SI4JXnS1Nl?J_v+eF=g56K7&aOrMAmiPT4%WGtmLy{nGfwMrQt$>2^ zv>Tl`l8D@TK7xyc-kwlz^2hbhY4<*DzCb~qvt9oKs-se@#`((9XMC|X%%Tv4CbI`G zeKffNLE3ixfkWc=zCSImtCOF;a1yyH-9%_$mAG+ZN_{zQa?Oo{bzmA&_V*h%(5vfv zG(4c<ZX?{T5U9Nr>w3NKL;4Db>a*4D4+ZrTZ{Qs$Hdjh4bn;$%VW{V*6=z(G;|g(y zf%P%T37OR!&ETQxyrW|SD)D<ddsDY34ipE+Y*NGj{Qh0FF#hQoIp1##oxRiog^4Eu zI(11BuI%U758j`Xc=m0QBy8T8-WjZ)ESsu-ZQjFNb)Pyd8~sjW2sUI<T(mN-*Km2# zZ;ezC-IWCJ4kyMgSa3teZ@jq61YQ&T_XjToaR93D*}i;dhFpE)>YvL@Qe0;?>p9tg z+v%b5aC`BlaXep~Eb|ZG7O#h|oavqZdGY_)dh4*Nvi5%%R8&HcZWs`xQ;-HFq@)`~ zq@+|px>34CL6qhI(hbrrB_h&Dhtl26@7~Tl-}j&QTr-z2GMuy5Uh9re+}laPQfT-H z$7^WodqN7^n05-ehs>Q>F3tRJJ3`h;NU_c>r@@@)>|1ch)=`3#_igCyudA?=AVjgd z)aI>QYOW3y-oiu^x81VY3hz0aeACXx#-{pY9SP$Y7)SP!7}HJ*9gU4zyZcFPU0es8 zZYHNA#a}Smuj^FKXu=Q0#1LoYjQY&Z#xS$kU6~r1+ITazcHg^!P4{5+X?jV?rS^z& zf33)&ky0`DWs=ob>Q2OB`?`Y(ZqE$c;burVb;!NDadBK|fFF4rnyzeyr}N@P`SMO# zh4WnF>mP5E7j_m5CGX!Czx!gec={~bQ^{)XSUF*_<@}7A&bLUn-V5z1Z1cD6u?&xj z>faHxCkV$B#zV#)9jlSLYW3oU(nwY5ZPe(yKP#A()E~3g*!oS(<DPJy1a9S=s^H`X zG5^t3Bf-ga(GcRt`3n*ppfRUHVT=#uPOEwBs||8|MiOUL|C<Ql5}}qrXrQ3~X}^0q z7O#PHtNj<1wQAjlto<cyEU^%-F>Rm7iaPvW{!mlRr|IZ1+Gyzm6ffUi9bf-?tk-^r zE>Z_<{v%Y@#sw-pK31+nSL!Q|r)G{jJEunq6Gg1w+?Pow!6sKwpc3>x&&aaM&mE&I z*~x%43=iMK#~>?NmD16{gA41O+UR3Ui7U)7a~?@#Jv-wZ7+f2~@!7=@e->)0Gh$rx z)@eQOHN&s@D`fwMcK>qOoYYkQ-^FQb%6(W`(K|NJ^YBh~82;u3{B4&^Woqpkk!1{B z!x~xEmgzoLU)Tsu4r@~94r6->E4jVY9E7B$t3OQ`FdE%q*X5{Y2zg6NT^aNM@a#Av zL74~YF$ZEE3<t<jXAZZ$7IQT~WA@PPHvRcW$pyCoDzCtq0a3zwy6!~9UO$b-HS04d zBpjyJ{w#?Ukl$uWp0aIW`E$zZRDqh`6v-)9J`CVXR*800v`JZ7Pi}fyg(+WR)RQFa zB5LDDt(m2Ei6%dO;AI6<j+ih~F|=gE&O$90s0lw)P81F^X&-IIQl%H#&(;XMMUkfc zWF3e6`C_rJT>cN_ug(+Lj6MvNYggwzOV(f*zB@2HWt^y}4_m4q=Y6y_P3M9<xsL1d zfYBf>gWkTSxM3M=oz5U_vxS+1waD3%jHxyWVZ&yfRTZNb%Grx0K|#hOK2)pquGjFU zsYQLz%bwnp{T2TH3Tz?fjFBGO5S+R0_(&6rQKYK?h$U-t#kC(N^DCLBJum9Oc}NsL zwvmCj(*4Q6s>3KG!mP`6ux6(f$D1uETMI{5me;xriOM??_0V>yd&cLURAIQ6OLy>N zZ2r<}XuddmZAfq3$zeLZAHMqG!-QJ+iFzr-xB2j0IhznRci%E3vG<j$>FK3fAIMfx zOYN{2rBawlrzW9p%u`U38m6<$-*s?W4?SF2j-T>S-+572mwBr|Yh^_ivxk1kA?{*p z>f*dYb82XEGJj=(6@p&aOV?+2#dUVa4!xEtdP~1x8x~9Wb0`V~bA|@Vk$OFDBc}4h zuGu76Z_|5@c~#q#9kADEEf*~Rk=xZcsDCcPhzlbqY_KllXGE6aWfe^S)57xlv*#VM zGrL1{Exn2Uk%3*{izyyY^kj>#XN{CBCUKgP@5=Daihh|B{nFxZu!*{i-oXr5!17PI zeC6^KW;l0HW`!K>tYnR#s%#V-NC%OQy2+rSG2l&8rG$=&Nu3op{*uzx*@*~W&9msl z2M=JC3<eA=zPVcZ3#U3U%V?OF8JIvY3%#lWr%laYV&_1j`^yM!$x+!Glts&(@|Bc5 z{wy6*tr8D0M#|0v{~qGAyGcj)2+#l2ryUZu)0%YkDRl_wAyd-QL)8+nuWDzi`a#G* zFS`e}?Tie5z#l@0&6op<_s>iZ1Kv*T(C6hFHunVtE}WXbI3r-6=xH+bA$3*vsA3wP z>5d;mAUI3b7cl*e$+ysA?hwQ7WfHDL0&Eh4iT(3*6yST%%w*MbXdb+$jpgwnsrAJI zWTJM_C+z)OJ6^$(-|S!Dt-F6Rsq5d5188GHk~@FPXFZA3QOJugI?Bu0G?MA}5ku!^ zR}Hau@w58WI^RC>-@?kQvEYFUUXwPGFD2MKQJ?=(s)%!QD!(LmoR32Hk3@boXXWlp z$E4IY^#}B@AKra3>m=}arH6s6hVuA{R9U_kNqHB|>sz674}zE-I|Ru+UjJqxYVtRz zeB<j;Y<lTNia$WHCh%<I7J)0)E3rj+`<x^DUKAhJ7vBDI_W0oqUp$2+!J=uv9vb3m z%Cl>Dt$tbd3_pt5l2rA`PH2R>+538sz>q-s;>pM7<Ri9+7xyi@Gi73}Et2Zzaw5m5 ztf6`+nchM(#Yw?1F9sNj+f+68w5nL^lSzRFn;hU6i^30n&g-TL_t`cJFfgPar=Lv- z-8v(X$;G}sj+;|Zko0y!!!4X)Km+m-rz0_Gp{D2K!l>tNk0tUcV&>W<*;L8NDk=7P zpjgO34`cY{fayu3Pi<JT8Y+~o@S!kMb0_N5c-7H^Tz12i#=!XkO(b-gOdDVA8~NAX z>7F^8nf2+=*3(M%>au7D{BT$qWU9KEtQf;{K&#LiSA~7e%AK3~&Zv0#w6A<OU-H6L zq@)RunQQ$VeR_IF+aY|hX7qIsGnFMFvLcnWA8rwcwG7|E-(DlhBzOM8(HgXKeeym= z?cz;?5+eh#d>Ykke+^$j3T^K4X(6io4o9L^%}i~<vR5r66S4w1i6Us-%B3y{tMa+V zJAy-IW@=zqBhO@1(ouhjoSR`bVNY0@0bPmN%>mC}cv!d4SDTqoJ_SXLtEKhgr`Y&F z?woZ!G`tFCxg3hcW9K!3Zaq7PvI~k9W!}Wr_6jnwGJqHTn)@=<ba~t`;|}BLEdn#* zB$!0xGd42-r=SJ*^D~X=0y6cC0_)f6@I*M2pW=~^l@oU>tz3BP@SWF|Q(^OCr6Ed{ zr7u|6e~cN3pm#K#$>ETbQdH%Lle#&Ps-f{d9>E}Wk~#bKJrB!JlQ#1wR^UK&qH*~v z-w_`L@+I?%@rNBd*}c^)1%t%=$wS?qb=3+4u0Nt!nLBjg?naP`Ef3__6<09ki02p5 z)``oOwp#l=ffJt*`sdTH!#Y&p=2@T3oZ-4i2uZtPiqo%K<Bw#dS<Ls(b1H0|Z3WnC za_K=51GEp#U(gY)@ykKKn!iTrA8M=FCpknzBKxkDOvAvV2KC9U?o{J^i|m3se|mqQ zQ4&0FR_sLr*;CKe_isUyq~-FBTVgSIzW)$i?blNJ>iZDKg}6?VF(2W4HNUOvS=%}} z8>MkUTi3R2J^IcIUK(h8`^fjV$tE@ZMY^MOU@P%t<xDdC1EEskXqoV<FirC;ldm=B zkW{8yZ>98AlgtDZN6`qVKREPAr|5dec=)xX{P4<<ap7FoVQcsO1gaxaXl|T0AG*oJ z%1Wol!&#cOD2o3U!b@aK$?!aY*bLQmhc7_G^vZ*!q!I^-OvR#Tpv{yQ?vT9zXi5Vm z=<4Vo;6&_!@h@eeMj=<_6Vjx){gYxtr%VK|YvmQmnG2UNcTn2KHLV-mQUsm~&3?<* zzZq6t1+ehNq}zG`d+o3g&0zbn<SF;Ka~7sVzw6iJ4=zrs96fQ3q&gQO+FwWb|2Vlr zR~H^@xK2D|gwOi5Z&{n?lGuX<M#aPj;=`(j70|*F4810`{%HN%`l0<q{G%Xud)n5G zG1}JfZ28l)@yPQnLP2p41qVwgawuA>4h~o<8s7{ue@%ndHb83!z`0xSRZDHwU5&X` zRBy++YZST`7G>O*xed>nEtm5<2+GCxmKR+Mjkh2rTv6rySKX<BH(Oq}A6*S`TDYH6 z?B|&<mV7Yw`Zp^d*?f$AFiFm>MV$zy$%|`wF8U_dUw>Wq4~d0>XSy`k%O8*@lz70{ zTGQ*xiO}bhcnb44C#kw&mp@_|`Wa-w)5Tl5ITcFt)w|vIV<o?DY1*(|->|Pnn%HUq zJt`Vidv6B|_i794t#Cp@IyCaj7EqxDJPowlN2VS4Mmz|xxqiEc@uA4jS1)efbZo-- z&G~M_nOjw|$U_WSI2kXo!aec%@KH8aZFXE#OlaZY_M^50PmQR!v&gr`9+x4H9~0e> z+OTCE?NMXxf=Xm0q-#W#o2=gssZGZ{m|5P?MX=pMnMTzyT*jN9dVOt2!nbhtP9-l- zgn;b%4fFO3@(b=$JXF^$`o8YfA_e%2vYz@%ao6v)xjq;8j=jrVr&mNla2KXNzWngm z>|V^WTf2B9@q8$Ar!ZSJ5xs(uyl18m8aby2I)YRC)ARM6toVGJ<!dSK33wRDGCy~0 zN6xwW#;;q~KOp+tNHtp5Sv4b0#J+8_b?_o0<I{T{>dd-2${RQG@jV~9R^7?tvDA0> z0li0W&MK8hwFR|!xZ@!S#pZs8_l&uKfuPW+KlU8y-(!GnhBJ+(|5Vn~)?AAf$fgGx zL9#NjH+Ak{QuL}A*YR!h)z_Yej?2nO+r2MCAN<Rw9<`VgY}Z`+xc%@l+VjC*MFM(` zcw(jreqrx%a+nJczVcB>L7N8^oZk6)DY_|hfUu%tMby-1gDTxwxNOpXuE2;<(~6qh z^+wXIo4*@zCTX^&7v?smHv+wbqAbs)5`x|(lTt%rq#fN9;U*PM)sGEq5q;X39=70c zOWvHtnU8%P9LX!2J-S<$t1xP?>gkb%RFfxHWs&fBm2UWId+#9{S~>;xs?t!Ucr1bD z-w?!VW?pRGz7(VQ=)=qA(FFD1@h`oTqA49~wl0>>9~-(@-`@9S=qQ0=E4Y*vgU3mU z1(#}ZfNG_}T!or~a;0TCnqGm##KZ;$3(Lir{%CCfkl);1gyp@M)ifB4=Eb|s>2>#< z#7p!T>oOa?g4MTB(ZcC}v}agaCPX7ikSk#OhU0u;ggVx!#?T}jOeXLYj=l$Ep37hb zWpWX9$k|hA=^X~Mdw-fq$&?w3qbB7?;`82Gv17U`|IzZzCey_DN6P6ue17b#;NDmF zG@7!4mgKx+to4q^_0um>+gd&Q&N(OJzqbKl<>D-=vYQbczn!tMM50_ZK?5ylZhd}! zKBkEC&{v03m$g#BgCgBQoAD?A``x)M6oF_20a|iX!&E|ZPkX_%;RBWF-xjfp+d)C7 z+4eutm^sh`sFB-oeQB7-{Ou&_i!=3>vt8jfdIzvDn{&KynR${@`fCgQEh=Y`jY&sr z9wXb;K&CObG8o+B53wH?iunqKaphd+<B^<Fe^GCE?#E16b;7>P(5Kx%wxmXLth5s& zxAV%HE`j{RKf2<`l>pKH@jA~X1mpI%6r`X26YH);TbP#@B$RN;=iEzYfR>Wghk}A4 z_@q4bH#A2B9*>|||2-BQw(MK=>G0`GOd2j$^rAatx^?`cfs?(sy?^lWWlWt^wZd%3 zwgcRl(*&=PIyFUhLCn){3_8ht_8fz3Yyu0)IAh@mxYCDO&+$El@vDN`rl*K?Y;XFy zU?|t3v3-+{{h;||Z|y-70hdAvSe*QW)H?tGleW4E=jR>|_b*;QNR&W%I&U^6(5k=d zM$@+?dGuyR^NGyo<&z0f>L-~h^_?NNXisxxTCyi6`;CSxg`J7u<jgu#zZBJ*ZN50~ zXt1u|NQo#d+A9JfMMOfpoi|NBntY@!R^>!$Oh<Jv5frW4D}m~**X-|Xxu{{Dqki`b z?xdO=&KSsU@w-#z<n4KAapE)Hkl=(yLojkpe#a(FEkQBIjirvvt~R;ZaOcW{_<FY0 zIsb$^oLrT$i|uAW`MNZblF2M*L}l7>sInq`9-aIzXy!@(O>WMbjIyB>+jt#E-Xy%# zw^MAanod-n)DaKajfFG>zgra{^=x?kI@gFw>5-Y4|MJI1yz^n}Lql5DmY6Nkhd<bx z2J#uP+pe6SSe&EUX%ot(>*UvNIskltReFk@Jmpq%D~r1;lHXPQcYNm0=P_GW56x=? z^C|b-9Am#yT(R)1C*xKXJlvC7nqMDhtP~kB+OvFITXjW(w&v3Cp;-deTJzo#HcF9! zzK>y!0bp!h|4d+_djD9cH?u^XF{QmL(sRJ1JF-q{EHk+QJ<FR;dzQS&PsPO3&(8Yc zX>9rqNBERq*>WPU{WC{Tf&NdnY~t-W@3s)y4vxd^ZLa2bO=o%1L^bKySwXubKEQhk zTJI*?`Q`v5%x0l+*8XuQDce>!tKM-z$Ig5GT1!r9ZZ6YjdmvYGCX3dWm+vcfz07;( zbv7b4G$XWe$J_5I>(6CdRu;R(SEnwX_0YQej;;0PD=R34p1I-;n#n|CDcIYj@;Nj5 z#2h9cD!DL~{1o8zb7tb2>+bb#^6%6!_QIv7uVa}jR4AUZ6&NK~R^ycmu=}Jz{D^zE zukb0<+Rui`P4}q{Z)$gsV8O5g?9Z%Uo<bD*SPWCmMOZ`YekRgs{f>UST&jKt#@UDH z^@Sha3L$08a=S)Mb}uyby!X}|!w+M{j_R@pr%ET!{&7Cxk37rFt$!0KkLRx?>+bIS zeE~H{{uhDi*>@8wuW*+7;K@UsmSZK=F-Pd%EU_VN|ErW~s}m(Ex>QLz)vypMSiDbL zG_{3QufD5u*qx9V;Q1N{KZDlnbP!EnI+lPhC=DmGWApplcUFZ_yd^e^8HPri`JaR? z>JHj&9PXc8KaXR2cQ@e@FltYBJwXmLcTVrXp^Drl$O<x${N;fV?-kwgWsS1$j%jUO zDE92tIWrZ07-yiVkFK>=B3o3RBE0Ihdz}Gz7yg=;knZQc++q2(Xh*$!=%J;p?RV<Y zO5vksHJ9v+`nlb$ahPv*+vA59QxZph>lp2^xR=AQ#4P1L?rFrHN^x_UnnSR3^nAhe zbV6MP3Q$r~CqPD96a&_?9e6|RjV|h%-m<>J$%gS|@}#Pa{cLK?RcFFkZfK;vAAhDO zV19<Ziht(AFsM5axqvlY_hU;a@=tu;;n~#T<B@i8+Z2t8I-W=|?Tq6}_7hc|3Z2-6 zpT0xkd%6d<-Jb`IP<Kf<2!fA2`1#6~oj92J8M~4XOy31H#LFerykgq2=;ie&H5H4P zIB~4qZ}R@?)y_6jzS>hvx6luT3yLp2Y>?1#ZYVTj`Z_0l+MF1hN${>Xu2fD3PdYtH zm(k#!48t2zYL{zxjs6B?UwbRXBE#ORVQ64ww_SSAA+`5HK=`Hcr~u*V8KLtj&4*7J zMG<2F>p4;(V8#56Aqdsul6ZRiGDM>mgCk?^`V~Lu@)v^4oHgks3<356iX(l@UTs<a zgTzKB1HQLFl-+ogSn!nov*z~^?prz;dxxE#g|ipqd#v>@y>am#dDF^#hB4s`C_aEP zLoL3_@ZBy8UBbfUO+ckL<Fc9re?Hlvr=SDPOy7GfWKYZVVQ3OGkHtt4;rR+;kvh%% zg}1(ng4clDS1<&<4Dha$E;hp0!G#=g@wND-nj0-2_q!XT%-YSdT27j(0B#5R&Y^CJ zMgA_pP?q&|P;&vp;OMRl7<$#w&GnkXyQt~Rk`l=s7dMQ1slr*PDm&W3o?(H8qxAVP zJSZg?5fUcSNC!*d|GQ2zjw=7Y@kcIs7L59eUe^kzPDowWd<*BesJM)WOC;Kl6I6mY zqk_~wl2RLm(+;=D@KIP@Bk48HW1bV2_uVr2CnwT=2D@1{{x)TRrZf?U{c4~bJ7zp& zp(_%cb6B{uP(H_|{CN4N;mmibZ+gR=>krPo0NPl5AF5bdmk+~#8i((oH?S2Iz0^V5 zxQjE_bzyz&+4`sZS9v9ARvKR`1J}m0&{hnPKvmRZJ-ycePufo3%Um9-sdoE0wb7g; z=7@mOISY%+%T2+Ap72L-_5A3l)nNSiHCzYD51vibO8WQvjRD2&#W9PfR!@Do&K6DC zzf+j`B)JfN5FuQvh84(JMn-fCU3VTULOj{DCthk-e<k;KohH2n7)$3`GHs1c>8bRb z1WQ)Ye6&iv5<}KIa8p=Cu4z@0HrAmfedV&5Z0>2}oHK0qj-ZV^7Yq1YwG$q+n;Le? z)_Pv)5PIbw6EqI0QW^QcgWNEtQLP(LyhN^nG^6Ng`C`8ug@W9kUN$+>-~G9%_O1i% zX2OwUyC-GwntyUofu-65-980VQ;j4`oYl7rVY~5#U%m*tT-LzEh>p?)oN;TrtIoED zbn^T1>Ud_Az%vk5buUnUqLCR6AGUMbWuK%Gqx2Xb6UM3<quusk=nTloxdB8?F#Lh` zALEeHFhyKTo*!1Ryy0vau|N7R>)BHOfk}DS2;sjZm{JRr?04w8DGwUg?4Cd^mr^?( zy#0!aq4O$Q)6OdVZ<EnLFe{awtMXg^Dzj`yne>0_O3VUU^<NI;EdwQd-_#Q`w)Xlj zwPD><kpJx)7Q!HEbGW)vI*Js!h|AWlge`3Ci91P2<v#1kzPYy`2G|%;@L>%Lx#NTj z^@(UtfJbt<PzGRxz71D>ZVWlH&>G*k#%t^LTVgA8%ey7JcdnAp^?`%Dbo3>t4T;k9 zD&|-O{Es#~6&@(pHsX6<wa1d-@vJ2_tE813Atz0Rh6o9c8e0bKZyF{m?Mz->)x2!c zL`(%L#HiFG19Vt*N3qYZN(K7j^V$PdjFK1h!XD;c*uFaZNjAAcrPART%$IV>2M#I8 z6_zM0M?&2Xo+H)e_YXXU{v}Qx49Cv`>mVg%J^mn*Cxt-6gg&xP_n+KMP24P>!;6XN z=gpXz&08ss)I;;p&2aEX6Z)P8#aP{bX*O-1CjPk6^+x7{sm4!RU^|wUmIvrSa7*&L z!PUPtq|C(DJ%-WSk4X(Kbrbl60f6$oy%>eFV*7Y^i6QaQd(v{Cko}KPP!V@Loxi3j zU*U_@n4o4Qo&IB%FYU1C%6pDm`@S>#%++$fiBU^xt2?5hnHOnVz?%A?CR}Y-OP92B zC+jcHY+4;3eke(kT?*^-B~Wfn8~X9XbEGtr^X0Iw`Xi_<0RHaZTM;v8J=yqdiqe4r zqc)LAturgKMLj$0;?7%mMdu5Tw$e{lEOuy;`q2|sOJcvL&`*W9olLkC?8+w`{p2}a zEQtNDengT31Een~@_Fil9B#_m(TqWX(KqWNG1r?*X#ZD%gi>Kz!ciJSTCw3v*+<4) z^nEJoS2YP}01s1BFB0tj7vvfl>R$V$K{`ak(Au%fJX#yLwb<Z^ZXoakZ^Z-}NoH|& zz!tu)xeW|yr@_&hjeO5QiEtngab}$~>R_X5Wa74al<HyD%;GC|5A~H$0v(r{{xx;Q zZcm(s9I#D(_<5?~!hVa3TBi5XrxVdQ(VP=5>XNxk6Na*XxXwkA&Lg!QU;`(~7cTY> z4;oZ`a;eR_;;puA`S-%lu3g|7mR6)XEzzbler-q&mWwYDVC{P=e<VoiM2DugYk5;9 zoGbk<jo4)yE@8n=7OZn}Hb^h}n(7gUm(fU_jF9^Oel#C!$oB73pLh;wTa3IPnweqf z>pO8>S1N1MJUdYpsD4=+Q9xN3xcX85d$c*lhGPVRb-s!mGLAO5i*S(n`9o`0U+U<n z*lvWETsG&43hNcNO(8rvaL!tf#*$fj74Mz2MPmRoM)>~zdX_BFhiJjg5fiPy^q>!` z-h&dmuZ9*tfkOngT35r?$@89k|7V3I+T~)xRGPGnYgYbX*yK2gFc;47NQna>&68@D z3};>RaT6Ko836opH#Iwoy}#WsbW&1dMNX)U8TXbho_fexk#FLBREcTWEEJ3FXZZL& zM8EE1jMJb`H*<nKf-z>l=A5d*?M#33>gQL48qoFMv)fWY`u|6dsGS5<AQ*1#FX~az zif6cYn|Nwey1Eg(*Rh!yg7Vq`eemZu(=MM@%Yd{)+~*hFkuwKgC(iHcDb4r0=Z})v zrk#9rLCoP*FYT;aIYCo<`ig7(CEobUNUQFh6>Tr2D`*fXQ!5Vmu3jxLwy==iv6g%H z94hba73OYox`a3t%v`Hju{Q|iFJzawS}g3nLvZf8%b!4bVGd86iE7eSyNVfa1Ufsl ztK<?_(QsyouWCfAS9*VQnZ;NAL<f>?qxQ!{?Br>O)MIpc-9s1k;9880#>_&S<{0nh zL6bK6CZJ~r@`7cjT1Z%LQlq0@;<7psy^!_w3`C>@%(!7>z&Bjc!qW%flri=EY@WzV z+zI1?*X<IMY|Y;%PZK#4+@15H0!e?jJ<S-@FzfC7Qq7kaeL+pG@lXMfg62Sunfy2Z zpa%FPQbJzvgg^Bkx%yZA7fp2ctBdb*Q#U>`g+v-L>&5stXtsyP_>ajNf`;(;GFo#- zf`j^GcoE)`^cCC$4A~FVA|YSW0Q^NMDg@!pKb!TfVnohFBMhXFmX6*YQ8IbB<#ylw zuT*VlrV{xGg~v{p(O}zS>C;#H=-RHcsU3=Qo@qa%opPLWgvez*62Za`VMnIlyX@~1 zavgYi#X>xj%-_$S+(dJ^T{p7eN-}o7hHXdgZ|y+)z5DB&45OfG386&QhE}cWDZ#mH zuc5K$4<>2gpQO{VG4TL$(F~h?{5aARKOCjPV_CNh4?4Gb31&ika%uHznjnyTT&*Bo zAyl$@n1341Lw!r{!1AlL014cm$@lApbImTVICb_Px^3-xm)({*(5W?ry36s)^MSFA zHv0^ftCw>Py3VO+zvmDc(13AF6Co}xVNT0j%M@-+abDeNddW(!U;|bu^i>o+Rv?Xu z|F+Ul`oz*MY-VKkidxvdYm(Bat<{$b*`C>6zO~P=+wzhe#zPzGGVz&)>jTU;M4KB! zf<Q(O1{4iZCzWhK6)K&qGOCl0X`6EECpLQ+rb1JL<s?8U+1Ch$GJ^<>n$@WE@zf?z z-!oTH*Lz(t5KuQ)K7;Uy1hO($yim?o)x3Gj)6b@#2zAe@=44LS`#hO>^NEqG=)JU> zgxVRQsqoZUn$A3z-Mn1oPX`Z?Qatwgh7$~5T?ZgcGS&6d%l5IALte;wA>#Q#aC;Cx z9E#b1tl?wH{U4Az`rLj`8N=IXa&<N7NT>!3Z=7MDwulwZK=<?9usYVHJ~*i3=E!}s zhhP^OvB&slPP9^mg#@52Na=mLeb+S6RD)i?Z{^LKVjH;VX?IpQXJ3+Jby9=dlMLBT zbm_c$k#}}^t+!OZ?h#uQR_SM?WjXD^JH37WM=Ef0)}U~9Wq)C_Xzu_KC5wXORqAhk z$(Az(Z(y2WAlMZ=N9EV_Q;2%%4~8pA<O<xCpihs!p2hHdK9@OIQ`EvBuw>lbQQ~EN zXPg6FOk|-l6TN~klro=XoO}JZp!`4;-98|pVbc#DdN<XCw0NVTk+a@JXN*G&9+C*4 z9(@(cZfpkTj!@jkP4|1v82EtzmU#Qf*2wrhf_1%Cr%$<585$zjT_EB`dgo(sSMiRL zw&>35+rQ)ArD4Pifba2L7p$nQ$6@p$FTsN)lDUK2#h70oQYO6wlGr>6Y$gv_ar2HT zS9SN9#tmhprR|!|G}-_^lT30(<9G{?+FoKp-jpj`6b`_v=k#jT$m5()aPy2kCj;NU z4yzOkyww%45q+xH=cfrDnM(Bi6OWB!eE76fQmkjDTvh(v7)KViqCUuNtaTaAJyhs5 zG<q?VhElvmk0NT47f)~V=emyFp)S8Mvapq7Q-LTU(A96J@JboW$?$dQXs?DmIv98k zMA#NENKAv3;B)2u;yc-5$up{QLn`M`_q{uIa_Lm?#?+3?Y5(Z(&k_`2r0zvf+9wEs zR;wwzoDx_4#GKK1IZ^oN9VjlTzLV?={95ka*v+0znO^B^cC$;YJ_ef7A=mO(W+%n? z<NM@W-@@TB-rHaN1^(mAXAt9F?AruCy`usE1ICC>33=xF3FYZvVxbYzHevNY09yk* z>#pc2zepC&_sA~EWbc2g6)q`-N)qN)Y$@+xYxGGQdIc>OVpTo0Hl3oI=!bnar%#%b z?@XDR$-(0DD7N={S#gFLeiiR21wo|iC&iaWzI@?K)CaR8b%yP|HHPgvA?H|s;|2vj zJ~`QjSg$eYU+H3$13s@Ez8-%AhZ`S+#;x}iF#dN62&{lzXYQ)g>9A*`8~l(FFKu`g zHnb#?m*E7!Gw;G6c?d3ZHBo&)6E|-l^mbRdrCcw8wQ01n5emYDAe?{+jW$N;ZVBGh zE;b@H@&g3~49~F<0910mLjpzg{uO!*_1@|I*L~UmG)m|n`E61loVHc$Rt$%<G|?vq z+O^Dp*NK8d2eRm2KAhruy_(9ksM)bmt=YwUYcs2a4^s%+aapm3(e$TfAbF{`0kAuL z?G?7{Iey05XzVPsl$((-g+wl>hxCOkM3F^aG&FZ=!?q{wu`;pvzdK4`c1%zZNz=<z z!!7~6;xr2pNQ59RNAJ*og-si^U3_r)(O)Uv(d>mUQ)qotG8d2*Z^;P|Q^i%wn|0m_ z0Go1$*u%n;Lo7j76Pqw$QYsotoi|0_|0={?#>a4R7xky_QC%OAB!;LsZfq%-Ox}YX zDZb8At8{e!>**9-HBq1H%dQsAldDv93$9dWPf1%?=}~<2Gw@s))$0#%vM#-a%Jzod zqmpe{#=egJMd)$hLK&-~ak9R@eJWcAXMkXNM`p}O?;S^V7zUiT*%<evcHbdK$(5UD zr_$18l{YL;oy+@p9Cwoziifw%0;uJ`MkNyC<UXlCk##|3y-tQF!xBBaU%W`bj0svg ze}n7yNDLGdTzBT3kgad4QUGQWd>NL@jbYpIBI{#8FSt&n9h9m8UjM7d{YN3l<2`Yq zP=k2~h?-i4Bd6VmBcH-SNbRY)n@Kdqb@pYkpNSsDja0ZVCR;Esp3uF4SO8~e6S|r& z?0<sZY1+351SLfYY>sZSS#Iq;l#b?HZ;vV)xep-*`&>hA1c&Y0n+tMF(o@&xfnl($ zKTT!G*W2+w(m}cM2V_y#bGGYY{0F_h^#65g%U3mhwi;OQm&{~)_tVKQ^FgxTFpziy zB`(wNXG(B~>LR#y+Gz3B2*^Ltv~JC406~cb^#QR#1Sc#c{gi1d(ra<Ia>nm&MQl(^ zlDXcHed!PkuzHYj87BC*Zt8#(2dzH%KGlsAlfPVpFP&tpX(g$J3^`Ji@T&J=?Z|jE zJ6&h{KK??{RMV1JwNo&7XWH0O!Bfoo;_5pgLkDtvwU^@cVs0eRJ}$XEhtdZkSTU>| z9@oTIN+0OypmHKYPT}sN-s4ZZ%>pZ}H{jd0vsPS%taP*UvFAIJ$+w<aehGe5VQYNI zu6%f|c9851G3}h;dE1#FeRWtR`918~#ULx3M2uXukhA8RuF2*Jd7cM75pL1O4e&X& z!9}$hH9l}wsu2CXj}<yr=S>)SsIHJ}uz!7DxSqW_>?4Z+xr*$j!VwhbMW6EQy^?Ka zUp)lVKW_o~cv7jjmo?1&IAA@utGq_qcEoB(k1{R7Qb{H2Ms)>YgJNKSKO=(-*uqS| z#C8@UO!sv;p7fAH=s}Z<Xe8x_^uU<X%MRL;|2eYM#!p*Daf#w$5h@>EsNef|vo@0_ zbkL`80<lJqMW=P3V$gISCq<@WF2BW2SM9^*4q2;ELhA=V2^)4Y_13A;RSl#j*5$1v zjPAG&4X&azDUprS0HyI&PBqa1PIo_W{UGs}t(fR9DIa_Cr0Jr_J9sWQI0%Q8xP=8l zt41BfK4+1JFtu1T9D(!)aXradl7flv*TFf3&E#(iGWuHzM?P4U)av*dD6YvZa-{Zx zhodU9D?ZHPI%bHN+!3wU@VE(z9ee|LN^Bh${AM&TsXF30J+Q+C<;={&yF4~=0F3Fh z5{}ICkaO<EJ$?x+A%Ob8vf!)cOJ0U&R{wdfSB>dx%88Vi@M>-H{lY&2Rnlbb2C+v= zuOA#LX@CKuhor;u6t9p=M0DB7+HoSk9i6!GEvp(>&^CQ%NNS-_O|^8&BP4$f^96#1 z<T0HFuwD1As?|PclPjqDCJis5s#V6@&mVokjN}~iqePd8xKa1|mcWzO|LJba{zj?A zACX;ll%Y)YDGE;CETom+gft*^BjRwpRmC;aB2;KEK^%3@viCm5CYQ4U$I)#zaVz(G zh+hppB^vq0h4-gl1XSoFjt6)}5Q`7Ap!SkujW`T74<hQ>RQ!6xfF+VmAWMF7(EQVI zHq$FY>ox)7i%YE7+IP}X(M_ILkYBX)qTGyyVpYTzV%%0k=mi!m^!@ry)@pVj>!U+v zh|mssZZ6C*IsJZux?Jp174$&)wL%JLry(u1rBZr_14EBIMAE76cFLs@8JX<4JN{sv zy@&knt7=9ygh&DjcJ~gtC_m;ZGGnnRxQV~SLfn3WzBQE_vsh=4{queX**!(u-?WTv zKg+0*GKdzZqEW0$8C0E?w>X?sS@M{D{kox20<)Uhqj-%F$sJx~UI*+F^cUX@LzRxK zdF)n5⪚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%0AE@1A|VQd{BhPPV$L;<~!iG5$*QoZm=wu>1J=c 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 literal 0 HcmV?d00001 diff --git a/examples/biomineralization/img/results_volfracs_over_length_100000s.png b/examples/biomineralization/img/results_volfracs_over_length_100000s.png new file mode 100644 index 0000000000000000000000000000000000000000..c052e724d2afd0e4211eb88f6d7bb2fa03904e86 GIT binary patch literal 17950 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 literal 0 HcmV?d00001 diff --git a/examples/biomineralization/injection_checkpoints.dat b/examples/biomineralization/injection_checkpoints.dat new file mode 100644 index 0000000000..fc7638a67a --- /dev/null +++ b/examples/biomineralization/injection_checkpoints.dat @@ -0,0 +1,212 @@ +900 +30600 +91800 +93600 +95400 +95520 +109920 +111720 +167520 +169320 +171120 +171240 +195540 +197340 +253140 +254940 +256740 +256860 +361260 +363060 +438660 +440460 +442260 +442380 +456780 +458580 +541260 +543060 +544860 +544980 +546660 +548460 +552060 +555660 +559260 +629580 +631380 +697860 +699660 +701460 +701580 +715980 +717780 +784260 +786060 +787860 +787980 +789660 +791460 +795060 +798660 +802260 +802380 +804180 +870660 +872460 +874260 +874380 +888780 +890580 +957060 +958860 +960660 +960780 +975180 +976980 +1043460 +1045260 +1047060 +1047180 +1048860 +1050660 +1054260 +1057860 +1061460 +1061580 +1063380 +1146060 +1147860 +1149660 +1149780 +1234380 +1236180 +1302660 +1304460 +1306260 +1306380 +1320780 +1322580 +1389060 +1390860 +1392660 +1392780 +1407180 +1408980 +1475460 +1477260 +1479060 +1479180 +1493580 +1495380 +1561860 +1563660 +1565460 +1565580 +1579980 +1581780 +1648260 +1650060 +1651860 +1651980 +1666380 +1668180 +1750860 +1752660 +1754460 +1754580 +1839180 +1840980 +1907460 +1909260 +1911060 +1911180 +1925580 +1927380 +1993860 +1995660 +1997460 +1997580 +2011980 +2013780 +2080260 +2082060 +2083860 +2083980 +2098380 +2100180 +2166660 +2168460 +2170260 +2170380 +2184780 +2186580 +2253060 +2254860 +2256660 +2256780 +2258460 +2260260 +2263860 +2271060 +2271180 +2272980 +2355660 +2357460 +2359260 +2359380 +2443980 +2445780 +2512260 +2514060 +2515860 +2515980 +2517660 +2519460 +2523060 +2526660 +2530260 +2530380 +2532180 +2598660 +2600460 +2602260 +2602380 +2616780 +2618580 +2685060 +2686860 +2688660 +2688780 +2703180 +2704980 +2771460 +2773260 +2775060 +2775180 +2789580 +2791380 +2857860 +2859660 +2861460 +2861580 +2875980 +2877780 +2960460 +2962260 +2964060 +2964180 +3048780 +3050580 +3117060 +3118860 +3120660 +3120780 +3122460 +3124260 +3127860 +3131460 +3135060 +3135180 +3136980 +3203460 diff --git a/examples/biomineralization/injection_type.dat b/examples/biomineralization/injection_type.dat new file mode 100644 index 0000000000..b2b6b791c0 --- /dev/null +++ b/examples/biomineralization/injection_type.dat @@ -0,0 +1,212 @@ +2 +-99 +3 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +9 +9 +9 +9 +9 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +9 +9 +9 +9 +9 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +9 +9 +9 +9 +9 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +9 +9 +9 +9 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +9 +9 +9 +9 +9 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +-99 +3 +-99 +-1 +1 +-1 +9 +9 +9 +9 +9 +-99 +3 +9 \ No newline at end of file diff --git a/examples/biomineralization/main.cc b/examples/biomineralization/main.cc new file mode 100644 index 0000000000..8ae2cc3b84 --- /dev/null +++ b/examples/biomineralization/main.cc @@ -0,0 +1,278 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +// ## The main file +// This files contains the main program flow for the biomineralization example. Here we can see the programme sequence and how the system is solved using newton's method. +// +// [[content]] +// +// ### Included header files +// <details> +// [[exclude]] +// Some generic includes. +#include <config.h> +#include <iostream> +#include <dumux/io/container.hh> +// [[/exclude]] + +// These are DUNE helper classes related to parallel computations +#include <dune/common/parallel/mpihelper.hh> + +// The following headers include functionality related to property definition or retrieval, as well as +// the retrieval of input parameters specified in the input file or via the command line. +#include <dumux/common/properties.hh> +#include <dumux/common/parameters.hh> + +// The follwoing files contain the nonlinear Newtown method, the linear solver and the assembler +#include <dumux/nonlinear/newtonsolver.hh> +#include <dumux/linear/amgbackend.hh> +#include <dumux/assembly/fvassembler.hh> +#include <dumux/assembly/diffmethod.hh> + +// The following class provides a convenient way of writing of dumux simulation results to VTK format. +#include <dumux/io/vtkoutputmodule.hh> + +// The gridmanager constructs a grid from the information in the input or grid file. There is a specification for the different supported grid managers. +// Many different Dune grid implementations are supported, of which a list can be found +// in `gridmanager.hh`. +#include <dumux/io/grid/gridmanager_yasp.hh> + +// We include the problem file which defines initial and boundary conditions to describe our example problem +//remove #include "problem.hh" +#include "properties.hh" +// </details> +// + +// ### The main function +// We will now discuss the main program flow implemented within the `main` function. +// At the beginning of each program using Dune, an instance `Dune::MPIHelper` has to +// be created. Moreover, we parse the run-time arguments from the command line and the +// input file: +// [[codeblock]] +int main(int argc, char** argv) try +{ + using namespace Dumux; + + // initialize MPI, finalize is done automatically on exit + const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); + + // parse command line arguments and input file + Parameters::init(argc, argv); + // [[/codeblock]] + + // For convenience we define the type tag for this problem. + // The type tags contain all the properties that are needed to run the simulations. + using TypeTag = Properties::TTag::MICPColumnSimpleChemistry; + + // ### Step 1: Create the grid + // The `GridManager` class creates the grid from information given in the input file. + // This can either be a grid file, or in the case of structured grids, one can specify the coordinates + // of the corners of the grid and the number of cells to be used to discretize each spatial direction. The latter is the case for this example. + // [[codeblock]] + GridManager<GetPropType<TypeTag, Properties::Grid>> gridManager; + gridManager.init(); + + // we compute on the leaf grid view + const auto& leafGridView = gridManager.grid().leafGridView(); + // [[/codeblock]] + + // ### Step 2: Setting up the problem + // We create and initialize the finite volume grid geometry, the problem, the linear system, including the jacobian matrix, the residual and the solution vector and the gridvariables. + // We need the finite volume geometry to build up the subcontrolvolumes (scv) and subcontrolvolume faces (scvf) for each element of the grid partition. + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + auto gridGeometry = std::make_shared<GridGeometry>(leafGridView); + gridGeometry->update(); + + // We now instantiate the problem, in which we define the boundary and initial conditions. + using Problem = GetPropType<TypeTag, Properties::Problem>; + auto problem = std::make_shared<Problem>(gridGeometry); + + // get some time loop parameters + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); + const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); + const auto dt = getParam<Scalar>("TimeLoop.DtInitial"); + + // We initialize the solution vector + using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + SolutionVector x; + problem->applyInitialSolution(x); + auto xOld = x; + + // on the basis of this solution, we initialize the grid variables + using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; + auto gridVariables = std::make_shared<GridVariables>(problem, gridGeometry); + gridVariables->init(x); + + // We intialize the vtk output module. Each model has a predefined model specific output with relevant parameters for that model. + // [[codeblock]] + VtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name()); + using VelocityOutput = GetPropType<TypeTag, Properties::VelocityOutput>; + vtkWriter.addVelocityOutput(std::make_shared<VelocityOutput>(*gridVariables)); + GetPropType<TypeTag, Properties::IOFields>::initOutputModule(vtkWriter); //!< Add model specific output fields + //we add permeability as a specific output + vtkWriter.addField(problem->getPermeability(), "Permeability"); + //We update the output fields before write + problem->updateVtkOutput(x); + vtkWriter.write(0.0); + // [[/codeblock]] + + //We instantiate the time loop and define an episode index to keep track of the the actual episode number + // [[codeblock]] + int episodeIdx = 0; + //We set the initial episodeIdx in the problem to zero + problem->setEpisodeIdx(episodeIdx); + //We set the time loop with episodes (check points) + auto timeLoop = std::make_shared<CheckPointTimeLoop<Scalar>>(0.0, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + // [[/codeblock]] + + // ### Step 3 Setting episodes specified from file + // In this example we want to specify the injected reactant solutions at certain times. + // This is specified in an external file injections_checkpoints.dat. + // Within the following code block, the parameter file read and the time for the injection are extracted. + // Based on that, the checkpoints for the simulation are set. + + // [[codeblock]] + //We use a time loop with episodes if an injection parameter file is specified in the input + if (hasParam("Injection.NumInjections")) + { + //We first read the times of the checkpoints from the injection file + const auto injectionCheckPoints = readFileToContainer<std::vector<double>>("injection_checkpoints.dat"); + + // We set the time loop with episodes of various lengths as specified in the injection file + // set the episode ends /check points: + timeLoop->setCheckPoint(injectionCheckPoints); + + // We also set the initial episodeIdx in the problem to zero, as in the problem the boundary conditions depend on the episode. + problem->setEpisodeIdx(episodeIdx); + } + + // If nothing specified, we do not need to use episodes + else + { + // In this case, we set the time loop with one big episodes + timeLoop->setCheckPoint(tEnd); + } + // [[/codeblock]] + + // ### Step 4 solving the instationary problem + + // We create and initialize the assembler with a time loop for the transient problem. + // Within the time loop, we will use this assembler in each time step to assemble the linear system. + // Additionally the linear and non-linear solvers are set + // [[codeblock]] + using Assembler = FVAssembler<TypeTag, DiffMethod::numeric>; + auto assembler = std::make_shared<Assembler>(problem, gridGeometry, gridVariables, timeLoop, xOld); + + //We set the linear solver + using LinearSolver = Dumux::ILU0BiCGSTABBackend; + auto linearSolver = std::make_shared<LinearSolver>(); + + //We set the non-linear solver + using NewtonSolver = NewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); + // [[/codeblock]] + + // #### The time loop + // We start the time loop and solve a new time step as long as `tEnd` is not reached. In every time step, + // the problem is assembled and solved, the solution is updated, and when a checkpoint is reached the solution + // is written to a new vtk file. In addition, statistics related to CPU time, the current simulation time + // and the time step sizes used is printed to the terminal. + + // [[codeblock]] + timeLoop->start(); do + { + // We set the time and time step size to be used in the problem + problem->setTime( timeLoop->time() + timeLoop->timeStepSize() ); + problem->setTimeStepSize( timeLoop->timeStepSize() ); + + // Solve the linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + // Update the old solution with the one computed in this time step and move to the next one + xOld = x; + gridVariables->advanceTimeStep(); + timeLoop->advanceTimeStep(); + + // We update the output fields before write + problem->updateVtkOutput(x); + + // We write vtk output on checkpoints or every 20th timestep + if (timeLoop->timeStepIndex() % 20 == 0 || timeLoop->isCheckPoint()) + { + // update the output fields before write + problem->updateVtkOutput(x); + + // write vtk output + vtkWriter.write(timeLoop->time()); + } + // We report statistics of this time step + timeLoop->reportTimeStep(); + + //If episodes/check points are used, we count episodes and update the episode indices in the main file and the problem. + if (hasParam("Injection.NumInjections") || hasParam("TimeLoop.EpisodeLength")) + { + if (timeLoop->isCheckPoint()) + { + episodeIdx++; + problem->setEpisodeIdx(episodeIdx); + } + } + + // set the new time step size that is suggested by the newton solver + timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); + + } while (!timeLoop->finished()); + timeLoop->finalize(leafGridView.comm()); + // [[/codeblock]] + + if (mpiHelper.rank() == 0) + Parameters::print(); + + return 0; +} + +// ### Exception handling +// In this part of the main file we catch and print possible exceptions that could +// occur during the simulation. +// [[details]] error handler +// [[codeblock]] +// errors related to run-time parameters +catch (const Dumux::ParameterException &e) +{ + std::cerr << std::endl << e << " ---> Abort!" << std::endl; + return 1; +} +catch (const Dune::DGFException & e) +{ + std::cerr << "DGF exception thrown (" << e << + "). Most likely, the DGF file name is wrong " + "or the DGF file is corrupted, " + "e.g. missing hash at end of file or wrong number (dimensions) of entries." + << " ---> Abort!" << std::endl; + return 2; +} +catch (const Dune::Exception &e) +{ + std::cerr << "Dune reported error: " << e << " ---> Abort!" << std::endl; + return 3; +} +// [[/codeblock]] +// [[/details]] +// [[/content]] diff --git a/examples/biomineralization/material/co2tableslaboratory.hh b/examples/biomineralization/material/co2tableslaboratory.hh new file mode 100644 index 0000000000..ec5f71af3c --- /dev/null +++ b/examples/biomineralization/material/co2tableslaboratory.hh @@ -0,0 +1,38 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ + +#ifndef DUMUX_ICP_CO2TABLES_LABORATORY_HH +#define DUMUX_ICP_CO2TABLES_LABORATORY_HH + +// ## The CO2 tables (`co2tableslaboratory.hh`) +// +// This file contains the __co2table class__ which forwards to tabulated properties of CO2 according to Span and Wagner 1996. +// The real work (creating the tables) is done by some external program by Span and Wagner 1996 which provides the ready-to-use tables. +// +// [[content]] +// +// [[codeblock]] + +#include <assert.h> +namespace Dumux::ICP { +#include "co2valueslaboratory.inc" +}// end namespace Dumux::ICP +// [[/codeblock]] +// [[/content]] +#endif diff --git a/examples/biomineralization/material/co2valueslaboratory.inc b/examples/biomineralization/material/co2valueslaboratory.inc new file mode 100644 index 0000000000..536074c76b --- /dev/null +++ b/examples/biomineralization/material/co2valueslaboratory.inc @@ -0,0 +1,424 @@ +/* Tables for CO2 fluid properties calculated according to Span and + * Wagner (1996). + * + * THIS AN AUTO-GENERATED FILE! DO NOT EDIT IT! + * + * Temperature range: 288.000 K to 303.000 K, using 15 sampling points + * Pressure range: 0.095 MPa to 0.145 MPa, using 50 sampling points + * + * Generated using: + * + * ./extractproperties 288 303 15 95000 145000 50 + */ + + +struct TabulatedDensityTraits { + typedef double Scalar; + static const char *name; + static const int numTempSteps = 15; + static constexpr Scalar minTemp = 2.880000000000000e+02; + static constexpr Scalar maxTemp = 3.030000000000000e+02; + static const int numPressSteps = 50; + static constexpr Scalar minPress = 9.500000000000000e+04; + static constexpr Scalar maxPress = 1.450000000000000e+05; + static const Scalar vals[numTempSteps][numPressSteps]; +}; + +const char *TabulatedDensityTraits::name = "density"; + +const double TabulatedDensityTraits::vals[15][50] = +{ + { + 1.755308372911512e+00, 1.774264402821289e+00, 1.793222621515086e+00, 1.812183029645950e+00, 1.831145627867246e+00, + 1.850110416832651e+00, 1.869077397196165e+00, 1.888046569612100e+00, 1.907017934735086e+00, 1.925991493220070e+00, + 1.944967245722317e+00, 1.963945192897409e+00, 1.982925335401247e+00, 2.001907673890049e+00, 2.020892209020350e+00, + 2.039878941449006e+00, 2.058867871833190e+00, 2.077859000830393e+00, 2.096852329098427e+00, 2.115847857295424e+00, + 2.134845586079831e+00, 2.153845516110419e+00, 2.172847648046278e+00, 2.191851982546817e+00, 2.210858520271766e+00, + 2.229867261881177e+00, 2.248878208035418e+00, 2.267891359395183e+00, 2.286906716621488e+00, 2.305924280375664e+00, + 2.324944051319368e+00, 2.343966030114581e+00, 2.362990217423599e+00, 2.382016613909049e+00, 2.401045220233873e+00, + 2.420076037061341e+00, 2.439109065055041e+00, 2.458144304878889e+00, 2.477181757197121e+00, 2.496221422674298e+00, + 2.515263301975305e+00, 2.534307395765349e+00, 2.553353704709964e+00, 2.572402229475007e+00, 2.591452970726658e+00, + 2.610505929131427e+00, 2.629561105356142e+00, 2.648618500067962e+00, 2.667678113934368e+00, 2.686739947623169e+00 + }, + { + 1.748688604734713e+00, 1.767571892229173e+00, 1.786457333061390e+00, 1.805344927864506e+00, 1.824234677271969e+00, + 1.843126581917526e+00, 1.862020642435228e+00, 1.880916859459429e+00, 1.899815233624782e+00, 1.918715765566246e+00, + 1.937618455919081e+00, 1.956523305318852e+00, 1.975430314401425e+00, 1.994339483802971e+00, 2.013250814159965e+00, + 2.032164306109183e+00, 2.051079960287710e+00, 2.069997777332932e+00, 2.088917757882538e+00, 2.107839902574526e+00, + 2.126764212047197e+00, 2.145690686939155e+00, 2.164619327889312e+00, 2.183550135536884e+00, 2.202483110521394e+00, + 2.221418253482670e+00, 2.240355565060845e+00, 2.259295045896362e+00, 2.278236696629965e+00, 2.297180517902710e+00, + 2.316126510355958e+00, 2.335074674631374e+00, 2.354025011370935e+00, 2.372977521216923e+00, 2.391932204811928e+00, + 2.410889062798848e+00, 2.429848095820891e+00, 2.448809304521571e+00, 2.467772689544708e+00, 2.486738251534437e+00, + 2.505705991135198e+00, 2.524675908991741e+00, 2.543648005749125e+00, 2.562622282052718e+00, 2.581598738548199e+00, + 2.600577375881557e+00, 2.619558194699090e+00, 2.638541195647405e+00, 2.657526379373425e+00, 2.676513746524379e+00 + }, + { + 1.742119513324718e+00, 1.760930634944350e+00, 1.779743875160616e+00, 1.798559234587417e+00, 1.817376713838946e+00, + 1.836196313529680e+00, 1.855018034274388e+00, 1.873841876688128e+00, 1.892667841386243e+00, 1.911495928984368e+00, + 1.930326140098427e+00, 1.949158475344631e+00, 1.967992935339483e+00, 1.986829520699775e+00, 2.005668232042588e+00, + 2.024509069985295e+00, 2.043352035145557e+00, 2.062197128141326e+00, 2.081044349590847e+00, 2.099893700112652e+00, + 2.118745180325567e+00, 2.137598790848708e+00, 2.156454532301483e+00, 2.175312405303590e+00, 2.194172410475020e+00, + 2.213034548436057e+00, 2.231898819807275e+00, 2.250765225209542e+00, 2.269633765264017e+00, 2.288504440592153e+00, + 2.307377251815696e+00, 2.326252199556683e+00, 2.345129284437447e+00, 2.364008507080612e+00, 2.382889868109099e+00, + 2.401773368146120e+00, 2.420659007815180e+00, 2.439546787740082e+00, 2.458436708544920e+00, 2.477328770854085e+00, + 2.496222975292262e+00, 2.515119322484431e+00, 2.534017813055865e+00, 2.552918447632137e+00, 2.571821226839111e+00, + 2.590726151302949e+00, 2.609633221650109e+00, 2.628542438507346e+00, 2.647453802501707e+00, 2.666367314260542e+00 + }, + { + 1.735600503086598e+00, 1.754340028201860e+00, 1.773081637860596e+00, 1.791825332658108e+00, 1.810571113189969e+00, + 1.829318980052027e+00, 1.848068933840407e+00, 1.866820975151510e+00, 1.885575104582009e+00, 1.904331322728859e+00, + 1.923089630189284e+00, 1.941850027560791e+00, 1.960612515441156e+00, 1.979377094428439e+00, 1.998143765120974e+00, + 2.016912528117368e+00, 2.035683384016511e+00, 2.054456333417567e+00, 2.073231376919978e+00, 2.092008515123465e+00, + 2.110787748628023e+00, 2.129569078033930e+00, 2.148352503941738e+00, 2.167138026952281e+00, 2.185925647666668e+00, + 2.204715366686289e+00, 2.223507184612810e+00, 2.242301102048181e+00, 2.261097119594628e+00, 2.279895237854655e+00, + 2.298695457431049e+00, 2.317497778926874e+00, 2.336302202945476e+00, 2.355108730090479e+00, 2.373917360965788e+00, + 2.392728096175590e+00, 2.411540936324352e+00, 2.430355882016820e+00, 2.449172933858022e+00, 2.467992092453268e+00, + 2.486813358408150e+00, 2.505636732328538e+00, 2.524462214820588e+00, 2.543289806490736e+00, 2.562119507945698e+00, + 2.580951319792477e+00, 2.599785242638353e+00, 2.618621277090893e+00, 2.637459423757945e+00, 2.656299683247639e+00 + }, + { + 1.729130988069413e+00, 1.747799479006408e+00, 1.766470021105015e+00, 1.785142614942543e+00, 1.803817261096561e+00, + 1.822493960144904e+00, 1.841172712665666e+00, 1.859853519237209e+00, 1.878536380438155e+00, 1.897221296847389e+00, + 1.915908269044062e+00, 1.934597297607586e+00, 1.953288383117640e+00, 1.971981526154163e+00, 1.990676727297363e+00, + 2.009373987127709e+00, 2.028073306225935e+00, 2.046774685173041e+00, 2.065478124550290e+00, 2.084183624939213e+00, + 2.102891186921603e+00, 2.121600811079520e+00, 2.140312497995291e+00, 2.159026248251505e+00, 2.177742062431020e+00, + 2.196459941116959e+00, 2.215179884892710e+00, 2.233901894341931e+00, 2.252625970048542e+00, 2.271352112596734e+00, + 2.290080322570960e+00, 2.308810600555946e+00, 2.327542947136680e+00, 2.346277362898420e+00, 2.365013848426691e+00, + 2.383752404307285e+00, 2.402493031126264e+00, 2.421235729469957e+00, 2.439980499924959e+00, 2.458727343078137e+00, + 2.477476259516623e+00, 2.496227249827822e+00, 2.514980314599402e+00, 2.533735454419308e+00, 2.552492669875746e+00, + 2.571251961557198e+00, 2.590013330052412e+00, 2.608776775950404e+00, 2.627542299840464e+00, 2.646309902312153e+00 + }, + { + 1.722710391762579e+00, 1.741308403925821e+00, 1.759908434523914e+00, 1.778510484116767e+00, 1.797114553264537e+00, + 1.815720642527634e+00, 1.834328752466721e+00, 1.852938883642709e+00, 1.871551036616761e+00, 1.890165211950294e+00, + 1.908781410204973e+00, 1.927399631942718e+00, 1.946019877725699e+00, 1.964642148116340e+00, 1.983266443677315e+00, + 2.001892764971552e+00, 2.020521112562232e+00, 2.039151487012787e+00, 2.057783888886904e+00, 2.076418318748522e+00, + 2.095054777161832e+00, 2.113693264691282e+00, 2.132333781901571e+00, 2.150976329357650e+00, 2.169620907624727e+00, + 2.188267517268265e+00, 2.206916158853976e+00, 2.225566832947831e+00, 2.244219540116054e+00, 2.262874280925123e+00, + 2.281531055941773e+00, 2.300189865732990e+00, 2.318850710866020e+00, 2.337513591908360e+00, 2.356178509427764e+00, + 2.374845463992243e+00, 2.393514456170064e+00, 2.412185486529745e+00, 2.430858555640066e+00, 2.449533664070059e+00, + 2.468210812389017e+00, 2.486890001166484e+00, 2.505571230972264e+00, 2.524254502376418e+00, 2.542939815949262e+00, + 2.561627172261374e+00, 2.580316571883581e+00, 2.599008015386975e+00, 2.617701503342902e+00, 2.636397036322968e+00 + }, + { + 1.716338146897580e+00, 1.734866228889907e+00, 1.753396297229703e+00, 1.771928352460044e+00, 1.790462395124249e+00, + 1.808998425765874e+00, 1.827536444928716e+00, 1.846076453156811e+00, 1.864618450994437e+00, 1.883162438986109e+00, + 1.901708417676587e+00, 1.920256387610867e+00, 1.938806349334189e+00, 1.957358303392030e+00, 1.975912250330114e+00, + 1.994468190694400e+00, 2.013026125031091e+00, 2.031586053886632e+00, 2.050147977807709e+00, 2.068711897341247e+00, + 2.087277813034418e+00, 2.105845725434632e+00, 2.124415635089543e+00, 2.142987542547046e+00, 2.161561448355279e+00, + 2.180137353062624e+00, 2.198715257217703e+00, 2.217295161369383e+00, 2.235877066066772e+00, 2.254460971859225e+00, + 2.273046879296335e+00, 2.291634788927943e+00, 2.310224701304131e+00, 2.328816616975225e+00, 2.347410536491797e+00, + 2.366006460404661e+00, 2.384604389264875e+00, 2.403204323623743e+00, 2.421806264032811e+00, 2.440410211043872e+00, + 2.459016165208964e+00, 2.477624127080368e+00, 2.496234097210611e+00, 2.514846076152465e+00, 2.533460064458948e+00, + 2.552076062683323e+00, 2.570694071379098e+00, 2.589314091100029e+00, 2.607936122400116e+00, 2.626560165833606e+00 + }, + { + 1.710013695254868e+00, 1.728472388994598e+00, 1.746933037618520e+00, 1.765395641653431e+00, 1.783860201626355e+00, + 1.802326718064545e+00, 1.820795191495484e+00, 1.839265622446885e+00, 1.857738011446687e+00, 1.876212359023062e+00, + 1.894688665704410e+00, 1.913166932019361e+00, 1.931647158496774e+00, 1.950129345665740e+00, 1.968613494055580e+00, + 1.987099604195842e+00, 2.005587676616308e+00, 2.024077711846988e+00, 2.042569710418126e+00, 2.061063672860195e+00, + 2.079559599703896e+00, 2.098057491480167e+00, 2.116557348720172e+00, 2.135059171955310e+00, 2.153562961717211e+00, + 2.172068718537734e+00, 2.190576442948971e+00, 2.209086135483248e+00, 2.227597796673122e+00, 2.246111427051381e+00, + 2.264627027151048e+00, 2.283144597505372e+00, 2.301664138647844e+00, 2.320185651112181e+00, 2.338709135432337e+00, + 2.357234592142493e+00, 2.375762021777073e+00, 2.394291424870723e+00, 2.412822801958331e+00, 2.431356153575015e+00, + 2.449891480256128e+00, 2.468428782537256e+00, 2.486968060954219e+00, 2.505509316043070e+00, 2.524052548340100e+00, + 2.542597758381833e+00, 2.561144946705024e+00, 2.579694113846667e+00, 2.598245260343989e+00, 2.616798386734454e+00 + }, + { + 1.703736487475788e+00, 1.722126328311195e+00, 1.740518093176789e+00, 1.758911782583613e+00, 1.777307397042928e+00, + 1.795704937066214e+00, 1.814104403165170e+00, 1.832505795851713e+00, 1.850909115637979e+00, 1.869314363036326e+00, + 1.887721538559327e+00, 1.906130642719779e+00, 1.924541676030695e+00, 1.942954639005309e+00, 1.961369532157075e+00, + 1.979786355999667e+00, 1.998205111046980e+00, 2.016625797813126e+00, 2.035048416812443e+00, 2.053472968559482e+00, + 2.071899453569022e+00, 2.090327872356059e+00, 2.108758225435809e+00, 2.127190513323711e+00, 2.145624736535425e+00, + 2.164060895586833e+00, 2.182498990994034e+00, 2.200939023273354e+00, 2.219380992941339e+00, 2.237824900514755e+00, + 2.256270746510591e+00, 2.274718531446059e+00, 2.293168255838592e+00, 2.311619920205845e+00, 2.330073525065698e+00, + 2.348529070936249e+00, 2.366986558335824e+00, 2.385445987782969e+00, 2.403907359796452e+00, 2.422370674895265e+00, + 2.440835933598625e+00, 2.459303136425971e+00, 2.477772283896963e+00, 2.496243376531490e+00, 2.514716414849660e+00, + 2.533191399371808e+00, 2.551668330618489e+00, 2.570147209110487e+00, 2.588628035368806e+00, 2.607110809914681e+00 + }, + { + 1.697505982879398e+00, 1.715827499700588e+00, 1.734150910292815e+00, 1.752476215151878e+00, 1.770803414773786e+00, + 1.789132509654754e+00, 1.807463500291209e+00, 1.825796387179785e+00, 1.844131170817327e+00, 1.862467851700888e+00, + 1.880806430327732e+00, 1.899146907195332e+00, 1.917489282801369e+00, 1.935833557643738e+00, 1.954179732220541e+00, + 1.972527807030090e+00, 1.990877782570909e+00, 2.009229659341731e+00, 2.027583437841500e+00, 2.045939118569371e+00, + 2.064296702024710e+00, 2.082656188707092e+00, 2.101017579116305e+00, 2.119380873752348e+00, 2.137746073115430e+00, + 2.156113177705973e+00, 2.174482188024609e+00, 2.192853104572181e+00, 2.211225927849747e+00, 2.229600658358574e+00, + 2.247977296600142e+00, 2.266355843076143e+00, 2.284736298288480e+00, 2.303118662739270e+00, 2.321502936930843e+00, + 2.339889121365739e+00, 2.358277216546714e+00, 2.376667222976734e+00, 2.395059141158978e+00, 2.413452971596841e+00, + 2.431848714793929e+00, 2.450246371254060e+00, 2.468645941481269e+00, 2.487047425979803e+00, 2.505450825254121e+00, + 2.523856139808898e+00, 2.542263370149021e+00, 2.560672516779593e+00, 2.579083580205932e+00, 2.597496560933566e+00 + }, + { + 1.691321649284043e+00, 1.709575364632300e+00, 1.727830944073291e+00, 1.746088388088063e+00, 1.764347697157863e+00, + 1.782608871764136e+00, 1.800871912388526e+00, 1.819136819512882e+00, 1.837403593619246e+00, 1.855672235189865e+00, + 1.873942744707183e+00, 1.892215122653849e+00, 1.910489369512707e+00, 1.928765485766804e+00, 1.947043471899390e+00, + 1.965323328393911e+00, 1.983605055734019e+00, 2.001888654403562e+00, 2.020174124886593e+00, 2.038461467667364e+00, + 2.056750683230330e+00, 2.075041772060146e+00, 2.093334734641670e+00, 2.111629571459961e+00, 2.129926283000279e+00, + 2.148224869748088e+00, 2.166525332189051e+00, 2.184827670809036e+00, 2.203131886094113e+00, 2.221437978530552e+00, + 2.239745948604829e+00, 2.258055796803620e+00, 2.276367523613803e+00, 2.294681129522462e+00, 2.312996615016882e+00, + 2.331313980584552e+00, 2.349633226713162e+00, 2.367954353890609e+00, 2.386277362604989e+00, 2.404602253344606e+00, + 2.422929026597965e+00, 2.441257682853774e+00, 2.459588222600948e+00, 2.477920646328603e+00, 2.496254954526061e+00, + 2.514591147682848e+00, 2.532929226288692e+00, 2.551269190833529e+00, 2.569611041807498e+00, 2.587954779700943e+00 + }, + { + 1.685182962833544e+00, 1.703369393008219e+00, 1.721557658164561e+00, 1.739747758769335e+00, 1.757939695289500e+00, + 1.776133468192206e+00, 1.794329077944792e+00, 1.812526525014790e+00, 1.830725809869921e+00, 1.848926932978100e+00, + 1.867129894807431e+00, 1.885334695826211e+00, 1.903541336502926e+00, 1.921749817306258e+00, 1.939960138705077e+00, + 1.958172301168445e+00, 1.976386305165618e+00, 1.994602151166044e+00, 2.012819839639362e+00, 2.031039371055401e+00, + 2.049260745884189e+00, 2.067483964595941e+00, 2.085709027661065e+00, 2.103935935550165e+00, 2.122164688734034e+00, + 2.140395287683661e+00, 2.158627732870225e+00, 2.176862024765100e+00, 2.195098163839856e+00, 2.213336150566250e+00, + 2.231575985416239e+00, 2.249817668861968e+00, 2.268061201375779e+00, 2.286306583430208e+00, 2.304553815497984e+00, + 2.322802898052028e+00, 2.341053831565459e+00, 2.359306616511588e+00, 2.377561253363920e+00, 2.395817742596156e+00, + 2.414076084682191e+00, 2.432336280096114e+00, 2.450598329312208e+00, 2.468862232804953e+00, 2.487127991049023e+00, + 2.505395604519288e+00, 2.523665073690812e+00, 2.541936399038852e+00, 2.560209581038867e+00, 2.578484620166506e+00 + }, + { + 1.679089407827878e+00, 1.697209062990904e+00, 1.715330524578524e+00, 1.733453793043684e+00, 1.751578868839513e+00, + 1.769705752419320e+00, 1.787834444236597e+00, 1.805964944745021e+00, 1.824097254398450e+00, 1.842231373650924e+00, + 1.860367302956667e+00, 1.878505042770085e+00, 1.896644593545767e+00, 1.914785955738489e+00, 1.932929129803203e+00, + 1.951074116195050e+00, 1.969220915369354e+00, 1.987369527781620e+00, 2.005519953887538e+00, 2.023672194142983e+00, + 2.041826249004011e+00, 2.059982118926865e+00, 2.078139804367971e+00, 2.096299305783937e+00, 2.114460623631559e+00, + 2.132623758367814e+00, 2.150788710449866e+00, 2.168955480335062e+00, 2.187124068480935e+00, 2.205294475345202e+00, + 2.223466701385763e+00, 2.241640747060706e+00, 2.259816612828304e+00, 2.277994299147012e+00, 2.296173806475474e+00, + 2.314355135272516e+00, 2.332538285997154e+00, 2.350723259108584e+00, 2.368910055066190e+00, 2.387098674329545e+00, + 2.405289117358405e+00, 2.423481384612710e+00, 2.441675476552588e+00, 2.459871393638356e+00, 2.478069136330513e+00, + 2.496268705089746e+00, 2.514470100376929e+00, 2.532673322653122e+00, 2.550878372379573e+00, 2.569085250017714e+00 + }, + { + 1.673040476558227e+00, 1.691093860836300e+00, 1.709149023523030e+00, 1.727205965057981e+00, 1.745264685880892e+00, + 1.763325186431675e+00, 1.781387467150417e+00, 1.799451528477381e+00, 1.817517370853002e+00, 1.835584994717892e+00, + 1.853654400512836e+00, 1.871725588678794e+00, 1.889798559656902e+00, 1.907873313888471e+00, 1.925949851814986e+00, + 1.944028173878108e+00, 1.962108280519675e+00, 1.980190172181696e+00, 1.998273849306359e+00, 2.016359312336028e+00, + 2.034446561713241e+00, 2.052535597880711e+00, 2.070626421281331e+00, 2.088719032358165e+00, 2.106813431554456e+00, + 2.124909619313623e+00, 2.143007596079261e+00, 2.161107362295140e+00, 2.179208918405208e+00, 2.197312264853591e+00, + 2.215417402084588e+00, 2.233524330542677e+00, 2.251633050672513e+00, 2.269743562918927e+00, 2.287855867726928e+00, + 2.305969965541701e+00, 2.324085856808610e+00, 2.342203541973195e+00, 2.360323021481173e+00, 2.378444295778439e+00, + 2.396567365311067e+00, 2.414692230525306e+00, 2.432818891867587e+00, 2.450947349784512e+00, 2.469077604722869e+00, + 2.487209657129619e+00, 2.505343507451902e+00, 2.523479156137038e+00, 2.541616603632523e+00, 2.559755850386034e+00 + }, + { + 1.667035669146253e+00, 1.685023280730779e+00, 1.703012643236649e+00, 1.721003757090469e+00, 1.738996622719014e+00, + 1.756991240549225e+00, 1.774987611008209e+00, 1.792985734523242e+00, 1.810985611521764e+00, 1.828987242431384e+00, + 1.846990627679876e+00, 1.864995767695184e+00, 1.883002662905417e+00, 1.901011313738852e+00, 1.919021720623934e+00, + 1.937033883989274e+00, 1.955047804263653e+00, 1.973063481876017e+00, 1.991080917255481e+00, 2.009100110831328e+00, + 2.027121063033010e+00, 2.045143774290143e+00, 2.063168245032518e+00, 2.081194475690086e+00, 2.099222466692973e+00, + 2.117252218471470e+00, 2.135283731456037e+00, 2.153317006077303e+00, 2.171352042766067e+00, 2.189388841953294e+00, + 2.207427404070120e+00, 2.225467729547847e+00, 2.243509818817949e+00, 2.261553672312070e+00, 2.279599290462019e+00, + 2.297646673699778e+00, 2.315695822457497e+00, 2.333746737167496e+00, 2.351799418262262e+00, 2.369853866174454e+00, + 2.387910081336903e+00, 2.405968064182606e+00, 2.424027815144730e+00, 2.442089334656615e+00, 2.460152623151768e+00, + 2.478217681063868e+00, 2.496284508826763e+00, 2.514353106874473e+00, 2.532423475641187e+00, 2.550495615561266e+00 + } +}; + +typedef TabulatedCO2Properties< TabulatedDensityTraits > TabulatedDensity; + +struct TabulatedEnthalpyTraits { + typedef double Scalar; + static const char *name; + static const int numTempSteps = 15; + static constexpr Scalar minTemp = 2.880000000000000e+02; + static constexpr Scalar maxTemp = 3.030000000000000e+02; + static const int numPressSteps = 50; + static constexpr Scalar minPress = 9.500000000000000e+04; + static constexpr Scalar maxPress = 1.450000000000000e+05; + static const Scalar vals[numTempSteps][numPressSteps]; +}; + +const char *TabulatedEnthalpyTraits::name = "enthalpy"; + +const double TabulatedEnthalpyTraits::vals[15][50] = +{ + { + 1.244801188627830e+04, 1.243776118212441e+04, 1.242750944725234e+04, 1.241725668135906e+04, 1.240700288414147e+04, + 1.239674805529627e+04, 1.238649219452005e+04, 1.237623530150919e+04, 1.236597737596004e+04, 1.235571841756868e+04, + 1.234545842603116e+04, 1.233519740104331e+04, 1.232493534230083e+04, 1.231467224949931e+04, 1.230440812233415e+04, + 1.229414296050063e+04, 1.228387676369388e+04, 1.227360953160892e+04, 1.226334126394057e+04, 1.225307196038350e+04, + 1.224280162063231e+04, 1.223253024438139e+04, 1.222225783132500e+04, 1.221198438115726e+04, 1.220170989357216e+04, + 1.219143436826350e+04, 1.218115780492498e+04, 1.217088020325013e+04, 1.216060156293235e+04, 1.215032188366487e+04, + 1.214004116514082e+04, 1.212975940705310e+04, 1.211947660909460e+04, 1.210919277095791e+04, 1.209890789233557e+04, + 1.208862197291995e+04, 1.207833501240327e+04, 1.206804701047762e+04, 1.205775796683492e+04, 1.204746788116695e+04, + 1.203717675316535e+04, 1.202688458252161e+04, 1.201659136892707e+04, 1.200629711207294e+04, 1.199600181165024e+04, + 1.198570546734989e+04, 1.197540807886265e+04, 1.196510964587912e+04, 1.195481016808974e+04, 1.194450964518485e+04 + }, + { + 1.334921879332812e+04, 1.333905343954384e+04, 1.332888707876712e+04, 1.331871971070738e+04, 1.330855133507387e+04, + 1.329838195157575e+04, 1.328821155992203e+04, 1.327804015982153e+04, 1.326786775098304e+04, 1.325769433311511e+04, + 1.324751990592623e+04, 1.323734446912471e+04, 1.322716802241874e+04, 1.321699056551638e+04, 1.320681209812554e+04, + 1.319663261995399e+04, 1.318645213070940e+04, 1.317627063009926e+04, 1.316608811783093e+04, 1.315590459361167e+04, + 1.314572005714856e+04, 1.313553450814857e+04, 1.312534794631852e+04, 1.311516037136511e+04, 1.310497178299487e+04, + 1.309478218091422e+04, 1.308459156482944e+04, 1.307439993444667e+04, 1.306420728947192e+04, 1.305401362961104e+04, + 1.304381895456975e+04, 1.303362326405367e+04, 1.302342655776822e+04, 1.301322883541872e+04, 1.300303009671038e+04, + 1.299283034134818e+04, 1.298262956903707e+04, 1.297242777948177e+04, 1.296222497238694e+04, 1.295202114745705e+04, + 1.294181630439645e+04, 1.293161044290934e+04, 1.292140356269980e+04, 1.291119566347175e+04, 1.290098674492898e+04, + 1.289077680677517e+04, 1.288056584871380e+04, 1.287035387044827e+04, 1.286014087168180e+04, 1.284992685211751e+04 + }, + { + 1.425153675761450e+04, 1.424145558062830e+04, 1.423137341974496e+04, 1.422129027468572e+04, 1.421120614517171e+04, + 1.420112103092392e+04, 1.419103493166322e+04, 1.418094784711038e+04, 1.417085977698598e+04, 1.416077072101051e+04, + 1.415068067890437e+04, 1.414058965038775e+04, 1.413049763518076e+04, 1.412040463300338e+04, 1.411031064357545e+04, + 1.410021566661668e+04, 1.409011970184669e+04, 1.408002274898492e+04, 1.406992480775069e+04, 1.405982587786323e+04, + 1.404972595904159e+04, 1.403962505100474e+04, 1.402952315347146e+04, 1.401942026616046e+04, 1.400931638879028e+04, + 1.399921152107939e+04, 1.398910566274605e+04, 1.397899881350843e+04, 1.396889097308459e+04, 1.395878214119243e+04, + 1.394867231754973e+04, 1.393856150187414e+04, 1.392844969388319e+04, 1.391833689329426e+04, 1.390822309982461e+04, + 1.389810831319137e+04, 1.388799253311155e+04, 1.387787575930201e+04, 1.386775799147951e+04, 1.385763922936062e+04, + 1.384751947266185e+04, 1.383739872109954e+04, 1.382727697438991e+04, 1.381715423224905e+04, 1.380703049439290e+04, + 1.379690576053730e+04, 1.378678003039795e+04, 1.377665330369038e+04, 1.376652558013005e+04, 1.375639685943226e+04 + }, + { + 1.515496541458116e+04, 1.514496726388252e+04, 1.513496815177172e+04, 1.512496807798126e+04, 1.511496704224361e+04, + 1.510496504429113e+04, 1.509496208385599e+04, 1.508495816067028e+04, 1.507495327446596e+04, 1.506494742497492e+04, + 1.505494061192882e+04, 1.504493283505930e+04, 1.503492409409782e+04, 1.502491438877576e+04, 1.501490371882435e+04, + 1.500489208397471e+04, 1.499487948395784e+04, 1.498486591850461e+04, 1.497485138734575e+04, 1.496483589021197e+04, + 1.495481942683368e+04, 1.494480199694134e+04, 1.493478360026519e+04, 1.492476423653538e+04, 1.491474390548194e+04, + 1.490472260683475e+04, 1.489470034032361e+04, 1.488467710567817e+04, 1.487465290262799e+04, 1.486462773090243e+04, + 1.485460159023084e+04, 1.484457448034232e+04, 1.483454640096598e+04, 1.482451735183071e+04, 1.481448733266532e+04, + 1.480445634319848e+04, 1.479442438315876e+04, 1.478439145227457e+04, 1.477435755027422e+04, 1.476432267688591e+04, + 1.475428683183771e+04, 1.474425001485754e+04, 1.473421222567321e+04, 1.472417346401242e+04, 1.471413372960275e+04, + 1.470409302217166e+04, 1.469405134144643e+04, 1.468400868715428e+04, 1.467396505902229e+04, 1.466392045677741e+04 + }, + { + 1.605950433294651e+04, 1.604958808049365e+04, 1.603967088852259e+04, 1.602975275677668e+04, 1.601983368499922e+04, + 1.600991367293331e+04, 1.599999272032205e+04, 1.599007082690831e+04, 1.598014799243494e+04, 1.597022421664459e+04, + 1.596029949927988e+04, 1.595037384008326e+04, 1.594044723879708e+04, 1.593051969516359e+04, 1.592059120892489e+04, + 1.591066177982301e+04, 1.590073140759983e+04, 1.589080009199715e+04, 1.588086783275664e+04, 1.587093462961981e+04, + 1.586100048232813e+04, 1.585106539062290e+04, 1.584112935424535e+04, 1.583119237293657e+04, 1.582125444643752e+04, + 1.581131557448906e+04, 1.580137575683196e+04, 1.579143499320681e+04, 1.578149328335418e+04, 1.577155062701443e+04, + 1.576160702392785e+04, 1.575166247383463e+04, 1.574171697647480e+04, 1.573177053158830e+04, 1.572182313891498e+04, + 1.571187479819451e+04, 1.570192550916651e+04, 1.569197527157041e+04, 1.568202408514563e+04, 1.567207194963135e+04, + 1.566211886476675e+04, 1.565216483029080e+04, 1.564220984594243e+04, 1.563225391146040e+04, 1.562229702658333e+04, + 1.561233919104983e+04, 1.560238040459830e+04, 1.559242066696704e+04, 1.558245997789426e+04, 1.557249833711804e+04 + }, + { + 1.696515301627922e+04, 1.695531755591777e+04, 1.694548117735978e+04, 1.693564388035892e+04, 1.692580566466881e+04, + 1.691596653004295e+04, 1.690612647623471e+04, 1.689628550299739e+04, 1.688644361008412e+04, 1.687660079724800e+04, + 1.686675706424200e+04, 1.685691241081894e+04, 1.684706683673154e+04, 1.683722034173249e+04, 1.682737292557428e+04, + 1.681752458800932e+04, 1.680767532878993e+04, 1.679782514766833e+04, 1.678797404439659e+04, 1.677812201872669e+04, + 1.676826907041053e+04, 1.675841519919986e+04, 1.674856040484634e+04, 1.673870468710153e+04, 1.672884804571687e+04, + 1.671899048044368e+04, 1.670913199103320e+04, 1.669927257723655e+04, 1.668941223880471e+04, 1.667955097548860e+04, + 1.666968878703902e+04, 1.665982567320664e+04, 1.664996163374202e+04, 1.664009666839563e+04, 1.663023077691784e+04, + 1.662036395905885e+04, 1.661049621456884e+04, 1.660062754319782e+04, 1.659075794469570e+04, 1.658088741881229e+04, + 1.657101596529728e+04, 1.656114358390027e+04, 1.655127027437072e+04, 1.654139603645801e+04, 1.653152086991137e+04, + 1.652164477448000e+04, 1.651176774991289e+04, 1.650188979595898e+04, 1.649201091236711e+04, 1.648213109888593e+04 + }, + { + 1.787191090459213e+04, 1.786215515148537e+04, 1.785239850094927e+04, 1.784264095274742e+04, 1.783288250664326e+04, + 1.782312316240021e+04, 1.781336291978155e+04, 1.780360177855044e+04, 1.779383973846997e+04, 1.778407679930311e+04, + 1.777431296081275e+04, 1.776454822276166e+04, 1.775478258491250e+04, 1.774501604702784e+04, 1.773524860887015e+04, + 1.772548027020181e+04, 1.771571103078506e+04, 1.770594089038209e+04, 1.769616984875494e+04, 1.768639790566556e+04, + 1.767662506087583e+04, 1.766685131414749e+04, 1.765707666524219e+04, 1.764730111392147e+04, 1.763752465994680e+04, + 1.762774730307949e+04, 1.761796904308081e+04, 1.760818987971189e+04, 1.759840981273377e+04, 1.758862884190736e+04, + 1.757884696699352e+04, 1.756906418775294e+04, 1.755928050394628e+04, 1.754949591533405e+04, 1.753971042167666e+04, + 1.752992402273442e+04, 1.752013671826755e+04, 1.751034850803618e+04, 1.750055939180027e+04, 1.749076936931976e+04, + 1.748097844035442e+04, 1.747118660466396e+04, 1.746139386200796e+04, 1.745160021214592e+04, 1.744180565483721e+04, + 1.743201018984114e+04, 1.742221381691684e+04, 1.741241653582341e+04, 1.740261834631982e+04, 1.739281924816492e+04 + }, + { + 1.877977737598986e+04, 1.877010026606088e+04, 1.876042227893256e+04, 1.875074341437791e+04, 1.874106367216987e+04, + 1.873138305208128e+04, 1.872170155388487e+04, 1.871201917735331e+04, 1.870233592225914e+04, 1.869265178837481e+04, + 1.868296677547268e+04, 1.867328088332501e+04, 1.866359411170398e+04, 1.865390646038166e+04, 1.864421792913001e+04, + 1.863452851772092e+04, 1.862483822592618e+04, 1.861514705351746e+04, 1.860545500026635e+04, 1.859576206594436e+04, + 1.858606825032287e+04, 1.857637355317319e+04, 1.856667797426651e+04, 1.855698151337396e+04, 1.854728417026652e+04, + 1.853758594471513e+04, 1.852788683649060e+04, 1.851818684536365e+04, 1.850848597110489e+04, 1.849878421348486e+04, + 1.848908157227397e+04, 1.847937804724257e+04, 1.846967363816089e+04, 1.845996834479905e+04, 1.845026216692713e+04, + 1.844055510431504e+04, 1.843084715673263e+04, 1.842113832394965e+04, 1.841142860573573e+04, 1.840171800186046e+04, + 1.839200651209326e+04, 1.838229413620351e+04, 1.837258087396047e+04, 1.836286672513328e+04, 1.835315168949101e+04, + 1.834343576680265e+04, 1.833371895683704e+04, 1.832400125936295e+04, 1.831428267414907e+04, 1.830456320096396e+04 + }, + { + 1.968875174839150e+04, 1.967915223777856e+04, 1.966955186967561e+04, 1.965995064386471e+04, 1.965034856012783e+04, + 1.964074561824686e+04, 1.963114181800357e+04, 1.962153715917969e+04, 1.961193164155682e+04, 1.960232526491650e+04, + 1.959271802904013e+04, 1.958310993370905e+04, 1.957350097870453e+04, 1.956389116380774e+04, 1.955428048879972e+04, + 1.954466895346145e+04, 1.953505655757382e+04, 1.952544330091763e+04, 1.951582918327359e+04, 1.950621420442230e+04, + 1.949659836414429e+04, 1.948698166221999e+04, 1.947736409842973e+04, 1.946774567255376e+04, 1.945812638437225e+04, + 1.944850623366526e+04, 1.943888522021276e+04, 1.942926334379464e+04, 1.941964060419069e+04, 1.941001700118059e+04, + 1.940039253454397e+04, 1.939076720406034e+04, 1.938114100950913e+04, 1.937151395066967e+04, 1.936188602732117e+04, + 1.935225723924283e+04, 1.934262758621367e+04, 1.933299706801268e+04, 1.932336568441872e+04, 1.931373343521055e+04, + 1.930410032016689e+04, 1.929446633906634e+04, 1.928483149168738e+04, 1.927519577780842e+04, 1.926555919720780e+04, + 1.925592174966373e+04, 1.924628343495435e+04, 1.923664425285771e+04, 1.922700420315175e+04, 1.921736328561433e+04 + }, + { + 2.059883328134778e+04, 2.058931034587392e+04, 2.057978657211463e+04, 2.057026195986062e+04, 2.056073650890254e+04, + 2.055121021903091e+04, 2.054168309003617e+04, 2.053215512170871e+04, 2.052262631383879e+04, 2.051309666621663e+04, + 2.050356617863231e+04, 2.049403485087588e+04, 2.048450268273725e+04, 2.047496967400630e+04, 2.046543582447280e+04, + 2.045590113392641e+04, 2.044636560215672e+04, 2.043682922895327e+04, 2.042729201410545e+04, 2.041775395740263e+04, + 2.040821505863405e+04, 2.039867531758886e+04, 2.038913473405616e+04, 2.037959330782493e+04, 2.037005103868408e+04, + 2.036050792642243e+04, 2.035096397082872e+04, 2.034141917169161e+04, 2.033187352879962e+04, 2.032232704194127e+04, + 2.031277971090492e+04, 2.030323153547890e+04, 2.029368251545138e+04, 2.028413265061053e+04, 2.027458194074437e+04, + 2.026503038564086e+04, 2.025547798508788e+04, 2.024592473887319e+04, 2.023637064678451e+04, 2.022681570860945e+04, + 2.021725992413548e+04, 2.020770329315010e+04, 2.019814581544059e+04, 2.018858749079427e+04, 2.017902831899827e+04, + 2.016946829983971e+04, 2.015990743310556e+04, 2.015034571858273e+04, 2.014078315605804e+04, 2.013121974531826e+04 + }, + { + 2.151002117795434e+04, 2.150057381261242e+04, 2.149112562770026e+04, 2.148167662301682e+04, 2.147222679836103e+04, + 2.146277615353168e+04, 2.145332468832754e+04, 2.144387240254723e+04, 2.143441929598936e+04, 2.142496536845241e+04, + 2.141551061973478e+04, 2.140605504963485e+04, 2.139659865795084e+04, 2.138714144448092e+04, 2.137768340902319e+04, + 2.136822455137568e+04, 2.135876487133630e+04, 2.134930436870289e+04, 2.133984304327324e+04, 2.133038089484503e+04, + 2.132091792321584e+04, 2.131145412818323e+04, 2.130198950954462e+04, 2.129252406709739e+04, 2.128305780063880e+04, + 2.127359070996605e+04, 2.126412279487627e+04, 2.125465405516648e+04, 2.124518449063364e+04, 2.123571410107462e+04, + 2.122624288628622e+04, 2.121677084606514e+04, 2.120729798020801e+04, 2.119782428851136e+04, 2.118834977077168e+04, + 2.117887442678532e+04, 2.116939825634861e+04, 2.115992125925773e+04, 2.115044343530886e+04, 2.114096478429800e+04, + 2.113148530602118e+04, 2.112200500027424e+04, 2.111252386685300e+04, 2.110304190555319e+04, 2.109355911617045e+04, + 2.108407549850033e+04, 2.107459105233831e+04, 2.106510577747980e+04, 2.105561967372010e+04, 2.104613274085443e+04 + }, + { + 2.242231458686298e+04, 2.241294180531756e+04, 2.240356822244238e+04, 2.239419383804431e+04, 2.238481865193019e+04, + 2.237544266390678e+04, 2.236606587378072e+04, 2.235668828135863e+04, 2.234730988644700e+04, 2.233793068885232e+04, + 2.232855068838091e+04, 2.231916988483910e+04, 2.230978827803306e+04, 2.230040586776896e+04, 2.229102265385284e+04, + 2.228163863609070e+04, 2.227225381428844e+04, 2.226286818825189e+04, 2.225348175778681e+04, 2.224409452269886e+04, + 2.223470648279365e+04, 2.222531763787671e+04, 2.221592798775350e+04, 2.220653753222936e+04, 2.219714627110960e+04, + 2.218775420419943e+04, 2.217836133130399e+04, 2.216896765222835e+04, 2.215957316677748e+04, 2.215017787475631e+04, + 2.214078177596965e+04, 2.213138487022227e+04, 2.212198715731884e+04, 2.211258863706393e+04, 2.210318930926211e+04, + 2.209378917371781e+04, 2.208438823023538e+04, 2.207498647861912e+04, 2.206558391867324e+04, 2.205618055020189e+04, + 2.204677637300910e+04, 2.203737138689886e+04, 2.202796559167508e+04, 2.201855898714158e+04, 2.200915157310209e+04, + 2.199974334936031e+04, 2.199033431571981e+04, 2.198092447198409e+04, 2.197151381795661e+04, 2.196210235344071e+04 + }, + { + 2.333571260437436e+04, 2.332641343848122e+04, 2.331711348903825e+04, 2.330781275585994e+04, 2.329851123876068e+04, + 2.328920893755483e+04, 2.327990585205664e+04, 2.327060198208032e+04, 2.326129732743997e+04, 2.325199188794967e+04, + 2.324268566342337e+04, 2.323337865367499e+04, 2.322407085851836e+04, 2.321476227776725e+04, 2.320545291123534e+04, + 2.319614275873626e+04, 2.318683182008354e+04, 2.317752009509066e+04, 2.316820758357102e+04, 2.315889428533795e+04, + 2.314958020020470e+04, 2.314026532798446e+04, 2.313094966849034e+04, 2.312163322153536e+04, 2.311231598693250e+04, + 2.310299796449465e+04, 2.309367915403464e+04, 2.308435955536519e+04, 2.307503916829900e+04, 2.306571799264867e+04, + 2.305639602822672e+04, 2.304707327484559e+04, 2.303774973231769e+04, 2.302842540045531e+04, 2.301910027907070e+04, + 2.300977436797601e+04, 2.300044766698335e+04, 2.299112017590471e+04, 2.298179189455205e+04, 2.297246282273725e+04, + 2.296313296027208e+04, 2.295380230696829e+04, 2.294447086263751e+04, 2.293513862709134e+04, 2.292580560014127e+04, + 2.291647178159873e+04, 2.290713717127507e+04, 2.289780176898159e+04, 2.288846557452950e+04, 2.287912858772991e+04 + }, + { + 2.425021427659378e+04, 2.424098777593805e+04, 2.423176050906557e+04, 2.422253247579806e+04, 2.421330367595718e+04, + 2.420407410936458e+04, 2.419484377584177e+04, 2.418561267521024e+04, 2.417638080729138e+04, 2.416714817190654e+04, + 2.415791476887697e+04, 2.414868059802389e+04, 2.413944565916843e+04, 2.413020995213165e+04, 2.412097347673454e+04, + 2.411173623279804e+04, 2.410249822014300e+04, 2.409325943859020e+04, 2.408401988796039e+04, 2.407477956807420e+04, + 2.406553847875223e+04, 2.405629661981499e+04, 2.404705399108293e+04, 2.403781059237643e+04, 2.402856642351580e+04, + 2.401932148432129e+04, 2.401007577461306e+04, 2.400082929421122e+04, 2.399158204293581e+04, 2.398233402060681e+04, + 2.397308522704410e+04, 2.396383566206751e+04, 2.395458532549681e+04, 2.394533421715169e+04, 2.393608233685177e+04, + 2.392682968441661e+04, 2.391757625966568e+04, 2.390832206241842e+04, 2.389906709249416e+04, 2.388981134971217e+04, + 2.388055483389168e+04, 2.387129754485182e+04, 2.386203948241165e+04, 2.385278064639019e+04, 2.384352103660635e+04, + 2.383426065287902e+04, 2.382499949502695e+04, 2.381573756286890e+04, 2.380647485622352e+04, 2.379721137490938e+04 + }, + { + 2.516581860162409e+04, 2.515666383307756e+04, 2.514750831521358e+04, 2.513835204786084e+04, 2.512919503084798e+04, + 2.512003726400359e+04, 2.511087874715617e+04, 2.510171948013416e+04, 2.509255946276593e+04, 2.508339869487983e+04, + 2.507423717630408e+04, 2.506507490686689e+04, 2.505591188639637e+04, 2.504674811472057e+04, 2.503758359166751e+04, + 2.502841831706510e+04, 2.501925229074121e+04, 2.501008551252365e+04, 2.500091798224013e+04, 2.499174969971836e+04, + 2.498258066478591e+04, 2.497341087727034e+04, 2.496424033699913e+04, 2.495506904379967e+04, 2.494589699749934e+04, + 2.493672419792541e+04, 2.492755064490508e+04, 2.491837633826553e+04, 2.490920127783382e+04, 2.490002546343700e+04, + 2.489084889490202e+04, 2.488167157205576e+04, 2.487249349472505e+04, 2.486331466273668e+04, 2.485413507591731e+04, + 2.484495473409360e+04, 2.483577363709210e+04, 2.482659178473931e+04, 2.481740917686167e+04, 2.480822581328557e+04, + 2.479904169383731e+04, 2.478985681834310e+04, 2.478067118662915e+04, 2.477148479852155e+04, 2.476229765384635e+04, + 2.475310975242952e+04, 2.474392109409700e+04, 2.473473167867461e+04, 2.472554150598814e+04, 2.471635057586330e+04 + } +}; + +typedef TabulatedCO2Properties< TabulatedEnthalpyTraits > TabulatedEnthalpy; + + +// this class collects all the tabulated quantities in one convenient place +struct CO2Tables { + static const TabulatedEnthalpy tabulatedEnthalpy; + static const TabulatedDensity tabulatedDensity; +}; + +const TabulatedEnthalpy CO2Tables::tabulatedEnthalpy; +const TabulatedDensity CO2Tables::tabulatedDensity; + diff --git a/examples/biomineralization/material/components/biofilm.hh b/examples/biomineralization/material/components/biofilm.hh new file mode 100644 index 0000000000..b906b030dc --- /dev/null +++ b/examples/biomineralization/material/components/biofilm.hh @@ -0,0 +1,74 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ + +#ifndef DUMUX_MATERIAL_COMPONENTS_BIOFILM_HH +#define DUMUX_MATERIAL_COMPONENTS_BIOFILM_HH + +// ## The biofilm component (`biofilm.hh`) +// +// This file contains the __solid component class__ which defines the name, molar mass and density of biofilm +// +// [[content]] +// +// ### Include files +// [[codeblock]] +// including the base and the generic solid component +#include <dumux/material/components/base.hh> +#include <dumux/material/components/solid.hh> +// [[/codeblock]] + +// ### The biofilm component +// [[codeblock]] +namespace Dumux::Components { + +// In Biofilm, we define the properties of the solid component biofilm +template <class Scalar> +class Biofilm +: public Components::Base<Scalar, Biofilm<Scalar> > +, public Components::Solid<Scalar, Biofilm<Scalar> > +{ +public: + // the name + static std::string name() + { return "Biofilm"; } +// [[/codeblock]] + +// ### The biofilm component's properties +// [[codeblock]] + // The molar mass, which is not really defined for biofilm. Thus, we read it from params.input or use a default of 1. + // Based on a cell mass of 2.5e-16, the molar mass of cells would be 1.5e8 kg/mol, but biofilms are more than just cells and such high molar masses would lead to numerical problems. + static Scalar molarMass() + { + Scalar molarMass = getParam<Scalar>("BioCoefficients.BiofilmMolarMass", 1); + return molarMass; + } + + // The density, or rather the dry density (dry biomass/wet volume), most of biofilm is water. + // It is typically highly variable for different biofilms, thus we read it from params.input or use the default value of 10 kg/m^3 + static Scalar solidDensity(Scalar temperature) + { + Scalar rho = getParam<Scalar>("BioCoefficients.BiofilmDensity", 10); + return rho; + } +}; + +} // end namespace Dumux::Components +// [[/codeblock]] +// [[/content]] +#endif diff --git a/examples/biomineralization/material/components/suspendedbiomass.hh b/examples/biomineralization/material/components/suspendedbiomass.hh new file mode 100644 index 0000000000..359f79eebd --- /dev/null +++ b/examples/biomineralization/material/components/suspendedbiomass.hh @@ -0,0 +1,65 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ + +#ifndef DUMUX_MATERIAL_COMPONENTS_SUSPENDEDBIOMASS_HH +#define DUMUX_MATERIAL_COMPONENTS_SUSPENDEDBIOMASS_HH + +// ## The suspended biomass component (`suspendedbiomass.hh`) +// +// This file contains the __ component class__ which defines the name and molar mass of suspended biomass +// +// [[content]] +// +// ### Include files +// [[codeblock]] +// including the base component +#include <dumux/material/components/base.hh> +// [[/codeblock]] + +// ### The suspended biomass component +// [[codeblock]] +namespace Dumux::Components { + +// In SuspendedBiomass, we define the properties of the component suspended biomass +template <class Scalar> +class SuspendedBiomass +: public Components::Base<Scalar, SuspendedBiomass<Scalar> > +{ +public: + // the name + static std::string name() + { return "Suspended_Biomass"; } +// [[/codeblock]] + +// ### The suspended biomass component's properties +// [[codeblock]] + // The molar mass, which is not really defined for suspended biomass. Thus, we read it from params.input or use a default of 1. + // Based on a cell mass of 2.5e-16, the molar mass of cells would be 1.5e8 kg/mol, but such high molar masses would lead to numerical problems. + static Scalar molarMass() + { + Scalar molarMass = getParam<Scalar>("BioCoefficients.SuspendedBiomassMolarMass", 1); + return molarMass; + } +}; + + +} // end namespace Dumux::Components +// [[/codeblock]] +// [[/content]] +#endif diff --git a/examples/biomineralization/material/fluidsystems/CMakeLists.txt b/examples/biomineralization/material/fluidsystems/CMakeLists.txt new file mode 100644 index 0000000000..5b7ccac5a7 --- /dev/null +++ b/examples/biomineralization/material/fluidsystems/CMakeLists.txt @@ -0,0 +1,5 @@ +#install headers +install(FILES +biominsimplechemistry.hh +icpcomplexsalinitybrine.hh +DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/material/fluidsystems) diff --git a/examples/biomineralization/material/fluidsystems/biominsimplechemistry.hh b/examples/biomineralization/material/fluidsystems/biominsimplechemistry.hh new file mode 100644 index 0000000000..0937c55e4a --- /dev/null +++ b/examples/biomineralization/material/fluidsystems/biominsimplechemistry.hh @@ -0,0 +1,582 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ + +#ifndef DUMUX_BIOFLUID_SIMPLE_CHEM_SYSTEM_HH +#define DUMUX_BIOFLUID_SIMPLE_CHEM_SYSTEM_HH + +// ## The fluid system (`biominsimplechemistry.hh`) +// +// This file contains the __fluidsystem class__ which defines all functions needed to describe the fluids and their properties, +// which are needed to model biomineralization. +// +// [[content]] +// +// ### Include files +// [[details]] +// [[codeblock]] +#include <dumux/material/idealgas.hh> + +// we include the base fluid system +#include <dumux/material/fluidsystems/base.hh> +// we include the brine adapter adapting component indices to use the brine fluidsystem +#include "icpcomplexsalinitybrine.hh" + +// we include all necessary fluid components +#include <dumux/material/fluidstates/adapter.hh> +#include <dumux/material/components/co2.hh> +#include <dumux/material/components/h2o.hh> +#include <dumux/material/components/tabulatedcomponent.hh> +#include <dumux/material/components/co2tablereader.hh> +#include <dumux/material/components/sodiumion.hh> +#include <dumux/material/components/chlorideion.hh> +#include <dumux/material/components/calciumion.hh> +#include <dumux/material/components/urea.hh> +#include <dumux/material/components/o2.hh> +#include <dumux/material/components/glucose.hh> +#include <examples/biomineralization/material/components/suspendedbiomass.hh> + +// we include brine-co2 and h2o-co2 binary coefficients +#include <dumux/material/binarycoefficients/brine_co2.hh> +#include <dumux/material/binarycoefficients/h2o_o2.hh> +// [[/codeblock]] + +#include <dumux/material/fluidsystems/nullparametercache.hh> +#include <dumux/common/valgrind.hh> +#include <dumux/common/exceptions.hh> + +#include <assert.h> +// [[/details]] +// +// ### The fluidsystem class +// In the BioMinSimpleChemistryFluid fluid system, we define all functions needed to describe the fluids and their properties accounted for in our simulation. +// The simplified biogeochemistry biomineralization fluid system requires the CO2 tables and the H2OType as template parameters. +// We enter the namespace Dumux. All Dumux functions and classes are in a namespace Dumux, to make sure they don`t clash with symbols from other libraries you may want to use in conjunction with Dumux. +// [[codeblock]] +namespace Dumux::FluidSystems { + +template <class Scalar, + class CO2Table, + class H2OType = Components::TabulatedComponent<Components::H2O<Scalar>> > +class BioMinSimpleChemistryFluid +: public Base<Scalar, BioMinSimpleChemistryFluid<Scalar, CO2Table, H2OType> > +{ + using ThisType = BioMinSimpleChemistryFluid<Scalar, CO2Table, H2OType>; + using Base = Dumux::FluidSystems::Base<Scalar, ThisType>; + using IdealGas = Dumux::IdealGas<Scalar>; +// [[/codeblock]] +// +// #### Component and phase definitions +// With the following function we define what phases and components will be used by the fluid system and define the indices used to distinguish phases and components in the course of the simulation. +// [[codeblock]] +public: + // We use convenient declarations that we derive from the property system + typedef Components::CO2<Scalar, CO2Table> CO2; + using H2O = H2OType; + // export the underlying brine fluid system for the liquid phase, as brine is used as a "pseudo component" + using Brine = Dumux::FluidSystems::ICPComplexSalinityBrine<Scalar, H2OType>; + using Na = Components::SodiumIon<Scalar>; + using Cl = Components::ChlorideIon<Scalar>; + using Ca = Components::CalciumIon<Scalar>; + using Urea = Components::Urea<Scalar>; + using O2 = Components::O2<Scalar>; + using Glucose = Components::Glucose<Scalar>; + using SuspendedBiomass = Components::SuspendedBiomass<Scalar>; + + // We define the binary coefficents file, which accounts for the interactions of the main fluids in our setup, water/brine and CO2 + using Brine_CO2 = BinaryCoeff::Brine_CO2<Scalar, CO2Table, true>; + + // the type of parameter cache objects. this fluid system does not + // cache anything, so it uses Dumux::NullParameterCache + typedef Dumux::NullParameterCache ParameterCache; + + // We define phase-related indices and properties + static constexpr int numPhases = 2; // liquid and gas phases + static constexpr int wPhaseIdx = 0; // index of the liquid phase + static constexpr int nPhaseIdx = 1; // index of the gas phase + static constexpr int phase0Idx = wPhaseIdx; + static constexpr int phase1Idx = nPhaseIdx; + + // the phase names + static std::string phaseName(int phaseIdx) + { + static std::string name[] = { + "w", + "n" + }; + + assert(0 <= phaseIdx && phaseIdx < numPhases); + return name[phaseIdx]; + } + + // We define component-related indices and properties + static constexpr int numComponents = 9; // H2O, TotalC, Na, Cl, Ca,... + static constexpr int numSecComponents = 6; + + static constexpr int H2OIdx = 0; + static constexpr int BrineIdx = 0; + static constexpr int TCIdx = 1; + static constexpr int wCompIdx = BrineIdx; + static constexpr int nCompIdx = TCIdx; + static constexpr int comp0Idx = wCompIdx; + static constexpr int comp1Idx = nCompIdx; + + static constexpr int NaIdx = 2; + static constexpr int ClIdx = 3; + static constexpr int CaIdx = 4; + static constexpr int UreaIdx = 5; + static constexpr int O2Idx = 6; + static constexpr int GlucoseIdx = 7; + static constexpr int SuspendedBiomassIdx = 8; +// [[/codeblock]] +// [[exclude]] + + // We check whether a phase is liquid + static constexpr bool isLiquid(int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + + return phaseIdx != nPhaseIdx; + } + + // We return whether a phase is gaseous + static constexpr bool isGas(int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + return phaseIdx == nPhaseIdx; + } + + // We assume ideal mixtures + static constexpr bool isIdealMixture(int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + + return true; + } + + // We assume compressible fluid phases + static constexpr bool isCompressible(int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + + return true; + } + + // The component names + static constexpr std::string componentName(int compIdx) + { + + switch (compIdx) { + case BrineIdx: return H2O::name(); + case TCIdx: return "TotalC"; + case CaIdx: return Ca::name(); + case NaIdx: return Na::name(); + case ClIdx: return Cl::name(); + case SuspendedBiomassIdx: return SuspendedBiomass::name(); + case GlucoseIdx: return Glucose::name(); + case O2Idx: return O2::name(); + case UreaIdx: return Urea::name(); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); break; + }; + } + + // The component molar masses + static constexpr Scalar molarMass(int compIdx) + { + switch (compIdx) { + case H2OIdx: return H2O::molarMass(); + // actually, the molar mass of brine is only needed for diffusion + // but since chloride and sodium are accounted for seperately + // only the molar mass of water is returned. + case TCIdx: return CO2::molarMass(); + case CaIdx: return Ca::molarMass(); + case NaIdx: return Na::molarMass(); + case ClIdx: return Cl::molarMass(); + case SuspendedBiomassIdx: return SuspendedBiomass::molarMass(); + case GlucoseIdx: return Glucose::molarMass(); + case O2Idx: return O2::molarMass(); + case UreaIdx: return Urea::molarMass(); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); break; + }; + } +// [[/exclude]] +// +// #### The Brine Adapter +// With the brine adapter, we link water and the components sodium, chloride, and calcium to form brine, to be able to use the "brine.hh" fluidsystem expecting only water and a single salt. +// Here, we define that the components water, sodium, chloride, and calcium contribute to brine. +// The real work is done by the adapter "icpcomplexsalinitybrine.hh". +// [[codeblock]] +private: + struct BrineAdapterPolicy + { + using FluidSystem = Brine; + + static constexpr int phaseIdx(int brinePhaseIdx) { return wPhaseIdx; } + static constexpr int compIdx(int brineCompIdx) + { + switch (brineCompIdx) + { + assert(brineCompIdx == Brine::H2OIdx + || brineCompIdx == Brine::NaIdx + || brineCompIdx == Brine::ClIdx + || brineCompIdx == Brine::CaIdx + ); + case Brine::H2OIdx: return H2OIdx; + case Brine::NaIdx: return NaIdx; + case Brine::ClIdx: return ClIdx; + case Brine::CaIdx: return CaIdx; + default: return 0; // this will never be reached, only needed to suppress compiler warning + } + } + }; + + template<class FluidState> + using BrineAdapter = FluidStateAdapter<FluidState, BrineAdapterPolicy>; +// [[/codeblock]] + + // #### Initializing the fluid system + // [[codeblock]] +public: + static void init() + { + init(/*startTemp=*/275.15, /*endTemp=*/455.15, /*tempSteps=*/30, + /*startPressure=*/1e4, /*endPressure=*/99e6, /*pressureSteps=*/500); + } + static void init(Scalar startTemp, Scalar endTemp, int tempSteps, + Scalar startPressure, Scalar endPressure, int pressureSteps) + { + std::cout << "Initializing tables for the pure-water properties.\n"; + H2O::init(startTemp, endTemp, tempSteps, + startPressure, endPressure, pressureSteps); + } +// [[/codeblock]] + + // #### The Component-Phase Interactions + // In the following, we define the component-phase interactions such as // each component's fugacity coefficient in each phase + // and each component's and the phases' main components binary diffusion coefficient in the respective phase. + // [[codeblock]] + // The component fugacity coefficients + template <class FluidState> + static Scalar fugacityCoefficient(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx, + int compIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + assert(0 <= compIdx && compIdx < numComponents); + + if (phaseIdx == nPhaseIdx) + // use the fugacity coefficients of an ideal gas. the + // actual value of the fugacity is not relevant, as long + // as the relative fluid compositions are observed, + return 1.0; + + Scalar temperature = fluidState.temperature(phaseIdx); + Scalar pressure = fluidState.pressure(phaseIdx); + if (pressure<0) + { + typedef Dune::FieldVector<Scalar, numComponents> ComponentVector; + ComponentVector moleFractionsw; + ComponentVector massFractionsw; + + for (int compIdx = 0; compIdx<numComponents;++compIdx) + { + moleFractionsw[compIdx] = fluidState.moleFraction(wPhaseIdx,compIdx); + massFractionsw[compIdx] = fluidState.massFraction(wPhaseIdx,compIdx); + } + } + + assert(temperature > 0); + assert(pressure > 0); + + // calulate the equilibrium composition for the given + // temperature and pressure. + Scalar xgH2O, xlH2O; + Scalar xlCO2, xgCO2; + Scalar Xl_Sal = fluidState.massFraction(wPhaseIdx, NaIdx) //Salinity= XNa+XCl+XCa + + fluidState.massFraction(wPhaseIdx, ClIdx) + + fluidState.massFraction(wPhaseIdx, CaIdx); + Brine_CO2::calculateMoleFractions(temperature, + pressure, + Xl_Sal, + /*knownPhaseIdx=*/ -1, + xlCO2, + xgH2O); + + xlCO2 = std::max(0.0, std::min(1.0, xlCO2)); + xgH2O = std::max(0.0, std::min(1.0, xgH2O)); + xlH2O = 1.0 - xlCO2; + xgCO2 = 1.0 - xgH2O; + + // Only H2O, CO2, and O2 in the gas phase + if (compIdx == BrineIdx) { + Scalar phigH2O = 1.0; + return phigH2O * xgH2O / xlH2O; + } + else if (compIdx == TCIdx) + { + Scalar phigCO2 = 1.0; + return phigCO2 * xgCO2 / xlCO2; + } + else if (compIdx == O2Idx) + { + return Dumux::BinaryCoeff::H2O_O2::henry(temperature)/pressure; + } + // All other components are assumed not be present in the gas phase + else + { + return 1e-20; + } + } + + template <class FluidState> + static Scalar diffusionCoefficient(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx, + int compIdx) + { + DUNE_THROW(Dune::NotImplemented, "Diffusion coefficients"); + }; + + // The binary diffusion coefficients of the components and the phases main component + template <class FluidState> + static Scalar binaryDiffusionCoefficient(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx, + int compIIdx, + int compJIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + assert(0 <= compIIdx && compIIdx < numComponents); + assert(0 <= compJIdx && compJIdx < numComponents); + + Scalar temperature = fluidState.temperature(phaseIdx); + Scalar pressure = fluidState.pressure(phaseIdx); + + if (phaseIdx == wPhaseIdx) { + assert(compIIdx == H2OIdx); + Scalar result = 0.0; + if(compJIdx == TCIdx) + result = Brine_CO2::liquidDiffCoeff(temperature, pressure); + else if(compJIdx == O2Idx) + result = Dumux::BinaryCoeff::H2O_O2::liquidDiffCoeff(temperature, pressure); + else //all other components + result = 1.587e-9; //[m²/s] //J. Phys. D: Appl. Phys. 40 (2007) 2769-2776 //old Value from Anozie 1e-9 + + Valgrind::CheckDefined(result); + return result; + } + else { + assert(phaseIdx == nPhaseIdx); + assert(compIIdx == TCIdx); + Scalar result = 0.0; + if(compJIdx == H2OIdx) + result = Brine_CO2::gasDiffCoeff(temperature, pressure); + else if(compJIdx == O2Idx) + result = Dumux::BinaryCoeff::H2O_O2::gasDiffCoeff(temperature, pressure); + else //all other components + result = 0.0; + + Valgrind::CheckDefined(result); + return result; + } + }; + // [[/codeblock]] + + // #### The Fluid Properties + // In the following, all functions defining the phase properties are given: + // the density, viscosity, enthalpy, thermal conductivities, and heat capacities + // of each phase depending on temperature, pressure, and phase composition + // [[codeblock]] + // The phase density of the liquid phase is calculated accounting for the impact of solutes in the brine as well as the contribution of CO2. + // For the gas phase, a mixture of water and CO2 is considered, as solutes do not partition into the gas phase. + template <class FluidState> + static Scalar density(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + + const Scalar T = fluidState.temperature(phaseIdx); + + if (phaseIdx == wPhaseIdx) + { + const Scalar pl = fluidState.pressure(phaseIdx); + const Scalar xlCO2 = fluidState.moleFraction(wPhaseIdx, TCIdx); + const Scalar xlH2O = fluidState.moleFraction(wPhaseIdx, H2OIdx); + if(T < 273.15) { + DUNE_THROW(NumericalProblem, + "Liquid density for Brine and CO2 is only " + "defined above 273.15K (is" << T << ")"); + } + if(pl >= 2.5e8) { + DUNE_THROW(NumericalProblem, + "Liquid density for Brine and CO2 is only " + "defined below 250MPa (is" << pl << ")"); + } + + // calling the brine adapter for brine density + Scalar rho_brine = Brine::molarDensity(BrineAdapter<FluidState>(fluidState), Brine::liquidPhaseIdx) + *(H2O::molarMass()*fluidState.moleFraction(wPhaseIdx, H2OIdx) + + Na::molarMass()*fluidState.moleFraction(wPhaseIdx, NaIdx) + + Cl::molarMass()*fluidState.moleFraction(wPhaseIdx, ClIdx) + + Ca::molarMass()*fluidState.moleFraction(wPhaseIdx, CaIdx) + ); + // the density of pure water + Scalar rho_pure = H2O::liquidDensity(T, pl); + //we also use a private helper function to calculate the liquid density of the same amount of CO2 in pure water + Scalar rho_lCO2 = liquidDensityWaterCO2_(T, pl, xlH2O, xlCO2); + // calculating the density contribution of CO2 in pure water + Scalar contribCO2 = rho_lCO2 - rho_pure; + // assuming CO2 increases the density for brine by the same amount as for pure water + return rho_brine + contribCO2; + } + + else if (phaseIdx == nPhaseIdx) + return H2O::gasDensity(T, fluidState.partialPressure(nPhaseIdx, H2OIdx)) + + CO2::gasDensity(T, fluidState.partialPressure(nPhaseIdx, TCIdx)); + else + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + } + + // The phase molar density of the liquid phase is assumed to not change significantly from the molar density of the pure brine. + // For the gas phase, a mixture of water and CO2 is considered, as solutes do not partition into the gas phase. + using Base::molarDensity; + template <class FluidState> + static Scalar molarDensity(const FluidState& fluidState, int phaseIdx) + { + if (phaseIdx == wPhaseIdx) + return Brine::molarDensity(BrineAdapter<FluidState>(fluidState), Brine::liquidPhaseIdx); + else if (phaseIdx == nPhaseIdx) + return H2O::gasMolarDensity(fluidState.temperature(phaseIdx), + fluidState.partialPressure(phaseIdx, H2OIdx)) + + CO2::gasMolarDensity(fluidState.temperature(phaseIdx), + fluidState.partialPressure(phaseIdx, TCIdx)); + else + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + } + + // The phase viscosities are assumed to not change significantly from those of the pure brine for the liquid and pure CO2 for the gas phase + using Base::viscosity; + template <class FluidState> + static Scalar viscosity(const FluidState& fluidState, int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + + if (phaseIdx == wPhaseIdx) + return Brine::viscosity(BrineAdapter<FluidState>(fluidState), Brine::liquidPhaseIdx); + else if (phaseIdx == nPhaseIdx) + { + return CO2::gasViscosity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); + } + else + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + + } + // [[/codeblock]] + + // [[exclude]] + // non-isothermal phase properties + // The phase enthalpies are assumed to not change significantly from those of the pure brine for the liquid and pure CO2 for the gas phase + template <class FluidState> + static Scalar enthalpy(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + + Scalar temperature = fluidState.temperature(phaseIdx); + Scalar pressure = fluidState.pressure(phaseIdx); + + if (phaseIdx == wPhaseIdx) + { + return Brine::enthalpy(BrineAdapter<FluidState>(fluidState), Brine::liquidPhaseIdx); + } + else { + Scalar XCO2 = fluidState.massFraction(nPhaseIdx, TCIdx); + Scalar XBrine = fluidState.massFraction(nPhaseIdx, H2OIdx); + + Scalar result = 0; + result += XBrine * Brine::gasEnthalpy(temperature, pressure); + result += XCO2 * CO2::gasEnthalpy(temperature, pressure); + Valgrind::CheckDefined(result); + return result; + } + }; + + // The phase thermal conductivities are assumed to not change significantly from those of the pure brine for the liquid and pure CO2 for the gas phase + template <class FluidState> + static Scalar thermalConductivity(const FluidState& fluidState, int phaseIdx) + { + if (phaseIdx == wPhaseIdx) + return Brine::thermalConductivity(BrineAdapter<FluidState>(fluidState), Brine::liquidPhaseIdx); + else if (phaseIdx ==nPhaseIdx) + return CO2::gasThermalConductivity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); + + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + } + + // The phase heat capacitiy of the liquid phase is assumed to not change significantly from the heat capacitiy of the pure brine. + // For the gas phase, a mixture of water and CO2 is considered, as solutes do not partition into the gas phase. + template <class FluidState> + static Scalar heatCapacity(const FluidState &fluidState, int phaseIdx) + { + const Scalar T = fluidState.temperature(phaseIdx); + const Scalar p = fluidState.pressure(phaseIdx); + + if (phaseIdx == wPhaseIdx) + return Brine::heatCapacity(BrineAdapter<FluidState>(fluidState), Brine::liquidPhaseIdx); + + // We assume NaCl not to be present in the gas phase here + else if (phaseIdx ==nPhaseIdx) + return CO2::gasHeatCapacity(T, p)*fluidState.moleFraction(nPhaseIdx, TCIdx) + + H2O::gasHeatCapacity(T, p)*fluidState.moleFraction(nPhaseIdx, H2OIdx); + + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + } + + +private: + + //a private helper function to calculate the liquid density of the same amount of CO2 as we have in our brine in pure water + static Scalar liquidDensityWaterCO2_(Scalar temperature, + Scalar pl, + Scalar xlH2O, + Scalar xlCO2) + { + const Scalar M_CO2 = CO2::molarMass(); + const Scalar M_H2O = H2O::molarMass(); + + const Scalar tempC = temperature - 273.15; /* tempC : temperature in °C */ + const Scalar rho_pure = H2O::liquidDensity(temperature, pl); + xlH2O = 1.0 - xlCO2; // xlH2O is available, but in case of a pure gas phase + // the value of M_T for the virtual liquid phase can become very large + const Scalar M_T = M_H2O * xlH2O + M_CO2 * xlCO2; + const Scalar V_phi = + (37.51 + + tempC*(-9.585e-2 + + tempC*(8.74e-4 - + tempC*5.044e-7))) / 1.0e6; + return 1/ (xlCO2 * V_phi/M_T + M_H2O * xlH2O / (rho_pure * M_T)); + } +}; + +} // end namespace Dumux::FluidSystems +// [[/exclude]] +// [[/content]] +#endif diff --git a/examples/biomineralization/material/fluidsystems/icpcomplexsalinitybrine.hh b/examples/biomineralization/material/fluidsystems/icpcomplexsalinitybrine.hh new file mode 100644 index 0000000000..23df24daf5 --- /dev/null +++ b/examples/biomineralization/material/fluidsystems/icpcomplexsalinitybrine.hh @@ -0,0 +1,391 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ + +#ifndef DUMUX_ICP_COMPLEX_SALINITY_BRINE_FLUID_SYSTEM_HH +#define DUMUX_ICP_COMPLEX_SALINITY_BRINE_FLUID_SYSTEM_HH + +// ## The brine adapter (`icpcomplexsalinitybrine.hh`) +// +// This file contains the brineadapter class__ which defines +// how to adapt values for communication between +// the "full" fluidsystem accounting for 4 components influencing the brine properties +// and the "brine" fluidsystem assuming water and a single salt determining the brine properties. +// +// [[content]] +// +// ### Include files +// [[details]] includes +// we include all necessary components +#include <dumux/material/fluidsystems/base.hh> +#include <dumux/material/constants.hh> +#include <dumux/material/components/h2o.hh> +#include <dumux/material/components/sodiumion.hh> +#include <dumux/material/components/chlorideion.hh> +#include <dumux/material/components/calciumion.hh> +#include <dumux/material/components/tabulatedcomponent.hh> + +#include <dumux/common/exceptions.hh> + +#include <dumux/io/name.hh> +// [[/details]] +// +// ### The brine adapter class +// In ICPComplexSalinityBrine we make the transition from 3 components additional to water contributing to salinity to the single component that is assumed in the brine fluid system. +// We enter the namespace Dumux. All Dumux functions and classes are in a namespace Dumux, to make sure they don`t clash with symbols from other libraries you may want to use in conjunction with Dumux. +// [[codeblock]] +namespace Dumux::FluidSystems { + +template< class Scalar, class H2OType = Components::TabulatedComponent<Dumux::Components::H2O<Scalar>> > +class ICPComplexSalinityBrine : public Base< Scalar, ICPComplexSalinityBrine<Scalar, H2OType>> +{ + using ThisType = ICPComplexSalinityBrine<Scalar, H2OType>; + using Base = Dumux::FluidSystems::Base<Scalar, ThisType>; + +public: + //! export the involved components + using H2O = H2OType; + using Na = Components::SodiumIon<Scalar>; + using Cl = Components::ChlorideIon<Scalar>; + using Ca = Components::CalciumIon<Scalar>; + // [[/codeblock]] + // + // #### Component and phase definitions + // With the following function we define what phases and components will be used by the fluid system and define the indices used to distinguish phases and components in the course of the simulation. + // [[codeblock]] + // We use convenient declarations that we derive from the property system. + static constexpr int numPhases = 1; //!< Number of phases in the fluid system + static constexpr int numComponents = 4; //!< Number of components in the fluid system (H2O, Na, Cl, Ca) + + static constexpr int phase0Idx = 0; //!< Index of the first (and only) phase + static constexpr int liquidPhaseIdx = phase0Idx; //!< The one considered phase is liquid + + static constexpr int H2OIdx = 0; //!< index of the water component + static constexpr int NaIdx = 1; //!< index of the Na component + static constexpr int ClIdx = 2; //!< index of the Cl component + static constexpr int CaIdx = 3; //!< index of the Ca component + static constexpr int comp0Idx = H2OIdx; //!< index of the first component + static constexpr int comp1Idx = NaIdx; //!< index of the second component + static constexpr int comp2Idx = ClIdx; //!< index of the third component + static constexpr int comp3Idx = CaIdx; //!< index of the fourth component + + // the fluid phase index + static std::string phaseName(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return IOName::liquidPhase(); + } + + // the miscibility + static constexpr bool isMiscible() + { + return false; + } + + // we do not have a gas phase + static constexpr bool isGas(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return false; + } + + // We need a ideal mixture + static constexpr bool isIdealMixture(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return true; + } + + // phase compressibility + static constexpr bool isCompressible(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return H2O::liquidIsCompressible(); + } + + // no gas, thus no ideal gas + static constexpr bool isIdealGas(int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + return false; /*we're a liquid!*/ + } +// [[/codeblock]] +// [[exclude]] + // The component names + static constexpr std::string componentName(int compIdx) + { + switch (compIdx) + { + case H2OIdx: return H2O::name(); + case CaIdx: return Ca::name(); + case NaIdx: return Na::name(); + case ClIdx: return Cl::name(); + }; + DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + + // The component molar masses + static constexpr Scalar molarMass(int compIdx) + { + switch (compIdx) + { + case H2OIdx: return H2O::molarMass(); + case CaIdx: return Ca::molarMass(); + case NaIdx: return Na::molarMass(); + case ClIdx: return Cl::molarMass(); + }; + DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + + //initializing + static void init() + { + init(/*tempMin=*/273.15, + /*tempMax=*/623.15, + /*numTemp=*/100, + /*pMin=*/-10., + /*pMax=*/20e6, + /*numP=*/200); + } + static void init(Scalar tempMin, Scalar tempMax, unsigned nTemp, + Scalar pressMin, Scalar pressMax, unsigned nPress) + { + + if (H2O::isTabulated) + { + std::cout << "Initializing tables for the H2O fluid properties (" + << nTemp*nPress + << " entries).\n"; + + H2O::init(tempMin, tempMax, nTemp, pressMin, pressMax, nPress); + } + } +// [[/exclude]] + // + // #### The Component-Phase Interactions + // In the following, we define the component-phase interactions such as // each component's fugacity coefficient in brine + // and each component's binary diffusion coefficient with water in brine + // [[codeblock]] + // The component fugacity coefficients + template <class FluidState> + static Scalar fugacityCoefficient(const FluidState &fluidState, + int phaseIdx, + int compIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + assert(0 <= compIdx && compIdx < numComponents); + + if (phaseIdx == compIdx) + // We could calculate the real fugacity coefficient of + // the component in the fluid. Probably that's not worth + // the effort, since the fugacity coefficient of the other + // component is infinite anyway... + return 1.0; + return std::numeric_limits<Scalar>::infinity(); + } + + // The binary diffusion coefficients of the components and the phases main component + template <class FluidState> + static Scalar binaryDiffusionCoefficient(const FluidState& fluidState, + int phaseIdx, + int compIIdx, + int compJIdx) + { + if (phaseIdx == liquidPhaseIdx) + { + if (compIIdx > compJIdx) + { + using std::swap; + swap(compIIdx, compJIdx); + } + if (compJIdx == NaIdx || compJIdx == ClIdx || compJIdx == CaIdx) + return 1.587e-9; //[m²/s] //J. Phys. D: Appl. Phys. 40 (2007) 2769-2776 + else + DUNE_THROW(Dune::NotImplemented, "Binary diffusion coefficient of components " + << compIIdx << " and " << compJIdx + << " in phase " << phaseIdx); + } + + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index: " << phaseIdx); + } + // [[/codeblock]] + // + // #### The Fluid (Brine) Properties + // In the following, all functions defining the phase properties are given: + // the density, viscosity, enthalpy, thermal conductivities, and heat capacities + // of each phase depending on temperature, pressure, and phase composition + // [[codeblock]] + // The phase density + template <class FluidState> + static Scalar density(const FluidState& fluidState, int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + const Scalar temperature = fluidState.temperature(phaseIdx); + const Scalar pressure = fluidState.pressure(phaseIdx); + const Scalar xNaCl = fluidState.massFraction(phaseIdx, NaIdx) + + fluidState.massFraction(phaseIdx, ClIdx) + + fluidState.massFraction(phaseIdx, CaIdx); + + using std::max; + const Scalar TempC = temperature - 273.15; + const Scalar pMPa = pressure/1.0E6; + const Scalar salinity = max(0.0, xNaCl); + + const Scalar rhow = H2O::liquidDensity(temperature, pressure); + const Scalar density = rhow + 1000*salinity*(0.668 + + 0.44*salinity + + 1.0E-6*(300*pMPa - + 2400*pMPa*salinity + + TempC*(80.0 + + 3*TempC - + 3300*salinity - + 13*pMPa + + 47*pMPa*salinity))); + assert(density > 0.0); + return density; + } + + + + // The phase viscosity + template <class FluidState> + static Scalar viscosity(const FluidState& fluidState, int phaseIdx = liquidPhaseIdx) + { + assert(phaseIdx == liquidPhaseIdx); + const Scalar temperature = fluidState.temperature(phaseIdx); + const Scalar xNaCl = fluidState.massFraction(phaseIdx, NaIdx) + + fluidState.massFraction(phaseIdx, ClIdx) + + fluidState.massFraction(phaseIdx, CaIdx); + + using std::pow; + using std::exp; + using std::max; + const Scalar T = max(temperature, 275.0); + const Scalar salinity = max(0.0, xNaCl); + + const Scalar T_C = T - 273.15; + const Scalar A = ((0.42*pow((pow(salinity, 0.8)-0.17), 2)) + 0.045)*pow(T_C, 0.8); + const Scalar mu_brine = 0.1 + (0.333*salinity) + (1.65+(91.9*salinity*salinity*salinity))*exp(-A); // [cP] + assert(mu_brine > 0.0); + return mu_brine/1000.0; // [Pa·s] + } +// [[/codeblock]] +// [[exclude]] + // The vapor pressure + template <class FluidState> + static Scalar vaporPressure(const FluidState& fluidState, int compIdx) + { + if (compIdx == H2OIdx) + { + // simplified version of Eq 2.29 in Vishal Jambhekar's Promo + const Scalar temperature = fluidState.temperature(H2OIdx); + return H2O::vaporPressure(temperature)/fluidState.massFraction(phase0Idx, H2OIdx); + } + else if (compIdx == NaIdx) + DUNE_THROW(Dune::NotImplemented, "Na::vaporPressure(t)"); + else if (compIdx == ClIdx) + DUNE_THROW(Dune::NotImplemented, "Cl::vaporPressure(t)"); + else if (compIdx == CaIdx) + DUNE_THROW(Dune::NotImplemented, "Ca::vaporPressure(t)"); + else + DUNE_THROW(Dune::NotImplemented, "Invalid component index " << compIdx); + } + + // The phase enthalpies + template <class FluidState> + static Scalar enthalpy(const FluidState& fluidState, int phaseIdx) + { + /*Numerical coefficients from PALLISER*/ + static constexpr Scalar f[] = { 2.63500E-1, 7.48368E-6, 1.44611E-6, -3.80860E-10 }; + + /*Numerical coefficients from MICHAELIDES for the enthalpy of brine*/ + static constexpr Scalar a[4][3] = { { +9633.6, -4080.0, +286.49 }, + { +166.58, +68.577, -4.6856 }, + { -0.90963, -0.36524, +0.249667E-1 }, + { +0.17965E-2, +0.71924E-3, -0.4900E-4 } }; + + const Scalar p = fluidState.pressure(phaseIdx); + const Scalar T = fluidState.temperature(phaseIdx); + const Scalar theta = T - 273.15; + const Scalar salSat = f[0] + f[1]*theta + f[2]*theta*theta + f[3]*theta*theta*theta; + + /*Regularization*/ + using std::min; + using std::max; + const Scalar xNaCl = fluidState.massFraction(phaseIdx, NaIdx) + + fluidState.massFraction(phaseIdx, ClIdx) + + fluidState.massFraction(phaseIdx, CaIdx); + const Scalar salinity = min(max(xNaCl,0.0), salSat); + + const Scalar hw = H2O::liquidEnthalpy(T, p)/1E3; /* kJ/kg */ + + /*DAUBERT and DANNER*/ + const Scalar h_NaCl = (3.6710E4*T + 0.5*(6.2770E1)*T*T - ((6.6670E-2)/3)*T*T*T + + ((2.8000E-5)/4)*(T*T*T*T))/(58.44E3)- 2.045698e+02; /* U [kJ/kg] */ + + const Scalar m = (1E3/58.44)*(salinity/(1-salinity)); + + using std::pow; + Scalar d_h = 0; + for (int i = 0; i<=3; i++) + for (int j=0; j<=2; j++) + d_h = d_h + a[i][j] * pow(theta, i) * pow(m, j); + + /* heat of dissolution for halite according to Michaelides 1971 */ + const Scalar delta_h = (4.184/(1E3 + (58.44 * m)))*d_h; + + /* Enthalpy of brine without any dissolved gas */ + const Scalar h_ls1 =(1-salinity)*hw + salinity*h_NaCl + salinity*delta_h; /* kJ/kg */ + return h_ls1*1E3; /*J/kg*/ + } + // The molar density + template <class FluidState> + static Scalar molarDensity(const FluidState& fluidState, int phaseIdx = liquidPhaseIdx) + { + return density(fluidState, phaseIdx)/fluidState.averageMolarMass(phaseIdx); + } + + template <class FluidState> + static Scalar diffusionCoefficient(const FluidState& fluidState, int phaseIdx, int compIdx) + { + DUNE_THROW(Dune::NotImplemented, "FluidSystems::ICPComplexSalinityBrine::diffusionCoefficient()"); + } + + // The thermal conductivity + template <class FluidState> + static Scalar thermalConductivity(const FluidState& fluidState, int phaseIdx) + { + if (phaseIdx == liquidPhaseIdx) + return H2O::liquidThermalConductivity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index: " << phaseIdx); + } + + // The phase heat capacity + template <class FluidState> + static Scalar heatCapacity(const FluidState &fluidState, int phaseIdx) + { + if (phaseIdx == liquidPhaseIdx) + return H2O::liquidHeatCapacity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + } +}; + +} // end namespace Dumux::FluidSystems +// [[/exclude]] +// [[/content]] +#endif diff --git a/examples/biomineralization/material/solidsystems/biominsolids.hh b/examples/biomineralization/material/solidsystems/biominsolids.hh new file mode 100644 index 0000000000..852ca636dc --- /dev/null +++ b/examples/biomineralization/material/solidsystems/biominsolids.hh @@ -0,0 +1,197 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ + +#ifndef DUMUX_SOLIDSYSTEMS_MICP_SOLID_PHASE_HH +#define DUMUX_SOLIDSYSTEMS_MICP_SOLID_PHASE_HH + +// ## The solid system (`biominsolids.hh`) +// +// This file contains the __solidystem class__ which defines all functions needed to describe the solid and their properties, +// which are needed to model biomineralization. +// +// [[content]] +// +// ### Include files +// [[codeblock]] +#include <string> +#include <dune/common/exceptions.hh> + +// we include all necessary solid components +#include <examples/biomineralization/material/components/biofilm.hh> +#include <dumux/material/components/calcite.hh> +#include <dumux/material/components/granite.hh> +// [[/codeblock]] + +// ### The solidsystem class +// In the BioMinSolidPhase solid system, we define all functions needed to describe the solids and their properties accounted for in our simulation. +// We enter the namespace Dumux. All Dumux functions and classes are in a namespace Dumux, to make sure they don`t clash with symbols from other libraries you may want to use in conjunction with Dumux. +// [[codeblock]] +namespace Dumux::SolidSystems { + +template <class Scalar> +class BioMinSolidPhase +{ +public: +// [[/codeblock]] + + // #### Component definitions + // With the following function we define what solid components will be used by the solid system and define the indices used to distinguish solid components in the course of the simulation. + // [[codeblock]] + // We use convenient declarations that we derive from the property system. + using Biofilm = Components::Biofilm<Scalar>; + using Calcite = Components::Calcite<Scalar>; + using Granite = Components::Granite<Scalar>; + + /**************************************** + * Solid phase related static parameters + ****************************************/ + static constexpr int numComponents = 3; + static constexpr int numInertComponents = 1; + static constexpr int BiofilmIdx = 0; + static constexpr int CalciteIdx = 1; + static constexpr int GraniteIdx = 2; + + // The component names + const static std::string componentName(int compIdx) + { + switch (compIdx) + { + case BiofilmIdx: return Biofilm::name(); + case CalciteIdx: return Calcite::name(); + case GraniteIdx: return Granite::name(); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + } + + // The solid system's name + static std::string name() + { return "BiomineralizationMinSolidPhase"; } + + // We assume incompressible solids + static constexpr bool isCompressible(int compIdx) + { return false; } + + // we have one inert component, the others may change + static constexpr bool isInert() + { return (numComponents == numInertComponents); } + // [[/codeblock]] + + // #### Component properties + // This simply forwards the component properties (name, molar mass, density). + // [[codeblock]] + // The component molar masses + static Scalar molarMass(int compIdx) + { + switch (compIdx) + { + case BiofilmIdx: return Biofilm::molarMass(); + case CalciteIdx: return Calcite::molarMass(); + case GraniteIdx: return Granite::molarMass(); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + } + + // The component densities + template <class SolidState> + static Scalar density(const SolidState& solidState, const int compIdx) + { + switch (compIdx) + { + case BiofilmIdx: return Biofilm::solidDensity(solidState.temperature()); + case CalciteIdx: return Calcite::solidDensity(solidState.temperature()); + case GraniteIdx: return Granite::solidDensity(solidState.temperature()); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + } + + // The component molar densities + template <class SolidState> + static Scalar molarDensity(const SolidState& solidState, const int compIdx) + { + switch (compIdx) + { + case BiofilmIdx: return Biofilm::solidDensity(solidState.temperature())/Biofilm::molarMass(); + case CalciteIdx: return Calcite::solidDensity(solidState.temperature())/Calcite::molarMass(); + case GraniteIdx: return Granite::solidDensity(solidState.temperature())/Calcite::molarMass(); + default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + } + // [[/codeblock]] + + // #### Averaged solid properties + // The overall solid properties are calculated by a volume-weigthed average of the pure component's properties. +// [[codeblock]] + // The average density + template <class SolidState> + static Scalar density(const SolidState& solidState) + { + const Scalar rho1 = Biofilm::solidDensity(solidState.temperature()); + const Scalar rho2 = Calcite::solidDensity(solidState.temperature()); + const Scalar rho3 = Granite::solidDensity(solidState.temperature()); + const Scalar volFrac1 = solidState.volumeFraction(BiofilmIdx); + const Scalar volFrac2 = solidState.volumeFraction(CalciteIdx); + const Scalar volFrac3 = solidState.volumeFraction(GraniteIdx); + + return (rho1*volFrac1+ + rho2*volFrac2+ + rho3*volFrac3) + /(volFrac1+volFrac2+volFrac3); + } +// [[/codeblock]] +// [[exclude]] + // The average thermal conductivity + template <class SolidState> + static Scalar thermalConductivity(const SolidState &solidState) + { + const Scalar lambda1 = Biofilm::solidThermalConductivity(solidState.temperature()); + const Scalar lambda2 = Calcite::solidThermalConductivity(solidState.temperature()); + const Scalar lambda3 = Granite::solidThermalConductivity(solidState.temperature()); + const Scalar volFrac1 = solidState.volumeFraction(BiofilmIdx); + const Scalar volFrac2 = solidState.volumeFraction(CalciteIdx); + const Scalar volFrac3 = solidState.volumeFraction(GraniteIdx); + + return (lambda1*volFrac1+ + lambda2*volFrac2+ + lambda3*volFrac3) + /(volFrac1+volFrac2+volFrac3); + } + + // The average heat capacity + template <class SolidState> + static Scalar heatCapacity(const SolidState &solidState) + { + const Scalar c1 = Biofilm::solidHeatCapacity(solidState.temperature()); + const Scalar c2 = Calcite::solidHeatCapacity(solidState.temperature()); + const Scalar c3 = Granite::solidHeatCapacity(solidState.temperature()); + const Scalar volFrac1 = solidState.volumeFraction(BiofilmIdx); + const Scalar volFrac2 = solidState.volumeFraction(CalciteIdx); + const Scalar volFrac3 = solidState.volumeFraction(GraniteIdx); + + return (c1*volFrac1+ + c2*volFrac2+ + c3*volFrac3) + /(volFrac1+volFrac2+volFrac3); + } + +}; + +} // end namespace Dumux::SolidSystems +// [[/exclude]] +// [[/content]] +#endif diff --git a/examples/biomineralization/params.input b/examples/biomineralization/params.input new file mode 100644 index 0000000000..9ec5f23397 --- /dev/null +++ b/examples/biomineralization/params.input @@ -0,0 +1,63 @@ +[Problem] +Name = biomineralization # +Temperature = 298.15 # [K] 25°C + +[Initial] +DensityW = 1087 # [kg/m³] Density of the mixture +Pressure = 1e5 # [Pa] +XwTC = 2.3864e-7 # [mol/mol] equilibrium with atmospheric CO2 under atmospheric pressure +XwNa = 0.0 # [mol/mol] +XwCl = 0.0 # [mol/mol] +XwCa = 0.0 # [mol/mol] +XwUrea = 0.0 # [mol/mol] +XwTNH = 3.341641e-3 # [mol/mol] +XwO2 = 4.4686e-6 # [mol/mol] +XwSubstrate = 2.97638e-4 # [mol/mol] +XwSuspendedBiomass = 0.0 # [mol/mol] +Biofilm = 0.0 # [-] +Calcite = 0.0 # [-] +XwNaCorr = 2.9466e-6 # [mol/mol] NaCorr to get the pH to 6.2 calculated as molefraction +XwClCorr = 0.0 # [mol/mol] + +[Injection] +FlowRate = 1.716666666667e-7 # [m³/s] The injected flow rate, see Hommel et al. 2015 =10.3/60/1e6 # = [ml/min] /[s/min] /[ml/m³] +MassFracTC = 5.8e-7 # [kg/kg] equilibrium with atmospheric CO2 under atmospheric pressure +ConcentrationNa = 0.0 # [kg/m³] NaCl injected +ConcentrationCa = 13.530742 # [kg/m³] computed from 49 g/l CaCl2*2H2O (molar mass = 147.68g/mol --> 0.33molCa/l, equimolar with urea (20g/l and 60g/mol)) +ConcentrationUrea = 20 # [kg/m³] +ConcentrationTNH = 3.183840574 # [kg/m³] computed from 10 g/l NH4Cl +ConcentrationO2 = 0.008 # [kg/m³] +ConcentrationSubstrate = 3 # [kg/m³] +ConcentrationSuspendedBiomass = 0.0665 # [kg/m³] 5.6e7 cfu/ml (40e8cfu/ml~1g/l) cfu = colony forming unit = approximately equal to viable cells +ConcentrationNaCorr= 0.00379 # [kg/m³] NaCorr to get the pH to 6.2 +NumInjections = 212 # [-] The number of injections, used to check, whether the matching injection file specified + +[TimeLoop] +DtInitial = 1 # [s] +TEnd = 100000 # [s] for the entire experiment setup described in Hommel et a. 2015 use TEnd = 3203460 # +MaxTimeStepSize = 500 # [s] limiting the time step size speeds up the simulation, avoiding failed Newton iterations + +[Grid] +UpperRight = 0.7112 # [m] upper right corner coordinates, the actual experiment was 0.61m long, extended the domain to reduce BC effects +Cells = 56 # [-] number of cells in x,y-direction + +[SpatialParams] +ReferencePorosity = 0.4 # [-] +ReferencePermeability = 2e-10 # [m^2] + +[BioCoefficients] +Ca1 = 8.3753e-8 # [1/s] fitted parameter, see Hommel et al. 2015 +Ca2 = 8.5114e-7 # [1/s] fitted parameter, see Hommel et al. 2015 +Cd1 = 2.894e-8 # [1/s] Ebigbo et al. 2010 +Dc0 = 3.183e-7 # [1/s] Taylor and Jaffe 1990 +Kmue = 4.1667e-5 # [1/s] Connolly et al. 2013 +F = 0.5 # [-] Mateles 1971 +Ke = 2e-5 # [kg/m³] Hao et al. 1983 +Ks = 7.99e-4 # [kg/m³] Taylor and Jaffe 1990 +Yield = 0.5 # [-] Seto and Alexander 1985 +BiofilmDensity = 6.9 # [kg/m³] fittet parameter, see Hommel et al. 2015 + +[UreolysisCoefficients] +Kub = 3.81e-4 # [kg_urease/kg_bio] fitted parameter, see Hommel et al. 2015 +Kurease = 706.6667 # [mol_urea/(kg_urease s)] Lauchnor et al. 2014 +Ku = 0.355 # [mol/kgH2O] Lauchnor et al. 2014 diff --git a/examples/biomineralization/problem.hh b/examples/biomineralization/problem.hh new file mode 100644 index 0000000000..701336e782 --- /dev/null +++ b/examples/biomineralization/problem.hh @@ -0,0 +1,590 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +#ifndef DUMUX_MICP_COLUMN_SIMPLE_CHEM_PROBLEM_HH +#define DUMUX_MICP_COLUMN_SIMPLE_CHEM_PROBLEM_HH + +// ## Initial and boundary conditions (`problem.hh`) +// +// This file contains the __problem class__ which defines the initial and boundary +// conditions for the biominearalization example. +// +// [[content]] +// +// ### Include files +// [[codeblock]] +// This header contains the PorousMediumFlowProblem class +#include <dumux/porousmediumflow/problem.hh> +#include <dumux/common/properties.hh> // GetPropType +#include <dumux/material/components/ammonia.hh> +#include <dumux/discretization/evalgradients.hh> +#include <dumux/io/container.hh> +#include <algorithm> // for std::transform +// [[/codeblock]] + +// ### The problem class +// The problem class defines the boundary and initial conditions. +// As this is a biomineralization problem in porous media, we inherit from the porous-media-flow problem + +// [[codeblock]] +namespace Dumux { + +template <class TypeTag> +class MICPColumnProblemSimpleChemistry : public PorousMediumFlowProblem<TypeTag> +{ + using ParentType = PorousMediumFlowProblem<TypeTag>; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using NH3 = Components::Ammonia<Scalar>; // for molar mass of Ammonia + using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>; + using SolidSystem = GetPropType<TypeTag, Properties::SolidSystem>; + using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; + using FluxVariables = GetPropType<TypeTag, Properties::FluxVariables>; + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + + // We define some indices for convenience to be used later when defining the initial and boundary conditions + enum { + numComponents = FluidSystem::numComponents, + + pressureIdx = Indices::pressureIdx, + switchIdx = Indices::switchIdx, //Saturation + xwNaIdx = FluidSystem::NaIdx, + xwClIdx = FluidSystem::ClIdx, + xwCaIdx = FluidSystem::CaIdx, + xwUreaIdx = FluidSystem::UreaIdx, + xwO2Idx = FluidSystem::O2Idx, + xwBiosubIdx = FluidSystem::GlucoseIdx, + xwSuspendedBiomassIdx = FluidSystem::SuspendedBiomassIdx, + phiBiofilmIdx = numComponents, + phiCalciteIdx = numComponents + 1, + + //Indices of the components + wCompIdx = FluidSystem::wCompIdx, + nCompIdx = FluidSystem::nCompIdx, + NaIdx = FluidSystem::NaIdx, + ClIdx = FluidSystem::ClIdx, + CaIdx = FluidSystem::CaIdx, + UreaIdx = FluidSystem::UreaIdx, + O2Idx = FluidSystem::O2Idx, + BiosubIdx = FluidSystem::GlucoseIdx, + SuspendedBiomassIdx = FluidSystem::SuspendedBiomassIdx, + + wPhaseIdx = FluidSystem::wPhaseIdx, + conti0EqIdx = Indices::conti0EqIdx, + + // Phase State + wPhaseOnly = Indices::firstPhaseOnly, + bothPhases = Indices::bothPhases + }; + + using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; + using NumEqVector = GetPropType<TypeTag, Properties::NumEqVector>; + using BoundaryTypes = GetPropType<TypeTag, Properties::BoundaryTypes>; + using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView; + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Element = typename GridView::template Codim<0>::Entity; + using FVElementGeometry = typename GridGeometry::LocalView; + using SubControlVolume = typename GridGeometry::SubControlVolume; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + static constexpr int dim = GridView::dimension; +// [[/codeblock]] +// +// We define an enum class to distinguish between different injection processes. +// We will use these later in the definition of the Neumann boundary conditions. + enum class InjectionProcess : int + { + noInjection = -99, + noFlow = -9, + rinse = -1, + resuscitation = 3, + inoculation = 2, + mineralization = 1 + }; +// +// ### Reading of parameters specified in the params.input file +// [[details]] parameters +// [[codeblock]] +public: + // This is the constructor of our problem class. + MICPColumnProblemSimpleChemistry(std::shared_ptr<const GridGeometry> gridGeometry) + : ParentType(gridGeometry) + { + // We read the parameters from the params.input file. + name_ = getParam<std::string>("Problem.Name"); + temperature_ = getParam<Scalar>("Problem.Temperature"); + + // biomass parameters + ca1_ = getParam<Scalar>("BioCoefficients.Ca1"); + ca2_ = getParam<Scalar>("BioCoefficients.Ca2"); + cd1_ = getParam<Scalar>("BioCoefficients.Cd1"); + dc0_ = getParam<Scalar>("BioCoefficients.Dc0"); + kmue_ = getParam<Scalar>("BioCoefficients.Kmue"); + f_ = getParam<Scalar>("BioCoefficients.F"); + ke_ = getParam<Scalar>("BioCoefficients.Ke"); + ks_ = getParam<Scalar>("BioCoefficients.Ks"); + yield_ = getParam<Scalar>("BioCoefficients.Yield"); + + // ureolysis kinetic parameters + kub_ = getParam<Scalar>("UreolysisCoefficients.Kub"); + kurease_ = getParam<Scalar>("UreolysisCoefficients.Kurease"); + ku_ = getParam<Scalar>("UreolysisCoefficients.Ku"); + + // initial values + densityW_ = getParam<Scalar>("Initial.DensityW"); + initPressure_ = getParam<Scalar>("Initial.Pressure"); + + initxwTC_ = getParam<Scalar>("Initial.XwTC"); + initxwNa_ = getParam<Scalar>("Initial.XwNa"); + initxwCl_ = getParam<Scalar>("Initial.XwCl"); + initxwCa_ = getParam<Scalar>("Initial.XwCa"); + initxwUrea_ = getParam<Scalar>("Initial.XwUrea"); + initxwTNH_ = getParam<Scalar>("Initial.XwTNH"); + initxwO2_ = getParam<Scalar>("Initial.XwO2"); + initxwBiosub_ = getParam<Scalar>("Initial.XwSubstrate"); + initxwBiosusp_ = getParam<Scalar>("Initial.XwSuspendedBiomass"); + initCalcite_ = getParam<Scalar>("Initial.Calcite"); + initBiofilm_ = getParam<Scalar>("Initial.Biofilm"); + + xwNaCorr_ = getParam<Scalar>("Initial.XwNaCorr"); + xwClCorr_ = getParam<Scalar>("Initial.XwClCorr"); + + // injection values + injQ_ = getParam<Scalar>("Injection.FlowRate"); + + injTC_ = getParam<Scalar>("Injection.MassFracTC"); + injNa_ = getParam<Scalar>("Injection.ConcentrationNa"); + injCa_ = getParam<Scalar>("Injection.ConcentrationCa"); + injUrea_ = getParam<Scalar>("Injection.ConcentrationUrea"); + injTNH_ = getParam<Scalar>("Injection.ConcentrationTNH"); + injO2_ = getParam<Scalar>("Injection.ConcentrationO2"); + injSub_ = getParam<Scalar>("Injection.ConcentrationSubstrate"); + injBiosusp_= getParam<Scalar>("Injection.ConcentrationSuspendedBiomass"); + injNaCorr_ = getParam<Scalar>("Injection.ConcentrationNaCorr"); + // [[/codeblock]] + // [[/details]] + // + // ### Reading of the temporal sequence of the different types of injection + // Here, the number of injections and the corresponding parameters are defined based on what is specified in the input files. + // [[codeblock]] + // We get the number of injections and the injection data file name from params.input + numInjections_ = getParam<int>("Injection.NumInjections"); + + // We resize the permeability vector contaning the permeabilities for the additional output + permeability_.resize(gridGeometry->numDofs()); + + // We read from the injection data file which injection type we have in each episode. + // We will use this in the Neumann boundary condition to set time dependend, changing boundary conditions. + // We do this similarly to the episode ends in the main file. + const auto injType = readFileToContainer<std::vector<int>>("injection_type.dat"); + // translate integer to InjectionProcess type + std::transform(injType.begin(), injType.end(), std::back_inserter(injectionType_), + [](int n){ return static_cast<InjectionProcess>(n); }); + + + // [[/codeblock]] + + // We check the injection data against the number of injections specified in the parameter file + // and print an error message if the test fails + // [[codeblock]] + if (injectionType_.size() != numInjections_) + DUNE_THROW(Dune::IOError, "numInjections from the parameterfile and the number of injection types " + << "specified in the injection data file do not match!\n" + << "numInjections from parameter file: " << numInjections_ << "\n" + << "numInjTypes from injection data file: "<< injectionType_.size()); + + // Initialize the fluidsystem + FluidSystem::init(/*startTemp=*/temperature_ -5.0, /*endTemp=*/temperature_ +5.0, /*tempSteps=*/5, + /*startPressure=*/1e4, /*endPressure=*/1e6, /*pressureSteps=*/500); + } + // [[/codeblock]] + + // In the follwing, functions to set the time, time step size and the index of the episode + // are declared which are used the time loop in main.cc + // [[codeblock]] + void setTime(const Scalar t) + { time_ = t; } + + // We need the time step size to regularize the reactive source terms. + void setTimeStepSize(const Scalar dt) + { timeStepSize_ = dt; } + + // We need the episode index to choose the right Neumann boundary condition for each episode based on the injection data. + void setEpisodeIdx(const Scalar epIdx) + { episodeIdx_ = epIdx; } + // [[/codeblock]] + + // Here, functions to return the injectionType, the name of the problem and the temperature + // are defined + // [[codeblock]] + int injectionType(int episodeIdx) const + { return injectionType_[episodeIdx]; } + + // Get the problem name. It is used as a prefix for files generated by the simulation. + const std::string& name() const + { return name_; } + + // Return the temperature + Scalar temperature() const + { return temperature_; } + // [[/codeblock]] + + // #### Boundary conditions + // With the following function we define the type of boundary conditions depending on the location. Two types of boundary conditions + // can be specified: Dirichlet or Neumann boundary condition. On a Dirichlet boundary, the values of the + // primary variables need to be fixed. On a Neumann boundary condition, values for derivatives need to be fixed. + + // [[codeblock]] + BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const + { + BoundaryTypes bcTypes; + // We set all to Neumann, except for the top boundary, which is set to Dirichlet. + const Scalar zmax = this->gridGeometry().bBoxMax()[dim - 1]; + bcTypes.setAllNeumann(); + if (globalPos[dim - 1] > zmax - eps_) + bcTypes.setAllDirichlet(); + + return bcTypes; + } + // [[/codeblock]] + + // We define the Dirichlet boundary conditions + // [[codeblock]] + PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const + { + PrimaryVariables priVars(0.0); + priVars.setState(wPhaseOnly); + // We recycle the initial conditions, but additionally enforce that substrate and oxygen necessary for biomass growth are zero. + priVars = initial_(globalPos); + priVars[xwBiosubIdx] = 0.0; + priVars[xwO2Idx] = 0.0; + return priVars; + } + // [[/codeblock]] + + // The injections can be described with a Neumann boundary condition. + // Since we have multiple injections durng the whole simulation period, the Neumann boundary conditions in this case are time or rather episode depended. + // [[codeblock]] + NumEqVector neumannAtPos(const GlobalPosition& globalPos) const + { + // We only have injection at the bottom, negative values for injection + if (globalPos[dim - 1] > eps_) + return NumEqVector(0.0); + + // We calculate the injected water velocity based on the volume flux injected into a 1 inch diameter column. + const Scalar diameter = 0.0254; + const Scalar waterFlux = injQ_/(3.14*diameter*diameter/4.); //[m/s] + const auto injProcess = injectionType_[episodeIdx_]; + + // We also have no-injection, no-flow periods, which are coded for by -99 or 9. + // Thus, for no flow, we set the Neumann BC to zero for all components. + if (injProcess == InjectionProcess::noInjection || injProcess == InjectionProcess::noFlow) + return NumEqVector(0.0); + + // We set the injection BC to the basic rinse injection and later only change the BC for those components that are different. + NumEqVector values(0.0); + + values[conti0EqIdx + wCompIdx] = -waterFlux * 996/FluidSystem::molarMass(wCompIdx); + values[conti0EqIdx + nCompIdx] = -waterFlux * injTC_*996 /FluidSystem::molarMass(nCompIdx); + values[conti0EqIdx + xwCaIdx] = 0; + values[conti0EqIdx + xwSuspendedBiomassIdx] = 0; + values[conti0EqIdx + xwBiosubIdx] = -waterFlux * injSub_ /FluidSystem::molarMass(xwBiosubIdx); + values[conti0EqIdx + xwO2Idx] = -waterFlux * injO2_ /FluidSystem::molarMass(O2Idx); + values[conti0EqIdx + xwUreaIdx] = 0; + values[conti0EqIdx + phiCalciteIdx] = 0; + values[conti0EqIdx + phiBiofilmIdx] = 0; + values[conti0EqIdx + xwNaIdx] = -waterFlux * (injNa_ + injNaCorr_) /FluidSystem::molarMass(NaIdx); + values[conti0EqIdx + xwClIdx] = -waterFlux *injTNH_ /NH3::molarMass() //NH4Cl ---> mol Cl = mol NH4 + -waterFlux *injNa_ /FluidSystem::molarMass(NaIdx); //NaCl ---> mol Cl = mol Na + // rinse, used as standard injection fluid + if (injProcess == InjectionProcess::rinse) + { + return values; // do not change anything. + } + + // injProcess == 1 codes for an injection of mineralization medium containing urea and calcium chloride. + // Thus, we add BC terms for those components. + // Additionally, we need to adjust the amount of water injected due to the high concentration of other components injected. + // Finally, we need to adapt the injected NaCorr concentration to account fo the lower pH. + else if (injProcess == InjectionProcess::mineralization) + { + values[conti0EqIdx + wCompIdx] = - waterFlux * 0.8716 * densityW_ /FluidSystem::molarMass(wCompIdx); //0.8716 factor accounts for less water per volume due to relatively high solute concentrations! + values[conti0EqIdx + nCompIdx] = - waterFlux * injTC_ * densityW_ /FluidSystem::molarMass(nCompIdx); + values[conti0EqIdx + xwCaIdx] = - waterFlux * injCa_/FluidSystem::molarMass(CaIdx); + values[conti0EqIdx + xwUreaIdx] = - waterFlux * injUrea_ /FluidSystem::molarMass(UreaIdx); + values[conti0EqIdx + xwNaIdx] = - waterFlux * injNa_ /FluidSystem::molarMass(NaIdx) + - waterFlux * injNaCorr_ /FluidSystem::molarMass(NaIdx)* 0.032; + values[conti0EqIdx + xwClIdx] = - waterFlux * injTNH_ /NH3::molarMass() //NH4Cl ---> mol Cl = mol NH4 + - waterFlux * 2 * injCa_/FluidSystem::molarMass(CaIdx) //+CaCl2 ---> mol Cl = mol Ca*2 + -waterFlux *injNa_ /FluidSystem::molarMass(NaIdx); //NaCl ---> mol Cl = mol Na + return values; + } + + // injProcess == 3 codes for a resuscitation injection to regrow biomass. + // It is similar to a rinse injection, but with added urea, which is what we add to the basic rinse + else if (injProcess == InjectionProcess::resuscitation ) + { + values[conti0EqIdx + xwUreaIdx] = - waterFlux * injUrea_ /FluidSystem::molarMass(UreaIdx); + return values; + } + + // injProcess == 2 codes for a inoculation or biomass injection. + // It is similar to a rinse injection, but with added suspended biomass, which is what we add to the basic rinse + else if (injProcess == InjectionProcess::inoculation) + { + values[conti0EqIdx + xwSuspendedBiomassIdx] = -waterFlux * injBiosusp_ /FluidSystem::molarMass(xwSuspendedBiomassIdx); + return values; + } + else + DUNE_THROW(Dune::InvalidStateException, "Invalid injection process " << static_cast<int>(injProcess)); + } + // [[/codeblock]] + + // #### Initial conditions + // We specify the initial conditions for the primary variable depending + // on the location. Here, we set zero model fractions everywhere in the domain except for a strip + // at the bottom of the domain where we set an initial mole fraction of $`1e-9`$. + // [[codeblock]] + PrimaryVariables initialAtPos(const GlobalPosition& globalPos) const + { return initial_(globalPos); } + + // [[/codeblock]] + + // #### Reactive source and sink terms + // We calculate the reactive source and sink terms. + // For the details, see the "simplified chemistry case" in the dissertation of Hommel available at https://elib.uni-stuttgart.de/handle/11682/8787 + // [[codeblock]] + NumEqVector source(const Element &element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolume &scv) const + { + const auto elemSol = elementSolution(element, elemVolVars, fvGeometry); + const auto gradPw = evalGradients(element, + element.geometry(), + this->gridGeometry(), + elemSol, + scv.center())[pressureIdx]; + const Scalar scvPotGradNorm = gradPw.two_norm(); + + //define and compute some parameters for siplicity: + const Scalar porosity = elemVolVars[scv].porosity(); + Scalar initialPorosity = 1.0; + constexpr int numActiveComps = SolidSystem::numComponents-SolidSystem::numInertComponents; + for (int i = numActiveComps; i<SolidSystem::numComponents; ++i) + initialPorosity -= elemVolVars[scv].solidVolumeFraction(i); + + const Scalar Sw = elemVolVars[scv].saturation(wPhaseIdx); + const Scalar xlSalinity = elemVolVars[scv].moleFraction(wPhaseIdx,NaIdx) + + elemVolVars[scv].moleFraction(wPhaseIdx,CaIdx) + + elemVolVars[scv].moleFraction(wPhaseIdx,ClIdx); + const Scalar densityBiofilm = elemVolVars[scv].solidComponentDensity(SolidSystem::BiofilmIdx); + const Scalar densityCalcite = elemVolVars[scv].solidComponentDensity(SolidSystem::CalciteIdx); + const Scalar cBio = std::max(0.0, elemVolVars[scv].moleFraction(wPhaseIdx, SuspendedBiomassIdx) + * elemVolVars[scv].molarDensity(wPhaseIdx) + * FluidSystem::molarMass(SuspendedBiomassIdx)); //[kg_suspended_Biomass/m³_waterphase] + const Scalar volFracCalcite = std::max(0.0, elemVolVars[scv].solidVolumeFraction(SolidSystem::CalciteIdx)); + const Scalar volFracBiofilm = std::max(0.0, elemVolVars[scv].solidVolumeFraction(SolidSystem::BiofilmIdx)); + const Scalar massBiofilm = densityBiofilm * volFracBiofilm; + const Scalar cSubstrate = std::max(0.0, elemVolVars[scv].moleFraction(wPhaseIdx, BiosubIdx) + * elemVolVars[scv].molarDensity(wPhaseIdx) + * FluidSystem::molarMass(BiosubIdx)); //[kg_substrate/m³_waterphase] + const Scalar cO2 = std::max(0.0, elemVolVars[scv].moleFraction(wPhaseIdx, O2Idx) + * elemVolVars[scv].molarDensity(wPhaseIdx) + * FluidSystem::molarMass(O2Idx)); //[kg_oxygen/m³_waterphase] + const Scalar mUrea = std::max(0.0, moleFracToMolality(elemVolVars[scv].moleFraction(wPhaseIdx,UreaIdx), + xlSalinity, + elemVolVars[scv].moleFraction(wPhaseIdx,nCompIdx))); //[mol_urea/kg_H2O] + // compute rate of ureolysis: + const Scalar vmax = kurease_; + const Scalar Zub = kub_ * massBiofilm; // [kgurease/m³] + const Scalar rurea = vmax * Zub * mUrea / (ku_ + mUrea); //[mol/m³s] + + // compute precipitation rate of calcite, no dissolution! Simplification: rprec = rurea + // additionally regularize the precipitation rate that we do not precipitate more calcium than available. + const Scalar maxPrecipitationRate = elemVolVars[scv].moleFraction(wPhaseIdx,CaIdx) * Sw * porosity + * elemVolVars[scv].molarDensity(wPhaseIdx) / timeStepSize_; + const Scalar rprec = std::min(rurea, maxPrecipitationRate); + + //compute biomass growth coefficient and rate + const Scalar mue = kmue_ * cSubstrate / (ks_ + cSubstrate) * cO2 / (ke_ + cO2);// [1/s] + const Scalar rgf = mue * massBiofilm; //[kg/m³s] + const Scalar rgb = mue * porosity * Sw * cBio; //[kg/m³s] + + // compute biomass decay coefficient and rate: + const Scalar dcf = dc0_ + (rprec * SolidSystem::molarMass(SolidSystem::CalciteIdx) + /(densityCalcite * (initialPorosity - volFracCalcite))); + const Scalar dcb = dc0_; //[1/s] + const Scalar rdcf = dcf * massBiofilm; //[kg/m³s] + const Scalar rdcb = dcb * porosity * Sw * cBio; //[kg/m³s] + + // compute attachment coefficient and rate: + const Scalar ka = ca1_ * volFracBiofilm + ca2_; //[1/s] + const Scalar ra = ka * porosity * Sw * cBio; //[kg/m³s] + + // compute detachment coefficient and rate: + const Scalar cd2 = volFracBiofilm / (initialPorosity - volFracCalcite); //[-] + const Scalar kd = cd1_ * std::pow((porosity * Sw * scvPotGradNorm),0.58) + cd2 * mue; //[1/s] + const Scalar rd = kd * massBiofilm; //[kg/m³s] + + // rprec[mol/m³s] + // rurea[mol/m³s] + // rgb + rdcb + ra + rd [kg/m³s] + // source[kg/m³s] + NumEqVector source(0.0); + source[wCompIdx] += 0; + source[nCompIdx] += rurea - rprec; + source[NaIdx] += 0; + source[ClIdx] += 0; + source[CaIdx] += - rprec; + source[UreaIdx] += - rurea; + source[O2Idx] += -(rgf + rgb) *f_/yield_ / FluidSystem::molarMass(O2Idx); + source[BiosubIdx] += -(rgf + rgb) / yield_ / FluidSystem::molarMass(BiosubIdx); + source[SuspendedBiomassIdx] += (rgb - rdcb - ra + rd) / FluidSystem::molarMass(SuspendedBiomassIdx); + source[phiBiofilmIdx] += (rgf - rdcf + ra - rd) / SolidSystem::molarMass(SolidSystem::BiofilmIdx); + source[phiCalciteIdx] += + rprec; + + return source; + } + // [[/codeblock]] + + // The permeability is added to the vtk output + // [[codeblock]] + // Function to return the permeability for additional vtk output + const std::vector<Scalar>& getPermeability() + { return permeability_; } + + // Function to update the permeability for additional vtk output + template<class SolutionVector> + void updateVtkOutput(const SolutionVector& curSol) + { + for (const auto& element : elements(this->gridGeometry().gridView())) + { + const auto elemSol = elementSolution(element, curSol, this->gridGeometry()); + auto fvGeometry = localView(this->gridGeometry()); + fvGeometry.bindElement(element); + for (const auto& scv : scvs(fvGeometry)) + { + VolumeVariables volVars; + volVars.update(elemSol, *this, element, scv); + const auto dofIdxGlobal = scv.dofIndex(); + permeability_[dofIdxGlobal] = volVars.permeability(); + } + } + } + // [[/codeblock]] + +// ### Declaring all necessary variables and private fuctions +// The internal methods are defined here +// [[codeblock]] +private: + // Internal method for the initial condition reused for the dirichlet conditions. + PrimaryVariables initial_(const GlobalPosition &globalPos) const + { + PrimaryVariables priVars(0.0); + priVars.setState(wPhaseOnly); + priVars[pressureIdx] = initPressure_ ; //70e5; // - (maxHeight - globalPos[1])*densityW_*9.81; //p_atm + rho*g*h + priVars[switchIdx] = initxwTC_; + priVars[xwNaIdx] = initxwNa_ + xwNaCorr_; + priVars[xwClIdx] = initxwCl_ + initxwTNH_ + 2*initxwCa_ + xwClCorr_; + priVars[xwCaIdx] = initxwCa_; + priVars[xwUreaIdx] = initxwUrea_; + priVars[xwO2Idx] = initxwO2_; + priVars[xwBiosubIdx] = initxwBiosub_; + priVars[xwSuspendedBiomassIdx] = initxwBiosusp_; + priVars[phiBiofilmIdx] = initBiofilm_; // [m^3/m^3] + priVars[phiCalciteIdx] = initCalcite_; // [m^3/m^3] + return priVars; + } + + // Internal method to calculate the molality of a component based on its mole fraction. + static Scalar moleFracToMolality(Scalar moleFracX, Scalar moleFracSalinity, Scalar moleFracCTot) + { + const Scalar molalityX = moleFracX / (1 - moleFracSalinity - moleFracCTot) + / FluidSystem::molarMass(FluidSystem::H2OIdx); + return molalityX; + } + // [[/codeblock]] + + // The remainder of the class contains an epsilon value used for floating point comparisons + // and parameters needed to describe the chemical processess. + // Additionally the problem name, the peremability vector as well as some time-parameters are declared + // [[details]] private members + // eps is used as a small value for the definition of the boundary conditions + static constexpr Scalar eps_ = 1e-6; + + // initial condition parameters + Scalar initPressure_; + Scalar densityW_;//1087; // rhow=1087; + Scalar initxwTC_;//2.3864e-7; // [mol/mol] + Scalar initxwNa_;//0; + Scalar initxwCl_;//0; + Scalar initxwCa_;//0; + Scalar initxwUrea_;//0; + Scalar initxwTNH_;//3.341641e-3; + Scalar initxwO2_;//4.4686e-6; + Scalar initxwBiosub_;//2.97638e-4; + Scalar initxwBiosusp_;//0; + Scalar xwNaCorr_;//2.9466e-6; + Scalar xwClCorr_;//0; + Scalar initBiofilm_; + Scalar initCalcite_; + Scalar temperature_; + + // biomass parameters for source/sink calculations + Scalar ca1_; + Scalar ca2_; + Scalar cd1_; + Scalar dc0_; + Scalar kmue_ ; + Scalar f_; + Scalar ke_; + Scalar ks_; + Scalar yield_; + // urease parameters for source/sink calculations + Scalar kub_; + Scalar kurease_; + Scalar ku_; + + // injection parameters + Scalar injQ_; + Scalar injTC_; // [kg/kg] + Scalar injNa_; // [kg/m³] + Scalar injCa_; // [kg/m³] //computed from CaCl2 + Scalar injUrea_; // [kg/m³] + Scalar injTNH_; // [kg/m³] //computed from NH4Cl + Scalar injO2_; // [kg/m³] + Scalar injSub_; // [kg/m³] + Scalar injBiosusp_; // [kg/m³] + Scalar injNaCorr_; // [kg/m³] + int numInjections_; + std::vector<InjectionProcess> injectionType_; + + // the problem name + std::string name_; + // the permeability for output + std::vector<Scalar> permeability_; + + // timing parameters + Scalar time_ = 0.0; + Scalar timeStepSize_ = 0.0; + int episodeIdx_ = 0; +}; +} // end namespace Dumux +// [[/details]] +// [[/content]] +#endif diff --git a/examples/biomineralization/properties.hh b/examples/biomineralization/properties.hh new file mode 100644 index 0000000000..86dd9660ad --- /dev/null +++ b/examples/biomineralization/properties.hh @@ -0,0 +1,125 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ + +#ifndef DUMUX_MICP_COLUMN_SIMPLE_CHEM_PROPERTIES_HH +#define DUMUX_MICP_COLUMN_SIMPLE_CHEM_PROPERTIES_HH + +// ## `TypeTag` and compile-time settings (`properties.hh`) +// +// This file defines the `TypeTag` used for the biomineralization example, +// for which we then specialize `properties` to the needs of this setup. +// +// [[content]] +// +// ### Include files +// <details> +// +// This type tag specializes most of the `properties` required for two phase flow with +// multiple components including mineralisation simulations (2pncmin) in DuMuX +// We will use this in the following to inherit the respective properties and +// subsequently specialize those `properties` for our `TypeTag`, which we want to +// modify or for which no meaningful default can be set. +#include <dumux/common/properties.hh> +#include <dumux/porousmediumflow/2pncmin/model.hh> + +// We want to use `YaspGrid`, an implementation of the dune grid interface for structured grids: +#include <dune/grid/yaspgrid.hh> + +// In this example, we want to discretize the equations with the box scheme +#include <dumux/discretization/box.hh> + +// We include the necessary material files +#include <examples/biomineralization/material/fluidsystems/biominsimplechemistry.hh> +#include <examples/biomineralization/material/solidsystems/biominsolids.hh> +#include <examples/biomineralization/material/co2tableslaboratory.hh> + +// We include the problem and spatial parameters headers used for this simulation. +#include "problem.hh" +#include "spatialparams.hh" + +// </details> +// +// ### Definition of the `TypeTag` used for the biomineralization problem +// +// We define a `TypeTag` for our simulation with the name `MICPColumnSimpleChemistry` +// and inherit the `properties` specialized for the type tags `TwoPNCMin` and `BoxModel` respectively. +// This way, most of the `properties` required for this simulations +// using the box scheme are conveniently specialized for our new `TypeTag`. +// However, some properties depend on user choices and no meaningful default value can be set. +// Those properties will be adressed later in this file. +// [[codeblock]] +namespace Dumux::Properties { + +// We create new type tag for our simulation which inherits from the 2pncmin model and the box discretization +namespace TTag { +struct MICPColumnSimpleChemistry { using InheritsFrom = std::tuple<TwoPNCMin, BoxModel>; }; +} // end namespace TTag +// [[/codeblock]] + +// ### Property specializations +// +// In the following piece of code, mandatory `properties` for which no meaningful +// dafault can be set, are specialized for our type tag `MICPColumnSimpleChemistry`. + +// [[codeblock]] +// We set the grid to a 1D Yasp Grid +template<class TypeTag> +struct Grid<TypeTag, TTag::MICPColumnSimpleChemistry> +{ using type = Dune::YaspGrid<1>; }; + +// We set the problem used for our simulation, defining boundary and initial conditions (see below) +template<class TypeTag> +struct Problem<TypeTag, TTag::MICPColumnSimpleChemistry> +{ using type = MICPColumnProblemSimpleChemistry<TypeTag>; }; + +// We set the fluidSystem used for our simulation +template<class TypeTag> +struct FluidSystem<TypeTag, TTag::MICPColumnSimpleChemistry> +{ + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using CO2Tables = Dumux::ICP::CO2Tables; + using H2OTabulated = Components::TabulatedComponent<Components::H2O<Scalar>>; + using type = Dumux::FluidSystems::BioMinSimpleChemistryFluid<Scalar, CO2Tables, H2OTabulated>; +}; + +// We set the solidSystem used for our simulation +template<class TypeTag> +struct SolidSystem<TypeTag, TTag::MICPColumnSimpleChemistry> +{ + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using type = SolidSystems::BioMinSolidPhase<Scalar>; +}; + +// We define the spatial parameters for our simulation. The values are specified in the corresponding spatialparameters header file, which is included above. +template<class TypeTag> +struct SpatialParams<TypeTag, TTag::MICPColumnSimpleChemistry> +{ + using type = ICPSpatialParams<GetPropType<TypeTag, Properties::GridGeometry>, + GetPropType<TypeTag, Properties::Scalar>>; +}; + +// We set the two-phase primary variable formulation used for our simulation +template<class TypeTag> +struct Formulation<TypeTag, TTag::MICPColumnSimpleChemistry> +{ static constexpr auto value = TwoPFormulation::p0s1; }; + +}// We leave the namespace Dumux::Properties. +// [[/codeblock]] +// [[/content]] +#endif diff --git a/examples/biomineralization/spatialparams.hh b/examples/biomineralization/spatialparams.hh new file mode 100644 index 0000000000..68ab59cfe0 --- /dev/null +++ b/examples/biomineralization/spatialparams.hh @@ -0,0 +1,149 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ + +#ifndef DUMUX_MICP_COLUMN_SIMPLE_CHEM_SPATIAL_PARAMS_HH +#define DUMUX_MICP_COLUMN_SIMPLE_CHEM_SPATIAL_PARAMS_HH + +// ## Parameter distributions (`spatialparams_1p.hh`) +// +// [[content]] +// +// This file contains the __spatial parameters class__ which defines the +// distributions for the porous medium parameters permeability and porosity +// over the computational grid +// +// ### Include files +// [[details]] includes +// We include the basic spatial parameters for finite volumes file from which we will inherit +#include <dumux/material/spatialparams/fv.hh> +// We include the files for the two-phase laws: the linear material law +#include <dumux/material/fluidmatrixinteractions/2p/linearmaterial.hh> +// We include the files for the two-phase laws: the regularized Brooks-Corey pc-Sw and relative permeability laws +#include <dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh> +// We include the files for the two-phase laws: the scaling from effective to absolute saturations +#include <dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh> +// We include the laws for changing porosity due to precipitation +#include <dumux/material/fluidmatrixinteractions/porosityprecipitation.hh> +// We include the laws for changing permeability based on porosity change according to Kozeny-Carman +#include <dumux/material/fluidmatrixinteractions/permeabilitykozenycarman.hh> +// [[/details]] +// +// ### The spatial parameters class +// In the `ICPSpatialParams` class, we define all functions needed to describe +// the porous medium, e.g. porosity and permeability. +// We inherit from the `FVSpatialParams` class which is the base class for spatial paramters using finite volume discretization schemes. + +// [[codeblock]] +namespace Dumux { + +// In the ICPSpatialParams class we define all functions needed to describe the spatial distributed parameters. +template<class GridGeometry, class Scalar> +class ICPSpatialParams +: public FVSpatialParams<GridGeometry, Scalar, ICPSpatialParams<GridGeometry, Scalar>> +{ + // We introduce using declarations that are derived from the property system which we need in this class + using ThisType = ICPSpatialParams<GridGeometry, Scalar>; + using ParentType = FVSpatialParams<GridGeometry, Scalar, ThisType>; + using GridView = typename GridGeometry::GridView; + using EffectiveLaw = RegularizedBrooksCorey<Scalar>; + using SubControlVolume = typename GridGeometry::SubControlVolume; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + +public: + // type used for the permeability (i.e. tensor or scalar) + using PermeabilityType = Scalar; + using MaterialLaw = EffToAbsLaw<EffectiveLaw>; + using MaterialLawParams = typename MaterialLaw::Params; + // [[/codeblock]] + // #### Using porosity and permeability laws to return the updated values + // Due due calcium carbonate precipitation the porosity and the permeability change with time. At first, the initial values for the porosity and permeability are defined. Moreover, the functions that return the updated values, based on the chosen laws are defined. + // [[codeblock]] + ICPSpatialParams(std::shared_ptr<const GridGeometry> gridGeometry) + : ParentType(gridGeometry) + { + // We read reference values for porosity and permeability from the input + referencePorosity_ = getParam<Scalar>("SpatialParams.ReferencePorosity", 0.4); + referencePermeability_ = getParam<Scalar>("SpatialParams.ReferencePermeability", 2.e-10); + + // Setting residual saturations + materialParams_.setSwr(0.2); + materialParams_.setSnr(0.05); + + // Setting parameters for the Brooks-Corey law + materialParams_.setPe(1e4); + materialParams_.setLambda(2.0); + } + + // We return the reference or initial porosity. + //This reference porosity is the porosity, for which the permeability is know and set as reference permeability + Scalar referencePorosity(const Element& element, const SubControlVolume &scv) const + { return referencePorosity_; } + + // We return the volume fraction of the inert (unreactive) component + template<class SolidSystem> + Scalar inertVolumeFractionAtPos(const GlobalPosition& globalPos, int compIdx) const + { return 1.0-referencePorosity_; } + + // [[codeblock]] + // We return the updated porosity using the specified porosity law + template<class ElementSolution> + Scalar porosity(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const + { return poroLaw_.evaluatePorosity(element, scv, elemSol, referencePorosity_); } + + // We return the updated permeability using the specified permeability law + template<class ElementSolution> + PermeabilityType permeability(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const + { + const auto poro = porosity(element, scv, elemSol); + return permLaw_.evaluatePermeability(referencePermeability_, referencePorosity_, poro); + } + // [[/codeblock]] + // Return the brooks-corey context depending on the position + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + { return materialParams_; } + + // Define the wetting phase + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::H2OIdx; } + + // The remainder of this class contains the data members and defines the porosity law which describes the change of porosity due to calcium carbonate precipitation. + // Additionally the change of porosity results in a change of permeability. This relation is described in the permeability law, in this case the Kozeny-Carman porosity-permeability relation + // [[codeblock]] +private: + + MaterialLawParams materialParams_; + // Setting porosity precipitation as the porosity law + PorosityPrecipitation<Scalar, /*numFluidComponents*/9, /*activeComponents*/2> poroLaw_; + // Setting the Kozeny-Carman porosity-permeability relation as the permeability law + PermeabilityKozenyCarman<PermeabilityType> permLaw_; + //The reference porosity is the porosity, for which the permeability is know and set as reference permeability + Scalar referencePorosity_; + //The reference permeability is the known (measured) permeability, of the porous medium in the initial condition, before the solid phases change during the simulation + PermeabilityType referencePermeability_ = 0.0; +};// end class definition of ICPSpatialParams +} //end namespace Dumux +// [[/codeblock]] +// [[/content]] +#endif diff --git a/test/references/example_biomineralization-reference.vtp b/test/references/example_biomineralization-reference.vtp new file mode 100644 index 0000000000..697e123337 --- /dev/null +++ b/test/references/example_biomineralization-reference.vtp @@ -0,0 +1,296 @@ +<?xml version="1.0"?> +<VTKFile type="PolyData" version="0.1" byte_order="LittleEndian"> + <PolyData> + <Piece NumberOfLines="56" NumberOfPoints="57"> + <PointData Scalars="S_w"> + <DataArray type="Float32" Name="S_w" NumberOfComponents="1" format="ascii"> + 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 + </DataArray> + <DataArray type="Float32" Name="p_w" NumberOfComponents="1" format="ascii"> + 108299 108154 108008 107863 107716 107570 107423 107276 107128 106981 106833 106685 + 106537 106389 106241 106093 105945 105796 105648 105499 105351 105202 105054 104905 + 104756 104608 104459 104310 104161 104013 103864 103715 103566 103417 103269 103120 + 102971 102822 102674 102525 102376 102228 102079 101930 101781 101633 101484 101336 + 101187 101038 100890 100741 100593 100444 100296 100147 100000 + </DataArray> + <DataArray type="Float32" Name="rho_w" NumberOfComponents="1" format="ascii"> + 1002.37 1004.45 1006.29 1007.93 1009.39 1010.68 1011.83 1012.85 1013.76 1014.57 1015.28 1015.92 + 1016.48 1016.98 1017.43 1017.82 1018.17 1018.48 1018.75 1018.99 1019.2 1019.39 1019.55 1019.69 + 1019.81 1019.91 1020 1020.08 1020.14 1020.19 1020.23 1020.26 1020.28 1020.29 1020.29 1020.29 + 1020.28 1020.26 1020.24 1020.21 1020.18 1020.14 1020.09 1020.04 1019.99 1019.93 1019.87 1019.81 + 1019.74 1019.67 1019.59 1019.51 1019.43 1019.34 1019.25 1019.16 1001.47 + </DataArray> + <DataArray type="Float32" Name="mob_w" NumberOfComponents="1" format="ascii"> + 1094.28 1080.56 1069.63 1060.68 1053.23 1046.95 1041.61 1037.03 1033.09 1029.67 1026.7 1024.11 + 1021.85 1019.88 1018.14 1016.62 1015.29 1014.12 1013.1 1012.2 1011.41 1010.73 1010.13 1009.61 + 1009.17 1008.79 1008.46 1008.19 1007.97 1007.79 1007.65 1007.54 1007.47 1007.43 1007.42 1007.43 + 1007.47 1007.53 1007.62 1007.72 1007.85 1007.99 1008.15 1008.33 1008.53 1008.74 1008.96 1009.2 + 1009.46 1009.72 1010 1010.3 1010.61 1010.92 1011.26 1011.6 1103.12 + </DataArray> + <DataArray type="Float32" Name="S_n" NumberOfComponents="1" format="ascii"> + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 + </DataArray> + <DataArray type="Float32" Name="p_n" NumberOfComponents="1" format="ascii"> + 117966 117821 117675 117529 117383 117236 117089 116942 116795 116648 116500 116352 + 116204 116056 115908 115760 115611 115463 115314 115166 115017 114869 114720 114572 + 114423 114274 114125 113977 113828 113679 113530 113382 113233 113084 112935 112787 + 112638 112489 112340 112192 112043 111894 111746 111597 111448 111299 111151 111002 + 110854 110705 110556 110408 110259 110111 109962 109814 109667 + </DataArray> + <DataArray type="Float32" Name="rho_n" NumberOfComponents="1" format="ascii"> + 1.7176 1.71751 1.71744 1.71737 1.7173 1.71725 1.7172 1.71716 1.71712 1.71708 1.71705 1.71703 + 1.717 1.71698 1.71696 1.71694 1.71693 1.71692 1.7169 1.71689 1.71688 1.71688 1.71687 1.71686 + 1.71686 1.71685 1.71685 1.71685 1.71684 1.71684 1.71684 1.71684 1.71684 1.71684 1.71684 1.71683 + 1.71684 1.71684 1.71684 1.71684 1.71684 1.71684 1.71684 1.71684 1.71684 1.71685 1.71685 1.71685 + 1.71685 1.71686 1.71686 1.71686 1.71687 1.71687 1.71687 1.71688 1.71765 + </DataArray> + <DataArray type="Float32" Name="mob_n" NumberOfComponents="1" format="ascii"> + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 + </DataArray> + <DataArray type="Float32" Name="pc" NumberOfComponents="1" format="ascii"> + 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 + 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 + 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 + 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 + 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 9666.67 + </DataArray> + <DataArray type="Float32" Name="porosity" NumberOfComponents="1" format="ascii"> + 0.398721 0.398721 0.39872 0.39872 0.39872 0.39872 0.39872 0.398721 0.398721 0.398722 0.398723 0.398724 + 0.398726 0.398728 0.39873 0.398733 0.398736 0.39874 0.398745 0.39875 0.398757 0.398763 0.398771 0.398779 + 0.398788 0.398798 0.398808 0.398819 0.398831 0.398844 0.398857 0.39887 0.398885 0.398899 0.398915 0.39893 + 0.398947 0.398963 0.39898 0.398997 0.399014 0.399032 0.39905 0.399068 0.399085 0.399103 0.399121 0.399139 + 0.399157 0.399175 0.399193 0.39921 0.399228 0.399245 0.399266 0.399343 0.4 + </DataArray> + <DataArray type="Float32" Name="x^H2O_w" NumberOfComponents="1" format="ascii"> + 0.994858 0.992255 0.989943 0.987889 0.986064 0.984443 0.983002 0.981722 0.980585 0.979575 0.978678 0.977881 + 0.977174 0.976547 0.97599 0.975497 0.975061 0.974675 0.974335 0.974035 0.973771 0.97354 0.973339 0.973163 + 0.973012 0.972882 0.972772 0.972679 0.972603 0.972541 0.972493 0.972457 0.972433 0.972419 0.972416 0.972421 + 0.972435 0.972457 0.972486 0.972522 0.972566 0.972615 0.972671 0.972732 0.972799 0.972871 0.972948 0.97303 + 0.973117 0.973208 0.973304 0.973404 0.973507 0.973615 0.973727 0.973844 0.996655 + </DataArray> + <DataArray type="Float32" Name="x^TotalC_w" NumberOfComponents="1" format="ascii"> + 2.38252e-07 2.41189e-07 2.43797e-07 2.46115e-07 2.48174e-07 2.50004e-07 2.51631e-07 2.53076e-07 2.5436e-07 2.55502e-07 2.56516e-07 2.57416e-07 + 2.58216e-07 2.58926e-07 2.59556e-07 2.60115e-07 2.6061e-07 2.61048e-07 2.61436e-07 2.61779e-07 2.62081e-07 2.62348e-07 2.62584e-07 2.62792e-07 + 2.62976e-07 2.63138e-07 2.63283e-07 2.63413e-07 2.63532e-07 2.63641e-07 2.63744e-07 2.63845e-07 2.63947e-07 2.64053e-07 2.64167e-07 2.64293e-07 + 2.64435e-07 2.64599e-07 2.64789e-07 2.65012e-07 2.65273e-07 2.65579e-07 2.65938e-07 2.66358e-07 2.66848e-07 2.67417e-07 2.68075e-07 2.68833e-07 + 2.69704e-07 2.70699e-07 2.71834e-07 2.73122e-07 2.74579e-07 2.76222e-07 2.78068e-07 2.8013e-07 2.3864e-07 + </DataArray> + <DataArray type="Float32" Name="x^Na+_w" NumberOfComponents="1" format="ascii"> + 2.80172e-06 2.50118e-06 2.2342e-06 1.997e-06 1.78623e-06 1.59894e-06 1.43251e-06 1.28461e-06 1.15318e-06 1.03641e-06 9.32667e-07 8.40527e-07 + 7.58717e-07 6.8611e-07 6.21707e-07 5.64625e-07 5.14077e-07 4.6937e-07 4.29886e-07 3.95081e-07 3.64471e-07 3.37627e-07 3.14172e-07 2.93768e-07 + 2.76118e-07 2.6096e-07 2.48061e-07 2.37213e-07 2.28236e-07 2.20966e-07 2.15261e-07 2.10994e-07 2.08053e-07 2.06338e-07 2.0576e-07 2.06242e-07 + 2.07714e-07 2.10112e-07 2.13383e-07 2.17476e-07 2.22348e-07 2.27958e-07 2.3427e-07 2.41253e-07 2.48876e-07 2.57114e-07 2.6594e-07 2.75334e-07 + 2.85275e-07 2.95742e-07 3.06717e-07 3.18185e-07 3.30127e-07 3.42531e-07 3.5538e-07 3.6894e-07 2.9466e-06 + </DataArray> + <DataArray type="Float32" Name="x^Cl-_w" NumberOfComponents="1" format="ascii"> + 0.00410809 0.00542141 0.00658811 0.00762468 0.00854574 0.0093642 0.0100915 0.0107379 0.0113122 0.0118225 0.0122759 0.0126785 + 0.0130361 0.0133534 0.0136348 0.0138843 0.0141052 0.0143006 0.0144732 0.0146253 0.0147591 0.0148764 0.014979 0.0150681 + 0.0151453 0.0152116 0.015268 0.0153154 0.0153546 0.0153864 0.0154114 0.01543 0.0154429 0.0154504 0.015453 0.0154509 + 0.0154445 0.015434 0.0154197 0.0154019 0.0153806 0.0153561 0.0153285 0.015298 0.0152647 0.0152287 0.0151902 0.0151491 + 0.0151057 0.01506 0.015012 0.0149619 0.0149097 0.0148555 0.0147994 0.0147401 0.00334164 + </DataArray> + <DataArray type="Float32" Name="x^Ca2+_w" NumberOfComponents="1" format="ascii"> + 0.000367046 0.001019 0.00159799 0.00211227 0.00256909 0.0029749 0.00333541 0.00365566 0.00394013 0.00419278 0.00441714 0.00461631 + 0.00479305 0.00494982 0.00508879 0.00521187 0.00532077 0.005417 0.0055019 0.00557665 0.0056423 0.00569979 0.00574993 0.00579346 + 0.00583102 0.00586319 0.00589047 0.0059133 0.00593209 0.00594718 0.00595889 0.0059675 0.00597324 0.00597633 0.00597697 0.00597533 + 0.00597155 0.00596578 0.00595813 0.00594871 0.00593762 0.00592494 0.00591075 0.00589513 0.00587813 0.00585982 0.00584024 0.00581945 + 0.0057975 0.00577441 0.00575024 0.00572502 0.00569878 0.00567156 0.00564339 0.00561373 0 + </DataArray> + <DataArray type="Float32" Name="x^Urea_w" NumberOfComponents="1" format="ascii"> + 0.000358807 0.000996118 0.00156211 0.00206483 0.00251139 0.00290808 0.00326047 0.00357352 0.00385159 0.00409855 0.00431785 0.00451254 + 0.0046853 0.00483853 0.00497436 0.00509466 0.0052011 0.00529515 0.00537812 0.00545118 0.00551534 0.00557152 0.00562053 0.00566307 + 0.00569977 0.0057312 0.00575786 0.00578017 0.00579853 0.00581328 0.00582472 0.00583313 0.00583875 0.00584178 0.00584241 0.00584082 + 0.00583715 0.00583154 0.00582409 0.00581493 0.00580413 0.0057918 0.00577801 0.00576282 0.0057463 0.00572851 0.0057095 0.00568932 + 0.00566802 0.00564563 0.00562221 0.00559779 0.0055724 0.00554608 0.00551886 0.00549021 0 + </DataArray> + <DataArray type="Float32" Name="x^O2_w" NumberOfComponents="1" format="ascii"> + 4.50823e-06 4.51269e-06 4.51582e-06 4.51778e-06 4.5187e-06 4.51869e-06 4.51786e-06 4.5163e-06 4.51409e-06 4.51131e-06 4.50801e-06 4.50427e-06 + 4.50012e-06 4.49563e-06 4.49082e-06 4.48574e-06 4.48042e-06 4.47489e-06 4.46919e-06 4.46333e-06 4.45733e-06 4.45123e-06 4.44504e-06 4.43878e-06 + 4.43246e-06 4.42609e-06 4.4197e-06 4.41329e-06 4.40688e-06 4.40047e-06 4.39408e-06 4.38771e-06 4.38138e-06 4.37508e-06 4.36882e-06 4.36262e-06 + 4.35647e-06 4.35039e-06 4.34437e-06 4.33841e-06 4.33253e-06 4.32673e-06 4.321e-06 4.31535e-06 4.30978e-06 4.30429e-06 4.29889e-06 4.29357e-06 + 4.28834e-06 4.28319e-06 4.27813e-06 4.27315e-06 4.26826e-06 4.26345e-06 4.25876e-06 4.25385e-06 0 + </DataArray> + <DataArray type="Float32" Name="x^Glucose_w" NumberOfComponents="1" format="ascii"> + 0.000300524 0.000301306 0.000302001 0.000302618 0.000303166 0.000303653 0.000304085 0.000304469 0.00030481 0.000305113 0.000305382 0.00030562 + 0.000305832 0.000306019 0.000306185 0.000306332 0.000306462 0.000306576 0.000306677 0.000306766 0.000306844 0.000306912 0.000306971 0.000307023 + 0.000307067 0.000307104 0.000307136 0.000307162 0.000307184 0.000307201 0.000307214 0.000307223 0.000307229 0.000307231 0.000307231 0.000307228 + 0.000307222 0.000307214 0.000307204 0.000307191 0.000307177 0.000307161 0.000307142 0.000307123 0.000307101 0.000307078 0.000307053 0.000307027 + 0.000307 0.000306971 0.000306941 0.000306909 0.000306877 0.000306843 0.000306808 0.000306739 0 + </DataArray> + <DataArray type="Float32" Name="x^Suspended_Biomass_w" NumberOfComponents="1" format="ascii"> + 1.1151e-11 3.35495e-11 5.60484e-11 7.86329e-11 1.0129e-10 1.2401e-10 1.46782e-10 1.69597e-10 1.92447e-10 2.15323e-10 2.38217e-10 2.61119e-10 + 2.84021e-10 3.06913e-10 3.29783e-10 3.5262e-10 3.75414e-10 3.9815e-10 4.20817e-10 4.434e-10 4.65886e-10 4.88261e-10 5.10509e-10 5.32618e-10 + 5.54572e-10 5.76358e-10 5.9796e-10 6.19367e-10 6.40564e-10 6.61538e-10 6.82278e-10 7.02772e-10 7.2301e-10 7.4298e-10 7.62674e-10 7.82083e-10 + 8.01199e-10 8.20015e-10 8.38525e-10 8.56724e-10 8.74606e-10 8.92167e-10 9.09406e-10 9.26318e-10 9.42902e-10 9.59158e-10 9.75084e-10 9.90681e-10 + 1.00595e-09 1.02089e-09 1.03551e-09 1.0498e-09 1.06377e-09 1.07742e-09 1.09069e-09 1.10242e-09 0 + </DataArray> + <DataArray type="Float32" Name="rhoMolar_w" NumberOfComponents="1" format="ascii"> + 55431.9 55467.6 55499.2 55527.3 55552.1 55574.2 55593.7 55611.1 55626.4 55640.1 55652.2 55663 + 55672.5 55680.9 55688.4 55695.1 55700.9 55706.1 55710.7 55714.7 55718.3 55721.4 55724.1 55726.4 + 55728.5 55730.2 55731.7 55732.9 55734 55734.8 55735.4 55735.9 55736.2 55736.4 55736.5 55736.4 + 55736.2 55735.9 55735.6 55735.1 55734.5 55733.8 55733.1 55732.3 55731.4 55730.4 55729.4 55728.3 + 55727.1 55725.9 55724.6 55723.3 55721.9 55720.4 55718.9 55717.3 55411 + </DataArray> + <DataArray type="Float32" Name="x^H2O_n" NumberOfComponents="1" format="ascii"> + 0.026815 0.0267443 0.0266854 0.0266367 0.0265973 0.026566 0.0265419 0.0265242 0.0265123 0.0265054 0.0265031 0.0265048 + 0.0265101 0.0265187 0.0265301 0.0265441 0.0265604 0.0265789 0.0265991 0.0266211 0.0266446 0.0266694 0.0266956 0.0267228 + 0.0267511 0.0267803 0.0268104 0.0268413 0.0268729 0.0269053 0.0269382 0.0269718 0.0270058 0.0270405 0.0270756 0.0271111 + 0.0271471 0.0271836 0.0272204 0.0272576 0.0272952 0.0273332 0.0273715 0.0274101 0.027449 0.0274883 0.0275279 0.0275678 + 0.027608 0.0276485 0.0276892 0.0277303 0.0277716 0.0278132 0.027855 0.0278972 0.0288955 + </DataArray> + <DataArray type="Float32" Name="x^TotalC_n" NumberOfComponents="1" format="ascii"> + 0.000352141 0.000362127 0.000371228 0.000379512 0.000387044 0.000393889 0.000400105 0.00040575 0.000410876 0.000415531 0.000419762 0.000423608 + 0.000427108 0.000430295 0.000433201 0.000435854 0.000438279 0.000440499 0.000442535 0.000444406 0.000446128 0.000447716 0.000449185 0.000450547 + 0.000451813 0.000452994 0.000454099 0.000455139 0.00045612 0.000457053 0.000457945 0.000458803 0.000459636 0.000460453 0.000461261 0.000462069 + 0.000462886 0.000463723 0.00046459 0.000465497 0.000466458 0.000467484 0.00046859 0.000469792 0.000471104 0.000472546 0.000474136 0.000475894 + 0.000477842 0.000480004 0.000482405 0.000485072 0.000488033 0.000491319 0.000494961 0.000498978 0.000376053 + </DataArray> + <DataArray type="Float32" Name="x^Na+_n" NumberOfComponents="1" format="ascii"> + 2.57213e-26 2.29597e-26 2.05067e-26 1.83275e-26 1.63913e-26 1.4671e-26 1.31424e-26 1.17842e-26 1.05774e-26 9.50519e-27 8.55278e-27 7.70695e-27 + 6.95601e-27 6.28961e-27 5.69857e-27 5.17475e-27 4.71093e-27 4.30073e-27 3.93849e-27 3.61919e-27 3.33839e-27 3.09215e-27 2.87699e-27 2.68982e-27 + 2.52791e-27 2.38885e-27 2.27049e-27 2.17095e-27 2.08853e-27 2.02176e-27 1.96932e-27 1.93005e-27 1.90291e-27 1.88699e-27 1.88148e-27 1.88566e-27 + 1.89888e-27 1.92057e-27 1.95022e-27 1.98738e-27 2.03165e-27 2.08264e-27 2.14004e-27 2.20355e-27 2.27289e-27 2.34783e-27 2.42812e-27 2.51357e-27 + 2.60398e-27 2.69918e-27 2.79899e-27 2.90326e-27 3.01184e-27 3.1246e-27 3.24139e-27 3.36463e-27 2.68687e-26 + </DataArray> + <DataArray type="Float32" Name="x^Cl-_n" NumberOfComponents="1" format="ascii"> + 3.77146e-23 4.97661e-23 6.04691e-23 6.99756e-23 7.84198e-23 8.59208e-23 9.25839e-23 9.85025e-23 1.03759e-22 1.08428e-22 1.12573e-22 1.16252e-22 + 1.19516e-22 1.22411e-22 1.24977e-22 1.27249e-22 1.29258e-22 1.31034e-22 1.32599e-22 1.33977e-22 1.35187e-22 1.36245e-22 1.37168e-22 1.37968e-22 + 1.38658e-22 1.39248e-22 1.39747e-22 1.40164e-22 1.40507e-22 1.4078e-22 1.40992e-22 1.41145e-22 1.41246e-22 1.41297e-22 1.41303e-22 1.41266e-22 + 1.4119e-22 1.41077e-22 1.40929e-22 1.40748e-22 1.40536e-22 1.40295e-22 1.40025e-22 1.39729e-22 1.39407e-22 1.39061e-22 1.38691e-22 1.38299e-22 + 1.37885e-22 1.3745e-22 1.36994e-22 1.36519e-22 1.36026e-22 1.35514e-22 1.34984e-22 1.34426e-22 3.04709e-23 + </DataArray> + <DataArray type="Float32" Name="x^Ca2+_n" NumberOfComponents="1" format="ascii"> + 3.36969e-24 9.35392e-24 1.46672e-23 1.93853e-23 2.35752e-23 2.72961e-23 3.06004e-23 3.35347e-23 3.61402e-23 3.84532e-23 4.05062e-23 4.23278e-23 + 4.39433e-23 4.53754e-23 4.66438e-23 4.77664e-23 4.87588e-23 4.96348e-23 5.04068e-23 5.10856e-23 5.16809e-23 5.22013e-23 5.26542e-23 5.30465e-23 + 5.33841e-23 5.36721e-23 5.39153e-23 5.41178e-23 5.42831e-23 5.44147e-23 5.45152e-23 5.45872e-23 5.4633e-23 5.46546e-23 5.46538e-23 5.4632e-23 + 5.45907e-23 5.45311e-23 5.44544e-23 5.43616e-23 5.42534e-23 5.41308e-23 5.39944e-23 5.38449e-23 5.36828e-23 5.35088e-23 5.33232e-23 5.31266e-23 + 5.29194e-23 5.27019e-23 5.24746e-23 5.22377e-23 5.19916e-23 5.17365e-23 5.14729e-23 5.11956e-23 0 + </DataArray> + <DataArray type="Float32" Name="x^Urea_n" NumberOfComponents="1" format="ascii"> + 3.29405e-24 9.14391e-24 1.43379e-23 1.895e-23 2.30457e-23 2.66829e-23 2.9913e-23 3.27813e-23 3.53281e-23 3.7589e-23 3.95958e-23 4.13763e-23 + 4.29554e-23 4.43552e-23 4.5595e-23 4.66922e-23 4.76621e-23 4.85183e-23 4.92728e-23 4.99362e-23 5.0518e-23 5.10266e-23 5.14693e-23 5.18526e-23 + 5.21824e-23 5.24639e-23 5.27015e-23 5.28994e-23 5.3061e-23 5.31895e-23 5.32877e-23 5.33581e-23 5.34029e-23 5.34241e-23 5.34233e-23 5.34022e-23 + 5.3362e-23 5.33041e-23 5.32294e-23 5.3139e-23 5.30337e-23 5.29144e-23 5.27817e-23 5.26363e-23 5.24788e-23 5.23097e-23 5.21295e-23 5.19386e-23 + 5.17375e-23 5.15266e-23 5.13063e-23 5.10768e-23 5.08386e-23 5.05919e-23 5.0337e-23 5.00692e-23 0 + </DataArray> + <DataArray type="Float32" Name="x^O2_n" NumberOfComponents="1" format="ascii"> + 0.16953 0.169907 0.170235 0.17052 0.170767 0.170981 0.171164 0.17132 0.171452 0.171563 0.171655 0.17173 + 0.171791 0.171838 0.171873 0.171899 0.171915 0.171924 0.171926 0.171922 0.171913 0.171899 0.171883 0.171863 + 0.171841 0.171818 0.171793 0.171768 0.171743 0.171718 0.171693 0.171669 0.171646 0.171625 0.171605 0.171588 + 0.171572 0.171559 0.171548 0.171541 0.171535 0.171533 0.171534 0.171538 0.171545 0.171556 0.171569 0.171587 + 0.171607 0.171631 0.171659 0.17169 0.171724 0.171762 0.171805 0.171839 0 + </DataArray> + <DataArray type="Float32" Name="x^Glucose_n" NumberOfComponents="1" format="ascii"> + 2.75898e-24 2.76585e-24 2.77192e-24 2.77728e-24 2.782e-24 2.78615e-24 2.78981e-24 2.79301e-24 2.79582e-24 2.79828e-24 2.80042e-24 2.80229e-24 + 2.8039e-24 2.8053e-24 2.80649e-24 2.80751e-24 2.80837e-24 2.8091e-24 2.80969e-24 2.81017e-24 2.81055e-24 2.81084e-24 2.81105e-24 2.81118e-24 + 2.81125e-24 2.81126e-24 2.81121e-24 2.81111e-24 2.81097e-24 2.81078e-24 2.81056e-24 2.8103e-24 2.81001e-24 2.80968e-24 2.80934e-24 2.80896e-24 + 2.80856e-24 2.80814e-24 2.8077e-24 2.80723e-24 2.80675e-24 2.80625e-24 2.80573e-24 2.80519e-24 2.80464e-24 2.80407e-24 2.80349e-24 2.8029e-24 + 2.80229e-24 2.80166e-24 2.80103e-24 2.80038e-24 2.79972e-24 2.79905e-24 2.79837e-24 2.79737e-24 0 + </DataArray> + <DataArray type="Float32" Name="x^Suspended_Biomass_n" NumberOfComponents="1" format="ascii"> + 1.02372e-31 3.07969e-31 5.14442e-31 7.21654e-31 9.2949e-31 1.13785e-30 1.34664e-30 1.55578e-30 1.76519e-30 1.97479e-30 2.18451e-30 2.39425e-30 + 2.60394e-30 2.81349e-30 3.02279e-30 3.23174e-30 3.44024e-30 3.64817e-30 3.8554e-30 4.06182e-30 4.26731e-30 4.47172e-30 4.67492e-30 4.8768e-30 + 5.07721e-30 5.27602e-30 5.47312e-30 5.66837e-30 5.86165e-30 6.05284e-30 6.24185e-30 6.42856e-30 6.61287e-30 6.79469e-30 6.97393e-30 7.15053e-30 + 7.3244e-30 7.49548e-30 7.66372e-30 7.82907e-30 7.99148e-30 8.15092e-30 8.30736e-30 8.46079e-30 8.61118e-30 8.75852e-30 8.90282e-30 9.04407e-30 + 9.18229e-30 9.31748e-30 9.44966e-30 9.57886e-30 9.7051e-30 9.82837e-30 9.94806e-30 1.00537e-29 0 + </DataArray> + <DataArray type="Float32" Name="rhoMolar_n" NumberOfComponents="1" format="ascii"> + 39.7913 39.7863 39.7819 39.778 39.7746 39.7715 39.7688 39.7664 39.7642 39.7623 39.7606 39.7591 + 39.7578 39.7566 39.7556 39.7546 39.7538 39.7531 39.7524 39.7518 39.7513 39.7509 39.7505 39.7501 + 39.7498 39.7496 39.7494 39.7492 39.749 39.7489 39.7488 39.7487 39.7486 39.7486 39.7486 39.7486 + 39.7486 39.7486 39.7486 39.7487 39.7488 39.7488 39.7489 39.749 39.7491 39.7492 39.7494 39.7495 + 39.7496 39.7498 39.75 39.7501 39.7503 39.7505 39.7507 39.7509 39.7935 + </DataArray> + <DataArray type="Float32" Name="phase presence" NumberOfComponents="1" format="ascii"> + 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 + </DataArray> + <DataArray type="Float32" Name="precipitateVolumeFraction^Biofilm" NumberOfComponents="1" format="ascii"> + 0.00120713 0.00120714 0.00120714 0.00120713 0.00120711 0.00120705 0.00120695 0.00120677 0.00120648 0.00120604 0.00120539 0.0012045 + 0.00120331 0.00120176 0.00119981 0.00119739 0.00119447 0.001191 0.00118693 0.00118224 0.00117689 0.00117087 0.00116416 0.00115675 + 0.00114864 0.00113983 0.00113033 0.00112015 0.00110932 0.00109786 0.00108578 0.00107313 0.00105994 0.00104623 0.00103205 0.00101744 + 0.00100243 0.000987064 0.000971379 0.000955416 0.000939213 0.000922811 0.000906246 0.000889555 0.000872774 0.000855936 0.000839074 0.000822219 + 0.000805401 0.000788649 0.000771987 0.00075544 0.000739023 0.000722556 0.000702465 0.000629157 0 + </DataArray> + <DataArray type="Float32" Name="precipitateVolumeFraction^Calcite" NumberOfComponents="1" format="ascii"> + 7.18412e-05 7.23394e-05 7.26286e-05 7.27719e-05 7.28079e-05 7.27617e-05 7.26499e-05 7.24835e-05 7.22697e-05 7.20132e-05 7.17168e-05 7.13819e-05 + 7.10088e-05 7.05976e-05 7.01476e-05 6.96582e-05 6.91285e-05 6.8558e-05 6.79462e-05 6.72927e-05 6.65977e-05 6.58614e-05 6.50846e-05 6.42682e-05 + 6.34135e-05 6.25219e-05 6.15955e-05 6.06361e-05 5.96461e-05 5.86278e-05 5.75839e-05 5.6517e-05 5.54298e-05 5.43251e-05 5.32057e-05 5.20743e-05 + 5.09338e-05 4.97868e-05 4.86359e-05 4.74836e-05 4.63324e-05 4.51846e-05 4.40423e-05 4.29077e-05 4.17827e-05 4.06691e-05 3.95685e-05 3.84824e-05 + 3.74123e-05 3.63594e-05 3.53248e-05 3.43094e-05 3.33139e-05 3.23299e-05 3.11987e-05 2.77353e-05 0 + </DataArray> + <DataArray type="Float32" Name="Permeability" NumberOfComponents="1" format="ascii"> + 1.97246e-10 1.97245e-10 1.97244e-10 1.97244e-10 1.97244e-10 1.97244e-10 1.97245e-10 1.97246e-10 1.97247e-10 1.97248e-10 1.97251e-10 1.97253e-10 + 1.97257e-10 1.97261e-10 1.97267e-10 1.97273e-10 1.97281e-10 1.9729e-10 1.973e-10 1.97312e-10 1.97325e-10 1.9734e-10 1.97357e-10 1.97375e-10 + 1.97394e-10 1.97416e-10 1.97438e-10 1.97462e-10 1.97488e-10 1.97515e-10 1.97544e-10 1.97573e-10 1.97604e-10 1.97636e-10 1.97669e-10 1.97703e-10 + 1.97738e-10 1.97774e-10 1.9781e-10 1.97847e-10 1.97884e-10 1.97922e-10 1.9796e-10 1.97998e-10 1.98037e-10 1.98075e-10 1.98114e-10 1.98152e-10 + 1.98191e-10 1.98229e-10 1.98267e-10 1.98305e-10 1.98342e-10 1.98382e-10 1.98457e-10 1.98935e-10 1.99644e-10 + </DataArray> + </PointData> + <CellData Scalars="process rank"> + <DataArray type="Float32" Name="process rank" NumberOfComponents="1" format="ascii"> + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + </DataArray> + </CellData> + <Points> + <DataArray type="Float32" Name="Coordinates" NumberOfComponents="3" format="ascii"> + 0 0 0 0.0127 0 0 0.0254 0 0 0.0381 0 0 + 0.0508 0 0 0.0635 0 0 0.0762 0 0 0.0889 0 0 + 0.1016 0 0 0.1143 0 0 0.127 0 0 0.1397 0 0 + 0.1524 0 0 0.1651 0 0 0.1778 0 0 0.1905 0 0 + 0.2032 0 0 0.2159 0 0 0.2286 0 0 0.2413 0 0 + 0.254 0 0 0.2667 0 0 0.2794 0 0 0.2921 0 0 + 0.3048 0 0 0.3175 0 0 0.3302 0 0 0.3429 0 0 + 0.3556 0 0 0.3683 0 0 0.381 0 0 0.3937 0 0 + 0.4064 0 0 0.4191 0 0 0.4318 0 0 0.4445 0 0 + 0.4572 0 0 0.4699 0 0 0.4826 0 0 0.4953 0 0 + 0.508 0 0 0.5207 0 0 0.5334 0 0 0.5461 0 0 + 0.5588 0 0 0.5715 0 0 0.5842 0 0 0.5969 0 0 + 0.6096 0 0 0.6223 0 0 0.635 0 0 0.6477 0 0 + 0.6604 0 0 0.6731 0 0 0.6858 0 0 0.6985 0 0 + 0.7112 0 0 + </DataArray> + </Points> + <Lines> + <DataArray type="Int32" Name="connectivity" NumberOfComponents="1" format="ascii"> + 0 1 1 2 2 3 3 4 4 5 5 6 + 6 7 7 8 8 9 9 10 10 11 11 12 + 12 13 13 14 14 15 15 16 16 17 17 18 + 18 19 19 20 20 21 21 22 22 23 23 24 + 24 25 25 26 26 27 27 28 28 29 29 30 + 30 31 31 32 32 33 33 34 34 35 35 36 + 36 37 37 38 38 39 39 40 40 41 41 42 + 42 43 43 44 44 45 45 46 46 47 47 48 + 48 49 49 50 50 51 51 52 52 53 53 54 + 54 55 55 56 + </DataArray> + <DataArray type="Int32" Name="offsets" NumberOfComponents="1" format="ascii"> + 2 4 6 8 10 12 14 16 18 20 22 24 + 26 28 30 32 34 36 38 40 42 44 46 48 + 50 52 54 56 58 60 62 64 66 68 70 72 + 74 76 78 80 82 84 86 88 90 92 94 96 + 98 100 102 104 106 108 110 112 + </DataArray> + </Lines> + </Piece> + </PolyData> +</VTKFile> -- GitLab