Skip to content

Commit

Permalink
Remove singleton parshell dims in solution of LRMP, CSTR
Browse files Browse the repository at this point in the history
Restores the previous behavior when reporting the solution of the LRMP
and CSTR units: The singleton particle shell dimension is removed from
the output tensor.

Fixes modsim#133.
  • Loading branch information
sleweke-bayer committed Jul 21, 2023
1 parent 4eeeed5 commit eeafb20
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 14 deletions.
7 changes: 7 additions & 0 deletions include/cadet/SolutionExporter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ class CADET_API ISolutionExporter
*/
virtual bool hasVolume() const CADET_NOEXCEPT = 0;

/**
* @brief Returns whether the particle is always lumped to a single element
* @details If particles are lumped to a single element, the singleton particle shell dimension can be removed.
* @return @c true if particles are always represented by a single element, otherwise @c false
*/
virtual bool isParticleLumped() const CADET_NOEXCEPT = 0;

/**
* @brief Returns the number of components
* @return Number of components
Expand Down
72 changes: 58 additions & 14 deletions include/common/SolutionRecorderImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ class InternalStorageUnitOpRecorder : public ISolutionRecorder
InternalStorageUnitOpRecorder(UnitOpIdx idx) : _cfgSolution({false, false, false, true, false, false, false}),
_cfgSolutionDot({false, false, false, false, false, false, false}), _cfgSensitivity({false, false, false, true, false, false, false}),
_cfgSensitivityDot({false, false, false, true, false, false, false}), _storeTime(false), _storeCoordinates(false), _splitComponents(true), _splitPorts(true),
_singleAsMultiPortUnitOps(false), _curCfg(nullptr), _nComp(0), _nVolumeDof(0), _nAxialCells(0), _nRadialCells(0), _nInletPorts(0), _nOutletPorts(0),
_numTimesteps(0), _numSens(0), _unitOp(idx), _needsReAlloc(false), _axialCoords(0), _radialCoords(0), _particleCoords(0)
_singleAsMultiPortUnitOps(false), _keepParticleSingletonDim(true), _curCfg(nullptr), _nComp(0), _nVolumeDof(0), _nAxialCells(0), _nRadialCells(0),
_nInletPorts(0), _nOutletPorts(0), _numTimesteps(0), _numSens(0), _unitOp(idx), _needsReAlloc(false), _axialCoords(0), _radialCoords(0), _particleCoords(0)
{
}

Expand Down Expand Up @@ -124,6 +124,8 @@ class InternalStorageUnitOpRecorder : public ISolutionRecorder
_nInletPorts = exporter.numInletPorts();
_nOutletPorts = exporter.numOutletPorts();

_keepParticleSingletonDim = !exporter.isParticleLumped();

_nAxialCells = exporter.numPrimaryCoordinates();
_nRadialCells = exporter.numSecondaryCoordinates();

Expand Down Expand Up @@ -445,6 +447,9 @@ class InternalStorageUnitOpRecorder : public ISolutionRecorder
inline bool treatSingleAsMultiPortUnitOps() const CADET_NOEXCEPT { return _singleAsMultiPortUnitOps; }
inline void treatSingleAsMultiPortUnitOps(bool smp) CADET_NOEXCEPT { _singleAsMultiPortUnitOps = smp; }

inline bool keepParticleSingletonDim() const CADET_NOEXCEPT { return _keepParticleSingletonDim; }
inline void keepParticleSingletonDim(bool keepSingleton) CADET_NOEXCEPT { _keepParticleSingletonDim = keepSingleton; }

inline UnitOpIdx unitOperation() const CADET_NOEXCEPT { return _unitOp; }
inline void unitOperation(UnitOpIdx idx) CADET_NOEXCEPT { _unitOp = idx; }

Expand Down Expand Up @@ -736,7 +741,12 @@ class InternalStorageUnitOpRecorder : public ISolutionRecorder
if (_nParShells.size() <= 1)
{
if (_nParShells[0] >= 1)
layout.push_back(_nParShells[0]);
{
if ((_nParShells[0] == 1) && _keepParticleSingletonDim)
layout.push_back(_nParShells[0]);
else if (_nParShells[0] > 1)
layout.push_back(_nParShells[0]);
}
layout.push_back(_nComp);

debugCheckTensorLayout(layout, _curStorage->particle[0].size());
Expand All @@ -754,14 +764,25 @@ class InternalStorageUnitOpRecorder : public ISolutionRecorder

for (std::size_t parType = 0; parType < _nParShells.size(); ++parType)
{
std::size_t layoutSize = layout.size();
if (hasParticleShells)
layout[layout.size() - 2] = _nParShells[parType];
{
if ((_nParShells[parType] == 1) && !_keepParticleSingletonDim)
{
layout[layoutSize - 2] = _nComp;
--layoutSize;
}
else if ((_nParShells[parType] == 1) && _keepParticleSingletonDim)
layout[layout.size() - 2] = _nParShells[parType];
else if (_nParShells[parType] > 1)
layout[layout.size() - 2] = _nParShells[parType];
}

debugCheckTensorLayout(layout, _curStorage->particle[parType].size());
debugCheckTensorLayout(layout, layoutSize, _curStorage->particle[parType].size());

oss.str("");
oss << prefix << "_PARTICLE_PARTYPE_" << std::setfill('0') << std::setw(3) << std::setprecision(0) << parType;
writer.template tensor<double>(oss.str(), layout.size(), layout.data(), _curStorage->particle[parType].data());
writer.template tensor<double>(oss.str(), layoutSize, layout.data(), _curStorage->particle[parType].data());
}
}
}
Expand All @@ -780,7 +801,12 @@ class InternalStorageUnitOpRecorder : public ISolutionRecorder
if (_nParShells.size() <= 1)
{
if (_nParShells[0] >= 1)
layout.push_back(_nParShells[0]);
{
if ((_nParShells[0] == 1) && _keepParticleSingletonDim)
layout.push_back(_nParShells[0]);
else if (_nParShells[0] > 1)
layout.push_back(_nParShells[0]);
}
layout.push_back(_nBoundStates[0]);

debugCheckTensorLayout(layout, _curStorage->solid[0].size());
Expand All @@ -798,15 +824,24 @@ class InternalStorageUnitOpRecorder : public ISolutionRecorder

for (std::size_t parType = 0; parType < _nParShells.size(); ++parType)
{
std::size_t layoutSize = layout.size();
if (hasParticleShells)
layout[layout.size() - 2] = _nParShells[parType];
layout[layout.size() - 1] = _nBoundStates[parType];
{
if ((_nParShells[parType] == 1) && !_keepParticleSingletonDim)
--layoutSize;
else if ((_nParShells[parType] == 1) && _keepParticleSingletonDim)
layout[layout.size() - 2] = _nParShells[parType];
else if (_nParShells[parType] > 1)
layout[layout.size() - 2] = _nParShells[parType];
}

layout[layoutSize - 1] = _nBoundStates[parType];

debugCheckTensorLayout(layout, _curStorage->solid[parType].size());
debugCheckTensorLayout(layout, layoutSize, _curStorage->solid[parType].size());

oss.str("");
oss << prefix << "_SOLID_PARTYPE_" << std::setfill('0') << std::setw(3) << std::setprecision(0) << parType;
writer.template tensor<double>(oss.str(), layout.size(), layout.data(), _curStorage->solid[parType].data());
writer.template tensor<double>(oss.str(), layoutSize, layout.data(), _curStorage->solid[parType].data());
}
}
}
Expand Down Expand Up @@ -856,17 +891,25 @@ class InternalStorageUnitOpRecorder : public ISolutionRecorder
}

template <typename T>
void debugCheckTensorLayout(const std::vector<T>& layout, std::size_t numElems)
void debugCheckTensorLayout(const std::vector<T>& layout, std::size_t layoutSize, std::size_t numElems)
{
#ifdef CADET_DEBUG
std::size_t layoutElems = 1;
for (T item : layout)
layoutElems *= item;
for (std::size_t i = 0; i < layoutSize; ++i)
layoutElems *= layout[i];

cadet_assert(numElems == layoutElems);
#endif
}

template <typename T>
void debugCheckTensorLayout(const std::vector<T>& layout, std::size_t numElems)
{
#ifdef CADET_DEBUG
debugCheckTensorLayout(layout, layout.size(), numElems);
#endif
}

StorageConfig _cfgSolution;
StorageConfig _cfgSolutionDot;
StorageConfig _cfgSensitivity;
Expand All @@ -876,6 +919,7 @@ class InternalStorageUnitOpRecorder : public ISolutionRecorder
bool _splitComponents;
bool _splitPorts;
bool _singleAsMultiPortUnitOps;
bool _keepParticleSingletonDim;

StorageConfig const* _curCfg;
Storage* _curStorage;
Expand Down
1 change: 1 addition & 0 deletions src/libcadet/model/GeneralRateModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ class GeneralRateModel : public UnitOperationBase
virtual bool hasParticleMobilePhase() const CADET_NOEXCEPT { return true; }
virtual bool hasSolidPhase() const CADET_NOEXCEPT { return _disc.strideBound[_disc.nParType] > 0; }
virtual bool hasVolume() const CADET_NOEXCEPT { return false; }
virtual bool isParticleLumped() const CADET_NOEXCEPT { return false; }

virtual unsigned int numComponents() const CADET_NOEXCEPT { return _disc.nComp; }
virtual unsigned int numPrimaryCoordinates() const CADET_NOEXCEPT { return _disc.nCol; }
Expand Down
1 change: 1 addition & 0 deletions src/libcadet/model/GeneralRateModel2D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ class GeneralRateModel2D : public UnitOperationBase
virtual bool hasParticleMobilePhase() const CADET_NOEXCEPT { return true; }
virtual bool hasSolidPhase() const CADET_NOEXCEPT { return _disc.strideBound[_disc.nParType] > 0; }
virtual bool hasVolume() const CADET_NOEXCEPT { return false; }
virtual bool isParticleLumped() const CADET_NOEXCEPT { return false; }

virtual unsigned int numComponents() const CADET_NOEXCEPT { return _disc.nComp; }
virtual unsigned int numPrimaryCoordinates() const CADET_NOEXCEPT { return _disc.nCol; }
Expand Down
1 change: 1 addition & 0 deletions src/libcadet/model/InletModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class InletModel : public IUnitOperation
virtual bool hasParticleMobilePhase() const CADET_NOEXCEPT { return false; }
virtual bool hasSolidPhase() const CADET_NOEXCEPT { return false; }
virtual bool hasVolume() const CADET_NOEXCEPT { return false; }
virtual bool isParticleLumped() const CADET_NOEXCEPT { return false; }

virtual unsigned int numComponents() const CADET_NOEXCEPT { return _nComp; }
virtual unsigned int numPrimaryCoordinates() const CADET_NOEXCEPT { return 0; }
Expand Down
1 change: 1 addition & 0 deletions src/libcadet/model/LumpedRateModelWithPores.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ class LumpedRateModelWithPores : public UnitOperationBase
virtual bool hasParticleMobilePhase() const CADET_NOEXCEPT { return true; }
virtual bool hasSolidPhase() const CADET_NOEXCEPT { return _disc.strideBound[_disc.nParType] > 0; }
virtual bool hasVolume() const CADET_NOEXCEPT { return false; }
virtual bool isParticleLumped() const CADET_NOEXCEPT { return true; }

virtual unsigned int numComponents() const CADET_NOEXCEPT { return _disc.nComp; }
virtual unsigned int numPrimaryCoordinates() const CADET_NOEXCEPT { return _disc.nCol; }
Expand Down
1 change: 1 addition & 0 deletions src/libcadet/model/LumpedRateModelWithoutPores.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ class LumpedRateModelWithoutPores : public UnitOperationBase
virtual bool hasParticleMobilePhase() const CADET_NOEXCEPT { return false; }
virtual bool hasSolidPhase() const CADET_NOEXCEPT { return _disc.strideBound > 0; }
virtual bool hasVolume() const CADET_NOEXCEPT { return false; }
virtual bool isParticleLumped() const CADET_NOEXCEPT { return false; }

virtual unsigned int numComponents() const CADET_NOEXCEPT { return _disc.nComp; }
virtual unsigned int numPrimaryCoordinates() const CADET_NOEXCEPT { return _disc.nCol; }
Expand Down
1 change: 1 addition & 0 deletions src/libcadet/model/OutletModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ class OutletModel : public IUnitOperation
virtual bool hasParticleMobilePhase() const CADET_NOEXCEPT { return false; }
virtual bool hasSolidPhase() const CADET_NOEXCEPT { return false; }
virtual bool hasVolume() const CADET_NOEXCEPT { return false; }
virtual bool isParticleLumped() const CADET_NOEXCEPT { return false; }

virtual unsigned int numComponents() const CADET_NOEXCEPT { return _nComp; }
virtual unsigned int numPrimaryCoordinates() const CADET_NOEXCEPT { return 0; }
Expand Down
1 change: 1 addition & 0 deletions src/libcadet/model/StirredTankModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class CSTRModel : public UnitOperationBase
virtual bool hasParticleMobilePhase() const CADET_NOEXCEPT { return false; }
virtual bool hasSolidPhase() const CADET_NOEXCEPT { return _totalBound > 0; }
virtual bool hasVolume() const CADET_NOEXCEPT { return true; }
virtual bool isParticleLumped() const CADET_NOEXCEPT { return true; }

virtual unsigned int numComponents() const CADET_NOEXCEPT { return _nComp; }
virtual unsigned int numPrimaryCoordinates() const CADET_NOEXCEPT { return 0; }
Expand Down

0 comments on commit eeafb20

Please sign in to comment.