Qucs-core
0.0.19
|
00001 /* 00002 * qucs_interface.cpp - m-code interface implementation 00003 * 00004 * Copyright (C) 2013 Richard Crozier <richard.crozier@yahoo.co.uk> 00005 * 00006 * This is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2, or (at your option) 00009 * any later version. 00010 * 00011 * This software is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this package; see the file COPYING. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 * 00021 * $Id$ 00022 * 00023 */ 00024 00025 #if HAVE_CONFIG_H 00026 # include <config.h> 00027 #endif 00028 00029 #include <stdio.h> 00030 #include <stdlib.h> 00031 #include <assert.h> 00032 #include <string.h> 00033 #include <time.h> 00034 00035 #include "logging.h" 00036 #include "precision.h" 00037 #include "component.h" 00038 #include "components.h" 00039 #include "net.h" 00040 #include "input.h" 00041 #include "dataset.h" 00042 #include "equation.h" 00043 #include "environment.h" 00044 #include "exceptionstack.h" 00045 #include "check_netlist.h" 00046 #include "module.h" 00047 #include "qucs_interface.h" 00048 #include "analysis.h" 00049 #include "e_trsolver.h" 00050 00051 #if HAVE_UNISTD_H 00052 #include <unistd.h> 00053 #endif 00054 00055 #include <string> 00056 00057 using namespace qucs; 00058 00059 // constructor 00060 qucsint::qucsint () 00061 { 00062 00063 //int listing = 0; 00064 ret = 0; 00065 err = 0; 00066 00067 loginit (); 00068 ::srand (::time (NULL)); 00069 00070 } 00071 00072 qucsint::qucsint (char* infile) 00073 { 00074 //int listing = 0; 00075 ret = 0; 00076 err = 0; 00077 00078 loginit (); 00079 ::srand (::time (NULL)); 00080 00081 prepare_netlist (infile); 00082 } 00083 00084 // destructor 00085 qucsint::~qucsint () 00086 { 00087 delete subnet; 00088 delete in; 00089 // delete out; 00090 delete root; 00091 00092 // delete modules 00093 module::unregisterModules (); 00094 00095 netlist_destroy_env (); 00096 } 00097 00099 int qucsint::prepare_netlist (char * infile) 00100 { 00101 00102 // create static modules 00103 module::registerModules (); 00104 00105 // create root environment 00106 root = new qucs::environment (std::string("root")); 00107 00108 // create netlist object and input 00109 subnet = new net ("subnet"); 00110 00111 // test if the file actually exists 00112 FILE * pFile; 00113 pFile = fopen (infile,"r"); 00114 if (pFile!=NULL) 00115 { 00116 // close the file again 00117 fclose (pFile); 00118 } 00119 else 00120 { 00121 return NETLIST_FILE_NOT_FOUND; 00122 } 00123 00124 in = infile ? new input (infile) : new input (); 00125 00126 // pass root environment to netlist object and input 00127 subnet->setEnv (root); 00128 in->setEnv (root); 00129 00130 // get input netlist 00131 if (in->netlist (subnet) != 0) 00132 { 00133 if (netlist_check) 00134 { 00135 // replace with mex error message 00136 logprint (LOG_STATUS, "checker notice, netlist check FAILED\n"); 00137 } 00138 return NETLIST_FAILED_CHECK; 00139 } 00140 00141 // attach a ground to the netlist 00142 gnd = new ground (); 00143 gnd->setNode (0, "gnd"); 00144 gnd->setName ("GND"); 00145 subnet->insertCircuit (gnd); 00146 00147 // apply some data to all analyses 00148 subnet->setActionNetAll(subnet); 00149 00150 return NETLIST_OK; 00151 } 00152 00153 int qucsint::evaluate () 00154 { 00155 // analyse the netlist 00156 err = 0; 00157 ret = 0; 00158 out = subnet->runAnalysis (err); 00159 ret |= err; 00160 00161 return ret; 00162 } 00163 00164 int qucsint::output (char * outfile) 00165 { 00166 // evaluate output dataset 00167 ret |= root->equationSolver (out); 00168 00169 if (outfile != NULL) 00170 { 00171 out->setFile (outfile); 00172 out->print (); 00173 } 00174 00175 return ret; 00176 } 00177 00178 /*///////////////////////////////////////////////////////////////////////////// 00179 00180 trsolver_interface 00181 00183 00184 trsolver_interface::trsolver_interface () 00185 : qucsint () 00186 { 00187 etr = 0; 00188 isInitialised = false; 00189 } 00190 00191 trsolver_interface::trsolver_interface (char * infile) 00192 : qucsint (infile) 00193 { 00194 isInitialised = false; 00195 00196 int result = prepare_netlist (infile); 00197 00198 if (result == NETLIST_OK) 00199 { 00200 getETR (); 00201 } 00202 } 00203 00204 //trsolver_interface::~trsolver_interface () 00205 //{ 00206 // 00207 //} 00208 00209 int trsolver_interface::getN (void) 00210 { 00211 if (etr) return etr->getN (); 00212 else return -2; 00213 } 00214 00215 int trsolver_interface::getM (void) 00216 { 00217 if (etr) return etr->getM (); 00218 else return -2; 00219 } 00220 00221 // gets a pointer to the trsolver_interface if it is present 00222 void trsolver_interface::getETR() 00223 { 00224 // get a pointer to the external transient solver interface 00225 // the pointer will be to the supclass of e_trsolver, analysis 00226 // so we must perform a dynamic cast to convert it to an e_trsolver 00227 etr = dynamic_cast<e_trsolver *>(subnet->findAnalysis (ANALYSIS_E_TRANSIENT)); 00228 00229 if (etr) 00230 { 00231 isInitialised = true; 00232 } 00233 else 00234 { 00235 isInitialised = false; 00236 } 00237 } 00238 00239 int trsolver_interface::init (double start, double firstdelta, int mode) 00240 { 00241 if (etr) return etr->init ((nr_double_t)start, (nr_double_t)firstdelta, mode); 00242 else return -2; 00243 } 00244 00245 00246 int trsolver_interface::stepsolve_sync (double synctime) 00247 { 00248 if (etr) return etr->stepsolve_sync ((nr_double_t)synctime); 00249 else return -2; 00250 } 00251 00252 void trsolver_interface::acceptstep_sync (void) 00253 { 00254 if (etr) etr->acceptstep_sync (); 00255 } 00256 00257 int trsolver_interface::stepsolve_async (double steptime) 00258 { 00259 if (etr) return etr->stepsolve_async ((nr_double_t)steptime); 00260 else return -2; 00261 } 00262 00263 void trsolver_interface::acceptstep_async (void) 00264 { 00265 if (etr) etr->acceptstep_async (); 00266 } 00267 00268 void trsolver_interface::rejectstep_async (void) 00269 { 00270 if (etr) etr->rejectstep_async (); 00271 } 00272 00273 void trsolver_interface::getsolution (double * sol) 00274 { 00275 if (etr) etr->getsolution (sol); 00276 } 00277 00278 int trsolver_interface::setECVSVoltage(char * ecvsname, double V) 00279 { 00280 if (etr) return etr->setECVSVoltage (ecvsname, (nr_double_t)V); 00281 else return -2; 00282 } 00283 00284 int trsolver_interface::getJacRows () 00285 { 00286 if (etr) return etr->getJacRows (); 00287 else return -2; 00288 } 00289 00290 int trsolver_interface::getJacCols () 00291 { 00292 if (etr) return etr->getJacCols (); 00293 else return -2; 00294 } 00295 00296 int trsolver_interface::getJacData (int r, int c, double& data) 00297 { 00298 if (etr) 00299 { 00300 nr_double_t tempdata = (nr_double_t)data; 00301 etr->getJacData (r, c, tempdata); 00302 data = (double)tempdata; 00303 return 0; 00304 } 00305 else 00306 { 00307 return -2; 00308 } 00309 } 00310 00311 int trsolver_interface::getNodeV (char * label, double& nodeV) 00312 { 00313 if (etr) 00314 { 00315 nr_double_t tempnodeV = (nr_double_t)nodeV; 00316 int flag = etr->getNodeV (label, tempnodeV); 00317 nodeV = (double)tempnodeV; 00318 return flag; 00319 } 00320 else 00321 { 00322 return -2; 00323 } 00324 } 00325 00326 int trsolver_interface::getVProbeV (char * probename, double& probeV) 00327 { 00328 if (etr) 00329 { 00330 nr_double_t tempprobeV = (nr_double_t)probeV; 00331 int flag = etr->getVProbeV (probename, tempprobeV); 00332 probeV = (double)tempprobeV; 00333 return flag; 00334 } 00335 else 00336 { 00337 return -2; 00338 } 00339 } 00340 00341 00342 int trsolver_interface::getIProbeI (char * probename, double& probeI) 00343 { 00344 if (etr) 00345 { 00346 nr_double_t tempprobeI = (nr_double_t)probeI; 00347 int flag = etr->getIProbeI (probename, tempprobeI); 00348 probeI = (double)tempprobeI; 00349 return flag; 00350 } 00351 else 00352 { 00353 return -2; 00354 } 00355 } 00356 00357 //void trsolver_interface::debug (void) 00358 //{ 00359 // if (etr) etr->debug (); 00360 //} 00361 // 00362 00363 void trsolver_interface::printSolution (void) 00364 { 00365 if (etr) etr->printx (); 00366 } 00367 00368 void trsolver_interface::setMessageFcn(void (*newmessagefcn)(int level, const char * format, ...)) 00369 { 00370 etr->messagefcn = newmessagefcn; 00371 }