Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions include/integrals/property_types.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2025 NWChemEx-Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/** @file property_types.hpp
*
* Property types defined by the Integrals library are defined here. It's likely
* that this file will be moved into a distinct subdirectory if more property
* types are added in the future.
*/
#pragma once
#include <pluginplay/plugin/plugin.hpp>
#include <simde/utils/convert.hpp>

/** @namespace integrals::property_types
*
* @brief The namespace for property types defined by the Integrals library
*/
namespace integrals::property_types {

using decontract_basis_set =
simde::Convert<simde::type::ao_basis_set, simde::type::ao_basis_set>;

} // end namespace integrals::property_types
2 changes: 2 additions & 0 deletions src/integrals/integrals_mm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "ao_integrals/ao_integrals.hpp"
#include "libint/libint.hpp"
#include "utils/utils.hpp"
#include <integrals/integrals_mm.hpp>

namespace integrals {
Expand All @@ -39,6 +40,7 @@ void set_defaults(pluginplay::ModuleManager& mm) {
void load_modules(pluginplay::ModuleManager& mm) {
ao_integrals::load_modules(mm);
libint::load_modules(mm);
utils::load_modules(mm);
set_defaults(mm);
ao_integrals::set_defaults(mm);
}
Expand Down
61 changes: 61 additions & 0 deletions src/integrals/utils/decontract_basis_set.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2025 NWChemEx-Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "utils.hpp"
#include <integrals/property_types.hpp>

namespace integrals::utils {

using pt = integrals::property_types::decontract_basis_set;
using mol_basis_t = simde::type::ao_basis_set;
using abs_t = simde::type::atomic_basis_set;
using cg_t = simde::type::contracted_gaussian;
using doubles_t = std::vector<double>;

MODULE_CTOR(DecontractBasisSet) {
satisfies_property_type<pt>();
description("Decontracts the input AO basis set");
}

MODULE_RUN(DecontractBasisSet) {
const auto& [input_bs] = pt::unwrap_inputs(inputs);

// Decontracted primitives all have a coefficient of 1.0.
doubles_t coeffs{1.0};

// Loop over the shells in each atomic basis set and decontract them.
// For each primitive in a contracted Gaussian, make a new shell with
// only that primitive.
mol_basis_t output_bs;
for(const auto& abs : input_bs) {
abs_t new_abs(abs.basis_set_name(), abs.atomic_number(),
abs.center().as_point());
for(const auto& shell : abs) {
for(const auto& prim : shell.contracted_gaussian()) {
doubles_t exponent{prim.exponent()};
cg_t cg(coeffs.begin(), coeffs.end(), exponent.begin(),
exponent.end(), abs.center().as_point());
new_abs.add_shell(shell.pure(), shell.l(), cg);
}
}
output_bs.add_center(new_abs);
}

auto result = results();
return pt::wrap_results(result, output_bs);
}

} // end namespace integrals::utils
41 changes: 41 additions & 0 deletions src/integrals/utils/utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2025 NWChemEx-Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/** @file utils.hpp
*
* Declaration of utility modules for the Integrals library, plus common
* infrastructural functions.
*/
#pragma once
#include <pluginplay/pluginplay.hpp>
#include <simde/simde.hpp>

/** @namespace integrals::utils
*
* @brief The namespace for general utility modules for integrals
*/
namespace integrals::utils {

DECLARE_MODULE(DecontractBasisSet);

inline void set_defaults(pluginplay::ModuleManager& mm) {}

inline void load_modules(pluginplay::ModuleManager& mm) {
mm.add_module<DecontractBasisSet>("Decontract Basis Set");
set_defaults(mm);
}

} // end namespace integrals::utils
54 changes: 54 additions & 0 deletions tests/cxx/unit/integrals/testing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,60 @@ inline simde::type::ao_basis_set water_sto3g_basis_set() {
return bs;
}

inline simde::type::ao_basis_set water_decontracted_sto3g_basis_set() {
using ao_basis_t = simde::type::ao_basis_set;
using atomic_basis_t = simde::type::atomic_basis_set;
using cg_t = simde::type::contracted_gaussian;
using point_t = simde::type::point;
using doubles_t = std::vector<double>;

auto mol = water_molecule();
point_t r0 = mol[0].as_nucleus();
point_t r1 = mol[1].as_nucleus();
point_t r2 = mol[2].as_nucleus();

// This is the only coefficient needed.
doubles_t cs{1.0};

atomic_basis_t o("sto-3g", 8, r0);
doubles_t es0{130.7093200, 23.8088610, 6.4436083};
doubles_t es1{5.0331513, 1.1695961, 0.3803890};

// Loops are ordered to match the order they would be decontracted in.
for(double e : es0) {
cg_t cg(cs.begin(), cs.end(), &e, &e + 1, r0);
o.add_shell(chemist::ShellType::pure, 0, cg);
}
for(double e : es1) {
cg_t cg(cs.begin(), cs.end(), &e, &e + 1, r0);
o.add_shell(chemist::ShellType::pure, 0, cg);
}
for(double e : es1) {
cg_t cg(cs.begin(), cs.end(), &e, &e + 1, r0);
o.add_shell(chemist::ShellType::pure, 1, cg);
}

atomic_basis_t h0("sto-3g", 1, r1);
atomic_basis_t h1("sto-3g", 1, r2);
doubles_t es2{3.425250914, 0.6239137298, 0.1688554040};

// Again, the loops are to replicate the decontraction order.
for(double e : es2) {
cg_t cg(cs.begin(), cs.end(), &e, &e + 1, r1);
h0.add_shell(chemist::ShellType::pure, 0, cg);
}
for(double e : es2) {
cg_t cg(cs.begin(), cs.end(), &e, &e + 1, r2);
h1.add_shell(chemist::ShellType::pure, 0, cg);
}

ao_basis_t bs;
bs.add_center(o);
bs.add_center(h0);
bs.add_center(h1);
return bs;
}

// Inputs for H2 tests
inline simde::type::molecule h2_molecule() {
using atom_t = simde::type::atom;
Expand Down
39 changes: 39 additions & 0 deletions tests/cxx/unit/integrals/utils/test_decontract_basis_set.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2025 NWChemEx-Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "../testing.hpp"
#include <integrals/property_types.hpp>

TEST_CASE("DecontractBasisSet") {
using test_pt = integrals::property_types::decontract_basis_set;

pluginplay::ModuleManager mm;
integrals::load_modules(mm);
REQUIRE(mm.count("Decontract Basis Set"));

// Get basis set
auto aobs = test::water_sto3g_basis_set();

// Get module
auto& mod = mm.at("Decontract Basis Set");

// Call module
auto decontracted_aobs = mod.run_as<test_pt>(aobs);

// Check output
auto corr = test::water_decontracted_sto3g_basis_set();
REQUIRE(decontracted_aobs == corr);
}