46 #include <Xyce_config.h>
59 #include <N_ERH_ErrorMgr.h>
61 #include <N_LAS_Vector.h>
64 #include <N_PDS_Comm.h>
65 #include <N_PDS_MPI.h>
66 #include <N_PDS_Manager.h>
67 #include <N_PDS_Serial.h>
71 #include <N_UTL_Algorithm.h>
72 #include <N_UTL_Diagnostic.h>
73 #include <N_UTL_Expression.h>
74 #include <N_UTL_ExtendedString.h>
75 #include <N_UTL_FeatureTest.h>
76 #include <N_UTL_OptionBlock.h>
108 int difference,
bool forceFD_,
double sqrtEta_, std::string & netlistFilename_,
111 const std::vector<std::string> & paramNameVec_,
132 std::vector<std::string>::const_iterator firstParam = paramNameVec_.begin ();
133 std::vector<std::string>::const_iterator lastParam = paramNameVec_.end ();
134 std::vector<std::string>::const_iterator iterParam;
136 int maxParamStringSize_=0;
137 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
139 for ( iterParam=firstParam, iparam=0;
140 iterParam!=lastParam; ++iterParam, ++iparam )
142 int sz = paramNameVec_[iparam].size();
143 if (sz > maxParamStringSize_)
145 maxParamStringSize_ = sz;
150 for ( iterParam=firstParam, iparam=0;
151 iterParam!=lastParam; ++iterParam, ++iparam )
153 std::string paramName(*iterParam);
157 double paramOrig = 0.0;
159 analysisManager_.
getPDSManager()->getPDSComm()->comm(),paramName, paramOrig);
163 std::string msg(
"Sensitivity::loadSensitivityResiduals: cannot find parameter ");
165 N_ERH_ErrorMgr::report (N_ERH_ErrorMgr::DEV_FATAL, msg);
170 bool analyticAvailable =
false;
175 if (analyticAvailable)
177 std::vector<double> dfdpVec;
178 std::vector<double> dqdpVec;
179 std::vector<double> dbdpVec;
181 std::vector<int> FindicesVec;
182 std::vector<int> QindicesVec;
183 std::vector<int> BindicesVec;
186 dfdpVec,dqdpVec,dbdpVec,
187 FindicesVec, QindicesVec, BindicesVec);
189 dfdpPtrVector_[iparam]->putScalar(0.0);
190 dqdpPtrVector_[iparam]->putScalar(0.0);
191 dbdpPtrVector_[iparam]->putScalar(0.0);
193 int Fsize=FindicesVec.size();
194 for (
int i=0;i<Fsize;++i)
196 Linear::Vector & dfdpRef = *(dfdpPtrVector_[iparam]);
197 dfdpRef[FindicesVec[i]] += dfdpVec[i];
200 int Qsize=QindicesVec.size();
201 for (
int i=0;i<Qsize;++i)
203 Linear::Vector & dqdpRef = *(dqdpPtrVector_[iparam]);
204 dqdpRef[QindicesVec[i]] += dqdpVec[i];
207 int Bsize=BindicesVec.size();
208 for (
int i=0;i<Bsize;++i)
210 Linear::Vector & dbdpRef = *(dbdpPtrVector_[iparam]);
211 dbdpRef[BindicesVec[i]] += dbdpVec[i];
214 dfdpPtrVector_[iparam]->fillComplete();
215 dqdpPtrVector_[iparam]->fillComplete();
216 dbdpPtrVector_[iparam]->fillComplete();
218 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
220 Xyce::dout() << *iterParam <<
": ";
221 Xyce::dout().setf(std::ios::scientific);
222 Xyce::dout() << std::endl;
224 int solutionSize_ = dfdpPtrVector_[iparam]->localLength();
226 for (
int k1 = 0; k1 < solutionSize_; ++k1)
229 <<
"dfdp["<<std::setw(3)<<k1<<
"]= "<<std::setw(15)<<std::scientific<<std::setprecision(8)<<(*(dfdpPtrVector_[iparam]))[k1]
230 <<
" dqdp["<<std::setw(3)<<k1<<
"]= "<<std::setw(15)<<std::scientific<<std::setprecision(8)<<(*(dqdpPtrVector_[iparam]))[k1]
231 <<
" dbdp["<<std::setw(3)<<k1<<
"]= "<<std::setw(15)<<std::scientific<<std::setprecision(8)<<(*(dbdpPtrVector_[iparam]))[k1]
238 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
240 Xyce::dout() << std::endl <<
" Calculating numerical df/dp, dq/dp and db/dp for: ";
241 Xyce::dout() << *iterParam << std::endl;
250 double dp = sqrtEta_ * (1.0 + fabs(paramOrig));
251 double paramPerturbed = paramOrig;
255 paramPerturbed += dp;
259 paramPerturbed -= dp;
263 static std::string tmp =
"difference=central not supported.\n";
264 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::USR_FATAL_0, tmp);
268 static std::string tmp =
"difference not recognized!\n";
269 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::USR_FATAL_0, tmp);
272 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
274 Xyce::dout() << std::setw(maxParamStringSize_)<< *iterParam
275 <<
" dp = " << std::setw(11)<< std::scientific<< std::setprecision(4) << dp
276 <<
" original value = " << std::setw(16)<< std::scientific<< std::setprecision(9) << paramOrig
277 <<
" modified value = " << std::setw(16)<< std::scientific<< std::setprecision(9) << paramPerturbed
281 nonlinearEquationLoader_.
setParam (paramName, paramPerturbed);
287 nonlinearEquationLoader_.
loadRHS();
296 dfdpPtrVector_[iparam]->putScalar(0.0);
297 dfdpPtrVector_[iparam]->addVec (+1.0, pertFVector);
298 dfdpPtrVector_[iparam]->addVec (-1.0, origFVector);
299 dfdpPtrVector_[iparam]->scale(rdp);
302 dqdpPtrVector_[iparam]->putScalar(0.0);
303 dqdpPtrVector_[iparam]->addVec (+1.0, pertQVector);
304 dqdpPtrVector_[iparam]->addVec (-1.0, origQVector);
305 dqdpPtrVector_[iparam]->scale(rdp);
308 dbdpPtrVector_[iparam]->putScalar(0.0);
309 dbdpPtrVector_[iparam]->addVec (+1.0, pertBVector);
310 dbdpPtrVector_[iparam]->addVec (-1.0, origBVector);
311 dbdpPtrVector_[iparam]->scale(rdp);
313 if (DEBUG_NONLINEAR && isActive(Diag::SENS_SOLVER))
315 Xyce::dout() << *iterParam <<
": ";
316 Xyce::dout().width(15); Xyce::dout().precision(7); Xyce::dout().setf(std::ios::scientific);
317 Xyce::dout() <<
"deviceSens_dp = " << dp << std::endl;
320 int solutionSize_ = pertFVector.localLength();
322 for (
int k1 = 0; k1 < solutionSize_; ++k1)
326 <<
"fpert["<<std::setw(3)<<k1<<
"]= "<<std::setw(15)<<std::scientific<<std::setprecision(8)<<(pertFVector)[k1]
327 <<
" forig["<<std::setw(3)<<k1<<
"]= "<<std::setw(15)<<std::scientific<<std::setprecision(8)<<(origFVector)[k1]
328 <<
" dfdp ["<<std::setw(3)<<k1<<
"]= "<<std::setw(15)<<std::scientific<<std::setprecision(8)<<(*(dfdpPtrVector_[iparam]))[k1]
332 Xyce::dout() << std::endl;
333 for (
int k1 = 0; k1 < solutionSize_; ++k1)
336 <<
"qpert["<<std::setw(3)<<k1<<
"]= "<<std::setw(15)<<std::scientific<<std::setprecision(8)<<(pertQVector)[k1]
337 <<
" qorig["<<std::setw(3)<<k1<<
"]= "<<std::setw(15)<<std::scientific<<std::setprecision(8)<<(origQVector)[k1]
338 <<
" dqdp ["<<std::setw(3)<<k1<<
"]= "<<std::setw(15)<<std::scientific<<std::setprecision(8)<<(*(dqdpPtrVector_[iparam]))[k1]
342 Xyce::dout() << std::endl ;
343 for (
int k1 = 0; k1 < solutionSize_; ++k1)
346 <<
"bpert["<<std::setw(3)<<k1<<
"]= "<<std::setw(15)<<std::scientific<<std::setprecision(8)<<(pertBVector)[k1]
347 <<
" borig["<<std::setw(3)<<k1<<
"]= "<<std::setw(15)<<std::scientific<<std::setprecision(8)<<(origBVector)[k1]
348 <<
" dbdp ["<<std::setw(3)<<k1<<
"]= "<<std::setw(15)<<std::scientific<<std::setprecision(8)<<(*(dbdpPtrVector_[iparam]))[k1]
353 std::ostringstream filename;
354 filename << netlistFilename_ <<
"_dfdp";
355 filename << std::setw(3) << std::setfill(
'0') << iparam;
357 dfdpPtrVector_[iparam]->writeToFile(const_cast<char *>(filename.str().c_str()));
360 filename << netlistFilename_ <<
"_fpert";
361 filename << std::setw(3) << std::setfill(
'0') << iparam;
363 pertFVector.writeToFile(const_cast<char *>(filename.str().c_str()));
366 filename << netlistFilename_ <<
"_dqdp";
367 filename << std::setw(3) << std::setfill(
'0') << iparam;
369 dqdpPtrVector_[iparam]->writeToFile(const_cast<char *>(filename.str().c_str()));
372 filename << netlistFilename_ <<
"_qpert";
373 filename << std::setw(3) << std::setfill(
'0') << iparam;
375 pertQVector.writeToFile(const_cast<char *>(filename.str().c_str()));
378 filename << netlistFilename_ <<
"_dbdp";
379 filename << std::setw(3) << std::setfill(
'0') << iparam;
381 dbdpPtrVector_[iparam]->writeToFile(const_cast<char *>(filename.str().c_str()));
384 filename << netlistFilename_ <<
"_bpert";
385 filename << std::setw(3) << std::setfill(
'0') << iparam;
387 pertBVector.writeToFile(const_cast<char *>(filename.str().c_str()));
391 nonlinearEquationLoader_.
setParam (paramName, paramOrig);
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_)
std::vector< Linear::Vector * > nextDqdpPtrVector
Pure virtual class to augment a linear system.
bool analyticSensitivitiesAvailable(std::string &name)
std::vector< Linear::Vector * > nextDbdpPtrVector
bool getParamAndReduce(Parallel::Machine comm, const std::string &name, double &val) const
std::vector< Linear::Vector * > nextDfdpPtrVector
Parallel::Manager * getPDSManager() const
bool setParam(std::string &name, double val, bool overrideOriginal=false)
Linear::Vector * daeQVectorPtr
Linear::Vector * daeFVectorPtr
void getAnalyticSensitivities(std::string &name, std::vector< double > &dfdpVec, std::vector< double > &dqdpVec, std::vector< double > &dbdpVec, std::vector< int > &FindicesVec, std::vector< int > &QindicesVec, std::vector< int > &BindicesVec) const
AnalysisManager & analysisManager_
Linear::Vector * daeBVectorPtr