208 lines
5.8 KiB
C
208 lines
5.8 KiB
C
/**********
|
||
Copyright 1991 Regents of the University of California. All rights reserved.
|
||
Author: 1991 David A. Gates, U. C. Berkeley CAD Group
|
||
Modifed: 2001 Paolo Nenzi
|
||
**********/
|
||
|
||
#include "ngspice.h"
|
||
#include "cktdefs.h"
|
||
#include "numenum.h"
|
||
#include "domndefs.h"
|
||
#include "material.h"
|
||
#include "meshext.h"
|
||
#include "gendev.h"
|
||
#include "sperror.h"
|
||
#include "suffix.h"
|
||
|
||
|
||
extern int DOMNcheck( DOMNcard *, MATLmaterial * );
|
||
extern int DOMNsetup( DOMNcard *, DOMNdomain **, MESHcoord *, MESHcoord *,
|
||
MATLmaterial * );
|
||
|
||
|
||
/*
|
||
* Name: DOMNcheck
|
||
* Purpose: checks a list of DOMNcards for input errors
|
||
* Formals: cardList: the list to check
|
||
* Returns: OK/E_PRIVATE
|
||
* Users: numerical device setup routines
|
||
* Calls: error message handler
|
||
*/
|
||
int
|
||
DOMNcheck(DOMNcard *cardList, MaterialInfo *matlList)
|
||
{
|
||
DOMNcard *card;
|
||
MATLmaterial *matl;
|
||
int cardNum = 0;
|
||
int error = OK;
|
||
char ebuf[512]; /* error message buffer */
|
||
|
||
for ( card = cardList; card != NIL(DOMNcard); card = card->DOMNnextCard ) {
|
||
cardNum++;
|
||
if (card->DOMNxLowGiven && card->DOMNixLowGiven) {
|
||
sprintf( ebuf,
|
||
"domain card %d uses both location and index - location ignored",
|
||
cardNum );
|
||
SPfrontEnd->IFerror( ERR_INFO, ebuf, NIL(IFuid) );
|
||
card->DOMNxLowGiven = FALSE;
|
||
}
|
||
if (card->DOMNxHighGiven && card->DOMNixHighGiven) {
|
||
sprintf( ebuf,
|
||
"domain card %d uses both location and index - location ignored",
|
||
cardNum );
|
||
SPfrontEnd->IFerror( ERR_INFO, ebuf, NIL(IFuid) );
|
||
card->DOMNxHighGiven = FALSE;
|
||
}
|
||
if (card->DOMNyLowGiven && card->DOMNiyLowGiven) {
|
||
sprintf( ebuf,
|
||
"domain card %d uses both location and index - location ignored",
|
||
cardNum );
|
||
SPfrontEnd->IFerror( ERR_INFO, ebuf, NIL(IFuid) );
|
||
card->DOMNyLowGiven = FALSE;
|
||
}
|
||
if (card->DOMNyHighGiven && card->DOMNiyHighGiven) {
|
||
sprintf( ebuf,
|
||
"domain card %d uses both location and index - location ignored",
|
||
cardNum );
|
||
SPfrontEnd->IFerror( ERR_INFO, ebuf, NIL(IFuid) );
|
||
card->DOMNyHighGiven = FALSE;
|
||
}
|
||
if (!card->DOMNmaterialGiven) {
|
||
sprintf( ebuf,
|
||
"domain card %d is missing a material index",
|
||
cardNum );
|
||
SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );
|
||
error = E_PRIVATE;
|
||
} else {
|
||
/* Make sure the material exists */
|
||
for ( matl = matlList; matl != NIL(MATLmaterial); matl = matl->next ) {
|
||
if ( card->DOMNmaterial == matl->id ) {
|
||
break;
|
||
}
|
||
}
|
||
if (matl == NIL(MATLmaterial)) {
|
||
sprintf( ebuf,
|
||
"domain card %d specifies a non-existent material",
|
||
cardNum );
|
||
SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );
|
||
error = E_PRIVATE;
|
||
}
|
||
}
|
||
if (!card->DOMNnumberGiven) {
|
||
sprintf( ebuf,
|
||
"domain 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);
|
||
}
|
||
return(OK);
|
||
}
|
||
|
||
|
||
|
||
/*
|
||
* Name: DOMNsetup
|
||
* Purpose: convert a list of DOMNcard's to DOMNdomain's
|
||
* Formals: cardList: list of cards to setup
|
||
* domainList: returns the list of DOMNdomain's
|
||
* xMeshList: list of coordinates in the x mesh
|
||
* yMeshList: list of coordinates in the y mesh
|
||
* Returns: OK/E_PRIVATE
|
||
* Users: numerical devices
|
||
* Calls: DOMNcheck
|
||
*/
|
||
int
|
||
DOMNsetup(DOMNcard *cardList, DOMNdomain **domainList, MESHcoord *xMeshList,
|
||
MESHcoord *yMeshList, MaterialInfo *materialList)
|
||
{
|
||
DOMNcard *card;
|
||
DOMNdomain *newDomain = NULL;
|
||
int ixMin, ixMax, iyMin, iyMax;
|
||
int cardNum = 0;
|
||
int error;
|
||
char ebuf[512]; /* error message buffer */
|
||
|
||
/* Initialize list of domains */
|
||
*domainList = NIL(DOMNdomain);
|
||
|
||
/* Check the card list */
|
||
if ((error = DOMNcheck( cardList, materialList ))) return( error );
|
||
|
||
/* Find the limits on the indices */
|
||
MESHiBounds( xMeshList, &ixMin, &ixMax );
|
||
MESHiBounds( yMeshList, &iyMin, &iyMax );
|
||
|
||
error = OK;
|
||
for ( card = cardList; card != NIL(DOMNcard); card = card->DOMNnextCard ) {
|
||
cardNum++;
|
||
|
||
if (*domainList == NIL(DOMNdomain)) {
|
||
RALLOC( newDomain, DOMNdomain, 1 );
|
||
*domainList = newDomain;
|
||
} else {
|
||
RALLOC( newDomain->next, DOMNdomain, 1 );
|
||
newDomain = newDomain->next;
|
||
}
|
||
|
||
newDomain->id = card->DOMNnumber;
|
||
newDomain->material = card->DOMNmaterial;
|
||
newDomain->next = NIL(DOMNdomain);
|
||
|
||
if (card->DOMNixLowGiven) {
|
||
newDomain->ixLo = MAX(card->DOMNixLow, ixMin);
|
||
}
|
||
else if (card->DOMNxLowGiven) {
|
||
newDomain->ixLo = MESHlocate( xMeshList, card->DOMNxLow );
|
||
}
|
||
else {
|
||
newDomain->ixLo = ixMin;
|
||
}
|
||
if (card->DOMNixHighGiven) {
|
||
newDomain->ixHi = MIN(card->DOMNixHigh, ixMax);
|
||
}
|
||
else if (card->DOMNxHighGiven) {
|
||
newDomain->ixHi = MESHlocate( xMeshList, card->DOMNxHigh );
|
||
}
|
||
else {
|
||
newDomain->ixHi = ixMax;
|
||
}
|
||
if (newDomain->ixLo > newDomain->ixHi) {
|
||
sprintf( ebuf,
|
||
"domain card %d has low x index (%d) > high x index (%d)",
|
||
cardNum, newDomain->ixLo, newDomain->ixHi );
|
||
SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );
|
||
error = E_PRIVATE;
|
||
}
|
||
if (card->DOMNiyLowGiven) {
|
||
newDomain->iyLo = MAX(card->DOMNiyLow, iyMin);
|
||
}
|
||
else if (card->DOMNyLowGiven) {
|
||
newDomain->iyLo = MESHlocate( yMeshList, card->DOMNyLow );
|
||
}
|
||
else {
|
||
newDomain->iyLo = iyMin;
|
||
}
|
||
if (card->DOMNiyHighGiven) {
|
||
newDomain->iyHi = MIN(card->DOMNiyHigh, iyMax);
|
||
}
|
||
else if (card->DOMNyHighGiven) {
|
||
newDomain->iyHi = MESHlocate( yMeshList, card->DOMNyHigh );
|
||
}
|
||
else {
|
||
newDomain->iyHi = iyMax;
|
||
}
|
||
if (newDomain->iyLo > newDomain->iyHi) {
|
||
sprintf( ebuf,
|
||
"domain card %d has low y index (%d) > high y index (%d)",
|
||
cardNum, newDomain->iyLo, newDomain->iyHi );
|
||
SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );
|
||
error = E_PRIVATE;
|
||
}
|
||
}
|
||
return( error );
|
||
}
|