Skip to content

Commit 04431ed

Browse files
committed
Outsource film diffusion Jacobian
1 parent 137d7fe commit 04431ed

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

src/libcadet/model/GeneralRateModelDG.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ class GeneralRateModelDG : public UnitOperationBase
709709

710710
delete[] invBetaP;
711711

712-
calcFluxJacobians(secIdx);
712+
_parDiffOp.calcFilmDiffJacobian(secIdx, idxr.offsetCp(), idxr.offsetC(), _disc.nPoints, static_cast<double>(_colPorosity), &_parTypeVolFrac[0], _globalJac);
713713

714714
return _globalJac.isCompressed(); // check if the jacobian estimation fits the pattern
715715
}

src/libcadet/model/parts/ParticleDiffusionOperatorDG.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,6 +2297,64 @@ namespace parts
22972297
return true;
22982298
}
22992299

2300+
int ParticleDiffusionOperatorDG::calcFilmDiffJacobian(unsigned int secIdx, const int offsetCp, const int offsetC, const int nBulkPoints, const double colPorosity, const active* const parTypeVolFrac, Eigen::SparseMatrix<double, RowMajor>& globalJac, bool outliersOnly)
2301+
{
2302+
for (unsigned int type = 0; type < _nParType; type++)
2303+
{
2304+
// lifting matrix entry for exact integration scheme depends on metrics for sphere and cylinder
2305+
double exIntLiftContribution = static_cast<double>(_Ir[_offsetMetric[type] + _nParElem[type] - 1][_nParNode[type] - 1]);
2306+
if (_parGeomSurfToVol[type] == _SurfVolRatioSlab)
2307+
exIntLiftContribution = 1.0;
2308+
2309+
// Ordering of diffusion:
2310+
// sec0type0comp0, sec0type0comp1, sec0type0comp2, sec0type1comp0, sec0type1comp1, sec0type1comp2,
2311+
// sec1type0comp0, sec1type0comp1, sec1type0comp2, sec1type1comp0, sec1type1comp1, sec1type1comp2, ...
2312+
active const* const filmDiff = getSectionDependentSlice(_filmDiffusion, _nComp * _nParType, secIdx) + type * _nComp;
2313+
2314+
linalg::BandedEigenSparseRowIterator jacCl(globalJac, offsetC);
2315+
linalg::BandedEigenSparseRowIterator jacCp(globalJac, offsetCp + (_nParPoints[type] + _nParPoints[type] - 1) * strideParNode(type));
2316+
2317+
for (unsigned int blk = 0; blk < nBulkPoints; blk++)
2318+
{
2319+
for (unsigned int comp = 0; comp < _nComp; comp++, ++jacCp, ++jacCl) {
2320+
// add Cl on Cl entries (added since these entries are also touched by bulk jacobian)
2321+
// row: already at bulk phase. already at current node and component.
2322+
// col: already at bulk phase. already at current node and component.
2323+
if (!outliersOnly)
2324+
jacCl[0] += static_cast<double>(filmDiff[comp]) * (1.0 - colPorosity) / colPorosity
2325+
* _parGeomSurfToVol[type] / static_cast<double>(_parRadius[type])
2326+
* static_cast<double>(parTypeVolFrac[type + blk * _nParType]);
2327+
// add Cl on Cp entries (added since these entries are also touched by bulk jacobian)
2328+
// row: already at bulk phase. already at current node and component.
2329+
// col: go to current particle phase entry.
2330+
jacCl[jacCp.row() - jacCl.row()] = -static_cast<double>(filmDiff[comp]) * (1.0 - colPorosity) / colPorosity
2331+
* _parGeomSurfToVol[type] / static_cast<double>(_parRadius[type])
2332+
* static_cast<double>(parTypeVolFrac[type + blk * _nParType]);
2333+
2334+
2335+
unsigned int entry = jacCp.row();
2336+
for (int node = _parPolyDeg[type]; node >= 0; node--, jacCp -= strideParNode(type)) {
2337+
// row: already at particle. Already at current node and liquid state.
2338+
// col: original entry at outer node.
2339+
if (!outliersOnly) // Cp on Cb
2340+
jacCp[entry - jacCp.row()]
2341+
+= static_cast<double>(filmDiff[comp]) * 2.0 / static_cast<double>(_deltaR[_offsetMetric[type]]) * _parInvMM[_offsetMetric[type] + _nParElem[type] - 1](node, _nParNode[type] - 1) * exIntLiftContribution / static_cast<double>(_parPorosity[type]) / static_cast<double>(_poreAccessFactor[type * _nComp + comp]);
2342+
// row: already at particle. Already at current node and liquid state.
2343+
// col: go to current bulk phase.
2344+
jacCp[jacCl.row() - jacCp.row()]
2345+
= -static_cast<double>(filmDiff[comp]) * 2.0 / static_cast<double>(_deltaR[_offsetMetric[type]]) * _parInvMM[_offsetMetric[type] + _nParElem[type] - 1](node, _nParNode[type] - 1) * exIntLiftContribution / static_cast<double>(_parPorosity[type]) / static_cast<double>(_poreAccessFactor[type * _nComp + comp]);
2346+
}
2347+
// set back iterator to first node as required by component loop
2348+
jacCp += _nParNode[type] * strideParNode(type);
2349+
}
2350+
if (blk < nBulkPoints - 1) // execute iteration statement only when condition is true in next loop.
2351+
jacCp += _strideBound[type] + (_nParPoints[type] - 1) * strideParNode(type);
2352+
}
2353+
}
2354+
2355+
return 1;
2356+
}
2357+
23002358
} // namespace parts
23012359

23022360
} // namespace model

src/libcadet/model/parts/ParticleDiffusionOperatorDG.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ namespace parts
223223

224224
void initializeDGjac(std::vector<double> parGeomSurfToVol);
225225

226+
int calcFilmDiffJacobian(unsigned int secIdx, const int offsetCp, const int offsetC, const int nBulkPoints, const double colPorosity, const active* const parTypeVolFrac, Eigen::SparseMatrix<double, RowMajor>& globalJac, bool outliersOnly = false);
227+
226228
int getParticleCoordinates(unsigned int parType, double* coords) const;
227229

228230
typedef Eigen::Triplet<double> T;

0 commit comments

Comments
 (0)