diff --git a/configure.ac b/configure.ac index 4903a338..57394977 100644 --- a/configure.ac +++ b/configure.ac @@ -205,6 +205,19 @@ if test x$acx_massv_ok == xyes; then LIBS="$LIBS_MASSV $LIBS" fi +AC_MSG_NOTICE([ +================================================================================ + LIBXC LIBRARY +================================================================================]) + +ACX_LIBXC + +if test x$acx_libxc_ok == xyes; then + LIBS="$LIBS_LIBXC $LIBS" + CFLAGS="$CFLAGS $CFLAGS_LIBXC" + CXXFLAGS="$CXXFLAGS $CFLAGS_LIBXC" +fi + AC_MSG_NOTICE([ ================================================================================ CHECKING FOR BLUEGENE/Q LIBRARIES @@ -246,5 +259,6 @@ SCALAPACK : $acx_scalapack_ok ($LIBS_SCALAPACK) SCALAPACK 2 : $acx_scalapack2_ok MASSV : $acx_massv_ok BlueGene/Q : $acx_bgq +LIBXC : $acx_libxc_ok ]) diff --git a/m4/libxc.m4 b/m4/libxc.m4 new file mode 100644 index 00000000..914b3cc7 --- /dev/null +++ b/m4/libxc.m4 @@ -0,0 +1,33 @@ +AC_DEFUN([ACX_LIBXC], [ +acx_libxc_ok=no + +acx_libxc_save_CFLAGS="$CFLAGS" +acx_libxc_save_LIBS="$LIBS" + +AC_ARG_WITH(libxc-prefix, + [AC_HELP_STRING([--with-libxc-prefix], [directory where the libxc library is installed])]) + +LIBS="$acx_libxc_save_LIBS" +CFLAGS="$acx_libxc_save_CFLAGS" + +if test x"$with_libxc_prefix" != x; then + CFLAGS_LIBXC="-I$with_libxc_prefix/include" + LIBS_LIBXC="-L$with_libxc_prefix/lib" +else + LIBS_LIBXC="" +fi + +CFLAGS="$CFLAGS_LIBXC $CFLAGS" +LIBS="$LIBS_LIBXC $LIBS $FCLIBS" + +AC_CHECK_LIB(xc, xc_func_info_get_name, [acx_libxc_ok=yes], []) + +if test x"$acx_libxc_ok" == xyes ; then + LIBS_LIBXC="$LIBS_LIBXC -lxc" + AC_DEFINE(HAVE_LIBXC, 1, [Define if you have a LIBXC library.]) +fi + +LIBS="$acx_libxc_save_LIBS" +CFLAGS="$acx_libxc_save_CFLAGS" + +])dnl ACX_LIBXC diff --git a/src/LIBXCFunctional.C b/src/LIBXCFunctional.C new file mode 100644 index 00000000..324c83e2 --- /dev/null +++ b/src/LIBXCFunctional.C @@ -0,0 +1,276 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// LIBXCFunctional.C +// +// Interface of Libxc Exchange-correlation energy and potential +// +//////////////////////////////////////////////////////////////////////////////// +// $Id: LIBXCFunctional.C,v Yi Yao $ + + +#include +#include +#include +#include "LIBXCFunctional.h" +#include + +/* include Libxc's header file */ +#ifdef HAVE_LIBXC +#include "xc.h" +#endif + + +void LIBXCFunctional::setxc(void) +{ + +#ifdef HAVE_LIBXC + int numberofxc = func_ids_.size(); + double coeff_temp; + switch (_xcfamily) + { + case XC_FAMILY_LDA: + { + if ( _np == 0 ) return; + if ( _nspin == 1 ) + { + double exc_tmp; + double vxc_tmp; + assert(rho != 0); + assert(exc != 0); + assert(vxc1 != 0); + for ( int ir = 0; ir < _np; ir++ ) + { + exc[ir] = 0.0; + vxc1[ir] = 0.0; + } + for ( int ixc = 0; ixc < numberofxc; ixc ++ ) { + xc_func_init(&func_, func_ids_[ixc], XC_UNPOLARIZED); + coeff_temp = func_coeffs_[ixc]; + + for ( int ir = 0; ir < _np; ir++ ) + { + if ( rho[ir] < 0 ) continue; + xc_lda_exc_vxc(&func_, 1, &rho[ir], &exc_tmp, &vxc_tmp); + exc[ir] += exc_tmp * coeff_temp; + vxc1[ir] += vxc_tmp * coeff_temp; + //xc_unpolarized(rho[ir],exc[ir],vxc1[ir]); + } + xc_func_end(&func_); + } + } + else + { + // spin polarized + assert(rho_up != 0); + assert(rho_dn != 0); + assert(exc != 0); + assert(vxc1_up != 0); + assert(vxc1_dn != 0); + double exc_spin_temp; + double vxc_spin_temp[2]; + double rho_spin_temp[2]; + + for ( int ir = 0; ir < _np; ir++ ) + { + exc[ir] = 0.0; + vxc1_up[ir] = 0.0; + vxc1_dn[ir] = 0.0; + } + + for ( int ixc = 0; ixc < numberofxc; ixc ++ ) { + xc_func_init(&func_, func_ids_[ixc], XC_POLARIZED); + coeff_temp = func_coeffs_[ixc]; + + for ( int ir = 0; ir < _np; ir++ ) + { + rho_spin_temp[0] = rho_up[ir]; + rho_spin_temp[1] = rho_dn[ir]; + if (rho_spin_temp[0] < 0 ) rho_spin_temp[0] = 0.0; + if (rho_spin_temp[1] < 0 ) rho_spin_temp[1] = 0.0; + if (rho_spin_temp[0] + rho_spin_temp[1] < 0) continue; + + xc_lda_exc_vxc(&func_, 1, &rho_spin_temp[0], &exc_spin_temp, &vxc_spin_temp[0]); + + exc[ir] += exc_spin_temp * coeff_temp; + vxc1_up[ir] += vxc_spin_temp[0] * coeff_temp; + vxc1_dn[ir] += vxc_spin_temp[1] * coeff_temp; + //std::cout << exc_spin_temp << " " << vxc_spin_temp[0] << " " << vxc_spin_temp[1] << std::endl; + } + xc_func_end(&func_); + } + + } + } // end case XC_FAMILY_LDA + break; + case XC_FAMILY_GGA: + { + if ( _np == 0 ) return; + if ( _nspin == 1 ) + { + assert( rho != 0 ); + assert( grad_rho[0] != 0 && grad_rho[1] != 0 && grad_rho[2] != 0 ); + assert( exc != 0 ); + assert( vxc1 != 0 ); + assert( vxc2 != 0 ); + + for ( int ir = 0; ir < _np; ir++ ) + { + exc[ir] = 0.0; + vxc1[ir] = 0.0; + vxc2[ir] = 0.0; + } + double exc_temp, vxc_rho_temp, vxc_sigma_temp, sigma; + for ( int ixc = 0; ixc < numberofxc; ixc ++ ) { + + xc_func_init(&func_, func_ids_[ixc], XC_UNPOLARIZED); + coeff_temp = func_coeffs_[ixc]; + switch ( func_families_[ixc] ) + { + case XC_FAMILY_LDA: + for ( int ir = 0; ir < _np; ir++ ) + { + if ( rho[ir] < 0 ) continue; + xc_lda_exc_vxc(&func_, 1, &rho[ir], &exc_temp, &vxc_rho_temp); + exc[ir] += exc_temp * coeff_temp; + vxc1[ir] += vxc_rho_temp * coeff_temp; + } + break; + case XC_FAMILY_GGA: + case XC_FAMILY_HYB_GGA: + for ( int ir = 0; ir < _np; ir++ ) + { + if (rho[ir] < 1.e-18 ) continue; + //if (rho[ir] >= 1.e-18) { + sigma = (grad_rho[0][ir]*grad_rho[0][ir] + + grad_rho[1][ir]*grad_rho[1][ir] + + grad_rho[2][ir]*grad_rho[2][ir] ); + xc_gga_exc_vxc(&func_, 1, &rho[ir], &sigma, &exc_temp, &vxc_rho_temp, &vxc_sigma_temp); + exc[ir] += exc_temp * coeff_temp; + vxc1[ir] += vxc_rho_temp * coeff_temp; + vxc2[ir] += - vxc_sigma_temp * 2.0 * coeff_temp; + //} + } + break; + } + + xc_func_end(&func_); + } + } + else + { + // spin polarized + assert( rho_up != 0 ); + assert( rho_dn != 0 ); + assert( grad_rho_up[0] != 0 && grad_rho_up[1] != 0 && grad_rho_up[2] != 0 ); + assert( grad_rho_dn[0] != 0 && grad_rho_dn[1] != 0 && grad_rho_dn[2] != 0 ); + assert( exc_up != 0 ); + assert( exc_dn != 0 ); + assert( vxc1_up != 0 ); + assert( vxc1_dn != 0 ); + assert( vxc2_upup != 0 ); + assert( vxc2_updn != 0 ); + assert( vxc2_dnup != 0 ); + assert( vxc2_dndn != 0 ); + + double exc_spin_temp; + double vxc_spin_temp[2]; + double vsigma_spin_temp[3]; + double rho_spin_temp[2]; + double sigma_spin_temp[3]; + + for ( int ir = 0; ir < _np; ir++ ) + { + exc_up[ir] = 0.0; + exc_dn[ir] = 0.0; + vxc1_up[ir] = 0.0; + vxc1_dn[ir] = 0.0; + vxc2_upup[ir] = 0.0; + vxc2_dndn[ir] = 0.0; + vxc2_updn[ir] = 0.0; + vxc2_dnup[ir] = 0.0; + } + for ( int ixc = 0; ixc < numberofxc; ixc ++ ) { + xc_func_init(&func_, func_ids_[ixc], XC_POLARIZED); + coeff_temp = func_coeffs_[ixc]; + switch ( func_families_[ixc] ) + { + case XC_FAMILY_LDA: + { + for ( int ir = 0; ir < _np; ir++ ) + { + rho_spin_temp[0] = rho_up[ir]; + rho_spin_temp[1] = rho_dn[ir]; + if (rho_spin_temp[0] < 0 ) rho_spin_temp[0] = 0.0; + if (rho_spin_temp[1] < 0 ) rho_spin_temp[1] = 0.0; + if (rho_spin_temp[0] + rho_spin_temp[1] < 0) continue; + + xc_lda_exc_vxc(&func_, 1, &rho_spin_temp[0], &exc_spin_temp, &vxc_spin_temp[0]); + + exc_up[ir] += exc_spin_temp * coeff_temp; + exc_dn[ir] += exc_spin_temp * coeff_temp; + vxc1_up[ir] += vxc_spin_temp[0] * coeff_temp; + vxc1_dn[ir] += vxc_spin_temp[1] * coeff_temp; + } + } + break; + + case XC_FAMILY_GGA: + case XC_FAMILY_HYB_GGA: + { + for ( int ir = 0; ir < _np; ir++ ) + { + if (rho_up[ir] < 1.e-10 && rho_dn[ir] < 1.e-10 ) continue; + if (rho_up[ir] + rho_dn[ir] < 1.e-10 ) continue; + double grx_up = grad_rho_up[0][ir]; + double gry_up = grad_rho_up[1][ir]; + double grz_up = grad_rho_up[2][ir]; + double grx_dn = grad_rho_dn[0][ir]; + double gry_dn = grad_rho_dn[1][ir]; + double grz_dn = grad_rho_dn[2][ir]; + double grad_up2 = grx_up*grx_up + gry_up*gry_up + grz_up*grz_up; + double grad_dn2 = grx_dn*grx_dn + gry_dn*gry_dn + grz_dn*grz_dn; + double grad_up_grad_dn = grx_up*grx_dn + gry_up*gry_dn + grz_up*grz_dn; + //double grx = grx_up + grx_dn; + //double gry = gry_up + gry_dn; + //double grz = grz_up + grz_dn; + //double grad2 = grx*grx + gry*gry + grz*grz; + + rho_spin_temp[0] = rho_up[ir]; + rho_spin_temp[1] = rho_dn[ir]; + if ( rho_spin_temp[0] < 0.0 ) rho_spin_temp[0] = 0.0; + if ( rho_spin_temp[1] < 0.0 ) rho_spin_temp[1] = 0.0; + sigma_spin_temp[0] = grad_up2; + sigma_spin_temp[1] = grad_up_grad_dn; + sigma_spin_temp[2] = grad_dn2; + + xc_gga_exc_vxc(&func_, 1, &rho_spin_temp[0], &sigma_spin_temp[0], + &exc_spin_temp, &vxc_spin_temp[0], &vsigma_spin_temp[0]); + + + exc_up[ir] += exc_spin_temp * coeff_temp; + exc_dn[ir] += exc_spin_temp * coeff_temp; + vxc1_up[ir] += vxc_spin_temp[0] * coeff_temp; + vxc1_dn[ir] += vxc_spin_temp[1] * coeff_temp; + + // I am not sure about these lines. They are not the same as native functionals. + // However for PBE and BLYP the actual results are identical in real calculations. + // YY + vxc2_upup[ir] += -vsigma_spin_temp[0] * 2.0 * coeff_temp; + vxc2_updn[ir] += -vsigma_spin_temp[1] * 1.0 * coeff_temp; + vxc2_dnup[ir] += -vsigma_spin_temp[1] * 1.0 * coeff_temp; + vxc2_dndn[ir] += -vsigma_spin_temp[2] * 2.0 * coeff_temp; + } + } + break; + } + xc_func_end(&func_); + } + } + + } // end case XC_FAMILY_GGA + break; + + } // end switch +#endif +} + diff --git a/src/LIBXCFunctional.h b/src/LIBXCFunctional.h new file mode 100644 index 00000000..a780f26b --- /dev/null +++ b/src/LIBXCFunctional.h @@ -0,0 +1,219 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2008 The Regents of the University of California +// +// This file is part of Qbox +// +// Qbox is distributed 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. +// See the file COPYING in the root directory of this distribution +// or . +// +//////////////////////////////////////////////////////////////////////////////// +// +// LIBXCFunctional.h +// +//////////////////////////////////////////////////////////////////////////////// +// $Id: LIBXCFunctional.h,v Yi Yao $ +// +// usage: +// LDA: set xc LIBXC LDA_X LDA_C_PZ_MOD +// PBE: set xc LIBXC GGA_X_PBE:1.0 GGA_C_PBE:1.0 +// BLYP: set xc LIBXC GGA_X_B88:1.0 GGA_C_LYP:1.0 +// PBESOL: set xc LIBXC GGA_X_PBE_SOL:1.0 GGA_C_PBE_SOL:1.0 +// PBEREV: set xc LIBXC GGA_X_PBE_R:1.0 GGA_C_PBE:1.0 + +#include + +#ifndef LIBXCFUNCTIONAL_H +#define LIBXCFUNCTIONAL_H + +#include +#include +#include +#include +#include +using namespace std; +#include "XCFunctional.h" + +#ifdef HAVE_LIBXC +#include "xc.h" +#endif + +class LIBXCFunctional : public XCFunctional +{ + int _xcfamily; + // LDA + vector _exc; + vector > _vxc; + + // GGA + vector _exc_up, _exc_dn; + vector _vxc1, _vxc1_up, _vxc1_dn, + _vxc2, _vxc2_upup, _vxc2_updn, _vxc2_dnup, _vxc2_dndn; + vector _grad_rho[3], _grad_rho_up[3], _grad_rho_dn[3]; + + +#ifdef HAVE_LIBXC + xc_func_type func_; +#endif + vector func_ids_; + vector func_families_; + vector func_coeffs_; + + LIBXCFunctional(); + + public: + + LIBXCFunctional(const vector > &rhoe, + const string functional_full_name) + { +#ifdef HAVE_LIBXC + string tempbuf; + stringstream ss(functional_full_name); + string functional_name_temp; + double functional_coeff_temp; + int n = 0; + + _xcfamily = XC_FAMILY_LDA; + while ( ss >> tempbuf ) + { + if (n > 0) + { + functional_name_temp = + tempbuf.substr(0, tempbuf.find(":")); + functional_coeff_temp = + atof(tempbuf.substr( tempbuf.find(":")+1, + tempbuf.length()).c_str()); + if (functional_name_temp != "HF") { + func_ids_.push_back(xc_functional_get_number(functional_name_temp.c_str())); + func_coeffs_.push_back(functional_coeff_temp); + } + } + n++; + } + for (int i = 0; i < func_ids_.size();i ++) + func_families_.push_back(xc_family_from_id(func_ids_[i],NULL,NULL)); + + for (int i = 0; i < func_ids_.size();i ++) { + if (func_families_[i] == XC_FAMILY_GGA + || func_families_[i] == XC_FAMILY_HYB_GGA + ) + _xcfamily = XC_FAMILY_GGA; + } + for (int i = 0; i < func_ids_.size();i ++) { + if ( func_families_[i] == XC_FAMILY_MGGA + || func_families_[i] == XC_FAMILY_HYB_MGGA + ) + _xcfamily = XC_FAMILY_MGGA; + } + + switch (_xcfamily) + { + case XC_FAMILY_LDA: + { + _nspin = rhoe.size(); + if ( _nspin > 1 ) assert(rhoe[0].size() == rhoe[1].size()); + _np = rhoe[0].size(); + _exc.resize(_np); + _vxc.resize(_nspin); + for ( int i = 0; i < _nspin; i++ ) + { + _vxc[i].resize(_np); + } + + if ( _nspin == 1 ) + { + rho = &rhoe[0][0]; + exc = &_exc[0]; + vxc1 = &_vxc[0][0]; + } + else + { + rho_up = &rhoe[0][0]; + rho_dn = &rhoe[1][0]; + exc = &_exc[0]; + vxc1_up = &_vxc[0][0]; + vxc1_dn = &_vxc[1][0]; + } + } + break; + case XC_FAMILY_GGA: + { + { + _nspin = rhoe.size(); + if ( _nspin > 1 ) assert(rhoe[0].size() == rhoe[1].size()); + _np = rhoe[0].size(); + + if ( _nspin == 1 ) + { + _exc.resize(_np); + _vxc1.resize(_np); + _vxc2.resize(_np); + _grad_rho[0].resize(_np); + _grad_rho[1].resize(_np); + _grad_rho[2].resize(_np); + rho = &rhoe[0][0]; + grad_rho[0] = &_grad_rho[0][0]; + grad_rho[1] = &_grad_rho[1][0]; + grad_rho[2] = &_grad_rho[2][0]; + exc = &_exc[0]; + vxc1 = &_vxc1[0]; + vxc2 = &_vxc2[0]; + } + else + { + _exc_up.resize(_np); + _exc_dn.resize(_np); + _vxc1_up.resize(_np); + _vxc1_dn.resize(_np); + _vxc2_upup.resize(_np); + _vxc2_updn.resize(_np); + _vxc2_dnup.resize(_np); + _vxc2_dndn.resize(_np); + _grad_rho_up[0].resize(_np); + _grad_rho_up[1].resize(_np); + _grad_rho_up[2].resize(_np); + _grad_rho_dn[0].resize(_np); + _grad_rho_dn[1].resize(_np); + _grad_rho_dn[2].resize(_np); + + rho_up = &rhoe[0][0]; + rho_dn = &rhoe[1][0]; + grad_rho_up[0] = &_grad_rho_up[0][0]; + grad_rho_up[1] = &_grad_rho_up[1][0]; + grad_rho_up[2] = &_grad_rho_up[2][0]; + grad_rho_dn[0] = &_grad_rho_dn[0][0]; + grad_rho_dn[1] = &_grad_rho_dn[1][0]; + grad_rho_dn[2] = &_grad_rho_dn[2][0]; + exc_up = &_exc_up[0]; + exc_dn = &_exc_dn[0]; + vxc1_up = &_vxc1_up[0]; + vxc1_dn = &_vxc1_dn[0]; + vxc2_upup = &_vxc2_upup[0]; + vxc2_updn = &_vxc2_updn[0]; + vxc2_dnup = &_vxc2_dnup[0]; + vxc2_dndn = &_vxc2_dndn[0]; + } + } + + } + break; + } +#endif + }; + +#ifdef HAVE_LIBXC + bool isGGA() { if (_xcfamily == XC_FAMILY_LDA) + return false; + else + return true; + }; +#endif + + string name() { return "LIBXC"; }; + void setxc(void); +}; +#endif + diff --git a/src/Makefile.am b/src/Makefile.am index e125ae7f..6d6891df 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -128,6 +128,7 @@ noinst_HEADERS = \ jade.h \ JDWavefunctionStepper.h \ KpointCmd.h \ + LIBXCFunctional.h \ LDAFunctional.h \ LineMinimizer.h \ ListAtomsCmd.h \ @@ -298,6 +299,7 @@ libqbLink_a_SOURCES = \ SpeciesHandler.C \ XCPotential.C \ LDAFunctional.C \ + LIBXCFunctional.C \ PBEFunctional.C \ PBESolFunctional.C \ PBERevFunctional.C \ diff --git a/src/PBESolFunctional.C b/src/PBESolFunctional.C index c7914bf6..ab2cfde2 100644 --- a/src/PBESolFunctional.C +++ b/src/PBESolFunctional.C @@ -175,7 +175,7 @@ void PBESolFunctional::excpbe(double rho, double grad, double *exc, double *vxc1 const double third = 1.0 / 3.0; const double third4 = 4.0 / 3.0; const double ax = -0.7385587663820224058; /* -0.75*pow(3.0/pi,third) */ - const double um = 11. / 81.; /* see [c] */ + const double um = 10. / 81.; /* see [c] */ const double uk = 0.804; const double ul = um / uk; const double pi32third = 3.09366772628014; /* (3*pi^2 ) ^(1/3) */ @@ -293,7 +293,7 @@ void PBESolFunctional::excpbe_sp(double rho_up, double rho_dn, const double third4 = 4.0 / 3.0; const double sixthm = -1.0 / 6.0; const double ax = -0.7385587663820224058; /* -0.75*pow(3.0/pi,third) */ - const double um = 11. / 81.; /* see [c] */ + const double um = 10. / 81.; /* see [c] */ const double uk = 0.804; const double ul = um / uk; const double pi32third = 3.09366772628014; /* (3*pi^2 ) ^(1/3) */ diff --git a/src/SaveCmd.C b/src/SaveCmd.C index 1dadfc9b..767713ba 100644 --- a/src/SaveCmd.C +++ b/src/SaveCmd.C @@ -771,14 +771,14 @@ int SaveCmd::action(int argc, char **argv) { // write density data to file int cnt = 0; for (int ii = 0; ii < np0; ii++) { - const ip = (ii + np0/2) % np0; + const int ip = (ii + np0/2) % np0; ostringstream oss; oss.setf(ios::scientific,ios::floatfield); oss << setprecision(5); for (int jj = 0; jj < np1; jj++) { - const jp = (jj + np1/2) % np1; + const int jp = (jj + np1/2) % np1; for (int kk = 0; kk < np2; kk++) { - const kp = (kk + np2/2) % np2; + const int kp = (kk + np2/2) % np2; int index = ip + jp*np0 + kp*np0*np1; oss << tmprecv[index] << " "; cnt++; diff --git a/src/XCPotential.C b/src/XCPotential.C index 83a0b779..a0169d6f 100644 --- a/src/XCPotential.C +++ b/src/XCPotential.C @@ -29,6 +29,7 @@ #include #include "XCPotential.h" + #include "Basis.h" #include "FourierTransform.h" #include "blas.h" // daxpy, dcopy @@ -53,8 +54,18 @@ XCPotential::XCPotential(ChargeDensity& cd, const string functional_name, Charge } //////////////////////////////////////////////////////////////////////////////// -void XCPotential::initialize(string functional_name) +void XCPotential::initialize(string functional_name_input) { + + string functional_name; + string tempbuf; + stringstream ss(functional_name_input); + vector functional_full_name; + while ( ss >> tempbuf ) + functional_full_name.push_back(tempbuf); + + functional_name = functional_full_name[0]; + if ( functional_name == "LDA" ) { if (cd_.nlcc()) xcf_ = new LDAFunctional(cd_.xcrhor); @@ -85,6 +96,16 @@ void XCPotential::initialize(string functional_name) else xcf_ = new BLYPFunctional(cd_.rhor); } + else if ( functional_name == "LIBXC" ) + { +#ifdef HAVE_LIBXC + if (cd_.nlcc()) + xcf_ = new LIBXCFunctional(cd_.xcrhor, functional_name_input); + else + xcf_ = new LIBXCFunctional(cd_.rhor, functional_name_input); +#endif + } + else { throw XCPotentialException("unknown functional name"); } diff --git a/src/XCPotential.h b/src/XCPotential.h index 149f14c7..e3e0e04a 100644 --- a/src/XCPotential.h +++ b/src/XCPotential.h @@ -37,6 +37,11 @@ #include "PBESolFunctional.h" #include "PBERevFunctional.h" #include "BLYPFunctional.h" + +#ifdef HAVE_LIBXC +#include "LIBXCFunctional.h" +#endif + #include #include #include diff --git a/src/Xc.h b/src/Xc.h index b2437908..e772556b 100644 --- a/src/Xc.h +++ b/src/Xc.h @@ -38,6 +38,10 @@ #include "Sample.h" +#ifdef HAVE_LIBXC +#include "xc.h" +#endif + class Xc : public Var { Sample *s; @@ -48,15 +52,26 @@ class Xc : public Var int set ( int argc, char **argv ) { - if ( argc != 2 ) + string v; + v = argv[1]; +#ifdef HAVE_LIBXC + if ( (argc > 2) && (v == "LIBXC") ) { + for ( int n = 2; n < argc ; n ++ ) { + v = v + " " + argv[n]; + } + } +#else + if (false) { + } +#endif + else if ( argc != 2 ) { if ( ui->oncoutpe() ) cout << " xc takes only one value " << endl; return 1; } - string v = argv[1]; - if ( !( v == "LDA" || v == "PBE" || v == "PBEsol" || v == "PBErev" || v == "BLYP" ) ) + else if ( !( v == "LDA" || v == "PBE" || v == "PBEsol" || v == "PBErev" || v == "BLYP" ) ) { if ( ui->oncoutpe() ) cout << " xc must be LDA, PBE, PBEsol, PBErev or BLYP " << endl; @@ -72,9 +87,9 @@ class Xc : public Var { ostringstream st; st.setf(ios::left,ios::adjustfield); - st << setw(10) << name() << " = "; + st << setw(50) << name() << " = "; st.setf(ios::right,ios::adjustfield); - st << setw(10) << s->ctrl.xc; + st << setw(50) << s->ctrl.xc; return st.str(); }