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>
78 :
DeviceEntity(parametric_data, factory_block.solverState_, factory_block.deviceOptions_, instance_block.getNetlistLocation().getPath(), instance_block.getNetlistLocation().getLineNumber()),
79 name_(instance_block.getInstanceName()),
84 mlData(factory_block.matrixLoadData_),
85 cols(factory_block.matrixLoadData_.cols),
86 vals(factory_block.matrixLoadData_.vals),
91 numLeadCurrentStoreVars(0),
92 configuredForLeadCurrent(false),
93 loadLeadCurrent(false),
94 mergeRowColChecked(false),
95 extData(factory_block.externData_),
177 (
const std::vector< std::vector<int> > & depSolnLIDVecRef)
179 int size = expVarLIDs.size();
180 if (size != depSolnLIDVecRef.size())
182 DevelFatal0(*this).in(
"DeviceInstance::registerDepSolnLIDs")
183 <<
"Inconsistent number of LIDs returned from topology";
185 for (
int i = 0; i < size; ++i)
187 if (depSolnLIDVecRef[i].size() != 1)
189 UserError0(*
this) <<
"Problem with value for " << expVarNames[i]
190 <<
". This may be an incorrect usage of a lead current in place of a current through a voltage source.";
192 expVarLIDs[i] = depSolnLIDVecRef[i][0];
216 const std::vector< std::vector<int> > & varList )
219 for (
int i = 0; i < size; ++i)
270 static std::vector<std::string> emptyList;
293 const std::vector< std::vector<int> > & varList )
295 if( varList.size() != 0 )
298 msg =
"DeviceInstance::registerDepStateGIDs\n";
299 msg +=
"\tCall to registerDepStateGIDs for a device which doesn't use it.";
300 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
318 static std::vector<std::string> emptyList;
341 const std::vector< std::vector<int> > & varList )
343 if( varList.size() != 0 )
346 msg =
"DeviceInstance::registerDepStoreGIDs\n";
347 msg +=
"\tCall to registerDepStoreGIDs for a device which doesn't use it.";
348 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
380 bool bsuccess =
true;
410 std::vector<int>::const_iterator firstVar;
411 std::vector<int>::const_iterator lastVar;
412 std::vector<int>::const_iterator iterVar;
413 int localRows = matPtr->getLocalNumRows();
417 Xyce::dout() << std::endl
418 <<
"Loading trivial stamp for " <<
getName() << std::endl;
421 if (
cols.size() < 1)
cols.resize(1);
422 if (
vals.size() < 1)
vals.resize(1);
439 for (iterVar=firstVar; iterVar!=lastVar; ++iterVar)
444 Xyce::dout() <<
"matrix row = " << row << std::endl;
448 Xyce::dout() <<
"\tNOT loading this one - too small" << std::endl;
453 Xyce::dout() <<
"\tloading this one" << std::endl;
460 matPtr->replaceLocalRow(row, count, &
vals[0], &
cols[0]);
496 std::vector<int>::const_iterator firstVar;
497 std::vector<int>::const_iterator lastVar;
498 std::vector<int>::const_iterator iterVar;
499 int localRows = matPtr->getLocalNumRows();
503 Xyce::dout() << std::endl
504 <<
"Zeroing the matrix diagonal for " <<
getName() << std::endl;
507 if (
cols.size() < 1)
cols.resize(1);
508 if (
vals.size() < 1)
vals.resize(1);
525 for (iterVar=firstVar; iterVar!=lastVar; ++iterVar)
530 Xyce::dout() <<
"matrix row = " << row << std::endl;
532 if (row < 0)
continue;
533 if (row >= localRows)
continue;
536 Xyce::dout() <<
"\tloading this one" << std::endl;
542 matPtr->putLocalRow(row, count, &
vals[0], &
cols[0]);
637 (std::vector< std::vector<int> > & stamp_parent,
638 std::vector<int> & map_parent,
639 std::vector< std::vector<int> > & map2_parent,
640 std::vector< std::vector<int> > & stamp,
641 std::vector<int> & map,
642 std::vector< std::vector<int> > & map2,
643 int from,
int to,
int original_size)
645 int i, j, t_index, f_index, t_index2, f_index2, p_size, p_row, f_mod;
648 std::vector< std::vector<int> > fill;
649 std::vector<int> dup;
650 std::vector< std::vector<int> > map2_tmp;
654 std::string msg =
"Internal Error 1 in DeviceInstance::jacStampMap. from <= to.";
657 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
660 if (map_parent.size() == 0)
662 map_parent.resize(original_size);
663 map2_parent.resize(original_size);
664 for (i=0 ; i<original_size ; ++i)
667 map2_parent[i].resize(stamp_parent[i].size());
668 for (j=0 ; j<stamp_parent[i].size() ; ++j)
670 map2_parent[i][j] = j;
674 map2.resize(original_size);
679 for (i=0 ; i<original_size ; ++i)
683 p_row = map_parent[i];
684 for (j=0 ; j<stamp_parent[p_row].size() ; ++j)
686 if (stamp_parent[p_row][j] == from)
688 if (stamp_parent[p_row][j] == to)
691 map2[i].resize(map2_parent[i].size());
694 for (j=0 ; j<map2_parent[i].size() ; ++j)
696 map2[i][j] = map2_parent[i][j];
697 if (stamp_parent[p_row][map2[i][j]] == from)
699 if (stamp_parent[p_row][map2[i][j]] == to)
706 for (j=0 ; j<map2[i].size() ; ++j)
708 if (map2[i][j] > f_index)
711 if (f_index2 >= 0 && t_index2 >= 0)
712 map2[i][f_index2] = map2[i][t_index2];
716 for (j=0 ; j<map2[i].size() ; ++j)
718 if (stamp_parent[p_row][map2[i][j]] > to && stamp_parent[p_row][map2[i][j]] < from)
722 for (j=0 ; j<stamp_parent[p_row].size() ; ++j)
724 if (to > stamp_parent[p_row][j])
730 map2[i][f_index2] = t_index;
734 map.resize(original_size);
735 p_size = stamp_parent.size();
742 for (i=0 ; i<stamp_parent[from].size() && stamp_parent[from][i] < p_size-1 ; ++i)
745 for (j=0 ; j<stamp_parent[to].size() ; ++j)
749 if (stamp_parent[from][i] == stamp_parent[to][j])
757 for (j=0 ; j<map2[to].size() ; ++j)
759 if (stamp_parent[to][map2_tmp[to][j]] > stamp_parent[from][i])
767 stamp.resize(p_size-1);
769 dup.resize(original_size);
771 for (i=1 ; i<original_size ; ++i)
774 for (j=0 ; j<i ; ++j)
776 if (map_parent[i] == map_parent[j])
786 for (i=0 ; i<f_mod ; ++i)
787 map[i] = map_parent[i];
788 map[f_mod] = map[to];
789 for (i=f_mod+1 ; i<original_size ; ++i)
790 map[i] = map_parent[i]-1;
792 for (i=1 ; i<original_size ; ++i)
795 map[i] = map[dup[i]];
803 if (map[from] != map[to]) {
804 for (i=from+1 ; i<original_size ; ++i) {
805 if (map[i] == map[to]) {
810 if (map_2_from == from) {
811 std::string msg =
"Internal Error 2 in DeviceInstance::jacStampMap";
812 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
816 for (i=0 ; i<stamp_parent[to].size() && stamp_parent[to][i] < p_size-1 ; ++i)
819 for (j=0 ; j<stamp_parent[from].size() ; ++j)
823 if (stamp_parent[to][i] == stamp_parent[from][j])
831 for (j=0 ; j<map2[map_2_from].size() ; ++j)
833 if (stamp_parent[from][map2_tmp[map_2_from][j]] > stamp_parent[to][i])
835 ++map2[map_2_from][j];
842 for (i=0 ; i<p_size ; ++i)
844 fill[i].resize(p_size);
845 for (j=0 ; j<p_size ; ++j)
847 for (j=0 ; j<stamp_parent[i].size() ; ++j)
848 fill[i][stamp_parent[i][j]] = 1;
850 for (i=0 ; i<p_size ; ++i)
852 fill[to][i] += fill[from][i];
854 for (i=0 ; i<p_size ; ++i)
856 fill[i][to] += fill[i][from];
858 for (i=from ; i<p_size-1 ; ++i)
860 for (j=0 ; j<p_size ; ++j)
861 fill[i][j] = fill[i+1][j];
862 for (j=0 ; j<p_size ; ++j)
863 fill[j][i] = fill[j][i+1];
865 for (i=0 ; i<p_size-1 ; ++i)
868 for (j=0 ; j<p_size-1 ; ++j)
871 stamp[i].push_back(j);
904 (std::vector< std::vector<int> > & stamp_parent,
905 std::vector< std::vector<int> > & map2_parent,
906 std::vector< std::vector<int> > & stamp,
907 std::vector< std::vector<int> > & map2)
910 int current_size = stamp_parent.size();
912 if (DEBUG_DEVICE && getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
914 Xyce::dout() << Xyce::section_divider << std::endl
915 <<
"Begin DeviceInstance::jacStampMap_fixOrder." << std::endl
916 << Xyce::section_divider << std::endl;
921 if (map2_parent.size() == 0)
923 map2_parent.resize(current_size);
924 for (i=0 ; i<current_size ; ++i)
926 map2_parent[i].resize(stamp_parent[i].size());
927 for (j=0 ; j<stamp_parent[i].size() ; ++j)
929 map2_parent[i][j] = j;
938 std::vector< std::vector<int> > denseStamp(current_size);
939 for (i=0;i<current_size;++i)
941 denseStamp[i].resize(current_size,-1);
943 for (j=0;j<stamp_parent[i].size();++j)
945 int denseCol = stamp_parent[i][j];
946 denseStamp[i][denseCol] = j;
955 stamp.resize(current_size);
956 map2.resize(current_size);
957 for (i=0;i<current_size;++i)
959 for (j=0;j<current_size;++j)
961 int colMapIndex = denseStamp[i][j];
964 stamp[i].push_back(j);
968 int stampRowLength=stamp[i].size();
969 map2[i].resize(stampRowLength, 0);
972 for (j=0;j<current_size;++j)
974 int colMapIndex = denseStamp[i][j];
975 if (colMapIndex!=-1 && colMapIndex < stampRowLength)
977 map2[i][colMapIndex] = k;
983 if (DEBUG_DEVICE && getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
985 Xyce::dout() <<
"From inside of DeviceInstance::jacStampMap_fixOrder:" << std::endl
986 <<
"The original parent stamp is:" << std::endl;
987 outputJacStamp(stamp_parent);
988 Xyce::dout() <<
"The new reduced stamp is:" << std::endl;
989 outputJacStamp(stamp);
990 Xyce::dout() <<
"The dense stamp is:" << std::endl;
991 outputJacStamp(denseStamp);
993 Xyce::dout() <<
"The new map is:" << std::endl;
994 outputJacStamp(map2);
996 Xyce::dout() << Xyce::section_divider << std::endl
997 <<
"End DeviceInstance::jacStampMap_fixOrder."<<std::endl
998 << Xyce::section_divider << std::endl;
1014 for (i=0 ; i<jac.size() ; ++i)
1016 Xyce::dout() <<
"Row: " << i <<
" ::";
1017 for (j=0 ; j<jac[i].size() ; ++j)
1018 Xyce::dout() <<
" " << jac[i][j];
1019 Xyce::dout() << std::endl;
1021 Xyce::dout() << std::endl;
1033 const std::vector<std::vector<int> > & jacMap2)
1037 for (i=0 ; i<jacMap.size() ; ++i)
1039 Xyce::dout() <<
"Row " << i <<
": ";
1040 for (j=0; j < jacMap2[i].size(); j++)
1042 Xyce::dout() << jacMap[i]<<
"," << jacMap2[i][j] <<
" ";
1044 Xyce::dout() << std::endl;
1047 Xyce::dout() << std::endl;
1066 const std::vector<int> & counts,
1067 const std::vector<int> & GIDs,
1068 const std::vector< std::vector<int> > & jacGIDs )
1078 int extSize = counts[0];
1079 int intSize = counts[1];
1080 int expSize = counts[2];
1081 int size = GIDs.size();
1084 std::map<int,int> testIndexMap;
1088 Xyce::dout() <<
"DeviceInstance::registerGIDData for " <<
getName() << std::endl
1089 <<
" extSize = " << extSize << std::endl
1090 <<
" intSize = " << intSize << std::endl
1091 <<
" expSize = " << expSize << std::endl
1092 <<
" GIDs.size = " << size << std::endl
1093 <<
" jacGIDs.size = " << jacGIDs.size () << std::endl
1099 for (i = 0; i < extSize; ++i )
1101 if ( testIndexMap.find(GIDs[i]) == testIndexMap.end() )
1103 extGIDList.push_back( index_pair( GIDs[i], 1 ) );
1104 testIndexMap[GIDs[i]] = 1;
1108 testIndexMap.clear ();
1112 for (; i<intSize+extSize;++i)
1114 if ( testIndexMap.find(GIDs[i]) == testIndexMap.end() )
1116 intGIDList.push_back( index_pair( GIDs[i], 1 ) );
1117 testIndexMap[GIDs[i]] = 1;
1121 testIndexMap.clear ();
1126 for (; i<intSize+extSize+expSize;++i)
1128 if ( testIndexMap.find(GIDs[i]) == testIndexMap.end() )
1131 testIndexMap[GIDs[i]] = 1;
1140 for (
int itmp = 0; itmp < expS; ++itmp)
1145 testIndexMap.clear ();
1149 for(i = 0; i < jacGIDs.size () ; ++i )
1152 if ( testIndexMap.find(GIDs[i]) == testIndexMap.end() )
1154 testIndexMap[GIDs[i]] = 1;
1156 std::map<int,int> testJMap;
1158 int length = jacGIDs[i].size();
1159 for(
int j = 0; j < length; ++j )
1161 if ( testJMap.find(jacGIDs[i][j]) == testJMap.end () )
1163 indexPairList.push_back( index_pair( GIDs[i], jacGIDs[i][j] ) );
1164 testJMap[jacGIDs[i][j]] = 1;
1172 std::vector<int>::const_iterator begin = GIDs.begin ();
1173 std::vector<int>::const_iterator end = GIDs.end ();
1174 std::vector<int>::const_iterator iterGID;
1176 Xyce::dout() <<
" Complete GIDs :" << std::endl;
1177 for (iterGID=begin;iterGID!=end ;++iterGID)
1179 Xyce::dout() <<
"\tgid=" << *iterGID << std::endl;
1181 Xyce::dout() << std::endl;
1183 std::list<index_pair>::iterator first;
1184 std::list<index_pair>::iterator last;
1185 std::list<index_pair>::iterator iter;
1187 Xyce::dout() <<
" intGIDList :" << std::endl;
1190 for (iter=first;iter!=last;++iter)
1192 Xyce::dout() <<
"\tgid=" << iter->row << std::endl;
1194 Xyce::dout() << std::endl;
1196 Xyce::dout() <<
" extGIDList :" << std::endl;
1199 for (iter=first;iter!=last;++iter)
1201 Xyce::dout() <<
"\tgid=" << iter->row << std::endl;
1203 Xyce::dout() << std::endl;
1206 Xyce::dout() <<
" indexPairList :" << std::endl;
1209 for (iter=first;iter!=last;++iter)
1211 Xyce::dout() <<
" row=" << iter->row <<
" col=" << iter->col << std::endl;
1213 Xyce::dout() << std::endl << std::endl;
1241 Report::DevelFatal0().in(
"DeviceInstance::processParams")
1242 <<
"DeviceInstance::processParams() must be implemented for device " <<
getName();
1295 Report::DevelFatal().in(
"DeviceInstance::setInternalState") <<
"does not exist for this device " <<
getName();