
.. _program_listing_file_cif++_atom_type.hpp:

Program Listing for File atom_type.hpp
======================================

|exhale_lsh| :ref:`Return to documentation for file <file_cif++_atom_type.hpp>` (``cif++/atom_type.hpp``)

.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS

.. code-block:: cpp

   /*-
    * SPDX-License-Identifier: BSD-2-Clause
    *
    * Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions are met:
    *
    * 1. Redistributions of source code must retain the above copyright notice, this
    *    list of conditions and the following disclaimer
    * 2. Redistributions in binary form must reproduce the above copyright notice,
    *    this list of conditions and the following disclaimer in the documentation
    *    and/or other materials provided with the distribution.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
    * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */
   
   #pragma once
   
   #include "cif++/exports.hpp"
   
   #include <cstdint>
   #include <limits>
   #include <stdexcept>
   #include <string>
   
   namespace cif
   {
   
   enum atom_type : uint8_t
   {
       Nn = 0, 
   
       H = 1,  
       He = 2, 
   
       Li = 3,  
       Be = 4,  
       B = 5,   
       C = 6,   
       N = 7,   
       O = 8,   
       F = 9,   
       Ne = 10, 
   
       Na = 11, 
       Mg = 12, 
       Al = 13, 
       Si = 14, 
       P = 15,  
       S = 16,  
       Cl = 17, 
       Ar = 18, 
   
       K = 19,  
       Ca = 20, 
       Sc = 21, 
       Ti = 22, 
       V = 23,  
       Cr = 24, 
       Mn = 25, 
       Fe = 26, 
       Co = 27, 
       Ni = 28, 
       Cu = 29, 
       Zn = 30, 
       Ga = 31, 
       Ge = 32, 
       As = 33, 
       Se = 34, 
       Br = 35, 
       Kr = 36, 
   
       Rb = 37, 
       Sr = 38, 
       Y = 39,  
       Zr = 40, 
       Nb = 41, 
       Mo = 42, 
       Tc = 43, 
       Ru = 44, 
       Rh = 45, 
       Pd = 46, 
       Ag = 47, 
       Cd = 48, 
       In = 49, 
       Sn = 50, 
       Sb = 51, 
       Te = 52, 
       I = 53,  
       Xe = 54, 
       Cs = 55, 
       Ba = 56, 
       La = 57, 
   
       Hf = 72, 
       Ta = 73, 
       W = 74,  
       Re = 75, 
       Os = 76, 
       Ir = 77, 
       Pt = 78, 
       Au = 79, 
       Hg = 80, 
       Tl = 81, 
       Pb = 82, 
       Bi = 83, 
       Po = 84, 
       At = 85, 
       Rn = 86, 
       Fr = 87, 
       Ra = 88, 
       Ac = 89, 
   
       Rf = 104, 
       Db = 105, 
       Sg = 106, 
       Bh = 107, 
       Hs = 108, 
       Mt = 109, 
       Ds = 110, 
       Rg = 111, 
       Cn = 112, 
       Nh = 113, 
       Fl = 114, 
       Mc = 115, 
       Lv = 116, 
       Ts = 117, 
       Og = 118, 
   
       Ce = 58, 
       Pr = 59, 
       Nd = 60, 
       Pm = 61, 
       Sm = 62, 
       Eu = 63, 
       Gd = 64, 
       Tb = 65, 
       Dy = 66, 
       Ho = 67, 
       Er = 68, 
       Tm = 69, 
       Yb = 70, 
       Lu = 71, 
   
       Th = 90,  
       Pa = 91,  
       U = 92,   
       Np = 93,  
       Pu = 94,  
       Am = 95,  
       Cm = 96,  
       Bk = 97,  
       Cf = 98,  
       Es = 99,  
       Fm = 100, 
       Md = 101, 
       No = 102, 
       Lr = 103, 
   
       D = 119, 
   };
   
   // --------------------------------------------------------------------
   
   
   enum class radius_type
   {
       calculated, 
       empirical,  
   
       covalent_empirical,
   
       single_bond, 
       double_bond, 
       triple_bond, 
   
       van_der_waals, 
   
       type_count 
   };
   
   constexpr std::size_t kRadiusTypeCount = static_cast<std::size_t>(radius_type::type_count);
   
   
   enum class ionic_radius_type
   {
       effective, 
       crystal    
   };
   
   constexpr float kNA = std::numeric_limits<float>::quiet_NaN();
   
   
   struct atom_type_info
   {
       atom_type type;
   
       std::string name;
   
       std::string symbol;
   
       float weight;
   
       bool metal;
   
       float radii[kRadiusTypeCount];
   };
   
   
   extern CIFPP_EXPORT const atom_type_info kKnownAtoms[];
   
   // --------------------------------------------------------------------
   // AtomTypeTraits
   
   
   class atom_type_traits
   {
     public:
       atom_type_traits(atom_type a);
   
       atom_type_traits(const std::string &symbol);
   
       atom_type type() const { return m_info->type; }       
       std::string name() const { return m_info->name; }     
       std::string symbol() const { return m_info->symbol; } 
       float weight() const { return m_info->weight; }       
   
       bool is_metal() const { return m_info->metal; } 
   
       static bool is_element(const std::string &symbol);
   
       static bool is_metal(const std::string &symbol);
   
       float radius(radius_type type = radius_type::single_bond) const
       {
           if (type >= radius_type::type_count)
               throw std::invalid_argument("invalid radius requested");
           return m_info->radii[static_cast<std::size_t>(type)] / 100.f;
       }
   
       float crystal_ionic_radius(int charge) const;
   
       float effective_ionic_radius(int charge) const;
   
       float ionic_radius(int charge, ionic_radius_type type = ionic_radius_type::effective) const
       {
           return type == ionic_radius_type::effective ? effective_ionic_radius(charge) : crystal_ionic_radius(charge);
       }
   
       struct SFData
       {
           double a[6], b[6];
       };
   
       static constexpr int kWKSFVal = -99;
   
       const SFData &wksf(int charge = 0) const;
   
       const SFData &elsf() const;
   
       bool has_sf(int charge) const;
   
     private:
       const struct atom_type_info *m_info;
   };
   
   } // namespace cif
