2003-08-11 21:25:28 +02:00
|
|
|
/**********
|
|
|
|
|
Copyright 1991 Regents of the University of California. All rights reserved.
|
|
|
|
|
Author: 1991 David A. Gates, U. C. Berkeley CAD Group
|
|
|
|
|
Modified: 2001 Paolo Nenzi
|
|
|
|
|
**********/
|
|
|
|
|
|
2011-12-11 19:05:00 +01:00
|
|
|
#include "ngspice/ngspice.h"
|
|
|
|
|
#include "ngspice/numcards.h"
|
|
|
|
|
#include "ngspice/numgen.h"
|
|
|
|
|
#include "ngspice/numenum.h"
|
|
|
|
|
#include "ngspice/methdefs.h"
|
|
|
|
|
#include "ngspice/sperror.h"
|
|
|
|
|
#include "ngspice/devdefs.h"
|
|
|
|
|
#include "ngspice/suffix.h"
|
2003-08-11 21:25:28 +02:00
|
|
|
|
|
|
|
|
|
2013-07-20 20:06:55 +02:00
|
|
|
extern int METHnewCard(GENcard**,GENmodel*);
|
|
|
|
|
extern int METHparam(int,IFvalue*,GENcard*);
|
2003-08-11 21:25:28 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
IFparm METHpTable[] = {
|
|
|
|
|
IP("devtol", METH_DABSTOL, IF_REAL, "Absolute tolerance on device equations"),
|
|
|
|
|
IP("dabstol", METH_DABSTOL, IF_REAL, "Absolute tolerance on device equations"),
|
|
|
|
|
IP("dreltol", METH_DRELTOL, IF_REAL, "Relative tolerance on device equations"),
|
|
|
|
|
IP("onecarrier",METH_ONEC, IF_FLAG, "Solve for majority carriers only"),
|
|
|
|
|
IP("ac.analysis",METH_ACANAL, IF_STRING, "AC solution technique"),
|
|
|
|
|
IP("frequency",METH_OMEGA, IF_REAL, "AC default frequency"),
|
|
|
|
|
IP("nomobderiv",METH_NOMOBDERIV,IF_FLAG, "Ignore mobility derivatives"),
|
|
|
|
|
IP("itlim", METH_ITLIM, IF_INTEGER, "Iteration limit"),
|
|
|
|
|
IP("voltpred",METH_VOLTPRED, IF_FLAG, "Perform DC voltage prediction")
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
IFcardInfo METHinfo = {
|
|
|
|
|
"method",
|
|
|
|
|
"Specify parameters and types of simulation methods",
|
|
|
|
|
NUMELEMS(METHpTable),
|
|
|
|
|
METHpTable,
|
|
|
|
|
|
|
|
|
|
METHnewCard,
|
|
|
|
|
METHparam,
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int
|
2013-07-20 20:06:55 +02:00
|
|
|
METHnewCard(GENcard **inCard, GENmodel *inModel)
|
2003-08-11 21:25:28 +02:00
|
|
|
{
|
|
|
|
|
METHcard *tmpCard, *newCard;
|
|
|
|
|
GENnumModel *model = (GENnumModel *)inModel;
|
|
|
|
|
|
|
|
|
|
tmpCard = model->GENmethods;
|
|
|
|
|
if (!tmpCard) { /* First in list */
|
|
|
|
|
newCard = NEW( METHcard );
|
|
|
|
|
if (!newCard) {
|
2011-04-28 17:59:36 +02:00
|
|
|
*inCard = NULL;
|
2003-08-11 21:25:28 +02:00
|
|
|
return(E_NOMEM);
|
|
|
|
|
}
|
2011-04-28 17:59:36 +02:00
|
|
|
newCard->METHnextCard = NULL;
|
2013-07-20 20:06:55 +02:00
|
|
|
*inCard = (GENcard *) newCard;
|
2003-08-11 21:25:28 +02:00
|
|
|
model->GENmethods = newCard;
|
|
|
|
|
} else { /* Only one card of this type allowed */
|
2013-07-20 20:06:55 +02:00
|
|
|
*inCard = (GENcard *)tmpCard;
|
2003-08-11 21:25:28 +02:00
|
|
|
}
|
|
|
|
|
return(OK);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2013-07-20 20:06:55 +02:00
|
|
|
METHparam(int param, IFvalue *value, GENcard *inCard)
|
2003-08-11 21:25:28 +02:00
|
|
|
{
|
|
|
|
|
METHcard *card = (METHcard *)inCard;
|
|
|
|
|
|
|
|
|
|
switch (param) {
|
|
|
|
|
case METH_DABSTOL:
|
|
|
|
|
card->METHdabstol = value->rValue;
|
|
|
|
|
card->METHdabstolGiven = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
case METH_DRELTOL:
|
|
|
|
|
card->METHdreltol = value->rValue;
|
|
|
|
|
card->METHdreltolGiven = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
case METH_OMEGA:
|
|
|
|
|
card->METHomega = 2.0 * M_PI * value->rValue;
|
|
|
|
|
card->METHomegaGiven = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
case METH_ONEC:
|
|
|
|
|
card->METHoneCarrier = value->iValue;
|
|
|
|
|
card->METHoneCarrierGiven = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
case METH_NOMOBDERIV:
|
|
|
|
|
card->METHmobDeriv = !(value->iValue);
|
|
|
|
|
card->METHmobDerivGiven = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
case METH_ACANAL:
|
|
|
|
|
if ( cinprefix( value->sValue, "direct", 1 ) ) {
|
|
|
|
|
card->METHacAnalysisMethod = DIRECT;
|
|
|
|
|
card->METHacAnalysisMethodGiven = TRUE;
|
|
|
|
|
} else if ( cinprefix( value->sValue, "sor", 1 ) ) {
|
|
|
|
|
card->METHacAnalysisMethod = SOR;
|
|
|
|
|
card->METHacAnalysisMethodGiven = TRUE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case METH_ITLIM:
|
|
|
|
|
card->METHitLim = value->iValue;
|
|
|
|
|
card->METHitLimGiven = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
case METH_VOLTPRED:
|
|
|
|
|
card->METHvoltPred = value->iValue;
|
|
|
|
|
card->METHvoltPredGiven = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return(E_BADPARM);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return(OK);
|
|
|
|
|
}
|