📄 nummset.c
字号:
/**********Copyright 1991 Regents of the University of California. All rights reserved.Author: 1987 Kartikeya Mayaram, U. C. Berkeley CAD Group**********/#include "spice.h"#include <stdio.h>#include "util.h"#include "strext.h"#include "cktdefs.h"#include "smpdefs.h"#include "numosdef.h"#include "numconst.h"#include "numenum.h"#include "meshext.h"#include "sperror.h"#include "suffix.h"#define NIL(type) ((type *)0)#define ALLOC(var, size, type)\if (size && (!(var =(type *)calloc(1, (unsigned)(size)*sizeof(type))))) {\ return(E_NOMEM);\}intNUMOSsetup(matrix, inModel, ckt, states) register SMPmatrix *matrix; GENmodel *inModel; CKTcircuit *ckt; int *states;/* * load the structure with those pointers needed later for fast matrix * loading */{ register NUMOSmodel *model = (NUMOSmodel *) inModel; register NUMOSinstance *inst; METHcard *methods; MODLcard *models; OPTNcard *options; OUTPcard *outputs; char *icFileName; int nameLen; int error, xIndex, yIndex; int xMeshSize, yMeshSize; TWOdevice *pDevice; TWOcoord *xCoordList = NIL(TWOcoord); TWOcoord *yCoordList = NIL(TWOcoord); TWOdomain *domainList = NIL(TWOdomain); TWOelectrode *electrodeList = NIL(TWOelectrode); TWOmaterial *pM, *pMaterial, *materialList = NIL(TWOmaterial); DOPprofile *profileList = NIL(DOPprofile); DOPtable *dopTableList = NIL(DOPtable); double startTime; void printCoordInfo(), killCoordInfo(); void TWOprintDomainInfo(), killDomainInfo(); void TWOprintElectrodeInfo(), killElectrodeInfo(); void TWObuildMesh(), TWOgetStatePointers(); void checkElectrodes(); /* loop through all the models */ for (; model != NULL; model = model->NUMOSnextModel) { if (!model->NUMOSpInfo) { ALLOC(model->NUMOSpInfo, 1, TWOtranInfo); } methods = model->NUMOSmethods; if (!methods) { ALLOC(methods, 1, METHcard); model->NUMOSmethods = methods; } models = model->NUMOSmodels; if (!models) { ALLOC(models, 1, MODLcard); model->NUMOSmodels = models; } options = model->NUMOSoptions; if (!options) { ALLOC(options, 1, OPTNcard); model->NUMOSoptions = options; } outputs = model->NUMOSoutputs; if (!outputs) { ALLOC(outputs, 1, OUTPcard); model->NUMOSoutputs = outputs; } if (!methods->METHvoltPredGiven) { methods->METHvoltPred = FALSE; } if (!methods->METHmobDerivGiven) { methods->METHmobDeriv = TRUE; } if (!methods->METHoneCarrierGiven) { methods->METHoneCarrier = FALSE; } if (!methods->METHacAnalysisMethodGiven) { methods->METHacAnalysisMethod = SOR; } if (!methods->METHdabstolGiven) { methods->METHdabstol = DABSTOL2D; } if (!methods->METHdreltolGiven) { methods->METHdreltol = ckt->CKTreltol; } if (!methods->METHitLimGiven) { methods->METHitLim = 50; } if (!methods->METHomegaGiven || methods->METHomega <= 0.0) { methods->METHomega = 2.0 * M_PI /* radians/sec */ ; } if (!options->OPTNdefaGiven || options->OPTNdefa <= 0.0) { options->OPTNdefa = 1.0e4 /* cm^2 */ ; } if (!options->OPTNdeflGiven || options->OPTNdefl <= 0.0) { options->OPTNdefl = 1.0e2 /* cm */ ; } if (!options->OPTNdefwGiven && options->OPTNdefaGiven) { options->OPTNdefw = options->OPTNdefa / options->OPTNdefl; } else if (!options->OPTNdefwGiven || options->OPTNdefw <= 0.0) { options->OPTNdefw = 1.0e2 /* cm */ ; } if (!options->OPTNdeviceTypeGiven) { options->OPTNdeviceType = OPTN_MOSFET; } if (!options->OPTNicFileGiven) { options->OPTNicFile = NULL; options->OPTNunique = FALSE; /* Can't form a unique name. */ } if (!options->OPTNuniqueGiven) { options->OPTNunique = FALSE; } OneCarrier = methods->METHoneCarrier; /* Set up the rest of the card lists */ if (error = MODLsetup(model->NUMOSmodels)) return (error); BandGapNarrowing = models->MODLbandGapNarrowing; ConcDepLifetime = models->MODLconcDepLifetime; TempDepMobility = models->MODLtempDepMobility; ConcDepMobility = models->MODLconcDepMobility; SurfaceMobility = models->MODLsurfaceMobility; if (error = OUTPsetup(model->NUMOSoutputs)) return (error); if (error = MATLsetup(model->NUMOSmaterials, &materialList)) return (error); if (error = MOBsetup(model->NUMOSmobility, materialList)) return (error); if (error = MESHsetup('x', model->NUMOSxMeshes, &xCoordList, &xMeshSize)) return (error); if (error = MESHsetup('y', model->NUMOSyMeshes, &yCoordList, &yMeshSize)) return (error); if (error = DOMNsetup(model->NUMOSdomains, &domainList, xCoordList, yCoordList, materialList)) return (error); if (error = BDRYsetup(model->NUMOSboundaries, xCoordList, yCoordList, domainList)) return (error); if (error = ELCTsetup(model->NUMOSelectrodes, &electrodeList, xCoordList, yCoordList)) return (error); /* Make sure electrodes are OK. */ checkElectrodes(electrodeList, 4); /* NUMOS has 4 electrodes */ if (error = CONTsetup(model->NUMOScontacts, electrodeList)) return (error); if (error = DOPsetup(model->NUMOSdopings, &profileList, &dopTableList, xCoordList, yCoordList)) return (error); model->NUMOSmatlInfo = materialList; model->NUMOSprofiles = profileList; model->NUMOSdopTables = dopTableList; /* loop through all the instances of the model */ for (inst = model->NUMOSinstances; inst != NULL; inst = inst->NUMOSnextInstance) { if (inst->NUMOSowner != ARCHme) goto matrixpointers; startTime = SPfrontEnd->IFseconds(); if (!inst->NUMOSprintGiven) { inst->NUMOSprint = 0; } else if (inst->NUMOSprint <= 0) { inst->NUMOSprint = 1; } if (!inst->NUMOSicFileGiven) { if (options->OPTNunique) { nameLen = strlen(options->OPTNicFile) + strlen(inst->NUMOSname) + 1; ALLOC(icFileName, nameLen+1, char); sprintf(icFileName, "%s.%s", options->OPTNicFile, inst->NUMOSname); icFileName[nameLen] = '\0'; inst->NUMOSicFile = icFileName; } else if (options->OPTNicFile != NULL) { nameLen = strlen(options->OPTNicFile); ALLOC(icFileName, nameLen+1, char); icFileName = strcpy(icFileName, options->OPTNicFile); inst->NUMOSicFile = icFileName; } else { inst->NUMOSicFile = NULL; } } inst->NUMOSstate = *states; *states += NUMOSnumStates; if (!inst->NUMOSpDevice) { /* Assign the mesh info to each instance. */ ALLOC(pDevice, 1, TWOdevice); ALLOC(pDevice->pStats, 1, TWOstats); pDevice->name = inst->NUMOSname; pDevice->solverType = SLV_NONE; pDevice->numXNodes = xMeshSize; pDevice->numYNodes = yMeshSize; pDevice->xScale = MESHmkArray(xCoordList, xMeshSize); pDevice->yScale = MESHmkArray(yCoordList, yMeshSize); pDevice->abstol = methods->METHdabstol; pDevice->reltol = methods->METHdreltol; ALLOC(pDevice->elemArray, pDevice->numXNodes, TWOelem **); for (xIndex = 1; xIndex < pDevice->numXNodes; xIndex++) { ALLOC(pDevice->elemArray[xIndex], pDevice->numYNodes, TWOelem *); } /* Create a copy of material data that can change with temperature. */ pDevice->pMaterials = NIL(TWOmaterial); for (pM = materialList; pM != NIL(TWOmaterial); pM = pM->next) { if (pDevice->pMaterials == NIL(TWOmaterial)) { ALLOC(pMaterial, 1, TWOmaterial); pDevice->pMaterials = pMaterial; } else { ALLOC(pMaterial->next, 1, TWOmaterial); pMaterial = pMaterial->next; } /* Copy everything, then fix the incorrect pointer. */ bcopy((char *) pM, (char *) pMaterial, sizeof(TWOmaterial)); pMaterial->next = NIL(TWOmaterial); } /* Generate the mesh structure for the device. */ TWObuildMesh(pDevice, domainList, electrodeList, pDevice->pMaterials); /* Store the device info in the instance. */ inst->NUMOSpDevice = pDevice; } /* Now update the state pointers. */ TWOgetStatePointers(inst->NUMOSpDevice, states); /* Wipe out statistics from previous runs (if any). */ bzero((char *) inst->NUMOSpDevice->pStats, sizeof(TWOstats)); inst->NUMOSpDevice->pStats->totalTime[STAT_SETUP] += SPfrontEnd->IFseconds() - startTime; /* macro to make elements with built in test for out of memory */#define TSTALLOC(ptr,first,second) \if ((inst->ptr = SMPmakeElt(matrix,inst->first,inst->second))==(double *)NULL){\ return(E_NOMEM);\}matrixpointers: TSTALLOC(NUMOSdrainDrainPtr, NUMOSdrainNode, NUMOSdrainNode) TSTALLOC(NUMOSdrainSourcePtr, NUMOSdrainNode, NUMOSsourceNode) TSTALLOC(NUMOSdrainGatePtr, NUMOSdrainNode, NUMOSgateNode) TSTALLOC(NUMOSdrainBulkPtr, NUMOSdrainNode, NUMOSbulkNode) TSTALLOC(NUMOSsourceDrainPtr, NUMOSsourceNode, NUMOSdrainNode) TSTALLOC(NUMOSsourceSourcePtr, NUMOSsourceNode, NUMOSsourceNode) TSTALLOC(NUMOSsourceGatePtr, NUMOSsourceNode, NUMOSgateNode) TSTALLOC(NUMOSsourceBulkPtr, NUMOSsourceNode, NUMOSbulkNode) TSTALLOC(NUMOSgateDrainPtr, NUMOSgateNode, NUMOSdrainNode) TSTALLOC(NUMOSgateSourcePtr, NUMOSgateNode, NUMOSsourceNode) TSTALLOC(NUMOSgateGatePtr, NUMOSgateNode, NUMOSgateNode) TSTALLOC(NUMOSgateBulkPtr, NUMOSgateNode, NUMOSbulkNode) TSTALLOC(NUMOSbulkDrainPtr, NUMOSbulkNode, NUMOSdrainNode) TSTALLOC(NUMOSbulkSourcePtr, NUMOSbulkNode, NUMOSsourceNode) TSTALLOC(NUMOSbulkGatePtr, NUMOSbulkNode, NUMOSgateNode) TSTALLOC(NUMOSbulkBulkPtr, NUMOSbulkNode, NUMOSbulkNode) } /* Clean up lists */ killCoordInfo(xCoordList); killCoordInfo(yCoordList); killDomainInfo(domainList); killElectrodeInfo(electrodeList); } return (OK);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -