46 #include <Xyce_config.h>
58 #include <N_ERH_ErrorMgr.h>
59 #include <N_IO_CircuitBlock.h>
60 #include <N_IO_OptionBlock.h>
61 #include <N_IO_PkgOptionsMgr.h>
62 #include <N_IO_SpiceSeparatedFieldTool.h>
63 #include <N_LAS_Builder.h>
64 #include <N_LAS_Matrix.h>
65 #include <N_LAS_Problem.h>
66 #include <N_LAS_Solver.h>
67 #include <N_LAS_System.h>
68 #include <N_LAS_Vector.h>
72 #include <N_PDS_Comm.h>
73 #include <N_PDS_MPI.h>
74 #include <N_PDS_Manager.h>
75 #include <N_PDS_Serial.h>
77 #include <N_TOP_Topology.h>
78 #include <N_UTL_Algorithm.h>
79 #include <N_UTL_Diagnostic.h>
80 #include <N_UTL_Expression.h>
81 #include <N_UTL_ExtendedString.h>
82 #include <N_UTL_FeatureTest.h>
83 #include <N_UTL_OptionBlock.h>
100 Topo::Topology & topTmp,
101 const IO::CmdParse & cp)
105 solveDirectFlag_(false),
106 solveAdjointFlag_(true),
107 outputScaledFlag_(false),
108 outputUnscaledFlag_(true),
109 maxParamStringSize_(0),
110 stdOutputFlag_(true),
111 fileOutputFlag_(false),
112 dakotaFileOutputFlag_(false),
115 objFuncGiven_(false),
116 objFuncGIDsetup_(false),
119 sqrtEtaGiven_(false),
122 savedRHSVectorPtr_(0),
123 savedNewtonVectorPtr_(0),
209 std::string idString,
210 std::vector<double> & paramVals,
211 std::vector<double> & sensitivities,
212 std::vector<double> & scaled_sensitivities)
215 #ifdef Xyce_PARALLEL_MPI
216 N_PDS_Comm *pdsCommPtr =
pdsMgrPtr_->getPDSComm();
217 int myPID = pdsCommPtr->procID();
223 Xyce::dout() <<
"\n"<<idString <<
" Sensitivities of objective function:";
230 Xyce::dout() <<
"\t"<<std::setw(13)<<
"Value";
231 Xyce::dout() <<
"\t"<<std::setw(13)<<
"Sensitivity";
232 Xyce::dout() <<
"\t"<<std::setw(13)<<
"Normalized"<<std::endl;
238 Xyce::dout() <<
"\t" << std::setw(13)<< std::scientific<< std::setprecision(4)
239 << paramVals[iparam];
241 int index= iobj*numSensParams_ +iparam;
242 Xyce::dout() <<
"\t" << std::setw(13)<< std::scientific<< std::setprecision(4)
243 << sensitivities[index];
245 Xyce::dout() <<
"\t" << std::setw(13)<< std::scientific<< std::setprecision(4)
246 << scaled_sensitivities[index] << std::endl;
250 #ifdef Xyce_PARALLEL_MPI
251 pdsCommPtr->barrier();
264 std::string idString,
265 std::vector<double> & paramVals,
266 std::vector<double> & sensitivities,
267 std::vector<double> & scaled_sensitivities)
269 #ifdef Xyce_PARALLEL_MPI
270 N_PDS_Comm *pdsCommPtr =
pdsMgrPtr_->getPDSComm();
271 int myPID = pdsCommPtr->procID();
275 std::ostringstream numSolvesOStr;
277 std::string dodpFileName =
netlistFilename_ + numSolvesOStr.str() +
"_dodp" + idString +
".txt";
278 FILE *fp = fopen(dodpFileName.c_str(),
"w");
281 fprintf(fp,
"\t%16.8e\n", sensitivities[iparam]);
285 #ifdef Xyce_PARALLEL_MPI
286 pdsCommPtr->barrier();
299 void Sensitivity::dakOutput (
300 std::string idString,
301 std::vector<double> & paramVals,
302 std::vector<double> & sensitivities,
303 std::vector<double> & scaled_sensitivities)
305 #ifdef Xyce_PARALLEL_MPI
306 N_PDS_Comm *pdsCommPtr =
pdsMgrPtr_->getPDSComm();
307 int myPID = pdsCommPtr->procID();
314 std::string dakotaFileName =
netlistFilename_ +
"_dodp" + idString +
"_all.txt";
315 FILE *fp2 = fopen(dakotaFileName.c_str(),
"w");
316 fprintf(fp2,
"%16.8e", objFuncEval_ );
317 fprintf(fp2,
"%s",
"\n[\n");
320 fprintf(fp2,
"\t%16.8e\n", sensitivities[iparam]);
322 fprintf(fp2,
"%s",
"]\n");
325 #ifdef Xyce_PARALLEL_MPI
326 pdsCommPtr->barrier();
342 std::vector<double> & objectiveVec,
343 std::vector<double> & dOdpVec,
344 std::vector<double> & dOdpAdjVec,
345 std::vector<double> & scaled_dOdpVec,
346 std::vector<double> & scaled_dOdpAdjVec)
367 objectiveVec.clear();
426 std::vector<double> & objectiveVec,
427 std::vector<double> & dOdpVec,
428 std::vector<double> & dOdpAdjVec,
429 std::vector<double> & scaled_dOdpVec,
430 std::vector<double> & scaled_dOdpAdjVec)
432 Stats::StatTop _solveStat(
"Sensistivity Solve");
433 Stats::TimeBlock _solveTimer(_solveStat);
457 objectiveVec.clear();
562 Stats::StatTop _solveDirectStat(
"Solve Direct");
563 Stats::TimeBlock _solveDirectTimer(_solveDirectStat);
565 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
567 Xyce::dout() << std::endl
568 <<
"In Sensitivity::solveDirect" << std::endl;
587 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
598 rhsVectorPtr_->update(1.0, *(sensRHSPtrVector[iparam]), 0.0);
606 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
608 Xyce::dout() <<
"iparam="<<iparam <<
"\t" <<
paramNameVec_[iparam] <<std::endl;
611 Xyce::dout() <<
"dXdp[" << std::setw(3) << k <<
"] = "<< std::setw(15)<< std::scientific
612 << std::setprecision(8)<< (*(dXdpPtrVector_[iparam]))[k]
616 std::ostringstream filename;
618 filename << std::setw(3) << std::setfill(
'0') << iparam;
620 dXdpPtrVector_[iparam]->writeToFile(const_cast<char *>(filename.str().c_str()));
625 bool Transpose =
false;
626 (DQdxDXdpPtrVector_[iparam])->putScalar(0.0);
627 dQdx.matvec( Transpose , *(dXdpPtrVector_[iparam]), *(DQdxDXdpPtrVector_[iparam]) );
643 double tmp =
objFuncDataVec_[iobj]->dOdXVectorPtr_->dotProduct( (*(dXdpPtrVector_[iparam])) );
699 bool bsuccess =
true;
711 bool foundLocal(
false);
712 bool foundLocal2(
false);
714 N_PDS_Comm & comm = *(
pdsMgrPtr_->getPDSComm());
715 int myPID = comm.procID();
727 std::vector<int> svGIDList1, dummyList;
729 foundLocal =
top_.getNodeSVarGIDs(NodeID(
objFuncDataVec_[iobj]->expVarNames_[i], Xyce::_VNODE), svGIDList1, dummyList, type1);
730 found =
static_cast<int>(foundLocal);
731 Xyce::Parallel::AllReduce(comm.comm(), MPI_LOR, &found, 1);
736 foundLocal2 =
top_.getNodeSVarGIDs(NodeID(
objFuncDataVec_[iobj]->expVarNames_[i], Xyce::_DNODE), svGIDList1, dummyList, type1);
738 found2 =
static_cast<int>(foundLocal2);
739 Xyce::Parallel::AllReduce(comm.comm(), MPI_LOR, &found2, 1);
741 if (!found && !found2)
743 static std::string tmp =
"objective function variable not found!\n";
744 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::USR_FATAL, tmp);
750 if(svGIDList1.size()==1)
752 tmpGID = svGIDList1.front();
775 tmpVal = (*nextSolVectorPtrPtr_)->getElementByGlobalIndex(tmpGID, 0);
778 Xyce::Parallel::AllReduce(comm.comm(), MPI_MAX, &root, 1);
780 comm.bcast( &tmpVal, 1, root );
802 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
804 Xyce::dout() <<
"i="<<i<<
" gid = " << tmpGID <<
" dodx = "<< tmpDODX << std::endl;
809 objFuncDataVec_[iobj]->dOdXVectorPtr_->setElementByGlobalIndex(tmpGID, tmpDODX, 0);
819 Report::UserWarning0() <<
"Objective function was not specified";
827 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
830 objFuncDataVec_[iobj]->dOdXVectorPtr_->writeToFile(const_cast<char *>(filename.c_str()));
848 Stats::StatTop _solveAdjointStat(
"Solve Adjoint");
849 Stats::TimeBlock _solveAdjointTimer(_solveAdjointStat);
851 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
853 Xyce::dout() << std::endl;
854 Xyce::dout() <<
"In Sensitivity::solveAdjoint" << std::endl;
868 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
882 std::string msg(
"Sensitivity::solveAdjoint. Solver failed\n");
883 N_ERH_ErrorMgr::report (N_ERH_ErrorMgr::DEV_FATAL, msg);
890 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
903 Linear::Vector & RHSVec = *(sensRHSPtrVector[iparam]);
904 Linear::Vector & dfdpVec = *(dfdpPtrVector_[iparam]);
905 Linear::Vector & dbdpVec = *(dbdpPtrVector_[iparam]);
906 RHSVec.linearCombo(0.0,RHSVec,+1.0,dfdpVec);
907 RHSVec.linearCombo(1.0,RHSVec,-1.0,dbdpVec);
958 bool bsuccess =
true;
959 Util::ParamList::const_iterator iter = OB.begin();
960 Util::ParamList::const_iterator end = OB.end();
964 for ( ; iter != end; ++ iter)
966 if ( std::string( iter->uTag() ,0,7) ==
"OBJFUNC")
970 ofDataPtr->
expPtr_ =
new Util::Expression(iter->stringValue());
976 else if ( std::string( iter->uTag() ,0,5) ==
"PARAM")
978 ExtendedString tag = iter->stringValue();
991 Xyce::Report::UserWarning() << iter->uTag()
992 <<
" is not a recognized sensitivity solver option.\n" << std::endl;
1006 std::vector<std::string> nodes;
1008 std::vector<std::string> instances;
1013 std::vector<std::string>::iterator iter;
1014 for (iter=instances.begin();iter!=instances.end();++iter)
1016 ExtendedString tmpString = *iter;
1017 tmpString.toUpper ();
1035 static std::string tmp =
"Objective function does not contain a resolvable solution variable.\n";
1036 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1041 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
1043 std::vector<std::string>::iterator iter;
1044 std::vector<std::string>::iterator begin =
paramNameVec_.begin();
1045 std::vector<std::string>::iterator end =
paramNameVec_.end ();
1047 for (iter=begin;iter!=end;++iter)
1049 Xyce::dout() << *iter<<std::endl;
1068 bool bsuccess =
true;
1069 Util::ParamList::const_iterator it = OB.begin();
1070 Util::ParamList::const_iterator end = OB.end();
1071 for ( ; it != end; ++ it)
1073 if ((*it).uTag() ==
"ADJOINT")
1076 static_cast<bool>((*it).getImmutableValue<
bool>());
1078 else if ((*it).uTag() ==
"DIRECT")
1081 static_cast<bool>((*it).getImmutableValue<
bool>());
1083 else if ((*it).uTag() ==
"OUTPUTSCALED")
1086 static_cast<bool>((*it).getImmutableValue<
bool>());
1088 else if ((*it).uTag() ==
"OUTPUTUNSCALED")
1091 static_cast<bool>((*it).getImmutableValue<
bool>());
1093 else if ((*it).uTag() ==
"STDOUTPUT")
1096 static_cast<bool>((*it).getImmutableValue<
bool>());
1098 else if ((*it).uTag() ==
"DAKOTAFILE")
1101 static_cast<bool>((*it).getImmutableValue<
bool>());
1103 else if ((*it).uTag() ==
"DIAGNOSTICFILE")
1106 static_cast<bool>((*it).getImmutableValue<
bool>());
1108 else if ((*it).uTag() ==
"FORCEFD")
1111 static_cast<bool>((*it).getImmutableValue<
bool>());
1113 else if ((*it).uTag() ==
"DIFFERENCE")
1115 ExtendedString sval=(*it).stringValue();
1121 else if(sval==
"REVERSE")
1125 else if(sval==
"CENTRAL")
1128 static std::string tmp =
"difference=central not supported.\n";
1129 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1133 static std::string tmp =
"difference not recognized!\n";
1134 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1137 else if ((*it).uTag() ==
"SQRTETA")
1139 sqrtEta_ = (*it).getImmutableValue<
double>();
1142 else if ((*it).uTag() ==
"REUSEFACTORS")
1146 else if (DEBUG_NONLINEAR && (*it).uTag() ==
"DEBUGLEVEL")
1153 Xyce::Report::UserWarning() << (*it).uTag()
1154 <<
" is not a recognized sensitivity solver option.\n" << std::endl;
1196 IO::PkgOptionsMgr & options_manager,
1197 IO::CircuitBlock & circuit_block,
1198 const std::string & netlist_filename,
1199 const IO::TokenVector & parsed_line)
1201 Util::OptionBlock option_block(
"SENS", Util::OptionBlock::ALLOW_EXPRESSIONS, netlist_filename, parsed_line[0].lineNumber_);
1203 int numFields = parsed_line.size();
1205 int parameterStartPos = 1;
1208 Util::OptionBlock defaultOptions;
1211 addDefaultOptionsParameters(options_manager, defaultOptions,
"SENS" );
1214 int parameterEndPos = numFields - 1;
1215 Util::ParamList inputParameters;
1216 Util::Param parameter(
"",
"");
1217 int intervalParameterStart = -1;
1218 int i = parameterStartPos;
1219 std::string paramBaseName;
1220 while (i <= parameterEndPos-1)
1223 if ( parsed_line[i+1].string_ !=
"=" )
1228 intervalParameterStart = i;
1235 parameter.set( parsed_line[i].string_,
"" );
1236 Util::Param *parameterPtr = Util::findParameter(defaultOptions.begin(), defaultOptions.end(), parameter.tag());
1237 if (parameterPtr == NULL)
1239 Report::UserWarning0().at(netlist_filename, parsed_line[0].lineNumber_)
1240 <<
"No options parameter " << parameter.tag() <<
" found, parameter will be ignored.";
1243 else if (parameterPtr->stringValue() !=
"VECTOR")
1245 parameter.setVal( parsed_line[i+2].string_ );
1246 inputParameters.push_back( parameter );
1249 if (i < parameterEndPos-1 && parsed_line[i].string_ ==
",")
1251 Report::UserError0().at(netlist_filename, parsed_line[0].lineNumber_)
1252 <<
"Options parameter " << parameter.tag() <<
" is flagged as not VECTOR, but has comma in value.";
1260 std::ostringstream paramName;
1261 paramBaseName = ExtendedString(parsed_line[i].string_).toUpper();
1264 paramName << paramBaseName << j;
1266 parameter.set(paramName.str(), parsed_line[i].string_);
1267 option_block.addParam(parameter);
1274 int testSize = parsed_line.size()-1;
1275 while ((i < testSize) && (parsed_line[i+1].string_ ==
",") )
1279 paramName << paramBaseName << j;
1281 parameter.set(paramName.str(), parsed_line[i].string_);
1282 option_block.addParam(parameter);
1292 for (Util::ParamList::const_iterator it = inputParameters.begin(), end = inputParameters.end(); it != end; ++it)
1294 Util::Param *parameterPtr = Util::findParameter(defaultOptions.begin(), defaultOptions.end(), (*it).tag());
1295 if ( parameterPtr != NULL )
1297 parameterPtr->setVal(*it);
1298 option_block.addParam( *parameterPtr );
1302 Report::UserWarning0().at(netlist_filename, parsed_line[0].lineNumber_)
1303 <<
"No options parameter " << (*it).tag() <<
" found, parameter will be ignored.";
1307 circuit_block.addOptions(option_block);
1321 IO::PkgOptionsMgr & options_manager)
1324 Util::ParamMap ¶meters = options_manager.addOptionsMetadataMap(
"SENSITIVITY");
1326 parameters.insert(Util::ParamMap::value_type(
"DEBUGLEVEL", Util::Param(
"DEBUGLEVEL", 0)));
1327 parameters.insert(Util::ParamMap::value_type(
"ADJOINT", Util::Param(
"ADJOINT", 0)));
1328 parameters.insert(Util::ParamMap::value_type(
"DIRECT", Util::Param(
"DIRECT", 0)));
1329 parameters.insert(Util::ParamMap::value_type(
"OUTPUTSCALED", Util::Param(
"OUTPUTSCALED", 0)));
1330 parameters.insert(Util::ParamMap::value_type(
"OUTPUTUNSCALED", Util::Param(
"OUTPUTUNSCALED", 1)));
1331 parameters.insert(Util::ParamMap::value_type(
"STDOUTPUT", Util::Param(
"STDOUTPUT", 1)));
1332 parameters.insert(Util::ParamMap::value_type(
"DIAGNOSTICFILE", Util::Param(
"DIAGNOSTICFILE", 0)));
1333 parameters.insert(Util::ParamMap::value_type(
"DAKOTAFILE", Util::Param(
"DAKOTAFILE", 0)));
1334 parameters.insert(Util::ParamMap::value_type(
"DIFFERENCE", Util::Param(
"DIFFERENCE", 0)));
1335 parameters.insert(Util::ParamMap::value_type(
"SQRTETA", Util::Param(
"SQRTETA", 1.0e-8)));
1336 parameters.insert(Util::ParamMap::value_type(
"FORCEFD", Util::Param(
"FORCEFD", 0)));
1340 Util::ParamMap ¶meters = options_manager.addOptionsMetadataMap(
"SENS");
1342 parameters.insert(Util::ParamMap::value_type(
"OBJFUNC", Util::Param(
"OBJFUNC",
"VECTOR")));
1343 parameters.insert(Util::ParamMap::value_type(
"PARAM", Util::Param(
"PARAM",
"VECTOR")));
static void populateMetadata(IO::PkgOptionsMgr &options_manager)
std::vector< double > paramOrigVals_
bool loadSensitivityResiduals(int difference, bool forceFD_, double sqrtEta_, std::string &netlistFilename_, TimeIntg::DataStore &ds, Loader::NonlinearEquationLoader &nonlinearEquationLoader_, const std::vector< std::string > ¶mNameVec_, const Analysis::AnalysisManager &analysisManager_)
virtual int getMaxNormFindex() const =0
std::string objFuncString_
bool extractSENSData(IO::PkgOptionsMgr &options_manager, IO::CircuitBlock &circuit_block, const std::string &netlist_filename, const IO::TokenVector &parsed_line)
Linear::Vector * lambdaVectorPtr_
virtual bool enableSensitivity()
Pure virtual class to augment a linear system.
std::vector< double > dOdpVec_
std::vector< double > scaled_dOdpVec_
Util::OptionBlock * linsolOptionBlockPtr_
void allocateSensitivityArrays(Linear::Builder &builder, int numParams)
bool dakotaFileOutputFlag_
std::vector< Linear::Vector * > nextDXdpPtrVector
virtual double getMaxNormF() const =0
std::string netlistFilename_
std::vector< double > scaled_dOdpAdjVec_
int solve(NonLinearSolver *nlsTmpPtr=NULL)
std::vector< Linear::Vector * > nextDbdpPtrVector
std::vector< Linear::Vector * > nextDfdpPtrVector
Linear::Vector * rhsVectorPtr_
TimeIntg::DataStore * dsPtr_
Linear::Vector * gradVectorPtr_
Linear::Vector * savedNewtonVectorPtr_
std::vector< double > objectiveVec_
std::vector< Linear::Vector * > currDXdpPtrVector
void stdOutput(std::string idString, std::vector< double > ¶mVals, std::vector< double > &sensitivities, std::vector< double > &scaled_sensitivities)
Linear::Matrix * jacobianMatrixPtr_
N_PDS_Manager * pdsMgrPtr_
Linear::Vector * dOdXVectorPtr_
const Analysis::AnalysisManager & getAnalysisManager() const
void fileOutput(std::string idString, std::vector< double > ¶mVals, std::vector< double > &sensitivities, std::vector< double > &scaled_sensitivities)
Sensitivity(NonLinearSolver &nls_, Topo::Topology &top_, const IO::CmdParse &cp)
Linear::System * lasSysPtr_
Linear::Vector ** nextSolVectorPtrPtr_
Linear::Solver * lasSolverPtr_
bool loadFinalSensitivityDerivatives()
bool icSensitivity(std::vector< double > &objectiveVec, std::vector< double > &dOdpVec, std::vector< double > &dOdpAdjVec, std::vector< double > &scaled_dOdpVec, std::vector< double > &scaled_dOdpAdjVec)
bool setOptions(const Util::OptionBlock &OB)
bool loadSensitivityResiduals()
bool setSensitivityOptions(const Util::OptionBlock &OB)
Linear::Vector * savedRHSVectorPtr_
Loader::NonlinearEquationLoader * nonlinearEquationLoader_
Linear::Vector * solWtVectorPtr_
Linear::Vector * NewtonVectorPtr_
int getMaxNormFindex() const
std::vector< double > dOdpAdjVec_
virtual bool registerAnalysisManager(Analysis::AnalysisManager *tmp_anaIntPtr)
Linear::Vector ** currSolVectorPtrPtr_
Util::Expression * expPtr_
std::vector< Linear::Vector * > sensRHSPtrVector
std::vector< objectiveFunctionData * > objFuncDataVec_
Linear::Matrix * dQdxMatrixPtr
std::vector< Linear::Vector * > nextDQdxDXdpPtrVector
double getMaxNormF() const
std::vector< std::string > paramNameVec_