180 lines
5.2 KiB
C
180 lines
5.2 KiB
C
/**********
|
|
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
|
|
**********/
|
|
|
|
#include "ngspice/ngspice.h"
|
|
#include "ngspice/cktdefs.h"
|
|
#include "ngspice/bdrydefs.h"
|
|
#include "ngspice/meshext.h"
|
|
#include "ngspice/gendev.h"
|
|
#include "ngspice/sperror.h"
|
|
|
|
extern int BDRYcheck( BDRYcard *, DOMNdomain * );
|
|
extern int BDRYsetup( BDRYcard *, MESHcoord *, MESHcoord *, DOMNdomain * );
|
|
|
|
|
|
/*
|
|
* Name: BDRYcheck
|
|
* Purpose: checks a list of BDRYcards for input errors
|
|
* Formals: cardList: the list to check
|
|
* Returns: OK/E_PRIVATE
|
|
* Users: numerical device setup routines
|
|
* Calls: error message handler
|
|
*/
|
|
int
|
|
BDRYcheck(BDRYcard *cardList, DOMNdomain *domnList)
|
|
{
|
|
BDRYcard *card;
|
|
DOMNdomain *domn;
|
|
int cardNum = 0;
|
|
int error = OK;
|
|
|
|
for ( card = cardList; card != NULL; card = card->BDRYnextCard ) {
|
|
cardNum++;
|
|
if (card->BDRYxLowGiven && card->BDRYixLowGiven) {
|
|
SPfrontEnd->IFerrorf( ERR_INFO, "boundary card %d uses both location and index - location ignored", cardNum );
|
|
card->BDRYxLowGiven = FALSE;
|
|
}
|
|
if (card->BDRYxHighGiven && card->BDRYixHighGiven) {
|
|
SPfrontEnd->IFerrorf( ERR_INFO, "boundary card %d uses both location and index - location ignored", cardNum );
|
|
card->BDRYxHighGiven = FALSE;
|
|
}
|
|
if (card->BDRYyLowGiven && card->BDRYiyLowGiven) {
|
|
SPfrontEnd->IFerrorf( ERR_INFO, "boundary card %d uses both location and index - location ignored", cardNum );
|
|
card->BDRYyLowGiven = FALSE;
|
|
}
|
|
if (card->BDRYyHighGiven && card->BDRYiyHighGiven) {
|
|
SPfrontEnd->IFerrorf( ERR_INFO, "boundary card %d uses both location and index - location ignored", cardNum );
|
|
card->BDRYyHighGiven = FALSE;
|
|
}
|
|
if (!card->BDRYdomainGiven) {
|
|
SPfrontEnd->IFerrorf( ERR_WARNING, "boundary card %d is missing a domain index", cardNum );
|
|
error = E_PRIVATE;
|
|
} else {
|
|
/* Make sure the domain exists */
|
|
for ( domn = domnList; domn != NULL; domn = domn->next ) {
|
|
if ( card->BDRYdomain == domn->id ) {
|
|
break;
|
|
}
|
|
}
|
|
if (domn == NULL) {
|
|
SPfrontEnd->IFerrorf( ERR_WARNING, "boundary card %d specifies a non-existent domain", cardNum );
|
|
error = E_PRIVATE;
|
|
}
|
|
}
|
|
|
|
if (!card->BDRYneighborGiven) {
|
|
card->BDRYneighbor = card->BDRYdomain;
|
|
} else {
|
|
/* Make sure the neighbor exists */
|
|
for ( domn = domnList; domn != NULL; domn = domn->next ) {
|
|
if ( card->BDRYneighbor == domn->id ) {
|
|
break;
|
|
}
|
|
}
|
|
if (domn == NULL) {
|
|
SPfrontEnd->IFerrorf( ERR_WARNING, "interface card %d specifies a non-existent domain", cardNum );
|
|
error = E_PRIVATE;
|
|
}
|
|
}
|
|
|
|
if (!card->BDRYqfGiven) {
|
|
card->BDRYqf = 0.0;
|
|
}
|
|
if (!card->BDRYsnGiven) {
|
|
card->BDRYsn = 0.0;
|
|
}
|
|
if (!card->BDRYspGiven) {
|
|
card->BDRYsp = 0.0;
|
|
}
|
|
if (!card->BDRYlayerGiven) {
|
|
card->BDRYlayer = 0.0;
|
|
}
|
|
|
|
/* Return now if anything has failed */
|
|
if (error) return(error);
|
|
}
|
|
return(OK);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Name: BDRYsetup
|
|
* Purpose: Checks BDRY cards and then sets the indices
|
|
* Formals: cardList: list of cards to setup, returns with indices set
|
|
* xMeshList: list of coordinates in the x mesh
|
|
* yMeshList: list of coordinates in the y mesh
|
|
* Returns: OK/E_PRIVATE
|
|
* Users: numerical devices
|
|
* Calls: BDRYcheck
|
|
*/
|
|
int
|
|
BDRYsetup(BDRYcard *cardList, MESHcoord *xMeshList, MESHcoord *yMeshList,DOMNdomain *domnList)
|
|
{
|
|
BDRYcard *card;
|
|
int ixMin, ixMax, iyMin, iyMax;
|
|
int cardNum = 0;
|
|
int error;
|
|
|
|
/* Check the card list */
|
|
if ((error = BDRYcheck( cardList, domnList )) != 0) return( error );
|
|
|
|
/* Find the limits on the indices */
|
|
MESHiBounds( xMeshList, &ixMin, &ixMax );
|
|
MESHiBounds( yMeshList, &iyMin, &iyMax );
|
|
|
|
error = OK;
|
|
for ( card = cardList; card != NULL; card = card->BDRYnextCard ) {
|
|
cardNum++;
|
|
|
|
if (card->BDRYixLowGiven) {
|
|
card->BDRYixLow = MAX(card->BDRYixLow, ixMin);
|
|
}
|
|
else if (card->BDRYxLowGiven) {
|
|
card->BDRYixLow = MESHlocate( xMeshList, card->BDRYxLow );
|
|
}
|
|
else {
|
|
card->BDRYixLow = ixMin;
|
|
}
|
|
if (card->BDRYixHighGiven) {
|
|
card->BDRYixHigh = MIN(card->BDRYixHigh, ixMax);
|
|
}
|
|
else if (card->BDRYxHighGiven) {
|
|
card->BDRYixHigh = MESHlocate( xMeshList, card->BDRYxHigh );
|
|
}
|
|
else {
|
|
card->BDRYixHigh = ixMax;
|
|
}
|
|
if (card->BDRYixLow > card->BDRYixHigh) {
|
|
SPfrontEnd->IFerrorf( ERR_WARNING, "boundary card %d has low x index (%d) > high x index (%d)", cardNum, card->BDRYixHigh, card->BDRYixLow );
|
|
error = E_PRIVATE;
|
|
}
|
|
if (card->BDRYiyLowGiven) {
|
|
card->BDRYiyLow = MAX(card->BDRYiyLow, iyMin);
|
|
}
|
|
else if (card->BDRYyLowGiven) {
|
|
card->BDRYiyLow = MESHlocate( yMeshList, card->BDRYyLow );
|
|
}
|
|
else {
|
|
card->BDRYiyLow = iyMin;
|
|
}
|
|
if (card->BDRYiyHighGiven) {
|
|
card->BDRYiyHigh = MIN(card->BDRYiyHigh, iyMax);
|
|
}
|
|
else if (card->BDRYyHighGiven) {
|
|
card->BDRYiyHigh = MESHlocate( yMeshList, card->BDRYyHigh );
|
|
}
|
|
else {
|
|
card->BDRYiyHigh = iyMax;
|
|
}
|
|
if (card->BDRYiyLow > card->BDRYiyHigh) {
|
|
SPfrontEnd->IFerrorf( ERR_WARNING, "boundary card %d has low y index (%d) > high y index (%d)", cardNum, card->BDRYiyHigh, card->BDRYiyLow );
|
|
error = E_PRIVATE;
|
|
}
|
|
}
|
|
return( error );
|
|
}
|