Skip to content

Commit

Permalink
[1D] Update formatting related to two point flame control
Browse files Browse the repository at this point in the history
  • Loading branch information
speth committed Jun 21, 2024
1 parent e4d4e20 commit b4fa531
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 83 deletions.
18 changes: 9 additions & 9 deletions doc/sphinx/reference/onedim/governing-equations.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,17 +263,17 @@ $$
At the left control point the residual for the $\Lambda$ equation is:

$$
T(z=Z_L) - T_{L, \t{control}}
T(z=z_L) - T_{L, \t{control}}
$$

At the left control point the residual for the $U_o$ equation is:

$$
T(z=Z_R) - T_{R, \t{control}}
T(z=z_R) - T_{R, \t{control}}
$$

Where $T(z=Z_L)$ is the temperature of the flowfield at the left control point,
$T(z=Z_R)$ is the temperature of the flowfield at the right control point,
Where $T(z=z_L)$ is the temperature of the flowfield at the left control point,
$T(z=z_R)$ is the temperature of the flowfield at the right control point,
$T_{L, \t{control}}$ is the left control point desired temperature, and
$T_{R, \t{control}}$ is the right control point desired temperature.

Expand All @@ -284,15 +284,15 @@ temperature at that point and the desired control point temperature. In order to
this error to zero, the solver adjusts the flow rates at the boundaries, which changes
the temperature distribution, which in turn affects the values of $\Lambda$ and $U_o$.

At the right boundary, the boundary condition for the continuity equation is imposed
by using the solution from the oxidizer velocity equation. At the left boundary, the
boundary condition for the continuity equation is imposed by using the value of the
axial velocity at the left boundary.
At the left boundary, the boundary condition for the continuity equation is imposed by
using the value of the axial velocity at the left boundary. At the right boundary, the
boundary condition for the continuity equation is imposed by using the solution from the
oxidizer velocity equation.

$$
\dot{m}_\t{in,left} = \rho(z_{\t{in,left}}) U(z_{\t{in,left}})
$$

$$
\dot{m}_\t{in,right} = \rho(z_{\t{in,right}}) U_0(z_{\t{in,right}})
\dot{m}_\t{in,right} = - \rho(z_{\t{in,right}}) U_o(z_{\t{in,right}})
$$
37 changes: 19 additions & 18 deletions include/cantera/oneD/StFlow.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ enum offset
{
c_offset_U //! axial velocity [m/s]
, c_offset_V //! strain rate
, c_offset_T //! temperature [Kelvin]
, c_offset_T //! temperature [kelvin]
, c_offset_L //! (1/r)dP/dr
, c_offset_E //! electric field
, c_offset_Uo //! oxidizer axial velocity [m/s]
Expand Down Expand Up @@ -262,20 +262,22 @@ class StFlow : public Domain1D
/**
* @name Two-Point control method
*
* In this method two control points are designated in the 1D domain, and
* the value of the temperature at these points is fixed. The values of the control
* points are imposed and thus serve as a boundary condition that affects the
* solution of the governing equations in the 1D domain. The imposition of fixed
* points in the domain means that the original set of governing equations' boundary
* conditions would over-determine the problem. Thus, the boundary conditions are changed
* to reflect the fact that the control points are serving as internal boundary conditions.
* In this method two control points are designated in the 1D domain, and the value
* of the temperature at these points is fixed. The values of the control points are
* imposed and thus serve as a boundary condition that affects the solution of the
* governing equations in the 1D domain. The imposition of fixed points in the
* domain means that the original set of governing equations' boundary conditions
* would over-determine the problem. Thus, the boundary conditions are changed to
* reflect the fact that the control points are serving as internal boundary
* conditions.
*
* The imposition of the two internal boundary conditions requires that two other
* boundary conditions be changed. The first is the boundary condition for the continuity equation
* at the left boundary, which is changed to be a value that is derived from the solution at the
* left boundary. The second is the continuity boundary condition at the right boundary, which is
* also determined from the flow solution by using the oxidizer axial velocity equation variable to
* compute the mass flux at the right boundary.
* boundary conditions be changed. The first is the boundary condition for the
* continuity equation at the left boundary, which is changed to be a value that is
* derived from the solution at the left boundary. The second is the continuity
* boundary condition at the right boundary, which is also determined from the flow
* solution by using the oxidizer axial velocity equation variable to compute the
* mass flux at the right boundary.
*
* This method is based on the work of Nishioka et al. @cite nishioka1996 .
*/
Expand Down Expand Up @@ -552,11 +554,10 @@ class StFlow : public Domain1D
* \frac{dU_{o}}{dz} = 0
* @f]
*
* This equation serves as a dummy equation that is used only in the context
* of two-point flame control, and serves as the way for two interior control
* points to be specified while maintaining block tridiagonal structure. The
* default boundary condition is @f$ U_o = 0 @f$
* at the right and zero flux at the left boundary.
* This equation serves as a dummy equation that is used only in the context of
* two-point flame control, and serves as the way for two interior control points to
* be specified while maintaining block tridiagonal structure. The default boundary
* condition is @f$ U_o = 0 @f$ at the right and zero flux at the left boundary.
*
* For argument explanation, see evalContinuity().
*/
Expand Down
10 changes: 6 additions & 4 deletions interfaces/cython/cantera/_onedim.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1341,8 +1341,9 @@ cdef class Sim1D:
Set the left control point using the specified temperature. This user-provided
temperature will be used to locate the closest grid point to that temperature,
which will serve to locate the left control point's coordinate. Starting from
the left boundary, the first grid point that is equal to or exceeds the specified
temperature will be used to locate the left control point's coordinate.
the left boundary, the first grid point that is equal to or exceeds the
specified temperature will be used to locate the left control point's
coordinate.
"""
self.sim.setLeftControlPoint(T)

Expand All @@ -1351,8 +1352,9 @@ cdef class Sim1D:
Set the right control point using a specified temperature. This user-provided
temperature will be used to locate the closest grid point to that temperature,
which will serve to locate the right control point's coordinate.Starting from
the right boundary, the first grid point that is equal to or exceeds the specified
temperature will be used to locate the right control point's coordinate.
the right boundary, the first grid point that is equal to or exceeds the
specified temperature will be used to locate the right control point's
coordinate.
"""
self.sim.setRightControlPoint(T)

Expand Down
2 changes: 1 addition & 1 deletion samples/python/onedim/diffusion_flame_continuation.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
try:
f.solve(loglevel=0)
except ct.CanteraError as e:
print('Error: Did not converge')
print('Solver did not converge. Stopping.')
break

maximum_temperature.append(np.max(f.T))
Expand Down
25 changes: 13 additions & 12 deletions src/oneD/Boundary1D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,13 +207,14 @@ void Inlet1D::eval(size_t jg, double* xg, double* rg,
// if the flow is a freely-propagating flame, mdot is not specified.
// Set mdot equal to rho*u, and also set lambda to zero.
m_mdot = m_flow->density(0) * xb[c_offset_U];
} else if (m_flow->isStrained()) { //axisymmetric flow
} else if (m_flow->isStrained()) { // axisymmetric flow
if (m_flow->twoPointControlEnabled()) {
// When using two-point control, the mass flow rate at the left inlet is not
// specified. Instead, the mass flow rate is dictated by the velocity at the
// left inlet, which comes from the U variable. The default boundary condition specified
// in the StFlow.cpp file already handles this case. We only need to update the stored
// value of m_mdot so that other equations that use the quantity are consistent.
// When using two-point control, the mass flow rate at the left inlet is
// not specified. Instead, the mass flow rate is dictated by the
// velocity at the left inlet, which comes from the U variable. The
// default boundary condition specified in the StFlow.cpp file already
// handles this case. We only need to update the stored value of m_mdot
// so that other equations that use the quantity are consistent.
m_mdot = m_flow->density(0)*xb[c_offset_U];
} else {
// The flow domain sets this to -rho*u. Add mdot to specify the mass
Expand All @@ -224,7 +225,7 @@ void Inlet1D::eval(size_t jg, double* xg, double* rg,
// spreading rate. The flow domain sets this to V(0),
// so for finite spreading rate subtract m_V0.
rb[c_offset_V] -= m_V0;
} else { //unstrained flow
} else { // unstrained flow
rb[c_offset_U] = m_flow->density(0) * xb[c_offset_U] - m_mdot;
}

Expand All @@ -249,11 +250,11 @@ void Inlet1D::eval(size_t jg, double* xg, double* rg,
rb[c_offset_T] -= m_flow->T_fixed(m_flow->nPoints() - 1);
}

if (m_flow->twoPointControlEnabled()) {// For point control adjustments
// At the right boundary, the mdot is dictated by the velocity at the
// right boundary, which comes from the Uo variable. The variable Uo is
// the left-moving velocity and has a negative value, so the mass flow has
// to be negated to give a positive value when using Uo.
if (m_flow->twoPointControlEnabled()) { // For point control adjustments
// At the right boundary, the mdot is dictated by the velocity at the right
// boundary, which comes from the Uo variable. The variable Uo is the
// left-moving velocity and has a negative value, so the mass flow has to be
// negated to give a positive value when using Uo.
m_mdot = -m_flow->density(last_index) * xb[c_offset_Uo];
}
rb[c_offset_U] += m_mdot;
Expand Down
5 changes: 2 additions & 3 deletions src/oneD/Sim1D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,15 +765,14 @@ void Sim1D::setLeftControlPoint(double temperature)
}
}

if (!two_point_domain_found){
if (!two_point_domain_found) {
throw CanteraError("Sim1D::setLeftControlPoint",
"No domain with two-point control enabled was found.");
} else {
throw CanteraError("Sim1D::setLeftControlPoint",
"No control point with temperature {} was able to be found in the"
"flame's temperature range.", temperature);
}

}

void Sim1D::setRightControlPoint(double temperature)
Expand Down Expand Up @@ -817,7 +816,7 @@ void Sim1D::setRightControlPoint(double temperature)
}
}

if (!two_point_domain_found){
if (!two_point_domain_found) {
throw CanteraError("Sim1D::setRightControlPoint",
"No domain with two-point control enabled was found.");
} else {
Expand Down
41 changes: 25 additions & 16 deletions src/oneD/StFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1158,9 +1158,10 @@ void StFlow::grad_hk(const double* x, size_t j)
}

// Two-point control functions
double StFlow::leftControlPointTemperature() const {
double StFlow::leftControlPointTemperature() const
{
if (m_twoPointControl) {
if (m_zLeft != Undef){
if (m_zLeft != Undef) {
return m_tLeft;
} else {
throw CanteraError("StFlow::leftControlPointTemperature",
Expand All @@ -1172,11 +1173,12 @@ double StFlow::leftControlPointTemperature() const {
}
}

double StFlow::leftControlPointCoordinate() const {
double StFlow::leftControlPointCoordinate() const
{
if (m_twoPointControl) {
if (m_zLeft != Undef)
if (m_zLeft != Undef) {
return m_zLeft;
else {
} else {
throw CanteraError("StFlow::leftControlPointCoordinate",
"Invalid operation: left control point location is not set");
}
Expand All @@ -1186,9 +1188,10 @@ double StFlow::leftControlPointCoordinate() const {
}
}

void StFlow::setLeftControlPointTemperature(double temperature) {
void StFlow::setLeftControlPointTemperature(double temperature)
{
if (m_twoPointControl) {
if (m_zLeft != Undef){
if (m_zLeft != Undef) {
m_tLeft = temperature;
} else {
throw CanteraError("StFlow::setLeftControlPointTemperature",
Expand All @@ -1200,7 +1203,8 @@ void StFlow::setLeftControlPointTemperature(double temperature) {
}
}

void StFlow::setLeftControlPointCoordinate(double z_left) {
void StFlow::setLeftControlPointCoordinate(double z_left)
{
if (m_twoPointControl) {
m_zLeft = z_left;
} else {
Expand All @@ -1209,7 +1213,8 @@ void StFlow::setLeftControlPointCoordinate(double z_left) {
}
}

double StFlow::rightControlPointTemperature() const {
double StFlow::rightControlPointTemperature() const
{
if (m_twoPointControl) {
if (m_zRight != Undef) {
return m_tRight;
Expand All @@ -1223,9 +1228,10 @@ double StFlow::rightControlPointTemperature() const {
}
}

double StFlow::rightControlPointCoordinate() const {
double StFlow::rightControlPointCoordinate() const
{
if (m_twoPointControl) {
if (m_zRight != Undef){
if (m_zRight != Undef) {
return m_zRight;
} else {
throw CanteraError("StFlow::rightControlPointCoordinate",
Expand All @@ -1237,9 +1243,10 @@ double StFlow::rightControlPointCoordinate() const {
}
}

void StFlow::setRightControlPointTemperature(double temperature) {
void StFlow::setRightControlPointTemperature(double temperature)
{
if (m_twoPointControl) {
if (m_zRight != Undef){
if (m_zRight != Undef) {
m_tRight = temperature;
} else {
throw CanteraError("StFlow::setRightControlPointTemperature",
Expand All @@ -1251,7 +1258,8 @@ void StFlow::setRightControlPointTemperature(double temperature) {
}
}

void StFlow::setRightControlPointCoordinate(double z_right) {
void StFlow::setRightControlPointCoordinate(double z_right)
{
if (m_twoPointControl) {
m_zRight = z_right;
} else {
Expand All @@ -1260,8 +1268,9 @@ void StFlow::setRightControlPointCoordinate(double z_right) {
}
}

void StFlow::enableTwoPointControl(bool twoPointControl) {
if (isStrained()){
void StFlow::enableTwoPointControl(bool twoPointControl)
{
if (isStrained()) {
m_twoPointControl = twoPointControl;
} else {
throw CanteraError("StFlow::enableTwoPointControl",
Expand Down
4 changes: 3 additions & 1 deletion src/oneD/refine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ int Refiner::analyze(size_t n, const double* z, const double* x)

// Keep the point if it is a control point used for two-point flame control
if (fflame && fflame->twoPointControlEnabled() &&
(z[j] == fflame->leftControlPointCoordinate() || z[j] == fflame->rightControlPointCoordinate())) {
(z[j] == fflame->leftControlPointCoordinate() ||
z[j] == fflame->rightControlPointCoordinate()))
{
m_keep[j] = 1;
}

Expand Down
Loading

0 comments on commit b4fa531

Please sign in to comment.