Commit 9f8c0321 by Francois Gygi

rel1_13_0: implemented stress calculations


git-svn-id: http://qboxcode.org/svn/qb/trunk@183 cba15fb0-1239-40c8-b417-11db7ca47a34
parent b970278c
////////////////////////////////////////////////////////////////////////////////
//
// CellStepper.h:
//
////////////////////////////////////////////////////////////////////////////////
// $Id: CellStepper.h,v 1.1 2004-03-11 21:58:10 fgygi Exp $
#ifndef CELLSTEPPER_H
#define CELLSTEPPER_H
#include "Sample.h"
#include <valarray>
#include <iostream>
#include <iomanip>
using namespace std;
class CellStepper
{
protected:
Sample& s_;
AtomSet& atoms_;
double ekin_;
UnitCell cellp;
public:
CellStepper (Sample& s) : s_(s), atoms_(s.atoms), ekin_(0.0) {}
virtual void compute_new_cell(const valarray<double>& sigma) = 0;
virtual void update_cell(void) = 0;
double ekin(void) const { return ekin_; }
virtual ~CellStepper() {}
};
#endif
////////////////////////////////////////////////////////////////////////////////
//
// ConfinementPotential.C
//
////////////////////////////////////////////////////////////////////////////////
// $Id: ConfinementPotential.C,v 1.1 2004-03-11 21:58:10 fgygi Exp $
#include "ConfinementPotential.h"
#include "Basis.h"
////////////////////////////////////////////////////////////////////////////////
ConfinementPotential::ConfinementPotential(double ecuts, double facs,
double sigmas, const Basis& basis): ecuts_(ecuts), facs_(facs),
sigmas_(sigmas), basis_(basis)
{
const int ngwloc = basis_.localsize();
fstress_.resize(ngwloc);
dfstress_.resize(ngwloc);
update();
}
////////////////////////////////////////////////////////////////////////////////
void ConfinementPotential::update(void)
{
// recompute confinement potential and its derivative
const double sigmas_inv = 1.0 / sigmas_;
const int ngwloc = basis_.localsize();
for ( int ig = 0; ig < ngwloc; ig++ )
{
const double gsq = basis_.kpg2(ig);
// Next line: 0.5 from 1/2m
const double arg = ( 0.5 * gsq - ecuts_ ) * sigmas_inv;
// Next lines: fp = fermi(arg);
// fm = fermi(-arg) = 1 - fp;
double fm,fp;
if ( arg > 50.0 )
{
fm = 1.0;
fp = 0.0;
}
else if ( arg < -50.0 )
{
fm = 0.0;
fp = 1.0;
}
else
{
fp = 1.0 / ( 1.0 + exp ( arg ) );
fm = 1.0 - fp;
}
// f(G) = facs * ( 1 - fermi( (G^2-ecuts)/sigmas ) )
// fg = f(G)
const double fg = facs_ * fm;
// gfgp = G f'(G)
const double gfgp = gsq * fg * fp * sigmas_inv;
// fstress[ig] = G^2 * f(G)
fstress_[ig] = gsq * fg;
// dfstress = 2 f(G) + G * f'(G)
dfstress_[ig] = 2.0 * fg + gfgp;
// ekin = sum_G |c_G|^2 G^2
// econf = sum_G |c_G|^2 fstress[G]
// stress_ekin_ij = (1/Omega) sum_G |c_G|^2 * 2 * G_i * G_j
// stress_econf_ij = (1/Omega) sum_G |c_G|^2 * dfstress[G] * G_i * G_j
}
}
////////////////////////////////////////////////////////////////////////////////
//
// ConfinementPotential.h
//
////////////////////////////////////////////////////////////////////////////////
// $Id: ConfinementPotential.h,v 1.1 2004-03-11 21:58:10 fgygi Exp $
#ifndef CONFINEMENTPOTENTIAL_H
#define CONFINEMENTPOTENTIAL_H
class Basis;
#include <valarray>
using namespace std;
class ConfinementPotential
{
private:
double ecuts_, facs_, sigmas_;
const Basis& basis_;
valarray<double> fstress_, dfstress_;
public:
const valarray<double>& fstress(void) const { return fstress_; }
const valarray<double>& dfstress(void) const { return dfstress_; }
void update(void);
const Basis& basis() const { return basis_; }
ConfinementPotential(double ecuts, double facs, double sigmas,
const Basis& basis);
~ConfinementPotential();
};
#endif
////////////////////////////////////////////////////////////////////////////////
//
// Debug.h
//
////////////////////////////////////////////////////////////////////////////////
// $Id: Debug.h,v 1.1 2004-03-11 22:01:24 fgygi Exp $
#ifndef DEBUG_H
#define DEBUG_H
#include<iostream>
#include<iomanip>
#include<sstream>
#include<stdlib.h>
#include "Sample.h"
class Debug : public Var
{
Sample *s;
public:
char *name ( void ) const { return "debug"; };
int set ( int argc, char **argv )
{
const string allowed_values("OFF STRESS");
if ( argc < 2 )
{
if ( ui->onpe0() )
cout << " debug must be in " << allowed_values << endl;
return 1;
}
string v;
for ( int iarg = 1; iarg < argc; iarg++ )
{
string vt = argv[iarg];
if ( allowed_values.find(vt) == string::npos )
{
// not a valid argument
if ( ui->onpe0() )
{
cout << vt << " is not a valid debug option " << endl;
cout << " valid debug options are: " << allowed_values << endl;
}
return 1;
}
v += " " + vt;
}
// check if OFF is found in the string v
if ( v.find("OFF") != string::npos )
v = "OFF";
s->ctrl.debug = v;
return 0;
}
string print (void) const
{
ostringstream st;
st.setf(ios::left,ios::adjustfield);
st << setw(10) << name() << " = ";
st.setf(ios::right,ios::adjustfield);
st << setw(10) << s->ctrl.debug;
return st.str();
}
Debug(Sample *sample) : s(sample) { s->ctrl.debug = "OFF"; }
};
#endif
////////////////////////////////////////////////////////////////////////////////
//
// Preconditioner.C
//
////////////////////////////////////////////////////////////////////////////////
// $Id: Preconditioner.C,v 1.1 2004-03-11 21:58:10 fgygi Exp $
#include "Preconditioner.h"
#include "EnergyFunctional.h"
#include "Sample.h"
#include "Basis.h"
#include "SlaterDet.h"
#include "ConfinementPotential.h"
////////////////////////////////////////////////////////////////////////////////
Preconditioner::Preconditioner(const Sample& s, const EnergyFunctional& ef) :
s_(s), ef_(ef)
{
update();
}
////////////////////////////////////////////////////////////////////////////////
void Preconditioner::update(void)
{
// reinitialize preconditioner
bool use_confinement = s_.ctrl.ecuts > 0.0;
const double ecutpr = s_.ctrl.ecutprec;
const Wavefunction& wf = s_.wf;
diag_.resize(wf.nspin());
for ( int ispin = 0; ispin < wf.nspin(); ispin++ )
{
diag_[ispin].resize(wf.nkp());
for ( int ikp = 0; ikp < wf.nkp(); ikp++ )
{
if ( wf.sd(ispin,ikp) != 0 && wf.sdcontext(ispin,ikp)->active() )
{
// Only resize and initialize diag_ if ikp is active on this task
const Basis& basis = wf.sd(ispin,ikp)->basis();
const int ngwloc = basis.localsize();
diag_[ispin][ikp].resize(ngwloc);
const double *g2_ptr = basis.g2_ptr();
if ( use_confinement )
{
const valarray<double>& fstress = ef_.confpot(ikp)->fstress();
for ( int ig = 0; ig < ngwloc; ig++ )
{
double e = ( 0.5 + fstress[ig] ) * g2_ptr[ig];
diag_[ispin][ikp][ig] = ( e < ecutpr ) ? 0.5 / ecutpr : 0.5 / e;
}
}
else
{
for ( int ig = 0; ig < ngwloc; ig++ )
{
double e = 0.5 * g2_ptr[ig];
diag_[ispin][ikp][ig] = ( e < ecutpr ) ? 0.5 / ecutpr : 0.5 / e;
}
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
//
// Preconditioner.h
//
////////////////////////////////////////////////////////////////////////////////
// $Id: Preconditioner.h,v 1.1 2004-03-11 21:58:10 fgygi Exp $
#ifndef PRECONDITIONER_H
#define PRECONDITIONER_H
class Sample;
class EnergyFunctional;
#include <vector>
#include <valarray>
using namespace std;
class Preconditioner
{
private:
const Sample& s_;
const EnergyFunctional& ef_;
vector<vector<valarray<double> > > diag_; // diag_[ispin][ikp][ig]
public:
void update(void);
const valarray<double>& diag(int ispin, int ikp) const
{ return diag_[ispin][ikp]; }
Preconditioner(const Sample& s, const EnergyFunctional& ef);
//~Preconditioner();
};
#endif
////////////////////////////////////////////////////////////////////////////////
//
// SDCellStepper.C
//
////////////////////////////////////////////////////////////////////////////////
// $Id: SDCellStepper.C,v 1.1 2004-03-11 21:58:10 fgygi Exp $
#include "SDCellStepper.h"
////////////////////////////////////////////////////////////////////////////////
void SDCellStepper::compute_new_cell(const valarray<double>& sigma)
{
cout << " SDCellStepper::compute_new_cell" << endl;
// multiply stress by A^T to get dE/da_ij
valarray<double> deda(9);
const UnitCell& cell = s_.wf.cell();
const double cell_mass = s_.ctrl.cell_mass;
if ( cell_mass <= 0.0 )
{
if ( s_.ctxt_.onpe0() )
{
cout << "<!-- SDCellStepper::compute_new_cell: cell mass is zero\n"
<< " cannot update cell -->" << endl;
return;
}
}
// deda = - omega * sigma * A^-T
cell.compute_deda(sigma,deda);
for ( int i = 0; i < 9; i++ )
cout << " deda[" << i << "] = " << deda[i] << endl;
string cell_lock = s_.ctrl.cell_lock;
if ( cell_lock != "OFF" )
{
// constraints on the cell derivatives
if ( cell_lock.find("A") != string::npos )
{
// vector A is locked
deda[0] = deda[1] = deda[2] = 0.0;
}
if ( cell_lock.find("B") != string::npos )
{
// vector B is locked
deda[3] = deda[4] = deda[5] = 0.0;
}
if ( cell_lock.find("C") != string::npos )
{
// vector C is locked
deda[6] = deda[7] = deda[8] = 0.0;
}
cout << " cell derivatives after constraints" << endl;
for ( int i = 0; i < 9; i++ )
cout << " deda[" << i << "] = " << deda[i] << endl;
}
const double dt = s_.ctrl.dt;
const double dt2bym = dt*dt/cell_mass;
// cellp = cell - deda * dt^2 / cell_mass
D3vector a0p = cell.a(0) - dt2bym * D3vector(deda[0],deda[1],deda[2]);
D3vector a1p = cell.a(1) - dt2bym * D3vector(deda[3],deda[4],deda[5]);
D3vector a2p = cell.a(2) - dt2bym * D3vector(deda[6],deda[7],deda[8]);
cellp = UnitCell(a0p,a1p,a2p);
cout << " SDCellStepper::compute_new_cell: cellp: " << endl;
cout << cellp;
}
////////////////////////////////////////////////////////////////////////////////
void SDCellStepper::update_cell(void)
{
const UnitCell& cell = s_.wf.cell();
// rescale atomic positions in AtomSet
// r_new = A_new A_old^-1 r_old
vector<vector<double> > r;
s_.atoms.get_positions(r);
const double* const ainv = cell.amat_inv();
const double* const ap = cellp.amat();
double tau[3];
for ( int is = 0; is < r.size(); is++ )
{
// transform r to tau: multiply by A^-1
const int nais = r[is].size()/3;
for ( int ia = 0; ia < nais; ia++ )
{
// multiply r[is][ia] by A_old^-1, result in tau
cell.vecmult3x3(cell.amat_inv(),&r[is][3*ia],&tau[0]);
// multiply tau by A_new, result in r[is][3*ia]
cellp.vecmult3x3(cellp.amat(),&tau[0],&r[is][3*ia]);
}
}
s_.atoms.set_positions(r);
// resize wavefunction and basis sets
cout << " SDCellStepper::update_cell" << endl;
s_.wf.resize(cellp,s_.wf.refcell(),s_.wf.ecut());
if ( s_.wfv != 0 )
{
s_.wfv->resize(cellp,s_.wf.refcell(),s_.wf.ecut());
// s_.wfv->clear();
}
}
////////////////////////////////////////////////////////////////////////////////
//
// SDCellStepper.h:
//
////////////////////////////////////////////////////////////////////////////////
// $Id: SDCellStepper.h,v 1.1 2004-03-11 21:58:10 fgygi Exp $
#ifndef SDCELLSTEPPER_H
#define SDCELLSTEPPER_H
#include "CellStepper.h"
class SDCellStepper : public CellStepper
{
private:
public:
SDCellStepper(Sample& s) : CellStepper(s) {}
void compute_new_cell(const valarray<double>& sigma_eks);
void update_cell(void);
double ekin(void) const { return 0.0; }
};
#endif
////////////////////////////////////////////////////////////////////////////////
//
// ThWidth.h
//
////////////////////////////////////////////////////////////////////////////////
// $Id: ThWidth.h,v 1.1 2004-03-11 21:58:10 fgygi Exp $
#ifndef THWIDTH_H
#define THWIDTH_H
#include<iostream>
#include<iomanip>
#include<sstream>
#include<stdlib.h>
#include "Sample.h"
class ThWidth : public Var
{
Sample *s;
public:
char *name ( void ) const { return "th_width"; };
int set ( int argc, char **argv )
{
if ( argc != 2 )
{
if ( ui->onpe0() )
cout << " th_width takes only one value" << endl;
return 1;
}
double v = atof(argv[1]);
if ( v <= 0.0 )
{
if ( ui->onpe0() )
cout << " th_width must be positive" << endl;
return 1;
}
s->ctrl.th_width = v;
return 0;
}
string print (void) const
{
ostringstream st;
st.setf(ios::left,ios::adjustfield);
st << setw(10) << name() << " = ";
st.setf(ios::right,ios::adjustfield);
st << setw(10) << s->ctrl.th_width;
return st.str();
}
ThWidth(Sample *sample) : s(sample) { s->ctrl.th_width = 100.0; }
};
#endif
#-------------------------------------------------------------------------------
#
# aix_mpi.mk
#
#-------------------------------------------------------------------------------
# $Id: aix_mpi_gcc.mk,v 1.1 2004-03-11 21:58:10 fgygi Exp $
PLT=AIX
#-------------------------------------------------------------------------------
XERCESCDIR=${HOME}/software/xml/xerces-c-${PLT}
XERCESCLIBDIR=/usr/apps/qbox/lib
MPIDIR=/usr/local/mpi
GCCDIR=/usr/local/tools/gnu/gcc/3.1_aix_5
CXX=$(GCCDIR)/bin/g++
LD=$(CXX)
DFLAGS += -DUSE_ESSL -DUSE_CSTDIO_LFS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
INCLUDE = -I$(XERCESCDIR)/include -I$(MPIDIR)/include
#CXXFLAGS= -O2 -DUSE_MPI -DSCALAPACK -D$(PLT) $(INCLUDE) $(DFLAGS)
CXXFLAGS= -g -DUSE_MPI -DSCALAPACK -D$(PLT) $(INCLUDE) $(DFLAGS)
LIBPATH = -L$(GCCDIR)/lib -L$(GCCDIR)/lib/gcc-lib/powerpc-ibm-aix5.1.0.0/3.1 \
-L $(XERCESCLIBDIR) -L $(MPIDIR)/lib
PLIBS = $(SCALAPACKLIB) $(PBLASLIB) $(TOOLSLIB) $(REDISTLIB) $(CBLACSLIB)
LIBS = $(PLIBS) -lessl -lm -lmassv -lxlf90_r \
$(XERCESCLIBDIR)/libxerces-c.so -lmpich \
$(GCCDIR)/lib/libg2c.a
LDFLAGS = $(LIBPATH) $(LIBS)
#
# BLACS setup. All version need the debug level (0 or 1),
# and the directory where the BLACS libraries are
#
BLACSDBGLVL = 0
BLACSdir = $(HOME)/lib
#
# MPI setup; uncomment and tailor to your system if using MPIBLACS
# Will need to comment out the default native BLACS setup below below
#
#USEMPI = -DUsingMpiBlacs
BLACSFINIT = $(BLACSdir)/blacsF77init_MPI-SP-$(BLACSDBGLVL).a
BLACSCINIT = $(BLACSdir)/blacsCinit_MPI-SP-$(BLACSDBGLVL).a
BLACSLIB = $(BLACSdir)/blacs_MPI-SP-$(BLACSDBGLVL).a
#
# system primitive BLACS setup, comment out if using MPI
#
CBLACSLIB = $(BLACSCINIT) $(BLACSLIB) $(BLACSCINIT)
FBLACSLIB = $(BLACSFINIT) $(BLACSLIB) $(BLACSFINIT)
#
# BLAS and LAPACK
#
#BLASLIB = /usr/local/lib/lapack.a -lesslsmp
BLASLIB = /usr/local/lib/lapack.a -lessl
#
# The name of the libraries to be linked to
#
PBLASLIB = $(HOME)/lib/pblas_SP.a
SCALAPACKLIB = $(HOME)/lib/libscalapack_SP.a
TOOLSLIB = $(HOME)/lib/tools_SP.a
REDISTLIB = $(HOME)/lib/redist_SP.a
#-------------------------------------------------------------------------------
#
# hbar-icc.mk
#
#-------------------------------------------------------------------------------
# $Id: hbar-icc.mk,v 1.1 2004-03-11 21:58:10 fgygi Exp $
#
PLT=LINUX
#-------------------------------------------------------------------------------
GCCDIR=/usr/apps/gcc/3.1
MPIDIR=/home/fgygi/software/gm
XERCESCDIR=/home/fgygi/software/xml/xerces-c-${PLT}
CXX=icc
LD=$(CXX)
PLTFLAGS = -DUSE_FFTW -DUSE_CSTDIO_LFS -D_LARGEFILE_SOURCE \
-D_FILE_OFFSET_BITS=64 -DUSE_MPI -DSCALAPACK -DADD_ \
-DAPP_NO_THREADS -DXML_USE_NO_THREADS
FFTWDIR=$(HOME)/fftw/fftw-2.1.3/fftw
BLASDIR=$(HOME)/software/mkl/lib/32
INCLUDE = -I$(MPIDIR)/include -I$(FFTWDIR) -I$(XERCESCDIR)/include
CXXFLAGS= -O3 -Zp16 \
-D$(PLT) $(INCLUDE) $(PLTFLAGS) $(DFLAGS)
LIBPATH = -L$(FFTWDIR) -L/usr/X11R6/lib \
-L$(MPIDIR)/lib -L $(BLASDIR) -L $(GCCDIR)/lib -L$(XERCESCDIR)/lib
LIBS = $(PLIBS) -lfftw -lmkl_lapack $(BLASDIR)/libmkl_def.a \
-lm -lmpich -lpmpich -lmpich -lgm \
-lg2c -lguide -pthread $(XERCESCDIR)/lib/libxerces-c.a
LDFLAGS = $(LIBPATH) $(LIBS)
# Blacs libraries
BLACSDBGLVL = 0
BLACSdir = /home/casc/repository/fpmd/software/BLACS/LIB
BLACSFINIT = $(BLACSdir)/blacsF77init_MPI-$(PLT)-$(BLACSDBGLVL).a
BLACSCINIT = $(BLACSdir)/blacsCinit_MPI-$(PLT)-$(BLACSDBGLVL).a
BLACSLIB = $(BLACSdir)/blacs_MPI-$(PLT)-$(BLACSDBGLVL).a
CBLACSLIB = $(BLACSCINIT) $(BLACSLIB) $(BLACSCINIT)
FBLACSLIB = $(BLACSFINIT) $(BLACSLIB) $(BLACSFINIT)
# Scalapack libraries
SCALAPACK_DIR = /home/casc/repository/fpmd/lib
PBLASLIB = $(SCALAPACK_DIR)/pblas_$(PLT).a
SCALAPACKLIB = $(SCALAPACK_DIR)/scalapack_$(PLT).a
TOOLSLIB = $(SCALAPACK_DIR)/tools_$(PLT).a
REDISTLIB = $(SCALAPACK_DIR)/redist_$(PLT).a
LAPACKLIB = -llapack
BLASLIB = -lblas
# Parallel libraries
PLIBS = $(SCALAPACKLIB) $(PBLASLIB) $(TOOLSLIB) $(REDISTLIB) $(CBLACSLIB)
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
#
# mcr-gcc.mk
#
#-------------------------------------------------------------------------------
# $Id: mcr-gcc.mk,v 1.1 2004-03-11 21:58:10 fgygi Exp $
#
PLT=LINUX
#-------------------------------------------------------------------------------
GCCDIR=/usr/local/tools/gnu/gcc/3.2.1_redhat_7a_ia32
MPIDIR=/usr/lib/mpi
XERCESCDIR=$(HOME)/software/xml/icc-7.0/xerces-c-src2_2_0
CXX=$(GCCDIR)/bin/g++
LD=$(CXX)
FFTWDIR=$(HOME)/fftw/linux-pc-icc/fftw-2.1.3/fftw
BLASDIR=/opt/intel/mkl/lib/32
INCLUDE = -I$(MPIDIR)/include -I$(FFTWDIR) -I$(XERCESCDIR)/include
CXXFLAGS= -O3 -DUSE_MPI -DSCALAPACK -DADD_ -D$(PLT) $(INCLUDE) $(DFLAGS)
LIBPATH = -L$(GCCDIR)/lib -L$(FFTWDIR) -L/usr/X11R6/lib \
-L$(MPIDIR)/lib -L$(BLASDIR) -L/usr/lib \
-L$(XERCESCDIR)/lib
#LIBS = $(PLIBS) $(GCCDIR)/lib/libg2c.a -lfftw \
# -lmkl_lapack -lmkl -lmkl_def -lmkl_p4 -lm -lmpi -lpmpi \
# -lelan -lelan3 -openmp -lrmscall -lxerces-c
LIBS = $(PLIBS) $(GCCDIR)/lib/libg2c.a -lfftw \
-lmkl_lapack -lmkl -lmkl_def -lguide -lpthread -lm -lmpi -lpmpi \
-lelan -lelan3 -lrmscall -lxerces-c
LDFLAGS = $(LIBPATH) $(LIBS)
PLAT=INTEL
# Blacs libraries
BLACSDBGLVL = 0
BLACSdir = $(HOME)/lib
BLACSFINIT = $(BLACSdir)/blacsF77init_MPI-$(PLAT)-$(BLACSDBGLVL).a
BLACSCINIT = $(BLACSdir)/blacsCinit_MPI-$(PLAT)-$(BLACSDBGLVL).a
BLACSLIB = $(BLACSdir)/blacs_MPI-$(PLAT)-$(BLACSDBGLVL).a
CBLACSLIB = $(BLACSCINIT) $(BLACSLIB) $(BLACSCINIT)
FBLACSLIB = $(BLACSFINIT) $(BLACSLIB) $(BLACSFINIT)
# Scalapack libraries
SCALAPACK_DIR = $(HOME)/lib
PBLASLIB = $(SCALAPACK_DIR)/pblas_$(PLAT).a
SCALAPACKLIB = $(SCALAPACK_DIR)/scalapack_$(PLAT).a
TOOLSLIB = $(SCALAPACK_DIR)/tools_$(PLAT).a
REDISTLIB = $(SCALAPACK_DIR)/redist_$(PLAT).a
#LAPACKLIB = -llapack
#BLASLIB = -lblas
LAPACKLIB = -lmkl_lapack
BLASLIB = -lmkl
# Parallel libraries
PLIBS = $(SCALAPACKLIB) $(PBLASLIB) $(TOOLSLIB) $(REDISTLIB) $(CBLACSLIB)
#-------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
//
// xmlget.C:
//
////////////////////////////////////////////////////////////////////////////////
#include <cassert>
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/sax2/Attributes.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include "StrX.h"
#include <xercesc/sax2/DefaultHandler.hpp>
using namespace xercesc;
////////////////////////////////////////////////////////////////////////////////
class TestHandler : public DefaultHandler
{
bool read;
vector<string> y;
string tag;
public:
string buffer;
TestHandler(string tag_) : tag(tag_), read(false) { buffer = ""; }
~TestHandler() {}