Skip to content

Commit 4efb580

Browse files
committed
break up equilbrium reactions to impl file:
1 parent 4fd890f commit 4efb580

File tree

1 file changed

+172
-0
lines changed

1 file changed

+172
-0
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#pragma once
2+
3+
namespace hpcReact
4+
{
5+
namespace bulkGeneric
6+
{
7+
8+
template< typename REAL_TYPE,
9+
typename INT_TYPE,
10+
typename INDEX_TYPE,
11+
bool LOGE_CONCENTRATION,
12+
bool LOGE_RESIDUAL >
13+
template< typename PARAMS_DATA,
14+
typename ARRAY_1D,
15+
typename ARRAY_1D_TO_CONST,
16+
typename ARRAY_1D_TO_CONST2,
17+
typename ARRAY_2D >
18+
HPCREACT_HOST_DEVICE void
19+
EquilibriumReactions< REAL_TYPE,
20+
INT_TYPE,
21+
INDEX_TYPE,
22+
LOGE_CONCENTRATION,
23+
LOGE_RESIDUAL >::computeResidualAndJacobian( RealType const & temperature,
24+
PARAMS_DATA const & params,
25+
ARRAY_1D_TO_CONST const & speciesConcentration0,
26+
ARRAY_1D_TO_CONST2 const & xi,
27+
ARRAY_1D & residual,
28+
ARRAY_2D & jacobian )
29+
{
30+
HPCREACT_UNUSED_VAR( temperature );
31+
constexpr int numSpecies = PARAMS_DATA::numSpecies;
32+
constexpr int numReactions = PARAMS_DATA::numReactions;
33+
34+
// initialize the species concentration
35+
RealType speciesConcentration[numSpecies];
36+
for( IndexType i=0; i<numSpecies; ++i )
37+
{
38+
if constexpr ( LOGE_CONCENTRATION )
39+
{
40+
for( IndexType r=0; r<numReactions; ++r )
41+
{
42+
speciesConcentration[i] = log( exp( speciesConcentration0[i] ) + params.stoichiometricMatrix( r, i ) * xi[r] );
43+
}
44+
}
45+
else
46+
{
47+
for( IndexType r=0; r<numReactions; ++r )
48+
{
49+
speciesConcentration[i] = speciesConcentration0[i] + params.stoichiometricMatrix( r, i ) * xi[r];
50+
}
51+
}
52+
}
53+
54+
// loop over reactions
55+
for( IndexType a=0; a<numReactions; ++a )
56+
{
57+
// get the equilibrium constant for this reaction
58+
RealType const Keq = params.equilibriumConstant( a );
59+
60+
RealType forwardProduct = 1.0;
61+
RealType reverseProduct = 1.0;
62+
RealType dForwardProduct_dxi[numReactions] = {0.0};
63+
RealType dReverseProduct_dxi[numReactions] = {0.0};
64+
// loop over species
65+
for( IndexType i=0; i<numSpecies; ++i )
66+
{
67+
RealType const s_ai = params.stoichiometricMatrix( a, i );
68+
69+
if( s_ai < 0.0 )
70+
{
71+
// forward reaction
72+
forwardProduct *= pow( speciesConcentration[i], -s_ai );
73+
// derivative of forward product with respect to xi
74+
for( IndexType b=0; b<numReactions; ++b )
75+
{
76+
dForwardProduct_dxi[b] += -s_ai / speciesConcentration[i] * params.stoichiometricMatrix( b, i );
77+
}
78+
}
79+
else if( s_ai > 0.0 )
80+
{
81+
// reverse reaction
82+
reverseProduct *= pow( speciesConcentration[i], s_ai );
83+
// derivative of reverse product with respect to xi
84+
for( IndexType b=0; b<numReactions; ++b )
85+
{
86+
dReverseProduct_dxi[b] += s_ai / speciesConcentration[i] * params.stoichiometricMatrix( b, i );
87+
}
88+
}
89+
}
90+
// compute the residual for this reaction
91+
residual[a] = forwardProduct - Keq * reverseProduct;
92+
93+
// Finish the derivatives of the product terms with respect to xi
94+
for( IndexType b=0; b<numReactions; ++b )
95+
{
96+
dForwardProduct_dxi[b] *= forwardProduct;
97+
dReverseProduct_dxi[b] *= reverseProduct;
98+
jacobian( a, b ) = dForwardProduct_dxi[b] - Keq * dReverseProduct_dxi[b];
99+
}
100+
}
101+
}
102+
103+
template< typename REAL_TYPE,
104+
typename INT_TYPE,
105+
typename INDEX_TYPE,
106+
bool LOGE_CONCENTRATION,
107+
bool LOGE_RESIDUAL >
108+
template< typename PARAMS_DATA,
109+
typename ARRAY_1D,
110+
typename ARRAY_1D_TO_CONST >
111+
HPCREACT_HOST_DEVICE
112+
void
113+
EquilibriumReactions< REAL_TYPE,
114+
INT_TYPE,
115+
INDEX_TYPE,
116+
LOGE_CONCENTRATION,
117+
LOGE_RESIDUAL >::enforceEquilibrium( RealType const & temperature,
118+
PARAMS_DATA const & params,
119+
ARRAY_1D_TO_CONST const & speciesConcentration0,
120+
ARRAY_1D & speciesConcentration )
121+
{
122+
HPCREACT_UNUSED_VAR( temperature );
123+
constexpr int numSpecies = PARAMS_DATA::numSpecies;
124+
constexpr int numReactions = PARAMS_DATA::numReactions;
125+
double residual[numReactions] = { 0.0 };
126+
double xi[numReactions] = { 0.0 };
127+
double dxi[numReactions] = { 0.0 };
128+
CArrayWrapper< double, numReactions, numReactions > jacobian;
129+
130+
REAL_TYPE residualNorm = 0.0;
131+
for( int k=0; k<10; ++k )
132+
{
133+
computeResidualAndJacobian( temperature,
134+
params,
135+
speciesConcentration0,
136+
xi,
137+
residual,
138+
jacobian );
139+
140+
residualNorm = 0.0;
141+
for( int j = 0; j < numReactions; ++j )
142+
{
143+
residualNorm += residual[j] * residual[j];
144+
}
145+
residualNorm = sqrt( residualNorm );
146+
if( residualNorm < 1.0e-14 )
147+
{
148+
break;
149+
}
150+
151+
solveNxN_pivoted< double, numReactions >( jacobian.data, residual, dxi );
152+
153+
// solve for the change in xi
154+
for( IndexType r=0; r<numReactions; ++r )
155+
{
156+
xi[r] -= dxi[r];
157+
}
158+
}
159+
160+
for( IndexType i=0; i<numSpecies; ++i )
161+
{
162+
speciesConcentration[i] = speciesConcentration0[i];
163+
for( IndexType r=0; r<numReactions; ++r )
164+
{
165+
speciesConcentration[i] += params.stoichiometricMatrix( r, i ) * xi[r];
166+
}
167+
}
168+
}
169+
170+
171+
} // namespace bulkGeneric
172+
} // namespace hpcReact

0 commit comments

Comments
 (0)