20 #define TOL_CONV 1.0E-5
22 static void print_funcEval(FILE* fp,
double xval,
double fval,
int its)
25 fprintf(fp,
"...............................................................\n");
26 fprintf(fp,
".................. vcs_root1d Function Evaluation .............\n");
27 fprintf(fp,
".................. iteration = %5d ........................\n", its);
28 fprintf(fp,
".................. value = %12.5g ......................\n", xval);
29 fprintf(fp,
".................. funct = %12.5g ......................\n", fval);
30 fprintf(fp,
"...............................................................\n");
36 double FuncTargVal,
int varID,
37 double* xbest,
int printLvl)
40 static int callNum = 0;
41 const char* stre =
"vcs_root1d ERROR: ";
42 const char* strw =
"vcs_root1d WARNING: ";
43 bool converged =
false;
53 double x1, x2, xnew, f1, f2, fnew, slope;
57 bool foundPosF =
false;
58 bool foundNegF =
false;
59 bool foundStraddle =
false;
64 double c[9], f[3], xn1, xn2, x0 = 0.0, f0 = 0.0, root, theta, xquad;
67 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
68 sprintf(fileName,
"rootfd_%d.log", callNum);
69 fp = fopen(fileName,
"w");
70 fprintf(fp,
" Iter TP_its xval Func_val | Reasoning\n");
71 fprintf(fp,
"-----------------------------------------------------"
72 "-------------------------------\n");
73 }
else if (printLvl >= 3) {
74 plogf(
"WARNING: vcsUtil_root1d: printlvl >= 3, but debug mode not turned on\n");
77 plogf(
"%sxmin and xmax are bad: %g %g\n", stre, xmin, xmax);
81 if (x1 < xmin || x1 > xmax) {
82 x1 = (xmin + xmax) / 2.0;
84 f1 = func(x1, FuncTargVal, varID, fptrPassthrough, &err);
85 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
86 print_funcEval(fp, x1, f1, static_cast<int>(its));
87 fprintf(fp,
"%-5d %-5d %-15.5E %-15.5E\n", -2, 0, x1, f1);
92 }
else if (f1 > 0.0) {
101 x2 = x1 - (xmax - xmin) / 100.;
103 f2 = func(x2, FuncTargVal, varID, fptrPassthrough, &err);
104 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
105 print_funcEval(fp, x2, f2, static_cast<int>(its));
106 fprintf(fp,
"%-5d %-5d %-15.5E %-15.5E", -1, 0, x2, f2);
109 if (FuncTargVal != 0.0) {
110 fnorm = fabs(FuncTargVal) + 1.0E-13;
112 fnorm = 0.5*(fabs(f1) + fabs(f2)) + fabs(FuncTargVal);
117 }
else if (f2 > 0.0) {
128 foundStraddle = foundPosF && foundNegF;
144 slope = (f2 - f1) / (x2 - x1);
146 plogf(
"%s functions evals produced the same result, %g, at %g and %g\n",
148 xnew = 2*x2 - x1 + 1.0E-3;
150 xnew = x2 - f2 / slope;
152 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
153 fprintf(fp,
" | xlin = %-9.4g", xnew);
175 ct_dgetrf(3, 3, c, 3, ipiv, info);
179 ct_dgetrs(ctlapack::NoTranspose, 3, 1, c, 3, ipiv, f, 3, info);
180 root = f[1]* f[1] - 4.0 * f[0] * f[2];
182 xn1 = (- f[1] + sqrt(root)) / (2.0 * f[2]);
183 xn2 = (- f[1] - sqrt(root)) / (2.0 * f[2]);
184 if (fabs(xn2 - x2) < fabs(xn1 - x2) && xn2 > 0.0) {
189 theta = fabs(xquad - xnew) / fabs(xnew - x2);
190 theta = std::min(1.0, theta);
191 xnew = theta * xnew + (1.0 - theta) * xquad;
192 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
194 fprintf(fp,
" | xquad = %-9.4g", xnew);
202 if ((
sign(xnew - x2) ==
sign(x2 - x1)) &&
205 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
206 fprintf(fp,
" | xquada = %-9.4g", xnew);
219 if ((xnew > x1 && xnew < x2) || (xnew < x1 && xnew > x2)) {
226 slope = fabs(x2 - x1) / 10.;
227 if (fabs(xnew - x1) < slope) {
228 xnew = x1 +
sign(xnew-x1) * slope;
229 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
230 fprintf(fp,
" | x10%% = %-9.4g", xnew);
233 if (fabs(xnew - x2) < slope) {
234 xnew = x2 +
sign(xnew-x2) * slope;
235 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
236 fprintf(fp,
" | x10%% = %-9.4g", xnew);
244 slope = 2.0 * fabs(x2 - x1);
245 if (fabs(slope) < fabs(xnew - x2)) {
246 xnew = x2 +
sign(xnew-x2) * slope;
247 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
248 fprintf(fp,
" | xlimitsize = %-9.4g", xnew);
255 xnew = x2 + (xmax - x2) / 2.0;
256 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
257 fprintf(fp,
" | xlimitmax = %-9.4g", xnew);
261 xnew = x2 + (x2 - xmin) / 2.0;
262 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
263 fprintf(fp,
" | xlimitmin = %-9.4g", xnew);
273 xnew = (xNegF + x2)/2;
276 xnew = (xNegF + x2)/2;
280 xnew = (xPosF + x2)/2;
283 xnew = (xPosF + x2)/2;
289 xnew = (xNegF + x2)/2;
292 xnew = (xNegF + x2)/2;
296 xnew = (xPosF + x2)/2;
299 xnew = (xPosF + x2)/2;
303 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
305 fprintf(fp,
" | xstraddle = %-9.4g", xnew);
310 fnew = func(xnew, FuncTargVal, varID, fptrPassthrough, &err);
311 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
313 print_funcEval(fp, xnew, fnew, static_cast<int>(its));
314 fprintf(fp,
"%-5d %-5d %-15.5E %-15.5E", (
int) its, 0, xnew, fnew);
341 if (! foundStraddle) {
346 foundStraddle =
true;
347 posStraddle = (xPosF > xNegF);
353 foundStraddle =
true;
354 posStraddle = (xPosF > xNegF);
365 if (fabs(fnew / fnorm) < 1.0E-5) {
369 }
while (! converged && its < itmax);
372 plogf(
"vcs_root1d success: convergence achieved\n");
374 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
375 fprintf(fp,
" | vcs_root1d success in %d its, fnorm = %g\n", (
int) its, fnorm);
378 retn = VCS_FAILED_CONVERGENCE;
380 plogf(
"vcs_root1d ERROR: maximum iterations exceeded without convergence\n");
382 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
383 fprintf(fp,
"\nvcs_root1d failure in %lu its\n", its);
387 if (DEBUG_MODE_ENABLED && printLvl >= 3) {
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
int sign(T x)
Sign of a number. Returns -1 if x < 0, 1 if x > 0 and 0 if x == 0.
int vcsUtil_root1d(double xmin, double xmax, size_t itmax, VCS_FUNC_PTR func, void *fptrPassthrough, double FuncTargVal, int varID, double *xbest, int printLvl)
One dimensional root finder.
Defines and definitions within the vcs package.
Internal declarations for the VCSnonideal package.
double(* VCS_FUNC_PTR)(double xval, double Vtarget, int varID, void *fptrPassthrough, int *err)
Definition of the function pointer for the root finder.
#define plogf
define this Cantera function to replace printf