Example #1
0
void nasolver<nr_type_t>::createCMatrix (void)
{
    int N = countNodes ();
    int M = countVoltageSources ();
    circuit * vs;
    struct nodelist_t * n;
    nr_type_t val;

    // go through each voltage sources (second dimension)
    for (int r = 0; r < M; r++)
    {
        vs = findVoltageSource (r);
        // go through each node (first dimension)
        for (int c = 0; c < N; c++)
        {
            val = 0.0;
            n = nlist->getNode (c);
            for (auto &current: *n)
            {
                // is voltage source connected to node ?
	      if (current->getCircuit () == vs)
                {
		  val += MatVal (vs->getC (r, current->getPort ()));
                }
            }
            // put value into C matrix
            A->set (r + N, c, val);
        }
    }
}
Example #2
0
void nasolver<nr_type_t>::solve_pre (void)
{
    // create node list, enumerate nodes and voltage sources
#if DEBUG
    logprint (LOG_STATUS, "NOTIFY: %s: creating node list for %s analysis\n",
              getName (), desc.c_str());
#endif
    nlist = new nodelist (subnet);
    nlist->assignNodes ();
    assignVoltageSources ();
#if DEBUG && 0
    nlist->print ();
#endif

    // create matrix, solution vector and right hand side vector
    int M = countVoltageSources ();
    int N = countNodes ();
    if (A != NULL) delete A;
    A = new tmatrix<nr_type_t> (M + N);
    if (z != NULL) delete z;
    z = new tvector<nr_type_t> (N + M);
    if (x != NULL) delete x;
    x = new tvector<nr_type_t> (N + M);

#if DEBUG
    logprint (LOG_STATUS, "NOTIFY: %s: solving %s netlist\n", getName (), desc.c_str());
#endif
}
Example #3
0
void nasolver<nr_type_t>::storeSolution (void)
{
    // cleanup solution previously
    solution.clear ();
    int r;
    int N = countNodes ();
    int M = countVoltageSources ();
    // store all nodes except reference node
    for (r = 0; r < N; r++)
    {
        struct nodelist_t * n = nlist->getNode (r);
	nr_type_t gr = x->get (r);
	qucs::naentry<nr_type_t> entry(gr, 0);
        solution.insert({{n->name, entry }});
    }
    // store all branch currents of voltage sources
    for (r = 0; r < M; r++)
    {
        circuit * vs = findVoltageSource (r);
        int vn = r - vs->getVoltageSource () + 1;
	nr_type_t xg = x->get (r + N);
	qucs::naentry<nr_type_t> entry(xg, vn);
        solution.insert({{vs->getName (), entry}});
    }
}
Example #4
0
void nasolver<nr_type_t>::recallSolution (void)
{
    int r;
    int N = countNodes ();
    int M = countVoltageSources ();
    // store all nodes except reference node
    for (r = 0; r < N; r++)
    {
        struct nodelist_t * n = nlist->getNode (r);
	auto na = solution.find(n->name);
	if (na != solution.end())
	  if ((*na).second.current == 0)
            x->set (r, (*na).second.value);
    }
    // store all branch currents of voltage sources
    for (r = 0; r < M; r++)
    {
        circuit * vs = findVoltageSource (r);
        int vn = r - vs->getVoltageSource () + 1;
	auto na = solution.find(vs->getName ());
	if (na != solution.end())
	  if ((*na).second.current == vn)
            x->set (r + N, (*na).second.value);
    }
}
Example #5
0
void e_trsolver::getsolution (double * lastsol)
{
    int N = countNodes ();
    int M = countVoltageSources ();

    // copy solution
    for (int r = 0; r < N + M; r++)
    {
        lastsol[r]  = real(x->get(r));
    }
}
Example #6
0
void nasolver<nr_type_t>::saveBranchCurrents (void)
{
    int N = countNodes ();
    int M = countVoltageSources ();
    circuit * vs;
    // save all branch currents of voltage sources
    for (int r = 0; r < M; r++)
    {
        vs = findVoltageSource (r);
        vs->setJ (r, x->get (r + N));
    }
}
Example #7
0
void nasolver<nr_type_t>::createEVector (void)
{
    int N = countNodes ();
    int M = countVoltageSources ();
    nr_type_t val;
    circuit * vs;

    // go through each voltage source
    for (int r = 0; r < M; r++)
    {
        vs = findVoltageSource (r);
        val = MatVal (vs->getE (r));
        // put value into e vector
        z->set (r + N, val);
    }
}
Example #8
0
void nasolver<nr_type_t>::createDMatrix (void)
{
    int M = countVoltageSources ();
    int N = countNodes ();
    circuit * vsr, * vsc;
    nr_type_t val;
    for (int r = 0; r < M; r++)
    {
        vsr = findVoltageSource (r);
        for (int c = 0; c < M; c++)
        {
            vsc = findVoltageSource (c);
            val = 0.0;
            if (vsr == vsc)
            {
                val = MatVal (vsr->getD (r, c));
            }
            A->set (r + N, c + N, val);
        }
    }
}
/* This function runs the AC noise analysis.  It saves its results in
   the 'xn' vector. */
void acsolver::solve_noise (void) {
  int N = countNodes ();
  int M = countVoltageSources ();

  // save usual AC results
  tvector<nr_complex_t> xsave = *x;

  // create the Cy matrix
  createNoiseMatrix ();
  // create noise result vector if necessary
  if (xn == NULL) xn = new tvector<nr_double_t> (N + M);

  // temporary result vector for transimpedances
  tvector<nr_complex_t> zn = tvector<nr_complex_t> (N + M);

  // create the MNA matrix once again and LU decompose the adjoint matrix
  createMatrix ();
  A->transpose ();
  eqnAlgo = ALGO_LU_FACTORIZATION_CROUT;
  runMNA ();

  // ensure skipping LU decomposition
  updateMatrix = 0;
  convHelper = CONV_None;
  eqnAlgo = ALGO_LU_SUBSTITUTION_CROUT;

  // compute noise voltage for each node (and voltage source)
  for (int i = 0; i < N + M; i++) {
    z->set (0); z->set (i, -1); // modify right hand side appropriately
    runMNA ();                  // solve
    zn = *x;                    // save transimpedance vector

    // compute actual noise voltage
    xn->set (i, sqrt (real (scalar (zn * (*C), conj (zn)))));
  }

  // restore usual AC results
  *x = xsave;
}
Example #10
0
int nasolver<nr_type_t>::checkConvergence (void)
{

    int N = countNodes ();
    int M = countVoltageSources ();
    nr_double_t v_abs, v_rel, i_abs, i_rel;
    int r;

    // check the nodal voltage changes against the allowed absolute
    // and relative tolerance values
    for (r = 0; r < N; r++)
    {
        v_abs = abs (x->get (r) - xprev->get (r));
        v_rel = abs (x->get (r));
        if (v_abs >= vntol + reltol * v_rel) return 0;
        if (!convHelper)
        {
            i_abs = abs (z->get (r) - zprev->get (r));
            i_rel = abs (z->get (r));
            if (i_abs >= abstol + reltol * i_rel) return 0;
        }
    }

    for (r = 0; r < M; r++)
    {
        i_abs = abs (x->get (r + N) - xprev->get (r + N));
        i_rel = abs (x->get (r + N));
        if (i_abs >= abstol + reltol * i_rel) return 0;
        if (!convHelper)
        {
            v_abs = abs (z->get (r + N) - zprev->get (r + N));
            v_rel = abs (z->get (r + N));
            if (v_abs >= vntol + reltol * v_rel) return 0;
        }
    }
    return 1;
}
Example #11
0
void nasolver<nr_type_t>::createMatrix (void)
{

    /* Generate the A matrix.  The A matrix consists of four (4) minor
       matrices in the form     +-   -+
                            A = | G B |
                                | C D |
    		      +-   -+.
       Each of these minor matrices is going to be generated here. */
    if (updateMatrix)
    {
        createGMatrix ();
        createBMatrix ();
        createCMatrix ();
        createDMatrix ();
    }

    /* Adjust G matrix if requested. */
    if (convHelper == CONV_GMinStepping)
    {
        int N = countNodes ();
        int M = countVoltageSources ();
        for (int n = 0; n < N + M; n++)
        {
            A->set (n, n, A->get (n, n) + gMin);
        }
    }

    /* Generate the z Matrix.  The z Matrix consists of two (2) minor
       matrices in the form     +- -+
                            z = | i |
                                | e |
    		      +- -+.
       Each of these minor matrices is going to be generated here. */
    createZVector ();
}
/* The function computes the final noise results and puts them into
   the output dataset. */
void acsolver::saveNoiseResults (vector * f) {
  int N = countNodes ();
  int M = countVoltageSources ();
  for (int r = 0; r < N + M; r++) {
    // renormalise the results
    x->set (r, fabs (xn->get (r) * sqrt (kB * T0)));
  }

  // apply probe data
  circuit * root = subnet->getRoot ();
  for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ()) {
    if (!c->isProbe ()) continue;
    int np, nn;
    nr_double_t vp, vn;
    np = getNodeNr (c->getNode (NODE_1)->getName ());
    vp = np > 0 ? xn->get (np - 1) : 0.0;
    nn = getNodeNr (c->getNode (NODE_2)->getName ());
    vn = nn > 0 ? xn->get (nn - 1) : 0.0;
    c->setOperatingPoint ("Vr", fabs ((vp - vn) * sqrt (kB * T0)));
    c->setOperatingPoint ("Vi", 0.0);
  }

  saveResults ("vn", "in", 0, f);
}
Example #13
0
void nasolver<nr_type_t>::createNoiseMatrix (void)
{
    int pr, pc, N = countNodes ();
    int M = countVoltageSources ();
    struct nodelist_t * n;
    nr_type_t val;
    int r, c, ri, ci;
    struct nodelist_t * nr, * nc;
    circuit * ct;

    // create new Cy matrix if necessary
    if (C != NULL) delete C;
    C = new tmatrix<nr_type_t> (N + M);

    // go through each column of the Cy matrix
    for (c = 0; c < N; c++)
    {
        nc = nlist->getNode (c);
        // go through each row of the Cy matrix
        for (r = 0; r < N; r++)
        {
            nr = nlist->getNode (r);
            val = 0.0;
            // sum up the noise-correlation of each connected circuit
            for (auto & currentnc: *nc)
		/* a = 0; a < nc->size(); a++ */
	      for (auto &currentnr : *nr)
		/* b = 0; b < nr->size(); b++) */
                    if (currentnc->getCircuit () == currentnr->getCircuit ())
                    {
                        ct = currentnc->getCircuit ();
                        pc = currentnc->getPort ();
                        pr = currentnr->getPort ();
                        val += MatVal (ct->getN (pr, pc));
                    }
            // put value into Cy matrix
            C->set (r, c, val);
        }
    }

    // go through each additional voltage source and put coefficients into
    // the noise current correlation matrix
    circuit * vsr, * vsc;
    for (r = 0; r < M; r++)
    {
        vsr = findVoltageSource (r);
        for (c = 0; c < M; c++)
        {
            vsc = findVoltageSource (c);
            val = 0.0;
            if (vsr == vsc)
            {
                ri = vsr->getSize () + r - vsr->getVoltageSource ();
                ci = vsc->getSize () + c - vsc->getVoltageSource ();
                val = MatVal (vsr->getN (ri, ci));
            }
            C->set (r + N, c + N, val);
        }
    }

    // go through each additional voltage source
    for (r = 0; r < M; r++)
    {
        vsr = findVoltageSource (r);
        // go through each node
        for (c = 0; c < N; c++)
        {
            val = 0.0;
            n = nlist->getNode (c);
            for (auto &currentn: *n)
	      /*i = 0; i < n->size(); i++ )*/
            {
                // is voltage source connected to node ?
                if (currentn->getCircuit () == vsr)
                {
                    ri = vsr->getSize () + r - vsr->getVoltageSource ();
                    ci = currentn->getPort ();
                    val += MatVal (vsr->getN (ri, ci));
                }
            }
            // put value into Cy matrix
            C->set (r + N, c, val);
        }
    }

    // go through each voltage source
    for (c = 0; c < M; c++)
    {
        vsc = findVoltageSource (c);
        // go through each node
        for (r = 0; r < N; r++)
        {
            val = 0.0;
            n = nlist->getNode (r);
            for (auto & currentn: *n)/*i = 0; i < n->size(); i++)*/
            {
                // is voltage source connected to node ?
                if (currentn->getCircuit () == vsc)
                {
                    ci = vsc->getSize () + c - vsc->getVoltageSource ();
                    ri = currentn->getPort ();
                    val += MatVal (vsc->getN (ri, ci));
                }
            }
            // put value into Cy matrix
            C->set (r, c + N, val);
        }
    }

}
Example #14
0
int nasolver<nr_type_t>::getM()
{
    return countVoltageSources ();
}
Example #15
0
void nasolver<nr_type_t>::saveResults (const std::string &volts, const std::string &amps,
                                       int saveOPs, qucs::vector * f)
{
    int N = countNodes ();
    int M = countVoltageSources ();

    // add node voltage variables
    if (!volts.empty())
    {
        for (int r = 0; r < N; r++)
        {
	  std::string n = createV (r, volts, saveOPs);
	  if(!n.empty())
	    {
                saveVariable (n, x->get (r), f);
            }
        }
    }

    // add branch current variables
    if (!amps.empty())
    {
        for (int r = 0; r < M; r++)
        {
	  std::string n = createI (r, amps, saveOPs);
	  if (!n.empty())
            {
                saveVariable (n, x->get (r + N), f);
            }
        }
    }

    // add voltage probe data
    if (!volts.empty())
    {
        circuit * root = subnet->getRoot ();
        for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ())
        {
            if (!c->isProbe ()) continue;
            if (!c->getSubcircuit().empty() && !(saveOPs & SAVE_ALL)) continue;
            if (volts != "vn")
                c->saveOperatingPoints ();	    
	    std::string n = createOP (c->getName (), volts);
            saveVariable (n, nr_complex_t (c->getOperatingPoint ("Vr"),
                                   c->getOperatingPoint ("Vi")), f);
        }
    }

    // save operating points of non-linear circuits if requested
    if (saveOPs & SAVE_OPS)
    {
        circuit * root = subnet->getRoot ();
        for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ())
        {
            if (!c->isNonLinear ()) continue;
            if (!c->getSubcircuit ().empty() && !(saveOPs & SAVE_ALL)) continue;
            c->calcOperatingPoints ();
            for (auto ops: c->getOperatingPoints ())
            {
                operatingpoint &p = ops.second;
		std::string n = createOP (c->getName (), p.getName ());
                saveVariable (n, p.getValue (), f);
            }
        }
    }
}