Skip to content

Commit 385a934

Browse files
sleweke-bayerschmoelder
authored andcommitted
Add axial dispersion and film diffusion parameter dependence
Axial dispersion for all models, film diffusion parameter dependence only for LRMP.
1 parent fbe8fa7 commit 385a934

12 files changed

+341
-86
lines changed

src/libcadet/model/GeneralRateModel2D.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ bool GeneralRateModel2D::configureModelDiscretization(IParameterProvider& paramP
703703
}
704704
}
705705

706-
const bool transportSuccess = _convDispOp.configureModelDiscretization(paramProvider, _disc.nComp, _disc.nCol, _disc.nRad, _dynReactionBulk);
706+
const bool transportSuccess = _convDispOp.configureModelDiscretization(paramProvider, helper, _disc.nComp, _disc.nCol, _disc.nRad, _dynReactionBulk);
707707

708708
// Setup the memory for tempState based on state vector
709709
_tempState = new double[numDofs()];
@@ -1316,7 +1316,7 @@ int GeneralRateModel2D::residualImpl(double t, unsigned int secIdx, StateType co
13161316
template <typename StateType, typename ResidualType, typename ParamType, bool wantJac>
13171317
int GeneralRateModel2D::residualBulk(double t, unsigned int secIdx, StateType const* yBase, double const* yDotBase, ResidualType* resBase, util::ThreadLocalStorage& threadLocalMem)
13181318
{
1319-
_convDispOp.residual(t, secIdx, yBase, yDotBase, resBase, wantJac, typename ParamSens<ParamType>::enabled());
1319+
_convDispOp.residual(*this, t, secIdx, yBase, yDotBase, resBase, wantJac, typename ParamSens<ParamType>::enabled());
13201320
if (!_dynReactionBulk || (_dynReactionBulk->numReactionsLiquid() == 0))
13211321
return 0;
13221322

src/libcadet/model/LumpedRateModelWithPores.cpp

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "model/BindingModel.hpp"
2222
#include "model/ReactionModel.hpp"
2323
#include "model/parts/BindingCellKernel.hpp"
24+
#include "model/ParameterDependence.hpp"
2425
#include "SimulationTypes.hpp"
2526
#include "linalg/DenseMatrix.hpp"
2627
#include "linalg/BandMatrix.hpp"
@@ -63,7 +64,7 @@ int schurComplementMultiplierLRMPores(void* userData, double const* x, double* z
6364

6465
template <typename ConvDispOperator>
6566
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),
6768
_jacobianAdDirs(0), _factorizeJacobian(false), _tempState(nullptr), _initC(0), _initCp(0), _initQ(0),
6869
_initState(0), _initStateDot(0)
6970
{
@@ -75,6 +76,7 @@ LumpedRateModelWithPores<ConvDispOperator>::~LumpedRateModelWithPores() CADET_NO
7576
delete[] _tempState;
7677

7778
delete _dynReactionBulk;
79+
delete _filmDiffDep;
7880

7981
delete[] _disc.parTypeOffset;
8082
delete[] _disc.nBound;
@@ -237,6 +239,18 @@ bool LumpedRateModelWithPores<ConvDispOperator>::configureModelDiscretization(IP
237239

238240
const bool transportSuccess = _convDispOp.configureModelDiscretization(paramProvider, helper, _disc.nComp, _disc.nCol);
239241

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+
240254
// Allocate memory
241255
Indexer idxr(_disc);
242256

@@ -376,6 +390,12 @@ bool LumpedRateModelWithPores<ConvDispOperator>::configure(IParameterProvider& p
376390

377391
const bool transportSuccess = _convDispOp.configure(_unitOpIdx, paramProvider, _parameters);
378392

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+
379399
// Read geometry parameters
380400
_colPorosity = paramProvider.getDouble("COL_POROSITY");
381401
_singleParRadius = readAndRegisterMultiplexTypeParam(paramProvider, _parameters, _parRadius, "PAR_RADIUS", _disc.nParType, _unitOpIdx);
@@ -1042,7 +1062,12 @@ int LumpedRateModelWithPores<ConvDispOperator>::residualFlux(double t, unsigned
10421062
{
10431063
const unsigned int colCell = i / _disc.nComp;
10441064
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];
10461071
}
10471072

10481073
// J_{f,0} block, adds bulk volume state c_i to flux equation
@@ -1058,10 +1083,15 @@ int LumpedRateModelWithPores<ConvDispOperator>::residualFlux(double t, unsigned
10581083
// J_{p,f} block, adds flux to particle / bead volume equations
10591084
for (unsigned int pblk = 0; pblk < _disc.nCol; ++pblk)
10601085
{
1086+
const double relPos = _convDispOp.relativeCoordinate(pblk);
1087+
const active curVelocity = _convDispOp.currentVelocity(relPos);
1088+
10611089
for (unsigned int comp = 0; comp < _disc.nComp; ++comp)
10621090
{
1091+
const active modifier = _filmDiffDep->getValue(*this, ColumnPosition{relPos, 0.0, 0.0}, comp, ParTypeIndep, BoundStateIndep, curVelocity);
1092+
10631093
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];
10651095
}
10661096
}
10671097

@@ -1122,8 +1152,12 @@ void LumpedRateModelWithPores<ConvDispOperator>::assembleOffdiagJac(double t, un
11221152
const unsigned int colCell = eq / _disc.nComp;
11231153
const unsigned int comp = eq % _disc.nComp;
11241154

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+
11251159
// 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]));
11271161
}
11281162

11291163
// J_{f,0} block, adds bulk volume state c_i to flux equation
@@ -1135,11 +1169,16 @@ void LumpedRateModelWithPores<ConvDispOperator>::assembleOffdiagJac(double t, un
11351169
// J_{p,f} block, implements bead boundary condition in outer bead shell equation
11361170
for (unsigned int pblk = 0; pblk < _disc.nCol; ++pblk)
11371171
{
1172+
const double relPos = _convDispOp.relativeCoordinate(pblk);
1173+
const double curVelocity = static_cast<double>(_convDispOp.currentVelocity(relPos));
1174+
11381175
for (unsigned int comp = 0; comp < _disc.nComp; ++comp)
11391176
{
11401177
const unsigned int eq = typeOffset + pblk * idxr.strideColCell() + comp * idxr.strideColComp();
11411178
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);
11431182
}
11441183
}
11451184

@@ -1442,6 +1481,15 @@ bool LumpedRateModelWithPores<ConvDispOperator>::setParameter(const ParameterId&
14421481

14431482
if (_convDispOp.setParameter(pId, value))
14441483
return true;
1484+
1485+
if (_filmDiffDep)
1486+
{
1487+
if (_filmDiffDep->hasParameter(pId))
1488+
{
1489+
_filmDiffDep->setParameter(pId, value);
1490+
return true;
1491+
}
1492+
}
14451493
}
14461494

14471495
return UnitOperationBase::setParameter(pId, value);
@@ -1483,6 +1531,16 @@ void LumpedRateModelWithPores<ConvDispOperator>::setSensitiveParameterValue(cons
14831531

14841532
if (_convDispOp.setSensitiveParameterValue(_sensParams, pId, value))
14851533
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+
}
14861544
}
14871545

14881546
UnitOperationBase::setSensitiveParameterValue(pId, value);
@@ -1549,6 +1607,17 @@ bool LumpedRateModelWithPores<ConvDispOperator>::setSensitiveParameter(const Par
15491607
LOG(Debug) << "Found parameter " << pId << ": Dir " << adDirection << " is set to " << adValue;
15501608
return true;
15511609
}
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+
}
15521621
}
15531622

15541623
return UnitOperationBase::setSensitiveParameter(pId, adDirection, adValue);

src/libcadet/model/LumpedRateModelWithPores.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ class LumpedRateModelWithPores : public UnitOperationBase
264264

265265
ConvDispOperator _convDispOp; //!< Convection dispersion operator for interstitial volume transport
266266
IDynamicReactionModel* _dynReactionBulk; //!< Dynamic reactions in the bulk volume
267+
IParameterParameterDependence* _filmDiffDep; //!< Film diffusion dependency on local velocity
267268

268269
std::vector<linalg::BandMatrix> _jacP; //!< Particle jacobian diagonal blocks (all of them for each particle type)
269270
std::vector<linalg::FactorizableBandMatrix> _jacPdisc; //!< Particle jacobian diagonal blocks (all of them for each particle type) with time derivatives from BDF method

src/libcadet/model/LumpedRateModelWithoutPores.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ template <typename ConvDispOperator>
775775
unsigned int LumpedRateModelWithoutPores<ConvDispOperator>::localOutletComponentIndex(unsigned int port) const CADET_NOEXCEPT
776776
{
777777
// Inlets are duplicated so need to be accounted for
778-
if (static_cast<double>(_convDispOp.currentVelocity()) >= 0.0)
778+
if (_convDispOp.forwardFlow())
779779
// Forward Flow: outlet is last cell
780780
return _disc.nComp + (_disc.nCol - 1) * (_disc.nComp + _disc.strideBound);
781781
else

src/libcadet/model/paramdep/DummyParameterDependence.cpp

Lines changed: 113 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@ namespace model
2727
{
2828

2929
/**
30-
* @brief Defines a dummy parameter dependence
30+
* @brief Defines a parameter dependence that outputs constant 0.0
3131
*/
32-
class DummyParameterStateDependence : public ParameterStateDependenceBase
32+
class ConstantZeroParameterStateDependence : public ParameterStateDependenceBase
3333
{
3434
public:
3535

36-
DummyParameterStateDependence() { }
37-
virtual ~DummyParameterStateDependence() CADET_NOEXCEPT { }
36+
ConstantZeroParameterStateDependence() { }
37+
virtual ~ConstantZeroParameterStateDependence() CADET_NOEXCEPT { }
3838

39-
static const char* identifier() { return "DUMMY"; }
40-
virtual const char* name() const CADET_NOEXCEPT { return DummyParameterStateDependence::identifier(); }
39+
static const char* identifier() { return "CONSTANT_ZERO"; }
40+
virtual const char* name() const CADET_NOEXCEPT { return ConstantZeroParameterStateDependence::identifier(); }
4141

4242
virtual int jacobianElementsPerRowLiquid() const CADET_NOEXCEPT { return 0; }
4343
virtual int jacobianElementsPerRowCombined() const CADET_NOEXCEPT { return 0; }
@@ -85,17 +85,75 @@ class DummyParameterStateDependence : public ParameterStateDependenceBase
8585

8686

8787
/**
88-
* @brief Defines a dummy parameter dependence
88+
* @brief Defines a parameter dependence that outputs constant 1.0
8989
*/
90-
class DummyParameterParameterDependence : public ParameterParameterDependenceBase
90+
class ConstantOneParameterStateDependence : public ParameterStateDependenceBase
9191
{
9292
public:
9393

94-
DummyParameterParameterDependence() { }
95-
virtual ~DummyParameterParameterDependence() CADET_NOEXCEPT { }
94+
ConstantOneParameterStateDependence() { }
95+
virtual ~ConstantOneParameterStateDependence() CADET_NOEXCEPT { }
9696

97-
static const char* identifier() { return "DUMMY"; }
98-
virtual const char* name() const CADET_NOEXCEPT { return DummyParameterParameterDependence::identifier(); }
97+
static const char* identifier() { return "CONSTANT_ONE"; }
98+
virtual const char* name() const CADET_NOEXCEPT { return ConstantOneParameterStateDependence::identifier(); }
99+
100+
virtual int jacobianElementsPerRowLiquid() const CADET_NOEXCEPT { return 0; }
101+
virtual int jacobianElementsPerRowCombined() const CADET_NOEXCEPT { return 0; }
102+
103+
virtual void analyticJacobianLiquidAdd(const ColumnPosition& colPos, double param, double const* y, int comp, double factor, int offset, int row, linalg::DoubleSparseMatrix& jac) const { }
104+
virtual void analyticJacobianCombinedAddLiquid(const ColumnPosition& colPos, double param, double const* yLiquid, double const* ySolid, int comp, double factor, int offset, int row, linalg::DoubleSparseMatrix& jac) const { }
105+
virtual void analyticJacobianCombinedAddSolid(const ColumnPosition& colPos, double param, double const* yLiquid, double const* ySolid, int bnd, double factor, int offset, int row, linalg::DoubleSparseMatrix& jac) const { }
106+
107+
CADET_PARAMETERSTATEDEPENDENCE_BOILERPLATE
108+
109+
protected:
110+
111+
virtual bool configureImpl(IParameterProvider& paramProvider, UnitOpIdx unitOpIdx, ParticleTypeIdx parTypeIdx, const std::string& name)
112+
{
113+
return true;
114+
}
115+
116+
template <typename StateType, typename ParamType>
117+
typename DoubleActivePromoter<StateType, ParamType>::type liquidParameterImpl(const ColumnPosition& colPos, const ParamType& param, StateType const* y, int comp) const
118+
{
119+
return 1.0;
120+
}
121+
122+
template <typename RowIterator>
123+
void analyticJacobianLiquidAddImpl(const ColumnPosition& colPos, double param, double const* y, int comp, double factor, int offset, RowIterator jac) const { }
124+
125+
template <typename StateType, typename ParamType>
126+
typename DoubleActivePromoter<StateType, ParamType>::type combinedParameterLiquidImpl(const ColumnPosition& colPos, const ParamType& param, StateType const* yLiquid, StateType const* ySolid, int comp) const
127+
{
128+
return 1.0;
129+
}
130+
131+
template <typename RowIterator>
132+
void analyticJacobianCombinedAddLiquidImpl(const ColumnPosition& colPos, double param, double const* yLiquid, double const* ySolid, int comp, double factor, int offset, RowIterator jac) const { }
133+
134+
template <typename StateType, typename ParamType>
135+
typename DoubleActivePromoter<StateType, ParamType>::type combinedParameterSolidImpl(const ColumnPosition& colPos, const ParamType& param, StateType const* yLiquid, StateType const* ySolid, int bnd) const
136+
{
137+
return 1.0;
138+
}
139+
140+
template <typename RowIterator>
141+
void analyticJacobianCombinedAddSolidImpl(const ColumnPosition& colPos, double param, double const* yLiquid, double const* ySolid, int bnd, double factor, int offset, RowIterator jac) const { }
142+
};
143+
144+
145+
/**
146+
* @brief Defines a parameter dependence that outputs constant 0.0
147+
*/
148+
class ConstantZeroParameterParameterDependence : public ParameterParameterDependenceBase
149+
{
150+
public:
151+
152+
ConstantZeroParameterParameterDependence() { }
153+
virtual ~ConstantZeroParameterParameterDependence() CADET_NOEXCEPT { }
154+
155+
static const char* identifier() { return "CONSTANT_ZERO"; }
156+
virtual const char* name() const CADET_NOEXCEPT { return ConstantZeroParameterParameterDependence::identifier(); }
99157

100158
CADET_PARAMETERPARAMETERDEPENDENCE_BOILERPLATE
101159

@@ -121,18 +179,57 @@ class DummyParameterParameterDependence : public ParameterParameterDependenceBas
121179
};
122180

123181

182+
/**
183+
* @brief Defines a parameter dependence that outputs constant 1.0
184+
*/
185+
class ConstantOneParameterParameterDependence : public ParameterParameterDependenceBase
186+
{
187+
public:
188+
189+
ConstantOneParameterParameterDependence() { }
190+
virtual ~ConstantOneParameterParameterDependence() CADET_NOEXCEPT { }
191+
192+
static const char* identifier() { return "CONSTANT_ONE"; }
193+
virtual const char* name() const CADET_NOEXCEPT { return ConstantOneParameterParameterDependence::identifier(); }
194+
195+
CADET_PARAMETERPARAMETERDEPENDENCE_BOILERPLATE
196+
197+
protected:
198+
199+
virtual bool configureImpl(IParameterProvider& paramProvider, UnitOpIdx unitOpIdx, ParticleTypeIdx parTypeIdx, BoundStateIdx bndIdx, const std::string& name)
200+
{
201+
return true;
202+
}
203+
204+
template <typename ParamType>
205+
ParamType getValueImpl(const IModel& model, const ColumnPosition& colPos, int comp, int parType, int bnd) const
206+
{
207+
return 1.0;
208+
}
209+
210+
template <typename ParamType>
211+
ParamType getValueImpl(const IModel& model, const ColumnPosition& colPos, int comp, int parType, int bnd, const ParamType& val) const
212+
{
213+
return 1.0;
214+
}
215+
216+
};
217+
218+
124219
namespace paramdep
125220
{
126221
void registerDummyParamDependence(std::unordered_map<std::string, std::function<model::IParameterStateDependence*()>>& paramDeps)
127222
{
128-
paramDeps[DummyParameterStateDependence::identifier()] = []() { return new DummyParameterStateDependence(); };
129-
paramDeps["NONE"] = []() { return new DummyParameterStateDependence(); };
223+
paramDeps[ConstantOneParameterStateDependence::identifier()] = []() { return new ConstantOneParameterStateDependence(); };
224+
paramDeps[ConstantZeroParameterStateDependence::identifier()] = []() { return new ConstantZeroParameterStateDependence(); };
225+
paramDeps["NONE"] = []() { return new ConstantOneParameterStateDependence(); };
130226
}
131227

132228
void registerDummyParamDependence(std::unordered_map<std::string, std::function<model::IParameterParameterDependence*()>>& paramDeps)
133229
{
134-
paramDeps[DummyParameterParameterDependence::identifier()] = []() { return new DummyParameterParameterDependence(); };
135-
paramDeps["NONE"] = []() { return new DummyParameterParameterDependence(); };
230+
paramDeps[ConstantOneParameterParameterDependence::identifier()] = []() { return new ConstantOneParameterParameterDependence(); };
231+
paramDeps[ConstantZeroParameterParameterDependence::identifier()] = []() { return new ConstantZeroParameterParameterDependence(); };
232+
paramDeps["NONE"] = []() { return new ConstantOneParameterParameterDependence(); };
136233
}
137234
} // namespace paramdep
138235

src/libcadet/model/paramdep/PowerLawParameterDependence.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ class PowerLawParameterParameterDependence : public ParameterParameterDependence
5151
const std::string baseName = name + "_BASE";
5252
const std::string expName = name + "_EXPONENT";
5353
const std::string flagName = name + "_ABS";
54-
_base = paramProvider.getDouble(baseName);
54+
55+
if (paramProvider.exists(baseName))
56+
_base = paramProvider.getDouble(baseName);
57+
else
58+
_base = 1.0;
59+
5560
_exponent = paramProvider.getDouble(expName);
5661

5762
if (paramProvider.exists(flagName))

0 commit comments

Comments
 (0)