forked from lijiext/lammps
205 lines
7.8 KiB
C++
205 lines
7.8 KiB
C++
# ifndef WPMD_SPLIT_H
|
|
# define WPMD_SPLIT_H
|
|
|
|
/** @file wpmd.h
|
|
@brief Representation of electrons by multiple wave packets within WPMD */
|
|
|
|
/*s****************************************************************************
|
|
* $Log: wpmd_split.h,v $
|
|
* Revision 1.2 2011/06/11 16:53:55 valuev
|
|
* sync with LAMMPS
|
|
*
|
|
* Revision 1.1 2011/06/10 17:15:07 morozov
|
|
* First Windows project with the correct directory structure
|
|
*
|
|
* Revision 1.17 2011/06/09 22:55:08 valuev
|
|
* norm matrices
|
|
*
|
|
* Revision 1.16 2011/06/07 19:58:42 valuev
|
|
* corrected partitions
|
|
*
|
|
* Revision 1.15 2011/06/07 17:43:00 valuev
|
|
* added Y derivatives
|
|
*
|
|
* Revision 1.14 2011/06/03 08:13:33 valuev
|
|
* added partitions to account for ghost atoms
|
|
*
|
|
* Revision 1.13 2011/06/01 23:45:35 valuev
|
|
* modified for LAMMPS compatibility
|
|
*
|
|
* Revision 1.12 2011/05/28 17:16:22 valuev
|
|
* fixed template<>, some fixes to UHF
|
|
*
|
|
* Revision 1.11 2011/05/27 08:43:52 valuev
|
|
* fixed split packet antisymmetrized version
|
|
*
|
|
* Revision 1.10 2011/05/25 05:23:43 valuev
|
|
* fixed variable transformation for norm matrix
|
|
*
|
|
* Revision 1.9 2011/05/24 19:54:32 valuev
|
|
* fixed sqmatrix::iterator
|
|
*
|
|
* Revision 1.8 2011/05/20 21:39:49 valuev
|
|
* separated norm calculation
|
|
*
|
|
* Revision 1.7 2011/05/14 18:56:19 valuev
|
|
* derivative for ee split interactions
|
|
*
|
|
* Revision 1.6 2011/05/05 08:56:02 valuev
|
|
* working split wp version
|
|
*
|
|
* Revision 1.5 2011/05/04 16:48:52 valuev
|
|
* fixed syntax
|
|
*
|
|
* Revision 1.4 2011/05/04 09:04:48 valuev
|
|
* completed wp_split (except for ee forces)
|
|
*
|
|
* Revision 1.3 2011/04/22 09:54:24 valuev
|
|
* working on split WP
|
|
*
|
|
* Revision 1.1 2011/04/20 08:43:09 valuev
|
|
* started adding split packet WPMD
|
|
*
|
|
*******************************************************************************/
|
|
|
|
#include "wpmd.h"
|
|
|
|
|
|
class AWPMD_split: public AWPMD {
|
|
protected:
|
|
int s_add, spl_add;
|
|
public:
|
|
vector<Vector_2> split_c[2]; ///<\en split coefficients for electrons (c_re, c_im) or (psi,phi) depending on the norm mode
|
|
vector<int> nspl[2]; ///<\en number of wave packets for each electron (size is ne[i])
|
|
|
|
vector<double> wf_norm[2]; ///<\en norms for each electron
|
|
vector<double> wf_norm_der[2]; ///<\en norm derivative
|
|
vector<cdouble> ovl_der[2]; ///<\en overlap derivative: \<psi|psi'\>
|
|
vector<double> E_der[2]; ///<\en energy derivative with respect to {a,b} coordinates
|
|
|
|
|
|
vector< cdouble > Lh[2]; ///<\en Substitute for L in Hartree case: block matrices 1x(10*nspl[i])
|
|
vector< sqmatrix<double> > Normh[2]; ///<\en Substitute for Norm in Hartree case: block matrices
|
|
|
|
///\en resizes all internal arrays according to new electrons (wavepackets) added
|
|
virtual void resize(int flag);
|
|
|
|
|
|
|
|
|
|
public:
|
|
AWPMD_split():s_add(0),spl_add(0){}
|
|
|
|
|
|
///\en Prepares to setup a new system of particles using \ref add_ion(),
|
|
/// \ref add_electron() and \ref add_split().
|
|
/// There is no need to call this function when using
|
|
/// \ref set_electrons() and \ref set_ions() to setup particles.
|
|
virtual void reset(){
|
|
for(int s=0;s<2;s++){
|
|
split_c[s].clear();
|
|
nspl[s].clear();
|
|
}
|
|
s_add=0;
|
|
spl_add=0;
|
|
AWPMD::reset();
|
|
}
|
|
|
|
|
|
|
|
///\en Setup electrons: forms internal wave packet representations.
|
|
/// If PBCs are used the coords must be within the range [0, cell)
|
|
/// the \a splits array defines the number of wavepackets required for each electron
|
|
/// the data for splits should be placed in the corresponding data arrays
|
|
/// \a c array contains the splits mixing coefficints
|
|
/// \a n is the number of electrons of a given spin component
|
|
/// Electron velocity v is multiplied by mass to obtain momentum.
|
|
/// Default mass (-1) means me.
|
|
/// Electronic charges q are -1 by default (when q=NULL), otherwise the charges are assigned for each split
|
|
int set_electrons(int s, int nel, Vector_3P x, Vector_3P v, double* w, double* pw, Vector_2 *c, int *splits, double mass=-1, double *q=NULL);
|
|
|
|
|
|
///\en Starts adding new electron: continue with \ref add_split functions.
|
|
int add_electron(int s){
|
|
if(s < 0 || s > 1)
|
|
return LOGERR(-1,fmt("AWPMD_split.add_electron: invaid spin setting (%d)!",s),LINFO);
|
|
s_add=s;
|
|
spl_add=0;
|
|
return ne[s_add];
|
|
}
|
|
|
|
///\en Adds a new split to current electron.
|
|
/// May change the arguments according to the constraints set.
|
|
/// \return global id of the wavepacket (starting from 0 for each spin s)
|
|
/// Electron velocity v is multiplied by mass to obtain momentum.
|
|
/// Default mass (-1) means me.
|
|
/// The tags must be nonzero, >0 for the local particle, <0 for ghost particle.
|
|
/// Unique particle id is abs(tag).
|
|
/// Default tag (0) means inserting the current particle id as local particle.
|
|
int add_split(Vector_3 &x, Vector_3 &v, double &w, double &pw, Vector_2 &c, double mass=-1, double q=-1., int tag=0);
|
|
|
|
|
|
///\en gets current electronic coordinates, and (optionally) number of wave packets for each electron
|
|
int get_electrons(int spin, Vector_3P x, Vector_3P v, double* w, double* pw, cdouble *c, int *splits=NULL, double mass=-1);
|
|
|
|
|
|
void eterm_deriv(int ic1,int s1, int c1,int k1,int ic2,int s2, int c2,int j2,cdouble pref,
|
|
const OverlapDeriv &o,cdouble v,cdouble dv_aj_conj,
|
|
cdouble dv_ak,cVector_3 dv_bj_conj, cVector_3 dv_bk);
|
|
|
|
///\en adds the derivatives of Y for the term v*Y[s](c2,c1)
|
|
void y_deriv(cdouble v,int s, int c2, int c1);
|
|
|
|
|
|
///\en Calculates block norms an derivatives
|
|
void calc_norms(int flag);
|
|
|
|
///\en Prepares force arrays according to \a flag setting for interaction()
|
|
virtual void clear_forces(int flagi,Vector_3P fi, Vector_3P fe_x,
|
|
Vector_3P fe_p, double *fe_w, double *fe_pw, Vector_2P fe_c);
|
|
|
|
///\en Calcualtes the overlap between two electrons taking all split WPs into account.
|
|
/// Norms must be pre-calculated.
|
|
cdouble overlap(int ic1, int s1, int c1,int ic2, int s2, int c2);
|
|
|
|
//e same as interaction, but using Hartee factorization (no antisymmetrization)
|
|
int interaction_hartree(int flag=0, Vector_3P fi=NULL, Vector_3P fe_x=NULL,
|
|
Vector_3P fe_p=NULL, double *fe_w=NULL, double *fe_pw=NULL, Vector_2P fe_c=NULL);
|
|
|
|
///\en Calculates interaction in the system of ni ions + electrons
|
|
/// the electonic subsystem must be previously setup by set_electrons, ionic by set_ions
|
|
/// 0x1 -- give back ion forces \n
|
|
/// 0x2 -- add ion forces to the existing set \n
|
|
/// 0x4 -- calculate electronic forces \n
|
|
/// 0x8 -- add electronic forces to the existing arrays \n
|
|
/// 0x10 -- calculate internal electronic derivatives only: \n
|
|
/// will not update electronic force arrays, which may be NULL, \n
|
|
/// the forces may be obtained then using \ref get_el_forces() for all WPs \n
|
|
/// or separately for each WP using \ref get_wp_force()
|
|
/// if PBCs are used the coords must be within a range [0, cell)
|
|
int interaction(int flag=0, Vector_3P fi=NULL, Vector_3P fe_x=NULL,
|
|
Vector_3P fe_p=NULL, double *fe_w=NULL, double *fe_pw=NULL, Vector_2P fe_c=NULL);
|
|
|
|
///\en Get electronic forcess in the arrays provided, using calculated internal representation
|
|
/// Valid flag settings are:\n
|
|
/// 0x4 -- overwrite existing forces \n
|
|
/// 0x8 -- add electronic forces to the existing arrays \n
|
|
void get_el_forces(int flag, Vector_3P fe_x,
|
|
Vector_3P fe_p, double *fe_w, double *fe_pw, Vector_2P fe_c);
|
|
|
|
|
|
void get_wp_force(int s, int ispl, Vector_3P fe_x, Vector_3P fe_p, double *fe_w, double *fe_pw, Vector_2P fe_c){
|
|
WavePacket wk=wp[s][ispl];
|
|
int indw1=8*ispl;
|
|
int indn1=(nvar[s]/10)*8+2*ispl;
|
|
wk.int2phys_der< eq_minus_second >(E_der[s].begin()+indw1,(double *)fe_x,(double *)fe_p,fe_w,fe_pw,1./one_h);
|
|
*fe_c=-Vector_2(E_der[s][indn1],E_der[s][indn1+1]);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
# endif
|