// Nonlinear_genTerm_xfem - A solver for nonlinear problems using X-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> or <duboeuf@outlook.com>.

#ifndef _NONLINEARXFEM_SOLVER_H_
#define _NONLINEARXFEM_SOLVER_H_

#include "nonLinearSolver.h"
#include "nonLinearXfemDomain.h"


class NonLinearXfemSolver : public NonLinearSolver
{
protected :
  // function spaces
  genFSpace<genTensor0<double> >::Handle FSpaceLagMult;  // Gaetan method
  std::vector<genFSpace<genTensor1<double> >::Handle> FSpaceStableLagMult;  // E. Bechet Method
  std::vector<genFSpace<genTensor1<double> >::Handle> FSpaceStableLagMultForInterface;  // E. Bechet Method
  std::vector<genTerm<genTensor1<double>,1>::Handle> DispJumps;
  std::vector<genTerm<genTensor2<double>,1>::Handle> EpsilonDispJumps;

  // supports for stableLagMult
  std::vector<genInterfaceDomain<genTensor0<double> >*> InterfaceDomains;
  std::vector<StableLagrangeMultiplierDomain*> StableLagMultDomains;
  std::vector<std::vector<genGroupOfElements*> > CombineSLMatDomain;

public :
  NonLinearXfemSolver() : NonLinearSolver() {}
  virtual ~NonLinearXfemSolver();
  //read data file
  virtual void readInputFile(const std::string &fileName);
  // builds local supports
  virtual void CheckProperties();
  // init and update SavedField
  virtual void InitField();
  virtual void CopyField();
  virtual void SaveField();
  // build the problem boundary conditions
  virtual void BuildDirichlet(double facDirichlet);
  virtual void BuildNeumann(double facNeumann);
  // build the initial problem function spaces
  virtual void BuildInitialFunctionSpaces();
  // assemble the initial problem
  virtual void AssembleInitialRHS();
  virtual void AssembleInitialLHS();
  // build the problem function spaces
  virtual void BuildFunctionSpaces();
  // assemble the problem
  virtual void AssembleRHS();
  virtual void AssembleLHS();
  // precision
  virtual bool ResidualForceCriterion(const double &criter, double &normResidual);
  //post-processing
  virtual void postprocessing(int step);
  virtual PView* buildInterfaceDisplacementView(const std::string &postFileName);
  virtual PView* buildInterfaceLagrangianView(const std::string &postFileName);
  void E();
};

#endif // _NONLINEARXFEM_SOLVER_H_
