LCOV - code coverage report
Current view: top level - src - dcsolver.cpp (source / functions) Hit Total Coverage
Test: qucs-core-0.0.19 Code Coverage Lines: 55 93 59.1 %
Date: 2015-01-05 16:01:02 Functions: 7 14 50.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 38 98 38.8 %

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

Generated by: LCOV version 1.11