Exemple #1
0
int
NIiter(CKTcircuit *ckt, int maxIter)
{
    double startTime, *OldCKTstate0 = NULL;
    int error, i, j;

    int iterno = 0;
    int ipass = 0;

    /* some convergence issues that get resolved by increasing max iter */
    if (maxIter < 100)
        maxIter = 100;

    if ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) {
        SWAP(double *, ckt->CKTrhs, ckt->CKTrhsOld);
        error = CKTload(ckt);
        if (error)
            return(error);
        return(OK);
    }
Exemple #2
0
int
ACan(CKTcircuit *ckt, int restart)
{

    double freq;
    double freqTol; /* tolerence parameter for finding final frequency */
    double startdTime;
    double startsTime;
    double startlTime;
    double startcTime;
    double startkTime;
    double startTime;
    int error;
    int numNames;
    IFuid *nameList;  /* va: tmalloc'ed list of names */
    IFuid freqUid;
    static void *acPlot = NULL;
    void *plot = NULL;


#ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */

    /* Tell the beginPlot routine what mode we're in */
    g_ipc.anal_type = IPC_ANAL_AC;

    /* Tell the code models what mode we're in */
    g_mif_info.circuit.anal_type = MIF_DC;
    g_mif_info.circuit.anal_init = MIF_TRUE;

/* gtri - end - wbk */
#endif

    /* start at beginning */
    if(((ACAN*)ckt->CKTcurJob)->ACsaveFreq == 0 || restart) { 
        if (((ACAN*)ckt->CKTcurJob)->ACnumberSteps < 1)
            ((ACAN*)ckt->CKTcurJob)->ACnumberSteps = 1;

        switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {

        case DECADE:
            ((ACAN*)ckt->CKTcurJob)->ACfreqDelta =
                exp(log(10.0)/((ACAN*)ckt->CKTcurJob)->ACnumberSteps);
            break;
        case OCTAVE:
            ((ACAN*)ckt->CKTcurJob)->ACfreqDelta =
                exp(log(2.0)/((ACAN*)ckt->CKTcurJob)->ACnumberSteps);
            break;
        case LINEAR:
            if (((ACAN*)ckt->CKTcurJob)->ACnumberSteps-1 > 1)
                ((ACAN*)ckt->CKTcurJob)->ACfreqDelta =
                    (((ACAN*)ckt->CKTcurJob)->ACstopFreq -
                    ((ACAN*)ckt->CKTcurJob)->ACstartFreq)/
                    (((ACAN*)ckt->CKTcurJob)->ACnumberSteps-1);
            else
            /* Patch from: Richard McRoberts
            * This patch is for a rather pathological case:
            * a linear step with only one point */
                ((ACAN*)ckt->CKTcurJob)->ACfreqDelta = 0; 
            break;
        default:
            return(E_BADPARM);
    }
#ifdef XSPICE
/* gtri - begin - wbk - Call EVTop if event-driven instances exist */

    if(ckt->evt->counts.num_insts != 0) {
        error = EVTop(ckt,
            (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
            (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
            ckt->CKTdcMaxIter,
            MIF_TRUE);
        EVTdump(ckt, IPC_ANAL_DCOP, 0.0);
        EVTop_save(ckt, MIF_TRUE, 0.0);
    }
    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(error){
        fprintf(stdout,"\nAC operating point failed -\n");
        CKTncDump(ckt);
        return(error);
    } 
		
#ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */

    /* Send the operating point results for Mspice compatibility */
    if(g_ipc.enabled) 
    {
        /* Call CKTnames to get names of nodes/branches used by 
            BeginPlot */
        /* Probably should free nameList after this block since 
            called again... */
        error = CKTnames(ckt,&numNames,&nameList);
        if(error) return(error);

        /* We have to do a beginPlot here since the data to return is
         * different for the DCOP than it is for the AC analysis.  
         * Moreover the begin plot has not even been done yet at this 
         * point... 
         */
        (*(SPfrontEnd->OUTpBeginPlot))(ckt,(void*)ckt->CKTcurJob,
            ckt->CKTcurJob->JOBname,(IFuid)NULL,IF_REAL,numNames,nameList,
            IF_REAL,&acPlot);
        tfree(nameList);

        ipc_send_dcop_prefix();
        CKTdump(ckt,(double)0,acPlot);
        ipc_send_dcop_suffix();

        (*(SPfrontEnd->OUTendPlot))(acPlot);
    }
/* gtri - end - wbk */
#endif

        ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
        error = CKTload(ckt);
        if(error) return(error);

        error = CKTnames(ckt,&numNames,&nameList);
        if(error) return(error);

	if (ckt->CKTkeepOpInfo) {
	    /* Dump operating point. */
	    error = (*(SPfrontEnd->OUTpBeginPlot))(ckt,
		(void*)ckt->CKTcurJob, "AC Operating Point",
		(IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&plot);
	    if(error) return(error);
	    CKTdump(ckt,(double)0,plot);
	    (*(SPfrontEnd->OUTendPlot))(plot);
	    plot = NULL;
	}

        (*(SPfrontEnd->IFnewUid))(ckt,&freqUid,(IFuid)NULL,
                "frequency", UID_OTHER, NULL);
        error = (*(SPfrontEnd->OUTpBeginPlot))(ckt,
		(void*)ckt->CKTcurJob,
                ckt->CKTcurJob->JOBname,freqUid,IF_REAL,numNames,nameList,
                IF_COMPLEX,&acPlot);
	tfree(nameList);		
	if(error) return(error);

        if (((ACAN*)ckt->CKTcurJob)->ACstepType != LINEAR) {
	    (*(SPfrontEnd->OUTattributes))((void *)acPlot,NULL,
		    OUT_SCALE_LOG, NULL);
	}
        freq = ((ACAN*)ckt->CKTcurJob)->ACstartFreq;

    } else {    /* continue previous analysis */
        freq = ((ACAN*)ckt->CKTcurJob)->ACsaveFreq;
        ((ACAN*)ckt->CKTcurJob)->ACsaveFreq = 0; /* clear the 'old' frequency */
	/* fix resume? saj*/
	error = (*(SPfrontEnd->OUTpBeginPlot))(ckt,
		(void*)ckt->CKTcurJob,
                ckt->CKTcurJob->JOBname,freqUid,IF_REAL,numNames,nameList,
                IF_COMPLEX,&acPlot);
	/* saj*/    
    }
        
    switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {
    case DECADE:
    case OCTAVE:
        freqTol = ((ACAN*)ckt->CKTcurJob)->ACfreqDelta * 
                ((ACAN*)ckt->CKTcurJob)->ACstopFreq * ckt->CKTreltol;
        break;
    case LINEAR:
        freqTol = ((ACAN*)ckt->CKTcurJob)->ACfreqDelta * ckt->CKTreltol;
        break;
    default:
        return(E_BADPARM);
    }


#ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Set anal_init and anal_type */

    g_mif_info.circuit.anal_init = MIF_TRUE;

    /* Tell the code models what mode we're in */
    g_mif_info.circuit.anal_type = MIF_AC;

/* gtri - end - wbk */
#endif


    startTime  = SPfrontEnd->IFseconds();
    startdTime = ckt->CKTstat->STATdecompTime;
    startsTime = ckt->CKTstat->STATsolveTime;
    startlTime = ckt->CKTstat->STATloadTime;
    startcTime = ckt->CKTstat->STATcombineTime;
    startkTime = ckt->CKTstat->STATsyncTime;

    /* main loop through all scheduled frequencies */
    while(freq <= ((ACAN*)ckt->CKTcurJob)->ACstopFreq+freqTol) {
        if( (*(SPfrontEnd->IFpauseTest))() ) { 
            /* user asked us to pause via an interrupt */
            ((ACAN*)ckt->CKTcurJob)->ACsaveFreq = freq;
            return(E_PAUSE);
        }
        ckt->CKTomega = 2.0 * M_PI *freq;

        /* Update opertating point, if variable 'hertz' is given */
        if (ckt->CKTvarHertz) {
#ifdef XSPICE
            /* Call EVTop if event-driven instances exist */

            if(ckt->evt->counts.num_insts != 0) {
                error = EVTop(ckt,
                    (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
                    (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
                    ckt->CKTdcMaxIter,
                    MIF_TRUE);
                EVTdump(ckt, IPC_ANAL_DCOP, 0.0);
                EVTop_save(ckt, MIF_TRUE, 0.0);
            }
            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(error){
                fprintf(stdout,"\nAC operating point failed -\n");
                CKTncDump(ckt);
                return(error);
            } 
            ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
            error = CKTload(ckt);
            if(error) return(error);
        }

        ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEAC;
        error = NIacIter(ckt);
        if (error) {
            ckt->CKTcurrentAnalysis = DOING_AC;
            ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime;
            ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime -
                startdTime;
            ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime -
                startsTime;
            ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime -
                startlTime;
            ckt->CKTstat->STATacCombTime += ckt->CKTstat->STATcombineTime -
                startcTime;
            ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime -
                startkTime;
            return(error);
        }

#ifdef WANT_SENSE2
        if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&ACSEN) ){

            save = ckt->CKTmode;
            ckt->CKTmode=(ckt->CKTmode&MODEUIC)|MODEDCOP|MODEINITSMSIG;
            save1 = ckt->CKTsenInfo->SENmode;
            ckt->CKTsenInfo->SENmode = ACSEN;
            if(freq == ((ACAN*)ckt->CKTcurJob)->ACstartFreq){
                ckt->CKTsenInfo->SENacpertflag = 1;
            }
            else{
                ckt->CKTsenInfo->SENacpertflag = 0;
            }
            if(error = CKTsenAC(ckt)) return (error);
            ckt->CKTmode = save;
            ckt->CKTsenInfo->SENmode = save1;
        }
#endif

#ifdef XSPICE
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */

        if(g_ipc.enabled)
            ipc_send_data_prefix(freq);

        error = CKTacDump(ckt,freq,acPlot);

        if(g_ipc.enabled)
            ipc_send_data_suffix();

/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
#else
        error = CKTacDump(ckt,freq,acPlot);
#endif	
        if (error) {
	    ckt->CKTcurrentAnalysis = DOING_AC;
	    ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime;
 	    ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime -
		    startdTime;
 	    ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime -
 		    startsTime;
 	    ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime -
 		    startlTime;
 	    ckt->CKTstat->STATacCombTime += ckt->CKTstat->STATcombineTime -
 		    startcTime;
	    ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime -
		    startkTime;
 	    return(error);
 	}

        /*  increment frequency */

        switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {
        case DECADE:
        case OCTAVE:

/* inserted again 14.12.2001  */
#ifdef HAS_WINDOWS
            {
                double endfreq   = ((ACAN*)ckt->CKTcurJob)->ACstopFreq;
                double startfreq = ((ACAN*)ckt->CKTcurJob)->ACstartFreq;
                endfreq   = log(endfreq);
                if (startfreq == 0.0)
                    startfreq = 1e-12;
                startfreq = log(startfreq);

                if (freq > 0.0)
                    SetAnalyse( "ac", (log(freq)-startfreq) * 1000.0 / (endfreq-startfreq));
            }
#endif

            freq *= ((ACAN*)ckt->CKTcurJob)->ACfreqDelta;
            if(((ACAN*)ckt->CKTcurJob)->ACfreqDelta==1) goto endsweep;
        break;
        case LINEAR:

#ifdef HAS_WINDOWS
			 {
				 double endfreq   = ((ACAN*)ckt->CKTcurJob)->ACstopFreq;
				 double startfreq = ((ACAN*)ckt->CKTcurJob)->ACstartFreq;
				 SetAnalyse( "ac", (freq - startfreq)* 1000.0 / (endfreq-startfreq));
			 }
#endif

            freq += ((ACAN*)ckt->CKTcurJob)->ACfreqDelta;
            if(((ACAN*)ckt->CKTcurJob)->ACfreqDelta==0) goto endsweep;
            break;
        default:
            return(E_INTERN);
    
        }

    }
endsweep:
    (*(SPfrontEnd->OUTendPlot))(acPlot);
    acPlot = NULL;
    ckt->CKTcurrentAnalysis = 0;
    ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime;
    ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime -
 	    startdTime;
    ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime -
 	    startsTime;
    ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime -
 	    startlTime;
    ckt->CKTstat->STATacCombTime += ckt->CKTstat->STATcombineTime -
	    startcTime;
    ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime -
	    startkTime;
    return(0);
}
Exemple #3
0
///<param name = "*ckt"> Circuit to operate on </param>
///<param name = "maxIter"> Maximum number of iterations to attempt </param>
int NIiter(register CKTcircuit *ckt, int maxIter)
{
    int iterno;
    int ipass;
    int error;
    int i, j; /* temporaries for finding error location */
    char *message;  /* temporary message buffer */
    double *temp;
    double startTime;
    static char *msg = "Too many iterations without convergence";


    iterno = 0;
    ipass = 0;


    if ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))
    {
        temp = ckt->CKTrhsOld;
        ckt->CKTrhsOld = ckt->CKTrhs;
        ckt->CKTrhs = temp;
        error = CKTload(ckt);
        if (error)
        {
            return(error);
        }
        return(OK);
    }
#ifdef HAS_SENSE2
    if (ckt->CKTsenInfo)
    {
        error = NIsenReinit(ckt);
        if (error)
            return(error);
    }
#endif
    if (ckt->CKTniState & NIUNINITIALIZED)
    {
        error = NIreinit(ckt);
        if (error)
        {
#ifdef STEPDEBUG
            printf("re-init returned error \n");
#endif
            return(error);
        }
    }
    while (1)
    {
        ckt->CKTnoncon = 0;
#ifdef NEWPRED
        if (!(ckt->CKTmode & MODEINITPRED))
        {
#else /* NEWPRED */
        if (1)
        {   /* } */
#endif /* NEWPRED */
            error = CKTload(ckt);
            /*printf("loaded, noncon is %d\n",ckt->CKTnoncon);*/
            /*fflush(stdout);*/
            iterno++;
            if (error)
            {
                ckt->CKTstat->STATnumIter += iterno;
#ifdef STEPDEBUG
                printf("load returned error \n");
#endif
                return(error);
            }
            /*printf("after loading, before solving\n");*/
            /*CKTdump(ckt);*/

            if (!(ckt->CKTniState & NIDIDPREORDER))
            {
                error = SMPpreOrder(ckt->CKTmatrix);
                if (error)
                {
                    ckt->CKTstat->STATnumIter += iterno;
#ifdef STEPDEBUG
                    printf("pre-order returned error \n");
#endif
                    return(error); /* badly formed matrix */
                }
                ckt->CKTniState |= NIDIDPREORDER;
            }
            if ((ckt->CKTmode & MODEINITJCT) || ((ckt->CKTmode & MODEINITTRAN) && (iterno == 1)))
            {
                ckt->CKTniState |= NISHOULDREORDER;
            }

            if (ckt->CKTniState & NISHOULDREORDER)
            {
                startTime = (*(SPfrontEnd->IFseconds))();
                error = SMPreorder(ckt->CKTmatrix, ckt->CKTpivotAbsTol, ckt->CKTpivotRelTol, ckt->CKTdiagGmin);
                ckt->CKTstat->STATreorderTime += (*(SPfrontEnd->IFseconds))() - startTime;
                if (error)
                {
                    /* new feature - we can now find out something about what is
                     * wrong - so we ask for the troublesome entry
                     */
                    SMPgetError(ckt->CKTmatrix, &i, &j);
                    message = (char *)MALLOC(1000); /* should be enough */
                    (void)sprintf(message, "singular matrix:  check nodes %s and %s\n", NODENAME(ckt, i), NODENAME(ckt, j));
                    (*(SPfrontEnd->IFerror))(ERR_WARNING, message, (IFuid *)NULL);
                    FREE(message);
                    ckt->CKTstat->STATnumIter += iterno;
#ifdef STEPDEBUG
                    printf("reorder returned error \n");
#endif
                    return(error); /* can't handle these errors - pass up! */
                }
                ckt->CKTniState &= ~NISHOULDREORDER;
            }
            else
            {
                startTime = (*(SPfrontEnd->IFseconds))();
                error = SMPluFac(ckt->CKTmatrix, ckt->CKTpivotAbsTol, ckt->CKTdiagGmin);
                ckt->CKTstat->STATdecompTime += (*(SPfrontEnd->IFseconds))() - startTime;
                if (error)
                {
                    if (error == E_SINGULAR)
                    {
                        ckt->CKTniState |= NISHOULDREORDER;
                        DEBUGMSG(" forced reordering....\n");
                        continue;
                    }
                    /*CKTload(ckt);*/
                    /*SMPprint(ckt->CKTmatrix,stdout);*/
                    /* seems to be singular - pass the bad news up */
                    ckt->CKTstat->STATnumIter += iterno;
#ifdef STEPDEBUG
                    printf("lufac returned error \n");
#endif
                    return(error);
                }
            }

            startTime = (*(SPfrontEnd->IFseconds))();
            SMPsolve(ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTrhsSpare);
            ckt->CKTstat->STATsolveTime += (*(SPfrontEnd->IFseconds))() - startTime;
#ifdef STEPDEBUG
            /*XXXX*/
            if (*ckt->CKTrhs != 0.0)
                printf("NIiter: CKTrhs[0] = %g\n", *ckt->CKTrhs);
            if (*ckt->CKTrhsSpare != 0.0)
                printf("NIiter: CKTrhsSpare[0] = %g\n", *ckt->CKTrhsSpare);
            if (*ckt->CKTrhsOld != 0.0)
                printf("NIiter: CKTrhsOld[0] = %g\n", *ckt->CKTrhsOld);
            /*XXXX*/
#endif
            *ckt->CKTrhs = 0;
            *ckt->CKTrhsSpare = 0;
            *ckt->CKTrhsOld = 0;

            if (iterno > maxIter)
            {
                /*printf("too many iterations without convergence: %d iter's\n",
                		iterno);*/
                ckt->CKTstat->STATnumIter += iterno;
                errMsg = MALLOC(strlen(msg) + 1);
                strcpy(errMsg, msg);
#ifdef STEPDEBUG
                printf("iterlim exceeded \n");
#endif
                return(E_ITERLIM);
            }
            if (ckt->CKTnoncon == 0 && iterno != 1)
            {
                ckt->CKTnoncon = NIconvTest(ckt);
            }
            else
            {
                ckt->CKTnoncon = 1;
            }
        }

        if (ckt->CKTmode & MODEINITFLOAT)
        {
            if ((ckt->CKTmode & MODEDC) && (ckt->CKThadNodeset))
            {
                if (ipass)
                {
                    ckt->CKTnoncon = ipass;
                }
                ipass = 0;
            }

            if (ckt->CKTnoncon == 0)
            {
                ckt->CKTstat->STATnumIter += iterno;
                return(OK);
            }
        }
        else if (ckt->CKTmode & MODEINITJCT)
        {
            ckt->CKTmode = (ckt->CKTmode&(~INITF)) | MODEINITFIX;
            ckt->CKTniState |= NISHOULDREORDER;
        }
        else if (ckt->CKTmode & MODEINITFIX)
        {
            if (ckt->CKTnoncon == 0)
                ckt->CKTmode = (ckt->CKTmode&(~INITF)) | MODEINITFLOAT;

            ipass = 1;
        }
        else if (ckt->CKTmode & MODEINITSMSIG)
        {
            ckt->CKTmode = (ckt->CKTmode&(~INITF)) | MODEINITFLOAT;
        }
        else if (ckt->CKTmode & MODEINITTRAN)
        {
            if (iterno <= 1)
                ckt->CKTniState |= NISHOULDREORDER;

            ckt->CKTmode = (ckt->CKTmode&(~INITF)) | MODEINITFLOAT;
        }
        else if (ckt->CKTmode & MODEINITPRED)
        {
            ckt->CKTmode = (ckt->CKTmode&(~INITF)) | MODEINITFLOAT;
        }
        else
        {
            ckt->CKTstat->STATnumIter += iterno;
#ifdef STEPDEBUG
            printf("bad initf state \n");
#endif
            return(E_INTERN);
            /* impossible - no such INITF flag! */
        }

        /* build up the lvnim1 array from the lvn array */
        temp = ckt->CKTrhsOld;
        ckt->CKTrhsOld = ckt->CKTrhs;
        ckt->CKTrhs = temp;
        /*printf("after loading, after solving\n");*/
        /*CKTdump(ckt);*/
    }
    /*NOTREACHED*/
}
Exemple #4
0
int
NOISEan (CKTcircuit *ckt, int restart)
{
    static Ndata *data; /* va, must be static, for continuation of 
                         * interrupted(Ctrl-C), longer lasting noise 
			 * analysis 
			 */
    double realVal;
    double imagVal;
    int error;
    int posOutNode;
    int negOutNode;
    int step;
    IFuid freqUid;
    double freqTol; /* tolerence parameter for finding final frequency; hack */
    int i, src_type;

    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 */
    {
        //bool ac_given = FALSE;
        int ac_given = FALSE;

        if (!inst || inst->GENmodPtr->GENmodType < 0) {
            SPfrontEnd->IFerrorf (ERR_WARNING,
                                 "Noise input source %s not in circuit",
                                 job->input);
            return E_NOTFOUND;
        }

        if (inst->GENmodPtr->GENmodType == CKTtypelook("Vsource")) {
            ac_given = ((VSRCinstance *)inst) -> VSRCacGiven;
            src_type = SV_VOLTAGE;
        } else if(inst->GENmodPtr->GENmodType == CKTtypelook("Isource")) {
            ac_given = ((ISRCinstance *)inst) -> ISRCacGiven;
            src_type = SV_CURRENT;
        } else {
            SPfrontEnd->IFerrorf (ERR_WARNING,
                                 "Noise input source %s is not of proper type",
                                 job->input);
            return E_NOTFOUND;
        }

        if (!ac_given) {
            SPfrontEnd->IFerrorf (ERR_WARNING,
                                 "Noise input source %s has no AC value",
                                 job->input);
            return E_NOACINPUT;
        }
    }

    if ( (job->NsavFstp == 0.0) || restart) { /* va, NsavFstp is double */
	switch (job->NstpType) {


        case DECADE:
            job->NfreqDelta = exp(log(10.0)/
                            job->NnumSteps);
            break;

        case OCTAVE:
            job->NfreqDelta = exp(log(2.0)/
	                    job->NnumSteps);
            break;

        case LINEAR:
            job->NfreqDelta = (job->NstopFreq - 
                            job->NstartFreq)/
			    (job->NnumSteps - 1);
            break;

        default:
            return(E_BADPARM);
        }

	/* error = DCop(ckt); */
	error = CKTop(ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
		(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
		ckt->CKTdcMaxIter);

	if (error) return(error);

	/* Patch to noisean.c by Richard D. McRoberts. */
	ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
     error = CKTload(ckt);
     if(error) return(error);
     
     data = TMALLOC(Ndata, 1);
	step = 0;
	data->freq = job->NstartFreq;
	data->outNoiz = 0.0;
	data->inNoise = 0.0;
	data->squared = cp_getvar("sqrnoise", CP_BOOL, NULL) ? 1 : 0;

	/* the current front-end needs the namelist to be fully
		declared before an OUTpBeginplot */

	SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);

	data->numPlots = 0;                /* we don't have any plots  yet */
        error = CKTnoise(ckt,N_DENS,N_OPEN,data);
        if (error) return(error);

	/*
	 * all names in the namelist have been declared. now start the
	 * plot
	 */

	if (src_type == SV_VOLTAGE)
	    fixme_inoise_type =
                data->squared ? SV_SQR_VOLTAGE_DENSITY : SV_VOLTAGE_DENSITY;
	else
	    fixme_inoise_type =
                data->squared ? SV_SQR_CURRENT_DENSITY : SV_CURRENT_DENSITY;

	fixme_onoise_type =
            data->squared ? SV_SQR_VOLTAGE_DENSITY : SV_VOLTAGE_DENSITY;

	if (!data->squared)
	    for (i = 0; i < data->numPlots; i++)
		data->squared_value[i] =
		    ciprefix("inoise", data->namelist[i]) ||
		    ciprefix("onoise", data->namelist[i]);

        error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
                                           data->squared
                                           ? "Noise Spectral Density Curves - (V^2 or A^2)/Hz"

                                           : "Noise Spectral Density Curves",
                                           freqUid, IF_REAL,
                                           data->numPlots, data->namelist, IF_REAL,
                                           &(data->NplotPtr));
	if (error) return(error);

        if (job->NstpType != LINEAR) {
	    SPfrontEnd->OUTattributes (data->NplotPtr, NULL, OUT_SCALE_LOG, NULL);
	}

    } else {   /* we must have paused before.  pick up where we left off */
	step = (int)(job->NsavFstp);
	switch (job->NstpType) {

	case DECADE:
        case OCTAVE:
	    data->freq = job->NstartFreq * exp (step *
		     log (job->NfreqDelta));
            break;
            
        case LINEAR:
	    data->freq = job->NstartFreq + step *
		     job->NfreqDelta;
            break;

        default:
            return(E_BADPARM);

        }
	job->NsavFstp = 0;
	data->outNoiz = job->NsavOnoise;
	data->inNoise = job->NsavInoise;
	/* saj resume rawfile fix*/
        error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
                                           NULL,
                                           NULL, 0,
                                           666, NULL, 666,
                                           &(data->NplotPtr));
	/*saj*/
    }

    switch (job->NstpType) {
    case DECADE:
    case OCTAVE:
        freqTol = job->NfreqDelta * job->NstopFreq * ckt->CKTreltol;
        break;
    case LINEAR:
        freqTol = job->NfreqDelta * ckt->CKTreltol;
        break;
    default:
        return(E_BADPARM);
    }

    data->lstFreq = data->freq;

    /* do the noise analysis over all frequencies */

    while (data->freq <= job->NstopFreq + freqTol) {
        if(SPfrontEnd->IFpauseTest()) {
	    job->NsavFstp = step;   /* save our results */
	    job->NsavOnoise = data->outNoiz; /* up until now     */
	    job->NsavInoise = data->inNoise;
	    return (E_PAUSE);
        }
	ckt->CKTomega = 2.0 * M_PI * data->freq;
	ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEAC | MODEACNOISE;
	ckt->noise_input = inst;

	/*
	 * solve the original AC system to get the transfer
	 * function between the input and output
	 */

	NIacIter(ckt);
	realVal = ckt->CKTrhsOld [posOutNode]
		- ckt->CKTrhsOld [negOutNode];
	imagVal = ckt->CKTirhsOld [posOutNode]
		- ckt->CKTirhsOld [negOutNode];
	data->GainSqInv = 1.0 / MAX(((realVal*realVal)
		+ (imagVal*imagVal)),N_MINGAIN);
	data->lnGainInv = log(data->GainSqInv);

	/* set up a block of "common" data so we don't have to
	 * recalculate it for every device
	 */

	data->delFreq = data->freq - data->lstFreq;
	data->lnFreq = log(MAX(data->freq,N_MINLOG));
	data->lnLastFreq = log(MAX(data->lstFreq,N_MINLOG));
        data->delLnFreq = data->lnFreq - data->lnLastFreq;

	if ((job->NStpsSm != 0) && ((step % (job->NStpsSm)) == 0)) {
	    data->prtSummary = TRUE;
        } else {
	    data->prtSummary = FALSE;
        }

	/*
	data->outNumber = 1;       
	*/

	data->outNumber = 0;
	/* the frequency will NOT be stored in array[0]  as before; instead,
	 * it will be given in refVal.rValue (see later)
	 */

	NInzIter(ckt,posOutNode,negOutNode);   /* solve the adjoint system */

	/* now we use the adjoint system to calculate the noise
	 * contributions of each generator in the circuit
	 */

	error = CKTnoise(ckt,N_DENS,N_CALC,data);
	if (error) return(error);
	data->lstFreq = data->freq;

	/* update the frequency */

	switch (job->NstpType) {

	case DECADE:
	case OCTAVE:
	    data->freq *= job->NfreqDelta;
	    break;

        case LINEAR:
	    data->freq += job->NfreqDelta;
	    break;
        
	default:
	    return(E_INTERN);
        }
	step++;
    }

    error = CKTnoise(ckt,N_DENS,N_CLOSE,data);
    if (error) return(error);
    
    data->numPlots = 0;
    data->outNumber = 0;

    if (job->NstartFreq != job->NstopFreq) {
	error = CKTnoise(ckt,INT_NOIZ,N_OPEN,data);

	if (error) return(error);

	if (src_type == SV_VOLTAGE)
	    fixme_inoise_type =
                data->squared ? SV_SQR_VOLTAGE : SV_VOLTAGE;
	else
	    fixme_inoise_type =
                data->squared ? SV_SQR_CURRENT : SV_CURRENT;

	fixme_onoise_type =
                data->squared ? SV_SQR_VOLTAGE : SV_VOLTAGE;

	if (!data->squared)
	    for (i = 0; i < data->numPlots; i++)
		data->squared_value[i] =
		    ciprefix("inoise", data->namelist[i]) ||
		    ciprefix("onoise", data->namelist[i]);

        SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
                                   data->squared
                                   ? "Integrated Noise - V^2 or A^2"
                                   : "Integrated Noise",
                                   NULL, 0,
                                   data->numPlots, data->namelist, IF_REAL,
                                   &(data->NplotPtr));

	error = CKTnoise(ckt,INT_NOIZ,N_CALC,data);
	if (error) return(error);

	error = CKTnoise(ckt,INT_NOIZ,N_CLOSE,data);
	if (error) return(error);
    }

    FREE(data);
    return(OK);
}