46 #include <Xyce_config.h>
50 #include <N_UTL_Math.h>
54 #include <N_ERH_ErrorMgr.h>
59 #define BP0_BERN -3.742945958815751e+01
60 #define BP1_BERN -1.948848145621305e-02
61 #define BP2_BERN 1.230611609815494e-02
62 #define BP3_BERN 3.742945958815751e+01
63 #define BP4_BERN 7.451332191019408e+02
64 #define BP0_DBERN -4.117119704160766e+01
65 #define BP1_DBERN -3.742945958815751e+01
66 #define BP2_DBERN -1.848271746976161e-02
67 #define BP3_DBERN 8.806697697210611e-03
68 #define BP4_DBERN 3.742945958815751e+01
69 #define BP5_DBERN 7.451332191019408e+02
70 #define BP0_AUX1 -8.301056680276218e-03
71 #define BP1_AUX1 8.301056680276218e-03
72 #define BP0_DAUX1 -4.826242066078996e-03
73 #define BP1_DAUX1 4.826242066078996e-03
74 #define BP0_AUX2 -4.436141955583643e+01
75 #define BP1_AUX2 3.680808162809191e+01
76 #define BP2_AUX2 7.451332191019419e+02
77 #define BP0_DAUX2 -7.451332191019419e+02
78 #define BP1_DAUX2 -4.436141955583643e+01
79 #define BP2_DAUX2 3.680808162809191e+01
80 #define BP3_DAUX2 7.451332191019419e+02
81 #define BP0_MISC 7.097827128183643e+02
84 #define PRECISION 1.0e-15
85 #define MAX_ITERATIONS 100
88 #define MAXDOUBLE 1.797693E+308
105 double Bbp0a(
double x) {
return exp(x) - 1.0; }
106 double Bbp0b(
double x) {
return - 1.0; }
108 double Bbp1a(
double x) {
return x / (exp(x) - 1.0); }
109 double Bbp1b(
double x)
111 return 1.0 - x/2.0 * (1.0 - x/6.0 * (1.0 - x*x/60.0));
114 double Bbp2a(
double x)
116 return 1.0 - x/2.0 * (1.0 - x/6.0 * (1.0 - x*x/60.0));
119 double Bbp2b(
double x)
121 return x * exp(-x) / (1.0 - exp(-x));
124 double Bbp3a(
double x) {
return 1.0 - exp(-x); }
125 double Bbp3b(
double x) {
return 1.0; }
127 double Bbp4a(
double x) {
return x * exp(-x); }
128 double Bbp4b(
double x) {
return 0.0; }
130 double dBbp0a(
double x) {
return (1.0 - x) * exp(x) - 1.0; }
131 double dBbp0b(
double x) {
return -1.0; }
133 double dBbp2a(
double x)
135 return ((1.0 - x) * exp(x) - 1.0) / ((exp(x) - 1.0) * (exp(x) - 1.0));
138 double dBbp2b(
double x) {
return -0.5 + x/6.0 * (1.0 - x*x/30.0); }
140 double dBbp3a(
double x) {
return -0.5 + x/6.0 * (1.0 - x*x/30.0); }
141 double dBbp3b(
double x)
143 return (exp(-x)*(1.0 - x) - exp(-2.0 * x))/((1.0 - exp(-x))*(1.0 - exp(-x)));
146 double dBbp5a(
double x) {
return exp(-x) * (1.0 - x) - exp(-2.0 * x); }
147 double dBbp5b(
double x) {
return 0.0; }
149 double AUX1bp0a(
double x) {
return x / sinh(x); }
150 double AUX1bp0b(
double x) {
return 1.0 - x*x/6.0 * (1.0 - 7.0*x*x/60.0); }
152 double dAUX1bp0a(
double x)
154 return (sinh(x) - x*cosh(x)) / (sinh(x) * sinh(x));
157 double dAUX1bp0b(
double x) {
return -x/3.0 * (1.0 - 7*x*x/30.0); }
159 double AUX2bp0a(
double x) {
return 1.0; }
160 double AUX2bp0b(
double x) {
return 1.0 + exp(x); }
162 double AUX2bp1a(
double x) {
return 1.0 + exp(x); }
163 double AUX2bp1b(
double x) {
return exp(x); }
165 double AUX2bp2a(
double x) {
return exp(-x); }
166 double AUX2bp2b(
double x) {
return 0.0; }
168 double dAUX2bp0a(
double x) {
return exp(x); }
169 double dAUX2bp0b(
double x) {
return 0.0; }
222 #define Xyce_NEW_BERN_CALCULATION 1
223 #ifndef Xyce_NEW_BERN_CALCULATION
273 Xyce::dout() << Xyce::section_divider << std::endl;
274 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
275 Xyce::dout() << std::endl;
276 Xyce::dout() <<
"Bernouli function breakpoints: " <<endl;
277 Xyce::dout() <<
"bp0_AUX1 = " <<
bp0_AUX1 << std::endl;
278 Xyce::dout() <<
"bp1_AUX1 = " <<
bp1_AUX1 << std::endl;
279 Xyce::dout() <<
"bp0_DAUX1 = " <<
bp0_DAUX1 << std::endl;
280 Xyce::dout() <<
"bp1_DAUX1 = " <<
bp1_DAUX1 << std::endl;
282 Xyce::dout() <<
"bp0_AUX2 = " <<
bp0_AUX2 << std::endl;
283 Xyce::dout() <<
"bp1_AUX2 = " <<
bp1_AUX2 << std::endl;
284 Xyce::dout() <<
"bp2_AUX2 = " <<
bp2_AUX2 << std::endl;
285 Xyce::dout() <<
"bp0_DAUX2 = " <<
bp0_DAUX2 << std::endl;
286 Xyce::dout() <<
"bp1_DAUX2 = " <<
bp1_DAUX2 << std::endl;
287 Xyce::dout() <<
"bp2_DAUX2 = " <<
bp2_DAUX2 << std::endl;
288 Xyce::dout() <<
"bp3_DAUX2 = " <<
bp3_DAUX2 << std::endl;
289 Xyce::dout() <<
"bp0_MISC = " <<
bp0_MISC << std::endl;
290 Xyce::dout() << Xyce::section_divider << std::endl;
332 if (x < 0.0)
return(-1);
333 else if (x > 0.0)
return(+1);
348 double Fpos = func1(Xpos) - func2(Xpos);
349 double Fneg = func1(Xneg) - func2(Xneg);
350 double Xmid, Fmid, Xlast;
352 if (Fpos == 0.0)
return(Xpos);
353 else if (Fneg == 0.0)
return(Xneg);
354 else if ((Fpos > 0.0) && (Fneg < 0.0)) ;
355 else if ((Fpos < 0.0) && (Fneg > 0.0))
363 std::string msg =
"BernouliSupport::Bisection ";
364 msg +=
" Initial interval may not contain a root";
365 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
371 Xmid = 0.5 * (Xpos + Xneg);
372 Fmid = func1(Xmid) - func2(Xmid);
373 if (Fmid < 0.0) Xneg = Xmid;
374 else if (Fmid > 0.0) Xpos = Xmid;
375 if (Xlast == Xmid)
return(Xmid);
377 }
while (Xneg != Xpos);
393 double slope, dx, x3, f3;
396 double x2 = 0.9 * x1;
397 double f1 = func1(x1) - func2(x1);
398 double f2 = func1(x2) - func2(x2);
404 slope = (f2 - f1) / (x2 - x1);
407 f3 = func1(x3) - func2(x3);
410 while ((fabs(f3) >= fabs(f2)) || (s3 != s2))
414 f3 = func1(x3) - func2(x3);
418 if (fabs(f2) <= 100.0 *
PRECISION)
return(x2);
419 std::string msg =
"BernouliSupport::Secant ";
420 msg +=
" method not converging.";
421 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
450 if (x==0.0) test = 1.0;
451 else test = fabs(dx/x);
454 while (func1(x) != func2(x))
458 if (x==0.0) test = 1.0;
459 else test = fabs(dx/x);
462 while (func1(x) == func2(x))
double Asymptotic(FUNC func1, FUNC func2, double x, double dx)
Pure virtual class to augment a linear system.
virtual ~BernouliSupport()
double Secant(FUNC func1, FUNC func2, double x1)
double Bisection(FUNC func1, FUNC func2, double Xpos, double Xneg)