46 #include <Xyce_config.h>
51 #include <N_UTL_Misc.h>
64 #include <N_LOA_Loader.h>
66 #include <N_UTL_OptionBlock.h>
68 #include <N_LAS_Matrix.h>
69 #include <N_LAS_Vector.h>
71 #include <N_LAS_Solver.h>
72 #include <N_LAS_Problem.h>
74 #include <N_LAS_System.h>
75 #include <N_LAS_Builder.h>
77 #include <N_ERH_ErrorMgr.h>
80 #include <N_TOP_Topology.h>
82 #include <N_UTL_Expression.h>
84 #include <N_PDS_ParMap.h>
85 #include <N_PDS_Comm.h>
87 #include <N_IO_CmdParse.h>
88 #include <N_IO_PkgOptionsMgr.h>
90 #include <Epetra_CrsMatrix.h>
107 N_TOP_Topology & topTmp,
121 matrixDiagonalPtr_(0),
123 jacobianMatrixPtr_(0),
124 nextSolVectorPtrPtr_(0),
125 currSolVectorPtrPtr_(0),
126 savedRHSVectorPtr_(0),
127 savedNewtonVectorPtr_(0),
131 gidsSetUpFlag_(false)
152 #ifdef Xyce_PARALLEL_MPI
155 columnMapPtr_ =
new N_PDS_ParMap( &(const_cast<Epetra_Map&>(col_map)),
190 for (
int ivec=0; ivec<vecSize ;++ivec)
237 std::string netListFile =
"";
258 bool bsuccess =
true;
260 for (std::list<N_UTL_Param>::const_iterator it_tpL = OB.getParams().begin();
261 it_tpL != OB.getParams().end(); ++ it_tpL)
264 if (it_tpL->uTag() ==
"DEBUGLEVEL")
293 (
const std::map<std::string,double> & inputMap)
295 bool bsuccess =
true;
298 int idSize = inputMap.size();
299 currentGIDs_.resize(idSize);
300 currentLIDs_.resize(idSize);
301 vsrcPosGIDs_.resize(idSize);
302 vsrcPosLIDs_.resize(idSize);
303 for (
int i=0; i<idSize ;++i)
305 dIdxPtrVector_.push_back(lasSysPtr_->builder().createVector());
306 currentGIDs_[i] = -1;
307 currentLIDs_[i] = -1;
308 vsrcPosGIDs_[i] = -1;
309 vsrcPosLIDs_[i] = -1;
314 std::map<std::string,double>::const_iterator iterM = inputMap.begin();
315 std::map<std::string,double>::const_iterator endM = inputMap.end ();
317 for (; iterM != endM; ++i, ++iterM)
321 ExtendedString src = iterM->first;
323 std::string sourceName = src;
329 std::list<int> GIDList, extGIDList;
330 top_.getNodeSVarGIDs(NodeID(sourceName, Xyce::_DNODE), GIDList, extGIDList, type);
332 std::list<int>::iterator iterI;
333 if (!(GIDList.empty ()))
335 iterI = GIDList.begin();
336 currentGIDs_[i] = *iterI;
337 currentLIDs_[i] = dIdxPtrVector_[0]->pmap()->globalToLocalIndex(currentGIDs_[i]);
339 iterI = extGIDList.begin();
340 vsrcPosGIDs_[i] = *iterI;
341 vsrcPosLIDs_[i] = dIdxPtrVector_[0]->pmap()->globalToLocalIndex(vsrcPosGIDs_[i]);
343 if( vsrcPosLIDs_[i] == -1 )
345 std::string msg =
"ConductanceExtractor::setupIDs_";
346 msg +=
" The " + sourceName +
" source has the positive node"
347 " owned by another processor. The 2-level solve can't handle that.";
348 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
353 int vnegGID = *iterI;
356 std::string msg =
"ConductanceExtractor::setupIDs_";
357 msg +=
" The " + sourceName +
" source has the negative node"
358 " connected to something other than ground! The 2-level solve can't handle that.";
359 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
365 #ifdef Xyce_DEBUG_CONDUCTANCE
368 cout <<
"current GIDs: " << std::endl;
369 for(
int i1=0; i1 < idSize; ++i1 )
371 cout <<
" currentGIDs_["<<i1<<
"] = " << currentGIDs_[i1] <<
", currentLIDs_["<<i1<<
"] = " << currentLIDs_[i1] << std::endl;
374 cout <<
"Vsrc pos equation rows: " << std::endl;
375 for(
int i1=0; i1 < idSize; ++i1 )
377 cout <<
" vsrcPosGIDs_["<<i1<<
"] = " << vsrcPosGIDs_[i1] <<
", vsrcPosLIDs_["<<i1<<
"] = " << vsrcPosLIDs_[i1] << std::endl;
382 gidsSetUpFlag_ =
true;
397 bool bsuccess =
true;
411 N_LAS_Vector * currentVec;
414 for(
int iC_row=0; iC_row < idSize; ++iC_row )
416 #ifdef Xyce_PARALLEL_MPI
422 currentVec->putScalar(0.0);
428 int numEntries = rowLength;
429 std::vector<double> coeffs(rowLength, 0.0);
430 std::vector<int> colIndices(rowLength, -1);
433 (iRow, rowLength, numEntries, &coeffs[0], &colIndices[0]);
435 for (
int ic=0;ic<rowLength;++ic)
439 int gid = colIndices[ic];
443 for (
int icol=0;icol<rowLength;++icol)
445 double val = coeffs[icol];
446 int gid = colIndices[icol];
448 currentVec->setElementByGlobalIndex(gid, val, 0);
451 currentVec->fillComplete();
453 #ifdef Xyce_PARALLEL_MPI
457 #ifdef Xyce_DEBUG_CONDUCTANCE
460 cout <<
"\ndIdx[" << iC_row <<
"]:" << std::endl;
478 const std::map<std::string,double> & inputMap,
479 std::vector<double> & outputVector,
480 std::vector< std::vector<double> > & jacobian )
483 bool bsuccess =
true;
485 #ifdef Xyce_DEBUG_CONDUCTANCE
488 cout << subsection_divider << std::endl;
489 cout <<
"ConductanceExtractor::extract" << std::endl;
490 cout << subsection_divider << std::endl;
494 if (inputMap.empty() ||
495 outputVector.empty() ||
522 outputVector[i] = solnVecPtr->getElementByGlobalIndex(index1);
524 outputVector[i] = 0.0;
527 #ifdef Xyce_PARALLEL_MPI
530 std::vector<double> tmpVector(idSize,0.0);
531 for(
int i = 0; i < idSize; ++i )
533 tmpVector[i] = outputVector[i];
534 outputVector[i] = 0.0;
537 comm->sumAll( &(tmpVector[0]), &(outputVector[0]), idSize );
540 #ifdef Xyce_DEBUG_CONDUCTANCE
544 for (itmp=0;itmp < outputVector.size();++itmp)
546 cout <<
"currentVector["<< itmp <<
"] = " << outputVector[itmp]<<std::endl;
598 double diagInfNorm = 0.0;
606 if (diagInfNorm < 1.0e-30)
608 #ifdef Xyce_DEBUG_CONDUCTANCE
609 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_WARNING_0,
610 "\n\tJacobian for inner problem not loaded. Forcing a load.\n");
620 std::map<std::string,double>::const_iterator iterM = inputMap.begin();
621 std::map<std::string,double>::const_iterator endM = inputMap.end ();
623 for (;iV_col<idSize;++iV_col,++iterM)
630 (*dfdvVectorPtr_)[irow] = 1.0;
635 for (;iC_row<idSize;++iC_row)
640 #ifdef Xyce_DEBUG_CONDUCTANCE
643 std::string vsrcName = iterM->first;
645 cout <<
"dIdv = " << dIdv << std::endl;
649 jacobian[iC_row][iV_col] = dIdv;
661 #ifdef Xyce_VERBOSE_CONDUCTANCE
683 bool bsuccess =
true;
691 for (
int i=0; i<idSize ;++i)
702 ExtendedString src = isoName;
704 std::string sourceName = src;
710 std::list<int> GIDList, extGIDList;
711 top_.getNodeSVarGIDs(NodeID(sourceName, Xyce::_DNODE), GIDList, extGIDList, type);
713 if (!(GIDList.empty ()))
715 std::list<int>::iterator gidIter = GIDList.begin();
716 std::list<int>::iterator gidExtIter = extGIDList.begin();
719 for (i=0;i<idSize;++i,++gidIter,++gidExtIter)
727 for (i=0;i<idSize;++i,++gidExtIter)
736 std::string msg =
"ConductanceExtractor::setupISO_IDs_";
737 msg +=
" The " + sourceName +
" source has the positive node"
738 " owned by another processor. The 2-level solve can't handle that.";
739 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
748 #ifdef Xyce_DEBUG_CONDUCTANCE
751 cout <<
"current GIDs: " << std::endl;
752 for(
int i1=0; i1 < idSize; ++i1 )
754 cout <<
" currentGIDs_["<<i1<<
"] = " <<
currentGIDs_[i1] << std::endl;
757 cout <<
"Vsrc pos equation rows: " << std::endl;
758 for(
int i1=0; i1 < idSize; ++i1 )
760 cout <<
" vsrcPosGIDs_["<<i1<<
"] = " <<
vsrcPosGIDs_[i1] << std::endl;
787 (
const std::string & isoName, std::vector< std::vector<double> > & jacobian )
789 bool bsuccess =
true;
791 int idSize = jacobian.size();
793 #ifdef Xyce_DEBUG_CONDUCTANCE
796 cout << subsection_divider << std::endl;
797 cout <<
"ConductanceExtractor::extract - iso2" << std::endl;
798 cout << subsection_divider << std::endl;
804 setupISO2_IDs_(isoName);
808 savedRHSVectorPtr_->putScalar(0.0);
809 savedRHSVectorPtr_->addVec(1.0, *(rhsVectorPtr_));
811 savedNewtonVectorPtr_->putScalar(0.0);
812 savedNewtonVectorPtr_->addVec(1.0, *(NewtonVectorPtr_));
815 bool b1 = setup_dIdX_Vectors_(); bsuccess = bsuccess && b1;
820 for (;iV_col<idSize;++iV_col)
823 dfdvVectorPtr_->putScalar(0.0);
824 int irow = currentLIDs_[iV_col];
827 (*dfdvVectorPtr_)[irow] = 1.0;
829 lasSolverPtr_->solve();
832 for (;iC_row<idSize;++iC_row)
835 double dIdv = dIdxPtrVector_[iC_row]->dotProduct(*(dxdvVectorPtr_));
837 #ifdef Xyce_DEBUG_CONDUCTANCE
840 std::string tmpName =
"unknown";
841 printPetraObjects_ (tmpName);
842 cout <<
"dIdv = " << dIdv << std::endl;
846 jacobian[iC_row][iV_col] = dIdv;
852 rhsVectorPtr_->putScalar(0.0);
853 rhsVectorPtr_->addVec(1.0, *(savedRHSVectorPtr_));
855 NewtonVectorPtr_->putScalar(0.0);
856 NewtonVectorPtr_->addVec(1.0, *(savedNewtonVectorPtr_));
858 #ifdef Xyce_VERBOSE_CONDUCTANCE
859 varMap_[
"Var 0"] = 0.0;
860 varMap_[
"Var 1"] = 0.0;
861 printJacobian_ (varMap_,jacobian);
876 (
const std::map<std::string,double> & inputMap,
877 std::vector< std::vector<double> > & jacobian)
879 Xyce::dout().width(15); Xyce::dout().precision(7); Xyce::dout().setf(std::ios::scientific);
880 Xyce::dout() <<
"Output Jacobian/Conductance array: \n";
884 int numElectrodes = jacobian.size();
885 std::map<std::string,double>::const_iterator iterM = inputMap.begin();
886 std::map<std::string,double>::const_iterator endM = inputMap.end ();
887 for (iE1 = 0; iE1 < numElectrodes; ++iE1,++iterM)
889 Xyce::dout() <<
"\t"<<iterM->first;
891 Xyce::dout() << std::endl;
892 iterM = inputMap.begin();
893 for (iE1 = 0; iE1 < numElectrodes; ++iE1,++iterM)
895 Xyce::dout() <<
"\t"<<iterM->first;
896 for (iE2 = 0; iE2 < numElectrodes; ++iE2)
898 Xyce::dout() <<
"\t" <<jacobian[iE1][iE2];
900 Xyce::dout() << std::endl;
902 Xyce::dout() << std::endl;
917 Xyce::dout().width(15); Xyce::dout().precision(7); Xyce::dout().setf(std::ios::scientific);
918 std::string srcName = varName;
919 Xyce::dout() <<
"Info for input voltage: " << srcName << std::endl;
920 Xyce::dout() <<
"Jacobian:" << std::endl;
924 Xyce::dout() <<
"dxdv:" << std::endl;
927 Xyce::dout() <<
"dfdv:" << std::endl;