/* 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; }
int nasolver<nr_type_t>::solve_once (void) { qucs::exception * e; int error = 0, d; // run the calculation function for each circuit calculate (); // generate A matrix and z vector createMatrix (); // solve equation system try_running () { runMNA (); } // appropriate exception handling catch_exception () { case EXCEPTION_PIVOT: case EXCEPTION_WRONG_VOLTAGE: e = new qucs::exception (EXCEPTION_NA_FAILED); d = top_exception()->getData (); pop_exception (); if (d >= countNodes ()) { d -= countNodes (); e->setText ("voltage source `%s' conflicts with some other voltage " "source", findVoltageSource(d)->getName ()); } else { e->setText ("circuit admittance matrix in %s solver is singular at " "node `%s' connected to [%s]", desc.c_str(), nlist->get (d).c_str(), nlist->getNodeString (d).c_str()); } throw_exception (e); error++; break; case EXCEPTION_SINGULAR: do { d = top_exception()->getData (); pop_exception (); if (d < countNodes ()) { logprint (LOG_ERROR, "WARNING: %s: inserted virtual resistance at " "node `%s' connected to [%s]\n", getName (), nlist->get (d).c_str(), nlist->getNodeString (d).c_str()); } } while (top_exception() != NULL && top_exception()->getCode () == EXCEPTION_SINGULAR); break; default: estack.print (); break; } // save results into circuits if (!error) saveSolution (); return error; }