Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dcsolver.cpp
Go to the documentation of this file.
1 /*
2  * dcsolver.cpp - DC solver class implementation
3  *
4  * Copyright (C) 2003-2008 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 
25 #if HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #include <stdio.h>
30 
31 #include "object.h"
32 #include "complex.h"
33 #include "circuit.h"
34 #include "net.h"
35 #include "netdefs.h"
36 #include "analysis.h"
37 #include "nasolver.h"
38 #include "dcsolver.h"
39 
40 namespace qucs {
41 
42 // Constructor creates an unnamed instance of the dcsolver class.
43 dcsolver::dcsolver () : nasolver<nr_double_t> () {
44  saveOPs = 0;
45  type = ANALYSIS_DC;
46  setDescription ("DC");
47 }
48 
49 // Constructor creates a named instance of the dcsolver class.
50 dcsolver::dcsolver (char * n) : nasolver<nr_double_t> (n) {
51  saveOPs = 0;
52  type = ANALYSIS_DC;
53  setDescription ("DC");
54 }
55 
56 // Destructor deletes the dcsolver class object.
58 }
59 
60 /* The copy constructor creates a new instance of the dcsolver class
61  based on the given dcsolver object. */
62 dcsolver::dcsolver (dcsolver & o) : nasolver<nr_double_t> (o) {
63  saveOPs = o.saveOPs;
64 }
65 
66 /* This is the DC netlist solver. It prepares the circuit list and
67  solves it then. */
68 int dcsolver::solve (void) {
69  // fetch simulation properties
70  saveOPs |= !strcmp (getPropertyString ("saveOPs"), "yes") ? SAVE_OPS : 0;
71  saveOPs |= !strcmp (getPropertyString ("saveAll"), "yes") ? SAVE_ALL : 0;
72  char * solver = getPropertyString ("Solver");
73 
74  // initialize node voltages, first guess for non-linear circuits and
75  // generate extra circuits if necessary
76  init ();
78 
79  // start the iterative solver
80  solve_pre ();
81 
82  // choose a solver
83  if (!strcmp (solver, "CroutLU"))
85  else if (!strcmp (solver, "DoolittleLU"))
87  else if (!strcmp (solver, "HouseholderQR"))
89  else if (!strcmp (solver, "HouseholderLQ"))
91  else if (!strcmp (solver, "GolubSVD"))
93 
94  // local variables for the fallback thingies
95  int retry = -1, error, fallback = 0, preferred;
96  int helpers[] = {
102  -1 };
103 
104  // is a certain convergence helper requested?
105  char * helper = getPropertyString ("convHelper");
107  if (!strcmp (helper, "LineSearch")) {
109  } else if (!strcmp (helper, "SteepestDescent")) {
111  } else if (!strcmp (helper, "Attenuation")) {
113  } else if (!strcmp (helper, "gMinStepping")) {
115  } else if (!strcmp (helper, "SourceStepping")) {
117  }
118  preferred = convHelper;
119 
120  if (!subnet->isNonLinear ()) {
121  // Start the linear solver.
123  error = solve_linear ();
124  }
125  else do {
126  // Run the DC solver once.
127  try_running () {
128  applyNodeset ();
129  error = solve_nonlinear ();
130 #if DEBUG
131  if (!error) {
133  "NOTIFY: %s: convergence reached after %d iterations\n",
134  getName (), iterations);
135  }
136 #endif /* DEBUG */
137  if (!error) retry = -1;
138  }
139  // Appropriate exception handling.
140  catch_exception () {
142  pop_exception ();
143  if (preferred == helpers[fallback] && preferred) fallback++;
144  convHelper = helpers[fallback++];
145  if (convHelper != -1) {
146  logprint (LOG_ERROR, "WARNING: %s: %s analysis failed, using fallback "
147  "#%d (%s)\n", getName (), getDescription (), fallback,
149  retry++;
150  restart ();
151  }
152  else {
153  retry = -1;
154  }
155  break;
156  default:
157  // Otherwise return.
158  estack.print ();
159  error++;
160  break;
161  }
162  } while (retry != -1);
163 
164  // save results and cleanup the solver
166  saveResults ("V", "I", saveOPs);
167 
168  solve_post ();
169  return 0;
170 }
171 
172 /* Goes through the list of circuit objects and runs its calcDC()
173  function. */
174 void dcsolver::calc (dcsolver * self) {
175  circuit * root = self->getNet()->getRoot ();
176  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ()) {
177  c->calcDC ();
178  }
179 }
180 
181 /* Goes through the list of circuit objects and runs its initDC()
182  function. */
183 void dcsolver::init (void) {
184  circuit * root = subnet->getRoot ();
185  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ()) {
186  c->initDC ();
187  }
188 }
189 
190 /* Goes through the list of non-linear circuit objects and runs its
191  restartDC() function. */
192 void dcsolver::restart (void) {
193  circuit * root = subnet->getRoot ();
194  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ()) {
195  if (c->isNonLinear ()) c->restartDC ();
196  }
197 }
198 
199 /* Goes through the list of non-linear circuit objects and runs its
200  saveOperatingPoints() function. */
202  circuit * root = subnet->getRoot ();
203  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ()) {
204  if (c->isNonLinear ()) c->saveOperatingPoints ();
205  }
206 }
207 
208 // properties
209 PROP_REQ [] = {
210  PROP_NO_PROP };
211 PROP_OPT [] = {
212  { "MaxIter", PROP_INT, { 150, PROP_NO_STR }, PROP_RNGII (2, 10000) },
213  { "abstol", PROP_REAL, { 1e-12, PROP_NO_STR }, PROP_RNG_X01I },
214  { "vntol", PROP_REAL, { 1e-6, PROP_NO_STR }, PROP_RNG_X01I },
215  { "reltol", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_RNG_X01I },
216  { "saveOPs", PROP_STR, { PROP_NO_VAL, "no" }, PROP_RNG_YESNO },
217  { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
218  { "saveAll", PROP_STR, { PROP_NO_VAL, "no" }, PROP_RNG_YESNO },
219  { "convHelper", PROP_STR, { PROP_NO_VAL, "none" },
220  PROP_RNG_STR6 ("none", "SourceStepping", "gMinStepping",
221  "LineSearch", "Attenuation", "SteepestDescent") },
222  { "Solver", PROP_STR, { PROP_NO_VAL, "CroutLU" }, PROP_RNG_SOL },
223  PROP_NO_PROP };
224 struct define_t dcsolver::anadef =
226 
227 } // namespace qucs
exceptionstack estack
circuit * getRoot(void)
Definition: net.h:46
net * subnet
Definition: analysis.h:273
#define PROP_RNGII(f, t)
Definition: netdefs.h:138
#define PROP_DEF
Definition: netdefs.h:189
PROP_OPT[]
Definition: acsolver.cpp:232
int solve(void)
placehoder for solution function
Definition: dcsolver.cpp:68
void applyNodeset(bool nokeep=true)
Definition: nasolver.cpp:247
#define PROP_REAL
Definition: netdefs.h:174
#define CONV_GMinStepping
Definition: nasolver.h:40
#define PROP_NO_PROP
Definition: netdefs.h:122
#define K
Absolute 0 in centigrade.
Definition: constants.h:59
#define PROP_NO_STR
Definition: netdefs.h:125
#define PROP_RNG_STR6(s1, s2, s3, s4, s5, s6)
Definition: netdefs.h:153
#define catch_exception()
n
Definition: parse_citi.y:147
#define PROP_LINEAR
Definition: netdefs.h:120
#define PROP_INT
Definition: netdefs.h:173
void setDescription(const char *n)
Definition: nasolver.h:65
#define PROP_RNG_X01I
Definition: netdefs.h:137
#define PROP_ACTION
Definition: netdefs.h:115
#define try_running()
#define PROP_RNG_SOL
Definition: netdefs.h:163
#define CONV_Attenuation
Definition: nasolver.h:37
#define pop_exception()
base class for qucs circuit elements.
Definition: circuit.h:92
void solve_pre(void)
Definition: nasolver.cpp:213
void saveResults(const char *, const char *, int, qucs::vector *f=NULL)
Definition: nasolver.cpp:1308
dcsolver(char *)
Definition: dcsolver.cpp:50
net * getNet(void)
Definition: circuit.h:173
void setCalculation(calculate_func_t f)
Definition: nasolver.h:69
static void calc(dcsolver *)
Definition: dcsolver.cpp:174
The analysis class header file.
void init(void)
Definition: dcsolver.cpp:183
void print(const char *prefix=NULL)
int solve_linear(void)
Definition: nasolver.cpp:525
The circuit class header file.
int solve_nonlinear(void)
Definition: nasolver.cpp:449
#define CONV_SourceStepping
Definition: nasolver.h:41
void saveOperatingPoints(void)
Definition: dcsolver.cpp:201
#define PROP_MIN_VAL(k)
Definition: netdefs.h:133
#define SAVE_OPS
Definition: analysis.h:36
const char * getHelperDescription(void)
Definition: nasolver.cpp:422
void restart(void)
Definition: dcsolver.cpp:192
#define CONV_LineSearch
Definition: nasolver.h:38
#define PROP_STR
Definition: netdefs.h:175
const char * getDescription(void)
Definition: nasolver.h:66
#define LOG_ERROR
Definition: logging.h:28
char * getName(void)
Definition: object.cpp:84
#define PROP_NO_VAL
Definition: netdefs.h:124
void solve_post(void)
Definition: nasolver.cpp:205
#define LOG_STATUS
Definition: logging.h:29
#define CONV_None
Definition: nasolver.h:36
PROP_REQ[]
Definition: acsolver.cpp:229
#define CONV_SteepestDescent
Definition: nasolver.h:39
#define PROP_RNG_YESNO
Definition: netdefs.h:158
char * getPropertyString(const char *)
Definition: object.cpp:159
void logprint(int level, const char *format,...)
Definition: logging.c:37
#define SAVE_ALL
Definition: analysis.h:37
void(* calculate_func_t)(nasolver< nr_type_t > *)
Definition: nasolver.h:68