31
31
#include < algorithm>
32
32
#include < functional>
33
33
34
+ #include < Eigen/Dense>
35
+
36
+ #include < iostream>
37
+
34
38
namespace cadet
35
39
{
36
40
@@ -76,7 +80,8 @@ CSTRModel::~CSTRModel() CADET_NOEXCEPT
76
80
delete[] _strideBound;
77
81
delete[] _offsetParType;
78
82
79
- delete _dynReactionBulk;
83
+ delete[] _dynReactionBulk;
84
+ // delete[] _temp; -> Jan warum funktioniert das nicht?
80
85
}
81
86
82
87
unsigned int CSTRModel::numDofs () const CADET_NOEXCEPT
@@ -235,6 +240,26 @@ bool CSTRModel::configureModelDiscretization(IParameterProvider& paramProvider,
235
240
236
241
if (_dynReactionBulk->usesParamProviderInDiscretizationConfig ())
237
242
paramProvider.popScope ();
243
+
244
+ if (true ) // paramProvider.exists("QUASI_STATIONARY_REACTION_BULK")
245
+ {
246
+ // _qsReacBulk = paramProvider.getIntArray("QUASI_STATIONARY_REACTION_BULK");
247
+ _qsReacBulk = {1 };
248
+ _nQsReacBulk = _qsReacBulk.size ();
249
+ // _temp = new active[_nComp];
250
+
251
+ _nMoitiesBulk = (_nComp + _totalBound) - _nQsReacBulk;
252
+ _MconvMoityBulk = Eigen::MatrixXd::Zero (_nMoitiesBulk, _nComp); // matrix for conserved moities
253
+ }
254
+ else
255
+ {
256
+ _QsCompBulk.clear ();
257
+ _qsReacBulk.clear ();
258
+ _nMoitiesBulk = 0 ;
259
+ _nQsReacBulk = 0 ;
260
+ _MconvMoityBulk = Eigen::MatrixXd::Zero (0 , 0 );
261
+
262
+ }
238
263
}
239
264
240
265
_dynReaction = std::vector<IDynamicReactionModel*>(_nParType, nullptr );
@@ -356,6 +381,12 @@ bool CSTRModel::configure(IParameterProvider& paramProvider)
356
381
paramProvider.pushScope (" reaction_bulk" );
357
382
dynReactionConfSuccess = _dynReactionBulk->configure (paramProvider, _unitOpIdx, ParTypeIndep);
358
383
paramProvider.popScope ();
384
+
385
+ if (true ) // paramProvider.exists("QUASI_STATIONARY_REACTION_BULK")
386
+ {
387
+ _dynReactionBulk->fillConservedMoietiesBulk (_MconvMoityBulk, _qsReacBulk, _QsCompBulk); // fill conserved moities matrix
388
+ int a = 0 ;
389
+ }
359
390
}
360
391
361
392
for (unsigned int type = 0 ; type < _nParType; ++type)
@@ -422,9 +453,7 @@ unsigned int CSTRModel::threadLocalMemorySize() const CADET_NOEXCEPT
422
453
return lms.bufferSize ();
423
454
}
424
455
425
- void CSTRModel::setSectionTimes (double const * secTimes, bool const * secContinuity, unsigned int nSections)
426
- {
427
- }
456
+ void CSTRModel::setSectionTimes (double const * secTimes, bool const * secContinuity, unsigned int nSections){}
428
457
429
458
void CSTRModel::useAnalyticJacobian (const bool analyticJac)
430
459
{
@@ -1247,7 +1276,7 @@ int CSTRModel::residualImpl(double t, unsigned int secIdx, StateType const* cons
1247
1276
1248
1277
const ParamType flowIn = static_cast <ParamType>(_flowRateIn);
1249
1278
const ParamType flowOut = static_cast <ParamType>(_flowRateOut);
1250
-
1279
+
1251
1280
// Inlet DOF
1252
1281
for (unsigned int i = 0 ; i < _nComp; ++i)
1253
1282
{
@@ -1256,7 +1285,7 @@ int CSTRModel::residualImpl(double t, unsigned int secIdx, StateType const* cons
1256
1285
1257
1286
// Concentrations: \dot{V^l} * c + V^l * \dot{c} + V^s * sum_j sum_m \dot{q}_{j,m}] = c_in * F_in - c * F_out
1258
1287
const ParamType vsolid = static_cast <ParamType>(_constSolidVolume);
1259
- ResidualType* const resC = res + _nComp;
1288
+ ResidualType* resC = res + _nComp;
1260
1289
for (unsigned int i = 0 ; i < _nComp; ++i)
1261
1290
{
1262
1291
resC[i] = 0.0 ;
@@ -1312,14 +1341,73 @@ int CSTRModel::residualImpl(double t, unsigned int secIdx, StateType const* cons
1312
1341
// Reactions in liquid phase
1313
1342
const ColumnPosition colPos{0.0 , 0.0 , 0.0 };
1314
1343
1315
- if (_dynReactionBulk && (_dynReactionBulk-> numReactionsLiquid () > 0 ))
1344
+ if (_dynReactionBulk && (_nQsReacBulk > 0 ))
1316
1345
{
1317
- LinearBufferAllocator subAlloc = tlmAlloc.manageRemainingMemory ();
1318
- BufferedArray<ResidualType> flux = subAlloc.array <ResidualType>(_nComp);
1346
+ LinearBufferAllocator subAlloc = tlmAlloc.manageRemainingMemory (); // todo nachgucken ob das wirklich so geht
1319
1347
1348
+ BufferedArray<ResidualType> flux = subAlloc.array <ResidualType>(_nComp);
1320
1349
std::fill_n (static_cast <ResidualType*>(flux), _nComp, 0.0 );
1350
+
1351
+ BufferedArray<ResidualType> qsflux = subAlloc.array <ResidualType>(_nQsReacBulk);
1352
+ std::fill_n (static_cast <ResidualType*>(qsflux), _nQsReacBulk, 0.0 );
1353
+
1354
+ BufferedArray<ResidualType> temp = subAlloc.array <ResidualType>(_nComp);
1355
+ std::fill_n (static_cast <ResidualType*>(temp), _nComp, 0.0 );
1356
+
1321
1357
_dynReactionBulk->residualLiquidAdd (t, secIdx, colPos, c, static_cast <ResidualType*>(flux), -1.0 , subAlloc);
1358
+ _dynReactionBulk->quasiStationaryFlux (t, secIdx, colPos, c, static_cast <ResidualType*>(qsflux), _qsReacBulk, subAlloc);
1359
+
1360
+
1361
+
1362
+ Eigen::Map<Eigen::Vector<ResidualType, Eigen::Dynamic>> resCMoities (static_cast <ResidualType*>(temp), _nComp);
1363
+ resCMoities.setZero ();
1364
+
1365
+ Eigen::Map<Eigen::Vector<ResidualType, Eigen::Dynamic>> mapResC (resC, _nComp);
1366
+ std::vector<int > visitedQSComp (_nComp, 0 );
1322
1367
1368
+ int MoityIdx = 0 ;
1369
+
1370
+ for (unsigned int state = 0 ; state < (_nComp - _nQsReacBulk); ++state)
1371
+ {
1372
+ if (_QsCompBulk[state] == 1 )
1373
+ {
1374
+ ResidualType dotProduct = 0.0 ;
1375
+ for (unsigned int i; i < _MconvMoityBulk.cols (); i++) // hier Optimierung durch Vermeidung von 0 Zeilen in MconvMoityBulk
1376
+ {
1377
+ dotProduct += static_cast <ResidualType>(_MconvMoityBulk (MoityIdx, i)) * (mapResC[i]);
1378
+
1379
+ if (wantJac)
1380
+ _jac.native (i, state) = vDotTimeFactor + static_cast <double >(flowOut); // dF_{ci}/dcj = v_liquidDot + F_out
1381
+ }
1382
+ resCMoities[state] = dotProduct;
1383
+
1384
+
1385
+ MoityIdx++;
1386
+ }
1387
+ else if (_QsCompBulk[state] == 0 )
1388
+ {
1389
+ resCMoities[state] += v * flux[state]; // hier sicher stellen, was in flux steht entweder res + flux oder nur flux
1390
+
1391
+ if (wantJac)
1392
+ _jac.native (state, _nComp + _totalBound) += static_cast <double >(flux[state]); dF/dvliquid = flux
1393
+ int a = 0 ; // add function that adds the jacobian for one state or change analyticJacobianLiquidAdd
1394
+ }
1395
+ }
1396
+
1397
+ int state = (_nComp - _nQsReacBulk);
1398
+ for (unsigned int qsreac = 0 ; qsreac < _nQsReacBulk; ++qsreac)
1399
+ {
1400
+ resCMoities[state++] = v * qsflux[qsreac];
1401
+
1402
+ if (wantJac)
1403
+ int a = 0 ; // add function that adds the jacobian for single reactions -> maybe der klammer
1404
+ }
1405
+
1406
+ mapResC = resCMoities;
1407
+
1408
+ }
1409
+ else
1410
+ {
1323
1411
for (unsigned int comp = 0 ; comp < _nComp; ++comp)
1324
1412
resC[comp] += v * flux[comp];
1325
1413
@@ -1331,7 +1419,7 @@ int CSTRModel::residualImpl(double t, unsigned int secIdx, StateType const* cons
1331
1419
_dynReactionBulk->analyticJacobianLiquidAdd (t, secIdx, colPos, reinterpret_cast <double const *>(c), -static_cast <double >(v), _jac.row (0 ), subAlloc);
1332
1420
}
1333
1421
}
1334
-
1422
+
1335
1423
// Bound states
1336
1424
for (unsigned int type = 0 ; type < _nParType; ++type)
1337
1425
{
@@ -1401,7 +1489,6 @@ int CSTRModel::residualImpl(double t, unsigned int secIdx, StateType const* cons
1401
1489
}
1402
1490
}
1403
1491
}
1404
-
1405
1492
if (wantJac)
1406
1493
{
1407
1494
// Assemble Jacobian: Reaction
@@ -1440,7 +1527,6 @@ int CSTRModel::residualImpl(double t, unsigned int secIdx, StateType const* cons
1440
1527
1441
1528
// Volume: \dot{V} = F_{in} - F_{out} - F_{filter}
1442
1529
res[2 * _nComp + _totalBound] = vDot - flowIn + flowOut + static_cast <ParamType>(_curFlowRateFilter);
1443
-
1444
1530
return 0 ;
1445
1531
}
1446
1532
0 commit comments