Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
e_trsolver.cpp
Go to the documentation of this file.
1 /*
2  * e_trsolver.cpp - external transient solver interface class implementation
3  *
4  * Copyright (C) 2004, 2005, 2006, 2007, 2009 Stefan Jahn <stefan@lkcc.org>
5  *
6  * This is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This software is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this package; see the file COPYING. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  * $Id$
22  *
23  */
24 
34 #if HAVE_CONFIG_H
35 # include <config.h>
36 #endif
37 
38 #include <stdio.h>
39 #include <string.h>
40 #include <cmath>
41 #include <float.h>
42 
43 #include "compat.h"
44 #include "object.h"
45 #include "logging.h"
46 #include "complex.h"
47 #include "circuit.h"
48 #include "sweep.h"
49 #include "net.h"
50 #include "netdefs.h"
51 #include "analysis.h"
52 #include "nasolver.h"
53 #include "history.h"
54 #include "transient.h"
55 #include "exception.h"
56 #include "exceptionstack.h"
57 #include "environment.h"
58 #include "e_trsolver.h"
59 #include "component_id.h"
60 #include "ecvs.h"
61 
62 #define STEPDEBUG 0 // set to zero for release
63 #define BREAKPOINTS 0 // exact breakpoint calculation
64 
65 #ifndef dState
66 #define dState 0 // delta T state
67 #endif
68 
69 #ifndef sState
70 #define sState 1 // solution state
71 #endif
72 
73 // Macro for the n-th state of the solution vector history.
74 #ifndef SOL
75 #define SOL(state) (solution[(int) getState (sState, (state))])
76 #endif
77 
78 namespace qucs {
79 
80 using namespace transient;
81 
82 // Constructor creates an unnamed instance of the trsolver class.
84  : trsolver ()
85 {
86  //swp = NULL;
88  //setDescription ("m-transient");
89  //for (int i = 0; i < 8; i++) solution[i] = NULL;
90  //tHistory = NULL;
91  //relaxTSR = false;
92  //initialDC = true;
93 
94  // initialise the message function pointer to
95  // point to the PrintWarningMsg function
96  messagefcn = &logprint;
97 #if DEBUG
98  //loginit ();
99  // produce an actual log file
100 // file_error = file_status = fopen("e_trsolver.log", "w+");
101 // precinit ();
102 // ::srand (::time (NULL));
103 #endif // DEBUG
104 }
105 
106 // Constructor creates a named instance of the e_trsolver class.
108  : trsolver (n)
109 {
110  //swp = NULL;
112  //setDescription ("m-transient");
113  //for (int i = 0; i < 8; i++) solution[i] = NULL;
114  //tHistory = NULL;
115  //relaxTSR = false;
116  //initialDC = true;
117 
118  // initialise the message function pointer to
119  // point to the PrintWarningMsg function
120  messagefcn = &logprint;
121 }
122 
123 // Destructor deletes the e_trsolver class object.
125 {
126 
127  solve_post ();
128  if (progress) logprogressclear (40);
129 
130  deinitTR ();
131 
132  if (swp) delete swp;
133 
134  for (int i = 0; i < 8; i++)
135  {
136  if (solution[i] != NULL)
137  {
138  delete solution[i];
139  }
140  if (lastsolution[i] != NULL)
141  {
142  delete lastsolution[i];
143  }
144  }
145  if (tHistory) delete tHistory;
146 
147 }
148 
149 /* The copy constructor creates a new instance of the e_trsolver class
150  based on the given e_trsolver object. */
152  : trsolver (o)
153 {
154  swp = o.swp ? new sweep (*o.swp) : NULL;
155  for (int i = 0; i < 8; i++) solution[i] = NULL;
156  tHistory = o.tHistory ? new history (*o.tHistory) : NULL;
157  relaxTSR = o.relaxTSR;
158  initialDC = o.initialDC;
159 }
160 
162 {
163  circuit * root = subnet->getRoot ();
164 
165  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ())
166  {
167  messagefcn (0, c->getName() );
168 
169  if (c->getSubcircuit ()) {
170  printf ("subcircuit Name %s\n", c->getSubcircuit ());
171  }
172  }
173 
174  //netlist_list();
175 }
176 
177 
178 /* This is the initialisation function for the slaved transient
179  netlist solver. It prepares the circuit for simulation. */
180 int e_trsolver::init (nr_double_t start, nr_double_t firstdelta, int mode)
181 {
182  // run the equation solver for the netlist
183  this->getEnv()->runSolver();
184 
185  int error = 0;
186  char * solver = getPropertyString ("Solver");
187  relaxTSR = !strcmp (getPropertyString ("relaxTSR"), "yes") ? true : false;
188  initialDC = !strcmp (getPropertyString ("initialDC"), "yes") ? true : false;
189  // fetch simulation properties
190  MaxIterations = getPropertyInteger ("MaxIter");
191  reltol = getPropertyDouble ("reltol");
192  abstol = getPropertyDouble ("abstol");
193  vntol = getPropertyDouble ("vntol");
194 
195  runs++;
196  saveCurrent = current = 0;
197  stepDelta = -1;
198  converged = 0;
199  fixpoint = 0;
200  lastsynctime = 0.0;
202 
203  // Choose a solver.
204  if (!strcmp (solver, "CroutLU"))
206  else if (!strcmp (solver, "DoolittleLU"))
208  else if (!strcmp (solver, "HouseholderQR"))
210  else if (!strcmp (solver, "HouseholderLQ"))
212  else if (!strcmp (solver, "GolubSVD"))
214 
215  // Perform initial DC analysis.
216  if (initialDC)
217  {
218  error = dcAnalysis ();
219  if (error)
220  return -1;
221  }
222 
223  // Initialize transient analysis.
224  setDescription ("transient");
225  initETR (start, firstdelta, mode);
227  solve_pre ();
228 
229  // Recall the DC solution.
230  recallSolution ();
231 
232  // Apply the nodesets and adjust previous solutions.
233  applyNodeset (false);
234  fillSolution (x);
236 
237  // Tell integrators to be initialized.
238  setMode (MODE_INIT);
239 
240  // reset the circuit status to not running so the histories
241  // etc will be reinitialised on the first time step
242  running = 0;
243  rejected = 0;
244  if (mode == ETR_MODE_ASYNC)
245  {
246  delta /= 10;
247 
248  }
249  else if (mode == ETR_MODE_SYNC)
250  {
251  //lastsynctime = start - delta;
252  }
253  else
254  {
256  e->setText ("Unknown ETR mode.");
257  throw_exception (e);
258  return -2;
259  }
261  adjustOrder (1);
262 
263  storeHistoryAges ();
264 
265  return 0;
266 
267 }
268 
269 /* Stores all the initial history lengths requested by the circuit
270  elements for later use (to make sure we don't set the histories
271  to be less than these initial requested values) */
273 {
274  circuit * root = subnet->getRoot ();
275  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ())
276  {
277  // get the a
278  if (c->hasHistory ())
279  {
280  initialhistages.push_back (c->getHistoryAge ());
281  }
282  }
283 }
284 
286 {
287  for (int i = 0; i < 8; i++) * lastsolution[(int) getState (sState, (i))] = *s;
288 }
289 
290 /* Goes through the list of circuit objects and runs its initTR()
291  function. */
292 void e_trsolver::initETR (nr_double_t start, nr_double_t firstdelta, int mode)
293 {
294  char * IMethod = getPropertyString ("IntegrationMethod");
295  //nr_double_t start = getPropertyDouble ("Start");
296  //nr_double_t stop = start + firstdelta;
297  //nr_double_t points = 1.0;
298 
299  // fetch corrector integration method and determine predicor method
300  corrMaxOrder = getPropertyInteger ("Order");
305 
306  // initialize step values
307  if (mode == ETR_MODE_ASYNC){
308  delta = getPropertyDouble ("InitialStep");
309  deltaMin = getPropertyDouble ("MinStep");
310  deltaMax = getPropertyDouble ("MaxStep");
311  if (deltaMax == 0.0)
312  deltaMax = firstdelta; // MIN ((stop - start) / (points - 1), stop / 200);
313  if (deltaMin == 0.0)
314  deltaMin = NR_TINY * 10 * deltaMax;
315  if (delta == 0.0)
316  delta = firstdelta; // MIN (stop / 200, deltaMax) / 10;
317  if (delta < deltaMin) delta = deltaMin;
318  if (delta > deltaMax) delta = deltaMax;
319  }
320  else if (mode == ETR_MODE_SYNC)
321  {
322  delta = firstdelta;
323  deltaMin = NR_TINY * 10;
324  deltaMax = NR_MAX / 10;
325  }
326 
327  // initialize step history
328  setStates (2);
329  initStates ();
330  // initialise the history of states, setting them all to 'delta'
332 
333  // copy the initialised states to the 'deltas' array
335  // copy the deltas to all the circuits
336  setDelta ();
337  // set the initial corrector and predictor coefficients
340 
341  // initialize history of solution vectors (solutions)
342  for (int i = 0; i < 8; i++)
343  {
344  // solution contains the last sets of node voltages and branch
345  // currents at each of the last 8 'deltas'.
346  // Note for convenience the definition:
347  // #define SOL(state) (solution[(int) getState (sState, (state))])
348  // is provided and used elsewhere to update the solutions
350  setState (sState, (nr_double_t) i, i);
352  }
353 
354  // Initialise history tracking for asynchronous solvers
355  // See acceptstep_async and rejectstep_async for more
356  // information
359  lastdelta = delta;
360 
361  // tell circuit elements about the transient analysis
362  circuit *c, * root = subnet->getRoot ();
363  for (c = root; c != NULL; c = (circuit *) c->getNext ())
364  initCircuitTR (c);
365  // also initialize the created circuit elements
366  for (c = root; c != NULL; c = (circuit *) c->getPrev ())
367  initCircuitTR (c);
368 }
369 
371 {
372  char buf [1024];
373 
374  for (int r = 0; r < x->getSize(); r++) {
375  buf[0] = '\0';
376  //sprintf (buf, "%+.2e%+.2ei", (double) real (x->get (r)), (double) imag (x->get (r)));
377 
378  if (r == 2)
379  {
380  // print just the currents
381 // SOL (0)->get->(r)
382 // solution[0]->get(r);
383  sprintf (buf, "%f\t%18.17f\t%6.5f %6.5f %6.5f %6.5f %6.5f %6.5f %6.5f %6.5f",
384  current,
385  (double) real (x->get (r)),
386  solution[0]->get(r) ,
387  solution[1]->get(r) ,
388  solution[2]->get(r) ,
389  solution[3]->get(r) ,
390  solution[4]->get(r) ,
391  solution[5]->get(r) ,
392  solution[6]->get(r) ,
393  solution[7]->get(r) );
394 
395  messagefcn(0, buf);
396  }
397  }
398 }
399 
400 /* synchronous step solver for external ode routine
401  *
402  * This function solves the circuit for a single time delta provided
403  * by an external source. Convergence issues etc. are expected to
404  * be handled by the external solver, as it is in full control of the
405  * time stepping.
406  */
407 int e_trsolver::stepsolve_sync(nr_double_t synctime)
408 {
409 
410  int error = 0;
411  convError = 0;
412 
413  time = synctime;
414  // update the interpolation time of any externally controlled
415  // components which require it.
417 
418  // copy the externally chosen time step to delta
419  delta = time - lastsynctime;
420 
421  // get the current solution time
422  //current += delta;
423 
424  // updates the integrator coefficients, and updates the array of prev
425  // 8 deltas with the new delta for this step
427 
428  // Run predictor to get a start value for the solution vector for
429  // the successive iterative corrector process
430  error += predictor ();
431 
432  // restart Newton iteration
433  restart (); // restart non-linear devices
434 
435  // Attempt to solve the circuit with the given delta
436  try_running () // #defined as: do {
437  {
438  //error += solve_nonlinear_step ();
439  error += corrector ();
440  }
441  catch_exception () // #defined as: } while (0); if (estack.top ()) switch (estack.top()->getCode ())
442  {
444  pop_exception ();
445 
446  // Retry using damped Newton-Raphson.
448  convError = 2;
449 #if DEBUG
450  messagefcn (LOG_ERROR, "WARNING: delta rejected at t = %.3e, h = %.3e "
451  "(no convergence)\n", (double) saveCurrent, (double) delta);
452 #endif
453 
454  try_running () // #defined as: do {
455  {
456 // error += solve_nonlinear_step ();
457  error += solve_nonlinear ();
458  }
459  catch_exception () // #defined as: } while (0); if (estack.top ()) switch (estack.top()->getCode ())
460  {
462  pop_exception ();
463 
464  // Update statistics.
465  statRejected++;
466  statConvergence++;
467  rejected++;
468  converged = 0;
469  error = 0;
470 
471  break;
472  default:
473  // Otherwise return.
474  estack.print ();
475  error++;
476  break;
477  }
478 
479  // Update statistics and no more damped Newton-Raphson.
480 // statIterations += iterations;
481 // if (--convError < 0) this->convHelper = 0;
482 
483 
484  break;
485  default:
486  // Otherwise return.
487  estack.print ();
488  error++;
489  break;
490  }
491  // if there was an error other than non-convergence, return -1
492  if (error) return -1;
493 
494  // check whether Jacobian matrix is still non-singular
495  if (!A->isFinite ())
496  {
497 // messagefcn (LOG_ERROR, "ERROR: %s: Jacobian singular at t = %.3e, "
498 // "aborting %s analysis\n", getName (), (double) current,
499 // getDescription ());
500  return -1;
501  }
502 
503  return 0;
504 }
505 
506 // accept a time step into the solution history
508 {
510  if (--convError < 0) convHelper = 0;
511 
512  // Now advance in time or not...
513  if (running > 1)
514  {
516 // deltaOld = delta;
517 // stepDelta = deltaOld;
518 // nextStates ();
519 // rejected = 0;
520  adjustOrder ();
521  }
522  else
523  {
524  fillStates ();
525  nextStates ();
526  rejected = 0;
527  }
528 
530  current += delta;
531  running++;
532  converged++;
533 
534  // Tell integrators to be running.
535  setMode (MODE_NONE);
536 
537  // Initialize or update history.
538  if (running > 1)
539  {
540  // update the solution history with the new results
542  }
543  else
544  {
545  // we have just solved the first transient state
547  }
548 
549  // store the current time
551 }
552 
553 /* This function tries to adapt the current time-step according to the
554  global truncation error. */
555 void e_trsolver::adjustDelta_sync (nr_double_t t)
556 {
557  deltaOld = delta;
558 
559  // makes a new delta based on truncation error
560 // delta = checkDelta ();
561 
562  if (delta > deltaMax)
563  {
564  delta = deltaMax;
565  }
566 
567  if (delta < deltaMin)
568  {
569  delta = deltaMin;
570  }
571 
572  // delta correction in order to hit exact breakpoint
573  int good = 0;
574 // if (!relaxTSR) // relaxed step raster?
575 // {
576 // if (!statConvergence || converged > 64) /* Is this a good guess? */
577 // {
578 // // check next breakpoint
579 // if (stepDelta > 0.0)
580 // {
581 // // restore last valid delta
582 // delta = stepDelta;
583 // stepDelta = -1.0;
584 // }
585 // else
586 // {
587 // if (delta > (t - current) && t > current)
588 // {
589 // // save last valid delta and set exact step
590 // stepDelta = deltaOld;
591 // delta = t - current;
592 // good = 1;
593 // }
594 // else
595 // {
596 // stepDelta = -1.0;
597 // }
598 // }
599 // if (delta > deltaMax) delta = deltaMax;
600 // if (delta < deltaMin) delta = deltaMin;
601 // }
602 // }
603 
604  stepDelta = -1;
605  good = 1;
606 
607  // usual delta correction
608  if (delta > 0.9 * deltaOld || good) // accept current delta
609  {
610  nextStates ();
611  rejected = 0;
612 #if STEPDEBUG
614  "DEBUG: delta accepted at t = %.3e, h = %.3e\n",
615  (double) current, (double) delta);
616 #endif
617  }
618  else if (deltaOld > delta) // reject current delta
619  {
620  rejected++;
621  statRejected++;
622 #if STEPDEBUG
624  "DEBUG: delta rejected at t = %.3e, h = %.3e\n",
625  (double) current, (double) delta);
626 #endif
627  if (current > 0) current -= deltaOld;
628  }
629  else
630  {
631  nextStates ();
632  rejected = 0;
633  }
634 }
635 
636 // asynchronous step solver
637 int e_trsolver::stepsolve_async(nr_double_t steptime)
638 {
639  // Start to sweep through time.
640  int error = 0;
641  convError = 0;
642 
643  time = steptime;
644  // update the interpolation time of any externally controlled
645  // components which require it.
647  // make the stored histories for all ircuits that have
648  // requested them at least as long as the next major time
649  // step so we can reject the step later if needed and
650  // restore all the histories to their previous state
652 
653  //delta = (steptime - time) / 10;
654  //if (progress) logprogressbar (i, swp->getSize (), 40);
655 #if DEBUG && 0
656  messagefcn (LOG_STATUS, "NOTIFY: %s: solving netlist for t = %e\n",
657  getName (), (double) time);
658 #endif
659 
660  do
661  {
662 #if STEPDEBUG
663  if (delta == deltaMin)
664  {
666  "WARNING: %s: minimum delta h = %.3e at t = %.3e\n",
667  getName (), (double) delta, (double) current);
668  }
669 #endif
670  // update the integration coefficients
672 
673  // Run predictor to get a start value for the solution vector for
674  // the successive iterative corrector process
675  error += predictor ();
676 
677  // restart Newton iteration
678  if (rejected)
679  {
680  restart (); // restart non-linear devices
681  rejected = 0;
682  }
683 
684  // Run corrector process with appropriate exception handling.
685  // The corrector iterates through the solutions of the integration
686  // process until a certain error tolerance has been reached.
687  try_running () // #defined as: do {
688  {
689  error += corrector ();
690  }
691  catch_exception () // #defined as: } while (0); if (estack.top ()) switch (estack.top()->getCode ())
692  {
694  pop_exception ();
695 
696  // Reduce step-size (by half) if failed to converge.
697  if (current > 0) current -= delta;
698  delta /= 2;
699  if (delta <= deltaMin)
700  {
701  delta = deltaMin;
702  adjustOrder (1);
703  }
704  if (current > 0) current += delta;
705 
706  // Update statistics.
707  statRejected++;
708  statConvergence++;
709  rejected++;
710  converged = 0;
711  error = 0;
712 
713  // Start using damped Newton-Raphson.
715  convError = 2;
716 #if DEBUG
717  messagefcn (LOG_ERROR, "WARNING: delta rejected at t = %.3e, h = %.3e "
718  "(no convergence)\n", (double) saveCurrent, (double) delta);
719 #endif
720  break;
721  default:
722  // Otherwise return.
723  estack.print ();
724  error++;
725  break;
726  }
727  if (error) return -1;
728  if (rejected) continue;
729 
730  // check whether Jacobian matrix is still non-singular
731  if (!A->isFinite ())
732  {
733  messagefcn (LOG_ERROR, "ERROR: %s: Jacobian singular at t = %.3e, "
734  "aborting %s analysis\n", getName (), (double) current,
735  getDescription ());
736  return -1;
737  }
738 
739  // Update statistics and no more damped Newton-Raphson.
741  if (--convError < 0) convHelper = 0;
742 
743  // Now advance in time or not...
744  if (running > 1)
745  {
746  adjustDelta (time);
747  adjustOrder ();
748  }
749  else
750  {
751  fillStates ();
752  nextStates ();
753  rejected = 0;
754  }
755 
757  current += delta;
758  running++;
759  converged++;
760 
761  // Tell integrators to be running.
762  setMode (MODE_NONE);
763 
764  // Initialize or update history.
765  if (running > 1)
766  {
768  }
769  else
770  {
772  }
773  }
774  while (saveCurrent < time); // Hit a requested time point?
775 
776  return 0;
777 }
778 
779 // accept an asynchronous step into the solution history
781 {
782  // copy the solution in case we wish to step back to this
783  // point later
785 
786  // Store the time
788 
789  // Store the deltas history
791 
792  // Store the current delta
793  lastdelta = delta;
794 }
795 
796 // reject the last asynchronous step and restore the history
797 // of solutions to the last major step
799 {
800  // restore the solution (node voltages and branch currents) from
801  // the previously stored solution
803 
804  // Restore the circuit histories to their previous states
806 
807  // Restore the time deltas
809 
810  for (int i = 0; i < 8; i++)
811  {
812  deltas[i] = lastdeltas[i];
813  }
814 
815  delta = lastdelta;
816 
817  // copy the deltas to all the circuit elements
818  setDelta ();
819 
820  // reset the corrector and predictor coefficients
823 }
824 
825 /* Makes a copy of a set of solution vectors */
827 {
828  for (int i = 0; i < 8; i++)
829  {
830  // check sizes are the same
831  assert (src[i]->getSize () == dest[i]->getSize ());
832  // copy over the data values
833  for (int j = 0; j < src[i]->getSize (); j++)
834  {
835  dest[i]->set (j, src[i]->get (j));
836  }
837  }
838 }
839 
840 void e_trsolver::updateHistoryAges (nr_double_t newage)
841 {
842  int i = 0;
843  circuit * root = subnet->getRoot ();
844  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ())
845  {
846  // set the history length to retain to be at least
847  // the length of the supplied age
848  if (c->hasHistory ())
849  {
850  c->setHistoryAge (std::max (initialhistages[i], newage));
851  i++;
852  }
853  }
854 }
855 
856 //int e_trsolver::finish()
857 //{
858 // solve_post ();
859 //
860 // if (progress) logprogressclear (40);
861 //
862 // messagefcn (LOG_STATUS, "NOTIFY: %s: average time-step %g, %d rejections\n",
863 // getName (), (double) (saveCurrent / statSteps), statRejected);
864 // messagefcn (LOG_STATUS, "NOTIFY: %s: average NR-iterations %g, "
865 // "%d non-convergences\n", getName (),
866 // (double) statIterations / statSteps, statConvergence);
867 //
868 // // cleanup
869 // return 0;
870 //}
871 
872 
873 void e_trsolver::getsolution (double * lastsol)
874 {
875  int N = countNodes ();
876  int M = countVoltageSources ();
877 
878  // copy solution
879  for (int r = 0; r < N + M; r++)
880  {
881  lastsol[r] = real(x->get(r));
882  }
883 }
884 
885 /* getNodeV attempts to get the voltage of the node with a
886  given name. returns -1 if the node name was not found */
887 int e_trsolver::getNodeV (char * label, nr_double_t& nodeV)
888 {
889  int r = nlist->getNodeNr (label);
890 
891  if (r == -1)
892  {
893  return r;
894  }
895  else
896  {
897  nodeV = x->get(r);
898  return 0;
899  }
900 }
901 
902 /* Get the voltage reported by a voltage probe */
903 int e_trsolver::getVProbeV (char * probename, nr_double_t& probeV)
904 {
905  // string to hold the full name of the circuit
906  std::string fullname;
907 
908  // check for NULL name
909  if (probename)
910  {
911  circuit * root = subnet->getRoot ();
912  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ())
913  {
914  if (c->getType () == CIR_VPROBE) {
915 
916  fullname.clear ();
917 
918  // Subcircuit elements top level name is the
919  // subcircuit type (the base name of the subcircuit
920  // file)
921  if (c->getSubcircuit ())
922  {
923  fullname.append (c->getSubcircuit ());
924  fullname.append (".");
925  }
926 
927  // append the user supplied name to search for
928  fullname.append (probename);
929 
930  // Check if it is the desired voltage source
931  if (strcmp (fullname.c_str(), c->getName ()) == 0)
932  {
933  // Saves the real and imaginary voltages in the probe to the
934  // named variables Vr and Vi
935  c->saveOperatingPoints ();
936  // We are only interested in the real part for transient
937  // analysis
938  probeV = c->getOperatingPoint ("Vr");
939 
940  return 0;
941  }
942  }
943  }
944  }
945  return -1;
946 }
947 
948 /* Get the current reported by a current probe */
949 int e_trsolver::getIProbeI (char * probename, nr_double_t& probeI)
950 {
951  // string to hold the full name of the circuit
952  std::string fullname;
953 
954  // check for NULL name
955  if (probename)
956  {
957  circuit * root = subnet->getRoot ();
958  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ())
959  {
960  if (c->getType () == CIR_IPROBE) {
961 
962  fullname.clear ();
963 
964  // Subcircuit elements top level name is the
965  // subcircuit type (the base name of the subcircuit
966  // file)
967  if (c->getSubcircuit ())
968  {
969  fullname.append (c->getSubcircuit ());
970  fullname.append (".");
971  }
972 
973  // append the user supplied name to search for
974  fullname.append (probename);
975 
976  // Check if it is the desired voltage source
977  if (strcmp (fullname.c_str(), c->getName ()) == 0)
978  {
979  // Get the current reported by the probe
980  probeI = real (x->get (c->getVoltageSource () + getN ()));
981 
982  return 0;
983  }
984  }
985  }
986  }
987  return -1;
988 }
989 
990 int e_trsolver::setECVSVoltage(char * ecvsname, nr_double_t V)
991 {
992  // string to hold the full name of the circuit
993  std::string fullname;
994 
995  // check for NULL name
996  if (ecvsname)
997  {
998  circuit * root = subnet->getRoot ();
999  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ())
1000  {
1001  // examine only ECVS elements
1002  if (c->getType () == CIR_ECVS) {
1003 
1004  fullname.clear ();
1005 
1006  // Subcircuit elements top level name is the
1007  // subcircuit type (the base name of the subcircuit
1008  // file)
1009  if (c->getSubcircuit ())
1010  {
1011  fullname.append (c->getSubcircuit ());
1012  fullname.append (".");
1013  }
1014 
1015  // append the user supplied name to search for
1016  fullname.append (ecvsname);
1017 
1018  // Check if it is the desired voltage source
1019  if (strcmp (fullname.c_str(), c->getName ()) == 0)
1020  {
1021  // Set the voltage to the desired value
1022  c->setProperty("U", V);
1023  return 0;
1024  }
1025  }
1026  }
1027  }
1028  return -1;
1029 }
1030 
1032 {
1033  circuit * root = subnet->getRoot ();
1034  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ())
1035  {
1036  // examine only external elements that have interpolation,
1037  // such as ECVS elements
1038  if (c->getType () == CIR_ECVS) {
1039  // Set the voltage to the desired value
1040  c->setProperty ("Tnext", t);
1041  if (tHistory != NULL && tHistory->getSize () > 0)
1042  {
1043  c->setHistoryAge ( t - tHistory->last () + 0.1 * (t - tHistory->last ()) );
1044  }
1045  }
1046  }
1047 }
1048 
1049 /* The following function removed stored times newer than a specified time
1050  from all the circuit element histories */
1051 void e_trsolver::truncateHistory (nr_double_t t)
1052 {
1053  // truncate all the circuit element histories
1054  circuit * root = subnet->getRoot ();
1055  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ())
1056  {
1057  if (c->hasHistory ()) c->truncateHistory (t);
1058  }
1059 }
1060 
1062 {
1063  return A->getRows();
1064 }
1065 
1067 {
1068  return A->getCols();
1069 }
1070 
1071 void e_trsolver::getJacData(int r, int c, nr_double_t& data)
1072 {
1073  data = A->get(r,c);
1074 }
1075 
1076 // properties
1077 PROP_REQ [] =
1078 {
1079  PROP_NO_PROP
1080 };
1081 PROP_OPT [] =
1082 {
1083  {
1084  "IntegrationMethod", PROP_STR, { PROP_NO_VAL, "Trapezoidal" },
1085  PROP_RNG_STR4 ("Euler", "Trapezoidal", "Gear", "AdamsMoulton")
1086  },
1087  { "Order", PROP_INT, { 2, PROP_NO_STR }, PROP_RNGII (1, 6) },
1088  { "InitialStep", PROP_REAL, { 1e-9, PROP_NO_STR }, PROP_POS_RANGE },
1089  { "MinStep", PROP_REAL, { 1e-16, PROP_NO_STR }, PROP_POS_RANGE },
1090  { "MaxStep", PROP_REAL, { 0, PROP_NO_STR }, PROP_POS_RANGE },
1091  { "MaxIter", PROP_INT, { 150, PROP_NO_STR }, PROP_RNGII (2, 10000) },
1092  { "abstol", PROP_REAL, { 1e-12, PROP_NO_STR }, PROP_RNG_X01I },
1093  { "vntol", PROP_REAL, { 1e-6, PROP_NO_STR }, PROP_RNG_X01I },
1094  { "reltol", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_RNG_X01I },
1095  { "LTEabstol", PROP_REAL, { 1e-6, PROP_NO_STR }, PROP_RNG_X01I },
1096  { "LTEreltol", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_RNG_X01I },
1097  { "LTEfactor", PROP_REAL, { 1, PROP_NO_STR }, PROP_RNGII (1, 16) },
1098  { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
1099  { "Solver", PROP_STR, { PROP_NO_VAL, "CroutLU" }, PROP_RNG_SOL },
1100  { "relaxTSR", PROP_STR, { PROP_NO_VAL, "no" }, PROP_RNG_YESNO },
1101  { "initialDC", PROP_STR, { PROP_NO_VAL, "yes" }, PROP_RNG_YESNO },
1102  PROP_NO_PROP
1103 };
1104 struct define_t e_trsolver::anadef =
1106 
1107 
1108 } // namespace qucs
start
Definition: parse_zvr.y:126
int statIterations
Definition: trsolver.h:97
#define PROP_POS_RANGE
Definition: netdefs.h:129
void getsolution(double *)
Definition: e_trsolver.cpp:873
exceptionstack estack
net * subnet
Definition: analysis.h:273
The externally controlled voltage source component implementation file.
matrix real(matrix a)
Real part matrix.
Definition: matrix.cpp:568
void fillLastSolution(tvector< nr_double_t > *)
Definition: e_trsolver.cpp:285
#define PROP_RNGII(f, t)
Definition: netdefs.h:138
tvector< nr_double_t > * lastsolution[8]
Definition: e_trsolver.h:198
int setECVSVoltage(char *ecvsname, nr_double_t V)
Sets the voltage of an exterally controlled voltage source.
Definition: e_trsolver.cpp:990
#define N(n)
Definition: equation.cpp:58
nr_double_t lastsynctime
Definition: e_trsolver.h:179
int corrector(void)
Definition: trsolver.cpp:570
void set(int, nr_type_t)
Definition: tvector.cpp:108
static void calcTR(trsolver *)
Definition: trsolver.cpp:734
#define PROP_DEF
Definition: netdefs.h:189
#define MODE_NONE
Definition: integrator.h:30
int getNodeNr(char *)
Definition: nodelist.cpp:210
void updateExternalInterpTime(nr_double_t)
void fillState(int, state_type_t)
Definition: states.cpp:132
PROP_OPT[]
Definition: acsolver.cpp:232
int correctorType(char *, int &)
Definition: transient.cpp:331
void recallSolution(void)
Definition: nasolver.cpp:1282
int getN()
Returns the number of node voltages in the circuit.
Definition: nasolver.cpp:1435
nodelist * nlist
Definition: nasolver.h:134
nr_double_t getPropertyDouble(const char *)
Definition: object.cpp:176
nr_double_t delta
Definition: trsolver.h:78
void applyNodeset(bool nokeep=true)
Definition: nasolver.cpp:247
#define PROP_REAL
Definition: netdefs.h:174
void setStates(int n)
Definition: states.h:52
void storeHistoryAges(void)
Definition: e_trsolver.cpp:272
t
Definition: parse_vcd.y:290
#define PROP_NO_PROP
Definition: netdefs.h:122
void(* messagefcn)(int level, const char *format,...)
Pointer to function used to print messages during a sim.
Definition: e_trsolver.h:169
void calcCorrectorCoeff(int, int, nr_double_t *, nr_double_t *)
Definition: transient.cpp:55
void debug(void)
Definition: e_trsolver.cpp:161
void logprogressclear(int points)
Definition: logging.c:90
void updateHistoryAges(nr_double_t)
Definition: e_trsolver.cpp:840
void setDelta(void)
Definition: trsolver.cpp:615
nr_double_t last(void)
Definition: history.cpp:113
nr_double_t abstol
Definition: e_trsolver.h:175
#define K
Absolute 0 in centigrade.
Definition: constants.h:59
int getPropertyInteger(const char *)
Definition: object.cpp:198
int countNodes(void)
Definition: nasolver.cpp:912
int predMaxOrder
Definition: trsolver.h:86
#define PROP_NO_STR
Definition: netdefs.h:125
int corrMaxOrder
Definition: trsolver.h:85
void truncateHistory(nr_double_t)
#define catch_exception()
n
Definition: parse_citi.y:147
#define PROP_LINEAR
Definition: netdefs.h:120
tvector< nr_double_t > * solution[8]
Definition: trsolver.h:93
r
Definition: parse_mdl.y:515
tmatrix< nr_type_t > * A
Definition: nasolver.h:125
object * getNext(void)
Definition: object.h:59
#define PROP_INT
Definition: netdefs.h:173
int getJacCols()
Returns the number of columns in the Jacobian matrix for the circuit.
void restart(void)
Definition: trsolver.cpp:745
void initStates(void)
Definition: states.cpp:75
void setDescription(const char *n)
Definition: nasolver.h:65
int statConvergence
Definition: trsolver.h:98
#define PROP_RNG_X01I
Definition: netdefs.h:137
#define throw_exception(e)
#define PROP_ACTION
Definition: netdefs.h:115
void deinitTR(void)
Definition: trsolver.cpp:830
#define try_running()
nr_double_t lastdeltas[8]
Definition: e_trsolver.h:200
#define PROP_RNG_SOL
Definition: netdefs.h:163
i
Definition: parse_mdl.y:516
void adjustDelta_sync(nr_double_t)
Definition: e_trsolver.cpp:555
void adjustDelta(nr_double_t)
Definition: trsolver.cpp:624
void copySolution(tvector< nr_double_t > *[8], tvector< nr_double_t > *[8])
Definition: e_trsolver.cpp:826
int dcAnalysis(void)
Definition: trsolver.cpp:123
void calcPredictorCoeff(int, int, nr_double_t *, nr_double_t *)
Definition: transient.cpp:169
int getNodeV(char *label, nr_double_t &nodeV)
Obtains the voltage of a node by name.
Definition: e_trsolver.cpp:887
#define dState
Definition: e_trsolver.cpp:66
std::vector< nr_double_t > initialhistages
Definition: e_trsolver.h:197
#define pop_exception()
void initHistory(nr_double_t)
Definition: trsolver.cpp:401
nr_double_t time
Definition: e_trsolver.h:177
void fillStates(void)
Definition: trsolver.cpp:596
base class for qucs circuit elements.
Definition: circuit.h:92
void solve_pre(void)
Definition: nasolver.cpp:213
nr_double_t deltas[8]
Definition: trsolver.h:77
void fillSolution(tvector< nr_double_t > *)
Definition: trsolver.cpp:500
nr_double_t deltaOld
Definition: trsolver.h:81
nr_type_t get(int)
Definition: tvector.cpp:101
int getVProbeV(char *probename, nr_double_t &probeV)
Obtains the voltage reported by a voltage probe.
Definition: e_trsolver.cpp:903
nr_double_t lastdelta
Definition: e_trsolver.h:201
void setCalculation(calculate_func_t f)
Definition: nasolver.h:69
environment * getEnv(void)
Definition: analysis.h:180
#define V(con)
Definition: evaluate.cpp:63
void initETR(nr_double_t start, nr_double_t, int)
Definition: e_trsolver.cpp:292
void setMode(int)
Definition: trsolver.cpp:607
void adjustOrder(int reduce=0)
Definition: trsolver.cpp:694
The analysis class header file.
void nextStates(void)
Definition: trsolver.cpp:578
void updateCoefficients(nr_double_t)
Definition: trsolver.cpp:919
void print(const char *prefix=NULL)
int predictor(void)
Definition: trsolver.cpp:476
nr_double_t deltaMax
Definition: trsolver.h:79
void rejectstep_async(void)
Definition: e_trsolver.cpp:798
int stepsolve_async(nr_double_t steptime)
Definition: e_trsolver.cpp:637
#define PROP_RNG_STR4(s1, s2, s3, s4)
Definition: netdefs.h:149
int predictorType(int, int, int &)
Definition: transient.cpp:361
state_type_t getState(int, int n=0)
Definition: states.cpp:99
The circuit class header file.
int solve_nonlinear(void)
Definition: nasolver.cpp:449
int getJacRows()
Returns the number of rows in the Jacobian matrix for the circuit.
bool initialDC
Definition: trsolver.h:101
The externally controlled trsolver external class header file.
type
Definition: parse_vcd.y:164
#define PROP_MIN_VAL(k)
Definition: netdefs.h:133
int countVoltageSources(void)
Definition: nasolver.cpp:944
int stepsolve_sync(nr_double_t synctime)
Definition: e_trsolver.cpp:407
void getJacData(int r, int c, nr_double_t &data)
Obtains the data from the Jacobian matrix for the circuit.
int getIProbeI(char *probename, nr_double_t &probeI)
Obtains the current reported by a current probe.
Definition: e_trsolver.cpp:949
External interface class for transient simulation.
nr_double_t saveCurrent
Definition: e_trsolver.h:178
int getSize(void)
Definition: history.cpp:230
void saveState(int, state_type_t *)
Definition: states.cpp:146
nr_double_t corrCoeff[8]
Definition: trsolver.h:76
nr_double_t deltaMin
Definition: trsolver.h:80
#define PROP_STR
Definition: netdefs.h:175
const char * getDescription(void)
Definition: nasolver.h:66
object * getPrev(void)
Definition: object.h:61
nr_double_t current
Definition: trsolver.h:94
void initCircuitTR(circuit *)
Definition: trsolver.cpp:847
The environment class definition.
void inputState(int, state_type_t *)
Definition: states.cpp:159
void setText(const char *,...)
Definition: exception.cpp:67
#define LOG_ERROR
Definition: logging.h:28
char * getName(void)
Definition: object.cpp:84
nr_double_t stepDelta
Definition: trsolver.h:82
nr_double_t lastasynctime
Definition: e_trsolver.h:199
nr_double_t reltol
Definition: e_trsolver.h:174
#define PROP_NO_VAL
Definition: netdefs.h:124
void solve_post(void)
Definition: nasolver.cpp:205
#define LOG_STATUS
Definition: logging.h:29
int init(nr_double_t, nr_double_t, int)
Definition: e_trsolver.cpp:180
PROP_REQ[]
Definition: acsolver.cpp:229
#define sState
Definition: e_trsolver.cpp:70
#define CONV_SteepestDescent
Definition: nasolver.h:39
#define PROP_RNG_YESNO
Definition: netdefs.h:158
char * getPropertyString(const char *)
Definition: object.cpp:159
void setState(int, state_type_t, int n=0)
Definition: states.cpp:109
sweep * swp
Definition: trsolver.h:74
#define M(con)
Definition: evaluate.cpp:64
void logprint(int level, const char *format,...)
Definition: logging.c:37
tvector< nr_type_t > * x
Definition: nasolver.h:122
void acceptstep_async(void)
Definition: e_trsolver.cpp:780
int statRejected
Definition: trsolver.h:96
void(* calculate_func_t)(nasolver< nr_type_t > *)
Definition: nasolver.h:68
void printx(void)
Definition: e_trsolver.cpp:370
int getSize(void)
Definition: tvector.h:82
nr_double_t vntol
Definition: e_trsolver.h:176
nr_double_t predCoeff[8]
Definition: trsolver.h:75
history * tHistory
Definition: trsolver.h:99
#define MODE_INIT
Definition: integrator.h:31
void updateHistory(nr_double_t)
Definition: trsolver.cpp:428
data
Definition: parse_citi.y:117
void acceptstep_sync(void)
Definition: e_trsolver.cpp:507