46 #include <Xyce_config.h>
51 #include <N_UTL_Misc.h>
59 #include <N_LOA_Loader.h>
61 #include <N_UTL_OptionBlock.h>
63 #include <N_LAS_Matrix.h>
64 #include <N_LAS_Vector.h>
66 #include <N_LAS_Solver.h>
67 #include <N_LAS_Problem.h>
69 #include <N_LAS_System.h>
70 #include <N_LAS_Builder.h>
72 #include <N_ERH_ErrorMgr.h>
75 #include <N_TOP_Topology.h>
77 #include <N_UTL_Expression.h>
79 #include <N_PDS_ParMap.h>
80 #ifdef Xyce_PARALLEL_MPI
81 #include <N_PDS_ParComm.h>
84 #include <N_PDS_SerialComm.h>
99 N_TOP_Topology & topTmp,
102 allocateddXVec_ (false),
105 solveDirectFlag_(true),
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),
124 sqrtEtaGiven_(false),
127 savedRHSVectorPtr_(0),
128 savedNewtonVectorPtr_(0),
244 std::string idString,
245 std::vector<double> & paramVals,
246 std::vector<double> & sensitivities,
247 std::vector<double> & scaled_sensitivities)
250 #ifdef Xyce_PARALLEL_MPI
251 N_PDS_Comm *pdsCommPtr =
pdsMgrPtr_->getPDSComm();
252 int myPID = pdsCommPtr->procID();
256 Xyce::dout() <<
"\n"<<idString <<
" Sensitivities of objective function:"
260 Xyce::dout() <<
"\t"<<std::setw(13)<<
"Value";
261 Xyce::dout() <<
"\t"<<std::setw(13)<<
"Sensitivity";
262 Xyce::dout() <<
"\t"<<std::setw(13)<<
"Normalized"<<std::endl;
268 Xyce::dout() <<
"\t" << std::setw(13)<< std::scientific<< std::setprecision(4)
269 << paramVals[iparam];
271 Xyce::dout() <<
"\t" << std::setw(13)<< std::scientific<< std::setprecision(4)
272 << sensitivities[iparam];
274 Xyce::dout() <<
"\t" << std::setw(13)<< std::scientific<< std::setprecision(4)
275 << scaled_sensitivities[iparam] << std::endl;
278 #ifdef Xyce_PARALLEL_MPI
279 pdsCommPtr->barrier();
292 std::string idString,
293 std::vector<double> & paramVals,
294 std::vector<double> & sensitivities,
295 std::vector<double> & scaled_sensitivities)
298 #ifdef Xyce_PARALLEL_MPI
299 N_PDS_Comm *pdsCommPtr =
pdsMgrPtr_->getPDSComm();
300 int myPID = pdsCommPtr->procID();
304 std::ostringstream numSolvesOStr;
306 std::string dodpFileName =
netlistFileName_ + numSolvesOStr.str() +
"_dodp" + idString +
".txt";
307 FILE *fp = fopen(dodpFileName.c_str(),
"w");
310 fprintf(fp,
"\t%16.8e\n", sensitivities[iparam]);
314 #ifdef Xyce_PARALLEL_MPI
315 pdsCommPtr->barrier();
328 std::string idString,
329 std::vector<double> & paramVals,
330 std::vector<double> & sensitivities,
331 std::vector<double> & scaled_sensitivities)
333 #ifdef Xyce_PARALLEL_MPI
334 N_PDS_Comm *pdsCommPtr =
pdsMgrPtr_->getPDSComm();
335 int myPID = pdsCommPtr->procID();
342 std::string dakotaFileName =
netlistFileName_ +
"_dodp" + idString +
"_all.txt";
343 FILE *fp2 = fopen(dakotaFileName.c_str(),
"w");
345 fprintf(fp2,
"%s",
"\n[\n");
348 fprintf(fp2,
"\t%16.8e\n", sensitivities[iparam]);
350 fprintf(fp2,
"%s",
"]\n");
353 #ifdef Xyce_PARALLEL_MPI
354 pdsCommPtr->barrier();
367 std::vector<double> & objectiveVec,
368 std::vector<double> & dOdpVec,
369 std::vector<double> & dOdpAdjVec,
370 std::vector<double> & scaled_dOdpVec,
371 std::vector<double> & scaled_dOdpAdjVec)
392 objectiveVec.clear();
492 #ifdef Xyce_DEBUG_NONLINEAR
495 Xyce::dout() << std::endl;
496 Xyce::dout() <<
"In N_NLS_Sensitivity::solveDirect" << std::endl;
526 #ifdef Xyce_DEBUG_NONLINEAR
530 Xyce::dout() <<
"iparam="<<iparam <<
"\t" <<
paramNameVec_[iparam] <<std::endl;
533 Xyce::dout() <<
"k = " << std::setw(4) << k
534 <<
" dXdp = "<< std::setw(11)<< std::scientific
539 std::ostringstream filename;
541 filename << std::setw(3) << std::setfill(
'0') << iparam;
543 dXdpPtrVector_[iparam]->writeToFile(const_cast<char *>(filename.str().c_str()));
611 bool bsuccess =
true;
628 std::list<int> svGIDList1, dummyList;
630 bool found =
top_.getNodeSVarGIDs(NodeID(
expVarNames_[i], Xyce::_VNODE), svGIDList1, dummyList, type1);
632 bool foundLocal = found;
633 #ifdef Xyce_PARALLEL_MPI
634 N_PDS_Comm *pdsCommPtr =
pdsMgrPtr_->getPDSComm();
637 double found_glob=0.0;
638 double found_local = found?1.0:0.0;
639 pdsCommPtr->barrier();
640 pdsCommPtr->sumAll(&found_local, &found_glob, 1);
641 found = (found_glob != 0.0)?
true:
false;
642 #ifdef Xyce_DEBUG_NONLINEAR
643 Xyce::dout() <<
"global found = " << found_glob <<std::endl;
651 found2 =
top_.getNodeSVarGIDs(NodeID(
expVarNames_[i], Xyce::_DNODE), svGIDList1, dummyList, type1);
654 bool foundLocal2 = found2;
655 #ifdef Xyce_PARALLEL_MPI
659 double found_glob=0.0;
660 double found_local = found2?1.0:0.0;
661 pdsCommPtr->barrier();
662 pdsCommPtr->sumAll(&found_local, &found_glob, 1);
663 found2 = (found_glob != 0.0)?
true:
false;
664 #ifdef Xyce_DEBUG_NONLINEAR
665 Xyce::dout() <<
"global found2 = " << found_glob <<std::endl;
670 if (!found && !found2)
672 static std::string tmp =
"objective function variable not found!\n";
673 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::USR_FATAL, tmp);
677 if (foundLocal || foundLocal2)
679 tmpGID = svGIDList1.front();
682 #ifdef Xyce_DEBUG_NONLINEAR
683 Xyce::dout() <<
"tmpGID = " << tmpGID <<std::endl;
698 (*nextSolVectorPtrPtr_)->getElementByGlobalIndex(
expVarGIDs_[i], 0);
715 #ifdef Xyce_DEBUG_NONLINEAR
716 Xyce::dout() <<
"i="<<i<<
" gid = " << tmpGID <<
" dodx = "<< tmpDODX << std::endl;
730 static std::string tmp =
" ***** WARNING: objective function was not specified.\n\n";
731 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
734 #ifdef Xyce_DEBUG_NONLINEAR
738 dOdXVectorPtr_->writeToFile(const_cast<char *>(filename.c_str()));
772 #ifdef Xyce_DEBUG_NONLINEAR
786 std::string msg(
"N_NLS_Sensitivity::solveAdjoint. Solver failed\n");
787 N_ERH_ErrorMgr::report (N_ERH_ErrorMgr::DEV_FATAL, msg);
794 #ifdef Xyce_DEBUG_NONLINEAR
861 N_LAS_System & lasSys_ = (*lasSysPtr_);
863 #ifdef Xyce_PARALLEL_MPI
864 N_PDS_Comm *pdsCommPtr =
pdsMgrPtr_->getPDSComm();
865 pdsCommPtr->barrier();
876 std::vector<std::string>::iterator firstParam =
paramNameVec_.begin ();
877 std::vector<std::string>::iterator lastParam =
paramNameVec_.end ();
878 std::vector<std::string>::iterator iterParam;
879 for ( iterParam=firstParam, iparam=0;
880 iterParam!=lastParam; ++iterParam, ++iparam )
883 #ifdef Xyce_DEBUG_NONLINEAR
886 Xyce::dout() << std::endl <<
" Calculating df/dp for: ";
887 Xyce::dout() << *iterParam << std::endl;
896 std::string paramName(*iterParam);
897 double paramOrig = 0.0;
898 bool found =
loaderPtr_->getParamAndReduce(paramName, paramOrig);
901 std::string msg(
"Sensitivity::calcSensitivities: cannot find parameter ");
903 N_ERH_ErrorMgr::report (N_ERH_ErrorMgr::DEV_FATAL, msg);
906 double dp =
sqrtEta_ * (1.0 + fabs(paramOrig));
907 double paramPerturbed = paramOrig;
912 paramPerturbed += dp;
916 paramPerturbed -= dp;
920 static std::string tmp =
"difference=central not supported.\n";
921 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::USR_FATAL_0, tmp);
925 static std::string tmp =
"difference not recognized!\n";
926 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::USR_FATAL_0, tmp);
929 #ifdef Xyce_DEBUG_NONLINEAR
933 <<
" dp = " << std::setw(11)<< std::scientific<< std::setprecision(4) << dp
934 <<
" original value = " << std::setw(16)<< std::scientific<< std::setprecision(9) << paramOrig
935 <<
" modified value = " << std::setw(16)<< std::scientific<< std::setprecision(9) << paramPerturbed
939 loaderPtr_->setParam (paramName, paramPerturbed);
958 #ifdef Xyce_DEBUG_NONLINEAR
961 Xyce::dout() << *iterParam <<
": ";
962 Xyce::dout().width(15); Xyce::dout().precision(7); Xyce::dout().setf(std::ios::scientific);
963 Xyce::dout() <<
"deviceSens_dp = " << dp << std::endl;
967 Xyce::dout() <<
"k = " << std::setw(4) << k1
968 <<
" fpert = "<< std::setw(11)<< std::scientific<< std::setprecision(4)<< (*(
pertFVectorPtr_))[k1]
969 <<
" forig = "<< std::setw(11)<< std::scientific<< std::setprecision(4)<< (*(
origFVectorPtr_))[k1]
970 <<
" dfdp = "<< std::setw(11)<< std::scientific<< std::setprecision(4)<< (*(
dfdpPtrVector_[iparam]))[k1]
974 std::ostringstream filename;
976 filename << std::setw(3) << std::setfill(
'0') << iparam;
978 dfdpPtrVector_[iparam]->writeToFile(const_cast<char *>(filename.str().c_str()));
981 filename << netlistFileName_ <<
"_fpert";
982 filename << std::setw(3) << std::setfill(
'0') << iparam;
984 pertFVectorPtr_->writeToFile(const_cast<char *>(filename.str().c_str()));
993 #ifdef Xyce_PARALLEL_MPI
994 pdsCommPtr->barrier();
1012 bool bsuccess =
true;
1013 std::list<N_UTL_Param>::const_iterator iter = OB.getParams().begin();
1014 std::list<N_UTL_Param>::const_iterator end = OB.getParams().end();
1017 for ( ; iter != end; ++ iter)
1019 if (iter->uTag() ==
"OBJFUNC")
1022 expPtr_ =
new N_UTL_Expression(iter->stringValue());
1025 else if ( std::string( iter->uTag() ,0,5) ==
"PARAM")
1027 ExtendedString tag = iter->stringValue();
1032 int sz = tag.size();
1040 Xyce::Report::UserWarning() << iter->uTag() <<
" is not a recognized sensitivity solver option.\n" << std::endl;
1051 std::vector<std::string> nodes;
1052 expPtr_->get_names(XEXP_NODE, nodes);
1053 std::vector<std::string> instances;
1054 expPtr_->get_names(XEXP_INSTANCE, instances);
1058 std::vector<std::string>::iterator iter;
1059 for (iter=instances.begin();iter!=instances.end();++iter)
1061 ExtendedString tmpString = *iter;
1062 tmpString.toUpper ();
1079 #ifdef Xyce_DEBUG_NONLINEAR
1082 std::vector<std::string>::iterator iter;
1083 std::vector<std::string>::iterator begin =
paramNameVec_.begin();
1084 std::vector<std::string>::iterator end =
paramNameVec_.end ();
1086 for (iter=begin;iter!=end;++iter)
1088 Xyce::dout() << *iter<<std::endl;
1095 N_LAS_System & lasSys_ = (*lasSysPtr_);
1115 bool bsuccess =
true;
1116 std::list<N_UTL_Param>::const_iterator iter = OB.getParams().begin();
1117 std::list<N_UTL_Param>::const_iterator end = OB.getParams().end();
1119 for ( ; iter != end; ++ iter)
1121 if (iter->uTag() ==
"ADJOINT")
1124 static_cast<bool>(iter->getImmutableValue<
bool>());
1126 else if (iter->uTag() ==
"DIRECT")
1129 static_cast<bool>(iter->getImmutableValue<
bool>());
1131 else if (iter->uTag() ==
"OUTPUTSCALED")
1134 static_cast<bool>(iter->getImmutableValue<
bool>());
1136 else if (iter->uTag() ==
"OUTPUTUNSCALED")
1139 static_cast<bool>(iter->getImmutableValue<
bool>());
1141 else if (iter->uTag() ==
"STDOUTPUT")
1144 static_cast<bool>(iter->getImmutableValue<
bool>());
1146 else if (iter->uTag() ==
"DAKOTAFILE")
1149 static_cast<bool>(iter->getImmutableValue<
bool>());
1151 else if (iter->uTag() ==
"DIAGNOSTICFILE")
1154 static_cast<bool>(iter->getImmutableValue<
bool>());
1156 else if (iter->uTag() ==
"DIFFERENCE")
1158 ExtendedString sval=iter->stringValue();
1164 else if(sval==
"REVERSE")
1168 else if(sval==
"CENTRAL")
1171 static std::string tmp =
"difference=central not supported.\n";
1172 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1176 static std::string tmp =
"difference not recognized!\n";
1177 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1180 else if (iter->uTag() ==
"SQRTETA")
1182 sqrtEta_ = iter->getImmutableValue<
double>();
1185 #ifdef Xyce_DEBUG_NONLINEAR
1186 else if (iter->uTag() ==
"DEBUGLEVEL")
1193 Xyce::Report::UserWarning() << iter->uTag() <<
" is not a recognized sensitivity solver option.\n" << std::endl;
1214 bool bsuccess =
true;
1228 bool bsuccess =
true;