Skip to content

Commit 30d9563

Browse files
committed
added aggregate based equilibrium enforcement
1 parent 2ffbbc4 commit 30d9563

File tree

5 files changed

+422
-182
lines changed

5 files changed

+422
-182
lines changed

src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ set( hpcReact_headers
33
common/macros.hpp
44
common/CArrayWrapper.hpp
55
reactions/bulkGeneric/EquilibriumReactions.hpp
6+
reactions/bulkGeneric/EquilibriumReactionsAggregatePrimaryConcentration_impl.hpp
7+
reactions/bulkGeneric/EquilibriumReactionsReactionExtents_impl.hpp
68
reactions/bulkGeneric/KineticReactions.hpp
79
reactions/bulkGeneric/KineticReactions_impl.hpp
810
reactions/bulkGeneric/Parameters.hpp

src/reactions/bulkGeneric/EquilibriumReactions.hpp

Lines changed: 27 additions & 181 deletions
Original file line numberDiff line numberDiff line change
@@ -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
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#if defined(__INTELLISENSE__)
2+
#include "EquilibriumReactions.hpp"
3+
#endif
4+
5+
#include "SpeciesUtilities.hpp"
6+
7+
namespace hpcReact
8+
{
9+
namespace bulkGeneric
10+
{
11+
12+
13+
template< typename REAL_TYPE,
14+
typename INT_TYPE,
15+
typename INDEX_TYPE >
16+
template< typename PARAMS_DATA,
17+
typename ARRAY_1D,
18+
typename ARRAY_1D_TO_CONST,
19+
typename ARRAY_2D >
20+
HPCREACT_HOST_DEVICE
21+
inline
22+
void
23+
EquilibriumReactions< REAL_TYPE,
24+
INT_TYPE,
25+
INDEX_TYPE >::computeResidualAndJacobianAggregatePrimaryConcentrations( RealType const & temperature,
26+
PARAMS_DATA const & params,
27+
ARRAY_1D_TO_CONST const & targetAggregatePrimaryConcentrations,
28+
ARRAY_1D_TO_CONST const & logPrimarySpeciesConcentration,
29+
ARRAY_1D & residual,
30+
ARRAY_2D & jacobian )
31+
{
32+
HPCREACT_UNUSED_VAR( temperature );
33+
constexpr int numSpecies = PARAMS_DATA::numSpecies;
34+
constexpr int numSecondarySpecies = PARAMS_DATA::numReactions;
35+
constexpr int numPrimarySpecies = numSpecies - numSecondarySpecies;
36+
37+
RealType aggregatePrimaryConcentrations[numPrimarySpecies] = {0.0};
38+
ARRAY_2D dAggregatePrimarySpeciesConcentrationsDerivatives_dLogPrimarySpeciesConcentrations = {{{0.0}}};
39+
calculateAggregatePrimaryConcentrationsWrtLogC<REAL_TYPE, INT_TYPE, INDEX_TYPE >( params,
40+
logPrimarySpeciesConcentration,
41+
aggregatePrimaryConcentrations,
42+
dAggregatePrimarySpeciesConcentrationsDerivatives_dLogPrimarySpeciesConcentrations );
43+
44+
45+
for( IndexType i=0; i<numPrimarySpecies; ++i )
46+
{
47+
residual[i] = -(1.0 - aggregatePrimaryConcentrations[i] / targetAggregatePrimaryConcentrations[i]);
48+
for( IndexType j=0; j<numPrimarySpecies; ++j )
49+
{
50+
jacobian( i, j ) = -dAggregatePrimarySpeciesConcentrationsDerivatives_dLogPrimarySpeciesConcentrations[i][j] / targetAggregatePrimaryConcentrations[i];
51+
}
52+
}
53+
}
54+
55+
template< typename REAL_TYPE,
56+
typename INT_TYPE,
57+
typename INDEX_TYPE >
58+
template< typename PARAMS_DATA,
59+
typename ARRAY_1D,
60+
typename ARRAY_1D_TO_CONST >
61+
HPCREACT_HOST_DEVICE inline
62+
void
63+
EquilibriumReactions< REAL_TYPE,
64+
INT_TYPE,
65+
INDEX_TYPE >::enforceEquilibrium_Aggregate( REAL_TYPE const & temperature,
66+
PARAMS_DATA const & params,
67+
ARRAY_1D_TO_CONST const & logPrimarySpeciesConcentration0,
68+
ARRAY_1D & logPrimarySpeciesConcentration )
69+
{
70+
HPCREACT_UNUSED_VAR( temperature );
71+
constexpr int numSpecies = PARAMS_DATA::numSpecies;
72+
constexpr int numReactions = PARAMS_DATA::numReactions;
73+
constexpr int numPrimarySpecies = numSpecies - numReactions;
74+
75+
double residual[numPrimarySpecies] = { 0.0 };
76+
// double aggregatePrimarySpeciesConcentration[numPrimarySpecies] = { 0.0 };
77+
double targetAggregatePrimarySpeciesConcentration[numPrimarySpecies] = { 0.0 };
78+
double dLogCp[numPrimarySpecies] = { 0.0 };
79+
CArrayWrapper< double, numPrimarySpecies, numPrimarySpecies > jacobian;
80+
81+
82+
for( int i=0; i<numPrimarySpecies; ++i )
83+
{
84+
targetAggregatePrimarySpeciesConcentration[i] = exp( logPrimarySpeciesConcentration0[i] );
85+
logPrimarySpeciesConcentration[i] = logPrimarySpeciesConcentration0[i] ;
86+
}
87+
88+
89+
REAL_TYPE residualNorm = 0.0;
90+
for( int k=0; k<30; ++k )
91+
{
92+
computeResidualAndJacobianAggregatePrimaryConcentrations( temperature,
93+
params,
94+
targetAggregatePrimarySpeciesConcentration,
95+
logPrimarySpeciesConcentration,
96+
residual,
97+
jacobian );
98+
99+
residualNorm = 0.0;
100+
for( int j = 0; j < numPrimarySpecies; ++j )
101+
{
102+
residualNorm += residual[j] * residual[j];
103+
}
104+
residualNorm = sqrt( residualNorm );
105+
printf( "iter, residualNorm = %2d, %16.10g \n", k, residualNorm );
106+
if( residualNorm < 1.0e-12 )
107+
{
108+
printf( " converged\n" );
109+
break;
110+
}
111+
112+
solveNxN_pivoted< double, numPrimarySpecies >( jacobian.data, residual, dLogCp );
113+
114+
115+
for( IndexType r=0; r<numReactions; ++r )
116+
{
117+
logPrimarySpeciesConcentration[r] += dLogCp[r];
118+
}
119+
120+
}
121+
}
122+
} // namespace bulkGeneric
123+
} // namespace hpcReact

0 commit comments

Comments
 (0)