// GenFem - A high-level finite element library
// Copyright (C) 2010-2026 Eric Bechet
//
// See the LICENSE file for license information and contributions.
// Please report all bugs and problems to <bechet@cadxfem.org>.
//
// Initial design: Frederic Duboeuf (rev.654)


#ifndef _SAVED_GENTERM_H_
#define _SAVED_GENTERM_H_

#include <vector>
#include <iostream>
#include "MElement.h"
#include "genTerm.h"
#include "genSimpleFunction.h"

template<class T,int n> class SavedGenTerm : public genTerm<T,n>
{
public:
  typedef typename TensorialTraits<T>::ValType ValType;
  typedef typename ContainerTraits<ValType,n>::Container ContainerValType;
  static const int Nsp=n;
private:
  std::map<int, std::vector<ContainerValType> >* mapvvals;

public:
  SavedGenTerm() {mapvvals = new std::map<int, std::vector<ContainerValType> >;}
  SavedGenTerm(std::map<int, std::vector<ContainerValType> >* mapvvals_) : mapvvals(mapvvals_) {}
  SavedGenTerm & operator= (const SavedGenTerm<T,n> &other)
  {
    if (&other != this)
      mapvvals = new std::map<int, std::vector<ContainerValType> >(*other.mapvvals);
    return *this;
  }
  virtual int getNumKeys(MElement* ele,int k=0) const  {return 0;};
  virtual void getKeys(MElement* ele, std::vector<Dof> &keys, int k=0) const {};
  virtual int getIncidentSpaceTag(int k=0) const { return 0;}
  virtual void get(MElement* ele, int npts, IntPt* GP, std::vector<ContainerValType> &vvals) const;
  virtual void get(MElement* ele, int npts, IntPt* GP, ContainerValType &vals) const
  {
    genTerm<T,n>::get(ele,npts,GP,vals);
  }
  virtual SavedGenTerm<T,n>* clone () const { return new SavedGenTerm<T,n>();}// SavedGenTerm<T>(_mapf)

  virtual int size() const { return mapvvals->size(); }
  virtual void set(MElement* ele, int npts, IntPt* GP, std::vector<ContainerValType> &vvals);
  virtual void print(const char* name);
  virtual bool printfile(const std::string &fileName,
                         const std::ios_base::openmode mode = std::ios::trunc,  // mode = app, ate, truncate
                         const int precision = 5);  // format = fixed, scientific
};


template<class T> class ConstantField : public genTerm<T,0>
{
public:
  typedef typename TensorialTraits<T>::ValType ValType;
  typedef typename ContainerTraits<ValType,0>::Container ContainerValType;
  static const int Nsp=0;
private:
  ValType value;

public:
  ConstantField(const ValType &value_ = ValType()) : value(value_) {}
  ConstantField & operator= (const ConstantField<T> &other)
  {
    if (&other != this)
      value = other.value;
    return *this;
  }
  virtual int getNumKeys(MElement* ele,int k=0) const  {return 0;};
  virtual void getKeys(MElement* ele, std::vector<Dof> &keys, int k=0) const {};
  virtual int getIncidentSpaceTag(int k=0) const { return 0;}
  virtual void get(MElement* ele, int npts, IntPt* GP, std::vector<ContainerValType> &vvals) const;
  virtual void get(MElement* ele, int npts, IntPt* GP, ContainerValType &vals) const
  {
    genTerm<T,0>::get(ele,npts,GP,vals);
  }
  virtual ConstantField<T>* clone () const { return new ConstantField<T>(value);}

  virtual void set(MElement* ele, int npts, IntPt* GP, std::vector<ContainerValType> &vvals);
  virtual void print(const char* name);
  virtual bool printfile(const std::string &fileName,
                         const std::ios_base::openmode mode = std::ios::trunc,  // mode = app, ate, truncate
                         const int precision = 5);  // format = fixed, scientific
};


template<class T> class FunctionField : public genTerm<T,0>
{
public:
  typedef typename TensorialTraits<T>::ValType ValType;
  typedef typename ContainerTraits<ValType,0>::Container ContainerValType;
  static const int Nsp=0;
private:
  const genSimpleFunction<ValType> &value;

public:
  FunctionField(const genSimpleFunction<ValType> &value_) : value(value_) {}
  virtual int getNumKeys(MElement* ele,int k=0) const  {return 0;};
  virtual void getKeys(MElement* ele, std::vector<Dof> &keys, int k=0) const {};
  virtual int getIncidentSpaceTag(int k=0) const { return 0;}
  virtual void get(MElement* ele, int npts, IntPt* GP, std::vector<ContainerValType> &vvals) const;
  virtual void get(MElement* ele, int npts, IntPt* GP, ContainerValType &vals) const
  {
    genTerm<T,0>::get(ele,npts,GP,vals);
  }
  virtual FunctionField<T>* clone () const { return new FunctionField<T>(value);}
};







template<class T> class InterpolatedField : public SavedGenTerm<T,0>
{
public:
  typedef typename TensorialTraits<T>::ValType ValType;
  typedef typename ContainerTraits<ValType,0>::Container ContainerValType;
  static const int Nsp=0;

public:
  InterpolatedField() {}
  InterpolatedField(std::map<int, std::vector<ContainerValType> >* mapvvals_) : SavedGenTerm<T,0>::SavedGenTerm(mapvvals_) {}
  virtual int getNumKeys(MElement* ele,int k=0) const  {return 0;};
  virtual void getKeys(MElement* ele, std::vector<Dof> &keys, int k=0) const {};
  virtual int getIncidentSpaceTag(int k=0) const { return 0;}
  virtual void get(MElement* ele, int npts, IntPt* GP, std::vector<ContainerValType> &vvals) const;
  virtual void get(MElement* ele, int npts, IntPt* GP, ContainerValType &vals) const
  {
    genTerm<T,0>::get(ele,npts,GP,vals);
  }
  virtual InterpolatedField<T>* clone () const { return new InterpolatedField<T>();}
};


#include "savedGenTerm.hpp"


#endif // _SAVED_GENTERM_H_




