ngspice/src/spicelib/devices/asrc/asrcset.c

166 lines
6.1 KiB
C

/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Kanwar Jit Singh
**********/
/*
* singh@ic.Berkeley.edu
*/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "asrcdefs.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
/*ARGSUSED*/
int
ASRCsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
/* load the voltage source structure with those
* pointers needed later for fast matrix loading
*/
{
ASRCinstance *here;
ASRCmodel *model = (ASRCmodel*) inModel;
int error, i, j;
int v_first;
CKTnode *tmp;
NG_IGNORE(states);
/* loop through all the user models*/
for (; model != NULL; model = model->ASRCnextModel) {
/* loop through all the instances of the model */
for (here = model->ASRCinstances; here != NULL;
here=here->ASRCnextInstance) {
if (!here->ASRCtc1Given) here->ASRCtc1 = 0.0;
if (!here->ASRCtc2Given) here->ASRCtc2 = 0.0;
if (!here->ASRCreciproctcGiven) here->ASRCreciproctc = 0;
here->ASRCposptr = NULL;
j = 0; /* strchr of the array holding ptrs to SMP */
v_first = 1;
if (here->ASRCtype == ASRC_VOLTAGE) {
if (here->ASRCbranch == 0) {
error = CKTmkCur(ckt, &tmp, here->ASRCname, "branch");
if (error) return(error);
here->ASRCbranch = tmp->number;
}
}
/* macro to make elements with built in test for out of memory */
#define TSTALLOC(ptr, first, second) \
do { if ((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL) { \
return(E_NOMEM); \
} } while(0)
#define MY_TSTALLOC(ptr, first, second) \
do { if ((here->ptr = SMPmakeElt(matrix, here->first, (second)->number)) == NULL) { \
return(E_NOMEM); \
} } while(0)
/* For each controlling variable set the entries
in the vector of the positions of the SMP */
if (!here->ASRCtree)
return E_PARMVAL;
if (here->ASRCtype == ASRC_VOLTAGE) {
if (here->ASRCposNode == here->ASRCnegNode) {
SPfrontEnd->IFerrorf(ERR_FATAL,
"instance %s is a shorted ASRC", here->ASRCname);
return(E_UNSUPP);
}
here->ASRCposptr = TREALLOC(double *, here->ASRCposptr, j + 5);
TSTALLOC(ASRCposptr[j++], ASRCposNode, ASRCbranch);
TSTALLOC(ASRCposptr[j++], ASRCnegNode, ASRCbranch);
TSTALLOC(ASRCposptr[j++], ASRCbranch, ASRCnegNode);
TSTALLOC(ASRCposptr[j++], ASRCbranch, ASRCposNode);
}
for (i = 0; i < here->ASRCtree->numVars; i++) {
switch (here->ASRCtree->varTypes[i]) {
case IF_INSTANCE:
here->ASRCcont_br = CKTfndBranch(ckt,
here->ASRCtree->vars[i].uValue);
if (here->ASRCcont_br == 0) {
SPfrontEnd->IFerrorf (ERR_FATAL,
"%s: unknown controlling source %s", here->ASRCname, here->ASRCtree->vars[i].uValue);
return(E_BADPARM);
}
if (here->ASRCtype == ASRC_VOLTAGE) {
/* CCVS */
if (v_first) {
TSTALLOC(ASRCposptr[j++], ASRCbranch, ASRCcont_br);
v_first = 0;
} else {
here->ASRCposptr = TREALLOC(double *, here->ASRCposptr, j + 1);
TSTALLOC(ASRCposptr[j++], ASRCbranch, ASRCcont_br);
}
} else if (here->ASRCtype == ASRC_CURRENT) {
/* CCCS */
here->ASRCposptr = TREALLOC(double *, here->ASRCposptr, j + 2);
TSTALLOC(ASRCposptr[j++], ASRCposNode, ASRCcont_br);
TSTALLOC(ASRCposptr[j++], ASRCnegNode, ASRCcont_br);
} else {
return (E_BADPARM);
}
break;
case IF_NODE:
if (here->ASRCtype == ASRC_VOLTAGE) {
/* VCVS */
if (v_first) {
MY_TSTALLOC(ASRCposptr[j++], ASRCbranch, here->ASRCtree->vars[i].nValue);
v_first = 0;
} else {
here->ASRCposptr = TREALLOC(double *, here->ASRCposptr, j + 1);
MY_TSTALLOC(ASRCposptr[j++], ASRCbranch, here->ASRCtree->vars[i].nValue);
}
} else if (here->ASRCtype == ASRC_CURRENT) {
/* VCCS */
here->ASRCposptr = TREALLOC(double *, here->ASRCposptr, j + 2);
MY_TSTALLOC(ASRCposptr[j++], ASRCposNode, here->ASRCtree->vars[i].nValue);
MY_TSTALLOC(ASRCposptr[j++], ASRCnegNode, here->ASRCtree->vars[i].nValue);
} else {
return (E_BADPARM);
}
break;
default:
break;
}
}
}
}
return(OK);
}
int
ASRCunsetup(
GENmodel *inModel,
CKTcircuit *ckt)
{
ASRCmodel *model;
ASRCinstance *here;
for (model = (ASRCmodel *) inModel; model != NULL;
model = model->ASRCnextModel)
{
for (here = model->ASRCinstances; here != NULL;
here = here->ASRCnextInstance)
{
if (here->ASRCbranch) {
CKTdltNNum(ckt, here->ASRCbranch);
here->ASRCbranch = 0;
}
}
}
return OK;
}