Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
acsolver.cpp
Go to the documentation of this file.
1 /*
2  * acsolver.cpp - AC solver class implementation
3  *
4  * Copyright (C) 2004, 2005, 2007, 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 #include <cmath>
31 
32 #include "object.h"
33 #include "complex.h"
34 #include "circuit.h"
35 #include "sweep.h"
36 #include "net.h"
37 #include "netdefs.h"
38 #include "analysis.h"
39 #include "nasolver.h"
40 #include "acsolver.h"
41 
42 namespace qucs {
43 
44 // Constructor creates an unnamed instance of the acsolver class.
45 acsolver::acsolver () : nasolver<nr_complex_t> () {
46  swp = NULL;
47  type = ANALYSIS_AC;
48  setDescription ("AC");
49  xn = NULL;
50  noise = 0;
51 }
52 
53 // Constructor creates a named instance of the acsolver class.
54 acsolver::acsolver (char * n) : nasolver<nr_complex_t> (n) {
55  swp = NULL;
56  type = ANALYSIS_AC;
57  setDescription ("AC");
58  xn = NULL;
59  noise = 0;
60 }
61 
62 // Destructor deletes the acsolver class object.
64  if (swp) delete swp;
65  if (xn) delete xn;
66 }
67 
68 /* The copy constructor creates a new instance of the acsolver class
69  based on the given acsolver object. */
70 acsolver::acsolver (acsolver & o) : nasolver<nr_complex_t> (o) {
71  swp = o.swp ? new sweep (*(o.swp)) : NULL;
72  xn = o.xn ? new tvector<nr_double_t> (*(o.xn)) : NULL;
73  noise = o.noise;
74 }
75 
76 /* This is the AC netlist solver. It prepares the circuit list for
77  each requested frequency and solves it then. */
78 int acsolver::solve (void) {
79  runs++;
80 
81  // run additional noise analysis ?
82  noise = !strcmp (getPropertyString ("Noise"), "yes") ? 1 : 0;
83 
84  // create frequency sweep if necessary
85  if (swp == NULL) {
86  swp = createSweep ("acfrequency");
87  }
88 
89  // initialize node voltages, first guess for non-linear circuits and
90  // generate extra circuits if necessary
91  init ();
93  solve_pre ();
94 
95  swp->reset ();
96  for (int i = 0; i < swp->getSize (); i++) {
97  freq = swp->next ();
98  if (progress) logprogressbar (i, swp->getSize (), 40);
99 
100 #if DEBUG && 0
101  logprint (LOG_STATUS, "NOTIFY: %s: solving netlist for f = %e\n",
102  getName (), (double) freq);
103 #endif
104 
105  // start the linear solver
107  solve_linear ();
108 
109  // compute noise if requested
110  if (noise) solve_noise ();
111 
112  // save results
113  saveAllResults (freq);
114  }
115  solve_post ();
116  if (progress) logprogressclear (40);
117  return 0;
118 }
119 
120 /* Goes through the list of circuit objects and runs its calcAC()
121  function. */
122 void acsolver::calc (acsolver * self) {
123  circuit * root = self->getNet()->getRoot ();
124  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ()) {
125  c->calcAC (self->freq);
126  if (self->noise) c->calcNoiseAC (self->freq);
127  }
128 }
129 
130 /* Goes through the list of circuit objects and runs its initAC()
131  function. */
132 void acsolver::init (void) {
133  circuit * root = subnet->getRoot ();
134  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ()) {
135  if (c->isNonLinear ()) c->calcOperatingPoints ();
136  c->initAC ();
137  if (noise) c->initNoiseAC ();
138  }
139 }
140 
141 /* This function saves the results of a single solve() functionality
142  (for the given frequency) into the output dataset. */
143 void acsolver::saveAllResults (nr_double_t freq) {
144  qucs::vector * f;
145  // add current frequency to the dependency of the output dataset
146  if ((f = data->findDependency ("acfrequency")) == NULL) {
147  f = new qucs::vector ("acfrequency");
148  data->addDependency (f);
149  }
150  if (runs == 1) f->add (freq);
151  saveResults ("v", "i", 0, f);
152 
153  // additionally save noise results if requested
154  if (noise) {
155  saveNoiseResults (f);
156  }
157 }
158 
159 /* The function computes the final noise results and puts them into
160  the output dataset. */
162  int N = countNodes ();
163  int M = countVoltageSources ();
164  for (int r = 0; r < N + M; r++) {
165  // renormalise the results
166  x->set (r, fabs (xn->get (r) * sqrt (kB * T0)));
167  }
168 
169  // apply probe data
170  circuit * root = subnet->getRoot ();
171  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ()) {
172  if (!c->isProbe ()) continue;
173  int np, nn;
174  nr_double_t vp, vn;
175  np = getNodeNr (c->getNode (NODE_1)->getName ());
176  vp = np > 0 ? xn->get (np - 1) : 0.0;
177  nn = getNodeNr (c->getNode (NODE_2)->getName ());
178  vn = nn > 0 ? xn->get (nn - 1) : 0.0;
179  c->setOperatingPoint ("Vr", fabs ((vp - vn) * sqrt (kB * T0)));
180  c->setOperatingPoint ("Vi", 0.0);
181  }
182 
183  saveResults ("vn", "in", 0, f);
184 }
185 
186 /* This function runs the AC noise analysis. It saves its results in
187  the 'xn' vector. */
189  int N = countNodes ();
190  int M = countVoltageSources ();
191 
192  // save usual AC results
193  tvector<nr_complex_t> xsave = *x;
194 
195  // create the Cy matrix
197  // create noise result vector if necessary
198  if (xn == NULL) xn = new tvector<nr_double_t> (N + M);
199 
200  // temporary result vector for transimpedances
201  tvector<nr_complex_t> zn = tvector<nr_complex_t> (N + M);
202 
203  // create the MNA matrix once again and LU decompose the adjoint matrix
204  createMatrix ();
205  A->transpose ();
207  runMNA ();
208 
209  // ensure skipping LU decomposition
210  updateMatrix = 0;
213 
214  // compute noise voltage for each node (and voltage source)
215  for (int i = 0; i < N + M; i++) {
216  z->set (0); z->set (i, -1); // modify right hand side appropriately
217  runMNA (); // solve
218  zn = *x; // save transimpedance vector
219 
220  // compute actual noise voltage
221  xn->set (i, sqrt (real (scalar (zn * (*C), conj (zn)))));
222  }
223 
224  // restore usual AC results
225  *x = xsave;
226 }
227 
228 // properties
229 PROP_REQ [] = {
230  { "Type", PROP_STR, { PROP_NO_VAL, "lin" }, PROP_RNG_TYP },
231  PROP_NO_PROP };
232 PROP_OPT [] = {
233  { "Noise", PROP_STR, { PROP_NO_VAL, "no" }, PROP_RNG_YESNO },
234  { "Start", PROP_REAL, { 1e9, PROP_NO_STR }, PROP_POS_RANGE },
235  { "Stop", PROP_REAL, { 10e9, PROP_NO_STR }, PROP_POS_RANGE },
236  { "Points", PROP_INT, { 10, PROP_NO_STR }, PROP_MIN_VAL (2) },
237  { "Values", PROP_LIST, { 10, PROP_NO_STR }, PROP_POS_RANGE },
238  PROP_NO_PROP };
239 struct define_t acsolver::anadef =
241 
242 } // namespace qucs
static void calc(acsolver *)
Definition: acsolver.cpp:122
int solve(void)
placehoder for solution function
Definition: acsolver.cpp:78
tvector< nr_double_t > * xn
Definition: acsolver.h:53
std::complex< nr_double_t > nr_complex_t
Definition: complex.h:31
#define PROP_POS_RANGE
Definition: netdefs.h:129
void solve_noise(void)
Definition: acsolver.cpp:188
net * subnet
Definition: analysis.h:273
#define NODE_2
Definition: circuit.h:35
matrix real(matrix a)
Real part matrix.
Definition: matrix.cpp:568
#define T0
standard temperature
Definition: constants.h:61
#define N(n)
Definition: equation.cpp:58
void set(int, nr_type_t)
Definition: tvector.cpp:108
nr_type_t scalar(tvector< nr_type_t > a, tvector< nr_type_t > b)
Definition: tvector.cpp:283
#define PROP_DEF
Definition: netdefs.h:189
void createMatrix(void)
Definition: nasolver.cpp:536
int updateMatrix
Definition: nasolver.h:131
PROP_OPT[]
Definition: acsolver.cpp:232
#define PROP_REAL
Definition: netdefs.h:174
#define PROP_RNG_TYP
Definition: netdefs.h:162
#define PROP_NO_PROP
Definition: netdefs.h:122
void logprogressclear(int points)
Definition: logging.c:90
void runMNA(void)
Definition: nasolver.cpp:987
int countNodes(void)
Definition: nasolver.cpp:912
#define PROP_NO_STR
Definition: netdefs.h:125
void init(void)
Definition: acsolver.cpp:132
n
Definition: parse_citi.y:147
#define PROP_LINEAR
Definition: netdefs.h:120
r
Definition: parse_mdl.y:515
tmatrix< nr_type_t > * A
Definition: nasolver.h:125
#define PROP_INT
Definition: netdefs.h:173
void saveNoiseResults(qucs::vector *)
Definition: acsolver.cpp:161
tmatrix< nr_type_t > * C
Definition: nasolver.h:126
void setDescription(const char *n)
Definition: nasolver.h:65
#define PROP_ACTION
Definition: netdefs.h:115
i
Definition: parse_mdl.y:516
nr_complex_t sqrt(const nr_complex_t z)
Compute principal value of square root.
Definition: complex.cpp:271
void solve_pre(void)
Definition: nasolver.cpp:213
void saveResults(const char *, const char *, int, qucs::vector *f=NULL)
Definition: nasolver.cpp:1308
nr_type_t get(int)
Definition: tvector.cpp:101
void add(nr_complex_t)
Definition: vector.cpp:151
void setCalculation(calculate_func_t f)
Definition: nasolver.h:69
tvector< nr_type_t > * z
Definition: nasolver.h:121
#define kB
Boltzmann constant ( )
Definition: constants.h:64
void saveAllResults(nr_double_t)
Definition: acsolver.cpp:143
The analysis class header file.
nr_double_t freq
Definition: acsolver.h:51
dataset * data
Definition: analysis.h:274
int solve_linear(void)
Definition: nasolver.cpp:525
The circuit 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
sweep * swp
Definition: acsolver.h:50
void logprogressbar(nr_double_t current, nr_double_t final, int points)
Definition: logging.c:63
acsolver(char *)
Definition: acsolver.cpp:54
#define PROP_STR
Definition: netdefs.h:175
sweep * createSweep(const char *)
create a named sweep object
Definition: analysis.cpp:107
#define NODE_1
Definition: circuit.h:34
void createNoiseMatrix(void)
Definition: nasolver.cpp:741
char * getName(void)
Definition: object.cpp:84
matrix conj(matrix a)
Conjugate complex matrix.
Definition: matrix.cpp:505
#define PROP_NO_VAL
Definition: netdefs.h:124
void solve_post(void)
Definition: nasolver.cpp:205
#define LOG_STATUS
Definition: logging.h:29
#define PROP_LIST
Definition: netdefs.h:176
#define CONV_None
Definition: nasolver.h:36
PROP_REQ[]
Definition: acsolver.cpp:229
#define PROP_RNG_YESNO
Definition: netdefs.h:158
char * getPropertyString(const char *)
Definition: object.cpp:159
#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
int getNodeNr(char *)
Definition: nasolver.cpp:919
void(* calculate_func_t)(nasolver< nr_type_t > *)
Definition: nasolver.h:68