1010// is available at http://www.gnu.org/licenses/gpl.html
1111// =============================================================================
1212
13- #include " model/LumpedRateModelWithPoresDG2D .hpp"
13+ #include " model/ColumnModel2D .hpp"
1414#include " model/BindingModel.hpp"
1515#include " model/parts/BindingCellKernel.hpp"
1616#include " linalg/DenseMatrix.hpp"
@@ -97,7 +97,7 @@ namespace model
9797 * @param [in] simState State of the simulation (state vector and its time derivatives) at which the Jacobian is evaluated
9898 * @return @c 0 on success, @c -1 on non-recoverable error, and @c +1 on recoverable error
9999 */
100- int LumpedRateModelWithPoresDG2D ::linearSolve (double t, double alpha, double outerTol, double * const rhs, double const * const weight,
100+ int ColumnModel2D ::linearSolve (double t, double alpha, double outerTol, double * const rhs, double const * const weight,
101101 const ConstSimulationState& simState)
102102{
103103 BENCH_SCOPE (_timerLinearSolve);
@@ -126,11 +126,11 @@ int LumpedRateModelWithPoresDG2D::linearSolve(double t, double alpha, double out
126126
127127 // rhs is passed twice but due to the values in jacA the writes happen to a different area of the rhs than the reads.
128128
129- // Handle inlet DOFs: // todo backward flow.
130- Eigen::Map<Eigen::Vector< double , Eigen::Dynamic>, 0 , Eigen::InnerStride<Eigen::Dynamic>> rInlet (rhs, _disc.radNPoints * _disc.nComp , Eigen::InnerStride<Eigen::Dynamic>(idxr. strideColRadialNode ()) );
131- Eigen::Map<Eigen::Vector< double , Eigen::Dynamic>, 0 , Eigen::InnerStride<Eigen::Dynamic>> rInletDep (rhs + idxr.offsetC (), _convDispOp.axNNodes () * _disc.radNPoints * _disc.nComp , Eigen::InnerStride<Eigen::Dynamic>(idxr. strideColRadialNode ()) );
129+ // Handle inlet DOFs:
130+ Eigen::Map<Eigen::VectorXd> rInlet (rhs, _disc.radNPoints * _disc.nComp );
131+ Eigen::Map<Eigen::VectorXd> rInletDep (rhs + idxr.offsetC (), _convDispOp.axNNodes () * _disc.radNPoints * _disc.nComp );
132132
133- rInletDep + = _jacInlet * rInlet;
133+ rInletDep - = _jacInlet * rInlet;
134134
135135 // ==== Step 2: Solve system of pure DOFs
136136 // The result is stored in rhs (in-place solution)
@@ -162,7 +162,7 @@ int LumpedRateModelWithPoresDG2D::linearSolve(double t, double alpha, double out
162162 *
163163 * @param [in] alpha Value of \f$ \alpha \f$ (arises from BDF time discretization)
164164 */
165- void LumpedRateModelWithPoresDG2D ::assembleDiscretizedGlobalJacobian (double alpha, Indexer idxr) {
165+ void ColumnModel2D ::assembleDiscretizedGlobalJacobian (double alpha, Indexer idxr) {
166166
167167 // set to static (per section) jacobian
168168 _globalJacDisc = _globalJac;
@@ -173,14 +173,19 @@ void LumpedRateModelWithPoresDG2D::assembleDiscretizedGlobalJacobian(double alph
173173 // Add time derivatives to particles
174174 for (unsigned int parType = 0 ; parType < _disc.nParType ; parType++)
175175 {
176- linalg::BandedEigenSparseRowIterator jac (_globalJacDisc, idxr.offsetCp (ParticleTypeIndex{ parType }) - idxr.offsetC ());
177-
178- for (unsigned int j = 0 ; j < _disc.nBulkPoints ; ++j)
176+ for (unsigned int colNode = 0 ; colNode < _disc.nBulkPoints ; ++colNode)
179177 {
180- addTimeDerivativeToJacobianParticleBlock (jac, idxr, alpha, parType); // Mobile and solid phase equations (advances jac accordingly)
178+ linalg::BandedEigenSparseRowIterator jac (_globalJacDisc, idxr.offsetCp (ParticleTypeIndex{ parType }, ParticleIndex{ colNode }) - idxr.offsetC ());
179+
180+ for (unsigned int j = 0 ; j < _disc.nParPoints [parType]; ++j)
181+ {
182+ // Time derivative for mobile and solid phase equations (advances jac accordingly)
183+ addTimeDerivativeToJacobianParticleShell (jac, idxr, alpha, parType);
184+ }
181185 }
182186 }
183187}
188+
184189/* *
185190 * @brief Adds Jacobian @f$ \frac{\partial F}{\partial \dot{y}} @f$ to bead rows of system Jacobian
186191 * @details Actually adds @f$ \alpha \frac{\partial F}{\partial \dot{y}} @f$, which is useful
@@ -191,40 +196,10 @@ void LumpedRateModelWithPoresDG2D::assembleDiscretizedGlobalJacobian(double alph
191196 * @param [in] alpha Value of \f$ \alpha \f$ (arises from BDF time discretization)
192197 * @param [in] parType Index of the particle type
193198 */
194- void LumpedRateModelWithPoresDG2D::addTimeDerivativeToJacobianParticleBlock (linalg::BandedEigenSparseRowIterator& jac, const Indexer& idxr, double alpha, unsigned int parType)
199+ void ColumnModel2D::addTimeDerivativeToJacobianParticleShell (linalg::BandedEigenSparseRowIterator& jac, const Indexer& idxr, double alpha, unsigned int parType)
195200{
196- // Mobile phase
197- for (int comp = 0 ; comp < static_cast <int >(_disc.nComp ); ++comp, ++jac)
198- {
199- // Add derivative with respect to dc_p / dt to Jacobian
200- jac[0 ] += alpha;
201-
202- const double invBetaP = (1.0 - static_cast <double >(_parPorosity[parType])) / (static_cast <double >(_poreAccessFactor[parType * _disc.nComp + comp]) * static_cast <double >(_parPorosity[parType]));
203-
204- // Add derivative with respect to dq / dt to Jacobian
205- const int nBound = static_cast <int >(_disc.nBound [parType * _disc.nComp + comp]);
206- for (int i = 0 ; i < nBound; ++i)
207- {
208- // Index explanation:
209- // -comp -> go back to beginning of liquid phase
210- // + strideParLiquid() skip to solid phase
211- // + offsetBoundComp() jump to component (skips all bound states of previous components)
212- // + i go to current bound state
213- jac[idxr.strideParLiquid () - comp + idxr.offsetBoundComp (ParticleTypeIndex{ parType }, ComponentIndex{ static_cast <unsigned int >(comp) }) + i] += alpha * invBetaP;
214- }
215- }
216-
217- // Solid phase
218- int const * const qsReaction = _binding[parType]->reactionQuasiStationarity ();
219- for (unsigned int bnd = 0 ; bnd < _disc.strideBound [parType]; ++bnd, ++jac)
220- {
221- // Add derivative with respect to dynamic states to Jacobian
222- if (qsReaction[bnd])
223- continue ;
224-
225- // Add derivative with respect to dq / dt to Jacobian
226- jac[0 ] += alpha;
227- }
201+ parts::cell::addTimeDerivativeToJacobianParticleShell<linalg::BandedEigenSparseRowIterator, true >(jac, alpha, static_cast <double >(_particles[parType]->getPorosity ()), _disc.nComp , _disc.nBound + _disc.nComp * parType,
202+ _particles[parType]->getPoreAccessFactor (), _disc.strideBound [parType], _disc.boundOffset + _disc.nComp * parType, _binding[parType]->reactionQuasiStationarity ());
228203}
229204
230205} // namespace model
0 commit comments