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>
62 #include <N_UTL_FeatureTest.h>
68 static const std::vector<std::string> emptyList;
83 :
DeviceEntity(parametric_data, factory_block.solverState_, factory_block.deviceOptions_, instance_block.getNetlistLocation().getFilename(), instance_block.getNetlistLocation().getLineNumber()),
84 name_(instance_block.getInstanceName()),
85 mlData(factory_block.matrixLoadData_),
86 extData(factory_block.externData_),
87 configuredForLeadCurrent(false),
88 cols(factory_block.matrixLoadData_.cols),
89 vals(factory_block.matrixLoadData_.vals),
99 numLeadCurrentVars(0),
100 numLeadCurrentStoreVars(0),
101 loadLeadCurrent(false),
102 numBranchDataVars(0),
103 numBranchDataVarsIfAllocated(0),
104 mergeRowColChecked(false)
187 const std::vector< std::vector<int> > & depSolnLIDVecRef)
190 if (size != depSolnLIDVecRef.size())
192 DevelFatal0(*this).in(
"DeviceInstance::registerDepSolnLIDs")
193 <<
"Inconsistent number of LIDs returned from topology";
195 for (
int i = 0; i < size; ++i)
197 if (depSolnLIDVecRef[i].size() != 1)
200 <<
". This may be an incorrect usage of a lead current in place of a current through a voltage source.";
224 const std::vector< std::vector<int> > & varList )
227 for (
int i = 0; i < size; ++i)
284 const std::vector< std::vector<int> > & varList )
286 if( varList.size() != 0 )
288 Report::DevelFatal().in(
"DeviceInstance::registerDepStateGIDs")
289 <<
"Call to registerDepStateGIDs for a device which doesn't use it.";
328 const std::vector< std::vector<int> > & varList )
330 if( varList.size() != 0 )
332 Report::DevelFatal().in(
"DeviceInstance::registerDepStoreGIDs")
333 <<
"Call to registerDepStoreGIDs for a device which doesn't use it.";
372 const std::vector< std::vector<int> > & varList )
374 if( varList.size() != 0 )
376 Report::DevelFatal().in(
"DeviceInstance::registerDepLeadCurrentGIDs")
377 <<
"Call to registerDepLeadCurrentGIDs for a device which doesn't use it.";
391 bool bsuccess =
true;
417 std::vector<int>::const_iterator firstVar;
418 std::vector<int>::const_iterator lastVar;
419 std::vector<int>::const_iterator iterVar;
421 int localRows = matPtr->getLocalNumRows();
423 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
425 Xyce::dout() << std::endl
426 <<
"Loading trivial stamp for " <<
getName() << std::endl;
429 if (
cols.size() < 1)
cols.resize(1);
430 if (
vals.size() < 1)
vals.resize(1);
432 for (
int i = 0; i < 2; ++i)
447 for (iterVar=firstVar; iterVar!=lastVar; ++iterVar)
451 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
453 Xyce::dout() <<
"matrix row = " << row << std::endl;
457 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
459 Xyce::dout() <<
"\tNOT loading this one - too small" << std::endl;
464 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
466 Xyce::dout() <<
"\tloading this one" << std::endl;
474 matPtr->replaceLocalRow(row, count, &
vals[0], &
cols[0]);
506 std::vector<int>::const_iterator firstVar;
507 std::vector<int>::const_iterator lastVar;
508 std::vector<int>::const_iterator iterVar;
510 int localRows = matPtr->getLocalNumRows();
512 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
514 Xyce::dout() << std::endl
515 <<
"Zeroing the matrix diagonal for " <<
getName() << std::endl;
518 if (
cols.size() < 1)
cols.resize(1);
519 if (
vals.size() < 1)
vals.resize(1);
521 for (
int i = 0; i < 2; ++i)
536 for (iterVar=firstVar; iterVar!=lastVar; ++iterVar)
540 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
542 Xyce::dout() <<
"matrix row = " << row << std::endl;
545 if (row < 0)
continue;
546 if (row >= localRows)
continue;
548 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
550 Xyce::dout() <<
"\tloading this one" << std::endl;
557 matPtr->putLocalRow(row, count, &
vals[0], &
cols[0]);
650 std::vector<int> & map_parent,
653 std::vector<int> & map,
661 Report::DevelFatal().in(
"DeviceInstance::jacStampMap")
662 <<
"From index " << from <<
" <= " <<
" to index " << to;
665 if (map_parent.size() == 0)
667 map_parent.resize(original_size);
668 map2_parent.resize(original_size);
669 for (
int i = 0; i < original_size; ++i)
672 map2_parent[i].resize(stamp_parent[i].size());
673 for (
int j = 0; j < stamp_parent[i].size(); ++j)
675 map2_parent[i][j] = j;
679 map2.resize(original_size);
684 for (
int i = 0; i < original_size; ++i)
688 int p_row = map_parent[i];
689 for (
int j = 0; j < stamp_parent[p_row].size(); ++j)
691 if (stamp_parent[p_row][j] == from)
693 if (stamp_parent[p_row][j] == to)
696 map2[i].resize(map2_parent[i].size());
699 for (
int j = 0; j < map2_parent[i].size(); ++j)
701 map2[i][j] = map2_parent[i][j];
702 if (stamp_parent[p_row][map2[i][j]] == from)
704 if (stamp_parent[p_row][map2[i][j]] == to)
711 for (
int j = 0; j < map2[i].size(); ++j)
713 if (map2[i][j] > f_index)
716 if (f_index2 >= 0 && t_index2 >= 0)
717 map2[i][f_index2] = map2[i][t_index2];
721 for (
int j = 0; j < map2[i].size(); ++j)
723 if (stamp_parent[p_row][map2[i][j]] > to && stamp_parent[p_row][map2[i][j]] < from)
727 for (
int j = 0; j < stamp_parent[p_row].size(); ++j)
729 if (to > stamp_parent[p_row][j])
735 map2[i][f_index2] = t_index;
739 map.resize(original_size);
740 int p_size = stamp_parent.size();
746 for (
int i = 0; i < stamp_parent[from].size() && stamp_parent[from][i] < p_size-1; ++i)
748 bool new_col =
false;
749 for (
int j = 0; j<stamp_parent[to].size(); ++j)
753 if (stamp_parent[from][i] == stamp_parent[to][j])
761 for (
int j = 0; j < map2[to].size(); ++j)
763 if (stamp_parent[to][map2_tmp[to][j]] > stamp_parent[from][i])
771 stamp.resize(p_size-1);
773 std::vector<int> dup(original_size);
776 for (
int i = 1; i < original_size; ++i)
779 for (
int j = 0; j < i; ++j)
781 if (map_parent[i] == map_parent[j])
791 for (
int i = 0; i < f_mod; ++i)
792 map[i] = map_parent[i];
793 map[f_mod] = map[to];
795 for (
int i = f_mod + 1; i < original_size; ++i)
796 map[i] = map_parent[i]-1;
798 for (
int i = 1; i < original_size; ++i)
801 map[i] = map[dup[i]];
808 int map_2_from = from;
809 if (map[from] != map[to]) {
810 for (
int i = from + 1; i < original_size; ++i) {
811 if (map[i] == map[to]) {
816 if (map_2_from == from) {
817 Report::DevelFatal().in(
"DeviceInstance::jacStampMap") <<
"Internal Error 2";
821 for (
int i = 0; i < stamp_parent[to].size() && stamp_parent[to][i] < p_size-1; ++i)
823 bool new_col =
false;
824 for (
int j = 0; j < stamp_parent[from].size(); ++j)
828 if (stamp_parent[to][i] == stamp_parent[from][j])
836 for (
int j = 0; j < map2[map_2_from].size(); ++j)
838 if (stamp_parent[from][map2_tmp[map_2_from][j]] > stamp_parent[to][i])
840 ++map2[map_2_from][j];
847 for (
int i = 0; i < p_size; ++i)
849 fill[i].resize(p_size);
850 for (
int j = 0 ; j < p_size; ++j)
852 for (
int j = 0; j < stamp_parent[i].size(); ++j)
853 fill[i][stamp_parent[i][j]] = 1;
855 for (
int i = 0; i < p_size; ++i)
857 fill[to][i] += fill[from][i];
859 for (
int i = 0; i < p_size; ++i)
861 fill[i][to] += fill[i][from];
863 for (
int i = from; i < p_size - 1; ++i)
865 for (
int j = 0; j < p_size; ++j)
866 fill[i][j] = fill[i+1][j];
867 for (
int j = 0; j < p_size; ++j)
868 fill[j][i] = fill[j][i+1];
870 for (
int i = 0; i < p_size - 1 ; ++i)
873 for (
int j = 0; j < p_size - 1; ++j)
876 stamp[i].push_back(j);
914 int current_size = stamp_parent.size();
916 if (DEBUG_DEVICE && isActive(Diag::DEVICE_JACSTAMP) &&
getSolverState().debugTimeFlag)
918 Xyce::dout() << Xyce::section_divider << std::endl
919 <<
"Begin DeviceInstance::jacStampMap_fixOrder." << std::endl
920 << Xyce::section_divider << std::endl;
925 if (map2_parent.size() == 0)
927 map2_parent.resize(current_size);
928 for (
int i = 0; i < current_size; ++i)
930 map2_parent[i].resize(stamp_parent[i].size());
931 for (
int j = 0; j < stamp_parent[i].size(); ++j)
933 map2_parent[i][j] = j;
943 for (
int i = 0; i < current_size; ++i)
945 denseStamp[i].resize(current_size,-1);
947 for (
int j = 0; j < stamp_parent[i].size(); ++j)
949 int denseCol = stamp_parent[i][j];
950 denseStamp[i][denseCol] = j;
959 stamp.resize(current_size);
960 map2.resize(current_size);
961 for (
int i = 0; i < current_size; ++i)
963 for (
int j = 0; j < current_size; ++j)
965 int colMapIndex = denseStamp[i][j];
968 stamp[i].push_back(j);
972 int stampRowLength=stamp[i].size();
973 map2[i].resize(stampRowLength, 0);
975 for (
int j = 0, k = 0; j < current_size; ++j)
977 int colMapIndex = denseStamp[i][j];
978 if (colMapIndex!=-1 && colMapIndex < stampRowLength)
980 map2[i][colMapIndex] = k;
986 if (DEBUG_DEVICE && isActive(Diag::DEVICE_JACSTAMP) &&
getSolverState().debugTimeFlag)
988 Xyce::dout() <<
"From inside of DeviceInstance::jacStampMap_fixOrder:" << std::endl
989 <<
"The original parent stamp is:" << std::endl;
991 Xyce::dout() <<
"The new reduced stamp is:" << std::endl;
993 Xyce::dout() <<
"The dense stamp is:" << std::endl;
996 Xyce::dout() <<
"The new map is:" << std::endl;
999 Xyce::dout() << Xyce::section_divider << std::endl
1000 <<
"End DeviceInstance::jacStampMap_fixOrder."<<std::endl
1001 << Xyce::section_divider << std::endl;
1017 for (
int i = 0 ; i < jac.size(); ++i)
1019 Xyce::dout() <<
"Row: " << i <<
" ::";
1020 for (
int j = 0 ; j < jac[i].size(); ++j)
1021 Xyce::dout() <<
" " << jac[i][j];
1023 Xyce::dout() << std::endl;
1025 Xyce::dout() << std::endl;
1038 const std::vector<int> & jacMap,
1041 for (
int i = 0 ; i < jacMap.size(); ++i)
1043 Xyce::dout() <<
"Row " << i <<
": ";
1044 for (
int j = 0; j < jacMap2[i].size(); j++)
1045 Xyce::dout() << jacMap[i]<<
"," << jacMap2[i][j] <<
" ";
1047 Xyce::dout() << std::endl;
1050 Xyce::dout() << std::endl;
1069 const std::vector<int> & counts,
1077 int extSize = counts[0];
1078 int intSize = counts[1];
1079 int expSize = counts[2];
1080 int size = GIDs.size();
1082 std::map<int,int> testIndexMap;
1084 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1086 Xyce::dout() <<
"DeviceInstance::registerGIDData for " <<
getName() << std::endl
1087 <<
" extSize = " << extSize << std::endl
1088 <<
" intSize = " << intSize << std::endl
1089 <<
" expSize = " << expSize << std::endl
1090 <<
" GIDs.size = " << size << std::endl
1091 <<
" jacGIDs.size = " << jacGIDs.size () << std::endl
1100 for (; gid_index < extSize; ++gid_index )
1102 if ( testIndexMap.find(GIDs[gid_index]) == testIndexMap.end() )
1104 extGIDList.push_back( IndexPair( GIDs[gid_index], 1 ) );
1105 testIndexMap[GIDs[gid_index]] = 1;
1109 testIndexMap.clear ();
1113 for (; gid_index < intSize + extSize; ++gid_index)
1115 if ( testIndexMap.find(GIDs[gid_index]) == testIndexMap.end() )
1117 intGIDList.push_back( IndexPair( GIDs[gid_index], 1 ) );
1118 testIndexMap[GIDs[gid_index]] = 1;
1122 testIndexMap.clear ();
1127 for (; gid_index < intSize + extSize + expSize; ++gid_index)
1129 if ( testIndexMap.find(GIDs[gid_index]) == testIndexMap.end() )
1132 testIndexMap[GIDs[gid_index]] = 1;
1142 for (
int i = 0; i < expS; ++i)
1147 testIndexMap.clear();
1151 for (
int i = 0; i < jacGIDs.size () ; ++i )
1153 if ( testIndexMap.find(GIDs[i]) == testIndexMap.end() )
1155 testIndexMap[GIDs[i]] = 1;
1157 std::map<int,int> testJMap;
1159 int length = jacGIDs[i].size();
1160 for(
int j = 0; j < length; ++j )
1162 if ( testJMap.find(jacGIDs[i][j]) == testJMap.end () )
1164 indexPairList.push_back( IndexPair( GIDs[i], jacGIDs[i][j] ) );
1165 testJMap[jacGIDs[i][j]] = 1;
1171 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1173 Xyce::dout() <<
" Complete GIDs :" << std::endl;
1174 for (std::vector<int>::const_iterator it = GIDs.begin(), end = GIDs.end(); it != end; ++it)
1175 Xyce::dout() <<
"\tgid=" << *it << std::endl;
1177 Xyce::dout() << std::endl;
1179 Xyce::dout() <<
" intGIDList :" << std::endl;
1180 for (IndexPairVector::const_iterator it =
intGIDList.begin(), end =
intGIDList.end(); it != end; ++it)
1181 Xyce::dout() <<
"\tgid=" << (*it).row << std::endl;
1183 Xyce::dout() << std::endl;
1185 Xyce::dout() <<
" extGIDList :" << std::endl;
1186 for (IndexPairVector::const_iterator it =
extGIDList.begin(), end =
extGIDList.end(); it != end; ++it)
1187 Xyce::dout() <<
"\tgid=" << (*it).row << std::endl;
1189 Xyce::dout() << std::endl;
1192 Xyce::dout() <<
" indexPairList :" << std::endl;
1194 Xyce::dout() <<
" row=" << (*it).row <<
" col=" << (*it).col << std::endl;
1196 Xyce::dout() << std::endl << std::endl;
1224 Report::DevelFatal0().in(
"DeviceInstance::processParams")
1225 <<
"DeviceInstance::processParams() must be implemented for device " <<
getName();
1241 Report::DevelFatal().in(
"DeviceInstance::setInternalState") <<
"does not exist for this device " <<
getName();
const InstanceName & getName() const
virtual void registerGIDData(const std::vector< int > &counts, const IdVector &GIDs, const JacobianStamp &jacGIDs)
virtual void enableLeadCurrentCalc()
const DeviceOptions & deviceOptions_
IndexPairVector intGIDList
virtual bool processParams()
std::vector< int > devConMap
std::vector< double > & vals
const ExternData & externData_
Pure virtual class to augment a linear system.
void outputJacMaps(const std::vector< int > &jacMap, const JacobianStamp &jacMap2)
const std::string & getEncodedName() const
Return the instance name encoded as: [s:]*xname [s:]*Ytype!name [s:]*Utype!name!count.
bool configuredForLeadCurrent
IndexPairVector extGIDList
virtual bool enablePDEContinuation(int &max_PDE_continuation_steps)
virtual void registerDepSolnGIDs(const std::vector< IdVector > &varList)
void jacStampMap_fixOrder(const JacobianStamp &stamp_parent, JacobianStamp &map2_parent, JacobianStamp &stamp, JacobianStamp &map2)
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
virtual bool setInternalState(const DeviceState &state)
virtual bool testDAEMatrices(const std::vector< const std::string * > &nameVec)
virtual const std::vector< std::string > & getDepStoreVars()
virtual void registerDepStateGIDs(const std::vector< IdVector > &varList)
std::vector< int > IdVector
NumericalJacobian * numJacPtr
IndexPairVector indexPairList
virtual ~DeviceInstance()
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
virtual void registerDepSolnLIDs(const std::vector< IdVector > &depSolnLIDVecRef)
virtual const std::vector< std::string > & getDepLeadCurrentVars()
const DeviceOptions & getDeviceOptions() const
bool testDAEMatrices(DeviceInstance &instance, const std::vector< const std::string * > &nameVec)
virtual void registerDepLeadCurrentGIDs(const std::vector< IdVector > &varList)
std::vector< std::vector< int > > JacobianStamp
int numBranchDataVarsIfAllocated
virtual bool updateTemperature(const double &temp_tmp)
Class ParametricData manages the configuration information and the parameter binding map...
bool trivialStampLoader(Linear::Matrix *matPtr)
virtual bool disablePDEContinuation()
virtual bool setInitialGuess()
Linear::Matrix * dFdxMatrixPtr
virtual double getMaxTimeStepSize()
const SolverState & solverState_
std::vector< int > expVarLIDs
void outputJacStamp(const JacobianStamp &jac)
virtual void setPDEContinuationBeta(double beta)
std::vector< int > expVarGIDs
virtual const std::vector< std::string > & getDepStateVars()
IdVector devLIDs
devLIDs is a combined LID vector, containing int, ext, and expVar ID's.
void jacStampMap(const JacobianStamp &stamp_parent, IdVector &map_parent, JacobianStamp &map2_parent, JacobianStamp &stamp, IdVector &map, JacobianStamp &map2, int from, int to, int original_size)
double defaultMaxTimeStep
mosfet homotopy:
virtual void registerDepStoreGIDs(const std::vector< IdVector > &varList)
const SolverState & getSolverState() const
virtual void setPDEContinuationAlpha(double alpha)
virtual bool loadTrivialDAE_FMatrixStamp()
MatrixLoadData & matrixLoadData_
bool zeroMatrixDiagonal(Linear::Matrix *matPtr)
virtual std::ostream & printName(std::ostream &os) const
const ExternData & extData
InstanceBlock represent a device instance line from the netlist.
std::vector< std::string > expVarNames
std::vector< int > & cols
virtual const std::vector< std::string > & getDepSolnVars()
int numLeadCurrentStoreVars