/* 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. */ /* $Id: transtest.cpp,v 1.1.2.3 2003/05/29 18:54:36 ivan Exp $ */ /* * $Log: transtest.cpp,v $ * Revision 1.1.2.3 2003/05/29 18:54:36 ivan * Update the PRL reference * * Revision 1.1.2.2 2003/05/23 01:49:17 sahak * added the new header * * Revision 1.1.2.1 2002/09/22 23:36:03 ivan * Incorporating development by Prof. Arias: * GGA - both for PW and WL branch * optest/transtest/gradtest for WL (note that for PW are trivial) * updated and incorporated to this code, added option WLtests * in makefile to compile them * * Revision 1.1 1999/09/14 19:40:35 torkel * Initial revision * * Revision 1.7 1999/08/06 19:25:39 torkel * *** empty log message *** * * Revision 1.6 1999/07/04 20:49:33 torkel * Full O implemented. * * Revision 1.5 1999/06/11 12:56:42 torkel * *** empty log message *** * * Revision 1.2 1999/04/25 21:00:31 muchomas * Longer run set for timing * * Revision 1.1 1999/04/21 02:32:32 muchomas * Initial revision * * Revision 1.2 1999/04/20 15:59:37 muchomas * Fully documented code * * Revision 1.1 1999/04/19 21:09:48 muchomas * Initial revision * * */ #include #include #include #include #include "WL_header.h" #define HFL 3 #define TIMELOOP 50 #define PX 3 #define PY 3 #define PZ 3 int Px,Py,Pz; /* Computes a multinomial function at a point in space (OUTPUT) USES multinomial exponents from GLOBAL variables Px, Py, Pz!!! r: real-space point return value: value of function */ double multi(struct Dvec r) { return( pow(r.x,Px)+pow(r.y,Py)+pow(r.z,Pz) ); } main() { /* Space for grid specification structure */ struct Gridspec spec[NgridMx]; /* Pointer to special grids (will be allocated below) */ struct Grid *ones,*onesc,*nononesc,*zeros,*ghosts,*nonghosts; /* Size needed for workspace */ struct Ivec szmx={0,0,0}; /* Pointer to "grid"s */ struct Grid *grid,*grid1,*grid2; /* Scale and origin structure for top level */ struct Dvec scale={1.,1.,1.}; struct Dvec org={-6.,-6.,-12.}; /* Work space variables */ double *work,*work_extra; int lwork; /* Timer variables */ struct timeval time1,time2; double rtime,mflop; /* Misc variables */ FILE *fp; double tmp; int i,j,k; printf("\n-----\n"); /* Read grid structure from file */ if ( (fp=fopen("gridspec","r")) == NULL ) { fprintf(stderr,"Can't open file \"gridspec\" for input.\n"); fprintf(stderr,"Exiting.\n"); exit(1); } readgridspec(fp,spec); close(fp); /* Set top level grid spacings to something non-trivial */ spec[0].scale.x=2.; spec[0].scale.y=3.; spec[0].scale.z=4.; printf("Seting (dx,dy,dz)=(%lf,%lf,%lf)...\n\n", spec[0].scale.x,spec[0].scale.y,spec[0].scale.z); /* Make and allocate special grids */ zeros=mkgridnew(spec,NULL); ones=mkgridnew(spec,NULL); onesc=mkgridnew(spec,NULL); nononesc=mkgridnew(spec,NULL); ghosts=mkgridnew(spec,NULL); nonghosts=mkgridnew(spec,NULL); /* Get needed work array size and memory */ getgridsizemx(ones,&szmx); lwork=(szmx.x+3*HFL)*(szmx.y+3*HFL)*(szmx.z+3*HFL); if ( (work=(double *) malloc(lwork*sizeof(double))) == NULL ) { fprintf(stderr,"malloc failed for %d doubles in main (1)\n",lwork); fprintf(stderr,"Exiting.\n"); exit(1); } if ( (work_extra=(double *) malloc(lwork*sizeof(double))) == NULL ) { fprintf(stderr,"malloc failed for %d doubles in main (1)\n",lwork); fprintf(stderr,"Exiting.\n"); exit(1); } for(i=0;i %.0lf MFLOPS.\n", mflop,rtime,mflop/rtime); evalgrid(grid,org,one); /* Time J */ evalgrid(grid,org,rnd); printf("Timing %d iterations... ",TIMELOOP); gettimeofday(&time1,NULL); for (i=0; i %.0lf MFLOPS.\n", mflop,rtime,mflop/rtime); /* Time Idag */ evalgrid(grid,org,rnd); printf("Timing %d iterations... ",TIMELOOP); gettimeofday(&time1,NULL); for (i=0; i %.0lf MFLOPS.\n", mflop,rtime,mflop/rtime); /* Time Jdag */ evalgrid(grid,org,rnd); printf("Timing %d iterations... ",TIMELOOP); gettimeofday(&time1,NULL); for (i=0; i %.0lf MFLOPS.\n\n", mflop,rtime,mflop/rtime); printf("Starting this: \n"); /* Test linearity of J */ evalgrid(grid1,org,rnd); evalgrid(grid2,org,rnd); gridadd(grid,grid1,grid2); J(grid,work,work_extra,lwork); J(grid1,work,work_extra,lwork); J(grid2,work,work_extra,lwork); gridsub(grid,grid,grid1); gridsub(grid,grid,grid2); printf("J is linear: %le %le\n",sqrt(griddot(grid,grid)), sqrt(griddot(grid2,grid2)) ); /* Test linearity of I (being sure to zero ghost points of input!) */ evalgrid(grid1,org,rnd); gridptmult(grid1,nonghosts,grid1); evalgrid(grid2,org,rnd); gridptmult(grid2,nonghosts,grid2); gridadd(grid,grid1,grid2); I(grid,work,work_extra,lwork); I(grid1,work,work_extra,lwork); I(grid2,work,work_extra,lwork); gridsub(grid,grid,grid1); gridsub(grid,grid,grid2); printf("I is linear: %le %le\n\n",sqrt(griddot(grid,grid)), sqrt(griddot(grid2,grid2)) ); /* Test J */ evalgrid(grid,org,rnd); gridptmult(grid1,ones,grid); J(grid,work,work_extra,lwork); printf("J is zero on ghosts: %le\n",sqrt(gridckghosts(grid,0))); I(grid,work,work_extra,lwork); gridsub(grid2,grid,grid1); gridptmult(grid2,grid2,grid2); printf("I is inverse of J: %le\n\n",sqrt(gridsum(grid2,0))); /* Test I */ evalgrid(grid,org,one); gridptmult(grid,nonghosts,grid); gridptmult(grid1,ones,grid); I(grid,work,work_extra,lwork); printf("I matches on ghosts: %le\n",sqrt(gridckghosts(grid,1))); J(grid,work,work_extra,lwork); gridsub(grid2,grid,grid1); gridptmult(grid2,grid2,grid2); printf("J is inverse of I: %le\n\n",sqrt(gridsum(grid2,0))); /* Test Jdag */ evalgrid(grid,org,rnd); gridptmult(grid,nonghosts,grid); gridptmult(grid1,ones,grid); Jdag(grid,work,work_extra,lwork); printf("Jdag matches on ghosts: %le\n",sqrt(gridckghosts(grid,1))); Idag(grid,work,work_extra,lwork); gridsub(grid2,grid,grid1); gridptmult(grid2,grid2,grid2); printf("Idag is inverse of Jdag: %le\n\n",sqrt(gridsum(grid2,0))); /* grid1 in coeff space, grid2 in real space */ evalgrid(grid1,org,rnd); gridptmult(grid1,nonghosts,grid); evalgrid(grid2,org,rnd); /* tmp=1'J(2) */ J(grid2,work,work_extra,lwork); tmp=griddot(grid1,grid2); I(grid2,work,work_extra,lwork); /* tmp-=Jdag(1)'2 */ Jdag(grid1,work,work_extra,lwork); tmp-=griddot(grid1,grid2); printf("Jdag is dag of J: %le %le \n\n",tmp, griddot(grid1,grid2) ); /* Test Idag */ evalgrid(grid,org,rnd); gridptmult(grid1,ones,grid); Idag(grid,work,work_extra,lwork); printf("Idag zero on ghosts: %le\n",sqrt(gridckghosts(grid,0))); Jdag(grid,work,work_extra,lwork); gridsub(grid2,grid,grid1); gridptmult(grid2,grid2,grid2); printf("Jdag is inverse of Idag: %le\n\n",sqrt(gridsum(grid2,0))); /* grid1 in real space, grid2 in coef space */ evalgrid(grid1,org,rnd); evalgrid(grid2,org,rnd); gridptmult(grid2,nonghosts,grid); /* tmp=1'I(2) */ I(grid2,work,work_extra,lwork); tmp=griddot(grid1,grid2); J(grid2,work,work_extra,lwork); /* tmp-=Jdag(1)'2 */ Idag(grid1,work,work_extra,lwork); tmp-=griddot(grid1,grid2); printf("Idag is dag of I: %le\n\n",tmp); tmp=0.; for (Px=0; Px<=PX; Px++) for (Py=0; Py<=PY; Py++) for (Pz=0; Pz<=PZ; Pz++) { evalgrid(grid,org,multi); J(grid,work,work_extra,lwork); gridptmult(grid,grid,nononesc); gridptmult(grid,grid,grid); tmp+=gridsum(grid,0); } printf("Multinomial tests summed up to (%d,%d,%d) [typically 1e-8]: %le\n",PX,PY,PZ,sqrt(tmp)); { Px=0; Py=0; Pz=4; evalgrid(grid,org,multi); J(grid,work,work_extra,lwork); gridptmult(grid,grid,nononesc); gridptmult(grid,grid,grid); printf("Test of (%d,%d,%d): %18.12lf\n\n",Px,Py,Pz,sqrt(gridsum(grid,0))); } printf("-----\n\n"); }