/*
    DFT++ is a density functional package developed by the research group
    of Professor Tomas Arias

    Copyright 1996-2003 Sohrab Ismail-Beigi

    This file is part of DFT++.

    DFT++ 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; either version 2 of the License, or
    (at your option) any later version.

    DFT++ 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 more details.

    You should have received a copy of the GNU General Public License
    along with DFT++; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Please see the file CREDITS for a list of authors.

    For academic users, we request that publications using results obtained with
    this software reference

    "New algebraic formulation of density functional calculation," by Sohrab Ismail-Beigi
    and T.A. Arias, Computer Physics Communications 128:1-2, 1-45 (June 2000).

    and, if using the wavelet basis, further reference

    "Multiresolution analysis of electronic structure: semicardinal and wavelet bases,"
    T.A. Arias, Reviews of Modern Physics 71:1, 267-311 (January 1999).

    and 

    "Robust ab initio calculation of condensed matter: transparent convergence through
    semicardinal multiresolution analysis,'' I.P. Daykov, T.A. Arias, and
    Torkel D. Engeness, Physical Review Letters, 90:21, 216402 (May 2003).

    For your convenience, preprints of the above articles may be obtained from
    http://arXiv.org/abs/cond-mat/9909130, 9805262, and 0204411, respectively.
*/

//
// Sohrab Ismail-Beigi   April 2000
//
// Here we define the command class (which holds all sorts of stuff
// about a command), #define all commands and their associated numbers
// (used for dependencies), and prototype the setup functions.
//
// Dependencies are positive (the command requires another one to be
// found first) or negative (the command can NOT coexist with another
// command).
//

#ifndef DFT_COMMAND_H
#define DFT_COMMAND_H

#include "../header.h"

// This class holds all the information
// about the allowed commands.  It is a
// linked list
class command
{
public:
  int number;
  char *name;
  char *format;
  char *comments;
  int *dependencies;
  int found;
  int allow_multiple;
  int has_default;
  int is_overall_action;
  int (*process_command)(char *input_line,Everything &everything);
  void (*set_default)(Everything &everything);
  void (*print_status)(Everything &everything,Output *log);
  command *next_command;
  
  void init()
    {
      name = format = comments = 0;
      number = found = allow_multiple = has_default = 0;
      dependencies = 0;
      process_command = 0;
      set_default = 0;
      print_status = 0;
      next_command = 0;
      is_overall_action = 0;
    }
};

// Allocates a command instance
command *alloc_command();

// Creates the linked list of all commands and
// calls all command setup functions
command *create_command_list();

// Free it up!
void free_command_list(command *list);

// Defines the command list and their numbers.  Each command must
// have a unique, positive integer as its number.
//
// ****************************************************************
// *********** DO NOT DEFINE A COMMAND WITH NUMBER ZERO! **********
// ****************************************************************
//
// Zero is used to mark processed commands in the parser.

// Overall tasks we might want to do
#define ELECTRONIC_MINIMIZATION     1
#define CALCULATE_FORCES            2
#define RELAX_IONS                  3
#define IONIC_DYNAMICS              4
#define BAND_STRUCTURE              5
#define SPINORBIT                   6
#define DUMP_BANDS                  7
#define FINITE_DIFF_TEST            8

// The lattice
#define LATTICE                     10
#define LATT_SCALE                  11

// The ions
#define ION                         20
#define ION_SPECIES                 21

// are we using lattice or cartesian coordinates for the ions?
#define COORDS_TYPE                 23

// The electronic system
#define ELEC_CUTOFF                 30
#define ELEC_N_BANDS                31
#define ELEC_FERMI_FILLINGS         32
#define ELEC_EX_CORR                33
#define ELEC_INITIAL_FILLINGS       34

// K-points
#define KPOINT                      50
#define KPOINT_FOLDING              51

// Spin information
#define SPINTYPE                    60

// Ewald sums
#define EWALD                       70

// Control information
#define CNTRL_MAX_ELEC_STEPS        80
#define CNTRL_ELEC_STEPSIZE         81
#define CNTRL_ENERGY_CONVERGENCE    82
#define CNTRL_FORCE_CONVERGENCE     83
#define CNTRL_UPDATE_STEPSIZE       84
#define CNTRL_STEPSIZE_MIN          85
#define CNTRL_NEL_FERMI_TOL         86
#define CNTRL_SUBSPACE_ROTATION     87
#define CNTRL_DUMP_N                88
#define CNTRL_ALGORITHM             89
#define CNTRL_MAX_IONIC_STEPS       90
#define CNTRL_READ_DENSITY          91
#define CNTRL_FORCE_DIFF_CONVERGENCE 92
#define CNTRL_FORCE_DIFF_CHECK       93
#define CNTRL_LINMIN_METHOD         94
#define CNTRL_READ_VLOC             95
#define CNTRL_READ_VSCLOC           96

// Initial wavefunction setup
#define WAVEFUNCTION               100

// Ion dynamics info
#define ION_DYNAMICS_PARAM         110

// Ionic relaxation params
#define ION_RELAX_PARAM            120

// FFT box overriding
#define FFTBOX                     130

// Defining the basis set
#define BASIS                      140

// Symmetries
#define SYMMETRIES                 150
#define SYMMETRY_MATRIX            151

// Wavelet stuff (use 4 digit numbers)

// Specify gridspec filename.
#define GRIDSPEC                   1000
#define WL_EMBEDDING               1001
#define WL_USE_L_ORTHORHOMBIC           1002

// All the setup routines
command *setup_electronic_minimization(command *p);
command *setup_calculate_forces(command *p);
command *setup_relax_ions(command *p);
command *setup_ionic_dynamics(command *p);
command *setup_band_structure(command *p);
command *setup_spinorbit(command *p);
command *setup_dump_bands(command *p);
command *setup_finite_diff_test(command *p);
command *setup_lattice(command *p);
command *setup_latt_scale(command *p);
command *setup_ion(command *p);
command *setup_ion_species(command *p);
command *setup_coords_type(command *p);
command *setup_elec_cutoff(command *p);
command *setup_elec_n_bands(command *p);
command *setup_elec_fermi_fillings(command *p);
command *setup_elec_ex_corr(command *p);
command *setup_elec_initial_fillings(command *p);
command *setup_kpoint(command *p);
command *setup_kpoint_folding(command *p);
command *setup_spintype(command *p);
command *setup_ewald(command *p);
command *setup_cntrl_max_elec_steps(command *p);
command *setup_cntrl_elec_stepsize(command *p);
command *setup_cntrl_energy_convergence(command *p);
command *setup_cntrl_force_convergence(command *p);
command *setup_cntrl_force_diff_convergence(command *p);
command *setup_cntrl_force_diff_check(command *p);
command *setup_cntrl_update_stepsize(command *p);
command *setup_cntrl_stepsize_min(command *p);
command *setup_cntrl_nel_fermi_tol(command *p);
command *setup_cntrl_subspace_rotation(command *p);
command *setup_cntrl_dump_n(command *p);
command *setup_cntrl_algorithm(command *p);
command *setup_cntrl_max_ionic_steps(command *p);
command *setup_cntrl_read_density(command *p);
command *setup_cntrl_linmin_method(command *p);
command *setup_cntrl_read_vloc(command *p);
command *setup_cntrl_read_vscloc(command *p);
command *setup_wavefunction(command *p);
command *setup_ion_dynamics_param(command *p);
command *setup_ion_relax_param(command *p);
command *setup_fftbox(command *p);
command *setup_basis(command *p);
command *setup_symmetries(command *p);
command *setup_symmetry_matrix(command *p);
command *setup_gridspec(command *p);
command *setup_wl_embedding(command *p);
command *setup_wl_use_L_orthorhombic(command *p);

#endif // DFT_COMMAND_H
