/* Copyright (c) 2015  Gerald Knizia
 * 
 * This file is part of the IboView program (see: http://www.iboview.org)
 * 
 * IboView 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, version 3.
 * 
 * IboView 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 details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with bfint (LICENSE). If not, see http://www.gnu.org/licenses/
 * 
 * Please see IboView documentation in README.txt for:
 * -- A list of included external software and their licenses. The included
 *    external software's copyright is not touched by this agreement.
 * -- Notes on re-distribution and contributions to/further development of
 *    the IboView software
 */

// this file exists for the sole purpose of avoiding circular header dependencies.
#ifndef CT_RHF_OPTIONS_H
#define CT_RHF_OPTIONS_H

#include <string>
#include "CtDftGrid.h" // for grid params.

namespace ct {

struct FWfDecl
{
   uint nElec, Ms2;

   uint nElecA() const { return (nElec + Ms2)/2; }
   uint nElecB() const { return (nElec - Ms2)/2; }
   uint nOpen() const { return Ms2; } // nOccA - nOccB
   uint nClosed() const { return nElecB(); } // nOccA - nOccB

   FWfDecl() : nElec(0), Ms2(0) {}
   explicit FWfDecl(uint nElec_, uint Ms2_=0)
      : nElec(nElec_), Ms2(Ms2_)
   {}
};

enum FXcAlgo {
   XCALGO_Regular, // standard computation of xc contributions, with full density.
   XCALGO_AuxiliaryExpand, // computation of xc contributions via auxiliary expansion of density computed in Coulomb.
   XCALGO_Gridless  // DFT without meshes and grids.
};

enum FJkAlgo {
   JKALGO_DfRhf, // regular density fitted RHF
   JKALGO_DfCoulombOnly, // regular density fitted RKS with pure functionals
   JKALGO_DfCoulombOnlyCache3ix // for small molecules: attempt to cache *all* 3ix integrals in memory.
};

enum FHfComputeFlags {
   COMPUTE_Gradient = 0x01, // compute analytic gradient?
   COMPUTE_IboAnalysis = 0x02
};


struct FHfOptions {
   double
      ThrOrb, ThrDen; // threshold for orbital gradient (residual) and energy change, respectively
   uint
      MaxIt; // maximum number of iterations.

//    double
//       ExactExchFactor; // prefactor for exact exchange. If 0, no exact exchange is computed.
   FXcAlgo
      // how to compute xc functional contributions, provided that an xc functional is set.
      XcAlgo;
   FJkAlgo
      // how to compute coulomb and exact exchange contributions.
      JkAlgo;
   uint32_t
      // decides on what we compute (COMPFLAG_*).
      ComputeFlags;
   double
      LevelShifts[2]; // [0]: for closed shells, [1]: for occupied open shells.

   std::string
      XcFunctionalName;
   FDftGridParams
      DftGridParams,
      DftGridParamsRefine;
   bool
      // if set, switch to FinalGrid after convergence and make one more iteration.
      UseRefineGrid;

   explicit FHfOptions(double ThrOrb_=1e-5, double ThrDen_=1e-6, uint MaxIt_=120)
      : ThrOrb(ThrOrb_), ThrDen(ThrDen_), MaxIt(MaxIt_),
        XcAlgo(XCALGO_Regular), JkAlgo(JKALGO_DfRhf), ComputeFlags(0),
        XcFunctionalName(""), UseRefineGrid(false)
   {
      LevelShifts[0] = -0.4;
      LevelShifts[1] = -0.2;
   }
};

} // namespace ct


#endif // CT_RHF_OPTIONS_H
