12 double electric_field,
16 double T_center_guess,
double rho_cp,
22 , m_Tcenter(T_center_guess)
24 , m_sigma(std::move(sigma))
25 , m_kappa(std::move(kappa))
26 , m_prad(std::move(p_rad))
27 , m_init(std::move(init_profile))
29 if (R <= 0.0 || npoints < 3) {
30 throw std::invalid_argument(
31 "ThermalPlasmaColumn1D: require R > 0 and at least 3 grid points "
32 "(got R=" + std::to_string(R) +
", n=" + std::to_string(npoints)
51 throw std::invalid_argument(
52 "ThermalPlasmaColumn1D: no component named '" + name +
"'.");
64 if (component !=
"T") {
65 throw std::invalid_argument(
66 "ThermalPlasmaColumn1D: no component named '" + component +
"'.");
69 throw std::runtime_error(
70 "ThermalPlasmaColumn1D::getValues: domain not installed in a container.");
73 for (std::size_t j = 0; j <
m_points; j++) {
81 if (!m_init.empty()) {
83 return m_init.eval(r);
87 return m_Twall + (m_Tcenter - m_Twall) * (1.0 - s * s);
92 auto x = xg.subspan(
loc(),
size());
95 for (std::size_t j = 0; j <
m_points; j++) {
96 double T = x[
index(0, j)];
97 x[
index(0, j)] = std::min(std::max(T, lo), hi);
118 auto x = xg.subspan(
loc(),
size());
120 auto rsd = rg.subspan(
loc(),
size());
122 auto diag = maskg.subspan(
loc(),
size());
126 std::size_t jmin, jmax;
131 std::size_t jpt = (jg == 0) ? 0 : jg -
firstPoint();
132 jmin = std::max<std::size_t>(jpt, 1) - 1;
133 jmax = std::min(jpt + 1,
m_points - 1);
136 const double E2 = m_E * m_E;
138 for (std::size_t j = jmin; j <= jmax; j++) {
139 const double Tj = x[
index(0, j)];
149 rsd[
index(0, j)] = Tj - m_Twall;
150 diag[
index(0, j)] = 0;
170 const double zj =
z(j);
171 const double re = 0.5 * (zj +
z(j + 1));
172 const double dre =
z(j + 1) - zj;
173 const double Tjp1 = x[
index(0, j + 1)];
174 const double kap_e = 0.5 * (m_kappa.eval(Tj) + m_kappa.eval(Tjp1));
190 rw = 0.5 * (
z(j - 1) + zj);
191 const double Tjm1 = x[
index(0, j - 1)];
192 const double drw = zj -
z(j - 1);
193 const double kap_w = 0.5 * (m_kappa.eval(Tjm1) + m_kappa.eval(Tj));
204 const double div_flux = (flux_e - flux_w) / vol;
213 const double source = m_sigma.eval(Tj) * E2 - m_prad.eval(Tj);
219 rsd[
index(0, j)] = (div_flux + source) / m_rho_cp
221 diag[
index(0, j)] = 1;
Pure-arithmetic primitives for a 1D cylindrical (radial) finite-volume discretization of the operator...
void setTransientTolerances(double rtol, double atol, size_t n=npos)
void setComponentName(size_t n, const string &name)
void setupUniformGrid(size_t points, double length, double start=0.)
double lowerBound(size_t n) const
shared_ptr< vector< double > > m_state
vector< double > values(const string &component) const
double z(size_t jlocal) const
double upperBound(size_t n) const
void setSteadyTolerances(double rtol, double atol, size_t n=npos)
void setBounds(size_t n, double lower, double upper)
double prevSoln(size_t n, size_t j) const
size_t firstPoint() const
Domain1D(size_t nv=1, size_t points=1, double time=0.0)
size_t index(size_t n, size_t j) const
virtual size_t loc(size_t j=0) const
std::size_t componentIndex(const std::string &name, bool checkAlias=true) const override
Return the index of the named solution component.
double initialValue(std::size_t n, std::size_t j) override
Initial guess for component n at grid point j.
void getValues(const std::string &component, Cantera::span< double > values) const override
Copy converged temperatures from the shared global solution vector.
bool hasComponent(const std::string &name, bool checkAlias=true) const override
Test whether a component name exists in this domain.
void eval(std::size_t jg, Cantera::span< const double > xg, Cantera::span< double > rg, Cantera::span< int > maskg, double rdt) override
Evaluate the residual function at point jg.
ThermalPlasmaColumn1D(double R, std::size_t npoints, double electric_field, double T_wall, PropertyTable sigma, PropertyTable kappa, PropertyTable p_rad, double T_center_guess, double rho_cp, PropertyTable init_profile=PropertyTable())
Construct a radial LTE arc-column domain with tabulated property closures.
void resetBadValues(Cantera::span< double > xg) override
Clamp any out-of-bound temperatures after a failed Newton step to keep the solve from wandering into ...
double faceFlux(double r_face, double coef_face, double value_inner, double value_outer, double spacing)
Conductive/diffusive flux across one radial cell face: r_face * coef_face * (value_outer - value_inne...
double annularVolume(double r_east, double r_west)
Annular cell volume per unit axial length between two face radii, 0.5 * (r_east^2 - r_west^2) [m^2].