Skip to content
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

explicitly instantiate CrystalLattice simplify initialization #5341

Merged
merged 6 commits into from
Feb 28, 2025
Merged
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
1 change: 1 addition & 0 deletions src/Particle/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ set(PARTICLE
createDistanceTableAA.cpp
createDistanceTableAB.cpp
HDFWalkerInputManager.cpp
Lattice/CrystalLattice.cpp
LongRange/KContainer.cpp
LongRange/StructFact.cpp
LongRange/LPQHIBasis.cpp
Expand Down
19 changes: 19 additions & 0 deletions src/Particle/Lattice/CrystalLattice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ CrystalLattice<T, D>::CrystalLattice()
reset();
}

template<class T, unsigned D>
bool CrystalLattice<T, D>::outOfBound(const TinyVector<T, D>& u) const
{
for (int i = 0; i < D; ++i)
if (std::abs(u[i]) > 0.5)
return true;
return false;
}


template<class T, unsigned D>
template<class TT>
void CrystalLattice<T, D>::set(const Tensor<TT, D>& lat)
Expand Down Expand Up @@ -182,4 +192,13 @@ inline bool operator!=(const CrystalLattice<T, D>& lhs, const CrystalLattice<T,
return !(lhs == rhs);
}

template struct CrystalLattice<double, OHMMS_DIM>;
template void CrystalLattice<double, OHMMS_DIM>::set(const Tensor<double, OHMMS_DIM>& tensor);
template void CrystalLattice<double, OHMMS_DIM>::set(const Tensor<float, OHMMS_DIM>& tensor);

template struct CrystalLattice<float, OHMMS_DIM>;
template void CrystalLattice<float, OHMMS_DIM>::set(const Tensor<double, OHMMS_DIM>& tensor);
template void CrystalLattice<float, OHMMS_DIM>::set(const Tensor<float, OHMMS_DIM>& tensor);


} // namespace qmcplusplus
73 changes: 58 additions & 15 deletions src/Particle/Lattice/CrystalLattice.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ enum
template<class T, unsigned D>
struct CrystalLattice : public LRBreakupParameters<T, D>
{
public:
using Real = T;
/// alias to the base class
using Base = LRBreakupParameters<T, D>;

Expand All @@ -63,7 +65,7 @@ struct CrystalLattice : public LRBreakupParameters<T, D>
DIM = D
};
//@{
///the type of scalar
///the type of scalar, actually can only be real based on Configuration.h
using Scalar_t = T;
///the type of a D-dimensional position vector
using SingleParticlePos = TinyVector<T, D>;
Expand All @@ -73,14 +75,50 @@ struct CrystalLattice : public LRBreakupParameters<T, D>
using Tensor_t = Tensor<T, D>;
//@}

///default constructor, assign a huge supercell
CrystalLattice();

const auto& getBoxBConds() const { return BoxBConds; }
const auto& getG() const { return G; }
const auto& getGv() const { return Gv; }
int getSuperCellEnum() const { return SuperCellEnum; }
const auto& getR() const { return R; };
const auto& getOneOverLength() const { return OneOverLength; }
const auto& getLength() const { return Length; }
const auto& getRv() const { return Rv; }
const auto& getVacuumScale() const { return VacuumScale; }
bool getExplicitlyDefined() const { return explicitly_defined; }
// \todo remove this and factor resetLRBox into lattice?
auto& getR() { return R; };
auto getVolume() const { return Volume; }
auto getCenter() const { return Center; }
// These are all a result of calling LatticeAnalyzer and not valid until reset is called after any number of changes
// to the lattice.
auto getCellRadiusSq() const { return CellRadiusSq; }
auto getWignerSeitzRadius() const { return WignerSeitzRadius; }
auto getWignerSeitzRadius_G() const { return WignerSeitzRadius_G; }
auto getSimulationCellRadius() const { return SimulationCellRadius; }
bool getDiagonalOnly() const { return DiagonalOnly; }

void setBoxBConds(TinyVector<int, D> bbc)
{
BoxBConds = bbc;
reset();
}
void setVacuumScale(Real vscale)
{
VacuumScale = vscale;
reset();
}

///true, if off-diagonal elements are zero so that other classes can take advantage of this
bool DiagonalOnly;
///supercell enumeration
int SuperCellEnum;
///The boundary condition in each direction.
TinyVector<int, D> BoxBConds;
TinyVector<int, D> BoxBConds{false, false, false};
///The scale factor for adding vacuum.
T VacuumScale;
T VacuumScale = 1.0;
//@{
/**@brief Physical properties of a supercell*/
/// Volume of a supercell
Expand Down Expand Up @@ -125,10 +163,7 @@ struct CrystalLattice : public LRBreakupParameters<T, D>
//angles between the two lattice vectors
SingleParticlePos ABC;
///true, the lattice is defined by the input instead of an artificial default
bool explicitly_defined;

///default constructor, assign a huge supercell
CrystalLattice();
bool explicitly_defined = false;

/**@param i the index of the directional vector, \f$i\in [0,D)\f$
*@return The lattice vector of the ith direction
Expand Down Expand Up @@ -183,13 +218,7 @@ struct CrystalLattice : public LRBreakupParameters<T, D>
}

/// return true if any direction of reduced coordinates u goes larger than 0.5
inline bool outOfBound(const TinyVector<T, D>& u) const
{
for (int i = 0; i < D; ++i)
if (std::abs(u[i]) > 0.5)
return true;
return false;
}
bool outOfBound(const TinyVector<T, D>& u) const;

inline void applyMinimumImage(TinyVector<T, D>& c) const
{
Expand Down Expand Up @@ -243,6 +272,7 @@ struct CrystalLattice : public LRBreakupParameters<T, D>

explicitly_defined = rhs.explicitly_defined;
BoxBConds = rhs.BoxBConds;
SuperCellEnum = rhs.getSuperCellEnum();
VacuumScale = rhs.VacuumScale;
R = rhs.R;
reset();
Expand Down Expand Up @@ -280,10 +310,23 @@ struct CrystalLattice : public LRBreakupParameters<T, D>

//! Print out CrystalLattice Data
void print(std::ostream&, int level = 2) const;

// Allow assignment operator between say T=double and T=float
template<class TT, unsigned DD>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the dimension be just D?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't partially specialize a class friend. So as soon as this stops being a struct and we stop direct access to lattice internals. The assignment operator becomes harder to write and dependent on accessors.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I forgot...

friend struct CrystalLattice;

friend class LatticeParser;
};

extern template struct CrystalLattice<double, OHMMS_DIM>;
extern template void CrystalLattice<double, OHMMS_DIM>::set(const Tensor<double, OHMMS_DIM>& tensor);
extern template void CrystalLattice<double, OHMMS_DIM>::set(const Tensor<float, OHMMS_DIM>& tensor);

extern template struct CrystalLattice<float, OHMMS_DIM>;
extern template void CrystalLattice<float, OHMMS_DIM>::set(const Tensor<double, OHMMS_DIM>& tensor);
extern template void CrystalLattice<float, OHMMS_DIM>::set(const Tensor<float, OHMMS_DIM>& tensor);

} // namespace qmcplusplus
//including the definitions of the member functions
#include "CrystalLattice.cpp"

#endif
7 changes: 6 additions & 1 deletion src/Particle/Lattice/LatticeAnalyzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#ifndef QMCPLUSPLUS_LATTICE_ANALYZER_H
#define QMCPLUSPLUS_LATTICE_ANALYZER_H
#include "OhmmsPETE/TinyVector.h"
#include "CrystalLattice.h"

namespace qmcplusplus
{
/** enumeration for DTD_BConds specialization
Expand All @@ -38,7 +40,10 @@ enum
};


///generic class to analyze a Lattice
/** generic class to analyze a Lattice
* NOTE: There is no constructor but operator() should be considered one in most
* cases as the "class" is invalid until it is called since mySC is not intialized.
*/
template<typename T, unsigned D>
struct LatticeAnalyzer
{};
Expand Down
7 changes: 5 additions & 2 deletions src/Particle/Lattice/ParticleBConds3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <config.h>
#include "Lattice/CrystalLattice.h"
#include "LatticeAnalyzer.h"

namespace qmcplusplus
{
Expand All @@ -27,7 +28,8 @@ struct DTD_BConds<T, 3, PPPO>
{
T Linv0, L0, Linv1, L1, Linv2, L2, r2max, dummy;

inline DTD_BConds(const CrystalLattice<T, 3>& lat)
template<typename TT>
inline DTD_BConds(const CrystalLattice<TT, 3>& lat)
: Linv0(lat.OneOverLength[0]),
L0(lat.Length[0]),
Linv1(lat.OneOverLength[1]),
Expand Down Expand Up @@ -163,7 +165,8 @@ struct DTD_BConds<T, 3, PPPG>
TinyVector<TinyVector<T, 3>, 3> rb;
std::vector<TinyVector<T, 3>> corners;

DTD_BConds(const CrystalLattice<T, 3>& lat)
template<typename TT>
DTD_BConds(const CrystalLattice<TT, 3>& lat)
{
rb[0] = lat.a(0);
rb[1] = lat.a(1);
Expand Down
6 changes: 5 additions & 1 deletion src/Particle/Lattice/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ set(UTEST_NAME deterministic-unit_test_${SRC_DIR})

add_executable(${UTEST_EXE} test_ParticleBConds.cpp test_CrystalLattice.cpp test_LRBreakupParameters.cpp)
target_include_directories(${UTEST_EXE} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../..")
target_link_libraries(${UTEST_EXE} catch_main qmcutil platform_runtime)
target_link_libraries(${UTEST_EXE} catch_main qmcutil platform_runtime qmcparticle)

if(USE_OBJECT_TARGET)
target_link_libraries(${UTEST_EXE} qmcparticle_omptarget)
endif()

add_unit_test(${UTEST_NAME} 1 1 $<TARGET_FILE:${UTEST_EXE}>)
2 changes: 1 addition & 1 deletion src/Particle/Lattice/tests/test_CrystalLattice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ using vec_t = TinyVector<double, 3>;
*/
TEST_CASE("Crystal_lattice_periodic_bulk", "[lattice]")
{
CrystalLattice<OHMMS_PRECISION, OHMMS_DIM> Lattice;
CrystalLattice<OHMMS_PRECISION_FULL, OHMMS_DIM> Lattice;
Lattice.BoxBConds = false; // Open BC
Lattice.R.diagonal(0.4);
Lattice.reset();
Expand Down
Loading