46 #include <Xyce_config.h>
56 #include <N_ERH_ErrorMgr.h>
58 #include <N_LAS_Matrix.h>
59 #include <N_LAS_Vector.h>
61 #include <N_UTL_BreakPoint.h>
62 #include <N_UTL_FeatureTest.h>
63 #include <N_UTL_Functors.h>
64 #include <N_UTL_Math.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 (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
387 Xyce::dout() << std::endl << section_divider << std::endl;
388 Xyce::dout() <<
"[LTRA-DBG-DEV] In Instance::registerLIDs\n\n";
389 Xyce::dout() <<
"name = " <<
getName() << std::endl;
390 Xyce::dout() <<
"[LTRA-DBG-DEV] number of internal variables: " <<
numIntVars << std::endl;
391 Xyce::dout() <<
"[LTRA-DBG-DEV] number of external variables: " <<
numExtVars << std::endl;
411 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
413 Xyce::dout() <<
"[LTRA-DBG-DEV] VARIABLE Indicies " << std::endl;
414 Xyce::dout() <<
"li_Pos1 = " <<
li_Pos1 << std::endl;
415 Xyce::dout() <<
"li_Neg1 = " <<
li_Neg1 << std::endl;
416 Xyce::dout() <<
"li_Pos2 = " <<
li_Pos2 << std::endl;
417 Xyce::dout() <<
"li_Neg2 = " <<
li_Neg2 << std::endl;
418 Xyce::dout() <<
"li_Ibr1 = " <<
li_Ibr1 << std::endl;
419 Xyce::dout() <<
"li_Ibr1 = " <<
li_Ibr1 << std::endl;
420 Xyce::dout() <<
"li_Ibr2 = " <<
li_Ibr2 << std::endl;
421 Xyce::dout() <<
"li_Ibr2 = " <<
li_Ibr2 << std::endl;
423 Xyce::dout() <<
"\nEnd of Instance::register LIDs\n";
424 Xyce::dout() << section_divider << std::endl;
521 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
643 bool bsuccess =
true;
661 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
663 Xyce::dout() <<
"[LTRA-DBG-DEV] In Instance::getBreakPoints "<<std::endl;
664 Xyce::dout() <<
" First time step, I don't get to set breakpoints. Time is ";
665 Xyce::dout() << currentTime << std::endl;
734 bool compact =
false;
809 #define CHECK(a,b,c) (std::max(std::max(a,b),c)-std::min(std::min(a,b),c) >= \
810 fabs(50.0*(getDeviceOptions().reltol/3.0*(a+b+c) + \
811 getDeviceOptions().abstol)))
813 bool tmp_test = (fabs(d1_ - d2_) >
model_.
reltol * std::max(fabs(d1_), fabs(d2_)) +
816 if (tmp_test || ((fabs(d3_ - d4_)
897 double d1_ = (i1_ - i2_) /
900 double d2_ = (i2_ - i3_) /
903 double d3_ = (i4_ - i5_) /
906 double d4_ = (i5_ - i6_) /
909 if ((fabs(d1_-d2_) >= model.
reltol * std::max(fabs(d1_), fabs(d2_)) + model.
abstol) ||
910 (fabs(d3_-d4_) >= model.
reltol * std::max(fabs(d3_), fabs(d4_)) + model.
abstol))
923 std::ostringstream msg;
924 msg <<
"**********" << std::endl;
925 msg <<
": Error. Case not handled in calculateMaxTimeStep_()";
926 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
969 if (current_lte >= tolerance) {
974 double y = current_lte;
981 if (deriv_delta <= 0.0)
982 Xyce::dout() <<
"LTRAtrunc: error: timestep is now less than zero" << std::endl;
984 double deriv = model.
lteCalculate_(*
this, x + deriv_delta) - y;
986 deriv /= deriv_delta;
987 double change = (tolerance - y) / deriv;
993 if (fabs(change) <= fabs(deriv_delta))
997 if (iterations >= maxiter)
1016 std::ostringstream msg;
1017 msg <<
"**********" << std::endl;
1018 msg <<
": Error. Case not handled in calculateMaxTimeStep_() [2]";
1019 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
1049 int origSize = myState->
data.size();
1060 Xyce::dout() <<
"LTRA::getInternalState: input1="<<
input1<<
" input2="<<
input2<<std::endl
1061 <<
"LTRA::getInternalState: initVolt11="<<
initVolt1<<
" initVolt2="<<
initVolt2<<std::endl
1062 <<
"LTRA::getInternalState: initCur11="<<
initCur1<<
" initCur2="<<
initCur2<<std::endl;
1069 myState->
data[j+1]=
v2[i];
1070 myState->
data[j+2]=
i1[i];
1071 myState->
data[j+3]=
i2[i];
1073 Xyce::dout() <<
"LTRA::getInternalState: v1["<<i<<
"]="<<
v1[i]
1074 <<
" v2["<<i<<
"]="<<
v2[i]
1075 <<
" i1["<<i<<
"]="<<
i1[i]
1076 <<
" i2["<<i<<
"]="<<
i2[i]
1085 origSize = myState->
data.size();
1094 Xyce::dout() <<
"LTRA::getInternalState: h1dashCoeffs["<<i<<
"] =" <<
model_.
h1dashCoeffs[i]
1118 if (
getName().getEncodedName() != state.
ID)
1120 DevelFatal(*this).in(
"LTRA::Instance::setInternalState") <<
"ID(" << state.
ID <<
") from restart does not match my name (" <<
getName() <<
")";
1126 v1.clear();
v2.clear();
i1.clear();
i2.clear();
1137 Xyce::dout() <<
"LTRA::setInternalState: input1="<<
input1<<
" input2="<<
input2<<std::endl
1138 <<
"LTRA::setInternalState: initVolt11="<<
initVolt1<<
" initVolt2="<<
initVolt2<<std::endl
1139 <<
"LTRA::setInternalState: initCur11="<<
initCur1<<
" initCur2="<<
initCur2<<std::endl;
1149 Xyce::dout() <<
"LTRA::setInternalState: v1["<<i<<
"]="<<
v1[i]
1150 <<
" v2["<<i<<
"]="<<
v2[i]
1151 <<
" i1["<<i<<
"]="<<
i1[i]
1152 <<
" i2["<<i<<
"]="<<
i2[i]
1169 j=(listSize*4+6)+i*3;
1174 Xyce::dout() <<
"LTRA::setInternalState: h1dashCoeffs["<<i<<
"] =" <<
model_.
h1dashCoeffs[i]
1209 std::vector<Instance*>::iterator iter;
1213 for (iter=first; iter!=last; ++iter)
1215 (*iter)->processParams();
1233 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
1235 h1dashFirstVal(0.0),
1237 h3dashFirstVal(0.0),
1238 h1dashFirstCoeff(0.0),
1240 h3dashFirstCoeff(0.0),
1262 truncDontCut(false),
1266 conductGiven(false),
1271 noStepLimitGiven(false),
1272 stepLimitGiven(false),
1273 linInterpGiven(false),
1274 quadInterpGiven(false),
1275 mixedInterpGiven(false),
1276 stLineReltolGiven(false),
1277 stLineAbstolGiven(false),
1278 truncNRGiven(false),
1279 truncDontCutGiven(false),
1300 maxSafeStep(1.0e99),
1301 maxTimeStep(1.0e99),
1302 lteTimeStepControl(false),
1307 restartStoredFlag(false)
1341 std::vector<Instance*>::iterator iter;
1345 for (iter=first; iter!=last; ++iter)
1361 std::vector<Instance*>::const_iterator iter;
1367 os <<
" name model name Parameters" << std::endl;
1368 for (i=0, iter=first; iter!=last; ++iter, ++i)
1370 os <<
" " << i <<
": " << (*iter)->getName() <<
" ";
1398 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1412 double& qf1,
double& qf2,
double& qf3,
1413 double& lf2,
double& lf3)
1415 double t1(0.0),t2(0.0),t3(0.0);
1416 double v1d(0.0), v2d(0.0), i1d(0.0), i2d(0.0);
1417 double dummy1(0.0), dummy2(0.0);
1428 dummy2 = exp(-dummy1);
1429 dummy1 = exp(dummy1);
1432 if (conduct <= 1.0e-10)
1458 std::ostringstream msg;
1459 msg <<
"**********" << std::endl;
1460 msg <<
": Error. Case not handled in modelCalculations_()";
1461 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
1523 Xyce::dout() <<
"[LTRA-DBG-DEV] LTRAload: Warning: timestep larger than delay of line" << std::endl;
1535 Xyce::dout() <<
"[LTRA-DBG-DEV] LTRAload: mistake: cannot find delayed timepoint" << std::endl;
1537 std::ostringstream msg;
1538 msg <<
"************" << std::endl;
1539 msg <<
": Error. Delayed time point not found.";
1540 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
1646 if( (t2-t1)==0 || (t3-t2) == 0 || (t1 - t3) ==0)
return(1);
1648 f1 = (t - t2) * (t - t3) ;
1649 f2 = (t - t1) * (t - t3) ;
1650 f3 = (t - t1) * (t - t2) ;
1702 if (t1 == t2)
return(1);
1718 temp = (t-t1)/(t2-t1);
1740 double lovalue,
double hivalue,
1741 double t1,
double t2)
1746 if (width == 0.0)
return(0.0);
1747 m = (hivalue - lovalue)/width;
1749 return( (hilimit-lolimit)*lovalue + 0.5*m*((hilimit-t1)*(hilimit-t1)
1750 - (lolimit - t1)*(lolimit - t1)));
1769 double otherlolimit,
double lovalue,
1770 double hivalue,
double t1,
double t2)
1772 double width, m, dummy;
1773 double temp1, temp2, temp3;
1776 if (width == 0.0)
return(0.0);
1777 m = (hivalue - lovalue)/width;
1779 temp1 = hilimit - t1;
1780 temp2 = lolimit - t1;
1781 temp3 = otherlolimit - t1;
1782 dummy = lovalue*((hilimit - otherlolimit)*(hilimit - otherlolimit) -
1783 (lolimit - otherlolimit)*(lolimit - otherlolimit));
1784 dummy += m*((temp1*temp1*temp1 - temp2*temp2*temp2)/3.0 -
1785 temp3*temp3*(hilimit - lolimit));
1806 double secondlolimit,
double thirdlolimit,
1807 double lovalue,
double hivalue,
double t1,
double t2)
1809 double width, m, dummy;
1810 double temp1, temp2, temp3, temp4;
1811 double temp5, temp6, temp7, temp8, temp9, temp10;
1815 if (width == 0.0)
return(0.0);
1816 m = (hivalue - lovalue)/width;
1818 temp1 = hilimit - t1;
1819 temp2 = lolimit - t1;
1820 temp3 = secondlolimit - t1;
1821 temp4 = thirdlolimit - t1;
1822 temp5 = hilimit - thirdlolimit;
1823 temp6 = lolimit - thirdlolimit;
1824 temp7 = secondlolimit - thirdlolimit;
1825 temp8 = hilimit - lolimit;
1826 temp9 = hilimit - secondlolimit;
1827 temp10 = lolimit - secondlolimit;
1828 dummy = lovalue*((temp5*temp5*temp5 - temp6*temp6*temp6)/3 -
1830 dummy += m*(((temp1*temp1*temp1*temp1 - temp2*temp2*temp2*temp2)*0.25 -
1831 temp3*temp3*temp3*temp8)/3 - temp4*temp4*0.5*(temp9*temp9 -
1850 if ((ax=fabs(x)) < 3.75)
1854 ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492
1855 +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2)))));
1860 ans=(exp(ax)/sqrt(ax))*
1861 (0.39894228+y*(0.1328592e-1+y*(0.225319e-2+
1862 y*(-0.157565e-2+y*(0.916281e-2+
1863 y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1
1864 +y*0.392377e-2))))))));
1882 if ((ax=fabs(x)) < 3.75)
1886 ans=ax*(0.5+y*(0.87890594+y*(0.51498869+y*(0.15084934
1887 +y*(0.2658733e-1+y*(0.301532e-2+y*0.32411e-3))))));
1892 ans=0.2282967e-1+y*(-0.2895312e-1+y*(0.1787654e-1
1894 ans=0.39894228+y*(-0.3988024e-1+y*(-0.362018e-2
1895 +y*(0.163801e-2+y*(-0.1031555e-1+y*ans))));
1896 ans *= (exp(ax)/sqrt(ax));
1898 return(x < 0.0 ? -ans : ans);
1914 if ((ax=fabs(x)) < 3.75) {
1917 ans=0.5+y*(0.87890594+y*(0.51498869+y*(0.15084934
1918 +y*(0.2658733e-1+y*(0.301532e-2+y*0.32411e-3)))));
1923 ans=0.2282967e-1+y*(-0.2895312e-1+y*(0.1787654e-1
1925 ans=0.39894228+y*(-0.3988024e-1+y*(-0.362018e-2
1926 +y*(0.163801e-2+y*(-0.1031555e-1+y*ans))));
1927 ans *= (exp(ax)/(ax*sqrt(ax)));
1942 double besselarg, exparg, returnval;
1949 if (alpha == 0.0)
return(0.0);
1951 exparg = - beta * time;
1952 besselarg = alpha*time;
1954 returnval = (
bessI1_(besselarg)-
bessI0_(besselarg))* alpha * exp(exparg);
1968 double besselarg, exparg, returnval;
1976 if (alpha == 0.0)
return(0.0);
1977 if (time < T)
return(0.0);
1980 besselarg = alpha*sqrt(time*time - T*T);
1984 exparg = -beta*time;
1986 returnval = alpha*alpha*T*exp(exparg)*
bessI1xOverX_(besselarg);
2000 double exparg,besselarg,returnval;
2008 if (alpha == 0.0)
return(0.0);
2009 if (time < T)
return(0.0);
2011 exparg = - beta*time;
2013 besselarg = alpha*sqrt(time*time - T*T);
2019 returnval *= alpha*exp(exparg);
2036 double arg, returnval;
2042 if (beta == 0.0)
return(time);
2044 if (arg == 0.0)
return(0.0);
2046 returnval = (
bessI1_(arg)+
bessI0_(arg))* time * exp(-arg) - time;
2063 double exparg, besselarg;
2066 if (time <= T)
return(0.0);
2067 if (beta == 0.0)
return(0.0);
2068 exparg = -beta*time;
2069 besselarg = beta*sqrt(time*time-T*T);
2070 returnval = exp(exparg)*
bessI0_(besselarg) - exp(-beta*T);
2084 return(sqrt(4*cbyr*time/
M_PI));
2100 temp = rclsqr/(4*time);
2112 return((time + rclsqr*0.5)*erfc_res - sqrt(time*rclsqr/
M_PI)*exp(- temp));
2133 temp = rclsqr/(4*time);
2138 temp = 2*sqrt(time/
M_PI)*exp(-temp) - sqrt(rclsqr)*erfc_res;
2139 return(sqrt(cbyr)*temp);
2160 double& h1dashfirstcoeff,
2161 double& h2firstcoeff,
2162 double& h3dashfirstcoeff,
2163 std::vector<double>& h1dashcoeffs,
2164 std::vector<double>& h2coeffs,
2165 std::vector<double>& h3dashcoeffs,
2166 size_t listsize,
double cbyr,
double rclsqr,
double curtime,
2167 const std::vector<double>& timelist,
int timeindex,
double reltol)
2169 double delta1, delta2;
2170 double h1dummy1, h1dummy2;
2171 double h2dummy1, h2dummy2;
2172 double h3dummy1, h3dummy2;
2173 double lolimit1,lolimit2, hilimit1, hilimit2;
2174 double h1lovalue1,h1lovalue2,h1hivalue1,h1hivalue2;
2175 double h2lovalue1,h2lovalue2,h2hivalue1,h2hivalue2;
2176 double h3lovalue1,h3lovalue2,h3hivalue1,h3hivalue2;
2177 double temp, temp2, temp3, temp4, temp5;
2178 double h1relval, h2relval, h3relval;
2179 int doh1=1, doh2=1, doh3=1;
2186 if (listsize < timeindex) {
2187 Xyce::dout() <<
"[LTRA-DBG-DEV]: LTRAcoeffSetup: not enough space in coefflist" << std::endl;
2191 auxindex = timeindex;
2195 delta1 = curtime - timelist[auxindex];
2201 sqrt(4*cbyr*hilimit1/
M_PI);
2202 h1dummy1 = h1hivalue1/delta1;
2203 h1dashfirstcoeff = h1dummy1;
2204 h1relval = fabs(h1dummy1*reltol);
2206 temp = rclsqr/(4*hilimit1);
2211 temp4 = sqrt(rclsqr);
2216 (hilimit1 != 0.0? (hilimit1 + rclsqr*0.5)*temp2 - sqrt(hilimit1*rclsqr/
M_PI)*temp3 : 0.0);
2219 h2dummy1 = h2hivalue1/delta1;
2220 h2firstcoeff = h2dummy1;
2221 h2relval = fabs(h2dummy1*reltol);
2225 (hilimit1 != 0.0? temp = 2*sqrt(hilimit1/
M_PI)*temp3 - temp4*temp2, (temp5*temp): 0.0);
2228 h3dummy1 = h3hivalue1/delta1;
2229 h3dashfirstcoeff = h3dummy1;
2230 h3relval = fabs(h3dummy1*reltol);
2234 for (i=auxindex; i>0; i--)
2237 lolimit2 = lolimit1;
2238 hilimit2 = hilimit1;
2240 delta1 = timelist[i] - timelist[i - 1];
2241 lolimit1 = hilimit2;
2242 hilimit1 = curtime - timelist[i - 1];
2246 h1lovalue2 = h1lovalue1;
2247 h1hivalue2 = h1hivalue1;
2248 h1dummy2 = h1dummy1;
2250 h1lovalue1 = h1hivalue2;
2252 sqrt(4*cbyr*hilimit1/
M_PI);
2253 h1dummy1 = (h1hivalue1 - h1lovalue1)/delta1;
2254 h1dashcoeffs[i] = h1dummy1 - h1dummy2;
2255 if (fabs(h1dashcoeffs[i]) < h1relval) doh1=0;
2259 h1dashcoeffs[i] = 0.0;
2263 temp = rclsqr/(4*hilimit1);
2271 h2lovalue2 = h2lovalue1;
2272 h2hivalue2 = h2hivalue1;
2273 h2dummy2 = h2dummy1;
2275 h2lovalue1 = h2hivalue2;
2277 (hilimit1 != 0.0? (hilimit1 + rclsqr*0.5)*temp2 - sqrt(hilimit1*rclsqr/
M_PI)*temp3 : 0.0);
2278 h2dummy1 = (h2hivalue1 - h2lovalue1)/delta1;
2279 h2coeffs[i] = h2dummy1 - h2dummy2;
2280 if (fabs(h2coeffs[i]) < h2relval) doh2=0;
2289 h3lovalue2 = h3lovalue1;
2290 h3hivalue2 = h3hivalue1;
2291 h3dummy2 = h3dummy1;
2293 h3lovalue1 = h3hivalue2;
2295 (hilimit1 != 0.0? temp = 2*sqrt(hilimit1/
M_PI)*temp3 - temp4*temp2, (temp5*temp): 0.0);
2296 h3dummy1 = (h3hivalue1 - h3lovalue1)/delta1;
2297 h3dashcoeffs[i] = h3dummy1 - h3dummy2;
2298 if (fabs(h3dashcoeffs[i]) < h3relval) doh3=0;
2302 h3dashcoeffs[i] = 0.0;
2316 double& h1dashfirstcoeff,
2317 double& h2firstcoeff,
2318 double& h3dashfirstcoeff,
2319 std::vector<double>& h1dashcoeffs,
2320 std::vector<double>& h2coeffs,
2321 std::vector<double>& h3dashcoeffs,
2323 double T,
double alpha,
double beta,
double curtime,
2324 const std::vector<double>& timelist,
int timeindex,
double reltol,
int* auxindexptr)
2327 double lolimit1,lolimit2,hilimit1,hilimit2;
2328 double delta1, delta2;
2330 double h1dummy1, h1dummy2;
2331 double h1lovalue1,h1lovalue2,h1hivalue1,h1hivalue2;
2333 double h2dummy1, h2dummy2;
2334 double h2lovalue1,h2lovalue2,h2hivalue1,h2hivalue2;
2336 double h3dummy1, h3dummy2;
2337 double h3lovalue1,h3lovalue2,h3hivalue1,h3hivalue2;
2339 double exparg, besselarg, expterm, bessi1overxterm, bessi0term;
2340 double expbetaTterm, alphasqTterm;
2341 double h1relval, h2relval, h3relval;
2342 int doh1=1, doh2=1, doh3=1;
2350 if (listsize < timeindex) {
2351 Xyce::dout() <<
"[LTRA-DBG-DEV]: LTRArlcCoeffsSetup_: not enough space in coefflist" << std::endl;
2363 auxindex = timeindex;
2366 if (curtime - T <= 0.0) {
2370 for (i = timeindex; i>= 0; i--) {
2371 if (curtime - timelist[i] == T) {
2375 if (curtime - timelist[i] > T)
break;
2380 if ((i < 0) || ((i==0) && (exact==1)))
2381 Xyce::dout() <<
"[LTRA-DBG-DEV]: LTRAcoeffSetup: i <= 0: some mistake!" << std::endl;
2396 hilimit1 = curtime - timelist[auxindex];
2397 delta1 = hilimit1 - lolimit1;
2400 besselarg = (hilimit1 > T) ? alpha*sqrt(hilimit1*hilimit1-T*T):0.0;
2401 exparg = -beta*hilimit1;
2402 expterm = exp(exparg);
2404 alphasqTterm = alpha*alpha*T;
2406 ((alpha == 0.0) || (hilimit1 < T)) ? 0.0: alphasqTterm*expterm*bessi1overxterm;
2409 h2hivalue1,lolimit1,hilimit1)/delta1;
2410 h2firstcoeff = h2dummy1;
2411 h2relval = fabs(reltol*h2dummy1);
2414 bessi0term =
bessI0_(besselarg);
2415 expbetaTterm = exp(-beta*T);
2417 ((hilimit1 <= T) || (beta == 0.0)) ? 0.0: expterm* bessi0term-expbetaTterm;
2418 h3dummy1 =
intlinfunc_(lolimit1,hilimit1,h3lovalue1,
2419 h3hivalue1,lolimit1,hilimit1)/delta1;
2420 h3dashfirstcoeff = h3dummy1;
2421 h3relval = fabs(h3dummy1*reltol);
2425 h2firstcoeff = h3dashfirstcoeff = 0.0;
2429 hilimit1 = curtime - timelist[timeindex];
2430 delta1 = hilimit1 - lolimit1;
2431 exparg = -beta*hilimit1;
2432 expterm = exp(exparg);
2436 (beta == 0.0) ? hilimit1 : ((hilimit1 == 0.0) ? 0.0 :
2437 (
bessI1_(-exparg)+
bessI0_(-exparg))* hilimit1 * expterm - hilimit1);
2438 h1dummy1 = h1hivalue1/delta1;
2439 h1dashfirstcoeff = h1dummy1;
2440 h1relval = fabs(h1dummy1*reltol);
2445 for (i=timeindex; i>0; i--)
2447 if (doh1 || doh2 || doh3)
2449 lolimit2 = lolimit1;
2450 hilimit2 = hilimit1;
2453 lolimit1 = hilimit2;
2454 hilimit1 = curtime - timelist[i - 1];
2455 delta1 = timelist[i] - timelist[i - 1];
2457 exparg = -beta*hilimit1;
2458 expterm = exp(exparg);
2463 h1lovalue2 = h1lovalue1;
2464 h1hivalue2 = h1hivalue1;
2465 h1dummy2 = h1dummy1;
2467 h1lovalue1 = h1hivalue2;
2469 (beta == 0.0) ? hilimit1 : ((hilimit1 == 0.0) ? 0.0 :
2470 (
bessI1_(-exparg)+
bessI0_(-exparg))* hilimit1 * expterm - hilimit1);
2471 h1dummy1 = (h1hivalue1 - h1lovalue1)/delta1;
2473 h1dashcoeffs[i] = h1dummy1 - h1dummy2;
2474 if (fabs(h1dashcoeffs[i]) <= h1relval) doh1 = 0;
2478 h1dashcoeffs[i] = 0.0;
2490 besselarg = (hilimit1 > T) ? alpha*sqrt(hilimit1*hilimit1-T*T):0.0;
2495 h2lovalue2 = h2lovalue1;
2496 h2hivalue2 = h2hivalue1;
2497 h2dummy2 = h2dummy1;
2499 h2lovalue1 = h2hivalue2;
2502 ((alpha == 0.0) || (hilimit1 < T)) ? 0.0: alphasqTterm*expterm*bessi1overxterm;
2504 h2lovalue1,h2hivalue1,lolimit1,hilimit1)/delta1;
2506 h2coeffs[i] = h2dummy1 - h2dummy2 +
intlinfunc_(lolimit2,hilimit2,
2507 h2lovalue2,h2hivalue2,lolimit2,hilimit2);
2508 if (fabs(h2coeffs[i]) <= h2relval) doh2 = 0;
2517 h3lovalue2 = h3lovalue1;
2518 h3hivalue2 = h3hivalue1;
2519 h3dummy2 = h3dummy1;
2521 h3lovalue1 = h3hivalue2;
2522 bessi0term =
bessI0_(besselarg);
2524 ((hilimit1 <= T) || (beta == 0.0)) ? 0.0: expterm* bessi0term-expbetaTterm;
2525 h3dummy1 =
intlinfunc_(lolimit1,hilimit1,h3lovalue1,h3hivalue1,lolimit1,hilimit1)/delta1;
2527 h3dashcoeffs[i] = h3dummy1 - h3dummy2;
2528 if (fabs(h3dashcoeffs[i]) <= h3relval) doh3 = 0;
2532 h3dashcoeffs[i] = 0.0;
2536 *auxindexptr = auxindex;
2559 double x2,
double y2,
2560 double x3,
double y3,
2561 double reltol,
double abstol)
2565 double TRarea, QUADarea1,QUADarea2,QUADarea3, area;
2579 QUADarea1 = (fabs(y2)+fabs(y1))*0.5*fabs(x2-x1);
2580 QUADarea2 = (fabs(y3)+fabs(y2))*0.5*fabs(x3-x2);
2581 QUADarea3 = (fabs(y3)+fabs(y1))*0.5*fabs(x3-x1);
2582 TRarea = fabs( QUADarea3 - QUADarea1 - QUADarea2);
2583 area = QUADarea1 + QUADarea2;
2584 if (area*reltol + abstol > TRarea)
2594 #define SECONDDERIV(i,a,b,c) \
2595 (oof = (i==getSolverState().ltraTimeIndex_?getSolverState().currTime_: \
2596 (getSolverState().ltraTimePoints_[i])), \
2597 (( c - b )/(oof-(getSolverState().ltraTimePoints_[i-1])) - \
2598 ( b - a )/((getSolverState().ltraTimePoints_[i-1])- \
2599 (getSolverState().ltraTimePoints_[i-2])))/(oof - \
2600 (getSolverState().ltraTimePoints_[i-2])))
2634 double h1dashTfirstCoeff;
2635 double h2TfirstCoeff;
2636 double h3dashTfirstCoeff;
2638 double hilimit1, lolimit1, hivalue1, lovalue1, f1i, g1i;
2639 double eq1LTE=0.0, eq2LTE=0.0;
2640 int auxindex,
tdover, i, exact;
2672 if ((i < 0) || ((i==0) && (exact==1)))
2673 Xyce::dout() <<
"[LTRA-DBG-DEV]: lteCalculate_: i <= 0: some mistake!" << std::endl;
2696 g1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,
2698 h1dashTfirstCoeff = 0.5 * f1i *
2705 lolimit1 = std::max(
td,lolimit1);
2710 f1i =
twiceintlinfunc_(lolimit1,hilimit1,lolimit1,lovalue1,hivalue1,lolimit1,
2713 hivalue1,lolimit1,hilimit1);
2719 f1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,lolimit1,
2722 hivalue1,lolimit1,hilimit1);
2739 eq1LTE +=
admit*fabs(dashdash * h1dashTfirstCoeff);
2746 instance.
v1[auxindex - 1],
2747 instance.
v1[auxindex],
2748 instance.
v1[auxindex + 1]) ;
2750 eq2LTE +=
admit*fabs(dashdash * h3dashTfirstCoeff);
2762 eq2LTE +=
admit*fabs(dashdash * h1dashTfirstCoeff);
2767 instance.
v2[auxindex - 1],
2768 instance.
v2[auxindex],
2769 instance.
v2[auxindex + 1]);
2771 eq1LTE +=
admit*fabs(dashdash * h3dashTfirstCoeff);
2782 instance.
i1[auxindex - 1],
2783 instance.
i1[auxindex],
2784 instance.
i1[auxindex + 1]) ;
2786 eq2LTE += fabs(dashdash * h2TfirstCoeff);
2796 instance.
i2[auxindex - 1],
2797 instance.
i2[auxindex],
2798 instance.
i2[auxindex + 1]) ;
2800 eq1LTE += fabs(dashdash * h2TfirstCoeff);
2816 g1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,lolimit1,hilimit1);
2824 g1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,lolimit1,hilimit1);
2832 hivalue1,lolimit1,hilimit1);
2846 eq1LTE += fabs(dashdash * h1dashTfirstCoeff);
2847 eq2LTE += fabs(dashdash * h3dashTfirstCoeff);
2859 eq2LTE += fabs(dashdash * h1dashTfirstCoeff);
2860 eq1LTE += fabs(dashdash * h3dashTfirstCoeff);
2872 eq2LTE += fabs(dashdash * h2TfirstCoeff);
2884 eq1LTE += fabs(dashdash * h2TfirstCoeff);
2896 Xyce::dout() <<
"[LTRA-DBG-DEV] " << instance.
getName() <<
": LTE/input for Eq1 at time "
2897 << curtime <<
" is: " << eq1LTE/instance.
input1 << std::endl;
2899 Xyce::dout() <<
"[LTRA-DBG-DEV] " << instance.
getName() <<
": LTE/input for Eq2 at time "
2900 << curtime <<
" is: " << eq2LTE/instance.
input1 << std::endl;
2903 return(fabs(eq1LTE) + fabs(eq2LTE));
2987 Model& m = (*it)->getModel();
3016 <<
"Modes supported: RC, RG, LC, RLC";
3022 UserError0(m) <<
"Nonzero G (except RG) transmission line not supported. "
3023 <<
"Modes supported: RC, RG, LC, RLC";
3028 if ((m.
resist == 0.0 ? 0 : 1) + (m.
conduct == 0.0 ? 0 : 1) +
3029 (m.
induct == 0.0 ? 0 : 1) + (m.
capac == 0.0 ? 0 : 1) <= 1)
3031 UserError0(m) <<
"Invalid specification. Specify at least "
3032 <<
"two of R, L, G, or C with nonzero values. "
3033 <<
"Modes supported: RC, RG, LC, RLC";
3046 UserWarning(*
this) <<
"Conflicting options STEPLIMIT and NOSTEPLIMIT given. Using STEPLIMIT";
3093 if (m.
alpha < 0.0) {
3094 UserError(m) <<
"Resistance and inductance must be greater than zero";
3101 double xbig, xsmall, xmid, y1big, y1small, y1mid;
3102 double y2big, y2small, y2mid;
3103 int done = 0, maxiter = 50, iters = 0;
3107 xmid = 0.5 * (xbig + xsmall);
3124 if ((done == 2) || (iters > maxiter))
3127 xmid = 0.5 * (xbig + xsmall);
3146 Report::DevelFatal().in(
"Master::initialize_vars_(void)") <<
"Unhandled LTRA special case encountered.";
3163 bool Master::loadDAEVectors (
double * solVec,
double * fVec,
double *qVec,
double * bVec,
double * storeLeadF,
double * storeLeadQ,
double * leadF,
double * leadQ,
double * junctionV)
3165 double max(0.0),min(0.0);
3166 double v1d(0.0), v2d(0.0), i1d(0.0), i2d(0.0);
3167 double dummy1(0.0), dummy2(0.0);
3168 std::ostringstream msg;
3181 dummy2 = exp(-dummy1);
3182 dummy1 = exp(dummy1);
3260 double qf1, qf2, qf3;
3263 qf1 = qf2 = qf3 = 0.0;
3278 if ((isaved != 0) &&
3281 v1d = di.
v1[isaved-1] * qf1
3282 + di.
v1[isaved] * qf2
3283 + di.
v1[isaved+1] * qf3;
3285 max = std::max(di.
v1[isaved-1], di.
v1[isaved]);
3286 max = std::max(max,di.
v1[isaved+1]);
3287 min = std::min(di.
v1[isaved-1], di.
v1[isaved]);
3288 min = std::min(min,di.
v1[isaved+1]);
3299 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated v1 is out of range after timepoint "
3301 Xyce::dout() <<
" values: "
3302 << di.
v1[isaved-1] <<
" "
3303 << di.
v1[isaved] <<
" "
3304 << di.
v1[isaved+1] <<
"; interpolated: "
3305 << v1d << std::endl;
3306 Xyce::dout() <<
" timepoints are: "
3312 v1d = di.
v1[isaved] * lf2 + di.
v1[isaved+1] * lf3;
3316 if ((isaved != 0) &&
3320 i1d = di.
i1[isaved-1] * qf1
3321 + di.
i1[isaved] * qf2
3322 + di.
i1[isaved+1] * qf3;
3324 max = std::max(di.
i1[isaved-1], di.
i1[isaved]);
3325 max = std::max(max,di.
i1[isaved+1]);
3326 min = std::min(di.
i1[isaved-1], di.
i1[isaved]);
3327 min = std::min(min,di.
i1[isaved+1]);
3333 ((i1d > max) || (i1d < min))))
3340 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated i1 is out of range after timepoint "
3342 Xyce::dout() <<
" values: "
3343 << di.
i1[isaved-1] <<
" "
3344 << di.
i1[isaved] <<
" "
3345 << di.
i1[isaved+1] <<
"; interpolated: "
3346 << i1d << std::endl;
3347 Xyce::dout() <<
" timepoints are: "
3353 i1d = di.
i1[isaved] * lf2 + di.
i1[isaved+1] * lf3;
3357 if ((isaved != 0) &&
3361 v2d = di.
v2[isaved-1] * qf1
3362 + di.
v2[isaved] * qf2
3363 + di.
v2[isaved+1] * qf3;
3365 max = std::max(di.
v2[isaved-1], di.
v2[isaved]);
3366 max = std::max(max,di.
v2[isaved+1]);
3367 min = std::min(di.
v2[isaved-1], di.
v2[isaved]);
3368 min = std::min(min,di.
v2[isaved+1]);
3376 ((v2d > max) || (v2d < min))))
3379 if ((isaved != 0) &&
3384 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated v2 is out of range after timepoint "
3386 Xyce::dout() <<
" values: "
3387 << di.
v2[isaved-1] <<
" "
3388 << di.
v2[isaved] <<
" "
3389 << di.
v2[isaved+1] <<
"; interpolated: "
3390 << v2d << std::endl;
3391 Xyce::dout() <<
" timepoints are: "
3397 v2d = di.
v2[isaved] * lf2
3403 if ((isaved != 0) &&
3407 i2d = di.
i2[isaved-1] * qf1
3408 + di.
i2[isaved] * qf2
3409 + di.
i2[isaved+1] * qf3;
3411 max = std::max(di.
i2[isaved-1], di.
i2[isaved]);
3412 max = std::max(max,di.
i2[isaved+1]); min = std::min(di.
i2[isaved-1], di.
i2[isaved]);
3413 min = std::min(min,di.
i2[isaved+1]);
3419 ((i2d > max) || (i2d < min))))
3425 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated i2 is out of range after timepoint "
3427 Xyce::dout() <<
" values: "
3428 << di.
i2[isaved-1] <<
" "
3429 << di.
i2[isaved] <<
" "
3430 << di.
i2[isaved+1] <<
"; interpolated: "
3431 << i2d << std::endl;
3432 Xyce::dout() <<
" timepoints are: "
3438 i2d = di.
i2[isaved] * lf2 + di.
i2[isaved+1] * lf3;
3463 dummy1 = dummy2 = 0.0;
3486 dummy1 = dummy2 = 0.0;
3518 dummy1 = dummy2 = 0.0;
3631 dummy1 = dummy2 = 0.0;
3698 double dummy1(0.0), dummy2(0.0);
3699 std::ostringstream msg;
3864 .registerDevice(
"o", 1)
3865 .registerModelType(
"ltra", 1);
const InstanceName & getName() const
bool modelCalculations_(int &isaved, double &qf1, double &qf2, double &qf3, double &lf2, double &lf3)
double rlcH3dashFunc_(double time, double T, double alpha, double beta)
virtual std::ostream & printOutInstances(std::ostream &os) const
double thriceintlinfunc_(double lolimit, double hilimit, double secondlolimit, double thirdlolimit, double lovalue, double hivalue, double t1, double t2)
bool updateIntermediateVars()
bool updateDependentParameters()
static void loadModelParameters(ParametricData< Model > &model_parameters)
void rlcCoeffsSetup_(double &h1dashfirstcoeff, double &h2firstcoeff, double &h3dashfirstcoeff, std::vector< double > &h1dashcoeffs, std::vector< double > &h2coeffs, std::vector< double > &h3dashcoeffs, size_t listsize, double T, double alpha, double beta, double curtime, const std::vector< double > &timelist, int timeindex, double reltol, int *auxindexptr)
bool getInstanceBreakPoints(std::vector< Util::BreakPoint > &breakPointTimes)
bool updateSecondaryState()
double rcH2TwiceIntFunc_(double time, double rclsqr)
const DeviceOptions & deviceOptions_
static std::vector< std::vector< int > > jacStamp
Descriptor & addPar(const char *parName, T default_value, T U::*varPtr)
Adds the parameter description to the parameter map.
int AIbr1EquNeg2NodeOffset
bool setInternalState(const DeviceState &state)
const std::vector< std::vector< int > > & jacobianStamp() const
std::vector< int > devConMap
int ANeg1EquNeg1NodeOffset
double reltol
relative current error tolerance.
DeviceState * getInternalState()
Pure virtual class to augment a linear system.
int AIbr2EquNeg2NodeOffset
void addInternalNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
int AIbr1EquPos1NodeOffset
const std::string & getEncodedName() const
Return the instance name encoded as: [s:]*xname [s:]*Ytype!name [s:]*Utype!name!count.
int ANeg1EquIbr1NodeOffset
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
int AIbr2EquIbr2NodeOffset
InstanceVector::const_iterator getInstanceEnd() const
Returns an iterator to the ending of the vector of all instances created for this device...
std::vector< double > h1dashCoeffs
int APos1EquPos1NodeOffset
#define SECONDDERIV(i, a, b, c)
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
size_t ltraTimeIndex_
LTRA, DeviceMgr::acceptStep()
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
double rcH3dashTwiceIntFunc_(double time, double cbyr, double rclsqr)
bool straightLineCheck_(double x1, double y1, double x2, double y2, double x3, double y3, double reltol, double abstol)
bool updatePrimaryState()
double rlcH3dashIntFunc_(double time, double T, double beta)
InstanceVector::const_iterator getInstanceBegin() const
Returns an iterator to the beginning of the vector of all instances created for this device...
std::vector< Param > params
Parameters from the line.
int AIbr2EquIbr1NodeOffset
#define LTRA_MOD_QUADINTERP
void setParams(const std::vector< Param > ¶ms)
const std::string & getName() const
double rcH1dashTwiceIntFunc_(double time, double cbyr)
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
double twiceintlinfunc_(double lolimit, double hilimit, double otherlolimit, double lovalue, double hivalue, double t1, double t2)
const DeviceOptions & getDeviceOptions() const
virtual bool loadDAEMatrices(Linear::Matrix &dFdx, Linear::Matrix &dQdx)
Populates the device's Jacobian object with these pointers.
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
int AIbr1EquIbr1NodeOffset
int ANeg2EquIbr2NodeOffset
#define LTRA_MOD_MIXEDINTERP
Linear::Matrix * dFdxMatrixPtr
const DeviceOptions & getDeviceOptions() const
Returns the device options given during device construction.
Instance(const Configuration &configuration, const InstanceBlock &instance_block, Model &model, const FactoryBlock &factory_block)
The Device class is an interface for device implementations.
double abstol
absolute current error tolerance.
int timeStepNumber_
Memristor, LTRA, TRA, testing if debug or jacobian for testing.
std::vector< double > data
double bessI1xOverX_(double x)
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
const SolverState & solverState_
double lteCalculate_(Instance &instance, double curtime)
Class Configuration contains device configuration data.
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
int AIbr2EquPos2NodeOffset
int quadInterp_(double t, double t1, double t2, double t3, double &c1, double &c2, double &c3)
int AIbr1EquPos2NodeOffset
const SolverState & getSolverState() const
int AIbr1EquNeg1NodeOffset
bool processInstanceParams()
processInstanceParams
int AIbr2EquPos1NodeOffset
void rcCoeffsSetup_(double &h1dashfirstcoeff, double &h2firstcoeff, double &h3dashfirstcoeff, std::vector< double > &h1dashcoeffs, std::vector< double > &h2coeffs, std::vector< double > &h3dashcoeffs, size_t listsize, double cbyr, double rclsqr, double curtime, const std::vector< double > &timelist, int timeindex, double reltol)
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
double rlcH1dashTwiceIntFunc_(double time, double beta)
#define LTRA_MOD_STEPLIMIT
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
int APos2EquPos2NodeOffset
std::vector< double > ltraTimePoints_
LTRA.
double SECONDDERIV_(int i, double a, double b, double c)
virtual bool loadDAEVectors(double *solVec, double *fVec, double *qVec, double *bVec, double *storeLeadF, double *storeLeadQ, double *leadF, double *leadQ, double *junctionV)
Populates the device's ExternData object with these pointers.
double gmin
minimum allowed conductance.
std::vector< double > h2Coeffs
double intlinfunc_(double lolimit, double hilimit, double lovalue, double hivalue, double t1, double t2)
int AIbr2EquNeg1NodeOffset
std::vector< double > h3dashCoeffs
const ExternData & extData
ModelBlock represents a .MODEL line from the netlist.
bool lteTimeStepControlGiven
double rlcH2Func_(double time, double T, double alpha, double beta)
Manages parameter binding for class C.
InstanceBlock represent a device instance line from the netlist.
double currTime_
DeviceEntity for expression time, breakpoints DeviceMgr for dependent parameters, breakpoints...
std::vector< Instance * > instanceContainer
#define LTRA_MOD_LININTERP
std::vector< Param > params
std::vector< size_t > dataSizeT
bool processParams()
processParams
void calculateMaxTimeStep_(void)
int APos2EquIbr2NodeOffset
#define LTRA_MOD_NOSTEPLIMIT
int linInterp_(double t, double t1, double t2, double &c1, double &c2)
double rlcH1dashFunc_(double time, double T, double alpha, double beta)
int APos1EquIbr1NodeOffset
virtual bool updateState(double *solVec, double *staVec, double *stoVec)
Updates the devices state information.
int ANeg2EquNeg2NodeOffset
const SolverState & getSolverState() const
Returns the solver state given during device construction.
void setModParams(const std::vector< Param > ¶ms)
double getMaxTimeStepSize()
double * nextSolVectorRawPtr
int AIbr1EquIbr2NodeOffset