21
21
#include " model/BindingModel.hpp"
22
22
#include " model/ReactionModel.hpp"
23
23
#include " model/parts/BindingCellKernel.hpp"
24
+ #include " model/ParameterDependence.hpp"
24
25
#include " SimulationTypes.hpp"
25
26
#include " linalg/DenseMatrix.hpp"
26
27
#include " linalg/BandMatrix.hpp"
@@ -63,7 +64,7 @@ int schurComplementMultiplierLRMPores(void* userData, double const* x, double* z
63
64
64
65
template <typename ConvDispOperator>
65
66
LumpedRateModelWithPores<ConvDispOperator>::LumpedRateModelWithPores(UnitOpIdx unitOpIdx) : UnitOperationBase(unitOpIdx),
66
- _dynReactionBulk (nullptr ), _jacP(0 ), _jacPdisc(0 ), _jacPF(0 ), _jacFP(0 ), _jacInlet(), _analyticJac(true ),
67
+ _dynReactionBulk (nullptr ), _filmDiffDep( nullptr ), _jacP(0 ), _jacPdisc(0 ), _jacPF(0 ), _jacFP(0 ), _jacInlet(), _analyticJac(true ),
67
68
_jacobianAdDirs(0 ), _factorizeJacobian(false ), _tempState(nullptr ), _initC(0 ), _initCp(0 ), _initQ(0 ),
68
69
_initState(0 ), _initStateDot(0 )
69
70
{
@@ -75,6 +76,7 @@ LumpedRateModelWithPores<ConvDispOperator>::~LumpedRateModelWithPores() CADET_NO
75
76
delete[] _tempState;
76
77
77
78
delete _dynReactionBulk;
79
+ delete _filmDiffDep;
78
80
79
81
delete[] _disc.parTypeOffset ;
80
82
delete[] _disc.nBound ;
@@ -263,6 +265,18 @@ bool LumpedRateModelWithPores<ConvDispOperator>::configureModelDiscretization(IP
263
265
264
266
const bool transportSuccess = _convDispOp.configureModelDiscretization (paramProvider, helper, _disc.nComp , _disc.nCol );
265
267
268
+ if (paramProvider.exists (" FILM_DIFFUSION_DEP" ))
269
+ {
270
+ const std::string paramDepName = paramProvider.getString (" FILM_DIFFUSION_DEP" );
271
+ _filmDiffDep = helper.createParameterParameterDependence (paramDepName);
272
+ if (!_filmDiffDep)
273
+ throw InvalidParameterException (" Unknown parameter dependence " + paramDepName + " in FILM_DIFFUSION_DEP" );
274
+
275
+ _filmDiffDep->configureModelDiscretization (paramProvider);
276
+ }
277
+ else
278
+ _filmDiffDep = helper.createParameterParameterDependence (" CONSTANT_ONE" );
279
+
266
280
// Allocate memory
267
281
Indexer idxr (_disc);
268
282
@@ -402,6 +416,12 @@ bool LumpedRateModelWithPores<ConvDispOperator>::configure(IParameterProvider& p
402
416
403
417
const bool transportSuccess = _convDispOp.configure (_unitOpIdx, paramProvider, _parameters);
404
418
419
+ if (_filmDiffDep)
420
+ {
421
+ if (!_filmDiffDep->configure (paramProvider, _unitOpIdx, ParTypeIndep, BoundStateIndep, " FILM_DIFFUSION_DEP" ))
422
+ throw InvalidParameterException (" Failed to configure film diffusion parameter dependency (FILM_DIFFUSION_DEP)" );
423
+ }
424
+
405
425
// Read geometry parameters
406
426
_colPorosity = paramProvider.getDouble (" COL_POROSITY" );
407
427
_singleParRadius = readAndRegisterMultiplexTypeParam (paramProvider, _parameters, _parRadius, " PAR_RADIUS" , _disc.nParType , _unitOpIdx);
@@ -964,7 +984,7 @@ template <typename ConvDispOperator>
964
984
template <typename StateType, typename ResidualType, typename ParamType, bool wantJac>
965
985
int LumpedRateModelWithPores<ConvDispOperator>::residualBulk(double t, unsigned int secIdx, StateType const * yBase, double const * yDotBase, ResidualType* resBase, util::ThreadLocalStorage& threadLocalMem)
966
986
{
967
- _convDispOp.residual (t, secIdx, yBase, yDotBase, resBase, wantJac, typename ParamSens<ParamType>::enabled ());
987
+ _convDispOp.residual (* this , t, secIdx, yBase, yDotBase, resBase, wantJac, typename ParamSens<ParamType>::enabled ());
968
988
if (!_dynReactionBulk || (_dynReactionBulk->numReactionsLiquid () == 0 ))
969
989
return 0 ;
970
990
@@ -1068,7 +1088,12 @@ int LumpedRateModelWithPores<ConvDispOperator>::residualFlux(double t, unsigned
1068
1088
{
1069
1089
const unsigned int colCell = i / _disc.nComp ;
1070
1090
const unsigned int comp = i % _disc.nComp ;
1071
- resCol[i] += jacCF_val * static_cast <ParamType>(filmDiff[comp]) * static_cast <ParamType>(_parTypeVolFrac[type + _disc.nParType * colCell]) * yFluxType[i];
1091
+
1092
+ const double relPos = _convDispOp.relativeCoordinate (colCell);
1093
+ const active curVelocity = _convDispOp.currentVelocity (relPos);
1094
+ const active modifier = _filmDiffDep->getValue (*this , ColumnPosition{relPos, 0.0 , 0.0 }, comp, ParTypeIndep, BoundStateIndep, curVelocity);
1095
+
1096
+ resCol[i] += jacCF_val * static_cast <ParamType>(filmDiff[comp]) * static_cast <ParamType>(modifier) * static_cast <ParamType>(_parTypeVolFrac[type + _disc.nParType * colCell]) * yFluxType[i];
1072
1097
}
1073
1098
1074
1099
// J_{f,0} block, adds bulk volume state c_i to flux equation
@@ -1084,10 +1109,15 @@ int LumpedRateModelWithPores<ConvDispOperator>::residualFlux(double t, unsigned
1084
1109
// J_{p,f} block, adds flux to particle / bead volume equations
1085
1110
for (unsigned int pblk = 0 ; pblk < _disc.nCol ; ++pblk)
1086
1111
{
1112
+ const double relPos = _convDispOp.relativeCoordinate (pblk);
1113
+ const active curVelocity = _convDispOp.currentVelocity (relPos);
1114
+
1087
1115
for (unsigned int comp = 0 ; comp < _disc.nComp ; ++comp)
1088
1116
{
1117
+ const active modifier = _filmDiffDep->getValue (*this , ColumnPosition{relPos, 0.0 , 0.0 }, comp, ParTypeIndep, BoundStateIndep, curVelocity);
1118
+
1089
1119
const unsigned int eq = pblk * idxr.strideColCell () + comp * idxr.strideColComp ();
1090
- resParType[pblk * idxr.strideParBlock (type) + comp] += jacPF_val / static_cast <ParamType>(poreAccFactor[comp]) * static_cast <ParamType>(filmDiff[comp]) * yFluxType[eq];
1120
+ resParType[pblk * idxr.strideParBlock (type) + comp] += jacPF_val / static_cast <ParamType>(poreAccFactor[comp]) * static_cast <ParamType>(filmDiff[comp]) * static_cast <ParamType>(modifier) * yFluxType[eq];
1091
1121
}
1092
1122
}
1093
1123
@@ -1148,8 +1178,12 @@ void LumpedRateModelWithPores<ConvDispOperator>::assembleOffdiagJac(double t, un
1148
1178
const unsigned int colCell = eq / _disc.nComp ;
1149
1179
const unsigned int comp = eq % _disc.nComp ;
1150
1180
1181
+ const double relPos = _convDispOp.relativeCoordinate (colCell);
1182
+ const double curVelocity = static_cast <double >(_convDispOp.currentVelocity (relPos));
1183
+ const double modifier = _filmDiffDep->getValue (*this , ColumnPosition{relPos, 0.0 , 0.0 }, comp, ParTypeIndep, BoundStateIndep, curVelocity);
1184
+
1151
1185
// Main diagonal corresponds to j_{f,i} (flux) state variable
1152
- _jacCF.addElement (eq, eq + typeOffset, jacCF_val * static_cast <double >(filmDiff[comp]) * static_cast <double >(_parTypeVolFrac[type + _disc.nParType * colCell]));
1186
+ _jacCF.addElement (eq, eq + typeOffset, jacCF_val * static_cast <double >(filmDiff[comp]) * modifier * static_cast <double >(_parTypeVolFrac[type + _disc.nParType * colCell]));
1153
1187
}
1154
1188
1155
1189
// J_{f,0} block, adds bulk volume state c_i to flux equation
@@ -1161,11 +1195,16 @@ void LumpedRateModelWithPores<ConvDispOperator>::assembleOffdiagJac(double t, un
1161
1195
// J_{p,f} block, implements bead boundary condition in outer bead shell equation
1162
1196
for (unsigned int pblk = 0 ; pblk < _disc.nCol ; ++pblk)
1163
1197
{
1198
+ const double relPos = _convDispOp.relativeCoordinate (pblk);
1199
+ const double curVelocity = static_cast <double >(_convDispOp.currentVelocity (relPos));
1200
+
1164
1201
for (unsigned int comp = 0 ; comp < _disc.nComp ; ++comp)
1165
1202
{
1166
1203
const unsigned int eq = typeOffset + pblk * idxr.strideColCell () + comp * idxr.strideColComp ();
1167
1204
const unsigned int col = pblk * idxr.strideParBlock (type) + comp;
1168
- _jacPF[type].addElement (col, eq, jacPF_val / static_cast <double >(poreAccFactor[comp]) * static_cast <double >(filmDiff[comp]));
1205
+
1206
+ const double modifier = _filmDiffDep->getValue (*this , ColumnPosition{relPos, 0.0 , 0.0 }, comp, ParTypeIndep, BoundStateIndep, curVelocity);
1207
+ _jacPF[type].addElement (col, eq, jacPF_val / static_cast <double >(poreAccFactor[comp]) * static_cast <double >(filmDiff[comp]) * modifier);
1169
1208
}
1170
1209
}
1171
1210
@@ -1468,6 +1507,15 @@ bool LumpedRateModelWithPores<ConvDispOperator>::setParameter(const ParameterId&
1468
1507
1469
1508
if (_convDispOp.setParameter (pId, value))
1470
1509
return true ;
1510
+
1511
+ if (_filmDiffDep)
1512
+ {
1513
+ if (_filmDiffDep->hasParameter (pId))
1514
+ {
1515
+ _filmDiffDep->setParameter (pId, value);
1516
+ return true ;
1517
+ }
1518
+ }
1471
1519
}
1472
1520
1473
1521
return UnitOperationBase::setParameter (pId, value);
@@ -1509,6 +1557,16 @@ void LumpedRateModelWithPores<ConvDispOperator>::setSensitiveParameterValue(cons
1509
1557
1510
1558
if (_convDispOp.setSensitiveParameterValue (_sensParams, pId, value))
1511
1559
return ;
1560
+
1561
+ if (_filmDiffDep)
1562
+ {
1563
+ active* const param = _filmDiffDep->getParameter (pId);
1564
+ if (param)
1565
+ {
1566
+ param->setValue (value);
1567
+ return ;
1568
+ }
1569
+ }
1512
1570
}
1513
1571
1514
1572
UnitOperationBase::setSensitiveParameterValue (pId, value);
@@ -1575,6 +1633,17 @@ bool LumpedRateModelWithPores<ConvDispOperator>::setSensitiveParameter(const Par
1575
1633
LOG (Debug) << " Found parameter " << pId << " : Dir " << adDirection << " is set to " << adValue;
1576
1634
return true ;
1577
1635
}
1636
+
1637
+ if (_filmDiffDep)
1638
+ {
1639
+ active* const param = _filmDiffDep->getParameter (pId);
1640
+ if (param)
1641
+ {
1642
+ LOG (Debug) << " Found parameter " << pId << " : Dir " << adDirection << " is set to " << adValue;
1643
+ param->setADValue (adDirection, adValue);
1644
+ return true ;
1645
+ }
1646
+ }
1578
1647
}
1579
1648
1580
1649
return UnitOperationBase::setSensitiveParameter (pId, adDirection, adValue);
0 commit comments