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;
532 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
654 bool bsuccess =
true;
672 #if defined(Xyce_DEBUG_DEVICE)
675 Xyce::dout() <<
"[LTRA-DBG-DEV] In Instance::getBreakPoints "<<std::endl;
676 Xyce::dout() <<
" First time step, I don't get to set breakpoints. Time is ";
677 Xyce::dout() << currentTime << std::endl;
748 bool compact =
false;
823 #define CHECK(a,b,c) (Xycemax(Xycemax(a,b),c)-Xycemin(Xycemin(a,b),c) >= \
824 fabs(50.0*(getDeviceOptions().reltol/3.0*(a+b+c) + \
825 getDeviceOptions().abstol)))
830 if (tmp_test || ((fabs(d3_ - d4_)
838 #ifdef Xyce_DEBUG_DEVICE
859 #ifdef Xyce_DEBUG_DEVICE
912 double d1_ = (i1_ - i2_) /
915 double d2_ = (i2_ - i3_) /
918 double d3_ = (i4_ - i5_) /
921 double d4_ = (i5_ - i6_) /
938 std::ostringstream msg;
939 msg <<
"**********" << std::endl;
940 msg <<
": Error. Case not handled in calculateMaxTimeStep_()";
941 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
984 if (current_lte >= tolerance) {
989 double y = current_lte;
994 #ifdef Xyce_DEBUG_DEVICE
995 if (deriv_delta <= 0.0)
996 Xyce::dout() <<
"LTRAtrunc: error: timestep is now less than zero" << std::endl;
998 double deriv = model.
lteCalculate_(*
this, x + deriv_delta) - y;
1000 deriv /= deriv_delta;
1001 double change = (tolerance - y) / deriv;
1007 if (fabs(change) <= fabs(deriv_delta))
1011 if (iterations >= maxiter)
1030 std::ostringstream msg;
1031 msg <<
"**********" << std::endl;
1032 msg <<
": Error. Case not handled in calculateMaxTimeStep_() [2]";
1033 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
1063 int origSize = myState->
data.size();
1073 #ifdef Xyce_DEBUG_RESTART
1074 Xyce::dout().width(18); Xyce::dout().precision(10); Xyce::dout().setf(std::ios::scientific);
1075 Xyce::dout() <<
"LTRA::getInternalState: input1="<<
input1<<
" input2="<<
input2<<std::endl;
1076 Xyce::dout() <<
"LTRA::getInternalState: initVolt11="<<
initVolt1<<
" initVolt2="<<
initVolt2<<std::endl;
1077 Xyce::dout() <<
"LTRA::getInternalState: initCur11="<<
initCur1<<
" initCur2="<<
initCur2<<std::endl;
1084 myState->
data[j+1]=
v2[i];
1085 myState->
data[j+2]=
i1[i];
1086 myState->
data[j+3]=
i2[i];
1087 #ifdef Xyce_DEBUG_RESTART
1088 Xyce::dout().width(18); Xyce::dout().precision(10); Xyce::dout().setf(std::ios::scientific);
1090 "LTRA::getInternalState: v1["<<i<<
"]="<<
v1[i]
1091 <<
" v2["<<i<<
"]="<<
v2[i]
1092 <<
" i1["<<i<<
"]="<<
i1[i]
1093 <<
" i2["<<i<<
"]="<<
i2[i]
1103 origSize = myState->
data.size();
1111 #ifdef Xyce_DEBUG_RESTART
1112 Xyce::dout().width(18); Xyce::dout().precision(10); Xyce::dout().setf(std::ios::scientific);
1139 if (
getName().getEncodedName() != state.
ID)
1141 DevelFatal(*this).in(
"LTRA::Instance::setInternalState") <<
"ID(" << state.
ID <<
") from restart does not match my name (" <<
getName() <<
")";
1147 v1.clear();
v2.clear();
i1.clear();
i2.clear();
1157 #ifdef Xyce_DEBUG_RESTART
1158 Xyce::dout().width(18); Xyce::dout().precision(10); Xyce::dout().setf(std::ios::scientific);
1159 Xyce::dout() <<
"LTRA::setInternalState: input1="<<
input1<<
" input2="<<
input2<<std::endl;
1160 Xyce::dout() <<
"LTRA::setInternalState: initVolt11="<<
initVolt1<<
" initVolt2="<<
initVolt2<<std::endl;
1161 Xyce::dout() <<
"LTRA::setInternalState: initCur11="<<
initCur1<<
" initCur2="<<
initCur2<<std::endl;
1171 #ifdef Xyce_DEBUG_RESTART
1172 Xyce::dout().width(18); Xyce::dout().precision(10); Xyce::dout().setf(std::ios::scientific);
1174 "LTRA::setInternalState: v1["<<i<<
"]="<<
v1[i]
1175 <<
" v2["<<i<<
"]="<<
v2[i]
1176 <<
" i1["<<i<<
"]="<<
i1[i]
1177 <<
" i2["<<i<<
"]="<<
i2[i]
1195 j=(listSize*4+6)+i*3;
1199 #ifdef Xyce_DEBUG_RESTART
1200 Xyce::dout().width(18); Xyce::dout().precision(10); Xyce::dout().setf(std::ios::scientific);
1238 std::vector<Instance*>::iterator iter;
1242 for (iter=first; iter!=last; ++iter)
1244 (*iter)->processParams();
1262 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
1264 h1dashFirstVal(0.0),
1266 h3dashFirstVal(0.0),
1267 h1dashFirstCoeff(0.0),
1269 h3dashFirstCoeff(0.0),
1291 truncDontCut(false),
1295 conductGiven(false),
1300 noStepLimitGiven(false),
1301 stepLimitGiven(false),
1302 linInterpGiven(false),
1303 quadInterpGiven(false),
1304 mixedInterpGiven(false),
1305 stLineReltolGiven(false),
1306 stLineAbstolGiven(false),
1307 truncNRGiven(false),
1308 truncDontCutGiven(false),
1329 maxSafeStep(1.0e99),
1330 maxTimeStep(1.0e99),
1331 lteTimeStepControl(false),
1336 restartStoredFlag(false)
1370 std::vector<Instance*>::iterator iter;
1374 for (iter=first; iter!=last; ++iter)
1390 std::vector<Instance*>::const_iterator iter;
1396 os <<
" name model name Parameters" << std::endl;
1397 for (i=0, iter=first; iter!=last; ++iter, ++i)
1399 os <<
" " << i <<
": " << (*iter)->getName() <<
" ";
1427 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1441 double& qf1,
double& qf2,
double& qf3,
1442 double& lf2,
double& lf3)
1444 double t1(0.0),t2(0.0),t3(0.0);
1445 double v1d(0.0), v2d(0.0), i1d(0.0), i2d(0.0);
1446 double dummy1(0.0), dummy2(0.0);
1457 dummy2 = exp(-dummy1);
1458 dummy1 = exp(dummy1);
1461 if (conduct <= 1.0e-10)
1487 std::ostringstream msg;
1488 msg <<
"**********" << std::endl;
1489 msg <<
": Error. Case not handled in modelCalculations_()";
1490 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
1548 #ifdef Xyce_DEBUG_DEVICE
1551 Xyce::dout() <<
"[LTRA-DBG-DEV] LTRAload: Warning: timestep larger than delay of line" << std::endl;
1561 #ifdef Xyce_DEBUG_DEVICE
1562 Xyce::dout() <<
"[LTRA-DBG-DEV] LTRAload: mistake: cannot find delayed timepoint" << std::endl;
1564 std::ostringstream msg;
1565 msg <<
"************" << std::endl;
1566 msg <<
": Error. Delayed time point not found.";
1567 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
1673 if( (t2-t1)==0 || (t3-t2) == 0 || (t1 - t3) ==0)
return(1);
1675 f1 = (t - t2) * (t - t3) ;
1676 f2 = (t - t1) * (t - t3) ;
1677 f3 = (t - t1) * (t - t2) ;
1729 if (t1 == t2)
return(1);
1745 temp = (t-t1)/(t2-t1);
1767 double lovalue,
double hivalue,
1768 double t1,
double t2)
1773 if (width == 0.0)
return(0.0);
1774 m = (hivalue - lovalue)/width;
1776 return( (hilimit-lolimit)*lovalue + 0.5*m*((hilimit-t1)*(hilimit-t1)
1777 - (lolimit - t1)*(lolimit - t1)));
1796 double otherlolimit,
double lovalue,
1797 double hivalue,
double t1,
double t2)
1799 double width, m, dummy;
1800 double temp1, temp2, temp3;
1803 if (width == 0.0)
return(0.0);
1804 m = (hivalue - lovalue)/width;
1806 temp1 = hilimit - t1;
1807 temp2 = lolimit - t1;
1808 temp3 = otherlolimit - t1;
1809 dummy = lovalue*((hilimit - otherlolimit)*(hilimit - otherlolimit) -
1810 (lolimit - otherlolimit)*(lolimit - otherlolimit));
1811 dummy += m*((temp1*temp1*temp1 - temp2*temp2*temp2)/3.0 -
1812 temp3*temp3*(hilimit - lolimit));
1833 double secondlolimit,
double thirdlolimit,
1834 double lovalue,
double hivalue,
double t1,
double t2)
1836 double width, m, dummy;
1837 double temp1, temp2, temp3, temp4;
1838 double temp5, temp6, temp7, temp8, temp9, temp10;
1842 if (width == 0.0)
return(0.0);
1843 m = (hivalue - lovalue)/width;
1845 temp1 = hilimit - t1;
1846 temp2 = lolimit - t1;
1847 temp3 = secondlolimit - t1;
1848 temp4 = thirdlolimit - t1;
1849 temp5 = hilimit - thirdlolimit;
1850 temp6 = lolimit - thirdlolimit;
1851 temp7 = secondlolimit - thirdlolimit;
1852 temp8 = hilimit - lolimit;
1853 temp9 = hilimit - secondlolimit;
1854 temp10 = lolimit - secondlolimit;
1855 dummy = lovalue*((temp5*temp5*temp5 - temp6*temp6*temp6)/3 -
1857 dummy += m*(((temp1*temp1*temp1*temp1 - temp2*temp2*temp2*temp2)*0.25 -
1858 temp3*temp3*temp3*temp8)/3 - temp4*temp4*0.5*(temp9*temp9 -
1877 if ((ax=fabs(x)) < 3.75)
1881 ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492
1882 +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2)))));
1887 ans=(exp(ax)/sqrt(ax))*
1888 (0.39894228+y*(0.1328592e-1+y*(0.225319e-2+
1889 y*(-0.157565e-2+y*(0.916281e-2+
1890 y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1
1891 +y*0.392377e-2))))))));
1909 if ((ax=fabs(x)) < 3.75)
1913 ans=ax*(0.5+y*(0.87890594+y*(0.51498869+y*(0.15084934
1914 +y*(0.2658733e-1+y*(0.301532e-2+y*0.32411e-3))))));
1919 ans=0.2282967e-1+y*(-0.2895312e-1+y*(0.1787654e-1
1921 ans=0.39894228+y*(-0.3988024e-1+y*(-0.362018e-2
1922 +y*(0.163801e-2+y*(-0.1031555e-1+y*ans))));
1923 ans *= (exp(ax)/sqrt(ax));
1925 return(x < 0.0 ? -ans : ans);
1941 if ((ax=fabs(x)) < 3.75) {
1944 ans=0.5+y*(0.87890594+y*(0.51498869+y*(0.15084934
1945 +y*(0.2658733e-1+y*(0.301532e-2+y*0.32411e-3)))));
1950 ans=0.2282967e-1+y*(-0.2895312e-1+y*(0.1787654e-1
1952 ans=0.39894228+y*(-0.3988024e-1+y*(-0.362018e-2
1953 +y*(0.163801e-2+y*(-0.1031555e-1+y*ans))));
1954 ans *= (exp(ax)/(ax*sqrt(ax)));
1969 double besselarg, exparg, returnval;
1976 if (alpha == 0.0)
return(0.0);
1978 exparg = - beta * time;
1979 besselarg = alpha*time;
1981 returnval = (
bessI1_(besselarg)-
bessI0_(besselarg))* alpha * exp(exparg);
1995 double besselarg, exparg, returnval;
2003 if (alpha == 0.0)
return(0.0);
2004 if (time < T)
return(0.0);
2007 besselarg = alpha*sqrt(time*time - T*T);
2011 exparg = -beta*time;
2013 returnval = alpha*alpha*T*exp(exparg)*
bessI1xOverX_(besselarg);
2027 double exparg,besselarg,returnval;
2035 if (alpha == 0.0)
return(0.0);
2036 if (time < T)
return(0.0);
2038 exparg = - beta*time;
2040 besselarg = alpha*sqrt(time*time - T*T);
2046 returnval *= alpha*exp(exparg);
2063 double arg, returnval;
2069 if (beta == 0.0)
return(time);
2071 if (arg == 0.0)
return(0.0);
2073 returnval = (
bessI1_(arg)+
bessI0_(arg))* time * exp(-arg) - time;
2090 double exparg, besselarg;
2093 if (time <= T)
return(0.0);
2094 if (beta == 0.0)
return(0.0);
2095 exparg = -beta*time;
2096 besselarg = beta*sqrt(time*time-T*T);
2097 returnval = exp(exparg)*
bessI0_(besselarg) - exp(-beta*T);
2111 return(sqrt(4*cbyr*time/
M_PI));
2127 temp = rclsqr/(4*time);
2139 return((time + rclsqr*0.5)*erfc_res - sqrt(time*rclsqr/
M_PI)*exp(- temp));
2160 temp = rclsqr/(4*time);
2165 temp = 2*sqrt(time/
M_PI)*exp(-temp) - sqrt(rclsqr)*erfc_res;
2166 return(sqrt(cbyr)*temp);
2187 double& h1dashfirstcoeff,
2188 double& h2firstcoeff,
2189 double& h3dashfirstcoeff,
2190 std::vector<double>& h1dashcoeffs,
2191 std::vector<double>& h2coeffs,
2192 std::vector<double>& h3dashcoeffs,
2193 size_t listsize,
double cbyr,
double rclsqr,
double curtime,
2194 const std::vector<double>& timelist,
int timeindex,
double reltol)
2196 double delta1, delta2;
2197 double h1dummy1, h1dummy2;
2198 double h2dummy1, h2dummy2;
2199 double h3dummy1, h3dummy2;
2200 double lolimit1,lolimit2, hilimit1, hilimit2;
2201 double h1lovalue1,h1lovalue2,h1hivalue1,h1hivalue2;
2202 double h2lovalue1,h2lovalue2,h2hivalue1,h2hivalue2;
2203 double h3lovalue1,h3lovalue2,h3hivalue1,h3hivalue2;
2204 double temp, temp2, temp3, temp4, temp5;
2205 double h1relval, h2relval, h3relval;
2206 int doh1=1, doh2=1, doh3=1;
2211 #ifdef Xyce_DEBUG_DEVICE
2212 if (listsize < timeindex) {
2213 Xyce::dout() <<
"[LTRA-DBG-DEV]: LTRAcoeffSetup: not enough space in coefflist" << std::endl;
2217 auxindex = timeindex;
2221 delta1 = curtime - timelist[auxindex];
2227 sqrt(4*cbyr*hilimit1/
M_PI);
2228 h1dummy1 = h1hivalue1/delta1;
2229 h1dashfirstcoeff = h1dummy1;
2230 h1relval = fabs(h1dummy1*reltol);
2232 temp = rclsqr/(4*hilimit1);
2237 temp4 = sqrt(rclsqr);
2242 (hilimit1 != 0.0? (hilimit1 + rclsqr*0.5)*temp2 - sqrt(hilimit1*rclsqr/
M_PI)*temp3 : 0.0);
2245 h2dummy1 = h2hivalue1/delta1;
2246 h2firstcoeff = h2dummy1;
2247 h2relval = fabs(h2dummy1*reltol);
2251 (hilimit1 != 0.0? temp = 2*sqrt(hilimit1/
M_PI)*temp3 - temp4*temp2, (temp5*temp): 0.0);
2254 h3dummy1 = h3hivalue1/delta1;
2255 h3dashfirstcoeff = h3dummy1;
2256 h3relval = fabs(h3dummy1*reltol);
2260 for (i=auxindex; i>0; i--)
2263 lolimit2 = lolimit1;
2264 hilimit2 = hilimit1;
2266 delta1 = timelist[i] - timelist[i - 1];
2267 lolimit1 = hilimit2;
2268 hilimit1 = curtime - timelist[i - 1];
2272 h1lovalue2 = h1lovalue1;
2273 h1hivalue2 = h1hivalue1;
2274 h1dummy2 = h1dummy1;
2276 h1lovalue1 = h1hivalue2;
2278 sqrt(4*cbyr*hilimit1/
M_PI);
2279 h1dummy1 = (h1hivalue1 - h1lovalue1)/delta1;
2280 h1dashcoeffs[i] = h1dummy1 - h1dummy2;
2281 if (fabs(h1dashcoeffs[i]) < h1relval) doh1=0;
2285 h1dashcoeffs[i] = 0.0;
2289 temp = rclsqr/(4*hilimit1);
2297 h2lovalue2 = h2lovalue1;
2298 h2hivalue2 = h2hivalue1;
2299 h2dummy2 = h2dummy1;
2301 h2lovalue1 = h2hivalue2;
2303 (hilimit1 != 0.0? (hilimit1 + rclsqr*0.5)*temp2 - sqrt(hilimit1*rclsqr/
M_PI)*temp3 : 0.0);
2304 h2dummy1 = (h2hivalue1 - h2lovalue1)/delta1;
2305 h2coeffs[i] = h2dummy1 - h2dummy2;
2306 if (fabs(h2coeffs[i]) < h2relval) doh2=0;
2315 h3lovalue2 = h3lovalue1;
2316 h3hivalue2 = h3hivalue1;
2317 h3dummy2 = h3dummy1;
2319 h3lovalue1 = h3hivalue2;
2321 (hilimit1 != 0.0? temp = 2*sqrt(hilimit1/
M_PI)*temp3 - temp4*temp2, (temp5*temp): 0.0);
2322 h3dummy1 = (h3hivalue1 - h3lovalue1)/delta1;
2323 h3dashcoeffs[i] = h3dummy1 - h3dummy2;
2324 if (fabs(h3dashcoeffs[i]) < h3relval) doh3=0;
2328 h3dashcoeffs[i] = 0.0;
2342 double& h1dashfirstcoeff,
2343 double& h2firstcoeff,
2344 double& h3dashfirstcoeff,
2345 std::vector<double>& h1dashcoeffs,
2346 std::vector<double>& h2coeffs,
2347 std::vector<double>& h3dashcoeffs,
2349 double T,
double alpha,
double beta,
double curtime,
2350 const std::vector<double>& timelist,
int timeindex,
double reltol,
int* auxindexptr)
2353 double lolimit1,lolimit2,hilimit1,hilimit2;
2354 double delta1, delta2;
2356 double h1dummy1, h1dummy2;
2357 double h1lovalue1,h1lovalue2,h1hivalue1,h1hivalue2;
2359 double h2dummy1, h2dummy2;
2360 double h2lovalue1,h2lovalue2,h2hivalue1,h2hivalue2;
2362 double h3dummy1, h3dummy2;
2363 double h3lovalue1,h3lovalue2,h3hivalue1,h3hivalue2;
2365 double exparg, besselarg, expterm, bessi1overxterm, bessi0term;
2366 double expbetaTterm, alphasqTterm;
2367 double h1relval, h2relval, h3relval;
2368 int doh1=1, doh2=1, doh3=1;
2374 #ifdef Xyce_DEBUG_DEVICE
2375 if (listsize < timeindex) {
2376 Xyce::dout() <<
"[LTRA-DBG-DEV]: LTRArlcCoeffsSetup_: not enough space in coefflist" << std::endl;
2388 auxindex = timeindex;
2391 if (curtime - T <= 0.0) {
2395 for (i = timeindex; i>= 0; i--) {
2396 if (curtime - timelist[i] == T) {
2400 if (curtime - timelist[i] > T)
break;
2403 #ifdef Xyce_DEBUG_DEVICE
2404 if ((i < 0) || ((i==0) && (exact==1)))
2405 Xyce::dout() <<
"[LTRA-DBG-DEV]: LTRAcoeffSetup: i <= 0: some mistake!" << std::endl;
2420 hilimit1 = curtime - timelist[auxindex];
2421 delta1 = hilimit1 - lolimit1;
2424 besselarg = (hilimit1 > T) ? alpha*sqrt(hilimit1*hilimit1-T*T):0.0;
2425 exparg = -beta*hilimit1;
2426 expterm = exp(exparg);
2428 alphasqTterm = alpha*alpha*T;
2430 ((alpha == 0.0) || (hilimit1 < T)) ? 0.0: alphasqTterm*expterm*bessi1overxterm;
2433 h2hivalue1,lolimit1,hilimit1)/delta1;
2434 h2firstcoeff = h2dummy1;
2435 h2relval = fabs(reltol*h2dummy1);
2438 bessi0term =
bessI0_(besselarg);
2439 expbetaTterm = exp(-beta*T);
2441 ((hilimit1 <= T) || (beta == 0.0)) ? 0.0: expterm* bessi0term-expbetaTterm;
2442 h3dummy1 =
intlinfunc_(lolimit1,hilimit1,h3lovalue1,
2443 h3hivalue1,lolimit1,hilimit1)/delta1;
2444 h3dashfirstcoeff = h3dummy1;
2445 h3relval = fabs(h3dummy1*reltol);
2449 h2firstcoeff = h3dashfirstcoeff = 0.0;
2453 hilimit1 = curtime - timelist[timeindex];
2454 delta1 = hilimit1 - lolimit1;
2455 exparg = -beta*hilimit1;
2456 expterm = exp(exparg);
2460 (beta == 0.0) ? hilimit1 : ((hilimit1 == 0.0) ? 0.0 :
2461 (
bessI1_(-exparg)+
bessI0_(-exparg))* hilimit1 * expterm - hilimit1);
2462 h1dummy1 = h1hivalue1/delta1;
2463 h1dashfirstcoeff = h1dummy1;
2464 h1relval = fabs(h1dummy1*reltol);
2469 for (i=timeindex; i>0; i--)
2471 if (doh1 || doh2 || doh3)
2473 lolimit2 = lolimit1;
2474 hilimit2 = hilimit1;
2477 lolimit1 = hilimit2;
2478 hilimit1 = curtime - timelist[i - 1];
2479 delta1 = timelist[i] - timelist[i - 1];
2481 exparg = -beta*hilimit1;
2482 expterm = exp(exparg);
2487 h1lovalue2 = h1lovalue1;
2488 h1hivalue2 = h1hivalue1;
2489 h1dummy2 = h1dummy1;
2491 h1lovalue1 = h1hivalue2;
2493 (beta == 0.0) ? hilimit1 : ((hilimit1 == 0.0) ? 0.0 :
2494 (
bessI1_(-exparg)+
bessI0_(-exparg))* hilimit1 * expterm - hilimit1);
2495 h1dummy1 = (h1hivalue1 - h1lovalue1)/delta1;
2497 h1dashcoeffs[i] = h1dummy1 - h1dummy2;
2498 if (fabs(h1dashcoeffs[i]) <= h1relval) doh1 = 0;
2502 h1dashcoeffs[i] = 0.0;
2514 besselarg = (hilimit1 > T) ? alpha*sqrt(hilimit1*hilimit1-T*T):0.0;
2519 h2lovalue2 = h2lovalue1;
2520 h2hivalue2 = h2hivalue1;
2521 h2dummy2 = h2dummy1;
2523 h2lovalue1 = h2hivalue2;
2526 ((alpha == 0.0) || (hilimit1 < T)) ? 0.0: alphasqTterm*expterm*bessi1overxterm;
2528 h2lovalue1,h2hivalue1,lolimit1,hilimit1)/delta1;
2530 h2coeffs[i] = h2dummy1 - h2dummy2 +
intlinfunc_(lolimit2,hilimit2,
2531 h2lovalue2,h2hivalue2,lolimit2,hilimit2);
2532 if (fabs(h2coeffs[i]) <= h2relval) doh2 = 0;
2541 h3lovalue2 = h3lovalue1;
2542 h3hivalue2 = h3hivalue1;
2543 h3dummy2 = h3dummy1;
2545 h3lovalue1 = h3hivalue2;
2546 bessi0term =
bessI0_(besselarg);
2548 ((hilimit1 <= T) || (beta == 0.0)) ? 0.0: expterm* bessi0term-expbetaTterm;
2549 h3dummy1 =
intlinfunc_(lolimit1,hilimit1,h3lovalue1,h3hivalue1,lolimit1,hilimit1)/delta1;
2551 h3dashcoeffs[i] = h3dummy1 - h3dummy2;
2552 if (fabs(h3dashcoeffs[i]) <= h3relval) doh3 = 0;
2556 h3dashcoeffs[i] = 0.0;
2560 *auxindexptr = auxindex;
2583 double x2,
double y2,
2584 double x3,
double y3,
2585 double reltol,
double abstol)
2589 double TRarea, QUADarea1,QUADarea2,QUADarea3, area;
2603 QUADarea1 = (fabs(y2)+fabs(y1))*0.5*fabs(x2-x1);
2604 QUADarea2 = (fabs(y3)+fabs(y2))*0.5*fabs(x3-x2);
2605 QUADarea3 = (fabs(y3)+fabs(y1))*0.5*fabs(x3-x1);
2606 TRarea = fabs( QUADarea3 - QUADarea1 - QUADarea2);
2607 area = QUADarea1 + QUADarea2;
2608 if (area*reltol + abstol > TRarea)
2618 #define SECONDDERIV(i,a,b,c) \
2619 (oof = (i==getSolverState().ltraTimeIndex?getSolverState().currTime: \
2620 (getSolverState().ltraTimePoints[i])), \
2621 (( c - b )/(oof-(getSolverState().ltraTimePoints[i-1])) - \
2622 ( b - a )/((getSolverState().ltraTimePoints[i-1])- \
2623 (getSolverState().ltraTimePoints[i-2])))/(oof - \
2624 (getSolverState().ltraTimePoints[i-2])))
2658 double h1dashTfirstCoeff;
2659 double h2TfirstCoeff;
2660 double h3dashTfirstCoeff;
2662 double hilimit1, lolimit1, hivalue1, lovalue1, f1i, g1i;
2663 double eq1LTE=0.0, eq2LTE=0.0;
2664 int auxindex,
tdover, i, exact;
2694 #ifdef Xyce_DEBUG_DEVICE
2695 if ((i < 0) || ((i==0) && (exact==1)))
2696 Xyce::dout() <<
"[LTRA-DBG-DEV]: lteCalculate_: i <= 0: some mistake!" << std::endl;
2719 g1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,
2721 h1dashTfirstCoeff = 0.5 * f1i *
2733 f1i =
twiceintlinfunc_(lolimit1,hilimit1,lolimit1,lovalue1,hivalue1,lolimit1,
2736 hivalue1,lolimit1,hilimit1);
2742 f1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,lolimit1,
2745 hivalue1,lolimit1,hilimit1);
2762 eq1LTE +=
admit*fabs(dashdash * h1dashTfirstCoeff);
2769 instance.
v1[auxindex - 1],
2770 instance.
v1[auxindex],
2771 instance.
v1[auxindex + 1]) ;
2773 eq2LTE +=
admit*fabs(dashdash * h3dashTfirstCoeff);
2785 eq2LTE +=
admit*fabs(dashdash * h1dashTfirstCoeff);
2790 instance.
v2[auxindex - 1],
2791 instance.
v2[auxindex],
2792 instance.
v2[auxindex + 1]);
2794 eq1LTE +=
admit*fabs(dashdash * h3dashTfirstCoeff);
2805 instance.
i1[auxindex - 1],
2806 instance.
i1[auxindex],
2807 instance.
i1[auxindex + 1]) ;
2809 eq2LTE += fabs(dashdash * h2TfirstCoeff);
2819 instance.
i2[auxindex - 1],
2820 instance.
i2[auxindex],
2821 instance.
i2[auxindex + 1]) ;
2823 eq1LTE += fabs(dashdash * h2TfirstCoeff);
2839 g1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,lolimit1,hilimit1);
2847 g1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,lolimit1,hilimit1);
2855 hivalue1,lolimit1,hilimit1);
2869 eq1LTE += fabs(dashdash * h1dashTfirstCoeff);
2870 eq2LTE += fabs(dashdash * h3dashTfirstCoeff);
2882 eq2LTE += fabs(dashdash * h1dashTfirstCoeff);
2883 eq1LTE += fabs(dashdash * h3dashTfirstCoeff);
2895 eq2LTE += fabs(dashdash * h2TfirstCoeff);
2907 eq1LTE += fabs(dashdash * h2TfirstCoeff);
2917 #ifdef Xyce_DEBUG_DEVICE
2918 Xyce::dout() <<
"[LTRA-DBG-DEV] " << instance.
getName() <<
": LTE/input for Eq1 at time "
2919 << curtime <<
" is: " << eq1LTE/instance.
input1 << std::endl;
2921 Xyce::dout() <<
"[LTRA-DBG-DEV] " << instance.
getName() <<
": LTE/input for Eq2 at time "
2922 << curtime <<
" is: " << eq2LTE/instance.
input1 << std::endl;
2925 return(fabs(eq1LTE) + fabs(eq2LTE));
3009 Model& m = (*it)->getModel();
3038 <<
"Modes supported: RC, RG, LC, RLC";
3044 UserError0(m) <<
"Nonzero G (except RG) transmission line not supported. "
3045 <<
"Modes supported: RC, RG, LC, RLC";
3050 if ((m.
resist == 0.0 ? 0 : 1) + (m.
conduct == 0.0 ? 0 : 1) +
3051 (m.
induct == 0.0 ? 0 : 1) + (m.
capac == 0.0 ? 0 : 1) <= 1)
3053 UserError0(m) <<
"Invalid specification. Specify at least "
3054 <<
"two of R, L, G, or C with nonzero values. "
3055 <<
"Modes supported: RC, RG, LC, RLC";
3068 UserWarning(*
this) <<
"Conflicting options STEPLIMIT and NOSTEPLIMIT given. Using STEPLIMIT";
3115 if (m.
alpha < 0.0) {
3116 UserError(m) <<
"Resistance and inductance must be greater than zero";
3123 double xbig, xsmall, xmid, y1big, y1small, y1mid;
3124 double y2big, y2small, y2mid;
3125 int done = 0, maxiter = 50, iters = 0;
3129 xmid = 0.5 * (xbig + xsmall);
3146 if ((done == 2) || (iters > maxiter))
3149 xmid = 0.5 * (xbig + xsmall);
3168 Report::DevelFatal().in(
"Master::initialize_vars_(void)") <<
"Unhandled LTRA special case encountered.";
3185 bool Master::loadDAEVectors (
double * solVec,
double * fVec,
double *qVec,
double * bVec,
double * storeLeadF,
double * storeLeadQ)
3187 double max(0.0),min(0.0);
3188 double v1d(0.0), v2d(0.0), i1d(0.0), i2d(0.0);
3189 double dummy1(0.0), dummy2(0.0);
3190 std::ostringstream msg;
3203 dummy2 = exp(-dummy1);
3204 dummy1 = exp(dummy1);
3282 double qf1, qf2, qf3;
3285 qf1 = qf2 = qf3 = 0.0;
3300 if ((isaved != 0) &&
3303 v1d = di.
v1[isaved-1] * qf1
3304 + di.
v1[isaved] * qf2
3305 + di.
v1[isaved+1] * qf3;
3319 #ifdef Xyce_DEBUG_DEVICE
3320 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated v1 is out of range after timepoint "
3322 Xyce::dout() <<
" values: "
3323 << di.
v1[isaved-1] <<
" "
3324 << di.
v1[isaved] <<
" "
3325 << di.
v1[isaved+1] <<
"; interpolated: "
3326 << v1d << std::endl;
3327 Xyce::dout() <<
" timepoints are: "
3333 v1d = di.
v1[isaved] * lf2 + di.
v1[isaved+1] * lf3;
3337 if ((isaved != 0) &&
3341 i1d = di.
i1[isaved-1] * qf1
3342 + di.
i1[isaved] * qf2
3343 + di.
i1[isaved+1] * qf3;
3354 ((i1d > max) || (i1d < min))))
3359 #ifdef Xyce_DEBUG_DEVICE
3360 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated i1 is out of range after timepoint "
3362 Xyce::dout() <<
" values: "
3363 << di.
i1[isaved-1] <<
" "
3364 << di.
i1[isaved] <<
" "
3365 << di.
i1[isaved+1] <<
"; interpolated: "
3366 << i1d << std::endl;
3367 Xyce::dout() <<
" timepoints are: "
3373 i1d = di.
i1[isaved] * lf2 + di.
i1[isaved+1] * lf3;
3377 if ((isaved != 0) &&
3381 v2d = di.
v2[isaved-1] * qf1
3382 + di.
v2[isaved] * qf2
3383 + di.
v2[isaved+1] * qf3;
3396 ((v2d > max) || (v2d < min))))
3399 if ((isaved != 0) &&
3402 #ifdef Xyce_DEBUG_DEVICE
3403 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated v2 is out of range after timepoint "
3405 Xyce::dout() <<
" values: "
3406 << di.
v2[isaved-1] <<
" "
3407 << di.
v2[isaved] <<
" "
3408 << di.
v2[isaved+1] <<
"; interpolated: "
3409 << v2d << std::endl;
3410 Xyce::dout() <<
" timepoints are: "
3416 v2d = di.
v2[isaved] * lf2
3422 if ((isaved != 0) &&
3426 i2d = di.
i2[isaved-1] * qf1
3427 + di.
i2[isaved] * qf2
3428 + di.
i2[isaved+1] * qf3;
3438 ((i2d > max) || (i2d < min))))
3442 #ifdef Xyce_DEBUG_DEVICE
3443 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated i2 is out of range after timepoint "
3445 Xyce::dout() <<
" values: "
3446 << di.
i2[isaved-1] <<
" "
3447 << di.
i2[isaved] <<
" "
3448 << di.
i2[isaved+1] <<
"; interpolated: "
3449 << i2d << std::endl;
3450 Xyce::dout() <<
" timepoints are: "
3456 i2d = di.
i2[isaved] * lf2 + di.
i2[isaved+1] * lf3;
3481 dummy1 = dummy2 = 0.0;
3504 dummy1 = dummy2 = 0.0;
3536 dummy1 = dummy2 = 0.0;
3649 dummy1 = dummy2 = 0.0;
3716 double dummy1(0.0), dummy2(0.0);
3717 std::ostringstream msg;
3882 .registerDevice(
"o", 1)
3883 .registerModelType(
"ltra", 1);