noise analysis, bug fix, override ac magnitude of all vsrc/isrc devices

Bug report due to Hartmut Henkel in
>> [Ngspice-users] Noise analysis depends on ac parameter

The noise analysis internally depends on an ac analysis
  to derive "inoise" from "onoise"
("onoise" is multiplied with the inverse ac gain from input to output)

This AC analysis used all the given ac magnitudes for all vsrc/isrc
  devices in the deck.

This fix overrides all ac magnitudes with zero,
  except for the given input device,
  whose magnitude is set to one.
This commit is contained in:
rlar 2015-03-03 21:27:29 +01:00
parent b3b543c1c7
commit 07ee771a96
4 changed files with 34 additions and 8 deletions

View File

@ -165,6 +165,9 @@ struct CKTcircuit {
#define MODETRAN 0x1
#define MODEAC 0x2
/* for noise analysis */
#define MODEACNOISE 0x8
/* old 'modedc' parameters */
#define MODEDC 0x70
#define MODEDCOP 0x10
@ -288,6 +291,8 @@ struct CKTcircuit {
NGHASHPTR DEVnameHash;
NGHASHPTR MODnameHash;
GENinstance *noise_input; /* identify the input vsrc/isrc during noise analysis */
};

View File

@ -37,13 +37,13 @@ NOISEan (CKTcircuit *ckt, int restart)
double freqTol; /* tolerence parameter for finding final frequency; hack */
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;
GENinstance *inst = CKTfndDev(ckt, job->input);
posOutNode = (job->output) -> number;
negOutNode = (job->outputRef) -> number;
/* see if the source specified is AC */
{
GENinstance *inst = CKTfndDev(ckt, job->input);
bool ac_given = FALSE;
if (!inst || inst->GENmodPtr->GENmodType < 0) {
@ -194,7 +194,8 @@ NOISEan (CKTcircuit *ckt, int restart)
return (E_PAUSE);
}
ckt->CKTomega = 2.0 * M_PI * data->freq;
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEAC;
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEAC | MODEACNOISE;
ckt->noise_input = inst;
/*
* solve the original AC system to get the transfer

View File

@ -23,16 +23,26 @@ ISRCacLoad(GENmodel *inModel, CKTcircuit *ckt)
for (here = model->ISRCinstances; here != NULL ;
here=here->ISRCnextInstance) {
double acReal, acImag;
if ((ckt->CKTmode & MODEACNOISE) && (here == ckt->noise_input)) {
acReal = 1.0;
acImag = 0.0;
} else {
acReal = here->ISRCacReal;
acImag = here->ISRCacImag;
}
m = here->ISRCmValue;
*(ckt->CKTrhs + (here->ISRCposNode)) +=
m * here->ISRCacReal;
m * acReal;
*(ckt->CKTrhs + (here->ISRCnegNode)) -=
m * here->ISRCacReal;
m * acReal;
*(ckt->CKTirhs + (here->ISRCposNode)) +=
m * here->ISRCacImag;
m * acImag;
*(ckt->CKTirhs + (here->ISRCnegNode)) -=
m * here->ISRCacImag;
m * acImag;
}
}

View File

@ -22,12 +22,22 @@ VSRCacLoad(GENmodel *inModel, CKTcircuit *ckt)
for (here = model->VSRCinstances; here != NULL ;
here=here->VSRCnextInstance) {
double acReal, acImag;
if ((ckt->CKTmode & MODEACNOISE) && (here == ckt->noise_input)) {
acReal = 1.0;
acImag = 0.0;
} else {
acReal = here->VSRCacReal;
acImag = here->VSRCacImag;
}
*(here->VSRCposIbrptr) += 1.0 ;
*(here->VSRCnegIbrptr) -= 1.0 ;
*(here->VSRCibrPosptr) += 1.0 ;
*(here->VSRCibrNegptr) -= 1.0 ;
*(ckt->CKTrhs + (here->VSRCbranch)) += here->VSRCacReal;
*(ckt->CKTirhs + (here->VSRCbranch)) += here->VSRCacImag;
*(ckt->CKTrhs + (here->VSRCbranch)) += acReal;
*(ckt->CKTirhs + (here->VSRCbranch)) += acImag;
}
}