@@ -246,44 +246,44 @@ namespace model
246246 };
247247 }
248248
249- int GeneralRateParticle::residual (double t, unsigned int secIdx, double const * yPar, double const * yBulk, double const * yDotPar, double * resPar, ColumnPosition colPos , linalg::BandedEigenSparseRowIterator& jacIt, LinearBufferAllocator tlmAlloc, WithoutParamSensitivity)
249+ int GeneralRateParticle::residual (double t, unsigned int secIdx, double const * yPar, double const * yBulk, double const * yDotPar, double * resPar, double * resBulk, columnPackingParameters packing , linalg::BandedEigenSparseRowIterator& jacIt, LinearBufferAllocator tlmAlloc, WithoutParamSensitivity)
250250 {
251251 if (resPar)
252252 {
253253 if (jacIt.data ())
254- return residualImpl<double , double , double , true , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, colPos , jacIt, tlmAlloc);
254+ return residualImpl<double , double , double , true , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, resBulk, packing , jacIt, tlmAlloc);
255255 else
256- return residualImpl<double , double , double , false , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, colPos , jacIt, tlmAlloc);
256+ return residualImpl<double , double , double , false , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, resBulk, packing , jacIt, tlmAlloc);
257257 }
258258 else if (jacIt.data ())
259- return residualImpl<double , double , double , true , false >(t, secIdx, yPar, yBulk, yDotPar, resPar, colPos , jacIt, tlmAlloc);
259+ return residualImpl<double , double , double , true , false >(t, secIdx, yPar, yBulk, yDotPar, resPar, resBulk, packing , jacIt, tlmAlloc);
260260 else
261261 return -1 ;
262262 }
263- int GeneralRateParticle::residual (double t, unsigned int secIdx, double const * yPar, double const * yBulk, double const * yDotPar, active* resPar, ColumnPosition colPos , linalg::BandedEigenSparseRowIterator& jacIt, LinearBufferAllocator tlmAlloc, WithParamSensitivity)
263+ int GeneralRateParticle::residual (double t, unsigned int secIdx, double const * yPar, double const * yBulk, double const * yDotPar, active* resPar, active* resBulk, columnPackingParameters packing , linalg::BandedEigenSparseRowIterator& jacIt, LinearBufferAllocator tlmAlloc, WithParamSensitivity)
264264 {
265265 if (jacIt.data ())
266- return residualImpl<double , active, active, true , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, colPos , jacIt, tlmAlloc);
266+ return residualImpl<double , active, active, true , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, resBulk, packing , jacIt, tlmAlloc);
267267 else
268- return residualImpl<double , active, active, false , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, colPos , jacIt, tlmAlloc);
268+ return residualImpl<double , active, active, false , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, resBulk, packing , jacIt, tlmAlloc);
269269 }
270- int GeneralRateParticle::residual (double t, unsigned int secIdx, active const * yPar, active const * yBulk, double const * yDotPar, active* resPar, ColumnPosition colPos , linalg::BandedEigenSparseRowIterator& jacIt, LinearBufferAllocator tlmAlloc, WithoutParamSensitivity)
270+ int GeneralRateParticle::residual (double t, unsigned int secIdx, active const * yPar, active const * yBulk, double const * yDotPar, active* resPar, active* resBulk, columnPackingParameters packing , linalg::BandedEigenSparseRowIterator& jacIt, LinearBufferAllocator tlmAlloc, WithoutParamSensitivity)
271271 {
272272 if (jacIt.data ())
273- return residualImpl<active, active, double , true , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, colPos , jacIt, tlmAlloc);
273+ return residualImpl<active, active, double , true , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, resBulk, packing , jacIt, tlmAlloc);
274274 else
275- return residualImpl<active, active, double , false , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, colPos , jacIt, tlmAlloc);
275+ return residualImpl<active, active, double , false , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, resBulk, packing , jacIt, tlmAlloc);
276276 }
277- int GeneralRateParticle::residual (double t, unsigned int secIdx, active const * yPar, active const * yBulk, double const * yDotPar, active* resPar, ColumnPosition colPos , linalg::BandedEigenSparseRowIterator& jacIt, LinearBufferAllocator tlmAlloc, WithParamSensitivity)
277+ int GeneralRateParticle::residual (double t, unsigned int secIdx, active const * yPar, active const * yBulk, double const * yDotPar, active* resPar, active* resBulk, columnPackingParameters packing , linalg::BandedEigenSparseRowIterator& jacIt, LinearBufferAllocator tlmAlloc, WithParamSensitivity)
278278 {
279279 if (jacIt.data ())
280- return residualImpl<active, active, active, true , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, colPos , jacIt, tlmAlloc);
280+ return residualImpl<active, active, active, true , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, resBulk, packing , jacIt, tlmAlloc);
281281 else
282- return residualImpl<active, active, active, false , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, colPos , jacIt, tlmAlloc);
282+ return residualImpl<active, active, active, false , true >(t, secIdx, yPar, yBulk, yDotPar, resPar, resBulk, packing , jacIt, tlmAlloc);
283283 }
284284
285285 template <typename StateType, typename ResidualType, typename ParamType, bool wantNonLinJac, bool wantRes>
286- int GeneralRateParticle::residualImpl (double t, unsigned int secIdx, StateType const * yPar, StateType const * yBulk, double const * yDotPar, ResidualType* resPar, ColumnPosition colPos , linalg::BandedEigenSparseRowIterator& jacIt, LinearBufferAllocator tlmAlloc)
286+ int GeneralRateParticle::residualImpl (double t, unsigned int secIdx, StateType const * yPar, StateType const * yBulk, double const * yDotPar, ResidualType* resPar, ResidualType* resBulk, columnPackingParameters packing , linalg::BandedEigenSparseRowIterator& jacIt, LinearBufferAllocator tlmAlloc)
287287 {
288288 int const * const qsBinding = _binding->reactionQuasiStationarity ();
289289 const parts::cell::CellParameters cellResParams = makeCellResidualParams (qsBinding, _parDiffOp->nBound ());
@@ -300,24 +300,43 @@ namespace model
300300 ResidualType* local_res = resPar ? resPar + par * stridePoint () : nullptr ;
301301
302302 // r (particle) coordinate of current node (particle radius normed to 1) - needed in externally dependent adsorption kinetic
303- colPos.particle = relativeCoordinate (par);
303+ packing. colPos .particle = relativeCoordinate (par);
304304
305305 if (wantRes)
306306 parts::cell::residualKernel<StateType, ResidualType, ParamType, parts::cell::CellParameters, linalg::BandedEigenSparseRowIterator, wantNonLinJac, true >(
307- t, secIdx, colPos, local_y, local_yDot, local_res, jacIt, cellResParams, tlmAlloc
307+ t, secIdx, packing. colPos , local_y, local_yDot, local_res, jacIt, cellResParams, tlmAlloc
308308 );
309309 else
310310 parts::cell::residualKernel<StateType, ResidualType, ParamType, parts::cell::CellParameters, linalg::BandedEigenSparseRowIterator, wantNonLinJac, false , false >(
311- t, secIdx, colPos, local_y, local_yDot, local_res, jacIt, cellResParams, tlmAlloc
311+ t, secIdx, packing. colPos , local_y, local_yDot, local_res, jacIt, cellResParams, tlmAlloc
312312 );
313313
314314 // Move rowiterator to next particle node
315315 jacIt += stridePoint ();
316316 }
317317
318+ // particle diffusion, including film diffusion boundary condition
318319 ResidualType* wantResPtr = wantRes ? resPar : nullptr ;
319320 linalg::BandedEigenSparseRowIterator jacSafe = wantNonLinJac ? jacBase : linalg::BandedEigenSparseRowIterator{};
320- return _parDiffOp->residual (t, secIdx, yPar, yBulk, yDotPar, wantResPtr, jacSafe, typename ParamSens<ParamType>::enabled ());
321+ _parDiffOp->residual (t, secIdx, yPar, yBulk, yDotPar, wantResPtr, jacSafe, typename ParamSens<ParamType>::enabled ());
322+
323+ if (wantRes)
324+ {
325+ // film diffusion bulk eq. term
326+ active const * const filmDiff = _parDiffOp->getFilmDiffusion (secIdx);
327+ const ParamType invBetaC = 1.0 / static_cast <ParamType>(packing.colPorosity ) - 1.0 ;
328+ const ParamType jacCF_val = invBetaC * static_cast <ParamType>(surfaceToVolumeRatio ());
329+ const ParamType jacPF_val = -1.0 / static_cast <ParamType>(getPorosity ());
330+
331+ // Add flux to column void / bulk volume
332+ for (unsigned int comp = 0 ; comp < _nComp; ++comp)
333+ {
334+ // + 1/Beta_c * (surfaceToVolumeRatio_{p,j}) * d_j * (k_f * [c_l - c_p])
335+ resBulk[comp] += static_cast <ParamType>(filmDiff[comp]) * jacCF_val * static_cast <ParamType>(packing.parTypeVolFrac [0 ]) * (yBulk[comp] - yPar[(nDiscPoints () - 1 ) * stridePoint () + comp]);
336+ }
337+ }
338+
339+ return 0 ;
321340 }
322341
323342 unsigned int GeneralRateParticle::jacobianNNZperParticle () const
0 commit comments