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 ;
@@ -237,6 +239,18 @@ bool LumpedRateModelWithPores<ConvDispOperator>::configureModelDiscretization(IP
237
239
238
240
const bool transportSuccess = _convDispOp.configureModelDiscretization (paramProvider, helper, _disc.nComp , _disc.nCol );
239
241
242
+ if (paramProvider.exists (" FILM_DIFFUSION_DEP" ))
243
+ {
244
+ const std::string paramDepName = paramProvider.getString (" FILM_DIFFUSION_DEP" );
245
+ _filmDiffDep = helper.createParameterParameterDependence (paramDepName);
246
+ if (!_filmDiffDep)
247
+ throw InvalidParameterException (" Unknown parameter dependence " + paramDepName + " in FILM_DIFFUSION_DEP" );
248
+
249
+ _filmDiffDep->configureModelDiscretization (paramProvider);
250
+ }
251
+ else
252
+ _filmDiffDep = helper.createParameterParameterDependence (" CONSTANT_ONE" );
253
+
240
254
// Allocate memory
241
255
Indexer idxr (_disc);
242
256
@@ -376,6 +390,12 @@ bool LumpedRateModelWithPores<ConvDispOperator>::configure(IParameterProvider& p
376
390
377
391
const bool transportSuccess = _convDispOp.configure (_unitOpIdx, paramProvider, _parameters);
378
392
393
+ if (_filmDiffDep)
394
+ {
395
+ if (!_filmDiffDep->configure (paramProvider, _unitOpIdx, ParTypeIndep, BoundStateIndep, " FILM_DIFFUSION_DEP" ))
396
+ throw InvalidParameterException (" Failed to configure film diffusion parameter dependency (FILM_DIFFUSION_DEP)" );
397
+ }
398
+
379
399
// Read geometry parameters
380
400
_colPorosity = paramProvider.getDouble (" COL_POROSITY" );
381
401
_singleParRadius = readAndRegisterMultiplexTypeParam (paramProvider, _parameters, _parRadius, " PAR_RADIUS" , _disc.nParType , _unitOpIdx);
@@ -1042,7 +1062,12 @@ int LumpedRateModelWithPores<ConvDispOperator>::residualFlux(double t, unsigned
1042
1062
{
1043
1063
const unsigned int colCell = i / _disc.nComp ;
1044
1064
const unsigned int comp = i % _disc.nComp ;
1045
- resCol[i] += jacCF_val * static_cast <ParamType>(filmDiff[comp]) * static_cast <ParamType>(_parTypeVolFrac[type + _disc.nParType * colCell]) * yFluxType[i];
1065
+
1066
+ const double relPos = _convDispOp.relativeCoordinate (colCell);
1067
+ const active curVelocity = _convDispOp.currentVelocity (relPos);
1068
+ const active modifier = _filmDiffDep->getValue (*this , ColumnPosition{relPos, 0.0 , 0.0 }, comp, ParTypeIndep, BoundStateIndep, curVelocity);
1069
+
1070
+ resCol[i] += jacCF_val * static_cast <ParamType>(filmDiff[comp]) * static_cast <ParamType>(modifier) * static_cast <ParamType>(_parTypeVolFrac[type + _disc.nParType * colCell]) * yFluxType[i];
1046
1071
}
1047
1072
1048
1073
// J_{f,0} block, adds bulk volume state c_i to flux equation
@@ -1058,10 +1083,15 @@ int LumpedRateModelWithPores<ConvDispOperator>::residualFlux(double t, unsigned
1058
1083
// J_{p,f} block, adds flux to particle / bead volume equations
1059
1084
for (unsigned int pblk = 0 ; pblk < _disc.nCol ; ++pblk)
1060
1085
{
1086
+ const double relPos = _convDispOp.relativeCoordinate (pblk);
1087
+ const active curVelocity = _convDispOp.currentVelocity (relPos);
1088
+
1061
1089
for (unsigned int comp = 0 ; comp < _disc.nComp ; ++comp)
1062
1090
{
1091
+ const active modifier = _filmDiffDep->getValue (*this , ColumnPosition{relPos, 0.0 , 0.0 }, comp, ParTypeIndep, BoundStateIndep, curVelocity);
1092
+
1063
1093
const unsigned int eq = pblk * idxr.strideColCell () + comp * idxr.strideColComp ();
1064
- resParType[pblk * idxr.strideParBlock (type) + comp] += jacPF_val / static_cast <ParamType>(poreAccFactor[comp]) * static_cast <ParamType>(filmDiff[comp]) * yFluxType[eq];
1094
+ resParType[pblk * idxr.strideParBlock (type) + comp] += jacPF_val / static_cast <ParamType>(poreAccFactor[comp]) * static_cast <ParamType>(filmDiff[comp]) * static_cast <ParamType>(modifier) * yFluxType[eq];
1065
1095
}
1066
1096
}
1067
1097
@@ -1122,8 +1152,12 @@ void LumpedRateModelWithPores<ConvDispOperator>::assembleOffdiagJac(double t, un
1122
1152
const unsigned int colCell = eq / _disc.nComp ;
1123
1153
const unsigned int comp = eq % _disc.nComp ;
1124
1154
1155
+ const double relPos = _convDispOp.relativeCoordinate (colCell);
1156
+ const double curVelocity = static_cast <double >(_convDispOp.currentVelocity (relPos));
1157
+ const double modifier = _filmDiffDep->getValue (*this , ColumnPosition{relPos, 0.0 , 0.0 }, comp, ParTypeIndep, BoundStateIndep, curVelocity);
1158
+
1125
1159
// Main diagonal corresponds to j_{f,i} (flux) state variable
1126
- _jacCF.addElement (eq, eq + typeOffset, jacCF_val * static_cast <double >(filmDiff[comp]) * static_cast <double >(_parTypeVolFrac[type + _disc.nParType * colCell]));
1160
+ _jacCF.addElement (eq, eq + typeOffset, jacCF_val * static_cast <double >(filmDiff[comp]) * modifier * static_cast <double >(_parTypeVolFrac[type + _disc.nParType * colCell]));
1127
1161
}
1128
1162
1129
1163
// J_{f,0} block, adds bulk volume state c_i to flux equation
@@ -1135,11 +1169,16 @@ void LumpedRateModelWithPores<ConvDispOperator>::assembleOffdiagJac(double t, un
1135
1169
// J_{p,f} block, implements bead boundary condition in outer bead shell equation
1136
1170
for (unsigned int pblk = 0 ; pblk < _disc.nCol ; ++pblk)
1137
1171
{
1172
+ const double relPos = _convDispOp.relativeCoordinate (pblk);
1173
+ const double curVelocity = static_cast <double >(_convDispOp.currentVelocity (relPos));
1174
+
1138
1175
for (unsigned int comp = 0 ; comp < _disc.nComp ; ++comp)
1139
1176
{
1140
1177
const unsigned int eq = typeOffset + pblk * idxr.strideColCell () + comp * idxr.strideColComp ();
1141
1178
const unsigned int col = pblk * idxr.strideParBlock (type) + comp;
1142
- _jacPF[type].addElement (col, eq, jacPF_val / static_cast <double >(poreAccFactor[comp]) * static_cast <double >(filmDiff[comp]));
1179
+
1180
+ const double modifier = _filmDiffDep->getValue (*this , ColumnPosition{relPos, 0.0 , 0.0 }, comp, ParTypeIndep, BoundStateIndep, curVelocity);
1181
+ _jacPF[type].addElement (col, eq, jacPF_val / static_cast <double >(poreAccFactor[comp]) * static_cast <double >(filmDiff[comp]) * modifier);
1143
1182
}
1144
1183
}
1145
1184
@@ -1442,6 +1481,15 @@ bool LumpedRateModelWithPores<ConvDispOperator>::setParameter(const ParameterId&
1442
1481
1443
1482
if (_convDispOp.setParameter (pId, value))
1444
1483
return true ;
1484
+
1485
+ if (_filmDiffDep)
1486
+ {
1487
+ if (_filmDiffDep->hasParameter (pId))
1488
+ {
1489
+ _filmDiffDep->setParameter (pId, value);
1490
+ return true ;
1491
+ }
1492
+ }
1445
1493
}
1446
1494
1447
1495
return UnitOperationBase::setParameter (pId, value);
@@ -1483,6 +1531,16 @@ void LumpedRateModelWithPores<ConvDispOperator>::setSensitiveParameterValue(cons
1483
1531
1484
1532
if (_convDispOp.setSensitiveParameterValue (_sensParams, pId, value))
1485
1533
return ;
1534
+
1535
+ if (_filmDiffDep)
1536
+ {
1537
+ active* const param = _filmDiffDep->getParameter (pId);
1538
+ if (param)
1539
+ {
1540
+ param->setValue (value);
1541
+ return ;
1542
+ }
1543
+ }
1486
1544
}
1487
1545
1488
1546
UnitOperationBase::setSensitiveParameterValue (pId, value);
@@ -1549,6 +1607,17 @@ bool LumpedRateModelWithPores<ConvDispOperator>::setSensitiveParameter(const Par
1549
1607
LOG (Debug) << " Found parameter " << pId << " : Dir " << adDirection << " is set to " << adValue;
1550
1608
return true ;
1551
1609
}
1610
+
1611
+ if (_filmDiffDep)
1612
+ {
1613
+ active* const param = _filmDiffDep->getParameter (pId);
1614
+ if (param)
1615
+ {
1616
+ LOG (Debug) << " Found parameter " << pId << " : Dir " << adDirection << " is set to " << adValue;
1617
+ param->setADValue (adDirection, adValue);
1618
+ return true ;
1619
+ }
1620
+ }
1552
1621
}
1553
1622
1554
1623
return UnitOperationBase::setSensitiveParameter (pId, adDirection, adValue);
0 commit comments