@startuml



package libint #c6ffb3 {
    namespace libint2 #ffffff {
        class Atom {
            + atomic_number
            + x
            + y
            + z
        }

        class Engine {
            == constructors ==
                **Engine**(Operator oper, size_t max_nprim, int max_l, <..>)
            __ public methods __
                + const target_ptr_vec& **results**()
                + const Engine::target_ptr_vec& **calculate**()
        }

        class BasisSet {
            == constructors ==
                **BasisSet**(std::string name, const std::vector<Atom>& atoms)
            __ public methods __
                + size_type **size**()
                + long **calculateNumberOfBasisFunctions**()
                + size_t **max_nprim**()
                + long **max_l**()
                + const std::vector<size_t>& **shell2bf**()
        }

        enum Operator {
            overlap
            kinetic
            nuclear
            coulomb
        }

        class cxxapi {
                void **initialize**()
                void **finalize**()
        }

        class atom {
            inline std::vector<Atom> **read_dotxyz**(std::istream& is, <...>)
        }
    }
}




namespace libwint {

    class AOBasis {
        __ private members __
            - bool are_calculated_overlap_integrals
            - bool are_calculated_nuclear_integrals
            - bool are_calculated_kinetic_integrals
            - bool are_calculated_electron_repulsion_integrals

            - libwint::Molecule& molecule
            - const std::string name
            - libint2::BasisSet& libint_basis

            - const Eigen::MatrixXd& S
            - const Eigen::MatrixXd& T
            - const Eigen::MatrixXd& V
            - const Eigen::Tensor<double, 4>& g
            - const size_t K
        == constructors ==
            **AOBasis**(Molecule& molecule, const std::string basis_name)
        __ public methods __
            + libwint::Molecule& **get_molecule**() const
            + Eigen::MatrixXd& **get_S**() const
            + Eigen::MatrixXd& **get_T**() const
            + Eigen::MatrixXd& **get_V**() const
            + Eigen::Tensor<double, 4>& **get_g**() const

            + size_t **calculateNumberOfBasisFunctions**()
            + void **calculateOverlapIntegrals**()
            + void **calculateKineticIntegrals**()
            + void **calculateNuclearIntegrals**()
            + void **calculateTwoElectronRepulsionIntegrals**()
            + void **calculateIntegrals**()
            + void **printShellSizes**()
    }


    class SOBasis {
        __ private members __
            - Eigen::MatrixXd& h_SO
            - Eigen::Tensor<double, 4>& g_SO
            - const size_t K
        == constructors ==
            **SOBasis**(const libwint::AOBasis& ao_basis, Eigen::MatrixXd& C)
        __ public methods __
            + inline Eigen::MatrixXd& **get_h_SO**() const
            + inline Eigen::Tensor<double, 4>& **get_g_SO**() const
            + inline const size_t **get_K**() const

            + void **transform**(Eigen::MatrixXd& T)
            + void **transformJacobi**(size_t p, size_t q, double angle)
    }


    class transformations {
            Eigen::MatrixXd **transformOneElectronIntegrals**(const Eigen::MatrixXd& h, const Eigen::MatrixXd& T)
            Eigen::Tensor<double, 4> **transformTwoElectronIntegrals**(const Eigen::Tensor<double, 4>& g, const Eigen::MatrixXd& T)

            Eigen::MatrixXd **AO_to_SO**(const Eigen::MatrixXd& f_AO, const Eigen::MatrixXd& C)
            Eigen::MatrixXd **SO_to_AO**(const Eigen::MatrixXd& f_SO, const Eigen::MatrixXd& C)
            Eigen::Tensor<double, 4> **AO_to_SO**(const Eigen::Tensor<double, 4>& g_AO, const Eigen::MatrixXd& C)

            Eigen::MatrixXd **jacobiRotationMatrix**(size_t P, size_t Q, double theta, size_t M)
            Eigen::MatrixXd **rotateOneElectronIntegralsJacobi**(const Eigen::MatrixXd& h, size_t P, size_t Q, double theta)
    }


    class LibintCommunicator {
        __ private methods __
            - **LibintCommunicator**()
        == private destructor ==
            ~ ~LibintCommunicator()
        __ public methods __
            + {static} LibintCommunicator& get()
            + LibintCommunicator(LibintCommunicator const& libint_communicator) = delete
            + void operator=(LibintCommunicator const& libint_communicator) = delete
            + Eigen::MatrixXd **calculateOneBodyIntegrals**(const libint2::Operator& opertype, const libint2::BasisSet& obs, const std::vector<libint2::Atom>& atoms)
            + Eigen::Tensor<double, 4> **calculateElectronRepulsionIntegrals**(const libint2::BasisSet& obs, const std::vector<libint2::Atom>& atoms)
    }


    class Molecule {
        __ private members __
            - const size_t N
            - const std::vector<libint2::Atom> atoms
        __ private methods __
            - std::vector<libint2::Atom> parseXYZFilename(const std::string filename) const
        == constructors ==
            **Molecule**(const std::string& xyz_filename)
            **Molecule**(const std::string& xyz_filename, int molecular_charge)
            **Molecule**(const std::vector<libint2::Atom>& atoms)
            **Molecule**(const std::vector<libint2::Atom>& atoms, int molecular_charge)
        __ public methods __
            + site_t **get_N** const ()

            + size_t numberOfAtoms() const
            + size_t **calculateTotalNucleicCharge**() const
            + double **calculateInternuclearDistance**(size_t index1, size_t index2) const
            + double **calculateInternuclearRepulsionEnergy**() const
    }

}



libwint.AOBasis o--> libwint.Molecule
libwint.AOBasis *--> libwint.LibintCommunicator

libwint.LibintCommunicator *--> libint2.BasisSet
libwint.LibintCommunicator ..> libint2.Operator
libwint.LibintCommunicator *--> libint2.Engine
libwint.LibintCommunicator ..> libint2.cxxapi

libwint.Molecule *--> "1..*" libint2.Atom
libwint.Molecule ..> libint2.atom

libwint.SOBasis ..> libwint.transformations
libwint.SOBasis o--> libwint.AOBasis


@enduml
