Xyce  6.1
N_ANP_SecondLevelManager.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2015 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-----------------------------------------------------------------------------
26 // Filename : $RCSfile: N_ANP_SecondLevelManager.C,v $
27 // Purpose : This file contains the functions which define the time
28 // domain & integration algorithm classes.
29 // Special Notes :
30 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
31 // Creation Date : 01/24/08
32 //
33 // Revision Information:
34 // ---------------------
35 // Revision Number: $Revision: 1.3.2.1 $
36 // Revision Date : $Date: 2015/04/02 18:20:07 $
37 // Current Owner : $Author: tvrusso $
38 //-----------------------------------------------------------------------------
39 
40 #include <Xyce_config.h>
41 
42 #include <N_ANP_OutputMgrAdapter.h>
44 #include <N_ANP_Transient.h>
45 #include <N_ERH_Message.h>
46 #include <N_IO_ActiveOutput.h>
47 #include <N_LOA_Loader.h>
49 #include <N_NLS_Manager.h>
50 #include <N_PDS_Comm.h>
51 #include <N_PDS_Manager.h>
52 #include <N_TIA_DataStore.h>
53 #include <N_TIA_StepErrorControl.h>
54 #include <N_TIA_TimeIntInfo.h>
57 #include <N_UTL_FeatureTest.h>
58 #include <N_UTL_Diagnostic.h>
59 
60 namespace Xyce {
61 namespace Analysis {
62 
63 //-----------------------------------------------------------------------------
64 // Function : AnalysisManager::setExternalSolverState
65 // Purpose :
66 // Special Notes : Used for multi-level Newton solves, for levels other
67 // than the top level.
68 // Scope : public
69 // Creator : Eric Keiter, SNL
70 // Creation Date : 05/22/2014
71 //-----------------------------------------------------------------------------
73 {
75 }
76 
77 //-----------------------------------------------------------------------------
78 // Function : AnalysisManager::runSecondLevelStep
79 //
80 // Purpose : This function is similar to "run" except that only a single
81 // integration (or DC sweep) step will be executed.
82 //
83 // Special Notes : Used for multi-level Newton solves, for levels other
84 // than the top level.
85 //
86 // Scope : public
87 // Creator : Eric Keiter, SNL
88 // Creation Date : 03/06/2006
89 //-----------------------------------------------------------------------------
90 bool
92  const TimeIntg::TimeIntInfo & tiInfo,
93  TimeIntg::TwoLevelError & tlError)
94 {
96  {
97  if (VERBOSE_TIME)
98  Xyce::dout() << "AnalysisManager::runStep:" << std::endl
99  << "nextTime = " << tiInfo.nextTime << std::endl
100  << "stepSize = " << tiInfo.nextTimeStep << std::endl;
101  }
102  else if (getAnalysisMode() == ANP_MODE_DC_SWEEP)
103  {
104  // do nothing
105  }
106  else
107  {
108  Report::DevelFatal().in("AnalysisManager::runSecondLevelStep")
109  << "Analysis mode " << getAnalysisMode() << " is not available";
110  return false;
111  }
112 
113 // solverStartTime_ = elapsedTimerPtr_->elapsedTime();
114 
115  bool status = twoLevelAnalysisObject_->twoLevelStep();
116 
118 
119  return status;
120 }
121 
122 //-----------------------------------------------------------------------------
123 // Function : AnalysisManager::startupSolvers
124 // Purpose :
125 // Special Notes : Used only for 2-level solves.
126 // Scope : public
127 // Creator : Eric R. Keiter
128 // Creation Date : 3/10/2006
129 //-----------------------------------------------------------------------------
130 bool
132  Linear::System & linear_system,
133  Nonlinear::Manager & nonlinear_manager)
134 {
135  bool bsuccess = true;
136 
137  // Hardwire the erroption parameter to 1, which will force the inner
138  // solve (initiated by this function) to only use the Newton success/failure
139  // as step criteria. Predictor-corrector information is handled in the
140  // upper level solver.
142 
143  if (!getCreatorVector().empty()) {
144  twoLevelAnalysisObject_ = (*getCreatorVector().front()).create();
145  }
146  else
147  {
148  Report::UserError() << "Multi-Level Newton solves only supports DC and Transient analysis";
149  return false;
150  }
151 
154 
155  activeOutput_ = new IO::ActiveOutput(getOutputManagerAdapter().getOutputManager());
156  activeOutput_->add(getPDSManager()->getPDSComm()->comm(), getAnalysisMode());
157 
158  // Reset the solvers timer.
159 // xyceTranTimerPtr_.resetStartTime();
160 
161  return bsuccess;
162 }
163 
164 //-----------------------------------------------------------------------------
165 // Function : AnalysisManager::finishSolvers
166 // Purpose :
167 // Special Notes : Used only for 2-level solves.
168 // Scope : public
169 // Creator : Eric Keiter
170 // Creation Date : 3/10/2006
171 //-----------------------------------------------------------------------------
172 bool
174 {
175  bool bsuccess = true;
176 
178 
179  delete activeOutput_;
180  activeOutput_ = 0;
181 
182  return bsuccess;
183 }
184 
185 
186 //-----------------------------------------------------------------------------
187 // Function : AnalysisManager::homotopyStepSuccess
188 // Purpose : Lower-level processing of a successful homotopy step,
189 // which was controlled from the upper level of a 2-level solve.
190 // Special Notes :
191 // Scope : public
192 // Creator : Eric R. Keiter, SNL
193 // Creation Date : 03/20/06
194 //-----------------------------------------------------------------------------
195 void
197  const std::vector<std::string> & paramNames,
198  const std::vector<double> & paramVals)
199 {
200  if (DEBUG_ANALYSIS)
201  Xyce::dout() << "\n " << getNetlistFilename()
202  << " AnalysisManager::homotopyStepSuccess " << std::endl;
203 
204  // output:
205  getOutputManagerAdapter().outputHomotopy( paramNames, paramVals, *getDataStore()->nextSolutionPtr );
206 
207  // update the data arrays:
209 
210  // pass info to the next level down, if it exists.
211  getNonlinearEquationLoader().homotopyStepSuccess(paramNames,paramVals);
212 }
213 
214 //-----------------------------------------------------------------------------
215 // Function : AnalysisManager::homotopyStepFailure
216 //
217 // Purpose : Lower-level processing of a failed homotopy step,
218 // which was controlled from the upper level of a
219 // 2-level solve.
220 // Special Notes :
221 // Scope : public
222 // Creator : Eric R. Keiter, SNL
223 // Creation Date : 03/30/06
224 //-----------------------------------------------------------------------------
225 void
227 {
228  if (DEBUG_ANALYSIS)
229  Xyce::dout() << "\n " << getNetlistFilename()
230  << " AnalysisManager::homotopyStepFailure " << std::endl;
231 
232  // The solutions currently in place represent failure. Get rid of them.
234 
235  // pass info to the next level down, if it exists.
237 }
238 
239 //-----------------------------------------------------------------------------
240 // Function : AnalysisManager::stepSuccess
241 // Purpose :
242 // Special Notes :
243 // Scope : public
244 // Creator : Eric R. Keiter, SNL
245 // Creation Date : 03/12/06
246 //-----------------------------------------------------------------------------
247 void
249  TwoLevelMode analysisUpper)
250 {
251 
252  if (DEBUG_ANALYSIS)
253  Xyce::dout() << "\n " << getNetlistFilename()
254  << " AnalysisManager::stepSuccess " << std::endl;
255 
256  setTwoLevelMode(analysisUpper);
258  switch (analysisUpper)
259  {
261  {
262  Transient * twoLevelTransientAnalysisObject = dynamic_cast<Transient *>(twoLevelAnalysisObject_);
263  if (twoLevelTransientAnalysisObject)
264  {
265  twoLevelTransientAnalysisObject->processSuccessfulDCOP();
266  }
267  else
268  {
269  Report::DevelFatal().in("AnalysisManager::stepSuccess") << "Failed dynamic_cast of twoLevelAnalysisObject to Transient.";
270  }
271  }
272  break;
275  break;
278  break;
279  default:
280  Report::DevelFatal().in("AnalysisManager::stepSecondLevelSuccess") << "TwoLevelMode " << analysisUpper << " is not available";
281  }
282 }
283 
284 //-----------------------------------------------------------------------------
285 // Function : AnalysisManager::stepFailure
286 // Purpose :
287 // Special Notes :
288 // Scope : public
289 // Creator : Eric R. Keiter, SNL
290 // Creation Date : 03/12/06
291 //-----------------------------------------------------------------------------
292 void
294  TwoLevelMode analysisUpper)
295 {
296  setTwoLevelMode(analysisUpper);
298  switch (analysisUpper)
299  {
301  {
302  Transient * twoLevelTransientAnalysisObject = dynamic_cast<Transient *>(twoLevelAnalysisObject_);
303  if (twoLevelTransientAnalysisObject)
304  {
305  twoLevelTransientAnalysisObject->processFailedDCOP();
306  }
307  else
308  {
309  Report::DevelFatal().in("AnalysisManager::stepFailure") << "Failed dynamic_cast of twoLevelAnalysisObject to Transient.";
310  }
311  }
312  break;
315  break;
318  break;
319  default:
320  Report::DevelFatal().in("AnalysisManager::stepSecondLevelFailure") << "TwoLevelMode " << analysisUpper << " is not available";
321  }
322 }
323 
324 //-----------------------------------------------------------------------------
325 // Function : AnalysisManager::getInitialQnorm
326 // Purpose : Used for 2-level solves.
327 // Special Notes :
328 // Scope : public
329 // Creator : Eric R. Keiter, SNL
330 // Creation Date : 03/12/06
331 //-----------------------------------------------------------------------------
332 bool
334  TimeIntg::TwoLevelError & tle) const
335 {
337 
338  return true;
339 }
340 
341 //-----------------------------------------------------------------------------
342 // Function : AnalysisManager::getBreakPoints
343 // Purpose : Used for 2-level solves.
344 // Special Notes :
345 // Scope : public
346 // Creator : Eric R. Keiter, SNL
347 // Creation Date : 03/12/06
348 //-----------------------------------------------------------------------------
349 bool
351  std::vector<Util::BreakPoint> & breakPointTimes) const
352 {
353  getLoader().getBreakPoints(breakPointTimes);
354 
355  return true;
356 }
357 
358 //-----------------------------------------------------------------------------
359 // Function : AnalysisManager::startSecondLevelTimeStep
360 // Purpose : used by 2-level solves.
361 // Special Notes : One of the primary purposes for this function is to impose
362 // a lot of upper level information from the top level time
363 // integrator on the inner level time integrator. This
364 // information is contained in the TimeIntg::TimeIntInfo
365 // class (tiInfo here). This includes things like the
366 // time step size, the time integration order, etc.
367 //
368 // In general, in a 2-level solve, an inner solver doesn't
369 // have enough information to correctly determine the
370 // step size, order, etc. This is in part because the
371 // inner solver, while it knows about the top level solver,
372 // it cannot know about any OTHER inner solvers.
373 //
374 // The top level solver, however, does have enough information.
375 // It gathers break point, error analysis, and other info
376 // from all the inner solves. So, the top level solver
377 // makes all the decisions and imposes them on the inner
378 // solves. This function is where it does that impose.
379 //
380 // Scope : public
381 // Creator : Eric Keiter, SNL
382 // Creation Date : 03/06/2006
383 //-----------------------------------------------------------------------------
384 bool
386  const TimeIntg::TIAParams & tia_params,
387  Nonlinear::Manager & nonlinear_manager,
388  const TimeIntg::TimeIntInfo & tiInfo)
389 {
390  // Beginning Integration flag is the only piece of data in tiInfo that is
391  // currently owned by the control algorithm class. Everything else
392  // is owned by the step error control, or the integration method.
394 
395  if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
396  {
397  Xyce::dout() << "AnalysisManager::startTimeStep:" << std::endl;
398  }
399 
400  if (VERBOSE_TIME && twoLevelAnalysisObject_)
401  {
403  }
404 
405  if (getSwitchIntegrator())
407 
408  // ------------------------------------------------------------------------
409  // Set the step size, current time and next time.
410 #ifndef Xyce_CHARON
412 #endif
413  {
415  getPDSManager()->getPDSComm()->comm(),
416  tiInfo,
417  tia_params.bpEnable,
418  tia_params.initialTime,
419  tia_params.minTimeStepsBPGiven,
420  tia_params.minTimeStepsBP);
421  }
422 
424  {
425  getWorkingIntegrationMethod().setTwoLevelTimeInfo(tiInfo); // new-dae only
426  }
427 
428  // ------------------------------------------------------------------------
429  // If we've switched the integration method, we need to obtain the
430  // corrector derivative only after we've updated the TimeInfo.
431  if (getSwitchIntegrator())
432  {
433  setSwitchIntegrator(false);
435  }
436 
437  bool dcopFlag = true;
438  Transient *twoLevelTransientAnalysisObject = dynamic_cast<Transient *>(twoLevelAnalysisObject_);
439  if (twoLevelTransientAnalysisObject) {
440  dcopFlag = twoLevelTransientAnalysisObject->getDCOPFlag();
441  }
442 
443  if (VERBOSE_TIME && !dcopFlag)
445 
446  // ------------------------------------------------------------------------
447  // Set the nonlinear solver parameters to those appropriate for the
448  // transient solution, if neccessary.
449  if (!dcopFlag)
450  {
452  }
453 
454  // Ask the method to update its coefficients
457 
458  return true;
459 }
460 
461 } // namespace Analysis
462 } // namespace Xyce
Pure virtual class to augment a linear system.
void stepSecondLevelFailure(TwoLevelMode analysisUpper)
void updateTwoLevelTimeInfo(Parallel::Machine comm, const TimeIntInfo &tiInfo, bool breakpoints_enabled, double initial_time, bool min_time_steps_breakpoint_given, double min_time_steps_breakpoint)
void setBeginningIntegrationFlag(bool bif)
int errorAnalysisOption
Error analysis option.
void createTimeIntegratorMethod(const TimeIntg::TIAParams &tia_params, const unsigned int integration_method)
double nextTimeStep
Step error control next time step.
void outputHomotopy(const std::vector< std::string > &paramNames, const std::vector< double > &paramVals, Linear::Vector &solnVecPtr)
void stepSecondLevelSuccess(TwoLevelMode analysisUpper)
void setAnalysisMode(AnalysisMode mode)
Parallel::Manager * getPDSManager() const
TimeIntg::StepErrorControl & getStepErrorControl()
const std::string & getNetlistFilename() const
void homotopyStepSuccess(const std::vector< std::string > &paramNames, const std::vector< double > &paramVals)
int minTimeStepsBP
User specified mininum number of steps between breakpoints.
void setPrimaryAnalysisObject(AnalysisBase *primary)
double nextTime
Step error control next time.
bool runSecondLevelStep(const TimeIntg::TimeIntInfo &tiInfo, TimeIntg::TwoLevelError &tlError)
void setExternalSolverState(const Device::SolverState &ss)
bool bpEnable
Enable breakpoints flag.
Nonlinear::AnalysisMode nonlinearAnalysisMode(Mode mode)
Returns the nonlinear analysis mode given the analysis mode.
virtual void printStepHeader(std::ostream &os)
void setTwoLevelMode(TwoLevelMode current_mode)
bool startSecondLevelTimeStep(const TimeIntg::TIAParams &tia_params, Nonlinear::Manager &nonlinear_manager, const TimeIntg::TimeIntInfo &tiInfo)
OutputMgrAdapter & getOutputManagerAdapter() const
Loader::NonlinearEquationLoader & getNonlinearEquationLoader()
void homotopyStepSuccess(const std::vector< std::string > &paramNames, const std::vector< double > &paramVals)
const TimeIntg::TIAParams & getTIAParams() const
bool getSecondLevelInitialQnorm(TimeIntg::TwoLevelError &tle) const
bool startupSecondLevelSolvers(Linear::System &linear_system, Nonlinear::Manager &nonlinear_manager)
double initialTime
Beginning time for the time integrator (StepErrorControl, integrators access from StepErrorControl) ...
bool getSecondLevelBreakPoints(std::vector< Util::BreakPoint > &breakPointTimes) const
TimeIntg::WorkingIntegrationMethod & getWorkingIntegrationMethod()
void setSwitchIntegrator(bool switch_itegrator)
TimeIntg::DataStore * getDataStore()
virtual void setExternalSolverState(const Device::SolverState &ss)
Definition: N_LOA_Loader.h:309
virtual bool getBreakPoints(std::vector< Util::BreakPoint > &breakPointTimes) const
Definition: N_LOA_Loader.h:272