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;
735 bool compact =
false;
810 #define CHECK(a,b,c) (std::max(std::max(a,b),c)-std::min(std::min(a,b),c) >= \
811 fabs(50.0*(getDeviceOptions().reltol/3.0*(a+b+c) + \
812 getDeviceOptions().abstol)))
814 bool tmp_test = (fabs(d1_ - d2_) >
model_.
reltol * std::max(fabs(d1_), fabs(d2_)) +
817 if (tmp_test || ((fabs(d3_ - d4_)
901 double d1_ = (i1_ - i2_) /
904 double d2_ = (i2_ - i3_) /
907 double d3_ = (i4_ - i5_) /
910 double d4_ = (i5_ - i6_) /
913 if ((fabs(d1_-d2_) >= model.
reltol * std::max(fabs(d1_), fabs(d2_)) + model.
abstol) ||
914 (fabs(d3_-d4_) >= model.
reltol * std::max(fabs(d3_), fabs(d4_)) + model.
abstol))
927 std::ostringstream msg;
928 msg <<
"**********" << std::endl;
929 msg <<
": Error. Case not handled in calculateMaxTimeStep_()";
930 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
973 if (current_lte >= tolerance) {
978 double y = current_lte;
985 if (deriv_delta <= 0.0)
986 Xyce::dout() <<
"LTRAtrunc: error: timestep is now less than zero" << std::endl;
988 double deriv = model.
lteCalculate_(*
this, x + deriv_delta) - y;
990 deriv /= deriv_delta;
991 double change = (tolerance - y) / deriv;
997 if (fabs(change) <= fabs(deriv_delta))
1001 if (iterations >= maxiter)
1020 std::ostringstream msg;
1021 msg <<
"**********" << std::endl;
1022 msg <<
": Error. Case not handled in calculateMaxTimeStep_() [2]";
1023 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
1053 int origSize = myState->
data.size();
1064 Xyce::dout() <<
"LTRA::getInternalState: input1="<<
input1<<
" input2="<<
input2<<std::endl
1065 <<
"LTRA::getInternalState: initVolt11="<<
initVolt1<<
" initVolt2="<<
initVolt2<<std::endl
1066 <<
"LTRA::getInternalState: initCur11="<<
initCur1<<
" initCur2="<<
initCur2<<std::endl;
1073 myState->
data[j+1]=
v2[i];
1074 myState->
data[j+2]=
i1[i];
1075 myState->
data[j+3]=
i2[i];
1077 Xyce::dout() <<
"LTRA::getInternalState: v1["<<i<<
"]="<<
v1[i]
1078 <<
" v2["<<i<<
"]="<<
v2[i]
1079 <<
" i1["<<i<<
"]="<<
i1[i]
1080 <<
" i2["<<i<<
"]="<<
i2[i]
1089 origSize = myState->
data.size();
1098 Xyce::dout() <<
"LTRA::getInternalState: h1dashCoeffs["<<i<<
"] =" <<
model_.
h1dashCoeffs[i]
1122 if (
getName().getEncodedName() != state.
ID)
1124 DevelFatal(*this).in(
"LTRA::Instance::setInternalState") <<
"ID(" << state.
ID <<
") from restart does not match my name (" <<
getName() <<
")";
1130 v1.clear();
v2.clear();
i1.clear();
i2.clear();
1141 Xyce::dout() <<
"LTRA::setInternalState: input1="<<
input1<<
" input2="<<
input2<<std::endl
1142 <<
"LTRA::setInternalState: initVolt11="<<
initVolt1<<
" initVolt2="<<
initVolt2<<std::endl
1143 <<
"LTRA::setInternalState: initCur11="<<
initCur1<<
" initCur2="<<
initCur2<<std::endl;
1153 Xyce::dout() <<
"LTRA::setInternalState: v1["<<i<<
"]="<<
v1[i]
1154 <<
" v2["<<i<<
"]="<<
v2[i]
1155 <<
" i1["<<i<<
"]="<<
i1[i]
1156 <<
" i2["<<i<<
"]="<<
i2[i]
1173 j=(listSize*4+6)+i*3;
1178 Xyce::dout() <<
"LTRA::setInternalState: h1dashCoeffs["<<i<<
"] =" <<
model_.
h1dashCoeffs[i]
1213 std::vector<Instance*>::iterator iter;
1217 for (iter=first; iter!=last; ++iter)
1219 (*iter)->processParams();
1237 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
1239 h1dashFirstVal(0.0),
1241 h3dashFirstVal(0.0),
1242 h1dashFirstCoeff(0.0),
1244 h3dashFirstCoeff(0.0),
1266 truncDontCut(false),
1270 conductGiven(false),
1275 noStepLimitGiven(false),
1276 stepLimitGiven(false),
1277 linInterpGiven(false),
1278 quadInterpGiven(false),
1279 mixedInterpGiven(false),
1280 stLineReltolGiven(false),
1281 stLineAbstolGiven(false),
1282 truncNRGiven(false),
1283 truncDontCutGiven(false),
1304 maxSafeStep(1.0e99),
1305 maxTimeStep(1.0e99),
1306 lteTimeStepControl(false),
1311 restartStoredFlag(false)
1345 std::vector<Instance*>::iterator iter;
1349 for (iter=first; iter!=last; ++iter)
1365 std::vector<Instance*>::const_iterator iter;
1371 os <<
" name model name Parameters" << std::endl;
1372 for (i=0, iter=first; iter!=last; ++iter, ++i)
1374 os <<
" " << i <<
": " << (*iter)->getName() <<
" ";
1402 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1416 double& qf1,
double& qf2,
double& qf3,
1417 double& lf2,
double& lf3)
1419 double t1(0.0),t2(0.0),t3(0.0);
1420 double v1d(0.0), v2d(0.0), i1d(0.0), i2d(0.0);
1421 double dummy1(0.0), dummy2(0.0);
1432 dummy2 = exp(-dummy1);
1433 dummy1 = exp(dummy1);
1436 if (conduct <= 1.0e-10)
1462 std::ostringstream msg;
1463 msg <<
"**********" << std::endl;
1464 msg <<
": Error. Case not handled in modelCalculations_()";
1465 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
1527 Xyce::dout() <<
"[LTRA-DBG-DEV] LTRAload: Warning: timestep larger than delay of line" << std::endl;
1539 Xyce::dout() <<
"[LTRA-DBG-DEV] LTRAload: mistake: cannot find delayed timepoint" << std::endl;
1541 std::ostringstream msg;
1542 msg <<
"************" << std::endl;
1543 msg <<
": Error. Delayed time point not found.";
1544 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg.str());
1650 if( (t2-t1)==0 || (t3-t2) == 0 || (t1 - t3) ==0)
return(1);
1652 f1 = (t - t2) * (t - t3) ;
1653 f2 = (t - t1) * (t - t3) ;
1654 f3 = (t - t1) * (t - t2) ;
1706 if (t1 == t2)
return(1);
1722 temp = (t-t1)/(t2-t1);
1744 double lovalue,
double hivalue,
1745 double t1,
double t2)
1750 if (width == 0.0)
return(0.0);
1751 m = (hivalue - lovalue)/width;
1753 return( (hilimit-lolimit)*lovalue + 0.5*m*((hilimit-t1)*(hilimit-t1)
1754 - (lolimit - t1)*(lolimit - t1)));
1773 double otherlolimit,
double lovalue,
1774 double hivalue,
double t1,
double t2)
1776 double width, m, dummy;
1777 double temp1, temp2, temp3;
1780 if (width == 0.0)
return(0.0);
1781 m = (hivalue - lovalue)/width;
1783 temp1 = hilimit - t1;
1784 temp2 = lolimit - t1;
1785 temp3 = otherlolimit - t1;
1786 dummy = lovalue*((hilimit - otherlolimit)*(hilimit - otherlolimit) -
1787 (lolimit - otherlolimit)*(lolimit - otherlolimit));
1788 dummy += m*((temp1*temp1*temp1 - temp2*temp2*temp2)/3.0 -
1789 temp3*temp3*(hilimit - lolimit));
1810 double secondlolimit,
double thirdlolimit,
1811 double lovalue,
double hivalue,
double t1,
double t2)
1813 double width, m, dummy;
1814 double temp1, temp2, temp3, temp4;
1815 double temp5, temp6, temp7, temp8, temp9, temp10;
1819 if (width == 0.0)
return(0.0);
1820 m = (hivalue - lovalue)/width;
1822 temp1 = hilimit - t1;
1823 temp2 = lolimit - t1;
1824 temp3 = secondlolimit - t1;
1825 temp4 = thirdlolimit - t1;
1826 temp5 = hilimit - thirdlolimit;
1827 temp6 = lolimit - thirdlolimit;
1828 temp7 = secondlolimit - thirdlolimit;
1829 temp8 = hilimit - lolimit;
1830 temp9 = hilimit - secondlolimit;
1831 temp10 = lolimit - secondlolimit;
1832 dummy = lovalue*((temp5*temp5*temp5 - temp6*temp6*temp6)/3 -
1834 dummy += m*(((temp1*temp1*temp1*temp1 - temp2*temp2*temp2*temp2)*0.25 -
1835 temp3*temp3*temp3*temp8)/3 - temp4*temp4*0.5*(temp9*temp9 -
1854 if ((ax=fabs(x)) < 3.75)
1858 ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492
1859 +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2)))));
1864 ans=(exp(ax)/sqrt(ax))*
1865 (0.39894228+y*(0.1328592e-1+y*(0.225319e-2+
1866 y*(-0.157565e-2+y*(0.916281e-2+
1867 y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1
1868 +y*0.392377e-2))))))));
1886 if ((ax=fabs(x)) < 3.75)
1890 ans=ax*(0.5+y*(0.87890594+y*(0.51498869+y*(0.15084934
1891 +y*(0.2658733e-1+y*(0.301532e-2+y*0.32411e-3))))));
1896 ans=0.2282967e-1+y*(-0.2895312e-1+y*(0.1787654e-1
1898 ans=0.39894228+y*(-0.3988024e-1+y*(-0.362018e-2
1899 +y*(0.163801e-2+y*(-0.1031555e-1+y*ans))));
1900 ans *= (exp(ax)/sqrt(ax));
1902 return(x < 0.0 ? -ans : ans);
1918 if ((ax=fabs(x)) < 3.75) {
1921 ans=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)/(ax*sqrt(ax)));
1946 double besselarg, exparg, returnval;
1953 if (alpha == 0.0)
return(0.0);
1955 exparg = - beta * time;
1956 besselarg = alpha*time;
1958 returnval = (
bessI1_(besselarg)-
bessI0_(besselarg))* alpha * exp(exparg);
1972 double besselarg, exparg, returnval;
1980 if (alpha == 0.0)
return(0.0);
1981 if (time < T)
return(0.0);
1984 besselarg = alpha*sqrt(time*time - T*T);
1988 exparg = -beta*time;
1990 returnval = alpha*alpha*T*exp(exparg)*
bessI1xOverX_(besselarg);
2004 double exparg,besselarg,returnval;
2012 if (alpha == 0.0)
return(0.0);
2013 if (time < T)
return(0.0);
2015 exparg = - beta*time;
2017 besselarg = alpha*sqrt(time*time - T*T);
2023 returnval *= alpha*exp(exparg);
2040 double arg, returnval;
2046 if (beta == 0.0)
return(time);
2048 if (arg == 0.0)
return(0.0);
2050 returnval = (
bessI1_(arg)+
bessI0_(arg))* time * exp(-arg) - time;
2067 double exparg, besselarg;
2070 if (time <= T)
return(0.0);
2071 if (beta == 0.0)
return(0.0);
2072 exparg = -beta*time;
2073 besselarg = beta*sqrt(time*time-T*T);
2074 returnval = exp(exparg)*
bessI0_(besselarg) - exp(-beta*T);
2088 return(sqrt(4*cbyr*time/
M_PI));
2104 temp = rclsqr/(4*time);
2116 return((time + rclsqr*0.5)*erfc_res - sqrt(time*rclsqr/
M_PI)*exp(- temp));
2137 temp = rclsqr/(4*time);
2142 temp = 2*sqrt(time/
M_PI)*exp(-temp) - sqrt(rclsqr)*erfc_res;
2143 return(sqrt(cbyr)*temp);
2164 double& h1dashfirstcoeff,
2165 double& h2firstcoeff,
2166 double& h3dashfirstcoeff,
2167 std::vector<double>& h1dashcoeffs,
2168 std::vector<double>& h2coeffs,
2169 std::vector<double>& h3dashcoeffs,
2170 size_t listsize,
double cbyr,
double rclsqr,
double curtime,
2171 const std::vector<double>& timelist,
int timeindex,
double reltol)
2173 double delta1, delta2;
2174 double h1dummy1, h1dummy2;
2175 double h2dummy1, h2dummy2;
2176 double h3dummy1, h3dummy2;
2177 double lolimit1,lolimit2, hilimit1, hilimit2;
2178 double h1lovalue1,h1lovalue2,h1hivalue1,h1hivalue2;
2179 double h2lovalue1,h2lovalue2,h2hivalue1,h2hivalue2;
2180 double h3lovalue1,h3lovalue2,h3hivalue1,h3hivalue2;
2181 double temp, temp2, temp3, temp4, temp5;
2182 double h1relval, h2relval, h3relval;
2183 int doh1=1, doh2=1, doh3=1;
2190 if (listsize < timeindex) {
2191 Xyce::dout() <<
"[LTRA-DBG-DEV]: LTRAcoeffSetup: not enough space in coefflist" << std::endl;
2195 auxindex = timeindex;
2199 delta1 = curtime - timelist[auxindex];
2205 sqrt(4*cbyr*hilimit1/
M_PI);
2206 h1dummy1 = h1hivalue1/delta1;
2207 h1dashfirstcoeff = h1dummy1;
2208 h1relval = fabs(h1dummy1*reltol);
2210 temp = rclsqr/(4*hilimit1);
2215 temp4 = sqrt(rclsqr);
2220 (hilimit1 != 0.0? (hilimit1 + rclsqr*0.5)*temp2 - sqrt(hilimit1*rclsqr/
M_PI)*temp3 : 0.0);
2223 h2dummy1 = h2hivalue1/delta1;
2224 h2firstcoeff = h2dummy1;
2225 h2relval = fabs(h2dummy1*reltol);
2229 (hilimit1 != 0.0? temp = 2*sqrt(hilimit1/
M_PI)*temp3 - temp4*temp2, (temp5*temp): 0.0);
2232 h3dummy1 = h3hivalue1/delta1;
2233 h3dashfirstcoeff = h3dummy1;
2234 h3relval = fabs(h3dummy1*reltol);
2238 for (i=auxindex; i>0; i--)
2241 lolimit2 = lolimit1;
2242 hilimit2 = hilimit1;
2244 delta1 = timelist[i] - timelist[i - 1];
2245 lolimit1 = hilimit2;
2246 hilimit1 = curtime - timelist[i - 1];
2250 h1lovalue2 = h1lovalue1;
2251 h1hivalue2 = h1hivalue1;
2252 h1dummy2 = h1dummy1;
2254 h1lovalue1 = h1hivalue2;
2256 sqrt(4*cbyr*hilimit1/
M_PI);
2257 h1dummy1 = (h1hivalue1 - h1lovalue1)/delta1;
2258 h1dashcoeffs[i] = h1dummy1 - h1dummy2;
2259 if (fabs(h1dashcoeffs[i]) < h1relval) doh1=0;
2263 h1dashcoeffs[i] = 0.0;
2267 temp = rclsqr/(4*hilimit1);
2275 h2lovalue2 = h2lovalue1;
2276 h2hivalue2 = h2hivalue1;
2277 h2dummy2 = h2dummy1;
2279 h2lovalue1 = h2hivalue2;
2281 (hilimit1 != 0.0? (hilimit1 + rclsqr*0.5)*temp2 - sqrt(hilimit1*rclsqr/
M_PI)*temp3 : 0.0);
2282 h2dummy1 = (h2hivalue1 - h2lovalue1)/delta1;
2283 h2coeffs[i] = h2dummy1 - h2dummy2;
2284 if (fabs(h2coeffs[i]) < h2relval) doh2=0;
2293 h3lovalue2 = h3lovalue1;
2294 h3hivalue2 = h3hivalue1;
2295 h3dummy2 = h3dummy1;
2297 h3lovalue1 = h3hivalue2;
2299 (hilimit1 != 0.0? temp = 2*sqrt(hilimit1/
M_PI)*temp3 - temp4*temp2, (temp5*temp): 0.0);
2300 h3dummy1 = (h3hivalue1 - h3lovalue1)/delta1;
2301 h3dashcoeffs[i] = h3dummy1 - h3dummy2;
2302 if (fabs(h3dashcoeffs[i]) < h3relval) doh3=0;
2306 h3dashcoeffs[i] = 0.0;
2320 double& h1dashfirstcoeff,
2321 double& h2firstcoeff,
2322 double& h3dashfirstcoeff,
2323 std::vector<double>& h1dashcoeffs,
2324 std::vector<double>& h2coeffs,
2325 std::vector<double>& h3dashcoeffs,
2327 double T,
double alpha,
double beta,
double curtime,
2328 const std::vector<double>& timelist,
int timeindex,
double reltol,
int* auxindexptr)
2331 double lolimit1,lolimit2,hilimit1,hilimit2;
2332 double delta1, delta2;
2334 double h1dummy1, h1dummy2;
2335 double h1lovalue1,h1lovalue2,h1hivalue1,h1hivalue2;
2337 double h2dummy1, h2dummy2;
2338 double h2lovalue1,h2lovalue2,h2hivalue1,h2hivalue2;
2340 double h3dummy1, h3dummy2;
2341 double h3lovalue1,h3lovalue2,h3hivalue1,h3hivalue2;
2343 double exparg, besselarg, expterm, bessi1overxterm, bessi0term;
2344 double expbetaTterm, alphasqTterm;
2345 double h1relval, h2relval, h3relval;
2346 int doh1=1, doh2=1, doh3=1;
2354 if (listsize < timeindex) {
2355 Xyce::dout() <<
"[LTRA-DBG-DEV]: LTRArlcCoeffsSetup_: not enough space in coefflist" << std::endl;
2367 auxindex = timeindex;
2370 if (curtime - T <= 0.0) {
2374 for (i = timeindex; i>= 0; i--) {
2375 if (curtime - timelist[i] == T) {
2379 if (curtime - timelist[i] > T)
break;
2384 if ((i < 0) || ((i==0) && (exact==1)))
2385 Xyce::dout() <<
"[LTRA-DBG-DEV]: LTRAcoeffSetup: i <= 0: some mistake!" << std::endl;
2400 hilimit1 = curtime - timelist[auxindex];
2401 delta1 = hilimit1 - lolimit1;
2404 besselarg = (hilimit1 > T) ? alpha*sqrt(hilimit1*hilimit1-T*T):0.0;
2405 exparg = -beta*hilimit1;
2406 expterm = exp(exparg);
2408 alphasqTterm = alpha*alpha*T;
2410 ((alpha == 0.0) || (hilimit1 < T)) ? 0.0: alphasqTterm*expterm*bessi1overxterm;
2413 h2hivalue1,lolimit1,hilimit1)/delta1;
2414 h2firstcoeff = h2dummy1;
2415 h2relval = fabs(reltol*h2dummy1);
2418 bessi0term =
bessI0_(besselarg);
2419 expbetaTterm = exp(-beta*T);
2421 ((hilimit1 <= T) || (beta == 0.0)) ? 0.0: expterm* bessi0term-expbetaTterm;
2422 h3dummy1 =
intlinfunc_(lolimit1,hilimit1,h3lovalue1,
2423 h3hivalue1,lolimit1,hilimit1)/delta1;
2424 h3dashfirstcoeff = h3dummy1;
2425 h3relval = fabs(h3dummy1*reltol);
2429 h2firstcoeff = h3dashfirstcoeff = 0.0;
2433 hilimit1 = curtime - timelist[timeindex];
2434 delta1 = hilimit1 - lolimit1;
2435 exparg = -beta*hilimit1;
2436 expterm = exp(exparg);
2440 (beta == 0.0) ? hilimit1 : ((hilimit1 == 0.0) ? 0.0 :
2441 (
bessI1_(-exparg)+
bessI0_(-exparg))* hilimit1 * expterm - hilimit1);
2442 h1dummy1 = h1hivalue1/delta1;
2443 h1dashfirstcoeff = h1dummy1;
2444 h1relval = fabs(h1dummy1*reltol);
2449 for (i=timeindex; i>0; i--)
2451 if (doh1 || doh2 || doh3)
2453 lolimit2 = lolimit1;
2454 hilimit2 = hilimit1;
2457 lolimit1 = hilimit2;
2458 hilimit1 = curtime - timelist[i - 1];
2459 delta1 = timelist[i] - timelist[i - 1];
2461 exparg = -beta*hilimit1;
2462 expterm = exp(exparg);
2467 h1lovalue2 = h1lovalue1;
2468 h1hivalue2 = h1hivalue1;
2469 h1dummy2 = h1dummy1;
2471 h1lovalue1 = h1hivalue2;
2473 (beta == 0.0) ? hilimit1 : ((hilimit1 == 0.0) ? 0.0 :
2474 (
bessI1_(-exparg)+
bessI0_(-exparg))* hilimit1 * expterm - hilimit1);
2475 h1dummy1 = (h1hivalue1 - h1lovalue1)/delta1;
2477 h1dashcoeffs[i] = h1dummy1 - h1dummy2;
2478 if (fabs(h1dashcoeffs[i]) <= h1relval) doh1 = 0;
2482 h1dashcoeffs[i] = 0.0;
2494 besselarg = (hilimit1 > T) ? alpha*sqrt(hilimit1*hilimit1-T*T):0.0;
2499 h2lovalue2 = h2lovalue1;
2500 h2hivalue2 = h2hivalue1;
2501 h2dummy2 = h2dummy1;
2503 h2lovalue1 = h2hivalue2;
2506 ((alpha == 0.0) || (hilimit1 < T)) ? 0.0: alphasqTterm*expterm*bessi1overxterm;
2508 h2lovalue1,h2hivalue1,lolimit1,hilimit1)/delta1;
2510 h2coeffs[i] = h2dummy1 - h2dummy2 +
intlinfunc_(lolimit2,hilimit2,
2511 h2lovalue2,h2hivalue2,lolimit2,hilimit2);
2512 if (fabs(h2coeffs[i]) <= h2relval) doh2 = 0;
2521 h3lovalue2 = h3lovalue1;
2522 h3hivalue2 = h3hivalue1;
2523 h3dummy2 = h3dummy1;
2525 h3lovalue1 = h3hivalue2;
2526 bessi0term =
bessI0_(besselarg);
2528 ((hilimit1 <= T) || (beta == 0.0)) ? 0.0: expterm* bessi0term-expbetaTterm;
2529 h3dummy1 =
intlinfunc_(lolimit1,hilimit1,h3lovalue1,h3hivalue1,lolimit1,hilimit1)/delta1;
2531 h3dashcoeffs[i] = h3dummy1 - h3dummy2;
2532 if (fabs(h3dashcoeffs[i]) <= h3relval) doh3 = 0;
2536 h3dashcoeffs[i] = 0.0;
2540 *auxindexptr = auxindex;
2563 double x2,
double y2,
2564 double x3,
double y3,
2565 double reltol,
double abstol)
2569 double TRarea, QUADarea1,QUADarea2,QUADarea3, area;
2583 QUADarea1 = (fabs(y2)+fabs(y1))*0.5*fabs(x2-x1);
2584 QUADarea2 = (fabs(y3)+fabs(y2))*0.5*fabs(x3-x2);
2585 QUADarea3 = (fabs(y3)+fabs(y1))*0.5*fabs(x3-x1);
2586 TRarea = fabs( QUADarea3 - QUADarea1 - QUADarea2);
2587 area = QUADarea1 + QUADarea2;
2588 if (area*reltol + abstol > TRarea)
2598 #define SECONDDERIV(i,a,b,c) \
2599 (oof = (i==getSolverState().ltraTimeIndex?getSolverState().currTime: \
2600 (getSolverState().ltraTimePoints[i])), \
2601 (( c - b )/(oof-(getSolverState().ltraTimePoints[i-1])) - \
2602 ( b - a )/((getSolverState().ltraTimePoints[i-1])- \
2603 (getSolverState().ltraTimePoints[i-2])))/(oof - \
2604 (getSolverState().ltraTimePoints[i-2])))
2638 double h1dashTfirstCoeff;
2639 double h2TfirstCoeff;
2640 double h3dashTfirstCoeff;
2642 double hilimit1, lolimit1, hivalue1, lovalue1, f1i, g1i;
2643 double eq1LTE=0.0, eq2LTE=0.0;
2644 int auxindex,
tdover, i, exact;
2676 if ((i < 0) || ((i==0) && (exact==1)))
2677 Xyce::dout() <<
"[LTRA-DBG-DEV]: lteCalculate_: i <= 0: some mistake!" << std::endl;
2700 g1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,
2702 h1dashTfirstCoeff = 0.5 * f1i *
2709 lolimit1 = std::max(
td,lolimit1);
2714 f1i =
twiceintlinfunc_(lolimit1,hilimit1,lolimit1,lovalue1,hivalue1,lolimit1,
2717 hivalue1,lolimit1,hilimit1);
2723 f1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,lolimit1,
2726 hivalue1,lolimit1,hilimit1);
2743 eq1LTE +=
admit*fabs(dashdash * h1dashTfirstCoeff);
2750 instance.
v1[auxindex - 1],
2751 instance.
v1[auxindex],
2752 instance.
v1[auxindex + 1]) ;
2754 eq2LTE +=
admit*fabs(dashdash * h3dashTfirstCoeff);
2766 eq2LTE +=
admit*fabs(dashdash * h1dashTfirstCoeff);
2771 instance.
v2[auxindex - 1],
2772 instance.
v2[auxindex],
2773 instance.
v2[auxindex + 1]);
2775 eq1LTE +=
admit*fabs(dashdash * h3dashTfirstCoeff);
2786 instance.
i1[auxindex - 1],
2787 instance.
i1[auxindex],
2788 instance.
i1[auxindex + 1]) ;
2790 eq2LTE += fabs(dashdash * h2TfirstCoeff);
2800 instance.
i2[auxindex - 1],
2801 instance.
i2[auxindex],
2802 instance.
i2[auxindex + 1]) ;
2804 eq1LTE += fabs(dashdash * h2TfirstCoeff);
2820 g1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,lolimit1,hilimit1);
2828 g1i =
intlinfunc_(lolimit1,hilimit1,lovalue1,hivalue1,lolimit1,hilimit1);
2836 hivalue1,lolimit1,hilimit1);
2850 eq1LTE += fabs(dashdash * h1dashTfirstCoeff);
2851 eq2LTE += fabs(dashdash * h3dashTfirstCoeff);
2863 eq2LTE += fabs(dashdash * h1dashTfirstCoeff);
2864 eq1LTE += fabs(dashdash * h3dashTfirstCoeff);
2876 eq2LTE += fabs(dashdash * h2TfirstCoeff);
2888 eq1LTE += fabs(dashdash * h2TfirstCoeff);
2900 Xyce::dout() <<
"[LTRA-DBG-DEV] " << instance.
getName() <<
": LTE/input for Eq1 at time "
2901 << curtime <<
" is: " << eq1LTE/instance.
input1 << std::endl;
2903 Xyce::dout() <<
"[LTRA-DBG-DEV] " << instance.
getName() <<
": LTE/input for Eq2 at time "
2904 << curtime <<
" is: " << eq2LTE/instance.
input1 << std::endl;
2907 return(fabs(eq1LTE) + fabs(eq2LTE));
2991 Model& m = (*it)->getModel();
3020 <<
"Modes supported: RC, RG, LC, RLC";
3026 UserError0(m) <<
"Nonzero G (except RG) transmission line not supported. "
3027 <<
"Modes supported: RC, RG, LC, RLC";
3032 if ((m.
resist == 0.0 ? 0 : 1) + (m.
conduct == 0.0 ? 0 : 1) +
3033 (m.
induct == 0.0 ? 0 : 1) + (m.
capac == 0.0 ? 0 : 1) <= 1)
3035 UserError0(m) <<
"Invalid specification. Specify at least "
3036 <<
"two of R, L, G, or C with nonzero values. "
3037 <<
"Modes supported: RC, RG, LC, RLC";
3050 UserWarning(*
this) <<
"Conflicting options STEPLIMIT and NOSTEPLIMIT given. Using STEPLIMIT";
3097 if (m.
alpha < 0.0) {
3098 UserError(m) <<
"Resistance and inductance must be greater than zero";
3105 double xbig, xsmall, xmid, y1big, y1small, y1mid;
3106 double y2big, y2small, y2mid;
3107 int done = 0, maxiter = 50, iters = 0;
3111 xmid = 0.5 * (xbig + xsmall);
3128 if ((done == 2) || (iters > maxiter))
3131 xmid = 0.5 * (xbig + xsmall);
3150 Report::DevelFatal().in(
"Master::initialize_vars_(void)") <<
"Unhandled LTRA special case encountered.";
3167 bool Master::loadDAEVectors (
double * solVec,
double * fVec,
double *qVec,
double * bVec,
double * storeLeadF,
double * storeLeadQ,
double * leadF,
double * leadQ,
double * junctionV)
3169 double max(0.0),min(0.0);
3170 double v1d(0.0), v2d(0.0), i1d(0.0), i2d(0.0);
3171 double dummy1(0.0), dummy2(0.0);
3172 std::ostringstream msg;
3185 dummy2 = exp(-dummy1);
3186 dummy1 = exp(dummy1);
3264 double qf1, qf2, qf3;
3267 qf1 = qf2 = qf3 = 0.0;
3282 if ((isaved != 0) &&
3285 v1d = di.
v1[isaved-1] * qf1
3286 + di.
v1[isaved] * qf2
3287 + di.
v1[isaved+1] * qf3;
3289 max = std::max(di.
v1[isaved-1], di.
v1[isaved]);
3290 max = std::max(max,di.
v1[isaved+1]);
3291 min = std::min(di.
v1[isaved-1], di.
v1[isaved]);
3292 min = std::min(min,di.
v1[isaved+1]);
3303 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated v1 is out of range after timepoint "
3305 Xyce::dout() <<
" values: "
3306 << di.
v1[isaved-1] <<
" "
3307 << di.
v1[isaved] <<
" "
3308 << di.
v1[isaved+1] <<
"; interpolated: "
3309 << v1d << std::endl;
3310 Xyce::dout() <<
" timepoints are: "
3316 v1d = di.
v1[isaved] * lf2 + di.
v1[isaved+1] * lf3;
3320 if ((isaved != 0) &&
3324 i1d = di.
i1[isaved-1] * qf1
3325 + di.
i1[isaved] * qf2
3326 + di.
i1[isaved+1] * qf3;
3328 max = std::max(di.
i1[isaved-1], di.
i1[isaved]);
3329 max = std::max(max,di.
i1[isaved+1]);
3330 min = std::min(di.
i1[isaved-1], di.
i1[isaved]);
3331 min = std::min(min,di.
i1[isaved+1]);
3337 ((i1d > max) || (i1d < min))))
3344 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated i1 is out of range after timepoint "
3346 Xyce::dout() <<
" values: "
3347 << di.
i1[isaved-1] <<
" "
3348 << di.
i1[isaved] <<
" "
3349 << di.
i1[isaved+1] <<
"; interpolated: "
3350 << i1d << std::endl;
3351 Xyce::dout() <<
" timepoints are: "
3357 i1d = di.
i1[isaved] * lf2 + di.
i1[isaved+1] * lf3;
3361 if ((isaved != 0) &&
3365 v2d = di.
v2[isaved-1] * qf1
3366 + di.
v2[isaved] * qf2
3367 + di.
v2[isaved+1] * qf3;
3369 max = std::max(di.
v2[isaved-1], di.
v2[isaved]);
3370 max = std::max(max,di.
v2[isaved+1]);
3371 min = std::min(di.
v2[isaved-1], di.
v2[isaved]);
3372 min = std::min(min,di.
v2[isaved+1]);
3380 ((v2d > max) || (v2d < min))))
3383 if ((isaved != 0) &&
3388 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated v2 is out of range after timepoint "
3390 Xyce::dout() <<
" values: "
3391 << di.
v2[isaved-1] <<
" "
3392 << di.
v2[isaved] <<
" "
3393 << di.
v2[isaved+1] <<
"; interpolated: "
3394 << v2d << std::endl;
3395 Xyce::dout() <<
" timepoints are: "
3401 v2d = di.
v2[isaved] * lf2
3407 if ((isaved != 0) &&
3411 i2d = di.
i2[isaved-1] * qf1
3412 + di.
i2[isaved] * qf2
3413 + di.
i2[isaved+1] * qf3;
3415 max = std::max(di.
i2[isaved-1], di.
i2[isaved]);
3416 max = std::max(max,di.
i2[isaved+1]); min = std::min(di.
i2[isaved-1], di.
i2[isaved]);
3417 min = std::min(min,di.
i2[isaved+1]);
3423 ((i2d > max) || (i2d < min))))
3429 Xyce::dout() <<
"[LTRA-DBG-DEV] load: warning: interpolated i2 is out of range after timepoint "
3431 Xyce::dout() <<
" values: "
3432 << di.
i2[isaved-1] <<
" "
3433 << di.
i2[isaved] <<
" "
3434 << di.
i2[isaved+1] <<
"; interpolated: "
3435 << i2d << std::endl;
3436 Xyce::dout() <<
" timepoints are: "
3442 i2d = di.
i2[isaved] * lf2 + di.
i2[isaved+1] * lf3;
3467 dummy1 = dummy2 = 0.0;
3490 dummy1 = dummy2 = 0.0;
3522 dummy1 = dummy2 = 0.0;
3635 dummy1 = dummy2 = 0.0;
3702 double dummy1(0.0), dummy2(0.0);
3703 std::ostringstream msg;
3868 .registerDevice(
"o", 1)
3869 .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
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
std::vector< double > ltraTimePoints
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)
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.
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
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.
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.
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