/* 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" // Member functions Symmetries::Symmetries() { calc_symmetries_flag = nrot = 0; maps = 0; done = 0; } Symmetries::~Symmetries() { if (maps != NULL) { for (int sp=0; sp < nsp; sp++) { for (int i=0; i < 48; i++) myfree(maps[sp][i]); myfree(maps[sp]); } myfree(maps); } if (done != NULL) myfree(done); } void Symmetries::setup(Everything &e, const Basis &basis) { maps = (int ***)mymalloc(sizeof(int **)*e.ioninfo.nspecies, "maps[]","Speciesinfo.setup()"); nsp = e.ioninfo.nspecies; for (int sp=0; sp < nsp; sp++){ maps[sp] = (int **)mymalloc(sizeof(int *)*48, "maps[][]","Speciesinfo.setup()"); for (int i=0; i < 48; i++) maps[sp][i] = (int *)mymalloc(sizeof(int)* e.ioninfo.species[sp].natoms, "maps[][][]","Speciesinfo.setup()"); } if (calc_symmetries_flag != 0) // done = (int *)mymalloc(sizeof(int)*basis.basis_spec->NxNyNz, // "done[]","Speciesinfo.setup()"); done = (int *)mymalloc(sizeof(int)*basis.basis_spec->size_realgrid, "done[]","Speciesinfo.setup()"); // Automatic calculation if (calc_symmetries_flag == 1) symmetries(&e.ioninfo,&e.lattice, this); // Manually input symmetries else if (calc_symmetries_flag == 2) { // If we are in manual mode, and no symmetry matrices were // input, we have a big problem! if (nrot<1) die("\nManual symmetry specification was specified,\nbut no symmetry matrices were given!\n\nExiting.\n\n"); else check_symmetries(&e.ioninfo,this); } // No symmetries. Identity only else { nrot = 1; done = NULL; sym[0].m[0][0] = sym[0].m[1][1] = sym[0].m[2][2] = 1.0; sym[0].m[0][1] = sym[0].m[0][2] = sym[0].m[1][0] = 0.0; sym[0].m[1][2] = sym[0].m[2][0] = sym[0].m[2][1] = 0.0; } /* * Check that the basis is commensurate with the symmetries. */ check_basis_symm_compatibility(*this,basis); /* * Map atoms to symmetry related ones if needs to calculate forces. */ if (e.cntrl.calculate_forces_flag) map_symm_atom(e.ioninfo, *this); dft_log("----- Symmetries::setup() -----\n\n"); }