/* branch.h  94.12.09
 * Copyright 1983-1992   Albert Davis
 * branch structure type definitions
 * device types (enumeration type?)
 */
#include "probh.h"	/* BUG: I don't like this */

#define BRANCH_H
#define NODESPERBRANCH	4
#define OUT1	0
#define OUT2	1
#define	IN1	2
#define	IN2	3
#define INVALIDNODE	-1
#define BRANCHCURRENT	-2

/* values for refnode, devclass.
 * either the node to which voltages are referenced or: */
#define rnONEPORT	-1	/* 2 nodes, 1 floating port,  no gnd ref */
#define rnTWOPORT	-2	/* 4 nodes, 2 floating ports, no gnd ref */
#define rnALL		-3	/* check all possible combinations */
#define rnLINEAR	-4	/* a linear device, always bypass */
#define rnGROUND	-5	/* reference to ground only */
#define rnCOMP		-6	/* companion elements, bypass tracks parent */
#define rnSOURCE	-7	/* a source: right side only, ac special */
#define rnNISOURCE	-8	/* non-ideal source, ONEPORT but ac special */
#define rnMODEL		-9	/* a model, always bypass */
#define	rnTEXT		-10	/* a non-circuit line, always bypass */
#define rnLOCAL		-11	/* device handles its own bypass */

typedef struct generic {
   struct generic *x;
   size_t  ssize;
   const struct generic *m;
   char    modelname[LABELEN+1];
   char	   args[1];	/* a fudge.  sizeof() >= 1		*/
} generic_t;

typedef struct {
   int m;		/* mapped, after reordering		*/
   int t;		/* m == nm[t] if properly set up	*/
   int e;		/* external, user numbers, t = subs exp	*/
   double v;		/* voltage ref for bypass check		*/
} node_t;

typedef struct branch {
   generic_t *x;		 /* extra stuff			*/
   size_t	 ssize;
   const struct functions *f;
   struct branch *next;		 /* linked list stuff		*/
   struct branch *prev;
   struct branch *stnext;	 /* list of same type		*/
   struct branch *stprev;
   struct branch *subckt;	 /* subckt expansion		*/
   struct branch *parent;
   char     label[LABELEN+1];	 /**** up to here initialized ***/
   node_t   *n;
   node_t   nodes[NODESPERBRANCH+1]; /* nodes (0,1:out, 2,3:in)	*/
   double   val;	/* value, for simple parts		*/
   double   ic;		/* initial condition			*/
   char     outputlabel[LABELEN+1];
   struct branch *output;
   char     inputlabel[LABELEN+1];
   struct branch *input;
   unsigned bypass:1,	/* is bypassing now			*/
   	  tracesubckt:1,/* trace subckt fanout			*/
	    nodamp:1,	/* don't apply iteration damping	*/
  	    converged:1;/* convergence status			*/
   int	    method_a;	/* actual integration method (auto)	*/
   int      method_u;	/* method to use for this part per user	*/
   int      loaditer;	/* load iteration number		*/
   int      evaliter;	/* model eval iteration number		*/
   double   time0;	/* time now (y[012], m[01])		*/
   double   time1;	/* one tick ago	 (mt1, yt1)		*/
   double   time2;	/* two tick ago	 (mt2, yt2)		*/
   double   time3;	/* two tick ago	 (mt3. yt3)		*/
   double   timef;	/* future event time			*/
   fpoly1_t y0;		/* iteration parameters, new		*/
   fpoly1_t yt1;	/* iteration parameters, 1 time ago	*/
   fpoly1_t yt2;	/* iteration parameters, 2 times ago	*/
   fpoly1_t yt3;	/* iteration parameters, 3 times ago	*/
   fpoly1_t y1;		/* iteration parameters, 1 iter ago	*/
   fpoly1_t y2;		/* iteration parameters, 2 iter ago	*/
   cpoly1_t m0;		/* matrix parameters, new		*/
   cpoly1_t m1;		/* matrix parameters, 1 fill ago	*/
   cpoly1_t mt1;	/* matrix parameters, 1 time ago	*/

   complex_t  ev;	/* ac effective value (usually real)	*/
   complex_t  acg;	/* ac admittance matrix values		*/   
   double   acbias;	/* dc bias for ac use			*/
} branch_t;

typedef struct functions {
     generic_t	*x;		/* extra stuff prototype	*/
     size_t	ssize;		/* self size			*/
     size_t	elementsize;	/* size of std element		*/
     struct functions *super;	/* type to revert to on parse	*/
     int	numnodes;	/* number of nodes (for parse)	*/
     int	refnode;	/* ref nodes etc for bypass chk	*/
     int	devclass;	/* is device or special device	*/
     branch_t*	(*create)(const struct functions*);
     branch_t*	(*copy)(const branch_t*);
     void	(*parse)(branch_t*,const char*,int*);
     void	(*print)(const branch_t*,int,int);
     void	(*expand)(branch_t*);
     double	(*probe)(const branch_t*,const char*);
     double	(*tr_probe)(const branch_t*,const char*);
     double	(*ac_probe)(const branch_t*,const char*);
     xprobe_t	(*xprobe)(const branch_t*,const char*);
     int	(*dotr)(branch_t*);
     void	(*untr)(branch_t*);
     void	(*doac)(branch_t*);
     void	(*trfun1)(branch_t*);
     void	(*trfun0)(branch_t*);
     complex_t	(*acfun)(branch_t*);
     void	(*tr_guess)(branch_t*);
     void	(*tr_advance)(branch_t*);
     double	(*tr_review)(branch_t*);
} functions_t;

#define isdevice(c)	(exists(c) && ((c)->f->devclass))
#define exists(c)	((c) && ((c)->f))
