// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  crystal growth group                                                  ==
// ==                                                                        ==
// ==  Stiftung caesar                                                       ==
// ==  Ludwig-Erhard-Allee 2                                                 ==
// ==  53175 Bonn                                                            ==
// ==  germany                                                               ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  http://www.caesar.de/cg/AMDiS                                         ==
// ==                                                                        ==
// ============================================================================

/** \file DiagonalPreconditioner.h */

#ifndef AMDIS_DIAGONAL_PRECONDITIONER_H
#define AMDIS_DIAGONAL_PRECONDITIONER_H

#include <vector>
#include "Preconditioner.h"
#include "MemoryManager.h"
#include "CreatorInterface.h"

namespace AMDiS {

  template<typename T> class DOFVector;
  template<typename T> class OEMSolver;

  // ============================================================================
  // ===== class DiagonalPreconditioner =========================================
  // ============================================================================

  /**
   * \ingroup Solver
   * 
   * \brief
   * diagonal preconditioner. Implements the singleton design pattern to allow
   * only one instance of this class.
   */
  class DiagonalPreconditioner : public PreconditionerScal
  {
  public:
    MEMORY_MANAGED(DiagonalPreconditioner);

    /** \brief
     * Creator class used in the PreconditionerMap.
     */
    class Creator : public PreconditionerScalCreator
    {
    public:
      MEMORY_MANAGED(Creator);

      /** \brief
       * Creates a DiagonalPreconditioner.
       */
      PreconditionerScal *create() { 
	return NEW DiagonalPreconditioner(size, row);
      };
    };

    /** \brief
     * Constructor.
     */
    DiagonalPreconditioner(int size = 1, int row = 0) 
      : PreconditionerScal(size, row) 
    {};

    /** \brief
     * Destructor.
     */
    virtual ~DiagonalPreconditioner() {};

    /** \brief
     * realisation of Preconditioner::init
     */
    inline void init() {
      FUNCNAME("DiagonalPreconditioner::init");
      TEST_EXIT(matrix[row])("no matrix\n");
    };

    /** \brief
     * realisation of Preconditioner::precon
     */
    void precon(DOFVector<double> *x);

    /** \brief
     * realisation of Preconditioner::exit
     */
    inline void exit() {};
  };


  class DiagonalPreconditionerStd : public PreconditionerScalStd
  {
  public:
    MEMORY_MANAGED(DiagonalPreconditionerStd);

    /** \brief
     * Constructor.
     */
    DiagonalPreconditionerStd() 
    {};

    /** \brief
     * Destructor.
     */
    virtual ~DiagonalPreconditionerStd() {};

    /** \brief
     * realisation of Preconditioner::init
     */
    inline void init() {};

    /** \brief
     * Realisation of Preconditioner::precon
     */
    void precon(std::vector<double>* x);

    /** \brief
     * realisation of Preconditioner::exit
     */
    inline void exit() {};
  };

}

#endif // AMDIS_DIAGONAL_PRECONDITIONER_H