// gen_LevelSet - An automatic generator of meshes from level-sets
// Copyright (C) 2012-2026 Eric Bechet, Frederic Duboeuf
//
// See the LICENSE file for license information.
// Please report all bugs and problems to <bechet@cadxfem.org> or <duboeuf@outlook.com>.


#ifndef _LEVELSET_DOMAIN_H_
#define _LEVELSET_DOMAIN_H_

#include <string>
#include <vector>

#include "genSupports.h"
#include "genTerm.h"
#include "genTensors.h"
#include "genDataLS.h"
#include "genMatrix.h"
#include "savedGenTerm.h"


class LevelSetDomain : public genSupport
{
protected :
  genGroupOfElements* gp; // group of elements of the parent support
public :
  genTerm<genTensor0<double>,0>::ConstHandle D; //Distance
  genTerm<genTensor1<double>,0>::ConstHandle N; //Normal
  genTerm<genTensor2<double>,0>::ConstHandle C; //Curvature
  int meshContainsLS;

public :
  LevelSetDomain(genLevelSetSupport &s)
  {
    dim=s.dim; // dimension of LevelSet (different from the suppodistancert)
    tag=s.tag; // physical of LevelSet (different from the support)

    gp = s.group(); // build group of elements and distances
    D = genTerm<genTensor0<double>,0>::Handle(new InterpolatedField<genTensor0<double> >(s.distances));
    meshContainsLS = s.meshContainsLS;
  }
  genTerm<genTensor0<double>,0>::ConstHandle Distance();
  genTerm<genTensor1<double>,0>::ConstHandle Normal();
  genTerm<genTensor2<double>,0>::ConstHandle Curvature();
  void defineParentGroup(genGroupOfElements* gp_) { gp=gp_; }
  genGroupOfElements* pgroup()
  {
    if (gp==NULL)
      printf("Parent group is not already existing.\n");
    return gp;
  }
  LevelSetDomain() : genSupport() {}
  virtual ~LevelSetDomain() {};
};

inline genTerm<genTensor0<double>,0>::ConstHandle LevelSetDomain::Distance()
{
  return genTerm<genTensor0<double>,0>::ConstHandle(D);
}

inline genTerm<genTensor1<double>,0>::ConstHandle LevelSetDomain::Normal()
{
  return genTerm<genTensor1<double>,0>::ConstHandle(N);
}

inline genTerm<genTensor2<double>,0>::ConstHandle LevelSetDomain::Curvature()
{
  return genTerm<genTensor2<double>,0>::ConstHandle(C);
}



class DiscreteLevelSetDomain : public LevelSetDomain
{
public :
  DiscreteLevelSetDomain(genLevelSetSupport &s)
  {
    dim=s.dim; // dimension of LevelSet (different from the support)
    tag=s.tag; // physical of LevelSet (different from the support)

    gp = s.group(); // build group of elements and distances
    D = genTerm<genTensor0<double>,0>::Handle(new SavedGenTerm<genTensor0<double>,0>(s.distances));
    meshContainsLS = s.meshContainsLS;
  }
  DiscreteLevelSetDomain() : LevelSetDomain() {}
  virtual ~DiscreteLevelSetDomain() {};
};


#endif// _LEVELSET_DOMAIN_H_