31#include <rapidxml.hpp> 
   35namespace pseudopotential {
 
   37class upf1 : 
public pseudopotential::upf {
 
   40  upf1(
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    std::istringstream header(doc_.first_node(
"PP_HEADER")->value());
 
   55    header >> version_number;
 
   56    getline(header, line);
 
   59    symbol_ = element::trim(symbol_);
 
   60    getline(header, line);
 
   63    header >> pseudo_type;
 
   64    getline(header, line);
 
   67    getline(header, line);
 
   69    getline(header, xc_functional_);
 
   72    getline(header, line);
 
   75    getline(header, line);
 
   78    getline(header, line);
 
   81    getline(header, line);
 
   85    getline(header, line);
 
   87    header >> nwavefunctions_;
 
   88    header >> nprojectors_;
 
   89    getline(header, line);
 
   91    std::transform(pseudo_type.begin(), pseudo_type.end(), pseudo_type.begin(),
 
   94    if (pseudo_type == 
"nc" || pseudo_type == 
"sl") {
 
   95      type_ = pseudopotential::type::KLEINMAN_BYLANDER;
 
   96    } 
else if (pseudo_type == 
"uspp") {
 
   97      throw status::UNSUPPORTED_TYPE_ULTRASOFT;
 
   98    } 
else if (pseudo_type == 
"paw") {
 
   99      throw status::UNSUPPORTED_TYPE_PAW;
 
  101      throw status::UNSUPPORTED_TYPE;
 
  106      rapidxml::xml_node<> *node =
 
  107          doc_.first_node(
"PP_MESH")->first_node(
"PP_R");
 
  110      std::istringstream stst(node->value());
 
  120      grid_.resize(size + start_point_);
 
  123      grid_[start_point_] = xmin;
 
  124      for (
int ii = 0; ii < size - 1; ii++)
 
  125        stst >> grid_[1 + start_point_ + ii];
 
  127      assert(
fabs(grid_[0]) <= 1e-10);
 
  130      for (
double rr = 0.0; rr <= grid_[grid_.size() - 1]; rr += mesh_spacing())
 
  135      rapidxml::xml_node<> *node =
 
  136          doc_.first_node(
"PP_MESH")->first_node(
"PP_R");
 
  139      std::istringstream stst(node->value());
 
  141      grid_weights_.resize(size + start_point_);
 
  143      grid_weights_[0] = 0.5 * (grid_[1] - grid_[0]);
 
  144      for (
int ii = 0; ii < size; ii++)
 
  145        stst >> grid_weights_[start_point_ + ii];
 
  151      proj_l_.resize(nprojectors());
 
  152      proj_c_.resize(nprojectors());
 
  154      rapidxml::xml_node<> *node =
 
  155          doc_.first_node(
"PP_NONLOCAL")->first_node(
"PP_BETA");
 
  157      std::vector<bool> has_l(MAX_L, 
false);
 
  165        std::istringstream stst(node->value());
 
  169        stst >> read_i >> read_l;
 
  173        assert(iproj == read_i);
 
  175        lmax_ = std::max(lmax_, read_l);
 
  176        has_l[read_l] = 
true;
 
  177        proj_l_[iproj] = read_l;
 
  179        for (
int jproj = 0; jproj < iproj; jproj++)
 
  180          if (read_l == proj_l_[jproj])
 
  183        nchannels_ = std::max(nchannels_, proj_c_[iproj] + 1);
 
  185        node = node->next_sibling(
"PP_BETA");
 
  192      for (
int l = 0; 
l <= lmax_; 
l++)
 
  199      rapidxml::xml_node<> *node =
 
  200          doc_.first_node(
"PP_NONLOCAL")->first_node(
"PP_DIJ");
 
  204      dij_.resize(nchannels() * nchannels() * (lmax_ + 1));
 
  206      for (
unsigned kk = 0; kk < dij_.size(); kk++)
 
  209      std::istringstream stst(node->value());
 
  216      for (
int kk = 0; kk < nnonzero; kk++) {
 
  219        stst >> ii >> jj >> val;
 
  224        assert(proj_l_[ii] == proj_l_[jj]);
 
  226        d_ij(proj_l_[ii], proj_c_[ii], proj_c_[jj]) = val;
 
  231  pseudopotential::format format()
 const {
 
  232    return pseudopotential::format::UPF2;
 
  235  int size()
 const { 
return buffer_.size(); };
 
  238    return doc_.first_node(
"PP_INFO")->value();
 
  243  int atomic_number()
 const {
 
  244    element el(symbol());
 
  245    return el.atomic_number();
 
  248  double mass()
 const {
 
  249    element el(symbol());
 
  253  double valence_charge()
 const { 
return zval_; }
 
  255  pseudopotential::exchange exchange()
 const {
 
  256    if (xc_functional_ == 
"PBE")
 
  257      return pseudopotential::exchange::PBE;
 
  258    if (xc_functional_ == 
"PBESOL")
 
  259      return pseudopotential::exchange::PBE_SOL;
 
  260    if (xc_functional_ == 
"SLA  PW   NOGX NOGC")
 
  261      return pseudopotential::exchange::LDA;
 
  262    if (xc_functional_ == 
"BLYP")
 
  263      return pseudopotential::exchange::B88;
 
  264    return pseudopotential::exchange::UNKNOWN;
 
  267  pseudopotential::correlation correlation()
 const {
 
  268    if (xc_functional_ == 
"PBE")
 
  269      return pseudopotential::correlation::PBE;
 
  270    if (xc_functional_ == 
"PBESOL")
 
  271      return pseudopotential::correlation::PBE_SOL;
 
  272    if (xc_functional_ == 
"SLA  PW   NOGX NOGC")
 
  273      return pseudopotential::correlation::LDA_PW;
 
  274    if (xc_functional_ == 
"BLYP")
 
  275      return pseudopotential::correlation::LYP;
 
  276    return pseudopotential::correlation::UNKNOWN;
 
  279  void local_potential(std::vector<double> &potential)
 const {
 
  280    rapidxml::xml_node<> *node = doc_.first_node(
"PP_LOCAL");
 
  284    potential.resize(grid_.size());
 
  285    std::istringstream stst(node->value());
 
  286    for (
unsigned ii = 0; ii < grid_.size() - start_point_; ii++) {
 
  287      stst >> potential[ii + start_point_];
 
  288      potential[ii + start_point_] *= 0.5; 
 
  290    if (start_point_ > 0)
 
  291      extrapolate_first_point(potential);
 
  293    interpolate(potential);
 
  296  int nprojectors()
 const { 
return nprojectors_; }
 
  298  int nprojectors_per_l(
int l)
 const {
 
  301    for (
int jproj = 0; jproj < nprojectors(); jproj++)
 
  302        if (proj_l_[jproj] == 
l)
 
  303          nchannel = std::max(proj_c_[jproj]+1, nchannel);
 
  308  void projector(
int l, 
int i, std::vector<double> &proj)
 const {
 
  311    rapidxml::xml_node<> *node =
 
  312        doc_.first_node(
"PP_NONLOCAL")->first_node(
"PP_BETA");
 
  317    while (
l != proj_l_[iproj] || 
i != proj_c_[iproj]) {
 
  319      node = node->next_sibling(
"PP_BETA");
 
  326    std::istringstream stst(node->value());
 
  328    int read_i, read_l, size;
 
  330    stst >> read_i >> read_l;
 
  333    assert(read_l == proj_l_[iproj]);
 
  339    assert(size <= 
int(grid_.size()));
 
  341    proj.resize(grid_.size());
 
  343    for (
int ii = 0; ii < size; ii++)
 
  344      stst >> proj[ii + start_point_];
 
  345    for (
unsigned ii = size; ii < grid_.size() - start_point_; ii++)
 
  346      proj[ii + start_point_] = 0.0;
 
  350    for (
unsigned ii = 1; ii < proj.size(); ii++)
 
  351      proj[ii] /= 2.0 * grid_[ii];
 
  352    extrapolate_first_point(proj);
 
  357  bool has_radial_function(
int l)
 const { 
return false; }
 
  359  void radial_function(
int l, std::vector<double> &function)
 const {
 
  363  void radial_potential(
int l, std::vector<double> &function)
 const {
 
  367  bool has_nlcc()
 const { 
return doc_.first_node(
"PP_NLCC"); }
 
  369  void nlcc_density(std::vector<double> &
density)
 const {
 
  370    rapidxml::xml_node<> *node = doc_.first_node(
"PP_NLCC");
 
  372    std::istringstream stst(node->value());
 
  376    for (
unsigned ii = 0; ii < grid_.size() - start_point_; ii++)
 
  377      stst >> 
density[start_point_ + ii];
 
  378    extrapolate_first_point(
density);
 
  384  bool has_density()
 const { 
return doc_.first_node(
"PP_RHOATOM"); }
 
  386  void density(std::vector<double> &val)
 const {
 
  387    rapidxml::xml_node<> *node = doc_.first_node(
"PP_RHOATOM");
 
  390    val.resize(grid_.size());
 
  392    std::istringstream stst(node->value());
 
  393    for (
unsigned ii = 0; ii < grid_.size() - start_point_; ii++)
 
  394      stst >> val[start_point_ + ii];
 
  397    for (
unsigned ii = 1; ii < val.size(); ii++)
 
  398      val[ii] /= 4.0 * M_PI * grid_[ii] * grid_[ii];
 
  399    extrapolate_first_point(val);
 
  404  int nwavefunctions()
 const { 
return nwavefunctions_; }
 
  406  void wavefunction(
int index, 
int &n, 
int &
l, 
double &occ,
 
  407                    std::vector<double> &proj)
 const {
 
  408    rapidxml::xml_node<> *node = doc_.first_node(
"PP_PSWFC");
 
  412    std::istringstream stst(node->value());
 
  417    for (
int ii = 0; ii < 
index; ii++) {
 
  422      for (
unsigned ii = 0; ii < grid_.size() - start_point_; ii++)
 
  427    stst >> label >> 
l >> occ;
 
  433      n = atoi(label.substr(0, 1).c_str());
 
  436    proj.resize(grid_.size());
 
  438    for (
unsigned ii = 0; ii < grid_.size() - start_point_; ii++)
 
  439      stst >> proj[ii + start_point_];
 
  443    for (
unsigned ii = 1; ii < grid_.size() - start_point_; ii++)
 
  444      proj[ii] /= grid_[ii];
 
  445    extrapolate_first_point(proj);
 
  450  bool has_total_angular_momentum()
 const {
 
  451    return doc_.first_node(
"PP_ADDINFO");
 
  454  int projector_2j(
int l, 
int ic)
 const {
 
  459    rapidxml::xml_node<> *node = doc_.first_node(
"PP_ADDINFO");
 
  462    std::istringstream stst(node->value());
 
  464    for (
int iwf = 0; iwf < nwavefunctions_; iwf++) {
 
  470    for (
int iproj = 0; iproj < nprojectors_; iproj++) {
 
  475      assert(read_l == proj_l_[iproj]);
 
  477      if (proj_l_[iproj] == 
l && proj_c_[iproj] == ic) {
 
  480        return lrint(read_j * 2.0);
 
  491  int wavefunction_2j(
int ii)
 const {
 
  493    assert(ii >= 0 && ii <= nwavefunctions_);
 
  495    rapidxml::xml_node<> *node = doc_.first_node(
"PP_ADDINFO");
 
  498    std::istringstream stst(node->value());
 
  501    for (
int iwf = 0; iwf < ii; iwf++) {
 
  505      stst >> label >> n >> 
l >> 
j >> occ;
 
  508    return lrint(
j * 2.0);
 
  513  std::vector<char> buffer_;
 
  514  rapidxml::xml_document<> doc_;
 
  521  std::vector<int> proj_l_;
 
  522  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