📄 diosacl.c
字号:
/**********Copyright 1990 Regents of the University of California. All rights reserved.Author: 1985 Thomas L. Quarles**********//* *//* actually load the current ac sensitivity * information into the array previously provided */#include "spice.h"#include <stdio.h>#include "util.h"#include "smpdefs.h"#include "const.h"#include "cktdefs.h"#include "diodefs.h"#include "sperror.h"#include "suffix.h"intDIOsAcLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt;{ register DIOmodel *model = (DIOmodel*)inModel; register 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=model->DIOconductance*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=model->DIOconductance*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=model->DIOconductance*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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -