46 #include <Xyce_config.h>
48 #include <N_UTL_Misc.h>
57 #include <N_ERH_ErrorMgr.h>
59 #include <N_LAS_Matrix.h>
60 #include <N_LAS_Vector.h>
62 #include <N_UTL_BreakPoint.h>
64 #include <N_UTL_Functors.h>
76 .setDescription(
"Initial voltage at end 1");
81 .setDescription(
"Initial voltage at end 2");
86 .setDescription(
"Initial current at end 1");
91 .setDescription(
"Initial current at end 2");
99 .setDescription(
"Resistance per unit length");
104 .setDescription(
"Inductance per unit length");
109 .setDescription(
"Conductance per unit length");
114 .setDescription(
"Capacitance per unit length");
119 .setDescription(
"length of line");
123 .setDescription(
"Rel. rate of change of deriv. for bkpt");
127 .setDescription(
"Abs. rate of change of deriv. for bkpt");
132 .setDescription(
"limit timestep size based on the time constant of the line");
137 .setDescription(
"don't limit timestep size based on the time constant of the line");
142 .setDescription(
"do complex time step control using local truncation error estimation");
147 .setDescription(
"use linear interpolation");
152 .setDescription(
"use quadratic interpolation");
157 .setDescription(
"use linear interpolation if quadratic results look unacceptable");
161 .setDescription(
"special reltol for straight line checking");
165 .setDescription(
"special abstol for straight line checking");
170 .setDescription(
"use N-R iterations for step calculation in LTRAtrunc");
175 .setDescription(
"don't limit timestep to keep impulse response calculation errors low");
198 :
DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block),
208 initVolt1Given(false),
209 initVolt2Given(false),
210 initCur1Given(false),
211 initCur2Given(false),
222 APos1EquPos1NodeOffset(-1),
223 APos1EquIbr1NodeOffset(-1),
225 ANeg1EquNeg1NodeOffset(-1),
226 ANeg1EquIbr1NodeOffset(-1),
228 APos2EquPos2NodeOffset(-1),
229 APos2EquIbr2NodeOffset(-1),
231 ANeg2EquNeg2NodeOffset(-1),
232 ANeg2EquIbr2NodeOffset(-1),
234 AIbr1EquPos1NodeOffset(-1),
235 AIbr1EquNeg1NodeOffset(-1),
236 AIbr1EquPos2NodeOffset(-1),
237 AIbr1EquNeg2NodeOffset(-1),
238 AIbr1EquIbr1NodeOffset(-1),
239 AIbr1EquIbr2NodeOffset(-1),
241 AIbr2EquPos1NodeOffset(-1),
242 AIbr2EquNeg1NodeOffset(-1),
243 AIbr2EquPos2NodeOffset(-1),
244 AIbr2EquNeg2NodeOffset(-1),
245 AIbr2EquIbr1NodeOffset(-1),
246 AIbr2EquIbr2NodeOffset(-1),
274 first_BP_call_done(false),
275 newBreakPoint(false),
276 newBreakPointTime(0.0)
352 bool bsuccess =
true;
380 const std::vector<int>& extLIDVecRef )
385 #if defined(Xyce_DEBUG_DEVICE)
388 Xyce::dout() << std::endl << section_divider << std::endl;
389 Xyce::dout() <<
"[LTRA-DBG-DEV] In Instance::registerLIDs\n\n";
390 Xyce::dout() <<
"name = " <<
getName() << std::endl;
391 Xyce::dout() <<
"[LTRA-DBG-DEV] number of internal variables: " <<
numIntVars << std::endl;
392 Xyce::dout() <<
"[LTRA-DBG-DEV] number of external variables: " <<
numExtVars << std::endl;
413 #if defined(Xyce_DEBUG_DEVICE)
416 Xyce::dout() <<
"[LTRA-DBG-DEV] VARIABLE Indicies " << std::endl;
417 Xyce::dout() <<
"li_Pos1 = " <<
li_Pos1 << std::endl;
418 Xyce::dout() <<
"li_Neg1 = " <<
li_Neg1 << std::endl;
419 Xyce::dout() <<
"li_Pos2 = " <<
li_Pos2 << std::endl;
420 Xyce::dout() <<
"li_Neg2 = " <<
li_Neg2 << std::endl;
421 Xyce::dout() <<
"li_Ibr1 = " <<
li_Ibr1 << std::endl;
422 Xyce::dout() <<
"li_Ibr1 = " <<
li_Ibr1 << std::endl;
423 Xyce::dout() <<
"li_Ibr2 = " <<
li_Ibr2 << std::endl;
424 Xyce::dout() <<
"li_Ibr2 = " <<
li_Ibr2 << std::endl;
426 Xyce::dout() <<
"\nEnd of Instance::register LIDs\n";
427 Xyce::dout() << section_divider << std::endl;
538 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
660 bool bsuccess =
true;
678 #if defined(Xyce_DEBUG_DEVICE)
681 Xyce::dout() <<
"[LTRA-DBG-DEV] In Instance::getBreakPoints "<<std::endl;
682 Xyce::dout() <<
" First time step, I don't get to set breakpoints. Time is ";
683 Xyce::dout() << currentTime << std::endl;
754 bool compact =
false;
829 #define CHECK(a,b,c) (Xycemax(Xycemax(a,b),c)-Xycemin(Xycemin(a,b),c) >= \
830 fabs(50.0*(getDeviceOptions().reltol/3.0*(a+b+c) + \
831 getDeviceOptions().abstol)))
833 bool tmp_test = (fabs(d1_ - d2_) >
model_.
reltol * Xycemax(fabs(d1_), fabs(d2_)) +
836 if (tmp_test || ((fabs(d3_ - d4_)
844 #ifdef Xyce_DEBUG_DEVICE
865 #ifdef Xyce_DEBUG_DEVICE
918 double d1_ = (i1_ - i2_) /
921 double d2_ = (i2_ - i3_) /
924 double d3_ = (i4_ - i5_) /
927 double d4_ = (i5_ - i6_) /
930 if ((fabs(d1_-d2_) >= model.
reltol * Xycemax(fabs(d1_), fabs(d2_)) + model.
abstol) ||
931 (fabs(d3_-d4_) >= model.
reltol * Xycemax(fabs(d3_), fabs(d4_)) + model.
abstol))
944 std::ostringstream msg;
945 msg <<
"**********" << std::endl;
946 msg <<
": Error. Case not handled in calculateMaxTimeStep_()";
947 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
990 if (current_lte >= tolerance) {
995 double y = current_lte;
1000 #ifdef Xyce_DEBUG_DEVICE
1001 if (deriv_delta <= 0.0)
1002 Xyce::dout() <<
"LTRAtrunc: error: timestep is now less than zero" << std::endl;
1004 double deriv = model.
lteCalculate_(*
this, x + deriv_delta) - y;
1006 deriv /= deriv_delta;
1007 double change = (tolerance - y) / deriv;
1013 if (fabs(change) <= fabs(deriv_delta))
1017 if (iterations >= maxiter)
1036 std::ostringstream msg;
1037 msg <<
"**********" << std::endl;
1038 msg <<
": Error. Case not handled in calculateMaxTimeStep_() [2]";
1039 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
1069 int origSize = myState->
data.size();
1079 #ifdef Xyce_DEBUG_RESTART
1080 Xyce::dout().width(18); Xyce::dout().precision(10); Xyce::dout().setf(std::ios::scientific);
1081 Xyce::dout() <<
"LTRA::getInternalState: input1="<<
input1<<
" input2="<<
input2<<std::endl;
1082 Xyce::dout() <<
"LTRA::getInternalState: initVolt11="<<
initVolt1<<
" initVolt2="<<
initVolt2<<std::endl;
1083 Xyce::dout() <<
"LTRA::getInternalState: initCur11="<<
initCur1<<
" initCur2="<<
initCur2<<std::endl;
1090 myState->
data[j+1]=
v2[i];
1091 myState->
data[j+2]=
i1[i];
1092 myState->
data[j+3]=
i2[i];
1093 #ifdef Xyce_DEBUG_RESTART
1094 Xyce::dout().width(18); Xyce::dout().precision(10); Xyce::dout().setf(std::ios::scientific);
1096 "LTRA::getInternalState: v1["<<i<<
"]="<<
v1[i]
1097 <<
" v2["<<i<<
"]="<<
v2[i]
1098 <<
" i1["<<i<<
"]="<<
i1[i]
1099 <<
" i2["<<i<<
"]="<<
i2[i]
1109 origSize = myState->
data.size();
1117 #ifdef Xyce_DEBUG_RESTART
1118 Xyce::dout().width(18); Xyce::dout().precision(10); Xyce::dout().setf(std::ios::scientific);
1148 msg =
"Instance::setInternalState: ID ("+state.
ID+
")";
1149 msg +=
"from restart does not match my name ("+
getName()+
")!\n";
1150 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL, msg);
1155 v1.clear();
v2.clear();
i1.clear();
i2.clear();
1165 #ifdef Xyce_DEBUG_RESTART
1166 Xyce::dout().width(18); Xyce::dout().precision(10); Xyce::dout().setf(std::ios::scientific);
1167 Xyce::dout() <<
"LTRA::setInternalState: input1="<<
input1<<
" input2="<<
input2<<std::endl;
1168 Xyce::dout() <<
"LTRA::setInternalState: initVolt11="<<
initVolt1<<
" initVolt2="<<
initVolt2<<std::endl;
1169 Xyce::dout() <<
"LTRA::setInternalState: initCur11="<<
initCur1<<
" initCur2="<<
initCur2<<std::endl;
1179 #ifdef Xyce_DEBUG_RESTART
1180 Xyce::dout().width(18); Xyce::dout().precision(10); Xyce::dout().setf(std::ios::scientific);
1182 "LTRA::setInternalState: v1["<<i<<
"]="<<
v1[i]
1183 <<
" v2["<<i<<
"]="<<
v2[i]
1184 <<
" i1["<<i<<
"]="<<
i1[i]
1185 <<
" i2["<<i<<
"]="<<
i2[i]
1203 j=(listSize*4+6)+i*3;
1207 #ifdef Xyce_DEBUG_RESTART
1208 Xyce::dout().width(18); Xyce::dout().precision(10); Xyce::dout().setf(std::ios::scientific);
1246 std::vector<Instance*>::iterator iter;
1250 for (iter=first; iter!=last; ++iter)
1252 (*iter)->processParams();
1270 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
1272 h1dashFirstVal(0.0),
1274 h3dashFirstVal(0.0),
1275 h1dashFirstCoeff(0.0),
1277 h3dashFirstCoeff(0.0),
1299 truncDontCut(false),
1303 conductGiven(false),
1308 noStepLimitGiven(false),
1309 stepLimitGiven(false),
1310 linInterpGiven(false),
1311 quadInterpGiven(false),
1312 mixedInterpGiven(false),
1313 stLineReltolGiven(false),
1314 stLineAbstolGiven(false),
1315 truncNRGiven(false),
1316 truncDontCutGiven(false),
1337 maxSafeStep(1.0e99),
1338 maxTimeStep(1.0e99),
1339 lteTimeStepControl(false),
1344 restartStoredFlag(false)
1378 std::vector<Instance*>::iterator iter;
1382 for (iter=first; iter!=last; ++iter)
1398 std::vector<Instance*>::const_iterator iter;
1404 os <<
" name model name Parameters" << std::endl;
1405 for (i=0, iter=first; iter!=last; ++iter, ++i)
1407 os <<
" " << i <<
": " << (*iter)->getName() <<
" ";
1435 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1449 double& qf1,
double& qf2,
double& qf3,
1450 double& lf2,
double& lf3)
1452 double t1(0.0),t2(0.0),t3(0.0);
1453 double v1d(0.0), v2d(0.0), i1d(0.0), i2d(0.0);
1454 double dummy1(0.0), dummy2(0.0);
1465 dummy2 = exp(-dummy1);
1466 dummy1 = exp(dummy1);
1469 if (conduct <= 1.0e-10)
1495 std::ostringstream msg;
1496 msg <<
"**********" << std::endl;
1497 msg <<
": Error. Case not handled in modelCalculations_()";
1498 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
1556 #ifdef Xyce_DEBUG_DEVICE
1559 Xyce::dout() <<
"[LTRA-DBG-DEV] LTRAload: Warning: timestep larger than delay of line" << std::endl;
1569 #ifdef Xyce_DEBUG_DEVICE
1570 Xyce::dout() <<
"[LTRA-DBG-DEV] LTRAload: mistake: cannot find delayed timepoint" << std::endl;
1572 std::ostringstream msg;
1573 msg <<
"************" << std::endl;
1574 msg <<
": Error. Delayed time point not found.";
1575 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
1681 if( (t2-t1)==0 || (t3-t2) == 0 || (t1 - t3) ==0)
return(1);
1683 f1 = (t - t2) * (t - t3) ;
1684 f2 = (t - t1) * (t - t3) ;
1685 f3 = (t - t1) * (t - t2) ;
1737 if (t1 == t2)
return(1);
1753 temp = (t-t1)/(t2-t1);
1775 double lovalue,
double hivalue,
1776 double t1,
double t2)
1781 if (width == 0.0)
return(0.0);
1782 m = (hivalue - lovalue)/width;
1784 return( (hilimit-lolimit)*lovalue + 0.5*m*((hilimit-t1)*(hilimit-t1)
1785 - (lolimit - t1)*(lolimit - t1)));
1804 double otherlolimit,
double lovalue,
1805 double hivalue,
double t1,
double t2)
1807 double width, m, dummy;
1808 double temp1, temp2, temp3;
1811 if (width == 0.0)
return(0.0);
1812 m = (hivalue - lovalue)/width;
1814 temp1 = hilimit - t1;
1815 temp2 = lolimit - t1;
1816 temp3 = otherlolimit - t1;
1817 dummy = lovalue*((hilimit - otherlolimit)*(hilimit - otherlolimit) -
1818 (lolimit - otherlolimit)*(lolimit - otherlolimit));
1819 dummy += m*((temp1*temp1*temp1 - temp2*temp2*temp2)/3.0 -
1820 temp3*temp3*(hilimit - lolimit));
1841 double secondlolimit,
double thirdlolimit,
1842 double lovalue,
double hivalue,
double t1,
double t2)
1844 double width, m, dummy;
1845 double temp1, temp2, temp3, temp4;
1846 double temp5, temp6, temp7, temp8, temp9, temp10;
1850 if (width == 0.0)
return(0.0);
1851 m = (hivalue - lovalue)/width;
1853 temp1 = hilimit - t1;
1854 temp2 = lolimit - t1;
1855 temp3 = secondlolimit - t1;
1856 temp4 = thirdlolimit - t1;
1857 temp5 = hilimit - thirdlolimit;
1858 temp6 = lolimit - thirdlolimit;
1859 temp7 = secondlolimit - thirdlolimit;
1860 temp8 = hilimit - lolimit;
1861 temp9 = hilimit - secondlolimit;
1862 temp10 = lolimit - secondlolimit;
1863 dummy = lovalue*((temp5*temp5*temp5 - temp6*temp6*temp6)/3 -
1865 dummy += m*(((temp1*temp1*temp1*temp1 - temp2*temp2*temp2*temp2)*0.25 -
1866 temp3*temp3*temp3*temp8)/3 - temp4*temp4*0.5*(temp9*temp9 -
1885 if ((ax=fabs(x)) < 3.75)
1889 ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492
1890 +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2)))));
1895 ans=(exp(ax)/sqrt(ax))*
1896 (0.39894228+y*(0.1328592e-1+y*(0.225319e-2+
1897 y*(-0.157565e-2+y*(0.916281e-2+
1898 y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1
1899 +y*0.392377e-2))))))));
1917 if ((ax=fabs(x)) < 3.75)
1921 ans=ax*(0.5+y*(0.87890594+y*(0.51498869+y*(0.15084934
1922 +y*(0.2658733e-1+y*(0.301532e-2+y*0.32411e-3))))));
1927 ans=0.2282967e-1+y*(-0.2895312e-1+y*(0.1787654e-1
1929 ans=0.39894228+y*(-0.3988024e-1+y*(-0.362018e-2
1930 +y*(0.163801e-2+y*(-0.1031555e-1+y*ans))));
1931 ans *= (exp(ax)/sqrt(ax));
1933 return(x < 0.0 ? -ans : ans);
1949 if ((ax=fabs(x)) < 3.75) {
1952 ans=0.5+y*(0.87890594+y*(0.51498869+y*(0.15084934
1953 +y*(0.2658733e-1+y*(0.301532e-2+y*0.32411e-3)))));
1958 ans=0.2282967e-1+y*(-0.2895312e-1+y*(0.1787654e-1
1960 ans=0.39894228+y*(-0.3988024e-1+y*(-0.362018e-2
1961 +y*(0.163801e-2+y*(-0.1031555e-1+y*ans))));
1962 ans *= (exp(ax)/(ax*sqrt(ax)));
1977 double besselarg, exparg, returnval;
1984 if (alpha == 0.0)
return(0.0);
1986 exparg = - beta * time;
1987 besselarg = alpha*time;
1989 returnval = (
bessI1_(besselarg)-
bessI0_(besselarg))* alpha * exp(exparg);
2003 double besselarg, exparg, returnval;
2011 if (alpha == 0.0)
return(0.0);
2012 if (time < T)
return(0.0);
2015 besselarg = alpha*sqrt(time*time - T*T);
2019 exparg = -beta*time;
2021 returnval = alpha*alpha*T*exp(exparg)*
bessI1xOverX_(besselarg);
2035 double exparg,besselarg,returnval;
2043 if (alpha == 0.0)
return(0.0);
2044 if (time < T)
return(0.0);
2046 exparg = - beta*time;
2048 besselarg = alpha*sqrt(time*time - T*T);
2054 returnval *= alpha*exp(exparg);
2071 double arg, returnval;
2077 if (beta == 0.0)
return(time);
2079 if (arg == 0.0)
return(0.0);
2081 returnval = (
bessI1_(arg)+
bessI0_(arg))* time * exp(-arg) - time;
2098 double exparg, besselarg;
2101 if (time <= T)
return(0.0);
2102 if (beta == 0.0)
return(0.0);
2103 exparg = -beta*time;
2104 besselarg = beta*sqrt(time*time-T*T);
2105 returnval = exp(exparg)*
bessI0_(besselarg) - exp(-beta*T);
2119 return(sqrt(4*cbyr*time/
M_PI));
2135 temp = rclsqr/(4*time);
2147 return((time + rclsqr*0.5)*erfc_res - sqrt(time*rclsqr/
M_PI)*exp(- temp));
2168 temp = rclsqr/(4*time);
2173 temp = 2*sqrt(time/
M_PI)*exp(-temp) - sqrt(rclsqr)*erfc_res;
2174 return(sqrt(cbyr)*temp);
2195 double& h1dashfirstcoeff,
2196 double& h2firstcoeff,
2197 double& h3dashfirstcoeff,
2198 std::vector<double>& h1dashcoeffs,
2199 std::vector<double>& h2coeffs,
2200 std::vector<double>& h3dashcoeffs,
2201 size_t listsize,
double cbyr,
double rclsqr,
double curtime,
2202 const std::vector<double>& timelist,
int timeindex,
double reltol)
2204 double delta1, delta2;
2205 double h1dummy1, h1dummy2;
2206 double h2dummy1, h2dummy2;
2207 double h3dummy1, h3dummy2;
2208 double lolimit1,lolimit2, hilimit1, hilimit2;
2209 double h1lovalue1,h1lovalue2,h1hivalue1,h1hivalue2;
2210 double h2lovalue1,h2lovalue2,h2hivalue1,h2hivalue2;
2211 double h3lovalue1,h3lovalue2,h3hivalue1,h3hivalue2;
2212 double temp, temp2, temp3, temp4, temp5;
2213 double h1relval, h2relval, h3relval;
2214 int doh1=1, doh2=1, doh3=1;
2219 #ifdef Xyce_DEBUG_DEVICE
2220 if (listsize < timeindex) {
2221 Xyce::dout() <<
"[LTRA-DBG-DEV]: LTRAcoeffSetup: not enough space in coefflist" << std::endl;
2225 auxindex = timeindex;
2229 delta1 = curtime - timelist[auxindex];
2235 sqrt(4*cbyr*hilimit1/
M_PI);
2236 h1dummy1 = h1hivalue1/delta1;
2237 h1dashfirstcoeff = h1dummy1;
2238 h1relval = fabs(h1dummy1*reltol);
2240 temp = rclsqr/(4*hilimit1);
2245 temp4 = sqrt(rclsqr);
2250 (hilimit1 != 0.0? (hilimit1 + rclsqr*0.5)*temp2 - sqrt(hilimit1*rclsqr/
M_PI)*temp3 : 0.0);
2253 h2dummy1 = h2hivalue1/delta1;
2254 h2firstcoeff = h2dummy1;
2255 h2relval = fabs(h2dummy1*reltol);
2259 (hilimit1 != 0.0? temp = 2*sqrt(hilimit1/
M_PI)*temp3 - temp4*temp2, (temp5*temp): 0.0);
2262 h3dummy1 = h3hivalue1/delta1;
2263 h3dashfirstcoeff = h3dummy1;
2264 h3relval = fabs(h3dummy1*reltol);
2268 for (i=auxindex; i>0; i--)
2271 lolimit2 = lolimit1;
2272 hilimit2 = hilimit1;
2274 delta1 = timelist[i] - timelist[i - 1];
2275 lolimit1 = hilimit2;
2276 hilimit1 = curtime - timelist[i - 1];
2280 h1lovalue2 = h1lovalue1;
2281 h1hivalue2 = h1hivalue1;
2282 h1dummy2 = h1dummy1;
2284 h1lovalue1 = h1hivalue2;
2286 sqrt(4*cbyr*hilimit1/
M_PI);
2287 h1dummy1 = (h1hivalue1 - h1lovalue1)/delta1;
2288 h1dashcoeffs[i] = h1dummy1 - h1dummy2;
2289 if (fabs(h1dashcoeffs[i]) < h1relval) doh1=0;
2293 h1dashcoeffs[i] = 0.0;
2297 temp = rclsqr/(4*hilimit1);
2305 h2lovalue2 = h2lovalue1;
2306 h2hivalue2 = h2hivalue1;
2307 h2dummy2 = h2dummy1;
2309 h2lovalue1 = h2hivalue2;
2311 (hilimit1 != 0.0? (hilimit1 + rclsqr*0.5)*temp2 - sqrt(hilimit1*rclsqr/
M_PI)*temp3 : 0.0);
2312 h2dummy1 = (h2hivalue1 - h2lovalue1)/delta1;
2313 h2coeffs[i] = h2dummy1 - h2dummy2;
2314 if (fabs(h2coeffs[i]) < h2relval) doh2=0;
2323 h3lovalue2 = h3lovalue1;
2324 h3hivalue2 = h3hivalue1;
2325 h3dummy2 = h3dummy1;
2327 h3lovalue1 = h3hivalue2;
2329 (hilimit1 != 0.0? temp = 2*sqrt(hilimit1/
M_PI)*temp3 - temp4*temp2, (temp5*temp): 0.0);
2330 h3dummy1 = (h3hivalue1 - h3lovalue1)/delta1;
2331 h3dashcoeffs[i] = h3dummy1 - h3dummy2;
2332 if (fabs(h3dashcoeffs[i]) < h3relval) doh3=0;
2336 h3dashcoeffs[i] = 0.0;
2350 double& h1dashfirstcoeff,
2351 double& h2firstcoeff,
2352 double& h3dashfirstcoeff,
2353 std::vector<double>& h1dashcoeffs,
2354 std::vector<double>& h2coeffs,
2355 std::vector<double>& h3dashcoeffs,
2357 double T,
double alpha,
double beta,
double curtime,
2358 const std::vector<double>& timelist,
int timeindex,
double reltol,
int* auxindexptr)
2361 double lolimit1,lolimit2,hilimit1,hilimit2;
2362 double delta1, delta2;
2364 double h1dummy1, h1dummy2;
2365 double h1lovalue1,h1lovalue2,h1hivalue1,h1hivalue2;
2367 double h2dummy1, h2dummy2;
2368 double h2lovalue1,h2lovalue2,h2hivalue1,h2hivalue2;
2370 double h3dummy1, h3dummy2;
2371 double h3lovalue1,h3lovalue2,h3hivalue1,h3hivalue2;
2373 double exparg, besselarg, expterm, bessi1overxterm, bessi0term;
2374 double expbetaTterm, alphasqTterm;
2375 double h1relval, h2relval, h3relval;
2376 int doh1=1, doh2=1, doh3=1;
2382 #ifdef Xyce_DEBUG_DEVICE
2383 if (listsize < timeindex) {
2384 Xyce::dout() <<
"[LTRA-DBG-DEV]: LTRArlcCoeffsSetup_: not enough space in coefflist" << std::endl;
2396 auxindex = timeindex;
2399 if (curtime - T <= 0.0) {
2403 for (i = timeindex; i>= 0; i--) {
2404 if (curtime - timelist[i] == T) {
2408 if (curtime - timelist[i] > T)
break;
2411 #ifdef Xyce_DEBUG_DEVICE
2412 if ((i < 0) || ((i==0) && (exact==1)))
2413 Xyce::dout() <<
"[LTRA-DBG-DEV]: LTRAcoeffSetup: i <= 0: some mistake!" << std::endl;
2428 hilimit1 = curtime - timelist[auxindex];
2429 delta1 = hilimit1 - lolimit1;
2432 besselarg = (hilimit1 > T) ? alpha*sqrt(hilimit1*hilimit1-T*T):0.0;
2433 exparg = -beta*hilimit1;
2434 expterm = exp(exparg);
2436 alphasqTterm = alpha*alpha*T;
2438 ((alpha == 0.0) || (hilimit1 < T)) ? 0.0: alphasqTterm*expterm*bessi1overxterm;
2441 h2hivalue1,lolimit1,hilimit1)/delta1;
2442 h2firstcoeff = h2dummy1;
2443 h2relval = fabs(reltol*h2dummy1);
2446 bessi0term =
bessI0_(besselarg);
2447 expbetaTterm = exp(-beta*T);
2449 ((hilimit1 <= T) || (beta == 0.0)) ? 0.0: expterm* bessi0term-expbetaTterm;
2450 h3dummy1 =
intlinfunc_(lolimit1,hilimit1,h3lovalue1,
2451 h3hivalue1,lolimit1,hilimit1)/delta1;
2452 h3dashfirstcoeff = h3dummy1;
2453 h3relval = fabs(h3dummy1*reltol);
2457 h2firstcoeff = h3dashfirstcoeff = 0.0;
2461 hilimit1 = curtime - timelist[timeindex];
2462 delta1 = hilimit1 - lolimit1;
2463 exparg = -beta*hilimit1;
2464 expterm = exp(exparg);
2468 (beta == 0.0) ? hilimit1 : ((hilimit1 == 0.0) ? 0.0 :
2469 (
bessI1_(-exparg)+
bessI0_(-exparg))* hilimit1 * expterm - hilimit1);
2470 h1dummy1 = h1hivalue1/delta1;
2471 h1dashfirstcoeff = h1dummy1;
2472 h1relval = fabs(h1dummy1*reltol);
2477 for (i=timeindex; i>0; i--)
2479 if (doh1 || doh2 || doh3)
2481 lolimit2 = lolimit1;
2482 hilimit2 = hilimit1;
2485 lolimit1 = hilimit2;
2486 hilimit1 = curtime - timelist[i - 1];
2487 delta1 = timelist[i] - timelist[i - 1];
2489 exparg = -beta*hilimit1;
2490 expterm = exp(exparg);
2495 h1lovalue2 = h1lovalue1;
2496 h1hivalue2 = h1hivalue1;
2497 h1dummy2 = h1dummy1;
2499 h1lovalue1 = h1hivalue2;
2501 (beta == 0.0) ? hilimit1 : ((hilimit1 == 0.0) ? 0.0 :
2502 (
bessI1_(-exparg)+
bessI0_(-exparg))* hilimit1 * expterm - hilimit1);
2503 h1dummy1 = (h1hivalue1 - h1lovalue1)/delta1;
2505 h1dashcoeffs[i] = h1dummy1 - h1dummy2;
2506 if (fabs(h1dashcoeffs[i]) <= h1relval) doh1 = 0;
2510 h1dashcoeffs[i] = 0.0;
2522 besselarg = (hilimit1 > T) ? alpha*sqrt(hilimit1*hilimit1-T*T):0.0;
2527 h2lovalue2 = h2lovalue1;
2528 h2hivalue2 = h2hivalue1;
2529 h2dummy2 = h2dummy1;
2531 h2lovalue1 = h2hivalue2;
2534 ((alpha == 0.0) || (hilimit1 < T)) ? 0.0: alphasqTterm*expterm*bessi1overxterm;
2536 h2lovalue1,h2hivalue1,lolimit1,hilimit1)/delta1;
2538 h2coeffs[i] = h2dummy1 - h2dummy2 +
intlinfunc_(lolimit2,hilimit2,
2539 h2lovalue2,h2hivalue2,lolimit2,hilimit2);
2540 if (fabs(h2coeffs[i]) <= h2relval) doh2 = 0;
2549 h3lovalue2 = h3lovalue1;
2550 h3hivalue2 = h3hivalue1;
2551 h3dummy2 = h3dummy1;
2553 h3lovalue1 = h3hivalue2;
2554 bessi0term =
bessI0_(besselarg);
2556 ((hilimit1 <= T) || (beta == 0.0)) ? 0.0: expterm* bessi0term-expbetaTterm;
2557 h3dummy1 =
intlinfunc_(lolimit1,hilimit1,h3lovalue1,h3hivalue1,lolimit1,hilimit1)/delta1;
2559 h3dashcoeffs[i] = h3dummy1 - h3dummy2;
2560 if (fabs(h3dashcoeffs[i]) <= h3relval) doh3 = 0;
2564 h3dashcoeffs[i] = 0.0;
2568 *auxindexptr = auxindex;
2591 double x2,
double y2,
2592 double x3,
double y3,
2593 double reltol,
double abstol)
2597 double TRarea, QUADarea1,QUADarea2,QUADarea3, area;
2611 QUADarea1 = (fabs(y2)+fabs(y1))*0.5*fabs(x2-x1);
2612 QUADarea2 = (fabs(y3)+fabs(y2))*0.5*fabs(x3-x2);
2613 QUADarea3 = (fabs(y3)+fabs(y1))*0.5*fabs(x3-x1);
2614 TRarea = fabs( QUADarea3 - QUADarea1 - QUADarea2);
2615 area = QUADarea1 + QUADarea2;
2616 if (area*reltol + abstol > TRarea)
2626 #define SECONDDERIV(i,a,b,c) \
2627 (oof = (i==getSolverState().ltraTimeIndex?getSolverState().currTime: \
2628 (getSolverState().ltraTimePoints[i])), \
2629 (( c - b )/(oof-(getSolverState().ltraTimePoints[i-1])) - \
2630 ( b - a )/((getSolverState().ltraTimePoints[i-1])- \
2631 (getSolverState().ltraTimePoints[i-2])))/(oof - \
2632 (getSolverState().ltraTimePoints[i-2])))
2666 double h1dashTfirstCoeff;
2667 double h2TfirstCoeff;
2668 double h3dashTfirstCoeff;
2670 double hilimit1, lolimit1, hivalue1, lovalue1, f1i, g1i;
2671 double eq1LTE=0.0, eq2LTE=0.0;
2672 int auxindex,
tdover, i, exact;
2702 #ifdef Xyce_DEBUG_DEVICE
2703 if ((i < 0) || ((i==0) && (exact==1)))
2704 Xyce::dout() <<
"[LTRA-DBG-DEV]: lteCalculate_: i <= 0: some mistake!" << std::endl;
2727 g1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,
2729 h1dashTfirstCoeff = 0.5 * f1i *
2736 lolimit1 = Xycemax(
td,lolimit1);
2741 f1i =
twiceintlinfunc_(lolimit1,hilimit1,lolimit1,lovalue1,hivalue1,lolimit1,
2744 hivalue1,lolimit1,hilimit1);
2750 f1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,lolimit1,
2753 hivalue1,lolimit1,hilimit1);
2770 eq1LTE +=
admit*fabs(dashdash * h1dashTfirstCoeff);
2777 instance.
v1[auxindex - 1],
2778 instance.
v1[auxindex],
2779 instance.
v1[auxindex + 1]) ;
2781 eq2LTE +=
admit*fabs(dashdash * h3dashTfirstCoeff);
2793 eq2LTE +=
admit*fabs(dashdash * h1dashTfirstCoeff);
2798 instance.
v2[auxindex - 1],
2799 instance.
v2[auxindex],
2800 instance.
v2[auxindex + 1]);
2802 eq1LTE +=
admit*fabs(dashdash * h3dashTfirstCoeff);
2813 instance.
i1[auxindex - 1],
2814 instance.
i1[auxindex],
2815 instance.
i1[auxindex + 1]) ;
2817 eq2LTE += fabs(dashdash * h2TfirstCoeff);
2827 instance.
i2[auxindex - 1],
2828 instance.
i2[auxindex],
2829 instance.
i2[auxindex + 1]) ;
2831 eq1LTE += fabs(dashdash * h2TfirstCoeff);
2847 g1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,lolimit1,hilimit1);
2855 g1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,lolimit1,hilimit1);
2863 hivalue1,lolimit1,hilimit1);
2877 eq1LTE += fabs(dashdash * h1dashTfirstCoeff);
2878 eq2LTE += fabs(dashdash * h3dashTfirstCoeff);
2890 eq2LTE += fabs(dashdash * h1dashTfirstCoeff);
2891 eq1LTE += fabs(dashdash * h3dashTfirstCoeff);
2903 eq2LTE += fabs(dashdash * h2TfirstCoeff);
2915 eq1LTE += fabs(dashdash * h2TfirstCoeff);
2925 #ifdef Xyce_DEBUG_DEVICE
2926 Xyce::dout() <<
"[LTRA-DBG-DEV] " << instance.
getName() <<
": LTE/input for Eq1 at time "
2927 << curtime <<
" is: " << eq1LTE/instance.
input1 << std::endl;
2929 Xyce::dout() <<
"[LTRA-DBG-DEV] " << instance.
getName() <<
": LTE/input for Eq2 at time "
2930 << curtime <<
" is: " << eq2LTE/instance.
input1 << std::endl;
2933 return(fabs(eq1LTE) + fabs(eq2LTE));
3017 Model& m = (*it)->getModel();
3046 <<
"Modes supported: RC, RG, LC, RLC";
3052 UserError0(m) <<
"Nonzero G (except RG) transmission line not supported. "
3053 <<
"Modes supported: RC, RG, LC, RLC";
3058 if ((m.
resist == 0.0 ? 0 : 1) + (m.
conduct == 0.0 ? 0 : 1) +
3059 (m.
induct == 0.0 ? 0 : 1) + (m.
capac == 0.0 ? 0 : 1) <= 1)
3061 UserError0(m) <<
"Invalid specification. Specify at least "
3062 <<
"two of R, L, G, or C with nonzero values. "
3063 <<
"Modes supported: RC, RG, LC, RLC";
3076 UserWarning(*
this) <<
"Conflicting options STEPLIMIT and NOSTEPLIMIT given. Using STEPLIMIT";
3123 if (m.
alpha < 0.0) {
3124 UserError(m) <<
"Resistance and inductance must be greater than zero";
3131 double xbig, xsmall, xmid, y1big, y1small, y1mid;
3132 double y2big, y2small, y2mid;
3133 int done = 0, maxiter = 50, iters = 0;
3137 xmid = 0.5 * (xbig + xsmall);
3154 if ((done == 2) || (iters > maxiter))
3157 xmid = 0.5 * (xbig + xsmall);
3176 Report::DevelFatal().in(
"Master::initialize_vars_(void)") <<
"Unhandled LTRA special case encountered.";
3195 double max(0.0),min(0.0);
3196 double v1d(0.0), v2d(0.0), i1d(0.0), i2d(0.0);
3197 double dummy1(0.0), dummy2(0.0);
3198 std::ostringstream msg;
3211 dummy2 = exp(-dummy1);
3212 dummy1 = exp(dummy1);
3290 double qf1, qf2, qf3;
3293 qf1 = qf2 = qf3 = 0.0;
3308 if ((isaved != 0) &&
3311 v1d = di.
v1[isaved-1] * qf1
3312 + di.
v1[isaved] * qf2
3313 + di.
v1[isaved+1] * qf3;
3315 max = Xycemax(di.
v1[isaved-1], di.
v1[isaved]);
3316 max = Xycemax(max,di.
v1[isaved+1]);
3317 min = Xycemin(di.
v1[isaved-1], di.
v1[isaved]);
3318 min = Xycemin(min,di.
v1[isaved+1]);
3327 #ifdef Xyce_DEBUG_DEVICE
3328 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated v1 is out of range after timepoint "
3330 Xyce::dout() <<
" values: "
3331 << di.
v1[isaved-1] <<
" "
3332 << di.
v1[isaved] <<
" "
3333 << di.
v1[isaved+1] <<
"; interpolated: "
3334 << v1d << std::endl;
3335 Xyce::dout() <<
" timepoints are: "
3341 v1d = di.
v1[isaved] * lf2 + di.
v1[isaved+1] * lf3;
3345 if ((isaved != 0) &&
3349 i1d = di.
i1[isaved-1] * qf1
3350 + di.
i1[isaved] * qf2
3351 + di.
i1[isaved+1] * qf3;
3353 max = Xycemax(di.
i1[isaved-1], di.
i1[isaved]);
3354 max = Xycemax(max,di.
i1[isaved+1]);
3355 min = Xycemin(di.
i1[isaved-1], di.
i1[isaved]);
3356 min = Xycemin(min,di.
i1[isaved+1]);
3362 ((i1d > max) || (i1d < min))))
3367 #ifdef Xyce_DEBUG_DEVICE
3368 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated i1 is out of range after timepoint "
3370 Xyce::dout() <<
" values: "
3371 << di.
i1[isaved-1] <<
" "
3372 << di.
i1[isaved] <<
" "
3373 << di.
i1[isaved+1] <<
"; interpolated: "
3374 << i1d << std::endl;
3375 Xyce::dout() <<
" timepoints are: "
3381 i1d = di.
i1[isaved] * lf2 + di.
i1[isaved+1] * lf3;
3385 if ((isaved != 0) &&
3389 v2d = di.
v2[isaved-1] * qf1
3390 + di.
v2[isaved] * qf2
3391 + di.
v2[isaved+1] * qf3;
3393 max = Xycemax(di.
v2[isaved-1], di.
v2[isaved]);
3394 max = Xycemax(max,di.
v2[isaved+1]);
3395 min = Xycemin(di.
v2[isaved-1], di.
v2[isaved]);
3396 min = Xycemin(min,di.
v2[isaved+1]);
3404 ((v2d > max) || (v2d < min))))
3407 if ((isaved != 0) &&
3410 #ifdef Xyce_DEBUG_DEVICE
3411 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated v2 is out of range after timepoint "
3413 Xyce::dout() <<
" values: "
3414 << di.
v2[isaved-1] <<
" "
3415 << di.
v2[isaved] <<
" "
3416 << di.
v2[isaved+1] <<
"; interpolated: "
3417 << v2d << std::endl;
3418 Xyce::dout() <<
" timepoints are: "
3424 v2d = di.
v2[isaved] * lf2
3430 if ((isaved != 0) &&
3434 i2d = di.
i2[isaved-1] * qf1
3435 + di.
i2[isaved] * qf2
3436 + di.
i2[isaved+1] * qf3;
3438 max = Xycemax(di.
i2[isaved-1], di.
i2[isaved]);
3439 max = Xycemax(max,di.
i2[isaved+1]); min = Xycemin(di.
i2[isaved-1], di.
i2[isaved]);
3440 min = Xycemin(min,di.
i2[isaved+1]);
3446 ((i2d > max) || (i2d < min))))
3450 #ifdef Xyce_DEBUG_DEVICE
3451 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated i2 is out of range after timepoint "
3453 Xyce::dout() <<
" values: "
3454 << di.
i2[isaved-1] <<
" "
3455 << di.
i2[isaved] <<
" "
3456 << di.
i2[isaved+1] <<
"; interpolated: "
3457 << i2d << std::endl;
3458 Xyce::dout() <<
" timepoints are: "
3464 i2d = di.
i2[isaved] * lf2 + di.
i2[isaved+1] * lf3;
3489 dummy1 = dummy2 = 0.0;
3512 dummy1 = dummy2 = 0.0;
3544 dummy1 = dummy2 = 0.0;
3657 dummy1 = dummy2 = 0.0;
3724 double dummy1(0.0), dummy2(0.0);
3725 std::ostringstream msg;
3890 .registerDevice(
"o", 1)
3891 .registerModelType(
"ltra", 1);