46 #include <Xyce_config.h>
48 #include <N_UTL_Misc.h>
59 #include <N_ERH_ErrorMgr.h>
61 #include <N_LAS_Matrix.h>
62 #include <N_LAS_Vector.h>
64 #include <N_UTL_BreakPoint.h>
66 #include <N_UTL_Functors.h>
76 .setDescription(
"Characteristic Impedance");
80 .setDescription(
"Characteristic Impedance");
84 .setDescription(
"Time delay");
88 .setDescription(
"Frequency");
91 .setDescription(
"Length in wavelengths");
114 :
DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block),
133 APos1EquPos1NodeOffset(-1),
134 APos1EquInt1NodeOffset(-1),
135 AInt1EquPos1NodeOffset(-1),
136 AInt1EquInt1NodeOffset(-1),
137 AInt1EquIbr1NodeOffset(-1),
138 ANeg1EquIbr1NodeOffset(-1),
139 AIbr1EquInt1NodeOffset(-1),
140 AIbr1EquNeg1NodeOffset(-1),
141 APos2EquPos2NodeOffset(-1),
142 APos2EquInt2NodeOffset(-1),
143 AInt2EquPos2NodeOffset(-1),
144 AInt2EquInt2NodeOffset(-1),
145 AInt2EquIbr2NodeOffset(-1),
146 ANeg2EquIbr2NodeOffset(-1),
147 AIbr2EquInt2NodeOffset(-1),
148 AIbr2EquNeg2NodeOffset(-1),
149 AIbr1EquPos2NodeOffset(-1),
150 AIbr1EquNeg2NodeOffset(-1),
151 AIbr1EquIbr2NodeOffset(-1),
152 AIbr2EquPos1NodeOffset(-1),
153 AIbr2EquNeg1NodeOffset(-1),
154 AIbr2EquIbr1NodeOffset(-1),
155 first_BP_call_done(false),
159 newBreakPoint(false),
160 newBreakPointTime(0.0)
235 UserError0(*
this) <<
"Invalid (zero or negative) impedance given.";
241 UserError0(*
this) <<
"Neither time delay (TD) nor frequency (F) given.";
245 UserError0(*
this) <<
"Both time delay (TD) and frequency (F) given. Pick one.";
252 else if (!
given(
"TD"))
254 UserError0(*
this) <<
"Zero or negative frequency given.";
264 #ifdef Xyce_DEBUG_DEVICE
267 Xyce::dout() <<
" Z0 = " <<
Z0 << std::endl;
268 Xyce::dout() <<
" td = " <<
td << std::endl;
269 Xyce::dout() <<
" freq = " <<
freq << std::endl;
270 Xyce::dout() <<
" NL = " <<
NL << std::endl;
285 bool bsuccess =
true;
312 const std::vector<int> & extLIDVecRef )
317 #ifdef Xyce_DEBUG_DEVICE
320 Xyce::dout() << std::endl << section_divider << std::endl;
321 Xyce::dout() <<
"In Instance::registerLIDs\n\n";
322 Xyce::dout() <<
"name = " <<
getName() << std::endl;
323 Xyce::dout() <<
"number of internal variables: " <<
numIntVars << std::endl;
324 Xyce::dout() <<
"number of external variables: " <<
numExtVars << std::endl;
347 #ifdef Xyce_DEBUG_DEVICE
350 Xyce::dout() <<
" VARIABLE Indicies " << std::endl;
351 Xyce::dout() <<
"li_Pos1 = " <<
li_Pos1 << std::endl;
352 Xyce::dout() <<
"li_Neg1 = " <<
li_Neg1 << std::endl;
353 Xyce::dout() <<
"li_Int1 = " <<
li_Int1 << std::endl;
354 Xyce::dout() <<
"li_Ibr1 = " <<
li_Ibr1 << std::endl;
355 Xyce::dout() <<
"li_Pos2 = " <<
li_Pos2 << std::endl;
356 Xyce::dout() <<
"li_Neg2 = " <<
li_Neg2 << std::endl;
357 Xyce::dout() <<
"li_Int2 = " <<
li_Int2 << std::endl;
358 Xyce::dout() <<
"li_Ibr2 = " <<
li_Ibr2 << std::endl;
360 Xyce::dout() <<
"\nEnd of Instance::register LIDs\n";
361 Xyce::dout() << section_divider << std::endl;
422 AssertLIDs(stoLIDVecRef.size() == getNumStoreVars());
424 if( loadLeadCurrent )
426 li_store_dev_i1 = stoLIDVecRef[0];
427 li_store_dev_i2 = stoLIDVecRef[1];
442 if( loadLeadCurrent && storeNameMap.empty ())
446 std::string modName(getName());
447 spiceInternalName(modName);
449 tmpstr = modName+
":DEV_I1";
450 storeNameMap[ li_store_dev_i1 ] = tmpstr;
451 tmpstr = modName+
":DEV_I2";
452 storeNameMap[ li_store_dev_i2 ] = tmpstr;
529 bool bsuccess =
true;
542 #ifdef Xyce_DEBUG_DEVICE
545 Xyce::dout() << subsection_divider << std::endl;
546 Xyce::dout() <<
" Instance::loadDAEFVector" << std::endl;
547 Xyce::dout() <<
" name = " <<
getName() <<std::endl;
651 #ifdef Xyce_DEBUG_DEVICE
654 Xyce::dout() << subsection_divider << std::endl;
655 Xyce::dout() <<
" name = " <<
getName() << std::endl;
718 #ifdef Xyce_DEBUG_DEVICE
720 Xyce::dout() << subsection_divider << std::endl;
736 #ifdef Xyce_DEBUG_DEVICE
739 Xyce::dout() << std::endl << subsection_divider << std::endl;
740 Xyce::dout() <<
"In TRA::updatePrimaryState\n";
741 Xyce::dout() <<
" last_t is " <<
last_t << std::endl;
742 Xyce::dout() <<
" v1 is " <<
v1 << std::endl;
743 Xyce::dout() <<
" v2 is " <<
v2 << std::endl;
762 #ifdef Xyce_DEBUG_DEVICE
765 Xyce::dout() << std::endl << subsection_divider << std::endl;
766 Xyce::dout() <<
" In ::updateIntermediateVars\n\n";
781 #ifdef Xyce_DEBUG_DEVICE
784 Xyce::dout() <<
" Vpos1 = " <<
Vpos1 << std::endl;
785 Xyce::dout() <<
" Vneg1 = " <<
Vneg1 << std::endl;
786 Xyce::dout() <<
" Vint1 = " <<
Vint1 << std::endl;
787 Xyce::dout() <<
" Ibr1 = " <<
Ibr1 << std::endl;
788 Xyce::dout() <<
" Vpos2 = " <<
Vpos2 << std::endl;
789 Xyce::dout() <<
" Vneg2 = " <<
Vneg2 << std::endl;
790 Xyce::dout() <<
" Vint2 = " <<
Vint2 << std::endl;
791 Xyce::dout() <<
" Ibr2 = " <<
Ibr2 << std::endl;
802 #ifdef Xyce_DEBUG_DEVICE
804 Xyce::dout() <<
"DC Mode, V1 = " <<
v1 <<
", V2 = " <<
v2 << std::endl;
811 #ifdef Xyce_DEBUG_DEVICE
815 Xyce::dout() <<
" Time is " << currentTime << std::endl;
836 #ifdef Xyce_DEBUG_DEVICE
839 Xyce::dout() <<
"Transient, first time, T = ";
840 Xyce::dout() << currentTime;
841 Xyce::dout() <<
", V1 = " <<
v1;
842 Xyce::dout() <<
", V2 = " <<
v2 << std::endl;
848 double delayedTime = currentTime-
td;
853 #ifdef Xyce_DEBUG_DEVICE
856 Xyce::dout() <<
" Done with interpolation to delayedTime=";
857 Xyce::dout() << delayedTime;
858 Xyce::dout() <<
", have v1="<<
v1 <<
" and v2=" <<
v2 << std::endl;
859 Xyce::dout() <<
" INTERP " << delayedTime <<
" " <<
v1 <<
" " <<
v2 << std::endl;
860 Xyce::dout() <<
" Set last_t to " << currentTime << std::endl;
874 #ifdef Xyce_DEBUG_DEVICE
877 Xyce::dout() <<
"second or later iteration, t is " << currentTime;
878 Xyce::dout() <<
" have last_t = " <<
last_t <<
" v1="<<
v1 <<
" and v2=" <<
v2 << std::endl;
904 std::vector<History>::iterator first =
history.begin();
905 std::vector<History>::iterator it1;
906 std::vector<History>::iterator last =
history.end();
910 #ifdef Xyce_DEBUG_DEVICE
913 Xyce::dout() << Xyce::section_divider << std::endl;
914 Xyce::dout() <<
"Pruning for time t1="<<t1 << std::endl;
915 Xyce::dout() <<
" Oldest in list is t="<<first->t<<
" v1 = "<<first->v1 <<
916 " v2="<<first->v2 << std::endl;
917 Xyce::dout() <<
" latest in list is t="<<last->t<<
" v1 = "<<last->v1
918 <<
" v2="<<last->v2 << std::endl;
922 for (it1 = first, i = 0; it1->t < t1 && it1 != last; ++it1, ++i)
924 #ifdef Xyce_DEBUG_DEVICE
927 Xyce::dout() <<
"i = " << i <<
" t = " << it1->t;
928 Xyce::dout() <<
" v1 = " << it1->v1;
929 Xyce::dout() <<
" v2 = " << it1->v2 << std::endl;
934 #ifdef Xyce_DEBUG_DEVICE
937 Xyce::dout() <<
" i ="<<i << std::endl;
944 #ifdef Xyce_DEBUG_DEVICE
947 Xyce::dout() <<
"Need to prune. Keeping " << it1->t << std::endl;
953 #ifdef Xyce_DEBUG_DEVICE
956 Xyce::dout() <<
" Keeping " << it1->t << std::endl;
961 #ifdef Xyce_DEBUG_DEVICE
964 Xyce::dout() <<
" Keeping " << it1->t << std::endl;
971 #ifdef Xyce_DEBUG_DEVICE
974 Xyce::dout() << Xyce::section_divider << std::endl;
992 std::vector<History>::iterator first =
history.begin();
993 std::vector<History>::iterator it1;
994 std::vector<History>::iterator last =
history.end();
997 double v11,v21,v12,v22,v13,v23;
998 double dt12,dt13,dt23;
1004 msg=
"Instance::InterpV1V2FromHistory called but history list is"
1005 " empty. Might be due to trying to restart this netlist.\n"
1006 "Restarts of netlists with transmission lines does not work yet.\n";
1007 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL, msg);
1014 if (t - first->t < -N_UTL_MachineDependentParams::MachinePrecision()
1015 || t - last->t > N_UTL_MachineDependentParams::MachinePrecision() )
1019 sprintf(msg2,
"Instance::InterpV1V2FromHistory: "
1020 "Asked to interpolate to a time (%20.17lg) prior to oldest(%20.17g) or "
1021 "after newest(%20.17lg) in history\n",t,first->t,last->t);
1023 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL, msg);
1026 #ifdef Xyce_DEBUG_DEVICE
1029 Xyce::dout() <<
" interpolating for t = " << t << std::endl;
1035 if ( fabs(t-first->t)<N_UTL_MachineDependentParams::MachinePrecision())
1040 else if ( fabs(t-last->t)<N_UTL_MachineDependentParams::MachinePrecision())
1048 LessThan<History,double> lessFunct;
1064 #ifdef Xyce_DEBUG_DEVICE
1067 Xyce::dout() <<
"Using time t3="<<t3<<
" v1(t3)="<<v13<<
" v2(t3)="<<v23 << std::endl;
1068 Xyce::dout() <<
"Using time t2="<<t2<<
" v1(t2)="<<v12<<
" v2(t2)="<<v22 << std::endl;
1069 Xyce::dout() <<
"Using time t1="<<t1<<
" v1(t1)="<<v11<<
" v2(t1)="<<v21 << std::endl;
1118 *v1p = f1*v11+f2*v12+f3*v13;
1119 *v2p = f1*v21+f2*v22+f3*v23;
1141 bool bsuccess =
true;
1159 #ifdef Xyce_DEBUG_DEVICE
1162 Xyce::dout() <<
" In Instance::getBreakPoints "<<std::endl;
1163 Xyce::dout() <<
" First time step, I don't get to set breakpoints. Time is ";
1164 Xyce::dout() << currentTime << std::endl;
1193 double d11, d21, d12, d22;
1198 std::vector<History>::iterator last =
history.end();
1204 double oVp1,oVp2,oVn1,oVn2,oI1,oI2;
1206 double tmp_v1,tmp_v2, tmp_t;
1208 #ifdef Xyce_DEBUG_DEVICE
1212 Xyce::dout() <<
" In Instance::acceptStep "<<std::endl;
1213 Xyce::dout() <<
"I want breakpoints. Time is " << currentTime << std::endl;
1214 Xyce::dout() <<
" timeOld is " <<
timeOld << std::endl;
1235 oVp1 = (*theSolVectorPtr)[
li_Pos1];
1236 oVn1 = (*theSolVectorPtr)[
li_Neg1];
1237 oI1 = (*theSolVectorPtr)[
li_Ibr1];
1238 oVp2 = (*theSolVectorPtr)[
li_Pos2];
1239 oVn2 = (*theSolVectorPtr)[
li_Neg2];
1240 oI2 = (*theSolVectorPtr)[
li_Ibr2];
1244 ov1=(oVp2-oVn2)+
Z0*oI2;
1245 ov2=(oVp1-oVn1)+
Z0*oI1;
1247 #ifdef Xyce_DEBUG_DEVICE
1248 oVi1 = (*theSolVectorPtr)[
li_Int1];
1249 oVi2 = (*theSolVectorPtr)[
li_Int2];
1253 Xyce::dout() <<
" ----- New time step -----" << std::endl;
1254 Xyce::dout() <<
" Last solution : " << std::endl;
1255 Xyce::dout() <<
" vpos1 = " << oVp1 << std::endl;
1256 Xyce::dout() <<
" vneg1 = " << oVn1 << std::endl;
1257 Xyce::dout() <<
" vint1 = " << oVi1 << std::endl;
1258 Xyce::dout() <<
" ibr1 = " << oI1 << std::endl;
1259 Xyce::dout() <<
" vpos2 = " << oVp2 << std::endl;
1260 Xyce::dout() <<
" vneg2 = " << oVn2 << std::endl;
1261 Xyce::dout() <<
" vint2 = " << oVi2 << std::endl;
1262 Xyce::dout() <<
" ibr2 = " << oI2 << std::endl;
1263 Xyce::dout() <<
"in set breakpoints, saving for time=" << currentTime <<
", V1 = " << ov1 <<
", V2 = " << ov2 << std::endl;
1264 Xyce::dout() <<
" V1V2DBG " << currentTime <<
" " << ov1 <<
" " << ov2 << std::endl;
1273 tmp_v1 = last->v1; tmp_v2 = last->v2; tmp_t = last->t;
1275 #ifdef Xyce_DEBUG_DEVICE
1278 Xyce::dout() <<
"tmp_t=" << tmp_t <<
" last->t =" << last->t << std::endl;
1279 Xyce::dout() <<
"tmp_v1=" << tmp_v1 <<
" last->v1=" << last->v1 << std::endl;
1280 Xyce::dout() <<
"tmp_v2=" << tmp_v2 <<
" last->v2=" << last->v2 << std::endl;
1283 d11 = (tmp_v1-last->v1)/(tmp_t-last->t);
1284 d12 = (tmp_v2-last->v2)/(tmp_t-last->t);
1285 tmp_v1 = last->v1; tmp_v2 = last->v2; tmp_t = last->t;
1287 #ifdef Xyce_DEBUG_DEVICE
1290 Xyce::dout() <<
"tmp_t=" << tmp_t <<
" last->t =" << last->t << std::endl;
1291 Xyce::dout() <<
"tmp_v1=" << tmp_v1 <<
" last->v1=" << last->v1 << std::endl;
1292 Xyce::dout() <<
"tmp_v2=" << tmp_v2 <<
" last->v2=" << last->v2 << std::endl;
1295 d21 = (tmp_v1-last->v1)/(tmp_t-last->t);
1296 d22 = (tmp_v2-last->v2)/(tmp_t-last->t);
1297 #ifdef Xyce_DEBUG_DEVICE
1300 Xyce::dout() <<
"Derivs are " << d11 <<
" " << d21 << std::endl;
1301 Xyce::dout() <<
" and " << d12 <<
" " <<d22 << std::endl;
1302 Xyce::dout() <<
" fabs(d11-d21) = " << fabs(d11-d21) << std::endl;
1303 Xyce::dout() <<
" fabs(d12-d22) = " << fabs(d12-d22) << std::endl;
1304 Xyce::dout() <<
"D1D2DBG " << currentTime <<
" " << d11 <<
" " << d12 << std::endl;
1308 if ((fabs(d11-d21) >= .99*Xycemax(fabs(d11),fabs(d21))+1) ||
1309 (fabs(d12-d22) >= .99*Xycemax(fabs(d12),fabs(d22))+1))
1311 #ifdef Xyce_DEBUG_DEVICE
1314 Xyce::dout() <<
"Derivative is changing enough, I want to set a break point ";
1315 Xyce::dout() <<
td <<
" ahead of discontinuity, which is ";
1316 Xyce::dout() << tmp_t+
td<<std::endl;
1349 for (i=0;i<hsize;++i)
1357 #ifdef Xyce_DEBUG_DEVICE
1360 Xyce::dout() << Xyce::section_divider
1362 Xyce::dout() <<
" In Instance::getInternalState " << std::endl;
1363 Xyce::dout() <<
" name=" <<
getName() << std::endl;
1364 Xyce::dout() <<
" history size = " << hsize << std::endl;
1365 Xyce::dout() <<
" history data: " << std::endl;
1366 for (i = 0 ; i < hsize ; ++i)
1368 Xyce::dout() <<
" (" <<
history[i].t <<
", " <<
history[i].v1 <<
", "
1369 <<
history[i].v2 <<
")"<< std::endl;
1372 Xyce::dout() <<
" DeviceState ID = " << myState->
ID << std::endl;
1373 Xyce::dout() <<
" DeviceState data size " << myState->
data.size() << std::endl;
1374 Xyce::dout() <<
" Device State data: " << std::endl;
1375 for (i = 0 ; i < myState->
data.size() ; ++i)
1377 Xyce::dout() <<
" " << myState->
data[i] << std::endl;
1379 Xyce::dout() << Xyce::section_divider
1399 int dsize=state.
data.size();
1404 msg =
"Instance::setInternalState: ID ("+state.
ID+
")";
1405 msg +=
"from restart does not match my name ("+
getName()+
")!\n";
1406 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL, msg);
1413 sprintf(msg2,
"Instance::setInternalState: "
1414 "Data size from restart (%d) not a multiple of 3!",
1417 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL, msg);
1423 for ( i=0; i<hsize; ++i)
1431 #ifdef Xyce_DEBUG_DEVICE
1434 Xyce::dout() << Xyce::section_divider
1436 Xyce::dout() <<
" In Instance::setInternalState " << std::endl;
1437 Xyce::dout() <<
" name=" <<
getName() << std::endl;
1438 Xyce::dout() <<
" history size = " << hsize << std::endl;
1439 Xyce::dout() <<
" history data: " << std::endl;
1440 for (i = 0 ; i < hsize ; ++i)
1442 Xyce::dout() <<
" (" <<
history[i].t <<
", " <<
history[i].v1 <<
", "
1443 <<
history[i].v2 <<
")"<< std::endl;
1446 Xyce::dout() <<
" DeviceState ID = " << state.
ID << std::endl;
1447 Xyce::dout() <<
" DeviceState data size " << state.
data.size() << std::endl;
1448 Xyce::dout() <<
" Device State data: " << std::endl;
1449 for (i = 0 ; i < state.
data.size() ; ++i)
1451 Xyce::dout() <<
" " << state.
data[i] << std::endl;
1453 Xyce::dout() << Xyce::section_divider
1487 std::vector<Instance*>::iterator iter;
1491 for (iter=first; iter!=last; ++iter)
1493 (*iter)->processParams();
1511 :
DeviceModel(MB, configuration.getModelParameters(), factory_block)
1526 std::vector<Instance*>::iterator iter;
1530 for (iter=first; iter!=last; ++iter)
1546 std::vector<Instance*>::const_iterator iter;
1552 os <<
" name model name Parameters" << std::endl;
1553 for (i=0, iter=first; iter!=last; ++iter, ++i)
1555 os <<
" " << i <<
": " << (*iter)->getName() <<
" ";
1559 os <<
"Z0 = " << (*iter)->Z0 << std::endl;
1560 os <<
"G0 = " << (*iter)->G0 << std::endl;
1561 os <<
"TD = " << (*iter)->td << std::endl;
1562 os <<
"FREQ = " << (*iter)->freq << std::endl;
1563 os <<
"NL = " << (*iter)->NL << std::endl;
1588 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1643 : t(right.t),v1(right.v1),v2(right.v2)
1669 .registerDevice(
"t", 1);