/* tr_z.c  93.12.21
 * Copyright 1983-1992   Albert Davis
 * impedance looking across two nodes
 */
#include "ecah.h"
#include "branch.h"
#include "error.h"
#include "nodestat.h"
#include "status.h"
#include "declare.h"
/*--------------------------------------------------------------------------*/
	double	trz(node_t,node_t,double);
/*--------------------------------------------------------------------------*/
extern const struct status stats;
extern       struct nodestuff ns;
extern const char e_om[];
/*--------------------------------------------------------------------------*/
/* trz: impedance looking across two nodes
 */
/*ARGSUSED*/
double trz(node_t n1, node_t n2, double parallel)
{
 static double *zapit;
 static unsigned gotsize;
 unsigned newsize;
 double *voltages;	/* save right side vector */
 double *rightside;
 double raw_z;

 newsize = ((unsigned)stats.total_nodes+2) * sizeof(double);
 if (!zapit){
    zapit = (double*)calloc(newsize,1);		/* alloc memory */
    gotsize = newsize;
 }else if (newsize > gotsize){
    zapit = (double*)realloc((void*)zapit,newsize);
    gotsize = newsize;
 }
 if (!zapit)
    error(bERROR, e_om, "trz");

 rightside = ns.i;			/* stash real voltages */
 voltages = ns.v0;
 ns.v0 = ns.i = zapit;

 (void)memset((void*)ns.i,0,newsize);
 if (n1.m != 0)				/* build new rt side */
    ns.i[n1.m] =  1.;			/* 1 amp current source */
 if (n2.m != 0)
    ns.i[n2.m] = -1.;

 solve();				/* solve for volts */
 raw_z = tr_volts(&n1,&n2);		/* volts is impedance */
 
 ns.v0 = voltages;			/* restore real stuff */
 ns.i = rightside;
 return  (parallel != 0.)
    ? 1. / ((1./raw_z)-parallel)
    : raw_z;
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
