/* tr_load.c  94.10.14
 * Copyright 1983-1992   Albert Davis
 * Load matrix from pre-computed values
 */
#include "ecah.h"
#include "array.h"
#include "branch.h"
#include "error.h"
#include "mode.h"
#include "nodestat.h"
#include "options.h"
#include "status.h"
#include "declare.h"
/*--------------------------------------------------------------------------*/
	void	trloadsource(branch_t*);
	void	trloadpassive(branch_t*);
	void	trloadactive(branch_t*);
	void	trloadactivereverse(branch_t*);
	void	trloadmutual(branch_t*);
	void	unloadsource(branch_t*);
	void	unloadpassive(branch_t*);
	void	unloadactive(branch_t*);
	void	unloadactivereverse(branch_t*);
	void	unloadmutual(branch_t*);
/*--------------------------------------------------------------------------*/
extern const struct options opt;
extern 	     struct nodestat *nstat;
extern       struct status stats;
extern       struct nodestuff ns;
extern int inc_mode;		    /* make incremental changes		    */
/*--------------------------------------------------------------------------*/
#define  setneedslu(brh,x)  nstat[(brh)->n[x].m].needslu = YES
/*--------------------------------------------------------------------------*/
/* trloadsource: load source to right side vector
 */
void trloadsource(branch_t *brh)
{
 double dc0;
 if (brh->loaditer == stats.iter[iTOTAL])
    error(bDANGER, "%s: double load\n", printlabel(brh,0));
 brh->loaditer = stats.iter[iTOTAL];
 
 if (stats.iter[iSTEP] > 1  &&  !brh->nodamp){
    dc0 = opt.damp * (brh->m0.c0 - brh->m1.c0);
    brh->m0.c0 = brh->m1.c0 + dc0;
    if (!inc_mode){
       dc0 = brh->m0.c0;
    }
 }else{
    if (inc_mode){
       dc0 = brh->m0.c0 - brh->m1.c0;
    }else{
       dc0 = brh->m0.c0;
    }
 }
 if (dc0 != 0.){
    if (brh->n[OUT2].m != 0)
       ns.i[brh->n[OUT2].m] += dc0;
    if (brh->n[OUT1].m != 0)
       ns.i[brh->n[OUT1].m] -= dc0;
 }
 brh->m1 = brh->m0;
}
/*--------------------------------------------------------------------------*/
/* trloadpassive: load passive element to matrix, and offset to right side
 * 	symmetric around diagonal: input == output
 * if's optimize for speed.  could be done like trloadactive, with OUT for IN.
 */
void trloadpassive(branch_t *brh)
{
 double dc0;
 double df1;
 if (brh->loaditer == stats.iter[iTOTAL])
    error(bDANGER, "%s: double load\n", printlabel(brh,0));
 brh->loaditer = stats.iter[iTOTAL];
 
 if (stats.iter[iSTEP] > 1  &&  !brh->nodamp){
    dc0 = opt.damp * (brh->m0.c0 - brh->m1.c0);
    brh->m0.c0 = brh->m1.c0 + dc0;
    df1 = opt.damp * (brh->m0.f1 - brh->m1.f1);
    brh->m0.f1 = brh->m1.f1 + df1;
    if (!inc_mode){
       dc0 = brh->m0.c0;
       df1 = brh->m0.f1;
    }
 }else{
    if (inc_mode){
       dc0 = brh->m0.c0 - brh->m1.c0;
       df1 = brh->m0.f1 - brh->m1.f1;
    }else{
       dc0 = brh->m0.c0;
       df1 = brh->m0.f1;
    }
 }
 if (df1 != 0.){
    if (brh->n[OUT2].m != 0){
       setneedslu(brh,OUT2);
       *AAd(brh->n[OUT2].m,brh->n[OUT2].m) += df1;
       if (brh->n[OUT1].m != 0){
          setneedslu(brh,OUT1);
	  *AAd(brh->n[OUT1].m,brh->n[OUT1].m) += df1;
	  *AA(brh->n[OUT1].m,brh->n[OUT2].m)  -= df1;
	  *AA(brh->n[OUT2].m,brh->n[OUT1].m)  -= df1;
       }
    }else if (brh->n[OUT1].m != 0){
       setneedslu(brh,OUT1);
       *AAd(brh->n[OUT1].m,brh->n[OUT1].m) += df1;
    }
 }
 if (dc0 != 0.){
    if (brh->n[OUT2].m != 0)
       ns.i[brh->n[OUT2].m] += dc0;
    if (brh->n[OUT1].m != 0)
       ns.i[brh->n[OUT1].m] -= dc0;
 }
 brh->m1 = brh->m0;
}
/*--------------------------------------------------------------------------*/
/* trloadactive: load active element to matrix, and offset to right side
 *	asymmetric around diagonal: input != output
 */
void trloadactive(branch_t *brh)
{
 double dc0;
 double df1;
 if (brh->loaditer == stats.iter[iTOTAL])
    error(bDANGER, "%s: double load\n", printlabel(brh,0));
 brh->loaditer = stats.iter[iTOTAL];

 if (stats.iter[iSTEP] > 1  &&  !brh->nodamp){
    dc0 = opt.damp * (brh->m0.c0 - brh->m1.c0);
    brh->m0.c0 = brh->m1.c0 + dc0;
    df1 = opt.damp * (brh->m0.f1 - brh->m1.f1);
    brh->m0.f1 = brh->m1.f1 + df1;
    if (!inc_mode){
       dc0 = brh->m0.c0;
       df1 = brh->m0.f1;
    }
 }else{
    if (inc_mode){
       dc0 = brh->m0.c0 - brh->m1.c0;
       df1 = brh->m0.f1 - brh->m1.f1;
    }else{
       dc0 = brh->m0.c0;
       df1 = brh->m0.f1;
    }
 }
 if (df1 != 0.){
    setneedslu(brh,OUT1);
    setneedslu(brh,OUT2);
    setneedslu(brh,IN1);
    setneedslu(brh,IN2);
    *re(brh->n[OUT1].m,brh->n[IN1].m) += df1;
    *re(brh->n[OUT2].m,brh->n[IN2].m) += df1;
    *re(brh->n[OUT1].m,brh->n[IN2].m) -= df1;
    *re(brh->n[OUT2].m,brh->n[IN1].m) -= df1;
 }
 if (dc0 != 0.){
    if (brh->n[OUT2].m != 0)
       ns.i[brh->n[OUT2].m] += dc0;
    if (brh->n[OUT1].m != 0)
       ns.i[brh->n[OUT1].m] -= dc0;
 }
 brh->m1 = brh->m0;
}
/*--------------------------------------------------------------------------*/
/* trloadactivereverse: reversed version of trloadactive
 */
void trloadactivereverse(branch_t *brh)
{
 double dc0;
 double df1;
 if (brh->loaditer == stats.iter[iTOTAL])
    error(bDANGER, "%s: double load\n", printlabel(brh,0));
 brh->loaditer = stats.iter[iTOTAL];

 if (stats.iter[iSTEP] > 1  &&  !brh->nodamp){
    dc0 = opt.damp * (brh->m0.c0 - brh->m1.c0);
    brh->m0.c0 = brh->m1.c0 + dc0;
    df1 = opt.damp * (brh->m0.f1 - brh->m1.f1);
    brh->m0.f1 = brh->m1.f1 + df1;
    if (!inc_mode){
       dc0 = brh->m0.c0;
       df1 = brh->m0.f1;
    }
 }else{
    if (inc_mode){
       dc0 = brh->m0.c0 - brh->m1.c0;
       df1 = brh->m0.f1 - brh->m1.f1;
    }else{
       dc0 = brh->m0.c0;
       df1 = brh->m0.f1;
    }
 }
 if (df1 != 0.){
    setneedslu(brh,OUT1);
    setneedslu(brh,OUT2);
    setneedslu(brh,IN1);
    setneedslu(brh,IN2);
    *re(brh->n[IN1].m,brh->n[OUT1].m) += df1;
    *re(brh->n[IN2].m,brh->n[OUT2].m) += df1;
    *re(brh->n[IN1].m,brh->n[OUT2].m) -= df1;
    *re(brh->n[IN2].m,brh->n[OUT1].m) -= df1;
 }
 if (dc0 != 0.){
    if (brh->n[IN2].m != 0)
       ns.i[brh->n[IN2].m] += dc0;
    if (brh->n[IN1].m != 0)
       ns.i[brh->n[IN1].m] -= dc0;
 }
 brh->m1 = brh->m0;
}
/*--------------------------------------------------------------------------*/
/* trloadmutual: mutual version of trloadactive
 */
void trloadmutual(branch_t *brh)
{
 double dc0;
 double df1;
 if (brh->loaditer == stats.iter[iTOTAL])
    error(bDANGER, "%s: double load\n", printlabel(brh,0));
 brh->loaditer = stats.iter[iTOTAL];

 if (stats.iter[iSTEP] > 1  &&  !brh->nodamp){
    dc0 = opt.damp * (brh->m0.c0 - brh->m1.c0);
    brh->m0.c0 = brh->m1.c0 + dc0;
    df1 = opt.damp * (brh->m0.f1 - brh->m1.f1);
    brh->m0.f1 = brh->m1.f1 + df1;
    if (!inc_mode){
       dc0 = brh->m0.c0;
       df1 = brh->m0.f1;
    }
 }else{
    if (inc_mode){
       dc0 = brh->m0.c0 - brh->m1.c0;
       df1 = brh->m0.f1 - brh->m1.f1;
    }else{
       dc0 = brh->m0.c0;
       df1 = brh->m0.f1;
    }
 }
 if (df1 != 0.){
    setneedslu(brh,OUT1);
    setneedslu(brh,OUT2);
    setneedslu(brh,IN1);
    setneedslu(brh,IN2);
    *re(brh->n[OUT1].m,brh->n[IN1].m) += df1;
    *re(brh->n[OUT2].m,brh->n[IN2].m) += df1;
    *re(brh->n[OUT1].m,brh->n[IN2].m) -= df1;
    *re(brh->n[OUT2].m,brh->n[IN1].m) -= df1;
    *re(brh->n[IN1].m,brh->n[OUT1].m) += df1;
    *re(brh->n[IN2].m,brh->n[OUT2].m) += df1;
    *re(brh->n[IN1].m,brh->n[OUT2].m) -= df1;
    *re(brh->n[IN2].m,brh->n[OUT1].m) -= df1;
 }
 if (dc0 != 0.){
    if (brh->n[OUT2].m != 0)
       ns.i[brh->n[OUT2].m] += dc0;
    if (brh->n[OUT1].m != 0)
       ns.i[brh->n[OUT1].m] -= dc0;
    if (brh->n[IN2].m != 0)
       ns.i[brh->n[IN2].m] += dc0;
    if (brh->n[IN1].m != 0)
       ns.i[brh->n[IN1].m] -= dc0;
 }
 brh->m1 = brh->m0;
}
/*--------------------------------------------------------------------------*/
/* unloadsource: unload source from right side vector
 */
void unloadsource(branch_t *brh)
{
 brh->m0.c0 = brh->m0.f1 = 0.;
 if (inc_mode)
    inc_mode = BAD;
 trloadsource(brh);
}
/*--------------------------------------------------------------------------*/
/* unloadpassive: unload passive element and offset
 * 	symmetric around diagonal: input == output
 */
void unloadpassive(branch_t *brh)
{
 brh->m0.c0 = brh->m0.f1 = 0.;
 if (inc_mode)
    inc_mode = BAD;
 trloadpassive(brh);
}
/*--------------------------------------------------------------------------*/
/* unloadactive: unload active element from matrix, and offset from right side
 *	asymmetric around diagonal: input != output
 */
void unloadactive(branch_t *brh)
{
 brh->m0.c0 = brh->m0.f1 = 0.;
 if (inc_mode)
    inc_mode = BAD;
 trloadactive(brh);
}
/*--------------------------------------------------------------------------*/
/* unloadactivereverse: reversed version of unloadactive
 */
void unloadactivereverse(branch_t *brh)
{
 brh->m0.c0 = brh->m0.f1 = 0.;
 if (inc_mode)
    inc_mode = BAD;
 trloadactivereverse(brh);
}
/*--------------------------------------------------------------------------*/
/* unloadmutual: mutual version of unloadactive
 */
void unloadmutual(branch_t *brh)
{
 brh->m0.c0 = brh->m0.f1 = 0.;
 if (inc_mode)
    inc_mode = BAD;
 trloadmutual(brh);
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
