new option noopac, don't do op simulation before ac if circuit is linear

May simplify ac simulation of passive RLC networks
(No need to add series resistors in Ls, allows to C inseries)
This commit is contained in:
h_vogt 2012-09-26 16:59:59 +02:00
parent 998c7f2934
commit 68c4de76b7
8 changed files with 69 additions and 12 deletions

View File

@ -10,6 +10,7 @@ Author: 1985 Wayne A. Christopher
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "ngspice/cpdefs.h"
#include "ngspice/inpdefs.h"
#include "ngspice/ftedefs.h"
@ -49,6 +50,7 @@ static char *upper(register char *string);
static bool doedit(char *filename);
static struct line *com_options = NULL;
static void consaves(wordlist *wl);
static void cktislinear(CKTcircuit *ckt, struct line *deck);
void line_free_x(struct line *deck, bool recurse);
@ -796,6 +798,7 @@ inp_dodeck(
ckt = NULL;
}
cktislinear(ckt, deck);
out_init();
ft_curckt->FTEstats->FTESTATdeckNumLines = 0;
@ -1138,3 +1141,40 @@ consaves(wordlist *wl_control)
com_save(wl);
}
/* check the input deck (after inpcom and numparam extensions)
for linear elements. If only linear elements are found,
ckt->CKTisLinear is set to 1. Return immediately if a first
non-linear element is found. */
static void
cktislinear(CKTcircuit *ckt, struct line *deck)
{
struct line *dd;
char firstchar;
if (deck->li_next)
for (dd = deck->li_next; dd; dd = dd->li_next) {
firstchar = *dd->li_line;
switch (firstchar) {
case 'r':
case 'l':
case 'c':
case 'i':
case 'v':
case '*':
case '.':
case 'e':
case 'g':
case 'f':
case 'h':
continue;
break;
default:
ckt->CKTisLinear = 0;
return;
}
}
ckt->CKTisLinear = 1;
}

View File

@ -275,7 +275,10 @@ struct CKTcircuit {
int CKTsc_iter;
/* SP: 100609 */
#endif
unsigned int CKTisLinear:1; /* flag to indicate that the circuit
contains only linear elements */
unsigned int CKTnoopac:1; /* flag to indicate that OP will not be evaluated
during AC simulation */
};

View File

@ -124,6 +124,8 @@ typedef struct {
#define OPT_ABSDV 66 /* Original: 51 (Node_Damping) */
#define OPT_RELDV 67 /* Original: 52 (Node_Damping) */
#define OPT_NOOPAC 68
#ifdef XSPICE
/* gtri - begin - wbk - add new options */
#define OPT_ENH_NOOPALTER 100

View File

@ -65,6 +65,7 @@ struct TSKtask {
unsigned int TSKnodeDamping:1; /* flag for node damping */
double TSKabsDv; /* abs limit for iter-iter voltage change */
double TSKrelDv; /* rel limit for iter-iter voltage change */
unsigned int TSKnoopac:1; /* flag for no OP calculation before AC */
};
#endif /*TSK*/

View File

@ -123,17 +123,21 @@ ACan(CKTcircuit *ckt, int restart)
}
else
#endif
/* If no event-driven instances, do what SPICE normally does */
error = CKTop(ckt,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter);
/* If no event-driven instances, do what SPICE normally does */
if (!ckt->CKTnoopac) { /* skip OP if option NOOPAC is set and circuit is linear */
error = CKTop(ckt,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter);
if(error){
fprintf(stdout,"\nAC operating point failed -\n");
CKTncDump(ckt);
return(error);
}
if(error){
fprintf(stdout,"\nAC operating point failed -\n");
CKTncDump(ckt);
return(error);
}
}
else
fprintf(stdout,"\n Linear circuit, option noopac given: no OP analysis\n");
#ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */

View File

@ -103,6 +103,7 @@ CKTdoJob(CKTcircuit *ckt, int reset, TSKtask *task)
ckt->CKTrelDv = task->TSKrelDv;
ckt->CKTtroubleNode = 0;
ckt->CKTtroubleElt = NULL;
ckt->CKTnoopac = task->TSKnoopac && ckt->CKTisLinear;
#ifdef NEWTRUNC
ckt->CKTlteReltol = task->TSKlteReltol;
ckt->CKTlteAbstol = task->TSKlteAbstol;

View File

@ -70,6 +70,7 @@ CKTnewTask(CKTcircuit *ckt, TSKtask **taskPtr, IFuid taskName, TSKtask **defPtr)
tsk->TSKnodeDamping = def->TSKnodeDamping;
tsk->TSKabsDv = def->TSKabsDv;
tsk->TSKrelDv = def->TSKrelDv;
tsk->TSKnoopac = def->TSKnoopac;
#ifdef NEWTRUNC
tsk->TSKlteReltol = def->TSKlteReltol;
tsk->TSKlteAbstol = def->TSKlteAbstol;

View File

@ -158,6 +158,9 @@ CKTsetOpt(CKTcircuit *ckt, JOB *anal, int opt, IFvalue *val)
case OPT_RELDV:
task->TSKrelDv = val->rValue;
break;
case OPT_NOOPAC:
task->TSKnoopac = (val->iValue != 0);
break;
/* gtri - begin - wbk - add new options */
#ifdef XSPICE
case OPT_EVT_MAX_OP_ALTER:
@ -311,7 +314,9 @@ static IFparm OPTtbl[] = {
{ "absdv", OPT_ABSDV, IF_SET|IF_REAL,
"Maximum absolute iter-iter node voltage change" },
{ "reldv", OPT_RELDV, IF_SET|IF_REAL,
"Maximum relative iter-iter node voltage change" }
"Maximum relative iter-iter node voltage change" },
{ "noopac", OPT_NOOPAC, IF_SET|IF_FLAG,
"No op calculation in ac if circuit is linear" }
};
int OPTcount = NUMELEMS(OPTtbl);