/*
DFT++ is a density functional package developed by the research group
of Professor Tomas Arias
Copyright 1996-2003 Sohrab Ismail-Beigi
This file is part of DFT++.
DFT++ 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.
DFT++ 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 DFT++; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Please see the file CREDITS for a list of authors.
For academic users, we request that publications using results obtained with
this software reference
"New algebraic formulation of density functional calculation," by Sohrab Ismail-Beigi
and T.A. Arias, Computer Physics Communications 128:1-2, 1-45 (June 2000).
and, if using the wavelet basis, further reference
"Multiresolution analysis of electronic structure: semicardinal and wavelet bases,"
T.A. Arias, Reviews of Modern Physics 71:1, 267-311 (January 1999).
and
"Robust ab initio calculation of condensed matter: transparent convergence through
semicardinal multiresolution analysis,'' I.P. Daykov, T.A. Arias, and
Torkel D. Engeness, Physical Review Letters, 90:21, 216402 (May 2003).
For your convenience, preprints of the above articles may be obtained from
http://arXiv.org/abs/cond-mat/9909130, 9805262, and 0204411, respectively.
*/
#include "header.h"
// constructor
Ioninfo::Ioninfo()
{
nspecies = 0;
species = NULL;
read_vloc_flag = FALSE;
}
Ioninfo::~Ioninfo()
{
if (nspecies>0)
{
for (int sp=0; sp < nspecies; sp++)
species[sp].Speciesinfo::~Speciesinfo();
myfree(species);
}
}
//
// Do the setup for the ionic information (read psps, alloc space, blah blah)
//
void
Ioninfo::setup(Everything &e)
{
dft_log("----- Ioninfo::setup() -----\n");
// Call the species setup routines
for (int sp=0; sp < e.ioninfo.nspecies; sp++)
e.ioninfo.species[sp].setup(e);
// Check atomic positions for problems
check_pos();
// Print out the internals of Ioninfo structure to the log file
dft_log("\n");
print(dft_global_log, e);
dft_log("\n");
}
// Print internal info for each species
void Ioninfo::print(Output *out, Everything &e)
{
out->printf("Displaying Ioninfo contents:\n");
out->printf("Found %d species:\n",nspecies);
for (int sp = 0; sp < nspecies; sp++)
species[sp].print(out, e);
}
/*
* Make sure no atoms are layed on top of each other.
*/
void Ioninfo::check_pos()
{
int dieflag = 0;
real sizetest = 0;
vector3 vtest[2];
for (int sp=0; sp < nspecies; sp++)
for (int n=0; n < species[sp].natoms; n++) {
vtest[0] = species[sp].atpos[n];
for (int sp1 = sp; sp1 < nspecies; sp1++)
for (int n1 = ((sp1==sp) ? (n+1) : 0);
n1 < species[sp1].natoms; n1++) {
vtest[1] = vtest[0] - species[sp1].atpos[n1];
sizetest = vtest[1] * vtest[1];
if (sizetest < MIN_ION_DISTANCE) {
dieflag = 1;
dft_log(">>Atoms' positions coincide!!\n");
dft_log(">>(sp %d : at %d) = (sp %d : at %d) : ",
sp, n, sp1, n1);
species[sp].atpos[n].print(dft_global_log," %f ");
}
}
}
if(dieflag != 0)
die(">> You put atoms on top of each other, moron. I have to quit now. Bye\n");
}
int Ioninfo::symmetrize_force(const Symmetries &symm)
{
if (symm.nrot <= 1) // no need to do any symmetrization
return 0;
// for each atom, each symmetry maps it to one of its own species.
for (int sp = 0; sp < nspecies; sp++)
{
vector3 *forces_tmp;
int iat;
int natoms = species[sp].natoms;
vector3 *forces = species[sp].forces;
forces_tmp = (vector3*)mymalloc(sizeof(vector3)*natoms,
"forces_tmp",
"symmetrize_force");
for (iat = 0; iat < natoms; iat++)
forces_tmp[iat] = 0;
for (iat = 0; iat < natoms; iat++)
for (int irot = 0; irot < symm.nrot; irot++)
forces_tmp[symm.maps[sp][irot][iat]] +=
symm.f_sym[irot] * forces[iat];
for (iat = 0; iat < natoms; iat++)
forces[iat] = forces_tmp[iat] / symm.nrot;
myfree(forces_tmp);
}
return 1;
}
void Ioninfo::print_force(const Output *out, Everything &e) const
{
for (int sp=0; sp < nspecies; sp++)
species[sp].print_force(out, e);
}
syntax highlighted by Code2HTML, v. 0.9.1