2018-03-13 13:51:09 +00:00
|
|
|
/*************************************************************************************
|
|
|
|
|
|
|
|
Grid physics library, www.github.com/paboyle/Grid
|
|
|
|
|
|
|
|
Source file: extras/Hadrons/EigenPack.hpp
|
|
|
|
|
|
|
|
Copyright (C) 2015-2018
|
|
|
|
|
|
|
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
|
|
|
|
See the full license in the file "LICENSE" in the top level distribution directory
|
|
|
|
*************************************************************************************/
|
|
|
|
/* END LEGAL */
|
|
|
|
#ifndef Hadrons_EigenPack_hpp_
|
|
|
|
#define Hadrons_EigenPack_hpp_
|
|
|
|
|
|
|
|
#include <Grid/Hadrons/Global.hpp>
|
2018-03-14 14:54:25 +00:00
|
|
|
#include <Grid/algorithms/iterative/Deflation.h>
|
2018-03-13 13:51:09 +00:00
|
|
|
#include <Grid/algorithms/iterative/LocalCoherenceLanczos.h>
|
|
|
|
|
|
|
|
BEGIN_HADRONS_NAMESPACE
|
|
|
|
|
|
|
|
// Lanczos type
|
|
|
|
#ifndef HADRONS_DEFAULT_LANCZOS_NBASIS
|
|
|
|
#define HADRONS_DEFAULT_LANCZOS_NBASIS 60
|
|
|
|
#endif
|
|
|
|
|
2018-03-14 14:54:25 +00:00
|
|
|
template <typename F>
|
2018-03-13 13:51:09 +00:00
|
|
|
class EigenPack
|
|
|
|
{
|
2018-03-14 14:54:25 +00:00
|
|
|
public:
|
|
|
|
typedef F Field;
|
2018-04-06 19:29:53 +01:00
|
|
|
struct PackRecord
|
2018-04-04 16:36:37 +01:00
|
|
|
{
|
2018-04-06 19:29:53 +01:00
|
|
|
std::string operatorXml, solverXml;
|
2018-04-04 16:36:37 +01:00
|
|
|
};
|
|
|
|
struct VecRecord: Serializable
|
|
|
|
{
|
|
|
|
GRID_SERIALIZABLE_CLASS_MEMBERS(VecRecord,
|
|
|
|
unsigned int, index,
|
|
|
|
double, eval);
|
|
|
|
VecRecord(void): index(0), eval(0.) {}
|
|
|
|
};
|
2018-03-13 13:51:09 +00:00
|
|
|
public:
|
|
|
|
std::vector<RealD> eval;
|
2018-03-14 14:54:25 +00:00
|
|
|
std::vector<F> evec;
|
2018-04-04 16:36:37 +01:00
|
|
|
PackRecord record;
|
2018-03-13 13:51:09 +00:00
|
|
|
public:
|
|
|
|
EigenPack(void) = default;
|
|
|
|
virtual ~EigenPack(void) = default;
|
|
|
|
|
|
|
|
EigenPack(const size_t size, GridBase *grid)
|
|
|
|
{
|
|
|
|
resize(size, grid);
|
|
|
|
}
|
|
|
|
|
|
|
|
void resize(const size_t size, GridBase *grid)
|
|
|
|
{
|
|
|
|
eval.resize(size);
|
|
|
|
evec.resize(size, grid);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void read(const std::string fileStem, const int traj = -1)
|
|
|
|
{
|
|
|
|
std::string evecFilename, evalFilename;
|
|
|
|
|
|
|
|
makeFilenames(evecFilename, evalFilename, fileStem, traj);
|
|
|
|
XmlReader xmlReader(evalFilename);
|
|
|
|
LOG(Message) << "Reading " << eval.size() << " eigenvalues from '"
|
|
|
|
<< evalFilename << "'" << std::endl;
|
|
|
|
Grid::read(xmlReader, "evals", eval);
|
2018-04-04 16:36:37 +01:00
|
|
|
basicRead(evec, evecFilename, evec.size());
|
2018-03-13 13:51:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void write(const std::string fileStem, const int traj = -1)
|
|
|
|
{
|
|
|
|
std::string evecFilename, evalFilename;
|
|
|
|
|
|
|
|
makeFilenames(evecFilename, evalFilename, fileStem, traj);
|
|
|
|
XmlWriter xmlWriter(evalFilename);
|
|
|
|
LOG(Message) << "Writing " << eval.size() << " eigenvalues to '"
|
|
|
|
<< evalFilename << "'" << std::endl;
|
|
|
|
Grid::write(xmlWriter, "evals", eval);
|
2018-04-04 16:36:37 +01:00
|
|
|
basicWrite(evecFilename, evec, evec.size());
|
2018-03-13 13:51:09 +00:00
|
|
|
}
|
|
|
|
protected:
|
|
|
|
void makeFilenames(std::string &evecFilename, std::string &evalFilename,
|
|
|
|
const std::string stem, const int traj = -1)
|
|
|
|
{
|
|
|
|
std::string t = (traj < 0) ? "" : ("." + std::to_string(traj));
|
|
|
|
|
|
|
|
evecFilename = stem + "_evec" + t + ".bin";
|
|
|
|
evalFilename = stem + "_eval" + t + ".xml";
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2018-04-04 16:36:37 +01:00
|
|
|
void basicRead(std::vector<T> &evec, const std::string filename,
|
|
|
|
const unsigned int size)
|
2018-03-13 13:51:09 +00:00
|
|
|
{
|
|
|
|
ScidacReader binReader;
|
|
|
|
|
|
|
|
binReader.open(filename);
|
2018-04-06 19:29:53 +01:00
|
|
|
binReader.skipPastObjectRecord(SCIDAC_FILE_XML);
|
2018-03-13 13:51:09 +00:00
|
|
|
for(int k = 0; k < size; ++k)
|
|
|
|
{
|
2018-04-04 16:36:37 +01:00
|
|
|
VecRecord vecRecord;
|
|
|
|
|
2018-04-06 19:38:20 +01:00
|
|
|
LOG(Message) << "Reading eigenvector " << k << std::endl;
|
2018-04-04 16:36:37 +01:00
|
|
|
binReader.readScidacFieldRecord(evec[k], vecRecord);
|
|
|
|
if (vecRecord.index != k)
|
|
|
|
{
|
|
|
|
HADRON_ERROR(Io, "Eigenvector " + std::to_string(k) + " has a"
|
|
|
|
+ " wrong index (expected " + std::to_string(vecRecord.index)
|
|
|
|
+ ") in file '" + filename + "'");
|
|
|
|
}
|
2018-03-13 13:51:09 +00:00
|
|
|
}
|
|
|
|
binReader.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2018-04-04 16:36:37 +01:00
|
|
|
void basicWrite(const std::string filename, std::vector<T> &evec,
|
|
|
|
const unsigned int size)
|
2018-03-13 13:51:09 +00:00
|
|
|
{
|
2018-04-06 19:29:53 +01:00
|
|
|
ScidacWriter binWriter(evec[0]._grid->IsBoss());
|
2018-04-06 19:32:22 +01:00
|
|
|
XmlWriter xmlWriter("", "eigenPackPar");
|
2018-03-13 13:51:09 +00:00
|
|
|
|
2018-04-06 19:29:53 +01:00
|
|
|
xmlWriter.pushXmlString(record.operatorXml);
|
|
|
|
xmlWriter.pushXmlString(record.solverXml);
|
2018-03-13 13:51:09 +00:00
|
|
|
binWriter.open(filename);
|
2018-04-06 22:52:11 +01:00
|
|
|
binWriter.writeLimeObject(1, 1, xmlWriter, "parameters", SCIDAC_FILE_XML);
|
2018-03-13 13:51:09 +00:00
|
|
|
for(int k = 0; k < size; ++k)
|
|
|
|
{
|
2018-04-04 16:36:37 +01:00
|
|
|
VecRecord vecRecord;
|
|
|
|
|
|
|
|
vecRecord.index = k;
|
|
|
|
vecRecord.eval = eval[k];
|
2018-04-06 19:38:20 +01:00
|
|
|
LOG(Message) << "Writing eigenvector " << k << std::endl;
|
2018-04-04 16:36:37 +01:00
|
|
|
binWriter.writeScidacFieldRecord(evec[k], vecRecord);
|
2018-03-13 13:51:09 +00:00
|
|
|
}
|
|
|
|
binWriter.close();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-03-14 14:54:25 +00:00
|
|
|
template <typename FineF, typename CoarseF>
|
|
|
|
class CoarseEigenPack: public EigenPack<FineF>
|
2018-03-13 13:51:09 +00:00
|
|
|
{
|
|
|
|
public:
|
2018-03-14 14:54:25 +00:00
|
|
|
typedef CoarseF CoarseField;
|
|
|
|
public:
|
|
|
|
std::vector<RealD> evalCoarse;
|
|
|
|
std::vector<CoarseF> evecCoarse;
|
2018-03-13 13:51:09 +00:00
|
|
|
public:
|
|
|
|
CoarseEigenPack(void) = default;
|
|
|
|
virtual ~CoarseEigenPack(void) = default;
|
|
|
|
|
|
|
|
CoarseEigenPack(const size_t sizeFine, const size_t sizeCoarse,
|
|
|
|
GridBase *gridFine, GridBase *gridCoarse)
|
|
|
|
{
|
|
|
|
resize(sizeFine, sizeCoarse, gridFine, gridCoarse);
|
|
|
|
}
|
|
|
|
|
|
|
|
void resize(const size_t sizeFine, const size_t sizeCoarse,
|
|
|
|
GridBase *gridFine, GridBase *gridCoarse)
|
|
|
|
{
|
2018-03-14 14:54:25 +00:00
|
|
|
EigenPack<FineF>::resize(sizeFine, gridFine);
|
2018-03-13 13:51:09 +00:00
|
|
|
evalCoarse.resize(sizeCoarse);
|
|
|
|
evecCoarse.resize(sizeCoarse, gridCoarse);
|
|
|
|
}
|
|
|
|
|
2018-04-03 17:42:21 +01:00
|
|
|
void readFine(const std::string fileStem, const int traj = -1)
|
2018-03-13 13:51:09 +00:00
|
|
|
{
|
|
|
|
std::string evecFineFilename, evalFineFilename;
|
|
|
|
std::string evecCoarseFilename, evalCoarseFilename;
|
|
|
|
|
|
|
|
this->makeFilenames(evecFineFilename, evalFineFilename,
|
|
|
|
fileStem + "_fine", traj);
|
|
|
|
XmlReader xmlFineReader(evalFineFilename);
|
|
|
|
LOG(Message) << "Reading " << this->eval.size() << " fine eigenvalues from '"
|
|
|
|
<< evalFineFilename << "'" << std::endl;
|
|
|
|
Grid::read(xmlFineReader, "evals", this->eval);
|
2018-04-04 16:36:37 +01:00
|
|
|
LOG(Message) << "Reading " << this->evec.size() << " fine eigenvectors from '"
|
|
|
|
<< evecFineFilename << "'" << std::endl;
|
|
|
|
this->basicRead(this->evec, evecFineFilename, this->evec.size());
|
2018-04-03 17:42:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void readCoarse(const std::string fileStem, const int traj = -1)
|
|
|
|
{
|
|
|
|
std::string evecCoarseFilename, evalCoarseFilename;
|
|
|
|
|
|
|
|
this->makeFilenames(evecCoarseFilename, evalCoarseFilename,
|
|
|
|
fileStem + "_coarse", traj);
|
|
|
|
XmlReader xmlCoarseReader(evalCoarseFilename);
|
2018-03-13 13:51:09 +00:00
|
|
|
LOG(Message) << "Reading " << evalCoarse.size() << " coarse eigenvalues from '"
|
|
|
|
<< evalCoarseFilename << "'" << std::endl;
|
|
|
|
Grid::read(xmlCoarseReader, "evals", evalCoarse);
|
2018-04-04 16:36:37 +01:00
|
|
|
LOG(Message) << "Reading " << evecCoarse.size() << " coarse eigenvectors from '"
|
|
|
|
<< evecCoarseFilename << "'" << std::endl;
|
|
|
|
this->basicRead(evecCoarse, evecCoarseFilename, evecCoarse.size());
|
2018-03-13 13:51:09 +00:00
|
|
|
}
|
|
|
|
|
2018-04-03 17:42:21 +01:00
|
|
|
virtual void read(const std::string fileStem, const int traj = -1)
|
|
|
|
{
|
|
|
|
readFine(fileStem, traj);
|
|
|
|
readCoarse(fileStem, traj);
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeFine(const std::string fileStem, const int traj = -1)
|
2018-03-13 13:51:09 +00:00
|
|
|
{
|
|
|
|
std::string evecFineFilename, evalFineFilename;
|
|
|
|
|
|
|
|
this->makeFilenames(evecFineFilename, evalFineFilename,
|
|
|
|
fileStem + "_fine", traj);
|
|
|
|
XmlWriter xmlFineWriter(evalFineFilename);
|
|
|
|
LOG(Message) << "Writing " << this->eval.size() << " fine eigenvalues to '"
|
|
|
|
<< evalFineFilename << "'" << std::endl;
|
|
|
|
Grid::write(xmlFineWriter, "evals", this->eval);
|
2018-04-04 16:36:37 +01:00
|
|
|
LOG(Message) << "Writing " << this->evec.size() << " fine eigenvectors to '"
|
|
|
|
<< evecFineFilename << "'" << std::endl;
|
|
|
|
this->basicWrite(evecFineFilename, this->evec, this->evec.size());
|
2018-04-03 17:42:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void writeCoarse(const std::string fileStem, const int traj = -1)
|
|
|
|
{
|
|
|
|
std::string evecCoarseFilename, evalCoarseFilename;
|
|
|
|
|
|
|
|
this->makeFilenames(evecCoarseFilename, evalCoarseFilename,
|
|
|
|
fileStem + "_coarse", traj);
|
|
|
|
XmlWriter xmlCoarseWriter(evalCoarseFilename);
|
2018-03-13 13:51:09 +00:00
|
|
|
LOG(Message) << "Writing " << evalCoarse.size() << " coarse eigenvalues to '"
|
|
|
|
<< evalCoarseFilename << "'" << std::endl;
|
|
|
|
Grid::write(xmlCoarseWriter, "evals", evalCoarse);
|
2018-04-04 16:36:37 +01:00
|
|
|
LOG(Message) << "Writing " << evecCoarse.size() << " coarse eigenvectors to '"
|
|
|
|
<< evecCoarseFilename << "'" << std::endl;
|
|
|
|
this->basicWrite(evecCoarseFilename, evecCoarse, evecCoarse.size());
|
2018-03-13 13:51:09 +00:00
|
|
|
}
|
2018-04-03 17:42:21 +01:00
|
|
|
|
|
|
|
virtual void write(const std::string fileStem, const int traj = -1)
|
|
|
|
{
|
|
|
|
writeFine(fileStem, traj);
|
|
|
|
writeCoarse(fileStem, traj);
|
|
|
|
}
|
2018-03-13 13:51:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename FImpl>
|
|
|
|
using FermionEigenPack = EigenPack<typename FImpl::FermionField>;
|
|
|
|
|
|
|
|
template <typename FImpl, int nBasis>
|
|
|
|
using CoarseFermionEigenPack = CoarseEigenPack<
|
|
|
|
typename FImpl::FermionField,
|
|
|
|
typename LocalCoherenceLanczos<typename FImpl::SiteSpinor,
|
|
|
|
typename FImpl::SiteComplex,
|
|
|
|
nBasis>::CoarseField>;
|
|
|
|
|
|
|
|
END_HADRONS_NAMESPACE
|
|
|
|
|
|
|
|
#endif // Hadrons_EigenPack_hpp_
|