+ ## Problem set-up N$_2$ is injected in an aquifer previously saturated with water with an injection rate of 0.0001 kg/(s*m$^2$). @@ -25,7 +26,7 @@ Locate all the files you will need for this exercise * The shared __spatial parameters file__: injection2pspatialparams.hh * The shared __input file__: params.input -

+

### Task 2: Compiling and running an executable
@@ -54,7 +55,7 @@ make exercise_basic_2p exercise_basic_2p2c paraview injection-2p2c.pvd  -

+

### Task 3: Setting up a new executable (for a non-isothermal simulation)
@@ -76,21 +77,21 @@ make # should rerun cmake make exercise_basic_2pni # builds new executable  -

+

### Task 4: Setting up a non-isothermal __2pni__ test problem
* Open the file injection2pniproblem.hh. It is a copy of the injection2pproblem.hh with some useful comments on how to implement a non-isothermal model. Look for comments containing c++ -// TODO: dumux-course-task +// TODO: dumux-course-task 4  * The following set-up should be realized: __Boundary conditions:__ Dirichlet conditions at the left boundary. For the primary variable 'temperature' use a varying temperature of
$\displaystyle T(y) = 283~\text{K} + 0.03~\frac{\text{K}}{\text{m}} \cdot \left( d_\text{aquifer} - y \right) $,
-with the aquifer depth +with the aquifer depth $\displaystyle d_\text{aquifer}=2700~\text{m}$. Assign Neumann no-flow for the energy balance to the rest of the boundaries. diff --git a/exercises/exercise-basic/injection2pniproblem.hh b/exercises/exercise-basic/injection2pniproblem.hh index 82967461b9d0109fbd623bff9c033f9825dcbf20..a56d804c4df74d583f86cb13a2526e997bd272b0 100644 --- a/exercises/exercise-basic/injection2pniproblem.hh +++ b/exercises/exercise-basic/injection2pniproblem.hh @@ -43,8 +43,8 @@ class Injection2PNIProblem; namespace Properties { /*! -* TODO:dumux-course-task: -* inherit from the TwoPNI model instead of TwoP here +* TODO:dumux-course-task 4 +* Inherit from the TwoPNI model instead of TwoP here */ // Create new type tags namespace TTag { diff --git a/exercises/exercise-biomineralization/README.md b/exercises/exercise-biomineralization/README.md index 329fc5318d9d062e2e38889ae3858ace3ebb0d2e..b4697c0e3d4e35b0fc59e03d0fa3416d8934c9a4 100644 --- a/exercises/exercise-biomineralization/README.md +++ b/exercises/exercise-biomineralization/README.md @@ -1,6 +1,6 @@ -# Exercise Biomineralization +# Exercise Biomineralization (DuMuX Course) -The aim of this exercise is to get a first glimpse at the _DuMuX_ way of implementing mineralization and reaction processes. In the scope of this exercise, the setting of boundary conditions is revisited and a new reaction term is implemented. +The aim of this exercise is to get a first glimpse at the _DuMux_ way of implementing mineralization and reaction processes. In the scope of this exercise, the setting of boundary conditions is revisited and a new reaction term is implemented. ## Problem set-up @@ -37,7 +37,7 @@ There are two types of solid components. Reactive and inert. For each reactive c ### 2. Implement a chemical equation -In the following the basic steps required to set the new chemical equation are outlined. Here, this is done in the __chemistry__ folder in the prepared file: simplebiominreactions.hh within the function reactionSource(). +In the following the basic steps required to set the new chemical equation are outlined. Here, this is done in the __chemistry__ folder in the prepared file: simplebiominreactions.hh within the function reactionSource(). Please be aware, that the chemistry file already provides some convenience functions (e.g. moleFracToMolality()). __Task__ @@ -74,7 +74,7 @@ To enable your newly created chemical equation, the chemistry file has to be inc #include "chemistry/simplebiominreactions.hh" // chemical reactions  -Additionally the TypeTag of your chemistry file needs to be set in the problem file, within the class ExerciseFourBioMinProblem: +Additionally the TypeTag of your chemistry file needs to be set in the problem file, within the class ExerciseFourBioMinProblem: c++ using Chemistry = typename Dumux::SimpleBiominReactions; @@ -82,7 +82,7 @@ using Chemistry = typename Dumux::SimpleBiominReactionsgetAnalyticalVelocityX(), "analyticalV_x");  @@ -145,11 +145,9 @@ stokesVtkWriter.addField(stokesProblem->getAnalyticalVelocityX(), "analyticalV_x After re-compiling and re-running the executable, we should be able to see also the analytical solution of $v_x$ on the free flow domain. Play around with the grid resolution to see how that affects the velocity profile. -__Task C: Cange shape of interface__ +__Task C: Change the shape of interface__ -Now we want to include a non-flat interface between the two domains. We use dune-subgrid to construct -two grids for the two domains from one common host grid. Comment out lines 96-106 in exerciseinterfacecouplingffpm.cc and comment lines 114-149 in the same file. This will instantiate a host grid and define two helper lambda functions that are used to choose elements from to host grid for the respective sub grid. In the given case, -the domain is split in two haves, separated by a sinusoidal interface. +Now we want to include a non-flat interface between the two domains. We use dune-subgrid to construct two grids for the two domains from one common host grid. To do so, open main.cc in the subfolder interface again and search for TODO: dumux-course-task 1.C. Comment out the first code block and uncomment the second. This will instantiate a host grid and define two helper lambda functions that are used to choose elements from to host grid for the respective sub grid. In the given case, the domain is split in two haves, separated by a sinusoidal interface. cpp auto elementSelectorStokes = [&](const auto& element) @@ -185,7 +183,9 @@ values.setCouplingNeumann(Indices::momentumYBalanceIdx); cpp values.setCouplingNeumann(scvf.directionIndex());  -The same if true for the BJS condition, however, here we need to consider the tangential direction: +in main.cc in the subfolder interface. + +The same is true for the BJS condition, however, here we need to consider the tangential direction: cpp values.setBJS(1 - scvf.directionIndex());  @@ -219,7 +219,7 @@ Although a 2p2c system is plugged in, we still want to simulate the same situati The following changes have to be made in the porous-medium model (models/porousmediumsubproblem.hh): * Include the 2pnc model: include the respective headers and inherit from the new model TwoPNC * Exchange the spatial parameters for the 1-phase system by those for a 2-phase system (hint: two occurrences). -* Since two phases are involved now, we do not need to use the OnePAdapter anymore. Change to property of the FluidSystem such that H2OAir is used directly. +* Since two phases are involved now, we do not need to use the OnePAdapter anymore. Change to property of the FluidSystem such that H2OAir is used directly. Afterwards, set the transportCompIdx to Indices::switchIdx. One big difference between the 1p and 2p model is, that the primary variables for which @@ -237,21 +237,19 @@ struct Formulation In contrast to the formulation, which stays the same during one simulation, the meaning of the primary variables may vary during one simulation. -In the case we are investigating, we want to use the gas pressure and the liquid saturation as primary variables. +In the case under investigation, we want to use the gas pressure and the liquid saturation as primary variables. However, if only the gas phase is present, the liquid saturation is always zero. In this case, the chosen formulation will set the given value as the mole fraction of water vapor in the gas phase. * To tell to program which phases are present in which parts of the domain at the beginning of the simulation, - you have to call values.setState(MY_PHASE_PRESENCE); in initialAtPos(). Have a look at the indices.hh - in the 2pnc model (as the 2p2c model is a special case of the 2pnc model) to figure out which is the correct value of MY_PHASE_PRESENCE for the presence of - a gas-phase only (hint: the numbering of phase indices begins with 0, the numbering of the phase presence states begins - with 1. Take a look at your formulation to find out which phase index to use for the gas phase.) + you have to call values.setState(MY_PHASE_PRESENCE); in initialAtPos(). MY_PHASE_PRESENCE should be replaced with the correct value for the case where only a gas-phase is present. + Have a look at the indices.hh in the 2pnc model (as the 2p2c model is a special case of the 2pnc model) in the subfolder porousmediumflow in your DuMuX directory. (hint: the numbering of phase indices begins with 0, the numbering of the phase presence states begins with 1. Take a look at your formulation to find out which phase index to use for the gas phase.) __Task B: Add output__: In the next step, we want to add some output to the simulation. First we want to know the water mass in the (porous-medium) system. Therefore, we evaluate the storage term of the water component. -* Have a look at the function evaluateWaterMassStorageTerm() in the porous medium subproblem. +* Have a look at the function evaluateWaterMassStorageTerm() in the porousmediumsubproblem.hh. Then implement a calculation of the total water mass: $\sum_{\alpha \in \textrm{g,l}} \left( \phi S_\alpha X^\text{w}_\alpha \varrho_\alpha V_\textrm{scv} \right)$. Afterwards, adapt the method init() such that the variable initialWaterContent_ is initialized correctly using the evaluateWaterMassStorageTerm() method and assign that value also to the variable lastWaterMass_. @@ -300,9 +298,9 @@ describe an algorithm to switch the primary variables, if phases should appear o Now you are able to simulate a complete drying of the porous medium. -### 4. Use a turbulence model in the free flow domain +### 3. Use a turbulence model in the free flow domain -Several RANS turbulence models are implemented in DuMuX. +Several RANS turbulence models are implemented in DuMux. This part of the exercise consists of the following steps: * replacing the Navier-Stokes model by the zero equation turbulence model, * switching to a symmetry boundary condition, @@ -355,7 +353,7 @@ These dynamic interactions are to be updated by calling cpp stokesProblem->updateDynamicWallProperties(stokesSol);  -in the time loop (after // update dynamic wall properties). +in the time loop (after // Update dynamic wall properties). Compile and run your new coupled problem and take a look at the results in Paraview. In addition to the standard variables and parameters, you can now analyze turbulence model specific quantities diff --git a/exercises/exercise-coupling-ff-pm/interface/freeflowsubproblem.hh b/exercises/exercise-coupling-ff-pm/interface/freeflowsubproblem.hh index 4e579e2d43aa4b9f89a3d89fbe308fc3b71539a7..8c22118b3e92e7aff777ea609a2673b4f506c2f6 100644 --- a/exercises/exercise-coupling-ff-pm/interface/freeflowsubproblem.hh +++ b/exercises/exercise-coupling-ff-pm/interface/freeflowsubproblem.hh @@ -25,9 +25,9 @@ #include -// TODO: dumux-course-task +// TODO: dumux-course-task 1.C //****** uncomment for the last exercise *****// -// #include +// #include #include #include @@ -64,7 +64,7 @@ struct Grid using Scalar = GetPropType; using TensorGrid = Dune::YaspGrid<2, Dune::TensorProductCoordinates >; -// TODO: dumux-course-task +// TODO: dumux-course-task 1.C //****** comment out for the last exercise *****// using type = TensorGrid; @@ -161,8 +161,8 @@ public: const auto& globalPos = scvf.dofPosition(); - // TODO: dumux-course-task - // change the boundary conditions here as described in the exercise + // TODO: dumux-course-task 1.A + // Change the boundary conditions here as described in the exercise if(onUpperBoundary_(globalPos)) { values.setDirichlet(Indices::velocityXIdx); @@ -181,7 +181,14 @@ public: { values.setCouplingNeumann(Indices::conti0EqIdx); values.setCouplingNeumann(Indices::momentumYBalanceIdx); + // TODO: dumux-course-task 1.B + // Replace Dirichlet BC with Beavers-Joseph-Saffman slip condition for the tangential momentum balance values.setDirichlet(Indices::velocityXIdx); // assume no slip on interface + + // TODO: dumux-course-task 1.C + // set the Beaver-Joseph-Saffman slip condition for the tangential momentum balance equation, + // consider orientation of face automatically + } return values; @@ -251,6 +258,8 @@ public: { PrimaryVariables values(0.0); values[Indices::velocityYIdx] = -1e-6 * globalPos[0] * (this->gridGeometry().bBoxMax()[0] - globalPos[0]); + // TODO: dumux-course-task 1.A + // Set fixed pressures on the left and right boundary return values; } diff --git a/exercises/exercise-coupling-ff-pm/interface/main.cc b/exercises/exercise-coupling-ff-pm/interface/main.cc index 1e3b4908a8cd614688286c700fba830a8281e401..9e70dca7f07fa75ce2a3c507a6b2e348be5f764a 100644 --- a/exercises/exercise-coupling-ff-pm/interface/main.cc +++ b/exercises/exercise-coupling-ff-pm/interface/main.cc @@ -88,8 +88,8 @@ int main(int argc, char** argv) try using DarcyTypeTag = Properties::TTag::DarcyOneP; - - // TODO: dumux-course-task: comment-out this section for the last exercise **************** // + //TODO: dumux-course-task 1.C + // ******************** comment-out this section for the last exercise **************** // // create two individual grids (from the given grid file or the input file) // for both sub-domains @@ -209,6 +209,7 @@ int main(int argc, char** argv) try StaggeredVtkOutputModule stokesVtkWriter(*stokesGridVariables, stokesSol, stokesName); GetPropType::initOutputModule(stokesVtkWriter); + //TODO: dumux-course-task 1.B //****** uncomment the add analytical solution of v_x *****// // stokesVtkWriter.addField(stokesProblem->getAnalyticalVelocityX(), "analyticalV_x"); diff --git a/exercises/exercise-coupling-ff-pm/interface/porousmediumsubproblem.hh b/exercises/exercise-coupling-ff-pm/interface/porousmediumsubproblem.hh index 848178a05bccf34f73d0679ce7cdec9b4feb1dcb..2a9e2bf58ad049479f26e015186fef99f56242c2 100644 --- a/exercises/exercise-coupling-ff-pm/interface/porousmediumsubproblem.hh +++ b/exercises/exercise-coupling-ff-pm/interface/porousmediumsubproblem.hh @@ -26,9 +26,9 @@ #include -// TODO: dumux-course-task +// TODO: dumux-course-task 1.C //****** uncomment for the last exercise *****// -// #include +// #include #include diff --git a/exercises/exercise-coupling-ff-pm/models/porousmediumsubproblem.hh b/exercises/exercise-coupling-ff-pm/models/porousmediumsubproblem.hh index e4845cfb66aac5a61d114d56d10d035d3dd5f954..2d3b64fd76f1b92c7d178d2306ed8d543d3e0752 100644 --- a/exercises/exercise-coupling-ff-pm/models/porousmediumsubproblem.hh +++ b/exercises/exercise-coupling-ff-pm/models/porousmediumsubproblem.hh @@ -33,8 +33,11 @@ #include #include - +// TODO: dumux-course-task 2.A +// Include 2pnc model here #include +// TODO: dumux-course-task 2.A +// Include spatial params for a 2-phase system #include "../1pspatialparams.hh" namespace Dumux @@ -46,6 +49,8 @@ namespace Properties { // Create new type tags namespace TTag { + // TODO: dumux-course-task 2.A + // Change to property of the FluidSystem such that H2OAir is used directly. struct DarcyOnePNC { using InheritsFrom = std::tuple; }; } // end namespace TTag @@ -77,8 +82,14 @@ struct EffectiveDiffusivityModel template struct Grid { using type = Dune::YaspGrid<2>; }; +// TODO: dumux-course-task 2.A +// Define new formulation for primary variables here. + + // Set the spatial paramaters type template +// TODO: dumux-course-task 2.A +// Adapt the spatial params here. struct SpatialParams { using type = OnePSpatialParams, GetPropType>; }; @@ -113,6 +124,8 @@ class PorousMediumSubProblem : public PorousMediumFlowProblem conti0EqIdx = Indices::conti0EqIdx, pressureIdx = Indices::pressureIdx, phaseIdx = 0, + // TODO: dumux-course-task 2.A + // set the transportCompIdx to Indices::switchIdx. transportCompIdx = 1 }; @@ -152,7 +165,11 @@ public: template void init(const SolutionVector& curSol, const GridVariables& gridVariables) - { } + { + // TODO: dumux-course-task 2.B + // Initialize initialWaterContent_ and assign that to lastWaterMass_. + + } template void postTimeStep(const SolutionVector& curSol, @@ -196,7 +213,9 @@ public: for (auto&& scv : scvs(fvGeometry)) { // const auto& volVars = elemVolVars[scv]; - // insert calculation of the water mass here + + // TODO: dumux-course-task 2.B + // Insert calculation of the water mass here waterMass += 0.0; } } @@ -237,7 +256,9 @@ public: if (!couplingManager().isCoupledEntity(CouplingManager::darcyIdx, scvf)) continue; - NumEqVector flux(0.0); // use "massCouplingCondition" from the couplingManager here + // TODO: dumux-course-task 2.B + // Use "massCouplingCondition" from the couplingManager here + NumEqVector flux(0.0); x.push_back(scvf.center()[0]); y.push_back(flux[transportCompIdx]); @@ -355,6 +376,10 @@ public: static const Scalar stokesPressure = getParamFromGroup("Stokes", "Problem.Pressure"); PrimaryVariables values(0.0); + + // TODO: dumux-course-task 2.A + // Declare here which phases are present. + values[Indices::pressureIdx] = stokesPressure; values[transportCompIdx] = moleFraction_; return values; diff --git a/exercises/exercise-coupling-ff-pm/turbulence/freeflowsubproblem.hh b/exercises/exercise-coupling-ff-pm/turbulence/freeflowsubproblem.hh index 346167057bcc5021f0aa17ceb280e7ec44556019..d4aec3fa7e516582b484679133e7f3ec38fa6d89 100644 --- a/exercises/exercise-coupling-ff-pm/turbulence/freeflowsubproblem.hh +++ b/exercises/exercise-coupling-ff-pm/turbulence/freeflowsubproblem.hh @@ -29,6 +29,8 @@ #include #include +// TODO: dumux-course-task 3.A +// Include headers for compositional zero equation turbulence model here. #include #include @@ -41,6 +43,8 @@ namespace Properties { // Create new type tags namespace TTag { + // TODO: dumux-course-task 3.A + // Change the entry in the StokesZeroEq definition accordingly. struct StokesZeroEq { using InheritsFrom = std::tuple; }; } // end namespace TTag @@ -80,6 +84,8 @@ struct EnableGridVolumeVariablesCache { static cons * \brief The free-flow sub problem */ template +// TODO: dumux-course-task 3.A +// Adapt the inheritance of the problem class. class FreeFlowSubProblem : public NavierStokesProblem { using ParentType = NavierStokesProblem; @@ -181,6 +187,8 @@ public: if (onUpperBoundary_(globalPos)) { + // TODO: dumux-course-task 3.B + // Replace all conditions here with symmetric BCs. values.setDirichlet(Indices::velocityXIdx); values.setDirichlet(Indices::velocityYIdx); values.setNeumann(Indices::conti0EqIdx); @@ -262,6 +270,12 @@ public: const CouplingManager& couplingManager() const { return *couplingManager_; } + // TODO: dumux-course-task 3.A + // Tell the turbulence model, where the walls are located + + // TODO: dumux-course-task 3.B + // Remove the condition onUpperBoundary_(globalPos) from the isOnWallAtPos(globalPos) + /*! * \name Volume terms */ @@ -285,6 +299,8 @@ public: values[Indices::velocityXIdx] = refVelocity(); values[Indices::temperatureIdx] = refTemperature(); + // TODO: dumux-course-task 3.B + // Remove the condition onUpperBoundary_(globalPos) here. if(onUpperBoundary_(globalPos) || onLowerBoundary_(globalPos)) values[Indices::velocityXIdx] = 0.0; diff --git a/exercises/exercise-coupling-ff-pm/turbulence/main.cc b/exercises/exercise-coupling-ff-pm/turbulence/main.cc index ac198a94997ca90e3fc799f7133ab2149932da47..5f1da8e2f37b41eedf32b619c65fbab83e1ba4a7 100644 --- a/exercises/exercise-coupling-ff-pm/turbulence/main.cc +++ b/exercises/exercise-coupling-ff-pm/turbulence/main.cc @@ -161,8 +161,11 @@ int main(int argc, char** argv) try couplingManager->init(stokesProblem, darcyProblem, sol); - // TODO: update static wall properties - // TODO: update dynamic wall properties + // TODO: dumux-course-task 3.A + // Update static wall properties + + // TODO: dumux-course-task 3.A + // Update dynamic wall properties // the grid variables using StokesGridVariables = GetPropType; @@ -218,7 +221,8 @@ int main(int argc, char** argv) try // make the new solution the old solution solOld = sol; - // TODO: update dynamic wall properties + // TODO: dumux-course-task 3.A + // Update dynamic wall properties // post time step treatment of Darcy problem darcyProblem->postTimeStep(sol[darcyIdx], *darcyGridVariables, timeLoop->timeStepSize()); diff --git a/exercises/exercise-dunemodule/README.md b/exercises/exercise-dunemodule/README.md index e396be75f52aef55968f14630c6c1e0ea5898028..a12cfa33d29871cd79cbdad2fc19468508f2706d 100644 --- a/exercises/exercise-dunemodule/README.md +++ b/exercises/exercise-dunemodule/README.md @@ -21,7 +21,7 @@ workflow to develop code on top of DuMuX. * a version at your choice (the version of your project, not of dumux.) * your email address -

+

@@ -33,7 +33,7 @@ The following command will configure your new module You need to run this command in the folder with content dumux, dumux-course, dune-common, dune-geometry, dune-grid, dune-istl, etc.  needs to be replaced (please replace the angle brackets also) by an options file, e.g., by ./dumux/cmake.opts. Have a look at the comments in this file to see how you can adapt it to your needs. -

+

### Task 3: Create a new test case within your new DuMuX module
@@ -77,7 +77,7 @@ cd appl ./test_1p_compressible_stationary_tpfa params.input  -

+

### Task 4: Create a new GitLab project
diff --git a/exercises/exercise-fluidsystem/2pproblem.hh b/exercises/exercise-fluidsystem/2pproblem.hh index 28a36b1ed86c5fe8d29faa41487070f14fa13cb4..995075b0d3d2579776e1ce25041c0f8508735de5 100644 --- a/exercises/exercise-fluidsystem/2pproblem.hh +++ b/exercises/exercise-fluidsystem/2pproblem.hh @@ -44,6 +44,8 @@ #include // The components that will be created in this exercise +// TODO: dumux-course-task 2.2 +//****** Include the corresponding header for the task *****// #include "components/myincompressiblecomponent.hh" // #include "components/mycompressiblecomponent.hh" @@ -94,10 +96,10 @@ private: using Scalar = GetPropType; using TabulatedH2O = Components::TabulatedComponent>; using LiquidWaterPhase = typename FluidSystems::OnePLiquid; - /*! - * Uncomment first line and comment second line for using the incompressible component - * Uncomment second line and comment first line for using the compressible component - */ + + // TODO: dumux-course-task 2.2 + //****** Select the corresponding component for the task *****// + // Uncomment first line and comment second line for using the compressible component using LiquidMyComponentPhase = typename FluidSystems::OnePLiquid >; // using LiquidMyComponentPhase = typename FluidSystems::OnePLiquid >; diff --git a/exercises/exercise-fluidsystem/README.md b/exercises/exercise-fluidsystem/README.md index df8f82a0e684dad95bad420d57c675da6ee15e2e..438ce7b4c86bc5c1b2a20b48215790babe912b4b 100644 --- a/exercises/exercise-fluidsystem/README.md +++ b/exercises/exercise-fluidsystem/README.md @@ -1,7 +1,6 @@ -# Exercise Fluidsystem +# Exercise Fluidsystem (DuMuX Course) -The aim of this exercise is to get familiar with the _DuMuX_ way of implementing new components (fluids) and fluid systems (mixtures). In the scope of this exercise, a new fictitious component is implemented -(exercise fluidsystem a) as well as its mixture with water (exercise fluidsystem b). +The aim of this exercise is to get familiar with the _DuMux_ way of implementing new components (fluids) and fluid systems (mixtures). In the scope of this exercise, a new fictitious component is implemented (Section 2) as well as its mixture with water (Section 3). ## Problem set-up @@ -91,9 +90,8 @@ This fluid system expects __phases__ as input and so far we have only included t #include  -which creates a _liquid phase_ from a given component. Finally, using all of the included classes we set the fluid system property by choosing that -the water phase is liquid (OnePLiquid) and consists of the tabulated water component, and -the other phase is liquid as well and consists of the incompressible fictitious component. Both will make up the immiscible fluid system (TwoPImmiscible): +which creates a _liquid phase_ from a given component. Finally, using all of the included classes we set the fluid system property by choosing that the water phase is liquid (OnePLiquid) and consists of the tabulated water component, and +the other phase is liquid as well and consists of the incompressible fictitious component. Both will make up the immiscible fluid system (TwoPImmiscible): c++ @@ -105,10 +103,10 @@ private: using Scalar = GetPropType; using TabulatedH2O = Components::TabulatedComponent>; using LiquidWaterPhase = typename FluidSystems::OnePLiquid; - /*! - * Uncomment first line and comment second line for using the incompressible component - * Uncomment second line and comment first line for using the compressible component - */ + + // TODO: dumux-course-task 2.2 + //****** Select the corresponding component for the task *****// + // Uncomment first line and comment second line for using the compressible component using LiquidMyComponentPhase = typename FluidSystems::OnePLiquid >; // using LiquidMyComponentPhase = typename FluidSystems::OnePLiquid >; @@ -164,7 +162,7 @@ We now want to implement a pressure-dependent density for our component. Open th $\displaystyle \rho_{MyComp} = \rho_{min} + \frac{ \rho_{max} - \rho_{min} }{ 1 + \rho_{min}*e^{-1.0*k*(\rho_{max} - \rho_{min})*p} } $ -where $p$ is the pressure and $\rho_{min} = 1440 $, $\rho_{max} = 1480 $ and $k = 5 \cdot 10^{-7} $. Also, make sure the header is included in the 2pproblem.hh file by uncommenting line 54. Furthermore, the new component has to be set as a liquid phase in the fluid system, i.e. comment line 109 and uncomment line 110. The density distribution of this phase (rhoN) at the final simulation time should look like this: +where $p$ is the pressure and $\rho_{min} = 1440 $, $\rho_{max} = 1480 $ and $k = 5 \cdot 10^{-7} $. Also, make sure the header is included in the 2pproblem.hh file by uncommenting the corresponding line. Furthermore, the new component has to be set as a liquid phase in the fluid system. To do so, search for TODO: dumux-course-task 2.2. Comment out the corresponding line and uncomment the other. The density distribution of this phase (rhoN) at the final simulation time should look like this: ![](../extradoc/exercise-fluidsystem_a_solution2.png) @@ -224,7 +222,7 @@ Under the assumption that one molecule of MyCompressibleComponent displaces ex $ \rho_{w} = \frac{ \rho_{w, pure} }{ M_{H_2O} }*(M_{H_2O}*x_{H_2O} + M_{MyComponent}*x_{MyComponent}) $ -Implement this dependency in the density() method in the fluid system. In order to compile and execute the program run +Implement this dependency in the density() method in the fluid system. In order to compile and execute the program, run the following commands: bash cd build-cmake/exercises/exercise-fluidsystem @@ -255,7 +253,7 @@ int wettingPhaseAtPos(const GlobalPosition& globalPos) const }  -Change this function such that the the phase of our new component is the wetting phase __only__ within the lenses. Execute the program of task 3 again: +Change this function such that the phase of our new component is the wetting phase __only__ within the lenses. Execute the program of task 3 again: bash cd build-cmake/exercises/exercise-fluidsystem diff --git a/exercises/exercise-fluidsystem/components/mycompressiblecomponent.hh b/exercises/exercise-fluidsystem/components/mycompressiblecomponent.hh index 927f046897324dfd2ebd94cd1eb2bc483f793515..ee8dc42c89e87e5fdfea9c3fb22810cd0968b4be 100644 --- a/exercises/exercise-fluidsystem/components/mycompressiblecomponent.hh +++ b/exercises/exercise-fluidsystem/components/mycompressiblecomponent.hh @@ -50,12 +50,7 @@ public: static std::string name() { return "MyCompressibleComponent"; } - /*! - * TODO: Copy the methods implemented in MyIncompressibleComponent and substitute - * the density calculation by the expression given in the exercise description. - */ - - /*! + /*! * \brief Returns true if the liquid phase is assumed to be compressible */ static constexpr bool liquidIsCompressible() @@ -66,7 +61,10 @@ public: */ static Scalar molarMass() { - // TODO: replace the line below by a meaningful return statement + // TODO: dumux-course-task 2.2 + // Copy the methods implemented in MyIncompressibleComponent and substitute + // the density calculation by the expression given in the exercise description. + // Replace the line below by a meaningful return statement DUNE_THROW(Dune::NotImplemented, "Todo: implement molar mass"); } @@ -79,7 +77,8 @@ public: */ static Scalar liquidDensity(Scalar temperature, Scalar pressure) { - // TODO: replace the line below by a meaningful return statement + // TODO: dumux-course-task 2.2: + // Replace the line below by a meaningful return statement DUNE_THROW(Dune::NotImplemented, "Todo: implement liquid density"); } @@ -104,7 +103,8 @@ public: */ static Scalar liquidViscosity(Scalar temperature, Scalar pressure) { - // TODO: replace the line below by a meaningful return statement + // TODO: dumux-course-task 2.2: + // Replace the line below by a meaningful return statement DUNE_THROW(Dune::NotImplemented, "Todo: implement liquid viscosity"); } @@ -116,7 +116,8 @@ public: */ static Scalar vaporPressure(Scalar t) { - // TODO: replace the line below by a meaningful return statement + // TODO: dumux-course-task 3 + // Replace the line below by a meaningful return statement DUNE_THROW(Dune::NotImplemented, "Todo: implement vapour pressure"); } }; diff --git a/exercises/exercise-fluidsystem/components/myincompressiblecomponent.hh b/exercises/exercise-fluidsystem/components/myincompressiblecomponent.hh index 37b04dad5c56457a9f1c5fe615d195040b650917..fa6074b27cd367f4c09bf1d7c187cc52e281ff52 100644 --- a/exercises/exercise-fluidsystem/components/myincompressiblecomponent.hh +++ b/exercises/exercise-fluidsystem/components/myincompressiblecomponent.hh @@ -49,10 +49,6 @@ public: static std::string name() { return "MyIncompressibleComponent"; } - /*! - * TODO: Implement the methods for the component data given in the exercise description. - */ - /*! * \brief Returns true if the liquid phase is assumed to be compressible */ @@ -64,7 +60,9 @@ public: */ static Scalar molarMass() { - // TODO: replace the line below by a meaningful return statement + // TODO: dumux-course-task 2.1 + // Implement the methods for the component data given in the exercise description. + // Replace the line below by a meaningful return statement DUNE_THROW(Dune::NotImplemented, "Todo: implement molarMass()"); } @@ -77,7 +75,9 @@ public: */ static Scalar liquidDensity(Scalar temperature, Scalar pressure) { - // TODO: replace the line below by a meaningful return statement + // TODO: dumux-course-task 2.1 + // Implement the methods for the component data given in the exercise description. + // Replace the line below by a meaningful return statement DUNE_THROW(Dune::NotImplemented, "Todo: implement liquidDensity()"); } @@ -102,7 +102,9 @@ public: */ static Scalar liquidViscosity(Scalar temperature, Scalar pressure) { - // TODO: replace the line below by a meaningful return statement + // TODO: dumux-course-task 2.1 + // Implement the methods for the component data given in the exercise description. + // Replace the line below by a meaningful return statement DUNE_THROW(Dune::NotImplemented, "Todo: implement liquidViscosity()"); } }; diff --git a/exercises/exercise-fluidsystem/fluidsystems/h2omycompressiblecomponent.hh b/exercises/exercise-fluidsystem/fluidsystems/h2omycompressiblecomponent.hh index 62965b2a29cab549becbdc54de506701e1aff5e3..f0ae0ea0f4fb361b8d767caf768738ea979fd0eb 100644 --- a/exercises/exercise-fluidsystem/fluidsystems/h2omycompressiblecomponent.hh +++ b/exercises/exercise-fluidsystem/fluidsystems/h2omycompressiblecomponent.hh @@ -51,7 +51,7 @@ class H2OMyCompressibleComponent { using ThisType = H2OMyCompressibleComponent; using Base = Dumux::FluidSystems::Base; - + public: using H2O = H2OType; using MyCompressibleComponent = Dumux::MyCompressibleComponent; @@ -229,9 +229,9 @@ public: // Scalar x_H2O = fluidState.moleFraction(phase0Idx, H2OIdx); // Scalar x_myComp = fluidState.moleFraction(phase0Idx, NAPLIdx); - /*! - * TODO: implement the composition-dependent water density from the exercise sheet. - */ + // TODO: dumux-course-task 3 + // Implement the composition-dependent water density from the exercise sheet. + DUNE_THROW(Dune::NotImplemented, "Todo: implement composition-dependent density"); } else diff --git a/exercises/exercise-fluidsystem/spatialparams.hh b/exercises/exercise-fluidsystem/spatialparams.hh index 1eda4bb1c1a1fe9d6d12f6be026b0c86dfb6a0a5..b3caeaec556a62b86b6033c63e697889476541e9 100644 --- a/exercises/exercise-fluidsystem/spatialparams.hh +++ b/exercises/exercise-fluidsystem/spatialparams.hh @@ -144,6 +144,10 @@ public: // Our fluid system is H2OMyCompressibleComponent // We want to define water as the wetting phase in // the entire domain (see fluid system for the phase indices) + + // TODO: dumux-course-task 4 + // Adapt the following line so that the phase of our new component is + // the wetting phase, only within the lenses. return FluidSystem::phase0Idx; } diff --git a/exercises/exercise-fractures/README.md b/exercises/exercise-fractures/README.md index 8fb0703c86821555daddb311e873c746221ff527..c5610c9cbbb52b48c0b44bf87f67bd333435bb94 100644 --- a/exercises/exercise-fractures/README.md +++ b/exercises/exercise-fractures/README.md @@ -155,7 +155,8 @@ BoundaryTypes interiorBoundaryTypes(const Element& element, const SubControlVolu // the interior boundary conditions to Dirichlet. // IMPORTANT: Note that you will never be asked to set any values at the interior boundaries! // This simply chooses a different interface condition! - // TODO Task C: Change coupling conditions! + // TODO dumux-course-task C + // Change coupling conditions! values.setAllDirichlet(); return values; @@ -180,7 +181,7 @@ Physical Line(1) = {6,7,9,11,12,13,14,15,16,17,18,19,20,21,23,25}; Physical Line(2) = {8,10,22,24,26};  -We now want to give all fracture elements that are tagged with domain marker 2 the properties for barriers and assign the parameters for open fractures to all other elements. The domain markers are read from the grid file and can be obtained from the GridManager subsequent to grid creation. The main file of this exercise has been implemented such that these markers are already passed to the spatial parameters of the sub-domains (see main.cc, lines 120-132). In the spatial parameters you will find a convenience function which allows you to obtain the domain marker for a given element (see fracturespatialparams.hh): +We now want to give all fracture elements that are tagged with domain marker 2 the properties for barriers and assign the parameters for open fractures to all other elements. The domain markers are read from the grid file and can be obtained from the GridManager subsequent to grid creation. The main file of this exercise has been implemented such that these markers are already passed to the spatial parameters of the sub-domains (see main.cc, search for // pass the model parameter group to the spatial params). In the spatial parameters you will find a convenience function which allows you to obtain the domain marker for a given element (see fracturespatialparams.hh): cpp //! returns the domain marker for an element @@ -188,7 +189,7 @@ int getElementDomainMarker(const Element& element) const { return gridDataPtr_->getElementDomainMarker(element); }  -The domain markers are also already added to the output (see main.cc, lines 195-199). To visualize them, open any of your previously produced results with _Paraview_ and take a look at them by selecting __domainMarker__. +The domain markers are also already added to the output (see main.cc, search for // add domain markers to output). To visualize them, open any of your previously produced results with _Paraview_ and take a look at them by selecting __domainMarker__. Adjust the functions for permeability, porosity and material law parameters in the fracturespatialparams.hh file such that they are selected depending on the domain marker of the elements. You will see in the results that the pressure jump across the first vertical fracture is now lower than before, because there are highly permeable fractures crossing it, allowing for a pressure release into the other parts of the domain. diff --git a/exercises/exercise-fractures/fractureproblem.hh b/exercises/exercise-fractures/fractureproblem.hh index 76493b12be18099eb3b963b34ae94033ac4b01ed..2e2c2daf63aadb19e5118bfd70f73e6a9b7ffe54 100644 --- a/exercises/exercise-fractures/fractureproblem.hh +++ b/exercises/exercise-fractures/fractureproblem.hh @@ -140,7 +140,8 @@ public: // However, there is one fracture reaching the top boundary. For this // fracture tip we set Dirichlet Bcs as in the matrix domain - // TODO Task A: Change boundary conditions + // TODO dumux-course-task A + // Change boundary conditions if (globalPos[1] > this->gridGeometry().bBoxMax()[1] - 1e-6) values.setAllDirichlet(); diff --git a/exercises/exercise-fractures/fracturespatialparams.hh b/exercises/exercise-fractures/fracturespatialparams.hh index 76edd2287504b6cfb043307e38076c086780854b..3431f3514265d4b1da41c203449aeb4e464d16e7 100644 --- a/exercises/exercise-fractures/fracturespatialparams.hh +++ b/exercises/exercise-fractures/fracturespatialparams.hh @@ -98,7 +98,8 @@ public: const SubControlVolume& scv, const ElementSolution& elemSol) const { - // TODO Task B: change fracture properties + // TODO dumux-course-task B + // Change fracture properties return permeability_; } @@ -108,7 +109,8 @@ public: const SubControlVolume& scv, const ElementSolution& elemSol) const { - // TODO Task B: change fracture properties + // TODO dumux-course-task B + // Change fracture properties return porosity_; } @@ -118,7 +120,8 @@ public: const SubControlVolume& scv, const ElementSolution& elemSol) const { - // TODO Task B: change fracture properties + // TODO dumux-course-task B + // Change fracture properties return materialLawParams_; } diff --git a/exercises/exercise-fractures/matrixproblem.hh b/exercises/exercise-fractures/matrixproblem.hh index 07920241a9dd0673e1caf9c11c0ecbbad9e88d32..1eb67c1dbf69088db203ff15f8a83e68d13e50b9 100644 --- a/exercises/exercise-fractures/matrixproblem.hh +++ b/exercises/exercise-fractures/matrixproblem.hh @@ -144,7 +144,8 @@ public: // we consider buoancy-driven upwards migration of nitrogen and set // Dirichlet BCs on the top and bottom boundary - // TODO Task A: Change boundary conditions and Dirichlet values! + // TODO dumux-course-task A + // Change boundary conditions and Dirichlet values! values.setAllNeumann(); if (globalPos[1] < 1e-6 || globalPos[1] > this->gridGeometry().bBoxMax()[1] - 1e-6) values.setAllDirichlet(); @@ -171,7 +172,8 @@ public: // the interior boundary conditions to Dirichlet. // IMPORTANT: Note that you will never be asked to set any values at the interior boundaries! // This simply chooses a different interface condition! - // TODO Task C: Change coupling conditions! + // TODO dumux-course-task C + // Change coupling conditions! values.setAllDirichlet(); return values; @@ -184,7 +186,8 @@ public: auto values = initialAtPos(globalPos); // nitrogen is in contact with the domain on the center half of the lower boundary - // TODO Task A: Change boundary conditions and Dirichlet values! + // TODO dumux-course-task A + // Change boundary conditions and Dirichlet values! if (globalPos[1] < 1e-6 && globalPos[0] > 25.0 && globalPos[0] < 75.0) values[saturationIdx] = boundarySaturation_; diff --git a/exercises/exercise-grids/README.md b/exercises/exercise-grids/README.md index 4edb8961866e45c106c1ec333a580807640e5e66..5ab7966c63e411c35f034c919cf9af2e01839f5e 100644 --- a/exercises/exercise-grids/README.md +++ b/exercises/exercise-grids/README.md @@ -1,5 +1,6 @@ # Exercise Grids (DuMuX course)
+ ## Problem set-up Here we will expand on what we've covered in the basics exercise, and the problem set up will remain the same. @@ -48,7 +49,7 @@ template struct Grid { using type = Dune::YaspGrid<2>; };  -This sets the Grid, which belongs to the Injection2pTypeTag type tag, and calls the manager with a basic YaspGrid in the second dimension. +This sets the Grid, which belongs to the Injection2pTypeTag type tag, and calls the manager with a basic YaspGrid in the second dimension. If we look in the grid manager header file, dumux/dumux/io/grid/gridmanager.hh, we will see that there are a few grid development options. Until now, we have used the most basic definition. @@ -136,9 +137,9 @@ Grading1 = 1.0 -1.3 1.3 1.0 DuMuX can also read in grids from external files. There are two supported file types: .dgf grids, and .msh grids. __.dgf__ grids (DUNE Grid Format grids) are developed within the dune environment and are often used in dumux tests. -(see: https://www.dune-project.org/doxygen/2.4.1/group__DuneGridFormatParser.html) +(see: [DUNE Grid Format grids](https://www.dune-project.org/doxygen/2.4.1/group__DuneGridFormatParser.html)) __.msh__ grids are made from the open-source Gmsh software, and is also supported by dumux. -(see: http://gmsh.info// and http://gmsh.info//doc/texinfo/gmsh.html) +(see: [Gmsh](http://gmsh.info//) and [Gmsh reference manual](http://gmsh.info//doc/texinfo/gmsh.html)) We can read in simple .dgf files using basic YaspGrids, but if we want to use more complicated external grids, we would need to use other grid formats, like UGGrid or ALUGrid. For this example, we can rewrite our Grid Properties to develop an ALUGrid. The grid manager class takes the following form: @@ -162,10 +163,3 @@ An example of an Unstructured grid is located in the grid/ folder (grid_unstr This grid is made up of triangles (simplices of dimension 2). This element type can be set in the grid properties section. * > __Task 5__: Change the grid property element type to include Dune::simplex instead of Dune::cube. Read in the unstructured grid via the input file and run the simulation. - - - - - - - diff --git a/exercises/exercise-grids/problem.hh b/exercises/exercise-grids/problem.hh index 855d4c9e2089ef729166c35393253a6c71938ba0..8995c5dac203ee7a34e42fbab368ba897bcbda8e 100644 --- a/exercises/exercise-grids/problem.hh +++ b/exercises/exercise-grids/problem.hh @@ -51,9 +51,14 @@ struct Injection2pCC { using InheritsFrom = std::tuple // Set the grid type template struct Grid { using type = Dune::YaspGrid<2>; }; -// TODO: Task 2: Replace the above Grid Property definition with a more flexible grid (Use Dune::TensorProductCoordinates) -// TODO: Task 4: Replace the above Grid Property definition to read in a external structured grid via a .msh file (Use Dune::ALUGrid and Dune:cube) -// TODO: Task 5: Replace the above Grid Property definition to read in a external unstructured grid via a .msh file (Use Dune::ALUGrid and Dune::simplex) +// TODO: dumux-course-task 2 +//Replace the above Grid Property definition with a more flexible grid (Use Dune::TensorProductCoordinates) + +// TODO: dumux-course-task 4 +// Replace the above Grid Property definition to read in a external structured grid via a .msh file (Use Dune::ALUGrid and Dune:cube) + +// TODO: dumux-course-task 5 +// Replace the above Grid Property definition to read in a external unstructured grid via a .msh file (Use Dune::ALUGrid and Dune::simplex) // Set the problem property template diff --git a/exercises/exercise-mainfile/1pproblem.hh b/exercises/exercise-mainfile/1pproblem.hh index 1f15312a001e12ca95892de4f824c4019af0043e..1b7133376bc2ddbf248bf4bdf78978ccc34417ad 100644 --- a/exercises/exercise-mainfile/1pproblem.hh +++ b/exercises/exercise-mainfile/1pproblem.hh @@ -36,7 +36,7 @@ #include -// TODO: dumux-course-task +// TODO: dumux-course-task 3 // uncomment the incompressiblelocalresidual which is a specialization of the standard immisible localresidual for one phase incompressible cases and provides an analytic jacobian. // #include @@ -84,7 +84,7 @@ public: using type = FluidSystems::OnePLiquid >; }; -// TODO: dumux-course-task +// TODO: dumux-course-task 3 // set the OneP Incompressible local residual for the OnePIncompressible type tag. This provides an analytic jacobian to be used for the analytic solution. Change that by setting: // template // struct LocalResidual { using type = OnePIncompressibleLocalResidual; }; diff --git a/exercises/exercise-mainfile/README.md b/exercises/exercise-mainfile/README.md index 1630d4d94aeba69ce163c09663f7bd6d2f10db57..8119e960db3738378a35581f6fbb759b4a99a8b7 100644 --- a/exercises/exercise-mainfile/README.md +++ b/exercises/exercise-mainfile/README.md @@ -1,14 +1,15 @@ # Exercise Mainfiles (DuMuX course)
+ ## Problem set-up -This exercise will make you familiar the program sequence in DuMux and how different levels of complexity can be realized in the main file according to the complexity of your physical problem. +This exercise will make you familiar the program sequence in DuMuX and how different levels of complexity can be realized in the main file according to the complexity of your physical problem. In order to do so, there are three examples of one phase flow problems. Two examples (a and b) are stationary problems and the third example (c) is an instationary problem. -The stationary examples differ in the fluidssystems they are using which means they differ in the fluid properties (e.g. density, thermal conductivity etc). The first problem (a) uses an incompressible fluid which means that the density does not change when pressure changes. This makes it possible to solve the system linearly. The second problem uses a compressible fluid, that means the density is a function of pressure and we need to use a nonlinear solver. +The stationary examples differ in the fluidssystems they are using, which means they differ in the fluid properties (e.g. density, thermal conductivity etc). The first problem (a) uses an incompressible fluid, i.e. the density does not change when pressure changes. This makes it possible to solve the system linearly. The second problem uses a compressible fluid, that means the density is a function of pressure and we need to use a nonlinear solver. -To summarize the problems differ in: +To summarize, the problems differ in: * exercise mainfile a: a one-phase incompressible, stationary problem * exercise mainfile b: a one-phase compressible, stationary problem * exercise mainfile c: a one-phase compressible, instationary problem @@ -17,7 +18,7 @@ The problem set-up for all three examples is always the same: It is a two dimens -In the beginning there is a uniform pressure of $1\cdot 10^5 Pa$ in the whole domain. On the top and the bottom border dirichlet boundary conditions are set with a pressure of $1\cdot 10^5 Pa$ on top and $2 \cdot 10^5 Pa$ on the bottom. At the sides there is no in- or outflow and there are no source terms. +In the beginning, there is a uniform pressure of $1\cdot 10^5 Pa$ in the whole domain. On the top and the bottom border, dirichlet boundary conditions are set with a pressure of $1\cdot 10^5 Pa$ on top and $2 \cdot 10^5 Pa$ on the bottom. At the sides, there is no in- or outflow and there are no source terms. ## Preparing the exercise @@ -37,25 +38,25 @@ Locate all the files you will need for this exercise * The __input file__ for the __compressible, stationary__ problem: exercise_mainfile_b.input * The __input file__ for the __compressible, instationary__ problem: exercise_mainfile_c.input -Please pay special attention to the similarities and differences in the three main files. The first main file is solved linearly and does not need a newton solver or any other nonlinear solver method. The second problem is a nonlinear problem and uses newton's method to solve the system. The third problem is nonlinear and additionally instationary. Therefore a time loop needs to be included in the main file. +Please pay special attention to the similarities and differences in the three main files. The first main file is solved linearly and does not need a newton solver or any other nonlinear solver method. The second problem is a nonlinear problem and uses newton's method to solve the system. The third problem is nonlinear and additionally instationary. Therefore, a time loop needs to be included in the main file. -The general structure of any main file in DuMux is: +The general structure of any main file in DuMuX is: -* the specific problem TypeTag is defined for the problem. This example shows the TypeTag for the CompressibleProblem +* the specific problem TypeTag is defined for the problem. This example shows the TypeTag for the CompressibleProblem: c++ // define the type tag for this problem using TypeTag = Properties::TTag::OnePCompressible;  -The TypeTag is created in the 1pproblem.hh. There you can see that it inherits from the __OneP__ and additionally from the __CCTpfaModel__ which defines the discretization method, which is in this case the cell-centered tpfa method. +The TypeTag is created in the 1pproblem.hh. There, you can see that it inherits from the __OneP__ and additionally from the __CCTpfaModel__. The latter defines the discretization method, which is in this case the cell-centered tpfa method. -* a gridmanager tries to create the grid either from a grid file or the input file +* A gridmanager tries to create the grid either from a grid file or the input file: c++ GridManager> gridManager; gridManager.init();  -* we create the finite volume grid geometry, the problem, solutionvector and the gridvariables and initialize them. Additionally we initialize the vtkoutput. Each model has a predefined model specific output with relevant parameters for that model. +* We create the finite volume grid geometry, the problem, solution vector and the grid variables and initialize them. Additionally, we initialize the vtk output. Each model has a predefined model specific output with relevant parameters for that model: c++ // create the finite volume grid geometry @@ -85,7 +86,7 @@ IOFields::initOutputModule(vtkWriter); //!< Add model specific output fields vtkWriter.write(0.0);  -* then we need to assemble and solve the system. Depending on the problem this can be done with a linear solver or with a nonlinear solver. If the problem is time dependent we additionally need a time loop. An example for that is given in exercise_1p_c: +* Then, we need to assemble and solve the system. Depending on the problem, this can be done with a linear solver or a nonlinear solver. If the problem is time dependent, we additionally need a time loop. An example for that is given in exercise1pcmain.cc: c++ // get some time loop parameters @@ -144,7 +145,7 @@ timeLoop->start(); do timeLoop->finalize(leafGridView.comm());  -

+

### Task 2: Compiling and running an executable
@@ -157,7 +158,7 @@ cd ../../build-cmake/exercises/exercise-mainfile * Compile all three executables exercise_mainfile_a and exercise_mainfile_b and exercise_mainfile_c bash -make exercise_1p_a exercise_1p_b exercise_1p_c +make exercise_mainfile_a exercise_mainfile_b exercise_mainfile_c  * Execute the three problems and inspect the result @@ -168,23 +169,23 @@ make exercise_1p_a exercise_1p_b exercise_1p_c ./exercise_mainfile_c  -* you can look at the results (e.g. for the first example) with paraview: +* You can look at the results (e.g. for the first example) with paraview: bash paraview 1p_incompressible_stationary.pvd  -

+

-In the input file exercise_1p_a.input you will see that there is a variable BaseEpsilon. This defines the base for the epsilon used in the numeric differentiation. If that value is too small, you will see that the solution of the numeric differentiation is not correct. Change that value to $1 \cdot 10^{-15}$ and have a look at the solution. +In the input file exercise_1p_a.input, you will see that there is a variable BaseEpsilon. This defines the base for the epsilon used in the numeric differentiation. If that value is too small, you will see that the solution of the numeric differentiation is not correct. Change that value to $1 \cdot 10^{-15}$ and have a look at the solution. -For the incompressible one phase problem it is possible to also have an analytic solution method. Then the epsilon does not play a role anymore since the derivatives are calculated analytically. To implement that follow the directions in the exercise1pamain.cc and the 1pproblem.hh marked by: +For the incompressible one phase problem, it is also possible to have an analytic solution method. In this case, the epsilon does not play a role anymore, since the derivatives are calculated analytically. To implement that, follow the tips in the exercise1pamain.cc and the 1pproblem.hh marked by: c++ -// TODO: dumux-course-task +// TODO: dumux-course-task 3  -For the analytic solution of your immiscible problem you need analytic solutions for the derivatives of the jacobian. For that we have a special local residual, the OnePIncompressibleLocalResidual which provides that. You just need to include incompressiblelocalresidual.hh in your 1pproblem.hh and use that instead of the immisciblelocalresidual.hh which is used as a standard for all immiscible models. +For the analytic solution of your immiscible problem, you need analytic solutions for the derivatives of the jacobian. For that, we have a special local residual, the OnePIncompressibleLocalResidual which provides that. You just need to include incompressiblelocalresidual.hh in your 1pproblem.hh and use that instead of the immisciblelocalresidual.hh which is used as a default for all immiscible models. -Additionally you need to set the differentiation method in the main file exercise1pamain.cc to analytic. +Additionally, you need to set the differentiation method in the main file exercise1pamain.cc to analytic. diff --git a/exercises/exercise-mainfile/exercise1pamain.cc b/exercises/exercise-mainfile/exercise1pamain.cc index 6cfe2dc436d398cd9966f8f5a56aba7861400134..208ffef7611493470f2741cb9e1a68cd2aeab1c4 100644 --- a/exercises/exercise-mainfile/exercise1pamain.cc +++ b/exercises/exercise-mainfile/exercise1pamain.cc @@ -105,11 +105,11 @@ int main(int argc, char** argv) try using IOFields = GetPropType; IOFields::initOutputModule(vtkWriter); //!< Add model specific output fields vtkWriter.write(0.0); - + Dune::Timer timer; - // TODO: dumux-course-task - // change the differentiation method to analytic by changing from DiffMethod::numeric to DiffMethod::analytic + // TODO: dumux-course-task 3 + // Change the differentiation method to analytic by changing from DiffMethod::numeric to DiffMethod::analytic // the assembler for stationary problems using Assembler = FVAssembler; diff --git a/exercises/exercise-properties/README.md b/exercises/exercise-properties/README.md index 8419bf83630fdd23dfda70c22bf4e2370a11d17f..b676f489e1be8c491f08f250214f1006e0aeace4 100644 --- a/exercises/exercise-properties/README.md +++ b/exercises/exercise-properties/README.md @@ -1,5 +1,6 @@ # Exercise Properties (DuMuX course)
+ ## Problem set-up The problem setup is identical to the two-phase incompressible test from DuMux. @@ -23,7 +24,7 @@ Locate all the files you will need for this exercise * a custom __local residual__ in: mylocalresidual.hh -

+

### Task 2: Compiling and running the program
@@ -44,15 +45,14 @@ make exercise_properties bash ./exercise_properties  -Note: Because the input file has the same name as the -executable, DuMux will find it automatically. +Note: Because the input file has the same name as the executable, DuMux will find it automatically. -

+

### Task 3: Implement a custom local residual
-Types that are properties can be changed on the problem level by using the property system. In the following task we implement our own 2p local residual, i.e. the class that computes the element residual in every Newton iteration. The file mylocalresidual.hh contains a copy of the original local residual class used for all immiscible models renamed to template class MyLocalResidual. +Types that are properties can be changed on the problem level by using the property system. In the following task, we implement our own 2p local residual, i.e. the class that computes the element residual in every Newton iteration. The file mylocalresidual.hh contains a copy of the original local residual class used for all immiscible models renamed to template class MyLocalResidual. * Make DuMux use this new local residual by including the header mylocalresidual.hh and setting the corresponding property in the Property namespace in the file problem.hh @@ -69,7 +69,6 @@ Simplify the original local residual by using the assumption that only incompres * Eliminate the density from the computeStorage and the computeFlux methods. -* Adapt the relevant routine in the problem file such that volume instead of mass is injected. The density of the employed NAPL is 1460 kg/m^3 . For a first try, you can use the hardcoded value. +* Adapt the relevant routine in the problem file such that volume instead of mass is injected. The density of the employed NAPL is 1460 kg/m3 . For a first try, you can use the hardcoded value. * Generalize your approach by using the component's liquidDensity(t, p) function instead of the hardcoded value. - diff --git a/exercises/exercise-properties/mylocalresidual.hh b/exercises/exercise-properties/mylocalresidual.hh index 67c390b47508fd2fb050b5aebdc55efde89c9781..d6c75f8194845305c15bc6b0bfcb5c81fee731eb 100644 --- a/exercises/exercise-properties/mylocalresidual.hh +++ b/exercises/exercise-properties/mylocalresidual.hh @@ -70,7 +70,8 @@ public: * \note The volVars can be different to allow computing * the implicit euler time derivative here */ - // TODO: eliminate density from the storage term + // TODO: dumux-course-task 3 + // Eliminate density from the storage term NumEqVector computeStorage(const Problem& problem, const SubControlVolume& scv, const VolumeVariables& volVars) const @@ -105,7 +106,8 @@ public: * \param scvf The sub control volume face to compute the flux on * \param elemFluxVarsCache The cache related to flux compuation */ - // TODO: eliminate the density from the flux term + // TODO: dumux-course-task + // Eliminate the density from the flux term NumEqVector computeFlux(const Problem& problem, const Element& element, const FVElementGeometry& fvGeometry, diff --git a/exercises/exercise-properties/problem.hh b/exercises/exercise-properties/problem.hh index 23c67f484de6a5b54df9b534770293fd94744460..1fec90825e3314a2c9d025a35bd007f8ebda1f09 100644 --- a/exercises/exercise-properties/problem.hh +++ b/exercises/exercise-properties/problem.hh @@ -40,7 +40,8 @@ #include "spatialparams.hh" -// TODO: include the local residual header +// TODO: dumux-course-task 3 +// Include the local residual header namespace Dumux { // forward declarations @@ -61,7 +62,9 @@ struct Grid { using type = Dune::YaspGrid<2>; template struct Problem { using type = TwoPTestProblem; }; -// TODO: use MyLocalResidual as LocalResidual +// TODO: dumux-course-task 3 +// Use MyLocalResidual as LocalResidual + // Set the fluid system template diff --git a/exercises/exercise-runtimeparams/README.md b/exercises/exercise-runtimeparams/README.md index 78875fd5816874d7d5c4bb238e7dd276ffd66950..595f2bb62db96869d02dcfe4845b652fd4aef0c0 100644 --- a/exercises/exercise-runtimeparams/README.md +++ b/exercises/exercise-runtimeparams/README.md @@ -1,5 +1,6 @@ # Exercise Runtime Parameters (DuMuX course)
+ ## Problem set-up Here we will expand on what we've covered in the basics exercise, and the problem set up will remain the same. @@ -47,9 +48,9 @@ EntryPressureAquitard = 4.5e4 # Pa PermeabilityAquifer = 1e-12 # m^2 EntryPressureAquifer = 1e4 # Pa  -When a parameter is defined directly within your program, you'll need to recompile your program everytime you change the value. When a parameter is passed via the input file, this is not the case. If we decided to vary the entry pressure in our geologic units a few times via the parameters listed above, there would be no need to recompile between simulation runs. +When a parameter is defined directly within your program, you'll need to recompile your program every time you change the value. When a parameter is passed via the input file, this is not the case. If we decided to vary the entry pressure in our geologic units a few times via the parameters listed above, there would be no need to recompile between simulation runs. -* > __Task 1__: Change the aquitard's entry pressure in the input file to a lower value and compare the results with the previous solution. You don't need to recompile the executable. +* > __Task 1__: Change the aquitard's entry pressure in the input file to a lower value and compare the results with the previous solution. You do not need to recompile the executable.

### Task 2: Setting a variable to collect a runtime parameter @@ -64,8 +65,7 @@ values[Indices::conti0EqIdx + FluidSystem::N2Idx]= -1e-4/FluidSystem::molarMass( values[Indices::conti0EqIdx + FluidSystem::H2OIdx] = 0.0;  -This parameter may need to change, and if we choose to always change this within the class, -we will need to recompile every time. +This parameter may need to change, and if we choose to always change this within the class, we will need to recompile every time. Instead of hard defining this parameter within the function, we can set a variable to read into our parameter tree via the input file and use this in our function instead. To do this, there are two functions defined in dumux/dumux/common/parameters.hh, getParam() and getParamFromGroup(). They use the following format: diff --git a/exercises/exercise-runtimeparams/problem.hh b/exercises/exercise-runtimeparams/problem.hh index 8cd8ddec8a711a246856dd84f0c53845f4f15631..922e375d7608963f839c65d9f4b8a18a15203ffd 100644 --- a/exercises/exercise-runtimeparams/problem.hh +++ b/exercises/exercise-runtimeparams/problem.hh @@ -131,9 +131,14 @@ public: aquiferDepth_ = getParam("Problem.AquiferDepth"); // the duration of the injection, units: second injectionDuration_ = getParamFromGroup("Problem","InjectionDuration"); - //TODO: Task 2: Set a variable "TotalAreaSpecificInflow" to read in a value from the parameter tree via the input file - //TODO: Task 3: Set a default value for the above parameter. - //TODO: Task 4: Provide output describing where the parameter value comes from using parameter bool functions. + // TODO: dumux-course-task 2 + // Set a variable "TotalAreaSpecificInflow" to read in a value from the parameter tree via the input file + + // TODO: dumux-course-task 3 + // Set a default value for the above parameter. + + // TODO: dumux-course-task 4 + // Provide output describing where the parameter value comes from using parameter bool functions. } /*! @@ -213,7 +218,8 @@ public: { // inject nitrogen. negative values mean injection // units kg/(s*m^2) - //TODO: Task 2: incorporate "totalAreaSpecificInflow_" into the injection boundary condition + // TODO: dumux-course-task 2 + // Incorporate "totalAreaSpecificInflow_" into the injection boundary condition values[Indices::conti0EqIdx + FluidSystem::N2Idx]= -1e-4/FluidSystem::molarMass(FluidSystem::N2Idx); values[Indices::conti0EqIdx + FluidSystem::H2OIdx] = 0.0; } @@ -262,7 +268,8 @@ private: std::string name_; //! Problem name Scalar aquiferDepth_; //! Depth of the aquifer in m Scalar injectionDuration_; //! Duration of the injection in seconds - //TODO: Task 2: Set a variable "totalAreaSpecificInflow_" to read in a value from the parameter tree via the input file + // TODO: dumux-course-task 2 + // Set a variable "totalAreaSpecificInflow_" to read in a value from the parameter tree via the input file Scalar time_; };