Skip to content

Commit

Permalink
Merge pull request #3774 from PDoakORNL/mccoords_abstraction
Browse files Browse the repository at this point in the history
Monte Carlo Coords Abstraction
  • Loading branch information
ye-luo authored Jan 29, 2022
2 parents 28db9e7 + 5115498 commit cb85ae6
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/Particle/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ set(PARTICLE
VirtualParticleSet.cpp
ParticleSet.BC.cpp
DynamicCoordinatesBuilder.cpp
MCCoords.cpp
MCWalkerConfiguration.cpp
WalkerConfigurations.cpp
SpeciesSet.cpp
Expand Down
24 changes: 24 additions & 0 deletions src/Particle/MCCoords.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//////////////////////////////////////////////////////////////////////////////////////
// This file is distributed under the University of Illinois/NCSA Open Source License.
// See LICENSE file in top directory for details.
//
// Copyright (c) 2022 developers.
//
// File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
//
// File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
//////////////////////////////////////////////////////////////////////////////////////

#include "MCCoords.hpp"

namespace qmcplusplus
{
template<CoordsType MCT>
void MCCoords<MCT>::resize(const std::size_t size)
{
positions.resize(size);
}

template struct MCCoords<CoordsType::POS>;
template struct MCCoords<CoordsType::POS_SPIN>;
} // namespace qmcplusplus
95 changes: 95 additions & 0 deletions src/Particle/MCCoords.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//////////////////////////////////////////////////////////////////////////////////////
// This file is distributed under the University of Illinois/NCSA Open Source License.
// See LICENSE file in top directory for details.
//
// Copyright (c) 2022 developers.
//
// File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
//
// File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
//////////////////////////////////////////////////////////////////////////////////////

#ifndef QMCPLUSPLUS_MCCOORDS_HPP
#define QMCPLUSPLUS_MCCOORDS_HPP

#include "Configuration.h"
#include "type_traits/complex_help.hpp"

#include <vector>

namespace qmcplusplus
{

enum class CoordsType
{
POS,
POS_SPIN
};

template<CoordsType MCT = CoordsType::POS>
struct MCCoords
{
// This cleans up some other code.
void resize(const std::size_t size);
std::vector<QMCTraits::PosType> positions;
};

template<>
struct MCCoords<CoordsType::POS_SPIN>
{
// This cleans up some other code.
void resize(const std::size_t size)
{
positions.resize(size);
spins.resize(size);
}
std::vector<QMCTraits::PosType> positions;
std::vector<QMCTraits::FullPrecRealType> spins;
};

/** Object to encapsulate appropriate tau derived values
* for a particular MCCoords specialization
*/
template<typename Real, CoordsType CT = CoordsType::POS>
struct Taus
{
Real tauovermass;
Real oneover2tau;
Real sqrttau;
Taus(Real tau, Real grp_inv_mass)
{
tauovermass = tau * grp_inv_mass;
oneover2tau = 0.5 / (tauovermass);
sqrttau = std::sqrt(tauovermass);
}
};

template<typename Real>
struct Taus<Real, CoordsType::POS_SPIN> : public Taus<Real, CoordsType::POS>
{
using Base = Taus<Real, CoordsType::POS>;
Real spin_tauovermass;
Real spin_oneover2tau;
Real spin_sqrttau;
Taus(Real tau, Real grp_inv_mass, Real spin_mass) : Base(tau, grp_inv_mass)
{
spin_tauovermass = Base::tauovermass / spin_mass;
spin_oneover2tau = 0.5 / (spin_tauovermass);
spin_sqrttau = std::sqrt(spin_tauovermass);
}
};

/** Factory function for Taus based on MCCoordsTypes
* Note as in previous code value of tau derived values is not full precision.
*/
template<CoordsType CT, typename... ARGS>
auto makeTaus(MCCoords<CT>& mc_coords, const ARGS&... args)
{
return Taus<QMCTraits::RealType, CT>(args...);
}

extern template struct MCCoords<CoordsType::POS>;
extern template struct MCCoords<CoordsType::POS_SPIN>;
} // namespace qmcplusplus

#endif
23 changes: 20 additions & 3 deletions src/Particle/ParticleBase/RandomSeqGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
// This file is distributed under the University of Illinois/NCSA Open Source License.
// See LICENSE file in top directory for details.
//
// Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
// Copyright (c) 2022 QMCPACK developers.
//
// File developed by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
// Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
// Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
//
// File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
//////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -15,8 +16,10 @@
#ifndef QMCPLUSPLUS_RANDOMSEQUENCEGENERATOR_H
#define QMCPLUSPLUS_RANDOMSEQUENCEGENERATOR_H
#include <algorithm>
#include <type_traits>
#include "OhmmsPETE/OhmmsMatrix.h"
#include "ParticleBase/ParticleAttrib.h"
#include "Particle/MCCoords.hpp"
#include "config/stdlib/Constants.h"

/*!\fn template<class T> void assignGaussRand(T* restrict a, unsigned n)
Expand Down Expand Up @@ -76,13 +79,27 @@ inline void makeGaussRandomWithEngine(std::vector<TinyVector<T, D>>& a, RG& rng)
assignGaussRand(&(a[0][0]), a.size() * D, rng);
}

template<CoordsType CT, class RG>
inline void makeGaussRandomWithEngine(MCCoords<CT>& a, RG& rng)
{
makeGaussRandomWithEngine(a.positions, rng);
if constexpr (std::is_same<MCCoords<CT>, MCCoords<CoordsType::POS_SPIN>>::value)
makeGaussRandomWithEngine(a.spins, rng);
}

template<typename T, class RG>
inline void makeGaussRandomWithEngine(std::vector<T>& a, RG& rng)
{
static_assert(std::is_floating_point<T>::value,
"makeGaussRandomWithEngine(std::vector<T>...) only implemented for floating point T");
assignGaussRand(&(a[0]), a.size(), rng);
}

template<typename T, class RG>
inline void makeGaussRandomWithEngine(ParticleAttrib<T>& a, RG& rng)
{
assignGaussRand(&(a[0]), a.size(), rng);
}

} // namespace qmcplusplus


#endif
44 changes: 43 additions & 1 deletion src/Particle/ParticleBase/tests/test_random_seq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// This file is distributed under the University of Illinois/NCSA Open Source License.
// See LICENSE file in top directory for details.
//
// Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
// Copyright (c) 2022 QMCPACK developers.
//
// File developed by: Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
//
// File created by: Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
//////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -13,6 +14,7 @@
#include "catch.hpp"

#include "Utilities/FakeRandom.h"
#include "Utilities/StdRandom.h"
#include "Message/Communicate.h"
#include "OhmmsPETE/OhmmsMatrix.h"
#include "OhmmsPETE/TinyVector.h"
Expand Down Expand Up @@ -102,4 +104,44 @@ TEST_CASE("gaussian random input zero", "[particle_base]")
REQUIRE(a[0] == Approx(0.0));
REQUIRE(a[1] == Approx(0.0));
}

TEST_CASE("makeGaussRandomWithEngine(MCCoords...)", "[particle_base]")
{
int size_test = 7;
std::vector<double> gauss_random_vals(size_test * 3 + (size_test * 3) % 2 + size_test );
{
StdRandom<double> rng;
makeGaussRandomWithEngine(gauss_random_vals, rng);
}

auto checkRs = [&](auto& rs) {
for (int i = 0; i < size_test; ++i)
{
CHECK(Approx(gauss_random_vals[3 * i]) == rs[i][0]);
CHECK(Approx(gauss_random_vals[3 * i + 1]) == rs[i][1]);
CHECK(Approx(gauss_random_vals[3 * i + 2]) == rs[i][2]);
}
};

MCCoords<CoordsType::POS> mc_coords_rs;
mc_coords_rs.resize(size_test);
{
StdRandom<double> rng;
makeGaussRandomWithEngine(mc_coords_rs, rng);
checkRs(mc_coords_rs.positions);
}
MCCoords<CoordsType::POS_SPIN> mc_coords_rsspins;
mc_coords_rsspins.resize(size_test);
{
StdRandom<double> rng;
makeGaussRandomWithEngine(mc_coords_rsspins, rng);
checkRs(mc_coords_rsspins.positions);
// Mod 2 is result of how gaussianDistribution is generated.
int offset_for_rs = ( 3 * size_test ) + (3* size_test) % 2;
for (int i = 0; i < size_test; ++i)
CHECK(Approx(gauss_random_vals[offset_for_rs + i]) == mc_coords_rsspins.spins[i]);
}
}


} // namespace qmcplusplus
3 changes: 2 additions & 1 deletion src/Particle/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ set(UTEST_EXE test_${SRC_DIR})
set(UTEST_NAME deterministic-unit_test_${SRC_DIR})

add_executable(${UTEST_EXE} test_particle.cpp test_distance_table.cpp test_walker.cpp test_particle_pool.cpp
test_sample_stack.cpp test_DTModes.cpp test_SoaDistanceTableAA.cpp)
test_sample_stack.cpp test_DTModes.cpp test_SoaDistanceTableAA.cpp
test_MCCoords.cpp)
target_link_libraries(${UTEST_EXE} catch_main qmcparticle)
if(USE_OBJECT_TARGET)
target_link_libraries(${UTEST_EXE} qmcutil)
Expand Down
57 changes: 57 additions & 0 deletions src/Particle/tests/test_MCCoords.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//////////////////////////////////////////////////////////////////////////////////////
// This file is distributed under the University of Illinois/NCSA Open Source License.
// See LICENSE file in top directory for details.
//
// Copyright (c) 2022 QMCPACK developers.
//
// File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
//
// File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
//////////////////////////////////////////////////////////////////////////////////////

#include "catch.hpp"
#include "MCCoords.hpp"
#include "Utilities/StlPrettyPrint.hpp"
#include "Utilities/StdRandom.h"
#include "ParticleBase/RandomSeqGenerator.h"

namespace qmcplusplus
{

TEST_CASE("MCCoords", "[Particle]")
{
{
constexpr auto mct = CoordsType::POS;
auto mc_coords = MCCoords<mct>();
REQUIRE(mc_coords.positions.size() == 0);
mc_coords.resize(3);
REQUIRE(mc_coords.positions.size() == 3);
}
{
constexpr auto mct = CoordsType::POS_SPIN;
auto mc_coords = MCCoords<mct>();
REQUIRE(mc_coords.spins.size() == 0);
mc_coords.resize(3);
REQUIRE(mc_coords.positions.size() == 3);
REQUIRE(mc_coords.spins.size() == 3);
}
}

TEST_CASE("Taus", "[Particle]")
{
MCCoords<CoordsType::POS> mc_coords_rs;
auto tau = 1.0;
auto invmass = 0.2;
auto taus_rs{makeTaus(mc_coords_rs, tau, invmass)};
CHECK(Approx(taus_rs.tauovermass) == 0.2);
CHECK(Approx(taus_rs.oneover2tau) == 2.5);
CHECK(Approx(taus_rs.sqrttau) == 0.447213595499957927703605);
MCCoords<CoordsType::POS_SPIN> mc_coords_rsspins;
auto spin_mass = 0.5;
auto taus_rsspins = makeTaus(mc_coords_rsspins, tau, invmass, spin_mass);
CHECK(Approx(taus_rsspins.spin_tauovermass) == 0.4);
CHECK(Approx(taus_rsspins.spin_oneover2tau) == 1.25);
CHECK(Approx(taus_rsspins.spin_sqrttau) == 0.632455532033675882352952);
}

} // namespace qmcplusplus

0 comments on commit cb85ae6

Please sign in to comment.