/* Fesslix - Stochastic Analysis
 * Copyright (C) 2010-2016 Wolfgang Betz
 *
 * Fesslix is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Fesslix is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Fesslix.  If not, see <http://www.gnu.org/licenses/>. 
 */

#ifndef fesslix_flxobjrf_H
#define fesslix_flxobjrf_H

#include "flxobjects.h"
#include "flxrandomFEM.h"



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

/**
* @brief object class: create a new random field
*
* rnd rf new ...;
*/
class FLXFEM_EXPORT FlxObjRndRfCreate : public FlxObjBase {
  protected:
    FlxFunction* index;
    FlxRF_Generator_base* rG;
    virtual void task();
  public:
    FlxObjRndRfCreate(bool dolog, FlxFunction* index, FlxRF_Generator_base* rG) : FlxObjBase(dolog), index(index), rG(rG) {}
    ~FlxObjRndRfCreate() {delete rG; delete index;};
};

class FLXFEM_EXPORT FlxObjReadRndRfCreate : public FlxObjReadBase {
  public:
    FlxObjReadRndRfCreate() : FlxObjReadBase(true) {}
    FlxObjBase* read ();
};

/**
* @brief object class: assign an element to a random field
*
* rnd rf elset ...;
*/
class FLXFEM_EXPORT FlxObjRndRfElSet : public FlxObjBase {
  protected:
    FlxFunction* index;				// index of the random field
    const flxDomain_base::geoel_type typeEL;	// type of the element (edge,face,box)
    FlxFunction* elindex;			// index of the element
    FlxKLelementProp_base* KLelProp;
    virtual void task();
  public:
    FlxObjRndRfElSet(bool dolog, FlxFunction* index, const flxDomain_base::geoel_type typeEL, FlxFunction* elindex, FlxKLelementProp_base* KLelProp) : FlxObjBase(dolog), index(index), typeEL(typeEL), elindex(elindex), KLelProp(KLelProp) {}
    ~FlxObjRndRfElSet() {delete index; delete elindex; delete KLelProp; };
};

class FLXFEM_EXPORT FlxObjReadRndRfElSet : public FlxObjReadBase {
  public:
    FlxObjReadRndRfElSet() : FlxObjReadBase(true) {}
    FlxObjBase* read ();
};

/**
* @brief object class: assign an element to a random field
*
* rnd rf solve ...;
*/
class FLXFEM_EXPORT FlxObjRndRfSolve : public FlxObjOutputBase {
  protected:
    FlxFunction* index;
    FlxRFsolveProp* RFsolveProp;
    virtual void task();
  public:
    FlxObjRndRfSolve(bool dolog, FlxFunction* index, FlxRFsolveProp* RFsolveProp, std::string ostreamV, bool verbose) : FlxObjOutputBase(dolog,ostreamV,verbose), index(index), RFsolveProp(RFsolveProp) {}
    ~FlxObjRndRfSolve() { delete index; delete RFsolveProp; };
};

class FLXFEM_EXPORT FlxObjReadRndRfSolve : public FlxObjReadOutputBase {
  public:
    FlxObjReadRndRfSolve() : FlxObjReadOutputBase(true) {}
    FlxObjBase* read ();
};

/**
* @brief object class: assign an element to a random field
*
* rnd rf err ...;
*/
class FLXFEM_EXPORT FlxObjRndRfErr : public FlxObjOutputBase {
  protected:
    FlxFunction* index;
    FlxFunction* errMeasure;
    virtual void task();
  public:
    FlxObjRndRfErr(bool dolog, FlxFunction* index, FlxFunction* errMeasure, std::string ostreamV, bool verbose) : FlxObjOutputBase(dolog,ostreamV,verbose), index(index), errMeasure(errMeasure) {}
    ~FlxObjRndRfErr() { delete index; delete errMeasure; };
};

class FLXFEM_EXPORT FlxObjReadRndRfErr : public FlxObjReadOutputBase {
  public:
    FlxObjReadRndRfErr();
    FlxObjBase* read ();
};

/**
* @brief object class: assign an element to a random field
*
* rnd rf plot ...;
*/
class FLXFEM_EXPORT FlxObjRndRfPlot : public FlxObjOutputBase {
  protected:
    FlxFunction* index;
    FlxMtxConstFun* ppdim;
    FlxFunction* errMeasure;
    const bool checkTOL;
    virtual void task();
  public:
    FlxObjRndRfPlot(const bool dolog, FlxFunction* index, FlxMtxConstFun* ppdim, FlxFunction* errMeasure, const std::string ostreamV, const bool verbose, const int prec, const int fixW, const bool checkTOL): FlxObjOutputBase(dolog,ostreamV,verbose,false,prec,fixW), index(index), ppdim(ppdim),errMeasure(errMeasure), checkTOL(checkTOL) {}
    ~FlxObjRndRfPlot() { delete index; delete ppdim; delete errMeasure; };
};

class FLXFEM_EXPORT FlxObjReadRndRfPlot : public FlxObjReadOutputBase {
  public:
    FlxObjReadRndRfPlot();
    FlxObjBase* read ();
};

/**
* @brief object class: assign an element to a random field
*
* rnd rf plotcov ...;
*/
class FLXFEM_EXPORT FlxObjRndRfPlotCov : public FlxObjOutputBase {
  protected:
    FlxFunction* index;
    FlxFunPoint* p;
    FlxMtxConstFun* ppdim;
    virtual void task();
  public:
    FlxObjRndRfPlotCov(const bool dolog, FlxFunction* index, FlxFunPoint* p, FlxMtxConstFun* ppdim, const std::string ostreamV, const bool verbose, const int prec, const int fixW): FlxObjOutputBase(dolog,ostreamV,verbose,false,prec,fixW), index(index),p(p), ppdim(ppdim) {}
    ~FlxObjRndRfPlotCov() { delete index; delete p; delete ppdim; };
};

class FLXFEM_EXPORT FlxObjReadRndRfPlotCov : public FlxObjReadOutputBase {
  public:
    FlxObjReadRndRfPlotCov();
    FlxObjBase* read ();
};

/**
* @brief arithmetic class: numerical integration of a function
*/
class FLXFEM_EXPORT FunRF : public FunBase {
  private:
    const tuint RFindex;
    FlxRandomField_base* rfb;
  public:
    FunRF(const tuint RFindex, FlxRandomField_base* rfb) : RFindex(RFindex), rfb(rfb)  {}
    ~FunRF() {}
    const tdouble calc() { return rfb->get_realization(); }
    const bool search_circref(FlxFunction* fcr) { return false; }
    const std::string write();
    const tuint precedence() { return 0; }
    const bool dependOn_Const(const tdouble* const thenumber) { return false; }
    const bool optimize(FunBasePtr& optf, const Fun_OptimizeInfo &foi) { return false; }
};

class FLXFEM_EXPORT FunReadFunRF : public FunReadFunBase {
  public:
    FunReadFunRF() : FunReadFunBase(true) {}
    FunBase* read ( bool errSerious );
};

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

class FLXFEM_EXPORT FlxObjMtxConstRfElIdVec : public FlxObjBase {
  protected:
    FlxMtxConstFun* mcn_target;		// where to store
    FlxFunction* rfID;
    const flxDomain_base::geoel_type typeEL;	// type of the element (edge,face,box)
    
    void task();
  public:
    FlxObjMtxConstRfElIdVec ( bool dolog, FlxMtxConstFun* mcn_target, FlxFunction* rfID, const flxDomain_base::geoel_type typeEL) : FlxObjBase(dolog), mcn_target(mcn_target), rfID(rfID), typeEL(typeEL) {}
    virtual ~FlxObjMtxConstRfElIdVec() { delete mcn_target; delete rfID; }
};

class FLXFEM_EXPORT FlxObjReadMtxConstRfElIdVec : public FlxObjReadBase {
  public:
    FlxObjReadMtxConstRfElIdVec() : FlxObjReadBase(true) {}
    FlxObjBase* read ();
};

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

/**
* @brief arithmetic class: rf_err(INDEX,MEASURE)
*/
class FLXFEM_EXPORT FunRFerr : public FunBaseFun_multPara, public FlxDataBase {
  public:
    FunRFerr (std::vector<FunBase*> *ParaListV) : FunBaseFun_multPara(ParaListV) {};
    const tdouble calc();
    const std::string write_v() { return "rf_err";}
};

class FLXFEM_EXPORT FunReadFunRFerr : public FunReadFunBase {
  public:
    FunReadFunRFerr() : FunReadFunBase(true) {}
    FunBase* read ( bool errSerious ) { return new FunRFerr( read_parameters(2,errSerious) ); }
};

/**
* @brief arithmetic class:
*/
class FLXFEM_EXPORT FunRFeigenvalue : public FunBaseFun_multPara, public FlxDataBase {
  public:
    FunRFeigenvalue (std::vector<FunBase*> *ParaListV) : FunBaseFun_multPara(ParaListV) {};
    const tdouble calc();
    const std::string write_v() { return "rfeigenvalue";}
};

class FLXFEM_EXPORT FunReadFunFunRFeigenvalue : public FunReadFunBase {
  public:
    FunReadFunFunRFeigenvalue() : FunReadFunBase(true) {}
    FunBase* read ( bool errSerious ) { return new FunRFeigenvalue( read_parameters(2,errSerious) ); }
};



#endif // fesslix_flxobjrf_H
