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>
104 N_TOP_Topology & topTmp,
118 matrixDiagonalPtr_(0),
120 jacobianMatrixPtr_(0),
121 nextSolVectorPtrPtr_(0),
122 currSolVectorPtrPtr_(0),
123 savedRHSVectorPtr_(0),
124 savedNewtonVectorPtr_(0),
128 gidsSetUpFlag_(false)
149 #ifdef Xyce_PARALLEL_MPI
152 columnMapPtr_ =
new N_PDS_ParMap( &(const_cast<Epetra_Map&>(col_map)),
187 for (
int ivec=0; ivec<vecSize ;++ivec)
234 std::string netListFile =
"";
255 bool bsuccess =
true;
257 for (std::list<N_UTL_Param>::const_iterator it_tpL = OB.getParams().begin();
258 it_tpL != OB.getParams().end(); ++ it_tpL)
261 if (it_tpL->uTag() ==
"DEBUGLEVEL")
290 (
const std::map<std::string,double> & inputMap)
292 bool bsuccess =
true;
295 int idSize = inputMap.size();
296 currentGIDs_.resize(idSize);
297 currentLIDs_.resize(idSize);
298 vsrcPosGIDs_.resize(idSize);
299 vsrcPosLIDs_.resize(idSize);
300 for (
int i=0; i<idSize ;++i)
302 dIdxPtrVector_.push_back(lasSysPtr_->builder().createVector());
303 currentGIDs_[i] = -1;
304 currentLIDs_[i] = -1;
305 vsrcPosGIDs_[i] = -1;
306 vsrcPosLIDs_[i] = -1;
311 std::map<std::string,double>::const_iterator iterM = inputMap.begin();
312 std::map<std::string,double>::const_iterator endM = inputMap.end ();
314 for (; iterM != endM; ++i, ++iterM)
318 ExtendedString src = iterM->first;
320 std::string sourceName = src;
326 std::list<int> GIDList, extGIDList;
327 top_.getNodeSVarGIDs(NodeID(sourceName, Xyce::_DNODE), GIDList, extGIDList, type);
329 std::list<int>::iterator iterI;
330 if (!(GIDList.empty ()))
332 iterI = GIDList.begin();
333 currentGIDs_[i] = *iterI;
334 currentLIDs_[i] = dIdxPtrVector_[0]->pmap()->globalToLocalIndex(currentGIDs_[i]);
336 iterI = extGIDList.begin();
337 vsrcPosGIDs_[i] = *iterI;
338 vsrcPosLIDs_[i] = dIdxPtrVector_[0]->pmap()->globalToLocalIndex(vsrcPosGIDs_[i]);
340 if( vsrcPosLIDs_[i] == -1 )
342 std::string msg =
"N_NLS_ConductanceExtractor::setupIDs_";
343 msg +=
" The " + sourceName +
" source has the positive node"
344 " owned by another processor. The 2-level solve can't handle that.";
345 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
350 int vnegGID = *iterI;
353 std::string msg =
"N_NLS_ConductanceExtractor::setupIDs_";
354 msg +=
" The " + sourceName +
" source has the negative node"
355 " connected to something other than ground! The 2-level solve can't handle that.";
356 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
362 #ifdef Xyce_DEBUG_CONDUCTANCE
365 cout <<
"current GIDs: " << std::endl;
366 for(
int i1=0; i1 < idSize; ++i1 )
368 cout <<
" currentGIDs_["<<i1<<
"] = " << currentGIDs_[i1] <<
", currentLIDs_["<<i1<<
"] = " << currentLIDs_[i1] << std::endl;
371 cout <<
"Vsrc pos equation rows: " << std::endl;
372 for(
int i1=0; i1 < idSize; ++i1 )
374 cout <<
" vsrcPosGIDs_["<<i1<<
"] = " << vsrcPosGIDs_[i1] <<
", vsrcPosLIDs_["<<i1<<
"] = " << vsrcPosLIDs_[i1] << std::endl;
379 gidsSetUpFlag_ =
true;
394 bool bsuccess =
true;
408 N_LAS_Vector * currentVec;
411 for(
int iC_row=0; iC_row < idSize; ++iC_row )
413 #ifdef Xyce_PARALLEL_MPI
419 currentVec->putScalar(0.0);
425 int numEntries = rowLength;
426 std::vector<double> coeffs(rowLength, 0.0);
427 std::vector<int> colIndices(rowLength, -1);
430 (iRow, rowLength, numEntries, &coeffs[0], &colIndices[0]);
432 for (
int ic=0;ic<rowLength;++ic)
436 int gid = colIndices[ic];
440 for (
int icol=0;icol<rowLength;++icol)
442 double val = coeffs[icol];
443 int gid = colIndices[icol];
445 currentVec->setElementByGlobalIndex(gid, val, 0);
448 currentVec->fillComplete();
450 #ifdef Xyce_PARALLEL_MPI
454 #ifdef Xyce_DEBUG_CONDUCTANCE
457 cout <<
"\ndIdx[" << iC_row <<
"]:" << std::endl;
475 const std::map<std::string,double> & inputMap,
476 std::vector<double> & outputVector,
477 std::vector< std::vector<double> > & jacobian )
480 bool bsuccess =
true;
482 #ifdef Xyce_DEBUG_CONDUCTANCE
485 cout << subsection_divider << std::endl;
486 cout <<
"N_NLS_ConductanceExtractor::extract" << std::endl;
487 cout << subsection_divider << std::endl;
491 if (inputMap.empty() ||
492 outputVector.empty() ||
519 outputVector[i] = solnVecPtr->getElementByGlobalIndex(index1);
521 outputVector[i] = 0.0;
524 #ifdef Xyce_PARALLEL_MPI
527 std::vector<double> tmpVector(idSize,0.0);
528 for(
int i = 0; i < idSize; ++i )
530 tmpVector[i] = outputVector[i];
531 outputVector[i] = 0.0;
534 comm->sumAll( &(tmpVector[0]), &(outputVector[0]), idSize );
537 #ifdef Xyce_DEBUG_CONDUCTANCE
541 for (itmp=0;itmp < outputVector.size();++itmp)
543 cout <<
"currentVector["<< itmp <<
"] = " << outputVector[itmp]<<std::endl;
595 double diagInfNorm = 0.0;
603 if (diagInfNorm < 1.0e-30)
605 #ifdef Xyce_DEBUG_CONDUCTANCE
606 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_WARNING_0,
607 "\n\tJacobian for inner problem not loaded. Forcing a load.\n");
617 std::map<std::string,double>::const_iterator iterM = inputMap.begin();
618 std::map<std::string,double>::const_iterator endM = inputMap.end ();
620 for (;iV_col<idSize;++iV_col,++iterM)
627 (*dfdvVectorPtr_)[irow] = 1.0;
632 for (;iC_row<idSize;++iC_row)
637 #ifdef Xyce_DEBUG_CONDUCTANCE
640 std::string vsrcName = iterM->first;
642 cout <<
"dIdv = " << dIdv << std::endl;
646 jacobian[iC_row][iV_col] = dIdv;
658 #ifdef Xyce_VERBOSE_CONDUCTANCE
680 bool bsuccess =
true;
688 for (
int i=0; i<idSize ;++i)
699 ExtendedString src = isoName;
701 std::string sourceName = src;
707 std::list<int> GIDList, extGIDList;
708 top_.getNodeSVarGIDs(NodeID(sourceName, Xyce::_DNODE), GIDList, extGIDList, type);
710 if (!(GIDList.empty ()))
712 std::list<int>::iterator gidIter = GIDList.begin();
713 std::list<int>::iterator gidExtIter = extGIDList.begin();
716 for (i=0;i<idSize;++i,++gidIter,++gidExtIter)
724 for (i=0;i<idSize;++i,++gidExtIter)
733 std::string msg =
"N_NLS_ConductanceExtractor::setupISO_IDs_";
734 msg +=
" The " + sourceName +
" source has the positive node"
735 " owned by another processor. The 2-level solve can't handle that.";
736 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
745 #ifdef Xyce_DEBUG_CONDUCTANCE
748 cout <<
"current GIDs: " << std::endl;
749 for(
int i1=0; i1 < idSize; ++i1 )
751 cout <<
" currentGIDs_["<<i1<<
"] = " <<
currentGIDs_[i1] << std::endl;
754 cout <<
"Vsrc pos equation rows: " << std::endl;
755 for(
int i1=0; i1 < idSize; ++i1 )
757 cout <<
" vsrcPosGIDs_["<<i1<<
"] = " <<
vsrcPosGIDs_[i1] << std::endl;
784 (
const std::string & isoName, std::vector< std::vector<double> > & jacobian )
786 bool bsuccess =
true;
788 int idSize = jacobian.size();
790 #ifdef Xyce_DEBUG_CONDUCTANCE
793 cout << subsection_divider << std::endl;
794 cout <<
"N_NLS_ConductanceExtractor::extract - iso2" << std::endl;
795 cout << subsection_divider << std::endl;
801 setupISO2_IDs_(isoName);
805 savedRHSVectorPtr_->putScalar(0.0);
806 savedRHSVectorPtr_->addVec(1.0, *(rhsVectorPtr_));
808 savedNewtonVectorPtr_->putScalar(0.0);
809 savedNewtonVectorPtr_->addVec(1.0, *(NewtonVectorPtr_));
812 bool b1 = setup_dIdX_Vectors_(); bsuccess = bsuccess && b1;
817 for (;iV_col<idSize;++iV_col)
820 dfdvVectorPtr_->putScalar(0.0);
821 int irow = currentLIDs_[iV_col];
824 (*dfdvVectorPtr_)[irow] = 1.0;
826 lasSolverPtr_->solve();
829 for (;iC_row<idSize;++iC_row)
832 double dIdv = dIdxPtrVector_[iC_row]->dotProduct(*(dxdvVectorPtr_));
834 #ifdef Xyce_DEBUG_CONDUCTANCE
837 std::string tmpName =
"unknown";
838 printPetraObjects_ (tmpName);
839 cout <<
"dIdv = " << dIdv << std::endl;
843 jacobian[iC_row][iV_col] = dIdv;
849 rhsVectorPtr_->putScalar(0.0);
850 rhsVectorPtr_->addVec(1.0, *(savedRHSVectorPtr_));
852 NewtonVectorPtr_->putScalar(0.0);
853 NewtonVectorPtr_->addVec(1.0, *(savedNewtonVectorPtr_));
855 #ifdef Xyce_VERBOSE_CONDUCTANCE
856 varMap_[
"Var 0"] = 0.0;
857 varMap_[
"Var 1"] = 0.0;
858 printJacobian_ (varMap_,jacobian);
873 (
const std::map<std::string,double> & inputMap,
874 std::vector< std::vector<double> > & jacobian)
876 Xyce::dout().width(15); Xyce::dout().precision(7); Xyce::dout().setf(std::ios::scientific);
877 Xyce::dout() <<
"Output Jacobian/Conductance array: \n";
881 int numElectrodes = jacobian.size();
882 std::map<std::string,double>::const_iterator iterM = inputMap.begin();
883 std::map<std::string,double>::const_iterator endM = inputMap.end ();
884 for (iE1 = 0; iE1 < numElectrodes; ++iE1,++iterM)
886 Xyce::dout() <<
"\t"<<iterM->first;
888 Xyce::dout() << std::endl;
889 iterM = inputMap.begin();
890 for (iE1 = 0; iE1 < numElectrodes; ++iE1,++iterM)
892 Xyce::dout() <<
"\t"<<iterM->first;
893 for (iE2 = 0; iE2 < numElectrodes; ++iE2)
895 Xyce::dout() <<
"\t" <<jacobian[iE1][iE2];
897 Xyce::dout() << std::endl;
899 Xyce::dout() << std::endl;
914 Xyce::dout().width(15); Xyce::dout().precision(7); Xyce::dout().setf(std::ios::scientific);
915 std::string srcName = varName;
916 Xyce::dout() <<
"Info for input voltage: " << srcName << std::endl;
917 Xyce::dout() <<
"Jacobian:" << std::endl;
921 Xyce::dout() <<
"dxdv:" << std::endl;
924 Xyce::dout() <<
"dfdv:" << std::endl;