8#include "cantera/oneD/refine.h"
18IonFlow::IonFlow(ThermoPhase* ph,
size_t nsp,
size_t points) :
19 StFlow(ph, nsp, points)
22 for (
size_t k = 0; k < m_nsp; k++) {
23 m_speciesCharge.push_back(m_thermo->charge(k));
27 for (
size_t k = 0; k < m_nsp; k++){
28 if (m_speciesCharge[k] != 0){
29 m_kCharge.push_back(k);
31 m_kNeutral.push_back(k);
36 if (m_thermo->speciesIndex(
"E") != npos ) {
37 m_kElectron = m_thermo->speciesIndex(
"E");
41 setBounds(c_offset_E, -1.0e20, 1.0e20);
46 for (
size_t k : m_kCharge) {
47 setBounds(c_offset_Y + k, -1e-14, 1.0);
49 setBounds(c_offset_Y + m_kElectron, -1e-18, 1.0);
51 m_refiner->setActive(c_offset_E,
false);
52 m_mobility.resize(m_nsp*m_points);
53 m_do_electric_field.resize(m_points,
false);
56IonFlow::IonFlow(shared_ptr<Solution> sol,
const string&
id,
size_t points)
57 :
IonFlow(sol->thermo().get(), sol->thermo()->nSpecies(), points)
66 "An appropriate transport model\nshould be set when instantiating the "
67 "Solution ('gas') object.\nImplicit setting of the transport model "
68 "is deprecated and\nwill be removed after Cantera 3.0.");
71 m_solution->registerChangedCallback(
this, [
this]() {
79 return "free-ion-flow";
82 return "axisymmetric-ion-flow";
84 return "unstrained-ion-flow";
90 m_do_species.resize(
m_nsp,
true);
106 for (
size_t j = j0; j < j1; j++) {
113 m_diff[k+
m_nsp*j] =
poly5(tlog, m_diff_e_fix.data());
130 for (
size_t j = j0; j < j1; j++) {
131 double wtm = m_wtm[j];
132 double rho = density(j);
133 double dz = z(j+1) - z(j);
136 m_flux(k,j) = m_wt[k]*(rho*m_diff[k+
m_nsp*j]/wtm);
137 m_flux(k,j) *= (X(x,k,j) - X(x,k,j+1))/dz;
143 m_flux(k,j) += sum*Y(x,k,j);
157 for (
size_t j = j0; j < j1; j++) {
158 double wtm = m_wtm[j];
159 double rho = density(j);
160 double dz = z(j+1) - z(j);
163 for (
size_t k = 0; k <
m_nsp; k++) {
164 m_flux(k,j) = m_wt[k]*(rho*m_diff[k+
m_nsp*j]/wtm);
165 m_flux(k,j) *= (X(x,k,j) - X(x,k,j+1))/dz;
169 double E_ambi =
E(x,j);
171 double Yav = 0.5 * (Y(x,k,j) + Y(x,k,j+1));
172 double drift = rho * Yav * E_ambi
174 m_flux(k,j) += drift;
178 double sum_flux = 0.0;
179 for (
size_t k = 0; k <
m_nsp; k++) {
180 sum_flux -= m_flux(k,j);
182 double sum_ion = 0.0;
188 m_flux(k,j) += Y(x,k,j) / (1-sum_ion) * sum_flux;
195 if (stage == 1 || stage == 2) {
199 "solution stage must be set to: "
200 "1) frozenIonMethod, "
201 "2) electricFieldEqnMethod");
206 double rdt,
size_t jmin,
size_t jmax)
213 for (
size_t j = jmin; j <= jmax; j++) {
219 rsd[index(
c_offset_Y + k, 0)] = Y(x,k,0) - Y(x,k,1);
242 bool changed =
false;
244 for (
size_t i = 0; i <
m_points; i++) {
267 bool changed =
false;
269 for (
size_t i = 0; i <
m_points; i++) {
291 vector<double>& mobi_e)
295 size_t n = tfix.size();
297 for (
size_t i = 0; i < n; i++) {
298 tlog.push_back(log(tfix[i]));
300 vector<double> w(n, -1.0);
301 m_diff_e_fix.resize(degree + 1);
303 polyfit(n, degree, tlog.data(), diff_e.data(), w.data(), m_diff_e_fix.data());
Headers for the Transport object, which is the virtual base class for all transport property evaluato...
Base class for exceptions thrown by Cantera classes.
shared_ptr< Solution > m_solution
Composite thermo/kinetics/transport handler.
size_t m_points
Number of grid points.
string m_id
Identity tag for the domain.
void needJacUpdate()
Set this if something has changed in the governing equations (for example, the value of a constant ha...
This class models the ion transportation in a flame.
vector< size_t > m_kCharge
index of species with charges
void electricFieldMethod(const double *x, size_t j0, size_t j1)
Solving phase two: the electric field equation is added coupled by the electrical drift.
double E(const double *x, size_t j) const
electric field
void evalResidual(double *x, double *rsd, int *diag, double rdt, size_t jmin, size_t jmax) override
vector< bool > m_do_electric_field
flag for solving electric field or not
size_t m_kElectron
index of electron
void frozenIonMethod(const double *x, size_t j0, size_t j1)
Solving phase one: the fluxes of charged species are turned off.
void resize(size_t components, size_t points) override
Resize the domain to have nv components and np grid points.
void setElectronTransport(vector< double > &tfix, vector< double > &diff_e, vector< double > &mobi_e)
Sometimes it is desired to carry out the simulation using a specified electron transport profile,...
string type() const override
String indicating the domain implemented.
double rho_e(double *x, size_t j) const
total charge density
void updateTransport(double *x, size_t j0, size_t j1) override
Update the transport properties at grid points in the range from j0 to j1, based on solution x.
vector< double > m_mobility
mobility
void updateDiffFluxes(const double *x, size_t j0, size_t j1) override
Update the diffusive mass fluxes.
size_t m_stage
solving stage
void _finalize(const double *x) override
In some cases, a domain may need to set parameters that depend on the initial solution estimate.
void setSolvingStage(const size_t stage) override
Solving stage mode for handling ionized species (used by IonFlow specialization)
bool m_import_electron_transport
flag for importing transport of electron
void solveElectricField(size_t j=npos) override
Set to solve electric field in a point (used by IonFlow specialization)
void fixElectricField(size_t j=npos) override
Set to fix voltage in a point (used by IonFlow specialization)
vector< size_t > m_kNeutral
index of neutral species
vector< double > m_mobi_e_fix
coefficients of polynomial fitting of fixed electron transport profile
bool componentActive(size_t n) const override
Returns true if the specified component is an active part of the solver state.
vector< double > m_speciesCharge
electrical properties
double temperature() const
Temperature (K).
virtual void evalResidual(double *x, double *rsd, int *diag, double rdt, size_t jmin, size_t jmax)
Evaluate the residual function.
void setTransportModel(const string &trans)
Set the transport model.
void setTransport(shared_ptr< Transport > trans) override
Set transport model to existing instance.
void setKinetics(shared_ptr< Kinetics > kin) override
Set the kinetics manager.
void resize(size_t components, size_t points) override
Change the grid size. Called after grid refinement.
virtual bool componentActive(size_t n) const
Returns true if the specified component is an active part of the solver state.
void _finalize(const double *x) override
In some cases, a domain may need to set parameters that depend on the initial solution estimate.
size_t m_nsp
Number of species in the mechanism.
void setGasAtMidpoint(const double *x, size_t j)
Set the gas state to be consistent with the solution at the midpoint between j and j + 1.
virtual void updateTransport(double *x, size_t j0, size_t j1)
Update the transport properties at grid points in the range from j0 to j1, based on solution x.
virtual string transportModel() const
Identifies the model represented by this Transport object.
virtual void getMobilities(double *const mobil_e)
Get the Electrical mobilities (m^2/V/s).
Header for a file containing miscellaneous numerical functions.
This file contains definitions for utility functions and text for modules, inputfiles and logging,...
R poly5(D x, R *c)
Templated evaluation of a polynomial of order 5.
double polyfit(size_t n, size_t deg, const double *xp, const double *yp, const double *wp, double *pp)
Fits a polynomial function to a set of data points.
const double epsilon_0
Permittivity of free space [F/m].
Namespace for the Cantera kernel.
const size_t npos
index returned by functions to indicate "no position"
@ c_offset_U
axial velocity
@ c_offset_E
electric poisson's equation
@ c_offset_Y
mass fractions
void warn_deprecated(const string &source, const AnyBase &node, const string &message)
A deprecation warning for syntax in an input file.
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...