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.8 $
36 // Revision Date : $Date: 2015/04/17 22:24:08 $
37 // Current Owner : $Author: dgbaur $
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_CktLoader.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>
56 #include <N_UTL_FeatureTest.h>
57 #include <N_UTL_Diagnostic.h>
58 
59 namespace Xyce {
60 namespace Analysis {
61 
62 //-----------------------------------------------------------------------------
63 // Function : AnalysisManager::setExternalSolverState
64 // Purpose :
65 // Special Notes : Used for multi-level Newton solves, for levels other
66 // than the top level.
67 // Scope : public
68 // Creator : Eric Keiter, SNL
69 // Creation Date : 05/22/2014
70 //-----------------------------------------------------------------------------
71 void
73  Loader::CktLoader & loader,
74  bool external_initJctFlag)
75 {
76  loader.setExternalSolverState(external_initJctFlag);
77 }
78 
79 //-----------------------------------------------------------------------------
80 // Function : AnalysisManager::runSecondLevelStep
81 //
82 // Purpose : This function is similar to "run" except that only a single
83 // integration (or DC sweep) step will be executed.
84 //
85 // Special Notes : Used for multi-level Newton solves, for levels other
86 // than the top level.
87 //
88 // Scope : public
89 // Creator : Eric Keiter, SNL
90 // Creation Date : 03/06/2006
91 //-----------------------------------------------------------------------------
92 bool
94  TimeIntg::TwoLevelError & tlError)
95 {
96  bool status = twoLevelAnalysisObject_->twoLevelStep();
97 
99 
100  return status;
101 }
102 
103 //-----------------------------------------------------------------------------
104 // Function : AnalysisManager::startupSolvers
105 // Purpose :
106 // Special Notes : Used only for 2-level solves.
107 // Scope : public
108 // Creator : Eric R. Keiter
109 // Creation Date : 3/10/2006
110 //-----------------------------------------------------------------------------
111 bool
113  Linear::System & linear_system,
114  Nonlinear::Manager & nonlinear_manager)
115 {
116  bool bsuccess = true;
117 
118  // Hardwire the erroption parameter to 1, which will force the inner
119  // solve (initiated by this function) to only use the Newton success/failure
120  // as step criteria. Predictor-corrector information is handled in the
121  // upper level solver.
123 
124  if (!getCreatorVector().empty()) {
125  twoLevelAnalysisObject_ = (*getCreatorVector().front()).create();
126  }
127  else
128  {
129  Report::UserError() << "Multi-Level Newton solves only supports DC and Transient analysis";
130  return false;
131  }
132 
135 
136  activeOutput_ = new IO::ActiveOutput(getOutputManagerAdapter().getOutputManager());
137  activeOutput_->add(getPDSManager()->getPDSComm()->comm(), getAnalysisMode());
138 
139  // Reset the solvers timer.
140 // xyceTranTimerPtr_.resetStartTime();
141 
142  return bsuccess;
143 }
144 
145 //-----------------------------------------------------------------------------
146 // Function : AnalysisManager::finishSolvers
147 // Purpose :
148 // Special Notes : Used only for 2-level solves.
149 // Scope : public
150 // Creator : Eric Keiter
151 // Creation Date : 3/10/2006
152 //-----------------------------------------------------------------------------
153 bool
155 {
156  bool bsuccess = true;
157 
159 
160  delete activeOutput_;
161  activeOutput_ = 0;
162 
163  return bsuccess;
164 }
165 
166 
167 //-----------------------------------------------------------------------------
168 // Function : AnalysisManager::homotopyStepSuccess
169 // Purpose : Lower-level processing of a successful homotopy step,
170 // which was controlled from the upper level of a 2-level solve.
171 // Special Notes :
172 // Scope : public
173 // Creator : Eric R. Keiter, SNL
174 // Creation Date : 03/20/06
175 //-----------------------------------------------------------------------------
176 void
178  const std::vector<std::string> & paramNames,
179  const std::vector<double> & paramVals)
180 {
181  if (DEBUG_ANALYSIS)
182  Xyce::dout() << "\n " << getNetlistFilename()
183  << " AnalysisManager::homotopyStepSuccess " << std::endl;
184 
185  // output:
186  getOutputManagerAdapter().outputHomotopy( paramNames, paramVals, *getDataStore()->nextSolutionPtr );
187 
188  // update the data arrays:
190 
191  // pass info to the next level down, if it exists.
192  getNonlinearEquationLoader().homotopyStepSuccess(paramNames,paramVals);
193 }
194 
195 //-----------------------------------------------------------------------------
196 // Function : AnalysisManager::homotopyStepFailure
197 //
198 // Purpose : Lower-level processing of a failed homotopy step,
199 // which was controlled from the upper level of a
200 // 2-level solve.
201 // Special Notes :
202 // Scope : public
203 // Creator : Eric R. Keiter, SNL
204 // Creation Date : 03/30/06
205 //-----------------------------------------------------------------------------
206 void
208 {
209  if (DEBUG_ANALYSIS)
210  Xyce::dout() << "\n " << getNetlistFilename()
211  << " AnalysisManager::homotopyStepFailure " << std::endl;
212 
213  // The solutions currently in place represent failure. Get rid of them.
215 
216  // pass info to the next level down, if it exists.
218 }
219 
220 //-----------------------------------------------------------------------------
221 // Function : AnalysisManager::stepSuccess
222 // Purpose :
223 // Special Notes :
224 // Scope : public
225 // Creator : Eric R. Keiter, SNL
226 // Creation Date : 03/12/06
227 //-----------------------------------------------------------------------------
228 void
230  TwoLevelMode analysisUpper)
231 {
232 
233  if (DEBUG_ANALYSIS)
234  Xyce::dout() << "\n " << getNetlistFilename()
235  << " AnalysisManager::stepSuccess " << std::endl;
236 
237  setTwoLevelMode(analysisUpper);
239  switch (analysisUpper)
240  {
242  {
243  Transient * twoLevelTransientAnalysisObject = dynamic_cast<Transient *>(twoLevelAnalysisObject_);
244  if (twoLevelTransientAnalysisObject)
245  {
246  twoLevelTransientAnalysisObject->processSuccessfulDCOP();
247  }
248  else
249  {
250  Report::DevelFatal().in("AnalysisManager::stepSuccess") << "Failed dynamic_cast of twoLevelAnalysisObject to Transient.";
251  }
252  }
253  break;
254 
257  break;
258 
261  break;
262 
263  default:
264  Report::DevelFatal().in("AnalysisManager::stepSecondLevelSuccess") << "TwoLevelMode " << analysisUpper << " is not available";
265  }
266 }
267 
268 //-----------------------------------------------------------------------------
269 // Function : AnalysisManager::stepFailure
270 // Purpose :
271 // Special Notes :
272 // Scope : public
273 // Creator : Eric R. Keiter, SNL
274 // Creation Date : 03/12/06
275 //-----------------------------------------------------------------------------
276 void
278  TwoLevelMode analysisUpper)
279 {
280  setTwoLevelMode(analysisUpper);
282  switch (analysisUpper)
283  {
285  {
286  Transient * twoLevelTransientAnalysisObject = dynamic_cast<Transient *>(twoLevelAnalysisObject_);
287  if (twoLevelTransientAnalysisObject)
288  {
289  twoLevelTransientAnalysisObject->processFailedDCOP();
290  }
291  else
292  {
293  Report::DevelFatal().in("AnalysisManager::stepFailure") << "Failed dynamic_cast of twoLevelAnalysisObject to Transient.";
294  }
295  }
296  break;
299  break;
302  break;
303  default:
304  Report::DevelFatal().in("AnalysisManager::stepSecondLevelFailure") << "TwoLevelMode " << analysisUpper << " is not available";
305  }
306 }
307 
308 //-----------------------------------------------------------------------------
309 // Function : AnalysisManager::getInitialQnorm
310 // Purpose : Used for 2-level solves.
311 // Special Notes :
312 // Scope : public
313 // Creator : Eric R. Keiter, SNL
314 // Creation Date : 03/12/06
315 //-----------------------------------------------------------------------------
316 bool
318  TimeIntg::TwoLevelError & tle) const
319 {
321 
322  return true;
323 }
324 
325 //-----------------------------------------------------------------------------
326 // Function : AnalysisManager::getBreakPoints
327 // Purpose : Used for 2-level solves.
328 // Special Notes :
329 // Scope : public
330 // Creator : Eric R. Keiter, SNL
331 // Creation Date : 03/12/06
332 //-----------------------------------------------------------------------------
333 bool
335  Loader::CktLoader & loader,
336  std::vector<Util::BreakPoint> & breakPointTimes) const
337 {
338  loader.getBreakPoints(breakPointTimes);
339 
340  return true;
341 }
342 
343 //-----------------------------------------------------------------------------
344 // Function : AnalysisManager::startSecondLevelTimeStep
345 // Purpose : used by 2-level solves.
346 // Special Notes : One of the primary purposes for this function is to impose
347 // a lot of upper level information from the top level time
348 // integrator on the inner level time integrator.
349 //
350 // In general, in a 2-level solve, an inner solver doesn't
351 // have enough information to correctly determine the
352 // step size, order, etc. This is in part because the
353 // inner solver, while it knows about the top level solver,
354 // it cannot know about any OTHER inner solvers.
355 //
356 // The top level solver, however, does have enough information.
357 // It gathers break point, error analysis, and other info
358 // from all the inner solves. So, the top level solver
359 // makes all the decisions and imposes them on the inner
360 // solves. This function is where it does that impose.
361 //
362 // Scope : public
363 // Creator : Eric Keiter, SNL
364 // Creation Date : 03/06/2006
365 //-----------------------------------------------------------------------------
366 bool
368  const TimeIntg::TIAParams & tia_params,
369  Nonlinear::Manager & nonlinear_manager,
370  bool beginIntegrationFlag,
371  double nextTimeStep,
372  double nextTime,
373  int currentOrder)
374 {
376 
377  if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
378  {
379  Xyce::dout() << "AnalysisManager::startTimeStep:" << std::endl;
380  }
381 
382  if (VERBOSE_TIME && twoLevelAnalysisObject_)
383  {
385  }
386 
387  if (getSwitchIntegrator())
389 
390  // ------------------------------------------------------------------------
391  // Set the step size, current time and next time.
392 #ifndef Xyce_CHARON
394 #endif
395  {
397  getPDSManager()->getPDSComm()->comm(),
398  nextTimeStep,
399  nextTime,
400  currentOrder,
401  tia_params.bpEnable,
402  tia_params.initialTime,
403  tia_params.minTimeStepsBPGiven,
404  tia_params.minTimeStepsBP);
405  }
406 
408  {
410  }
411 
412  // ------------------------------------------------------------------------
413  // If we've switched the integration method, we need to obtain the
414  // corrector derivative only after we've updated the TimeInfo.
415  if (getSwitchIntegrator())
416  {
417  setSwitchIntegrator(false);
419  }
420 
421  bool dcopFlag = true;
422  Transient *twoLevelTransientAnalysisObject = dynamic_cast<Transient *>(twoLevelAnalysisObject_);
423  if (twoLevelTransientAnalysisObject) {
424  dcopFlag = twoLevelTransientAnalysisObject->getDCOPFlag();
425  }
426 
427  if (VERBOSE_TIME && !dcopFlag)
429 
430  // ------------------------------------------------------------------------
431  // Set the nonlinear solver parameters to those appropriate for the
432  // transient solution, if neccessary.
433  if (!dcopFlag)
434  {
436  }
437 
438  // Ask the method to update its coefficients
441 
442  return true;
443 }
444 
445 } // namespace Analysis
446 } // namespace Xyce
bool getSecondLevelBreakPoints(Loader::CktLoader &loader, std::vector< Util::BreakPoint > &breakPointTimes) const
Pure virtual class to augment a linear system.
void stepSecondLevelFailure(TwoLevelMode analysisUpper)
void setExternalSolverState(Loader::CktLoader &loader, bool external_initJctFlag)
bool runSecondLevelStep(TimeIntg::TwoLevelError &tlError)
void setBeginningIntegrationFlag(bool bif)
int errorAnalysisOption
Error analysis option.
void createTimeIntegratorMethod(const TimeIntg::TIAParams &tia_params, const unsigned int integration_method)
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.
bool startSecondLevelTimeStep(const TimeIntg::TIAParams &tia_params, Nonlinear::Manager &nonlinear_manager, bool beginIntegrationFlag, double nextTimeStep, double nextTime, int currentOrder)
void setPrimaryAnalysisObject(AnalysisBase *primary)
void updateTwoLevelTimeInfo(Parallel::Machine comm, double nextTimeStep, double nextTime, int currentOrder, bool breakpoints_enabled, double initial_time, bool min_time_steps_breakpoint_given, double min_time_steps_breakpoint)
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)
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) ...
TimeIntg::WorkingIntegrationMethod & getWorkingIntegrationMethod()
void setSwitchIntegrator(bool switch_itegrator)
TimeIntg::DataStore * getDataStore()
void setExternalSolverState(bool external_initJctFlag)
void setTwoLevelMode(TwoLevelMode two_level_mode)
bool getBreakPoints(std::vector< Util::BreakPoint > &breakPointTimes) const