Skip to content

Commit 50b853f

Browse files
committed
Deprecate collocation variant of DGSEM particle discretization (#411)
1 parent aeed290 commit 50b853f

4 files changed

+241
-825
lines changed

src/libcadet/model/GeneralRateModelDG-InitialConditions.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -303,15 +303,6 @@ void GeneralRateModelDG::consistentInitialState(const SimulationTime& simTime, d
303303

304304
Indexer idxr(_disc);
305305

306-
// initialization for inexact integration DG discretization of particle mass balance not supported. This would require the consideration of the additional algebraic constraints,
307-
// but the general performance (stiffness due to the additional algebraic constraints) of this scheme does not justify the effort here.
308-
for (unsigned int type = 0; type < _disc.nParType; type++) {
309-
if (_disc.parExactInt[type] == false) {
310-
LOG(Error) << "No consistent initialization for inexact integration DG discretization in particles (cf. par_exact_integration). If consistent initialization is required, change to exact integration.";
311-
return;
312-
}
313-
}
314-
315306
// Step 1: Solve algebraic equations
316307

317308
// Step 1a: Compute quasi-stationary binding model state

src/libcadet/model/GeneralRateModelDG-LinearSolver.cpp

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -189,33 +189,7 @@ void GeneralRateModelDG::assembleDiscretizedGlobalJacobian(double alpha, Indexer
189189

190190
linalg::BandedEigenSparseRowIterator jac(_globalJacDisc, idxr.offsetCp(ParticleTypeIndex{ parType }, ParticleIndex{ colNode }));
191191

192-
// If special case for inexact integration DG scheme:
193-
// Do not add time derivative to particle mass balance equation at inner particle boundary for mass balance(s)
194-
if (!_disc.parExactInt[parType] && _parGeomSurfToVol[parType] != _disc.SurfVolRatioSlab && _parCoreRadius[parType] == 0.0) {
195-
// we still need to add the derivative for the binding
196-
// move iterator to solid phase
197-
jac += idxr.strideParLiquid();
198-
// Solid phase
199-
for (unsigned int comp = 0; comp < _disc.nComp; ++comp) {
200-
for (unsigned int bnd = 0; bnd < _disc.nBound[parType * _disc.nComp + comp]; ++bnd, ++jac)
201-
{
202-
// Add derivative with respect to dynamic states to Jacobian
203-
if (_binding[parType]->reactionQuasiStationarity()[idxr.offsetBoundComp(ParticleTypeIndex{ parType }, ComponentIndex{ comp }) + bnd])
204-
continue;
205-
206-
// surface diffusion + kinetic binding -> additional DG-discretized mass balance equation for solid, for which the (inexact integration) discretization special case also holds
207-
else if (_hasSurfaceDiffusion[parType]
208-
&& static_cast<double>(getSectionDependentSlice(_parSurfDiffusion, _disc.strideBound[_disc.nParType], _disc.curSection)[_disc.nBoundBeforeType[parType] + getOffsetSurfDiff(parType, comp, bnd)]) != 0.0)
209-
continue;
210-
211-
// Add derivative with respect to dq / dt to Jacobian
212-
jac[0] += alpha;
213-
}
214-
}
215-
}
216-
else { // else, treat boundary node "normally"
217-
addTimeDerivativeToJacobianParticleShell(jac, idxr, alpha, parType);
218-
}
192+
addTimeDerivativeToJacobianParticleShell(jac, idxr, alpha, parType);
219193

220194
// compute time derivative of remaining points
221195
// Iterator jac has already been advanced to next shell

src/libcadet/model/GeneralRateModelDG.cpp

Lines changed: 7 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,10 @@ bool GeneralRateModelDG::configureModelDiscretization(IParameterProvider& paramP
186186

187187
std::vector<int> parPolyDeg(_disc.nParType);
188188
std::vector<int> ParNelem(_disc.nParType);
189-
std::vector<bool> parExactInt(_disc.nParType, true);
190189
if (firstConfigCall)
191190
{
192191
_disc.parPolyDeg = new unsigned int[_disc.nParType];
193192
_disc.nParCell = new unsigned int[_disc.nParType];
194-
_disc.parExactInt = new bool[_disc.nParType];
195193
_disc.parGSM = new bool[_disc.nParType];
196194
}
197195

@@ -206,12 +204,6 @@ bool GeneralRateModelDG::configureModelDiscretization(IParameterProvider& paramP
206204
if ((std::any_of(ParNelem.begin(), ParNelem.end(), [](int value) { return value < 1; })))
207205
throw InvalidParameterException("Particle number of elements must be at least 1!");
208206

209-
if(paramProvider.exists("PAR_EXACT_INTEGRATION"))
210-
parExactInt = paramProvider.getBoolArray("PAR_EXACT_INTEGRATION");
211-
212-
if ((std::any_of(parExactInt.begin(), parExactInt.end(), [](bool value) { return !value; })))
213-
LOG(Warning) << "Inexact integration method (cf. PAR_EXACT_INTEGRATION) in particles might add severe! stiffness to the system and disables consistent initialization!";
214-
215207
if (parPolyDeg.size() == 1)
216208
{
217209
// Multiplex number of particle shells to all particle types
@@ -232,16 +224,6 @@ bool GeneralRateModelDG::configureModelDiscretization(IParameterProvider& paramP
232224
throw InvalidParameterException("Field PAR_NELEM must have 1 or NPARTYPE (" + std::to_string(_disc.nParType) + ") entries");
233225
else
234226
std::copy_n(ParNelem.begin(), _disc.nParType, _disc.nParCell);
235-
if (parExactInt.size() == 1)
236-
{
237-
// Multiplex number of particle shells to all particle types
238-
for (unsigned int i = 0; i < _disc.nParType; ++i)
239-
std::fill(_disc.parExactInt, _disc.parExactInt + _disc.nParType, parExactInt[0]);
240-
}
241-
else if (parExactInt.size() < _disc.nParType)
242-
throw InvalidParameterException("Field PAR_EXACT_INTEGRATION must have 1 or NPARTYPE (" + std::to_string(_disc.nParType) + ") entries");
243-
else
244-
std::copy_n(parExactInt.begin(), _disc.nParType, _disc.parExactInt);
245227
}
246228
else if (paramProvider.exists("NPAR"))
247229
{
@@ -1366,9 +1348,6 @@ int GeneralRateModelDG::residualParticle(double t, unsigned int parType, unsigne
13661348

13671349
LinearBufferAllocator tlmAlloc = threadLocalMem.get();
13681350

1369-
// Special case: individual treatment of time derivatives in particle mass balance at inner particle boundary node
1370-
bool specialCase = !_disc.parExactInt[parType] && (_parGeomSurfToVol[parType] != _disc.SurfVolRatioSlab && _parCoreRadius[parType] == 0.0);
1371-
13721351
// Prepare parameters
13731352
active const* const parDiff = getSectionDependentSlice(_parDiffusion, _disc.nComp * _disc.nParType, secIdx) + parType * _disc.nComp;
13741353

@@ -1407,62 +1386,14 @@ int GeneralRateModelDG::residualParticle(double t, unsigned int parType, unsigne
14071386
);
14081387
const ColumnPosition colPos{ z, 0.0, r };
14091388

1410-
// Handle time derivatives, binding, dynamic reactions.
1411-
// Special case: Dont add time derivatives to inner boundary node for DG discretized mass balance equations.
1412-
// This can be achieved by setting yDot pointer to null before passing to residual kernel, and adding only the time derivative for dynamic binding
1413-
// TODO Check Treatment of reactions (do we need yDot then?)
1414-
if (cadet_unlikely(par == 0 && specialCase))
1415-
{
1416-
if (wantRes)
1417-
parts::cell::residualKernel<StateType, ResidualType, ParamType, parts::cell::CellParameters, linalg::BandedEigenSparseRowIterator, wantJac, true>(
1418-
t, secIdx, colPos, local_y, nullptr, local_res, jac, cellResParams, tlmAlloc // TODO Check Treatment of reactions (do we need yDot then?)
1419-
);
1420-
else
1421-
parts::cell::residualKernel<StateType, ResidualType, ParamType, parts::cell::CellParameters, linalg::BandedEigenSparseRowIterator, wantJac, false, false>(
1422-
t, secIdx, colPos, local_y, nullptr, local_res, jac, cellResParams, tlmAlloc // TODO Check Treatment of reactions (do we need yDot then?)
1423-
);
1424-
1425-
if (!wantRes)
1426-
continue;
1427-
1428-
if (cellResParams.binding->hasDynamicReactions() && local_yDot)
1429-
{
1430-
unsigned int idx = 0;
1431-
for (unsigned int comp = 0; comp < cellResParams.nComp; ++comp)
1432-
{
1433-
for (unsigned int state = 0; state < cellResParams.nBound[comp]; ++state, ++idx)
1434-
{
1435-
// Skip quasi-stationary fluxes
1436-
if (cellResParams.qsReaction[idx])
1437-
continue;
1438-
1439-
// For kinetic bindings and surface diffusion, we have an additional DG-discretized mass balance eq.
1440-
// -> add time derivate at inner bonudary node only without surface diffusion
1441-
else if (_hasSurfaceDiffusion[parType])
1442-
continue;
1443-
// Some bound states might still not be effected by surface diffusion
1444-
else if (parSurfDiff[idx] != 0.0)
1445-
continue;
1446-
1447-
// Add time derivative to solid phase
1448-
local_res[idxr.strideParLiquid() + idx] += local_yDot[idxr.strideParLiquid() + idx];
1449-
}
1450-
}
1451-
}
1452-
}
1389+
if (wantRes)
1390+
parts::cell::residualKernel<StateType, ResidualType, ParamType, parts::cell::CellParameters, linalg::BandedEigenSparseRowIterator, wantJac, true>(
1391+
t, secIdx, colPos, local_y, local_yDot, local_res, jac, cellResParams, tlmAlloc
1392+
);
14531393
else
1454-
{
1455-
if (wantRes)
1456-
parts::cell::residualKernel<StateType, ResidualType, ParamType, parts::cell::CellParameters, linalg::BandedEigenSparseRowIterator, wantJac, true>(
1457-
t, secIdx, colPos, local_y, local_yDot, local_res, jac, cellResParams, tlmAlloc
1458-
);
1459-
else
1460-
{
1461-
parts::cell::residualKernel<StateType, ResidualType, ParamType, parts::cell::CellParameters, linalg::BandedEigenSparseRowIterator, wantJac, false, false>(
1462-
t, secIdx, colPos, local_y, local_yDot, local_res, jac, cellResParams, tlmAlloc
1463-
);
1464-
}
1465-
}
1394+
parts::cell::residualKernel<StateType, ResidualType, ParamType, parts::cell::CellParameters, linalg::BandedEigenSparseRowIterator, wantJac, false, false>(
1395+
t, secIdx, colPos, local_y, local_yDot, local_res, jac, cellResParams, tlmAlloc
1396+
);
14661397

14671398
// Move rowiterator to next particle node
14681399
jac += idxr.strideParNode(parType);

0 commit comments

Comments
 (0)