From 3490ccfc8fd41ad906cf2af45128596dce399e9a Mon Sep 17 00:00:00 2001 From: gitpeterwind Date: Mon, 5 Aug 2024 16:11:23 +0200 Subject: [PATCH 1/8] conflict solved --- external/upstream/fetch_mrcpp.cmake | 2 +- .../NuclearGradientFunction.h | 2 +- src/driver.cpp | 8 +- src/environment/GPESolver.cpp | 74 +++-- src/environment/GPESolver.h | 20 +- src/environment/LPBESolver.cpp | 4 +- src/environment/LPBESolver.h | 4 +- src/environment/PBESolver.cpp | 16 +- src/environment/PBESolver.h | 8 +- src/initial_guess/core.cpp | 7 +- src/initial_guess/cube.cpp | 2 +- src/initial_guess/gto.cpp | 7 +- src/initial_guess/mw.cpp | 10 +- src/initial_guess/sad.cpp | 6 +- src/mrenv.cpp | 2 +- src/parallel.cpp | 10 +- src/properties/OrbitalEnergies.h | 20 +- src/qmfunctions/CMakeLists.txt | 4 +- src/qmfunctions/ComplexFunction.h | 6 +- src/qmfunctions/Density.cpp | 36 +-- src/qmfunctions/Density.h | 8 +- src/qmfunctions/Orbital.cpp | 148 +++------ src/qmfunctions/Orbital.h | 43 ++- src/qmfunctions/OrbitalIterator.cpp | 244 --------------- src/qmfunctions/OrbitalIterator.h | 63 ---- src/qmfunctions/QMFunction.cpp | 286 ------------------ src/qmfunctions/QMFunction.h | 82 ----- src/qmfunctions/density_utils.cpp | 66 ++-- src/qmfunctions/density_utils.h | 1 + src/qmfunctions/orbital_utils.cpp | 202 +++++++------ src/qmfunctions/orbital_utils.h | 10 +- src/qmfunctions/qmfunction_fwd.h | 12 +- src/qmfunctions/qmfunction_utils.cpp | 76 +---- src/qmfunctions/qmfunction_utils.h | 21 +- src/qmoperators/QMDerivative.cpp | 28 +- src/qmoperators/QMIdentity.cpp | 6 +- src/qmoperators/QMOperator.h | 3 +- src/qmoperators/QMPotential.cpp | 95 ++---- src/qmoperators/QMPotential.h | 7 +- src/qmoperators/QMSpin.cpp | 10 +- src/qmoperators/one_electron/DeltaOperator.h | 2 +- .../one_electron/NuclearGradientOperator.h | 6 +- .../one_electron/NuclearOperator.cpp | 6 +- .../one_electron/NuclearOperator.h | 4 +- .../one_electron/PositionOperator.h | 7 +- src/qmoperators/one_electron/ZoraOperator.cpp | 2 +- .../two_electron/CoulombPotential.cpp | 18 +- .../two_electron/CoulombPotential.h | 4 +- .../two_electron/ExchangePotential.cpp | 23 +- .../two_electron/ExchangePotentialD1.cpp | 37 ++- .../two_electron/ExchangePotentialD2.cpp | 55 ++-- src/qmoperators/two_electron/FockBuilder.cpp | 6 +- .../two_electron/ReactionPotential.cpp | 4 +- .../two_electron/ReactionPotential.h | 2 +- .../two_electron/ReactionPotentialD1.cpp | 2 +- .../two_electron/ReactionPotentialD1.h | 2 +- .../two_electron/ReactionPotentialD2.cpp | 2 +- .../two_electron/ReactionPotentialD2.h | 2 +- src/scf_solver/Accelerator.cpp | 8 +- src/scf_solver/HelmholtzVector.cpp | 26 +- src/scf_solver/HelmholtzVector.h | 2 +- src/scf_solver/KAIN.cpp | 31 +- src/scf_solver/LinearResponseSolver.cpp | 2 +- src/scf_solver/SCFSolver.cpp | 4 +- src/tensor/RankOneOperator.h | 2 - src/tensor/RankTwoOperator.h | 2 - src/tensor/RankZeroOperator.cpp | 43 +-- src/tensor/RankZeroOperator.h | 2 +- src/utils/MolPlotter.h | 6 +- src/utils/RRMaximizer.cpp | 7 +- src/utils/print_utils.cpp | 6 +- src/utils/print_utils.h | 2 +- tests/qmfunctions/density.cpp | 17 +- tests/qmfunctions/orbital.cpp | 42 +-- tests/qmfunctions/orbital_vector.cpp | 32 +- tests/qmfunctions/qmfunction.cpp | 166 +++++----- tests/qmoperators/coulomb_hessian.cpp | 14 +- tests/qmoperators/coulomb_operator.cpp | 12 +- tests/qmoperators/electric_field_operator.cpp | 26 +- tests/qmoperators/exchange_hessian.cpp | 14 +- tests/qmoperators/exchange_operator.cpp | 12 +- tests/qmoperators/identity_operator.cpp | 16 +- tests/qmoperators/kinetic_operator.cpp | 10 +- tests/qmoperators/momentum_operator.cpp | 2 +- tests/qmoperators/nuclear_operator.cpp | 36 +-- tests/qmoperators/operator_composition.cpp | 4 +- tests/qmoperators/position_operator.cpp | 2 +- tests/qmoperators/xc_hessian_lda.cpp | 14 +- tests/qmoperators/xc_hessian_pbe.cpp | 14 +- tests/qmoperators/xc_operator_blyp.cpp | 12 +- tests/qmoperators/xc_operator_lda.cpp | 12 +- tests/solventeffect/PB_solver.cpp | 4 +- tests/solventeffect/reaction_operator.cpp | 2 +- tests/unit_tests.cpp | 2 +- 94 files changed, 821 insertions(+), 1630 deletions(-) delete mode 100644 src/qmfunctions/OrbitalIterator.cpp delete mode 100644 src/qmfunctions/OrbitalIterator.h delete mode 100644 src/qmfunctions/QMFunction.cpp delete mode 100644 src/qmfunctions/QMFunction.h diff --git a/external/upstream/fetch_mrcpp.cmake b/external/upstream/fetch_mrcpp.cmake index dbe0d273f..59f1bc309 100644 --- a/external/upstream/fetch_mrcpp.cmake +++ b/external/upstream/fetch_mrcpp.cmake @@ -39,7 +39,7 @@ else() GIT_REPOSITORY https://github.com/MRChemSoft/mrcpp.git GIT_TAG - 720133372c9717134c5a01e963cb9804a1e8c36e + 0df20bca9c03eb894462ce923155c7033b4fdbcd ) FetchContent_GetProperties(mrcpp_sources) diff --git a/src/analyticfunctions/NuclearGradientFunction.h b/src/analyticfunctions/NuclearGradientFunction.h index 271108823..41b522edb 100644 --- a/src/analyticfunctions/NuclearGradientFunction.h +++ b/src/analyticfunctions/NuclearGradientFunction.h @@ -31,7 +31,7 @@ namespace mrchem { -class NuclearGradientFunction : public mrcpp::RepresentableFunction<3> { + class NuclearGradientFunction : public mrcpp::RepresentableFunction<3, double> { public: /*! * @brief NuclearGradientFunction represents the function: Z * [x,y,z]/|r - o|^3 diff --git a/src/driver.cpp b/src/driver.cpp index 29d75c2da..187a321b3 100644 --- a/src/driver.cpp +++ b/src/driver.cpp @@ -390,7 +390,7 @@ bool driver::scf::guess_orbitals(const json &json_guess, Molecule &mol) { success = false; } for (const auto &phi_i : Phi) { - double err = (mrcpp::mpi::my_orb(phi_i)) ? std::abs(phi_i.norm() - 1.0) : 0.0; + double err = (mrcpp::mpi::my_func(phi_i)) ? std::abs(phi_i.norm() - 1.0) : 0.0; if (err > 0.01) MSG_WARN("MO not normalized!"); } @@ -660,10 +660,10 @@ void driver::scf::plot_quantities(const json &json_plot, Molecule &mol) { if (orb_idx[0] < 0) { // Plotting ALL orbitals for (auto i = 0; i < Phi.size(); i++) { - if (not mrcpp::mpi::my_orb(Phi[i])) continue; + if (not mrcpp::mpi::my_func(Phi[i])) continue; t_lap.start(); std::stringstream name; - name << path << "/phi_" << Phi[i].printSpin() << "_scf_idx_" << i; + name << path << "/phi_" << Orbital(Phi[i]).printSpin() << "_scf_idx_" << i; if (line) plt.linePlot(npts, Phi[i], name.str()); if (surf) plt.surfPlot(npts, Phi[i], name.str()); if (cube) plt.cubePlot(npts, Phi[i], name.str()); @@ -672,7 +672,7 @@ void driver::scf::plot_quantities(const json &json_plot, Molecule &mol) { } else { // Plotting some orbitals for (auto &i : orb_idx) { - if (not mrcpp::mpi::my_orb(Phi[i])) continue; + if (not mrcpp::mpi::my_func(Phi[i])) continue; t_lap.start(); std::stringstream name; auto sp = 'u'; diff --git a/src/environment/GPESolver.cpp b/src/environment/GPESolver.cpp index df7141c04..743850a6a 100644 --- a/src/environment/GPESolver.cpp +++ b/src/environment/GPESolver.cpp @@ -80,15 +80,13 @@ void GPESolver::computeDensities(const Density &rho_el, Density &rho_out) { switch (this->density_type) { case SCRFDensityType::TOTAL: - mrcpp::cplxfunc::add(rho_out, 1.0, rho_el, 1.0, this->rho_nuc, -1.0); + mrcpp::add(rho_out, 1.0, rho_el, 1.0, this->rho_nuc, -1.0); break; case SCRFDensityType::ELECTRONIC: - // using const_cast is absolutely EVIL here and in principle shouldn't be needed! - // however MRCPP is not everywhere const-correct, so here we go! - mrcpp::cplxfunc::deep_copy(rho_out, const_cast(rho_el)); + mrcpp::deep_copy(rho_out, rho_el); break; case SCRFDensityType::NUCLEAR: - mrcpp::cplxfunc::deep_copy(rho_out, this->rho_nuc); + mrcpp::deep_copy(rho_out, this->rho_nuc); break; default: MSG_ABORT("Invalid density type"); @@ -96,7 +94,7 @@ void GPESolver::computeDensities(const Density &rho_el, Density &rho_out) { print_utils::qmfunction(3, "Vacuum density", rho_out, timer); } -void GPESolver::computeGamma(mrcpp::ComplexFunction &potential, mrcpp::ComplexFunction &out_gamma) { +void GPESolver::computeGamma(mrcpp::CompFunction<3> &potential, mrcpp::CompFunction<3> &out_gamma) { auto d_V = mrcpp::gradient(*derivative, potential.real()); // FunctionTreeVector resetComplexFunction(out_gamma); @@ -104,11 +102,11 @@ void GPESolver::computeGamma(mrcpp::ComplexFunction &potential, mrcpp::ComplexFu for (int d = 0; d < 3; d++) { auto C_pin = this->epsilon.getCavity_p(); mrcpp::AnalyticFunction<3> d_cav(C_pin->getGradVector()[d]); - mrcpp::ComplexFunction cplxfunc_prod; - mrcpp::cplxfunc::multiply(cplxfunc_prod, get_func(d_V, d), d_cav, this->apply_prec, 1); + mrcpp::CompFunction<3> cplxfunc_prod; + mrcpp::multiply(cplxfunc_prod, get_func(d_V, d), d_cav, this->apply_prec, 1); // add result into out_gamma if (d == 0) { - mrcpp::cplxfunc::deep_copy(out_gamma, cplxfunc_prod); + mrcpp::deep_copy(out_gamma, cplxfunc_prod); } else { out_gamma.add(1.0, cplxfunc_prod); } @@ -118,32 +116,30 @@ void GPESolver::computeGamma(mrcpp::ComplexFunction &potential, mrcpp::ComplexFu mrcpp::clear(d_V, true); } -mrcpp::ComplexFunction GPESolver::solvePoissonEquation(const mrcpp::ComplexFunction &in_gamma, const Density &rho_el) { - mrcpp::ComplexFunction Poisson_func; - mrcpp::ComplexFunction rho_eff; - mrcpp::ComplexFunction first_term; - mrcpp::ComplexFunction Vr_np1; +mrcpp::CompFunction<3> GPESolver::solvePoissonEquation(const mrcpp::CompFunction<3> &in_gamma, const Density &rho_el) { + mrcpp::CompFunction<3> Poisson_func; + mrcpp::CompFunction<3> rho_eff; + mrcpp::CompFunction<3> first_term; + mrcpp::CompFunction<3> Vr_np1; Vr_np1.alloc(NUMBER::Real); auto eps_inv_func = mrcpp::AnalyticFunction<3>([this](const mrcpp::Coord<3> &r) { return 1.0 / this->epsilon.evalf(r); }); Density rho_tot(false); computeDensities(rho_el, rho_tot); - mrcpp::cplxfunc::multiply(first_term, rho_tot, eps_inv_func, this->apply_prec); + mrcpp::multiply(first_term, rho_tot, eps_inv_func, this->apply_prec); - mrcpp::cplxfunc::add(rho_eff, 1.0, first_term, -1.0, rho_tot, -1.0); + mrcpp::add(rho_eff, 1.0, first_term, -1.0, rho_tot, -1.0); rho_tot.free(NUMBER::Real); - mrcpp::cplxfunc::add(Poisson_func, 1.0, in_gamma, 1.0, rho_eff, -1.0); + mrcpp::add(Poisson_func, 1.0, in_gamma, 1.0, rho_eff, -1.0); mrcpp::apply(this->apply_prec, Vr_np1.real(), *poisson, Poisson_func.real()); return Vr_np1; } -void GPESolver::accelerateConvergence(mrcpp::ComplexFunction &dfunc, mrcpp::ComplexFunction &func, KAIN &kain) { - OrbitalVector phi_n(0); - OrbitalVector dPhi_n(0); - phi_n.push_back(Orbital(SPIN::Paired)); - dPhi_n.push_back(Orbital(SPIN::Paired)); +void GPESolver::accelerateConvergence(mrcpp::CompFunction<3> &dfunc, mrcpp::CompFunction<3> &func, KAIN &kain) { + OrbitalVector phi_n(1); + OrbitalVector dPhi_n(1); phi_n[0] = func; dPhi_n[0] = dfunc; @@ -160,7 +156,7 @@ void GPESolver::accelerateConvergence(mrcpp::ComplexFunction &dfunc, mrcpp::Comp dPhi_n.clear(); } -void GPESolver::runMicroIterations(const mrcpp::ComplexFunction &V_vac, const Density &rho_el) { +void GPESolver::runMicroIterations(const mrcpp::CompFunction<3> &V_vac, const Density &rho_el) { KAIN kain(this->history); kain.setLocalPrintLevel(10); @@ -171,29 +167,29 @@ void GPESolver::runMicroIterations(const mrcpp::ComplexFunction &V_vac, const De while (update >= this->conv_thrs && iter <= max_iter) { Timer t_iter; // solve the poisson equation - mrcpp::ComplexFunction V_tot; - mrcpp::ComplexFunction gamma_n; - mrcpp::ComplexFunction dVr_n; + mrcpp::CompFunction<3> V_tot; + mrcpp::CompFunction<3> gamma_n; + mrcpp::CompFunction<3> dVr_n; - mrcpp::cplxfunc::add(V_tot, 1.0, this->Vr_n, 1.0, V_vac, -1.0); + mrcpp::add(V_tot, 1.0, this->Vr_n, 1.0, V_vac, -1.0); computeGamma(V_tot, gamma_n); auto Vr_np1 = solvePoissonEquation(gamma_n, rho_el); norm = Vr_np1.norm(); // use a convergence accelerator - mrcpp::cplxfunc::add(dVr_n, 1.0, Vr_np1, -1.0, this->Vr_n, -1.0); + mrcpp::add(dVr_n, 1.0, Vr_np1, -1.0, this->Vr_n, -1.0); update = dVr_n.norm(); if (iter > 1 and this->history > 0) { accelerateConvergence(dVr_n, Vr_n, kain); Vr_np1.free(NUMBER::Real); - mrcpp::cplxfunc::add(Vr_np1, 1.0, Vr_n, 1.0, dVr_n, -1.0); + mrcpp::add(Vr_np1, 1.0, Vr_n, 1.0, dVr_n, -1.0); } // set up for next iteration resetComplexFunction(this->Vr_n); - mrcpp::cplxfunc::deep_copy(this->Vr_n, Vr_np1); + mrcpp::deep_copy(this->Vr_n, Vr_np1); Vr_np1.free(NUMBER::Real); printConvergenceRow(iter, norm, update, t_iter.elapsed()); @@ -233,12 +229,12 @@ void GPESolver::printConvergenceRow(int i, double norm, double update, double ti println(3, o_txt.str()); } -mrcpp::ComplexFunction &GPESolver::solveEquation(double prec, const Density &rho_el) { +mrcpp::CompFunction<3> &GPESolver::solveEquation(double prec, const Density &rho_el) { this->apply_prec = prec; Density rho_tot(false); computeDensities(rho_el, rho_tot); Timer t_vac; - mrcpp::ComplexFunction V_vac; + mrcpp::CompFunction<3> V_vac; V_vac.alloc(NUMBER::Real); mrcpp::apply(this->apply_prec, V_vac.real(), *poisson, rho_tot.real()); rho_tot.free(NUMBER::Real); @@ -248,8 +244,8 @@ mrcpp::ComplexFunction &GPESolver::solveEquation(double prec, const Density &rho Timer t_gamma; if (not this->Vr_n.hasReal()) { - mrcpp::ComplexFunction gamma_0; - mrcpp::ComplexFunction V_tot; + mrcpp::CompFunction<3> gamma_0; + mrcpp::CompFunction<3> V_tot; computeGamma(V_vac, gamma_0); this->Vr_n = solvePoissonEquation(gamma_0, rho_el); } @@ -263,15 +259,13 @@ mrcpp::ComplexFunction &GPESolver::solveEquation(double prec, const Density &rho } auto GPESolver::computeEnergies(const Density &rho_el) -> std::tuple { - auto Er_nuc = 0.5 * mrcpp::cplxfunc::dot(this->rho_nuc, this->Vr_n).real(); - auto Er_el = 0.5 * mrcpp::cplxfunc::dot(rho_el, this->Vr_n).real(); + auto Er_nuc = 0.5 * mrcpp::dot(this->rho_nuc, this->Vr_n).real(); + auto Er_el = 0.5 * mrcpp::dot(rho_el, this->Vr_n).real(); return {Er_el, Er_nuc}; } -void GPESolver::resetComplexFunction(mrcpp::ComplexFunction &function) { - if (function.hasReal()) function.free(NUMBER::Real); - if (function.hasImag()) function.free(NUMBER::Imag); - function.alloc(NUMBER::Real); +void GPESolver::resetComplexFunction(mrcpp::CompFunction<3> &function) { + function.alloc(0); } void GPESolver::printParameters() const { diff --git a/src/environment/GPESolver.h b/src/environment/GPESolver.h index acd8adf8e..621140be0 100644 --- a/src/environment/GPESolver.h +++ b/src/environment/GPESolver.h @@ -129,7 +129,7 @@ class GPESolver { // just iterate through V_R only. Only issue here is (1 -1\epsilon)/\epsilon * \rho_nuc as I am not sure how to represent this as an analytitcal function, // maybe after applying the Poisson operator? - mrcpp::ComplexFunction Vr_n; + mrcpp::CompFunction<3> Vr_n; std::shared_ptr> derivative; std::shared_ptr poisson; @@ -152,14 +152,14 @@ class GPESolver { /** @brief Computes the surface charge distibution due to polarization at the solute-solvent boundary * @param potential Potential used to compute \f$\nabla V(\mathbf{r})\f$ - * @param out_gamma ComplexFunction in which the surface charge distribution will be computed. + * @param out_gamma CompFunction<3> in which the surface charge distribution will be computed. * @details The surface charge distribution is given by * \f[ * \gamma_s(\mathbf{r}) = \frac{\log \frac{\epsilon_{in}}{\epsilon_{out}}}{4 \pi } \left( \nabla C(\mathbf{r}) \cdot \nabla V(\mathbf{r})\right) * \f] * where \f$\epsilon_{in}\f$ is the permittivity inside the cavity and \f$\epsilon_{out}\f$ is the permittivity outside the cavity. */ - virtual void computeGamma(mrcpp::ComplexFunction &potential, mrcpp::ComplexFunction &out_gamma); + virtual void computeGamma(mrcpp::CompFunction<3> &potential, mrcpp::CompFunction<3> &out_gamma); /** @brief Iterates once through the Generalized Poisson equation to compute the reaction potential * @param ingamma the surface charge distribution @@ -172,14 +172,14 @@ class GPESolver { * where \f$\gamma_s(\mathbf{r})\f$ is the surface charge distribution describing the polarization at the surface, \f$\rho_{eff}(\mathbf{r})\f$ is the effective charge density given by * \f$\frac{\rho(\mathbf{r})}{\epsilon(\mathbf{r})}\f$ and \f$V_R(\mathbf{r})\f$ is the reaction potential. */ - mrcpp::ComplexFunction solvePoissonEquation(const mrcpp::ComplexFunction &ingamma, const Density &rho_el); + mrcpp::CompFunction<3> solvePoissonEquation(const mrcpp::CompFunction<3> &ingamma, const Density &rho_el); /** @brief Uses KAIN to accelerate convergece of the reaction potential * @param dfunc the current update of the reaction potential * @param func the current reaction potential * @param kain the KAIN object */ - void accelerateConvergence(mrcpp::ComplexFunction &dfunc, mrcpp::ComplexFunction &func, KAIN &kain); + void accelerateConvergence(mrcpp::CompFunction<3> &dfunc, mrcpp::CompFunction<3> &func, KAIN &kain); /** @brief Iterates through the application of the Poisson operator to Solve the Generalized Poisson equation * @param V_vac the vacuum potential @@ -195,7 +195,7 @@ class GPESolver { * -# Update the reaction potential as \f$V_R(\mathbf{r}) = V_R^{old}(\mathbf{r}) + \Delta V_R(\mathbf{r})\f$ * -# Check if the reaction potential has converged, if not, repeat from step 1. */ - void runMicroIterations(const mrcpp::ComplexFunction &V_vac, const Density &rho_el); + void runMicroIterations(const mrcpp::CompFunction<3> &V_vac, const Density &rho_el); /** @brief Setups and computes the reaction potential through the microiterations * @param V_vac the vacuum potential @@ -209,13 +209,13 @@ class GPESolver { * the method then runs the micro-iterations through #runMicroIterations and returns the converged reaction potential. * If this is not the first SCF iteration, the previous converged reaction potential is used as an initial guess for the micro-iterations. */ - mrcpp::ComplexFunction &solveEquation(double prec, const Density &rho_el); + mrcpp::CompFunction<3> &solveEquation(double prec, const Density &rho_el); /** @brief Frees the memory used by the FunctionTrees of the input Complexfunction and reallocates them. - * @param function the ComplexFunction to reset - * @details This is done to avoid memory leaks when the ComplexFunction is used in the micro-iterations. + * @param function the CompFunction<3> to reset + * @details This is done to avoid memory leaks when the CompFunction<3> is used in the micro-iterations. */ - void resetComplexFunction(mrcpp::ComplexFunction &function); + void resetComplexFunction(mrcpp::CompFunction<3> &function); virtual void printParameters() const; void printConvergenceRow(int i, double norm, double update, double time) const; diff --git a/src/environment/LPBESolver.cpp b/src/environment/LPBESolver.cpp index 6d6bb6868..1a3c046db 100644 --- a/src/environment/LPBESolver.cpp +++ b/src/environment/LPBESolver.cpp @@ -56,9 +56,9 @@ LPBESolver::LPBESolver(const Permittivity &e, SCRFDensityType density_type) : PBESolver(e, k, rho_nuc, P, D, kain_hist, max_iter, dyn_thrs, density_type) {} // TODO separate this for the linear and non-linear solver -void LPBESolver::computePBTerm(mrcpp::ComplexFunction &V_tot, const double salt_factor, mrcpp::ComplexFunction &pb_term) { +void LPBESolver::computePBTerm(mrcpp::CompFunction<3> &V_tot, const double salt_factor, mrcpp::CompFunction<3> &pb_term) { resetComplexFunction(pb_term); - mrcpp::cplxfunc::multiply(pb_term, V_tot, this->kappa, this->apply_prec); + mrcpp::multiply(pb_term, V_tot, this->kappa, this->apply_prec); pb_term.rescale(salt_factor / (4.0 * mrcpp::pi)); } diff --git a/src/environment/LPBESolver.h b/src/environment/LPBESolver.h index 25f617d3c..db6174217 100644 --- a/src/environment/LPBESolver.h +++ b/src/environment/LPBESolver.h @@ -61,10 +61,10 @@ class LPBESolver final : public PBESolver { /** @brief Computes the PB term * @param[in] V_tot the total potential * @param[in] salt_factor the salt factor deciding how much of the total concentration to include in the PB term - * @param[out] pb_term the ComplexFunction in which to store the result + * @param[out] pb_term the CompFunction<3> in which to store the result * @details The PB term is computed as \f$ \kappa^2 V_{tot} \f$ and returned. */ - void computePBTerm(mrcpp::ComplexFunction &V_tot, const double salt_factor, mrcpp::ComplexFunction &pb_term) override; + void computePBTerm(mrcpp::CompFunction<3> &V_tot, const double salt_factor, mrcpp::CompFunction<3> &pb_term) override; std::string solver_name{"Linearized Poisson-Boltzmann"}; }; } // namespace mrchem diff --git a/src/environment/PBESolver.cpp b/src/environment/PBESolver.cpp index 6c5e22fd6..502d814a0 100644 --- a/src/environment/PBESolver.cpp +++ b/src/environment/PBESolver.cpp @@ -57,18 +57,18 @@ PBESolver::PBESolver(const Permittivity &e, : GPESolver(e, rho_nuc, P, D, kain_hist, max_iter, dyn_thrs, density_type) , kappa(k) {} -void PBESolver::computePBTerm(mrcpp::ComplexFunction &V_tot, const double salt_factor, mrcpp::ComplexFunction &pb_term) { +void PBESolver::computePBTerm(mrcpp::CompFunction<3> &V_tot, const double salt_factor, mrcpp::CompFunction<3> &pb_term) { // create a lambda function for the sinh(V) term and multiply it with kappa and salt factor to get the PB term auto sinh_f = [salt_factor](const double &V) { return (salt_factor / (4.0 * mrcpp::pi)) * std::sinh(V); }; resetComplexFunction(pb_term); - mrcpp::ComplexFunction sinhV; + mrcpp::CompFunction<3> sinhV; sinhV.alloc(NUMBER::Real); mrcpp::map(this->apply_prec / 100, sinhV.real(), V_tot.real(), sinh_f); - mrcpp::cplxfunc::multiply(pb_term, sinhV, this->kappa, this->apply_prec); + mrcpp::multiply(pb_term, sinhV, this->kappa, this->apply_prec); } -void PBESolver::computeGamma(mrcpp::ComplexFunction &potential, mrcpp::ComplexFunction &out_gamma) { +void PBESolver::computeGamma(mrcpp::CompFunction<3> &potential, mrcpp::CompFunction<3> &out_gamma) { auto d_V = mrcpp::gradient(*derivative, potential.real()); // FunctionTreeVector resetComplexFunction(out_gamma); @@ -76,11 +76,11 @@ void PBESolver::computeGamma(mrcpp::ComplexFunction &potential, mrcpp::ComplexFu for (int d = 0; d < 3; d++) { auto C_pin = this->epsilon.getCavity_p(); mrcpp::AnalyticFunction<3> d_cav(C_pin->getGradVector()[d]); - mrcpp::ComplexFunction cplxfunc_prod; - mrcpp::cplxfunc::multiply(cplxfunc_prod, get_func(d_V, d), d_cav, this->apply_prec, 1); + mrcpp::CompFunction<3> cplxfunc_prod; + mrcpp::multiply(cplxfunc_prod, get_func(d_V, d), d_cav, this->apply_prec, 1); // add result into out_gamma if (d == 0) { - mrcpp::cplxfunc::deep_copy(out_gamma, cplxfunc_prod); + mrcpp::deep_copy(out_gamma, cplxfunc_prod); } else { out_gamma.add(1.0, cplxfunc_prod); } @@ -90,7 +90,7 @@ void PBESolver::computeGamma(mrcpp::ComplexFunction &potential, mrcpp::ComplexFu mrcpp::clear(d_V, true); // add PB term - mrcpp::ComplexFunction pb_term; + mrcpp::CompFunction<3> pb_term; auto salt_factor = 1.0; // placeholder for now, want to change it wrt to convergence in future computePBTerm(potential, salt_factor, pb_term); out_gamma.add(-1.0, pb_term); diff --git a/src/environment/PBESolver.h b/src/environment/PBESolver.h index c5215d55b..12d690bd0 100644 --- a/src/environment/PBESolver.h +++ b/src/environment/PBESolver.h @@ -78,17 +78,17 @@ class PBESolver : public GPESolver { /** @brief constructs the surface chage distribution and adds it to the PB term * @param[in] potential the potential to compute \f$\nabla V\f$ from - * @param[out] out_gamma the ComplexFunction in which to store the result + * @param[out] out_gamma the CompFunction<3> in which to store the result * @details Method follows the implementation in GPESolver::computeGamma, but adds the PB term to the surface charge distribution. */ - void computeGamma(mrcpp::ComplexFunction &potential, mrcpp::ComplexFunction &out_gamma) override; + void computeGamma(mrcpp::CompFunction<3> &potential, mrcpp::CompFunction<3> &out_gamma) override; /** @brief Computes the PB term * @param[in] V_tot the total potential * @param[in] salt_factor the salt factor deciding how much of the total concentration to include in the PB term - * @param[out] pb_term the ComplexFunction in which to store the result + * @param[out] pb_term the CompFunction<3> in which to store the result * @details The PB term is computed as \f$ \kappa^2 \sinh(V_{tot}) \f$ and returned. */ - virtual void computePBTerm(mrcpp::ComplexFunction &V_tot, const double salt_factor, mrcpp::ComplexFunction &pb_term); + virtual void computePBTerm(mrcpp::CompFunction<3> &V_tot, const double salt_factor, mrcpp::CompFunction<3> &pb_term); }; } // namespace mrchem diff --git a/src/initial_guess/core.cpp b/src/initial_guess/core.cpp index 6df6ea298..b5bdc2892 100644 --- a/src/initial_guess/core.cpp +++ b/src/initial_guess/core.cpp @@ -37,7 +37,6 @@ #include "utils/print_utils.h" #include "qmfunctions/Orbital.h" -#include "qmfunctions/OrbitalIterator.h" #include "qmfunctions/orbital_utils.h" #include "qmoperators/one_electron/MomentumOperator.h" @@ -205,8 +204,8 @@ void initial_guess::core::project_ao(OrbitalVector &Phi, double prec, const Nucl HydrogenFunction h_func(n, l, m, Z, R); Phi.push_back(Orbital(SPIN::Paired)); Phi.back().setRank(Phi.size() - 1); - if (mrcpp::mpi::my_orb(Phi.back())) { - mrcpp::cplxfunc::project(Phi.back(), h_func, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi.back())) { + mrcpp::project(Phi.back(), h_func, prec); if (std::abs(Phi.back().norm() - 1.0) > 0.01) MSG_WARN("AO not normalized!"); } @@ -227,7 +226,7 @@ void initial_guess::core::project_ao(OrbitalVector &Phi, double prec, const Nucl void initial_guess::core::rotate_orbitals(OrbitalVector &Psi, double prec, ComplexMatrix &U, OrbitalVector &Phi) { if (Psi.size() == 0) return; Timer t_tot; - mrcpp::mpifuncvec::rotate(Phi, U, Psi, prec); + mrcpp::rotate(Phi, U, Psi, prec); mrcpp::print::time(1, "Rotating orbitals", t_tot); } diff --git a/src/initial_guess/cube.cpp b/src/initial_guess/cube.cpp index 36bb0491f..a9c2681cc 100644 --- a/src/initial_guess/cube.cpp +++ b/src/initial_guess/cube.cpp @@ -118,7 +118,7 @@ bool initial_guess::cube::project_mo(OrbitalVector &Phi, double prec, const std: bool success = true; for (int i = 0; i < Phi.size(); i++) { Timer t_i; - if (mrcpp::mpi::my_orb(Phi[i])) { + if (mrcpp::mpi::my_func(Phi[i])) { CUBEfunction phi_i = CUBEVector[i]; Phi[i].alloc(NUMBER::Real); mrcpp::project(prec, Phi[i].real(), phi_i); diff --git a/src/initial_guess/gto.cpp b/src/initial_guess/gto.cpp index 8a2082d4a..d71a4a28e 100644 --- a/src/initial_guess/gto.cpp +++ b/src/initial_guess/gto.cpp @@ -148,10 +148,9 @@ void initial_guess::gto::project_mo(OrbitalVector &Phi, double prec, const std:: Timer t3; for (int i = 0; i < Phi.size(); i++) { Timer t_i; - if (mrcpp::mpi::my_orb(Phi[i])) { + if (mrcpp::mpi::my_func(Phi[i])) { GaussExp<3> mo_i = gto_exp.getMO(i, MO.transpose()); mo_i.calcScreening(screen); - Phi[i].alloc(NUMBER::Real); mrcpp::project(prec, Phi[i].real(), mo_i); } std::stringstream o_txt; @@ -224,8 +223,8 @@ void initial_guess::gto::project_ao(OrbitalVector &Phi, double prec, const Nucle Phi.back().setRank(Phi.size() - 1); GaussExp<3> ao_i = gto_exp.getAO(i); ao_i.calcScreening(screen); - if (mrcpp::mpi::my_orb(Phi.back())) { - mrcpp::cplxfunc::project(Phi.back(), ao_i, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi.back())) { + mrcpp::project(Phi.back(), ao_i, prec); if (std::abs(Phi.back().norm() - 1.0) > 0.01) MSG_WARN("AO not normalized!"); } diff --git a/src/initial_guess/mw.cpp b/src/initial_guess/mw.cpp index 2548917e3..c00b4fdea 100644 --- a/src/initial_guess/mw.cpp +++ b/src/initial_guess/mw.cpp @@ -104,7 +104,7 @@ bool initial_guess::mw::project_mo(OrbitalVector &Phi, double prec, const std::s bool success = true; for (int i = 0; i < Phi.size(); i++) { Timer t_i; - if (mrcpp::mpi::my_orb(Phi[i])) { + if (mrcpp::mpi::my_func(Phi[i])) { std::stringstream orbname; orbname << mo_file << "_idx_" << i; @@ -114,17 +114,15 @@ bool initial_guess::mw::project_mo(OrbitalVector &Phi, double prec, const std::s MSG_ERROR("Guess orbital not found: " << orbname.str()); success &= false; } - if (phi_i.hasReal()) { - Phi[i].alloc(NUMBER::Real); + if (phi_i.isreal) { // Refine to get accurate function values mrcpp::refine_grid(phi_i.real(), 1); mrcpp::project(prec, Phi[i].real(), phi_i.real()); } - if (phi_i.hasImag()) { - Phi[i].alloc(NUMBER::Imag); + if (phi_i.iscomplex) { // Refine to get accurate function values mrcpp::refine_grid(phi_i.imag(), 1); - mrcpp::project(prec, Phi[i].imag(), phi_i.imag()); + mrcpp::project(prec, Phi[i].complex(), phi_i.complex()); } std::stringstream o_txt; o_txt << std::setw(w1 - 1) << i; diff --git a/src/initial_guess/sad.cpp b/src/initial_guess/sad.cpp index 86176ad87..779361f9e 100644 --- a/src/initial_guess/sad.cpp +++ b/src/initial_guess/sad.cpp @@ -104,7 +104,7 @@ bool initial_guess::sad::setup(OrbitalVector &Phi, double prec, double screen, c // Compute XC density Density &rho_xc = XC.getDensity(DensityType::Total); - mrcpp::cplxfunc::deep_copy(rho_xc, rho_j); + mrcpp::deep_copy(rho_xc, rho_j); if (plevel == 1) mrcpp::print::time(1, "Projecting GTO density", t_lap); // Project AO basis of hydrogen functions @@ -182,7 +182,7 @@ bool initial_guess::sad::setup(OrbitalVector &Phi, double prec, double screen, c // Compute XC density Density &rho_xc = XC.getDensity(DensityType::Total); - mrcpp::cplxfunc::deep_copy(rho_xc, rho_j); + mrcpp::deep_copy(rho_xc, rho_j); if (plevel == 1) mrcpp::print::time(1, "Projecting GTO density", t_lap); // Project AO basis of hydrogen functions @@ -249,7 +249,7 @@ void initial_guess::sad::project_atomic_densities(double prec, Density &rho_tot, Timer t_tot; Density rho_loc(false); - rho_loc.alloc(NUMBER::Real); + rho_loc.alloc(); rho_loc.real().setZero(); Timer t_loc; diff --git a/src/mrenv.cpp b/src/mrenv.cpp index 6823031a2..3ce5a755c 100644 --- a/src/mrenv.cpp +++ b/src/mrenv.cpp @@ -123,7 +123,7 @@ void mrenv::init_mra(const json &json_mra) { } else { MSG_ABORT("Invalid basis type!"); } - mrcpp::cplxfunc::SetdefaultMRA(MRA); + mrcpp::SetdefaultMRA(MRA); } void mrenv::init_mpi(const json &json_mpi) { diff --git a/src/parallel.cpp b/src/parallel.cpp index 10b6cdacc..29b9cd369 100644 --- a/src/parallel.cpp +++ b/src/parallel.cpp @@ -27,7 +27,7 @@ #include #include "parallel.h" -#include "qmfunctions/ComplexFunction.h" +#include "qmfunctions/CompFunction.h" #include "qmfunctions/Density.h" #include "qmfunctions/Orbital.h" #include "utils/Bank.h" @@ -223,7 +223,7 @@ bool mpi::share_master() { } /** @brief Test if orbital belongs to this MPI rank (or is common)*/ -bool mpi::my_orb(const Orbital &orb) { +bool mpi::my_func(const Orbital &orb) { return (orb.rankID() < 0 or orb.rankID() == mpi::orb_rank) ? true : false; } @@ -240,7 +240,7 @@ void mpi::distribute(OrbitalVector &Phi) { /** @brief Free all function pointers not belonging to this MPI rank */ void mpi::free_foreign(OrbitalVector &Phi) { for (auto &i : Phi) { - if (not mpi::my_orb(i)) i.free(NUMBER::Total); + if (not mpi::my_func(i)) i.free(NUMBER::Total); } } @@ -248,7 +248,7 @@ void mpi::free_foreign(OrbitalVector &Phi) { OrbitalChunk mpi::get_my_chunk(OrbitalVector &Phi) { OrbitalChunk chunk; for (int i = 0; i < Phi.size(); i++) { - if (mpi::my_orb(Phi[i])) chunk.push_back(std::make_tuple(i, Phi[i])); + if (mpi::my_func(Phi[i])) chunk.push_back(std::make_tuple(i, Phi[i])); } return chunk; } @@ -469,7 +469,7 @@ void mpi::allreduce_Tree_noCoeff(mrcpp::FunctionTree<3> &tree, OrbitalVector &Ph */ int N = Phi.size(); for (int j = 0; j < N; j++) { - if (not mpi::my_orb(Phi[j])) continue; + if (not mpi::my_func(Phi[j])) continue; if (Phi[j].hasReal()) tree.appendTreeNoCoeff(Phi[j].real()); if (Phi[j].hasImag()) tree.appendTreeNoCoeff(Phi[j].imag()); } diff --git a/src/properties/OrbitalEnergies.h b/src/properties/OrbitalEnergies.h index 93441c56e..43db0a055 100644 --- a/src/properties/OrbitalEnergies.h +++ b/src/properties/OrbitalEnergies.h @@ -41,11 +41,11 @@ namespace mrchem { // clang-format off class OrbitalEnergies final { public: - IntVector &getSpin() { return this->spin; } + IntVector &getSpin() { return this->spinVec; } IntVector &getOccupation() { return this->occupation; } DoubleVector &getEpsilon() { return this->epsilon; } - const IntVector &getSpin() const { return this->spin; } + const IntVector &getSpin() const { return this->spinVec; } const IntVector &getOccupation() const { return this->occupation; } const DoubleVector &getEpsilon() const { return this->epsilon; } @@ -69,9 +69,9 @@ class OrbitalEnergies final { for (int i = 0; i < this->epsilon.size(); i++) { auto sp = 'u'; - if (this->spin(i) == SPIN::Paired) sp = 'p'; - if (this->spin(i) == SPIN::Alpha) sp = 'a'; - if (this->spin(i) == SPIN::Beta) sp = 'b'; + if (this->spinVec(i) == SPIN::Paired) sp = 'p'; + if (this->spinVec(i) == SPIN::Alpha) sp = 'a'; + if (this->spinVec(i) == SPIN::Beta) sp = 'b'; std::stringstream o_txt; o_txt << std::setw(w1 - 1) << i; o_txt << std::setw(w1) << this->occupation(i); @@ -88,10 +88,10 @@ class OrbitalEnergies final { DoubleVector occ = getOccupation().cast(); const DoubleVector &eps = getEpsilon(); std::vector spn; - for (auto i = 0; i < spin.size(); i++) { - if (this->spin(i) == SPIN::Paired) spn.push_back("p"); - if (this->spin(i) == SPIN::Alpha) spn.push_back("a"); - if (this->spin(i) == SPIN::Beta) spn.push_back("b"); + for (auto i = 0; i < spinVec.size(); i++) { + if (this->spinVec(i) == SPIN::Paired) spn.push_back("p"); + if (this->spinVec(i) == SPIN::Alpha) spn.push_back("a"); + if (this->spinVec(i) == SPIN::Beta) spn.push_back("b"); } return { {"spin", spn}, @@ -102,7 +102,7 @@ class OrbitalEnergies final { } private: - IntVector spin; + IntVector spinVec; IntVector occupation; DoubleVector epsilon; }; diff --git a/src/qmfunctions/CMakeLists.txt b/src/qmfunctions/CMakeLists.txt index c03b9731b..5cc52936d 100644 --- a/src/qmfunctions/CMakeLists.txt +++ b/src/qmfunctions/CMakeLists.txt @@ -1,6 +1,6 @@ target_sources(mrchem PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/OrbitalIterator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Density.cpp ${CMAKE_CURRENT_SOURCE_DIR}/orbital_utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/density_utils.cpp - ) + ${CMAKE_CURRENT_SOURCE_DIR}/Orbital.cpp +) diff --git a/src/qmfunctions/ComplexFunction.h b/src/qmfunctions/ComplexFunction.h index 851759a8a..e85f6dff2 100644 --- a/src/qmfunctions/ComplexFunction.h +++ b/src/qmfunctions/ComplexFunction.h @@ -44,9 +44,9 @@ struct FunctionData { bool is_shared{false}; }; -class ComplexFunction final { +class CompFunction<3> final { public: - explicit ComplexFunction(bool share) + explicit CompFunction<3>(bool share) : shared_mem_re(nullptr) , shared_mem_im(nullptr) , re(nullptr) @@ -61,7 +61,7 @@ class ComplexFunction final { } } - ~ComplexFunction() { + ~CompFunction<3>() { if (this->shared_mem_re != nullptr) delete this->shared_mem_re; if (this->shared_mem_im != nullptr) delete this->shared_mem_im; if (this->re != nullptr) delete this->re; diff --git a/src/qmfunctions/Density.cpp b/src/qmfunctions/Density.cpp index db920197f..990f75ba1 100644 --- a/src/qmfunctions/Density.cpp +++ b/src/qmfunctions/Density.cpp @@ -40,7 +40,7 @@ namespace mrchem { * NO transfer of ownership. */ Density &Density::operator=(const Density &dens) { - if (this != &dens) mrcpp::ComplexFunction::operator=(dens); + if (this != &dens) mrcpp::CompFunction<3>::operator=(dens); return *this; } @@ -58,7 +58,8 @@ void Density::saveDensity(const std::string &file) { metafile << file << ".meta"; // this flushes tree sizes - mrcpp::FunctionData &func_data = mrcpp::ComplexFunction::getFunctionData(); + mrcpp::CompFunctionData<3> &func_data = mrcpp::CompFunction<3>::data; + flushFuncData(); std::fstream f; f.open(metafile.str(), std::ios::out | std::ios::binary); @@ -67,17 +68,17 @@ void Density::saveDensity(const std::string &file) { f.close(); // writing real part - if (hasReal()) { + if (isreal) { std::stringstream fname; fname << file << "_re"; - real().saveTree(fname.str()); + CompD[0]->saveTree(fname.str()); } // writing imaginary part - if (hasImag()) { + if (iscomplex) { std::stringstream fname; - fname << file << "_im"; - imag().saveTree(fname.str()); + fname << file << "_cx"; + CompC[0]->saveTree(fname.str()); } } @@ -98,27 +99,28 @@ void Density::loadDensity(const std::string &file) { fmeta << file << ".meta"; // this flushes tree sizes - mrcpp::FunctionData &func_data = mrcpp::ComplexFunction::getFunctionData(); + mrcpp::CompFunctionData<3> &func_data = mrcpp::CompFunction<3>::data; + flushFuncData(); std::fstream f; f.open(fmeta.str(), std::ios::in | std::ios::binary); if (f.is_open()) f.read((char *)&func_data, sizeof(mrcpp::FunctionData)); f.close(); - // reading real part - if (func_data.real_size > 0) { + // reading real tree + if (isreal) { std::stringstream fname; fname << file << "_re"; - alloc(NUMBER::Real); - real().loadTree(fname.str()); + alloc(0); + CompD[0]->loadTree(fname.str()); } - // reading imaginary part - if (func_data.imag_size > 0) { + // reading complex tree + if (iscomplex) { std::stringstream fname; - fname << file << "_im"; - alloc(NUMBER::Imag); - imag().loadTree(fname.str()); + fname << file << "_cx"; + alloc(0); + CompC[0]->loadTree(fname.str()); } } diff --git a/src/qmfunctions/Density.h b/src/qmfunctions/Density.h index 7f389b8a4..f5ffbca80 100644 --- a/src/qmfunctions/Density.h +++ b/src/qmfunctions/Density.h @@ -33,7 +33,7 @@ * * @brief General complex-valued function to handle densities (incl trans. densities) * - * Inherits the general features of a complex function from mrcpp::ComplexFunction which + * Inherits the general features of a complex function from mrcpp::CompFunction<3> which * means separate MW function representations for the real and imaginary parts. * Note that there are several options for copying/assignment: the proper copy * constructor and assignment operator are *shallow* copies, which means that @@ -48,12 +48,12 @@ namespace mrchem { -class Density final : public mrcpp::ComplexFunction { +class Density final : public mrcpp::CompFunction<3> { public: explicit Density(bool share) - : mrcpp::ComplexFunction(0, -1, -1, share) {} + : mrcpp::CompFunction<3>(0, share) {} Density(const Density &dens) - : mrcpp::ComplexFunction(dens) {} + : mrcpp::CompFunction<3>(dens) {} Density &operator=(const Density &dens); void saveDensity(const std::string &file); diff --git a/src/qmfunctions/Orbital.cpp b/src/qmfunctions/Orbital.cpp index 2e13c526a..c513538d6 100644 --- a/src/qmfunctions/Orbital.cpp +++ b/src/qmfunctions/Orbital.cpp @@ -35,69 +35,67 @@ namespace mrchem { /** @brief Default constructor * - * Initializes the QMFunction with NULL pointers for both real and imaginary part. + * Initializes with NULL tree pointers. */ Orbital::Orbital() - : QMFunction(false) - , orb_data({-1, 0, 0}) {} + : mrcpp::CompFunction<3>() {} + +/** @brief Constructor with only spin + * + * Initializes with NULL tree pointers. + */ +Orbital::Orbital(SPIN::type spin) + : mrcpp::CompFunction<3>(spin) { + if (this->spin() < 0) INVALID_ARG_ABORT; + // n2 is used to store occupancy + if (this->spin() == SPIN::Paired) this->data.n2[0] = 2; + if (this->spin() == SPIN::Alpha) this->data.n2[0] = 1; + if (this->spin() == SPIN::Beta) this->data.n2[0] = 1; +} /** @brief Constructor * * @param spin: electron spin (SPIN::Alpha/Beta/Paired) * @param occ: occupation - * @param rank: MPI ownership (-1 means all MPI ranks) + * @param rank: position in vector if part of a vector * - * Initializes the QMFunction with NULL pointers for both real and imaginary part. */ Orbital::Orbital(int spin, int occ, int rank) - : QMFunction(false) - , orb_data({rank, spin, occ}) { + : mrcpp::CompFunction<3>(spin){ if (this->spin() < 0) INVALID_ARG_ABORT; if (this->occ() < 0) { - if (this->spin() == SPIN::Paired) this->orb_data.occ = 2; - if (this->spin() == SPIN::Alpha) this->orb_data.occ = 1; - if (this->spin() == SPIN::Beta) this->orb_data.occ = 1; + // n2 is defined as occupancy + if (this->spin() == SPIN::Paired) this->data.n2[0] = 2; + if (this->spin() == SPIN::Alpha) this->data.n2[0] = 1; + if (this->spin() == SPIN::Beta) this->data.n2[0] = 1; } + this->rank = rank; } + /** @brief Copy constructor * * @param orb: orbital to copy * - * Shallow copy: meta data is copied along with the *re and *im pointers, + * Shallow copy: meta data is copied along with the pointers, * NO transfer of ownership. */ -Orbital::Orbital(const Orbital &orb) - : QMFunction(orb) - , orb_data(orb.orb_data) {} +Orbital::Orbital(Orbital &orb) + : mrcpp::CompFunction<3>(orb) {} -/** @brief Assignment operator + +/** @brief Copy constructor * * @param orb: orbital to copy * - * Shallow copy: meta data is copied along with the *re and *im pointers, + * Shallow copy: meta data is copied along with the pointers, * NO transfer of ownership. */ -Orbital &Orbital::operator=(const Orbital &orb) { - if (this != &orb) { - QMFunction::operator=(orb); - this->orb_data = orb.orb_data; - } - return *this; -} +//Orbital::Orbital(const mrcpp::CompFunction<3> &orb) +// : mrcpp::CompFunction<3>(orb) {} +Orbital::Orbital(const mrcpp::CompFunction<3>& orb) + : mrcpp::CompFunction<3>(orb) {} -Orbital &Orbital::operator=(const QMFunction &func) { - if (this != &func) QMFunction::operator=(func); - return *this; -} - -/** @brief Parameter copy - * - * Returns a new orbital with the same spin, occupation and rank_id as *this orbital. - */ -Orbital Orbital::paramCopy() const { - return Orbital(this->spin(), this->occ(), this->rankID()); -} /** @brief Complex conjugation * @@ -121,34 +119,8 @@ Orbital Orbital::dagger() const { * and imaginary ("phi_0_im.tree") parts. */ void Orbital::saveOrbital(const std::string &file) { - // writing meta data - std::stringstream metafile; - metafile << file << ".meta"; - - // this flushes tree sizes - FunctionData &func_data = getFunctionData(); - OrbitalData &orb_data = getOrbitalData(); - - std::fstream f; - f.open(metafile.str(), std::ios::out | std::ios::binary); - if (not f.is_open()) MSG_ERROR("Unable to open file"); - f.write((char *)&func_data, sizeof(FunctionData)); - f.write((char *)&orb_data, sizeof(OrbitalData)); - f.close(); - - // writing real part - if (hasReal()) { - std::stringstream fname; - fname << file << "_re"; - real().saveTree(fname.str()); - } - - // writing imaginary part - if (hasImag()) { - std::stringstream fname; - fname << file << "_im"; - imag().saveTree(fname.str()); - } + if (isreal) CompD[0]->saveTree(file); + if (iscomplex) CompC[0]->saveTree(file); } /** @brief Read orbital from disk @@ -160,54 +132,8 @@ void Orbital::saveOrbital(const std::string &file) { * and imaginary ("phi_0_im.tree") parts. */ void Orbital::loadOrbital(const std::string &file) { - if (hasReal()) MSG_ERROR("Orbital not empty"); - if (hasImag()) MSG_ERROR("Orbital not empty"); - - // reading meta data - std::stringstream fmeta; - fmeta << file << ".meta"; - - // this flushes tree sizes - FunctionData &func_data = getFunctionData(); - OrbitalData &orb_data = getOrbitalData(); - - std::fstream f; - f.open(fmeta.str(), std::ios::in | std::ios::binary); - if (f.is_open()) f.read((char *)&func_data, sizeof(FunctionData)); - if (f.is_open()) f.read((char *)&orb_data, sizeof(OrbitalData)); - f.close(); - - std::array corner{func_data.corner[0], func_data.corner[1], func_data.corner[2]}; - std::array boxes{func_data.boxes[0], func_data.boxes[1], func_data.boxes[2]}; - mrcpp::BoundingBox<3> world(func_data.scale, corner, boxes); - - mrcpp::MultiResolutionAnalysis<3> *mra = nullptr; - if (func_data.type == mrcpp::Interpol) { - mrcpp::InterpolatingBasis basis(func_data.order); - mra = new mrcpp::MultiResolutionAnalysis<3>(world, basis, func_data.depth); - } else if (func_data.type == mrcpp::Legendre) { - mrcpp::LegendreBasis basis(func_data.order); - mra = new mrcpp::MultiResolutionAnalysis<3>(world, basis, func_data.depth); - } else { - MSG_ABORT("Invalid basis type!"); - } - - // reading real part - if (func_data.real_size > 0) { - std::stringstream fname; - fname << file << "_re"; - alloc(NUMBER::Real, mra); - real().loadTree(fname.str()); - } - - // reading imaginary part - if (func_data.imag_size > 0) { - std::stringstream fname; - fname << file << "_im"; - alloc(NUMBER::Imag, mra); - imag().loadTree(fname.str()); - } - delete mra; + if (isreal) CompD[0]->loadTree(file); + if (iscomplex) CompC[0]->loadTree(file); } /** @brief Returns a character representing the spin (a/b/p) */ diff --git a/src/qmfunctions/Orbital.h b/src/qmfunctions/Orbital.h index 99a770441..de2ececef 100644 --- a/src/qmfunctions/Orbital.h +++ b/src/qmfunctions/Orbital.h @@ -27,12 +27,13 @@ #include "MRCPP/MWFunctions" #include "MRCPP/Parallel" +#include "mrchem.h" /** @class Orbital * * @brief General complex-valued function with spin * - * Inherits the general features of a complex function from mrcpp::ComplexFunction which + * Inherits the general features of a complex function from mrcpp::CompFunction<3> which * means separate MW function representations for the real and imaginary parts. * Note that there are several options for copying/assignment: the proper copy * constructor and assignment operator are *shallow* copies, which means that @@ -48,7 +49,43 @@ namespace mrchem { -using Orbital = mrcpp::ComplexFunction; -using OrbitalVector = mrcpp::MPI_FuncVector; +#define spin() data.n1[0] +#define occ() data.n2[0] +class Orbital : public mrcpp::CompFunction<3> { +public: + Orbital(); + Orbital(SPIN::type spin); + Orbital(Orbital &orb); + Orbital(const mrcpp::CompFunction<3> &orb); + Orbital(int spin, int occ, int rank = -1); + Orbital dagger() const; + + // const int spin() const {return data.n1[0];} + // const int occ() const {return data.n2[0];} + char printSpin() const; + void setSpin(int spin) {this->data.n2[0] = spin;} + void saveOrbital(const std::string &file); + void loadOrbital(const std::string &file); +}; + +//using OrbitalVector = mrcpp::CompFunctionVector<3>; +class OrbitalVector : public mrcpp::CompFunctionVector { +public: + OrbitalVector(int N = 0) : mrcpp::CompFunctionVector(N) {} + void push_back(Orbital orb) { orb.rank = size(); this->push_back(orb);} + void distribute() {this->distribute();} + // Overloaded operator[] to return an Orbital element + // for read (returns lvalue) + Orbital operator[](int i) const { + // Create a temporary copy of the base class element to avoid discarding qualifiers + mrcpp::CompFunction<3> func = mrcpp::CompFunctionVector::operator[](i); + return Orbital(func); + } + // Non-const version of operator[] to allow modification of elements + // for write (returns rvalue). Cannot return an Orbital + mrcpp::CompFunction<3>& operator[](int i) { + return mrcpp::CompFunctionVector::operator[](i); + } +}; } // namespace mrchem diff --git a/src/qmfunctions/OrbitalIterator.cpp b/src/qmfunctions/OrbitalIterator.cpp deleted file mode 100644 index c91b3834a..000000000 --- a/src/qmfunctions/OrbitalIterator.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - * MRChem, a numerical real-space code for molecular electronic structure - * calculations within the self-consistent field (SCF) approximations of quantum - * chemistry (Hartree-Fock and Density Functional Theory). - * Copyright (C) 2023 Stig Rune Jensen, Luca Frediani, Peter Wind and contributors. - * - * This file is part of MRChem. - * - * MRChem is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MRChem is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with MRChem. If not, see . - * - * For information on the complete list of contributors to MRChem, see: - * - */ - -#include "MRCPP/Parallel" -#include "MRCPP/Printer" - -#include "Orbital.h" -#include "OrbitalIterator.h" - -namespace mrchem { - -OrbitalIterator::OrbitalIterator(OrbitalVector &Phi, bool sym) - : symmetric(sym) - , iter(0) - , received_counter(0) - , sent_counter(0) - , orbitals(&Phi) { - // Find and save the orbitals each rank owns - int my_mpi_rank = mrcpp::mpi::wrk_rank; - for (int impi = 0; impi < mrcpp::mpi::wrk_size; impi++) { - std::vector orb_ix; - for (int i = 0; i < this->orbitals->size(); i++) { - Orbital &phi_i = (*this->orbitals)[i]; - int phi_rank = phi_i.getRank(); - if (mrcpp::mpi::my_orb(i)) orb_ix.push_back(i); - // if (impi == my_mpi_rank and phi_rank < 0) orb_ix.push_back(i); - } - this->orb_ix_map.push_back(orb_ix); - } -} - -// Receive all the orbitals, for non symmetric treatment -// Receive half of the orbitals, for symmetric treatment -// Send own orbitals to half of the MPI, for symmetric treatment -// The algorithm ensures that at each iteration, each MPI is communicating -// with only one other MPI. This ensures good communication parallelism. -// NB: iter counts the number of MPI looped over: -// there may be several calls to "next" for the same iter in case max_recv<0, -// or double iterations for symmetric treatment. -bool OrbitalIterator::next(int max_recv) { - mrcpp::mpi::free_foreign(*this->orbitals); // delete foreign orbitals - // NB: for now we completely delete orbitals at each iteration. Could reuse the memory in next iteration. - this->received_orbital_index.clear(); - this->received_orbitals.clear(); - this->sent_orbital_index.clear(); - this->sent_orbital_mpirank.clear(); - this->rcv_step.clear(); - - if (this->iter >= mrcpp::mpi::wrk_size) { - // We have talked to all MPIs -> return - this->iter = 0; - return false; - } - - // We communicate with one MPI per iteration: - // - Symmetric: do two iterations, send in one step receive in the other - // - send ALL my orbitals to other_rank (or max_recv if set) - // - receive ALL orbitals owned by other_rank (or max_recv if set) - // - other_rank increases by one for each iteration, modulo size - // Each MPI pair will be treated exactly once at the end of the iteration process - - int my_rank = mrcpp::mpi::wrk_rank; - int max_rank = mrcpp::mpi::wrk_size; - int received = 0; // number of new received orbitals this call - int sent = 0; // number of new sent orbitals this call - int maxget = max_recv; // max number of orbitals to receive - if (maxget < 0) maxget = this->orbitals->size(); // unlimited - - int nstep = 1; // send and receive in the same iteration - if (this->symmetric) nstep = 2; // one iteration is receive, one iteration is send - - for (int step = 0; step < nstep; step++) { - if (this->iter >= mrcpp::mpi::wrk_size) break; // last iteration is completed - - bool IamReceiver = true; // default, both send and receive - bool IamSender = true; // default, both send and receive - - // Figure out which MPI to talk to - int other_rank = (max_rank + this->iter - my_rank) % max_rank; - // note: my_rank= (max_rank + this->iter - other_rank)%max_rank - - int send_size = this->orb_ix_map[my_rank].size(); - int recv_size = this->orb_ix_map[other_rank].size(); - - if (other_rank == my_rank) { - // We receive from ourself - IamSender = false; // sending data is "for free" - for (int i = this->received_counter; i < send_size and received < maxget; i++) { - int orb_ix = this->orb_ix_map[my_rank][i]; - Orbital &phi_i = (*this->orbitals)[orb_ix]; - this->rcv_step.push_back(step); - this->received_orbital_index.push_back(orb_ix); - this->received_orbitals.push_back(phi_i); - this->received_counter++; - received++; - } - } else { - if (this->symmetric) { - // Either send or receive - // Figure out which one will send and receive - //(my_rank + other_rank )%2 flips each time other_rank changes by one - //(my_rank < other_rank) ensures that my_rank and other_rank are opposite - // my_rank = other_rank must correspond to a receive (since it implicitely means extra work later on) - // NB: must take care that if at one step other_rank == my_rank, the other step must not be a receive!! - // not trivial - if ((my_rank + other_rank + (my_rank > other_rank)) % 2) { - IamReceiver = false; - } else { - IamSender = false; - } - } - - // highest mpi rank send first receive after, the other does the opposite - if (my_rank > other_rank) { - // send - for (int i = this->sent_counter; i < send_size and IamSender and sent < maxget; i++) { - int tag = this->orbitals->size() * this->iter + i; - int orb_ix = this->orb_ix_map[my_rank][i]; - Orbital &phi_i = (*this->orbitals)[orb_ix]; - mrcpp::mpi::send_function(phi_i, other_rank, tag); - this->sent_orbital_index.push_back(orb_ix); - this->sent_orbital_mpirank.push_back(other_rank); - this->sent_counter++; // total to other_rank - sent++; // this call - } - // receive - for (int i = this->received_counter; i < recv_size and IamReceiver and received < maxget; i++) { - int tag = this->orbitals->size() * this->iter + i; - int orb_ix = this->orb_ix_map[other_rank][i]; - Orbital &phi_i = (*this->orbitals)[orb_ix]; - mrcpp::mpi::recv_function(phi_i, other_rank, tag); - this->received_orbital_index.push_back(orb_ix); - this->received_orbitals.push_back(phi_i); - this->rcv_step.push_back(step); - this->received_counter++; // total from other_rank - received++; // this call - } - } else { - // my_rank < other_rank -> receive first, send after receive - for (int i = this->received_counter; i < recv_size and IamReceiver and received < maxget; i++) { - int tag = this->orbitals->size() * this->iter + i; - int orb_ix = this->orb_ix_map[other_rank][i]; - Orbital &phi_i = (*this->orbitals)[orb_ix]; - mrcpp::mpi::recv_function(phi_i, other_rank, tag); - this->received_orbital_index.push_back(orb_ix); - this->received_orbitals.push_back(phi_i); - this->rcv_step.push_back(step); - this->received_counter++; // total from other_rank - received++; // this call - } - // send - for (int i = this->sent_counter; i < send_size and IamSender and sent < maxget; i++) { - int tag = this->orbitals->size() * this->iter + i; - int orb_ix = this->orb_ix_map[my_rank][i]; - Orbital &phi_i = (*this->orbitals)[orb_ix]; - mrcpp::mpi::send_function(phi_i, other_rank, tag); - this->sent_orbital_index.push_back(orb_ix); - this->sent_orbital_mpirank.push_back(other_rank); - this->sent_counter++; // total to other_rank - sent++; // this call - } - } - } - - if ((this->sent_counter >= send_size or not IamSender) and (this->received_counter >= recv_size or not IamReceiver)) { - // all orbitals to be processed during this iteration are ready. Start next iteration - this->sent_counter = 0; - this->received_counter = 0; - this->iter++; - if (this->iter % 2 == 0) break; // must always exit after odd iterations in order to finish duties outside - } - } - return true; -} - -// Receive all the orbitals from Bank -bool OrbitalIterator::bank_next(int max_recv) { - mrcpp::mpi::free_foreign(*this->orbitals); // delete foreign orbitals - // NB: for now we completely delete orbitals at each iteration. Could reuse the memory in next iteration. - this->received_orbital_index.clear(); - this->received_orbitals.clear(); - this->rcv_step.clear(); - - if (this->iter >= this->orbitals->size()) { - // We have received all orbitals -> return - this->iter = 0; - return false; - } - - int my_rank = mrcpp::mpi::wrk_rank; - int max_rank = mrcpp::mpi::wrk_size; - int received = 0; // number of new received orbitals this call - int recv_size = 1; // number of orbitals to receive per iteration - - if (this->iter == 0) { - // send all my orbitals to bank - for (int i = 0; i < this->orbitals->size(); i++) { - Orbital &phi_i = (*this->orbitals)[i]; - if (not mrcpp::mpi::my_orb(i)) continue; - orbBank.put_func(i, phi_i); - } - } - - // receive - for (int i = 0; i < recv_size; i++) { - int tag = i; - int orb_ix = this->received_counter; - Orbital &phi_i = (*this->orbitals)[orb_ix]; - orbBank.get_func(orb_ix, phi_i); - this->received_orbital_index.push_back(orb_ix); - this->received_orbitals.push_back(phi_i); - this->received_counter++; // total - received++; // this call - } - - // all orbitals to be processed during this iteration are ready. Start next iteration - this->iter++; - - return true; -} - -} // namespace mrchem diff --git a/src/qmfunctions/OrbitalIterator.h b/src/qmfunctions/OrbitalIterator.h deleted file mode 100644 index f40559823..000000000 --- a/src/qmfunctions/OrbitalIterator.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * MRChem, a numerical real-space code for molecular electronic structure - * calculations within the self-consistent field (SCF) approximations of quantum - * chemistry (Hartree-Fock and Density Functional Theory). - * Copyright (C) 2023 Stig Rune Jensen, Luca Frediani, Peter Wind and contributors. - * - * This file is part of MRChem. - * - * MRChem is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MRChem is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with MRChem. If not, see . - * - * For information on the complete list of contributors to MRChem, see: - * - */ - -#pragma once - -#include "orbital_utils.h" - -namespace mrchem { - -class OrbitalIterator final { -public: - OrbitalIterator(OrbitalVector &Phi, bool sym = false); - - mrcpp::BankAccount orbBank; - bool next(int max_recv = -1); - bool bank_next(int max_recv = 1); - - int idx(int i) const { return (this->received_orbital_index)[i]; } - Orbital &orbital(int i) { return (this->received_orbitals)[i]; } - - int get_size() const { return this->received_orbitals.size(); } - int get_idx_sent(int i) const { return (this->sent_orbital_index)[i]; } - int get_rank_sent(int i) const { return (this->sent_orbital_mpirank)[i]; } - int get_step(int i) const { return (this->rcv_step)[i]; } - int get_sent_size() const { return this->sent_orbital_index.size(); } - -protected: - const bool symmetric; - int iter; - int received_counter; // number of orbitals fetched during this iteration - int sent_counter; // number of orbitals sent during this iteration - OrbitalVector *orbitals; - OrbitalVector received_orbitals; - std::vector received_orbital_index; // index of the orbitals received - std::vector sent_orbital_index; // indices of the orbitals sent out - std::vector sent_orbital_mpirank; // mpi rank (=rank) of the orbitals sent out - std::vector rcv_step; // for symmetric treatment: if the send was at step=0 or 1 - std::vector> orb_ix_map; // indices in the original orbital vector for each MPI -}; - -} // namespace mrchem diff --git a/src/qmfunctions/QMFunction.cpp b/src/qmfunctions/QMFunction.cpp deleted file mode 100644 index 2bb81d0f6..000000000 --- a/src/qmfunctions/QMFunction.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* - * MRChem, a numerical real-space code for molecular electronic structure - * calculations within the self-consistent field (SCF) approximations of quantum - * chemistry (Hartree-Fock and Density Functional Theory). - * Copyright (C) 2023 Stig Rune Jensen, Luca Frediani, Peter Wind and contributors. - * - * This file is part of MRChem. - * - * MRChem is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MRChem is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with MRChem. If not, see . - * - * For information on the complete list of contributors to MRChem, see: - * - */ - -#include "MRCPP/Parallel" -#include "MRCPP/Printer" - -#include "QMFunction.h" -#include "parallel.h" -#include "qmfunctions/qmfunction_utils.h" - -namespace mrchem { -extern mrcpp::MultiResolutionAnalysis<3> *MRA; // Global MRA - -QMFunction::QMFunction(bool share) - : func_ptr(std::make_shared(share)) {} - -QMFunction::QMFunction(const QMFunction &func) - : conj(func.conj) - , func_ptr(func.func_ptr) {} - -QMFunction &QMFunction::operator=(const QMFunction &func) { - if (this != &func) { - this->conj = func.conj; - this->func_ptr = func.func_ptr; - } - return *this; -} - -QMFunction QMFunction::dagger() { - QMFunction out(*this); - out.conj = not(this->conj); - return out; -} - -void QMFunction::setReal(mrcpp::FunctionTree<3> *tree) { - if (isShared()) MSG_ABORT("Cannot set in shared function"); - this->func_ptr->re = tree; -} - -void QMFunction::setImag(mrcpp::FunctionTree<3> *tree) { - if (isShared()) MSG_ABORT("Cannot set in shared function"); - this->func_ptr->im = tree; -} - -void QMFunction::alloc(int type, mrcpp::MultiResolutionAnalysis<3> *mra) { - if (mra == nullptr) MSG_ABORT("Invalid argument"); - if (type == NUMBER::Real or type == NUMBER::Total) { - if (hasReal()) MSG_ABORT("Real part already allocated"); - this->func_ptr->re = new mrcpp::FunctionTree<3>(*mra, this->func_ptr->shared_mem_re); - } - if (type == NUMBER::Imag or type == NUMBER::Total) { - if (hasImag()) MSG_ABORT("Imaginary part already allocated"); - this->func_ptr->im = new mrcpp::FunctionTree<3>(*mra, this->func_ptr->shared_mem_im); - } -} - -void QMFunction::free(int type) { - if (type == NUMBER::Real or type == NUMBER::Total) { - if (hasReal()) delete this->func_ptr->re; - this->func_ptr->re = nullptr; - if (this->func_ptr->shared_mem_re) this->func_ptr->shared_mem_re->clear(); - } - if (type == NUMBER::Imag or type == NUMBER::Total) { - if (hasImag()) delete this->func_ptr->im; - this->func_ptr->im = nullptr; - if (this->func_ptr->shared_mem_im) this->func_ptr->shared_mem_im->clear(); - } -} - -/** @brief Returns the orbital meta data - * - * Tree sizes (nChunks) are flushed before return. - */ -FunctionData &QMFunction::getFunctionData() { - this->func_ptr->flushFuncData(); - return this->func_ptr->func_data; -} - -int QMFunction::getSizeNodes(int type) const { - int size_mb = 0; // Memory size in kB - if (type == NUMBER::Real or type == NUMBER::Total) { - if (hasReal()) size_mb += real().getSizeNodes(); - } - if (type == NUMBER::Imag or type == NUMBER::Total) { - if (hasImag()) size_mb += imag().getSizeNodes(); - } - return size_mb; -} - -int QMFunction::getNNodes(int type) const { - int nNodes = 0; - if (type == NUMBER::Real or type == NUMBER::Total) { - if (hasReal()) nNodes += real().getNNodes(); - } - if (type == NUMBER::Imag or type == NUMBER::Total) { - if (hasImag()) nNodes += imag().getNNodes(); - } - return nNodes; -} - -int QMFunction::crop(double prec) { - if (prec < 0.0) return 0; - bool need_to_crop = not(isShared()) or mpi::share_master(); - int nChunksremoved = 0; - if (need_to_crop) { - if (hasReal()) nChunksremoved = real().crop(prec, 1.0, false); - if (hasImag()) nChunksremoved += imag().crop(prec, 1.0, false); - } - mpi::share_function(*this, 0, 7744, mpi::comm_share); - return nChunksremoved; -} - -ComplexDouble QMFunction::integrate() const { - double int_r = 0.0; - double int_i = 0.0; - if (hasReal()) int_r = real().integrate(); - if (hasImag()) int_i = imag().integrate(); - return ComplexDouble(int_r, int_i); -} - -/** @brief Returns the norm of the orbital */ -double QMFunction::norm() const { - double norm = squaredNorm(); - if (norm > 0.0) norm = std::sqrt(norm); - return norm; -} - -/** @brief Returns the squared norm of the orbital */ -double QMFunction::squaredNorm() const { - double sq_r = -1.0; - double sq_i = -1.0; - if (hasReal()) sq_r = real().getSquareNorm(); - if (hasImag()) sq_i = imag().getSquareNorm(); - - double sq_norm = 0.0; - if (sq_r < 0.0 and sq_i < 0.0) { - sq_norm = -1.0; - } else { - if (sq_r >= 0.0) sq_norm += sq_r; - if (sq_i >= 0.0) sq_norm += sq_i; - } - return sq_norm; -} - -/** @brief In place addition. - * - * Output is extended to union grid. - * - */ -void QMFunction::add(ComplexDouble c, QMFunction inp) { - double thrs = mrcpp::MachineZero; - bool cHasReal = (std::abs(c.real()) > thrs); - bool cHasImag = (std::abs(c.imag()) > thrs); - bool outNeedsReal = (cHasReal and inp.hasReal()) or (cHasImag and inp.hasImag()); - bool outNeedsImag = (cHasReal and inp.hasImag()) or (cHasImag and inp.hasReal()); - - QMFunction &out = *this; - bool clearReal(false), clearImag(false); - if (outNeedsReal and not(out.hasReal())) { - out.alloc(NUMBER::Real); - clearReal = true; - } - - if (outNeedsImag and not(out.hasImag())) { - out.alloc(NUMBER::Imag); - clearImag = true; - } - - bool need_to_add = not(out.isShared()) or mpi::share_master(); - if (need_to_add) { - if (clearReal) out.real().setZero(); - if (clearImag) out.imag().setZero(); - if (cHasReal and inp.hasReal()) { - while (mrcpp::refine_grid(out.real(), inp.real())) {} - out.real().add(c.real(), inp.real()); - } - if (cHasReal and inp.hasImag()) { - double conj = (inp.conjugate()) ? -1.0 : 1.0; - while (mrcpp::refine_grid(out.imag(), inp.imag())) {} - out.imag().add(conj * c.real(), inp.imag()); - } - if (cHasImag and inp.hasReal()) { - while (mrcpp::refine_grid(out.imag(), inp.real())) {} - out.imag().add(c.imag(), inp.real()); - } - if (cHasImag and inp.hasImag()) { - double conj = (inp.conjugate()) ? -1.0 : 1.0; - while (mrcpp::refine_grid(out.real(), inp.imag())) {} - out.real().add(-1.0 * conj * c.imag(), inp.imag()); - } - } - mpi::share_function(out, 0, 9911, mpi::comm_share); -} - -/** @brief In place addition of absolute values. - * - * Output is extended to union grid. - * - */ -void QMFunction::absadd(ComplexDouble c, QMFunction inp) { - double thrs = mrcpp::MachineZero; - bool cHasReal = (std::abs(c.real()) > thrs); - bool cHasImag = (std::abs(c.imag()) > thrs); - bool outNeedsReal = (cHasReal and inp.hasReal()) or (cHasImag and inp.hasImag()); - bool outNeedsImag = (cHasReal and inp.hasImag()) or (cHasImag and inp.hasReal()); - - QMFunction &out = *this; - bool clearReal(false), clearImag(false); - if (outNeedsReal and not(out.hasReal())) { - out.alloc(NUMBER::Real); - clearReal = true; - } - - if (outNeedsImag and not(out.hasImag())) { - out.alloc(NUMBER::Imag); - clearImag = true; - } - - bool need_to_add = not(out.isShared()) or mpi::share_master(); - if (need_to_add) { - if (clearReal) out.real().setZero(); - if (clearImag) out.imag().setZero(); - if (cHasReal and inp.hasReal()) { - while (mrcpp::refine_grid(out.real(), inp.real())) {} - out.real().absadd(c.real(), inp.real()); - } - if (cHasReal and inp.hasImag()) { - double conj = (inp.conjugate()) ? -1.0 : 1.0; - while (mrcpp::refine_grid(out.imag(), inp.imag())) {} - out.imag().absadd(conj * c.real(), inp.imag()); - } - if (cHasImag and inp.hasReal()) { - while (mrcpp::refine_grid(out.imag(), inp.real())) {} - out.imag().absadd(c.imag(), inp.real()); - } - if (cHasImag and inp.hasImag()) { - double conj = (inp.conjugate()) ? -1.0 : 1.0; - while (mrcpp::refine_grid(out.real(), inp.imag())) {} - out.real().absadd(-1.0 * conj * c.imag(), inp.imag()); - } - } - mpi::share_function(out, 0, 9912, mpi::comm_share); -} - -/** @brief In place multiply with real scalar. Fully in-place.*/ -void QMFunction::rescale(double c) { - bool need_to_rescale = not(isShared()) or mpi::share_master(); - if (need_to_rescale) { - if (hasReal()) real().rescale(c); - if (hasImag()) imag().rescale(c); - } - mpi::share_function(*this, 0, 5543, mpi::comm_share); -} - -/** @brief In place multiply with complex scalar. Involves a deep copy.*/ -void QMFunction::rescale(ComplexDouble c) { - QMFunction &out = *this; - QMFunction tmp(isShared()); - qmfunction::deep_copy(tmp, out); - out.free(NUMBER::Total); - out.add(c, tmp); -} - -} // namespace mrchem diff --git a/src/qmfunctions/QMFunction.h b/src/qmfunctions/QMFunction.h deleted file mode 100644 index a49b7fbf7..000000000 --- a/src/qmfunctions/QMFunction.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * MRChem, a numerical real-space code for molecular electronic structure - * calculations within the self-consistent field (SCF) approximations of quantum - * chemistry (Hartree-Fock and Density Functional Theory). - * Copyright (C) 2023 Stig Rune Jensen, Luca Frediani, Peter Wind and contributors. - * - * This file is part of MRChem. - * - * MRChem is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MRChem is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with MRChem. If not, see . - * - * For information on the complete list of contributors to MRChem, see: - * - */ - -#pragma once - -#include - -#include "ComplexFunction.h" -#include "qmfunction_fwd.h" - -namespace mrchem { - -class QMFunction { -public: - explicit QMFunction(bool share = false); - QMFunction(const QMFunction &func); - QMFunction &operator=(const QMFunction &func); - QMFunction dagger(); - virtual ~QMFunction() = default; - - void alloc(int type, mrcpp::MultiResolutionAnalysis<3> *mra = MRA); - void free(int type); - - bool isShared() const { return this->func_ptr->func_data.is_shared; } - bool hasReal() const { return (this->func_ptr->re == nullptr) ? false : true; } - bool hasImag() const { return (this->func_ptr->im == nullptr) ? false : true; } - - int getSizeNodes(int type) const; - int getNNodes(int type) const; - - FunctionData &getFunctionData(); - - void setReal(mrcpp::FunctionTree<3> *tree); - void setImag(mrcpp::FunctionTree<3> *tree); - - mrcpp::FunctionTree<3> &real() { return *this->func_ptr->re; } - mrcpp::FunctionTree<3> &imag() { return *this->func_ptr->im; } - - const mrcpp::FunctionTree<3> &real() const { return *this->func_ptr->re; } - const mrcpp::FunctionTree<3> &imag() const { return *this->func_ptr->im; } - - void release() { this->func_ptr.reset(); } - bool conjugate() const { return this->conj; } - - double norm() const; - double squaredNorm() const; - ComplexDouble integrate() const; - - int crop(double prec); - void rescale(double c); - void rescale(ComplexDouble c); - void add(ComplexDouble c, QMFunction inp); - void absadd(ComplexDouble c, QMFunction inp); - -protected: - bool conj{false}; - std::shared_ptr func_ptr; -}; - -} // namespace mrchem diff --git a/src/qmfunctions/density_utils.cpp b/src/qmfunctions/density_utils.cpp index 423017543..13368571c 100644 --- a/src/qmfunctions/density_utils.cpp +++ b/src/qmfunctions/density_utils.cpp @@ -50,12 +50,27 @@ namespace density { Density compute(double prec, Orbital phi, DensityType spin); void compute_local_X(double prec, Density &rho, OrbitalVector &Phi, OrbitalVector &X, DensityType spin); void compute_local_XY(double prec, Density &rho, OrbitalVector &Phi, OrbitalVector &X, OrbitalVector &Y, DensityType spin); -double compute_occupation(Orbital &phi, DensityType dens_spin); +double compute_occupation(const Orbital &phi, DensityType dens_spin); } // namespace density +double density::compute_occupation(const Orbital &phi, DensityType dens_spin) { + double occ_a(0.0), occ_b(0.0), occ_p(0.0); + if (phi.spin() == SPIN::Alpha) occ_a = (double)phi.occ(); + if (phi.spin() == SPIN::Beta) occ_b = (double)phi.occ(); + if (phi.spin() == SPIN::Paired) occ_p = (double)phi.occ(); + + double occup(0.0); + if (dens_spin == DensityType::Total) occup = occ_a + occ_b + occ_p; + if (dens_spin == DensityType::Alpha) occup = occ_a + 0.5 * occ_p; + if (dens_spin == DensityType::Beta) occup = occ_b + 0.5 * occ_p; + if (dens_spin == DensityType::Spin) occup = occ_a - occ_b; + + return occup; +} + /** @brief Compute density as the square of an orbital * - * This routine is similar to mrcpp::cplxfunc::multiply_real(), but it uses + * This routine is similar to mrcpp::multiply_real(), but it uses * mrcpp::square(phi) instead of mrcpp::multiply(phi, phi), which makes it * slightly faster. * @@ -140,7 +155,7 @@ void density::compute_local(double prec, Density &rho, OrbitalVector &Phi, Densi if (rho.hasImag()) rho.imag().setZero(); for (auto &phi_i : Phi) { - if (mrcpp::mpi::my_orb(phi_i)) { + if (mrcpp::mpi::my_func(phi_i)) { Density rho_i = density::compute(prec, phi_i, spin); rho.add(1.0, rho_i); // Extends to union grid rho.crop(abs_prec); // Truncates to given precision @@ -164,19 +179,19 @@ void density::compute_local_X(double prec, Density &rho, OrbitalVector &Phi, Orb double add_prec = prec / N_el; // prec for rho = sum_i rho_i if (Phi.size() != X.size()) MSG_ERROR("Size mismatch"); - if (not rho.hasReal()) rho.alloc(NUMBER::Real); + if (rho.Ncomp == 0) rho.alloc(0); // Compute local density from own orbitals rho.real().setZero(); for (int i = 0; i < Phi.size(); i++) { - if (mrcpp::mpi::my_orb(Phi[i])) { - if (not mrcpp::mpi::my_orb(X[i])) MSG_ABORT("Inconsistent MPI distribution"); - - double occ = density::compute_occupation(Phi[i], spin); + if (mrcpp::mpi::my_func(Phi[i])) { + if (not mrcpp::mpi::my_func(X[i])) MSG_ABORT("Inconsistent MPI distribution"); + Orbital phi_i = Phi[i]; + double occ = density::compute_occupation(phi_i, spin); if (std::abs(occ) < mrcpp::MachineZero) continue; // next orbital if this one is not occupied! Density rho_i(false); - mrcpp::cplxfunc::multiply_real(rho_i, Phi[i], X[i], mult_prec); + mrcpp::multiply(rho_i, phi_i, X[i], mult_prec); rho.add(2.0 * occ, rho_i); rho.crop(add_prec); } @@ -190,22 +205,26 @@ void density::compute_local_XY(double prec, Density &rho, OrbitalVector &Phi, Or if (Phi.size() != X.size()) MSG_ERROR("Size mismatch"); if (Phi.size() != Y.size()) MSG_ERROR("Size mismatch"); - if (not rho.hasReal()) rho.alloc(NUMBER::Real); + if (rho.Ncomp == 0) rho.alloc(0); // Compute local density from own orbitals rho.real().setZero(); for (int i = 0; i < Phi.size(); i++) { - if (mrcpp::mpi::my_orb(Phi[i])) { - if (not mrcpp::mpi::my_orb(X[i])) MSG_ABORT("Inconsistent MPI distribution"); - if (not mrcpp::mpi::my_orb(Y[i])) MSG_ABORT("Inconsistent MPI distribution"); + if (mrcpp::mpi::my_func(Phi[i])) { + Orbital phi_i = Phi[i]; + if (not mrcpp::mpi::my_func(X[i])) MSG_ABORT("Inconsistent MPI distribution"); + if (not mrcpp::mpi::my_func(Y[i])) MSG_ABORT("Inconsistent MPI distribution"); - double occ = density::compute_occupation(Phi[i], spin); + double occ = density::compute_occupation(phi_i, spin); if (std::abs(occ) < mrcpp::MachineZero) continue; // next orbital if this one is not occupied! Density rho_x(false); Density rho_y(false); - mrcpp::cplxfunc::multiply(rho_x, X[i], Phi[i].dagger(), mult_prec); - mrcpp::cplxfunc::multiply(rho_y, Phi[i], Y[i].dagger(), mult_prec); + MSG_ERROR("Complex trees not yet included"); + // mrcpp::multiply(rho_x, X[i], Phi[i].dagger(), mult_prec); + // mrcpp::multiply(rho_y, Phi[i], Y[i].dagger(), mult_prec); + mrcpp::multiply(rho_x, X[i], Phi[i], mult_prec); + mrcpp::multiply(rho_y, Phi[i], Y[i], mult_prec); rho.add(occ, rho_x); rho.add(occ, rho_y); rho.crop(add_prec); @@ -219,21 +238,6 @@ void density::compute(double prec, Density &rho, mrcpp::GaussExp<3> &dens_exp) { mrcpp::project(prec, rho.real(), dens_exp); } -double density::compute_occupation(Orbital &phi, DensityType dens_spin) { - double occ_a(0.0), occ_b(0.0), occ_p(0.0); - if (phi.spin() == SPIN::Alpha) occ_a = (double)phi.occ(); - if (phi.spin() == SPIN::Beta) occ_b = (double)phi.occ(); - if (phi.spin() == SPIN::Paired) occ_p = (double)phi.occ(); - - double occ(0.0); - if (dens_spin == DensityType::Total) occ = occ_a + occ_b + occ_p; - if (dens_spin == DensityType::Alpha) occ = occ_a + 0.5 * occ_p; - if (dens_spin == DensityType::Beta) occ = occ_b + 0.5 * occ_p; - if (dens_spin == DensityType::Spin) occ = occ_a - occ_b; - - return occ; -} - /** @brief Add up local density contributions and broadcast * * MPI: Each rank first computes its own local density, which is then reduced diff --git a/src/qmfunctions/density_utils.h b/src/qmfunctions/density_utils.h index 2c2f02bac..30e836cb2 100644 --- a/src/qmfunctions/density_utils.h +++ b/src/qmfunctions/density_utils.h @@ -35,6 +35,7 @@ void allreduce_density(double prec, Density &rho_tot, Density &rho_loc); void compute(double prec, Density &rho, mrcpp::GaussExp<3> &dens_exp); void compute(double prec, Density &rho, OrbitalVector &Phi, DensityType spin); void compute(double prec, Density &rho, OrbitalVector &Phi, OrbitalVector &X, OrbitalVector &Y, DensityType spin); + //double compute_occupation(const Orbital &phi, DensityType dens_spin); void compute_local(double prec, Density &rho, OrbitalVector &Phi, DensityType spin); void compute_local(double prec, Density &rho, OrbitalVector &Phi, OrbitalVector &X, OrbitalVector &Y, DensityType spin); diff --git a/src/qmfunctions/orbital_utils.cpp b/src/qmfunctions/orbital_utils.cpp index ccbf93286..9b425e314 100644 --- a/src/qmfunctions/orbital_utils.cpp +++ b/src/qmfunctions/orbital_utils.cpp @@ -35,7 +35,6 @@ #include "utils/print_utils.h" #include "Orbital.h" -#include "OrbitalIterator.h" #include "orbital_utils.h" using mrcpp::FunctionNode; @@ -79,7 +78,21 @@ OrbitalData getOrbitalData(const Orbital &orb) { ComplexDouble orbital::dot(Orbital bra, Orbital ket) { if ((bra.spin() == SPIN::Alpha) and (ket.spin() == SPIN::Beta)) return 0.0; if ((bra.spin() == SPIN::Beta) and (ket.spin() == SPIN::Alpha)) return 0.0; - return mrcpp::cplxfunc::dot(bra, ket); + return mrcpp::dot(bra, ket); +} + + +/** @brief Compute = int bra^\dag(r) * ket(r) dr. + * + * Notice that the bra, mrcpp::CompFunction<3>ket) { + if ((bra.data.n1[0] == SPIN::Alpha) and (ket.data.n1[0] == SPIN::Beta)) return 0.0; + if ((bra.data.n1[0] == SPIN::Beta) and (ket.data.n1[0] == SPIN::Alpha)) return 0.0; + return mrcpp::dot(bra, ket); } /** @brief Compute the diagonal dot products @@ -96,15 +109,15 @@ ComplexVector orbital::dot(OrbitalVector &Bra, OrbitalVector &Ket) { ComplexVector result = ComplexVector::Zero(N); for (int i = 0; i < N; i++) { // The bra is sent to the owner of the ket - if (mrcpp::mpi::my_orb(Bra[i]) != mrcpp::mpi::my_orb(Ket[i])) { + if (mrcpp::mpi::my_func(Bra[i]) != mrcpp::mpi::my_func(Ket[i])) { int tag = 8765 + i; int src = (Bra[i].getRank()) % mrcpp::mpi::wrk_size; int dst = (Ket[i].getRank()) % mrcpp::mpi::wrk_size; - if (mrcpp::mpi::my_orb(Bra[i])) mrcpp::mpi::send_function(Bra[i], dst, tag, mrcpp::mpi::comm_wrk); - if (mrcpp::mpi::my_orb(Ket[i])) mrcpp::mpi::recv_function(Bra[i], src, tag, mrcpp::mpi::comm_wrk); + if (mrcpp::mpi::my_func(Bra[i])) mrcpp::mpi::send_function(Bra[i], dst, tag, mrcpp::mpi::comm_wrk); + if (mrcpp::mpi::my_func(Ket[i])) mrcpp::mpi::recv_function(Bra[i], src, tag, mrcpp::mpi::comm_wrk); } result[i] = orbital::dot(Bra[i], Ket[i]); - if (not mrcpp::mpi::my_orb(Bra[i])) Bra[i].free(NUMBER::Total); + if (not mrcpp::mpi::my_func(Bra[i])) Bra[i].free(); } mrcpp::mpi::allreduce_vector(result, mrcpp::mpi::comm_wrk); return result; @@ -113,12 +126,22 @@ ComplexVector orbital::dot(OrbitalVector &Bra, OrbitalVector &Ket) { /** @brief Compute = int |bra^\dag(r)| * |ket(r)| dr. * */ -ComplexDouble orbital::node_norm_dot(Orbital bra, Orbital ket, bool exact) { +double orbital::node_norm_dot(Orbital bra, Orbital ket) { if ((bra.spin() == SPIN::Alpha) and (ket.spin() == SPIN::Beta)) return 0.0; if ((bra.spin() == SPIN::Beta) and (ket.spin() == SPIN::Alpha)) return 0.0; - return mrcpp::cplxfunc::node_norm_dot(bra, ket, exact); + return mrcpp::node_norm_dot(bra, ket); } + +/** @brief Compute = int |bra^\dag(r)| * |ket(r)| dr. + * + +double orbital::node_norm_dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3> ket, bool exact) { + if ((bra.spin() == SPIN::Alpha) and (ket.spin() == SPIN::Beta)) return 0.0; + if ((bra.spin() == SPIN::Beta) and (ket.spin() == SPIN::Alpha)) return 0.0; + return mrcpp::node_norm_dot(bra, ket, exact); +}*/ + /** @brief Compare spin and occupation of two orbitals * * Returns true if orbital parameters are the same. @@ -225,8 +248,8 @@ OrbitalVector orbital::add(ComplexDouble a, OrbitalVector &Phi_a, ComplexDouble OrbitalVector out = orbital::param_copy(Phi_a); for (int i = 0; i < Phi_a.size(); i++) { - if (mrcpp::mpi::my_orb(Phi_a[i]) != mrcpp::mpi::my_orb(Phi_b[i])) MSG_ABORT("MPI rank mismatch"); - mrcpp::cplxfunc::add(out[i], a, Phi_a[i], b, Phi_b[i], prec); + if (mrcpp::mpi::my_func(Phi_a[i]) != mrcpp::mpi::my_func(Phi_b[i])) MSG_ABORT("MPI rank mismatch"); + mrcpp::add(out[i], a, Phi_a[i], b, Phi_b[i], prec); } return out; } @@ -245,7 +268,7 @@ OrbitalVector orbital::rotate(OrbitalVector &Phi, const ComplexMatrix &U, double // MPI version does not use OMP yet, Serial version uses OMP OrbitalVector Psi = orbital::deep_copy(Phi); - mrcpp::mpifuncvec::rotate(Psi, U, prec); + mrcpp::rotate(Psi, U, prec); return Psi; } @@ -263,7 +286,7 @@ void orbital::save_nodes(OrbitalVector Phi, mrcpp::FunctionTree<3> &refTree, mrc int N = Phi.size(); int max_ix; for (int j = 0; j < N; j++) { - if (not mrcpp::mpi::my_orb(Phi[j])) continue; + if (not mrcpp::mpi::my_func(Phi[j])) continue; // make vector with all coef address and their index in the union grid if (Phi[j].hasReal()) { Phi[j].real().makeCoeffVector(coeffVec, indexVec, parindexVec, scalefac, max_ix, refTree); @@ -301,8 +324,8 @@ void orbital::save_nodes(OrbitalVector Phi, mrcpp::FunctionTree<3> &refTree, mrc OrbitalVector orbital::deep_copy(OrbitalVector &Phi) { OrbitalVector out; for (auto &i : Phi) { - Orbital out_i(i.spin(), i.occ(), i.getRank()); - if (mrcpp::mpi::my_orb(out_i)) mrcpp::cplxfunc::deep_copy(out_i, i); + Orbital out_i; + if (mrcpp::mpi::my_func(out_i)) mrcpp::deep_copy(out_i, i); out.push_back(out_i); } return out; @@ -316,7 +339,8 @@ OrbitalVector orbital::deep_copy(OrbitalVector &Phi) { OrbitalVector orbital::param_copy(const OrbitalVector &Phi) { OrbitalVector out; for (const auto &i : Phi) { - Orbital out_i(i.spin(), i.occ(), i.getRank()); + Orbital out_i; + out_i.data = i.data; out.push_back(out_i); } return out; @@ -334,8 +358,8 @@ OrbitalVector orbital::adjoin(OrbitalVector &Phi_a, OrbitalVector &Phi_b) { for (auto &phi : Phi_a) { if (phi.getRank() % mrcpp::mpi::wrk_size != out.size() % mrcpp::mpi::wrk_size) { // need to send orbital from owner to new owner - if (mrcpp::mpi::my_orb(phi)) { mrcpp::mpi::send_function(phi, out.size() % mrcpp::mpi::wrk_size, phi.getRank(), mrcpp::mpi::comm_wrk); } - if (mrcpp::mpi::my_orb(out.size())) { mrcpp::mpi::recv_function(phi, phi.getRank() % mrcpp::mpi::wrk_size, phi.getRank(), mrcpp::mpi::comm_wrk); } + if (mrcpp::mpi::my_func(phi)) { mrcpp::mpi::send_function(phi, out.size() % mrcpp::mpi::wrk_size, phi.getRank(), mrcpp::mpi::comm_wrk); } + if (mrcpp::mpi::my_func(out.size())) { mrcpp::mpi::recv_function(phi, phi.getRank() % mrcpp::mpi::wrk_size, phi.getRank(), mrcpp::mpi::comm_wrk); } } phi.setRank(out.size()); out.push_back(phi); @@ -343,8 +367,8 @@ OrbitalVector orbital::adjoin(OrbitalVector &Phi_a, OrbitalVector &Phi_b) { for (auto &phi : Phi_b) { if (phi.getRank() % mrcpp::mpi::wrk_size != out.size() % mrcpp::mpi::wrk_size) { // need to send orbital from owner to new owner - if (mrcpp::mpi::my_orb(phi)) { mrcpp::mpi::send_function(phi, out.size() % mrcpp::mpi::wrk_size, phi.getRank(), mrcpp::mpi::comm_wrk); } - if (mrcpp::mpi::my_orb(out.size())) { mrcpp::mpi::recv_function(phi, phi.getRank() % mrcpp::mpi::wrk_size, phi.getRank(), mrcpp::mpi::comm_wrk); } + if (mrcpp::mpi::my_func(phi)) { mrcpp::mpi::send_function(phi, out.size() % mrcpp::mpi::wrk_size, phi.getRank(), mrcpp::mpi::comm_wrk); } + if (mrcpp::mpi::my_func(out.size())) { mrcpp::mpi::recv_function(phi, phi.getRank() % mrcpp::mpi::wrk_size, phi.getRank(), mrcpp::mpi::comm_wrk); } } phi.setRank(out.size()); out.push_back(phi); @@ -364,20 +388,21 @@ OrbitalVector orbital::adjoin(OrbitalVector &Phi_a, OrbitalVector &Phi_b) { OrbitalVector orbital::disjoin(OrbitalVector &Phi, int spin) { OrbitalVector out; OrbitalVector tmp; - for (auto &i : Phi) { + for (auto &Phi_i : Phi) { + Orbital i(Phi_i); if (i.spin() == spin) { if (i.getRank() % mrcpp::mpi::wrk_size != out.size() % mrcpp::mpi::wrk_size) { // need to send orbital from owner to new owner - if (mrcpp::mpi::my_orb(i)) { mrcpp::mpi::send_function(i, out.size() % mrcpp::mpi::wrk_size, i.getRank(), mrcpp::mpi::comm_wrk); } - if (mrcpp::mpi::my_orb(out.size())) { mrcpp::mpi::recv_function(i, i.getRank() % mrcpp::mpi::wrk_size, i.getRank(), mrcpp::mpi::comm_wrk); } + if (mrcpp::mpi::my_func(i)) { mrcpp::mpi::send_function(i, out.size() % mrcpp::mpi::wrk_size, i.getRank(), mrcpp::mpi::comm_wrk); } + if (mrcpp::mpi::my_func(out.size())) { mrcpp::mpi::recv_function(i, i.getRank() % mrcpp::mpi::wrk_size, i.getRank(), mrcpp::mpi::comm_wrk); } } i.setRank(out.size()); out.push_back(i); } else { if (i.getRank() % mrcpp::mpi::wrk_size != tmp.size() % mrcpp::mpi::wrk_size) { // need to send orbital from owner to new owner - if (mrcpp::mpi::my_orb(i)) { mrcpp::mpi::send_function(i, tmp.size() % mrcpp::mpi::wrk_size, i.getRank(), mrcpp::mpi::comm_wrk); } - if (mrcpp::mpi::my_orb(tmp.size())) { mrcpp::mpi::recv_function(i, i.getRank() % mrcpp::mpi::wrk_size, i.getRank(), mrcpp::mpi::comm_wrk); } + if (mrcpp::mpi::my_func(i)) { mrcpp::mpi::send_function(i, tmp.size() % mrcpp::mpi::wrk_size, i.getRank(), mrcpp::mpi::comm_wrk); } + if (mrcpp::mpi::my_func(tmp.size())) { mrcpp::mpi::recv_function(i, i.getRank() % mrcpp::mpi::wrk_size, i.getRank(), mrcpp::mpi::comm_wrk); } } i.setRank(tmp.size()); tmp.push_back(i); @@ -417,7 +442,7 @@ void orbital::save_orbitals(OrbitalVector &Phi, const std::string &file, int spi Timer t1; std::stringstream orbname; orbname << file << "_idx_" << n; - if (mrcpp::mpi::my_orb(Phi[i])) saveOrbital(orbname.str(), Phi[i]); + if (mrcpp::mpi::my_func(Phi[i])) saveOrbital(orbname.str(), Phi[i]); print_utils::qmfunction(2, "'" + orbname.str() + "'", Phi[i], t1); n++; } @@ -452,7 +477,7 @@ OrbitalVector orbital::load_orbitals(const std::string &file, int n_orbs) { if (phi_i.hasReal() or phi_i.hasImag()) { Phi.push_back(phi_i); print_utils::qmfunction(2, "'" + orbname.str() + "'", phi_i, t1); - if (not mrcpp::mpi::my_orb(phi_i)) phi_i.free(NUMBER::Total); + if (not mrcpp::mpi::my_func(phi_i)) phi_i.free(NUMBER::Total); } else { break; } @@ -470,11 +495,11 @@ void orbital::normalize(Orbital phi) { void orbital::normalize(OrbitalVector &Phi) { mrcpp::mpi::free_foreign(Phi); for (auto &phi_i : Phi) - if (mrcpp::mpi::my_orb(phi_i)) orbital::normalize(phi_i); + if (mrcpp::mpi::my_func(phi_i)) orbital::normalize(phi_i); } /** @brief In place orthogonalize against inp. Private function. */ -void orbital::orthogonalize(double prec, Orbital &phi, Orbital psi) { +void orbital::orthogonalize(double prec, Orbital &&phi, Orbital psi) { ComplexDouble overlap = orbital::dot(psi, phi); double sq_norm = psi.squaredNorm(); if (std::abs(overlap) > prec) phi.add(-1.0 * overlap / sq_norm, psi); @@ -488,15 +513,15 @@ void orbital::orthogonalize(double prec, OrbitalVector &Phi) { int tag = 7632 * i + j; int src = (Phi[j].getRank()) % mrcpp::mpi::wrk_size; int dst = (Phi[i].getRank()) % mrcpp::mpi::wrk_size; - if (mrcpp::mpi::my_orb(Phi[i]) and mrcpp::mpi::my_orb(Phi[j])) { + if (mrcpp::mpi::my_func(Phi[i]) and mrcpp::mpi::my_func(Phi[j])) { orbital::orthogonalize(prec / Phi.size(), Phi[i], Phi[j]); } else { - if (mrcpp::mpi::my_orb(Phi[i])) { + if (mrcpp::mpi::my_func(Phi[i])) { mrcpp::mpi::recv_function(Phi[j], src, tag, mrcpp::mpi::comm_wrk); orbital::orthogonalize(prec / Phi.size(), Phi[i], Phi[j]); Phi[j].free(NUMBER::Total); } - if (mrcpp::mpi::my_orb(Phi[j])) mrcpp::mpi::send_function(Phi[j], dst, tag, mrcpp::mpi::comm_wrk); + if (mrcpp::mpi::my_func(Phi[j])) mrcpp::mpi::send_function(Phi[j], dst, tag, mrcpp::mpi::comm_wrk); } } } @@ -505,7 +530,7 @@ void orbital::orthogonalize(double prec, OrbitalVector &Phi) { OrbitalChunk orbital::get_my_chunk(OrbitalVector &Phi) { OrbitalChunk chunk; for (int i = 0; i < Phi.size(); i++) { - if (mrcpp::mpi::my_orb(i)) chunk.push_back(std::make_tuple(i, Phi[i])); + if (mrcpp::mpi::my_func(i)) chunk.push_back(std::make_tuple(i, Orbital(Phi[i]))); } return chunk; } @@ -514,7 +539,7 @@ OrbitalChunk orbital::get_my_chunk(OrbitalVector &Phi) { * orthogonal spins means orthogonal orbitals. */ void orbital::orthogonalize(double prec, OrbitalVector &Phi, OrbitalVector &Psi) { - mrcpp::mpifuncvec::orthogonalize(prec, Phi, Psi); + mrcpp::orthogonalize(prec, Phi, Psi); } /** @brief Orbital transformation out_j = sum_i inp_i*U_ij @@ -526,14 +551,14 @@ void orbital::orthogonalize(double prec, OrbitalVector &Phi, OrbitalVector &Psi) * */ ComplexMatrix orbital::calc_overlap_matrix(OrbitalVector &BraKet) { - return mrcpp::mpifuncvec::calc_overlap_matrix(BraKet); + return mrcpp::calc_overlap_matrix(BraKet); } /** @brief Compute the overlap matrix S_ij = * */ ComplexMatrix orbital::calc_overlap_matrix(OrbitalVector &Bra, OrbitalVector &Ket) { - return mrcpp::mpifuncvec::calc_overlap_matrix(Bra, Ket); + return mrcpp::calc_overlap_matrix(Bra, Ket); } /** @brief Compute the overlap matrix of the absolute value of the functions S_ij = <|bra_i|||ket_j|> @@ -666,7 +691,7 @@ DoubleMatrix orbital::calc_norm_overlap_matrix(OrbitalVector &BraKet) { IntVector conjMat = IntVector::Zero(N); for (int i = 0; i < N; i++) { - if (!mrcpp::mpi::my_orb(BraKet[i])) continue; + if (!mrcpp::mpi::my_func(BraKet[i])) continue; conjMat[i] = (BraKet[i].conjugate()) ? -1 : 1; } mrcpp::mpi::allreduce_vector(conjMat, mrcpp::mpi::comm_wrk); @@ -737,7 +762,7 @@ ComplexMatrix orbital::localize(double prec, OrbitalVector &Phi, int spin) { OrbitalVector Phi_s = orbital::disjoin(Phi, spin); ComplexMatrix U = calc_localization_matrix(prec, Phi_s); Timer rot_t; - mrcpp::mpifuncvec::rotate(Phi_s, U, prec); + mrcpp::rotate(Phi_s, U, prec); Phi = orbital::adjoin(Phi, Phi_s); mrcpp::print::time(2, "Rotating orbitals", rot_t); return U; @@ -808,7 +833,7 @@ ComplexMatrix orbital::diagonalize(double prec, OrbitalVector &Phi, ComplexMatri mrcpp::print::time(2, "Diagonalizing matrix", diag_t); Timer rot_t; - mrcpp::mpifuncvec::rotate(Phi, U, prec); + mrcpp::rotate(Phi, U, prec); mrcpp::print::time(2, "Rotating orbitals", rot_t); mrcpp::print::footer(2, t_tot, 2); @@ -831,7 +856,7 @@ ComplexMatrix orbital::orthonormalize(double prec, OrbitalVector &Phi, ComplexMa ComplexMatrix U = orbital::calc_lowdin_matrix(Phi); t_lap.start(); - mrcpp::mpifuncvec::rotate(Phi, U, prec); + mrcpp::rotate(Phi, U, prec); mrcpp::print::time(2, "Rotating orbitals", t_lap); // Transform Fock matrix @@ -931,9 +956,9 @@ int orbital::get_electron_number(const OrbitalVector &Phi, int spin) { int orbital::get_n_nodes(const OrbitalVector &Phi, bool avg) { long long totNodes = 0; int mysize = 0; - for (const auto &phi_i : Phi) totNodes += phi_i.getNNodes(NUMBER::Total); + for (const auto &phi_i : Phi) totNodes += phi_i.getNNodes(); for (const auto &phi_i : Phi) - if (mrcpp::mpi::my_orb(phi_i)) mysize++; + if (mrcpp::mpi::my_func(phi_i)) mysize++; if (avg and mysize > 0) totNodes /= mysize; if (totNodes > INT_MAX) MSG_WARN("Integer overflow: " << totNodes); return static_cast(totNodes); @@ -943,9 +968,9 @@ int orbital::get_n_nodes(const OrbitalVector &Phi, bool avg) { int orbital::get_size_nodes(const OrbitalVector &Phi, bool avg) { long long totSize = 0; int mysize = 0; - for (const auto &phi_i : Phi) totSize += phi_i.getSizeNodes(NUMBER::Total); + for (const auto &phi_i : Phi) totSize += phi_i.getSizeNodes(); for (const auto &phi_i : Phi) - if (mrcpp::mpi::my_orb(phi_i)) mysize++; + if (mrcpp::mpi::my_func(phi_i)) mysize++; if (avg and mysize > 0) totSize /= mysize; if (totSize > INT_MAX) MSG_WARN("Integer overflow: " << totSize); return static_cast(totSize); @@ -966,15 +991,15 @@ IntVector orbital::get_spins(const OrbitalVector &Phi) { */ void orbital::set_spins(OrbitalVector &Phi, const IntVector &spins) { if (Phi.size() != spins.size()) MSG_ERROR("Size mismatch"); - for (int i = 0; i < Phi.size(); i++) Phi[i].setSpin(spins(i)); + for (int i = 0; i < Phi.size(); i++) Phi[i].spin() = i; } /** @brief Returns a vector containing the orbital occupations */ IntVector orbital::get_occupations(const OrbitalVector &Phi) { int nOrbs = Phi.size(); - IntVector occ = IntVector::Zero(nOrbs); - for (int i = 0; i < nOrbs; i++) occ(i) = Phi[i].occ(); - return occ; + IntVector occup = IntVector::Zero(nOrbs); + for (int i = 0; i < nOrbs; i++) occup(i) = Phi[i].occ(); + return occup; } /** @brief Assigns occupation to each orbital @@ -982,9 +1007,9 @@ IntVector orbital::get_occupations(const OrbitalVector &Phi) { * Length of input vector must match the number of orbitals in the set. * */ -void orbital::set_occupations(OrbitalVector &Phi, const IntVector &occ) { - if (Phi.size() != occ.size()) MSG_ERROR("Size mismatch"); - for (int i = 0; i < Phi.size(); i++) Phi[i].setOcc(occ(i)); +void orbital::set_occupations(OrbitalVector &Phi, const IntVector &occup) { + if (Phi.size() != occup.size()) MSG_ERROR("Size mismatch"); + for (int i = 0; i < Phi.size(); i++) Phi[i].occ() = occup(i); } /** @brief Returns a vector containing the orbital square norms */ @@ -992,7 +1017,7 @@ DoubleVector orbital::get_squared_norms(const OrbitalVector &Phi) { int nOrbs = Phi.size(); DoubleVector norms = DoubleVector::Zero(nOrbs); for (int i = 0; i < nOrbs; i++) { - if (mrcpp::mpi::my_orb(Phi[i])) norms(i) = Phi[i].squaredNorm(); + if (mrcpp::mpi::my_func(Phi[i])) norms(i) = Phi[i].squaredNorm(); } mrcpp::mpi::allreduce_vector(norms, mrcpp::mpi::comm_wrk); return norms; @@ -1003,7 +1028,7 @@ DoubleVector orbital::get_norms(const OrbitalVector &Phi) { int nOrbs = Phi.size(); DoubleVector norms = DoubleVector::Zero(nOrbs); for (int i = 0; i < nOrbs; i++) { - if (mrcpp::mpi::my_orb(Phi[i])) norms(i) = Phi[i].norm(); + if (mrcpp::mpi::my_func(Phi[i])) norms(i) = Phi[i].norm(); } mrcpp::mpi::allreduce_vector(norms, mrcpp::mpi::comm_wrk); return norms; @@ -1014,7 +1039,7 @@ ComplexVector orbital::get_integrals(const OrbitalVector &Phi) { int nOrbs = Phi.size(); ComplexVector ints = DoubleVector::Zero(nOrbs); for (int i = 0; i < nOrbs; i++) { - if (mrcpp::mpi::my_orb(Phi[i])) ints(i) = Phi[i].integrate(); + if (mrcpp::mpi::my_func(Phi[i])) ints(i) = Phi[i].integrate(); } mrcpp::mpi::allreduce_vector(ints, mrcpp::mpi::comm_wrk); return ints; @@ -1081,8 +1106,8 @@ void orbital::print(const OrbitalVector &Phi) { auto nodes = 0; auto memory = 0.0; for (int i = 0; i < Phi.size(); i++) { - nodes += Phi[i].getNNodes(NUMBER::Total); - memory += Phi[i].getSizeNodes(NUMBER::Total) / 1024.0; + nodes += Phi[i].getNNodes(); + memory += Phi[i].getSizeNodes() / 1024.0; std::stringstream o_txt; o_txt << std::setw(w1 - 1) << i; o_txt << std::setw(w1) << Phi[i].occ(); @@ -1147,7 +1172,7 @@ int orbital::print_size_nodes(const OrbitalVector &Phi, const std::string &txt, println(0, "OrbitalVector sizes statistics " << txt << " (MB)"); IntVector sNodes = IntVector::Zero(Phi.size()); - for (int i = 0; i < Phi.size(); i++) sNodes[i] = Phi[i].getSizeNodes(NUMBER::Total); + for (int i = 0; i < Phi.size(); i++) sNodes[i] = Phi[i].getSizeNodes(); // stats for own orbitals for (int i = 0; i < Phi.size(); i++) { @@ -1207,6 +1232,10 @@ int orbital::print_size_nodes(const OrbitalVector &Phi, const std::string &txt, return vSum; } +void orbital::saveOrbital(const std::string &file, mrcpp::CompFunction<3>& orb) { + orbital::saveOrbital(file, Orbital(orb)); +} + /** @brief Write orbital to disk * * @param file: file name prefix @@ -1215,32 +1244,30 @@ int orbital::print_size_nodes(const OrbitalVector &Phi, const std::string &txt, * binary files for meta data ("phi_0.meta"), real ("phi_0_re.tree") * and imaginary ("phi_0_im.tree") parts. */ -void orbital::saveOrbital(const std::string &file, Orbital &orb) { +void orbital::saveOrbital(const std::string &file, const Orbital &orb) { // writing meta data std::stringstream metafile; metafile << file << ".meta"; - // this flushes tree sizes - mrcpp::FunctionData &func_data = orb.getFunctionData(); - std::fstream f; f.open(metafile.str(), std::ios::out | std::ios::binary); if (not f.is_open()) MSG_ERROR("Unable to open file"); - f.write((char *)&func_data, sizeof(mrcpp::FunctionData)); + mrcpp::CompFunctionData<3> orbdata = orb.getFuncData(); + f.write((char *)& orb.data, sizeof(mrcpp::CompFunctionData<3>)); f.close(); // writing real part - if (orb.hasReal()) { + if (orb.isreal) { std::stringstream fname; - fname << file << "_re"; - orb.real().saveTree(fname.str()); + fname << file << "_real"; + orb.CompD[0]->saveTree(fname.str()); } - // writing imaginary part - if (orb.hasImag()) { + // writing complex tree + if (orb.iscomplex) { std::stringstream fname; - fname << file << "_im"; - orb.imag().saveTree(fname.str()); + fname << file << "_complex"; + orb.CompC[0]->saveTree(fname.str()); } } @@ -1260,43 +1287,40 @@ void orbital::loadOrbital(const std::string &file, Orbital &orb) { std::stringstream fmeta; fmeta << file << ".meta"; - // this flushes tree sizes - mrcpp::FunctionData &func_data = orb.getFunctionData(); - std::fstream f; f.open(fmeta.str(), std::ios::in | std::ios::binary); - if (f.is_open()) f.read((char *)&func_data, sizeof(mrcpp::FunctionData)); + if (f.is_open()) f.read((char *)&orb.data, sizeof(mrcpp::CompFunctionData<3>)); f.close(); - std::array corner{func_data.corner[0], func_data.corner[1], func_data.corner[2]}; - std::array boxes{func_data.boxes[0], func_data.boxes[1], func_data.boxes[2]}; - mrcpp::BoundingBox<3> world(func_data.scale, corner, boxes); + std::array corner{orb.data.corner[0], orb.data.corner[1], orb.data.corner[2]}; + std::array boxes{orb.data.boxes[0], orb.data.boxes[1], orb.data.boxes[2]}; + mrcpp::BoundingBox<3> world(orb.data.scale, corner, boxes); mrcpp::MultiResolutionAnalysis<3> *mra = nullptr; - if (func_data.type == mrcpp::Interpol) { - mrcpp::InterpolatingBasis basis(func_data.order); - mra = new mrcpp::MultiResolutionAnalysis<3>(world, basis, func_data.depth); - } else if (func_data.type == mrcpp::Legendre) { - mrcpp::LegendreBasis basis(func_data.order); - mra = new mrcpp::MultiResolutionAnalysis<3>(world, basis, func_data.depth); + if (orb.data.type == mrcpp::Interpol) { + mrcpp::InterpolatingBasis basis(orb.data.order); + mra = new mrcpp::MultiResolutionAnalysis<3>(world, basis, orb.data.depth); + } else if (orb.data.type == mrcpp::Legendre) { + mrcpp::LegendreBasis basis(orb.data.order); + mra = new mrcpp::MultiResolutionAnalysis<3>(world, basis, orb.data.depth); } else { MSG_ABORT("Invalid basis type!"); } // reading real part - if (func_data.real_size > 0) { + if (orb.data.isreal) { std::stringstream fname; - fname << file << "_re"; - orb.alloc(NUMBER::Real, mra); - orb.real().loadTree(fname.str()); + fname << file << "_real"; + orb.alloc(0); + orb.CompD[0]->loadTree(fname.str()); } // reading imaginary part - if (func_data.imag_size > 0) { + if (orb.data.iscomplex) { std::stringstream fname; - fname << file << "_im"; - orb.alloc(NUMBER::Imag, mra); - orb.imag().loadTree(fname.str()); + fname << file << "_complex"; + orb.alloc(0); + orb.CompC[0]->loadTree(fname.str()); } delete mra; } diff --git a/src/qmfunctions/orbital_utils.h b/src/qmfunctions/orbital_utils.h index 9e1547a7e..015ee6ada 100644 --- a/src/qmfunctions/orbital_utils.h +++ b/src/qmfunctions/orbital_utils.h @@ -37,12 +37,14 @@ int compare_spin(const Orbital &phi_a, const Orbital &phi_b); int compare_occupation(const Orbital &phi_a, const Orbital &phi_b); ComplexDouble dot(Orbital bra, Orbital ket); +ComplexDouble dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3>ket); ComplexVector dot(OrbitalVector &Bra, OrbitalVector &Ket); -ComplexDouble node_norm_dot(Orbital bra, Orbital ket, bool exact); +double node_norm_dot(Orbital bra, Orbital ket); +double node_norm_dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3> ket, bool exact); void normalize(Orbital phi); OrbitalChunk get_my_chunk(OrbitalVector &Phi); -void orthogonalize(double prec, Orbital &phi, Orbital psi); +void orthogonalize(double prec, Orbital &&phi, Orbital psi); OrbitalVector add(ComplexDouble a, OrbitalVector &Phi_a, ComplexDouble b, OrbitalVector &Phi_b, double prec = -1.0); OrbitalVector rotate(OrbitalVector &Phi, const ComplexMatrix &U, double prec = -1.0); @@ -97,9 +99,9 @@ ComplexVector get_integrals(const OrbitalVector &Phi); void print(const OrbitalVector &Phi); int print_size_nodes(const OrbitalVector &Phi, const std::string &txt = "", bool all = true, int plevel = 0); -void saveOrbital(const std::string &file, Orbital& orb); +void saveOrbital(const std::string &file, const Orbital& orb); +void saveOrbital(const std::string &file, mrcpp::CompFunction<3>& orb); void loadOrbital(const std::string &file, Orbital& orb); - //char printSpin(const Orbital& orb); } // namespace orbital } // namespace mrchem diff --git a/src/qmfunctions/qmfunction_fwd.h b/src/qmfunctions/qmfunction_fwd.h index a1d0d1aca..39c31f1bd 100644 --- a/src/qmfunctions/qmfunction_fwd.h +++ b/src/qmfunctions/qmfunction_fwd.h @@ -30,11 +30,11 @@ /** Notes on vectors: * The OrbitalVector (std::vector) is conceptually different from the - * mrcpp::ComplexFunctionVector (std::vector). The former should be a collection + * mrcpp::CompFunction<3>Vector (std::vector>). The former should be a collection * of orbitals defining a proper Slater determinant, while the latter is any * arbitrary collection of functions (could also be orbitals) used e.g. when * adding several orbitals into one. The difference is important when MPI is - * considered, as OrbitalVectors are distributed while mrcpp::ComplexFunctionVectors are + * considered, as OrbitalVectors are distributed while mrcpp::CompFunction<3>Vectors are * not. This is reflected in the functionality that is available for the * different vectors, where OrbitalVectors should always be treated as a whole, * e.g. in an orbital rotation Psi = orbital::rotate(U, Phi), where U is a @@ -46,14 +46,14 @@ namespace mrchem { -class ComplexFunction; +class CompFunction; // class Orbital; -using Orbital = mrcpp::ComplexFunction; +class Orbital; using OrbitalChunk = std::vector>; -using OrbitalVector = mrcpp::MPI_FuncVector; -// class OrbitalVector; +// using OrbitalVector = mrcpp::CompFunctionVector<3>; +class OrbitalVector; class Density; diff --git a/src/qmfunctions/qmfunction_utils.cpp b/src/qmfunctions/qmfunction_utils.cpp index 6112106ad..8cdc8d35f 100644 --- a/src/qmfunctions/qmfunction_utils.cpp +++ b/src/qmfunctions/qmfunction_utils.cpp @@ -29,7 +29,7 @@ #include "parallel.h" -#include "mrcpp::ComplexFunction.h" +#include "mrcpp::CompFunction.h" #include "qmfunction_utils.h" using mrcpp::FunctionTree; @@ -45,7 +45,7 @@ extern mrcpp::MultiResolutionAnalysis<3> *MRA; // Global MRA * Notice that the bra, mrcpp::CompFunction<3> ket) { double rr(0.0), ri(0.0), ir(0.0), ii(0.0); if (bra.hasReal() and ket.hasReal()) rr = mrcpp::dot(bra.real(), ket.real()); if (bra.hasReal() and ket.hasImag()) ri = mrcpp::dot(bra.real(), ket.imag()); @@ -63,7 +63,7 @@ ComplexDouble mrcpp::cplxfunc::dot(mrcpp::ComplexFunction bra, mrcpp::ComplexFun /** @brief Compute = int |bra^\dag(r)| * |ket(r)| dr. * */ -ComplexDouble mrcpp::cplxfunc::node_norm_dot(mrcpp::ComplexFunction bra, mrcpp::ComplexFunction ket, bool exact) { +ComplexDouble mrcpp::node_norm_dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3> ket, bool exact) { double rr(0.0), ri(0.0), ir(0.0), ii(0.0); if (bra.hasReal() and ket.hasReal()) rr = mrcpp::node_norm_dot(bra.real(), ket.real(), exact); if (bra.hasReal() and ket.hasImag()) ri = mrcpp::node_norm_dot(bra.real(), ket.imag(), exact); @@ -84,7 +84,7 @@ ComplexDouble mrcpp::cplxfunc::node_norm_dot(mrcpp::ComplexFunction bra, mrcpp:: * This is achieved by building a new grid for the real and imaginary parts and * copying. */ -void mrcpp::cplxfunc::deep_copy(mrcpp::ComplexFunction &out, mrcpp::ComplexFunction &inp) { +void mrcpp::deep_copy(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> &inp) { bool need_to_copy = not(out.isShared()) or mrcpp::mpi::share_master(); if (inp.hasReal()) { if (not out.hasReal()) out.alloc(NUMBER::Real); @@ -104,7 +104,7 @@ void mrcpp::cplxfunc::deep_copy(mrcpp::ComplexFunction &out, mrcpp::ComplexFunct mrcpp::mpi::share_function(out, 0, 1324, mrcpp::mpi::comm_share); } -void mrcpp::cplxfunc::project(mrcpp::ComplexFunction &out, std::function &r)> f, int type, double prec) { +void mrcpp::project(mrcpp::CompFunction<3> &out, std::function &r)> f, int type, double prec) { bool need_to_project = not(out.isShared()) or mrcpp::mpi::share_master(); if (type == NUMBER::Real or type == NUMBER::Total) { if (not out.hasReal()) out.alloc(NUMBER::Real); @@ -117,7 +117,7 @@ void mrcpp::cplxfunc::project(mrcpp::ComplexFunction &out, std::function &f, int type, double prec) { +void mrcpp::project(mrcpp::CompFunction<3> &out, mrcpp::GaussExp<3> &f, int type, double prec) { bool need_to_project = not(out.isShared()) or mrcpp::mpi::share_master(); if (type == NUMBER::Real or type == NUMBER::Total) { if (not out.hasReal()) out.alloc(NUMBER::Real); @@ -136,7 +136,7 @@ void mrcpp::cplxfunc::project(mrcpp::ComplexFunction &out, mrcpp::GaussExp<3> &f mrcpp::mpi::share_function(out, 0, 132231, mrcpp::mpi::comm_share); } -void mrcpp::cplxfunc::project(mrcpp::ComplexFunction &out, mrcpp::RepresentableFunction<3> &f, int type, double prec) { +void mrcpp::project(mrcpp::CompFunction<3> &out, mrcpp::RepresentableFunction<3> &f, int type, double prec) { bool need_to_project = not(out.isShared()) or mrcpp::mpi::share_master(); if (type == NUMBER::Real or type == NUMBER::Total) { if (not out.hasReal()) out.alloc(NUMBER::Real); @@ -156,80 +156,30 @@ void mrcpp::cplxfunc::project(mrcpp::ComplexFunction &out, mrcpp::RepresentableF * Recast into linear_combination. * */ -void mrcpp::cplxfunc::add(mrcpp::ComplexFunction &out, ComplexDouble a, mrcpp::ComplexFunction inp_a, ComplexDouble b, mrcpp::ComplexFunction inp_b, double prec) { +void mrcpp::add(mrcpp::CompFunction<3> &out, ComplexDouble a, mrcpp::CompFunction<3> inp_a, ComplexDouble b, mrcpp::CompFunction<3> inp_b, double prec) { ComplexVector coefs(2); coefs(0) = a; coefs(1) = b; - mrcpp::ComplexFunctionVector funcs; + mrcpp::CompFunction<3>Vector funcs; funcs.push_back(inp_a); funcs.push_back(inp_b); - mrcpp::cplxfunc::linear_combination(out, coefs, funcs, prec); + mrcpp::linear_combination(out, coefs, funcs, prec); } /** @brief out = inp_a * inp_b * */ -void mrcpp::cplxfunc::multiply(mrcpp::ComplexFunction &out, mrcpp::ComplexFunction inp_a, mrcpp::ComplexFunction inp_b, double prec, bool absPrec, bool useMaxNorms) { +void mrcpp::multiply(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> inp_a, mrcpp::CompFunction<3> inp_b, double prec, bool absPrec, bool useMaxNorms) { multiply_real(out, inp_a, inp_b, prec, absPrec, useMaxNorms); multiply_imag(out, inp_a, inp_b, prec, absPrec, useMaxNorms); } -/** @brief out = c_0*inp_0 + c_1*inp_1 + ... + c_N*inp_N - * - */ -void mrcpp::cplxfunc::linear_combination(mrcpp::ComplexFunction &out, const ComplexVector &c, mrcpp::ComplexFunctionVector &inp, double prec) { - FunctionTreeVector<3> rvec; - FunctionTreeVector<3> ivec; - - double thrs = mrcpp::MachineZero; - for (int i = 0; i < inp.size(); i++) { - double sign = (inp[i].conjugate()) ? -1.0 : 1.0; - - bool cHasReal = (std::abs(c[i].real()) > thrs); - bool cHasImag = (std::abs(c[i].imag()) > thrs); - - if (cHasReal and inp[i].hasReal()) rvec.push_back(std::make_tuple(c[i].real(), &inp[i].real())); - if (cHasImag and inp[i].hasImag()) rvec.push_back(std::make_tuple(-sign * c[i].imag(), &inp[i].imag())); - - if (cHasImag and inp[i].hasReal()) ivec.push_back(std::make_tuple(c[i].imag(), &inp[i].real())); - if (cHasReal and inp[i].hasImag()) ivec.push_back(std::make_tuple(sign * c[i].real(), &inp[i].imag())); - } - - if (rvec.size() > 0 and not out.hasReal()) out.alloc(NUMBER::Real); - if (ivec.size() > 0 and not out.hasImag()) out.alloc(NUMBER::Imag); - - bool need_to_add = not(out.isShared()) or mrcpp::mpi::share_master(); - if (need_to_add) { - if (rvec.size() > 0) { - if (prec < 0.0) { - mrcpp::build_grid(out.real(), rvec); - mrcpp::add(prec, out.real(), rvec, 0); - } else { - mrcpp::add(prec, out.real(), rvec); - } - } else if (out.hasReal()) { - out.real().setZero(); - } - if (ivec.size() > 0) { - if (prec < 0.0) { - mrcpp::build_grid(out.imag(), ivec); - mrcpp::add(prec, out.imag(), ivec, 0); - } else { - mrcpp::add(prec, out.imag(), ivec); - } - } else if (out.hasImag()) { - out.imag().setZero(); - } - } - mrcpp::mpi::share_function(out, 0, 9911, mrcpp::mpi::comm_share); -} - /** @brief out = Re(inp_a * inp_b) * */ -void mrcpp::cplxfunc::multiply_real(mrcpp::ComplexFunction &out, mrcpp::ComplexFunction inp_a, mrcpp::ComplexFunction inp_b, double prec, bool absPrec, bool useMaxNorms) { +void mrcpp::multiply_real(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> inp_a, mrcpp::CompFunction<3> inp_b, double prec, bool absPrec, bool useMaxNorms) { double conj_a = (inp_a.conjugate()) ? -1.0 : 1.0; double conj_b = (inp_b.conjugate()) ? -1.0 : 1.0; @@ -298,7 +248,7 @@ void mrcpp::cplxfunc::multiply_real(mrcpp::ComplexFunction &out, mrcpp::ComplexF /** @brief out = Im(inp_a * inp_b) * */ -void mrcpp::cplxfunc::multiply_imag(mrcpp::ComplexFunction &out, mrcpp::ComplexFunction inp_a, mrcpp::ComplexFunction inp_b, double prec, bool absPrec, bool useMaxNorms) { +void mrcpp::multiply_imag(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> inp_a, mrcpp::CompFunction<3> inp_b, double prec, bool absPrec, bool useMaxNorms) { double conj_a = (inp_a.conjugate()) ? -1.0 : 1.0; double conj_b = (inp_b.conjugate()) ? -1.0 : 1.0; diff --git a/src/qmfunctions/qmfunction_utils.h b/src/qmfunctions/qmfunction_utils.h index 98ab8d08d..aa9e4edb2 100644 --- a/src/qmfunctions/qmfunction_utils.h +++ b/src/qmfunctions/qmfunction_utils.h @@ -31,17 +31,16 @@ namespace mrchem { namespace qmfunction { -ComplexDouble dot(mrcpp::ComplexFunction bra, mrcpp::ComplexFunction ket); -ComplexDouble node_norm_dot(mrcpp::ComplexFunction bra, mrcpp::ComplexFunction ket, bool exact); -void deep_copy(mrcpp::ComplexFunction &out, mrcpp::ComplexFunction &inp); -void add(mrcpp::ComplexFunction &out, ComplexDouble a, mrcpp::ComplexFunction inp_a, ComplexDouble b, mrcpp::ComplexFunction inp_b, double prec); -void project(mrcpp::ComplexFunction &out, std::function &r)> f, int type, double prec); -void project(mrcpp::ComplexFunction &out, mrcpp::RepresentableFunction<3> &f, int type, double prec); -void project(mrcpp::ComplexFunction &out, mrcpp::GaussExp<3> &f, int type, double prec); -void multiply(mrcpp::ComplexFunction &out, mrcpp::ComplexFunction inp_a, mrcpp::ComplexFunction inp_b, double prec, bool absPrec = false, bool useMaxNorms = false); -void multiply_real(mrcpp::ComplexFunction &out, mrcpp::ComplexFunction inp_a, mrcpp::ComplexFunction inp_b, double prec, bool absPrec = false, bool useMaxNorms = false); -void multiply_imag(mrcpp::ComplexFunction &out, mrcpp::ComplexFunction inp_a, mrcpp::ComplexFunction inp_b, double prec, bool absPrec = false, bool useMaxNorms = false); -void linear_combination(mrcpp::ComplexFunction &out, const ComplexVector &c, mrcpp::ComplexFunctionVector &inp, double prec); +ComplexDouble dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3> ket); +ComplexDouble node_norm_dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3> ket, bool exact); +void deep_copy(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> &inp); +void add(mrcpp::CompFunction<3> &out, ComplexDouble a, mrcpp::CompFunction<3> inp_a, ComplexDouble b, mrcpp::CompFunction<3> inp_b, double prec); +void project(mrcpp::CompFunction<3> &out, std::function &r)> f, int type, double prec); +void project(mrcpp::CompFunction<3> &out, mrcpp::RepresentableFunction<3> &f, int type, double prec); +void project(mrcpp::CompFunction<3> &out, mrcpp::GaussExp<3> &f, int type, double prec); +void multiply(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> inp_a, mrcpp::CompFunction<3> inp_b, double prec, bool absPrec = false, bool useMaxNorms = false); +void multiply_real(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> inp_a, mrcpp::CompFunction<3> inp_b, double prec, bool absPrec = false, bool useMaxNorms = false); +void multiply_imag(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> inp_a, mrcpp::CompFunction<3> inp_b, double prec, bool absPrec = false, bool useMaxNorms = false); } // namespace qmfunction } // namespace mrchem diff --git a/src/qmoperators/QMDerivative.cpp b/src/qmoperators/QMDerivative.cpp index 8090518f7..88f5aca97 100644 --- a/src/qmoperators/QMDerivative.cpp +++ b/src/qmoperators/QMDerivative.cpp @@ -27,12 +27,12 @@ #include #include +#include "qmfunctions/Orbital.h" #include "QMDerivative.h" #include "QMIdentity.h" #include "QMPotential.h" #include "QMSpin.h" -#include "qmfunctions/Orbital.h" #include "qmfunctions/orbital_utils.h" #include "utils/print_utils.h" @@ -64,28 +64,10 @@ Orbital QMDerivative::apply(Orbital inp) { auto dir = this->apply_dir; auto &D = *this->derivative; - Orbital out = inp.paramCopy(); - if (this->isReal()) { - if (inp.hasReal()) { - out.alloc(NUMBER::Real); - mrcpp::apply(out.real(), D, inp.real(), dir); - } - if (inp.hasImag()) { - out.alloc(NUMBER::Imag); - mrcpp::apply(out.imag(), D, inp.imag(), dir); - if (inp.conjugate()) out.imag().rescale(-1.0); - } - } else { - if (inp.hasImag()) { - out.alloc(NUMBER::Real); - mrcpp::apply(out.real(), D, inp.imag(), dir); - if (!inp.conjugate()) out.real().rescale(-1.0); - } - if (inp.hasReal()) { - out.alloc(NUMBER::Imag); - mrcpp::apply(out.imag(), D, inp.real(), dir); - } - } + Orbital out(inp); + out.alloc(0); + mrcpp::apply(out, D, inp, dir); + return out; } diff --git a/src/qmoperators/QMIdentity.cpp b/src/qmoperators/QMIdentity.cpp index 6af9de69f..52a26597e 100644 --- a/src/qmoperators/QMIdentity.cpp +++ b/src/qmoperators/QMIdentity.cpp @@ -25,9 +25,9 @@ #include +#include "qmfunctions/Orbital.h" #include "QMIdentity.h" -#include "qmfunctions/Orbital.h" #include "qmfunctions/orbital_utils.h" using QMOperator_p = std::shared_ptr; @@ -37,8 +37,8 @@ namespace mrchem { /** Identity operator is a deep copy */ Orbital QMIdentity::apply(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); - Orbital out = inp.paramCopy(); - mrcpp::cplxfunc::deep_copy(out, inp); + Orbital out(inp); + mrcpp::deep_copy(out, inp); return out; } diff --git a/src/qmoperators/QMOperator.h b/src/qmoperators/QMOperator.h index 464da701f..fc653b1e1 100644 --- a/src/qmoperators/QMOperator.h +++ b/src/qmoperators/QMOperator.h @@ -31,6 +31,7 @@ #include "mrchem.h" #include "tensor/tensor_fwd.h" +#include "qmfunctions/Orbital.h" /** @class QMOperator * @@ -53,8 +54,6 @@ */ namespace mrchem { -using Orbital = mrcpp::ComplexFunction; - class QMOperator { public: QMOperator() = default; diff --git a/src/qmoperators/QMPotential.cpp b/src/qmoperators/QMPotential.cpp index ada2860ef..63c671830 100644 --- a/src/qmoperators/QMPotential.cpp +++ b/src/qmoperators/QMPotential.cpp @@ -26,12 +26,12 @@ #include #include +#include "qmfunctions/Orbital.h" #include "QMPotential.h" #include "QMDerivative.h" #include "QMIdentity.h" #include "QMSpin.h" -#include "qmfunctions/Orbital.h" #include "utils/print_utils.h" using mrcpp::FunctionTree; @@ -47,19 +47,19 @@ namespace mrchem { * * @param adap: extra refinement in output * - * Initializes the mrcpp::ComplexFunction with NULL pointers for both real and imaginary part. + * Initializes the mrcpp::CompFunction<3> with NULL pointers for both real and imaginary part. * These must be computed in setup() of derived classes. The initial output grid * in application will be a copy of the input orbital but NOT a copy of the * potential grid. The argument sets how many extra refinement levels is allowed * beyond this initial refinement. */ QMPotential::QMPotential(int adap, bool shared) - : mrcpp::ComplexFunction(0, -1, -1, shared) + : mrcpp::CompFunction<3>(0, shared) , QMOperator() , adap_build(adap) {} QMPotential::QMPotential(const QMPotential &inp) - : mrcpp::ComplexFunction(0, -1, -1, inp.isShared()) + : mrcpp::CompFunction<3>(0, inp.isShared()) , QMOperator() , adap_build(inp.adap_build) {} @@ -73,14 +73,13 @@ QMPotential::QMPotential(const QMPotential &inp) Orbital QMPotential::apply(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); - Orbital out = inp.paramCopy(); - calcRealPart(out, inp, false); - calcImagPart(out, inp, false); + Orbital out(inp); + calc(out, inp, false); return out; } -/** @brief apply complex cojugate potential +/** @brief apply complex conjugate potential * * @param inp: orbital on which to apply * @@ -90,10 +89,8 @@ Orbital QMPotential::apply(Orbital inp) { Orbital QMPotential::dagger(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); - Orbital out = inp.paramCopy(); - calcRealPart(out, inp, true); - calcImagPart(out, inp, true); - + Orbital out(inp.data); + calc(out, inp, true); return out; } @@ -105,18 +102,17 @@ QMOperatorVector QMPotential::apply(QMOperator_p &O) { if (I) { // O == identity: skip it auto V_out = std::make_shared(*this); - mrcpp::cplxfunc::deep_copy(*V_out, *this); + mrcpp::deep_copy(*V_out, *this); out.push_back(V_out); } else if (V_inp) { // O == potential: merge into single potential auto V_out = std::make_shared(*this); - calcRealPart(*V_out, *V_inp, false); - calcImagPart(*V_out, *V_inp, false); + calc(*V_out, *V_inp, false); out.push_back(V_out); } else { // fallback: treat as individual operators auto V_out = std::make_shared(*this); - mrcpp::cplxfunc::deep_copy(*V_out, *this); + mrcpp::deep_copy(*V_out, *this); out.push_back(O); out.push_back(V_out); } @@ -128,71 +124,22 @@ QMOperatorVector QMPotential::apply(QMOperator_p &O) { * @param inp: input orbital * @param dagger: apply complex conjugate potential * - * Computes the real part of the output orbital. The initial output grid is a - * copy of the input orbital grid but NOT a copy of the potential grid. - */ -void QMPotential::calcRealPart(mrcpp::ComplexFunction &out, mrcpp::ComplexFunction &inp, bool dagger) { - int adap = this->adap_build; - double prec = this->apply_prec; - - if (out.hasReal()) MSG_ABORT("Output not empty"); - if (out.isShared()) MSG_ABORT("Cannot share this function"); - - mrcpp::ComplexFunction &V = *this; - if (V.hasReal() and inp.hasReal()) { - double coef = 1.0; - mrcpp::ComplexFunction tmp(false); - tmp.alloc(NUMBER::Real); - mrcpp::copy_grid(tmp.real(), inp.real()); - mrcpp::multiply(prec, tmp.real(), coef, V.real(), inp.real(), adap); - out.add(1.0, tmp); - } - if (V.hasImag() and inp.hasImag()) { - double coef = -1.0; - if (dagger) coef *= -1.0; - if (inp.conjugate()) coef *= -1.0; - mrcpp::ComplexFunction tmp(false); - tmp.alloc(NUMBER::Real); - mrcpp::copy_grid(tmp.real(), inp.imag()); - mrcpp::multiply(prec, tmp.real(), coef, V.imag(), inp.imag(), adap); - out.add(1.0, tmp); - } -} - -/** @brief compute imaginary part of output - * - * @param inp: input orbital - * @param dagger: apply complex conjugate potential - * - * Computes the imaginary part of the output orbital. The initial output grid is a + * Multiplies the potential with the orbital. The initial output grid is a * copy of the input orbital grid but NOT a copy of the potential grid. */ -void QMPotential::calcImagPart(mrcpp::ComplexFunction &out, mrcpp::ComplexFunction &inp, bool dagger) { +void QMPotential::calc(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> &inp, bool dagger) { int adap = this->adap_build; double prec = this->apply_prec; - if (out.hasImag()) MSG_ABORT("Output not empty"); + if (out.Ncomp > 0) MSG_ABORT("Output not empty"); if (out.isShared()) MSG_ABORT("Cannot share this function"); + if (dagger) MSG_ERROR("Not implemented"); + if (inp.conjugate()) MSG_ERROR("Not implemented"); - mrcpp::ComplexFunction &V = *this; - if (V.hasReal() and inp.hasImag()) { - double coef = 1.0; - if (inp.conjugate()) coef *= -1.0; - mrcpp::ComplexFunction tmp(false); - tmp.alloc(NUMBER::Imag); - mrcpp::copy_grid(tmp.imag(), inp.imag()); - mrcpp::multiply(prec, tmp.imag(), coef, V.real(), inp.imag(), adap); - out.add(1.0, tmp); - } - if (V.hasImag() and inp.hasReal()) { - double coef = 1.0; - if (dagger) coef *= -1.0; - mrcpp::ComplexFunction tmp(false); - tmp.alloc(NUMBER::Imag); - mrcpp::copy_grid(tmp.imag(), inp.real()); - mrcpp::multiply(prec, tmp.imag(), coef, V.imag(), inp.real(), adap); - out.add(1.0, tmp); - } + mrcpp::CompFunction<3> &V = *this; + double coef = 1.0; + mrcpp::copy_grid(out, inp); + mrcpp::multiply(prec, out, coef, V, inp, adap); } } // namespace mrchem diff --git a/src/qmoperators/QMPotential.h b/src/qmoperators/QMPotential.h index 130f6a221..da0858cb2 100644 --- a/src/qmoperators/QMPotential.h +++ b/src/qmoperators/QMPotential.h @@ -33,7 +33,7 @@ * * @brief Operator defining a multiplicative potential * - * Inherits the general features of a complex function from mrcpp::ComplexFunction and + * Inherits the general features of a complex function from mrcpp::CompFunction<3> and * implements the multiplication of this function with an Orbital. The actual * function representing the operator needs to be implemented in the derived * classes, where the *re and *im FunctionTree pointers should be assigned in @@ -43,7 +43,7 @@ namespace mrchem { -class QMPotential : public mrcpp::ComplexFunction, public QMOperator { +class QMPotential : public mrcpp::CompFunction<3>, public QMOperator { public: explicit QMPotential(int adap, bool shared = false); QMPotential(const QMPotential &pot); @@ -64,8 +64,7 @@ class QMPotential : public mrcpp::ComplexFunction, public QMOperator { Orbital dagger(Orbital inp) override; QMOperatorVector apply(std::shared_ptr &O) override; - void calcRealPart(mrcpp::ComplexFunction &out, mrcpp::ComplexFunction &inp, bool dagger); - void calcImagPart(mrcpp::ComplexFunction &out, mrcpp::ComplexFunction &inp, bool dagger); + void calc(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> &inp, bool dagger); }; } // namespace mrchem diff --git a/src/qmoperators/QMSpin.cpp b/src/qmoperators/QMSpin.cpp index dec2d8755..e2c1475aa 100644 --- a/src/qmoperators/QMSpin.cpp +++ b/src/qmoperators/QMSpin.cpp @@ -65,7 +65,7 @@ Orbital QMSpin::apply(Orbital inp) { } Orbital out = inp.paramCopy(); - mrcpp::cplxfunc::deep_copy(out, inp); + mrcpp::deep_copy(out, inp); out.rescale(coef); // Flip spin for s_x and s_y @@ -106,7 +106,7 @@ Orbital QMAlpha::apply(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); Orbital out(SPIN::Alpha, 1, inp.getRank()); - if (inp.spin() == SPIN::Alpha || inp.spin() == SPIN::Paired) mrcpp::cplxfunc::deep_copy(out, inp); + if (inp.spin() == SPIN::Alpha || inp.spin() == SPIN::Paired) mrcpp::deep_copy(out, inp); return out; } @@ -115,7 +115,7 @@ Orbital QMAlpha::dagger(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); Orbital out(SPIN::Alpha, 1, inp.getRank()); - if (inp.spin() == SPIN::Alpha || inp.spin() == SPIN::Paired) mrcpp::cplxfunc::deep_copy(out, inp); + if (inp.spin() == SPIN::Alpha || inp.spin() == SPIN::Paired) mrcpp::deep_copy(out, inp); return out; } @@ -146,7 +146,7 @@ Orbital QMBeta::apply(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); Orbital out(SPIN::Beta, 1, inp.getRank()); - if (inp.spin() == SPIN::Beta || inp.spin() == SPIN::Paired) mrcpp::cplxfunc::deep_copy(out, inp); + if (inp.spin() == SPIN::Beta || inp.spin() == SPIN::Paired) mrcpp::deep_copy(out, inp); return out; } @@ -155,7 +155,7 @@ Orbital QMBeta::dagger(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); Orbital out(SPIN::Beta, 1, inp.getRank()); - if (inp.spin() == SPIN::Beta || inp.spin() == SPIN::Paired) mrcpp::cplxfunc::deep_copy(out, inp); + if (inp.spin() == SPIN::Beta || inp.spin() == SPIN::Paired) mrcpp::deep_copy(out, inp); return out; } diff --git a/src/qmoperators/one_electron/DeltaOperator.h b/src/qmoperators/one_electron/DeltaOperator.h index cd619bf17..c5d8e1bb3 100644 --- a/src/qmoperators/one_electron/DeltaOperator.h +++ b/src/qmoperators/one_electron/DeltaOperator.h @@ -53,7 +53,7 @@ class DeltaOperator final : public RankZeroOperator { // Project analytic potential auto delta = std::make_shared(1); - mrcpp::cplxfunc::project(*delta, f, NUMBER::Real, proj_prec); + mrcpp::project<3>(*delta, f, proj_prec); // Invoke operator= to assign *this operator RankZeroOperator &h = (*this); diff --git a/src/qmoperators/one_electron/NuclearGradientOperator.h b/src/qmoperators/one_electron/NuclearGradientOperator.h index 7a89425ba..c4b8e5439 100644 --- a/src/qmoperators/one_electron/NuclearGradientOperator.h +++ b/src/qmoperators/one_electron/NuclearGradientOperator.h @@ -55,9 +55,9 @@ class NuclearGradientOperator final : public RankOneOperator<3> { auto z_rm3 = std::make_shared(1); // Project analytic potential - mrcpp::cplxfunc::project(*x_rm3, f_x, NUMBER::Real, proj_prec); - mrcpp::cplxfunc::project(*y_rm3, f_y, NUMBER::Real, proj_prec); - mrcpp::cplxfunc::project(*z_rm3, f_z, NUMBER::Real, proj_prec); + mrcpp::project<3>(*x_rm3, f_x, proj_prec); + mrcpp::project<3>(*y_rm3, f_y, proj_prec); + mrcpp::project<3>(*z_rm3, f_z, proj_prec); // Invoke operator= to assign *this operator RankOneOperator &v = (*this); diff --git a/src/qmoperators/one_electron/NuclearOperator.cpp b/src/qmoperators/one_electron/NuclearOperator.cpp index c0dd46815..5926d11f1 100644 --- a/src/qmoperators/one_electron/NuclearOperator.cpp +++ b/src/qmoperators/one_electron/NuclearOperator.cpp @@ -99,8 +99,8 @@ NuclearOperator::NuclearOperator(const Nuclei &nucs, double proj_prec, double sm loc_prec /= pow(vol, 1.0 / 6.0); // norm of 1/r over the box ~ root_6(Volume) // Project local potential - mrcpp::ComplexFunction V_loc(false); - mrcpp::cplxfunc::project(V_loc, *f_loc, NUMBER::Real, loc_prec); + mrcpp::CompFunction<3> V_loc(false); + mrcpp::project(V_loc, *f_loc, loc_prec); t_loc.stop(); mrcpp::print::separator(1, '-'); print_utils::qmfunction(1, "Local potential", V_loc, t_loc); @@ -162,7 +162,7 @@ void NuclearOperator::setupLocalPotential(NuclearFunction &f_loc, const Nuclei & } } -void NuclearOperator::allreducePotential(double prec, mrcpp::ComplexFunction &V_tot, mrcpp::ComplexFunction &V_loc) const { +void NuclearOperator::allreducePotential(double prec, mrcpp::CompFunction<3> &V_tot, mrcpp::CompFunction<3> &V_loc) const { // Add up local contributions into the grand master mrcpp::mpi::reduce_function(prec, V_loc, mrcpp::mpi::comm_wrk); if (mrcpp::mpi::grand_master()) { diff --git a/src/qmoperators/one_electron/NuclearOperator.h b/src/qmoperators/one_electron/NuclearOperator.h index b16afd461..6e56d8c64 100644 --- a/src/qmoperators/one_electron/NuclearOperator.h +++ b/src/qmoperators/one_electron/NuclearOperator.h @@ -36,10 +36,10 @@ class NuclearOperator final : public RankZeroOperator { NuclearOperator(const Nuclei &nucs, double proj_prec, double smooth_prec = -1.0, bool mpi_share = false, const std::string &model = "point_like"); private: - mrcpp::ComplexFunction V_func; // The MW Function representation of the potential + mrcpp::CompFunction<3> V_func; // The MW Function representation of the potential void setupLocalPotential(NuclearFunction &f_loc, const Nuclei &nucs, double smooth_prec) const; - void allreducePotential(double prec, mrcpp::ComplexFunction &V_tot, mrcpp::ComplexFunction &V_loc) const; + void allreducePotential(double prec, mrcpp::CompFunction<3> &V_tot, mrcpp::CompFunction<3> &V_loc) const; }; } // namespace mrchem diff --git a/src/qmoperators/one_electron/PositionOperator.h b/src/qmoperators/one_electron/PositionOperator.h index ba301472a..30afd88f7 100644 --- a/src/qmoperators/one_electron/PositionOperator.h +++ b/src/qmoperators/one_electron/PositionOperator.h @@ -49,9 +49,10 @@ class PositionOperator : public RankOneOperator<3> { auto r_z = std::make_shared(1); // Project analytic potential (exact on root scale, thus no prec) - mrcpp::cplxfunc::project(*r_x, f_x, NUMBER::Real, -1.0); - mrcpp::cplxfunc::project(*r_y, f_y, NUMBER::Real, -1.0); - mrcpp::cplxfunc::project(*r_z, f_z, NUMBER::Real, -1.0); + // the cast is required, because otherwise the compiler is not smart enough to understand that it returns a double + mrcpp::project(*r_x, static_cast&)>>(f_x), -1.0); + mrcpp::project(*r_y, static_cast&)>>(f_y), -1.0); + mrcpp::project(*r_z, static_cast&)>>(f_z), -1.0); // Invoke operator= to assign *this operator RankOneOperator &r = (*this); diff --git a/src/qmoperators/one_electron/ZoraOperator.cpp b/src/qmoperators/one_electron/ZoraOperator.cpp index e2b38f505..3b2387f31 100644 --- a/src/qmoperators/one_electron/ZoraOperator.cpp +++ b/src/qmoperators/one_electron/ZoraOperator.cpp @@ -41,7 +41,7 @@ ZoraOperator::ZoraOperator(QMPotential &vz, double c, double proj_prec, bool inv double two_cc = 2.0 * c * c; auto k = std::make_shared(1); - mrcpp::cplxfunc::deep_copy(*k, vz); + mrcpp::deep_copy(*k, vz); if (k->hasImag()) MSG_ERROR("Inverse of complex function"); if (k->hasReal()) { diff --git a/src/qmoperators/two_electron/CoulombPotential.cpp b/src/qmoperators/two_electron/CoulombPotential.cpp index 26309f073..9165eb405 100644 --- a/src/qmoperators/two_electron/CoulombPotential.cpp +++ b/src/qmoperators/two_electron/CoulombPotential.cpp @@ -87,7 +87,7 @@ void CoulombPotential::setup(double prec) { // Keep each local contribution a bit // more precise than strictly necessary setupLocalDensity(0.1 * prec); - mrcpp::ComplexFunction V = setupLocalPotential(0.1 * prec); + mrcpp::CompFunction<3> V = setupLocalPotential(0.1 * prec); allreducePotential(0.1 * prec, V); } if (plevel == 2) print_utils::qmfunction(2, "Coulomb operator", *this, timer); @@ -100,7 +100,7 @@ void CoulombPotential::setup(double prec) { * The operator can now be reused after another setup. */ void CoulombPotential::clear() { - mrcpp::ComplexFunction::free(NUMBER::Total); // delete FunctionTree pointers + mrcpp::CompFunction<3>::free(NUMBER::Total); // delete FunctionTree pointers this->density.free(NUMBER::Total); // delete FunctionTree pointers clearApplyPrec(); // apply_prec = -1 } @@ -116,8 +116,8 @@ void CoulombPotential::setupGlobalPotential(double prec) { if (this->poisson == nullptr) MSG_ERROR("Poisson operator not initialized"); PoissonOperator &P = *this->poisson; - mrcpp::ComplexFunction &V = *this; - mrcpp::ComplexFunction &rho = this->density; + mrcpp::CompFunction<3> &V = *this; + mrcpp::CompFunction<3> &rho = this->density; if (V.hasReal()) MSG_ERROR("Potential not properly cleared"); if (V.hasImag()) MSG_ERROR("Potential not properly cleared"); @@ -140,18 +140,18 @@ void CoulombPotential::setupGlobalPotential(double prec) { * This will compute the Coulomb potential by application o the Poisson operator * to the precomputed electron density. */ -mrcpp::ComplexFunction CoulombPotential::setupLocalPotential(double prec) { +mrcpp::CompFunction<3> CoulombPotential::setupLocalPotential(double prec) { if (this->poisson == nullptr) MSG_ERROR("Poisson operator not initialized"); PoissonOperator &P = *this->poisson; OrbitalVector &Phi = *this->orbitals; - mrcpp::ComplexFunction &rho = this->density; + mrcpp::CompFunction<3> &rho = this->density; // Adjust precision by system size double abs_prec = prec / orbital::get_electron_number(Phi); Timer timer; - mrcpp::ComplexFunction V(false); + mrcpp::CompFunction<3> V(false); V.alloc(NUMBER::Real); mrcpp::apply(abs_prec, V.real(), P, rho.real()); print_utils::qmfunction(3, "Compute local potential", V, timer); @@ -159,10 +159,10 @@ mrcpp::ComplexFunction CoulombPotential::setupLocalPotential(double prec) { return V; } -void CoulombPotential::allreducePotential(double prec, mrcpp::ComplexFunction &V_loc) { +void CoulombPotential::allreducePotential(double prec, mrcpp::CompFunction<3> &V_loc) { Timer t_com; - mrcpp::ComplexFunction &V_tot = *this; + mrcpp::CompFunction<3> &V_tot = *this; OrbitalVector &Phi = *this->orbitals; double abs_prec = prec / orbital::get_electron_number(Phi); diff --git a/src/qmoperators/two_electron/CoulombPotential.h b/src/qmoperators/two_electron/CoulombPotential.h index 5eb1157af..f287527c3 100644 --- a/src/qmoperators/two_electron/CoulombPotential.h +++ b/src/qmoperators/two_electron/CoulombPotential.h @@ -74,8 +74,8 @@ class CoulombPotential : public QMPotential { virtual void setupLocalDensity(double prec) {} void setupGlobalPotential(double prec); - mrcpp::ComplexFunction setupLocalPotential(double prec); - void allreducePotential(double prec, mrcpp::ComplexFunction &V_loc); + mrcpp::CompFunction<3> setupLocalPotential(double prec); + void allreducePotential(double prec, mrcpp::CompFunction<3> &V_loc); }; } // namespace mrchem diff --git a/src/qmoperators/two_electron/ExchangePotential.cpp b/src/qmoperators/two_electron/ExchangePotential.cpp index 296ab00c2..e53c3d6e0 100644 --- a/src/qmoperators/two_electron/ExchangePotential.cpp +++ b/src/qmoperators/two_electron/ExchangePotential.cpp @@ -29,7 +29,6 @@ #include "ExchangePotential.h" #include "qmfunctions/Orbital.h" -#include "qmfunctions/OrbitalIterator.h" #include "qmfunctions/orbital_utils.h" #include "utils/print_utils.h" @@ -59,7 +58,7 @@ ExchangePotential::ExchangePotential(PoissonOperator_p P, OrbitalVector_p Phi, d */ void ExchangePotential::rotate(const ComplexMatrix &U) { if (this->exchange.size() == 0) return; - mrcpp::mpifuncvec::rotate(this->exchange, U, this->apply_prec); + mrcpp::rotate(this->exchange, U, this->apply_prec); // NOTE: The following MPI point is currently NOT implemented! // @@ -172,13 +171,13 @@ void ExchangePotential::calcExchange_kij(double prec, Orbital phi_k, Orbital phi // the result is expected to be negligible Timer timer_ij; Orbital rho_ij = phi_i.paramCopy(); - mrcpp::cplxfunc::multiply(rho_ij, phi_i.dagger(), phi_j, prec_m1, true, true); + mrcpp::multiply(rho_ij, phi_i.dagger(), phi_j, prec_m1, true, true); timer_ij.stop(); if (rho_ij.norm() < prec) return; - auto N_i = phi_i.getNNodes(NUMBER::Total); - auto N_j = phi_j.getNNodes(NUMBER::Total); - auto N_ij = rho_ij.getNNodes(NUMBER::Total); + auto N_i = phi_i.getNNodes(); + auto N_j = phi_j.getNNodes(); + auto N_ij = rho_ij.getNNodes(); auto norm_ij = rho_ij.norm(); // prepare vector used to steer precision of Poisson application @@ -203,15 +202,15 @@ void ExchangePotential::calcExchange_kij(double prec, Orbital phi_k, Orbital phi V_ij.alloc(NUMBER::Imag); mrcpp::apply(prec_p, V_ij.imag(), P, rho_ij.imag(), phi_opt_vec, -1, true); } - rho_ij.release(); + rho_ij.free(); timer_p.stop(); - auto N_p = V_ij.getNNodes(NUMBER::Total); + auto N_p = V_ij.getNNodes(); auto norm_p = V_ij.norm(); // compute out_kij = phi_k * V_ij Timer timer_kij; - mrcpp::cplxfunc::multiply(out_kij, phi_k, V_ij, prec_m2, true, true); - auto N_kij = out_kij.getNNodes(NUMBER::Total); + mrcpp::multiply(out_kij, phi_k, V_ij, prec_m2, true, true); + auto N_kij = out_kij.getNNodes(); auto norm_kij = out_kij.norm(); timer_kij.stop(); @@ -220,8 +219,8 @@ void ExchangePotential::calcExchange_kij(double prec, Orbital phi_k, Orbital phi auto N_jji = 0; auto norm_jji = 0.0; if (out_jji != nullptr) { - mrcpp::cplxfunc::multiply(*out_jji, phi_j, V_ij.dagger(), prec_m2, true, true); - N_jji = out_jji->getNNodes(NUMBER::Total); + mrcpp::multiply(*out_jji, phi_j, V_ij.dagger(), prec_m2, true, true); + N_jji = out_jji->getNNodes(); norm_jji = out_jji->norm(); } timer_jji.stop(); diff --git a/src/qmoperators/two_electron/ExchangePotentialD1.cpp b/src/qmoperators/two_electron/ExchangePotentialD1.cpp index c77d20d1a..1815b4887 100644 --- a/src/qmoperators/two_electron/ExchangePotentialD1.cpp +++ b/src/qmoperators/two_electron/ExchangePotentialD1.cpp @@ -29,7 +29,6 @@ #include "ExchangePotentialD1.h" #include "qmfunctions/Orbital.h" -#include "qmfunctions/OrbitalIterator.h" #include "qmfunctions/orbital_utils.h" #include "utils/print_utils.h" @@ -59,7 +58,7 @@ void ExchangePotentialD1::setupBank() { mrcpp::mpi::barrier(mrcpp::mpi::comm_wrk); OrbitalVector &Phi = *this->orbitals; for (int i = 0; i < Phi.size(); i++) { - if (mrcpp::mpi::my_orb(i)) PhiBank.put_func(i, Phi[i]); + if (mrcpp::mpi::my_func(i)) PhiBank.put_func(i, Phi[i]); } mrcpp::mpi::barrier(mrcpp::mpi::comm_wrk); mrcpp::print::time(3, "Setting up exchange bank", timer); @@ -110,7 +109,7 @@ Orbital ExchangePotentialD1::apply(Orbital phi_p) { } int i = testInternal(phi_p); if (i < 0) { - if (not mrcpp::mpi::my_orb(phi_p)) { + if (not mrcpp::mpi::my_func(phi_p)) { MSG_WARN("Not computing exchange contributions that are not mine"); return out_p; } @@ -158,7 +157,7 @@ void ExchangePotentialD1::setupInternal(double prec) { for (auto &phi_i : Phi) { Orbital ex_iii(phi_i.spin(), phi_i.occ(), phi_i.getRank()); t_calc.resume(); - if (mrcpp::mpi::my_orb(i)) calcExchange_kij(precf, phi_i, phi_i, phi_i, ex_iii); + if (mrcpp::mpi::my_func(i)) calcExchange_kij(precf, phi_i, phi_i, phi_i, ex_iii); t_calc.stop(); Ex.push_back(ex_iii); i++; @@ -242,7 +241,7 @@ void ExchangePotentialD1::setupInternal(double prec) { task = tasksMaster.next_task(); if (task < 0) break; // we fetch all required i (but only one j at a time) - OrbitalVector iorb_vec; + std::vector iorb_vec; int i0 = -1; for (int i = 0; i < itasks[task].size(); i++) { int iorb = itasks[task][i]; @@ -268,8 +267,8 @@ void ExchangePotentialD1::setupInternal(double prec) { } else phi_j = Phi[jorb]; t_orb.stop(); - std::vector iijfunc_vec; - ComplexVector coef_vec(N); + std::vector> iijfunc_vec; + std::vector coef_vec(N); for (int i = 0; i < iorb_vec.size(); i++) { int iorb = itasks[task][i]; Orbital &phi_i = iorb_vec[i]; @@ -314,7 +313,7 @@ void ExchangePotentialD1::setupInternal(double prec) { if (mrcpp::mpi::bank_size > 0 and iijfunc_vec.size() > 0) { Orbital ex_j = phi_j.paramCopy(); t_add.resume(); - mrcpp::cplxfunc::linear_combination(ex_j, coef_vec, iijfunc_vec, prec); + mrcpp::linear_combination(ex_j, coef_vec, iijfunc_vec, prec); t_add.stop(); // ex_j is sent to Bank if (ex_j.hasReal() or ex_j.hasImag()) { @@ -342,10 +341,10 @@ void ExchangePotentialD1::setupInternal(double prec) { t_wait.stop(); for (int j = 0; j < N; j++) { - if (not mrcpp::mpi::my_orb(j) or mrcpp::mpi::bank_size == 0) continue; // fetch only own j + if (not mrcpp::mpi::my_func(j) or mrcpp::mpi::bank_size == 0) continue; // fetch only own j std::vector iVec = tasksMaster.get_readytask(j, 1); - std::vector iijfunc_vec; - ComplexVector coef_vec(N); + std::vector> iijfunc_vec; + std::vector coef_vec(N); int tot = 0; int totmax = 2 * block_size; for (int i : iVec) { @@ -363,7 +362,7 @@ void ExchangePotentialD1::setupInternal(double prec) { // we sum the contributions so far before fetching new ones t_add.resume(); auto tmp_j = Ex[j].paramCopy(); - mrcpp::cplxfunc::linear_combination(tmp_j, coef_vec, iijfunc_vec, prec); + mrcpp::linear_combination(tmp_j, coef_vec, iijfunc_vec, prec); Ex[j].add(1.0, tmp_j); tmp_j.free(NUMBER::Total); for (int jj = 0; jj < iijfunc_vec.size(); jj++) iijfunc_vec[jj].free(NUMBER::Total); @@ -376,7 +375,7 @@ void ExchangePotentialD1::setupInternal(double prec) { if (iijfunc_vec.size() > 0) { t_add.resume(); auto tmp_j = Ex[j].paramCopy(); - mrcpp::cplxfunc::linear_combination(tmp_j, coef_vec, iijfunc_vec, prec); + mrcpp::linear_combination(tmp_j, coef_vec, iijfunc_vec, prec); Ex[j].add(1.0, tmp_j); tmp_j.free(NUMBER::Total); for (int jj = 0; jj < iijfunc_vec.size(); jj++) iijfunc_vec[jj].free(NUMBER::Total); @@ -419,11 +418,11 @@ Orbital ExchangePotentialD1::calcExchange(Orbital phi_p) { // adjust precision since we sum over orbitals precf /= std::min(10.0, std::sqrt(1.0 * Phi.size())); - std::vector func_vec; + std::vector> func_vec; std::vector coef_vec; for (int i = 0; i < Phi.size(); i++) { - Orbital &phi_i = Phi[i]; - if (not mrcpp::mpi::my_orb(i)) PhiBank.get_func(i, phi_i, 1); + Orbital phi_i(Phi[i]); + if (not mrcpp::mpi::my_func(i)) PhiBank.get_func(i, phi_i, 1); double spin_fac = getSpinFactor(phi_i, phi_p); if (std::abs(spin_fac) >= mrcpp::MachineZero) { @@ -433,13 +432,13 @@ Orbital ExchangePotentialD1::calcExchange(Orbital phi_p) { func_vec.push_back(ex_iip); } - if (not mrcpp::mpi::my_orb(i)) phi_i.free(NUMBER::Total); + if (not mrcpp::mpi::my_func(i)) phi_i.free(NUMBER::Total); } // compute ex_p = sum_i c_i*ex_iip Orbital ex_p = phi_p.paramCopy(); - Eigen::Map coefs(coef_vec.data(), coef_vec.size()); - mrcpp::cplxfunc::linear_combination(ex_p, coefs, func_vec, prec); + //Eigen::Map coefs(coef_vec.data(), coef_vec.size()); + mrcpp::linear_combination(ex_p, coef_vec, func_vec, prec); print_utils::qmfunction(4, "Applied exchange", ex_p, timer); return ex_p; } diff --git a/src/qmoperators/two_electron/ExchangePotentialD2.cpp b/src/qmoperators/two_electron/ExchangePotentialD2.cpp index e263b7fe3..e57955611 100644 --- a/src/qmoperators/two_electron/ExchangePotentialD2.cpp +++ b/src/qmoperators/two_electron/ExchangePotentialD2.cpp @@ -29,7 +29,6 @@ #include "ExchangePotentialD2.h" #include "qmfunctions/Orbital.h" -#include "qmfunctions/OrbitalIterator.h" #include "qmfunctions/orbital_utils.h" #include "utils/print_utils.h" @@ -63,15 +62,15 @@ void ExchangePotentialD2::setupBank() { mrcpp::mpi::barrier(mrcpp::mpi::comm_wrk); OrbitalVector &Phi = *this->orbitals; for (int i = 0; i < Phi.size(); i++) { - if (mrcpp::mpi::my_orb(Phi[i])) PhiBank.put_func(i, Phi[i]); + if (mrcpp::mpi::my_func(Phi[i])) PhiBank.put_func(i, Phi[i]); } OrbitalVector &X = *this->orbitals_x; for (int i = 0; i < X.size(); i++) { - if (mrcpp::mpi::my_orb(X[i])) XBank.put_func(i, X[i]); + if (mrcpp::mpi::my_func(X[i])) XBank.put_func(i, X[i]); } OrbitalVector &Y = *this->orbitals_y; for (int i = 0; i < Y.size(); i++) { - if (mrcpp::mpi::my_orb(Y[i])) YBank.put_func(i, Y[i]); + if (mrcpp::mpi::my_func(Y[i])) YBank.put_func(i, Y[i]); } mrcpp::mpi::barrier(mrcpp::mpi::comm_wrk); mrcpp::print::time(3, "Setting up exchange bank", timer); @@ -111,16 +110,16 @@ Orbital ExchangePotentialD2::apply(Orbital phi_p) { // adjust precision since we sum over orbitals precf /= std::sqrt(1 * Phi.size()); - std::vector func_vec; + std::vector> func_vec; std::vector coef_vec; for (int i = 0; i < Phi.size(); i++) { - Orbital &phi_i = Phi[i]; - Orbital &x_i = X[i]; - Orbital &y_i = Y[i]; + Orbital phi_i(Phi[i]); + Orbital x_i(X[i]); + Orbital y_i(Y[i]); - if (not mrcpp::mpi::my_orb(phi_i)) PhiBank.get_func(i, phi_i, 1); - if (not mrcpp::mpi::my_orb(x_i)) XBank.get_func(i, x_i, 1); - if (not mrcpp::mpi::my_orb(y_i)) YBank.get_func(i, y_i, 1); + if (not mrcpp::mpi::my_func(phi_i)) PhiBank.get_func(i, phi_i, 1); + if (not mrcpp::mpi::my_func(x_i)) XBank.get_func(i, x_i, 1); + if (not mrcpp::mpi::my_func(y_i)) YBank.get_func(i, y_i, 1); double spin_fac = getSpinFactor(phi_i, phi_p); if (std::abs(spin_fac) >= mrcpp::MachineZero) { @@ -133,15 +132,15 @@ Orbital ExchangePotentialD2::apply(Orbital phi_p) { coef_vec.push_back(spin_fac / phi_i.squaredNorm()); coef_vec.push_back(spin_fac / phi_i.squaredNorm()); } - if (not mrcpp::mpi::my_orb(phi_i)) phi_i.free(NUMBER::Total); - if (not mrcpp::mpi::my_orb(x_i)) x_i.free(NUMBER::Total); - if (not mrcpp::mpi::my_orb(y_i)) y_i.free(NUMBER::Total); + if (not mrcpp::mpi::my_func(phi_i)) phi_i.free(NUMBER::Total); + if (not mrcpp::mpi::my_func(x_i)) x_i.free(NUMBER::Total); + if (not mrcpp::mpi::my_func(y_i)) y_i.free(NUMBER::Total); } // compute out_p = sum_i c_i*(ex_xip + ex_iyp) Orbital out_p = phi_p.paramCopy(); - Eigen::Map coefs(coef_vec.data(), coef_vec.size()); - mrcpp::cplxfunc::linear_combination(out_p, coefs, func_vec, prec); + //Eigen::Map coefs(coef_vec.data(), coef_vec.size()); + mrcpp::linear_combination(out_p, coef_vec, func_vec, prec); print_utils::qmfunction(4, "Applied exchange", out_p, timer); return out_p; } @@ -170,16 +169,16 @@ Orbital ExchangePotentialD2::dagger(Orbital phi_p) { // adjust precision since we sum over orbitals precf /= std::min(10.0, std::sqrt(1.0 * Phi.size())); - std::vector func_vec; + std::vector> func_vec; std::vector coef_vec; for (int i = 0; i < Phi.size(); i++) { - Orbital &phi_i = Phi[i]; - Orbital &x_i = X[i]; - Orbital &y_i = Y[i]; + Orbital phi_i(Phi[i]); + Orbital x_i(X[i]); + Orbital y_i(Y[i]); - if (not mrcpp::mpi::my_orb(phi_i)) PhiBank.get_func(i, phi_i, 1); - if (not mrcpp::mpi::my_orb(x_i)) XBank.get_func(i, x_i, 1); - if (not mrcpp::mpi::my_orb(y_i)) YBank.get_func(i, y_i, 1); + if (not mrcpp::mpi::my_func(phi_i)) PhiBank.get_func(i, phi_i, 1); + if (not mrcpp::mpi::my_func(x_i)) XBank.get_func(i, x_i, 1); + if (not mrcpp::mpi::my_func(y_i)) YBank.get_func(i, y_i, 1); double spin_fac = getSpinFactor(phi_i, phi_p); if (std::abs(spin_fac) >= mrcpp::MachineZero) { @@ -192,15 +191,15 @@ Orbital ExchangePotentialD2::dagger(Orbital phi_p) { coef_vec.push_back(spin_fac / phi_i.squaredNorm()); coef_vec.push_back(spin_fac / phi_i.squaredNorm()); } - if (not mrcpp::mpi::my_orb(phi_i)) phi_i.free(NUMBER::Total); - if (not mrcpp::mpi::my_orb(x_i)) x_i.free(NUMBER::Total); - if (not mrcpp::mpi::my_orb(y_i)) y_i.free(NUMBER::Total); + if (not mrcpp::mpi::my_func(phi_i)) phi_i.free(NUMBER::Total); + if (not mrcpp::mpi::my_func(x_i)) x_i.free(NUMBER::Total); + if (not mrcpp::mpi::my_func(y_i)) y_i.free(NUMBER::Total); } // compute ex_p = sum_i c_i*(ex_ixp + ex_yip) Orbital ex_p = phi_p.paramCopy(); - Eigen::Map coefs(coef_vec.data(), coef_vec.size()); - mrcpp::cplxfunc::linear_combination(ex_p, coefs, func_vec, prec); + //Eigen::Map coefs(coef_vec.data(), coef_vec.size()); + mrcpp::linear_combination(ex_p, coef_vec, func_vec, prec); print_utils::qmfunction(4, "Applied exchange", ex_p, timer); return ex_p; } diff --git a/src/qmoperators/two_electron/FockBuilder.cpp b/src/qmoperators/two_electron/FockBuilder.cpp index ad9aaa5d9..5f5830161 100644 --- a/src/qmoperators/two_electron/FockBuilder.cpp +++ b/src/qmoperators/two_electron/FockBuilder.cpp @@ -270,7 +270,7 @@ OrbitalVector FockBuilder::buildHelmholtzArgumentZORA(OrbitalVector &Phi, Orbita Timer t_3; OrbitalVector epsPhi = orbital::deep_copy(Phi); for (int i = 0; i < epsPhi.size(); i++) { - if (not mrcpp::mpi::my_orb(epsPhi[i])) continue; + if (not mrcpp::mpi::my_func(epsPhi[i])) continue; epsPhi[i].rescale(eps[i] / two_cc); } OrbitalVector termThree = operThree(epsPhi); @@ -285,7 +285,7 @@ OrbitalVector FockBuilder::buildHelmholtzArgumentZORA(OrbitalVector &Phi, Orbita Timer t_add; OrbitalVector arg = orbital::deep_copy(termOne); for (int i = 0; i < arg.size(); i++) { - if (not mrcpp::mpi::my_orb(arg[i])) continue; + if (not mrcpp::mpi::my_func(arg[i])) continue; arg[i].add(1.0, termTwo[i]); arg[i].add(1.0, termThree[i]); arg[i].add(1.0, Psi[i]); @@ -316,7 +316,7 @@ OrbitalVector FockBuilder::buildHelmholtzArgumentNREL(OrbitalVector &Phi, Orbita Timer t_add; OrbitalVector out = orbital::deep_copy(termOne); for (int i = 0; i < out.size(); i++) { - if (not mrcpp::mpi::my_orb(out[i])) continue; + if (not mrcpp::mpi::my_func(out[i])) continue; out[i].add(1.0, Psi[i]); }; mrcpp::print::time(2, "Adding contributions", t_add); diff --git a/src/qmoperators/two_electron/ReactionPotential.cpp b/src/qmoperators/two_electron/ReactionPotential.cpp index 1a6b671c0..84ce0d8b0 100644 --- a/src/qmoperators/two_electron/ReactionPotential.cpp +++ b/src/qmoperators/two_electron/ReactionPotential.cpp @@ -52,13 +52,13 @@ void ReactionPotential::setup(double prec) { mrcpp::print::value(3, "Threshold", thrs, "(abs)", 5); mrcpp::print::separator(3, '-'); auto potential = this->computePotential(prec); - mrcpp::cplxfunc::deep_copy(*this, potential); + mrcpp::deep_copy(*this, potential); if (plevel == 2) print_utils::qmfunction(2, "Reaction operator", *this, timer); mrcpp::print::footer(3, timer, 2); } void ReactionPotential::clear() { - mrcpp::ComplexFunction::free(NUMBER::Total); // delete FunctionTree pointers + mrcpp::CompFunction<3>::free(NUMBER::Total); // delete FunctionTree pointers clearApplyPrec(); this->solver->clear(); } diff --git a/src/qmoperators/two_electron/ReactionPotential.h b/src/qmoperators/two_electron/ReactionPotential.h index 6e37fc6ea..987208f83 100644 --- a/src/qmoperators/two_electron/ReactionPotential.h +++ b/src/qmoperators/two_electron/ReactionPotential.h @@ -63,7 +63,7 @@ class ReactionPotential : public QMPotential { void clear() override; private: - virtual mrcpp::ComplexFunction &computePotential(double prec) const = 0; + virtual mrcpp::CompFunction<3> &computePotential(double prec) const = 0; }; } // namespace mrchem diff --git a/src/qmoperators/two_electron/ReactionPotentialD1.cpp b/src/qmoperators/two_electron/ReactionPotentialD1.cpp index 2b12e30fd..8861f7b17 100644 --- a/src/qmoperators/two_electron/ReactionPotentialD1.cpp +++ b/src/qmoperators/two_electron/ReactionPotentialD1.cpp @@ -38,7 +38,7 @@ using PoissonOperator = mrcpp::PoissonOperator; using PoissonOperator_p = std::shared_ptr; namespace mrchem { -mrcpp::ComplexFunction &ReactionPotentialD1::computePotential(double prec) const { +mrcpp::CompFunction<3> &ReactionPotentialD1::computePotential(double prec) const { // construct electronic density from the orbitals OrbitalVector &Phi = *this->orbitals; Density rho_el(false); diff --git a/src/qmoperators/two_electron/ReactionPotentialD1.h b/src/qmoperators/two_electron/ReactionPotentialD1.h index e470fb170..844dbdd47 100644 --- a/src/qmoperators/two_electron/ReactionPotentialD1.h +++ b/src/qmoperators/two_electron/ReactionPotentialD1.h @@ -36,7 +36,7 @@ class ReactionPotentialD1 final : public ReactionPotential { : ReactionPotential(std::move(gpesolver), Phi, mpi_share) {} private: - mrcpp::ComplexFunction &computePotential(double prec) const override; + mrcpp::CompFunction<3> &computePotential(double prec) const override; }; } // namespace mrchem diff --git a/src/qmoperators/two_electron/ReactionPotentialD2.cpp b/src/qmoperators/two_electron/ReactionPotentialD2.cpp index 03328b0ed..1013c7fb7 100644 --- a/src/qmoperators/two_electron/ReactionPotentialD2.cpp +++ b/src/qmoperators/two_electron/ReactionPotentialD2.cpp @@ -35,7 +35,7 @@ using mrcpp::Printer; using mrcpp::Timer; namespace mrchem { -mrcpp::ComplexFunction &ReactionPotentialD2::computePotential(double prec) const { +mrcpp::CompFunction<3> &ReactionPotentialD2::computePotential(double prec) const { // construct perturbed density from the orbitals if (this->orbitals == nullptr) MSG_ERROR("Orbitals not initialized"); if (this->orbitals_x == nullptr) MSG_ERROR("Perturbed X orbitals not initialized"); diff --git a/src/qmoperators/two_electron/ReactionPotentialD2.h b/src/qmoperators/two_electron/ReactionPotentialD2.h index c77aafcbc..875792760 100644 --- a/src/qmoperators/two_electron/ReactionPotentialD2.h +++ b/src/qmoperators/two_electron/ReactionPotentialD2.h @@ -40,6 +40,6 @@ class ReactionPotentialD2 final : public ReactionPotential { std::shared_ptr orbitals_x; ///< Perturbed orbitals std::shared_ptr orbitals_y; ///< Perturbed orbitals - mrcpp::ComplexFunction &computePotential(double prec) const override; + mrcpp::CompFunction<3> &computePotential(double prec) const override; }; } // namespace mrchem diff --git a/src/scf_solver/Accelerator.cpp b/src/scf_solver/Accelerator.cpp index f63f2d67f..a77c98677 100644 --- a/src/scf_solver/Accelerator.cpp +++ b/src/scf_solver/Accelerator.cpp @@ -94,10 +94,10 @@ void Accelerator::rotate(const ComplexMatrix &U, bool all) { if (nOrbs <= 0) { return; } for (int i = 0; i < nOrbs; i++) { auto &Phi = this->orbitals[i]; - mrcpp::mpifuncvec::rotate(Phi, U); + mrcpp::rotate(Phi, U); auto &dPhi = this->dOrbitals[i]; - mrcpp::mpifuncvec::rotate(dPhi, U); + mrcpp::rotate(dPhi, U); } for (int i = 0; i < nFock; i++) { auto &F = this->fock[i]; @@ -162,9 +162,9 @@ bool Accelerator::verifyOverlap(OrbitalVector &Phi) { if (nHistory > 0) { for (int i = 0; i < nOrbs; i++) { auto &phi_i = Phi[i]; - if (mrcpp::mpi::my_orb(phi_i)) { + if (mrcpp::mpi::my_func(phi_i)) { auto &last_i = this->orbitals[nHistory][i]; - if (not mrcpp::mpi::my_orb(last_i)) MSG_ABORT("MPI rank mismatch"); + if (not mrcpp::mpi::my_func(last_i)) MSG_ABORT("MPI rank mismatch"); auto sqNorm = phi_i.squaredNorm(); auto overlap = orbital::dot(phi_i, last_i); if (std::abs(overlap) < 0.5 * sqNorm) { diff --git a/src/scf_solver/HelmholtzVector.cpp b/src/scf_solver/HelmholtzVector.cpp index 70a1a4073..af699bbb0 100644 --- a/src/scf_solver/HelmholtzVector.cpp +++ b/src/scf_solver/HelmholtzVector.cpp @@ -75,7 +75,7 @@ OrbitalVector HelmholtzVector::operator()(OrbitalVector &Phi) const { int pprec = Printer::getPrecision(); OrbitalVector out = orbital::param_copy(Phi); for (int i = 0; i < Phi.size(); i++) { - if (not mrcpp::mpi::my_orb(out[i])) continue; + if (not mrcpp::mpi::my_func(out[i])) continue; t_lap.start(); out[i] = apply(i, Phi[i]); @@ -114,7 +114,7 @@ OrbitalVector HelmholtzVector::apply(RankZeroOperator &V, OrbitalVector &Phi, Or OrbitalVector out = orbital::param_copy(Phi); for (int i = 0; i < Phi.size(); i++) { - if (not mrcpp::mpi::my_orb(out[i])) continue; + if (not mrcpp::mpi::my_func(out[i])) continue; t_lap.start(); Orbital Vphi_i = V(Phi[i]); @@ -138,23 +138,23 @@ OrbitalVector HelmholtzVector::apply(RankZeroOperator &V, OrbitalVector &Phi, Or * * Computes output as: out_i = -2H_i[phi_i] */ -Orbital HelmholtzVector::apply(int i, Orbital &phi) const { +Orbital HelmholtzVector::apply(int i, const Orbital &phi) const { ComplexDouble mu_i = std::sqrt(-2.0 * this->lambda(i)); if (std::abs(mu_i.imag()) > mrcpp::MachineZero) MSG_ABORT("Mu cannot be complex"); mrcpp::HelmholtzOperator H(*MRA, mu_i.real(), this->prec); Orbital out = phi.paramCopy(); - if (phi.hasReal()) { - out.alloc(NUMBER::Real); - mrcpp::apply(this->prec, out.real(), H, phi.real(), -1, true); // Absolute prec - out.real().rescale(-1.0 / (2.0 * mrcpp::pi)); - } - if (phi.hasImag()) { - out.alloc(NUMBER::Imag); - mrcpp::apply(this->prec, out.imag(), H, phi.imag(), -1, true); // Absolute prec - double sign = (phi.conjugate()) ? 1.0 : -1.0; - out.imag().rescale(sign / (2.0 * mrcpp::pi)); + out.alloc(0); + ComplexDouble metric[4][4]; + for (int i=0; i<4; i++){ + for (int j=0; j<4; j++){ + if (i==j) metric[i][j] = 1.0; + else metric[i][j] = 0.0; + } } + mrcpp::apply(this->prec, out, H, phi, metric, -1, true); // Absolute prec + out.rescale(-1.0 / (2.0 * mrcpp::pi)); + return out; } } // namespace mrchem diff --git a/src/scf_solver/HelmholtzVector.h b/src/scf_solver/HelmholtzVector.h index 4eff81d22..c3ee3a0bd 100644 --- a/src/scf_solver/HelmholtzVector.h +++ b/src/scf_solver/HelmholtzVector.h @@ -52,7 +52,7 @@ class HelmholtzVector final { double prec; ///< Precision for construction and application of Helmholtz operators DoubleVector lambda; ///< Helmholtz parameter, mu_i = sqrt(-2.0*lambda_i) - Orbital apply(int i, Orbital &phi) const; + Orbital apply(int i, const Orbital &phi) const; }; } // namespace mrchem diff --git a/src/scf_solver/KAIN.cpp b/src/scf_solver/KAIN.cpp index 4317b149d..97dfd1178 100644 --- a/src/scf_solver/KAIN.cpp +++ b/src/scf_solver/KAIN.cpp @@ -61,17 +61,17 @@ void KAIN::setupLinearSystem() { auto &phi_m = this->orbitals[nHistory][n]; auto &fPhi_m = this->dOrbitals[nHistory][n]; - if (mrcpp::mpi::my_orb(phi_m)) { + if (mrcpp::mpi::my_func(phi_m)) { for (int i = 0; i < nHistory; i++) { auto &phi_i = this->orbitals[i][n]; auto dPhi_im = phi_m.paramCopy(); - mrcpp::cplxfunc::add(dPhi_im, 1.0, phi_i, -1.0, phi_m, -1.0); + mrcpp::add(dPhi_im, 1.0, phi_i, -1.0, phi_m, -1.0); for (int j = 0; j < nHistory; j++) { auto &fPhi_j = this->dOrbitals[j][n]; auto dfPhi_jm = fPhi_m.paramCopy(); - mrcpp::cplxfunc::add(dfPhi_jm, 1.0, fPhi_j, -1.0, fPhi_m, -1.0); + mrcpp::add(dfPhi_jm, 1.0, fPhi_j, -1.0, fPhi_m, -1.0); // Ref. Harrisons KAIN paper the following has the wrong sign, // but we define the updates (lowercase f) with opposite sign. @@ -136,9 +136,9 @@ void KAIN::expandSolution(double prec, OrbitalVector &Phi, OrbitalVector &dPhi, int m = 0; for (int n = 0; n < nOrbitals; n++) { if (this->sepOrbitals) m = n; - if (mrcpp::mpi::my_orb(Phi[n])) { + if (mrcpp::mpi::my_func(Phi[n])) { std::vector totCoefs; - std::vector totOrbs; + std::vector> totOrbs; auto &phi_m = this->orbitals[nHistory][n]; auto &fPhi_m = this->dOrbitals[nHistory][n]; @@ -149,37 +149,36 @@ void KAIN::expandSolution(double prec, OrbitalVector &Phi, OrbitalVector &dPhi, // but we define the updates (lowercase f) with opposite sign // (but not the orbitals themselves). for (int j = 0; j < nHistory; j++) { - ComplexVector partCoefs(4); - std::vector partOrbs; + std::vector partCoefs(4); + std::vector> partOrbs; - partCoefs(0) = {1.0, 0.0}; + partCoefs[0] = {1.0, 0.0}; auto &phi_j = this->orbitals[j][n]; partOrbs.push_back(phi_j); - partCoefs(1) = {1.0, 0.0}; + partCoefs[1] = {1.0, 0.0}; auto &fPhi_j = this->dOrbitals[j][n]; partOrbs.push_back(fPhi_j); - partCoefs(2) = {-1.0, 0.0}; + partCoefs[2] = {-1.0, 0.0}; partOrbs.push_back(phi_m); - partCoefs(3) = {-1.0, 0.0}; + partCoefs[3] = {-1.0, 0.0}; partOrbs.push_back(fPhi_m); auto partStep = phi_m.paramCopy(); - mrcpp::cplxfunc::linear_combination(partStep, partCoefs, partOrbs, prec); + mrcpp::linear_combination(partStep, partCoefs, partOrbs, prec); auto c_j = this->c[m](j); totCoefs.push_back(c_j); totOrbs.push_back(partStep); } - // std::vector -> ComplexVector - ComplexVector coefsVec(totCoefs.size()); - for (int i = 0; i < totCoefs.size(); i++) coefsVec(i) = totCoefs[i]; + std::vector coefsVec(totCoefs.size()); + for (int i = 0; i < totCoefs.size(); i++) coefsVec[i] = totCoefs[i]; dPhi[n] = Phi[n].paramCopy(); - mrcpp::cplxfunc::linear_combination(dPhi[n], coefsVec, totOrbs, prec); + mrcpp::linear_combination(dPhi[n], coefsVec, totOrbs, prec); } } diff --git a/src/scf_solver/LinearResponseSolver.cpp b/src/scf_solver/LinearResponseSolver.cpp index fc0f99038..649433b8b 100644 --- a/src/scf_solver/LinearResponseSolver.cpp +++ b/src/scf_solver/LinearResponseSolver.cpp @@ -127,7 +127,7 @@ json LinearResponseSolver::optimize(double omega, Molecule &mol, FockBuilder &F_ mrcpp::print::time(2, "Applying V_1", t_lap); t_lap.start(); - mrcpp::mpifuncvec::orthogonalize(this->orth_prec, Psi_1, Phi_0); + mrcpp::orthogonalize(this->orth_prec, Psi_1, Phi_0); mrcpp::print::time(2, "Projecting (1 - rho_0)", t_lap); t_lap.start(); diff --git a/src/scf_solver/SCFSolver.cpp b/src/scf_solver/SCFSolver.cpp index 1dde77443..8ad2af6d8 100644 --- a/src/scf_solver/SCFSolver.cpp +++ b/src/scf_solver/SCFSolver.cpp @@ -197,8 +197,8 @@ void SCFSolver::printOrbitals(const DoubleVector &norms, const DoubleVector &err bool conv_i = (errors(i) < this->orbThrs) or (this->orbThrs < 0.0); std::stringstream o_row; o_row << std::setw(w1) << i; - o_row << std::setw(w2) << Phi[i].printSpin(); - o_row << std::setw(w3) << Phi[i].getNNodes(NUMBER::Total); + o_row << std::setw(w2) << Orbital(Phi[i]).printSpin(); + o_row << std::setw(w3) << Phi[i].getNNodes(); o_row << std::setw(w4) << std::setprecision(2 * pprec) << std::fixed << norms(i); o_row << std::setw(w6) << std::setprecision(pprec) << std::scientific << errors(i); o_row << std::setw(w5) << conv_i; diff --git a/src/tensor/RankOneOperator.h b/src/tensor/RankOneOperator.h index 84273bbe2..bc4dbf5de 100644 --- a/src/tensor/RankOneOperator.h +++ b/src/tensor/RankOneOperator.h @@ -30,8 +30,6 @@ namespace mrchem { -using Orbital = mrcpp::ComplexFunction; - /** @class RankOneOperator * * @brief Vector of RankZeroOperator diff --git a/src/tensor/RankTwoOperator.h b/src/tensor/RankTwoOperator.h index e067f0d16..65581affe 100644 --- a/src/tensor/RankTwoOperator.h +++ b/src/tensor/RankTwoOperator.h @@ -30,8 +30,6 @@ namespace mrchem { -using Orbital = mrcpp::ComplexFunction; - /** @class RankTwoOperator * * @brief Matrix of RankZeroOperator diff --git a/src/tensor/RankZeroOperator.cpp b/src/tensor/RankZeroOperator.cpp index fa23dfef1..beb06fb5f 100644 --- a/src/tensor/RankZeroOperator.cpp +++ b/src/tensor/RankZeroOperator.cpp @@ -43,10 +43,10 @@ namespace mrchem { * * Converts std::vector > to Eigen::VectorXcd */ -ComplexVector RankZeroOperator::getCoefVector() const { + std::vector RankZeroOperator::getCoefVector() const { int nCoefs = this->coef_exp.size(); - ComplexVector out(nCoefs); - for (int i = 0; i < nCoefs; i++) out(i) = this->coef_exp[i]; + std::vector out(nCoefs); + for (int i = 0; i < nCoefs; i++) out[i] = this->coef_exp[i]; return out; } @@ -241,17 +241,17 @@ ComplexDouble RankZeroOperator::dagger(const mrcpp::Coord<3> &r) const { * is added upp with the corresponding coefficient. */ Orbital RankZeroOperator::operator()(Orbital inp) { - if (inp.getNNodes(NUMBER::Total) == 0) return inp.paramCopy(); + if (not mrcpp::mpi::my_func(inp)) return inp.paramCopy(); RankZeroOperator &O = *this; - std::vector func_vec; - ComplexVector coef_vec = getCoefVector(); + std::vector> func_vec; + std::vector coef_vec = getCoefVector(); for (int n = 0; n < O.size(); n++) { Orbital out_n = O.applyOperTerm(n, inp); func_vec.push_back(out_n); } Orbital out = inp.paramCopy(); - mrcpp::cplxfunc::linear_combination(out, coef_vec, func_vec, -1.0); + mrcpp::linear_combination(out, coef_vec, func_vec, -1.0); return out; } @@ -262,17 +262,17 @@ Orbital RankZeroOperator::operator()(Orbital inp) { * NOT IMPLEMENTED */ Orbital RankZeroOperator::dagger(Orbital inp) { - if (inp.getNNodes(NUMBER::Total) == 0) return inp.paramCopy(); + if (not mrcpp::mpi::my_func(inp)) return inp.paramCopy(); RankZeroOperator &O = *this; - std::vector func_vec; - ComplexVector coef_vec = getCoefVector(); + std::vector> func_vec; + std::vector coef_vec = getCoefVector(); for (int n = 0; n < O.size(); n++) { Orbital out_n = O.daggerOperTerm(n, inp); func_vec.push_back(out_n); } Orbital out = inp.paramCopy(); - mrcpp::cplxfunc::linear_combination(out, coef_vec, func_vec, -1.0); + mrcpp::linear_combination(out, coef_vec, func_vec, -1.0); return out; } @@ -399,8 +399,15 @@ ComplexDouble RankZeroOperator::trace(OrbitalVector &Phi) { Timer t1; RankZeroOperator &O = *this; OrbitalVector OPhi = O(Phi); - ComplexVector eta = orbital::get_occupations(Phi).cast(); - ComplexVector phi_vec = orbital::dot(Phi, OPhi); + std::vector eta(Phi.size()); + std::vector phi_vec(Phi.size()); + auto phiOPhi = orbital::dot(Phi, OPhi); + ComplexDouble out = 0.0; + for (int i=0; i(); + ComplexVector eta = orbital::get_occupations(Phi).cast(); return eta.dot(x_vec + y_vec); } ComplexDouble RankZeroOperator::trace(const Nuclei &nucs) { Timer t1; RankZeroOperator &O = *this; - ComplexVector coef_vec = getCoefVector(); + std::vector coef_vec = getCoefVector(); ComplexDouble out = 0.0; for (int n = 0; n < O.size(); n++) out += coef_vec[n] * O.traceOperTerm(n, nucs); @@ -470,7 +477,7 @@ ComplexDouble RankZeroOperator::trace(const Nuclei &nucs) { */ Orbital RankZeroOperator::applyOperTerm(int n, Orbital inp) { if (n >= this->oper_exp.size()) MSG_ABORT("Invalid oper term"); - if (inp.getNNodes(NUMBER::Total) == 0) return inp.paramCopy(); + if (not mrcpp::mpi::my_func(inp)) return inp.paramCopy(); Orbital out = inp; for (auto O_nm : this->oper_exp[n]) { @@ -482,7 +489,7 @@ Orbital RankZeroOperator::applyOperTerm(int n, Orbital inp) { Orbital RankZeroOperator::daggerOperTerm(int n, Orbital inp) { if (n >= this->oper_exp.size()) MSG_ABORT("Invalid oper term"); - if (inp.getNNodes(NUMBER::Total) == 0) return inp.paramCopy(); + if (not mrcpp::mpi::my_func(inp)) return inp.paramCopy(); Orbital out = inp; for (int i = this->oper_exp[n].size() - 1; i >= 0; i--) { diff --git a/src/tensor/RankZeroOperator.h b/src/tensor/RankZeroOperator.h index 62fca176b..1403afbd8 100644 --- a/src/tensor/RankZeroOperator.h +++ b/src/tensor/RankZeroOperator.h @@ -122,7 +122,7 @@ class RankZeroOperator { Orbital applyOperTerm(int n, Orbital inp); Orbital daggerOperTerm(int n, Orbital inp); ComplexDouble traceOperTerm(int n, const Nuclei &nucs); - ComplexVector getCoefVector() const; + std::vector getCoefVector() const; }; inline RankZeroOperator operator*(ComplexDouble a, RankZeroOperator A) { diff --git a/src/utils/MolPlotter.h b/src/utils/MolPlotter.h index 15fcaec8b..481901221 100644 --- a/src/utils/MolPlotter.h +++ b/src/utils/MolPlotter.h @@ -39,15 +39,15 @@ class MolPlotter final : public mrcpp::Plotter<3> { : mrcpp::Plotter<3>(o) , molecule(&mol) {} - void linePlot(const std::array &npts, mrcpp::ComplexFunction &func, const std::string &fname) { + void linePlot(const std::array &npts, const mrcpp::CompFunction<3> &func, const std::string &fname) { if (func.hasReal()) linePlot(npts, func.real(), fname + "_re"); if (func.hasImag()) linePlot(npts, func.imag(), fname + "_im"); } - void surfPlot(const std::array &npts, mrcpp::ComplexFunction &func, const std::string &fname) { + void surfPlot(const std::array &npts, const mrcpp::CompFunction<3> &func, const std::string &fname) { if (func.hasReal()) surfPlot(npts, func.real(), fname + "_re"); if (func.hasImag()) surfPlot(npts, func.imag(), fname + "_im"); } - void cubePlot(const std::array &npts, mrcpp::ComplexFunction &func, const std::string &fname) { + void cubePlot(const std::array &npts, const mrcpp::CompFunction<3> &func, const std::string &fname) { if (func.hasReal()) cubePlot(npts, func.real(), fname + "_re"); if (func.hasImag()) cubePlot(npts, func.imag(), fname + "_im"); } diff --git a/src/utils/RRMaximizer.cpp b/src/utils/RRMaximizer.cpp index abcf73eb5..ba08b92e4 100644 --- a/src/utils/RRMaximizer.cpp +++ b/src/utils/RRMaximizer.cpp @@ -30,7 +30,6 @@ #include "utils/math_utils.h" #include "qmfunctions/Orbital.h" -#include "qmfunctions/OrbitalIterator.h" #include "qmfunctions/orbital_utils.h" #include "qmoperators/one_electron/PositionOperator.h" @@ -64,7 +63,7 @@ RRMaximizer::RRMaximizer(double prec, OrbitalVector &Phi) { r_x.clear(); R_x = orbital::calc_overlap_matrix(Phi, xPhi_Vec); for (int i = 0; i < Phi.size(); i++) { - if(!mrcpp::mpi::my_orb(i)) continue; + if(!mrcpp::mpi::my_func(i)) continue; xPhi_Vec[i].free(NUMBER::Total); } @@ -72,7 +71,7 @@ RRMaximizer::RRMaximizer(double prec, OrbitalVector &Phi) { r_y.clear(); R_y = orbital::calc_overlap_matrix(Phi, yPhi_Vec); for (int i = 0; i < Phi.size(); i++) { - if(!mrcpp::mpi::my_orb(i)) continue; + if(!mrcpp::mpi::my_func(i)) continue; yPhi_Vec[i].free(NUMBER::Total); } @@ -80,7 +79,7 @@ RRMaximizer::RRMaximizer(double prec, OrbitalVector &Phi) { r_z.clear(); R_z = orbital::calc_overlap_matrix(Phi, zPhi_Vec); for (int i = 0; i < Phi.size(); i++) { - if(!mrcpp::mpi::my_orb(i)) continue; + if(!mrcpp::mpi::my_func(i)) continue; zPhi_Vec[i].free(NUMBER::Total); } diff --git a/src/utils/print_utils.cpp b/src/utils/print_utils.cpp index ddcc7b3e9..e07108de0 100644 --- a/src/utils/print_utils.cpp +++ b/src/utils/print_utils.cpp @@ -243,9 +243,9 @@ void print_utils::matrix(int level, const std::string &txt, const DoubleMatrix & printout(level, o.str()); } -void print_utils::qmfunction(int level, const std::string &txt, const mrcpp::ComplexFunction &func, mrcpp::Timer &timer) { - auto nodes = func.getNNodes(NUMBER::Total); - auto memory = func.getSizeNodes(NUMBER::Total); +void print_utils::qmfunction(int level, const std::string &txt, const mrcpp::CompFunction<3> &func, mrcpp::Timer &timer) { + auto nodes = func.getNNodes(); + auto memory = func.getSizeNodes(); auto time = timer.elapsed(); mrcpp::print::tree(level, txt, nodes, memory, time); } diff --git a/src/utils/print_utils.h b/src/utils/print_utils.h index dd8046552..b2629121c 100644 --- a/src/utils/print_utils.h +++ b/src/utils/print_utils.h @@ -41,7 +41,7 @@ void coord(int level, const std::string &txt, const mrcpp::Coord<3> &val, int p void scalar(int level, const std::string &txt, double val, const std::string &unit = "", int p = -1, bool s = false); void vector(int level, const std::string &txt, const DoubleVector &val, int p = -1, bool s = false); void matrix(int level, const std::string &txt, const DoubleMatrix &val, int p = -1, bool s = false); -void qmfunction(int level, const std::string &txt, const mrcpp::ComplexFunction &func, mrcpp::Timer &t); +void qmfunction(int level, const std::string &txt, const mrcpp::CompFunction<3> &func, mrcpp::Timer &t); std::string dbl_to_str(double d, int p, bool sci); std::vector eigen_to_vector(const DoubleVector &inp, double thrs); std::vector eigen_to_vector(const DoubleMatrix &inpm, double thrs); diff --git a/tests/qmfunctions/density.cpp b/tests/qmfunctions/density.cpp index e15309a5f..c2d7b7e06 100644 --- a/tests/qmfunctions/density.cpp +++ b/tests/qmfunctions/density.cpp @@ -43,6 +43,9 @@ TEST_CASE("Density", "[density]") { OrbitalVector Phi; for (int i = 0; i < 5; i++) Phi.push_back(Orbital(SPIN::Alpha)); for (int i = 0; i < 2; i++) Phi.push_back(Orbital(SPIN::Beta)); + for (int i = 0; i < 7; i++) Phi[i].isreal = 0; + for (int i = 0; i < 7; i++) Phi[i].iscomplex = 1; + Phi.distribute(); HydrogenFunction s1(1, 0, 0); @@ -50,13 +53,13 @@ TEST_CASE("Density", "[density]") { HydrogenFunction px(2, 1, 0); HydrogenFunction py(2, 1, 1); HydrogenFunction pz(2, 1, 2); - if (mrcpp::mpi::my_orb(Phi[0])) mrcpp::cplxfunc::project(Phi[0], s1, NUMBER::Real, prec); - if (mrcpp::mpi::my_orb(Phi[1])) mrcpp::cplxfunc::project(Phi[1], s2, NUMBER::Real, prec); - if (mrcpp::mpi::my_orb(Phi[2])) mrcpp::cplxfunc::project(Phi[2], px, NUMBER::Imag, prec); - if (mrcpp::mpi::my_orb(Phi[3])) mrcpp::cplxfunc::project(Phi[3], py, NUMBER::Imag, prec); - if (mrcpp::mpi::my_orb(Phi[4])) mrcpp::cplxfunc::project(Phi[4], pz, NUMBER::Imag, prec); - if (mrcpp::mpi::my_orb(Phi[5])) mrcpp::cplxfunc::project(Phi[5], s1, NUMBER::Real, prec); - if (mrcpp::mpi::my_orb(Phi[6])) mrcpp::cplxfunc::project(Phi[6], s1, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], s1, prec); + if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], s2, prec); + if (mrcpp::mpi::my_func(Phi[2])) mrcpp::project(Phi[2], px, prec); + if (mrcpp::mpi::my_func(Phi[3])) mrcpp::project(Phi[3], py, prec); + if (mrcpp::mpi::my_func(Phi[4])) mrcpp::project(Phi[4], pz, prec); + if (mrcpp::mpi::my_func(Phi[5])) mrcpp::project(Phi[5], s1, prec); + if (mrcpp::mpi::my_func(Phi[6])) mrcpp::project(Phi[6], s1, prec); SECTION("non-shared memory total/spin density") { Density rho_t(false); diff --git a/tests/qmfunctions/orbital.cpp b/tests/qmfunctions/orbital.cpp index df36cdd1f..e843a7fd0 100644 --- a/tests/qmfunctions/orbital.cpp +++ b/tests/qmfunctions/orbital.cpp @@ -38,9 +38,10 @@ auto f = [](const mrcpp::Coord<3> &r) -> double { return std::exp(-1.0 * R * R); }; -auto g = [](const mrcpp::Coord<3> &r) -> double { +ComplexDouble i1 = {0.0, 1.0}; +auto g = [](const mrcpp::Coord<3> &r) -> ComplexDouble { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); - return std::exp(-2.0 * R * R); + return std::exp(-2.0 * R * R) * i1; }; TEST_CASE("Orbital", "[orbital]") { @@ -49,7 +50,7 @@ TEST_CASE("Orbital", "[orbital]") { SECTION("copy orbital") { Orbital phi_1(SPIN::Paired); - mrcpp::cplxfunc::project(phi_1, f, NUMBER::Real, prec); + mrcpp::project(phi_1, static_cast &r)>>(f), prec); SECTION("copy constructor") { Orbital phi_2(phi_1); @@ -57,7 +58,7 @@ TEST_CASE("Orbital", "[orbital]") { REQUIRE(phi_2.spin() == phi_1.spin()); REQUIRE(phi_2.norm() == phi_1.norm()); REQUIRE(&phi_2.real() == &phi_1.real()); - REQUIRE(&phi_2.imag() == &phi_1.imag()); + REQUIRE(&phi_2.complex() == &phi_1.complex()); } SECTION("default constructor plus assignment") { @@ -67,7 +68,7 @@ TEST_CASE("Orbital", "[orbital]") { REQUIRE(phi_2.spin() == phi_1.spin()); REQUIRE(phi_2.norm() == phi_1.norm()); REQUIRE(&phi_2.real() == &phi_1.real()); - REQUIRE(&phi_2.imag() == &phi_1.imag()); + REQUIRE(&phi_2.complex() == &phi_1.complex()); } SECTION("assigment constructor") { @@ -76,12 +77,12 @@ TEST_CASE("Orbital", "[orbital]") { REQUIRE(phi_2.spin() == phi_1.spin()); REQUIRE(phi_2.norm() == phi_1.norm()); REQUIRE(&phi_2.real() == &phi_1.real()); - REQUIRE(&phi_2.imag() == &phi_1.imag()); + REQUIRE(&phi_2.complex() == &phi_1.complex()); } SECTION("deep copy") { Orbital phi_2(SPIN::Alpha); - mrcpp::cplxfunc::deep_copy(phi_2, phi_1); + mrcpp::deep_copy(phi_2, phi_1); REQUIRE(phi_2.occ() != phi_1.occ()); REQUIRE(phi_2.spin() != phi_1.spin()); REQUIRE(phi_2.norm() == phi_1.norm()); @@ -103,8 +104,7 @@ TEST_CASE("Orbital", "[orbital]") { Orbital phi(SPIN::Paired); REQUIRE(phi.norm() == Approx(-1.0)); - mrcpp::cplxfunc::project(phi, f, NUMBER::Real, prec); - mrcpp::cplxfunc::project(phi, g, NUMBER::Imag, prec); + mrcpp::project(phi, g, prec); REQUIRE(phi.norm() > 1.0); orbital::normalize(phi); @@ -113,11 +113,11 @@ TEST_CASE("Orbital", "[orbital]") { SECTION("orthogonalize") { Orbital phi_1(SPIN::Alpha); - mrcpp::cplxfunc::project(phi_1, f, NUMBER::Real, prec); + mrcpp::project(phi_1, static_cast &r)>>(f), prec); WHEN("orbitals have different spins") { Orbital phi_2(SPIN::Beta); - mrcpp::cplxfunc::project(phi_2, g, NUMBER::Imag, prec); + mrcpp::project(phi_2, static_cast &r)>>(g), prec); THEN("their overlap is zero") { ComplexDouble S = orbital::dot(phi_1, phi_2); @@ -128,7 +128,7 @@ TEST_CASE("Orbital", "[orbital]") { WHEN("orbitals have the same spin") { Orbital phi_2(SPIN::Alpha); - mrcpp::cplxfunc::project(phi_2, g, NUMBER::Imag, prec); + mrcpp::project(phi_2, static_cast &r)>>(g), prec); THEN("their overlap is non-zero") { ComplexDouble S1 = orbital::dot(phi_1, phi_2); @@ -142,15 +142,15 @@ TEST_CASE("Orbital", "[orbital]") { } } - AND_THEN("they are orthogonalized") { - orbital::orthogonalize(prec, phi_2, phi_1); - - THEN("their overlap is zero") { - ComplexDouble S3 = orbital::dot(phi_1, phi_2); - REQUIRE(std::abs(S3.real()) < thrs); - REQUIRE(std::abs(S3.imag()) < thrs); - } - } + // AND_THEN("they are orthogonalized") { + // orbital::orthogonalize(prec, phi_2, phi_1); +// + // THEN("their overlap is zero") { + // ComplexDouble S3 = orbital::dot(phi_1, phi_2); + // REQUIRE(std::abs(S3.real()) < thrs); + // REQUIRE(std::abs(S3.imag()) < thrs); + // } + // } } } } diff --git a/tests/qmfunctions/orbital_vector.cpp b/tests/qmfunctions/orbital_vector.cpp index dd9ce18b2..f11578368 100644 --- a/tests/qmfunctions/orbital_vector.cpp +++ b/tests/qmfunctions/orbital_vector.cpp @@ -129,8 +129,8 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { Phi.push_back(Orbital(SPIN::Paired)); Phi.push_back(Orbital(SPIN::Alpha)); Phi.distribute(); - if (mrcpp::mpi::my_orb(Phi[0])) mrcpp::cplxfunc::project(Phi[0], f1, NUMBER::Real, prec); - if (mrcpp::mpi::my_orb(Phi[1])) mrcpp::cplxfunc::project(Phi[1], f2, NUMBER::Imag, prec); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], static_cast &r)>>(f1), prec); + if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], static_cast &r)>>(f2), prec); normalize(Phi); SECTION("copy constructor") { @@ -202,8 +202,8 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { REQUIRE(norms1[0] == Approx(-1.0)); REQUIRE(norms1[1] == Approx(-1.0)); - if (mrcpp::mpi::my_orb(Phi[0])) mrcpp::cplxfunc::project(Phi[0], f1, NUMBER::Real, prec); - if (mrcpp::mpi::my_orb(Phi[1])) mrcpp::cplxfunc::project(Phi[1], f2, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], static_cast &r)>>(f1), prec); + if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], static_cast &r)>>(f2), prec); DoubleVector norms2 = get_norms(Phi); REQUIRE(norms2[0] > 0.0); @@ -235,10 +235,10 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { Phi.push_back(Orbital(SPIN::Beta)); Phi.distribute(); - if (true or mrcpp::mpi::my_orb(Phi[0])) mrcpp::cplxfunc::project(Phi[0], f1, NUMBER::Real, prec); - if (true or mrcpp::mpi::my_orb(Phi[1])) mrcpp::cplxfunc::project(Phi[1], f2, NUMBER::Real, prec); - if (true or mrcpp::mpi::my_orb(Phi[2])) mrcpp::cplxfunc::project(Phi[2], f3, NUMBER::Real, prec); - if (true or mrcpp::mpi::my_orb(Phi[3])) mrcpp::cplxfunc::project(Phi[3], f4, NUMBER::Real, prec); + if (true or mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], static_cast &r)>>(f1), prec); + if (true or mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], static_cast &r)>>(f2), prec); + if (true or mrcpp::mpi::my_func(Phi[2])) mrcpp::project(Phi[2], static_cast &r)>>(f3), prec); + if (true or mrcpp::mpi::my_func(Phi[3])) mrcpp::project(Phi[3], static_cast &r)>>(f4), prec); // Complex phase rotation for (int n = 0; n < Phi.size(); n++) { @@ -290,8 +290,8 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { Psi.push_back(Orbital(SPIN::Beta)); Psi.distribute(); - if (mrcpp::mpi::my_orb(Psi[0])) mrcpp::cplxfunc::project(Psi[0], f5, NUMBER::Real, prec); - if (mrcpp::mpi::my_orb(Psi[1])) mrcpp::cplxfunc::project(Psi[1], f6, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Psi[0])) mrcpp::project(Psi[0], static_cast &r)>>(f5), prec); + if (mrcpp::mpi::my_func(Psi[1])) mrcpp::project(Psi[1], static_cast &r)>>(f6), prec); orthogonalize(prec, Phi); orthogonalize(prec, Psi, Phi); @@ -309,14 +309,14 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { Phi.push_back(Orbital(SPIN::Paired)); Phi.distribute(); - if (mrcpp::mpi::my_orb(Phi[0])) { - mrcpp::cplxfunc::project(Phi[0], f1, NUMBER::Real, prec); - mrcpp::cplxfunc::project(Phi[0], f2, NUMBER::Imag, prec); + if (mrcpp::mpi::my_func(Phi[0])) { + mrcpp::project(Phi[0], static_cast &r)>>(f1), prec); + mrcpp::project(Phi[0], static_cast &r)>>(f2), prec); } - if (mrcpp::mpi::my_orb(Phi[1])) { - mrcpp::cplxfunc::project(Phi[1], f3, NUMBER::Real, prec); - mrcpp::cplxfunc::project(Phi[1], f4, NUMBER::Imag, prec); + if (mrcpp::mpi::my_func(Phi[1])) { + mrcpp::project(Phi[1], static_cast &r)>>(f3), prec); + mrcpp::project(Phi[1], static_cast &r)>>(f4), prec); } orthogonalize(prec, Phi); diff --git a/tests/qmfunctions/qmfunction.cpp b/tests/qmfunctions/qmfunction.cpp index 361294d84..d701173b6 100644 --- a/tests/qmfunctions/qmfunction.cpp +++ b/tests/qmfunctions/qmfunction.cpp @@ -33,75 +33,77 @@ using MATHCONST::pi; namespace qmfunction_tests { -auto f = [](const mrcpp::Coord<3> &r) -> double { +ComplexDouble i1 = {0.0, 1.0}; + +auto f = [](const mrcpp::Coord<3> &r) -> ComplexDouble { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); return std::exp(-1.0 * R * R); }; -auto g = [](const mrcpp::Coord<3> &r) -> double { +auto g = [](const mrcpp::Coord<3> &r) -> ComplexDouble { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); - return std::exp(-2.0 * R * R); + return std::exp(-2.0 * R * R ) * i1; }; TEST_CASE("QMFunction", "[qmfunction]") { const double prec = 1.0e-3; SECTION("copy non-shared function") { - mrcpp::ComplexFunction func_1(false); - mrcpp::cplxfunc::project(func_1, f, NUMBER::Real, prec); + mrcpp::CompFunction func_1(false); + mrcpp::project(func_1, static_cast &r)>>(f), prec); SECTION("copy constructor") { - mrcpp::ComplexFunction func_2(func_1); + mrcpp::CompFunction func_2(func_1); REQUIRE(func_2.isShared() == func_1.isShared()); REQUIRE(func_2.norm() == Approx(func_1.norm())); REQUIRE(&func_2.real() == &func_1.real()); - REQUIRE(&func_2.imag() == &func_1.imag()); + REQUIRE(&func_2.complex() == &func_1.complex()); } SECTION("default constructor plus assignment") { - mrcpp::ComplexFunction func_2; + mrcpp::CompFunction func_2; func_2 = func_1; REQUIRE(func_2.isShared() == func_1.isShared()); REQUIRE(func_2.norm() == Approx(func_1.norm())); REQUIRE(&func_2.real() == &func_1.real()); - REQUIRE(&func_2.imag() == &func_1.imag()); + REQUIRE(&func_2.complex() == &func_1.complex()); } SECTION("assigment constructor") { - mrcpp::ComplexFunction func_2 = func_1; + mrcpp::CompFunction func_2 = func_1; REQUIRE(func_2.isShared() == func_1.isShared()); REQUIRE(func_2.norm() == Approx(func_1.norm())); REQUIRE(&func_2.real() == &func_1.real()); - REQUIRE(&func_2.imag() == &func_1.imag()); + REQUIRE(&func_2.complex() == &func_1.complex()); } SECTION("deep copy to non-shared") { - mrcpp::ComplexFunction func_2(false); - mrcpp::cplxfunc::deep_copy(func_2, func_1); + mrcpp::CompFunction func_2(false); + mrcpp::deep_copy(func_2, func_1); REQUIRE(not func_2.isShared()); REQUIRE(func_2.norm() == Approx(func_1.norm())); REQUIRE(&func_2.real() != &func_1.real()); - REQUIRE(&func_2.imag() == &func_1.imag()); + REQUIRE(&func_2.complex() == &func_1.complex()); } #ifdef MRCHEM_HAS_MPI SECTION("deep copy to shared") { - mrcpp::ComplexFunction func_2(true); - mrcpp::cplxfunc::deep_copy(func_2, func_1); + mrcpp::CompFunction func_2(true); + mrcpp::deep_copy(func_2, func_1); REQUIRE(func_2.norm() == Approx(func_1.norm())); REQUIRE(&func_2.real() != &func_1.real()); - REQUIRE(&func_2.imag() == &func_1.imag()); + REQUIRE(&func_2.complex() == &func_1.complex()); } #endif } #ifdef MRCHEM_HAS_MPI SECTION("copy shared function") { - mrcpp::ComplexFunction func_1(true); - mrcpp::cplxfunc::project(func_1, f, NUMBER::Real, prec); - mrcpp::cplxfunc::project(func_1, g, NUMBER::Imag, prec); + mrcpp::CompFunction func_1(true); + mrcpp::project(func_1, f, prec); + mrcpp::project(func_1, g, prec); SECTION("copy constructor") { - mrcpp::ComplexFunction func_2(func_1); + mrcpp::CompFunction func_2(func_1); REQUIRE(func_2.isShared() == func_1.isShared()); REQUIRE(func_2.norm() == Approx(func_1.norm())); REQUIRE(func_2.integrate().real() == Approx(func_1.integrate().real())); @@ -109,7 +111,7 @@ TEST_CASE("QMFunction", "[qmfunction]") { } SECTION("default constructor plus assignment") { - mrcpp::ComplexFunction func_2; + mrcpp::CompFunction func_2; func_2 = func_1; REQUIRE(func_2.isShared() == func_1.isShared()); REQUIRE(func_2.norm() == Approx(func_1.norm())); @@ -118,7 +120,7 @@ TEST_CASE("QMFunction", "[qmfunction]") { } SECTION("assigment constructor") { - mrcpp::ComplexFunction func_2 = func_1; + mrcpp::CompFunction func_2 = func_1; REQUIRE(func_2.isShared() == func_1.isShared()); REQUIRE(func_2.norm() == Approx(func_1.norm())); REQUIRE(func_2.integrate().real() == Approx(func_1.integrate().real())); @@ -126,8 +128,8 @@ TEST_CASE("QMFunction", "[qmfunction]") { } SECTION("deep copy to non-shared") { - mrcpp::ComplexFunction func_2(false); - mrcpp::cplxfunc::deep_copy(func_2, func_1); + mrcpp::CompFunction func_2(false); + mrcpp::deep_copy(func_2, func_1); REQUIRE(not func_2.isShared()); REQUIRE(func_2.norm() == Approx(func_1.norm())); REQUIRE(func_2.integrate().real() == Approx(func_1.integrate().real())); @@ -135,8 +137,8 @@ TEST_CASE("QMFunction", "[qmfunction]") { } SECTION("deep copy to shared") { - mrcpp::ComplexFunction func_2(true); - mrcpp::cplxfunc::deep_copy(func_2, func_1); + mrcpp::CompFunction func_2(true); + mrcpp::deep_copy(func_2, func_1); REQUIRE(func_2.isShared() == func_1.isShared()); REQUIRE(func_2.norm() == Approx(func_1.norm())); REQUIRE(func_2.integrate().real() == Approx(func_1.integrate().real())); @@ -146,25 +148,25 @@ TEST_CASE("QMFunction", "[qmfunction]") { #endif SECTION("rescale non-shared function") { - mrcpp::ComplexFunction func(false); - mrcpp::cplxfunc::project(func, f, NUMBER::Real, prec); - mrcpp::cplxfunc::project(func, g, NUMBER::Imag, prec); + mrcpp::CompFunction func(false); + mrcpp::project(func, f, prec); + mrcpp::project(func, g, prec); const double ref_norm = func.norm(); - const double f_int = func.real().integrate(); - const double g_int = func.imag().integrate(); + const ComplexDouble f_int = func.complex().integrate(); + const ComplexDouble g_int = func.complex().integrate(); SECTION("real scalar") { func.rescale(pi); REQUIRE(func.norm() == Approx(pi * ref_norm)); - REQUIRE(func.real().integrate() == Approx(pi * f_int)); - REQUIRE(func.imag().integrate() == Approx(pi * g_int)); + REQUIRE(std::real(func.complex().integrate()) == Approx(std::real(pi * f_int))); + REQUIRE(std::real(func.complex().integrate()) == Approx(std::real(pi * g_int))); } - SECTION("imaginary unit") { + SECTION("complexinary unit") { ComplexDouble i(0.0, 1.0); func.rescale(i); REQUIRE(func.norm() == Approx(ref_norm)); - REQUIRE(func.real().integrate() == Approx(-g_int)); - REQUIRE(func.imag().integrate() == Approx(f_int)); + REQUIRE(std::real(func.complex().integrate()) == Approx(std::real(-g_int))); + REQUIRE(std::real(func.complex().integrate()) == Approx(std::real(f_int))); } SECTION("unitary rotation") { double re = std::sin(0.5); @@ -172,75 +174,75 @@ TEST_CASE("QMFunction", "[qmfunction]") { ComplexDouble c(re, im); func.rescale(c); REQUIRE(func.norm() == Approx(ref_norm)); - REQUIRE(func.real().integrate() == Approx(re * f_int - im * g_int)); - REQUIRE(func.imag().integrate() == Approx(im * f_int + re * g_int)); + REQUIRE(std::real(func.complex().integrate()) == Approx(std::real(re * f_int - im * g_int))); + REQUIRE(std::real(func.complex().integrate()) == Approx(std::real(im * f_int + re * g_int))); } } #ifdef MRCHEM_HAS_MPI SECTION("rescale shared function") { - mrcpp::ComplexFunction func(true); - mrcpp::cplxfunc::project(func, g, NUMBER::Real, prec); - mrcpp::cplxfunc::project(func, f, NUMBER::Imag, prec); + mrcpp::CompFunction func(true); + mrcpp::project(func, g, prec); + mrcpp::project(func, f, prec); const double ref_norm = func.norm(); - const double f_int = func.real().integrate(); - const double g_int = func.imag().integrate(); + const ComplexDouble f_int = func.real().integrate(); + const ComplexDouble g_int = func.complex().integrate(); SECTION("real scalar") { func.rescale(pi); REQUIRE(func.norm() == Approx(pi * ref_norm)); - REQUIRE(func.real().integrate() == Approx(pi * f_int)); - REQUIRE(func.imag().integrate() == Approx(pi * g_int)); + REQUIRE(std::real(func.complex().integrate()) == Approx(std::real(pi * f_int))); + REQUIRE(std::real(func.complex().integrate()) == Approx(std::real(pi * g_int))); } - SECTION("imaginary unit") { + SECTION("complexinary unit") { ComplexDouble i(0.0, 1.0); func.rescale(i); mrcpp::mpi::barrier(mrcpp::mpi::comm_share); REQUIRE(func.norm() == Approx(ref_norm)); - REQUIRE(func.real().integrate() == Approx(-g_int)); - REQUIRE(func.imag().integrate() == Approx(f_int)); - } - SECTION("unitary rotation") { - double re = std::sin(0.5); - double im = std::cos(0.5); - ComplexDouble c(re, im); - func.rescale(c); - REQUIRE(func.norm() == Approx(ref_norm)); - REQUIRE(func.real().integrate() == Approx(re * f_int - im * g_int)); - REQUIRE(func.imag().integrate() == Approx(im * f_int + re * g_int)); + REQUIRE(std::real(func.complex().integrate()) == Approx(std::real(-g_int))); + REQUIRE(std::real(func.complex().integrate()) == Approx(std::real(f_int))); } + // SECTION("unitary rotation") { + // double re = std::sin(0.5); + // double im = std::cos(0.5); + // ComplexDouble c(re, im); + // func.rescale(c); + // REQUIRE(func.norm() == Approx(ref_norm)); + // REQUIRE(func.real().integrate() == Approx(re * f_int - im * g_int)); + // REQUIRE(func.complex().integrate() == Approx(im * f_int + re * g_int)); + // } } SECTION("add shared function") { - mrcpp::ComplexFunction f_re(false); - mrcpp::ComplexFunction f_im(true); - mrcpp::cplxfunc::project(f_re, f, NUMBER::Real, prec); - mrcpp::cplxfunc::project(f_im, f, NUMBER::Imag, prec); + mrcpp::CompFunction f_re(false); + mrcpp::CompFunction f_im(true); + mrcpp::project(f_re, f, prec); + mrcpp::project(f_im, f, prec); SECTION("into non-shared function") { ComplexDouble c(0.5, 0.5); - mrcpp::ComplexFunction func_h(false); + mrcpp::CompFunction func_h(false); SECTION("with complex scalar") { - mrcpp::cplxfunc::add(func_h, c, f_re, c, f_im, -1.0); + mrcpp::add(func_h, c, f_re, c, f_im, -1.0); REQUIRE(func_h.integrate().real() == Approx(0.0)); REQUIRE(func_h.integrate().imag() == Approx(f_im.integrate().imag())); } SECTION("with function conjugate") { - mrcpp::cplxfunc::add(func_h, c, f_re, c, f_im.dagger(), -1.0); + mrcpp::add(func_h, c, f_re, c, f_im.dagger(), -1.0); REQUIRE(func_h.integrate().real() == Approx(f_re.integrate().real())); REQUIRE(func_h.integrate().imag() == Approx(0.0)); } } SECTION("into shared function") { ComplexDouble c(0.5, 0.5); - mrcpp::ComplexFunction func_h(true); + mrcpp::CompFunction func_h(true); SECTION("with complex scalar") { - mrcpp::cplxfunc::add(func_h, c, f_re, c, f_im, -1.0); + mrcpp::add(func_h, c, f_re, c, f_im, -1.0); REQUIRE(func_h.integrate().real() == Approx(0.0)); REQUIRE(func_h.integrate().imag() == Approx(f_im.integrate().imag())); } SECTION("with function conjugate") { - mrcpp::cplxfunc::add(func_h, c, f_re, c, f_im.dagger(), -1.0); + mrcpp::add(func_h, c, f_re, c, f_im.dagger(), -1.0); REQUIRE(func_h.integrate().real() == Approx(f_re.integrate().real())); REQUIRE(func_h.integrate().imag() == Approx(0.0)); } @@ -249,20 +251,20 @@ TEST_CASE("QMFunction", "[qmfunction]") { #endif SECTION("multiply non-shared function") { - mrcpp::ComplexFunction func_1(false); - mrcpp::cplxfunc::project(func_1, f, NUMBER::Real, prec); - mrcpp::cplxfunc::project(func_1, g, NUMBER::Imag, prec); + mrcpp::CompFunction func_1(false); + mrcpp::project(func_1, f, prec); + mrcpp::project(func_1, g, prec); SECTION("into non-shared function") { - mrcpp::ComplexFunction func_2(false); - mrcpp::cplxfunc::multiply(func_2, func_1, func_1.dagger(), -1.0); + mrcpp::CompFunction func_2(false); + mrcpp::multiply(func_2, func_1, func_1.dagger(), -1.0); REQUIRE(func_2.integrate().real() == Approx(func_1.squaredNorm())); REQUIRE(func_2.integrate().imag() == Approx(0.0)); } #ifdef MRCHEM_HAS_MPI SECTION("into shared function") { - mrcpp::ComplexFunction func_2(true); - mrcpp::cplxfunc::multiply(func_2, func_1, func_1.dagger(), -1.0); + mrcpp::CompFunction func_2(true); + mrcpp::multiply(func_2, func_1, func_1.dagger(), -1.0); REQUIRE(func_2.integrate().real() == Approx(func_1.squaredNorm())); REQUIRE(func_2.integrate().imag() == Approx(0.0)); } @@ -271,19 +273,19 @@ TEST_CASE("QMFunction", "[qmfunction]") { #ifdef MRCHEM_HAS_MPI SECTION("multiply shared function") { - mrcpp::ComplexFunction func_1(true); - mrcpp::cplxfunc::project(func_1, f, NUMBER::Real, prec); - mrcpp::cplxfunc::project(func_1, g, NUMBER::Imag, prec); + mrcpp::CompFunction func_1(true); + mrcpp::project(func_1, f, prec); + mrcpp::project(func_1, g, prec); SECTION("into non-shared function") { - mrcpp::ComplexFunction func_2(false); - mrcpp::cplxfunc::multiply(func_2, func_1, func_1.dagger(), -1.0); + mrcpp::CompFunction func_2(false); + mrcpp::multiply(func_2, func_1, func_1.dagger(), -1.0); REQUIRE(func_2.integrate().real() == Approx(func_1.squaredNorm())); REQUIRE(func_2.integrate().imag() == Approx(0.0)); } SECTION("into shared function") { - mrcpp::ComplexFunction func_2(true); - mrcpp::cplxfunc::multiply(func_2, func_1, func_1.dagger(), -1.0); + mrcpp::CompFunction func_2(true); + mrcpp::multiply(func_2, func_1, func_1.dagger(), -1.0); REQUIRE(func_2.integrate().real() == Approx(func_1.squaredNorm())); REQUIRE(func_2.integrate().imag() == Approx(0.0)); } diff --git a/tests/qmoperators/coulomb_hessian.cpp b/tests/qmoperators/coulomb_hessian.cpp index fb802cacb..48bd33050 100644 --- a/tests/qmoperators/coulomb_hessian.cpp +++ b/tests/qmoperators/coulomb_hessian.cpp @@ -67,7 +67,7 @@ TEST_CASE("CoulombHessian", "[coulomb_hessian]") { for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } std::vector ns_x; @@ -89,7 +89,7 @@ TEST_CASE("CoulombHessian", "[coulomb_hessian]") { for (int i = 0; i < Phi_x.size(); i++) { HydrogenFunction f(ns_x[i], ls_x[i], ms_x[i]); - if (mrcpp::mpi::my_orb(Phi_x[i])) mrcpp::cplxfunc::project(Phi_x[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi_x[i])) mrcpp::project(Phi_x[i], f, prec); } int i = 0; @@ -103,8 +103,8 @@ TEST_CASE("CoulombHessian", "[coulomb_hessian]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(Phi[0], Vphi_0); - if (mrcpp::mpi::my_orb(Phi[0])) { + ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { @@ -115,8 +115,8 @@ TEST_CASE("CoulombHessian", "[coulomb_hessian]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(Phi[i], VPhi[i]); - if (mrcpp::mpi::my_orb(Phi[i])) { + ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); } else { @@ -127,7 +127,7 @@ TEST_CASE("CoulombHessian", "[coulomb_hessian]") { } SECTION("expectation value") { ComplexDouble V_00 = V(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { diff --git a/tests/qmoperators/coulomb_operator.cpp b/tests/qmoperators/coulomb_operator.cpp index bd72bbe35..9e20a8e49 100644 --- a/tests/qmoperators/coulomb_operator.cpp +++ b/tests/qmoperators/coulomb_operator.cpp @@ -69,7 +69,7 @@ TEST_CASE("CoulombOperator", "[coulomb_operator]") { for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } int i = 0; @@ -86,8 +86,8 @@ TEST_CASE("CoulombOperator", "[coulomb_operator]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(Phi[0], Vphi_0); - if (mrcpp::mpi::my_orb(Phi[0])) { + ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { @@ -98,8 +98,8 @@ TEST_CASE("CoulombOperator", "[coulomb_operator]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(Phi[i], VPhi[i]); - if (mrcpp::mpi::my_orb(Phi[i])) { + ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); } else { @@ -110,7 +110,7 @@ TEST_CASE("CoulombOperator", "[coulomb_operator]") { } SECTION("expectation value") { ComplexDouble V_00 = V(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { diff --git a/tests/qmoperators/electric_field_operator.cpp b/tests/qmoperators/electric_field_operator.cpp index 6e8642c88..f2e52c258 100644 --- a/tests/qmoperators/electric_field_operator.cpp +++ b/tests/qmoperators/electric_field_operator.cpp @@ -79,23 +79,23 @@ TEST_CASE("ElectricFieldOperator", "[electric_field_operator]") { for (int i = 0; i < nFuncs; i++) { HydrogenFunction f(std::get<0>(qn[i]), std::get<1>(qn[i]), std::get<2>(qn[i]), 1.0, o); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } SECTION("apply") { // update ref based on MPI for (int i = 0; i < nFuncs; i++) { for (int j = 0; j < nFuncs; j++) { - if (not(mrcpp::mpi::my_orb(Phi[i])) or not(mrcpp::mpi::my_orb(Phi[j]))) ref(i, j) = 0.0; + if (not(mrcpp::mpi::my_func(Phi[i])) or not(mrcpp::mpi::my_func(Phi[j]))) ref(i, j) = 0.0; } } Orbital phi_x = EF(Phi[0]); - ComplexDouble X_00 = orbital::dot(Phi[0], phi_x); - ComplexDouble X_10 = orbital::dot(Phi[1], phi_x); - ComplexDouble X_20 = orbital::dot(Phi[2], phi_x); - ComplexDouble X_30 = orbital::dot(Phi[3], phi_x); - ComplexDouble X_40 = orbital::dot(Phi[4], phi_x); + ComplexDouble X_00 = orbital::dot(static_cast(Phi[0]), phi_x); + ComplexDouble X_10 = orbital::dot(static_cast(Phi[1]), phi_x); + ComplexDouble X_20 = orbital::dot(static_cast(Phi[2]), phi_x); + ComplexDouble X_30 = orbital::dot(static_cast(Phi[3]), phi_x); + ComplexDouble X_40 = orbital::dot(static_cast(Phi[4]), phi_x); REQUIRE(X_00.real() == Approx(ref(0, 0)).margin(thrs)); REQUIRE(X_10.real() == Approx(ref(0, 1)).margin(thrs)); REQUIRE(X_20.real() == Approx(ref(0, 2)).margin(thrs)); @@ -107,7 +107,7 @@ TEST_CASE("ElectricFieldOperator", "[electric_field_operator]") { // update ref based on MPI for (int i = 0; i < nFuncs; i++) { for (int j = 0; j < nFuncs; j++) { - if (not(mrcpp::mpi::my_orb(Phi[i])) or not(mrcpp::mpi::my_orb(Phi[j]))) ref(i, j) = 0.0; + if (not(mrcpp::mpi::my_func(Phi[i])) or not(mrcpp::mpi::my_func(Phi[j]))) ref(i, j) = 0.0; } } @@ -121,7 +121,7 @@ TEST_CASE("ElectricFieldOperator", "[electric_field_operator]") { } SECTION("expectation value") { ComplexDouble X_00 = EF(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(X_00.real() == Approx(ref(0, 0))); } else { REQUIRE(X_00.real() == Approx(0.0).margin(thrs)); @@ -158,13 +158,13 @@ TEST_CASE("ElectricFieldEnergy", "[electric_field_energy]") { // Setting up the 1s orbital on H HydrogenFunction sh(1, 0, 0, 1.0, {1.0, 0.0, 0.0}); - Orbital &phi_h = Phi[0]; - if (mrcpp::mpi::my_orb(phi_h)) mrcpp::cplxfunc::project(phi_h, sh, NUMBER::Real, prec); + Orbital phi_h = Phi[0]; + if (mrcpp::mpi::my_func(phi_h)) mrcpp::project(phi_h, sh, prec); // Setting up the 1s orbital on Li HydrogenFunction sli(1, 0, 0, 3.0, {-1.0, 0.0, 0.0}); - Orbital &phi_li = Phi[1]; - if (mrcpp::mpi::my_orb(phi_li)) mrcpp::cplxfunc::project(phi_li, sli, NUMBER::Real, prec); + Orbital phi_li = Phi[1]; + if (mrcpp::mpi::my_func(phi_li)) mrcpp::project(phi_li, sli, prec); SECTION("energy in the external field") { double E_ext = EF.trace(Phi).real(); diff --git a/tests/qmoperators/exchange_hessian.cpp b/tests/qmoperators/exchange_hessian.cpp index 0b4e70af3..50df9caa6 100644 --- a/tests/qmoperators/exchange_hessian.cpp +++ b/tests/qmoperators/exchange_hessian.cpp @@ -72,7 +72,7 @@ TEST_CASE("ExchangeHessian", "[exchange_hessian]") { for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } std::vector ns_x; @@ -98,7 +98,7 @@ TEST_CASE("ExchangeHessian", "[exchange_hessian]") { for (int i = 0; i < Phi_x.size(); i++) { HydrogenFunction f(ns_x[i], ls_x[i], ms_x[i]); - if (mrcpp::mpi::my_orb(Phi_x[i])) mrcpp::cplxfunc::project(Phi_x[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi_x[i])) mrcpp::project(Phi_x[i], f, prec); } int i = 0; @@ -111,8 +111,8 @@ TEST_CASE("ExchangeHessian", "[exchange_hessian]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(Phi[0], Vphi_0); - if (mrcpp::mpi::my_orb(Phi[0])) { + ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { @@ -123,8 +123,8 @@ TEST_CASE("ExchangeHessian", "[exchange_hessian]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(Phi[i], VPhi[i]); - if (mrcpp::mpi::my_orb(Phi[i])) { + ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); } else { @@ -135,7 +135,7 @@ TEST_CASE("ExchangeHessian", "[exchange_hessian]") { } SECTION("expectation value") { ComplexDouble V_00 = V(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { diff --git a/tests/qmoperators/exchange_operator.cpp b/tests/qmoperators/exchange_operator.cpp index 47395fcd3..a1529dbc2 100644 --- a/tests/qmoperators/exchange_operator.cpp +++ b/tests/qmoperators/exchange_operator.cpp @@ -66,7 +66,7 @@ TEST_CASE("ExchangeOperator", "[exchange_operator]") { for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } int i = 0; @@ -81,8 +81,8 @@ TEST_CASE("ExchangeOperator", "[exchange_operator]") { SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(Phi[0], Vphi_0); - if (mrcpp::mpi::my_orb(Phi[0])) { + ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { @@ -93,8 +93,8 @@ TEST_CASE("ExchangeOperator", "[exchange_operator]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(Phi[i], VPhi[i]); - if (mrcpp::mpi::my_orb(Phi[i])) { + ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); } else { @@ -105,7 +105,7 @@ TEST_CASE("ExchangeOperator", "[exchange_operator]") { } SECTION("expectation value") { ComplexDouble V_00 = V(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { diff --git a/tests/qmoperators/identity_operator.cpp b/tests/qmoperators/identity_operator.cpp index 39fe01657..7fc9ceb82 100644 --- a/tests/qmoperators/identity_operator.cpp +++ b/tests/qmoperators/identity_operator.cpp @@ -52,8 +52,8 @@ TEST_CASE("IdentityOperator", "[identity_operator]") { SECTION("apply") { Orbital phi(SPIN::Paired); - mrcpp::cplxfunc::project(phi, f, NUMBER::Real, prec); - mrcpp::cplxfunc::project(phi, g, NUMBER::Imag, prec); + mrcpp::project(phi, static_cast &r)>>(f), prec); + mrcpp::project(phi, static_cast &r)>>(g), prec); IdentityOperator I; I.setup(prec); @@ -70,8 +70,8 @@ TEST_CASE("IdentityOperator", "[identity_operator]") { Phi.push_back(Orbital(SPIN::Paired)); Phi.distribute(); - if (mrcpp::mpi::my_orb(Phi[0])) mrcpp::cplxfunc::project(Phi[0], f, NUMBER::Real, prec); - if (mrcpp::mpi::my_orb(Phi[1])) mrcpp::cplxfunc::project(Phi[1], g, NUMBER::Imag, prec); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], static_cast &r)>>(f), prec); + if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], static_cast &r)>>(g), prec); normalize(Phi); IdentityOperator I; @@ -96,8 +96,8 @@ TEST_CASE("IdentityOperator", "[identity_operator]") { SECTION("expectation value") { Orbital phi(SPIN::Paired); - mrcpp::cplxfunc::project(phi, f, NUMBER::Real, prec); - mrcpp::cplxfunc::project(phi, g, NUMBER::Imag, prec); + mrcpp::project(phi, static_cast &r)>>(f), prec); + mrcpp::project(phi, static_cast &r)>>(g), prec); IdentityOperator I; I.setup(prec); @@ -114,8 +114,8 @@ TEST_CASE("IdentityOperator", "[identity_operator]") { Phi.push_back(Orbital(SPIN::Paired)); Phi.distribute(); - if (mrcpp::mpi::my_orb(Phi[0])) mrcpp::cplxfunc::project(Phi[0], f, NUMBER::Imag, prec); - if (mrcpp::mpi::my_orb(Phi[1])) mrcpp::cplxfunc::project(Phi[1], g, NUMBER::Imag, prec); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], static_cast &r)>>(f), prec); + if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], static_cast &r)>>(g), prec); IdentityOperator I; I.setup(prec); diff --git a/tests/qmoperators/kinetic_operator.cpp b/tests/qmoperators/kinetic_operator.cpp index ade98fdfe..c417af5e4 100644 --- a/tests/qmoperators/kinetic_operator.cpp +++ b/tests/qmoperators/kinetic_operator.cpp @@ -51,7 +51,7 @@ TEST_CASE("KineticOperator", "[kinetic_operator]") { for (int n = 0; n < nFuncs; n++) { int nu[3] = {n, 0, 0}; HarmonicOscillatorFunction f(nu); - if (mrcpp::mpi::my_orb(Phi[n])) mrcpp::cplxfunc::project(Phi[n], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[n])) mrcpp::project(Phi[n], f, prec); } // reference values for harmonic oscillator eigenfunctions @@ -71,8 +71,8 @@ TEST_CASE("KineticOperator", "[kinetic_operator]") { T.setup(prec); SECTION("apply") { Orbital Tphi_0 = T(Phi[0]); - ComplexDouble T_00 = orbital::dot(Phi[0], Tphi_0); - if (mrcpp::mpi::my_orb(Phi[0])) { + ComplexDouble T_00 = orbital::dot(static_cast(Phi[0]), Tphi_0); + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(T_00.real() == Approx(E_K(0))); REQUIRE(T_00.imag() < thrs); } else { @@ -85,7 +85,7 @@ TEST_CASE("KineticOperator", "[kinetic_operator]") { ComplexMatrix t = orbital::calc_overlap_matrix(Phi, TPhi); for (int i = 0; i < Phi.size(); i++) { ComplexDouble T_ii = orbital::dot(Phi[i], TPhi[i]); - if (mrcpp::mpi::my_orb(Phi[i])) { + if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(T_ii.real() == Approx(E_K(i))); REQUIRE(T_ii.imag() < thrs); } else { @@ -96,7 +96,7 @@ TEST_CASE("KineticOperator", "[kinetic_operator]") { } SECTION("expectation value") { ComplexDouble T_00 = T(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(T_00.real() == Approx(E_K(0))); REQUIRE(T_00.imag() < thrs); } else { diff --git a/tests/qmoperators/momentum_operator.cpp b/tests/qmoperators/momentum_operator.cpp index cff69edea..9c25f6a0c 100644 --- a/tests/qmoperators/momentum_operator.cpp +++ b/tests/qmoperators/momentum_operator.cpp @@ -51,7 +51,7 @@ TEST_CASE("MomentumOperator", "[momentum_operator]") { for (int n = 0; n < nFuncs; n++) { int nu[3] = {n, 0, 0}; HarmonicOscillatorFunction f(nu); - if (mrcpp::mpi::my_orb(Phi[n])) mrcpp::cplxfunc::project(Phi[n], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[n])) mrcpp::project(Phi[n], f, prec); } // reference values for harmonic oscillator eigenfunctions diff --git a/tests/qmoperators/nuclear_operator.cpp b/tests/qmoperators/nuclear_operator.cpp index ade3c25a3..86aae731c 100644 --- a/tests/qmoperators/nuclear_operator.cpp +++ b/tests/qmoperators/nuclear_operator.cpp @@ -66,7 +66,7 @@ TEST_CASE("PointNucleusHFYGB", "[nuclear_operator]") { for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } // reference values for hydrogen eigenfunctions @@ -90,8 +90,8 @@ TEST_CASE("PointNucleusHFYGB", "[nuclear_operator]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(Phi[0], Vphi_0); - if (mrcpp::mpi::my_orb(Phi[0])) { + ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), Vphi_0); + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0)).epsilon(prec)); REQUIRE(V_00.imag() < thrs); } else { @@ -102,8 +102,8 @@ TEST_CASE("PointNucleusHFYGB", "[nuclear_operator]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(Phi[i], VPhi[i]); - if (mrcpp::mpi::my_orb(Phi[i])) { + ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i)).epsilon(prec)); REQUIRE(V_ii.imag() < thrs); } else { @@ -114,7 +114,7 @@ TEST_CASE("PointNucleusHFYGB", "[nuclear_operator]") { } SECTION("expectation value") { ComplexDouble V_00 = V(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0)).epsilon(prec)); REQUIRE(V_00.imag() < thrs); } else { @@ -159,7 +159,7 @@ TEST_CASE("PointNucleusParabola", "[nuclear_operator]") { for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } // reference values for hydrogen eigenfunctions @@ -183,8 +183,8 @@ TEST_CASE("PointNucleusParabola", "[nuclear_operator]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(Phi[0], Vphi_0); - if (mrcpp::mpi::my_orb(Phi[0])) { + ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), Vphi_0); + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0)).epsilon(prec)); REQUIRE(V_00.imag() < thrs); } else { @@ -195,8 +195,8 @@ TEST_CASE("PointNucleusParabola", "[nuclear_operator]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(Phi[i], VPhi[i]); - if (mrcpp::mpi::my_orb(Phi[i])) { + ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i)).epsilon(prec)); REQUIRE(V_ii.imag() < thrs); } else { @@ -207,7 +207,7 @@ TEST_CASE("PointNucleusParabola", "[nuclear_operator]") { } SECTION("expectation value") { ComplexDouble V_00 = V(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0)).epsilon(prec)); REQUIRE(V_00.imag() < thrs); } else { @@ -252,7 +252,7 @@ TEST_CASE("PointNucleusMinimum", "[nuclear_operator]") { for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } // reference values for hydrogen eigenfunctions @@ -276,8 +276,8 @@ TEST_CASE("PointNucleusMinimum", "[nuclear_operator]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(Phi[0], Vphi_0); - if (mrcpp::mpi::my_orb(Phi[0])) { + ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), Vphi_0); + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0)).epsilon(prec)); REQUIRE(V_00.imag() < thrs); } else { @@ -288,8 +288,8 @@ TEST_CASE("PointNucleusMinimum", "[nuclear_operator]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(Phi[i], VPhi[i]); - if (mrcpp::mpi::my_orb(Phi[i])) { + ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i)).epsilon(prec)); REQUIRE(V_ii.imag() < thrs); } else { @@ -300,7 +300,7 @@ TEST_CASE("PointNucleusMinimum", "[nuclear_operator]") { } SECTION("expectation value") { ComplexDouble V_00 = V(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0)).epsilon(prec)); REQUIRE(V_00.imag() < thrs); } else { diff --git a/tests/qmoperators/operator_composition.cpp b/tests/qmoperators/operator_composition.cpp index 2b211df43..f62e75cd2 100644 --- a/tests/qmoperators/operator_composition.cpp +++ b/tests/qmoperators/operator_composition.cpp @@ -57,7 +57,7 @@ TEST_CASE("Operator composition", "[operator_composition]") { for (int i = 0; i < 3; i++) { int nu[3] = {i, 0, 0}; HarmonicOscillatorFunction f(nu); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } SECTION("identity operator") { @@ -495,7 +495,7 @@ TEST_CASE("Operator composition", "[operator_composition]") { REQUIRE(gradV[2].size(0) == 1); gradV.setup(prec); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { OrbitalVector dPhi_0 = gradV(Phi[0]); REQUIRE(dPhi_0.size() == 3); REQUIRE(dPhi_0[0].norm() == Approx(1.0).epsilon(thrs)); diff --git a/tests/qmoperators/position_operator.cpp b/tests/qmoperators/position_operator.cpp index 7d7ae4bae..e0b6fc9ed 100644 --- a/tests/qmoperators/position_operator.cpp +++ b/tests/qmoperators/position_operator.cpp @@ -49,7 +49,7 @@ TEST_CASE("PositionOperator", "[position_operator]") { for (int n = 0; n < nFuncs; n++) { int nu[3] = {n, 0, 0}; HarmonicOscillatorFunction f(nu); - if (mrcpp::mpi::my_orb(Phi[n])) mrcpp::cplxfunc::project(Phi[n], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[n])) mrcpp::project(Phi[n], f, prec); } // reference values for harmonic oscillator eigenfunctions diff --git a/tests/qmoperators/xc_hessian_lda.cpp b/tests/qmoperators/xc_hessian_lda.cpp index a1680583c..738648a1f 100644 --- a/tests/qmoperators/xc_hessian_lda.cpp +++ b/tests/qmoperators/xc_hessian_lda.cpp @@ -77,7 +77,7 @@ TEST_CASE("XCHessianLDA", "[xc_hessian_lda]") { for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } std::vector ns_x; @@ -99,7 +99,7 @@ TEST_CASE("XCHessianLDA", "[xc_hessian_lda]") { for (int i = 0; i < Phi_x.size(); i++) { HydrogenFunction f(ns_x[i], ls_x[i], ms_x[i]); - if (mrcpp::mpi::my_orb(Phi_x[i])) mrcpp::cplxfunc::project(Phi_x[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi_x[i])) mrcpp::project(Phi_x[i], f, prec); } int i = 0; @@ -113,8 +113,8 @@ TEST_CASE("XCHessianLDA", "[xc_hessian_lda]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(Phi[0], Vphi_0); - if (mrcpp::mpi::my_orb(Phi[0])) { + ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { @@ -125,8 +125,8 @@ TEST_CASE("XCHessianLDA", "[xc_hessian_lda]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(Phi[i], VPhi[i]); - if (mrcpp::mpi::my_orb(Phi[i])) { + ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); } else { @@ -137,7 +137,7 @@ TEST_CASE("XCHessianLDA", "[xc_hessian_lda]") { } SECTION("expectation value") { ComplexDouble V_00 = V(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { diff --git a/tests/qmoperators/xc_hessian_pbe.cpp b/tests/qmoperators/xc_hessian_pbe.cpp index 162e8ece1..343bcf1a5 100644 --- a/tests/qmoperators/xc_hessian_pbe.cpp +++ b/tests/qmoperators/xc_hessian_pbe.cpp @@ -76,7 +76,7 @@ TEST_CASE("XCHessianPBE", "[xc_hessian_pbe]") { for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } std::vector ns_x; @@ -97,7 +97,7 @@ TEST_CASE("XCHessianPBE", "[xc_hessian_pbe]") { for (int i = 0; i < Phi_x.size(); i++) { HydrogenFunction f(ns_x[i], ls_x[i], ms_x[i]); - if (mrcpp::mpi::my_orb(Phi_x[i])) mrcpp::cplxfunc::project(Phi_x[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi_x[i])) mrcpp::project(Phi_x[i], f, prec); } int i = 0; @@ -111,8 +111,8 @@ TEST_CASE("XCHessianPBE", "[xc_hessian_pbe]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(Phi[0], Vphi_0); - if (mrcpp::mpi::my_orb(Phi[0])) { + ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { @@ -123,8 +123,8 @@ TEST_CASE("XCHessianPBE", "[xc_hessian_pbe]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(Phi[i], VPhi[i]); - if (mrcpp::mpi::my_orb(Phi[i])) { + ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); } else { @@ -135,7 +135,7 @@ TEST_CASE("XCHessianPBE", "[xc_hessian_pbe]") { } SECTION("expectation value") { ComplexDouble V_00 = V(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { diff --git a/tests/qmoperators/xc_operator_blyp.cpp b/tests/qmoperators/xc_operator_blyp.cpp index 9095cd00a..e72ad271b 100644 --- a/tests/qmoperators/xc_operator_blyp.cpp +++ b/tests/qmoperators/xc_operator_blyp.cpp @@ -79,7 +79,7 @@ TEST_CASE("XCOperatorBLYP", "[xc_operator_blyp]") { for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } // reference values obtained with a test run at order=9 in unit_test.cpp and prec=1.0e-5 here @@ -96,8 +96,8 @@ TEST_CASE("XCOperatorBLYP", "[xc_operator_blyp]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(Phi[0], Vphi_0); - if (mrcpp::mpi::my_orb(Phi[0])) { + ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { @@ -108,8 +108,8 @@ TEST_CASE("XCOperatorBLYP", "[xc_operator_blyp]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(Phi[i], VPhi[i]); - if (mrcpp::mpi::my_orb(Phi[i])) { + ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); } else { @@ -120,7 +120,7 @@ TEST_CASE("XCOperatorBLYP", "[xc_operator_blyp]") { } SECTION("expectation value") { ComplexDouble V_00 = V(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { diff --git a/tests/qmoperators/xc_operator_lda.cpp b/tests/qmoperators/xc_operator_lda.cpp index fc873c178..a41f1b06a 100644 --- a/tests/qmoperators/xc_operator_lda.cpp +++ b/tests/qmoperators/xc_operator_lda.cpp @@ -79,7 +79,7 @@ TEST_CASE("[XCOperatorLDA]", "[xc_operator_lda]") { for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); - if (mrcpp::mpi::my_orb(Phi[i])) mrcpp::cplxfunc::project(Phi[i], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } // reference values obtained with a test run at order=9 in unit_test.cpp and prec=1.0e-5 here @@ -96,8 +96,8 @@ TEST_CASE("[XCOperatorLDA]", "[xc_operator_lda]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(Phi[0], Vphi_0); - if (mrcpp::mpi::my_orb(Phi[0])) { + ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { @@ -108,8 +108,8 @@ TEST_CASE("[XCOperatorLDA]", "[xc_operator_lda]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(Phi[i], VPhi[i]); - if (mrcpp::mpi::my_orb(Phi[i])) { + ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); } else { @@ -120,7 +120,7 @@ TEST_CASE("[XCOperatorLDA]", "[xc_operator_lda]") { } SECTION("expectation value") { ComplexDouble V_00 = V(Phi[0], Phi[0]); - if (mrcpp::mpi::my_orb(Phi[0])) { + if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); } else { diff --git a/tests/solventeffect/PB_solver.cpp b/tests/solventeffect/PB_solver.cpp index a53ab9fe5..ff9ba52e0 100644 --- a/tests/solventeffect/PB_solver.cpp +++ b/tests/solventeffect/PB_solver.cpp @@ -91,7 +91,7 @@ TEST_CASE("Poisson Boltzmann equation solver standard", "[PB_solver][pb_standard Phi.distribute(); HydrogenFunction f(1, 0, 0); - if (mrcpp::mpi::my_orb(Phi[0])) mrcpp::cplxfunc::project(Phi[0], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], f, prec); auto rho_nuc = chemistry::compute_nuclear_density(prec, molecule, 100); @@ -148,7 +148,7 @@ TEST_CASE("Poisson Boltzmann equation solver linearized", "[PB_solver][pb_linear Phi.distribute(); HydrogenFunction f(1, 0, 0); - if (mrcpp::mpi::my_orb(Phi[0])) mrcpp::cplxfunc::project(Phi[0], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], f, prec); auto rho_nuc = chemistry::compute_nuclear_density(prec, molecule, 100); diff --git a/tests/solventeffect/reaction_operator.cpp b/tests/solventeffect/reaction_operator.cpp index 323b579a0..b9a83647b 100644 --- a/tests/solventeffect/reaction_operator.cpp +++ b/tests/solventeffect/reaction_operator.cpp @@ -85,7 +85,7 @@ TEST_CASE("ReactionOperator", "[reaction_operator]") { // project analytic 1s orbital HydrogenFunction f(1, 0, 0); - if (mrcpp::mpi::my_orb(Phi[0])) mrcpp::cplxfunc::project(Phi[0], f, NUMBER::Real, prec); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], f, prec); auto rho_nuc = chemistry::compute_nuclear_density(prec, molecule, 100); diff --git a/tests/unit_tests.cpp b/tests/unit_tests.cpp index 840feafea..0e33fec09 100644 --- a/tests/unit_tests.cpp +++ b/tests/unit_tests.cpp @@ -80,7 +80,7 @@ void initialize_mra() { // Constructing global MRA mrchem::MRA = new mrcpp::MultiResolutionAnalysis<3>(world, basis, max_depth); - mrcpp::cplxfunc::SetdefaultMRA(mrchem::MRA); + mrcpp::SetdefaultMRA(mrchem::MRA); } void finalize_mra() { From ef25796dc428041022b0971bf54e89f86ac0d3ad Mon Sep 17 00:00:00 2001 From: gitpeterwind Date: Mon, 12 Aug 2024 09:22:29 +0200 Subject: [PATCH 2/8] compiles with Func methods instead of variable --- src/initial_guess/mw.cpp | 4 +- src/parallel.cpp | 546 ------------------------------ src/parallel.h | 113 ------- src/qmfunctions/Density.cpp | 16 +- src/qmfunctions/Orbital.cpp | 32 +- src/qmfunctions/Orbital.h | 12 +- src/qmfunctions/density_utils.cpp | 4 +- src/qmfunctions/orbital_utils.cpp | 36 +- src/qmoperators/QMPotential.cpp | 4 +- src/tensor/RankZeroOperator.cpp | 8 +- src/utils/NonlinearMaximizer.cpp | 1 + tests/qmfunctions/density.cpp | 2 - tests/qmfunctions/qmfunction.cpp | 87 ++--- 13 files changed, 105 insertions(+), 760 deletions(-) delete mode 100644 src/parallel.cpp delete mode 100644 src/parallel.h diff --git a/src/initial_guess/mw.cpp b/src/initial_guess/mw.cpp index c00b4fdea..2012511a3 100644 --- a/src/initial_guess/mw.cpp +++ b/src/initial_guess/mw.cpp @@ -114,12 +114,12 @@ bool initial_guess::mw::project_mo(OrbitalVector &Phi, double prec, const std::s MSG_ERROR("Guess orbital not found: " << orbname.str()); success &= false; } - if (phi_i.isreal) { + if (phi_i.isreal()) { // Refine to get accurate function values mrcpp::refine_grid(phi_i.real(), 1); mrcpp::project(prec, Phi[i].real(), phi_i.real()); } - if (phi_i.iscomplex) { + if (phi_i.iscomplex()) { // Refine to get accurate function values mrcpp::refine_grid(phi_i.imag(), 1); mrcpp::project(prec, Phi[i].complex(), phi_i.complex()); diff --git a/src/parallel.cpp b/src/parallel.cpp deleted file mode 100644 index 29b9cd369..000000000 --- a/src/parallel.cpp +++ /dev/null @@ -1,546 +0,0 @@ -/* - * MRChem, a numerical real-space code for molecular electronic structure - * calculations within the self-consistent field (SCF) approximations of quantum - * chemistry (Hartree-Fock and Density Functional Theory). - * Copyright (C) 2023 Stig Rune Jensen, Luca Frediani, Peter Wind and contributors. - * - * This file is part of MRChem. - * - * MRChem is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MRChem is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with MRChem. If not, see . - * - * For information on the complete list of contributors to MRChem, see: - * - */ - -#include -#include - -#include "parallel.h" -#include "qmfunctions/CompFunction.h" -#include "qmfunctions/Density.h" -#include "qmfunctions/Orbital.h" -#include "utils/Bank.h" - -#ifdef MRCHEM_HAS_OMP -#ifndef MRCPP_HAS_OMP -#include -#endif -#define mrchem_get_max_threads() omp_get_max_threads() -#define mrchem_get_num_threads() omp_get_num_threads() -#define mrchem_get_thread_num() omp_get_thread_num() -#define mrchem_set_dynamic(n) omp_set_dynamic(n) -#else -#define mrchem_get_max_threads() 1 -#define mrchem_get_num_threads() 1 -#define mrchem_get_thread_num() 0 -#define mrchem_set_dynamic(n) -#endif - -using mrcpp::Printer; - -namespace mrchem { - -namespace omp { - -int n_threads = mrchem_get_max_threads(); - -} // namespace omp - -using namespace Eigen; - -Bank dataBank; - -namespace mpi { - -bool numerically_exact = false; -int shared_memory_size = 1000; - -// these parameters set by initialize() -int world_size = 1; -int world_rank = 0; -int orb_size = 1; -int orb_rank = 0; -int share_size = 1; -int share_rank = 0; -int sh_group_rank = 0; -int is_bank = 0; -int is_centralbank = 0; -int is_bankclient = 1; -int is_bankmaster = 0; // only one bankmaster is_bankmaster -int bank_size = 0; -int tot_bank_size = 0; // size of bank, including the task manager -int max_tag = 0; // max value allowed by MPI -std::vector bankmaster; -int task_bank = -1; // world rank of the task manager - -MPI_Comm comm_orb; -MPI_Comm comm_share; -MPI_Comm comm_sh_group; -MPI_Comm comm_bank; - -} // namespace mpi - -int id_shift; // to ensure that nodes, orbitals and functions do not collide - -extern int metadata_block[3]; // can add more metadata in future -extern int const size_metadata = 3; - -void mpi::initialize() { - Eigen::setNbThreads(1); - mrchem_set_dynamic(0); - mrcpp::set_max_threads(omp::n_threads); - -#ifdef MRCHEM_HAS_MPI - MPI_Init(nullptr, nullptr); - MPI_Comm_size(MPI_COMM_WORLD, &mpi::world_size); - MPI_Comm_rank(MPI_COMM_WORLD, &mpi::world_rank); - - // divide the world into groups - // each group has its own group communicator definition - - // define independent group of MPI processes, that are not part of comm_orb - // for now the new group does not include comm_share - mpi::comm_bank = MPI_COMM_WORLD; // clients and master - MPI_Comm comm_remainder; // clients only - - // set bank_size automatically if not defined by user - if (mpi::world_size < 2) { - mpi::bank_size = 0; - } else if (mpi::bank_size < 0) { - mpi::bank_size = std::max(mpi::world_size / 3, 1); - } - if (mpi::world_size - mpi::bank_size < 1) MSG_ABORT("No MPI ranks left for working!"); - if (mpi::bank_size < 1 and mpi::world_size > 1) MSG_ABORT("Bank size must be at least one when using MPI!"); - - mpi::bankmaster.resize(mpi::bank_size); - for (int i = 0; i < mpi::bank_size; i++) { - mpi::bankmaster[i] = mpi::world_size - i - 1; // rank of the bankmasters - } - if (mpi::world_rank < mpi::world_size - mpi::bank_size) { - // everything which is left - mpi::is_bank = 0; - mpi::is_centralbank = 0; - mpi::is_bankclient = 1; - } else { - // special group of centralbankmasters - mpi::is_bank = 1; - mpi::is_centralbank = 1; - mpi::is_bankclient = 0; - if (mpi::world_rank == mpi::world_size - mpi::bank_size) mpi::is_bankmaster = 1; - } - MPI_Comm_split(MPI_COMM_WORLD, mpi::is_bankclient, mpi::world_rank, &comm_remainder); - - // split world into groups that can share memory - MPI_Comm_split_type(comm_remainder, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, &mpi::comm_share); - - MPI_Comm_rank(mpi::comm_share, &mpi::share_rank); - MPI_Comm_size(mpi::comm_share, &mpi::share_size); - - // define a rank of the group - MPI_Comm_split(comm_remainder, mpi::share_rank, mpi::world_rank, &mpi::comm_sh_group); - // mpiShRank is color (same color->in same group) - // MPI_worldrank is key (orders rank within the groups) - - // we define a new orbital rank, so that the orbitals within - // a shared memory group, have consecutive ranks - MPI_Comm_rank(mpi::comm_sh_group, &mpi::sh_group_rank); - - mpi::orb_rank = mpi::share_rank + mpi::sh_group_rank * mpi::world_size; - MPI_Comm_split(comm_remainder, 0, mpi::orb_rank, &mpi::comm_orb); - // 0 is color (same color->in same group) - // mpiOrbRank is key (orders rank in the group) - - MPI_Comm_rank(mpi::comm_orb, &mpi::orb_rank); - MPI_Comm_size(mpi::comm_orb, &mpi::orb_size); - - // if bank_size is large enough, we reserve one as "task manager" - mpi::tot_bank_size = mpi::bank_size; - if (mpi::bank_size <= 2 and mpi::bank_size > 0) { - // use the first bank as task manager - mpi::task_bank = mpi::bankmaster[0]; - } else if (mpi::bank_size > 1) { - // reserve one bank for task management only - mpi::bank_size--; - mpi::task_bank = mpi::bankmaster[mpi::bank_size]; // the last rank is reserved as task manager - } - - // determine the maximum value alowed for mpi tags - void *val; - int flag; - MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &val, &flag); // max value allowed by MPI for tags - max_tag = *(int *)val / 2; - id_shift = max_tag / 2; // half is reserved for non orbital. - - if (mpi::is_bank) { - // bank is open until end of program - if (mpi::is_centralbank) { dataBank.open(); } - mpi::finalize(); - exit(EXIT_SUCCESS); - } -#else - mpi::bank_size = 0; -#endif -} - -void mpi::finalize() { -#ifdef MRCHEM_HAS_MPI - if (mpi::bank_size > 0 and mpi::grand_master()) { - println(4, " max data in bank " << dataBank.get_maxtotalsize() << " MB "); - dataBank.close(); - } - MPI_Barrier(MPI_COMM_WORLD); // to ensure everybody got here - MPI_Finalize(); -#endif -} - -void mpi::barrier(MPI_Comm comm) { -#ifdef MRCHEM_HAS_MPI - MPI_Barrier(comm); -#endif -} - -/********************************* - * Orbital related MPI functions * - *********************************/ - -bool mpi::grand_master() { - return (mpi::world_rank == 0 and is_bankclient) ? true : false; -} - -bool mpi::share_master() { - return (mpi::share_rank == 0) ? true : false; -} - -/** @brief Test if orbital belongs to this MPI rank (or is common)*/ -bool mpi::my_func(const Orbital &orb) { - return (orb.rankID() < 0 or orb.rankID() == mpi::orb_rank) ? true : false; -} - -/** @brief Test if orbital belongs to this MPI rank */ -bool mpi::my_unique_orb(const Orbital &orb) { - return (orb.rankID() == mpi::orb_rank) ? true : false; -} - -/** @brief Distribute orbitals in vector round robin. Orbitals should be empty.*/ -void mpi::distribute(OrbitalVector &Phi) { - for (int i = 0; i < Phi.size(); i++) Phi[i].setRankID(i % mpi::orb_size); -} - -/** @brief Free all function pointers not belonging to this MPI rank */ -void mpi::free_foreign(OrbitalVector &Phi) { - for (auto &i : Phi) { - if (not mpi::my_func(i)) i.free(NUMBER::Total); - } -} - -/** @brief Return the subset of an OrbitalVector that belongs to this MPI rank */ -OrbitalChunk mpi::get_my_chunk(OrbitalVector &Phi) { - OrbitalChunk chunk; - for (int i = 0; i < Phi.size(); i++) { - if (mpi::my_func(Phi[i])) chunk.push_back(std::make_tuple(i, Phi[i])); - } - return chunk; -} - -/** @brief Add up each entry of the vector with contributions from all MPI ranks */ -void mpi::allreduce_vector(IntVector &vec, MPI_Comm comm) { -#ifdef MRCHEM_HAS_MPI - int N = vec.size(); - MPI_Allreduce(MPI_IN_PLACE, vec.data(), N, MPI_INT, MPI_SUM, comm); -#endif -} - -/** @brief Add up each entry of the vector with contributions from all MPI ranks */ -void mpi::allreduce_vector(DoubleVector &vec, MPI_Comm comm) { -#ifdef MRCHEM_HAS_MPI - int N = vec.size(); - MPI_Allreduce(MPI_IN_PLACE, vec.data(), N, MPI_DOUBLE, MPI_SUM, comm); -#endif -} - -/** @brief Add up each entry of the vector with contributions from all MPI ranks */ -void mpi::allreduce_vector(ComplexVector &vec, MPI_Comm comm) { -#ifdef MRCHEM_HAS_MPI - int N = vec.size(); - MPI_Allreduce(MPI_IN_PLACE, vec.data(), N, MPI_C_DOUBLE_COMPLEX, MPI_SUM, comm); -#endif -} - -/** @brief Add up each entry of the matrix with contributions from all MPI ranks */ -void mpi::allreduce_matrix(IntMatrix &mat, MPI_Comm comm) { -#ifdef MRCHEM_HAS_MPI - int N = mat.size(); - MPI_Allreduce(MPI_IN_PLACE, mat.data(), N, MPI_INT, MPI_SUM, comm); -#endif -} - -/** @brief Add up each entry of the matrix with contributions from all MPI ranks */ -void mpi::allreduce_matrix(DoubleMatrix &mat, MPI_Comm comm) { -#ifdef MRCHEM_HAS_MPI - int N = mat.size(); - MPI_Allreduce(MPI_IN_PLACE, mat.data(), N, MPI_DOUBLE, MPI_SUM, comm); -#endif -} - -/** @brief Add up each entry of the matrix with contributions from all MPI ranks */ -void mpi::allreduce_matrix(ComplexMatrix &mat, MPI_Comm comm) { -#ifdef MRCHEM_HAS_MPI - int N = mat.size(); - MPI_Allreduce(MPI_IN_PLACE, mat.data(), N, MPI_C_DOUBLE_COMPLEX, MPI_SUM, comm); -#endif -} - -// send an orbital with MPI, includes orbital meta data -void mpi::send_orbital(Orbital &orb, int dst, int tag, MPI_Comm comm) { -#ifdef MRCHEM_HAS_MPI - mpi::send_function(orb, dst, tag, comm); - OrbitalData &orbinfo = orb.getOrbitalData(); - MPI_Send(&orbinfo, sizeof(OrbitalData), MPI_BYTE, dst, 0, comm); -#endif -} - -// receive an orbital with MPI, includes orbital meta data -void mpi::recv_orbital(Orbital &orb, int src, int tag, MPI_Comm comm) { -#ifdef MRCHEM_HAS_MPI - mpi::recv_function(orb, src, tag, comm); - - MPI_Status status; - OrbitalData &orbinfo = orb.getOrbitalData(); - MPI_Recv(&orbinfo, sizeof(OrbitalData), MPI_BYTE, src, 0, comm, &status); -#endif -} - -// send a function with MPI -void mpi::send_function(QMFunction &func, int dst, int tag, MPI_Comm comm) { -#ifdef MRCHEM_HAS_MPI -#ifdef MRCPP_HAS_MPI - if (func.isShared()) MSG_WARN("Sending a shared function is not recommended"); - FunctionData &funcinfo = func.getFunctionData(); - MPI_Send(&funcinfo, sizeof(FunctionData), MPI_BYTE, dst, 0, comm); - if (func.hasReal()) mrcpp::send_tree(func.real(), dst, tag, comm, funcinfo.real_size); - if (func.hasImag()) mrcpp::send_tree(func.imag(), dst, tag + 10000, comm, funcinfo.imag_size); -#else - MSG_ABORT("MRCPP compiled without MPI support"); -#endif -#endif -} - -// receive a function with MPI -void mpi::recv_function(QMFunction &func, int src, int tag, MPI_Comm comm) { -#ifdef MRCHEM_HAS_MPI -#ifdef MRCPP_HAS_MPI - if (func.isShared()) MSG_WARN("Receiving a shared function is not recommended"); - MPI_Status status; - - FunctionData &funcinfo = func.getFunctionData(); - MPI_Recv(&funcinfo, sizeof(FunctionData), MPI_BYTE, src, 0, comm, &status); - if (funcinfo.real_size > 0) { - // We must have a tree defined for receiving nodes. Define one: - if (not func.hasReal()) func.alloc(NUMBER::Real); - mrcpp::recv_tree(func.real(), src, tag, comm, funcinfo.real_size); - } - - if (funcinfo.imag_size > 0) { - // We must have a tree defined for receiving nodes. Define one: - if (not func.hasImag()) func.alloc(NUMBER::Imag); - mrcpp::recv_tree(func.imag(), src, tag + 10000, comm, funcinfo.imag_size); - } -#else - MSG_ABORT("MRCPP compiled without MPI support"); -#endif -#endif -} - -/** Update a shared function after it has been changed by one of the MPI ranks. */ -void mpi::share_function(QMFunction &func, int src, int tag, MPI_Comm comm) { -#ifdef MRCHEM_HAS_MPI -#ifdef MRCPP_HAS_MPI - if (func.isShared()) { - if (func.hasReal()) mrcpp::share_tree(func.real(), src, tag, comm); - if (func.hasImag()) mrcpp::share_tree(func.imag(), src, 2 * tag, comm); - } -#else - MSG_ABORT("MRCPP compiled without MPI support"); -#endif -#endif -} - -/** @brief Add all mpi function into rank zero */ -void mpi::reduce_function(double prec, QMFunction &func, MPI_Comm comm) { -/* 1) Each odd rank send to the left rank - 2) All odd ranks are "deleted" (can exit routine) - 3) new "effective" ranks are defined within the non-deleted ranks - effective rank = rank/fac , where fac are powers of 2 - 4) repeat - */ -#ifdef MRCHEM_HAS_MPI - int comm_size, comm_rank; - MPI_Comm_rank(comm, &comm_rank); - MPI_Comm_size(comm, &comm_size); - if (comm_size == 1) return; - - int fac = 1; // powers of 2 - while (fac < comm_size) { - if ((comm_rank / fac) % 2 == 0) { - // receive - int src = comm_rank + fac; - if (src < comm_size) { - QMFunction func_i(false); - int tag = 3333 + src; - mpi::recv_function(func_i, src, tag, comm); - func.add(1.0, func_i); // add in place using union grid - func.crop(prec); - } - } - if ((comm_rank / fac) % 2 == 1) { - // send - int dest = comm_rank - fac; - if (dest >= 0) { - int tag = 3333 + comm_rank; - mpi::send_function(func, dest, tag, comm); - break; // once data is sent we are done - } - } - fac *= 2; - } - MPI_Barrier(comm); -#endif -} - -/** @brief make union tree and send into rank zero */ -void mpi::reduce_Tree_noCoeff(mrcpp::FunctionTree<3> &tree, MPI_Comm comm) { -/* 1) Each odd rank send to the left rank - 2) All odd ranks are "deleted" (can exit routine) - 3) new "effective" ranks are defined within the non-deleted ranks - effective rank = rank/fac , where fac are powers of 2 - 4) repeat - */ -#ifdef MRCHEM_HAS_MPI - int comm_size, comm_rank; - MPI_Comm_rank(comm, &comm_rank); - MPI_Comm_size(comm, &comm_size); - if (comm_size == 1) return; - - int fac = 1; // powers of 2 - while (fac < comm_size) { - if ((comm_rank / fac) % 2 == 0) { - // receive - int src = comm_rank + fac; - if (src < comm_size) { - int tag = 3333 + src; - mrcpp::FunctionTree<3> tree_i(*MRA); - mrcpp::recv_tree(tree_i, src, tag, comm, -1, false); - tree.appendTreeNoCoeff(tree_i); // make union grid - } - } - if ((comm_rank / fac) % 2 == 1) { - // send - int dest = comm_rank - fac; - if (dest >= 0) { - int tag = 3333 + comm_rank; - mrcpp::send_tree(tree, dest, tag, comm, -1, false); - break; // once data is sent we are done - } - } - fac *= 2; - } - MPI_Barrier(comm); -#endif -} - -/** @brief make union tree without coeff and send to all - * Include both real and imaginary parts - */ -void mpi::allreduce_Tree_noCoeff(mrcpp::FunctionTree<3> &tree, OrbitalVector &Phi, MPI_Comm comm) { - /* 1) make union grid of own orbitals - 2) make union grid with others orbitals (sent to rank zero) - 3) rank zero broadcast func to everybody - */ - int N = Phi.size(); - for (int j = 0; j < N; j++) { - if (not mpi::my_func(Phi[j])) continue; - if (Phi[j].hasReal()) tree.appendTreeNoCoeff(Phi[j].real()); - if (Phi[j].hasImag()) tree.appendTreeNoCoeff(Phi[j].imag()); - } -#ifdef MRCHEM_HAS_MPI - mpi::reduce_Tree_noCoeff(tree, mpi::comm_orb); - mpi::broadcast_Tree_noCoeff(tree, mpi::comm_orb); -#endif -} - -/** @brief Distribute rank zero function to all ranks */ -void mpi::broadcast_function(QMFunction &func, MPI_Comm comm) { -/* use same strategy as a reduce, but in reverse order */ -#ifdef MRCHEM_HAS_MPI - int comm_size, comm_rank; - MPI_Comm_rank(comm, &comm_rank); - MPI_Comm_size(comm, &comm_size); - if (comm_size == 1) return; - - int fac = 1; // powers of 2 - while (fac < comm_size) fac *= 2; - fac /= 2; - - while (fac > 0) { - if (comm_rank % fac == 0 and (comm_rank / fac) % 2 == 1) { - // receive - int src = comm_rank - fac; - int tag = 4334 + comm_rank; - mpi::recv_function(func, src, tag, comm); - } - if (comm_rank % fac == 0 and (comm_rank / fac) % 2 == 0) { - // send - int dst = comm_rank + fac; - int tag = 4334 + dst; - if (dst < comm_size) mpi::send_function(func, dst, tag, comm); - } - fac /= 2; - } - MPI_Barrier(comm); -#endif -} - -/** @brief Distribute rank zero function to all ranks */ -void mpi::broadcast_Tree_noCoeff(mrcpp::FunctionTree<3> &tree, MPI_Comm comm) { -/* use same strategy as a reduce, but in reverse order */ -#ifdef MRCHEM_HAS_MPI - int comm_size, comm_rank; - MPI_Comm_rank(comm, &comm_rank); - MPI_Comm_size(comm, &comm_size); - if (comm_size == 1) return; - - int fac = 1; // powers of 2 - while (fac < comm_size) fac *= 2; - fac /= 2; - - while (fac > 0) { - if (comm_rank % fac == 0 and (comm_rank / fac) % 2 == 1) { - // receive - int src = comm_rank - fac; - int tag = 4334 + comm_rank; - mrcpp::recv_tree(tree, src, tag, comm, -1, false); - } - if (comm_rank % fac == 0 and (comm_rank / fac) % 2 == 0) { - // send - int dst = comm_rank + fac; - int tag = 4334 + dst; - if (dst < comm_size) mrcpp::send_tree(tree, dst, tag, comm, -1, false); - } - fac /= 2; - } - MPI_Barrier(comm); -#endif -} - -} // namespace mrchem diff --git a/src/parallel.h b/src/parallel.h deleted file mode 100644 index 76dee6a05..000000000 --- a/src/parallel.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * MRChem, a numerical real-space code for molecular electronic structure - * calculations within the self-consistent field (SCF) approximations of quantum - * chemistry (Hartree-Fock and Density Functional Theory). - * Copyright (C) 2023 Stig Rune Jensen, Luca Frediani, Peter Wind and contributors. - * - * This file is part of MRChem. - * - * MRChem is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MRChem is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with MRChem. If not, see . - * - * For information on the complete list of contributors to MRChem, see: - * - */ - -#pragma once - -#include "MRCPP/Parallel" -#include - -#ifdef MRCHEM_HAS_MPI -#ifndef MRCPP_HAS_MPI -#include -#endif -#else -#ifndef MRCPP_HAS_MPI -using MPI_Comm = int; -#endif -#endif - -#include "mrchem.h" -#include "qmfunctions/qmfunction_fwd.h" - -namespace mrchem { - -namespace omp { -extern int n_threads; -} // namespace omp - -class Bank; -extern Bank dataBank; - -namespace mpi { - -extern bool numerically_exact; -extern int shared_memory_size; - -extern int world_rank; -extern int world_size; -extern int orb_rank; -extern int orb_size; -extern int share_rank; -extern int share_size; -extern int sh_group_rank; -extern int is_bank; -extern int is_bankclient; -extern int bank_size; -extern int tot_bank_size; -extern int max_tag; -extern std::vector bankmaster; -extern int task_bank; - -extern MPI_Comm comm_orb; -extern MPI_Comm comm_share; -extern MPI_Comm comm_sh_group; -extern MPI_Comm comm_bank; - -void initialize(); -void finalize(); -void barrier(MPI_Comm comm); - -bool grand_master(); -bool share_master(); -bool my_orb(const Orbital &orb); -bool my_unique_orb(const Orbital &orb); -void distribute(OrbitalVector &Phi); -void free_foreign(OrbitalVector &Phi); -OrbitalChunk get_my_chunk(OrbitalVector &Phi); - -void send_orbital(Orbital &orb, int dst, int tag, MPI_Comm comm = mpi::comm_orb); -void recv_orbital(Orbital &orb, int src, int tag, MPI_Comm comm = mpi::comm_orb); - -void send_function(QMFunction &func, int dst, int tag, MPI_Comm comm); -void recv_function(QMFunction &func, int src, int tag, MPI_Comm comm); -void share_function(QMFunction &func, int src, int tag, MPI_Comm comm); - -void reduce_function(double prec, QMFunction &func, MPI_Comm comm); -void broadcast_function(QMFunction &func, MPI_Comm comm); - -void reduce_Tree_noCoeff(mrcpp::FunctionTree<3> &tree, MPI_Comm comm); -void allreduce_Tree_noCoeff(mrcpp::FunctionTree<3> &tree, OrbitalVector &Phi, MPI_Comm comm); -void broadcast_Tree_noCoeff(mrcpp::FunctionTree<3> &tree, MPI_Comm comm); - -void allreduce_vector(IntVector &vec, MPI_Comm comm); -void allreduce_vector(DoubleVector &vec, MPI_Comm comm); -void allreduce_vector(ComplexVector &vec, MPI_Comm comm); -void allreduce_matrix(IntMatrix &vec, MPI_Comm comm); -void allreduce_matrix(DoubleMatrix &mat, MPI_Comm comm); -void allreduce_matrix(ComplexMatrix &mat, MPI_Comm comm); - -} // namespace mpi - -} // namespace mrchem diff --git a/src/qmfunctions/Density.cpp b/src/qmfunctions/Density.cpp index 990f75ba1..f00aa11b2 100644 --- a/src/qmfunctions/Density.cpp +++ b/src/qmfunctions/Density.cpp @@ -58,24 +58,24 @@ void Density::saveDensity(const std::string &file) { metafile << file << ".meta"; // this flushes tree sizes - mrcpp::CompFunctionData<3> &func_data = mrcpp::CompFunction<3>::data; + mrcpp::CompFunctionData<3> &func_data = mrcpp::CompFunction<3>::func_ptr->data; flushFuncData(); std::fstream f; f.open(metafile.str(), std::ios::out | std::ios::binary); if (not f.is_open()) MSG_ERROR("Unable to open file"); - f.write((char *)&func_data, sizeof(mrcpp::FunctionData)); + f.write((char *)&func_data, sizeof(mrcpp::CompFunctionData<3>)); f.close(); // writing real part - if (isreal) { + if (isreal()) { std::stringstream fname; fname << file << "_re"; CompD[0]->saveTree(fname.str()); } // writing imaginary part - if (iscomplex) { + if (iscomplex()) { std::stringstream fname; fname << file << "_cx"; CompC[0]->saveTree(fname.str()); @@ -99,16 +99,16 @@ void Density::loadDensity(const std::string &file) { fmeta << file << ".meta"; // this flushes tree sizes - mrcpp::CompFunctionData<3> &func_data = mrcpp::CompFunction<3>::data; + mrcpp::CompFunctionData<3> &func_data = mrcpp::CompFunction<3>::func_ptr->data; flushFuncData(); std::fstream f; f.open(fmeta.str(), std::ios::in | std::ios::binary); - if (f.is_open()) f.read((char *)&func_data, sizeof(mrcpp::FunctionData)); + if (f.is_open()) f.read((char *)&func_data, sizeof(mrcpp::CompFunctionData<3>)); f.close(); // reading real tree - if (isreal) { + if (isreal()) { std::stringstream fname; fname << file << "_re"; alloc(0); @@ -116,7 +116,7 @@ void Density::loadDensity(const std::string &file) { } // reading complex tree - if (iscomplex) { + if (iscomplex()) { std::stringstream fname; fname << file << "_cx"; alloc(0); diff --git a/src/qmfunctions/Orbital.cpp b/src/qmfunctions/Orbital.cpp index c513538d6..20f75ec9d 100644 --- a/src/qmfunctions/Orbital.cpp +++ b/src/qmfunctions/Orbital.cpp @@ -48,9 +48,9 @@ Orbital::Orbital(SPIN::type spin) : mrcpp::CompFunction<3>(spin) { if (this->spin() < 0) INVALID_ARG_ABORT; // n2 is used to store occupancy - if (this->spin() == SPIN::Paired) this->data.n2[0] = 2; - if (this->spin() == SPIN::Alpha) this->data.n2[0] = 1; - if (this->spin() == SPIN::Beta) this->data.n2[0] = 1; + if (this->spin() == SPIN::Paired) this->func_ptr->data.n2[0] = 2; + if (this->spin() == SPIN::Alpha) this->func_ptr->data.n2[0] = 1; + if (this->spin() == SPIN::Beta) this->func_ptr->data.n2[0] = 1; } /** @brief Constructor @@ -65,11 +65,11 @@ Orbital::Orbital(int spin, int occ, int rank) if (this->spin() < 0) INVALID_ARG_ABORT; if (this->occ() < 0) { // n2 is defined as occupancy - if (this->spin() == SPIN::Paired) this->data.n2[0] = 2; - if (this->spin() == SPIN::Alpha) this->data.n2[0] = 1; - if (this->spin() == SPIN::Beta) this->data.n2[0] = 1; + if (this->spin() == SPIN::Paired) this->func_ptr->data.n2[0] = 2; + if (this->spin() == SPIN::Alpha) this->func_ptr->data.n2[0] = 1; + if (this->spin() == SPIN::Beta) this->func_ptr->data.n2[0] = 1; } - this->rank = rank; + this->func_ptr->rank = rank; } @@ -78,7 +78,8 @@ Orbital::Orbital(int spin, int occ, int rank) * @param orb: orbital to copy * * Shallow copy: meta data is copied along with the pointers, - * NO transfer of ownership. + * NO transfer of ownership: + * both orbitals are pointing to the same tree */ Orbital::Orbital(Orbital &orb) : mrcpp::CompFunction<3>(orb) {} @@ -89,7 +90,8 @@ Orbital::Orbital(Orbital &orb) * @param orb: orbital to copy * * Shallow copy: meta data is copied along with the pointers, - * NO transfer of ownership. + * NO transfer of ownership: + * both orbitals are pointing to the same tree */ //Orbital::Orbital(const mrcpp::CompFunction<3> &orb) // : mrcpp::CompFunction<3>(orb) {} @@ -101,12 +103,12 @@ Orbital::Orbital(const mrcpp::CompFunction<3>& orb) * * Returns a new orbital which is a shallow copy of *this orbital, with a flipped * conjugate parameter. Pointer ownership is not transferred, so *this and the output - * orbital points to the same MW representations of the real and imaginary parts, + * orbital points to the same MW representations of the function tree, * however, they interpret the imaginary part with opposite sign. */ Orbital Orbital::dagger() const { Orbital out(*this); // Shallow copy - out.conj = not this->conjugate(); + out.func_ptr->conj = not this->conjugate(); return out; // Return shallow copy } @@ -119,8 +121,8 @@ Orbital Orbital::dagger() const { * and imaginary ("phi_0_im.tree") parts. */ void Orbital::saveOrbital(const std::string &file) { - if (isreal) CompD[0]->saveTree(file); - if (iscomplex) CompC[0]->saveTree(file); + if (isreal()) CompD[0]->saveTree(file); + if (iscomplex()) CompC[0]->saveTree(file); } /** @brief Read orbital from disk @@ -132,8 +134,8 @@ void Orbital::saveOrbital(const std::string &file) { * and imaginary ("phi_0_im.tree") parts. */ void Orbital::loadOrbital(const std::string &file) { - if (isreal) CompD[0]->loadTree(file); - if (iscomplex) CompC[0]->loadTree(file); + if (isreal()) CompD[0]->loadTree(file); + if (iscomplex()) CompC[0]->loadTree(file); } /** @brief Returns a character representing the spin (a/b/p) */ diff --git a/src/qmfunctions/Orbital.h b/src/qmfunctions/Orbital.h index de2ececef..88cef8640 100644 --- a/src/qmfunctions/Orbital.h +++ b/src/qmfunctions/Orbital.h @@ -49,8 +49,8 @@ namespace mrchem { -#define spin() data.n1[0] -#define occ() data.n2[0] +#define spin() func_ptr->data.n1[0] +#define occ() func_ptr->data.n2[0] class Orbital : public mrcpp::CompFunction<3> { public: Orbital(); @@ -60,10 +60,10 @@ class Orbital : public mrcpp::CompFunction<3> { Orbital(int spin, int occ, int rank = -1); Orbital dagger() const; - // const int spin() const {return data.n1[0];} - // const int occ() const {return data.n2[0];} + // const int spin() const {return data().n1[0];} + // const int occ() const {return data().n2[0];} char printSpin() const; - void setSpin(int spin) {this->data.n2[0] = spin;} + void setSpin(int spin) {this->func_ptr->data.n2[0] = spin;} void saveOrbital(const std::string &file); void loadOrbital(const std::string &file); }; @@ -72,7 +72,7 @@ class Orbital : public mrcpp::CompFunction<3> { class OrbitalVector : public mrcpp::CompFunctionVector { public: OrbitalVector(int N = 0) : mrcpp::CompFunctionVector(N) {} - void push_back(Orbital orb) { orb.rank = size(); this->push_back(orb);} + void push_back(Orbital orb) { orb.func_ptr->rank = size(); this->push_back(orb);} void distribute() {this->distribute();} // Overloaded operator[] to return an Orbital element // for read (returns lvalue) diff --git a/src/qmfunctions/density_utils.cpp b/src/qmfunctions/density_utils.cpp index 13368571c..60352966a 100644 --- a/src/qmfunctions/density_utils.cpp +++ b/src/qmfunctions/density_utils.cpp @@ -179,7 +179,7 @@ void density::compute_local_X(double prec, Density &rho, OrbitalVector &Phi, Orb double add_prec = prec / N_el; // prec for rho = sum_i rho_i if (Phi.size() != X.size()) MSG_ERROR("Size mismatch"); - if (rho.Ncomp == 0) rho.alloc(0); + if (rho.Ncomp() == 0) rho.alloc(0); // Compute local density from own orbitals rho.real().setZero(); @@ -205,7 +205,7 @@ void density::compute_local_XY(double prec, Density &rho, OrbitalVector &Phi, Or if (Phi.size() != X.size()) MSG_ERROR("Size mismatch"); if (Phi.size() != Y.size()) MSG_ERROR("Size mismatch"); - if (rho.Ncomp == 0) rho.alloc(0); + if (rho.Ncomp() == 0) rho.alloc(0); // Compute local density from own orbitals rho.real().setZero(); diff --git a/src/qmfunctions/orbital_utils.cpp b/src/qmfunctions/orbital_utils.cpp index 9b425e314..605f45927 100644 --- a/src/qmfunctions/orbital_utils.cpp +++ b/src/qmfunctions/orbital_utils.cpp @@ -90,8 +90,8 @@ ComplexDouble orbital::dot(Orbital bra, Orbital ket) { * */ ComplexDouble orbital::dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3>ket) { - if ((bra.data.n1[0] == SPIN::Alpha) and (ket.data.n1[0] == SPIN::Beta)) return 0.0; - if ((bra.data.n1[0] == SPIN::Beta) and (ket.data.n1[0] == SPIN::Alpha)) return 0.0; + if ((bra.data().n1[0] == SPIN::Alpha) and (ket.data().n1[0] == SPIN::Beta)) return 0.0; + if ((bra.data().n1[0] == SPIN::Beta) and (ket.data().n1[0] == SPIN::Alpha)) return 0.0; return mrcpp::dot(bra, ket); } @@ -340,7 +340,7 @@ OrbitalVector orbital::param_copy(const OrbitalVector &Phi) { OrbitalVector out; for (const auto &i : Phi) { Orbital out_i; - out_i.data = i.data; + out_i.func_ptr->data = i.func_ptr->data; out.push_back(out_i); } return out; @@ -1253,18 +1253,18 @@ void orbital::saveOrbital(const std::string &file, const Orbital &orb) { f.open(metafile.str(), std::ios::out | std::ios::binary); if (not f.is_open()) MSG_ERROR("Unable to open file"); mrcpp::CompFunctionData<3> orbdata = orb.getFuncData(); - f.write((char *)& orb.data, sizeof(mrcpp::CompFunctionData<3>)); + f.write((char *)& orb.func_ptr->data, sizeof(mrcpp::CompFunctionData<3>)); f.close(); // writing real part - if (orb.isreal) { + if (orb.isreal()) { std::stringstream fname; fname << file << "_real"; orb.CompD[0]->saveTree(fname.str()); } // writing complex tree - if (orb.iscomplex) { + if (orb.iscomplex()) { std::stringstream fname; fname << file << "_complex"; orb.CompC[0]->saveTree(fname.str()); @@ -1289,26 +1289,26 @@ void orbital::loadOrbital(const std::string &file, Orbital &orb) { std::fstream f; f.open(fmeta.str(), std::ios::in | std::ios::binary); - if (f.is_open()) f.read((char *)&orb.data, sizeof(mrcpp::CompFunctionData<3>)); + if (f.is_open()) f.read((char *)&orb.func_ptr->data, sizeof(mrcpp::CompFunctionData<3>)); f.close(); - std::array corner{orb.data.corner[0], orb.data.corner[1], orb.data.corner[2]}; - std::array boxes{orb.data.boxes[0], orb.data.boxes[1], orb.data.boxes[2]}; - mrcpp::BoundingBox<3> world(orb.data.scale, corner, boxes); + std::array corner{orb.data().corner[0], orb.data().corner[1], orb.data().corner[2]}; + std::array boxes{orb.data().boxes[0], orb.data().boxes[1], orb.data().boxes[2]}; + mrcpp::BoundingBox<3> world(orb.data().scale, corner, boxes); mrcpp::MultiResolutionAnalysis<3> *mra = nullptr; - if (orb.data.type == mrcpp::Interpol) { - mrcpp::InterpolatingBasis basis(orb.data.order); - mra = new mrcpp::MultiResolutionAnalysis<3>(world, basis, orb.data.depth); - } else if (orb.data.type == mrcpp::Legendre) { - mrcpp::LegendreBasis basis(orb.data.order); - mra = new mrcpp::MultiResolutionAnalysis<3>(world, basis, orb.data.depth); + if (orb.data().type == mrcpp::Interpol) { + mrcpp::InterpolatingBasis basis(orb.data().order); + mra = new mrcpp::MultiResolutionAnalysis<3>(world, basis, orb.data().depth); + } else if (orb.data().type == mrcpp::Legendre) { + mrcpp::LegendreBasis basis(orb.data().order); + mra = new mrcpp::MultiResolutionAnalysis<3>(world, basis, orb.data().depth); } else { MSG_ABORT("Invalid basis type!"); } // reading real part - if (orb.data.isreal) { + if (orb.isreal()) { std::stringstream fname; fname << file << "_real"; orb.alloc(0); @@ -1316,7 +1316,7 @@ void orbital::loadOrbital(const std::string &file, Orbital &orb) { } // reading imaginary part - if (orb.data.iscomplex) { + if (orb.iscomplex()) { std::stringstream fname; fname << file << "_complex"; orb.alloc(0); diff --git a/src/qmoperators/QMPotential.cpp b/src/qmoperators/QMPotential.cpp index 63c671830..365dd7e89 100644 --- a/src/qmoperators/QMPotential.cpp +++ b/src/qmoperators/QMPotential.cpp @@ -89,7 +89,7 @@ Orbital QMPotential::apply(Orbital inp) { Orbital QMPotential::dagger(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); - Orbital out(inp.data); + Orbital out(inp.data()); calc(out, inp, true); return out; } @@ -131,7 +131,7 @@ void QMPotential::calc(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> &inp, int adap = this->adap_build; double prec = this->apply_prec; - if (out.Ncomp > 0) MSG_ABORT("Output not empty"); + if (out.Ncomp() > 0) MSG_ABORT("Output not empty"); if (out.isShared()) MSG_ABORT("Cannot share this function"); if (dagger) MSG_ERROR("Not implemented"); if (inp.conjugate()) MSG_ERROR("Not implemented"); diff --git a/src/tensor/RankZeroOperator.cpp b/src/tensor/RankZeroOperator.cpp index beb06fb5f..c204e208e 100644 --- a/src/tensor/RankZeroOperator.cpp +++ b/src/tensor/RankZeroOperator.cpp @@ -241,7 +241,7 @@ ComplexDouble RankZeroOperator::dagger(const mrcpp::Coord<3> &r) const { * is added upp with the corresponding coefficient. */ Orbital RankZeroOperator::operator()(Orbital inp) { - if (not mrcpp::mpi::my_func(inp)) return inp.paramCopy(); + if (inp.getNNodes() == 0) return inp.paramCopy(); RankZeroOperator &O = *this; std::vector> func_vec; @@ -262,7 +262,7 @@ Orbital RankZeroOperator::operator()(Orbital inp) { * NOT IMPLEMENTED */ Orbital RankZeroOperator::dagger(Orbital inp) { - if (not mrcpp::mpi::my_func(inp)) return inp.paramCopy(); + if (inp.getNNodes() == 0) return inp.paramCopy(); RankZeroOperator &O = *this; std::vector> func_vec; @@ -477,7 +477,7 @@ ComplexDouble RankZeroOperator::trace(const Nuclei &nucs) { */ Orbital RankZeroOperator::applyOperTerm(int n, Orbital inp) { if (n >= this->oper_exp.size()) MSG_ABORT("Invalid oper term"); - if (not mrcpp::mpi::my_func(inp)) return inp.paramCopy(); + if (inp.getNNodes() == 0) return inp.paramCopy(); Orbital out = inp; for (auto O_nm : this->oper_exp[n]) { @@ -489,7 +489,7 @@ Orbital RankZeroOperator::applyOperTerm(int n, Orbital inp) { Orbital RankZeroOperator::daggerOperTerm(int n, Orbital inp) { if (n >= this->oper_exp.size()) MSG_ABORT("Invalid oper term"); - if (not mrcpp::mpi::my_func(inp)) return inp.paramCopy(); + if (inp.getNNodes() == 0) return inp.paramCopy(); Orbital out = inp; for (int i = this->oper_exp[n].size() - 1; i >= 0; i--) { diff --git a/src/utils/NonlinearMaximizer.cpp b/src/utils/NonlinearMaximizer.cpp index ae3c65533..cc7bfb0e4 100644 --- a/src/utils/NonlinearMaximizer.cpp +++ b/src/utils/NonlinearMaximizer.cpp @@ -26,6 +26,7 @@ #include #include "MRCPP/Printer" +#include "MRCPP/Parallel" #include #include "utils/NonlinearMaximizer.h" diff --git a/tests/qmfunctions/density.cpp b/tests/qmfunctions/density.cpp index c2d7b7e06..780bc4051 100644 --- a/tests/qmfunctions/density.cpp +++ b/tests/qmfunctions/density.cpp @@ -43,8 +43,6 @@ TEST_CASE("Density", "[density]") { OrbitalVector Phi; for (int i = 0; i < 5; i++) Phi.push_back(Orbital(SPIN::Alpha)); for (int i = 0; i < 2; i++) Phi.push_back(Orbital(SPIN::Beta)); - for (int i = 0; i < 7; i++) Phi[i].isreal = 0; - for (int i = 0; i < 7; i++) Phi[i].iscomplex = 1; Phi.distribute(); diff --git a/tests/qmfunctions/qmfunction.cpp b/tests/qmfunctions/qmfunction.cpp index d701173b6..44e8cefcb 100644 --- a/tests/qmfunctions/qmfunction.cpp +++ b/tests/qmfunctions/qmfunction.cpp @@ -49,15 +49,19 @@ TEST_CASE("QMFunction", "[qmfunction]") { const double prec = 1.0e-3; SECTION("copy non-shared function") { - mrcpp::CompFunction func_1(false); - mrcpp::project(func_1, static_cast &r)>>(f), prec); - + mrcpp::CompFunction func_1; + std::cout<<" project "< Date: Wed, 14 Aug 2024 15:25:53 +0200 Subject: [PATCH 3/8] qmfunction tests passes --- src/qmfunctions/Density.h | 2 +- src/qmfunctions/Orbital.h | 11 +++- src/qmfunctions/density_utils.cpp | 27 +-------- src/qmfunctions/orbital_utils.cpp | 1 - .../two_electron/ExchangePotential.cpp | 40 +++++++------ tests/qmfunctions/density.cpp | 2 - tests/qmfunctions/orbital.cpp | 58 +++++++++---------- tests/qmfunctions/orbital_vector.cpp | 24 +++----- tests/qmfunctions/qmfunction.cpp | 53 +++++++++-------- 9 files changed, 96 insertions(+), 122 deletions(-) diff --git a/src/qmfunctions/Density.h b/src/qmfunctions/Density.h index f5ffbca80..c1bb26607 100644 --- a/src/qmfunctions/Density.h +++ b/src/qmfunctions/Density.h @@ -50,7 +50,7 @@ namespace mrchem { class Density final : public mrcpp::CompFunction<3> { public: - explicit Density(bool share) + explicit Density(bool share = false) : mrcpp::CompFunction<3>(0, share) {} Density(const Density &dens) : mrcpp::CompFunction<3>(dens) {} diff --git a/src/qmfunctions/Orbital.h b/src/qmfunctions/Orbital.h index 88cef8640..7815ab881 100644 --- a/src/qmfunctions/Orbital.h +++ b/src/qmfunctions/Orbital.h @@ -49,6 +49,7 @@ namespace mrchem { +// Note: cannot only define "getSpin()", because sometime we only have a CompFunction, not an Orbital #define spin() func_ptr->data.n1[0] #define occ() func_ptr->data.n2[0] class Orbital : public mrcpp::CompFunction<3> { @@ -63,7 +64,7 @@ class Orbital : public mrcpp::CompFunction<3> { // const int spin() const {return data().n1[0];} // const int occ() const {return data().n2[0];} char printSpin() const; - void setSpin(int spin) {this->func_ptr->data.n2[0] = spin;} + void setSpin(int spin) {this->func_ptr->data.n1[0] = spin;} void saveOrbital(const std::string &file); void loadOrbital(const std::string &file); }; @@ -72,8 +73,12 @@ class Orbital : public mrcpp::CompFunction<3> { class OrbitalVector : public mrcpp::CompFunctionVector { public: OrbitalVector(int N = 0) : mrcpp::CompFunctionVector(N) {} - void push_back(Orbital orb) { orb.func_ptr->rank = size(); this->push_back(orb);} - void distribute() {this->distribute();} + void push_back(Orbital orb) { + mrcpp::CompFunction<3>& compfunc = orb; + compfunc.func_ptr->rank = size(); + mrcpp::CompFunctionVector* compfuncvec = this; + compfuncvec->push_back(compfunc); // we must push in the vector, not into the OrbitalVector! + } // Overloaded operator[] to return an Orbital element // for read (returns lvalue) Orbital operator[](int i) const { diff --git a/src/qmfunctions/density_utils.cpp b/src/qmfunctions/density_utils.cpp index 60352966a..70592ec06 100644 --- a/src/qmfunctions/density_utils.cpp +++ b/src/qmfunctions/density_utils.cpp @@ -80,28 +80,7 @@ Density density::compute(double prec, Orbital phi, DensityType spin) { if (std::abs(occ) < mrcpp::MachineZero) return Density(false); Density rho(false); - FunctionTreeVector<3> sum_vec; - if (phi.hasReal()) { - auto *real_2 = new FunctionTree<3>(*MRA); - mrcpp::copy_grid(*real_2, phi.real()); - mrcpp::square(prec, *real_2, phi.real()); - sum_vec.push_back(std::make_tuple(occ, real_2)); - } - if (phi.hasImag()) { - auto *imag_2 = new FunctionTree<3>(*MRA); - mrcpp::copy_grid(*imag_2, phi.imag()); - mrcpp::square(prec, *imag_2, phi.imag()); - sum_vec.push_back(std::make_tuple(occ, imag_2)); - } - - rho.alloc(NUMBER::Real); - if (sum_vec.size() > 0) { - mrcpp::build_grid(rho.real(), sum_vec); - mrcpp::add(-1.0, rho.real(), sum_vec, 0); - mrcpp::clear(sum_vec, true); - } else { - rho.real().setZero(); - } + mrcpp::multiply(-1.0, rho, occ, phi, phi, false, false, true); // the last "true" means use complex conjugate of the first phi return rho; } @@ -149,10 +128,6 @@ void density::compute(double prec, Density &rho, OrbitalVector &Phi, OrbitalVect void density::compute_local(double prec, Density &rho, OrbitalVector &Phi, DensityType spin) { int N_el = orbital::get_electron_number(Phi); double abs_prec = (mrcpp::mpi::numerically_exact) ? -1.0 : prec / N_el; - if (not rho.hasReal()) rho.alloc(NUMBER::Real); - - if (rho.hasReal()) rho.real().setZero(); - if (rho.hasImag()) rho.imag().setZero(); for (auto &phi_i : Phi) { if (mrcpp::mpi::my_func(phi_i)) { diff --git a/src/qmfunctions/orbital_utils.cpp b/src/qmfunctions/orbital_utils.cpp index 605f45927..dda9849b0 100644 --- a/src/qmfunctions/orbital_utils.cpp +++ b/src/qmfunctions/orbital_utils.cpp @@ -266,7 +266,6 @@ OrbitalVector orbital::rotate(OrbitalVector &Phi, const ComplexMatrix &U, double // The principle of this routine is that nodes are rotated one by one using matrix multiplication. // The routine does avoid when possible to move data, but uses pointers and indices manipulation. // MPI version does not use OMP yet, Serial version uses OMP - OrbitalVector Psi = orbital::deep_copy(Phi); mrcpp::rotate(Psi, U, prec); return Psi; diff --git a/src/qmoperators/two_electron/ExchangePotential.cpp b/src/qmoperators/two_electron/ExchangePotential.cpp index e53c3d6e0..727c5f179 100644 --- a/src/qmoperators/two_electron/ExchangePotential.cpp +++ b/src/qmoperators/two_electron/ExchangePotential.cpp @@ -171,7 +171,7 @@ void ExchangePotential::calcExchange_kij(double prec, Orbital phi_k, Orbital phi // the result is expected to be negligible Timer timer_ij; Orbital rho_ij = phi_i.paramCopy(); - mrcpp::multiply(rho_ij, phi_i.dagger(), phi_j, prec_m1, true, true); + mrcpp::multiply(rho_ij, phi_i, phi_j, prec_m1, true, true, true); timer_ij.stop(); if (rho_ij.norm() < prec) return; @@ -179,28 +179,30 @@ void ExchangePotential::calcExchange_kij(double prec, Orbital phi_k, Orbital phi auto N_j = phi_j.getNNodes(); auto N_ij = rho_ij.getNNodes(); auto norm_ij = rho_ij.norm(); + // For now we assume all phi are complex or all ar real. - // prepare vector used to steer precision of Poisson application - mrcpp::FunctionTreeVector<3> phi_opt_vec; - if (phi_k.hasReal()) phi_opt_vec.push_back(std::make_tuple(1.0, &phi_k.real())); - if (phi_k.hasImag()) phi_opt_vec.push_back(std::make_tuple(1.0, &phi_k.imag())); - - if (phi_j.hasReal() and &phi_j != &phi_k) phi_opt_vec.push_back(std::make_tuple(1.0, &phi_j.real())); - if (phi_j.hasImag() and &phi_j != &phi_k) phi_opt_vec.push_back(std::make_tuple(1.0, &phi_j.imag())); - - if (phi_i.hasReal() and &phi_i != &phi_k and &phi_i != &phi_j) phi_opt_vec.push_back(std::make_tuple(1.0, &phi_i.real())); - if (phi_i.hasImag() and &phi_i != &phi_k and &phi_i != &phi_j) phi_opt_vec.push_back(std::make_tuple(1.0, &phi_i.imag())); + bool RealOrbitals = phi_i.isreal(); + // prepare vector used to steer precision of Poisson application + mrcpp::FunctionTreeVector<3, double> phi_opt_vec_real; + mrcpp::FunctionTreeVector<3, ComplexDouble> phi_opt_vec_cplx; + if (RealOrbitals) { + if (phi_k.isreal()) phi_opt_vec_real.push_back(std::make_tuple(1.0, phi_k.CompD[0])); + if (phi_j.isreal() and &phi_j != &phi_k) phi_opt_vec_real.push_back(std::make_tuple(1.0, phi_j.CompD[0])); + if (phi_i.isreal() and &phi_i != &phi_k and &phi_i != &phi_j) phi_opt_vec_real.push_back(std::make_tuple(1.0, phi_i.CompD[0])); + } else { + if (phi_k.iscomplex()) phi_opt_vec_cplx.push_back(std::make_tuple(1.0, phi_k.CompC[0])); + if (phi_j.iscomplex() and &phi_j != &phi_k) phi_opt_vec_cplx.push_back(std::make_tuple(1.0, phi_j.CompC[0])); + if (phi_i.iscomplex() and &phi_i != &phi_k and &phi_i != &phi_j) phi_opt_vec_cplx.push_back(std::make_tuple(1.0, phi_i.CompC[0])); + } // compute V_ij = P[rho_ij] Timer timer_p; Orbital V_ij = rho_ij.paramCopy(); - if (rho_ij.hasReal()) { - V_ij.alloc(NUMBER::Real); - mrcpp::apply(prec_p, V_ij.real(), P, rho_ij.real(), phi_opt_vec, -1, true); - } - if (rho_ij.hasImag()) { - V_ij.alloc(NUMBER::Imag); - mrcpp::apply(prec_p, V_ij.imag(), P, rho_ij.imag(), phi_opt_vec, -1, true); + V_ij.alloc(0); + if (RealOrbitals) { + mrcpp::apply(prec_p, *V_ij.CompD[0], P, *rho_ij.CompD[0], phi_opt_vec_real, -1, true); + } else { + mrcpp::apply(prec_p, *V_ij.CompC[0], P, *rho_ij.CompC[0], phi_opt_vec_cplx, -1, true); } rho_ij.free(); timer_p.stop(); @@ -219,7 +221,7 @@ void ExchangePotential::calcExchange_kij(double prec, Orbital phi_k, Orbital phi auto N_jji = 0; auto norm_jji = 0.0; if (out_jji != nullptr) { - mrcpp::multiply(*out_jji, phi_j, V_ij.dagger(), prec_m2, true, true); + mrcpp::multiply(*out_jji, V_ij, phi_j, prec_m2, true, true, true); N_jji = out_jji->getNNodes(); norm_jji = out_jji->norm(); } diff --git a/tests/qmfunctions/density.cpp b/tests/qmfunctions/density.cpp index 780bc4051..5f0766a01 100644 --- a/tests/qmfunctions/density.cpp +++ b/tests/qmfunctions/density.cpp @@ -44,8 +44,6 @@ TEST_CASE("Density", "[density]") { for (int i = 0; i < 5; i++) Phi.push_back(Orbital(SPIN::Alpha)); for (int i = 0; i < 2; i++) Phi.push_back(Orbital(SPIN::Beta)); - Phi.distribute(); - HydrogenFunction s1(1, 0, 0); HydrogenFunction s2(2, 0, 0); HydrogenFunction px(2, 1, 0); diff --git a/tests/qmfunctions/orbital.cpp b/tests/qmfunctions/orbital.cpp index e843a7fd0..9e068f471 100644 --- a/tests/qmfunctions/orbital.cpp +++ b/tests/qmfunctions/orbital.cpp @@ -39,9 +39,9 @@ auto f = [](const mrcpp::Coord<3> &r) -> double { }; ComplexDouble i1 = {0.0, 1.0}; -auto g = [](const mrcpp::Coord<3> &r) -> ComplexDouble { +auto g = [](const mrcpp::Coord<3> &r) -> double { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); - return std::exp(-2.0 * R * R) * i1; + return std::exp(-2.0 * R * R); }; TEST_CASE("Orbital", "[orbital]") { @@ -58,7 +58,7 @@ TEST_CASE("Orbital", "[orbital]") { REQUIRE(phi_2.spin() == phi_1.spin()); REQUIRE(phi_2.norm() == phi_1.norm()); REQUIRE(&phi_2.real() == &phi_1.real()); - REQUIRE(&phi_2.complex() == &phi_1.complex()); + REQUIRE(phi_2.iscomplex() == phi_1.iscomplex()); } SECTION("default constructor plus assignment") { @@ -68,7 +68,7 @@ TEST_CASE("Orbital", "[orbital]") { REQUIRE(phi_2.spin() == phi_1.spin()); REQUIRE(phi_2.norm() == phi_1.norm()); REQUIRE(&phi_2.real() == &phi_1.real()); - REQUIRE(&phi_2.complex() == &phi_1.complex()); + REQUIRE(phi_2.iscomplex() == phi_1.iscomplex()); } SECTION("assigment constructor") { @@ -77,17 +77,17 @@ TEST_CASE("Orbital", "[orbital]") { REQUIRE(phi_2.spin() == phi_1.spin()); REQUIRE(phi_2.norm() == phi_1.norm()); REQUIRE(&phi_2.real() == &phi_1.real()); - REQUIRE(&phi_2.complex() == &phi_1.complex()); + REQUIRE(phi_2.iscomplex() == phi_1.iscomplex()); } SECTION("deep copy") { - Orbital phi_2(SPIN::Alpha); + Orbital phi_2; mrcpp::deep_copy(phi_2, phi_1); - REQUIRE(phi_2.occ() != phi_1.occ()); - REQUIRE(phi_2.spin() != phi_1.spin()); + REQUIRE(phi_2.occ() == phi_1.occ()); + REQUIRE(phi_2.spin() == phi_1.spin()); REQUIRE(phi_2.norm() == phi_1.norm()); REQUIRE(&phi_2.real() != &phi_1.real()); - REQUIRE(not(phi_2.hasImag())); + REQUIRE(not(phi_2.iscomplex())); } SECTION("parameter copy") { @@ -95,17 +95,17 @@ TEST_CASE("Orbital", "[orbital]") { REQUIRE(phi_2.occ() == phi_1.occ()); REQUIRE(phi_2.spin() == phi_1.spin()); REQUIRE(phi_2.norm() < 1.0); - REQUIRE(not(phi_2.hasReal())); - REQUIRE(not(phi_2.hasImag())); + REQUIRE(phi_2.isreal()); + REQUIRE(not(phi_2.iscomplex())); } } SECTION("normalize") { Orbital phi(SPIN::Paired); - REQUIRE(phi.norm() == Approx(-1.0)); + REQUIRE(phi.norm() == Approx(0.0)); - mrcpp::project(phi, g, prec); - REQUIRE(phi.norm() > 1.0); + mrcpp::project(phi, static_cast &r)>>(f), prec); + REQUIRE(phi.norm() > 0.8); orbital::normalize(phi); REQUIRE(phi.norm() == Approx(1.0)); @@ -117,7 +117,7 @@ TEST_CASE("Orbital", "[orbital]") { WHEN("orbitals have different spins") { Orbital phi_2(SPIN::Beta); - mrcpp::project(phi_2, static_cast &r)>>(g), prec); + mrcpp::project(phi_2, static_cast &r)>>(g), prec); THEN("their overlap is zero") { ComplexDouble S = orbital::dot(phi_1, phi_2); @@ -128,29 +128,23 @@ TEST_CASE("Orbital", "[orbital]") { WHEN("orbitals have the same spin") { Orbital phi_2(SPIN::Alpha); - mrcpp::project(phi_2, static_cast &r)>>(g), prec); + mrcpp::project(phi_2, static_cast &r)>>(f), prec); THEN("their overlap is non-zero") { ComplexDouble S1 = orbital::dot(phi_1, phi_2); - REQUIRE(std::abs(S1.real()) < thrs); - REQUIRE(std::abs(S1.imag()) > thrs); + REQUIRE(std::abs(S1.real()) > thrs); + REQUIRE(std::abs(S1.imag()) < thrs); + } + + AND_THEN("they are orthogonalized") { + mrcpp::orthogonalize(prec, phi_2, phi_1); - AND_THEN(" = *") { - ComplexDouble S2 = orbital::dot(phi_1, phi_2.dagger()); - REQUIRE(S2.real() == Approx(S1.real())); - REQUIRE(S2.imag() == Approx(-S1.imag())); + THEN("their overlap is zero") { + ComplexDouble S3 = orbital::dot(phi_1, phi_2); + REQUIRE(std::abs(S3.real()) < thrs); + REQUIRE(std::abs(S3.imag()) < thrs); } } - - // AND_THEN("they are orthogonalized") { - // orbital::orthogonalize(prec, phi_2, phi_1); -// - // THEN("their overlap is zero") { - // ComplexDouble S3 = orbital::dot(phi_1, phi_2); - // REQUIRE(std::abs(S3.real()) < thrs); - // REQUIRE(std::abs(S3.imag()) < thrs); - // } - // } } } } diff --git a/tests/qmfunctions/orbital_vector.cpp b/tests/qmfunctions/orbital_vector.cpp index f11578368..93ca6a237 100644 --- a/tests/qmfunctions/orbital_vector.cpp +++ b/tests/qmfunctions/orbital_vector.cpp @@ -97,7 +97,6 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { Phi.push_back(Orbital(SPIN::Paired)); Phi.push_back(Orbital(SPIN::Beta)); Phi.push_back(Orbital(SPIN::Beta)); - Phi.distribute(); OrbitalVector Phi_p = disjoin(Phi, SPIN::Paired); OrbitalVector Phi_a = disjoin(Phi, SPIN::Alpha); @@ -128,7 +127,7 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { OrbitalVector Phi; Phi.push_back(Orbital(SPIN::Paired)); Phi.push_back(Orbital(SPIN::Alpha)); - Phi.distribute(); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], static_cast &r)>>(f1), prec); if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], static_cast &r)>>(f2), prec); normalize(Phi); @@ -187,8 +186,8 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { REQUIRE(get_electron_number(Psi, SPIN::Beta) == get_electron_number(Phi, SPIN::Beta)); DoubleVector norms = get_norms(Psi); - REQUIRE(norms[0] < 0.0); - REQUIRE(norms[1] < 0.0); + REQUIRE(norms[0] < thrs); + REQUIRE(norms[1] < thrs); } } @@ -196,11 +195,11 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { OrbitalVector Phi; Phi.push_back(Orbital(SPIN::Paired)); Phi.push_back(Orbital(SPIN::Alpha)); - Phi.distribute(); DoubleVector norms1 = get_norms(Phi); - REQUIRE(norms1[0] == Approx(-1.0)); - REQUIRE(norms1[1] == Approx(-1.0)); + + REQUIRE(norms1[0] == Approx(0.0)); + REQUIRE(norms1[1] == Approx(0.0)); if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], static_cast &r)>>(f1), prec); if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], static_cast &r)>>(f2), prec); @@ -224,7 +223,7 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { if (i != j) REQUIRE(Snorm(i, j) >= Approx(std::abs(S(i, j)))); } } - } + } } SECTION("orthogonalization") { @@ -307,17 +306,12 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { OrbitalVector Phi; Phi.push_back(Orbital(SPIN::Paired)); Phi.push_back(Orbital(SPIN::Paired)); - Phi.distribute(); if (mrcpp::mpi::my_func(Phi[0])) { - mrcpp::project(Phi[0], static_cast &r)>>(f1), prec); - mrcpp::project(Phi[0], static_cast &r)>>(f2), prec); + mrcpp::project(Phi[0], static_cast &r)>>(f1), prec); + mrcpp::project(Phi[1], static_cast &r)>>(f2), prec); } - if (mrcpp::mpi::my_func(Phi[1])) { - mrcpp::project(Phi[1], static_cast &r)>>(f3), prec); - mrcpp::project(Phi[1], static_cast &r)>>(f4), prec); - } orthogonalize(prec, Phi); normalize(Phi); diff --git a/tests/qmfunctions/qmfunction.cpp b/tests/qmfunctions/qmfunction.cpp index 44e8cefcb..ac272e103 100644 --- a/tests/qmfunctions/qmfunction.cpp +++ b/tests/qmfunctions/qmfunction.cpp @@ -50,18 +50,12 @@ TEST_CASE("QMFunction", "[qmfunction]") { SECTION("copy non-shared function") { mrcpp::CompFunction func_1; - std::cout<<" project "< Date: Thu, 22 Aug 2024 16:19:18 +0200 Subject: [PATCH 4/8] all tests passes except hessians --- external/upstream/fetch_mrcpp.cmake | 2 +- src/qmfunctions/Orbital.cpp | 1 - src/qmfunctions/density_utils.cpp | 2 + src/qmfunctions/orbital_utils.cpp | 10 +- src/qmfunctions/qmfunction_utils.cpp | 317 ------------------ src/qmfunctions/qmfunction_utils.h | 46 --- src/qmoperators/QMDerivative.cpp | 57 ++-- src/qmoperators/QMIdentity.cpp | 3 +- src/qmoperators/QMOperator.h | 2 +- src/qmoperators/QMPotential.cpp | 7 +- src/qmoperators/QMSpin.h | 2 +- .../one_electron/MomentumOperator.h | 3 +- .../two_electron/CoulombPotential.cpp | 13 +- .../two_electron/CoulombPotential.h | 2 +- .../two_electron/ExchangePotentialD1.cpp | 16 +- .../two_electron/ExchangePotentialD2.cpp | 12 +- .../two_electron/ReactionPotential.cpp | 2 +- src/qmoperators/two_electron/XCPotential.cpp | 2 +- .../two_electron/XCPotentialD1.cpp | 7 +- src/tensor/RankOneOperator.cpp | 4 +- src/tensor/RankOneOperator.h | 2 +- src/tensor/RankTwoOperator.cpp | 6 +- src/tensor/RankZeroOperator.cpp | 21 +- src/tensor/RankZeroOperator.h | 4 +- src/utils/RRMaximizer.cpp | 6 +- tests/qmfunctions/orbital_vector.cpp | 5 +- tests/qmfunctions/qmfunction.cpp | 2 +- tests/qmoperators/coulomb_operator.cpp | 9 +- tests/qmoperators/identity_operator.cpp | 35 +- tests/qmoperators/kinetic_operator.cpp | 1 - tests/qmoperators/momentum_operator.cpp | 1 - tests/qmoperators/operator_composition.cpp | 14 +- tests/qmoperators/position_operator.cpp | 2 - tests/qmoperators/xc_hessian_lda.cpp | 8 +- tests/qmoperators/xc_operator_blyp.cpp | 16 +- tests/qmoperators/xc_operator_lda.cpp | 12 +- tests/solventeffect/reaction_operator.cpp | 1 - 37 files changed, 154 insertions(+), 501 deletions(-) delete mode 100644 src/qmfunctions/qmfunction_utils.cpp delete mode 100644 src/qmfunctions/qmfunction_utils.h diff --git a/external/upstream/fetch_mrcpp.cmake b/external/upstream/fetch_mrcpp.cmake index 59f1bc309..646de0bd0 100644 --- a/external/upstream/fetch_mrcpp.cmake +++ b/external/upstream/fetch_mrcpp.cmake @@ -39,7 +39,7 @@ else() GIT_REPOSITORY https://github.com/MRChemSoft/mrcpp.git GIT_TAG - 0df20bca9c03eb894462ce923155c7033b4fdbcd + 6624a73fadcb9083ef86fad24c2635bfb882b ) FetchContent_GetProperties(mrcpp_sources) diff --git a/src/qmfunctions/Orbital.cpp b/src/qmfunctions/Orbital.cpp index 20f75ec9d..8d1399c5e 100644 --- a/src/qmfunctions/Orbital.cpp +++ b/src/qmfunctions/Orbital.cpp @@ -29,7 +29,6 @@ #include "Orbital.h" #include "orbital_utils.h" -#include "qmfunction_utils.h" namespace mrchem { diff --git a/src/qmfunctions/density_utils.cpp b/src/qmfunctions/density_utils.cpp index 70592ec06..cff3067c6 100644 --- a/src/qmfunctions/density_utils.cpp +++ b/src/qmfunctions/density_utils.cpp @@ -177,6 +177,8 @@ void density::compute_local_XY(double prec, Density &rho, OrbitalVector &Phi, Or int N_el = orbital::get_electron_number(Phi); double mult_prec = prec; // prec for rho_i = |x_i> diff --git a/src/qmfunctions/qmfunction_utils.cpp b/src/qmfunctions/qmfunction_utils.cpp deleted file mode 100644 index 8cdc8d35f..000000000 --- a/src/qmfunctions/qmfunction_utils.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/* - * MRChem, a numerical real-space code for molecular electronic structure - * calculations within the self-consistent field (SCF) approximations of quantum - * chemistry (Hartree-Fock and Density Functional Theory). - * Copyright (C) 2023 Stig Rune Jensen, Luca Frediani, Peter Wind and contributors. - * - * This file is part of MRChem. - * - * MRChem is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MRChem is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with MRChem. If not, see . - * - * For information on the complete list of contributors to MRChem, see: - * - */ - -#include "MRCPP/Gaussians" -#include "MRCPP/Printer" -#include "MRCPP/Timer" - -#include "parallel.h" - -#include "mrcpp::CompFunction.h" -#include "qmfunction_utils.h" - -using mrcpp::FunctionTree; -using mrcpp::FunctionTreeVector; -using mrcpp::Printer; -using mrcpp::Timer; - -namespace mrchem { -extern mrcpp::MultiResolutionAnalysis<3> *MRA; // Global MRA - -/** @brief Compute = int bra^\dag(r) * ket(r) dr. - * - * Notice that the bra, mrcpp::CompFunction<3> ket) { - double rr(0.0), ri(0.0), ir(0.0), ii(0.0); - if (bra.hasReal() and ket.hasReal()) rr = mrcpp::dot(bra.real(), ket.real()); - if (bra.hasReal() and ket.hasImag()) ri = mrcpp::dot(bra.real(), ket.imag()); - if (bra.hasImag() and ket.hasReal()) ir = mrcpp::dot(bra.imag(), ket.real()); - if (bra.hasImag() and ket.hasImag()) ii = mrcpp::dot(bra.imag(), ket.imag()); - - double bra_conj = (bra.conjugate()) ? -1.0 : 1.0; - double ket_conj = (ket.conjugate()) ? -1.0 : 1.0; - - double real_part = rr + bra_conj * ket_conj * ii; - double imag_part = ket_conj * ri - bra_conj * ir; - return ComplexDouble(real_part, imag_part); -} - -/** @brief Compute = int |bra^\dag(r)| * |ket(r)| dr. - * - */ -ComplexDouble mrcpp::node_norm_dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3> ket, bool exact) { - double rr(0.0), ri(0.0), ir(0.0), ii(0.0); - if (bra.hasReal() and ket.hasReal()) rr = mrcpp::node_norm_dot(bra.real(), ket.real(), exact); - if (bra.hasReal() and ket.hasImag()) ri = mrcpp::node_norm_dot(bra.real(), ket.imag(), exact); - if (bra.hasImag() and ket.hasReal()) ir = mrcpp::node_norm_dot(bra.imag(), ket.real(), exact); - if (bra.hasImag() and ket.hasImag()) ii = mrcpp::node_norm_dot(bra.imag(), ket.imag(), exact); - - double bra_conj = (bra.conjugate()) ? -1.0 : 1.0; - double ket_conj = (ket.conjugate()) ? -1.0 : 1.0; - - double real_part = rr + bra_conj * ket_conj * ii; - double imag_part = ket_conj * ri - bra_conj * ir; - return ComplexDouble(real_part, imag_part); -} - -/** @brief Deep copy - * - * Returns a new function which is a full blueprint copy of the input function. - * This is achieved by building a new grid for the real and imaginary parts and - * copying. - */ -void mrcpp::deep_copy(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> &inp) { - bool need_to_copy = not(out.isShared()) or mrcpp::mpi::share_master(); - if (inp.hasReal()) { - if (not out.hasReal()) out.alloc(NUMBER::Real); - if (need_to_copy) { - mrcpp::copy_grid(out.real(), inp.real()); - mrcpp::copy_func(out.real(), inp.real()); - } - } - if (inp.hasImag()) { - if (not out.hasImag()) out.alloc(NUMBER::Imag); - if (need_to_copy) { - mrcpp::copy_grid(out.imag(), inp.imag()); - mrcpp::copy_func(out.imag(), inp.imag()); - if (out.conjugate()) out.imag().rescale(-1.0); - } - } - mrcpp::mpi::share_function(out, 0, 1324, mrcpp::mpi::comm_share); -} - -void mrcpp::project(mrcpp::CompFunction<3> &out, std::function &r)> f, int type, double prec) { - bool need_to_project = not(out.isShared()) or mrcpp::mpi::share_master(); - if (type == NUMBER::Real or type == NUMBER::Total) { - if (not out.hasReal()) out.alloc(NUMBER::Real); - if (need_to_project) mrcpp::project<3>(prec, out.real(), f); - } - if (type == NUMBER::Imag or type == NUMBER::Total) { - if (not out.hasImag()) out.alloc(NUMBER::Imag); - if (need_to_project) mrcpp::project<3>(prec, out.imag(), f); - } - mrcpp::mpi::share_function(out, 0, 123123, mrcpp::mpi::comm_share); -} - -void mrcpp::project(mrcpp::CompFunction<3> &out, mrcpp::GaussExp<3> &f, int type, double prec) { - bool need_to_project = not(out.isShared()) or mrcpp::mpi::share_master(); - if (type == NUMBER::Real or type == NUMBER::Total) { - if (not out.hasReal()) out.alloc(NUMBER::Real); - if (need_to_project) { - for (int i = 0; i < f.size(); i++) mrcpp::build_grid(out.real(), *f[i]); - } - if (need_to_project) mrcpp::project<3>(prec, out.real(), f); - } - if (type == NUMBER::Imag or type == NUMBER::Total) { - if (not out.hasImag()) out.alloc(NUMBER::Imag); - if (need_to_project) { - for (int i = 0; i < f.size(); i++) mrcpp::build_grid(out.imag(), *f[i]); - } - if (need_to_project) mrcpp::project<3>(prec, out.imag(), f); - } - mrcpp::mpi::share_function(out, 0, 132231, mrcpp::mpi::comm_share); -} - -void mrcpp::project(mrcpp::CompFunction<3> &out, mrcpp::RepresentableFunction<3> &f, int type, double prec) { - bool need_to_project = not(out.isShared()) or mrcpp::mpi::share_master(); - if (type == NUMBER::Real or type == NUMBER::Total) { - if (not out.hasReal()) out.alloc(NUMBER::Real); - if (need_to_project) mrcpp::build_grid(out.real(), f); - if (need_to_project) mrcpp::project<3>(prec, out.real(), f); - } - if (type == NUMBER::Imag or type == NUMBER::Total) { - if (not out.hasImag()) out.alloc(NUMBER::Imag); - if (need_to_project) mrcpp::build_grid(out.imag(), f); - if (need_to_project) mrcpp::project<3>(prec, out.imag(), f); - } - mrcpp::mpi::share_function(out, 0, 132231, mrcpp::mpi::comm_share); -} - -/** @brief out = a*inp_a + b*inp_b - * - * Recast into linear_combination. - * - */ -void mrcpp::add(mrcpp::CompFunction<3> &out, ComplexDouble a, mrcpp::CompFunction<3> inp_a, ComplexDouble b, mrcpp::CompFunction<3> inp_b, double prec) { - ComplexVector coefs(2); - coefs(0) = a; - coefs(1) = b; - - mrcpp::CompFunction<3>Vector funcs; - funcs.push_back(inp_a); - funcs.push_back(inp_b); - - mrcpp::linear_combination(out, coefs, funcs, prec); -} - -/** @brief out = inp_a * inp_b - * - */ -void mrcpp::multiply(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> inp_a, mrcpp::CompFunction<3> inp_b, double prec, bool absPrec, bool useMaxNorms) { - multiply_real(out, inp_a, inp_b, prec, absPrec, useMaxNorms); - multiply_imag(out, inp_a, inp_b, prec, absPrec, useMaxNorms); -} - -/** @brief out = Re(inp_a * inp_b) - * - */ -void mrcpp::multiply_real(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> inp_a, mrcpp::CompFunction<3> inp_b, double prec, bool absPrec, bool useMaxNorms) { - double conj_a = (inp_a.conjugate()) ? -1.0 : 1.0; - double conj_b = (inp_b.conjugate()) ? -1.0 : 1.0; - - bool need_to_multiply = not(out.isShared()) or mrcpp::mpi::share_master(); - - FunctionTreeVector<3> vec; - if (inp_a.hasReal() and inp_b.hasReal()) { - auto *tree = new FunctionTree<3>(*MRA); - if (need_to_multiply) { - double coef = 1.0; - if (prec < 0.0) { - // Union grid - mrcpp::build_grid(*tree, inp_a.real()); - mrcpp::build_grid(*tree, inp_b.real()); - mrcpp::multiply(prec, *tree, coef, inp_a.real(), inp_b.real(), 0); - } else { - // Adaptive grid - mrcpp::multiply(prec, *tree, coef, inp_a.real(), inp_b.real(), -1, absPrec, useMaxNorms); - } - } - vec.push_back(std::make_tuple(1.0, tree)); - } - if (inp_a.hasImag() and inp_b.hasImag()) { - auto *tree = new FunctionTree<3>(*MRA); - if (need_to_multiply) { - double coef = -1.0 * conj_a * conj_b; - if (prec < 0.0) { - // Union grid - mrcpp::build_grid(*tree, inp_a.imag()); - mrcpp::build_grid(*tree, inp_b.imag()); - mrcpp::multiply(prec, *tree, coef, inp_a.imag(), inp_b.imag(), 0); - } else { - // Adaptive grid - mrcpp::multiply(prec, *tree, coef, inp_a.imag(), inp_b.imag(), -1, absPrec, useMaxNorms); - } - } - vec.push_back(std::make_tuple(1.0, tree)); - } - - if (vec.size() > 0) { - if (out.hasReal()) { - if (need_to_multiply) out.real().clear(); - } else { - // All sharing procs must allocate - out.alloc(NUMBER::Real); - } - } - - if (need_to_multiply) { - if (vec.size() == 1) { - mrcpp::FunctionTree<3> &func_0 = mrcpp::get_func(vec, 0); - mrcpp::copy_grid(out.real(), func_0); - mrcpp::copy_func(out.real(), func_0); - mrcpp::clear(vec, true); - } else if (vec.size() == 2) { - mrcpp::build_grid(out.real(), vec); - mrcpp::add(prec, out.real(), vec, 0); - mrcpp::clear(vec, true); - } else if (out.hasReal()) { - out.real().setZero(); - } - } - mrcpp::mpi::share_function(out, 0, 9191, mrcpp::mpi::comm_share); -} - -/** @brief out = Im(inp_a * inp_b) - * - */ -void mrcpp::multiply_imag(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> inp_a, mrcpp::CompFunction<3> inp_b, double prec, bool absPrec, bool useMaxNorms) { - double conj_a = (inp_a.conjugate()) ? -1.0 : 1.0; - double conj_b = (inp_b.conjugate()) ? -1.0 : 1.0; - - bool need_to_multiply = not(out.isShared()) or mrcpp::mpi::share_master(); - - FunctionTreeVector<3> vec; - if (inp_a.hasReal() and inp_b.hasImag()) { - auto *tree = new FunctionTree<3>(*MRA); - if (need_to_multiply) { - double coef = conj_b; - if (prec < 0.0) { - // Union grid - mrcpp::build_grid(*tree, inp_a.real()); - mrcpp::build_grid(*tree, inp_b.imag()); - mrcpp::multiply(prec, *tree, coef, inp_a.real(), inp_b.imag(), 0); - } else { - // Adaptive grid - mrcpp::multiply(prec, *tree, coef, inp_a.real(), inp_b.imag(), -1, absPrec, useMaxNorms); - } - } - vec.push_back(std::make_tuple(1.0, tree)); - } - if (inp_a.hasImag() and inp_b.hasReal()) { - auto *tree = new FunctionTree<3>(*MRA); - if (need_to_multiply) { - double coef = conj_a; - if (prec < 0.0) { - // Union grid - mrcpp::build_grid(*tree, inp_a.imag()); - mrcpp::build_grid(*tree, inp_b.real()); - mrcpp::multiply(prec, *tree, coef, inp_a.imag(), inp_b.real(), 0); - } else { - // Adaptive grid - mrcpp::multiply(prec, *tree, coef, inp_a.imag(), inp_b.real(), -1, absPrec, useMaxNorms); - } - } - vec.push_back(std::make_tuple(1.0, tree)); - } - - if (vec.size() > 0) { - if (out.hasImag()) { - if (need_to_multiply) out.imag().clear(); - } else { - // All sharing procs must allocate - out.alloc(NUMBER::Imag); - } - } - - if (need_to_multiply) { - if (vec.size() == 1) { - mrcpp::FunctionTree<3> &func_0 = mrcpp::get_func(vec, 0); - mrcpp::copy_grid(out.imag(), func_0); - mrcpp::copy_func(out.imag(), func_0); - mrcpp::clear(vec, true); - } else if (vec.size() == 2) { - mrcpp::build_grid(out.imag(), vec); - mrcpp::add(prec, out.imag(), vec, 0); - mrcpp::clear(vec, true); - } else if (out.hasImag()) { - out.imag().setZero(); - } - } - mrcpp::mpi::share_function(out, 0, 9292, mrcpp::mpi::comm_share); -} - -} // namespace mrchem diff --git a/src/qmfunctions/qmfunction_utils.h b/src/qmfunctions/qmfunction_utils.h deleted file mode 100644 index aa9e4edb2..000000000 --- a/src/qmfunctions/qmfunction_utils.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * MRChem, a numerical real-space code for molecular electronic structure - * calculations within the self-consistent field (SCF) approximations of quantum - * chemistry (Hartree-Fock and Density Functional Theory). - * Copyright (C) 2023 Stig Rune Jensen, Luca Frediani, Peter Wind and contributors. - * - * This file is part of MRChem. - * - * MRChem is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MRChem is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with MRChem. If not, see . - * - * For information on the complete list of contributors to MRChem, see: - * - */ - -#pragma once - -#include "mrchem.h" -#include "qmfunction_fwd.h" - -namespace mrchem { -namespace qmfunction { - -ComplexDouble dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3> ket); -ComplexDouble node_norm_dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3> ket, bool exact); -void deep_copy(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> &inp); -void add(mrcpp::CompFunction<3> &out, ComplexDouble a, mrcpp::CompFunction<3> inp_a, ComplexDouble b, mrcpp::CompFunction<3> inp_b, double prec); -void project(mrcpp::CompFunction<3> &out, std::function &r)> f, int type, double prec); -void project(mrcpp::CompFunction<3> &out, mrcpp::RepresentableFunction<3> &f, int type, double prec); -void project(mrcpp::CompFunction<3> &out, mrcpp::GaussExp<3> &f, int type, double prec); -void multiply(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> inp_a, mrcpp::CompFunction<3> inp_b, double prec, bool absPrec = false, bool useMaxNorms = false); -void multiply_real(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> inp_a, mrcpp::CompFunction<3> inp_b, double prec, bool absPrec = false, bool useMaxNorms = false); -void multiply_imag(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> inp_a, mrcpp::CompFunction<3> inp_b, double prec, bool absPrec = false, bool useMaxNorms = false); - -} // namespace qmfunction -} // namespace mrchem diff --git a/src/qmoperators/QMDerivative.cpp b/src/qmoperators/QMDerivative.cpp index 88f5aca97..670ded3b5 100644 --- a/src/qmoperators/QMDerivative.cpp +++ b/src/qmoperators/QMDerivative.cpp @@ -33,7 +33,7 @@ #include "QMIdentity.h" #include "QMPotential.h" #include "QMSpin.h" -#include "qmfunctions/orbital_utils.h" +//#include "qmfunctions/orbital_utils.h" #include "utils/print_utils.h" using mrcpp::DerivativeOperator; @@ -60,14 +60,20 @@ QMDerivative::QMDerivative(const QMDerivative &inp) Orbital QMDerivative::apply(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); if (this->derivative == nullptr) MSG_ERROR("No derivative operator"); - auto dir = this->apply_dir; auto &D = *this->derivative; - Orbital out(inp); - out.alloc(0); - mrcpp::apply(out, D, inp, dir); - + Orbital out = inp.paramCopy(); + ComplexDouble metric[4][4]; + ComplexDouble diago = 1.0; + if (isImag()) diago = {0.0, 1.0}; + for (int i=0; i<4; i++){ + for (int j=0; j<4; j++){ + if (i==j) metric[i][j] = diago; + else metric[i][j] = 0.0; + } + } + mrcpp::apply(out, D, inp, dir, metric); return out; } @@ -84,29 +90,40 @@ QMOperatorVector QMDerivative::apply(QMOperator_p &O) { // O == identity: skip it out.push_back(std::make_shared(*this)); } else if (V_inp) { - // O == potential: compute its derivative + // O == potential: compute its derivative auto &D = *this->derivative; auto d = this->apply_dir; auto V_out = std::make_shared(*V_inp); + // does not compile? mrcpp::apply(V_out_base, D, V_inp, d); if (this->isReal()) { - if (V_inp->hasReal()) { - V_out->alloc(NUMBER::Real); + if (V_inp->isreal()) { + V_out->alloc(0); mrcpp::apply(V_out->real(), D, V_inp->real(), d); } - if (V_inp->hasImag()) { - V_out->alloc(NUMBER::Imag); - mrcpp::apply(V_out->imag(), D, V_inp->imag(), d); - if (V_inp->conjugate()) V_out->imag().rescale(-1.0); + if (V_inp->iscomplex()) { + V_out->func_ptr->isreal = 0; + V_out->func_ptr->iscomplex = 1; + V_out->alloc(0); + mrcpp::apply(V_out->complex(), D, V_inp->complex(), d); + //if (V_inp->conjugate()) V_out->imag().rescale(-1.0); } } else { - if (V_inp->hasImag()) { - V_out->alloc(NUMBER::Real); - mrcpp::apply(V_out->real(), D, V_inp->imag(), d); - if (!V_inp->conjugate()) V_out->real().rescale(-1.0); + if (V_inp->iscomplex()) { + V_out->func_ptr->isreal = 0; + V_out->func_ptr->iscomplex = 1; + V_out->alloc(0); + mrcpp::apply(V_out->complex(), D, V_inp->complex(), d); + if (!V_inp->conjugate()) V_out->CompC[0]->rescale({0.0, 1.0}); } - if (V_inp->hasReal()) { - V_out->alloc(NUMBER::Imag); - mrcpp::apply(V_out->imag(), D, V_inp->real(), d); + if (V_inp->isreal()) { + mrcpp::copy_grid(V_out->real(), V_inp->real()); + mrcpp::apply(V_out->real(), D, V_inp->real(), d); + V_out->CompD[0]->CopyTreeToComplex(V_out->CompC[0]); + V_out->func_ptr->isreal = 0; + V_out->func_ptr->iscomplex = 1; + delete V_out->CompD[0]; + V_out->CompD[0] = nullptr; + V_out->CompC[0]->rescale({0.0, 1.0}); } } out.push_back(V_out); diff --git a/src/qmoperators/QMIdentity.cpp b/src/qmoperators/QMIdentity.cpp index 52a26597e..88d826044 100644 --- a/src/qmoperators/QMIdentity.cpp +++ b/src/qmoperators/QMIdentity.cpp @@ -37,8 +37,9 @@ namespace mrchem { /** Identity operator is a deep copy */ Orbital QMIdentity::apply(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); - Orbital out(inp); + Orbital out = inp.paramCopy(); mrcpp::deep_copy(out, inp); + return out; } diff --git a/src/qmoperators/QMOperator.h b/src/qmoperators/QMOperator.h index fc653b1e1..2db00fc1c 100644 --- a/src/qmoperators/QMOperator.h +++ b/src/qmoperators/QMOperator.h @@ -58,7 +58,7 @@ class QMOperator { public: QMOperator() = default; virtual ~QMOperator() { - if (prec() > 0.0) MSG_ERROR("Operator not properly cleared"); + if (prec() > 0.0) MSG_ERROR("QMOperator not properly cleared"); } double prec() { return this->apply_prec; } diff --git a/src/qmoperators/QMPotential.cpp b/src/qmoperators/QMPotential.cpp index 365dd7e89..396aed539 100644 --- a/src/qmoperators/QMPotential.cpp +++ b/src/qmoperators/QMPotential.cpp @@ -73,7 +73,7 @@ QMPotential::QMPotential(const QMPotential &inp) Orbital QMPotential::apply(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); - Orbital out(inp); + Orbital out; calc(out, inp, false); return out; @@ -89,7 +89,7 @@ Orbital QMPotential::apply(Orbital inp) { Orbital QMPotential::dagger(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); - Orbital out(inp.data()); + Orbital out = inp.paramCopy(); calc(out, inp, true); return out; } @@ -130,7 +130,6 @@ QMOperatorVector QMPotential::apply(QMOperator_p &O) { void QMPotential::calc(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> &inp, bool dagger) { int adap = this->adap_build; double prec = this->apply_prec; - if (out.Ncomp() > 0) MSG_ABORT("Output not empty"); if (out.isShared()) MSG_ABORT("Cannot share this function"); if (dagger) MSG_ERROR("Not implemented"); @@ -139,7 +138,7 @@ void QMPotential::calc(mrcpp::CompFunction<3> &out, mrcpp::CompFunction<3> &inp, mrcpp::CompFunction<3> &V = *this; double coef = 1.0; mrcpp::copy_grid(out, inp); - mrcpp::multiply(prec, out, coef, V, inp, adap); + mrcpp::multiply(prec, out, coef, inp, V, adap); } } // namespace mrchem diff --git a/src/qmoperators/QMSpin.h b/src/qmoperators/QMSpin.h index 9bda1a051..1f7513861 100644 --- a/src/qmoperators/QMSpin.h +++ b/src/qmoperators/QMSpin.h @@ -101,7 +101,7 @@ class QMAlpha final : public QMOperator { * @brief Spin beta operator * * Operator that acts as Identity when applied on beta (or paired) orbitals, - * and as Zero when applid on alpha orbitals. + * and as Zero when applied on alpha orbitals. * * Can be defined as: * diff --git a/src/qmoperators/one_electron/MomentumOperator.h b/src/qmoperators/one_electron/MomentumOperator.h index b45ae0ad4..d7a8aa83d 100644 --- a/src/qmoperators/one_electron/MomentumOperator.h +++ b/src/qmoperators/one_electron/MomentumOperator.h @@ -34,7 +34,8 @@ namespace mrchem { class MomentumOperator final : public RankOneOperator<3> { public: MomentumOperator(std::shared_ptr> D) - : MomentumOperator(NablaOperator(D, true)) {} + : MomentumOperator(NablaOperator(D, true)) {} //2.610296212006e+02 + // : MomentumOperator(NablaOperator(D, false)) {} //7.500000129099e-01 MomentumOperator(NablaOperator D) { // Invoke operator= to assign *this operator diff --git a/src/qmoperators/two_electron/CoulombPotential.cpp b/src/qmoperators/two_electron/CoulombPotential.cpp index 9165eb405..7b9be8fb2 100644 --- a/src/qmoperators/two_electron/CoulombPotential.cpp +++ b/src/qmoperators/two_electron/CoulombPotential.cpp @@ -81,8 +81,8 @@ void CoulombPotential::setup(double prec) { if (hasDensity()) { setupGlobalPotential(prec); } else if (mrcpp::mpi::numerically_exact) { - setupGlobalDensity(prec); - setupGlobalPotential(prec); + setupGlobalDensity(prec); + setupGlobalPotential(prec); } else { // Keep each local contribution a bit // more precise than strictly necessary @@ -100,8 +100,8 @@ void CoulombPotential::setup(double prec) { * The operator can now be reused after another setup. */ void CoulombPotential::clear() { - mrcpp::CompFunction<3>::free(NUMBER::Total); // delete FunctionTree pointers - this->density.free(NUMBER::Total); // delete FunctionTree pointers + mrcpp::CompFunction<3>::free(); // delete FunctionTree pointers + this->density.free(); // delete FunctionTree pointers clearApplyPrec(); // apply_prec = -1 } @@ -119,15 +119,14 @@ void CoulombPotential::setupGlobalPotential(double prec) { mrcpp::CompFunction<3> &V = *this; mrcpp::CompFunction<3> &rho = this->density; - if (V.hasReal()) MSG_ERROR("Potential not properly cleared"); - if (V.hasImag()) MSG_ERROR("Potential not properly cleared"); + if (V.getNNodes()>8) MSG_ERROR("Potential not properly cleared"); // Adjust precision by system size double abs_prec = prec / rho.norm(); bool need_to_apply = not(V.isShared()) or mrcpp::mpi::share_master(); Timer timer; - V.alloc(NUMBER::Real); + V.alloc(0); if (need_to_apply) mrcpp::apply(abs_prec, V.real(), P, rho.real()); mrcpp::mpi::share_function(V, 0, 22445, mrcpp::mpi::comm_share); print_utils::qmfunction(3, "Compute global potential", V, timer); diff --git a/src/qmoperators/two_electron/CoulombPotential.h b/src/qmoperators/two_electron/CoulombPotential.h index f287527c3..d26b54cfd 100644 --- a/src/qmoperators/two_electron/CoulombPotential.h +++ b/src/qmoperators/two_electron/CoulombPotential.h @@ -65,7 +65,7 @@ class CoulombPotential : public QMPotential { auto &getPoisson() { return this->poisson; } auto &getDensity() { return this->density; } - bool hasDensity() const { return (this->density.squaredNorm() < 0.0) ? false : true; } + bool hasDensity() const { return (this->density.squaredNorm() <= 0.0) ? false : true; } void setup(double prec) override; void clear() override; diff --git a/src/qmoperators/two_electron/ExchangePotentialD1.cpp b/src/qmoperators/two_electron/ExchangePotentialD1.cpp index 1815b4887..fb7037b85 100644 --- a/src/qmoperators/two_electron/ExchangePotentialD1.cpp +++ b/src/qmoperators/two_electron/ExchangePotentialD1.cpp @@ -292,7 +292,7 @@ void ExchangePotentialD1::setupInternal(double prec) { Ex[iorb].add(j_fac, ex_jji); Ex[jorb].add(j_fac, ex_iij); } - ex_jji.free(NUMBER::Total); + ex_jji.free(); t_snd.stop(); } Timer timerx; @@ -326,11 +326,11 @@ void ExchangePotentialD1::setupInternal(double prec) { tasksMaster.put_readytask(jorb, i0 + N); } t_snd.stop(); - ex_j.free(NUMBER::Total); + ex_j.free(); } else if (iijfunc_vec.size() > 0) { MSG_ERROR("Exchange exists but has no real and no Imag parts"); } - for (int jj = 0; jj < iijfunc_vec.size(); jj++) iijfunc_vec[jj].free(NUMBER::Total); + for (int jj = 0; jj < iijfunc_vec.size(); jj++) iijfunc_vec[jj].free(); } } } @@ -364,8 +364,8 @@ void ExchangePotentialD1::setupInternal(double prec) { auto tmp_j = Ex[j].paramCopy(); mrcpp::linear_combination(tmp_j, coef_vec, iijfunc_vec, prec); Ex[j].add(1.0, tmp_j); - tmp_j.free(NUMBER::Total); - for (int jj = 0; jj < iijfunc_vec.size(); jj++) iijfunc_vec[jj].free(NUMBER::Total); + tmp_j.free(); + for (int jj = 0; jj < iijfunc_vec.size(); jj++) iijfunc_vec[jj].free(); iijfunc_vec.clear(); Ex[j].crop(prec); t_add.stop(); @@ -377,8 +377,8 @@ void ExchangePotentialD1::setupInternal(double prec) { auto tmp_j = Ex[j].paramCopy(); mrcpp::linear_combination(tmp_j, coef_vec, iijfunc_vec, prec); Ex[j].add(1.0, tmp_j); - tmp_j.free(NUMBER::Total); - for (int jj = 0; jj < iijfunc_vec.size(); jj++) iijfunc_vec[jj].free(NUMBER::Total); + tmp_j.free(); + for (int jj = 0; jj < iijfunc_vec.size(); jj++) iijfunc_vec[jj].free(); Ex[j].crop(prec); t_add.stop(); } @@ -432,7 +432,7 @@ Orbital ExchangePotentialD1::calcExchange(Orbital phi_p) { func_vec.push_back(ex_iip); } - if (not mrcpp::mpi::my_func(i)) phi_i.free(NUMBER::Total); + if (not mrcpp::mpi::my_func(i)) phi_i.free(); } // compute ex_p = sum_i c_i*ex_iip diff --git a/src/qmoperators/two_electron/ExchangePotentialD2.cpp b/src/qmoperators/two_electron/ExchangePotentialD2.cpp index e57955611..7b1d39bc0 100644 --- a/src/qmoperators/two_electron/ExchangePotentialD2.cpp +++ b/src/qmoperators/two_electron/ExchangePotentialD2.cpp @@ -132,9 +132,9 @@ Orbital ExchangePotentialD2::apply(Orbital phi_p) { coef_vec.push_back(spin_fac / phi_i.squaredNorm()); coef_vec.push_back(spin_fac / phi_i.squaredNorm()); } - if (not mrcpp::mpi::my_func(phi_i)) phi_i.free(NUMBER::Total); - if (not mrcpp::mpi::my_func(x_i)) x_i.free(NUMBER::Total); - if (not mrcpp::mpi::my_func(y_i)) y_i.free(NUMBER::Total); + if (not mrcpp::mpi::my_func(phi_i)) phi_i.free(); + if (not mrcpp::mpi::my_func(x_i)) x_i.free(); + if (not mrcpp::mpi::my_func(y_i)) y_i.free(); } // compute out_p = sum_i c_i*(ex_xip + ex_iyp) @@ -191,9 +191,9 @@ Orbital ExchangePotentialD2::dagger(Orbital phi_p) { coef_vec.push_back(spin_fac / phi_i.squaredNorm()); coef_vec.push_back(spin_fac / phi_i.squaredNorm()); } - if (not mrcpp::mpi::my_func(phi_i)) phi_i.free(NUMBER::Total); - if (not mrcpp::mpi::my_func(x_i)) x_i.free(NUMBER::Total); - if (not mrcpp::mpi::my_func(y_i)) y_i.free(NUMBER::Total); + if (not mrcpp::mpi::my_func(phi_i)) phi_i.free(); + if (not mrcpp::mpi::my_func(x_i)) x_i.free(); + if (not mrcpp::mpi::my_func(y_i)) y_i.free(); } // compute ex_p = sum_i c_i*(ex_ixp + ex_yip) diff --git a/src/qmoperators/two_electron/ReactionPotential.cpp b/src/qmoperators/two_electron/ReactionPotential.cpp index 84ce0d8b0..7fbfa180c 100644 --- a/src/qmoperators/two_electron/ReactionPotential.cpp +++ b/src/qmoperators/two_electron/ReactionPotential.cpp @@ -58,7 +58,7 @@ void ReactionPotential::setup(double prec) { } void ReactionPotential::clear() { - mrcpp::CompFunction<3>::free(NUMBER::Total); // delete FunctionTree pointers + mrcpp::CompFunction<3>::free(); // delete FunctionTree pointers clearApplyPrec(); this->solver->clear(); } diff --git a/src/qmoperators/two_electron/XCPotential.cpp b/src/qmoperators/two_electron/XCPotential.cpp index 8d06a336d..f35e5dbdc 100644 --- a/src/qmoperators/two_electron/XCPotential.cpp +++ b/src/qmoperators/two_electron/XCPotential.cpp @@ -104,7 +104,7 @@ void XCPotential::setup(double prec) { /** @brief Clears all data in the XCPotential object */ void XCPotential::clear() { this->energy = 0.0; - for (auto &rho : this->densities) rho.free(NUMBER::Total); + for (auto &rho : this->densities) rho.free(); mrcpp::clear(this->potentials, true); clearApplyPrec(); } diff --git a/src/qmoperators/two_electron/XCPotentialD1.cpp b/src/qmoperators/two_electron/XCPotentialD1.cpp index da8b922f9..62ddc6d42 100644 --- a/src/qmoperators/two_electron/XCPotentialD1.cpp +++ b/src/qmoperators/two_electron/XCPotentialD1.cpp @@ -49,11 +49,12 @@ XCPotentialD1::XCPotentialD1(std::unique_ptr &F, std::shared_ptr XCPotentialD1::setupDensities(double prec, mrcpp::FunctionTree<3> &grid) { mrcpp::FunctionTreeVector<3> dens_vec; if (not this->mrdft->functional().isSpin()) { - { // Unperturbed total density + + { // Unperturbed total density Timer timer; Density &rho = getDensity(DensityType::Total, 0); - if (not rho.hasReal()) { - rho.alloc(NUMBER::Real); + if (rho.squaredNorm() <= 0.0) { + rho.alloc(0); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Total); } diff --git a/src/tensor/RankOneOperator.cpp b/src/tensor/RankOneOperator.cpp index b9767ab22..127e86138 100644 --- a/src/tensor/RankOneOperator.cpp +++ b/src/tensor/RankOneOperator.cpp @@ -37,9 +37,9 @@ template RankOneOperator RankOneOperator::operator()(RankZeroOpera return out; } -template OrbitalVector RankOneOperator::operator()(Orbital phi) { +template std::vector RankOneOperator::operator()(Orbital phi) { RankOneOperator &O = *this; - OrbitalVector out; + std::vector out; for (int i = 0; i < I; i++) out.push_back(O[i](phi)); return out; } diff --git a/src/tensor/RankOneOperator.h b/src/tensor/RankOneOperator.h index bc4dbf5de..99ac334f5 100644 --- a/src/tensor/RankOneOperator.h +++ b/src/tensor/RankOneOperator.h @@ -42,7 +42,7 @@ namespace mrchem { template class RankOneOperator : public TensorOperator { public: RankOneOperator operator()(RankZeroOperator B); - OrbitalVector operator()(Orbital phi); + std::vector operator()(Orbital phi); //NB: not an "OrbitalVector", because is not related to MPI ComplexVector operator()(Orbital bra, Orbital ket); ComplexVector trace(OrbitalVector &phi); ComplexVector trace(OrbitalVector &phi, OrbitalVector &x, OrbitalVector &y); diff --git a/src/tensor/RankTwoOperator.cpp b/src/tensor/RankTwoOperator.cpp index 5bd10db12..9b4755f83 100644 --- a/src/tensor/RankTwoOperator.cpp +++ b/src/tensor/RankTwoOperator.cpp @@ -31,9 +31,11 @@ namespace mrchem { template ComplexMatrix RankTwoOperator::operator()(Orbital bra, Orbital ket) { - RankTwoOperator &O = *this; + std::cout<<" RankTwoOperator "< &O = *this; ComplexMatrix out(I, J); for (int i = 0; i < I; i++) out.row(i) = O[i](bra, ket); + std::cout<<" RankTwoOperator done "< ComplexMatrix RankTwoOperator::trace(OrbitalVector } template ComplexMatrix RankTwoOperator::trace(OrbitalVector &phi, OrbitalVector &x, OrbitalVector &y) { + std::cout<<" ARankTwoOperator "< &O = *this; ComplexMatrix out(I, J); for (int i = 0; i < I; i++) out.row(i) = O[i].trace(phi, x, y); @@ -52,6 +55,7 @@ template ComplexMatrix RankTwoOperator::trace(OrbitalVector } template ComplexMatrix RankTwoOperator::trace(const Nuclei &nucs) { + std::cout<<" BRankTwoOperator "< &O = *this; ComplexMatrix out(I, J); for (int i = 0; i < I; i++) out.row(i) = O[i].trace(nucs); diff --git a/src/tensor/RankZeroOperator.cpp b/src/tensor/RankZeroOperator.cpp index c204e208e..55502b171 100644 --- a/src/tensor/RankZeroOperator.cpp +++ b/src/tensor/RankZeroOperator.cpp @@ -201,7 +201,8 @@ RankZeroOperator &RankZeroOperator::operator-=(const RankZeroOperator &O) { void RankZeroOperator::setup(double prec) { for (auto &i : this->oper_exp) { for (int j = 0; j < i.size(); j++) { - i[j]->setup(prec); } + i[j]->setup(prec); + } } } @@ -239,6 +240,7 @@ ComplexDouble RankZeroOperator::dagger(const mrcpp::Coord<3> &r) const { * Applies each term of the operator expansion to the input orbital. First all * components of each term are applied consecutively, then the output of each term * is added upp with the corresponding coefficient. + * NB: the result is put at the same location as the input (out and inp trees are the same tree) */ Orbital RankZeroOperator::operator()(Orbital inp) { if (inp.getNNodes() == 0) return inp.paramCopy(); @@ -475,23 +477,26 @@ ComplexDouble RankZeroOperator::trace(const Nuclei &nucs) { * This consecutively applies all components of a particular term of the operator * expansion to the input orbital. */ -Orbital RankZeroOperator::applyOperTerm(int n, Orbital inp) { +Orbital RankZeroOperator::applyOperTerm(int n, const Orbital& inp) { if (n >= this->oper_exp.size()) MSG_ABORT("Invalid oper term"); - if (inp.getNNodes() == 0) return inp.paramCopy(); + Orbital out; + mrcpp::deep_copy(out, inp); - Orbital out = inp; - for (auto O_nm : this->oper_exp[n]) { + if (inp.getNNodes() == 0) return out; + int i=0; + for (auto O_nm : this->oper_exp[n]) { if (O_nm == nullptr) MSG_ABORT("Invalid oper term"); out = O_nm->apply(out); } return out; } -Orbital RankZeroOperator::daggerOperTerm(int n, Orbital inp) { +Orbital RankZeroOperator::daggerOperTerm(int n, const Orbital& inp) { if (n >= this->oper_exp.size()) MSG_ABORT("Invalid oper term"); - if (inp.getNNodes() == 0) return inp.paramCopy(); + Orbital out; + mrcpp::deep_copy(out, inp); + if (inp.getNNodes() == 0) return out; - Orbital out = inp; for (int i = this->oper_exp[n].size() - 1; i >= 0; i--) { auto O_nm = this->oper_exp[n][i]; if (O_nm == nullptr) MSG_ABORT("Invalid oper term"); diff --git a/src/tensor/RankZeroOperator.h b/src/tensor/RankZeroOperator.h index 1403afbd8..2468a1894 100644 --- a/src/tensor/RankZeroOperator.h +++ b/src/tensor/RankZeroOperator.h @@ -119,8 +119,8 @@ class RankZeroOperator { std::vector coef_exp; std::vector oper_exp; - Orbital applyOperTerm(int n, Orbital inp); - Orbital daggerOperTerm(int n, Orbital inp); + Orbital applyOperTerm(int n, const Orbital& inp); + Orbital daggerOperTerm(int n, const Orbital& inp); ComplexDouble traceOperTerm(int n, const Nuclei &nucs); std::vector getCoefVector() const; }; diff --git a/src/utils/RRMaximizer.cpp b/src/utils/RRMaximizer.cpp index ba08b92e4..6923134ed 100644 --- a/src/utils/RRMaximizer.cpp +++ b/src/utils/RRMaximizer.cpp @@ -64,7 +64,7 @@ RRMaximizer::RRMaximizer(double prec, OrbitalVector &Phi) { R_x = orbital::calc_overlap_matrix(Phi, xPhi_Vec); for (int i = 0; i < Phi.size(); i++) { if(!mrcpp::mpi::my_func(i)) continue; - xPhi_Vec[i].free(NUMBER::Total); + xPhi_Vec[i].free(); } OrbitalVector yPhi_Vec = r_y(Phi); @@ -72,7 +72,7 @@ RRMaximizer::RRMaximizer(double prec, OrbitalVector &Phi) { R_y = orbital::calc_overlap_matrix(Phi, yPhi_Vec); for (int i = 0; i < Phi.size(); i++) { if(!mrcpp::mpi::my_func(i)) continue; - yPhi_Vec[i].free(NUMBER::Total); + yPhi_Vec[i].free(); } OrbitalVector zPhi_Vec = r_z(Phi); @@ -80,7 +80,7 @@ RRMaximizer::RRMaximizer(double prec, OrbitalVector &Phi) { R_z = orbital::calc_overlap_matrix(Phi, zPhi_Vec); for (int i = 0; i < Phi.size(); i++) { if(!mrcpp::mpi::my_func(i)) continue; - zPhi_Vec[i].free(NUMBER::Total); + zPhi_Vec[i].free(); } for (int i = 0; i < this->N; i++) { diff --git a/tests/qmfunctions/orbital_vector.cpp b/tests/qmfunctions/orbital_vector.cpp index 93ca6a237..28c75c247 100644 --- a/tests/qmfunctions/orbital_vector.cpp +++ b/tests/qmfunctions/orbital_vector.cpp @@ -287,10 +287,9 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { OrbitalVector Psi; Psi.push_back(Orbital(SPIN::Alpha)); Psi.push_back(Orbital(SPIN::Beta)); - Psi.distribute(); - if (mrcpp::mpi::my_func(Psi[0])) mrcpp::project(Psi[0], static_cast &r)>>(f5), prec); - if (mrcpp::mpi::my_func(Psi[1])) mrcpp::project(Psi[1], static_cast &r)>>(f6), prec); + if (mrcpp::mpi::my_func(Psi[0])) mrcpp::project(Psi[0], static_cast &r)>>(f5), prec); + if (mrcpp::mpi::my_func(Psi[1])) mrcpp::project(Psi[1], static_cast &r)>>(f6), prec); orthogonalize(prec, Phi); orthogonalize(prec, Psi, Phi); diff --git a/tests/qmfunctions/qmfunction.cpp b/tests/qmfunctions/qmfunction.cpp index ac272e103..3313c3547 100644 --- a/tests/qmfunctions/qmfunction.cpp +++ b/tests/qmfunctions/qmfunction.cpp @@ -220,7 +220,7 @@ TEST_CASE("QMFunction", "[qmfunction]") { ComplexDouble c(0.5, 0.5); mrcpp::CompFunction func_h; SECTION("with complex scalar") { - mrcpp::add(func_h, c, f_re, c, f_im, -1.0); + mrcpp::add(func_h, c, f_re, c, f_im, -1.0); REQUIRE(func_h.integrate().real() == Approx(std::real(std::real(c)*f_re.integrate() - std::imag(c)*std::imag(f_im.integrate())))); REQUIRE(func_h.integrate().imag() == Approx(std::real(std::imag(c)*f_re.integrate() + std::real(c)*std::imag(f_im.integrate())))); } diff --git a/tests/qmoperators/coulomb_operator.cpp b/tests/qmoperators/coulomb_operator.cpp index 9e20a8e49..4c98e79aa 100644 --- a/tests/qmoperators/coulomb_operator.cpp +++ b/tests/qmoperators/coulomb_operator.cpp @@ -65,19 +65,18 @@ TEST_CASE("CoulombOperator", "[coulomb_operator]") { } } } - Phi.distribute(); for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); - if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); + if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } int i = 0; DoubleMatrix E_P = DoubleMatrix::Zero(Phi.size(), Phi.size()); E_P(0, 0) = 3.1676468518; - E_P(0, 1) = 0.262570199; - E_P(1, 0) = 0.262570199; + E_P(0, 1) = 0.262570192; + E_P(1, 0) = 0.262570192; E_P(1, 1) = 1.6980679074; E_P(2, 2) = 1.8983578764; E_P(3, 3) = 1.8983578764; @@ -86,7 +85,7 @@ TEST_CASE("CoulombOperator", "[coulomb_operator]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + ComplexDouble V_00 = mrcpp::dot(Phi[0],Vphi_0); if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); diff --git a/tests/qmoperators/identity_operator.cpp b/tests/qmoperators/identity_operator.cpp index 7fc9ceb82..fd2df2810 100644 --- a/tests/qmoperators/identity_operator.cpp +++ b/tests/qmoperators/identity_operator.cpp @@ -36,14 +36,15 @@ using namespace orbital; namespace identity_operator_tests { -auto f = [](const mrcpp::Coord<3> &r) -> double { +ComplexDouble i1 = {0.0, 1.0}; +auto f = [](const mrcpp::Coord<3> &r) -> ComplexDouble { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); return std::exp(-1.0 * R * R); }; -auto g = [](const mrcpp::Coord<3> &r) -> double { +auto g = [](const mrcpp::Coord<3> &r) -> ComplexDouble { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); - return std::exp(-2.0 * R * R); + return std::exp(-2.0 * R * R) * i1; }; TEST_CASE("IdentityOperator", "[identity_operator]") { @@ -52,26 +53,28 @@ TEST_CASE("IdentityOperator", "[identity_operator]") { SECTION("apply") { Orbital phi(SPIN::Paired); - mrcpp::project(phi, static_cast &r)>>(f), prec); - mrcpp::project(phi, static_cast &r)>>(g), prec); + Orbital psi(SPIN::Paired); + mrcpp::project(phi, f, prec); + mrcpp::project(psi, g, prec); + mrcpp::CompFunction func_h; + ComplexDouble c(1.0, 0.0); + mrcpp::add(func_h, c, phi, c, psi, -1.0); IdentityOperator I; I.setup(prec); - Orbital Iphi = I(phi); + Orbital Iphi = I(func_h); I.clear(); - REQUIRE(Iphi.integrate().real() == Approx(phi.integrate().real())); - REQUIRE(Iphi.integrate().imag() == Approx(phi.integrate().imag())); + REQUIRE(Iphi.integrate().imag() == Approx(psi.integrate().imag())); } SECTION("vector apply") { OrbitalVector Phi; Phi.push_back(Orbital(SPIN::Paired)); Phi.push_back(Orbital(SPIN::Paired)); - Phi.distribute(); - if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], static_cast &r)>>(f), prec); - if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], static_cast &r)>>(g), prec); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], f, prec); + if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], g, prec); normalize(Phi); IdentityOperator I; @@ -96,8 +99,8 @@ TEST_CASE("IdentityOperator", "[identity_operator]") { SECTION("expectation value") { Orbital phi(SPIN::Paired); - mrcpp::project(phi, static_cast &r)>>(f), prec); - mrcpp::project(phi, static_cast &r)>>(g), prec); + mrcpp::project(phi, f, prec); + mrcpp::project(phi, g, prec); IdentityOperator I; I.setup(prec); @@ -112,12 +115,12 @@ TEST_CASE("IdentityOperator", "[identity_operator]") { OrbitalVector Phi; Phi.push_back(Orbital(SPIN::Paired)); Phi.push_back(Orbital(SPIN::Paired)); - Phi.distribute(); - if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], static_cast &r)>>(f), prec); - if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], static_cast &r)>>(g), prec); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], f, prec); + if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], g, prec); IdentityOperator I; + I.setup(prec); ComplexMatrix S = I(Phi, Phi); I.clear(); diff --git a/tests/qmoperators/kinetic_operator.cpp b/tests/qmoperators/kinetic_operator.cpp index c417af5e4..625fb4f68 100644 --- a/tests/qmoperators/kinetic_operator.cpp +++ b/tests/qmoperators/kinetic_operator.cpp @@ -46,7 +46,6 @@ TEST_CASE("KineticOperator", "[kinetic_operator]") { int nFuncs = 3; OrbitalVector Phi; for (int n = 0; n < nFuncs; n++) Phi.push_back(Orbital(SPIN::Paired)); - Phi.distribute(); for (int n = 0; n < nFuncs; n++) { int nu[3] = {n, 0, 0}; diff --git a/tests/qmoperators/momentum_operator.cpp b/tests/qmoperators/momentum_operator.cpp index 9c25f6a0c..7611adeb3 100644 --- a/tests/qmoperators/momentum_operator.cpp +++ b/tests/qmoperators/momentum_operator.cpp @@ -46,7 +46,6 @@ TEST_CASE("MomentumOperator", "[momentum_operator]") { int nFuncs = 3; OrbitalVector Phi; for (int n = 0; n < nFuncs; n++) Phi.push_back(Orbital(SPIN::Paired)); - Phi.distribute(); for (int n = 0; n < nFuncs; n++) { int nu[3] = {n, 0, 0}; diff --git a/tests/qmoperators/operator_composition.cpp b/tests/qmoperators/operator_composition.cpp index f62e75cd2..aa0c2fb31 100644 --- a/tests/qmoperators/operator_composition.cpp +++ b/tests/qmoperators/operator_composition.cpp @@ -53,7 +53,7 @@ TEST_CASE("Operator composition", "[operator_composition]") { Phi.push_back(Orbital{SPIN::Alpha}); Phi.push_back(Orbital{SPIN::Alpha}); Phi.push_back(Orbital{SPIN::Alpha}); - Phi.distribute(); + for (int i = 0; i < 3; i++) { int nu[3] = {i, 0, 0}; HarmonicOscillatorFunction f(nu); @@ -124,7 +124,7 @@ TEST_CASE("Operator composition", "[operator_composition]") { REQUIRE(val(0, 1).real() == Approx(ref(0, 1).real()).margin(thrs)); REQUIRE(val(0, 1).imag() == Approx(ref(0, 1).imag()).epsilon(thrs)); ID.clear(); - } + } SECTION("composition I(D)") { MomentumOperator D(std::make_shared>(*MRA, 0.5, 0.5)); RankZeroOperator ID = I(D[0]); @@ -229,8 +229,8 @@ TEST_CASE("Operator composition", "[operator_composition]") { REQUIRE(val(0, 0).real() == Approx(ref.real()).margin(thrs)); REQUIRE(val(0, 0).imag() == Approx(ref.imag()).epsilon(thrs)); VD.clear(); - } - SECTION("composition V(D)") { + } + SECTION("composition V(D)") { MomentumOperator D(std::make_shared>(*MRA, 0.5, 0.5)); RankZeroOperator VD = V[0](D[0]); REQUIRE(VD.size() == 1); @@ -389,7 +389,7 @@ TEST_CASE("Operator composition", "[operator_composition]") { REQUIRE(val(0, 0).real() == Approx(ref.real()).margin(thrs)); REQUIRE(val(0, 0).imag() == Approx(ref.imag()).epsilon(thrs)); SI.clear(); - } + } SECTION("composition S(I)") { IdentityOperator I; RankZeroOperator SI = S[1](I); @@ -496,7 +496,7 @@ TEST_CASE("Operator composition", "[operator_composition]") { gradV.setup(prec); if (mrcpp::mpi::my_func(Phi[0])) { - OrbitalVector dPhi_0 = gradV(Phi[0]); + std::vector dPhi_0 = gradV(Phi[0]); REQUIRE(dPhi_0.size() == 3); REQUIRE(dPhi_0[0].norm() == Approx(1.0).epsilon(thrs)); REQUIRE(dPhi_0[1].norm() == Approx(0.0).margin(thrs)); @@ -527,7 +527,7 @@ TEST_CASE("Operator composition", "[operator_composition]") { REQUIRE(curlV[i].size() == 2); REQUIRE(curlV[i].size(0) == 1); REQUIRE(curlV[i].size(1) == 1); - OrbitalVector Psi = curlV[i](Phi); + OrbitalVector Psi = curlV[i](Phi); const DoubleVector val = orbital::get_norms(Psi); for (int n = 0; n < Psi.size(); n++) REQUIRE(val(n) == Approx(0.0).margin(thrs)); } diff --git a/tests/qmoperators/position_operator.cpp b/tests/qmoperators/position_operator.cpp index e0b6fc9ed..18197306b 100644 --- a/tests/qmoperators/position_operator.cpp +++ b/tests/qmoperators/position_operator.cpp @@ -44,14 +44,12 @@ TEST_CASE("PositionOperator", "[position_operator]") { int nFuncs = 3; OrbitalVector Phi; for (int n = 0; n < nFuncs; n++) Phi.push_back(Orbital(SPIN::Paired)); - Phi.distribute(); for (int n = 0; n < nFuncs; n++) { int nu[3] = {n, 0, 0}; HarmonicOscillatorFunction f(nu); if (mrcpp::mpi::my_func(Phi[n])) mrcpp::project(Phi[n], f, prec); } - // reference values for harmonic oscillator eigenfunctions DoubleMatrix ref(nFuncs, nFuncs); for (int i = 0; i < nFuncs; i++) { diff --git a/tests/qmoperators/xc_hessian_lda.cpp b/tests/qmoperators/xc_hessian_lda.cpp index 738648a1f..09f490478 100644 --- a/tests/qmoperators/xc_hessian_lda.cpp +++ b/tests/qmoperators/xc_hessian_lda.cpp @@ -73,8 +73,6 @@ TEST_CASE("XCHessianLDA", "[xc_hessian_lda]") { ms.push_back(0); Phi.push_back(Orbital(SPIN::Paired)); - Phi.distribute(); - for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); @@ -95,8 +93,6 @@ TEST_CASE("XCHessianLDA", "[xc_hessian_lda]") { ms_x.push_back(1); Phi_x.push_back(Orbital(SPIN::Paired)); - Phi_x.distribute(); - for (int i = 0; i < Phi_x.size(); i++) { HydrogenFunction f(ns_x[i], ls_x[i], ms_x[i]); if (mrcpp::mpi::my_func(Phi_x[i])) mrcpp::project(Phi_x[i], f, prec); @@ -113,7 +109,7 @@ TEST_CASE("XCHessianLDA", "[xc_hessian_lda]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + ComplexDouble V_00 = mrcpp::dot(Phi[0], Vphi_0); if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); @@ -125,7 +121,7 @@ TEST_CASE("XCHessianLDA", "[xc_hessian_lda]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + ComplexDouble V_ii = mrcpp::dot(Phi[i], VPhi[i]); if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); diff --git a/tests/qmoperators/xc_operator_blyp.cpp b/tests/qmoperators/xc_operator_blyp.cpp index e72ad271b..4e83a5a5a 100644 --- a/tests/qmoperators/xc_operator_blyp.cpp +++ b/tests/qmoperators/xc_operator_blyp.cpp @@ -82,16 +82,14 @@ TEST_CASE("XCOperatorBLYP", "[xc_operator_blyp]") { if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); } - // reference values obtained with a test run at order=9 in unit_test.cpp and prec=1.0e-5 here - DoubleMatrix E_P = DoubleMatrix::Zero(Phi.size(), Phi.size()); - E_P(0, 0) = -0.4632575525; - E_P(0, 1) = -0.0654671939; - E_P(1, 0) = -0.0654671939; - E_P(1, 1) = -0.1793901783; - E_P(2, 2) = -0.1988746865; - E_P(3, 3) = -0.1988746865; - E_P(4, 4) = -0.1988746865; + E_P(0, 0) = -0.4630476513; + E_P(0, 1) = -0.0654140779; + E_P(1, 0) = -0.0654140779;; + E_P(1, 1) = -0.1793674201; + E_P(2, 2) = -0.1988517872; + E_P(3, 3) = -0.1988517872; + E_P(4, 4) = -0.1988517872; V.setup(prec); SECTION("apply") { diff --git a/tests/qmoperators/xc_operator_lda.cpp b/tests/qmoperators/xc_operator_lda.cpp index a41f1b06a..1efa64086 100644 --- a/tests/qmoperators/xc_operator_lda.cpp +++ b/tests/qmoperators/xc_operator_lda.cpp @@ -75,8 +75,6 @@ TEST_CASE("[XCOperatorLDA]", "[xc_operator_lda]") { } } - Phi.distribute(); - for (int i = 0; i < Phi.size(); i++) { HydrogenFunction f(ns[i], ls[i], ms[i]); if (mrcpp::mpi::my_func(Phi[i])) mrcpp::project(Phi[i], f, prec); @@ -85,9 +83,9 @@ TEST_CASE("[XCOperatorLDA]", "[xc_operator_lda]") { // reference values obtained with a test run at order=9 in unit_test.cpp and prec=1.0e-5 here DoubleMatrix E_P = DoubleMatrix::Zero(Phi.size(), Phi.size()); - E_P(0, 0) = -0.4574999901; - E_P(0, 1) = -0.0593789497; - E_P(1, 0) = -0.0593789497; + E_P(0, 0) = -0.457499976; + E_P(0, 1) = -0.0593789451; + E_P(1, 0) = -0.0593789451; E_P(1, 1) = -0.1894199551; E_P(2, 2) = -0.2109971956; E_P(3, 3) = -0.2109971956; @@ -96,7 +94,7 @@ TEST_CASE("[XCOperatorLDA]", "[xc_operator_lda]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + ComplexDouble V_00 = mrcpp::dot(Phi[0], Vphi_0); if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); @@ -108,7 +106,7 @@ TEST_CASE("[XCOperatorLDA]", "[xc_operator_lda]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + ComplexDouble V_ii = mrcpp::dot(Phi[i], VPhi[i]); if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); diff --git a/tests/solventeffect/reaction_operator.cpp b/tests/solventeffect/reaction_operator.cpp index b9a83647b..c0a0e3c5c 100644 --- a/tests/solventeffect/reaction_operator.cpp +++ b/tests/solventeffect/reaction_operator.cpp @@ -81,7 +81,6 @@ TEST_CASE("ReactionOperator", "[reaction_operator]") { auto Phi_p = std::make_shared(); auto &Phi = *Phi_p; Phi.push_back(Orbital(SPIN::Paired)); - Phi.distribute(); // project analytic 1s orbital HydrogenFunction f(1, 0, 0); From 66947ac10cf5c7137bad3ab5d366aece986c26c9 Mon Sep 17 00:00:00 2001 From: gitpeterwind Date: Fri, 23 Aug 2024 17:36:24 +0200 Subject: [PATCH 5/8] all tests passes --- src/driver.cpp | 8 ++--- src/environment/GPESolver.cpp | 36 +++++++++++-------- src/environment/PBESolver.cpp | 7 ++-- src/initial_guess/cube.cpp | 2 +- src/initial_guess/mw.cpp | 2 +- src/qmfunctions/orbital_utils.cpp | 4 +-- .../one_electron/DistanceOperator.h | 2 +- .../one_electron/NuclearOperator.cpp | 2 +- .../two_electron/CoulombPotential.cpp | 4 +-- .../two_electron/CoulombPotential.h | 2 +- .../two_electron/ExchangePotentialD1.cpp | 2 +- .../two_electron/ExchangePotentialD2.cpp | 8 ++--- .../two_electron/XCPotentialD1.cpp | 10 +++--- .../two_electron/XCPotentialD2.cpp | 24 ++++++------- src/scf_solver/Accelerator.cpp | 2 +- tests/qmfunctions/qmfunction.cpp | 10 +++--- tests/qmoperators/identity_operator.cpp | 2 +- tests/qmoperators/operator_composition.cpp | 8 ++--- tests/qmoperators/xc_hessian_lda.cpp | 4 +-- tests/qmoperators/xc_hessian_pbe.cpp | 8 ++--- tests/solventeffect/PB_solver.cpp | 2 -- tests/solventeffect/reaction_operator.cpp | 3 +- 22 files changed, 79 insertions(+), 73 deletions(-) diff --git a/src/driver.cpp b/src/driver.cpp index 187a321b3..fc3ce8ea6 100644 --- a/src/driver.cpp +++ b/src/driver.cpp @@ -622,7 +622,7 @@ void driver::scf::plot_quantities(const json &json_plot, Molecule &mol) { if (line) plt.linePlot(npts, rho, fname); if (surf) plt.surfPlot(npts, rho, fname); if (cube) plt.cubePlot(npts, rho, fname); - rho.free(NUMBER::Total); + rho.free(); mrcpp::print::time(1, fname, t_lap); if (orbital::size_singly(Phi) > 0) { @@ -633,7 +633,7 @@ void driver::scf::plot_quantities(const json &json_plot, Molecule &mol) { if (surf) plt.surfPlot(npts, rho, fname); if (cube) plt.cubePlot(npts, rho, fname); mrcpp::print::time(1, fname, t_lap); - rho.free(NUMBER::Total); + rho.free(); t_lap.start(); fname = path + "/rho_a"; @@ -642,7 +642,7 @@ void driver::scf::plot_quantities(const json &json_plot, Molecule &mol) { if (surf) plt.surfPlot(npts, rho, fname); if (cube) plt.cubePlot(npts, rho, fname); mrcpp::print::time(1, fname, t_lap); - rho.free(NUMBER::Total); + rho.free(); t_lap.start(); fname = path + "/rho_b"; @@ -650,7 +650,7 @@ void driver::scf::plot_quantities(const json &json_plot, Molecule &mol) { if (line) plt.linePlot(npts, rho, fname); if (surf) plt.surfPlot(npts, rho, fname); if (cube) plt.cubePlot(npts, rho, fname); - rho.free(NUMBER::Total); + rho.free(); mrcpp::print::time(1, fname, t_lap); } } diff --git a/src/environment/GPESolver.cpp b/src/environment/GPESolver.cpp index 743850a6a..5e214b8ba 100644 --- a/src/environment/GPESolver.cpp +++ b/src/environment/GPESolver.cpp @@ -60,7 +60,7 @@ GPESolver::GPESolver(const Permittivity &e, const Density &rho_nuc, PoissonOpera , poisson(P) {} GPESolver::~GPESolver() { - this->rho_nuc.free(NUMBER::Real); + this->rho_nuc.free(); clear(); } @@ -95,7 +95,6 @@ void GPESolver::computeDensities(const Density &rho_el, Density &rho_out) { } void GPESolver::computeGamma(mrcpp::CompFunction<3> &potential, mrcpp::CompFunction<3> &out_gamma) { - auto d_V = mrcpp::gradient(*derivative, potential.real()); // FunctionTreeVector resetComplexFunction(out_gamma); @@ -103,7 +102,9 @@ void GPESolver::computeGamma(mrcpp::CompFunction<3> &potential, mrcpp::CompFunct auto C_pin = this->epsilon.getCavity_p(); mrcpp::AnalyticFunction<3> d_cav(C_pin->getGradVector()[d]); mrcpp::CompFunction<3> cplxfunc_prod; - mrcpp::multiply(cplxfunc_prod, get_func(d_V, d), d_cav, this->apply_prec, 1); + + mrcpp::FunctionTree<3, double>& Tree = get_func(d_V, d); + mrcpp::multiply(cplxfunc_prod, Tree, d_cav, this->apply_prec, 1); // add result into out_gamma if (d == 0) { mrcpp::deep_copy(out_gamma, cplxfunc_prod); @@ -121,7 +122,8 @@ mrcpp::CompFunction<3> GPESolver::solvePoissonEquation(const mrcpp::CompFunction mrcpp::CompFunction<3> rho_eff; mrcpp::CompFunction<3> first_term; mrcpp::CompFunction<3> Vr_np1; - Vr_np1.alloc(NUMBER::Real); + Vr_np1.func_ptr->isreal = 1; + Vr_np1.alloc(0); auto eps_inv_func = mrcpp::AnalyticFunction<3>([this](const mrcpp::Coord<3> &r) { return 1.0 / this->epsilon.evalf(r); }); Density rho_tot(false); @@ -130,7 +132,7 @@ mrcpp::CompFunction<3> GPESolver::solvePoissonEquation(const mrcpp::CompFunction mrcpp::multiply(first_term, rho_tot, eps_inv_func, this->apply_prec); mrcpp::add(rho_eff, 1.0, first_term, -1.0, rho_tot, -1.0); - rho_tot.free(NUMBER::Real); + rho_tot.free(); mrcpp::add(Poisson_func, 1.0, in_gamma, 1.0, rho_eff, -1.0); mrcpp::apply(this->apply_prec, Vr_np1.real(), *poisson, Poisson_func.real()); @@ -183,14 +185,14 @@ void GPESolver::runMicroIterations(const mrcpp::CompFunction<3> &V_vac, const De if (iter > 1 and this->history > 0) { accelerateConvergence(dVr_n, Vr_n, kain); - Vr_np1.free(NUMBER::Real); + Vr_np1.free(); mrcpp::add(Vr_np1, 1.0, Vr_n, 1.0, dVr_n, -1.0); } // set up for next iteration resetComplexFunction(this->Vr_n); mrcpp::deep_copy(this->Vr_n, Vr_np1); - Vr_np1.free(NUMBER::Real); + Vr_np1.free(); printConvergenceRow(iter, norm, update, t_iter.elapsed()); @@ -235,19 +237,23 @@ mrcpp::CompFunction<3> &GPESolver::solveEquation(double prec, const Density &rho computeDensities(rho_el, rho_tot); Timer t_vac; mrcpp::CompFunction<3> V_vac; - V_vac.alloc(NUMBER::Real); + V_vac.func_ptr->isreal = 1; + V_vac.alloc(0); mrcpp::apply(this->apply_prec, V_vac.real(), *poisson, rho_tot.real()); - rho_tot.free(NUMBER::Real); + rho_tot.free(); print_utils::qmfunction(3, "Vacuum potential", V_vac, t_vac); // set up the zero-th iteration potential and gamma, so the first iteration gamma and potentials can be made Timer t_gamma; - if (not this->Vr_n.hasReal()) { - mrcpp::CompFunction<3> gamma_0; - mrcpp::CompFunction<3> V_tot; - computeGamma(V_vac, gamma_0); - this->Vr_n = solvePoissonEquation(gamma_0, rho_el); + if (Vr_n.Ncomp() == 0) { + mrcpp::CompFunction<3> gamma_0; + mrcpp::CompFunction<3> V_tot; + gamma_0.func_ptr->isreal = 1; + gamma_0.alloc(0); + + computeGamma(V_vac, gamma_0); + this->Vr_n = solvePoissonEquation(gamma_0, rho_el); } // update the potential/gamma before doing anything with them @@ -265,6 +271,8 @@ auto GPESolver::computeEnergies(const Density &rho_el) -> std::tuple &function) { + function.func_ptr->isreal = 1; + function.func_ptr->iscomplex = 0; function.alloc(0); } diff --git a/src/environment/PBESolver.cpp b/src/environment/PBESolver.cpp index 502d814a0..5ea02e2ae 100644 --- a/src/environment/PBESolver.cpp +++ b/src/environment/PBESolver.cpp @@ -62,7 +62,8 @@ void PBESolver::computePBTerm(mrcpp::CompFunction<3> &V_tot, const double salt_f auto sinh_f = [salt_factor](const double &V) { return (salt_factor / (4.0 * mrcpp::pi)) * std::sinh(V); }; resetComplexFunction(pb_term); mrcpp::CompFunction<3> sinhV; - sinhV.alloc(NUMBER::Real); + sinhV.func_ptr->isreal = 1; + sinhV.alloc(0); mrcpp::map(this->apply_prec / 100, sinhV.real(), V_tot.real(), sinh_f); mrcpp::multiply(pb_term, sinhV, this->kappa, this->apply_prec); @@ -77,7 +78,8 @@ void PBESolver::computeGamma(mrcpp::CompFunction<3> &potential, mrcpp::CompFunct auto C_pin = this->epsilon.getCavity_p(); mrcpp::AnalyticFunction<3> d_cav(C_pin->getGradVector()[d]); mrcpp::CompFunction<3> cplxfunc_prod; - mrcpp::multiply(cplxfunc_prod, get_func(d_V, d), d_cav, this->apply_prec, 1); + mrcpp::FunctionTree<3, double>& Tree = get_func(d_V, d); + mrcpp::multiply(cplxfunc_prod, Tree, d_cav, this->apply_prec, 1); // add result into out_gamma if (d == 0) { mrcpp::deep_copy(out_gamma, cplxfunc_prod); @@ -85,7 +87,6 @@ void PBESolver::computeGamma(mrcpp::CompFunction<3> &potential, mrcpp::CompFunct out_gamma.add(1.0, cplxfunc_prod); } } - out_gamma.rescale(std::log((epsilon.getValueIn() / epsilon.getValueOut())) * (1.0 / (4.0 * mrcpp::pi))); mrcpp::clear(d_V, true); diff --git a/src/initial_guess/cube.cpp b/src/initial_guess/cube.cpp index a9c2681cc..a199df375 100644 --- a/src/initial_guess/cube.cpp +++ b/src/initial_guess/cube.cpp @@ -120,7 +120,7 @@ bool initial_guess::cube::project_mo(OrbitalVector &Phi, double prec, const std: Timer t_i; if (mrcpp::mpi::my_func(Phi[i])) { CUBEfunction phi_i = CUBEVector[i]; - Phi[i].alloc(NUMBER::Real); + Phi[i].alloc(0); mrcpp::project(prec, Phi[i].real(), phi_i); std::stringstream o_txt; o_txt << std::setw(w1 - 1) << i; diff --git a/src/initial_guess/mw.cpp b/src/initial_guess/mw.cpp index 2012511a3..89660b675 100644 --- a/src/initial_guess/mw.cpp +++ b/src/initial_guess/mw.cpp @@ -110,7 +110,7 @@ bool initial_guess::mw::project_mo(OrbitalVector &Phi, double prec, const std::s Orbital phi_i; orbital::loadOrbital(orbname.str(), phi_i); - if (phi_i.squaredNorm() < 0.0) { + if (phi_i.getSquareNorm() < 0.0) { MSG_ERROR("Guess orbital not found: " << orbname.str()); success &= false; } diff --git a/src/qmfunctions/orbital_utils.cpp b/src/qmfunctions/orbital_utils.cpp index bdb60ccd6..a594213b1 100644 --- a/src/qmfunctions/orbital_utils.cpp +++ b/src/qmfunctions/orbital_utils.cpp @@ -500,7 +500,7 @@ void orbital::normalize(OrbitalVector &Phi) { /** @brief In place orthogonalize against inp. Private function. */ void orbital::orthogonalize(double prec, Orbital &&phi, Orbital psi) { ComplexDouble overlap = orbital::dot(psi, phi); - double sq_norm = psi.squaredNorm(); + double sq_norm = psi.getSquareNorm(); if (std::abs(overlap) > prec) phi.add(-1.0 * overlap / sq_norm, psi); } @@ -1016,7 +1016,7 @@ DoubleVector orbital::get_squared_norms(const OrbitalVector &Phi) { int nOrbs = Phi.size(); DoubleVector norms = DoubleVector::Zero(nOrbs); for (int i = 0; i < nOrbs; i++) { - if (mrcpp::mpi::my_func(Phi[i])) norms(i) = Phi[i].squaredNorm(); + if (mrcpp::mpi::my_func(Phi[i])) norms(i) = Phi[i].getSquareNorm(); } mrcpp::mpi::allreduce_vector(norms, mrcpp::mpi::comm_wrk); return norms; diff --git a/src/qmoperators/one_electron/DistanceOperator.h b/src/qmoperators/one_electron/DistanceOperator.h index f0851f5d6..8988a1345 100644 --- a/src/qmoperators/one_electron/DistanceOperator.h +++ b/src/qmoperators/one_electron/DistanceOperator.h @@ -57,7 +57,7 @@ class DistanceOperator final : public RankZeroOperator { // Project analytic potential, building grid for 1/r auto r_pow = std::make_shared(1); - r_pow->alloc(NUMBER::Real); + r_pow->alloc(0); mrcpp::build_grid(r_pow->real(), nuc_func); mrcpp::project<3>(proj_prec, r_pow->real(), f); diff --git a/src/qmoperators/one_electron/NuclearOperator.cpp b/src/qmoperators/one_electron/NuclearOperator.cpp index 5926d11f1..bbb259eb0 100644 --- a/src/qmoperators/one_electron/NuclearOperator.cpp +++ b/src/qmoperators/one_electron/NuclearOperator.cpp @@ -170,7 +170,7 @@ void NuclearOperator::allreducePotential(double prec, mrcpp::CompFunction<3> &V_ if (mrcpp::mpi::numerically_exact) V_loc.crop(prec); } - if (not V_tot.hasReal()) V_tot.alloc(NUMBER::Real); + if (not V_tot.hasReal()) V_tot.alloc(0); if (V_tot.isShared()) { int tag = 3141; // MPI grand master distributes to shared masters diff --git a/src/qmoperators/two_electron/CoulombPotential.cpp b/src/qmoperators/two_electron/CoulombPotential.cpp index 7b9be8fb2..89cc0bfb9 100644 --- a/src/qmoperators/two_electron/CoulombPotential.cpp +++ b/src/qmoperators/two_electron/CoulombPotential.cpp @@ -151,7 +151,7 @@ mrcpp::CompFunction<3> CoulombPotential::setupLocalPotential(double prec) { Timer timer; mrcpp::CompFunction<3> V(false); - V.alloc(NUMBER::Real); + V.alloc(0); mrcpp::apply(abs_prec, V.real(), P, rho.real()); print_utils::qmfunction(3, "Compute local potential", V, timer); @@ -169,7 +169,7 @@ void CoulombPotential::allreducePotential(double prec, mrcpp::CompFunction<3> &V // Add up local contributions into the grand master mrcpp::mpi::reduce_function(abs_prec, V_loc, mrcpp::mpi::comm_wrk); - if (not V_tot.hasReal()) V_tot.alloc(NUMBER::Real); + if (not V_tot.hasReal()) V_tot.alloc(0); if (V_tot.isShared()) { int tag = 3141; // MPI grand master distributes to shared masters diff --git a/src/qmoperators/two_electron/CoulombPotential.h b/src/qmoperators/two_electron/CoulombPotential.h index d26b54cfd..629275ad0 100644 --- a/src/qmoperators/two_electron/CoulombPotential.h +++ b/src/qmoperators/two_electron/CoulombPotential.h @@ -65,7 +65,7 @@ class CoulombPotential : public QMPotential { auto &getPoisson() { return this->poisson; } auto &getDensity() { return this->density; } - bool hasDensity() const { return (this->density.squaredNorm() <= 0.0) ? false : true; } + bool hasDensity() const { return (this->density.getSquareNorm() <= 0.0) ? false : true; } void setup(double prec) override; void clear() override; diff --git a/src/qmoperators/two_electron/ExchangePotentialD1.cpp b/src/qmoperators/two_electron/ExchangePotentialD1.cpp index fb7037b85..514631b6d 100644 --- a/src/qmoperators/two_electron/ExchangePotentialD1.cpp +++ b/src/qmoperators/two_electron/ExchangePotentialD1.cpp @@ -428,7 +428,7 @@ Orbital ExchangePotentialD1::calcExchange(Orbital phi_p) { if (std::abs(spin_fac) >= mrcpp::MachineZero) { Orbital ex_iip = phi_p.paramCopy(); calcExchange_kij(precf, phi_i, phi_i, phi_p, ex_iip); - coef_vec.push_back(spin_fac / phi_i.squaredNorm()); + coef_vec.push_back(spin_fac / phi_i.getSquareNorm()); func_vec.push_back(ex_iip); } diff --git a/src/qmoperators/two_electron/ExchangePotentialD2.cpp b/src/qmoperators/two_electron/ExchangePotentialD2.cpp index 7b1d39bc0..ca136e501 100644 --- a/src/qmoperators/two_electron/ExchangePotentialD2.cpp +++ b/src/qmoperators/two_electron/ExchangePotentialD2.cpp @@ -129,8 +129,8 @@ Orbital ExchangePotentialD2::apply(Orbital phi_p) { calcExchange_kij(precf, phi_i, y_i, phi_p, ex_iyp); func_vec.push_back(ex_xip); func_vec.push_back(ex_iyp); - coef_vec.push_back(spin_fac / phi_i.squaredNorm()); - coef_vec.push_back(spin_fac / phi_i.squaredNorm()); + coef_vec.push_back(spin_fac / phi_i.getSquareNorm()); + coef_vec.push_back(spin_fac / phi_i.getSquareNorm()); } if (not mrcpp::mpi::my_func(phi_i)) phi_i.free(); if (not mrcpp::mpi::my_func(x_i)) x_i.free(); @@ -188,8 +188,8 @@ Orbital ExchangePotentialD2::dagger(Orbital phi_p) { calcExchange_kij(precf, y_i, phi_i, phi_p, ex_yip); func_vec.push_back(ex_ixp); func_vec.push_back(ex_yip); - coef_vec.push_back(spin_fac / phi_i.squaredNorm()); - coef_vec.push_back(spin_fac / phi_i.squaredNorm()); + coef_vec.push_back(spin_fac / phi_i.getSquareNorm()); + coef_vec.push_back(spin_fac / phi_i.getSquareNorm()); } if (not mrcpp::mpi::my_func(phi_i)) phi_i.free(); if (not mrcpp::mpi::my_func(x_i)) x_i.free(); diff --git a/src/qmoperators/two_electron/XCPotentialD1.cpp b/src/qmoperators/two_electron/XCPotentialD1.cpp index 62ddc6d42..14c38b7ee 100644 --- a/src/qmoperators/two_electron/XCPotentialD1.cpp +++ b/src/qmoperators/two_electron/XCPotentialD1.cpp @@ -53,7 +53,7 @@ mrcpp::FunctionTreeVector<3> XCPotentialD1::setupDensities(double prec, mrcpp::F { // Unperturbed total density Timer timer; Density &rho = getDensity(DensityType::Total, 0); - if (rho.squaredNorm() <= 0.0) { + if (rho.Ncomp() == 0) { rho.alloc(0); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Total); @@ -65,8 +65,8 @@ mrcpp::FunctionTreeVector<3> XCPotentialD1::setupDensities(double prec, mrcpp::F { // Unperturbed alpha density Timer timer; Density &rho = getDensity(DensityType::Alpha, 0); - if (not rho.hasReal()) { - rho.alloc(NUMBER::Real); + if (rho.Ncomp() == 0) { + rho.alloc(0); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Alpha); } @@ -76,8 +76,8 @@ mrcpp::FunctionTreeVector<3> XCPotentialD1::setupDensities(double prec, mrcpp::F { // Unperturbed beta density Timer timer; Density &rho = getDensity(DensityType::Beta, 0); - if (not rho.hasReal()) { - rho.alloc(NUMBER::Real); + if (rho.Ncomp() == 0) { + rho.alloc(0); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Beta); } diff --git a/src/qmoperators/two_electron/XCPotentialD2.cpp b/src/qmoperators/two_electron/XCPotentialD2.cpp index 7c6fd1050..94b279c18 100644 --- a/src/qmoperators/two_electron/XCPotentialD2.cpp +++ b/src/qmoperators/two_electron/XCPotentialD2.cpp @@ -74,8 +74,8 @@ mrcpp::FunctionTreeVector<3> XCPotentialD2::setupDensities(double prec, mrcpp::F { // Unperturbed total density Timer timer; Density &rho = getDensity(DensityType::Total, 0); - if (not rho.hasReal()) { - rho.alloc(NUMBER::Real); + if (rho.Ncomp() == 0) { + rho.alloc(0); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Total); } @@ -85,8 +85,8 @@ mrcpp::FunctionTreeVector<3> XCPotentialD2::setupDensities(double prec, mrcpp::F { // Perturbed total density Timer timer; Density &rho = getDensity(DensityType::Total, 1); - if (not rho.hasReal()) { - rho.alloc(NUMBER::Real); + if (rho.Ncomp() == 0) { + rho.alloc(0); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, *orbitals_x, *orbitals_y, DensityType::Total); } @@ -97,8 +97,8 @@ mrcpp::FunctionTreeVector<3> XCPotentialD2::setupDensities(double prec, mrcpp::F { // Unperturbed alpha density Timer timer; Density &rho = getDensity(DensityType::Alpha, 0); - if (not rho.hasReal()) { - rho.alloc(NUMBER::Real); + if (rho.Ncomp() == 0) { + rho.alloc(0); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Alpha); } @@ -108,8 +108,8 @@ mrcpp::FunctionTreeVector<3> XCPotentialD2::setupDensities(double prec, mrcpp::F { // Unperturbed beta density Timer timer; Density &rho = getDensity(DensityType::Beta, 0); - if (not rho.hasReal()) { - rho.alloc(NUMBER::Real); + if (rho.Ncomp() == 0) { + rho.alloc(0); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Beta); } @@ -119,8 +119,8 @@ mrcpp::FunctionTreeVector<3> XCPotentialD2::setupDensities(double prec, mrcpp::F { // Perturbed alpha density Timer timer; Density &rho = getDensity(DensityType::Alpha, 1); - if (not rho.hasReal()) { - rho.alloc(NUMBER::Real); + if (rho.Ncomp() == 0) { + rho.alloc(0); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, *orbitals_x, *orbitals_y, DensityType::Alpha); } @@ -130,8 +130,8 @@ mrcpp::FunctionTreeVector<3> XCPotentialD2::setupDensities(double prec, mrcpp::F { // Perturbed beta density Timer timer; Density &rho = getDensity(DensityType::Beta, 1); - if (not rho.hasReal()) { - rho.alloc(NUMBER::Real); + if (rho.Ncomp() == 0) { + rho.alloc(0); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, *orbitals_x, *orbitals_y, DensityType::Beta); } diff --git a/src/scf_solver/Accelerator.cpp b/src/scf_solver/Accelerator.cpp index a77c98677..8f9234125 100644 --- a/src/scf_solver/Accelerator.cpp +++ b/src/scf_solver/Accelerator.cpp @@ -165,7 +165,7 @@ bool Accelerator::verifyOverlap(OrbitalVector &Phi) { if (mrcpp::mpi::my_func(phi_i)) { auto &last_i = this->orbitals[nHistory][i]; if (not mrcpp::mpi::my_func(last_i)) MSG_ABORT("MPI rank mismatch"); - auto sqNorm = phi_i.squaredNorm(); + auto sqNorm = phi_i.getSquareNorm(); auto overlap = orbital::dot(phi_i, last_i); if (std::abs(overlap) < 0.5 * sqNorm) { mrcpp::print::value(this->pl + 2, "Overlap not verified ", std::abs(overlap)); diff --git a/tests/qmfunctions/qmfunction.cpp b/tests/qmfunctions/qmfunction.cpp index 3313c3547..78a942c24 100644 --- a/tests/qmfunctions/qmfunction.cpp +++ b/tests/qmfunctions/qmfunction.cpp @@ -263,20 +263,20 @@ TEST_CASE("QMFunction", "[qmfunction]") { SECTION("into non-shared function") { mrcpp::CompFunction func_2; mrcpp::multiply(func_2, func_1, func_1, -1.0); - REQUIRE(func_2.integrate().real() == Approx(func_1.squaredNorm())); + REQUIRE(func_2.integrate().real() == Approx(func_1.getSquareNorm())); REQUIRE(func_2.integrate().imag() == Approx(0.0)); } SECTION("into non-shared function conjugate") { mrcpp::CompFunction func_2; mrcpp::multiply(func_2, func_1, func_1, -1.0, false, false, true); - REQUIRE(func_2.integrate().real() == Approx(func_1.squaredNorm())); + REQUIRE(func_2.integrate().real() == Approx(func_1.getSquareNorm())); REQUIRE(func_2.integrate().imag() == Approx(0.0)); } #ifdef MRCHEM_HAS_MPI SECTION("into shared function") { mrcpp::CompFunction func_2(0, true); mrcpp::multiply(func_2, func_1, func_1, -1.0, false, false, true); - REQUIRE(func_2.integrate().real() == Approx(func_1.squaredNorm())); + REQUIRE(func_2.integrate().real() == Approx(func_1.getSquareNorm())); REQUIRE(func_2.integrate().imag() == Approx(0.0)); } #endif @@ -290,13 +290,13 @@ TEST_CASE("QMFunction", "[qmfunction]") { SECTION("into non-shared function") { mrcpp::CompFunction func_2(0, false);; mrcpp::multiply(func_2, func_1, func_1, -1.0, true); - REQUIRE(func_2.integrate().real() == Approx(func_1.squaredNorm())); + REQUIRE(func_2.integrate().real() == Approx(func_1.getSquareNorm())); REQUIRE(func_2.integrate().imag() == Approx(0.0)); } SECTION("into shared function") { mrcpp::CompFunction func_2(0, true); mrcpp::multiply(func_2, func_1, func_1, -1.0,true); - REQUIRE(func_2.integrate().real() == Approx(func_1.squaredNorm())); + REQUIRE(func_2.integrate().real() == Approx(func_1.getSquareNorm())); REQUIRE(func_2.integrate().imag() == Approx(0.0)); } } diff --git a/tests/qmoperators/identity_operator.cpp b/tests/qmoperators/identity_operator.cpp index fd2df2810..b694bc9ed 100644 --- a/tests/qmoperators/identity_operator.cpp +++ b/tests/qmoperators/identity_operator.cpp @@ -107,7 +107,7 @@ TEST_CASE("IdentityOperator", "[identity_operator]") { ComplexDouble S = I(phi, phi); I.clear(); - REQUIRE(S.real() == Approx(phi.squaredNorm())); + REQUIRE(S.real() == Approx(phi.getSquareNorm())); REQUIRE(S.imag() < thrs); } diff --git a/tests/qmoperators/operator_composition.cpp b/tests/qmoperators/operator_composition.cpp index aa0c2fb31..d70c931ac 100644 --- a/tests/qmoperators/operator_composition.cpp +++ b/tests/qmoperators/operator_composition.cpp @@ -384,7 +384,7 @@ TEST_CASE("Operator composition", "[operator_composition]") { REQUIRE(SI.size(0) == 2); SI.setup(prec); - const ComplexDouble ref = {0.0, 0.5}; + const ComplexDouble ref = {0.0, 0.0}; //spin is flipped->orthogonal const ComplexMatrix val = SI(Phi, Phi); REQUIRE(val(0, 0).real() == Approx(ref.real()).margin(thrs)); REQUIRE(val(0, 0).imag() == Approx(ref.imag()).epsilon(thrs)); @@ -397,7 +397,7 @@ TEST_CASE("Operator composition", "[operator_composition]") { REQUIRE(SI.size(0) == 1); SI.setup(prec); - const ComplexDouble ref = {0.0, 0.5}; + const ComplexDouble ref = {0.0, 0.0}; //spin is flipped->orthogonal const ComplexMatrix val = SI(Phi, Phi); REQUIRE(val(0, 0).real() == Approx(ref.real()).margin(thrs)); REQUIRE(val(0, 0).imag() == Approx(ref.imag()).epsilon(thrs)); @@ -436,7 +436,7 @@ TEST_CASE("Operator composition", "[operator_composition]") { REQUIRE(SD.size(0) == 2); SD.setup(prec); - const ComplexDouble ref = {0.0, -std::sqrt(2.0) / 4.0}; + const ComplexDouble ref = {0.0, 0.0}; //spin is flipped->orthogonal const ComplexMatrix val = SD(Phi, Phi); REQUIRE(val(0, 1).real() == Approx(ref.real()).margin(thrs)); REQUIRE(val(0, 1).imag() == Approx(ref.imag()).epsilon(thrs)); @@ -449,7 +449,7 @@ TEST_CASE("Operator composition", "[operator_composition]") { REQUIRE(SD.size(0) == 2); SD.setup(prec); - const ComplexDouble ref = {0.0, -std::sqrt(2.0) / 4.0}; + const ComplexDouble ref = {0.0, 0.0}; //spin is flipped->orthogonal const ComplexMatrix val = SD(Phi, Phi); REQUIRE(val(0, 1).real() == Approx(ref.real()).margin(thrs)); REQUIRE(val(0, 1).imag() == Approx(ref.imag()).epsilon(thrs)); diff --git a/tests/qmoperators/xc_hessian_lda.cpp b/tests/qmoperators/xc_hessian_lda.cpp index 09f490478..e06b95cfb 100644 --- a/tests/qmoperators/xc_hessian_lda.cpp +++ b/tests/qmoperators/xc_hessian_lda.cpp @@ -101,10 +101,10 @@ TEST_CASE("XCHessianLDA", "[xc_hessian_lda]") { int i = 0; DoubleMatrix E_P = DoubleMatrix::Zero(Phi.size(), Phi.size()); - E_P(0, 0) = -0.0507818907147; + E_P(0, 0) = -0.050781893; E_P(0, 1) = -0.0226852770676; E_P(1, 0) = -0.0226852770676; - E_P(1, 1) = 0.00549970397828; + E_P(1, 1) = 0.0054997041; V.setup(prec); SECTION("apply") { diff --git a/tests/qmoperators/xc_hessian_pbe.cpp b/tests/qmoperators/xc_hessian_pbe.cpp index 343bcf1a5..a68a8b2c9 100644 --- a/tests/qmoperators/xc_hessian_pbe.cpp +++ b/tests/qmoperators/xc_hessian_pbe.cpp @@ -103,10 +103,10 @@ TEST_CASE("XCHessianPBE", "[xc_hessian_pbe]") { int i = 0; DoubleMatrix E_P = DoubleMatrix::Zero(Phi.size(), Phi.size()); - E_P(0, 0) = -0.0496021801; - E_P(0, 1) = -0.0234437207; - E_P(1, 0) = -0.0234437207; - E_P(1, 1) = 0.0061055193; + E_P(0, 0) = -0.049699524; + E_P(0, 1) = -0.0234667191; + E_P(1, 0) = -0.0234667191; + E_P(1, 1) = 0.0060967104; V.setup(prec); SECTION("apply") { diff --git a/tests/solventeffect/PB_solver.cpp b/tests/solventeffect/PB_solver.cpp index ff9ba52e0..35d07a974 100644 --- a/tests/solventeffect/PB_solver.cpp +++ b/tests/solventeffect/PB_solver.cpp @@ -88,11 +88,9 @@ TEST_CASE("Poisson Boltzmann equation solver standard", "[PB_solver][pb_standard auto Phi_p = std::make_shared(); auto &Phi = *Phi_p; Phi.push_back(Orbital(SPIN::Paired)); - Phi.distribute(); HydrogenFunction f(1, 0, 0); if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], f, prec); - auto rho_nuc = chemistry::compute_nuclear_density(prec, molecule, 100); auto scrf_p = std::make_unique(dielectric_func, kappa_sq, rho_nuc, P_p, D_p, kain, max_iter, dyn_thrs, SCRFDensityType::NUCLEAR); diff --git a/tests/solventeffect/reaction_operator.cpp b/tests/solventeffect/reaction_operator.cpp index c0a0e3c5c..fc92f50c1 100644 --- a/tests/solventeffect/reaction_operator.cpp +++ b/tests/solventeffect/reaction_operator.cpp @@ -85,7 +85,6 @@ TEST_CASE("ReactionOperator", "[reaction_operator]") { // project analytic 1s orbital HydrogenFunction f(1, 0, 0); if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], f, prec); - auto rho_nuc = chemistry::compute_nuclear_density(prec, molecule, 100); int kain = 4; @@ -101,7 +100,7 @@ TEST_CASE("ReactionOperator", "[reaction_operator]") { auto [Er_nuc, Er_el] = Reo->getSolver()->computeEnergies(rho_el); auto total_energy = Er_nuc + Er_el; Reo->clear(); - REQUIRE(total_energy == Approx(-1.022729683846e-01).epsilon(thrs)); + REQUIRE(total_energy == Approx(-0.102272804).epsilon(thrs)); } } // namespace reaction_operator From 2fc0119f03bc2ec39f911c7f8abe57bde19785ab Mon Sep 17 00:00:00 2001 From: gitpeterwind Date: Mon, 26 Aug 2024 14:58:09 +0200 Subject: [PATCH 6/8] some cleaning --- external/upstream/fetch_mrcpp.cmake | 2 +- src/qmfunctions/Orbital.h | 6 +- src/qmfunctions/density_utils.cpp | 11 +-- src/qmfunctions/orbital_utils.cpp | 76 +------------------ src/qmfunctions/orbital_utils.h | 6 -- src/qmoperators/QMDerivative.cpp | 2 +- src/qmoperators/QMIdentity.cpp | 2 +- src/qmoperators/QMPotential.cpp | 2 +- src/qmoperators/QMSpin.cpp | 2 +- .../two_electron/ExchangePotential.cpp | 5 +- .../two_electron/ExchangePotentialD1.cpp | 16 ++-- .../two_electron/ExchangePotentialD2.cpp | 16 ++-- src/scf_solver/Accelerator.cpp | 2 +- src/scf_solver/HelmholtzVector.cpp | 3 +- src/scf_solver/KAIN.cpp | 12 +-- src/tensor/RankZeroOperator.cpp | 32 +++++--- tests/qmfunctions/orbital.cpp | 20 ++--- tests/qmfunctions/orbital_vector.cpp | 38 +++++----- tests/qmoperators/coulomb_hessian.cpp | 4 +- tests/qmoperators/coulomb_operator.cpp | 2 +- tests/qmoperators/electric_field_operator.cpp | 12 +-- tests/qmoperators/exchange_hessian.cpp | 4 +- tests/qmoperators/exchange_operator.cpp | 4 +- tests/qmoperators/kinetic_operator.cpp | 4 +- tests/qmoperators/nuclear_operator.cpp | 12 +-- tests/qmoperators/xc_hessian_pbe.cpp | 4 +- tests/qmoperators/xc_operator_blyp.cpp | 4 +- 27 files changed, 115 insertions(+), 188 deletions(-) diff --git a/external/upstream/fetch_mrcpp.cmake b/external/upstream/fetch_mrcpp.cmake index 646de0bd0..4b4105bb3 100644 --- a/external/upstream/fetch_mrcpp.cmake +++ b/external/upstream/fetch_mrcpp.cmake @@ -39,7 +39,7 @@ else() GIT_REPOSITORY https://github.com/MRChemSoft/mrcpp.git GIT_TAG - 6624a73fadcb9083ef86fad24c2635bfb882b + d9b07c274b0d8d87cc57ecf23fc9f4139467fc6d ) FetchContent_GetProperties(mrcpp_sources) diff --git a/src/qmfunctions/Orbital.h b/src/qmfunctions/Orbital.h index 7815ab881..305ece53f 100644 --- a/src/qmfunctions/Orbital.h +++ b/src/qmfunctions/Orbital.h @@ -69,7 +69,11 @@ class Orbital : public mrcpp::CompFunction<3> { void loadOrbital(const std::string &file); }; -//using OrbitalVector = mrcpp::CompFunctionVector<3>; +// All MPI processes have a vector of full length, but +// only "my_func" are fully defined. +// The others orbitals (not my_func) have only basic data (spin etc) but no trees defined. +// Vector of orbitals where all orbitals are defined for all MPI, should not have typoe +// OrbitalVectors, but directly vector. class OrbitalVector : public mrcpp::CompFunctionVector { public: OrbitalVector(int N = 0) : mrcpp::CompFunctionVector(N) {} diff --git a/src/qmfunctions/density_utils.cpp b/src/qmfunctions/density_utils.cpp index cff3067c6..2613e0017 100644 --- a/src/qmfunctions/density_utils.cpp +++ b/src/qmfunctions/density_utils.cpp @@ -157,14 +157,12 @@ void density::compute_local_X(double prec, Density &rho, OrbitalVector &Phi, Orb if (rho.Ncomp() == 0) rho.alloc(0); // Compute local density from own orbitals - rho.real().setZero(); for (int i = 0; i < Phi.size(); i++) { if (mrcpp::mpi::my_func(Phi[i])) { if (not mrcpp::mpi::my_func(X[i])) MSG_ABORT("Inconsistent MPI distribution"); Orbital phi_i = Phi[i]; double occ = density::compute_occupation(phi_i, spin); if (std::abs(occ) < mrcpp::MachineZero) continue; // next orbital if this one is not occupied! - Density rho_i(false); mrcpp::multiply(rho_i, phi_i, X[i], mult_prec); rho.add(2.0 * occ, rho_i); @@ -177,8 +175,7 @@ void density::compute_local_XY(double prec, Density &rho, OrbitalVector &Phi, Or int N_el = orbital::get_electron_number(Phi); double mult_prec = prec; // prec for rho_i = |x_i> = int bra^\dag(r) * ket(r) dr. - * - * Notice that the = int bra^\dag(r) * ket(r) dr. - * - * Notice that the bra, mrcpp::CompFunction<3>ket) { - if ((bra.data().n1[0] == SPIN::Alpha) and (ket.data().n1[0] == SPIN::Beta)) return 0.0; - if ((bra.data().n1[0] == SPIN::Beta) and (ket.data().n1[0] == SPIN::Alpha)) return 0.0; - return mrcpp::dot(bra, ket); -} - -/** @brief Compute the diagonal dot products - * - * MPI: dot product is computed by the ket owner and the corresponding - * bra is communicated. The resulting vector is allreduced, and - * the foreign bra's are cleared. - * - */ -ComplexVector orbital::dot(OrbitalVector &Bra, OrbitalVector &Ket) { - if (Bra.size() != Ket.size()) MSG_ABORT("Size mismatch"); - - int N = Bra.size(); - ComplexVector result = ComplexVector::Zero(N); - for (int i = 0; i < N; i++) { - // The bra is sent to the owner of the ket - if (mrcpp::mpi::my_func(Bra[i]) != mrcpp::mpi::my_func(Ket[i])) { - int tag = 8765 + i; - int src = (Bra[i].getRank()) % mrcpp::mpi::wrk_size; - int dst = (Ket[i].getRank()) % mrcpp::mpi::wrk_size; - if (mrcpp::mpi::my_func(Bra[i])) mrcpp::mpi::send_function(Bra[i], dst, tag, mrcpp::mpi::comm_wrk); - if (mrcpp::mpi::my_func(Ket[i])) mrcpp::mpi::recv_function(Bra[i], src, tag, mrcpp::mpi::comm_wrk); - } - result[i] = orbital::dot(Bra[i], Ket[i]); - if (not mrcpp::mpi::my_func(Bra[i])) Bra[i].free(); - } - mrcpp::mpi::allreduce_vector(result, mrcpp::mpi::comm_wrk); - return result; -} - -/** @brief Compute = int |bra^\dag(r)| * |ket(r)| dr. - * - */ -double orbital::node_norm_dot(Orbital bra, Orbital ket) { - if ((bra.spin() == SPIN::Alpha) and (ket.spin() == SPIN::Beta)) return 0.0; - if ((bra.spin() == SPIN::Beta) and (ket.spin() == SPIN::Alpha)) return 0.0; - return mrcpp::node_norm_dot(bra, ket); -} - - -/** @brief Compute = int |bra^\dag(r)| * |ket(r)| dr. - * - -double orbital::node_norm_dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3> ket, bool exact) { - if ((bra.spin() == SPIN::Alpha) and (ket.spin() == SPIN::Beta)) return 0.0; - if ((bra.spin() == SPIN::Beta) and (ket.spin() == SPIN::Alpha)) return 0.0; - return mrcpp::node_norm_dot(bra, ket, exact); -}*/ - /** @brief Compare spin and occupation of two orbitals * * Returns true if orbital parameters are the same. @@ -499,7 +425,7 @@ void orbital::normalize(OrbitalVector &Phi) { /** @brief In place orthogonalize against inp. Private function. */ void orbital::orthogonalize(double prec, Orbital &&phi, Orbital psi) { - ComplexDouble overlap = orbital::dot(psi, phi); + ComplexDouble overlap = mrcpp::dot(psi, phi); double sq_norm = psi.getSquareNorm(); if (std::abs(overlap) > prec) phi.add(-1.0 * overlap / sq_norm, psi); } diff --git a/src/qmfunctions/orbital_utils.h b/src/qmfunctions/orbital_utils.h index 015ee6ada..1b1a919b5 100644 --- a/src/qmfunctions/orbital_utils.h +++ b/src/qmfunctions/orbital_utils.h @@ -36,12 +36,6 @@ bool compare(const Orbital &phi_a, const Orbital &phi_b); int compare_spin(const Orbital &phi_a, const Orbital &phi_b); int compare_occupation(const Orbital &phi_a, const Orbital &phi_b); -ComplexDouble dot(Orbital bra, Orbital ket); -ComplexDouble dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3>ket); -ComplexVector dot(OrbitalVector &Bra, OrbitalVector &Ket); -double node_norm_dot(Orbital bra, Orbital ket); -double node_norm_dot(mrcpp::CompFunction<3> bra, mrcpp::CompFunction<3> ket, bool exact); - void normalize(Orbital phi); OrbitalChunk get_my_chunk(OrbitalVector &Phi); void orthogonalize(double prec, Orbital &&phi, Orbital psi); diff --git a/src/qmoperators/QMDerivative.cpp b/src/qmoperators/QMDerivative.cpp index 670ded3b5..f37521ee9 100644 --- a/src/qmoperators/QMDerivative.cpp +++ b/src/qmoperators/QMDerivative.cpp @@ -63,7 +63,7 @@ Orbital QMDerivative::apply(Orbital inp) { auto dir = this->apply_dir; auto &D = *this->derivative; - Orbital out = inp.paramCopy(); + Orbital out = inp.paramCopy(true); ComplexDouble metric[4][4]; ComplexDouble diago = 1.0; if (isImag()) diago = {0.0, 1.0}; diff --git a/src/qmoperators/QMIdentity.cpp b/src/qmoperators/QMIdentity.cpp index 88d826044..4e32afa7c 100644 --- a/src/qmoperators/QMIdentity.cpp +++ b/src/qmoperators/QMIdentity.cpp @@ -37,7 +37,7 @@ namespace mrchem { /** Identity operator is a deep copy */ Orbital QMIdentity::apply(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); - Orbital out = inp.paramCopy(); + Orbital out; mrcpp::deep_copy(out, inp); return out; diff --git a/src/qmoperators/QMPotential.cpp b/src/qmoperators/QMPotential.cpp index 396aed539..16e23e06b 100644 --- a/src/qmoperators/QMPotential.cpp +++ b/src/qmoperators/QMPotential.cpp @@ -89,7 +89,7 @@ Orbital QMPotential::apply(Orbital inp) { Orbital QMPotential::dagger(Orbital inp) { if (this->apply_prec < 0.0) MSG_ERROR("Uninitialized operator"); - Orbital out = inp.paramCopy(); + Orbital out = inp.paramCopy(true); calc(out, inp, true); return out; } diff --git a/src/qmoperators/QMSpin.cpp b/src/qmoperators/QMSpin.cpp index e2c1475aa..141f304af 100644 --- a/src/qmoperators/QMSpin.cpp +++ b/src/qmoperators/QMSpin.cpp @@ -64,7 +64,7 @@ Orbital QMSpin::apply(Orbital inp) { MSG_ABORT("Cannot apply spin operator on paired orbital"); } - Orbital out = inp.paramCopy(); + Orbital out; mrcpp::deep_copy(out, inp); out.rescale(coef); diff --git a/src/qmoperators/two_electron/ExchangePotential.cpp b/src/qmoperators/two_electron/ExchangePotential.cpp index 727c5f179..e54cba0ec 100644 --- a/src/qmoperators/two_electron/ExchangePotential.cpp +++ b/src/qmoperators/two_electron/ExchangePotential.cpp @@ -170,7 +170,7 @@ void ExchangePotential::calcExchange_kij(double prec, Orbital phi_k, Orbital phi // if the product is smaller than the target precision, // the result is expected to be negligible Timer timer_ij; - Orbital rho_ij = phi_i.paramCopy(); + Orbital rho_ij = phi_i.paramCopy(true); mrcpp::multiply(rho_ij, phi_i, phi_j, prec_m1, true, true, true); timer_ij.stop(); if (rho_ij.norm() < prec) return; @@ -197,8 +197,7 @@ void ExchangePotential::calcExchange_kij(double prec, Orbital phi_k, Orbital phi } // compute V_ij = P[rho_ij] Timer timer_p; - Orbital V_ij = rho_ij.paramCopy(); - V_ij.alloc(0); + Orbital V_ij = rho_ij.paramCopy(true); if (RealOrbitals) { mrcpp::apply(prec_p, *V_ij.CompD[0], P, *rho_ij.CompD[0], phi_opt_vec_real, -1, true); } else { diff --git a/src/qmoperators/two_electron/ExchangePotentialD1.cpp b/src/qmoperators/two_electron/ExchangePotentialD1.cpp index 514631b6d..6e696ec86 100644 --- a/src/qmoperators/two_electron/ExchangePotentialD1.cpp +++ b/src/qmoperators/two_electron/ExchangePotentialD1.cpp @@ -102,7 +102,7 @@ int ExchangePotentialD1::testInternal(Orbital phi_p) const { * particular exchange contribution has been precomputed. */ Orbital ExchangePotentialD1::apply(Orbital phi_p) { - Orbital out_p = phi_p.paramCopy(); + Orbital out_p = phi_p.paramCopy(true); if (this->apply_prec < 0.0) { MSG_ERROR("Uninitialized operator"); return out_p; @@ -272,8 +272,8 @@ void ExchangePotentialD1::setupInternal(double prec) { for (int i = 0; i < iorb_vec.size(); i++) { int iorb = itasks[task][i]; Orbital &phi_i = iorb_vec[i]; - Orbital ex_jji = phi_i.paramCopy(); - Orbital ex_iij = phi_j.paramCopy(); + Orbital ex_jji = phi_i.paramCopy(true); + Orbital ex_iij = phi_j.paramCopy(true); // compute K_iij and K_jji in one operation double j_fac = getSpinFactor(phi_i, phi_j); @@ -311,7 +311,7 @@ void ExchangePotentialD1::setupInternal(double prec) { } // add all contributions to ex_j, if (mrcpp::mpi::bank_size > 0 and iijfunc_vec.size() > 0) { - Orbital ex_j = phi_j.paramCopy(); + Orbital ex_j = phi_j.paramCopy(true); t_add.resume(); mrcpp::linear_combination(ex_j, coef_vec, iijfunc_vec, prec); t_add.stop(); @@ -361,7 +361,7 @@ void ExchangePotentialD1::setupInternal(double prec) { if (tot >= totmax) { // we sum the contributions so far before fetching new ones t_add.resume(); - auto tmp_j = Ex[j].paramCopy(); + auto tmp_j = Ex[j].paramCopy(true); mrcpp::linear_combination(tmp_j, coef_vec, iijfunc_vec, prec); Ex[j].add(1.0, tmp_j); tmp_j.free(); @@ -374,7 +374,7 @@ void ExchangePotentialD1::setupInternal(double prec) { } if (iijfunc_vec.size() > 0) { t_add.resume(); - auto tmp_j = Ex[j].paramCopy(); + auto tmp_j = Ex[j].paramCopy(true); mrcpp::linear_combination(tmp_j, coef_vec, iijfunc_vec, prec); Ex[j].add(1.0, tmp_j); tmp_j.free(); @@ -426,7 +426,7 @@ Orbital ExchangePotentialD1::calcExchange(Orbital phi_p) { double spin_fac = getSpinFactor(phi_i, phi_p); if (std::abs(spin_fac) >= mrcpp::MachineZero) { - Orbital ex_iip = phi_p.paramCopy(); + Orbital ex_iip = phi_p.paramCopy(true); calcExchange_kij(precf, phi_i, phi_i, phi_p, ex_iip); coef_vec.push_back(spin_fac / phi_i.getSquareNorm()); func_vec.push_back(ex_iip); @@ -436,7 +436,7 @@ Orbital ExchangePotentialD1::calcExchange(Orbital phi_p) { } // compute ex_p = sum_i c_i*ex_iip - Orbital ex_p = phi_p.paramCopy(); + Orbital ex_p = phi_p.paramCopy(true); //Eigen::Map coefs(coef_vec.data(), coef_vec.size()); mrcpp::linear_combination(ex_p, coef_vec, func_vec, prec); print_utils::qmfunction(4, "Applied exchange", ex_p, timer); diff --git a/src/qmoperators/two_electron/ExchangePotentialD2.cpp b/src/qmoperators/two_electron/ExchangePotentialD2.cpp index ca136e501..d6901ef85 100644 --- a/src/qmoperators/two_electron/ExchangePotentialD2.cpp +++ b/src/qmoperators/two_electron/ExchangePotentialD2.cpp @@ -96,7 +96,7 @@ void ExchangePotentialD2::clearBank() { Orbital ExchangePotentialD2::apply(Orbital phi_p) { if (this->apply_prec < 0.0) { MSG_ERROR("Uninitialized operator"); - return phi_p.paramCopy(); + return phi_p.paramCopy(true); } Timer timer; @@ -123,8 +123,8 @@ Orbital ExchangePotentialD2::apply(Orbital phi_p) { double spin_fac = getSpinFactor(phi_i, phi_p); if (std::abs(spin_fac) >= mrcpp::MachineZero) { - Orbital ex_xip = phi_p.paramCopy(); - Orbital ex_iyp = phi_p.paramCopy(); + Orbital ex_xip = phi_p.paramCopy(true); + Orbital ex_iyp = phi_p.paramCopy(true); calcExchange_kij(precf, x_i, phi_i, phi_p, ex_xip); calcExchange_kij(precf, phi_i, y_i, phi_p, ex_iyp); func_vec.push_back(ex_xip); @@ -138,7 +138,7 @@ Orbital ExchangePotentialD2::apply(Orbital phi_p) { } // compute out_p = sum_i c_i*(ex_xip + ex_iyp) - Orbital out_p = phi_p.paramCopy(); + Orbital out_p = phi_p.paramCopy(true); //Eigen::Map coefs(coef_vec.data(), coef_vec.size()); mrcpp::linear_combination(out_p, coef_vec, func_vec, prec); print_utils::qmfunction(4, "Applied exchange", out_p, timer); @@ -155,7 +155,7 @@ Orbital ExchangePotentialD2::apply(Orbital phi_p) { Orbital ExchangePotentialD2::dagger(Orbital phi_p) { if (this->apply_prec < 0.0) { MSG_ERROR("Uninitialized operator"); - return phi_p.paramCopy(); + return phi_p.paramCopy(true); } Timer timer; @@ -182,8 +182,8 @@ Orbital ExchangePotentialD2::dagger(Orbital phi_p) { double spin_fac = getSpinFactor(phi_i, phi_p); if (std::abs(spin_fac) >= mrcpp::MachineZero) { - Orbital ex_ixp = phi_p.paramCopy(); - Orbital ex_yip = phi_p.paramCopy(); + Orbital ex_ixp = phi_p.paramCopy(true); + Orbital ex_yip = phi_p.paramCopy(true); calcExchange_kij(precf, phi_i, x_i, phi_p, ex_ixp); calcExchange_kij(precf, y_i, phi_i, phi_p, ex_yip); func_vec.push_back(ex_ixp); @@ -197,7 +197,7 @@ Orbital ExchangePotentialD2::dagger(Orbital phi_p) { } // compute ex_p = sum_i c_i*(ex_ixp + ex_yip) - Orbital ex_p = phi_p.paramCopy(); + Orbital ex_p = phi_p.paramCopy(true); //Eigen::Map coefs(coef_vec.data(), coef_vec.size()); mrcpp::linear_combination(ex_p, coef_vec, func_vec, prec); print_utils::qmfunction(4, "Applied exchange", ex_p, timer); diff --git a/src/scf_solver/Accelerator.cpp b/src/scf_solver/Accelerator.cpp index 8f9234125..875da50cc 100644 --- a/src/scf_solver/Accelerator.cpp +++ b/src/scf_solver/Accelerator.cpp @@ -166,7 +166,7 @@ bool Accelerator::verifyOverlap(OrbitalVector &Phi) { auto &last_i = this->orbitals[nHistory][i]; if (not mrcpp::mpi::my_func(last_i)) MSG_ABORT("MPI rank mismatch"); auto sqNorm = phi_i.getSquareNorm(); - auto overlap = orbital::dot(phi_i, last_i); + auto overlap = mrcpp::dot(phi_i, last_i); if (std::abs(overlap) < 0.5 * sqNorm) { mrcpp::print::value(this->pl + 2, "Overlap not verified ", std::abs(overlap)); out(i) = 1; diff --git a/src/scf_solver/HelmholtzVector.cpp b/src/scf_solver/HelmholtzVector.cpp index af699bbb0..524b9fade 100644 --- a/src/scf_solver/HelmholtzVector.cpp +++ b/src/scf_solver/HelmholtzVector.cpp @@ -143,8 +143,7 @@ Orbital HelmholtzVector::apply(int i, const Orbital &phi) const { if (std::abs(mu_i.imag()) > mrcpp::MachineZero) MSG_ABORT("Mu cannot be complex"); mrcpp::HelmholtzOperator H(*MRA, mu_i.real(), this->prec); - Orbital out = phi.paramCopy(); - out.alloc(0); + Orbital out = phi.paramCopy(true); ComplexDouble metric[4][4]; for (int i=0; i<4; i++){ for (int j=0; j<4; j++){ diff --git a/src/scf_solver/KAIN.cpp b/src/scf_solver/KAIN.cpp index 97dfd1178..6629c89b5 100644 --- a/src/scf_solver/KAIN.cpp +++ b/src/scf_solver/KAIN.cpp @@ -65,19 +65,19 @@ void KAIN::setupLinearSystem() { for (int i = 0; i < nHistory; i++) { auto &phi_i = this->orbitals[i][n]; - auto dPhi_im = phi_m.paramCopy(); + auto dPhi_im = phi_m.paramCopy(true); mrcpp::add(dPhi_im, 1.0, phi_i, -1.0, phi_m, -1.0); for (int j = 0; j < nHistory; j++) { auto &fPhi_j = this->dOrbitals[j][n]; - auto dfPhi_jm = fPhi_m.paramCopy(); + auto dfPhi_jm = fPhi_m.paramCopy(true); mrcpp::add(dfPhi_jm, 1.0, fPhi_j, -1.0, fPhi_m, -1.0); // Ref. Harrisons KAIN paper the following has the wrong sign, // but we define the updates (lowercase f) with opposite sign. - orbA(i, j) -= orbital::dot(dPhi_im, dfPhi_jm); + orbA(i, j) -= mrcpp::dot(dPhi_im, dfPhi_jm); } - orbB(i) += orbital::dot(dPhi_im, fPhi_m); + orbB(i) += mrcpp::dot(dPhi_im, fPhi_m); } } double alpha = (this->scaling.size() == nOrbitals) ? scaling[n] : 1.0; @@ -166,7 +166,7 @@ void KAIN::expandSolution(double prec, OrbitalVector &Phi, OrbitalVector &dPhi, partCoefs[3] = {-1.0, 0.0}; partOrbs.push_back(fPhi_m); - auto partStep = phi_m.paramCopy(); + auto partStep = phi_m.paramCopy(true); mrcpp::linear_combination(partStep, partCoefs, partOrbs, prec); auto c_j = this->c[m](j); @@ -177,7 +177,7 @@ void KAIN::expandSolution(double prec, OrbitalVector &Phi, OrbitalVector &dPhi, std::vector coefsVec(totCoefs.size()); for (int i = 0; i < totCoefs.size(); i++) coefsVec[i] = totCoefs[i]; - dPhi[n] = Phi[n].paramCopy(); + dPhi[n] = Phi[n].paramCopy(true); mrcpp::linear_combination(dPhi[n], coefsVec, totOrbs, prec); } } diff --git a/src/tensor/RankZeroOperator.cpp b/src/tensor/RankZeroOperator.cpp index 55502b171..76c0b7e6c 100644 --- a/src/tensor/RankZeroOperator.cpp +++ b/src/tensor/RankZeroOperator.cpp @@ -243,7 +243,7 @@ ComplexDouble RankZeroOperator::dagger(const mrcpp::Coord<3> &r) const { * NB: the result is put at the same location as the input (out and inp trees are the same tree) */ Orbital RankZeroOperator::operator()(Orbital inp) { - if (inp.getNNodes() == 0) return inp.paramCopy(); + if (inp.getNNodes() == 0) return inp.paramCopy(false); RankZeroOperator &O = *this; std::vector> func_vec; @@ -252,7 +252,7 @@ Orbital RankZeroOperator::operator()(Orbital inp) { Orbital out_n = O.applyOperTerm(n, inp); func_vec.push_back(out_n); } - Orbital out = inp.paramCopy(); + Orbital out = inp.paramCopy(true); mrcpp::linear_combination(out, coef_vec, func_vec, -1.0); return out; } @@ -264,7 +264,7 @@ Orbital RankZeroOperator::operator()(Orbital inp) { * NOT IMPLEMENTED */ Orbital RankZeroOperator::dagger(Orbital inp) { - if (inp.getNNodes() == 0) return inp.paramCopy(); + if (inp.getNNodes() == 0) return inp.paramCopy(false); RankZeroOperator &O = *this; std::vector> func_vec; @@ -273,7 +273,7 @@ Orbital RankZeroOperator::dagger(Orbital inp) { Orbital out_n = O.daggerOperTerm(n, inp); func_vec.push_back(out_n); } - Orbital out = inp.paramCopy(); + Orbital out = inp.paramCopy(true); mrcpp::linear_combination(out, coef_vec, func_vec, -1.0); return out; } @@ -290,7 +290,12 @@ OrbitalVector RankZeroOperator::operator()(OrbitalVector &inp) { OrbitalVector out; for (auto i = 0; i < inp.size(); i++) { Timer t1; - Orbital out_i = O(inp[i]); + Orbital out_i; + if (mrcpp::mpi::my_func(inp[i])) { + out_i = O(inp[i]); + } else { + out_i = inp[i].paramCopy(false); + } out.push_back(out_i); std::stringstream o_name; o_name << O.name() << "|" << i << ">"; @@ -310,7 +315,12 @@ OrbitalVector RankZeroOperator::dagger(OrbitalVector &inp) { OrbitalVector out; for (auto i = 0; i < inp.size(); i++) { Timer t1; - Orbital out_i = O.dagger(inp[i]); + Orbital out_i; + if (mrcpp::mpi::my_func(inp[i])) { + out_i = O.dagger(inp[i]); + } else { + out_i = inp[i].paramCopy(false); + } out.push_back(out_i); std::stringstream o_name; o_name << O.name() << "^dagger|" << i << ">"; @@ -331,7 +341,7 @@ OrbitalVector RankZeroOperator::dagger(OrbitalVector &inp) { ComplexDouble RankZeroOperator::operator()(Orbital bra, Orbital ket) { RankZeroOperator &O = *this; Orbital Oket = O(ket); - ComplexDouble out = orbital::dot(bra, Oket); + ComplexDouble out = mrcpp::dot(bra, Oket); return out; } @@ -345,7 +355,7 @@ ComplexDouble RankZeroOperator::operator()(Orbital bra, Orbital ket) { ComplexDouble RankZeroOperator::dagger(Orbital bra, Orbital ket) { RankZeroOperator &O = *this; Orbital Oket = O.dagger(ket); - ComplexDouble out = orbital::dot(bra, Oket); + ComplexDouble out = mrcpp::dot(bra, Oket); return out; } @@ -403,7 +413,7 @@ ComplexDouble RankZeroOperator::trace(OrbitalVector &Phi) { OrbitalVector OPhi = O(Phi); std::vector eta(Phi.size()); std::vector phi_vec(Phi.size()); - auto phiOPhi = orbital::dot(Phi, OPhi); + auto phiOPhi = mrcpp::dot(Phi, OPhi); ComplexDouble out = 0.0; for (int i=0; i &r) -> double { +std::function &r)> f = [](const mrcpp::Coord<3> &r) -> double { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); return std::exp(-1.0 * R * R); }; ComplexDouble i1 = {0.0, 1.0}; -auto g = [](const mrcpp::Coord<3> &r) -> double { +std::function &r)> g = [](const mrcpp::Coord<3> &r) -> double { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); return std::exp(-2.0 * R * R); }; @@ -50,7 +50,7 @@ TEST_CASE("Orbital", "[orbital]") { SECTION("copy orbital") { Orbital phi_1(SPIN::Paired); - mrcpp::project(phi_1, static_cast &r)>>(f), prec); + mrcpp::project(phi_1, f, prec); SECTION("copy constructor") { Orbital phi_2(phi_1); @@ -104,7 +104,7 @@ TEST_CASE("Orbital", "[orbital]") { Orbital phi(SPIN::Paired); REQUIRE(phi.norm() == Approx(0.0)); - mrcpp::project(phi, static_cast &r)>>(f), prec); + mrcpp::project(phi, f, prec); REQUIRE(phi.norm() > 0.8); orbital::normalize(phi); @@ -113,14 +113,14 @@ TEST_CASE("Orbital", "[orbital]") { SECTION("orthogonalize") { Orbital phi_1(SPIN::Alpha); - mrcpp::project(phi_1, static_cast &r)>>(f), prec); + mrcpp::project(phi_1, f, prec); WHEN("orbitals have different spins") { Orbital phi_2(SPIN::Beta); - mrcpp::project(phi_2, static_cast &r)>>(g), prec); + mrcpp::project(phi_2, g, prec); THEN("their overlap is zero") { - ComplexDouble S = orbital::dot(phi_1, phi_2); + ComplexDouble S = mrcpp::dot(phi_1, phi_2); REQUIRE(std::abs(S.real()) < thrs); REQUIRE(std::abs(S.imag()) < thrs); } @@ -128,10 +128,10 @@ TEST_CASE("Orbital", "[orbital]") { WHEN("orbitals have the same spin") { Orbital phi_2(SPIN::Alpha); - mrcpp::project(phi_2, static_cast &r)>>(f), prec); + mrcpp::project(phi_2, f, prec); THEN("their overlap is non-zero") { - ComplexDouble S1 = orbital::dot(phi_1, phi_2); + ComplexDouble S1 = mrcpp::dot(phi_1, phi_2); REQUIRE(std::abs(S1.real()) > thrs); REQUIRE(std::abs(S1.imag()) < thrs); } @@ -140,7 +140,7 @@ TEST_CASE("Orbital", "[orbital]") { mrcpp::orthogonalize(prec, phi_2, phi_1); THEN("their overlap is zero") { - ComplexDouble S3 = orbital::dot(phi_1, phi_2); + ComplexDouble S3 = mrcpp::dot(phi_1, phi_2); REQUIRE(std::abs(S3.real()) < thrs); REQUIRE(std::abs(S3.imag()) < thrs); } diff --git a/tests/qmfunctions/orbital_vector.cpp b/tests/qmfunctions/orbital_vector.cpp index 28c75c247..022fa6028 100644 --- a/tests/qmfunctions/orbital_vector.cpp +++ b/tests/qmfunctions/orbital_vector.cpp @@ -35,32 +35,32 @@ using namespace orbital; namespace orbital_vector_tests { -auto f1 = [](const mrcpp::Coord<3> &r) -> double { +std::function &r)> f1 = [](const mrcpp::Coord<3> &r) -> double { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); return std::exp(-1.0 * R * R); }; -auto f2 = [](const mrcpp::Coord<3> &r) -> double { +std::function &r)> f2 = [](const mrcpp::Coord<3> &r) -> double { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); return std::exp(-2.0 * R * R); }; -auto f3 = [](const mrcpp::Coord<3> &r) -> double { +std::function &r)> f3 = [](const mrcpp::Coord<3> &r) -> double { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); return std::exp(-3.0 * R * R); }; -auto f4 = [](const mrcpp::Coord<3> &r) -> double { +std::function &r)> f4 = [](const mrcpp::Coord<3> &r) -> double { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); return std::exp(-4.0 * R * R); }; -auto f5 = [](const mrcpp::Coord<3> &r) -> double { +std::function &r)> f5 = [](const mrcpp::Coord<3> &r) -> double { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); return std::exp(-5.0 * R * R); }; -auto f6 = [](const mrcpp::Coord<3> &r) -> double { +std::function &r)> f6 = [](const mrcpp::Coord<3> &r) -> double { double R = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); return std::exp(-6.0 * R * R); }; @@ -128,8 +128,8 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { Phi.push_back(Orbital(SPIN::Paired)); Phi.push_back(Orbital(SPIN::Alpha)); - if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], static_cast &r)>>(f1), prec); - if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], static_cast &r)>>(f2), prec); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], f1, prec); + if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], f2, prec); normalize(Phi); SECTION("copy constructor") { @@ -201,8 +201,8 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { REQUIRE(norms1[0] == Approx(0.0)); REQUIRE(norms1[1] == Approx(0.0)); - if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], static_cast &r)>>(f1), prec); - if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], static_cast &r)>>(f2), prec); + if (mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], f1, prec); + if (mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], f2, prec); DoubleVector norms2 = get_norms(Phi); REQUIRE(norms2[0] > 0.0); @@ -234,12 +234,13 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { Phi.push_back(Orbital(SPIN::Beta)); Phi.distribute(); - if (true or mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], static_cast &r)>>(f1), prec); - if (true or mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], static_cast &r)>>(f2), prec); - if (true or mrcpp::mpi::my_func(Phi[2])) mrcpp::project(Phi[2], static_cast &r)>>(f3), prec); - if (true or mrcpp::mpi::my_func(Phi[3])) mrcpp::project(Phi[3], static_cast &r)>>(f4), prec); + if (true or mrcpp::mpi::my_func(Phi[0])) mrcpp::project(Phi[0], f1, prec); + if (true or mrcpp::mpi::my_func(Phi[1])) mrcpp::project(Phi[1], f2, prec); + if (true or mrcpp::mpi::my_func(Phi[2])) mrcpp::project(Phi[2], f3, prec); + if (true or mrcpp::mpi::my_func(Phi[3])) mrcpp::project(Phi[3], f4, prec); // Complex phase rotation + // NB: Phi becomes complex for (int n = 0; n < Phi.size(); n++) { double theta = (n + 1.0) * mrcpp::pi / 7.0; ComplexDouble phase(std::cos(theta), std::sin(theta)); @@ -288,8 +289,8 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { Psi.push_back(Orbital(SPIN::Alpha)); Psi.push_back(Orbital(SPIN::Beta)); - if (mrcpp::mpi::my_func(Psi[0])) mrcpp::project(Psi[0], static_cast &r)>>(f5), prec); - if (mrcpp::mpi::my_func(Psi[1])) mrcpp::project(Psi[1], static_cast &r)>>(f6), prec); + if (mrcpp::mpi::my_func(Psi[0])) mrcpp::project(Psi[0], f5, prec); + if (mrcpp::mpi::my_func(Psi[1])) mrcpp::project(Psi[1], f6, prec); orthogonalize(prec, Phi); orthogonalize(prec, Psi, Phi); @@ -307,11 +308,10 @@ TEST_CASE("OrbitalVector", "[orbital_vector]") { Phi.push_back(Orbital(SPIN::Paired)); if (mrcpp::mpi::my_func(Phi[0])) { - mrcpp::project(Phi[0], static_cast &r)>>(f1), prec); - mrcpp::project(Phi[1], static_cast &r)>>(f2), prec); + mrcpp::project(Phi[0], f1, prec); + mrcpp::project(Phi[1], f2, prec); } - orthogonalize(prec, Phi); normalize(Phi); diff --git a/tests/qmoperators/coulomb_hessian.cpp b/tests/qmoperators/coulomb_hessian.cpp index 48bd33050..b2b2a6a2d 100644 --- a/tests/qmoperators/coulomb_hessian.cpp +++ b/tests/qmoperators/coulomb_hessian.cpp @@ -103,7 +103,7 @@ TEST_CASE("CoulombHessian", "[coulomb_hessian]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + ComplexDouble V_00 = mrcpp::dot(Phi[0], Vphi_0); if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); @@ -115,7 +115,7 @@ TEST_CASE("CoulombHessian", "[coulomb_hessian]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + ComplexDouble V_ii = mrcpp::dot(Phi[i], VPhi[i]); if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); diff --git a/tests/qmoperators/coulomb_operator.cpp b/tests/qmoperators/coulomb_operator.cpp index 4c98e79aa..dbbdbf9e5 100644 --- a/tests/qmoperators/coulomb_operator.cpp +++ b/tests/qmoperators/coulomb_operator.cpp @@ -97,7 +97,7 @@ TEST_CASE("CoulombOperator", "[coulomb_operator]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + ComplexDouble V_ii = mrcpp::dot(Phi[i], VPhi[i]); if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); diff --git a/tests/qmoperators/electric_field_operator.cpp b/tests/qmoperators/electric_field_operator.cpp index f2e52c258..97874f2a2 100644 --- a/tests/qmoperators/electric_field_operator.cpp +++ b/tests/qmoperators/electric_field_operator.cpp @@ -91,11 +91,11 @@ TEST_CASE("ElectricFieldOperator", "[electric_field_operator]") { } Orbital phi_x = EF(Phi[0]); - ComplexDouble X_00 = orbital::dot(static_cast(Phi[0]), phi_x); - ComplexDouble X_10 = orbital::dot(static_cast(Phi[1]), phi_x); - ComplexDouble X_20 = orbital::dot(static_cast(Phi[2]), phi_x); - ComplexDouble X_30 = orbital::dot(static_cast(Phi[3]), phi_x); - ComplexDouble X_40 = orbital::dot(static_cast(Phi[4]), phi_x); + ComplexDouble X_00 = mrcpp::dot(Phi[0], phi_x); + ComplexDouble X_10 = mrcpp::dot(Phi[1], phi_x); + ComplexDouble X_20 = mrcpp::dot(Phi[2], phi_x); + ComplexDouble X_30 = mrcpp::dot(Phi[3], phi_x); + ComplexDouble X_40 = mrcpp::dot(Phi[4], phi_x); REQUIRE(X_00.real() == Approx(ref(0, 0)).margin(thrs)); REQUIRE(X_10.real() == Approx(ref(0, 1)).margin(thrs)); REQUIRE(X_20.real() == Approx(ref(0, 2)).margin(thrs)); @@ -114,7 +114,7 @@ TEST_CASE("ElectricFieldOperator", "[electric_field_operator]") { OrbitalVector xPhi = EF(Phi); for (int i = 0; i < Phi.size(); i++) { for (int j = 0; j < xPhi.size(); j++) { - ComplexDouble X_ij = orbital::dot(Phi[i], xPhi[j]); + ComplexDouble X_ij = mrcpp::dot(Phi[i], xPhi[j]); REQUIRE(std::abs(X_ij.real()) == Approx(ref(i, j)).margin(thrs)); } } diff --git a/tests/qmoperators/exchange_hessian.cpp b/tests/qmoperators/exchange_hessian.cpp index 50df9caa6..aa44ebb72 100644 --- a/tests/qmoperators/exchange_hessian.cpp +++ b/tests/qmoperators/exchange_hessian.cpp @@ -111,7 +111,7 @@ TEST_CASE("ExchangeHessian", "[exchange_hessian]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + ComplexDouble V_00 = mrcpp::dot(Phi[0], Vphi_0); if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); @@ -123,7 +123,7 @@ TEST_CASE("ExchangeHessian", "[exchange_hessian]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + ComplexDouble V_ii = mrcpp::dot(Phi[i], VPhi[i]); if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); diff --git a/tests/qmoperators/exchange_operator.cpp b/tests/qmoperators/exchange_operator.cpp index a1529dbc2..70ac2be0d 100644 --- a/tests/qmoperators/exchange_operator.cpp +++ b/tests/qmoperators/exchange_operator.cpp @@ -81,7 +81,7 @@ TEST_CASE("ExchangeOperator", "[exchange_operator]") { SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + ComplexDouble V_00 = mrcpp::dot(Phi[0], Vphi_0); if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); @@ -93,7 +93,7 @@ TEST_CASE("ExchangeOperator", "[exchange_operator]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + ComplexDouble V_ii = mrcpp::dot(Phi[i], VPhi[i]); if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); diff --git a/tests/qmoperators/kinetic_operator.cpp b/tests/qmoperators/kinetic_operator.cpp index 625fb4f68..d4601edee 100644 --- a/tests/qmoperators/kinetic_operator.cpp +++ b/tests/qmoperators/kinetic_operator.cpp @@ -70,7 +70,7 @@ TEST_CASE("KineticOperator", "[kinetic_operator]") { T.setup(prec); SECTION("apply") { Orbital Tphi_0 = T(Phi[0]); - ComplexDouble T_00 = orbital::dot(static_cast(Phi[0]), Tphi_0); + ComplexDouble T_00 = mrcpp::dot(Phi[0], Tphi_0); if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(T_00.real() == Approx(E_K(0))); REQUIRE(T_00.imag() < thrs); @@ -83,7 +83,7 @@ TEST_CASE("KineticOperator", "[kinetic_operator]") { OrbitalVector TPhi = T(Phi); ComplexMatrix t = orbital::calc_overlap_matrix(Phi, TPhi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble T_ii = orbital::dot(Phi[i], TPhi[i]); + ComplexDouble T_ii = mrcpp::dot(Phi[i], TPhi[i]); if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(T_ii.real() == Approx(E_K(i))); REQUIRE(T_ii.imag() < thrs); diff --git a/tests/qmoperators/nuclear_operator.cpp b/tests/qmoperators/nuclear_operator.cpp index 86aae731c..5a3355adc 100644 --- a/tests/qmoperators/nuclear_operator.cpp +++ b/tests/qmoperators/nuclear_operator.cpp @@ -90,7 +90,7 @@ TEST_CASE("PointNucleusHFYGB", "[nuclear_operator]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), Vphi_0); + ComplexDouble V_00 = mrcpp::dot(Phi[0], Vphi_0); if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0)).epsilon(prec)); REQUIRE(V_00.imag() < thrs); @@ -102,7 +102,7 @@ TEST_CASE("PointNucleusHFYGB", "[nuclear_operator]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + ComplexDouble V_ii = mrcpp::dot(Phi[i], VPhi[i]); if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i)).epsilon(prec)); REQUIRE(V_ii.imag() < thrs); @@ -183,7 +183,7 @@ TEST_CASE("PointNucleusParabola", "[nuclear_operator]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), Vphi_0); + ComplexDouble V_00 = mrcpp::dot(Phi[0], Vphi_0); if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0)).epsilon(prec)); REQUIRE(V_00.imag() < thrs); @@ -195,7 +195,7 @@ TEST_CASE("PointNucleusParabola", "[nuclear_operator]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + ComplexDouble V_ii = mrcpp::dot(Phi[i], VPhi[i]); if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i)).epsilon(prec)); REQUIRE(V_ii.imag() < thrs); @@ -276,7 +276,7 @@ TEST_CASE("PointNucleusMinimum", "[nuclear_operator]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), Vphi_0); + ComplexDouble V_00 = mrcpp::dot(Phi[0], Vphi_0); if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0)).epsilon(prec)); REQUIRE(V_00.imag() < thrs); @@ -288,7 +288,7 @@ TEST_CASE("PointNucleusMinimum", "[nuclear_operator]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + ComplexDouble V_ii = mrcpp::dot(Phi[i], VPhi[i]); if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i)).epsilon(prec)); REQUIRE(V_ii.imag() < thrs); diff --git a/tests/qmoperators/xc_hessian_pbe.cpp b/tests/qmoperators/xc_hessian_pbe.cpp index a68a8b2c9..2b01c91d0 100644 --- a/tests/qmoperators/xc_hessian_pbe.cpp +++ b/tests/qmoperators/xc_hessian_pbe.cpp @@ -111,7 +111,7 @@ TEST_CASE("XCHessianPBE", "[xc_hessian_pbe]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + ComplexDouble V_00 = mrcpp::dot(Phi[0], Vphi_0); if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); @@ -123,7 +123,7 @@ TEST_CASE("XCHessianPBE", "[xc_hessian_pbe]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + ComplexDouble V_ii = mrcpp::dot(Phi[i], VPhi[i]); if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); diff --git a/tests/qmoperators/xc_operator_blyp.cpp b/tests/qmoperators/xc_operator_blyp.cpp index 4e83a5a5a..c34a5d1d6 100644 --- a/tests/qmoperators/xc_operator_blyp.cpp +++ b/tests/qmoperators/xc_operator_blyp.cpp @@ -94,7 +94,7 @@ TEST_CASE("XCOperatorBLYP", "[xc_operator_blyp]") { V.setup(prec); SECTION("apply") { Orbital Vphi_0 = V(Phi[0]); - ComplexDouble V_00 = orbital::dot(static_cast(Phi[0]), static_cast(Vphi_0)); + ComplexDouble V_00 = mrcpp::dot(Phi[0], Vphi_0); if (mrcpp::mpi::my_func(Phi[0])) { REQUIRE(V_00.real() == Approx(E_P(0, 0)).epsilon(thrs)); REQUIRE(V_00.imag() < thrs); @@ -106,7 +106,7 @@ TEST_CASE("XCOperatorBLYP", "[xc_operator_blyp]") { SECTION("vector apply") { OrbitalVector VPhi = V(Phi); for (int i = 0; i < Phi.size(); i++) { - ComplexDouble V_ii = orbital::dot(static_cast(Phi[i]), static_cast(VPhi[i])); + ComplexDouble V_ii = mrcpp::dot(Phi[i], VPhi[i]); if (mrcpp::mpi::my_func(Phi[i])) { REQUIRE(V_ii.real() == Approx(E_P(i, i)).epsilon(thrs)); REQUIRE(V_ii.imag() < thrs); From a8bf937e494bd66a68c6733a2a802b685a0f1bc1 Mon Sep 17 00:00:00 2001 From: gitpeterwind Date: Mon, 26 Aug 2024 15:45:42 +0200 Subject: [PATCH 7/8] compatibility for redefined mrcpp alloc --- src/environment/GPESolver.cpp | 8 ++++---- src/environment/PBESolver.cpp | 2 +- src/initial_guess/cube.cpp | 2 +- src/initial_guess/sad.cpp | 2 +- src/qmfunctions/Density.cpp | 4 ++-- src/qmfunctions/density_utils.cpp | 8 ++++---- src/qmfunctions/orbital_utils.cpp | 4 ++-- src/qmoperators/QMDerivative.cpp | 6 +++--- src/qmoperators/one_electron/DistanceOperator.h | 2 +- src/qmoperators/one_electron/NuclearOperator.cpp | 2 +- src/qmoperators/two_electron/CoulombPotential.cpp | 6 +++--- src/qmoperators/two_electron/XCPotentialD1.cpp | 6 +++--- src/qmoperators/two_electron/XCPotentialD2.cpp | 12 ++++++------ tests/qmoperators/position_operator.cpp | 2 +- 14 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/environment/GPESolver.cpp b/src/environment/GPESolver.cpp index 5e214b8ba..a1b6151ad 100644 --- a/src/environment/GPESolver.cpp +++ b/src/environment/GPESolver.cpp @@ -123,7 +123,7 @@ mrcpp::CompFunction<3> GPESolver::solvePoissonEquation(const mrcpp::CompFunction mrcpp::CompFunction<3> first_term; mrcpp::CompFunction<3> Vr_np1; Vr_np1.func_ptr->isreal = 1; - Vr_np1.alloc(0); + Vr_np1.alloc(1); auto eps_inv_func = mrcpp::AnalyticFunction<3>([this](const mrcpp::Coord<3> &r) { return 1.0 / this->epsilon.evalf(r); }); Density rho_tot(false); @@ -238,7 +238,7 @@ mrcpp::CompFunction<3> &GPESolver::solveEquation(double prec, const Density &rho Timer t_vac; mrcpp::CompFunction<3> V_vac; V_vac.func_ptr->isreal = 1; - V_vac.alloc(0); + V_vac.alloc(1); mrcpp::apply(this->apply_prec, V_vac.real(), *poisson, rho_tot.real()); rho_tot.free(); print_utils::qmfunction(3, "Vacuum potential", V_vac, t_vac); @@ -250,7 +250,7 @@ mrcpp::CompFunction<3> &GPESolver::solveEquation(double prec, const Density &rho mrcpp::CompFunction<3> gamma_0; mrcpp::CompFunction<3> V_tot; gamma_0.func_ptr->isreal = 1; - gamma_0.alloc(0); + gamma_0.alloc(1); computeGamma(V_vac, gamma_0); this->Vr_n = solvePoissonEquation(gamma_0, rho_el); @@ -273,7 +273,7 @@ auto GPESolver::computeEnergies(const Density &rho_el) -> std::tuple &function) { function.func_ptr->isreal = 1; function.func_ptr->iscomplex = 0; - function.alloc(0); + function.alloc(1); } void GPESolver::printParameters() const { diff --git a/src/environment/PBESolver.cpp b/src/environment/PBESolver.cpp index 5ea02e2ae..39944dad2 100644 --- a/src/environment/PBESolver.cpp +++ b/src/environment/PBESolver.cpp @@ -63,7 +63,7 @@ void PBESolver::computePBTerm(mrcpp::CompFunction<3> &V_tot, const double salt_f resetComplexFunction(pb_term); mrcpp::CompFunction<3> sinhV; sinhV.func_ptr->isreal = 1; - sinhV.alloc(0); + sinhV.alloc(1); mrcpp::map(this->apply_prec / 100, sinhV.real(), V_tot.real(), sinh_f); mrcpp::multiply(pb_term, sinhV, this->kappa, this->apply_prec); diff --git a/src/initial_guess/cube.cpp b/src/initial_guess/cube.cpp index a199df375..ebc5693ce 100644 --- a/src/initial_guess/cube.cpp +++ b/src/initial_guess/cube.cpp @@ -120,7 +120,7 @@ bool initial_guess::cube::project_mo(OrbitalVector &Phi, double prec, const std: Timer t_i; if (mrcpp::mpi::my_func(Phi[i])) { CUBEfunction phi_i = CUBEVector[i]; - Phi[i].alloc(0); + Phi[i].alloc(1); mrcpp::project(prec, Phi[i].real(), phi_i); std::stringstream o_txt; o_txt << std::setw(w1 - 1) << i; diff --git a/src/initial_guess/sad.cpp b/src/initial_guess/sad.cpp index 779361f9e..489350158 100644 --- a/src/initial_guess/sad.cpp +++ b/src/initial_guess/sad.cpp @@ -249,7 +249,7 @@ void initial_guess::sad::project_atomic_densities(double prec, Density &rho_tot, Timer t_tot; Density rho_loc(false); - rho_loc.alloc(); + rho_loc.alloc(1); rho_loc.real().setZero(); Timer t_loc; diff --git a/src/qmfunctions/Density.cpp b/src/qmfunctions/Density.cpp index f00aa11b2..843e6f50e 100644 --- a/src/qmfunctions/Density.cpp +++ b/src/qmfunctions/Density.cpp @@ -111,7 +111,7 @@ void Density::loadDensity(const std::string &file) { if (isreal()) { std::stringstream fname; fname << file << "_re"; - alloc(0); + alloc(1); CompD[0]->loadTree(fname.str()); } @@ -119,7 +119,7 @@ void Density::loadDensity(const std::string &file) { if (iscomplex()) { std::stringstream fname; fname << file << "_cx"; - alloc(0); + alloc(1); CompC[0]->loadTree(fname.str()); } } diff --git a/src/qmfunctions/density_utils.cpp b/src/qmfunctions/density_utils.cpp index 2613e0017..dd7947dd0 100644 --- a/src/qmfunctions/density_utils.cpp +++ b/src/qmfunctions/density_utils.cpp @@ -154,7 +154,7 @@ void density::compute_local_X(double prec, Density &rho, OrbitalVector &Phi, Orb double add_prec = prec / N_el; // prec for rho = sum_i rho_i if (Phi.size() != X.size()) MSG_ERROR("Size mismatch"); - if (rho.Ncomp() == 0) rho.alloc(0); + if (rho.Ncomp() == 0) rho.alloc(1); // Compute local density from own orbitals for (int i = 0; i < Phi.size(); i++) { @@ -179,7 +179,7 @@ void density::compute_local_XY(double prec, Density &rho, OrbitalVector &Phi, Or if (Phi.size() != X.size()) MSG_ERROR("Size mismatch"); if (Phi.size() != Y.size()) MSG_ERROR("Size mismatch"); - if (rho.Ncomp() == 0) rho.alloc(0); + if (rho.Ncomp() == 0) rho.alloc(1); // Compute local density from own orbitals rho.real().setZero(); @@ -205,7 +205,7 @@ void density::compute_local_XY(double prec, Density &rho, OrbitalVector &Phi, Or } void density::compute(double prec, Density &rho, mrcpp::GaussExp<3> &dens_exp) { - if (not rho.hasReal()) rho.alloc(NUMBER::Real); + if (not rho.hasReal()) rho.alloc(1); mrcpp::build_grid(rho.real(), dens_exp); mrcpp::project(prec, rho.real(), dens_exp); } @@ -228,7 +228,7 @@ void density::allreduce_density(double prec, Density &rho_tot, Density &rho_loc) if (mrcpp::mpi::numerically_exact) rho_loc.crop(prec); } - if (not rho_tot.hasReal()) rho_tot.alloc(NUMBER::Real); + if (not rho_tot.hasReal()) rho_tot.alloc(1); if (rho_tot.isShared()) { int tag = 2002; diff --git a/src/qmfunctions/orbital_utils.cpp b/src/qmfunctions/orbital_utils.cpp index 4e7f418ac..d4bfcfdce 100644 --- a/src/qmfunctions/orbital_utils.cpp +++ b/src/qmfunctions/orbital_utils.cpp @@ -1236,7 +1236,7 @@ void orbital::loadOrbital(const std::string &file, Orbital &orb) { if (orb.isreal()) { std::stringstream fname; fname << file << "_real"; - orb.alloc(0); + orb.alloc(1); orb.CompD[0]->loadTree(fname.str()); } @@ -1244,7 +1244,7 @@ void orbital::loadOrbital(const std::string &file, Orbital &orb) { if (orb.iscomplex()) { std::stringstream fname; fname << file << "_complex"; - orb.alloc(0); + orb.alloc(1); orb.CompC[0]->loadTree(fname.str()); } delete mra; diff --git a/src/qmoperators/QMDerivative.cpp b/src/qmoperators/QMDerivative.cpp index f37521ee9..3c9046205 100644 --- a/src/qmoperators/QMDerivative.cpp +++ b/src/qmoperators/QMDerivative.cpp @@ -97,13 +97,13 @@ QMOperatorVector QMDerivative::apply(QMOperator_p &O) { // does not compile? mrcpp::apply(V_out_base, D, V_inp, d); if (this->isReal()) { if (V_inp->isreal()) { - V_out->alloc(0); + V_out->alloc(1); mrcpp::apply(V_out->real(), D, V_inp->real(), d); } if (V_inp->iscomplex()) { V_out->func_ptr->isreal = 0; V_out->func_ptr->iscomplex = 1; - V_out->alloc(0); + V_out->alloc(1); mrcpp::apply(V_out->complex(), D, V_inp->complex(), d); //if (V_inp->conjugate()) V_out->imag().rescale(-1.0); } @@ -111,7 +111,7 @@ QMOperatorVector QMDerivative::apply(QMOperator_p &O) { if (V_inp->iscomplex()) { V_out->func_ptr->isreal = 0; V_out->func_ptr->iscomplex = 1; - V_out->alloc(0); + V_out->alloc(1); mrcpp::apply(V_out->complex(), D, V_inp->complex(), d); if (!V_inp->conjugate()) V_out->CompC[0]->rescale({0.0, 1.0}); } diff --git a/src/qmoperators/one_electron/DistanceOperator.h b/src/qmoperators/one_electron/DistanceOperator.h index 8988a1345..aaa4a0e2a 100644 --- a/src/qmoperators/one_electron/DistanceOperator.h +++ b/src/qmoperators/one_electron/DistanceOperator.h @@ -57,7 +57,7 @@ class DistanceOperator final : public RankZeroOperator { // Project analytic potential, building grid for 1/r auto r_pow = std::make_shared(1); - r_pow->alloc(0); + r_pow->alloc(1); mrcpp::build_grid(r_pow->real(), nuc_func); mrcpp::project<3>(proj_prec, r_pow->real(), f); diff --git a/src/qmoperators/one_electron/NuclearOperator.cpp b/src/qmoperators/one_electron/NuclearOperator.cpp index bbb259eb0..d2a9646f8 100644 --- a/src/qmoperators/one_electron/NuclearOperator.cpp +++ b/src/qmoperators/one_electron/NuclearOperator.cpp @@ -170,7 +170,7 @@ void NuclearOperator::allreducePotential(double prec, mrcpp::CompFunction<3> &V_ if (mrcpp::mpi::numerically_exact) V_loc.crop(prec); } - if (not V_tot.hasReal()) V_tot.alloc(0); + if (not V_tot.hasReal()) V_tot.alloc(1); if (V_tot.isShared()) { int tag = 3141; // MPI grand master distributes to shared masters diff --git a/src/qmoperators/two_electron/CoulombPotential.cpp b/src/qmoperators/two_electron/CoulombPotential.cpp index 89cc0bfb9..4195634f1 100644 --- a/src/qmoperators/two_electron/CoulombPotential.cpp +++ b/src/qmoperators/two_electron/CoulombPotential.cpp @@ -126,7 +126,7 @@ void CoulombPotential::setupGlobalPotential(double prec) { bool need_to_apply = not(V.isShared()) or mrcpp::mpi::share_master(); Timer timer; - V.alloc(0); + V.alloc(1); if (need_to_apply) mrcpp::apply(abs_prec, V.real(), P, rho.real()); mrcpp::mpi::share_function(V, 0, 22445, mrcpp::mpi::comm_share); print_utils::qmfunction(3, "Compute global potential", V, timer); @@ -151,7 +151,7 @@ mrcpp::CompFunction<3> CoulombPotential::setupLocalPotential(double prec) { Timer timer; mrcpp::CompFunction<3> V(false); - V.alloc(0); + V.alloc(1); mrcpp::apply(abs_prec, V.real(), P, rho.real()); print_utils::qmfunction(3, "Compute local potential", V, timer); @@ -169,7 +169,7 @@ void CoulombPotential::allreducePotential(double prec, mrcpp::CompFunction<3> &V // Add up local contributions into the grand master mrcpp::mpi::reduce_function(abs_prec, V_loc, mrcpp::mpi::comm_wrk); - if (not V_tot.hasReal()) V_tot.alloc(0); + if (not V_tot.hasReal()) V_tot.alloc(1); if (V_tot.isShared()) { int tag = 3141; // MPI grand master distributes to shared masters diff --git a/src/qmoperators/two_electron/XCPotentialD1.cpp b/src/qmoperators/two_electron/XCPotentialD1.cpp index 14c38b7ee..6313e0206 100644 --- a/src/qmoperators/two_electron/XCPotentialD1.cpp +++ b/src/qmoperators/two_electron/XCPotentialD1.cpp @@ -54,7 +54,7 @@ mrcpp::FunctionTreeVector<3> XCPotentialD1::setupDensities(double prec, mrcpp::F Timer timer; Density &rho = getDensity(DensityType::Total, 0); if (rho.Ncomp() == 0) { - rho.alloc(0); + rho.alloc(1); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Total); } @@ -66,7 +66,7 @@ mrcpp::FunctionTreeVector<3> XCPotentialD1::setupDensities(double prec, mrcpp::F Timer timer; Density &rho = getDensity(DensityType::Alpha, 0); if (rho.Ncomp() == 0) { - rho.alloc(0); + rho.alloc(1); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Alpha); } @@ -77,7 +77,7 @@ mrcpp::FunctionTreeVector<3> XCPotentialD1::setupDensities(double prec, mrcpp::F Timer timer; Density &rho = getDensity(DensityType::Beta, 0); if (rho.Ncomp() == 0) { - rho.alloc(0); + rho.alloc(1); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Beta); } diff --git a/src/qmoperators/two_electron/XCPotentialD2.cpp b/src/qmoperators/two_electron/XCPotentialD2.cpp index 94b279c18..f45beb154 100644 --- a/src/qmoperators/two_electron/XCPotentialD2.cpp +++ b/src/qmoperators/two_electron/XCPotentialD2.cpp @@ -75,7 +75,7 @@ mrcpp::FunctionTreeVector<3> XCPotentialD2::setupDensities(double prec, mrcpp::F Timer timer; Density &rho = getDensity(DensityType::Total, 0); if (rho.Ncomp() == 0) { - rho.alloc(0); + rho.alloc(1); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Total); } @@ -86,7 +86,7 @@ mrcpp::FunctionTreeVector<3> XCPotentialD2::setupDensities(double prec, mrcpp::F Timer timer; Density &rho = getDensity(DensityType::Total, 1); if (rho.Ncomp() == 0) { - rho.alloc(0); + rho.alloc(1); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, *orbitals_x, *orbitals_y, DensityType::Total); } @@ -98,7 +98,7 @@ mrcpp::FunctionTreeVector<3> XCPotentialD2::setupDensities(double prec, mrcpp::F Timer timer; Density &rho = getDensity(DensityType::Alpha, 0); if (rho.Ncomp() == 0) { - rho.alloc(0); + rho.alloc(1); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Alpha); } @@ -109,7 +109,7 @@ mrcpp::FunctionTreeVector<3> XCPotentialD2::setupDensities(double prec, mrcpp::F Timer timer; Density &rho = getDensity(DensityType::Beta, 0); if (rho.Ncomp() == 0) { - rho.alloc(0); + rho.alloc(1); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, DensityType::Beta); } @@ -120,7 +120,7 @@ mrcpp::FunctionTreeVector<3> XCPotentialD2::setupDensities(double prec, mrcpp::F Timer timer; Density &rho = getDensity(DensityType::Alpha, 1); if (rho.Ncomp() == 0) { - rho.alloc(0); + rho.alloc(1); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, *orbitals_x, *orbitals_y, DensityType::Alpha); } @@ -131,7 +131,7 @@ mrcpp::FunctionTreeVector<3> XCPotentialD2::setupDensities(double prec, mrcpp::F Timer timer; Density &rho = getDensity(DensityType::Beta, 1); if (rho.Ncomp() == 0) { - rho.alloc(0); + rho.alloc(1); mrcpp::copy_grid(rho.real(), grid); density::compute(prec, rho, *orbitals, *orbitals_x, *orbitals_y, DensityType::Beta); } diff --git a/tests/qmoperators/position_operator.cpp b/tests/qmoperators/position_operator.cpp index 18197306b..47d695684 100644 --- a/tests/qmoperators/position_operator.cpp +++ b/tests/qmoperators/position_operator.cpp @@ -63,7 +63,7 @@ TEST_CASE("PositionOperator", "[position_operator]") { r.setup(prec); SECTION("vector apply") { OrbitalVector xPhi = r[0](Phi); - ComplexMatrix X = orbital::calc_overlap_matrix(Phi, xPhi); + ComplexMatrix X = mrcpp::calc_overlap_matrix(Phi, xPhi); for (int i = 0; i < X.rows(); i++) { for (int j = 0; j < X.cols(); j++) { REQUIRE(std::abs(X(i, j).real() - ref(i, j)) < thrs); } } From 81e088ee6ccf7947361e77b7c823aef1731c5dbe Mon Sep 17 00:00:00 2001 From: gitpeterwind Date: Wed, 28 Aug 2024 10:51:24 +0200 Subject: [PATCH 8/8] resolve conflict --- src/initial_guess/core.cpp | 2 +- src/initial_guess/sad.cpp | 1 - src/qmfunctions/orbital_utils.cpp | 2 +- src/qmoperators/qmoperator_utils.cpp | 8 ++++---- src/tensor/RankTwoOperator.cpp | 6 +----- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/initial_guess/core.cpp b/src/initial_guess/core.cpp index b5bdc2892..ca4411b4b 100644 --- a/src/initial_guess/core.cpp +++ b/src/initial_guess/core.cpp @@ -232,7 +232,7 @@ void initial_guess::core::rotate_orbitals(OrbitalVector &Psi, double prec, Compl ComplexMatrix initial_guess::core::diagonalize(OrbitalVector &Phi, MomentumOperator &p, RankZeroOperator &V) { Timer t1; - ComplexMatrix S_m12 = orbital::calc_lowdin_matrix(Phi); + ComplexMatrix S_m12 = mrcpp::calc_lowdin_matrix(Phi); mrcpp::print::separator(2, '-'); ComplexMatrix t_tilde = qmoperator::calc_kinetic_matrix(p, Phi, Phi); ComplexMatrix v_tilde = V(Phi, Phi); diff --git a/src/initial_guess/sad.cpp b/src/initial_guess/sad.cpp index 489350158..afc31cbb5 100644 --- a/src/initial_guess/sad.cpp +++ b/src/initial_guess/sad.cpp @@ -200,7 +200,6 @@ bool initial_guess::sad::setup(OrbitalVector &Phi, double prec, double screen, c // Compute Fock matrix mrcpp::print::header(2, "Diagonalizing Fock matrix"); ComplexMatrix U = initial_guess::core::diagonalize(Psi, p, V); - // Rotate orbitals and fill electrons by Aufbau t_lap.start(); auto Phi_a = orbital::disjoin(Phi, SPIN::Alpha); diff --git a/src/qmfunctions/orbital_utils.cpp b/src/qmfunctions/orbital_utils.cpp index d4bfcfdce..f67d3f00a 100644 --- a/src/qmfunctions/orbital_utils.cpp +++ b/src/qmfunctions/orbital_utils.cpp @@ -250,7 +250,7 @@ OrbitalVector orbital::deep_copy(OrbitalVector &Phi) { OrbitalVector out; for (auto &i : Phi) { Orbital out_i; - if (mrcpp::mpi::my_func(out_i)) mrcpp::deep_copy(out_i, i); + if (mrcpp::mpi::my_func(i)) mrcpp::deep_copy(out_i, i); out.push_back(out_i); } return out; diff --git a/src/qmoperators/qmoperator_utils.cpp b/src/qmoperators/qmoperator_utils.cpp index fb149bb77..e5fdd668d 100644 --- a/src/qmoperators/qmoperator_utils.cpp +++ b/src/qmoperators/qmoperator_utils.cpp @@ -129,7 +129,7 @@ ComplexMatrix qmoperator::calc_kinetic_matrix_component(int d, MomentumOperator OrbitalVector dKet = p[d](ket); nNodes += orbital::get_n_nodes(dKet); sNodes += orbital::get_size_nodes(dKet); - T = orbital::calc_overlap_matrix(dKet); + T = mrcpp::calc_overlap_matrix(dKet); } else { OrbitalVector dBra = p[d](bra); OrbitalVector dKet = p[d](ket); @@ -137,7 +137,7 @@ ComplexMatrix qmoperator::calc_kinetic_matrix_component(int d, MomentumOperator nNodes += orbital::get_n_nodes(dKet); sNodes += orbital::get_size_nodes(dBra); sNodes += orbital::get_size_nodes(dKet); - T = orbital::calc_overlap_matrix(dBra, dKet); + T = mrcpp::calc_overlap_matrix(dBra, dKet); } if (d == 0) mrcpp::print::tree(2, "", nNodes, sNodes, timer.elapsed()); if (d == 1) mrcpp::print::tree(2, "", nNodes, sNodes, timer.elapsed()); @@ -156,7 +156,7 @@ ComplexMatrix qmoperator::calc_kinetic_matrix_component_symmetrized(int d, Momen OrbitalVector dKet = (V * p[d])(ket); nNodes += orbital::get_n_nodes(dKet); sNodes += orbital::get_size_nodes(dKet); - T = orbital::calc_overlap_matrix(dKet, dKet); + T = mrcpp::calc_overlap_matrix(dKet, dKet); } else { OrbitalVector dBra = (V * p[d])(bra); OrbitalVector dKet = (V * p[d])(ket); @@ -164,7 +164,7 @@ ComplexMatrix qmoperator::calc_kinetic_matrix_component_symmetrized(int d, Momen nNodes += orbital::get_n_nodes(dKet); sNodes += orbital::get_size_nodes(dBra); sNodes += orbital::get_size_nodes(dKet); - T = orbital::calc_overlap_matrix(dBra, dKet); + T = mrcpp::calc_overlap_matrix(dBra, dKet); } if (d == 0) mrcpp::print::tree(2, "", nNodes, sNodes, timer.elapsed()); if (d == 1) mrcpp::print::tree(2, "", nNodes, sNodes, timer.elapsed()); diff --git a/src/tensor/RankTwoOperator.cpp b/src/tensor/RankTwoOperator.cpp index 9b4755f83..5bd10db12 100644 --- a/src/tensor/RankTwoOperator.cpp +++ b/src/tensor/RankTwoOperator.cpp @@ -31,11 +31,9 @@ namespace mrchem { template ComplexMatrix RankTwoOperator::operator()(Orbital bra, Orbital ket) { - std::cout<<" RankTwoOperator "< &O = *this; + RankTwoOperator &O = *this; ComplexMatrix out(I, J); for (int i = 0; i < I; i++) out.row(i) = O[i](bra, ket); - std::cout<<" RankTwoOperator done "< ComplexMatrix RankTwoOperator::trace(OrbitalVector } template ComplexMatrix RankTwoOperator::trace(OrbitalVector &phi, OrbitalVector &x, OrbitalVector &y) { - std::cout<<" ARankTwoOperator "< &O = *this; ComplexMatrix out(I, J); for (int i = 0; i < I; i++) out.row(i) = O[i].trace(phi, x, y); @@ -55,7 +52,6 @@ template ComplexMatrix RankTwoOperator::trace(OrbitalVector } template ComplexMatrix RankTwoOperator::trace(const Nuclei &nucs) { - std::cout<<" BRankTwoOperator "< &O = *this; ComplexMatrix out(I, J); for (int i = 0; i < I; i++) out.row(i) = O[i].trace(nucs);