ngspice/src/maths/ni/nipred.c

155 lines
4.6 KiB
C

/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/*
* NIpred(ckt)
*
* This subroutine does node voltage prediction based on the
* integration method
*/
#include "ngspice.h"
#include "trandefs.h"
#include "cktdefs.h"
#include "sperror.h"
#include "smpdefs.h"
#include "nipred.h"
#ifdef PREDICTOR
int
NIpred(CKTcircuit * ckt)
{
int i;
double *temp;
int size;
CKTnode *node;
/* for our prediction, we have:
* ckt->CKTrhs[] is the current solution
* ckt->CKTsols[8][] is the set of previous solutions
*
* we want:
* ckt->CKTpred[] = ckt->CKTrhs = prediction based on proper number of
* previous time steps.
*/
size = SMPmatSize(ckt->CKTmatrix);
switch(ckt->CKTintegrateMethod) {
case TRAPEZOIDAL: {
double dd0,dd1,a,b;
switch(ckt->CKTorder) {
case 1:
for(i=0;i<=size;i++) {
dd0=(ckt->CKTsols[0][i]-ckt->CKTsols[1][i])/
(ckt->CKTdeltaOld[1]);
ckt->CKTpred[i] = ckt->CKTrhs[i] = ckt->CKTsols[0][i]+
ckt->CKTdeltaOld[0]*dd0;
}
break;
case 2:
for(i=0;i<=size;i++) {
b = -ckt->CKTdeltaOld[0]/(2*ckt->CKTdeltaOld[1]);
a = 1-b;
dd0=(ckt->CKTsols[0][i]-ckt->CKTsols[1][i])/
(ckt->CKTdeltaOld[1]);
dd1= ((ckt->CKTsols[1][i]-ckt->CKTsols[2][i])/
ckt->CKTdeltaOld[2] );
ckt->CKTpred[i] = ckt->CKTrhs[i] =
ckt->CKTsols[0][i]+
(b*dd1 + a*dd0)* ckt->CKTdeltaOld[0];
}
break;
default:
return(E_ORDER);
}
case GEAR:
node = ckt->CKTnodes;
switch(ckt->CKTorder) {
case 1:
for(i=0;i<=size;i++) {
ckt->CKTpred[i]=ckt->CKTrhs[i] =
ckt->CKTagp[0]* ckt->CKTsols[0][i] +
ckt->CKTagp[1]* ckt->CKTsols[1][i] ;
node = node->next;
}
break;
case 2:
for(i=0;i<=size;i++) {
ckt->CKTpred[i]=ckt->CKTrhs[i] =
ckt->CKTagp[0]* ckt->CKTsols[0][i] +
ckt->CKTagp[1]* ckt->CKTsols[1][i] +
ckt->CKTagp[2]* ckt->CKTsols[2][i] ;
node = node->next;
}
break;
case 3:
for(i=0;i<=size;i++) {
ckt->CKTpred[i]=ckt->CKTrhs[i] =
ckt->CKTagp[0]* ckt->CKTsols[0][i] +
ckt->CKTagp[1]* ckt->CKTsols[1][i] +
ckt->CKTagp[2]* ckt->CKTsols[2][i] +
ckt->CKTagp[3]* ckt->CKTsols[3][i] ;
}
break;
case 4:
for(i=0;i<=size;i++) {
ckt->CKTpred[i]=ckt->CKTrhs[i] =
ckt->CKTagp[0]* ckt->CKTsols[0][i] +
ckt->CKTagp[1]* ckt->CKTsols[1][i] +
ckt->CKTagp[2]* ckt->CKTsols[2][i] +
ckt->CKTagp[3]* ckt->CKTsols[3][i] +
ckt->CKTagp[4]* ckt->CKTsols[4][i] ;
}
break;
case 5:
for(i=0;i<=size;i++) {
ckt->CKTpred[i]=ckt->CKTrhs[i] =
ckt->CKTagp[0]* ckt->CKTsols[0][i] +
ckt->CKTagp[1]* ckt->CKTsols[1][i] +
ckt->CKTagp[2]* ckt->CKTsols[2][i] +
ckt->CKTagp[3]* ckt->CKTsols[3][i] +
ckt->CKTagp[4]* ckt->CKTsols[4][i] +
ckt->CKTagp[5]* ckt->CKTsols[5][i] ;
}
break;
case 6:
for(i=0;i<=size;i++) {
ckt->CKTpred[i]=ckt->CKTrhs[i] =
ckt->CKTagp[0]* ckt->CKTsols[0][i] +
ckt->CKTagp[1]* ckt->CKTsols[1][i] +
ckt->CKTagp[2]* ckt->CKTsols[2][i] +
ckt->CKTagp[3]* ckt->CKTsols[3][i] +
ckt->CKTagp[4]* ckt->CKTsols[4][i] +
ckt->CKTagp[5]* ckt->CKTsols[5][i] +
ckt->CKTagp[6]* ckt->CKTsols[6][i] ;
}
break;
default:
return(E_ORDER);
}
}
break;
default:
return(E_METHOD);
}
return(OK);
}
#else
int Dummy_Symbol;
#endif /* PREDICTOR */