Using MPQC to Develop New Features

There are three modes in which MPQC can be used in developing software implementation of existing and new methods:

  • native: you develop within the MPQC source tree directly;
  • plug-in: you plug your code into MPQC to extend its functionality, e.g. by adding new classes to MPQC;
  • plug-out: you plug MPQC libraries into your project, e.g. by using MPQC classes and functions in your code.

These methods are demonstrated and discussed below.

Developing code within MPQC

This approach is useful when you want to extend and replace existing classes in MPQC, e.g. you want to add a new Wavefunction class that implements a new or existing electronic structure method.

The pros of this approach are:

  • the user can take advantage of the MPQC infrastructure, e.g. the build system and test harness;
  • this approach makes it possible to eventually incorporate the new code into the MPQC master source repository for release and maintenance by the core MPQC team.

The workflow for developing code within MPQC is based on pull requests, albeit it differs for core and non-core developers. Since MPQC is hosted on GitHub, we by default assume everyone will use the GitHub-provided mechanisms for working with pull requests. For more info see GitHub Help.

  • Core MPQC developers (e.g. anyone with write access to the private MPQC repo) are encouraged to use the shared repository model, i.e. create a feature branch (and create a pull request immediately), add/modify code, mark the pull request "ready to merge" when done, and respond to feedback (if any) before merging.
  • Others can use the pull-and-fork model.

When you start working on a feature, it is recommended to immediately create a pull request. There are several reasons to do this.

  1. This will advertise your work to the rest of the team and avoid duplicate effort by keeping everyone abreast of what's in the pipeline.
  2. Others will be able to contribute to your work by pushing to your feature branch.
  3. This will enable Continuous Integration tests to be done on your feature branch.

You will want to periodically (i.e., often) sync with the changes in the main repo by merging in changes via the pull request mechanism or by direct git merge. When you are ready to merge your changes into the main repo create a pull request for code review and incorporation.

If you are a core MPQC developer or want to contribute your code to MPQC refer to Contrubutor Guide for more recommended practices.

Extending MPQC functionality

It is also possible to extend the functionality of the MPQC executable by adding new classes. The plug-in style approach allows you to keep your source separate from the rest of the MPQC.

To use this approach it is necessary to compile MPQC libraries and install them to the location specifies by the CMAKE_INSTALL_PREFIX CMake variable. It is recommended that the MPQC is validated before installation.

MP2 Implementation Example

To illustrate how to use the plug-in approach let's consider a simple example in which we extend the MPQC executable with a new implementation of MP2 energy. Although MPQC has several implementations of MP2 already, they all assume canonical orbitals, and whereas our new formulation will not make this assumption by solving the MP1 amplitude equations iteratively.

MP2 Implementation Example: Source

This example code illustrates a complete MP2 energy implementation using the MPQC Toolkit. The source file can be found at doc/dev/examples/mp2/mp2.cpp in the MPQC source directory. Note that the source file does not contain the main() function. Instead the MP2 class defined here will be linked into the MPQC executable and will become usable just like any other existing Wavefunction class in MPQC: you will be able to use it to compute gradients by finite differences, etc.

To compile the new class and link into the MPQC executable see the MP2 Implementation Example: CMakeLists.txt section.

using namespace mpqc;
// This is a basic implementation of (iterative) MP2 energy.
// This is formulated in terms of occupied and unoccupied states represented
// as LCAOs, hence it's derived from LCAOWfn, aka ::mpqc::lcao::LCAOWavefunction
// .
// This class can only compute the energy, this is indicated by deriving it from
// Provides<Energy> (this introduces virtual methods can_evaluate() and
// evaluate() that specify, respectively, the ability to compute the energy and
// how the energy is computed).
class MP2 : public LCAOWfn, public Provides<Energy> {
public:
// a few abbreviations to make the code less verbose
using Array = TA::DistArray<TA::TensorD, TA::SparsePolicy>;
// the KeyVal constructor takes a KeyVal object that represents a keyword
// group of the input file that corresponds to this object (see the "mp2"
// group in the mp2.json file that accompanies this example).
// The Keyval object will be queried for all keywords needed by
// the KeyVal ctor of LCAOWfn, as well as keyword "ref" that specifies
// the reference wave function.
MP2(const KeyVal& kv) : LCAOWfn(kv) {
ref_wfn_ = kv.object<RHF>("ref");
if (!ref_wfn_)
throw InputError("missing reference RHF wave function", __FILE__,
__LINE__, "ref");
}
private:
// This implements the Energy::Provider::can_evaluate() virtual
// function. This function returns true is the energy object can be computed.
bool can_evaluate(Energy* energy) override {
// can only compute energies (not forces (energy->order() == 1),
// hessians, or higher derivatives)
return energy->order() == 0;
}
// This implements the Energy::Provider::evaluate() virtual function.
// This function computes the MP2 energy and assigns it to the Energy object.
void evaluate(Energy* energy) override {
// how precisely to compute the energy
auto target_precision = energy->target_precision(0);
// if has not been computed to the desired precision
// (or never computed at all) ...
if (computed_precision_ > target_precision) {
// compute reference to higher precision than this wfn
auto target_ref_precision = target_precision / 100.;
auto ref_energy =
std::make_shared<Energy>(ref_wfn_, target_ref_precision);
ref_wfn_->evaluate(ref_energy.get());
// use the reference orbitals to populate the orbital space registry
init_sdref(ref_wfn_, target_ref_precision);
// this actually computes the energy
double mp2_corr_energy = compute_mp2_energy(target_precision);
energy_ = ref_energy->energy() + mp2_corr_energy;
}
// commit the result to energy
this->set_value(energy, energy_);
}
// This function actually solves the MP1 equations and returns the MP2 energy.
double compute_mp2_energy(double target_precision) {
// fac is an LCAOFactory object which evaluates integrals in terms of AOs
// and LCAOs
auto& fac = this->lcao_factory();
auto& world = fac.world();
// ofac is an OrbitalSpaceRegistry that defines the LCAO spaces that fac can
// use ofac was populated by the init_sdref() call above
auto& ofac = fac.orbital_registry();
auto nocc = ofac.retrieve("m").rank();
auto nocc_act = ofac.retrieve("i").rank();
auto nvir = ofac.retrieve("a").rank();
auto nfzc = nocc - nocc_act;
auto F = fac.compute(L"(p|F|q)");
Eigen::VectorXd eps_p = math::array_to_eigen(F).diagonal();
// replicated diagonal elements of Fo
auto eps_o = eps_p.segment(nfzc, nocc_act);
// replicated diagonal elements of Fv
auto eps_v = eps_p.tail(nvir);
// G_iajb
auto G = fac.compute(L"(i a|G|j b)");
// Fij
auto Fo = fac.compute(L"(i|F|j)");
// Fab
auto Fv = fac.compute(L"(a|F|b)");
// zero out amplitudes
if (!T_.is_initialized()) {
T_ = Array(world, G.trange(), G.shape());
T_.fill(0.0);
}
// lambda function will be used to do a Jacobi update of the residual
auto jacobi_update = [eps_o, eps_v](TA::TensorD& result_tile) {
const auto& range = result_tile.range();
double norm = 0.0;
for (const auto& i : range) {
const auto result_abij = result_tile[i] / (eps_o[i[0]] - eps_v[i[1]] +
eps_o[i[2]] - eps_v[i[3]]);
result_tile[i] = result_abij;
norm += result_abij * result_abij;
}
return std::sqrt(norm);
};
// solve the MP1 equations
auto converged = false;
auto iter = 0;
auto energy = +1.0;
ExEnv::out0() << "Start solving MP2 Energy\n";
while (not converged) {
Array R;
R("i,a,j,b") = G("i,a,j,b") + Fv("a,c") * T_("i,c,j,b") +
Fv("b,c") * T_("i,a,j,c") - Fo("i,k") * T_("k,a,j,b") -
Fo("j,k") * T_("i,a,k,b");
// estimate the MP2 energy ... the Hylleraas formula is quadratic in error
double updated_energy =
(G("i,a,j,b") + R("i,a,j,b")).dot(2 * T_("i,a,j,b") - T_("i,b,j,a"));
ExEnv::out0() << indent << "Iteration: " << iter
<< " Energy: " << updated_energy << std::endl;
computed_precision_ = std::abs(updated_energy - energy);
energy = updated_energy;
// update the amplitudes, if needed
converged = computed_precision_ <= target_precision;
if (not converged) {
// R^{ij}_{ab} -> R^{ij}_{ab} / (F^i_i + F^j_j - F^a_a - F^b_b)
TA::foreach_inplace(R, jacobi_update);
// need a fence here since foreach_inplace mutates the contents of R
// as a side effect.
// N.B. most TiledArray ops will not need a fence (except to control
// the resource use)
world.gop.fence();
T_("i,a,j,b") += R("i,a,j,b");
++iter;
}
}
return energy;
}
// This reimplements the ::mpqc::Wavefunction::obsolete() virtual function.
// It gets called when, for example, the atomic positions get updated in
// geometry optimization.
void obsolete() override {
LCAOWfn::obsolete();
ref_wfn_->obsolete();
computed_precision_ = std::numeric_limits<double>::max();
energy_ = 0.0;
}
std::shared_ptr<RHF> ref_wfn_;
Array T_;
double computed_precision_ = std::numeric_limits<double>::max();
double energy_ = 0.0;
};
// This macro registers the KeyVal constructor of our MP2 class and associates
// it with the "MP2" key, so that the KeyVal class knows how to find it when it
// finds this key as the object type in the user input.
MPQC_CLASS_EXPORT2("MP2", MP2);
// Creating this variable forces the code for the MP2 class to be linked into
// the mp2 executable (otherwise the MPQC main function will not see any
// references to this class and thus the linker will simply skip it).

MP2 Implementation Example: CMakeLists.txt

Although it is possible to build our example manually, or use Make, it is recommended to use CMake. This is because KitWare's CMake tool is used to configure, build, and install MPQC itself. Installing MPQC will export key information about the MPQC libraries and other prerequisites (e.g., TiledArray and MADWorld runtime) that is necessary to compile the code against them (e.g., the interlibrary dependencies, the compiler and linker flags, etc.). This exported info then makes it incredibly easy to use CMake to build our example in a few lines of CMake code. This file, located at doc/dev/examples/mp2/CMakeLists.txt in the MPQC build directory, was generated from the doc/dev/examples/mp2/CMakeLists.txt.in template located in the MPQC source directory.

The CMakeLists.txt file illustrates how to compile the mp2.cpp source and use it to create the mp2 executable by linking against MPQC libraries. Note that the MPQC library names do not appear explicitly: instead we use their CMake target MPQCmain .

set(program mp2)
cmake_minimum_required(VERSION 3.16.0)
project(${program} LANGUAGES CXX)
# Import MPQC package from this location
set(mpqc_root_dir "/home/travis/_install/mpqc")
# MPQCmain provides MPQC's main and the full MPQC functionality as its prereq (omit if roll your own)
find_package(mpqc 4.0.0 CONFIG QUIET REQUIRED COMPONENTS MPQCmain HINTS ${mpqc_root_dir})
include("${mpqc_root_dir}/lib/cmake/mpqc/modules/AddMPQCExecutable.cmake")
# add the executable
# mp2 uses MPQC main and thus links in all classes that the MPQC main links in
# to customize the included functionality you will need to provide your own main
add_mpqc_executable(${program} "${program}.cpp" "MPQCmain")

MP2 Implementation Example: Input

This input JSON file can be used with the program illustrated in the MP2 Implementation Example: Source section.

{
"property" : {
"type" : "Energy",
"wfn" : "$:mp2"
},
"mp2":{
"type": "MP2",
"frozen_core" : true,
"atoms" : "$:water",
"wfn_world" : "$:wfn_world",
"ref" : "$:rhf"
},
"wfn_world":{
"atoms" : "$:water",
"basis" : "$:basis"
},
"rhf":{
"type": "RHF",
"atoms" : "$:water",
"wfn_world" : "$:wfn_world",
"localize" : true,
"localize_core" : false
},
"water": {
"atoms": [
{ "element": "O", "xyz":[ 0.00000, -0.07579, 0.00000] },
{ "element": "H", "xyz":[ 0.86681, 0.60144, 0.00000] },
{ "element": "H", "xyz":[-0.86681, 0.60144, 0.00000] }
]
},
"basis": {
"name": "6-31G",
"atoms": "$:water"
}
}

Using MPQC as an external library in a separate project

To use MPQC from a standalone project it is necessary to compile MPQC libraries and install them to the location specifies by the CMAKE_INSTALL_PREFIX CMake variable. It is recommended that the MPQC is validated before installation.

To use the MPQC code your program must do the following before using any nontrivial MPQC functionality:

  • initialize the MADWorld parallel runtime + miscellaneous TiledArray runtime components (e.g. CUDA streams, memory pools), by calling TA::initialize() ; this will initialize the MPI runtime by calling MPI_Init_thread ;
  • initialize the MPQC package and the dependent components (e.g., the Libint2 Gaussian integral library) by calling mpqc::initialize();

Here's a brief example:

#include <mpqc/mpqc_init.h>
int main(int argc, char* argv[]) {
// initialize MADWorld + TiledArray runtime components
auto& world = TA::initialize(argc, argv);
// initialize MPQC to use world as the execution context
mpqc::initialize(argc, argv, world);
// use MPQC here
// finalize MPQC
// finalize MADWorld + TiledArray
}

Note that there are more elaborate use cases that we do not discuss here, e.g., it is possible to initialize MADWorld using a communicator other than MPI_COMM_WORLD; please see the documentation for TA::initialize().

After the MPQC functionality is no longer needed, you can release resources by calling mpqc::finalize() . This is not necessary if you are about to exit the program: the MPQC resources are released automatically when the program exits. Note that it is possible to call mpqc::initialize() again after calling mpqc::finalize().

After the MADWorld runtime is no longer needed, it is recommended to call TA::finalize() . You should not call TA::initialize() again after calling TA::finalize() because the MPI Standard does not specify whether the MPI libraries must support more than one initialize/finalize cycle.

Note that the most common use case is to initialize MADworld+TiledArray+MPQC all in one shot; for this purpose there is an ::mpqc::finalize(argc,argv) overload that should be used as demonstrated here:

#include <mpqc/mpqc_init.h>
int main(int argc, char* argv[]) {
// initialize MADWorld + TiledArray + MPQC runtime components
mpqc::initialize(argc, argv);
// to access the world object used to initialize MPQC use *mpqc::get_default_world()
// finalize MADWorld + TiledArray + MPQC runtime components
}

AOInts Implementation Example

To illustrate how to use the plug-out approach let's consider a simple example in which we use MPQC functionality to compute 2-body Coulomb integrals with brakets constisting of 2, 3, and 4 atomic orbitals (in the quantum chemistry context these are referred to as 2-, 3-, and 4-center electron repulsion integrals). The 2- and 3-index integrals are used to approximate the 4-center integrals by density fitting, which involves some simple tensor algebra.

AOInts Implementation Example: Source

This example code illustrates how to construct TiledArray tensors of AO integrals using the MPQC Toolkit. The source file can be found at doc/dev/examples/aoints/aoints.cpp in the MPQC source directory. Note that the source file does contain the main() function which explicitly includes all steps needed to initialize MPQC.

To compile the new class and link into the MPQC executable see the AOInts Implementation Example: CMakeLists.txt section.

//
// Created by Eduard Valeyev on 8/13/18.
//
#include <madness/world/worldgop.h>
#include <clocale>
#include "mpqc/mpqc_init.h"
int main(int argc, char* argv[]) {
mpqc::initialize(argc, argv);
auto& world = *mpqc::get_default_world();
std::shared_ptr<mpqc::KeyVal> kv =
mpqc::MPQCInit::instance().make_keyval(world, "aoints.json");
kv->assign("world",
&world); // set "$:world" keyword to &world to define the
// default execution context for this input
auto aofactory =
std::make_shared<AOFactory<TA::TensorD, TA::SparsePolicy>>(*kv);
auto eri4 = aofactory->compute(L"(μ ν| G |κ λ)");
auto eri3 = aofactory->compute(L"( Κ | G |κ λ)");
auto eri2 = aofactory->compute(L"( Κ | G | Λ )");
auto eri2_sqrt_inv = aofactory->compute(L"( Κ | G | Λ )[inv_sqr]");
// test eri2_sqrt_inv
{
auto identity = mpqc::math::create_diagonal_matrix(eri2, 1.0);
TA::TSpArrayD zero;
zero("m,l") = identity("m,l") -
eri2("m,n") * eri2_sqrt_inv("n,k") * eri2_sqrt_inv("k,l");
mpqc::ExEnv::out0() << "testing V^{-1/2}: this should be zero = "
<< TA::norm2(zero) << std::endl;
}
// test DF reconstruction of eri4
{
TA::TSpArrayD B;
B("K,p,q") = eri2_sqrt_inv("K,X") * eri3("X,p,q");
TA::TSpArrayD dferror4;
dferror4("p,q,r,s") = eri4("p,q,r,s") - B("K,p,q") * B("K,r,s");
mpqc::ExEnv::out0() << "testing DF: this should be small (and decrease "
"with increasing DF basis) = "
<< TA::norm2(dferror4) << std::endl;
}
return 0;
}

AOInts Implementation Example: CMakeLists.txt

Just like with the MP2 example, it is recommended to use CMake to build this example. See file doc/dev/examples/aoints/CMakeLists.txt located in the MPQC build directory that was generated from the doc/dev/examples/aoints/CMakeLists.txt.in template located in the MPQC source directory.

The CMakeLists.txt file illustrates how to compile the aoints.cpp source and use it to create the aoints executable by linking against MPQC libraries. Note that the MPQC library names do not appear explicitly: instead we use their CMake target libmpqc (unlike the CMake target MPQCmain that we used previously, libmpqc does not include MPQC's main() function ).

set(program aoints)
cmake_minimum_required(VERSION 3.16.0)
project(${program} LANGUAGES CXX)
# Import MPQC package from this location
set(mpqc_root_dir "/home/travis/_install/mpqc")
find_package(mpqc 4.0.0 CONFIG QUIET REQUIRED COMPONENTS libmpqc HINTS ${mpqc_root_dir})
include("${mpqc_root_dir}/lib/cmake/mpqc/modules/AddMPQCExecutable.cmake")
# add the executable
add_mpqc_executable(${program} "${program}.cpp" "libmpqc")

AOInts Implementation Example: Input

This input JSON file can be used with the program illustrated in the AOInts Implementation Example: Source section.

{
"wfn_world": {
"atoms" : "$:water",
"basis": {
"name": "6-31G",
"atoms": "$:water"
},
"df_basis": {
"name": "aug-cc-pVDZ",
"atoms": "$:water"
}
},
"water": {
"atoms": [
{ "element": "O", "xyz":[ 0.00000, -0.07579, 0.00000] },
{ "element": "H", "xyz":[ 0.86681, 0.60144, 0.00000] },
{ "element": "H", "xyz":[-0.86681, 0.60144, 0.00000] }
]
}
}

The contents of this file are used to construct a KeyVal object used to construct MPQC infrastructure classes; since it is possible to construct KeyVal objects programmatically, it is not necessary to use input files, but here we use it for simplicity. It is, for example, possible to change the basis sets in this file without needing to recompile the aoints program.

Additional notes on development within and with MPQC.

Reducing compile time

Due to the design of C++, compiling C++ programs can be time- and resource-intensive. It is a common misconception that you are working when your code is being compiled. Some improvements are on the way (e.g. Modules in C++20) but for the foreseeable future reducing compilation resource requirements falls on the developer, by designing for compile times and by utilizing special build techniques. Below you will find some tips on how to the compile times of MPQC and MPQC-dependent codes.

Generic recommendations for reducing compile times

  • Use RAM disk to compile as well as for IDE (e.g. CLion) to keep its wares. See https://github.com/zafarella/OSX-RAMDisk for a fancy script that will move caches for various apps (including CLion) or just google ‘ramdisk macos’. To tell the compiler to use RAM disk you need to set the environment variable TMPDIR (Preferences->Build,Execution,Deployment->CMake then edit Environment) to point to a directory in ramdisk, e.g. set TMPDIR to /Users/yourname/ramdisk/Clion
  • Use Ninja (instead of GNU Make) to speed up builds. It may not speed up the template heavy C++ code in MPQC by much, but its ability to accurately compute prerequisites for targets is key to making the next idea work well. If you use the CLion IDE, note that Ninja (and other non-Make) generator support was introduced in CLion 2019.3!
  • Use a faster compiler. Clang is often faster than GCC at compiling code (but this != "produces faster code"). You can even squeeze out top performance from your C++ compiler by recompiling it with profile-guided optimizations.
  • Set up a compile farm.

These are just few examples; for a more thorough discussion please see http://www.bitsnbites.eu/faster-c-builds/ .

MPQC-specific recommendations for reducing compile times

  • When developing within MPQC it is recommended to make a unit test for the feature you are working on, and then compile that unit test only. Currently MPQC’s unit tests are all integrated into a single executable unit_tests, so you want to trim the list of source files included in that executable; edit CMake variable utests_src in tests/unit/CMakeLists.txt.
  • If to test your work you cannot unit test and you need to run the mpqc executable, unless you must run a feature that integrates almost everything in MPQC (e.g. CCSD-F12) you can still drastically reduce the time it takes to build mpqc by trimming down the MPQC feature list. This is particularly important when you work on heavily reused features (i.e. you are modifying files that are included by many other files). To trim it set the MPQC_FEATURES CMake cache variable to the minimum list of features you need, e.g., to only compile mean-field methods add -DMPQC_FEATURES="lcao_scf" to the CMake command line. Figuring out the shortest MPQC_FEATURES that you need may require some experimentation, but it will be worth it; see src/bin/mpqc/CMakeLists.txt for more details. N.B. It seems that even with a trimmed-down MPQC_FEATURES all libraries are compiled the first time you build MPQC, unless you use Ninja, which can properly deduce the correct list of dependencies for the mpqc executable. So it is another reason to use Ninja.
  • Ask cmake to enable unity builds for MPQC (and any other components built as part of MPQC) by giving it -DCMAKE_UNITY_BUILD=ON. Unity builds are especially recommended for complete* (as opposed to incremental) builds of MPQC (e.g. if you are working on low-level features that touch most of the code so that almost all MPQC libraries are rebuilt every time); if you only touch a particular top-level source file unity builds may actually make incremental recompilation slower. Also, unity builds will stress your compiler so stick with Clang if you want to use them; variable CMAKE_UNITY_BUILD_BATCH_SIZE can be used to control the granularity of the unity targets to manage the resource requirements.
  • Choose your build target wisely. Most of the time there is no need to build the executable to test the latest rounds of changes, it's sufficient to build a library that has .cpp files that use your feature. E.g. when changing something in lcao/scf I would just build MPQClcao_scf-obj target to test it. Note the -obj suffix: this ensures that transitive dependencies are ignored. This is important when you are tweaking something in the core of MPQC and you just want whether it breaks the simplest wavefunction class (e.g. RHF). Compiling the object SCF library builds only the SCF-related files, and avoids rebuilding libraries that MPQClcao_scf depends on (i.e. all libraries in util and math, and most libraries in chemistry).
auto foreach_inplace(DistArrayVector< Tile, Policy > &arg, Op &&op, bool fence=true)
Definition: dist_array_vector.h:629
lcao::gaussian::AOFactory< TA::TensorD, TAPolicy > AOFactory
Definition: wfn.h:23
std::shared_ptr< mpqc::KeyVal > make_keyval(madness::World &world, const std::string &filename)
Definition: mpqc_init.cpp:298
The top-level namespace for all Massively Parallel Quantum Chemistry package.
Definition: libmpqc.cpp:1
std::shared_ptr< LCAOFactory > lcao_factory(std::shared_ptr< LCAOWavefunction > wfn)
Definition: wfn.h:78
std::shared_ptr< T > object(const key_type &path=key_type(), bool bypass_registry=false, bool disable_bad_input=false) const
return a pointer to an object at the given path
Definition: keyval.h:1094
auto nocc(const PopulatedSparseOrbitalRange &poporbs)
Definition: orb.h:206
madness::World * get_default_world()
Definition: default_madworld.cpp:28
Matrix< typename Tile::value_type > array_to_eigen(TA::DistArray< Tile, Policy > const &A)
converts a TiledArray::Array to a row-major Eigen Matrix
Definition: array_to_eigen.h:37
void finalize()
Finalize MPQC.
Definition: mpqc_init.cpp:76
T max(DecomposedTensor< T > const &t)
Returns the max of a decomposed tensor tile Currently not recommended due to implementation details.
Definition: decomposed_tensor_unary.h:39
int main(int argc, char *argv[])
Definition: mpqc.cpp:305
Definition: rhf.h:21
Base for classes that provide Properties .
Definition: provider.h:35
Taylor expansion of the molecular energy computed by a Wavefunction.
Definition: energy.h:14
static MPQCInit & instance()
Definition: mpqc_init.cpp:228
static std::ostream & out0()
Definition: exenv.cpp:86
auto norm2(const DistArrayVector< Tile, Policy > &a) -> decltype(norm2(std::declval< typename DistArrayVector< Tile, Policy >::array_type >()))
Definition: dist_array_vector.h:638
TiledArray::DistArray< Tile, typename std::enable_if< std::is_same< Policy, TA::SparsePolicy >::value, TA::SparsePolicy >::type > create_diagonal_matrix(TiledArray::DistArray< Tile, Policy > const &model, double val)
Definition: diagonal_array.h:70
std::basic_ios< Char > & indent(std::basic_ios< Char > &o)
Definition: formio.impl.h:287
DArray Array
Definition: tiledarray.h:20
auto dot(const DistArrayVector< Tile, Policy > &a, const DistArrayVector< Tile, Policy > &b)
Definition: dist_array_vector.h:656
void initialize(int &argc, char **argv, madness::World &top_world, std::shared_ptr< GetLongOpt > opt)
Static MPQC initializer. Must be called from the main thread of every process in the default MADWorld...
Definition: mpqc_init.cpp:41
std::enable_if_t<(detail::has_provider< Property >::value &&!std::is_const< Property >::value), void > evaluate(Property &property, Provider &provider, EvaluateArgs... eval_args)
Evaluates property using provider.
Definition: provider.h:116
LCAOWavefunction is a Wavefunction with an LCAOFactory.
Definition: lcao_wfn.h:26
KeyVal specifies C++ primitive data (booleans, integers, reals, string) and user-defined objects obta...
Definition: keyval.h:368
void zero(DistArrayVector< Tile, Policy > &a)
Definition: dist_array_vector.h:649
mpqc::lcao::RHF< TA::TensorD, TAPolicy > RHF
Definition: scf.h:15
Definition: exception.h:179
double norm(const std::vector< double > &vec)
Definition: f12_utility.cpp:73
const Vector3d & L() const
Definition: group.cpp:74