32namespace pseudopotential {
 
   34class psp8 : 
public pseudopotential::base {
 
   41    std::ifstream original_file(filename.c_str());
 
   42    std::string buffer((std::istreambuf_iterator<char>(original_file)),
 
   43                       std::istreambuf_iterator<char>());
 
   44    std::replace(buffer.begin(), buffer.end(), 
'D', 
'E');
 
   45    std::replace(buffer.begin(), buffer.end(), 
'd', 
'e');
 
   47    std::istringstream 
file(buffer);
 
   49    type_ = pseudopotential::type::KLEINMAN_BYLANDER;
 
   52    file.seekg(0, std::ios::beg);
 
   53    std::streampos file_size_ = 
file.tellg();
 
   54    file.seekg(0, std::ios::end);
 
   55    file_size_ = 
file.tellg() - file_size_;
 
   58    file.seekg(0, std::ios::beg);
 
   62    getline(
file, description_);
 
   67    atomic_number_ = round(val);
 
   68    file >> valence_charge_;
 
   73    file >> pspcod >> ixc_ >> lmax_ >> llocal_ >> mesh_size_;
 
   75      throw status::UNKNOWN_FORMAT;
 
   87    for (
int l = 0; 
l <= lmax_; 
l++) {
 
   90      nprojl_.push_back(np);
 
   92      nchannels_ = std::max(nchannels_, np);
 
   98    file >> extension_switch;
 
  100    has_density_ = extension_switch == 1;
 
  101    has_soc_ = extension_switch == 2;
 
  107    if (extension_switch > 2)
 
  108      throw status::FORMAT_NOT_SUPPORTED;
 
  111    projectors_.resize(lmax_ + 1);
 
  112    ekb_.resize(lmax_ + 1);
 
  113    for (
int l = 0; 
l <= lmax_; 
l++) {
 
  114      projectors_[
l].resize(nprojl_[
l]);
 
  115      ekb_[
l].resize(nprojl_[
l]);
 
  118        read_local_potential(
file);
 
  130      for (
int iproj = 0; iproj < nprojl_[
l]; iproj++) {
 
  131        projectors_[
l][iproj].resize(mesh_size_);
 
  132        file >> ekb_[
l][iproj];
 
  136      for (
int ip = 0; ip < mesh_size_; ip++) {
 
  139        file >> read_ip >> grid_point;
 
  141        assert(read_ip == ip + 1);
 
  143        for (
int iproj = 0; iproj < nprojl_[
l]; iproj++)
 
  144          file >> projectors_[
l][iproj][ip];
 
  151      read_local_potential(
file);
 
  155      nlcc_density_.resize(mesh_size_);
 
  157      for (
int ip = 0; ip < mesh_size_; ip++) {
 
  160        file >> read_ip >> grid_point >> nlcc_density_[ip];
 
  161        assert(read_ip == ip + 1);
 
  166    if (extension_switch == 1) {
 
  168      density_.resize(mesh_size_);
 
  170      for (
int ip = 0; ip < mesh_size_; ip++) {
 
  173        file >> read_ip >> grid_point >> density_[ip];
 
  174        assert(read_ip == ip + 1);
 
  180  pseudopotential::format format()
 const {
 
  181    return pseudopotential::format::PSP8;
 
  184  int size()
 const { 
return file_size_; };
 
  186  std::string description()
 const { 
return description_; }
 
  189    pseudopotential::element el(atomic_number_);
 
  193  int atomic_number()
 const { 
return atomic_number_; }
 
  195  double mass()
 const {
 
  196    pseudopotential::element el(atomic_number_);
 
  200  double valence_charge()
 const { 
return valence_charge_; }
 
  202  pseudopotential::exchange exchange()
 const {
 
  205        return pseudopotential::exchange::NONE;
 
  206      if (ixc_ >= 2 && ixc_ <= 9)
 
  207        return pseudopotential::exchange::LDA;
 
  208      if (ixc_ == 11 || ixc_ == 12)
 
  209        return pseudopotential::exchange::PBE;
 
  211      return pseudopotential::exchange((-ixc_ + ixc_ % 1000) / 1000);
 
  214    return pseudopotential::exchange::UNKNOWN;
 
  217  pseudopotential::correlation correlation()
 const {
 
  220        return pseudopotential::correlation::LDA_XC_TETER93;
 
  222        return pseudopotential::correlation::LDA_PZ;
 
  224        return pseudopotential::correlation::LDA_PW;
 
  225      if (ixc_ == 7 || ixc_ == 8)
 
  226        return pseudopotential::correlation::NONE;
 
  228        return pseudopotential::correlation::PBE;
 
  230        return pseudopotential::correlation::NONE;
 
  232      return pseudopotential::correlation(-ixc_ % 1000);
 
  235    return pseudopotential::correlation::UNKNOWN;
 
  244  int nchannels()
 const { 
return nchannels_; }
 
  246  double mesh_spacing()
 const { 
return mesh_spacing_; }
 
  248  int mesh_size()
 const { 
return mesh_size_; }
 
  250  void local_potential(std::vector<double> &potential)
 const {
 
  251    potential.resize(mesh_size_);
 
  252    assert(mesh_size_ == local_potential_.size());
 
  253    for (
int ip = 0; ip < mesh_size_; ip++)
 
  254      potential[ip] = local_potential_[ip];
 
  257  int nprojectors()
 const { 
return nprojectors_; }
 
  259  int nprojectors_per_l(
int l)
 const { 
 
  263  void projector(
int l, 
int i, std::vector<double> &proj)
 const {
 
  271    proj.resize(mesh_size_);
 
  272    assert(mesh_size_ == projectors_[
l][
i].size());
 
  274    for (
int ip = 1; ip < mesh_size_; ip++)
 
  275      proj[ip] = projectors_[
l][
i][ip] / (mesh_spacing() * ip);
 
  277    extrapolate_first_point(proj);
 
  280  double d_ij(
int l, 
int i, 
int j)
 const {
 
  288  bool has_radial_function(
int l)
 const { 
return false; }
 
  290  void radial_function(
int l, std::vector<double> &function)
 const {
 
  294  void radial_potential(
int l, std::vector<double> &function)
 const {
 
  298  bool has_nlcc()
 const { 
return nlcc_; }
 
  300  bool has_total_angular_momentum()
 const { 
return has_soc_;  }
 
  302  void nlcc_density(std::vector<double> &
density)
 const {
 
  304    assert(mesh_size_ == nlcc_density_.size());
 
  305    for (
int ip = 0; ip < mesh_size_; ip++)
 
  306      density[ip] = nlcc_density_[ip] / (4.0 * M_PI);
 
  309  bool has_density()
 const { 
return has_density_; }
 
  313    assert(mesh_size_ == density_.size());
 
  314    for (
int ip = 0; ip < mesh_size_; ip++)
 
  315      density[ip] = density_[ip] / (4.0 * M_PI);
 
  319  void extrapolate_first_point(std::vector<double> &function_)
 const {
 
  321    assert(function_.size() >= 4);
 
  323    double x1 = mesh_spacing();
 
  324    double x2 = 2 * mesh_spacing();
 
  325    double x3 = 3 * mesh_spacing();
 
  326    double f1 = function_[1];
 
  327    double f2 = function_[2];
 
  328    double f3 = function_[3];
 
  333    function_[0] = 
f1 * x2 * x3 * (x2 - x3) + 
f2 * x1 * x3 * (x3 - x1) +
 
  334                   f3 * x1 * x2 * (x1 - x2);
 
  335    function_[0] /= (x1 - x2) * (x1 - x3) * (x2 - x3);
 
  338  void read_local_potential(std::istream &
file) {
 
  344    assert(llocal_ == read_llocal);
 
  347    local_potential_.resize(mesh_size_);
 
  348    for (
int ip = 0; ip < mesh_size_; ip++) {
 
  351      file >> read_ip >> grid_point >> local_potential_[ip];
 
  352      assert(read_ip == ip + 1);
 
  356        mesh_spacing_ = grid_point;
 
  364  double valence_charge_;
 
  369  double mesh_spacing_;
 
  370  std::vector<int> nprojl_;
 
  372  std::vector<std::vector<std::vector<double>>> projectors_;
 
  373  std::vector<std::vector<double>> ekb_;
 
  374  std::vector<double> local_potential_;
 
  376  std::vector<double> nlcc_density_;
 
  378  std::vector<double> density_;
 
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 the file
 
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
 
integer, parameter, public density
 
integer, parameter, public mass