31#include <rapidxml.hpp> 
   35namespace pseudopotential {
 
   37class upf2 : 
public pseudopotential::upf {
 
   40  upf2(
const std::string &filename, 
bool uniform_grid = 
false)
 
   41      : pseudopotential::upf(uniform_grid), file_(filename.c_str()),
 
   42        buffer_((std::istreambuf_iterator<char>(file_)),
 
   43                std::istreambuf_iterator<char>()) {
 
   47    buffer_.push_back(
'\0');
 
   48    doc_.parse<0>(&buffer_[0]);
 
   50    root_node_ = doc_.first_node(
"UPF");
 
   53      throw status::FORMAT_NOT_SUPPORTED;
 
   55    if (root_node_->first_attribute(
"version")->value()[0] != 
'2')
 
   56      throw status::FORMAT_NOT_SUPPORTED;
 
   58    std::string pseudo_type = root_node_->first_node(
"PP_HEADER")
 
   59                                  ->first_attribute(
"pseudo_type")
 
   62    if (pseudo_type == 
"NC" || pseudo_type == 
"SL") {
 
   63      type_ = pseudopotential::type::KLEINMAN_BYLANDER;
 
   64    } 
else if (pseudo_type == 
"USPP") {
 
   65      throw status::UNSUPPORTED_TYPE_ULTRASOFT;
 
   66    } 
else if (pseudo_type == 
"PAW") {
 
   67      throw status::UNSUPPORTED_TYPE_PAW;
 
   69      throw status::UNSUPPORTED_TYPE;
 
   76      rapidxml::xml_base<> *xmin =
 
   77          root_node_->first_node(
"PP_MESH")->first_attribute(
"xmin");
 
   80      if (xmin && 
fabs(value<double>(xmin)) > 1.0e-10)
 
   83      rapidxml::xml_node<> *node =
 
   84          root_node_->first_node(
"PP_MESH")->first_node(
"PP_R");
 
   88      rapidxml::xml_attribute<> *size_attr = node->first_attribute(
"size");
 
   91      if (size_attr == NULL)
 
   92        size_attr = root_node_->first_node(
"PP_MESH")->first_attribute(
"mesh");
 
   94      if (size_attr == NULL)
 
   95        throw status::FORMAT_NOT_SUPPORTED;
 
   97      int size = value<int>(size_attr);
 
   99      grid_.resize(size + start_point_);
 
  100      std::istringstream stst(node->value());
 
  102      for (
int ii = 0; ii < size; ii++)
 
  103        stst >> grid_[start_point_ + ii];
 
  105      assert(
fabs(grid_[0]) <= 1e-10);
 
  109      rapidxml::xml_node<> *node =
 
  110          root_node_->first_node(
"PP_MESH")->first_node(
"PP_RAB");
 
  114      int size = get_size(node);
 
  116      grid_weights_.resize(size + start_point_);
 
  117      std::istringstream stst(node->value());
 
  118      grid_weights_[0] = 0.5 * (grid_[1] - grid_[0]);
 
  119      for (
int ii = 0; ii < size; ii++)
 
  120        stst >> grid_weights_[start_point_ + ii];
 
  123      for (
double rr = 0.0; rr <= grid_[grid_.size() - 1]; rr += mesh_spacing())
 
  129    std::vector<bool> has_l(MAX_L, 
false);
 
  134    proj_l_.resize(nprojectors());
 
  135    proj_c_.resize(nprojectors());
 
  138    for (
int iproj = 0; iproj < nprojectors(); iproj++) {
 
  139      std::ostringstream tag;
 
  140      tag << 
"PP_BETA." << iproj + 1;
 
  141      rapidxml::xml_node<> *node =
 
  142          root_node_->first_node(
"PP_NONLOCAL")->first_node(tag.str().c_str());
 
  146      int read_l = value<int>(node->first_attribute(
"angular_momentum"));
 
  148      lmax_ = std::max(lmax_, read_l);
 
  149      proj_l_[iproj] = read_l;
 
  150      has_l[read_l] = 
true;
 
  155      for (
int jproj = 0; jproj < iproj; jproj++)
 
  156        if (read_l == proj_l_[jproj])
 
  159      nchannels_ = std::max(nchannels_, proj_c_[iproj] + 1);
 
  165    for (
int l = 0; 
l <= lmax_; 
l++)
 
  172      rapidxml::xml_node<> *node =
 
  173          root_node_->first_node(
"PP_NONLOCAL")->first_node(
"PP_DIJ");
 
  177      dij_.resize((lmax_ + 1) * nchannels_ * nchannels_);
 
  179      for (
unsigned kk = 0; kk < dij_.size(); kk++)
 
  182      std::istringstream stst(node->value());
 
  183      for (
int ii = 0; ii < nprojectors(); ii++) {
 
  184        for (
int jj = 0; jj < nprojectors(); jj++) {
 
  188          if (proj_l_[ii] != proj_l_[jj]) {
 
  189            assert(
fabs(val) < 1.0e-10);
 
  194          d_ij(proj_l_[ii], proj_c_[ii], proj_c_[jj]) = val;
 
  200  pseudopotential::format format()
 const {
 
  201    return pseudopotential::format::UPF2;
 
  204  int size()
 const { 
return buffer_.size(); };
 
  207    return root_node_->first_node(
"PP_INFO")->value();
 
  211    return element::trim(root_node_->first_node(
"PP_HEADER")
 
  212                             ->first_attribute(
"element")
 
  216  int atomic_number()
 const {
 
  217    element el(symbol());
 
  218    return el.atomic_number();
 
  221  double mass()
 const {
 
  222    element el(symbol());
 
  226  double valence_charge()
 const {
 
  227    return value<double>(
 
  228        root_node_->first_node(
"PP_HEADER")->first_attribute(
"z_valence"));
 
  231  pseudopotential::exchange exchange()
 const {
 
  232    std::string functional = root_node_->first_node(
"PP_HEADER")
 
  233                                 ->first_attribute(
"functional")
 
  235    if (functional == 
"PBE")
 
  236      return pseudopotential::exchange::PBE;
 
  237    if (functional == 
"PBESOL")
 
  238      return pseudopotential::exchange::PBE_SOL;
 
  239    if (functional == 
"SLA  PW   NOGX NOGC")
 
  240      return pseudopotential::exchange::LDA;
 
  241    if (functional == 
"BLYP")
 
  242      return pseudopotential::exchange::B88;
 
  243    return pseudopotential::exchange::UNKNOWN;
 
  246  pseudopotential::correlation correlation()
 const {
 
  247    std::string functional = root_node_->first_node(
"PP_HEADER")
 
  248                                 ->first_attribute(
"functional")
 
  250    if (functional == 
"PBE")
 
  251      return pseudopotential::correlation::PBE;
 
  252    if (functional == 
"PBESOL")
 
  253      return pseudopotential::correlation::PBE_SOL;
 
  254    if (functional == 
"SLA  PW   NOGX NOGC")
 
  255      return pseudopotential::correlation::LDA_PW;
 
  256    if (functional == 
"BLYP")
 
  257      return pseudopotential::correlation::LYP;
 
  258    return pseudopotential::correlation::UNKNOWN;
 
  261  void local_potential(std::vector<double> &potential)
 const {
 
  262    rapidxml::xml_node<> *node = root_node_->first_node(
"PP_LOCAL");
 
  266    int size = get_size(node);
 
  268    potential.resize(size + start_point_);
 
  269    std::istringstream stst(node->value());
 
  270    for (
int ii = 0; ii < size; ii++) {
 
  271      stst >> potential[ii + start_point_];
 
  272      potential[ii + start_point_] *= 0.5; 
 
  274    if (start_point_ > 0)
 
  275      extrapolate_first_point(potential);
 
  277    interpolate(potential);
 
  280  int nprojectors()
 const {
 
  282        root_node_->first_node(
"PP_HEADER")->first_attribute(
"number_of_proj"));
 
  285  int nprojectors_per_l(
int l)
 const {
 
  288    for (
int jproj = 0; jproj < nprojectors(); jproj++)
 
  289        if (proj_l_[jproj] == 
l)
 
  290          nchannel = std::max(proj_c_[jproj]+1, nchannel);
 
  294  void projector(
int l, 
int i, std::vector<double> &proj)
 const {
 
  295    rapidxml::xml_node<> *node = NULL;
 
  298    while ((
l != proj_l_[iproj] || 
i != proj_c_[iproj]) && iproj < nprojectors()) {
 
  301    std::stringstream tag;
 
  302    tag << 
"PP_BETA." << iproj+1;
 
  303    node = root_node_->first_node(
"PP_NONLOCAL")->first_node(tag.str().c_str());
 
  307    int size = get_size(node);
 
  309    proj.resize(size + start_point_);
 
  310    std::istringstream stst(node->value());
 
  311    for (
int ii = 0; ii < size; ii++)
 
  312      stst >> proj[ii + start_point_];
 
  316    for (
int ii = 1; ii < size + start_point_; ii++)
 
  317      proj[ii] /= grid_[ii];
 
  318    extrapolate_first_point(proj);
 
  323  bool has_radial_function(
int l)
 const { 
return false; }
 
  325  void radial_function(
int l, std::vector<double> &function)
 const {
 
  329  void radial_potential(
int l, std::vector<double> &function)
 const {
 
  333  bool has_nlcc()
 const { 
return root_node_->first_node(
"PP_NLCC"); }
 
  335  void nlcc_density(std::vector<double> &
density)
 const {
 
  336    rapidxml::xml_node<> *node = root_node_->first_node(
"PP_NLCC");
 
  339    int size = get_size(node);
 
  341    density.resize(size + start_point_);
 
  343    std::istringstream stst(node->value());
 
  344    for (
int ii = 0; ii < size; ii++)
 
  345      stst >> 
density[start_point_ + ii];
 
  346    extrapolate_first_point(
density);
 
  352  bool has_total_angular_momentum()
 const {
 
  353    return root_node_->first_node(
"PP_SPIN_ORB");
 
  356  void beta(
int iproj, 
int &
l, std::vector<double> &proj)
 const {
 
  357    rapidxml::xml_node<> *node = NULL;
 
  359    std::stringstream tag;
 
  360    tag << 
"PP_BETA." << iproj + 1;
 
  361    node = root_node_->first_node(
"PP_NONLOCAL")->first_node(tag.str().c_str());
 
  365    l = value<int>(node->first_attribute(
"angular_momentum"));
 
  367    int size = get_size(node);
 
  369    proj.resize(size + start_point_);
 
  370    std::istringstream stst(node->value());
 
  371    for (
int ii = 0; ii < size; ii++)
 
  372      stst >> proj[ii + start_point_];
 
  376    for (
int ii = 1; ii < size + start_point_; ii++)
 
  377      proj[ii] /= grid_[ii];
 
  378    extrapolate_first_point(proj);
 
  383  void dnm_zero(
int nbeta, std::vector<std::vector<double>> &dnm)
 const {
 
  385    for (
int i = 0; 
i < nbeta; 
i++) {
 
  386      dnm[
i].resize(nbeta);
 
  387      for (
int j = 0; 
j < nbeta; 
j++) {
 
  388        dnm[
i][
j] = dij_[
i * nbeta + 
j];
 
  393  bool has_density()
 const { 
return root_node_->first_node(
"PP_RHOATOM"); }
 
  395  void density(std::vector<double> &val)
 const {
 
  396    rapidxml::xml_node<> *node = root_node_->first_node(
"PP_RHOATOM");
 
  399    int size = get_size(node);
 
  401    val.resize(size + start_point_);
 
  403    std::istringstream stst(node->value());
 
  404    for (
int ii = 0; ii < size; ii++)
 
  405      stst >> val[start_point_ + ii];
 
  408    for (
int ii = 1; ii < size + start_point_; ii++)
 
  409      val[ii] /= 4.0 * M_PI * grid_[ii] * grid_[ii];
 
  410    extrapolate_first_point(val);
 
  415  int nwavefunctions()
 const {
 
  417        root_node_->first_node(
"PP_HEADER")->first_attribute(
"number_of_wfc"));
 
  420  void wavefunction(
int index, 
int &n, 
int &
l, 
double &occ,
 
  421                    std::vector<double> &proj)
 const {
 
  422    rapidxml::xml_node<> *node = NULL;
 
  424    std::stringstream tag;
 
  425    tag << 
"PP_CHI." << 
index + 1;
 
  426    node = root_node_->first_node(
"PP_PSWFC")->first_node(tag.str().c_str());
 
  431    if (node->first_attribute(
"n")) {
 
  432      n = value<int>(node->first_attribute(
"n"));
 
  434      std::string label = node->first_attribute(
"label")->value();
 
  435      n = atoi(label.substr(0, 1).c_str());
 
  438    l = value<int>(node->first_attribute(
"l"));
 
  440    occ = value<double>(node->first_attribute(
"occupation"));
 
  442    int size = get_size(node);
 
  444    proj.resize(size + start_point_);
 
  445    std::istringstream stst(node->value());
 
  446    for (
int ii = 0; ii < size; ii++)
 
  447      stst >> proj[ii + start_point_];
 
  451    for (
int ii = 1; ii < size + start_point_; ii++)
 
  452      proj[ii] /= grid_[ii];
 
  453    extrapolate_first_point(proj);
 
  459  int projector_2j(
int l, 
int ic)
 const {
 
  464    for (
int iproj = 0; iproj < nprojectors(); iproj++) {
 
  465      std::stringstream tag;
 
  466      tag << 
"PP_RELBETA." << iproj + 1;
 
  468      rapidxml::xml_node<> *node =
 
  469          root_node_->first_node(
"PP_SPIN_ORB")->first_node(tag.str().c_str());
 
  472      std::string labell = node->first_attribute(
"lll")->value();
 
  473      if(atoi(labell.c_str()) == 
l && proj_c_[iproj] == ic){
 
  474        std::string labelj = node->first_attribute(
"jjj")->value();
 
  475        float j = atof(labelj.c_str());
 
  477        return lrint(
j * 2.0);
 
  486  int wavefunction_2j(
int ii)
 const {
 
  488    std::stringstream tag;
 
  489    tag << 
"PP_RELWFC." << ii;
 
  491    rapidxml::xml_node<> *node =
 
  492          root_node_->first_node(
"PP_SPIN_ORB")->first_node(tag.str().c_str());
 
  495    std::string label = node->first_attribute(
"jchi")->value();
 
  496    float j = atof(label.c_str());
 
  498    return lrint(
j * 2.0);
 
  503  int get_size(
const rapidxml::xml_node<> *node)
 const {
 
  504    int size = grid_.size() - start_point_;
 
  506    rapidxml::xml_attribute<> *size_attr = node->first_attribute(
"size");
 
  508    if (size_attr != NULL)
 
  509      size = value<int>(size_attr);
 
  515  std::vector<char> buffer_;
 
  516  rapidxml::xml_document<> doc_;
 
  517  rapidxml::xml_node<> *root_node_;
 
  518  std::vector<int> proj_l_;
 
  519  std::vector<int> proj_c_;
 
if write to the Free Software Franklin Fifth USA !If the compiler accepts long Fortran it is better to use that and build all the preprocessor definitions in one line In !this the debuggers will provide the right line numbers !If the compiler accepts line number then CARDINAL and ACARDINAL !will put them just a new line or a ampersand plus a new line !These macros should be used in macros that span several lines They should by !put immedialty before a line where a compilation error might occur and at the !end of the macro !Note that the cardinal and newline words are substituted by the program !preprocess pl by the ampersand and by a real new line just before compilation !The assertions are ignored if the code is compiled in not debug when !prints out the assertion string
 
double fabs(double __x) __attribute__((__nothrow__
 
integer, parameter, public density
 
integer, parameter, public mass
 
const int *restrict index