Qucs-core
0.0.19
|
00001 /* 00002 * parasweep.cpp - parameter sweep class implementation 00003 * 00004 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Stefan Jahn <stefan@lkcc.org> 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 <string.h> 00032 00033 #include "logging.h" 00034 #include "complex.h" 00035 #include "object.h" 00036 #include "vector.h" 00037 #include "dataset.h" 00038 #include "net.h" 00039 #include "netdefs.h" 00040 #include "ptrlist.h" 00041 #include "analysis.h" 00042 #include "variable.h" 00043 #include "environment.h" 00044 #include "sweep.h" 00045 #include "parasweep.h" 00046 00047 using namespace qucs::eqn; 00048 00049 namespace qucs { 00050 00051 // Constructor creates an unnamed instance of the parasweep class. 00052 parasweep::parasweep () : analysis () { 00053 var = NULL; 00054 swp = NULL; 00055 eqn = NULL; 00056 type = ANALYSIS_SWEEP; 00057 } 00058 00059 // Constructor creates a named instance of the parasweep class. 00060 parasweep::parasweep (char * n) : analysis (n) { 00061 var = NULL; 00062 swp = NULL; 00063 eqn = NULL; 00064 type = ANALYSIS_SWEEP; 00065 } 00066 00067 // Destructor deletes the parasweep class object. 00068 parasweep::~parasweep () { 00069 delete swp; 00070 } 00071 00072 /* The copy constructor creates a new instance of the parasweep class 00073 based on the given parasweep object. */ 00074 parasweep::parasweep (parasweep & p) : analysis (p) { 00075 var = new variable (*p.var); 00076 if (p.swp) swp = new sweep (*p.swp); 00077 } 00078 00079 // Short macro in order to obtain the correct constant value. 00080 #define D(con) ((constant *) (con))->d 00081 #define E(equ) ((eqn::node *) (equ)) 00082 00083 /* Initializes the parameter sweep. */ 00084 int parasweep::initialize (void) { 00085 constant * val; 00086 00087 // get fixed simulation properties 00088 const char * const n = getPropertyString ("Param"); 00089 00090 // create sweep if necessary 00091 if (swp == NULL) { 00092 swp = createSweep (n); 00093 } 00094 00095 // get parameter name and the appropriate variable from the current 00096 // environment, possibly add the variable to the environment if it 00097 // does not exist yet (which is somehow useless at all) 00098 if ((var = env->getVariable (n)) == NULL) { 00099 var = new variable (n); 00100 val = new constant (TAG_DOUBLE); 00101 var->setConstant (val); 00102 env->addVariable (var); 00103 } 00104 else val = var->getConstant (); 00105 00106 // put variable also into equation checker if necessary 00107 if (!env->getChecker()->containsVariable (n)) { 00108 eqn = env->getChecker()->addDouble ("#sweep", n, 0); 00109 } 00110 00111 // initialize first sweep value in environment and equation checker 00112 nr_double_t v = swp->get (0); 00113 env->setDoubleConstant (n, v); 00114 env->setDouble (n, v); 00115 00116 // also run initialize functionality for all children 00117 if (actions != nullptr) { 00118 for (auto *a : *actions) { 00119 a->initialize (); 00120 a->setProgress (false); 00121 } 00122 } 00123 return 0; 00124 } 00125 00126 /* Cleans the parameter sweep up. */ 00127 int parasweep::cleanup (void) { 00128 00129 // remove additional equation from equation checker 00130 if (eqn) { 00131 env->getChecker()->dropEquation (E (eqn)); 00132 delete E (eqn); 00133 eqn = NULL; 00134 } 00135 00136 // also run cleanup functionality for all children 00137 if( actions != nullptr) 00138 for (auto *a : *actions) 00139 a->cleanup (); 00140 00141 return 0; 00142 } 00143 00144 /* This is the parameter sweep solver. */ 00145 int parasweep::solve (void) { 00146 int err = 0; 00147 runs++; 00148 00149 // get fixed simulation properties 00150 const char * const n = getPropertyString ("Param"); 00151 00152 // run the parameter sweep 00153 swp->reset (); 00154 for (int i = 0; i < swp->getSize (); i++) { 00155 // obtain next sweep point 00156 nr_double_t v = swp->next (); 00157 // display progress bar if requested 00158 if (progress) logprogressbar (i, swp->getSize (), 40); 00159 // update environment and equation checker, then run solver 00160 env->setDoubleConstant (n, v); 00161 env->setDouble (n, v); 00162 env->runSolver (); 00163 // save results (swept parameter values) 00164 if (runs == 1) saveResults (); 00165 #if DEBUG 00166 logprint (LOG_STATUS, "NOTIFY: %s: running netlist for %s = %g\n", 00167 getName (), n, v); 00168 #endif 00169 for (auto *a : *actions) { 00170 err |= a->solve (); 00171 // assign variable dataset dependencies to last order analyses 00172 ptrlist<analysis> * lastorder = subnet->findLastOrderChildren (this); 00173 for (auto *dep : *lastorder) 00174 data->assignDependency (dep->getName (), var->getName ()); 00175 } 00176 } 00177 // clear progress bar 00178 if (progress) logprogressclear (40); 00179 return err; 00180 } 00181 00182 /* This function saves the results of a single solve() functionality 00183 into the output dataset. */ 00184 void parasweep::saveResults (void) { 00185 qucs::vector * v; 00186 00187 // add current frequency to the dependencies of the output dataset 00188 if ((v = data->findDependency (var->getName ())) == NULL) { 00189 v = new qucs::vector (var->getName ()); 00190 v->setOrigin (getName ()); 00191 data->addDependency (v); 00192 } 00193 v->add (D (var->getConstant ())); 00194 } 00195 00196 // properties 00197 PROP_REQ [] = { 00198 { "Type", PROP_STR, { PROP_NO_VAL, "lin" }, PROP_RNG_TYP }, 00199 { "Param", PROP_STR, { PROP_NO_VAL, "R1" }, PROP_NO_RANGE }, 00200 { "Sim", PROP_STR, { PROP_NO_VAL, "DC1" }, PROP_NO_RANGE }, 00201 PROP_NO_PROP }; 00202 PROP_OPT [] = { 00203 { "Points", PROP_INT, { 5, PROP_NO_STR }, PROP_MIN_VAL (2) }, 00204 { "Stop", PROP_REAL, { 50, PROP_NO_STR }, PROP_NO_RANGE }, 00205 { "Start", PROP_REAL, { 5, PROP_NO_STR }, PROP_NO_RANGE }, 00206 { "Values", PROP_LIST, { 5, PROP_NO_STR }, PROP_NO_RANGE }, 00207 PROP_NO_PROP }; 00208 struct define_t parasweep::anadef = 00209 { "SW", 0, PROP_ACTION, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF }; 00210 00211 } // namespace qucs