46 #include <Xyce_config.h>
52 #include <N_ERH_ErrorMgr.h>
53 #include <N_IO_CmdParse.h>
54 #include <N_IO_PkgOptionsMgr.h>
55 #include <N_LAS_Builder.h>
56 #include <N_LAS_Matrix.h>
57 #include <N_LAS_Problem.h>
58 #include <N_LAS_Solver.h>
59 #include <N_LAS_System.h>
60 #include <N_LAS_Vector.h>
64 #include <N_PDS_Comm.h>
65 #include <N_PDS_ParMap.h>
66 #include <N_TOP_Topology.h>
67 #include <N_UTL_Diagnostic.h>
68 #include <N_UTL_Expression.h>
69 #include <N_UTL_ExtendedString.h>
70 #include <N_UTL_FeatureTest.h>
71 #include <N_UTL_OptionBlock.h>
73 #include <Epetra_CrsMatrix.h>
90 Topo::Topology & topTmp)
98 matrixDiagonalPtr_(0),
100 jacobianMatrixPtr_(0),
101 nextSolVectorPtrPtr_(0),
102 currSolVectorPtrPtr_(0),
103 savedRHSVectorPtr_(0),
104 savedNewtonVectorPtr_(0),
108 gidsSetUpFlag_(false)
126 #ifdef Xyce_PARALLEL_MPI
163 const Util::OptionBlock & option_block)
165 bool bsuccess =
true;
167 for (Util::ParamList::const_iterator it = option_block.begin(), end = option_block.end(); it != end; ++it)
169 if ((*it).uTag() ==
"DEBUGLEVEL")
171 setNonlinearConductanceDebugLevel((*it).getImmutableValue<
int>());
199 const std::map<std::string, double> & inputMap)
201 bool bsuccess =
true;
204 int idSize = inputMap.size();
209 for (
int i=0; i<idSize ;++i)
220 std::map<std::string,double>::const_iterator iterM = inputMap.begin();
221 std::map<std::string,double>::const_iterator endM = inputMap.end ();
223 for (; iterM != endM; ++i, ++iterM)
227 ExtendedString src = iterM->first;
229 std::string sourceName = src;
235 std::vector<int> GIDList, extGIDList;
236 top_.getNodeSVarGIDs(NodeID(sourceName, Xyce::_DNODE), GIDList, extGIDList, type);
238 std::vector<int>::iterator iterI;
239 if (!(GIDList.empty ()))
241 iterI = GIDList.begin();
245 iterI = extGIDList.begin();
251 std::string msg =
"ConductanceExtractor::setupIDs_";
252 msg +=
" The " + sourceName +
" source has the positive node"
253 " owned by another processor. The 2-level solve can't handle that.";
254 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
259 int vnegGID = *iterI;
262 std::string msg =
"ConductanceExtractor::setupIDs_";
263 msg +=
" The " + sourceName +
" source has the negative node"
264 " connected to something other than ground! The 2-level solve can't handle that.";
265 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
271 if (DEBUG_CONDUCTANCE && isActive(Diag::NONLINEAR_CONDUCTANCE))
273 Xyce::dout() <<
"current GIDs: " << std::endl;
274 for(
int i1=0; i1 < idSize; ++i1 )
276 Xyce::dout() <<
" currentGIDs_["<<i1<<
"] = " <<
currentGIDs_[i1] <<
", currentLIDs_["<<i1<<
"] = " <<
currentLIDs_[i1] << std::endl;
279 Xyce::dout() <<
"Vsrc pos equation rows: " << std::endl;
280 for(
int i1=0; i1 < idSize; ++i1 )
282 Xyce::dout() <<
" vsrcPosGIDs_["<<i1<<
"] = " <<
vsrcPosGIDs_[i1] <<
", vsrcPosLIDs_["<<i1<<
"] = " <<
vsrcPosLIDs_[i1] << std::endl;
301 bool bsuccess =
true;
315 Linear::Vector * currentVec;
317 for(
int iC_row=0; iC_row < idSize; ++iC_row )
319 #ifdef Xyce_PARALLEL_MPI
325 currentVec->putScalar(0.0);
331 int numEntries = rowLength;
332 std::vector<double> coeffs(rowLength, 0.0);
333 std::vector<int> colIndices(rowLength, -1);
336 (iRow, rowLength, numEntries, &coeffs[0], &colIndices[0]);
338 for (
int ic=0;ic<rowLength;++ic)
342 int gid = colIndices[ic];
346 for (
int icol=0;icol<rowLength;++icol)
348 double val = coeffs[icol];
349 int gid = colIndices[icol];
351 currentVec->setElementByGlobalIndex(gid, val, 0);
354 currentVec->fillComplete();
356 #ifdef Xyce_PARALLEL_MPI
360 if (DEBUG_CONDUCTANCE && isActive(Diag::NONLINEAR_CONDUCTANCE))
362 Xyce::dout() <<
"\ndIdx[" << iC_row <<
"]:" << std::endl;
380 const std::map<std::string,double> & inputMap,
381 std::vector<double> & outputVector,
382 std::vector< std::vector<double> > & jacobian)
384 bool bsuccess =
true;
386 if (DEBUG_CONDUCTANCE && isActive(Diag::NONLINEAR_CONDUCTANCE))
388 Xyce::dout() << subsection_divider << std::endl;
389 Xyce::dout() <<
"ConductanceExtractor::extract" << std::endl;
390 Xyce::dout() << subsection_divider << std::endl;
393 if (inputMap.empty() ||
394 outputVector.empty() ||
421 outputVector[i] = solnVecPtr->getElementByGlobalIndex(index1);
423 outputVector[i] = 0.0;
426 #ifdef Xyce_PARALLEL_MPI
429 std::vector<double> tmpVector(idSize,0.0);
430 for(
int i = 0; i < idSize; ++i )
432 tmpVector[i] = outputVector[i];
433 outputVector[i] = 0.0;
436 comm.sumAll( &(tmpVector[0]), &(outputVector[0]), idSize );
439 if (DEBUG_CONDUCTANCE && isActive(Diag::NONLINEAR_CONDUCTANCE))
442 for (itmp=0;itmp < outputVector.size();++itmp)
444 Xyce::dout() <<
"currentVector["<< itmp <<
"] = " << outputVector[itmp]<<std::endl;
495 double diagInfNorm = 0.0;
503 if (diagInfNorm < 1.0e-30)
505 if (DEBUG_CONDUCTANCE)
506 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_WARNING_0,
507 "\n\tJacobian for inner problem not loaded. Forcing a load.\n");
517 std::map<std::string,double>::const_iterator iterM = inputMap.begin();
518 std::map<std::string,double>::const_iterator endM = inputMap.end ();
520 for (;iV_col<idSize;++iV_col,++iterM)
527 (*dfdvVectorPtr_)[irow] = 1.0;
532 for (;iC_row<idSize;++iC_row)
537 if (DEBUG_CONDUCTANCE && isActive(Diag::NONLINEAR_CONDUCTANCE))
539 std::string vsrcName = iterM->first;
541 Xyce::dout() <<
"dIdv = " << dIdv << std::endl;
545 jacobian[iC_row][iV_col] = dIdv;
557 if (VERBOSE_CONDUCTANCE)
768 (
const std::map<std::string,double> & inputMap,
769 std::vector< std::vector<double> > & jacobian)
771 Xyce::dout().width(15); Xyce::dout().precision(7); Xyce::dout().setf(std::ios::scientific);
772 Xyce::dout() <<
"Output Jacobian/Conductance array: \n";
776 int numElectrodes = jacobian.size();
777 std::map<std::string,double>::const_iterator iterM = inputMap.begin();
778 std::map<std::string,double>::const_iterator endM = inputMap.end ();
779 for (iE1 = 0; iE1 < numElectrodes; ++iE1,++iterM)
781 Xyce::dout() <<
"\t"<<iterM->first;
783 Xyce::dout() << std::endl;
784 iterM = inputMap.begin();
785 for (iE1 = 0; iE1 < numElectrodes; ++iE1,++iterM)
787 Xyce::dout() <<
"\t"<<iterM->first;
788 for (iE2 = 0; iE2 < numElectrodes; ++iE2)
790 Xyce::dout() <<
"\t" <<jacobian[iE1][iE2];
792 Xyce::dout() << std::endl;
794 Xyce::dout() << std::endl;
809 Xyce::dout().width(15); Xyce::dout().precision(7); Xyce::dout().setf(std::ios::scientific);
810 std::string srcName = varName;
811 Xyce::dout() <<
"Info for input voltage: " << srcName << std::endl;
812 Xyce::dout() <<
"Jacobian:" << std::endl;
816 Xyce::dout() <<
"dxdv:" << std::endl;
819 Xyce::dout() <<
"dfdv:" << std::endl;
Pure virtual class to augment a linear system.
Linear::Vector * rhsVectorPtr_
Linear::Matrix * jacobianMatrixPtr_
Linear::System * lasSysPtr_
Linear::Vector ** nextSolVectorPtrPtr_
Linear::Solver * lasSolverPtr_
Linear::Vector * NewtonVectorPtr_
Linear::Vector ** currSolVectorPtrPtr_