/*
 $Id: precond.cc,v 1.2 1996/10/04 15:07:16 roitzsch Exp $
 (C)opyright 1996 by Konrad-Zuse-Center, Berlin
 All rights reserved.
 Part of the Kaskade distribution
*/

#include "precond.h"

#include "sysmat.h"
#include "sysmatsp.h"

#include "family.h"
#include "dirichlet.h"

#include "cmdpars.h"
extern CmdPars Cmd;


// Note: 
//
// single- and multi-grid preconditioners delete all system matrices 
// which have been handed over to them (via the function update(...))

//-------------------------------------------------------------------------

Preconditioner:: Preconditioner() : AP(0)
{ 
    infoLinSystem = 0;    Cmd.get("infoLinSystem", &infoLinSystem); 
    timeLinSystem = 0;    Cmd.get("timeLinSystem", &timeLinSystem);
    accTimeLinSystem = 0; Cmd.get("accTimeLinSystem", &accTimeLinSystem);

    infoPrecond   = 0;    Cmd.get("infoPrecond", &infoPrecond);
}
//-------------------------------------------------------------------------

Preconditioner:: ~Preconditioner()  { delete AP; }

//-------------------------------------------------------------------------

void Preconditioner:: update(SystemMatrix* APNew, FamilyTree* /*familyTree0*/,
			     DirichletBCs* dirichletBCs0)  
{ 
    dirichletBCs = dirichletBCs0;

    if (APNew != AP) 
    {
	delete AP;
	AP = APNew;
    }
    initParameters();
}
//-------------------------------------------------------------------------

void Preconditioner:: AMult(Vector<Num>& lhs, SystemMatrix* A, Vector<Num>& rhs) 
{
    A->Mult(lhs,rhs);
}

void Preconditioner:: ATMult(Vector<Num>& lhs, SystemMatrix* A,Vector<Num>& rhs) 
{
    A->ATMult(lhs,rhs);
}
//-------------------------------------------------------------------------


void Preconditioner:: residual(Vector<Num>& newR, Vector<Num>& r, 
			       SystemMatrix& A, Vector<Num>& e)
{
    int n, dim;
    dim = A.Dim();
    for (n=1; n<=dim; ++n) newR[n] = 0.0;	  // local smoothing possible!
    A.Mult(newR,e); 
    for (n=1; n<=dim; ++n) newR[n] = r[n]-newR[n];   
}
