# Program Listing for File atom_type.hpp

↰ Return to documentation for file (`cif++/atom_type.hpp`)

    /*-
     * 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