Added in a more robust treatment of handling limits
This commit is contained in:
parent
a36864543a
commit
f727cd44af
3 changed files with 52 additions and 9 deletions
|
|
@ -1585,6 +1585,7 @@ namespace Cantera {
|
|||
{
|
||||
int i, j;
|
||||
double* col_j;
|
||||
int info;
|
||||
doublereal ysave, ydotsave, dy;
|
||||
int retn = 1;
|
||||
/*
|
||||
|
|
@ -1595,9 +1596,12 @@ namespace Cantera {
|
|||
/********************************************************************
|
||||
* Call the function to get a jacobian.
|
||||
*/
|
||||
m_func->evalJacobian(time_curr, delta_t_n, y, ydot, J, f);
|
||||
info = m_func->evalJacobian(time_curr, delta_t_n, y, ydot, J, f);
|
||||
m_nJacEval++;
|
||||
m_nfe++;
|
||||
if (info != 1) {
|
||||
return info;
|
||||
}
|
||||
} else {
|
||||
/*******************************************************************
|
||||
* Generic algorithm to calculate a numerical Jacobian
|
||||
|
|
@ -1607,8 +1611,11 @@ namespace Cantera {
|
|||
* current conditions.
|
||||
*/
|
||||
|
||||
m_func->evalResidNJ(time_curr, delta_t_n, y, ydot, f, JacBase_ResidEval);
|
||||
info = m_func->evalResidNJ(time_curr, delta_t_n, y, ydot, f, JacBase_ResidEval);
|
||||
m_nfe++;
|
||||
if (info != 1) {
|
||||
return info;
|
||||
}
|
||||
m_nJacEval++;
|
||||
|
||||
/*
|
||||
|
|
@ -1668,9 +1675,14 @@ namespace Cantera {
|
|||
*/
|
||||
|
||||
|
||||
m_func->evalResidNJ(time_curr, delta_t_n, y, ydot, DATA_PTR(m_wksp),
|
||||
JacDelta_ResidEval, j, dy);
|
||||
info = m_func->evalResidNJ(time_curr, delta_t_n, y, ydot, DATA_PTR(m_wksp),
|
||||
JacDelta_ResidEval, j, dy);
|
||||
m_nfe++;
|
||||
if (info != 1) {
|
||||
mdp::mdp_safe_free((void **) &dyVector);
|
||||
return info;
|
||||
}
|
||||
|
||||
doublereal diff;
|
||||
for (i = 0; i < neq_; i++) {
|
||||
diff = subtractRD(m_wksp[i], f[i]);
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ namespace Cantera {
|
|||
* return:
|
||||
* 0 Found function
|
||||
*/
|
||||
int RootFind::solve(doublereal xmin, doublereal xmax, int itmax, doublereal funcTargetValue, doublereal *xbest) {
|
||||
int RootFind::solve(doublereal xmin, doublereal xmax, int itmax, doublereal &funcTargetValue, doublereal *xbest) {
|
||||
|
||||
/*
|
||||
* We store the function target and then actually calculate a modified functional
|
||||
|
|
@ -201,6 +201,8 @@ namespace Cantera {
|
|||
const char *stre = "RootFind ERROR: ";
|
||||
const char *strw = "RootFind WARNING: ";
|
||||
int converged = 0;
|
||||
int bottomBump = 0;
|
||||
int topBump = 0;
|
||||
#ifdef DEBUG_MODE
|
||||
char fileName[80];
|
||||
FILE *fp = 0;
|
||||
|
|
@ -236,6 +238,7 @@ namespace Cantera {
|
|||
#endif
|
||||
if (xmax <= xmin) {
|
||||
writelogf("%sxmin and xmax are bad: %g %g\n", stre, xmin, xmax);
|
||||
funcTargetValue = func(*xbest);
|
||||
return ROOTFIND_BADINPUT;
|
||||
}
|
||||
/*
|
||||
|
|
@ -566,7 +569,18 @@ namespace Cantera {
|
|||
* Guard against going above xmax or below xmin
|
||||
*/
|
||||
if (xnew > xmax) {
|
||||
xnew = x2 + (xmax - x2) / 2.0;
|
||||
topBump++;
|
||||
if (topBump < 5) {
|
||||
xnew = x2 + (xmax - x2) / 2.0;
|
||||
} else {
|
||||
if (x2 == xmax || x1 == xmax) {
|
||||
// we are here when we are bumping against the top limit.
|
||||
// No further action is possible
|
||||
goto done;
|
||||
} else {
|
||||
xnew = xmax;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_MODE
|
||||
if (printLvl >= 3) {
|
||||
fprintf(fp, " | xlimitmax = %-11.5E", xnew);
|
||||
|
|
@ -574,7 +588,18 @@ namespace Cantera {
|
|||
#endif
|
||||
}
|
||||
if (xnew < xmin) {
|
||||
xnew = x2 + (x2 - xmin) / 2.0;
|
||||
bottomBump++;
|
||||
if (bottomBump < 5) {
|
||||
xnew = x2 + (x2 - xmin) / 2.0;
|
||||
} else {
|
||||
if (x2 == xmin || x1 == xmin) {
|
||||
// we are here when we are bumping against the bottom limit.
|
||||
// No further action is possible
|
||||
goto done;
|
||||
} else {
|
||||
xnew = xmin;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_MODE
|
||||
if (printLvl >= 3) {
|
||||
fprintf(fp, " | xlimitmin = %-11.5E", xnew);
|
||||
|
|
@ -658,6 +683,8 @@ namespace Cantera {
|
|||
}
|
||||
its++;
|
||||
} while (! converged && its < itmax);
|
||||
|
||||
done:
|
||||
if (converged) {
|
||||
if (printLvl >= 1) {
|
||||
writelogf("RootFind success: convergence achieved\n");
|
||||
|
|
@ -679,11 +706,13 @@ namespace Cantera {
|
|||
#endif
|
||||
}
|
||||
*xbest = x2;
|
||||
funcTargetValue = f2 + m_funcTargetValue;
|
||||
#ifdef DEBUG_MODE
|
||||
if (printLvl >= 3) {
|
||||
fclose(fp);
|
||||
}
|
||||
#endif
|
||||
|
||||
return retn;
|
||||
}
|
||||
//================================================================================================
|
||||
|
|
|
|||
|
|
@ -76,7 +76,9 @@ namespace Cantera {
|
|||
* @param xmin Minimum value of x to be used.
|
||||
* @param xmax Maximum value of x to be used
|
||||
* @param itmax maximum number of iterations. Usually, it can be less than 50.
|
||||
* @param funcTargetValue Value of \f$ f_o \f$ in the equation.
|
||||
* @param funcTargetValue
|
||||
* Value of \f$ f_o \f$ in the equation.
|
||||
* On return, it contains the value of the function actually obtained.
|
||||
* @param xbest Returns the x that satisfies the function
|
||||
* On input, xbest should contain the best estimate of the solution.
|
||||
* An attempt to find the solution near xbest is made.
|
||||
|
|
@ -86,7 +88,7 @@ namespace Cantera {
|
|||
* -1 = ROOTFIND_FAILEDCONVERGENCE Failed to find the answer
|
||||
* -2 = ROOTFIND_BADINPUT Bad input was detected
|
||||
*/
|
||||
int solve(doublereal xmin, doublereal xmax, int itmax, doublereal funcTargetValue, doublereal *xbest);
|
||||
int solve(doublereal xmin, doublereal xmax, int itmax, doublereal &funcTargetValue, doublereal *xbest);
|
||||
|
||||
|
||||
//! Return the function value
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue