46 #include <Xyce_config.h>
54 #include <N_DEV_ExternDevice.h>
59 #include <N_ERH_ErrorMgr.h>
60 #include <N_LAS_Matrix.h>
61 #include <N_LAS_Vector.h>
80 :
DeviceEntity(
instanceEntityType, instance_block.getName(), parametric_data, factory_block.solverState_, factory_block.deviceOptions_, instance_block.netlistFileName_, instance_block.lineNumber_),
85 mlData(factory_block.matrixLoadData_),
86 cols(factory_block.matrixLoadData_.cols),
87 vals(factory_block.matrixLoadData_.vals),
92 numLeadCurrentStoreVars(0),
93 configuredForLeadCurrent(false),
94 loadLeadCurrent(false),
95 mergeRowColChecked(false),
96 extData(factory_block.externData_),
178 (
const std::vector< std::vector<int> > & depSolnLIDVecRef)
180 int size = expVarLIDs.size();
181 if (size != depSolnLIDVecRef.size())
183 DevelFatal0(*this).in(
"DeviceInstance::registerDepSolnLIDs")
184 <<
"Inconsistent number of LIDs returned from topology";
186 for (
int i = 0; i < size; ++i)
188 if (depSolnLIDVecRef[i].size() != 1)
190 UserError0(*
this) <<
"Problem with value for " << expVarNames[i]
191 <<
". This may be an incorrect usage of a lead current in place of a current through a voltage source.";
193 expVarLIDs[i] = depSolnLIDVecRef[i][0];
217 const std::vector< std::vector<int> > & varList )
220 for (
int i = 0; i < size; ++i)
271 static std::vector<std::string> emptyList;
294 const std::vector< std::vector<int> > & varList )
296 if( varList.size() != 0 )
299 msg =
"DeviceInstance::registerDepStateGIDs\n";
300 msg +=
"\tCall to registerDepStateGIDs for a device which doesn't use it.";
301 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
319 static std::vector<std::string> emptyList;
342 const std::vector< std::vector<int> > & varList )
344 if( varList.size() != 0 )
347 msg =
"DeviceInstance::registerDepStoreGIDs\n";
348 msg +=
"\tCall to registerDepStoreGIDs for a device which doesn't use it.";
349 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
381 bool bsuccess =
true;
411 std::vector<int>::const_iterator firstVar;
412 std::vector<int>::const_iterator lastVar;
413 std::vector<int>::const_iterator iterVar;
414 int localRows = matPtr->getLocalNumRows();
418 Xyce::dout() << std::endl
419 <<
"Loading trivial stamp for " <<
getName() << std::endl;
422 if (
cols.size() < 1)
cols.resize(1);
423 if (
vals.size() < 1)
vals.resize(1);
440 for (iterVar=firstVar; iterVar!=lastVar; ++iterVar)
445 Xyce::dout() <<
"matrix row = " << row << std::endl;
449 Xyce::dout() <<
"\tNOT loading this one - too small" << std::endl;
454 Xyce::dout() <<
"\tloading this one" << std::endl;
461 matPtr->replaceLocalRow(row, count, &
vals[0], &
cols[0]);
497 std::vector<int>::const_iterator firstVar;
498 std::vector<int>::const_iterator lastVar;
499 std::vector<int>::const_iterator iterVar;
500 int localRows = matPtr->getLocalNumRows();
504 Xyce::dout() << std::endl
505 <<
"Zeroing the matrix diagonal for " <<
getName() << std::endl;
508 if (
cols.size() < 1)
cols.resize(1);
509 if (
vals.size() < 1)
vals.resize(1);
526 for (iterVar=firstVar; iterVar!=lastVar; ++iterVar)
531 Xyce::dout() <<
"matrix row = " << row << std::endl;
533 if (row < 0)
continue;
534 if (row >= localRows)
continue;
537 Xyce::dout() <<
"\tloading this one" << std::endl;
543 matPtr->putLocalRow(row, count, &
vals[0], &
cols[0]);
569 size_t pos=tmpname.find_last_of(
":");
570 if (pos != std::string::npos)
572 tmpname=tmpname.substr(pos+1,1)+
":"+tmpname.substr(0,pos+1)+tmpname.substr(pos+2);
664 (std::vector< std::vector<int> > & stamp_parent,
665 std::vector<int> & map_parent,
666 std::vector< std::vector<int> > & map2_parent,
667 std::vector< std::vector<int> > & stamp,
668 std::vector<int> & map,
669 std::vector< std::vector<int> > & map2,
670 int from,
int to,
int original_size)
672 int i, j, t_index, f_index, t_index2, f_index2, p_size, p_row, f_mod;
675 std::vector< std::vector<int> > fill;
676 std::vector<int> dup;
677 std::vector< std::vector<int> > map2_tmp;
681 std::string msg =
"Internal Error 1 in DeviceInstance::jacStampMap. from <= to.";
684 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
687 if (map_parent.size() == 0)
689 map_parent.resize(original_size);
690 map2_parent.resize(original_size);
691 for (i=0 ; i<original_size ; ++i)
694 map2_parent[i].resize(stamp_parent[i].size());
695 for (j=0 ; j<stamp_parent[i].size() ; ++j)
697 map2_parent[i][j] = j;
701 map2.resize(original_size);
706 for (i=0 ; i<original_size ; ++i)
710 p_row = map_parent[i];
711 for (j=0 ; j<stamp_parent[p_row].size() ; ++j)
713 if (stamp_parent[p_row][j] == from)
715 if (stamp_parent[p_row][j] == to)
718 map2[i].resize(map2_parent[i].size());
721 for (j=0 ; j<map2_parent[i].size() ; ++j)
723 map2[i][j] = map2_parent[i][j];
724 if (stamp_parent[p_row][map2[i][j]] == from)
726 if (stamp_parent[p_row][map2[i][j]] == to)
733 for (j=0 ; j<map2[i].size() ; ++j)
735 if (map2[i][j] > f_index)
738 if (f_index2 >= 0 && t_index2 >= 0)
739 map2[i][f_index2] = map2[i][t_index2];
743 for (j=0 ; j<map2[i].size() ; ++j)
745 if (stamp_parent[p_row][map2[i][j]] > to && stamp_parent[p_row][map2[i][j]] < from)
749 for (j=0 ; j<stamp_parent[p_row].size() ; ++j)
751 if (to > stamp_parent[p_row][j])
757 map2[i][f_index2] = t_index;
761 map.resize(original_size);
762 p_size = stamp_parent.size();
769 for (i=0 ; i<stamp_parent[from].size() && stamp_parent[from][i] < p_size-1 ; ++i)
772 for (j=0 ; j<stamp_parent[to].size() ; ++j)
776 if (stamp_parent[from][i] == stamp_parent[to][j])
784 for (j=0 ; j<map2[to].size() ; ++j)
786 if (stamp_parent[to][map2_tmp[to][j]] > stamp_parent[from][i])
794 stamp.resize(p_size-1);
796 dup.resize(original_size);
798 for (i=1 ; i<original_size ; ++i)
801 for (j=0 ; j<i ; ++j)
803 if (map_parent[i] == map_parent[j])
813 for (i=0 ; i<f_mod ; ++i)
814 map[i] = map_parent[i];
815 map[f_mod] = map[to];
816 for (i=f_mod+1 ; i<original_size ; ++i)
817 map[i] = map_parent[i]-1;
819 for (i=1 ; i<original_size ; ++i)
822 map[i] = map[dup[i]];
830 if (map[from] != map[to]) {
831 for (i=from+1 ; i<original_size ; ++i) {
832 if (map[i] == map[to]) {
837 if (map_2_from == from) {
838 std::string msg =
"Internal Error 2 in DeviceInstance::jacStampMap";
839 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
843 for (i=0 ; i<stamp_parent[to].size() && stamp_parent[to][i] < p_size-1 ; ++i)
846 for (j=0 ; j<stamp_parent[from].size() ; ++j)
850 if (stamp_parent[to][i] == stamp_parent[from][j])
858 for (j=0 ; j<map2[map_2_from].size() ; ++j)
860 if (stamp_parent[from][map2_tmp[map_2_from][j]] > stamp_parent[to][i])
862 ++map2[map_2_from][j];
869 for (i=0 ; i<p_size ; ++i)
871 fill[i].resize(p_size);
872 for (j=0 ; j<p_size ; ++j)
874 for (j=0 ; j<stamp_parent[i].size() ; ++j)
875 fill[i][stamp_parent[i][j]] = 1;
877 for (i=0 ; i<p_size ; ++i)
879 fill[to][i] += fill[from][i];
881 for (i=0 ; i<p_size ; ++i)
883 fill[i][to] += fill[i][from];
885 for (i=from ; i<p_size-1 ; ++i)
887 for (j=0 ; j<p_size ; ++j)
888 fill[i][j] = fill[i+1][j];
889 for (j=0 ; j<p_size ; ++j)
890 fill[j][i] = fill[j][i+1];
892 for (i=0 ; i<p_size-1 ; ++i)
895 for (j=0 ; j<p_size-1 ; ++j)
898 stamp[i].push_back(j);
931 (std::vector< std::vector<int> > & stamp_parent,
932 std::vector< std::vector<int> > & map2_parent,
933 std::vector< std::vector<int> > & stamp,
934 std::vector< std::vector<int> > & map2)
937 int current_size = stamp_parent.size();
939 if (DEBUG_DEVICE && getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
941 Xyce::dout() << Xyce::section_divider << std::endl
942 <<
"Begin DeviceInstance::jacStampMap_fixOrder." << std::endl
943 << Xyce::section_divider << std::endl;
948 if (map2_parent.size() == 0)
950 map2_parent.resize(current_size);
951 for (i=0 ; i<current_size ; ++i)
953 map2_parent[i].resize(stamp_parent[i].size());
954 for (j=0 ; j<stamp_parent[i].size() ; ++j)
956 map2_parent[i][j] = j;
965 std::vector< std::vector<int> > denseStamp(current_size);
966 for (i=0;i<current_size;++i)
968 denseStamp[i].resize(current_size,-1);
970 for (j=0;j<stamp_parent[i].size();++j)
972 int denseCol = stamp_parent[i][j];
973 denseStamp[i][denseCol] = j;
982 stamp.resize(current_size);
983 map2.resize(current_size);
984 for (i=0;i<current_size;++i)
986 for (j=0;j<current_size;++j)
988 int colMapIndex = denseStamp[i][j];
991 stamp[i].push_back(j);
995 int stampRowLength=stamp[i].size();
996 map2[i].resize(stampRowLength, 0);
999 for (j=0;j<current_size;++j)
1001 int colMapIndex = denseStamp[i][j];
1002 if (colMapIndex!=-1 && colMapIndex < stampRowLength)
1004 map2[i][colMapIndex] = k;
1010 if (DEBUG_DEVICE && getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
1012 Xyce::dout() <<
"From inside of DeviceInstance::jacStampMap_fixOrder:" << std::endl
1013 <<
"The original parent stamp is:" << std::endl;
1014 outputJacStamp(stamp_parent);
1015 Xyce::dout() <<
"The new reduced stamp is:" << std::endl;
1016 outputJacStamp(stamp);
1017 Xyce::dout() <<
"The dense stamp is:" << std::endl;
1018 outputJacStamp(denseStamp);
1020 Xyce::dout() <<
"The new map is:" << std::endl;
1021 outputJacStamp(map2);
1023 Xyce::dout() << Xyce::section_divider << std::endl
1024 <<
"End DeviceInstance::jacStampMap_fixOrder."<<std::endl
1025 << Xyce::section_divider << std::endl;
1041 for (i=0 ; i<jac.size() ; ++i)
1043 Xyce::dout() <<
"Row: " << i <<
" ::";
1044 for (j=0 ; j<jac[i].size() ; ++j)
1045 Xyce::dout() <<
" " << jac[i][j];
1046 Xyce::dout() << std::endl;
1048 Xyce::dout() << std::endl;
1060 const std::vector<std::vector<int> > & jacMap2)
1064 for (i=0 ; i<jacMap.size() ; ++i)
1066 Xyce::dout() <<
"Row " << i <<
": ";
1067 for (j=0; j < jacMap2[i].size(); j++)
1069 Xyce::dout() << jacMap[i]<<
"," << jacMap2[i][j] <<
" ";
1071 Xyce::dout() << std::endl;
1074 Xyce::dout() << std::endl;
1093 const std::vector<int> & counts,
1094 const std::vector<int> & GIDs,
1095 const std::vector< std::vector<int> > & jacGIDs )
1105 int extSize = counts[0];
1106 int intSize = counts[1];
1107 int expSize = counts[2];
1108 int size = GIDs.size();
1111 std::map<int,int> testIndexMap;
1115 Xyce::dout() <<
"DeviceInstance::registerGIDData for " <<
getName() << std::endl
1116 <<
" extSize = " << extSize << std::endl
1117 <<
" intSize = " << intSize << std::endl
1118 <<
" expSize = " << expSize << std::endl
1119 <<
" GIDs.size = " << size << std::endl
1120 <<
" jacGIDs.size = " << jacGIDs.size () << std::endl
1126 for (i = 0; i < extSize; ++i )
1128 if ( testIndexMap.find(GIDs[i]) == testIndexMap.end() )
1130 extGIDList.push_back( index_pair( GIDs[i], 1 ) );
1131 testIndexMap[GIDs[i]] = 1;
1135 testIndexMap.clear ();
1139 for (; i<intSize+extSize;++i)
1141 if ( testIndexMap.find(GIDs[i]) == testIndexMap.end() )
1143 intGIDList.push_back( index_pair( GIDs[i], 1 ) );
1144 testIndexMap[GIDs[i]] = 1;
1148 testIndexMap.clear ();
1153 for (; i<intSize+extSize+expSize;++i)
1155 if ( testIndexMap.find(GIDs[i]) == testIndexMap.end() )
1158 testIndexMap[GIDs[i]] = 1;
1167 for (
int itmp = 0; itmp < expS; ++itmp)
1172 testIndexMap.clear ();
1176 for(i = 0; i < jacGIDs.size () ; ++i )
1179 if ( testIndexMap.find(GIDs[i]) == testIndexMap.end() )
1181 testIndexMap[GIDs[i]] = 1;
1183 std::map<int,int> testJMap;
1185 int length = jacGIDs[i].size();
1186 for(
int j = 0; j < length; ++j )
1188 if ( testJMap.find(jacGIDs[i][j]) == testJMap.end () )
1190 indexPairList.push_back( index_pair( GIDs[i], jacGIDs[i][j] ) );
1191 testJMap[jacGIDs[i][j]] = 1;
1199 std::vector<int>::const_iterator begin = GIDs.begin ();
1200 std::vector<int>::const_iterator end = GIDs.end ();
1201 std::vector<int>::const_iterator iterGID;
1203 Xyce::dout() <<
" Complete GIDs :" << std::endl;
1204 for (iterGID=begin;iterGID!=end ;++iterGID)
1206 Xyce::dout() <<
"\tgid=" << *iterGID << std::endl;
1208 Xyce::dout() << std::endl;
1210 std::list<index_pair>::iterator first;
1211 std::list<index_pair>::iterator last;
1212 std::list<index_pair>::iterator iter;
1214 Xyce::dout() <<
" intGIDList :" << std::endl;
1217 for (iter=first;iter!=last;++iter)
1219 Xyce::dout() <<
"\tgid=" << iter->row << std::endl;
1221 Xyce::dout() << std::endl;
1223 Xyce::dout() <<
" extGIDList :" << std::endl;
1226 for (iter=first;iter!=last;++iter)
1228 Xyce::dout() <<
"\tgid=" << iter->row << std::endl;
1230 Xyce::dout() << std::endl;
1233 Xyce::dout() <<
" indexPairList :" << std::endl;
1236 for (iter=first;iter!=last;++iter)
1238 Xyce::dout() <<
" row=" << iter->row <<
" col=" << iter->col << std::endl;
1240 Xyce::dout() << std::endl << std::endl;
1268 Report::DevelFatal0().in(
"DeviceInstance::processParams")
1269 <<
"DeviceInstance::processParams() must be implemented for device " <<
getName();
1285 msg =
"DeviceInstance::updateIntermediateVars does not exist";
1286 msg +=
" for this device: " +
getName() +
"\n";
1287 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1304 msg =
"DeviceInstance::updatePrimaryState does not exist";
1305 msg +=
" for this device: " +
getName() +
"\n";
1306 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1322 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
1323 "DeviceInstance::setInternalState does not exist for this device: "