Skip to content

Commit fed831b

Browse files
committed
Refactor LRMP2D to generalized 2D column unit
1 parent 0e892ce commit fed831b

35 files changed

+20862
-1900
lines changed

src/libcadet/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,9 @@ if (ENABLE_DG)
229229
if (ENABLE_2D_MODELS)
230230
list (APPEND LIBCADET_SOURCES
231231
${CMAKE_SOURCE_DIR}/src/libcadet/model/parts/TwoDimensionalConvectionDispersionOperatorDG.cpp
232-
${CMAKE_SOURCE_DIR}/src/libcadet/model/LumpedRateModelWithPoresDG2D.cpp
233-
${CMAKE_SOURCE_DIR}/src/libcadet/model/LumpedRateModelWithPoresDG2D-LinearSolver.cpp
234-
${CMAKE_SOURCE_DIR}/src/libcadet/model/LumpedRateModelWithPoresDG2D-InitialConditions.cpp
232+
${CMAKE_SOURCE_DIR}/src/libcadet/model/ColumnModel2D.cpp
233+
${CMAKE_SOURCE_DIR}/src/libcadet/model/ColumnModel2D-LinearSolver.cpp
234+
${CMAKE_SOURCE_DIR}/src/libcadet/model/ColumnModel2D-InitialConditions.cpp
235235
)
236236
endif()
237237
endif()

src/libcadet/ModelBuilderImpl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ namespace cadet
4242
void registerGeneralRateModel2D(std::unordered_map<std::string, std::function<IUnitOperation*(UnitOpIdx, IParameterProvider&)>>& models);
4343
void registerMultiChannelTransportModel(std::unordered_map<std::string, std::function<IUnitOperation*(UnitOpIdx, IParameterProvider&)>>& models);
4444
#ifdef ENABLE_DG
45-
void registerLumpedRateModelWithPoresDG2D(std::unordered_map<std::string, std::function<IUnitOperation* (UnitOpIdx, IParameterProvider&)>>& models);
45+
void registerColumnModel2D(std::unordered_map<std::string, std::function<IUnitOperation* (UnitOpIdx, IParameterProvider&)>>& models);
4646
#endif
4747
#endif
4848

@@ -75,7 +75,7 @@ namespace cadet
7575
model::registerGeneralRateModel2D(_modelCreators);
7676
model::registerMultiChannelTransportModel(_modelCreators);
7777
#ifdef ENABLE_DG
78-
model::registerLumpedRateModelWithPoresDG2D(_modelCreators);
78+
model::registerColumnModel2D(_modelCreators);
7979
#endif
8080
#endif
8181

src/libcadet/model/LumpedRateModelWithPoresDG2D-InitialConditions.cpp renamed to src/libcadet/model/ColumnModel2D-InitialConditions.cpp

Lines changed: 374 additions & 378 deletions
Large diffs are not rendered by default.

src/libcadet/model/LumpedRateModelWithPoresDG2D-LinearSolver.cpp renamed to src/libcadet/model/ColumnModel2D-LinearSolver.cpp

Lines changed: 19 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// is available at http://www.gnu.org/licenses/gpl.html
1111
// =============================================================================
1212

13-
#include "model/LumpedRateModelWithPoresDG2D.hpp"
13+
#include "model/ColumnModel2D.hpp"
1414
#include "model/BindingModel.hpp"
1515
#include "model/parts/BindingCellKernel.hpp"
1616
#include "linalg/DenseMatrix.hpp"
@@ -97,7 +97,7 @@ namespace model
9797
* @param [in] simState State of the simulation (state vector and its time derivatives) at which the Jacobian is evaluated
9898
* @return @c 0 on success, @c -1 on non-recoverable error, and @c +1 on recoverable error
9999
*/
100-
int LumpedRateModelWithPoresDG2D::linearSolve(double t, double alpha, double outerTol, double* const rhs, double const* const weight,
100+
int ColumnModel2D::linearSolve(double t, double alpha, double outerTol, double* const rhs, double const* const weight,
101101
const ConstSimulationState& simState)
102102
{
103103
BENCH_SCOPE(_timerLinearSolve);
@@ -126,11 +126,11 @@ int LumpedRateModelWithPoresDG2D::linearSolve(double t, double alpha, double out
126126

127127
// rhs is passed twice but due to the values in jacA the writes happen to a different area of the rhs than the reads.
128128

129-
// Handle inlet DOFs: // todo backward flow.
130-
Eigen::Map<Eigen::Vector<double, Eigen::Dynamic>, 0, Eigen::InnerStride<Eigen::Dynamic>> rInlet(rhs, _disc.radNPoints * _disc.nComp, Eigen::InnerStride<Eigen::Dynamic>(idxr.strideColRadialNode()));
131-
Eigen::Map<Eigen::Vector<double, Eigen::Dynamic>, 0, Eigen::InnerStride<Eigen::Dynamic>> rInletDep(rhs + idxr.offsetC(), _convDispOp.axNNodes() * _disc.radNPoints * _disc.nComp, Eigen::InnerStride<Eigen::Dynamic>(idxr.strideColRadialNode()));
129+
// Handle inlet DOFs:
130+
Eigen::Map<Eigen::VectorXd> rInlet(rhs, _disc.radNPoints * _disc.nComp);
131+
Eigen::Map<Eigen::VectorXd> rInletDep(rhs + idxr.offsetC(), _convDispOp.axNNodes() * _disc.radNPoints * _disc.nComp);
132132

133-
rInletDep += _jacInlet * rInlet;
133+
rInletDep -= _jacInlet * rInlet;
134134

135135
// ==== Step 2: Solve system of pure DOFs
136136
// The result is stored in rhs (in-place solution)
@@ -162,7 +162,7 @@ int LumpedRateModelWithPoresDG2D::linearSolve(double t, double alpha, double out
162162
*
163163
* @param [in] alpha Value of \f$ \alpha \f$ (arises from BDF time discretization)
164164
*/
165-
void LumpedRateModelWithPoresDG2D::assembleDiscretizedGlobalJacobian(double alpha, Indexer idxr) {
165+
void ColumnModel2D::assembleDiscretizedGlobalJacobian(double alpha, Indexer idxr) {
166166

167167
// set to static (per section) jacobian
168168
_globalJacDisc = _globalJac;
@@ -173,14 +173,19 @@ void LumpedRateModelWithPoresDG2D::assembleDiscretizedGlobalJacobian(double alph
173173
// Add time derivatives to particles
174174
for (unsigned int parType = 0; parType < _disc.nParType; parType++)
175175
{
176-
linalg::BandedEigenSparseRowIterator jac(_globalJacDisc, idxr.offsetCp(ParticleTypeIndex{ parType }) - idxr.offsetC());
177-
178-
for (unsigned int j = 0; j < _disc.nBulkPoints; ++j)
176+
for (unsigned int colNode = 0; colNode < _disc.nBulkPoints; ++colNode)
179177
{
180-
addTimeDerivativeToJacobianParticleBlock(jac, idxr, alpha, parType); // Mobile and solid phase equations (advances jac accordingly)
178+
linalg::BandedEigenSparseRowIterator jac(_globalJacDisc, idxr.offsetCp(ParticleTypeIndex{ parType }, ParticleIndex{ colNode }) - idxr.offsetC());
179+
180+
for (unsigned int j = 0; j < _disc.nParPoints[parType]; ++j)
181+
{
182+
// Time derivative for mobile and solid phase equations (advances jac accordingly)
183+
addTimeDerivativeToJacobianParticleShell(jac, idxr, alpha, parType);
184+
}
181185
}
182186
}
183187
}
188+
184189
/**
185190
* @brief Adds Jacobian @f$ \frac{\partial F}{\partial \dot{y}} @f$ to bead rows of system Jacobian
186191
* @details Actually adds @f$ \alpha \frac{\partial F}{\partial \dot{y}} @f$, which is useful
@@ -191,40 +196,10 @@ void LumpedRateModelWithPoresDG2D::assembleDiscretizedGlobalJacobian(double alph
191196
* @param [in] alpha Value of \f$ \alpha \f$ (arises from BDF time discretization)
192197
* @param [in] parType Index of the particle type
193198
*/
194-
void LumpedRateModelWithPoresDG2D::addTimeDerivativeToJacobianParticleBlock(linalg::BandedEigenSparseRowIterator& jac, const Indexer& idxr, double alpha, unsigned int parType)
199+
void ColumnModel2D::addTimeDerivativeToJacobianParticleShell(linalg::BandedEigenSparseRowIterator& jac, const Indexer& idxr, double alpha, unsigned int parType)
195200
{
196-
// Mobile phase
197-
for (int comp = 0; comp < static_cast<int>(_disc.nComp); ++comp, ++jac)
198-
{
199-
// Add derivative with respect to dc_p / dt to Jacobian
200-
jac[0] += alpha;
201-
202-
const double invBetaP = (1.0 - static_cast<double>(_parPorosity[parType])) / (static_cast<double>(_poreAccessFactor[parType * _disc.nComp + comp]) * static_cast<double>(_parPorosity[parType]));
203-
204-
// Add derivative with respect to dq / dt to Jacobian
205-
const int nBound = static_cast<int>(_disc.nBound[parType * _disc.nComp + comp]);
206-
for (int i = 0; i < nBound; ++i)
207-
{
208-
// Index explanation:
209-
// -comp -> go back to beginning of liquid phase
210-
// + strideParLiquid() skip to solid phase
211-
// + offsetBoundComp() jump to component (skips all bound states of previous components)
212-
// + i go to current bound state
213-
jac[idxr.strideParLiquid() - comp + idxr.offsetBoundComp(ParticleTypeIndex{ parType }, ComponentIndex{ static_cast<unsigned int>(comp) }) + i] += alpha * invBetaP;
214-
}
215-
}
216-
217-
// Solid phase
218-
int const* const qsReaction = _binding[parType]->reactionQuasiStationarity();
219-
for (unsigned int bnd = 0; bnd < _disc.strideBound[parType]; ++bnd, ++jac)
220-
{
221-
// Add derivative with respect to dynamic states to Jacobian
222-
if (qsReaction[bnd])
223-
continue;
224-
225-
// Add derivative with respect to dq / dt to Jacobian
226-
jac[0] += alpha;
227-
}
201+
parts::cell::addTimeDerivativeToJacobianParticleShell<linalg::BandedEigenSparseRowIterator, true>(jac, alpha, static_cast<double>(_particles[parType]->getPorosity()), _disc.nComp, _disc.nBound + _disc.nComp * parType,
202+
_particles[parType]->getPoreAccessFactor(), _disc.strideBound[parType], _disc.boundOffset + _disc.nComp * parType, _binding[parType]->reactionQuasiStationarity());
228203
}
229204

230205
} // namespace model

0 commit comments

Comments
 (0)