Cantera
2.0
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
src
equil
vcs_nondim.cpp
Go to the documentation of this file.
1
/**
2
* @file vcs_nondim.cpp
3
* Nondimensionalization routines within VCSnonideal
4
*/
5
/*
6
* Copyright (2007) Sandia Corporation. Under the terms of
7
* Contract DE-AC04-94AL85000 with Sandia Corporation, the
8
* U.S. Government retains certain rights in this software.
9
*/
10
11
#include "
cantera/equil/vcs_solve.h
"
12
#include "
cantera/equil/vcs_internal.h
"
13
#include "
cantera/equil/vcs_VolPhase.h
"
14
#include "
cantera/base/stringUtils.h
"
15
#include "
vcs_Exception.h
"
16
17
#include <cstdio>
18
#include <cstdlib>
19
#include <cmath>
20
21
namespace
VCSnonideal
22
{
23
24
// Returns the multiplier for electric charge terms
25
/*
26
* This is basically equal to F/RT
27
*
28
* @param mu_units integer representing the dimensional units system
29
* @param TKelvin double Temperature in Kelvin
30
*
31
* @return Returns the value of F/RT
32
*/
33
double
VCS_SOLVE::vcs_nondim_Farad
(
int
mu_units,
double
TKelvin)
const
34
{
35
double
Farad;
36
if
(TKelvin <= 0.0) {
37
TKelvin = 293.15;
38
}
39
switch
(mu_units) {
40
case
VCS_UNITS_MKS:
41
case
VCS_UNITS_KJMOL:
42
case
VCS_UNITS_KCALMOL:
43
Farad = Cantera::ElectronCharge *
Cantera::Avogadro
/
44
(TKelvin *
Cantera::GasConstant
);
45
break
;
46
case
VCS_UNITS_UNITLESS:
47
Farad = Cantera::ElectronCharge *
Cantera::Avogadro
;
48
break
;
49
case
VCS_UNITS_KELVIN:
50
Farad = Cantera::ElectronCharge * Cantera::Avogadro/ TKelvin;
51
break
;
52
default
:
53
plogf
(
"vcs_nondim_Farad error: unknown units: %d\n"
, mu_units);
54
plogendl
();
55
exit(EXIT_FAILURE);
56
}
57
return
Farad;
58
}
59
60
// Returns the multiplier for the nondimensionalization of the equations
61
/*
62
* This is basically equal to RT
63
*
64
* @param mu_units integer representing the dimensional units system
65
* @param TKelvin double Temperature in Kelvin
66
*
67
* @return Returns the value of RT
68
*/
69
double
VCS_SOLVE::vcs_nondimMult_TP
(
int
mu_units,
double
TKelvin)
const
70
{
71
double
rt;
72
if
(TKelvin <= 0.0) {
73
TKelvin = 293.15;
74
}
75
switch
(mu_units) {
76
case
VCS_UNITS_KCALMOL:
77
rt = TKelvin *
Cantera::GasConst_cal_mol_K
* 1e-3;
78
break
;
79
case
VCS_UNITS_UNITLESS:
80
rt = 1.0;
81
break
;
82
case
VCS_UNITS_KJMOL:
83
rt = TKelvin *
Cantera::GasConstant
* 1e-6;
84
break
;
85
case
VCS_UNITS_KELVIN:
86
rt = TKelvin;
87
break
;
88
case
VCS_UNITS_MKS:
89
rt = TKelvin *
Cantera::GasConstant
;
90
break
;
91
default
:
92
plogf
(
"vcs_nondimMult_TP error: unknown units: %d\n"
, mu_units);
93
plogendl
();
94
exit(EXIT_FAILURE);
95
}
96
return
rt;
97
}
98
99
// Nondimensionalize the problem data
100
/*
101
* Nondimensionalize the free energies using the divisor, R * T
102
*
103
* Essentially the internal data can either be in dimensional form
104
* or in nondimensional form. This routine switches the data from
105
* dimensional form into nondimensional form.
106
*
107
* What we do is to divide by RT.
108
*
109
* @todo Add a scale factor based on the total mole numbers.
110
* The algorithm contains hard coded numbers based on the
111
* total mole number. If we ever were faced with a problem
112
* with significantly different total kmol numbers than one
113
* the algorithm would have problems.
114
*/
115
void
VCS_SOLVE::vcs_nondim_TP
()
116
{
117
double
tf;
118
if
(
m_unitsState
==
VCS_DIMENSIONAL_G
) {
119
m_unitsState
=
VCS_NONDIMENSIONAL_G
;
120
tf = 1.0 /
vcs_nondimMult_TP
(
m_VCS_UnitsFormat
,
m_temperature
);
121
for
(
size_t
i = 0; i <
m_numSpeciesTot
; ++i) {
122
/*
123
* Modify the standard state and total chemical potential data,
124
* FF(I), to make it dimensionless, i.e., mu / RT.
125
* Thus, we may divide it by the temperature.
126
*/
127
m_SSfeSpecies
[i] *= tf;
128
m_deltaGRxn_new
[i] *= tf;
129
m_deltaGRxn_old
[i] *= tf;
130
m_feSpecies_old
[i] *= tf;
131
}
132
133
m_Faraday_dim
=
vcs_nondim_Farad
(
m_VCS_UnitsFormat
,
m_temperature
);
134
135
/*
136
* Scale the total moles if necessary:
137
* First find out the total moles
138
*/
139
double
tmole_orig =
vcs_tmoles
();
140
141
/*
142
* Then add in the total moles of elements that are goals. Either one
143
* or the other is specified here.
144
*/
145
double
esum = 0.0;
146
for
(
size_t
i = 0; i <
m_numElemConstraints
; ++i) {
147
if
(
m_elType
[i] ==
VCS_ELEM_TYPE_ABSPOS
) {
148
esum += fabs(
m_elemAbundancesGoal
[i]);
149
}
150
}
151
tmole_orig += esum;
152
153
/*
154
* Ok now test out the bounds on the total moles that this program can
155
* handle. These are a bit arbitrary. However, it would seem that any
156
* reasonable input would be between these two numbers below.
157
*/
158
if
(tmole_orig < 1.0E-200 || tmole_orig > 1.0E200) {
159
plogf
(
" VCS_SOLVE::vcs_nondim_TP ERROR: Total input moles , %g, is outside the range handled by vcs. exit"
,
160
tmole_orig);
161
plogendl
();
162
throw
vcsError(
"VCS_SOLVE::vcs_nondim_TP"
,
" Total input moles ,"
+
Cantera::fp2str
(tmole_orig) +
163
"is outside the range handled by vcs.\n"
);
164
}
165
166
// Determine the scale of the problem
167
if
(tmole_orig > 1.0E4) {
168
m_totalMoleScale
= tmole_orig / 1.0E4;
169
}
else
if
(tmole_orig < 1.0E-4) {
170
m_totalMoleScale
= tmole_orig / 1.0E-4;
171
}
else
{
172
m_totalMoleScale
= 1.0;
173
}
174
175
if
(
m_totalMoleScale
!= 1.0) {
176
if
(
m_VCS_UnitsFormat
== VCS_UNITS_MKS) {
177
#ifdef DEBUG_MODE
178
if
(
m_debug_print_lvl
>= 2) {
179
plogf
(
" --- vcs_nondim_TP() called: USING A MOLE SCALE OF %g until further notice"
,
m_totalMoleScale
);
180
plogendl
();
181
}
182
#endif
183
for
(
size_t
i = 0; i <
m_numSpeciesTot
; ++i) {
184
if
(
m_speciesUnknownType
[i] !=
VCS_SPECIES_TYPE_INTERFACIALVOLTAGE
) {
185
m_molNumSpecies_old
[i] *= (1.0 /
m_totalMoleScale
);
186
}
187
}
188
for
(
size_t
i = 0; i <
m_numElemConstraints
; ++i) {
189
m_elemAbundancesGoal
[i] *= (1.0 /
m_totalMoleScale
);
190
}
191
192
for
(
size_t
iph = 0; iph <
m_numPhases
; iph++) {
193
TPhInertMoles
[iph] *= (1.0 /
m_totalMoleScale
);
194
if
(
TPhInertMoles
[iph] != 0.0) {
195
vcs_VolPhase
* vphase =
m_VolPhaseList
[iph];
196
vphase->
setTotalMolesInert
(
TPhInertMoles
[iph]);
197
}
198
}
199
}
200
vcs_tmoles
();
201
}
202
}
203
}
204
205
// Redimensionalize the problem data
206
/*
207
* Redimensionalize the free energies using the multiplier R * T
208
*
209
* Essentially the internal data can either be in dimensional form
210
* or in nondimensional form. This routine switches the data from
211
* nondimensional form into dimensional form.
212
*
213
* What we do is to multiply by RT.
214
*/
215
void
VCS_SOLVE::vcs_redim_TP
(
void
)
216
{
217
double
tf;
218
if
(
m_unitsState
!=
VCS_DIMENSIONAL_G
) {
219
m_unitsState
=
VCS_DIMENSIONAL_G
;
220
tf =
vcs_nondimMult_TP
(
m_VCS_UnitsFormat
,
m_temperature
);
221
for
(
size_t
i = 0; i <
m_numSpeciesTot
; ++i) {
222
/*
223
* Modify the standard state and total chemical potential data,
224
* FF(I), to make it have units, i.e. mu = RT * mu_star
225
*/
226
m_SSfeSpecies
[i] *= tf;
227
m_deltaGRxn_new
[i] *= tf;
228
m_deltaGRxn_old
[i] *= tf;
229
m_feSpecies_old
[i] *= tf;
230
}
231
m_Faraday_dim
*= tf;
232
}
233
if
(
m_totalMoleScale
!= 1.0) {
234
if
(
m_VCS_UnitsFormat
== VCS_UNITS_MKS) {
235
#ifdef DEBUG_MODE
236
if
(
m_debug_print_lvl
>= 2) {
237
plogf
(
" --- vcs_redim_TP() called: getting rid of mole scale of %g"
,
m_totalMoleScale
);
238
plogendl
();
239
}
240
#endif
241
for
(
size_t
i = 0; i <
m_numSpeciesTot
; ++i) {
242
if
(
m_speciesUnknownType
[i] !=
VCS_SPECIES_TYPE_INTERFACIALVOLTAGE
) {
243
m_molNumSpecies_old
[i] *=
m_totalMoleScale
;
244
}
245
}
246
for
(
size_t
i = 0; i <
m_numElemConstraints
; ++i) {
247
m_elemAbundancesGoal
[i] *=
m_totalMoleScale
;
248
}
249
250
for
(
size_t
iph = 0; iph <
m_numPhases
; iph++) {
251
TPhInertMoles
[iph] *=
m_totalMoleScale
;
252
if
(
TPhInertMoles
[iph] != 0.0) {
253
vcs_VolPhase
* vphase =
m_VolPhaseList
[iph];
254
vphase->
setTotalMolesInert
(
TPhInertMoles
[iph]);
255
}
256
}
257
vcs_tmoles
();
258
}
259
}
260
}
261
262
// Computes the current elemental abundances vector
263
/*
264
* Computes the elemental abundances vector, m_elemAbundances[], and stores it
265
* back into the global structure
266
*/
267
void
VCS_SOLVE::vcs_printChemPotUnits
(
int
unitsFormat)
const
268
{
269
switch
(unitsFormat) {
270
case
VCS_UNITS_KCALMOL:
271
plogf
(
"kcal/gmol"
);
272
break
;
273
case
VCS_UNITS_UNITLESS:
274
plogf
(
"dimensionless"
);
275
break
;
276
case
VCS_UNITS_KJMOL:
277
plogf
(
"kJ/gmol"
);
278
break
;
279
case
VCS_UNITS_KELVIN:
280
plogf
(
"Kelvin"
);
281
break
;
282
case
VCS_UNITS_MKS:
283
plogf
(
"J/kmol"
);
284
break
;
285
default
:
286
plogf
(
"unknown units!"
);
287
exit(EXIT_FAILURE);
288
}
289
}
290
291
}
292
Generated by
1.8.2