182 lines
4.8 KiB
C
182 lines
4.8 KiB
C
/**********
|
|
Copyright 1992 Regents of the University of California. All rights reserved.
|
|
Author: 1992 David A. Gates, U. C. Berkeley CAD Group
|
|
Modified: 2001 Paolo Nenzi
|
|
$Id$
|
|
**********/
|
|
|
|
#include "ngspice.h"
|
|
#include "cktdefs.h"
|
|
#include "numconst.h"
|
|
#include "numenum.h"
|
|
#include "matldefs.h"
|
|
#include "material.h"
|
|
#include "sperror.h"
|
|
#include "suffix.h"
|
|
#include "cidersupt.h"
|
|
|
|
extern int MATLcheck( MATLcard * );
|
|
extern int MATLsetup( MATLcard *, MaterialInfo ** );
|
|
|
|
/*
|
|
* Name: MATLcheck
|
|
* Purpose: checks a list of MATLcards for input errors
|
|
* Formals: cardList: the list to check
|
|
* Returns: OK/E_PRIVATE
|
|
* Users: numerical device setup routines
|
|
* Calls: error message handler
|
|
*/
|
|
int
|
|
MATLcheck(MATLcard *cardList)
|
|
{
|
|
MATLcard *card, *card2;
|
|
int cardNum = 0, cardNum2;
|
|
int error = OK;
|
|
char ebuf[512]; /* error message buffer */
|
|
|
|
for ( card = cardList; card != NIL(MATLcard); card = card->MATLnextCard ) {
|
|
cardNum++;
|
|
|
|
if( !card->MATLmaterialGiven ) {
|
|
card->MATLmaterial = SILICON;
|
|
}
|
|
if (!card->MATLnumberGiven) {
|
|
sprintf( ebuf,
|
|
"material card %d is missing an id number",
|
|
cardNum );
|
|
SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );
|
|
error = E_PRIVATE;
|
|
}
|
|
|
|
/* Return now if anything has failed */
|
|
if (error) return(error);
|
|
|
|
/* Make sure this id is different from all previous ones. */
|
|
cardNum2 = 0;
|
|
for ( card2 = cardList; card2 != card; card2 = card2->MATLnextCard ) {
|
|
cardNum2++;
|
|
if (card2->MATLnumber == card->MATLnumber) {
|
|
sprintf( ebuf,
|
|
"material cards %d and %d use same id %d",
|
|
cardNum2, cardNum, card->MATLnumber );
|
|
SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );
|
|
error = E_PRIVATE;
|
|
}
|
|
}
|
|
|
|
/* Return now if anything has failed */
|
|
if (error) return(error);
|
|
}
|
|
return(OK);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Name: MATLsetup
|
|
* Purpose: setup the physical model parameters
|
|
* Formals: cardList: list of cards to setup
|
|
* Returns: OK/E_PRIVATE
|
|
* Users: numerical devices
|
|
* Calls: MATLcheck
|
|
*/
|
|
int
|
|
MATLsetup(MATLcard *cardList, MaterialInfo **materialList)
|
|
{
|
|
MATLcard *card;
|
|
MATLmaterial *newMaterial = NULL;
|
|
int error;
|
|
|
|
/* Initialize list of electrodes */
|
|
*materialList = NIL(MATLmaterial);
|
|
|
|
/* Check the card list */
|
|
if ((error = MATLcheck( cardList ))) return( error );
|
|
|
|
for ( card = cardList; card != NIL(MATLcard); card = card->MATLnextCard ) {
|
|
|
|
if (*materialList == NIL(MATLmaterial)) {
|
|
RALLOC( newMaterial, MATLmaterial, 1 );
|
|
*materialList = newMaterial;
|
|
}
|
|
else {
|
|
RALLOC( newMaterial->next, MATLmaterial, 1 );
|
|
newMaterial = newMaterial->next;
|
|
}
|
|
newMaterial->next = NIL(MATLmaterial);
|
|
newMaterial->id = card->MATLnumber;
|
|
newMaterial->material = card->MATLmaterial;
|
|
|
|
/* Fill in default values */
|
|
MATLdefaults( newMaterial );
|
|
|
|
/* Now override with parameters set on the card */
|
|
if ( card->MATLpermittivityGiven ) {
|
|
newMaterial->eps = card->MATLpermittivity;
|
|
/* Multiply by permittivity of free space if relative epsilon given. */
|
|
if (newMaterial->eps > 0.1) {
|
|
newMaterial->eps *= EPS0;
|
|
}
|
|
}
|
|
if ( card->MATLaffinityGiven ) {
|
|
newMaterial->affin = card->MATLaffinity;
|
|
}
|
|
if ( card->MATLnc0Given ) {
|
|
newMaterial->nc0 = card->MATLnc0;
|
|
}
|
|
if ( card->MATLnv0Given ) {
|
|
newMaterial->nv0 = card->MATLnv0;
|
|
}
|
|
if ( card->MATLeg0Given ) {
|
|
newMaterial->eg0 = card->MATLeg0;
|
|
}
|
|
if ( card->MATLdEgdTGiven ) {
|
|
newMaterial->dEgDt = card->MATLdEgdT;
|
|
}
|
|
if ( card->MATLtrefEgGiven ) {
|
|
newMaterial->trefBGN = card->MATLtrefEg;
|
|
}
|
|
if ( card->MATLdEgdNGiven ) {
|
|
newMaterial->dEgDn[ELEC] = card->MATLdEgdN;
|
|
}
|
|
if ( card->MATLnrefEgGiven ) {
|
|
newMaterial->nrefBGN[ELEC] = card->MATLnrefEg;
|
|
}
|
|
if ( card->MATLdEgdPGiven ) {
|
|
newMaterial->dEgDn[HOLE] = card->MATLdEgdP;
|
|
}
|
|
if ( card->MATLprefEgGiven ) {
|
|
newMaterial->nrefBGN[HOLE] = card->MATLprefEg;
|
|
}
|
|
if ( card->MATLtaup0Given ) {
|
|
newMaterial->tau0[HOLE] = card->MATLtaup0;
|
|
}
|
|
if ( card->MATLtaun0Given ) {
|
|
newMaterial->tau0[ELEC] = card->MATLtaun0;
|
|
}
|
|
if ( card->MATLtaup0Given ) {
|
|
newMaterial->tau0[HOLE] = card->MATLtaup0;
|
|
}
|
|
if ( card->MATLnrefSRHnGiven ) {
|
|
newMaterial->nrefSRH[ELEC] = card->MATLnrefSRHn;
|
|
}
|
|
if ( card->MATLnrefSRHpGiven ) {
|
|
newMaterial->nrefSRH[HOLE] = card->MATLnrefSRHp;
|
|
}
|
|
if ( card->MATLcnAugGiven ) {
|
|
newMaterial->cAug[ELEC] = card->MATLcnAug;
|
|
}
|
|
if ( card->MATLcpAugGiven ) {
|
|
newMaterial->cAug[HOLE] = card->MATLcpAug;
|
|
}
|
|
if ( card->MATLaRichNGiven ) {
|
|
newMaterial->aRich[ELEC] = card->MATLaRichN;
|
|
}
|
|
if ( card->MATLaRichPGiven ) {
|
|
newMaterial->aRich[HOLE] = card->MATLaRichP;
|
|
}
|
|
|
|
}
|
|
return( OK );
|
|
}
|