You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

283 lines
9.3 KiB

/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
This function is obsolete (was used by an old sensitivity analysis)
**********/
/*
*/
/* actually load the current ac sensitivity
* information into the array previously provided
*/
#include "ngspice.h"
#include "smpdefs.h"
#include "const.h"
#include "cktdefs.h"
#include "diodefs.h"
#include "sperror.h"
#include "suffix.h"
int
DIOsAcLoad(GENmodel *inModel, CKTcircuit *ckt)
{
DIOmodel *model = (DIOmodel*)inModel;
DIOinstance *here;
double SaveState[5];
int error;
int i;
int iparmno;
int flag;
double A0;
double DELA;
double Apert;
double DELAinv;
double vte;
double gspr0;
double geq0;
double xceq0;
double vspr;
double ivspr;
double vd;
double ivd;
double vdOp;
double gspr;
double geq;
double xceq;
double cspr;
double icspr;
double cd;
double icd;
double cpos0;
double icpos0;
double cpos;
double icpos;
double cposprm0;
double icposprm0;
double cposprm;
double icposprm;
double cneg0;
double icneg0;
double cneg;
double icneg;
double DvdDp;
SENstruct *info;
#ifdef SENSDEBUG
printf("DIOsenacload\n");
#endif /* SENSDEBUG */
info = ckt->CKTsenInfo;
info->SENstatus = PERTURBATION;
/* loop through all the models */
for( ; model != NULL; model = model->DIOnextModel ) {
/* loop through all the instances of the model */
for (here = model->DIOinstances; here != NULL ;
here=here->DIOnextInstance) {
if (here->DIOowner != ARCHme) continue;
/* save the unperturbed values in the state vector */
for(i=0; i <= 4; i++) {
*(SaveState + i) = *(ckt->CKTstate0 + here->DIOstate + i);
}
vspr = *(ckt->CKTrhsOld + here->DIOposNode)
- *(ckt->CKTrhsOld + here->DIOposPrimeNode) ;
ivspr = *(ckt->CKTirhsOld + here->DIOposNode)
- *(ckt->CKTirhsOld + here->DIOposPrimeNode) ;
vd = *(ckt->CKTrhsOld + here->DIOposPrimeNode)
- *(ckt->CKTrhsOld + here->DIOnegNode) ;
ivd = *(ckt->CKTirhsOld + here->DIOposPrimeNode)
- *(ckt->CKTirhsOld + here->DIOnegNode) ;
vdOp = *(ckt->CKTrhsOp + here->DIOposPrimeNode)
- *(ckt->CKTrhsOp + here->DIOnegNode);
/* without perturbation */
#ifdef SENSDEBUG
printf("without perturbation \n");
#endif /* SENSDEBUG */
*(ckt->CKTstate0 + here->DIOvoltage) = vdOp;
here->DIOsenPertFlag = ON;
if(info->SENacpertflag == 1){
if ((error = DIOload((GENmodel*)model,ckt)))
return(error);
*(here->DIOsenGeq) = *(ckt->CKTstate0 + here->DIOconduct);
*(here->DIOsenCeq) = *(ckt->CKTstate0 + here->DIOcapCurrent);
}
geq0 = *(here->DIOsenGeq);
xceq0 = *(here->DIOsenCeq) * ckt->CKTomega;
A0 = here->DIOarea;
gspr0=here->DIOtConductance*A0;
cpos0 = gspr0 * vspr;
icpos0 = gspr0 * ivspr;
cposprm0 = geq0 * vd - xceq0 * ivd - cpos0;
icposprm0 = geq0 * ivd + xceq0 * vd - icpos0;
cneg0 = - geq0 * vd + xceq0 * ivd;
icneg0 = - geq0 * ivd - xceq0 * vd;
#ifdef SENSDEBUG
printf("gspr0 = %.7e , geq0 = %.7e ,xceq0 = %.7e\n",
gspr0 ,geq0,xceq0);
printf("cpos0 = %.7e + j%.7e , cneg0 = %.7e + j%.7e\n",
cpos0,icpos0,cneg0,icneg0);
#endif /* SENSDEBUG */
/* Perturbation of Area */
#ifdef SENSDEBUG
printf("Perturbation of Area\n");
#endif /* SENSDEBUG */
if(here->DIOsenParmNo == 0) goto pertvd;
DELA = info->SENpertfac * A0;
Apert = A0 + DELA;
DELAinv = 1.0/DELA;
if(info->SENacpertflag == 1){
here->DIOarea = Apert;
*(ckt->CKTstate0 + here->DIOvoltage) = vdOp;
if ((error = DIOload((GENmodel*)model,ckt)))
return(error);
*(here->DIOsenGeq + 1) = *(ckt->CKTstate0 + here->DIOconduct);
*(here->DIOsenCeq + 1)= *(ckt->CKTstate0 + here->DIOcapCurrent);
here->DIOarea = A0;
}
gspr=here->DIOtConductance*Apert;
geq = *(here->DIOsenGeq + 1);
xceq = *(here->DIOsenCeq + 1) * ckt->CKTomega;
flag = 0;
goto load;
pertvd: /* Perturbation of Diode Voltage */
#ifdef SENSDEBUG
printf("Perturbation of vd\n");
#endif /* SENSDEBUG */
vte=model->DIOemissionCoeff * CONSTKoverQ * here->DIOtemp;
A0 = vdOp;
DELA = info->SENpertfac * vte;
Apert = A0 + DELA;
DELAinv = 1.0/DELA;
if(info->SENacpertflag == 1){
*(ckt->CKTstate0 + here->DIOvoltage) = Apert;
if ((error = DIOload((GENmodel*)model,ckt)))
return(error);
*(here->DIOsenGeq + 2) = *(ckt->CKTstate0 + here->DIOconduct);
*(here->DIOsenCeq + 2)= *(ckt->CKTstate0 + here->DIOcapCurrent);
*(ckt->CKTstate0 + here->DIOvoltage) = A0;
}
gspr=here->DIOtConductance*here->DIOarea;
geq = *(here->DIOsenGeq + 2);
xceq = *(here->DIOsenCeq + 2) * ckt->CKTomega;
flag = 1;
load:
cspr = gspr * vspr;
icspr = gspr * ivspr;
cd = geq * vd - xceq * ivd;
icd = geq * ivd + xceq * vd;
cpos = cspr;
icpos = icspr;
cposprm = ( - cspr + cd );
icposprm = ( - icspr + icd );
cneg = ( - cd );
icneg = ( - icd );
#ifdef SENSDEBUG
printf("gspr = %.7e , geq = %.7e , xceq = %.7e\n",
gspr,geq,xceq);
printf("cspr = %.7e + j%.7e , cd = %.7e + j%.7e\n",
cspr,icspr,cd,icd);
printf("cpos = %.7e + j%.7e , cposprm = %.7e + j%.7e",
cpos,icpos,cposprm,icposprm);
printf(", cneg = %.7e + %.7e\n",cneg,icneg);
printf("senpprm = %.7e "
,info->SEN_Sap[here->DIOposPrimeNode][here->DIOsenParmNo]);
printf("senneg = %.7e \n",
info->SEN_Sap[here->DIOnegNode][here->DIOsenParmNo]);
printf("A0 = %.7e , Apert = %.7e ,factor = %.7e\n,vte = %.7e",
A0 ,Apert,DELAinv,vte);
#endif /* SENSDEBUG */
for(iparmno = 1;iparmno<=info->SENparms;iparmno++){
/* calculate the DC sensitivities of operating points */
DvdDp = info->SEN_Sap[here->DIOposPrimeNode][iparmno]
- info->SEN_Sap[here->DIOnegNode][iparmno];
if(flag == 0){
if (here->DIOsenParmNo != iparmno) continue;
/* area : so no DC sensitivity term involved */
DvdDp =1;
}
/* load the RHS matrix */
if(here->DIOposNode != here->DIOposPrimeNode){
/* DcposDp */
*(info->SEN_RHS[here->DIOposNode] + iparmno) -=
(cpos - cpos0) * DELAinv * DvdDp ;
/* DicposDp */
*(info->SEN_iRHS[here->DIOposNode] + iparmno) -=
(icpos - icpos0) * DELAinv * DvdDp ;
}
/* DcposprmDp */
*(info->SEN_RHS[here->DIOposPrimeNode] + iparmno) -=
(cposprm - cposprm0) * DELAinv * DvdDp ;
/* DicposprmDp */
*(info->SEN_iRHS[here->DIOposPrimeNode] + iparmno) -=
(icposprm - icposprm0) * DELAinv * DvdDp ;
/* DcnegDp */
*(info->SEN_RHS[here->DIOnegNode] + iparmno) -=
(cneg - cneg0) * DELAinv * DvdDp ;
/* DicnegDp */
*(info->SEN_iRHS[here->DIOnegNode] + iparmno) -=
(icneg - icneg0) * DELAinv * DvdDp ;
#ifdef SENSDEBUG
printf("senpos = %.7e + j%.7e ",
*(info->SEN_RHS[here->DIOposNode] + iparmno),
*(info->SEN_iRHS[here->DIOposNode] + iparmno));
printf("senposprm = %.7e + j%.7e ",
*(info->SEN_RHS[here->DIOposPrimeNode] + iparmno),
*(info->SEN_iRHS[here->DIOposPrimeNode] + iparmno));
printf("senneg = %.7e + j%.7e ",
*(info->SEN_RHS[here->DIOnegNode] + iparmno),
*(info->SEN_iRHS[here->DIOnegNode] + iparmno));
printf("flag = %d ,DvdDp = %.7e ,iparmno = %d,senparmno = %d\n"
,flag,DvdDp,iparmno,here->DIOsenParmNo);
#endif /* SENSDEBUG */
}
if(!flag) goto pertvd;
/* put the unperturbed values back into the state vector */
for(i=0; i <= 4; i++) {
*(ckt->CKTstate0 + here->DIOstate + i) = *(SaveState + i);
}
here->DIOsenPertFlag = OFF;
}
}
info->SENstatus = NORMAL;
#ifdef SENSDEBUG
printf("DIOsenacload end \n");
#endif /* SENSDEBUG */
return(OK);
}