/* ac_z.c  93.12.19
 * Copyright 1983-1992   Albert Davis
 * impedance at a port
 */
#include "ecah.h"
#include "branch.h"
#include "error.h"
#include "nodestat.h"
#include "status.h"
#include "declare.h"
/*--------------------------------------------------------------------------*/
	complex_t	acz(node_t,node_t,complex_t);
/*--------------------------------------------------------------------------*/
extern const struct status stats;
extern       struct nodestuff ns;
extern const char e_om[];
/*--------------------------------------------------------------------------*/
complex_t acz(node_t n1, node_t n2, complex_t parallel)
{
 static double *rezap, *imzap;
 static unsigned gotsize;
 unsigned newsize;
 double *resave, *imsave;	    /* temporary storage: normal right side */
 complex_t raw_z;		    /* raw impedance (includes par branch)  */

 newsize = ((unsigned)stats.total_nodes+2) * sizeof(double);
 if (!rezap || !imzap){
    rezap = (double*)calloc(newsize,1);
    imzap = (double*)calloc(newsize,1);
    gotsize = newsize;
 }else if (newsize > gotsize){
    rezap = (double*)realloc((void*)rezap,newsize);
    imzap = (double*)realloc((void*)imzap,newsize);
    gotsize = newsize;
 }
 if (!rezap || !imzap)
    error(bERROR, e_om, "acz");
 
 resave = ns.acx;
 imsave = ns.acy;
 ns.acx = rezap;
 ns.acy = imzap;
 
 (void)memset((void*)ns.acx,0,newsize);
 (void)memset((void*)ns.acy,0,newsize);
 if (n1.m != 0)
    ns.acx[n1.m] =  1.;
 if (n2.m != 0)
    ns.acx[n2.m] = -1.;
 
 xsolve();
 raw_z.x = ns.acx[n1.m] - ns.acx[n2.m];
 raw_z.y = ns.acy[n1.m] - ns.acy[n2.m];
 
 ns.acx = resave;
 ns.acy = imsave;
 
 return (parallel.x != 0. || parallel.y != 0.)
    ? cflip(csub(cflip(raw_z),parallel))  /* 1 / ((1/raw_z)-parallel) */
    : raw_z;
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
