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

adding qmcfinitesize tool #2329

Merged
merged 33 commits into from
Mar 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2b977cf
broken, but initial update of qmcfinite to new code
camelto2 Feb 28, 2020
545c267
edits to make qmcfinitesize up to date with develop
camelto2 Mar 4, 2020
638152d
changes to output formatting
camelto2 Mar 4, 2020
519ba94
Merge branch 'develop' into qmcFScorr
camelto2 Mar 5, 2020
2a3387b
clang-formatting
camelto2 Mar 5, 2020
0150c9b
removed empty file SkParserHDF5.h
camelto2 Mar 5, 2020
0326b05
remove unused code
camelto2 Mar 6, 2020
9493edb
improved spherical grid and handling cases outside spline grid
camelto2 Mar 10, 2020
c741895
add warning for S(k) not being convegred
camelto2 Mar 10, 2020
901c0ef
small fix
camelto2 Mar 10, 2020
4e69879
Merge remote-tracking branch 'upstream/develop' into qmcFScorr
camelto2 Mar 10, 2020
d21f65b
isolate qmcfinitesize in cmake
camelto2 Mar 10, 2020
3f34114
small change to spherical_grid
camelto2 Mar 11, 2020
4575b2b
refactoring for error estimates
camelto2 Mar 11, 2020
273c40b
add stats function, and get potential corr ready for bootstrap
camelto2 Mar 11, 2020
971336b
FS corrections with bootstrapped error estimate
camelto2 Mar 11, 2020
2b180af
Merge remote-tracking branch 'upstream/develop' into qmcFScorr
camelto2 Mar 11, 2020
920fe12
clang format and remove unused CellParserBase
camelto2 Mar 11, 2020
e425e64
fix to rng to work with mixed precision build
camelto2 Mar 11, 2020
65e8602
removed empty CMakeLists
camelto2 Mar 18, 2020
f5a36af
Merge remote-tracking branch 'upstream/develop' into qmcFScorr
camelto2 Mar 23, 2020
f852a4c
initial unit test architecture for QMCTools and QMCFiniteSize
camelto2 Mar 23, 2020
c0b999f
adding unit test, interface to vlr_k in LRHandlers
camelto2 Mar 27, 2020
d06cda6
Merge remote-tracking branch 'upstream/develop' into qmcFScorr
camelto2 Mar 27, 2020
327a9e2
clang-formatting and copyright updates on touched files
camelto2 Mar 27, 2020
34a226f
Merge branch 'develop' into qmcFScorr
prckent Mar 30, 2020
dcada08
fix constructor initialization order and no return type
camelto2 Mar 30, 2020
15cf71f
Merge remote-tracking branch 'upstream/develop' into qmcFScorr
camelto2 Mar 30, 2020
a506037
Merge remote-tracking branch 'origin/qmcFScorr' into qmcFScorr
camelto2 Mar 30, 2020
5d9e634
to trigger the CI
PDoakORNL Mar 30, 2020
8f7dba4
fix compiler warnings for return types and QMCFiniteSize initializatino
camelto2 Mar 30, 2020
2f8ad91
Merge branch 'qmcFScorr' of https://github.com/camelto2/qmcpack into …
camelto2 Mar 30, 2020
2113d4c
to trigger CI
PDoakORNL Mar 30, 2020
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/.clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ CheckOptions: [ { key: readability-identifier-naming.NamespaceCase, value: lower
{ key: readability-identifier-naming.VariableCase, value: lower_case },
{ key: readability-identifier-naming.ClassMethodCase, value: camelBack },
{ key: readability-identifier-naming.PrivateMemberPostfix, value: _ }]

1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ else() #{{{
SUBDIRS(OpenMP/tests)
SUBDIRS(Optimize/tests)
SUBDIRS(MinimalContainers/tests)
SUBDIRS(QMCTools/tests)
endif() #}

endif() #}}}
64 changes: 44 additions & 20 deletions src/LongRange/EwaldHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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) 2020 QMCPACK developers.
//
// File developed by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
// Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
Expand Down Expand Up @@ -78,8 +78,8 @@ void EwaldHandler::fillFk(KContainer& KList)
else
{
#if OHMMS_DIM == 2
mRealType kgauss = 1.0 / (4 * Sigma * Sigma);
mRealType knorm = 2 * M_PI / Volume;
mRealType kgauss = 1.0 / (4 * Sigma * Sigma);
mRealType knorm = 2 * M_PI / Volume;
for (int ks = 0, ki = 0; ks < Fk_symm.size(); ks++)
{
mRealType t2e = KList.ksq[ki] * kgauss;
Expand All @@ -90,8 +90,8 @@ void EwaldHandler::fillFk(KContainer& KList)
}
PreFactors[3] = 0.0;
#elif OHMMS_DIM == 3
mRealType kgauss = 1.0 / (4 * Sigma * Sigma);
mRealType knorm = 4 * M_PI / Volume;
mRealType kgauss = 1.0 / (4 * Sigma * Sigma);
mRealType knorm = 4 * M_PI / Volume;
for (int ks = 0, ki = 0; ks < Fk_symm.size(); ks++)
{
mRealType t2e = KList.ksq[ki] * kgauss;
Expand All @@ -100,27 +100,51 @@ void EwaldHandler::fillFk(KContainer& KList)
while (ki < KList.kshell[ks + 1] && ki < Fk.size())
Fk[ki++] = uk;
}
PreFactors[3] = 0.0;
PreFactors[3] = 0.0;
#endif
}
app_log().flush();
}

EwaldHandler::mRealType EwaldHandler::evaluate_slab(mRealType z,
const std::vector<int>& kshell,
const pComplexType* restrict eikr_i,
const pComplexType* restrict eikr_j)
EwaldHandler::mRealType EwaldHandler::evaluate_vlr_k(mRealType k)
{
mRealType zp = z * Sigma;
mRealType vk = -SlabFunc0(z, zp);
//cout << "### SLAB " << z << " " << zp << std::endl;
for (int ks = 0, ki = 0; ks < MaxKshell; ks++)
mRealType uk = 0.0;
if (SuperCellEnum == SUPERCELL_SLAB)
{
mRealType u = 0; //\sum Real (e^ikr_i e^(-ikr_j))
for (; ki < kshell[ks + 1]; ki++, eikr_i++, eikr_j++)
u += ((*eikr_i).real() * (*eikr_j).real() + (*eikr_i).imag() * (*eikr_j).imag());
vk += u * Fk_symm[ks] * SlabFuncK(ks, z, zp);
mRealType knorm = M_PI / Area;
uk = knorm / k; //pi/(A*k)
}
else
{
#if OHMMS_DIM == 2
mRealType kgauss = 1.0 / (4 * Sigma * Sigma);
mRealType knorm = 2 * M_PI / Volume;
mRealType k2 = k * k;
uk = knorm * std::exp(-k2 * kgauss) / k2;
#elif OHMMS_DIM == 3
mRealType kgauss = 1.0 / (4 * Sigma * Sigma);
mRealType knorm = 4 * M_PI / Volume;
mRealType k2 = k * k;
uk = knorm * std::exp(-k2 * kgauss) / k2;
}
#endif
return uk;
}

EwaldHandler::mRealType EwaldHandler::evaluate_slab(mRealType z, const std::vector<int>& kshell,
const pComplexType* restrict eikr_i,
const pComplexType* restrict eikr_j)
{
mRealType zp = z * Sigma;
mRealType vk = -SlabFunc0(z, zp);
//cout << "### SLAB " << z << " " << zp << std::endl;
for (int ks = 0, ki = 0; ks < MaxKshell; ks++)
{
mRealType u = 0; //\sum Real (e^ikr_i e^(-ikr_j))
for (; ki < kshell[ks + 1]; ki++, eikr_i++, eikr_j++)
u += ((*eikr_i).real() * (*eikr_j).real() + (*eikr_i).imag() * (*eikr_j).imag());
vk += u * Fk_symm[ks] * SlabFuncK(ks, z, zp);
}
return vk;
}
return vk;
}
} // namespace qmcplusplus
4 changes: 3 additions & 1 deletion src/LongRange/EwaldHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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) 2020 QMCPACK developers.
//
// File developed by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
// Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
Expand Down Expand Up @@ -93,6 +93,8 @@ class EwaldHandler : public LRHandlerBase
*/
inline mRealType srDf(mRealType r, mRealType rinv) { return 0.0; }

inline mRealType evaluate_vlr_k(mRealType k) override;

void fillFk(KContainer& KList);

/** evaluate k-dependent
Expand Down
15 changes: 12 additions & 3 deletions src/LongRange/EwaldHandler3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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) 2020 QMCPACK developers.
//
// File developed by: Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
//
Expand Down Expand Up @@ -61,8 +61,8 @@ void EwaldHandler3D::fillFk(KContainer& KList)

Fk_symm.resize(MaxKshell);
kMag.resize(MaxKshell);
mRealType kgauss = 1.0 / (4 * Sigma * Sigma);
mRealType knorm = 4 * M_PI / Volume;
mRealType kgauss = 1.0 / (4 * Sigma * Sigma);
mRealType knorm = 4 * M_PI / Volume;
for (int ks = 0, ki = 0; ks < Fk_symm.size(); ks++)
{
mRealType t2e = KList.ksq[ki] * kgauss;
Expand All @@ -78,4 +78,13 @@ void EwaldHandler3D::fillFk(KContainer& KList)
PreFactors[3] = 0.0;
app_log().flush();
}

EwaldHandler3D::mRealType EwaldHandler3D::evaluate_vlr_k(mRealType k)
{
mRealType kgauss = 1.0 / (4 * Sigma * Sigma);
mRealType knorm = 4 * M_PI / Volume;
mRealType k2 = k * k;
return knorm * std::exp(-k2 * kgauss) / k2;
}

} // namespace qmcplusplus
6 changes: 4 additions & 2 deletions src/LongRange/EwaldHandler3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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) 2020 QMCPACK developers.
//
// File developed by: Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
//
Expand Down Expand Up @@ -75,7 +75,9 @@ class EwaldHandler3D : public LRHandlerBase
return v0;
}

inline mRealType evaluateLR_r0() { return 2.0 * Sigma / std::sqrt(M_PI); }
mRealType evaluate_vlr_k(mRealType k) override;

mRealType evaluateLR_r0() { return 2.0 * Sigma / std::sqrt(M_PI); }

/** evaluate the first derivative of the short range part at r
*
Expand Down
24 changes: 20 additions & 4 deletions src/LongRange/LRHandlerBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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) 2020 QMCPACK developers.
//
// File developed by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
// Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
Expand Down Expand Up @@ -55,6 +55,8 @@ struct LRHandlerBase
///Coefficient for strain fit.
std::vector<mRealType> gstraincoefs;

virtual mRealType evaluate_vlr_k(mRealType k) = 0;


//constructor
explicit LRHandlerBase(mRealType kc) : MaxKshell(0), LR_kc(kc), LR_rc(0), ClassName("LRHandlerBase") {}
Expand Down Expand Up @@ -89,6 +91,19 @@ struct LRHandlerBase
return vk;
}

inline mRealType evaluate_w_sk(const std::vector<int>& kshell, const pRealType* restrict sk)
{
mRealType vk = 0.0;
for (int ks = 0, ki = 0; ks < MaxKshell; ks++)
{
mRealType u = 0;
for (; ki < kshell[ks + 1]; ki++)
u += (*sk++);
vk += Fk_symm[ks] * u;
}
return vk;
}

inline mRealType evaluate(const std::vector<int>& kshell,
const pRealType* restrict rk1_r,
const pRealType* restrict rk1_i,
Expand Down Expand Up @@ -303,19 +318,20 @@ struct DummyLRHandler : public LRHandlerBase
Fk.resize(KList.kpts_cart.size());
for (ksh = 0, ik = 0; ksh < MaxKshell; ksh++, ik++)
{
mRealType v = norm * myFunc(kk[KList.kshell[ksh]]); //rpa=u0/kk[ik];
mRealType v = norm * myFunc(kk[KList.kshell[ksh]]); //rpa=u0/kk[ik];
Fk_symm[ksh] = v;
for (; ik < KList.kshell[ksh + 1]; ik++)
Fk[ik] = v;
}
}

mRealType evaluate_vlr_k(mRealType k) override { return 0.0; }
mRealType evaluate(mRealType r, mRealType rinv) { return 0.0; }
mRealType evaluateLR(mRealType r) { return 0.0; }
mRealType srDf(mRealType r, mRealType rinv) { return 0.0; }
void Breakup(ParticleSet& ref, mRealType rs_in) {}
void resetTargetParticleSet(ParticleSet& ref) {}
virtual LRHandlerBase* makeClone(ParticleSet& ref){return new DummyLRHandler<Func>(LR_kc);}
void resetTargetParticleSet(ParticleSet& ref) {}
virtual LRHandlerBase* makeClone(ParticleSet& ref) { return new DummyLRHandler<Func>(LR_kc); }
};

} // namespace qmcplusplus
Expand Down
6 changes: 4 additions & 2 deletions src/LongRange/LRHandlerSRCoulomb.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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) 2020 QMCPACK developers.
//
// File developed by: Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
// Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
Expand Down Expand Up @@ -117,6 +117,8 @@ class LRHandlerSRCoulomb : public LRHandlerBase
return v;
}

inline mRealType evaluate_vlr_k(mRealType k) { return evalYk(k); }

/** evaluate the first derivative of the short range part at r
*
* @param r radius
Expand Down Expand Up @@ -282,7 +284,7 @@ class LRHandlerSRCoulomb : public LRHandlerBase
LRBreakup<BreakupBasis> breakuphandler(Basis);
//Find size of basis from cutoffs
mRealType kc = (LR_kc < 0) ? ref.LR_kc : LR_kc;
LR_kc = kc; // set internal kc
LR_kc = kc; // set internal kc
//mRealType kc(ref.LR_kc); //User cutoff parameter...
//kcut is the cutoff for switching to approximate k-point degeneracies for
//better performance in making the breakup. A good bet is 30*K-spacing so that
Expand Down
15 changes: 10 additions & 5 deletions src/LongRange/LRHandlerTemp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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) 2020 QMCPACK developers.
//
// File developed by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
// Bryan Clark, bclark@Princeton.edu, Princeton University
Expand Down Expand Up @@ -102,7 +102,8 @@ class LRHandlerTemp : public LRHandlerBase
inline mRealType evaluate(mRealType r, mRealType rinv)
{
mRealType v = 0.0;
if (r>=LR_rc) return v;
if (r >= LR_rc)
return v;
v = myFunc(r, rinv);
for (int n = 0; n < coefs.size(); n++)
v -= coefs[n] * Basis.h(n, r);
Expand All @@ -118,21 +119,25 @@ class LRHandlerTemp : public LRHandlerBase
{
APP_ABORT("LRHandlerTemp::srDF not implemented (missing gcoefs)");
mRealType df = 0.0;
if (r>=LR_rc) return df;
if (r >= LR_rc)
return df;
df = myFunc.df(r);
//RealType df = myFunc.df(r, rinv);
for (int n = 0; n < coefs.size(); n++)
df -= gcoefs[n] * Basis.dh_dr(n, r);
return df;
}

inline mRealType evaluate_vlr_k(mRealType k) { return evalFk(k); }


/** evaluate the contribution from the long-range part for for spline
*/
inline mRealType evaluateLR(mRealType r)
{
mRealType v = 0.0;
if (r>=LR_rc) return myFunc(r, 1./r);
if (r >= LR_rc)
return myFunc(r, 1. / r);
for (int n = 0; n < coefs.size(); n++)
v += coefs[n] * Basis.h(n, r);
return v;
Expand Down Expand Up @@ -208,7 +213,7 @@ class LRHandlerTemp : public LRHandlerBase
LRBreakup<BreakupBasis> breakuphandler(Basis);
//Find size of basis from cutoffs
mRealType kc = (LR_kc < 0) ? ref.LR_kc : LR_kc;
LR_kc = kc; // set internal kc
LR_kc = kc; // set internal kc
//RealType kc(ref.LR_kc); //User cutoff parameter...
//kcut is the cutoff for switching to approximate k-point degeneracies for
//better performance in making the breakup. A good bet is 30*K-spacing so that
Expand Down
4 changes: 3 additions & 1 deletion src/LongRange/LRRPABFeeHandlerTemp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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) 2020 QMCPACK developers.
//
// File developed by: Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
// Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
Expand Down Expand Up @@ -155,6 +155,8 @@ struct LRRPABFeeHandlerTemp : public LRHandlerBase
return vk;
}

inline mRealType evaluate_vlr_k(mRealType k) override { return evalFk(k); }

private:
inline mRealType evalFk(mRealType k)
{
Expand Down
5 changes: 4 additions & 1 deletion src/LongRange/LRRPAHandlerTemp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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) 2020 QMCPACK developers.
//
// File developed by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
// Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
Expand Down Expand Up @@ -156,6 +156,9 @@ struct LRRPAHandlerTemp : public LRHandlerBase
return vk;
}

// use what is put in fillFk. Multiplies evalFk by -1
inline mRealType evaluate_vlr_k(mRealType k) override { return -1.0 * evalFk(k); }

private:
inline mRealType evalFk(mRealType k)
{
Expand Down
18 changes: 17 additions & 1 deletion src/QMCTools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ PROJECT(qmctools)

SET(MOSRCS
../Particle/InitMolecularSystem.cpp
../Particle/ParticleSetPool.cpp
QMCGaussianParserBase.cpp
GaussianFCHKParser.cpp
GamesXmlParser.cpp
Expand Down Expand Up @@ -69,6 +68,23 @@ TARGET_LINK_LIBRARIES(convertpw4qmc PRIVATE qmcutil Math::FFTW3)
INSTALL(TARGETS convertpw4qmc
RUNTIME DESTINATION bin)

SET(FSSRCS
QMCFiniteSize/QMCFiniteSize.cpp
QMCFiniteSize/SkParserBase.cpp
QMCFiniteSize/SkParserASCII.cpp
QMCFiniteSize/SkParserScalarDat.cpp
QMCFiniteSize/FSUtilities.cpp
)

ADD_LIBRARY(fstool ${FSSRCS})
TARGET_LINK_LIBRARIES(fstool PUBLIC qmc qmcbase qmcwfs)
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you check if the dependencies here are necessary?
Do you need qmcwfs or just einspline?
Is qmc target really necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

at the moment, it only needs einspline. this will change in the future when a kinetic energy FS correction is added, which will depend on the 2body jastrow and a kspace jastrow. if it is preferable to just add the various .cpp files in FSSRCS that each thing depends on I can do that instead as opposed to targetting libraries that include those dependencies

Copy link
Contributor

Choose a reason for hiding this comment

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

Let us put einspline and change it to qmcwfs when actual WFS dependence comes in.

Copy link
Contributor

Choose a reason for hiding this comment

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

For user friendliness, this tool should work with any QMCPACK xml input file. Unfortunately, even if you're not using any wavefunction specific information, the system initialization path that allows you to grab a particle set and box from ESHDF file, in the event it's not specified in the XML, needs to go through the wavefunction builder. So I think that qmcwfs is a necessary dependency right now.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks. I see. The dependency is needed right now.


ADD_EXECUTABLE(qmcfinitesize qmcfinitesize.cpp)
TARGET_LINK_LIBRARIES(qmcfinitesize PRIVATE fstool)

INSTALL(TARGETS qmcfinitesize
RUNTIME DESTINATION bin)

#ppconvert
if( BUILD_PPCONVERT )
SUBDIRS(ppconvert)
Expand Down
Loading