You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

139 lines
3.9 KiB

/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Kanwar Jit Singh
**********/
/*
* singh@ic.Berkeley.edu
*/
#include "ngspice.h"
#include "cktdefs.h"
#include "asrcdefs.h"
#include "sperror.h"
#include "suffix.h"
double *asrc_vals, *asrc_derivs;
int asrc_nvals;
/*ARGSUSED*/
int
ASRCload(GENmodel *inModel, CKTcircuit *ckt)
{
/* actually load the current voltage value into the
* sparse matrix previously provided
*/
ASRCmodel *model = (ASRCmodel*) inModel;
ASRCinstance *here;
int i, j;
double rhs;
/* loop through all the Arbitrary source 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->ASRCowner != ARCHme)
continue;
/*
* Get the function and its derivatives evaluated
*/
i = here->ASRCtree->numVars;
if (asrc_nvals < i) {
if (asrc_nvals) {
FREE(asrc_vals);
FREE(asrc_derivs);
}
asrc_nvals = i;
asrc_vals = NEWN(double, i);
asrc_derivs = NEWN(double, i);
}
j=0;
/*
* Fill the vector of values from the previous solution
*/
for( i=0; i < here->ASRCtree->numVars; i++)
if( here->ASRCtree->varTypes[i] == IF_INSTANCE) {
int branch = CKTfndBranch(ckt, here->ASRCtree->vars[i].uValue);
asrc_vals[i] = *(ckt->CKTrhsOld + branch);
} else {
int node_num = (here->ASRCtree->vars[i].nValue) -> number;
asrc_vals[i] = *(ckt->CKTrhsOld + node_num);
}
if ((*(here->ASRCtree->IFeval))(here->ASRCtree,ckt->CKTgmin, &rhs, asrc_vals,asrc_derivs) != OK)
return(E_BADPARM);
/* The convergence test */
here->ASRCprev_value = rhs;
/* The ac load precomputation and storage */
if (ckt->CKTmode & MODEINITSMSIG) {
int size = (here->ASRCtree->numVars) + 1 ;
here->ASRCacValues = NEWN(double, size);
for ( i = 0; i < here->ASRCtree->numVars; i++)
here->ASRCacValues[i] = asrc_derivs[i];
}
if( here->ASRCtype == ASRC_VOLTAGE) {
*(here->ASRCposptr[j++]) += 1.0;
*(here->ASRCposptr[j++]) -= 1.0;
*(here->ASRCposptr[j++]) -= 1.0;
*(here->ASRCposptr[j++]) += 1.0;
}
for(i=0; i < here->ASRCtree->numVars; i++) {
rhs -= (asrc_vals[i] * asrc_derivs[i]);
switch(here->ASRCtree->varTypes[i]) {
case IF_INSTANCE:
if( here->ASRCtype == ASRC_VOLTAGE) {
/* CCVS */
*(here->ASRCposptr[j++]) -= asrc_derivs[i];
} else{
/* CCCS */
*(here->ASRCposptr[j++]) += asrc_derivs[i];
*(here->ASRCposptr[j++]) -= asrc_derivs[i];
}
break;
case IF_NODE:
if(here->ASRCtype == ASRC_VOLTAGE) {
/* VCVS */
*(here->ASRCposptr[j++]) -= asrc_derivs[i];
} else {
/*VCCS*/
*(here->ASRCposptr[j++]) += asrc_derivs[i];
*(here->ASRCposptr[j++]) -= asrc_derivs[i];
}
break;
default:
return(E_BADPARM);
}
}
/* Insert the RHS */
if( here->ASRCtype == ASRC_VOLTAGE) {
*(ckt->CKTrhs+(here->ASRCbranch)) += rhs;
} else {
*(ckt->CKTrhs+(here->ASRCposNode)) -= rhs;
*(ckt->CKTrhs+(here->ASRCnegNode)) += rhs;
}
/* Store the rhs for small signal analysis */
if (ckt->CKTmode & MODEINITSMSIG) {
here->ASRCacValues[here->ASRCtree->numVars] = rhs;
}
}
}
return(OK);
}