Branch data Line data Source code
1 : : /*
2 : : * qucs_interface.cpp - m-code interface implementation
3 : : *
4 : : * Copyright (C) 2013 Richard Crozier <richard.crozier@yahoo.co.uk>
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 <stdlib.h>
31 : : #include <assert.h>
32 : : #include <string.h>
33 : : #include <time.h>
34 : :
35 : : #include "logging.h"
36 : : #include "precision.h"
37 : : #include "component.h"
38 : : #include "components.h"
39 : : #include "net.h"
40 : : #include "input.h"
41 : : #include "dataset.h"
42 : : #include "equation.h"
43 : : #include "environment.h"
44 : : #include "exceptionstack.h"
45 : : #include "check_netlist.h"
46 : : #include "module.h"
47 : : #include "qucs_interface.h"
48 : : #include "analysis.h"
49 : : #include "e_trsolver.h"
50 : :
51 : : #if HAVE_UNISTD_H
52 : : #include <unistd.h>
53 : : #endif
54 : :
55 : : #include <string>
56 : :
57 : : using namespace qucs;
58 : :
59 : : // constructor
60 : 0 : qucsint::qucsint ()
61 : : {
62 : :
63 : : //int listing = 0;
64 : 0 : ret = 0;
65 : 0 : err = 0;
66 : :
67 : 0 : loginit ();
68 : 0 : ::srand (::time (NULL));
69 : :
70 : 0 : }
71 : :
72 : 0 : qucsint::qucsint (char* infile)
73 : : {
74 : : //int listing = 0;
75 : 0 : ret = 0;
76 : 0 : err = 0;
77 : :
78 : 0 : loginit ();
79 : 0 : ::srand (::time (NULL));
80 : :
81 : 0 : prepare_netlist (infile);
82 : 0 : }
83 : :
84 : : // destructor
85 : 0 : qucsint::~qucsint ()
86 : : {
87 [ # # ][ # # ]: 0 : delete subnet;
88 [ # # ][ # # ]: 0 : delete in;
89 : : // delete out;
90 [ # # ][ # # ]: 0 : delete root;
91 : :
92 : : // delete modules
93 : 0 : module::unregisterModules ();
94 : :
95 : 0 : netlist_destroy_env ();
96 : 0 : }
97 : :
98 : : /*!\ todo: replace "root" by / as environement root */
99 : 0 : int qucsint::prepare_netlist (char * infile)
100 : : {
101 : :
102 : : // create static modules
103 : 0 : module::registerModules ();
104 : :
105 : : // create root environment
106 [ # # ][ # # ]: 0 : root = new qucs::environment (std::string("root"));
[ # # ]
107 : :
108 : : // create netlist object and input
109 [ # # ]: 0 : subnet = new net ("subnet");
110 : :
111 : : // test if the file actually exists
112 : : FILE * pFile;
113 : 0 : pFile = fopen (infile,"r");
114 [ # # ]: 0 : if (pFile!=NULL)
115 : : {
116 : : // close the file again
117 : 0 : fclose (pFile);
118 : : }
119 : : else
120 : : {
121 : 0 : return NETLIST_FILE_NOT_FOUND;
122 : : }
123 : :
124 [ # # ][ # # ]: 0 : in = infile ? new input (infile) : new input ();
[ # # ]
125 : :
126 : : // pass root environment to netlist object and input
127 : 0 : subnet->setEnv (root);
128 : 0 : in->setEnv (root);
129 : :
130 : : // get input netlist
131 [ # # ]: 0 : if (in->netlist (subnet) != 0)
132 : : {
133 [ # # ]: 0 : if (netlist_check)
134 : : {
135 : : // replace with mex error message
136 : 0 : logprint (LOG_STATUS, "checker notice, netlist check FAILED\n");
137 : : }
138 : 0 : return NETLIST_FAILED_CHECK;
139 : : }
140 : :
141 : : // attach a ground to the netlist
142 [ # # ]: 0 : gnd = new ground ();
143 : 0 : gnd->setNode (0, "gnd");
144 : 0 : gnd->setName ("GND");
145 : 0 : subnet->insertCircuit (gnd);
146 : :
147 : : // apply some data to all analyses
148 : 0 : subnet->setActionNetAll(subnet);
149 : :
150 : 0 : return NETLIST_OK;
151 : : }
152 : :
153 : 0 : int qucsint::evaluate ()
154 : : {
155 : : // analyse the netlist
156 : 0 : err = 0;
157 : 0 : ret = 0;
158 : 0 : out = subnet->runAnalysis (err);
159 : 0 : ret |= err;
160 : :
161 : 0 : return ret;
162 : : }
163 : :
164 : 0 : int qucsint::output (char * outfile)
165 : : {
166 : : // evaluate output dataset
167 : 0 : ret |= root->equationSolver (out);
168 : :
169 [ # # ]: 0 : if (outfile != NULL)
170 : : {
171 : 0 : out->setFile (outfile);
172 : 0 : out->print ();
173 : : }
174 : :
175 : 0 : return ret;
176 : : }
177 : :
178 : : /*/////////////////////////////////////////////////////////////////////////////
179 : :
180 : : trsolver_interface
181 : :
182 : : /////////////////////////////////////////////////////////////////////////////*/
183 : :
184 : 0 : trsolver_interface::trsolver_interface ()
185 : 0 : : qucsint ()
186 : : {
187 : 0 : etr = 0;
188 : 0 : isInitialised = false;
189 : 0 : }
190 : :
191 : 0 : trsolver_interface::trsolver_interface (char * infile)
192 : 0 : : qucsint (infile)
193 : : {
194 : 0 : isInitialised = false;
195 : :
196 [ # # # # ]: 0 : int result = prepare_netlist (infile);
197 : :
198 [ # # ][ # # ]: 0 : if (result == NETLIST_OK)
199 : : {
200 [ # # ][ # # ]: 0 : getETR ();
201 : : }
202 : 0 : }
203 : :
204 : : //trsolver_interface::~trsolver_interface ()
205 : : //{
206 : : //
207 : : //}
208 : :
209 : 0 : int trsolver_interface::getN (void)
210 : : {
211 [ # # ]: 0 : if (etr) return etr->getN ();
212 : 0 : else return -2;
213 : : }
214 : :
215 : 0 : int trsolver_interface::getM (void)
216 : : {
217 [ # # ]: 0 : if (etr) return etr->getM ();
218 : 0 : else return -2;
219 : : }
220 : :
221 : : // gets a pointer to the trsolver_interface if it is present
222 : 0 : void trsolver_interface::getETR()
223 : : {
224 : : // get a pointer to the external transient solver interface
225 : : // the pointer will be to the supclass of e_trsolver, analysis
226 : : // so we must perform a dynamic cast to convert it to an e_trsolver
227 [ # # ]: 0 : etr = dynamic_cast<e_trsolver *>(subnet->findAnalysis (ANALYSIS_E_TRANSIENT));
228 : :
229 [ # # ]: 0 : if (etr)
230 : : {
231 : 0 : isInitialised = true;
232 : : }
233 : : else
234 : : {
235 : 0 : isInitialised = false;
236 : : }
237 : 0 : }
238 : :
239 : 0 : int trsolver_interface::init (double start, double firstdelta, int mode)
240 : : {
241 [ # # ]: 0 : if (etr) return etr->init ((nr_double_t)start, (nr_double_t)firstdelta, mode);
242 : 0 : else return -2;
243 : : }
244 : :
245 : :
246 : 0 : int trsolver_interface::stepsolve_sync (double synctime)
247 : : {
248 [ # # ]: 0 : if (etr) return etr->stepsolve_sync ((nr_double_t)synctime);
249 : 0 : else return -2;
250 : : }
251 : :
252 : 0 : void trsolver_interface::acceptstep_sync (void)
253 : : {
254 [ # # ]: 0 : if (etr) etr->acceptstep_sync ();
255 : 0 : }
256 : :
257 : 0 : int trsolver_interface::stepsolve_async (double steptime)
258 : : {
259 [ # # ]: 0 : if (etr) return etr->stepsolve_async ((nr_double_t)steptime);
260 : 0 : else return -2;
261 : : }
262 : :
263 : 0 : void trsolver_interface::acceptstep_async (void)
264 : : {
265 [ # # ]: 0 : if (etr) etr->acceptstep_async ();
266 : 0 : }
267 : :
268 : 0 : void trsolver_interface::rejectstep_async (void)
269 : : {
270 [ # # ]: 0 : if (etr) etr->rejectstep_async ();
271 : 0 : }
272 : :
273 : 0 : void trsolver_interface::getsolution (double * sol)
274 : : {
275 [ # # ]: 0 : if (etr) etr->getsolution (sol);
276 : 0 : }
277 : :
278 : 0 : int trsolver_interface::setECVSVoltage(char * ecvsname, double V)
279 : : {
280 [ # # ]: 0 : if (etr) return etr->setECVSVoltage (ecvsname, (nr_double_t)V);
281 : 0 : else return -2;
282 : : }
283 : :
284 : 0 : int trsolver_interface::getJacRows ()
285 : : {
286 [ # # ]: 0 : if (etr) return etr->getJacRows ();
287 : 0 : else return -2;
288 : : }
289 : :
290 : 0 : int trsolver_interface::getJacCols ()
291 : : {
292 [ # # ]: 0 : if (etr) return etr->getJacCols ();
293 : 0 : else return -2;
294 : : }
295 : :
296 : 0 : int trsolver_interface::getJacData (int r, int c, double& data)
297 : : {
298 [ # # ]: 0 : if (etr)
299 : : {
300 : 0 : nr_double_t tempdata = (nr_double_t)data;
301 [ # # ]: 0 : etr->getJacData (r, c, tempdata);
302 : 0 : data = (double)tempdata;
303 : 0 : return 0;
304 : : }
305 : : else
306 : : {
307 : 0 : return -2;
308 : : }
309 : : }
310 : :
311 : 0 : int trsolver_interface::getNodeV (char * label, double& nodeV)
312 : : {
313 [ # # ]: 0 : if (etr)
314 : : {
315 : 0 : nr_double_t tempnodeV = (nr_double_t)nodeV;
316 [ # # ]: 0 : int flag = etr->getNodeV (label, tempnodeV);
317 : 0 : nodeV = (double)tempnodeV;
318 : 0 : return flag;
319 : : }
320 : : else
321 : : {
322 : 0 : return -2;
323 : : }
324 : : }
325 : :
326 : 0 : int trsolver_interface::getVProbeV (char * probename, double& probeV)
327 : : {
328 [ # # ]: 0 : if (etr)
329 : : {
330 : 0 : nr_double_t tempprobeV = (nr_double_t)probeV;
331 [ # # ]: 0 : int flag = etr->getVProbeV (probename, tempprobeV);
332 : 0 : probeV = (double)tempprobeV;
333 : 0 : return flag;
334 : : }
335 : : else
336 : : {
337 : 0 : return -2;
338 : : }
339 : : }
340 : :
341 : :
342 : 0 : int trsolver_interface::getIProbeI (char * probename, double& probeI)
343 : : {
344 [ # # ]: 0 : if (etr)
345 : : {
346 : 0 : nr_double_t tempprobeI = (nr_double_t)probeI;
347 [ # # ]: 0 : int flag = etr->getIProbeI (probename, tempprobeI);
348 : 0 : probeI = (double)tempprobeI;
349 : 0 : return flag;
350 : : }
351 : : else
352 : : {
353 : 0 : return -2;
354 : : }
355 : : }
356 : :
357 : : //void trsolver_interface::debug (void)
358 : : //{
359 : : // if (etr) etr->debug ();
360 : : //}
361 : : //
362 : :
363 : 0 : void trsolver_interface::printSolution (void)
364 : : {
365 [ # # ]: 0 : if (etr) etr->printx ();
366 : 0 : }
367 : :
368 : 0 : void trsolver_interface::setMessageFcn(void (*newmessagefcn)(int level, const char * format, ...))
369 : : {
370 : 0 : etr->messagefcn = newmessagefcn;
371 : 0 : }
|