GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/porousmediumflow/2pnc/primaryvariableswitch.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 46 67 68.7%
Functions: 28 28 100.0%
Branches: 53 154 34.4%

Line Branch Exec Source
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 //
4 // SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 /*!
8 * \file
9 * \ingroup TwoPNCModel
10 * \brief The primary variable switch for the 2pnc model.
11 */
12
13 #ifndef DUMUX_2PNC_PRIMARY_VARIABLE_SWITCH_HH
14 #define DUMUX_2PNC_PRIMARY_VARIABLE_SWITCH_HH
15
16 #include <iostream>
17
18 #include <dumux/porousmediumflow/compositional/primaryvariableswitch.hh>
19 #include <dumux/porousmediumflow/2p/formulation.hh>
20
21 namespace Dumux {
22
23 /*!
24 * \ingroup TwoPNCModel
25 * \brief The primary variable switch controlling the phase presence state variable.
26 */
27 class TwoPNCPrimaryVariableSwitch
28 : public PrimaryVariableSwitch<TwoPNCPrimaryVariableSwitch>
29 {
30 using ParentType = PrimaryVariableSwitch<TwoPNCPrimaryVariableSwitch>;
31 friend ParentType;
32 public:
33 using ParentType::ParentType;
34
35 protected:
36 // perform variable switch at a degree of freedom location
37 template<class VolumeVariables, class IndexType, class GlobalPosition>
38 1899429 bool update_(typename VolumeVariables::PrimaryVariables& priVars,
39 const VolumeVariables& volVars,
40 IndexType dofIdxGlobal,
41 const GlobalPosition& globalPos)
42 {
43 using Scalar = typename VolumeVariables::PrimaryVariables::value_type;
44
45 using FluidSystem = typename VolumeVariables::FluidSystem;
46 static constexpr int phase0Idx = FluidSystem::phase0Idx;
47 static constexpr int phase1Idx = FluidSystem::phase1Idx;
48 static constexpr int comp0Idx = FluidSystem::comp0Idx;
49 static constexpr int comp1Idx = FluidSystem::comp1Idx;
50
51 static constexpr auto numComponents = VolumeVariables::numFluidComponents();
52 static constexpr bool useMoles = VolumeVariables::useMoles();
53 static_assert(useMoles || numComponents < 3, "!useMoles is only implemented for numComponents < 3.");
54 static constexpr auto numMajorComponents = VolumeVariables::numFluidPhases();
55 static constexpr auto formulation = VolumeVariables::priVarFormulation();
56 static_assert( (formulation == TwoPFormulation::p0s1 || formulation == TwoPFormulation::p1s0),
57 "Chosen TwoPFormulation not supported!");
58
59 using Indices = typename VolumeVariables::Indices;
60 static constexpr int switchIdx = Indices::switchIdx;
61
62 // evaluate primary variable switch
63 1899429 bool wouldSwitch = false;
64 1899429 int phasePresence = priVars.state();
65 1899429 int newPhasePresence = phasePresence;
66
67 //check if a primary variable switch is necessary
68
2/2
✓ Branch 0 taken 822496 times.
✓ Branch 1 taken 1076933 times.
1899429 if (phasePresence == Indices::bothPhases)
69 {
70 822496 Scalar Smin = 0; //saturation threshold
71
6/6
✓ Branch 0 taken 373 times.
✓ Branch 1 taken 822123 times.
✓ Branch 2 taken 373 times.
✓ Branch 3 taken 822123 times.
✓ Branch 4 taken 373 times.
✓ Branch 5 taken 822123 times.
2467488 if (this->wasSwitched_[dofIdxGlobal])
72 373 Smin = -0.01;
73
74 // if saturation of first phase is smaller 0: switch
75
4/4
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 822401 times.
✓ Branch 2 taken 95 times.
✓ Branch 3 taken 822401 times.
1644992 if (volVars.saturation(phase0Idx) <= Smin)
76 {
77 95 wouldSwitch = true;
78 // first phase has to disappear
79
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95 times.
95 if (this->verbosity() > 1)
80 std::cout << "First phase (" << FluidSystem::phaseName(phase0Idx) << ")"
81 << " disappears at dof " << dofIdxGlobal
82 << ", coordinates: " << globalPos
83 << ", S_" << FluidSystem::phaseName(phase0Idx) << ": " << volVars.saturation(phase0Idx)
84 << std::endl;
85 95 newPhasePresence = Indices::secondPhaseOnly;
86
87 // switch not depending on formulation, switch "S0" to "x10"
88 if(useMoles) // mole-fraction formulation
89 190 priVars[switchIdx] = volVars.moleFraction(phase1Idx, comp0Idx);
90 else // mass-fraction formulation
91 priVars[switchIdx] = volVars.massFraction(phase1Idx, comp0Idx);
92
93 // switch all secondary components to mole fraction in nonwetting phase
94 if(useMoles) // mole-fraction formulation
95
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
95 for (int compIdx = numMajorComponents; compIdx < numComponents; ++compIdx)
96 priVars[compIdx] = volVars.moleFraction(phase1Idx, compIdx);
97 else // mass-fraction formulation
98 for (int compIdx = numMajorComponents; compIdx < numComponents; ++compIdx)
99 priVars[compIdx] = volVars.massFraction(phase1Idx, compIdx);
100 }
101
102 // if saturation of second phase is smaller than 0: switch
103
4/4
✓ Branch 0 taken 293 times.
✓ Branch 1 taken 822108 times.
✓ Branch 2 taken 293 times.
✓ Branch 3 taken 822108 times.
1644802 else if (volVars.saturation(phase1Idx) <= Smin)
104 {
105 293 wouldSwitch = true;
106 // second phase has to disappear
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 293 times.
293 if (this->verbosity() > 1)
108 std::cout << "Second phase (" << FluidSystem::phaseName(phase1Idx) << ")"
109 << " disappears at dof " << dofIdxGlobal
110 << ", coordinates: " << globalPos
111 << ", S_" << FluidSystem::phaseName(phase1Idx) << ": " << volVars.saturation(phase1Idx)
112 << std::endl;
113 293 newPhasePresence = Indices::firstPhaseOnly;
114
115 // switch "S1" to "x01"
116 if(useMoles) // mole-fraction formulation
117 879 priVars[switchIdx] = volVars.moleFraction(phase0Idx, comp1Idx);
118 else // mass-fraction formulation
119 priVars[switchIdx] = volVars.massFraction(phase0Idx, comp1Idx);
120 }
121 }
122
2/2
✓ Branch 0 taken 1108 times.
✓ Branch 1 taken 1075825 times.
1076933 else if (phasePresence == Indices::secondPhaseOnly)
123 {
124 Scalar x0Max = 1;
125 Scalar x0Sum = 0;
126 // Calculate sum of mole fractions in the hypothetical first phase
127
2/2
✓ Branch 0 taken 2216 times.
✓ Branch 1 taken 1108 times.
3324 for (int compIdx = 0; compIdx < numComponents; compIdx++)
128 4432 x0Sum += volVars.moleFraction(phase0Idx, compIdx);
129
130
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 1068 times.
1108 if (x0Sum > x0Max)
131 40 wouldSwitch = true;
132
6/6
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 1040 times.
✓ Branch 2 taken 68 times.
✓ Branch 3 taken 1040 times.
✓ Branch 4 taken 68 times.
✓ Branch 5 taken 1040 times.
3324 if (this->wasSwitched_[dofIdxGlobal])
133 68 x0Max *= 1.02;
134
135 // first phase appears if sum is larger than one
136
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 1068 times.
1108 if (x0Sum/*sum of mole fractions*/ > x0Max/*1*/)
137 {
138
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if (this->verbosity() > 1)
139 std::cout << "Second phase (" << FluidSystem::phaseName(phase0Idx) << ")"
140 << " appears at dof " << dofIdxGlobal
141 << ", coordinates: " << globalPos
142 << ", sum x^i_" << FluidSystem::phaseName(phase0Idx) << ": " << x0Sum
143 << std::endl;
144 40 newPhasePresence = Indices::bothPhases;
145
146 // saturation of the first phase set to 0.0001 (if formulation TwoPFormulation::p1s0 and vice versa)
147 if (formulation == TwoPFormulation::p1s0)
148 priVars[switchIdx] = 0.0001;
149 else
150 40 priVars[switchIdx] = 0.9999;
151
152 // switch all secondary components back to first component mole fraction
153
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
40 for (int compIdx = numMajorComponents; compIdx < numComponents; ++compIdx)
154 priVars[compIdx] = volVars.moleFraction(phase0Idx,compIdx);
155 }
156 }
157
1/2
✓ Branch 0 taken 1075825 times.
✗ Branch 1 not taken.
1075825 else if (phasePresence == Indices::firstPhaseOnly)
158 {
159 Scalar x1Max = 1;
160 Scalar x1Sum = 0;
161
162 // Calculate sum of mole fractions in the hypothetical wetting phase
163
2/2
✓ Branch 0 taken 2791126 times.
✓ Branch 1 taken 1075825 times.
3866951 for (int compIdx = 0; compIdx < numComponents; compIdx++)
164 5582252 x1Sum += volVars.moleFraction(phase1Idx, compIdx);
165
166
2/2
✓ Branch 0 taken 343 times.
✓ Branch 1 taken 1075482 times.
1075825 if (x1Sum > x1Max)
167 343 wouldSwitch = true;
168
6/6
✓ Branch 0 taken 293 times.
✓ Branch 1 taken 1075532 times.
✓ Branch 2 taken 293 times.
✓ Branch 3 taken 1075532 times.
✓ Branch 4 taken 293 times.
✓ Branch 5 taken 1075532 times.
3227475 if (this->wasSwitched_[dofIdxGlobal])
169 293 x1Max *= 1.02;
170
171 // wetting phase appears if sum is larger than one
172
2/2
✓ Branch 0 taken 340 times.
✓ Branch 1 taken 1075485 times.
1075825 if (x1Sum > x1Max)
173 {
174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 340 times.
340 if (this->verbosity() > 1)
175 std::cout << "Second phase (" << FluidSystem::phaseName(phase1Idx) << ")"
176 << " appears at dof " << dofIdxGlobal
177 << ", coordinates: " << globalPos
178 << ", sum x^i_" << FluidSystem::phaseName(phase1Idx) << ": " << x1Sum
179 << std::endl;
180 340 newPhasePresence = Indices::bothPhases;
181 //saturation of the wetting phase set to 0.9999 (if formulation TwoPFormulation::pnsw and vice versa)
182 if (formulation == TwoPFormulation::p1s0)
183 82 priVars[switchIdx] = 0.9999;
184 else
185 598 priVars[switchIdx] = 0.0001;
186 }
187 }
188
189
2/2
✓ Branch 0 taken 771 times.
✓ Branch 1 taken 1898658 times.
1899429 priVars.setState(newPhasePresence);
190
4/4
✓ Branch 0 taken 771 times.
✓ Branch 1 taken 1898658 times.
✓ Branch 2 taken 771 times.
✓ Branch 3 taken 1898658 times.
3798858 this->wasSwitched_[dofIdxGlobal] = wouldSwitch;
191 1899429 return phasePresence != newPhasePresence;
192 }
193 };
194
195 } // end namespace Dumux
196
197 #endif
198