// elastic_genTerm_dfloat - A solver for non linear elastic problems using FEM
// Copyright (C) 2010-2026 Eric Bechet, Frederic Duboeuf
//
// See the LICENSE file for license information and contributions.
// Please report all bugs and problems to <bechet@cadxfem.org>.

#ifndef _MECHANICS_DOMAIN_H_
#define _MECHANICS_DOMAIN_H_

#include <string>
#include <vector>

#include "genSupports.h"
#include "genTerm.h"
#include "genTermApply.h"
#include "genTensors.h"
#include "genDataIO.h"
#include "genMatrix.h"
#include "savedGenTerm.h"
#include "savedGenTermManager.h"
#include "genAlgorithms.h"
#include "genOperators.h"
#include "dfloat.h"


#define Macro_Stress \
protected : \
  template <class scalar, int n> typename genTerm<genTensor2<scalar>,n>::ConstHandle UserStress(const typename genTerm<genTensor2<scalar>,n>::ConstHandle &Eps); \
public : \
  virtual genTerm<genTensor2<double>,0>::ConstHandle Stress(const genTerm<genTensor2<double>,0>::ConstHandle &Eps) { return UserStress<double,0>(Eps); } \
  virtual genTerm<genTensor2<double>,1>::ConstHandle Stress(const genTerm<genTensor2<double>,1>::ConstHandle &Eps) { return UserStress<double,1>(Eps); } \
  virtual genTerm<genTensor2<double>,2>::ConstHandle Stress(const genTerm<genTensor2<double>,2>::ConstHandle &Eps) { return UserStress<double,2>(Eps); } \
  virtual genTerm<genTensor2<dfloat<double> >,0>::ConstHandle Stress(const genTerm<genTensor2<dfloat<double> >,0>::ConstHandle &Eps) { return UserStress<dfloat<double>,0>(Eps); } \
  virtual genTerm<genTensor2<dfloat<double> >,1>::ConstHandle Stress(const genTerm<genTensor2<dfloat<double> >,1>::ConstHandle &Eps) { return UserStress<dfloat<double>,1>(Eps); } \
  virtual genTerm<genTensor2<dfloat<double> >,2>::ConstHandle Stress(const genTerm<genTensor2<dfloat<double> >,2>::ConstHandle &Eps) { return UserStress<dfloat<double>,2>(Eps); } \

#define Macro_History \
protected : \
  template <class T> typename genTerm<T,0>::Handle saveGenTermInHistory(std::string name, QuadratureBase &integrator, const typename genTerm<T,0>::ConstHandle &gt) \
  { \
    int step = History.getcurrentstep(name); \
    std::shared_ptr<SavedGenTerm<T,0> > SaveGt(new SavedGenTerm<T,0>()); \
    SavePtGauss(*gt, begin(), end(), integrator, *SaveGt); \
    History.addSavedGenTerm(name, SaveGt, step); \
    return SaveGt; \
  } \
public : \
  virtual void CopyHistory(); \
  virtual void UpdateHistory(const genTerm<genTensor2<double>,0>::ConstHandle &Eps); \


class MechanicsDomain : public genSupport
{
public :
  MechanicsDomain (const genDomain &s) : genSupport()
  {
    dim=s.dim;
    tag=s.tag;
  }
  MechanicsDomain () : genSupport() {}
  virtual ~MechanicsDomain() {};

  virtual genTerm<genTensor2<double>,0>::ConstHandle Stress(const genTerm<genTensor2<double>,0>::ConstHandle &Eps) =0;
  virtual genTerm<genTensor2<double>,1>::ConstHandle Stress(const genTerm<genTensor2<double>,1>::ConstHandle &Eps) =0;
  virtual genTerm<genTensor2<double>,2>::ConstHandle Stress(const genTerm<genTensor2<double>,2>::ConstHandle &Eps) =0;

  virtual genTerm<genTensor2<dfloat<double> >,0>::ConstHandle Stress(const genTerm<genTensor2<dfloat<double> >,0>::ConstHandle &Eps) =0;
  virtual genTerm<genTensor2<dfloat<double> >,1>::ConstHandle Stress(const genTerm<genTensor2<dfloat<double> >,1>::ConstHandle &Eps) =0;
  virtual genTerm<genTensor2<dfloat<double> >,2>::ConstHandle Stress(const genTerm<genTensor2<dfloat<double> >,2>::ConstHandle &Eps) =0;

  virtual void CopyHistory() {}
  virtual void UpdateHistory(const genTerm<genTensor2<double>,0>::ConstHandle &Eps) {}
protected :
  SavedGenTermManager History;
};


#endif// _MECHANICS_DOMAIN_H_