Skip to content

Lindh-Malmqvist-Gagliardi Radial Grid #84

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 22 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9256a78
Add Lambert-W0 implementation for inverting exponential products
wavefunction91 Sep 26, 2023
7fe816f
Added and tested Lambert Wm1 function
wavefunction91 Sep 27, 2023
7853fed
Added LMG utility functions to compute upper/lower radial bounds
wavefunction91 Sep 27, 2023
54f13f4
Added LMG utility to compute step size for radial grid of a given pre…
wavefunction91 Sep 28, 2023
26f9c63
Remove boost header
wavefunction91 Sep 28, 2023
7b71e32
Added parameter fall through for lmg::r_lower per source provided by …
wavefunction91 Sep 28, 2023
7e71f94
Start LMG RadialTraits + misc dox++
wavefunction91 Oct 2, 2023
6c41dde
Added initial implementation of LMG + UTs
wavefunction91 Oct 3, 2023
cb6a4f9
Added implementations of integer and half-integer math functions
wavefunction91 Oct 12, 2023
bbb2483
Replace tgamma with half_integer_tgamma where appropriate
wavefunction91 Oct 12, 2023
6495dc5
Added integer POW routines
wavefunction91 Oct 12, 2023
2ef9ca3
function wrappers
wavefunction91 Nov 1, 2023
bdc342e
Add util_test to Ctest
wavefunction91 Nov 6, 2023
80e592c
Add INTEGRATORXX_HEADER_ONLY + requisite source refactor to enable he…
wavefunction91 Jan 3, 2024
482d871
Update README with header-only instructions
wavefunction91 Jan 3, 2024
e92cb07
Add header-only to CI
wavefunction91 Jan 3, 2024
e1a440b
Merge branch 'feature/lmg' of github.com:wavefunction91/IntegratorXX …
wavefunction91 Jan 3, 2024
861cc16
Merge branch 'feature/lmg' of github.com:wavefunction91/IntegratorXX …
wavefunction91 Jan 3, 2024
bd95ee0
Testing LMG grids
wavefunction91 Jan 3, 2024
6e23fe1
Merge branch 'feature/header_only' into merge_header_only_into_lmg
wavefunction91 Jan 3, 2024
dba0abc
Make LMG work with new RadialTraits schema
wavefunction91 Jan 3, 2024
15ed819
Add LMG to runtime generator
wavefunction91 Jan 3, 2024
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
4 changes: 4 additions & 0 deletions .github/workflows/build_and_test_compiler_zoo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ jobs:
runs-on: ubuntu-latest
container:
image: dbwy/chemistry
strategy:
matrix:
header_only: [ON,OFF]

steps:
- uses: actions/checkout@v3
Expand All @@ -64,6 +67,7 @@ jobs:
- name: Configure CMake
shell: bash
run: cmake -S $GITHUB_WORKSPACE -B ${{runner.workspace}}/build
-DINTEGRATORXX_HEADER_ONLY=${{matrix.header_only}}
-DCMAKE_INSTALL_PREFIX=${{runner.workspace}}/install
-DCMAKE_PREFIX_PATH=${ENV_PREFIX_PATH}
-DCMAKE_TOOLCHAIN_FILE=${GITHUB_WORKSPACE}/${GH_ACTIONS_TOOLCHAIN}
Expand Down
89 changes: 87 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,99 @@ cmake_minimum_required( VERSION 3.17 ) # Require CMake 3.17+
# Set up project definition + version information
project( IntegratorXX VERSION 1.2.0 LANGUAGES CXX )

#add_library( integratorxx INTERFACE )
add_subdirectory(src)
option(INTEGRATORXX_HEADER_ONLY "Force header-only build" OFF)

if(INTEGRATORXX_HEADER_ONLY)
add_library( integratorxx INTERFACE )
set(INTEGRATORXX_TARGET_TYPE INTERFACE)
else()
add_subdirectory(src)
set(INTEGRATORXX_TARGET_TYPE PUBLIC)
endif()

# Target features
target_compile_features( integratorxx ${INTEGRATORXX_TARGET_TYPE} cxx_std_17 )
target_include_directories( integratorxx
${INTEGRATORXX_TARGET_TYPE}
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
)

include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-Wno-missing-braces" INTEGRATORXX_HAS_NO_MISSING_BRACES )
if( INTEGRATORXX_HAS_NO_MISSING_BRACES )
target_compile_options( integratorxx INTERFACE $<$<COMPILE_LANGUAGE:CXX>: -Wno-missing-braces> )
endif()




# INSTALL rules
add_library( IntegratorXX::IntegratorXX ALIAS integratorxx )
include( GNUInstallDirs )
set( INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/IntegratorXX )

# Targets
install(TARGETS integratorxx
EXPORT integratorxx-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

set_target_properties( integratorxx PROPERTIES EXPORT_NAME IntegratorXX )

# Install Headers
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )

# Export target to script
install(EXPORT integratorxx-targets
FILE
IntegratorXXTargets.cmake
NAMESPACE
IntegratorXX::
DESTINATION
${INSTALL_CONFIGDIR}
)

# Export build-tree targets also (e.g. to be usable by FetchContent)
export(EXPORT integratorxx-targets
NAMESPACE IntegratorXX::
FILE "${PROJECT_BINARY_DIR}/IntegratorXXTargets.cmake")

# Create a ConfigVersion.cmake file
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/IntegratorXXConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)

# Setup IntegratorXXConfig.cmake
configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/IntegratorXXConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/IntegratorXXConfig.cmake
INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
)

#Install the config, configversion and custom find modules
install(DIRECTORY
${PROJECT_SOURCE_DIR}/cmake/
DESTINATION ${INSTALL_CONFIGDIR}
FILES_MATCHING PATTERN "*.cmake"
)


install(FILES
${CMAKE_CURRENT_BINARY_DIR}/IntegratorXXConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/IntegratorXXConfigVersion.cmake
DESTINATION ${INSTALL_CONFIGDIR}
)

# Testing
if( NOT DEFINED INTEGRATORXX_ENABLE_TESTS )
set( INTEGRATORXX_ENABLE_TESTS ON )
endif()


if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include(CTest)
endif()
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,26 @@ const auto& weights = sph_quad->weights(); // std::vector<double>

```

### Header-only builds

With the exception of the runtime grid generator, the entirety
of the grid specification in IntegratorXX is header-only and can operate
without pre-compiled components. By default, the runtime generator is
pre-compiled to improve the efficiency of the compilation process and to
avoid excessive build times in complex projects with aggressive compiler
optimization. **N.B. it is highly recommend that users maintain this default
behavior to avoid excessive compilation sizes and build times**.

IntegratorXX also allows for header-only use of the runtime generator by
setting `INTEGRATORXX_HEADER_ONLY=ON`.
This feature also allows for circumvention of
the CMake build system by simply including the requisite implementation
header.

To use the runtime generator header-only, one needs to include
`<integratorxx/generators/impl/impl.hpp>` **exactly once** per project,
otherwise duplicate / incompatible symbols will occur.

## Contributing and Bug Reports

We welcome any and all contributions and encourage bug reports. Please use the
Expand Down
5 changes: 5 additions & 0 deletions include/integratorxx/generators/impl/impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <integratorxx/generators/impl/unpruned_grid.hpp>
#include <integratorxx/generators/impl/pruned_grid.hpp>
#include <integratorxx/generators/impl/radial_factory.hpp>
#include <integratorxx/generators/impl/s2_factory.hpp>

112 changes: 112 additions & 0 deletions include/integratorxx/generators/impl/pruned_grid.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#pragma once

#include <integratorxx/generators/spherical_factory.hpp>

#include <integratorxx/generators/impl/radial_types.hpp>
#include <integratorxx/generators/impl/s2_types.hpp>

#include <integratorxx/generators/impl/robust_pruning.hpp>
#include <integratorxx/generators/impl/treutler_pruning.hpp>

namespace IntegratorXX {

namespace detail {

template <typename AngularQuadType, typename RadialQuadType>
auto make_pruned_grid_impl(const RadialQuadType& rq,
const std::vector<PruningRegion>& pruning_regions) {

RadialGridPartition<AngularQuadType> rgp;
for( auto& region : pruning_regions ) {
rgp.add_quad( rq, region.idx_st, AngularQuadType(region.angular_size) );
}
rgp.finalize(rq);

return SphericalGridFactory::generate_pruned_grid(rq, std::move(rgp));

}

template <typename RadialQuadType>
auto make_pruned_grid(const RadialQuadType& rq,
const std::vector<PruningRegion>& pruning_regions) {

if(pruning_regions.size() == 0)
throw std::runtime_error("No Pruning Regions");

auto angular_quad = pruning_regions[0].angular_quad;
for(auto r : pruning_regions) {
if(r.angular_quad != angular_quad)
throw std::runtime_error("Mixed Angular Pruning Not Supported");
}

switch(angular_quad) {
case AngularQuad::AhrensBeylkin:
return make_pruned_grid_impl<ah_type>(rq, pruning_regions);
case AngularQuad::Delley:
return make_pruned_grid_impl<de_type>(rq, pruning_regions);
case AngularQuad::LebedevLaikov:
return make_pruned_grid_impl<ll_type>(rq, pruning_regions);
case AngularQuad::Womersley:
return make_pruned_grid_impl<wo_type>(rq, pruning_regions);
default:
throw std::runtime_error("Unsupported Angular Quadrature");
abort();
}


}

} // Implementation Details

SphericalGridFactory::spherical_grid_ptr
SphericalGridFactory::generate_pruned_grid( RadialQuad rq,
const RadialTraits& traits,
const std::vector<PruningRegion>& pruning_regions) {

switch( rq ) {

case RadialQuad::Becke:
return detail::make_pruned_grid( bk_type(traits), pruning_regions );
case RadialQuad::MuraKnowles:
return detail::make_pruned_grid( mk_type(traits), pruning_regions );
case RadialQuad::MurrayHandyLaming:
return detail::make_pruned_grid( mhl_type(traits), pruning_regions );
case RadialQuad::TreutlerAhlrichs:
return detail::make_pruned_grid( ta_type(traits), pruning_regions );
case RadialQuad::LindhMalmqvistGagliardi:
return detail::make_pruned_grid( lmg_type(traits), pruning_regions );

default:
throw std::runtime_error("Unsupported Radial Quadrature");
abort();

}

}


PrunedSphericalGridSpecification create_pruned_spec(
PruningScheme scheme, UnprunedSphericalGridSpecification unp
) {

if(!unp.radial_traits) throw std::runtime_error("RadialTraits Not Set");
switch(scheme) {
case PruningScheme::Robust:
return robust_psi4_pruning_scheme(unp);
case PruningScheme::Treutler:
return treutler_pruning_scheme(unp);

// Default to Unpruned Grid
case PruningScheme::Unpruned:
default:
std::vector<PruningRegion> pruning_regions = {
{0ul, unp.radial_traits->npts(), unp.angular_quad, unp.angular_size}
};
return PrunedSphericalGridSpecification(
unp.radial_quad, unp.radial_traits->clone(), pruning_regions
);
}

}

}
45 changes: 45 additions & 0 deletions include/integratorxx/generators/impl/radial_factory.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once
#include <integratorxx/generators/radial_factory.hpp>

#include <integratorxx/generators/impl/radial_types.hpp>

#include <algorithm>

namespace IntegratorXX {

RadialQuad radial_from_string(std::string name) {
std::transform(name.begin(), name.end(), name.begin(), ::toupper);
if(name == "BECKE") return RadialQuad::Becke;
if(name == "MURAKNOWLES") return RadialQuad::MuraKnowles;
if(name == "MK") return RadialQuad::MuraKnowles;
if(name == "MURRAYHANDYLAMING") return RadialQuad::MurrayHandyLaming;
if(name == "MHL") return RadialQuad::MurrayHandyLaming;
if(name == "TREUTLERAHLRICHS") return RadialQuad::TreutlerAhlrichs;
if(name == "TA") return RadialQuad::TreutlerAhlrichs;
if(name == "LINDHMALMQVISTGAGLIARDI") return RadialQuad::LindhMalmqvistGagliardi;
if(name == "LMG") return RadialQuad::LindhMalmqvistGagliardi;

throw std::runtime_error("Unrecognized Radial Quadrature");
}

RadialFactory::radial_grid_ptr RadialFactory::generate(RadialQuad rq, const RadialTraits& traits) {

switch(rq) {
case RadialQuad::Becke:
return std::make_unique<bk_type>(traits);
case RadialQuad::MuraKnowles:
return std::make_unique<mk_type>(traits);
case RadialQuad::MurrayHandyLaming:
return std::make_unique<mhl_type>(traits);
case RadialQuad::TreutlerAhlrichs:
return std::make_unique<ta_type>(traits);
case RadialQuad::LindhMalmqvistGagliardi:
return std::make_unique<lmg_type>(traits);
default:
throw std::runtime_error("Unsupported Radial Quadrature");
abort();
}
}


}
13 changes: 13 additions & 0 deletions include/integratorxx/generators/impl/radial_types.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once
#include <integratorxx/quadratures/radial.hpp>

namespace IntegratorXX {

using bk_type = Becke<double,double>;
using mk_type = MuraKnowles<double,double>;
using mhl_type = MurrayHandyLaming<double,double>;
using ta_type = TreutlerAhlrichs<double,double>;
using lmg_type = LindhMalmqvistGagliardi<double,double>;

}

Loading