@@ -43,7 +43,17 @@ class EquilibriumReactions
4343 typename ARRAY_1D_TO_CONST >
4444 static HPCREACT_HOST_DEVICE
4545 void
46- enforceEquilibrium ( RealType const & temperature,
46+ enforceEquilibrium_Extents ( RealType const & temperature,
47+ PARAMS_DATA const & params,
48+ ARRAY_1D_TO_CONST const & speciesConcentration0,
49+ ARRAY_1D & speciesConcentration );
50+
51+ template < typename PARAMS_DATA,
52+ typename ARRAY_1D,
53+ typename ARRAY_1D_TO_CONST >
54+ static HPCREACT_HOST_DEVICE
55+ void
56+ enforceEquilibrium_Aggregate ( RealType const & temperature,
4757 PARAMS_DATA const & params,
4858 ARRAY_1D_TO_CONST const & speciesConcentration0,
4959 ARRAY_1D & speciesConcentration );
@@ -62,190 +72,26 @@ class EquilibriumReactions
6272 ARRAY_1D & residual,
6373 ARRAY_2D & jacobian );
6474
75+ template < typename PARAMS_DATA,
76+ typename ARRAY_1D,
77+ typename ARRAY_1D_TO_CONST,
78+ typename ARRAY_2D >
79+ static HPCREACT_HOST_DEVICE void
80+ computeResidualAndJacobianAggregatePrimaryConcentrations ( RealType const & temperature,
81+ PARAMS_DATA const & params,
82+ ARRAY_1D_TO_CONST const & targetAggregatePrimaryConcentrations,
83+ ARRAY_1D_TO_CONST const & logPrimarySpeciesConcentration,
84+ ARRAY_1D & residual,
85+ ARRAY_2D & jacobian );
6586};
6687
67- constexpr bool debugPrinting = false ;
68-
69- template < typename REAL_TYPE,
70- typename INT_TYPE,
71- typename INDEX_TYPE >
72- template < typename PARAMS_DATA,
73- typename ARRAY_1D,
74- typename ARRAY_1D_TO_CONST,
75- typename ARRAY_1D_TO_CONST2,
76- typename ARRAY_2D >
77- HPCREACT_HOST_DEVICE inline
78- void
79- EquilibriumReactions< REAL_TYPE,
80- INT_TYPE,
81- INDEX_TYPE >::computeResidualAndJacobian( REAL_TYPE const & temperature,
82- PARAMS_DATA const & params,
83- ARRAY_1D_TO_CONST const & speciesConcentration0,
84- ARRAY_1D_TO_CONST2 const & xi,
85- ARRAY_1D & residual,
86- ARRAY_2D & jacobian )
87- {
8888
89- HPCREACT_UNUSED_VAR ( temperature );
90- constexpr int numSpecies = PARAMS_DATA::numSpecies;
91- constexpr int numReactions = PARAMS_DATA::numReactions;
92-
93- // initialize the species concentration
94- RealType speciesConcentration[numSpecies];
95- for ( IndexType i=0 ; i<numSpecies; ++i )
96- {
97- speciesConcentration[i] = speciesConcentration0[i];
98- for ( IndexType r=0 ; r<numReactions; ++r )
99- {
100- speciesConcentration[i] += params.stoichiometricMatrix ( r, i ) * xi[r];
101- }
102- }
103-
104-
105- // loop over reactions
106- for ( IndexType a=0 ; a<numReactions; ++a )
107- {
108- // get the equilibrium constant for this reaction
109- RealType const Keq = params.equilibriumConstant ( a );
110-
111-
112- RealType forwardProduct = 1.0 ;
113- RealType reverseProduct = 1.0 ;
114-
115- // these actually only hold the derivatives of the single concentration term for the product...not the full product.
116- // it will have to be multiplied by the product itself to get the derivative of the product.
117- RealType dForwardProduct_dxi_divProduct[numReactions] = {0.0 };
118- RealType dReverseProduct_dxi_divProduct[numReactions] = {0.0 };
119- // loop over species
120- for ( IndexType i=0 ; i<numSpecies; ++i )
121- {
122- RealType const s_ai = params.stoichiometricMatrix ( a, i );
123- if ( s_ai < 0.0 )
124- {
125- // forward reaction
126- forwardProduct *= pow ( speciesConcentration[i], -s_ai );
127- // derivative of forward product with respect to xi
128- for ( IndexType b=0 ; b<numReactions; ++b )
129- {
130- dForwardProduct_dxi_divProduct[b] += -s_ai / speciesConcentration[i] * params.stoichiometricMatrix ( b, i );
131- }
132- }
133- else if ( s_ai > 0.0 )
134- {
135- // reverse reaction
136- reverseProduct *= pow ( speciesConcentration[i], s_ai );
137- // derivative of reverse product with respect to xi
138- for ( IndexType b=0 ; b<numReactions; ++b )
139- {
140- dReverseProduct_dxi_divProduct[b] += s_ai / speciesConcentration[i] * params.stoichiometricMatrix ( b, i );
141- }
142- }
143- }
144- // compute the residual for this reaction
145- residual[a] = log ( reverseProduct / ( forwardProduct * Keq ) );
146-
147- // compute the jacobian
148- for ( IndexType b=0 ; b<numReactions; ++b )
149- {
150- jacobian ( a, b ) = -dForwardProduct_dxi_divProduct[b] + dReverseProduct_dxi_divProduct[b];
151- }
152- }
153- }
15489
155- template < typename REAL_TYPE,
156- typename INT_TYPE,
157- typename INDEX_TYPE >
158- template < typename PARAMS_DATA,
159- typename ARRAY_1D,
160- typename ARRAY_1D_TO_CONST >
161- HPCREACT_HOST_DEVICE inline
162- void
163- EquilibriumReactions< REAL_TYPE,
164- INT_TYPE,
165- INDEX_TYPE >::enforceEquilibrium( REAL_TYPE const & temperature,
166- PARAMS_DATA const & params,
167- ARRAY_1D_TO_CONST const & speciesConcentration0,
168- ARRAY_1D & speciesConcentration )
169- {
170- HPCREACT_UNUSED_VAR ( temperature );
171- constexpr int numSpecies = PARAMS_DATA::numSpecies;
172- constexpr int numReactions = PARAMS_DATA::numReactions;
173- double residual[numReactions] = { 0.0 };
174- double xi[numReactions] = { 0.0 };
175- double dxi[numReactions] = { 0.0 };
176- CArrayWrapper< double , numReactions, numReactions > jacobian;
177-
178- REAL_TYPE residualNorm = 0.0 ;
179- for ( int k=0 ; k<30 ; ++k )
180- {
181- computeResidualAndJacobian ( temperature,
182- params,
183- speciesConcentration0,
184- xi,
185- residual,
186- jacobian );
187-
188- residualNorm = 0.0 ;
189- for ( int j = 0 ; j < numReactions; ++j )
190- {
191- residualNorm += residual[j] * residual[j];
192- }
193- residualNorm = sqrt ( residualNorm );
194- printf ( " iter, residualNorm = %2d, %16.10g \n " , k, residualNorm );
195- if ( residualNorm < 1.0e-12 )
196- {
197- printf ( " converged\n " );
198- break ;
199- }
200-
201- // solve for the change in xi
202- for ( int r=0 ; r<numReactions; ++r )
203- {
204- dxi[r] = 0.0 ;
205- residual[r] = -residual[r];
206- }
207-
208- solveNxN_Cholesky< double , numReactions >( jacobian.data , residual, dxi );
209-
210-
211- // scaling
212- REAL_TYPE scale = 1.0 ;
213- for ( IndexType i=0 ; i<numSpecies; ++i )
214- {
215- REAL_TYPE cn = speciesConcentration0[i];
216- REAL_TYPE dc = 0.0 ;
217- for ( IndexType r=0 ; r<numReactions; ++r )
218- {
219- dc += params.stoichiometricMatrix ( r, i ) * dxi[r];
220- cn += params.stoichiometricMatrix ( r, i ) * xi[r];
221- }
222- if ( cn+dc < 1.0e-30 )
223- {
224- REAL_TYPE const fscale = ( 1.0e-30 - cn ) / (dc);
225- if ( fscale < scale )
226- {
227- scale = 0.9 *fscale;
228- // printf( "i, cn, dc, scale = %d, %18.12g %18.12g %18.12g\n", i, cn, dc, scale );
229- }
230- }
231- }
232-
233- for ( IndexType r=0 ; r<numReactions; ++r )
234- {
235- xi[r] += scale * dxi[r];
236- }
237-
238- }
239-
240- for ( IndexType i=0 ; i<numSpecies; ++i )
241- {
242- speciesConcentration[i] = speciesConcentration0[i];
243- for ( IndexType r=0 ; r<numReactions; ++r )
244- {
245- speciesConcentration[i] += params.stoichiometricMatrix ( r, i ) * xi[r];
246- }
247- }
248- }
24990
25091} // namespace bulkGeneric
25192} // namespace hpcReact
93+
94+ #if !defined(__INTELLISENSE__)
95+ #include " EquilibriumReactionsAggregatePrimaryConcentration_impl.hpp"
96+ #include " EquilibriumReactionsReactionExtents_impl.hpp"
97+ #endif
0 commit comments