My Project
0.0.16
QUCS Mapping
Main Page
Related Pages
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Pages
DownLoad
QUCS-src
qucs-0.0.16
qucs-core
src
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: dcsolver.cpp 1825 2011-03-11 20:42:14Z ela $
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
// Constructor creates an unnamed instance of the dcsolver class.
41
dcsolver::dcsolver
() :
nasolver
<nr_double_t> () {
42
saveOPs = 0;
43
type =
ANALYSIS_DC
;
44
setDescription (
"DC"
);
45
}
46
47
// Constructor creates a named instance of the dcsolver class.
48
dcsolver::dcsolver
(
char
*
n
) :
nasolver
<nr_double_t> (n) {
49
saveOPs = 0;
50
type
=
ANALYSIS_DC
;
51
setDescription
(
"DC"
);
52
}
53
54
// Destructor deletes the dcsolver class object.
55
dcsolver::~dcsolver
() {
56
}
57
58
/* The copy constructor creates a new instance of the dcsolver class
59
based on the given dcsolver object. */
60
dcsolver::dcsolver
(
dcsolver
& o) :
nasolver
<nr_double_t> (o) {
61
saveOPs = o.saveOPs;
62
}
63
64
/* This is the DC netlist solver. It prepares the circuit list and
65
solves it then. */
66
int
dcsolver::solve
(
void
) {
67
// fetch simulation properties
68
saveOPs |= !strcmp (
getPropertyString
(
"saveOPs"
),
"yes"
) ?
SAVE_OPS
: 0;
69
saveOPs |= !strcmp (
getPropertyString
(
"saveAll"
),
"yes"
) ?
SAVE_ALL
: 0;
70
char
* solver =
getPropertyString
(
"Solver"
);
71
72
// initialize node voltages, first guess for non-linear circuits and
73
// generate extra circuits if necessary
74
init
();
75
setCalculation
((
calculate_func_t
) &
calc
);
76
77
// start the iterative solver
78
solve_pre
();
79
80
// choose a solver
81
if
(!strcmp (solver,
"CroutLU"
))
82
eqnAlgo
=
ALGO_LU_DECOMPOSITION_CROUT
;
83
else
if
(!strcmp (solver,
"DoolittleLU"
))
84
eqnAlgo
=
ALGO_LU_DECOMPOSITION_DOOLITTLE
;
85
else
if
(!strcmp (solver,
"HouseholderQR"
))
86
eqnAlgo
=
ALGO_QR_DECOMPOSITION
;
87
else
if
(!strcmp (solver,
"HouseholderLQ"
))
88
eqnAlgo
=
ALGO_QR_DECOMPOSITION_LS
;
89
else
if
(!strcmp (solver,
"GolubSVD"
))
90
eqnAlgo
=
ALGO_SV_DECOMPOSITION
;
91
92
// local variables for the fallback thingies
93
int
retry = -1,
error
, fallback = 0, preferred;
94
int
helpers[] = {
95
CONV_SourceStepping
,
96
CONV_GMinStepping
,
97
CONV_SteepestDescent
,
98
CONV_LineSearch
,
99
CONV_Attenuation
,
100
-1 };
101
102
// is a certain convergence helper requested?
103
char
* helper =
getPropertyString
(
"convHelper"
);
104
convHelper
=
CONV_None
;
105
if
(!strcmp (helper,
"LineSearch"
)) {
106
convHelper
=
CONV_LineSearch
;
107
}
else
if
(!strcmp (helper,
"SteepestDescent"
)) {
108
convHelper
=
CONV_SteepestDescent
;
109
}
else
if
(!strcmp (helper,
"Attenuation"
)) {
110
convHelper
=
CONV_Attenuation
;
111
}
else
if
(!strcmp (helper,
"gMinStepping"
)) {
112
convHelper
=
CONV_GMinStepping
;
113
}
else
if
(!strcmp (helper,
"SourceStepping"
)) {
114
convHelper
=
CONV_SourceStepping
;
115
}
116
preferred =
convHelper
;
117
118
if
(!
subnet
->
isNonLinear
()) {
119
// Start the linear solver.
120
convHelper
=
CONV_None
;
121
error
=
solve_linear
();
122
}
123
else
do
{
124
// Run the DC solver once.
125
try_running
() {
126
applyNodeset
();
127
error
=
solve_nonlinear
();
128
#if DEBUG
129
if
(!
error
) {
130
logprint
(
LOG_STATUS
,
131
"NOTIFY: %s: convergence reached after %d iterations\n"
,
132
getName
(),
iterations
);
133
}
134
#endif
/* DEBUG */
135
if
(!
error
) retry = -1;
136
}
137
// Appropriate exception handling.
138
catch_exception
() {
139
case
EXCEPTION_NO_CONVERGENCE
:
140
pop_exception
();
141
if
(preferred == helpers[fallback] && preferred) fallback++;
142
convHelper
= helpers[fallback++];
143
if
(
convHelper
!= -1) {
144
logprint
(
LOG_ERROR
,
"WARNING: %s: %s analysis failed, using fallback "
145
"#%d (%s)\n"
,
getName
(),
getDescription
(), fallback,
146
getHelperDescription
());
147
retry++;
148
restart
();
149
}
150
else
{
151
retry = -1;
152
}
153
break
;
154
default
:
155
// Otherwise return.
156
estack
.
print
();
157
error
++;
158
break
;
159
}
160
}
while
(retry != -1);
161
162
// save results and cleanup the solver
163
saveOperatingPoints
();
164
saveResults
(
"V"
,
"I"
, saveOPs);
165
166
solve_post
();
167
return
0;
168
}
169
170
/* Goes through the list of circuit objects and runs its calcDC()
171
function. */
172
void
dcsolver::calc
(
dcsolver
*
self
) {
173
circuit
* root =
self
->
getNet
()->
getRoot
();
174
for
(
circuit
*
c
= root;
c
!= NULL;
c
= (
circuit
*)
c
->getNext ()) {
175
c
->calcDC ();
176
}
177
}
178
179
/* Goes through the list of circuit objects and runs its initDC()
180
function. */
181
void
dcsolver::init
(
void
) {
182
circuit
* root =
subnet
->
getRoot
();
183
for
(
circuit
*
c
= root;
c
!= NULL;
c
= (
circuit
*)
c
->getNext ()) {
184
c
->initDC ();
185
}
186
}
187
188
/* Goes through the list of non-linear circuit objects and runs its
189
restartDC() function. */
190
void
dcsolver::restart
(
void
) {
191
circuit
* root =
subnet
->
getRoot
();
192
for
(
circuit
*
c
= root;
c
!= NULL;
c
= (
circuit
*)
c
->getNext ()) {
193
if
(
c
->isNonLinear ())
c
->restartDC ();
194
}
195
}
196
197
/* Goes through the list of non-linear circuit objects and runs its
198
saveOperatingPoints() function. */
199
void
dcsolver::saveOperatingPoints
(
void
) {
200
circuit
* root =
subnet
->
getRoot
();
201
for
(
circuit
*
c
= root;
c
!= NULL;
c
= (
circuit
*)
c
->getNext ()) {
202
if
(
c
->isNonLinear ())
c
->saveOperatingPoints ();
203
}
204
}
205
206
// properties
207
PROP_REQ
[] = {
208
PROP_NO_PROP
};
209
PROP_OPT
[] = {
210
{
"MaxIter"
,
PROP_INT
, { 150,
PROP_NO_STR
},
PROP_RNGII
(2, 10000) },
211
{
"abstol"
,
PROP_REAL
, { 1
e
-12,
PROP_NO_STR
},
PROP_RNG_X01I
},
212
{
"vntol"
,
PROP_REAL
, { 1
e
-6,
PROP_NO_STR
},
PROP_RNG_X01I
},
213
{
"reltol"
,
PROP_REAL
, { 1
e
-3,
PROP_NO_STR
},
PROP_RNG_X01I
},
214
{
"saveOPs"
,
PROP_STR
, {
PROP_NO_VAL
,
"no"
},
PROP_RNG_YESNO
},
215
{
"Temp"
,
PROP_REAL
, { 26.85,
PROP_NO_STR
},
PROP_MIN_VAL
(
K
) },
216
{
"saveAll"
,
PROP_STR
, {
PROP_NO_VAL
,
"no"
},
PROP_RNG_YESNO
},
217
{
"convHelper"
,
PROP_STR
, {
PROP_NO_VAL
,
"none"
},
218
PROP_RNG_STR6
(
"none"
,
"SourceStepping"
,
"gMinStepping"
,
219
"LineSearch"
,
"Attenuation"
,
"SteepestDescent"
) },
220
{
"Solver"
,
PROP_STR
, {
PROP_NO_VAL
,
"CroutLU"
},
PROP_RNG_SOL
},
221
PROP_NO_PROP
};
222
struct
define_t
dcsolver
::anadef =
223
{
"DC"
, 0,
PROP_ACTION
,
PROP_NO_SUBSTRATE
,
PROP_LINEAR
,
PROP_DEF
};
Generated on Tue Dec 25 2012 14:30:33 for My Project by
1.8.2