source: pcp/src/density.c@ 774ae8

Last change on this file since 774ae8 was a0bcf1, checked in by Frederik Heber <heber@…>, 17 years ago

-initial commit
-Minimum set of files needed from ESPACK SVN repository
-Switch to three tantamount package parts instead of all relating to pcp (as at some time Ralf's might find inclusion as well)

  • Property mode set to 100644
File size: 61.4 KB
Line 
1/** \file density.c
2 * Density Calculation.
3 *
4 * The basic routines are CalculateOneDensityR() and CalculateOneDensityC(), which do the
5 * level up from wave function coefficients in the current level to real density in the upper
6 * and from density in the current (upper) to complex wave function coefficients.
7 * Initialization of necessary structure such as Density is done in InitDensity(), where in
8 * InitDensityCalculation() the density arrays are allocated, zeroed, and the first density
9 * calculated and stored. The Density is updated after every minimisation step via
10 * UpdateDensityCalculation.
11 * Small routines such as DensityRTransformPos() - performing coefficient permutation before
12 * the Levelup fft - CalculateNativeIntDens() - calculating \a naively the density and
13 * ControlNativeDensity - checking current electronic density against number of electrons -
14 * help in the calculation of these and keeping them valid.
15 * One last important function is ChangePsiAndDensToLevUp(), which performs similarly to
16 * CalculateOneDensityR(), implementing afterwards also CalculateOneDensityC. It basically
17 * calculates the density in the upper level from the coefficients and there retrieves the
18 * coefficients by back transformation, thus doing the LevelUp for the Psis and the Density.
19 *
20 *
21 Project: ParallelCarParrinello
22 \author Jan Hamaekers
23 \date 2000
24
25 File: density.c
26 $Id: density.c,v 1.70 2007-03-30 15:29:18 foo Exp $
27*/
28
29#include <stdlib.h>
30#include <stdio.h>
31#include <stddef.h>
32#include <math.h>
33#include <string.h>
34
35#include"data.h"
36#include"errors.h"
37#include"helpers.h"
38#include"density.h"
39#include"myfft.h"
40#include"mymath.h"
41#include"density.h"
42#include"perturbed.h"
43
44
45/** Marks one array as in use and not to be overwritten.
46 * \param *Dens pointer to Density structure
47 * \param DensityType DensityType
48 * \param re_im 0 - Density#DensityArray, 1 - Density#DensityCArray
49 */
50void LockDensityArray(struct Density *Dens, enum UseType DensityType, enum complex re_im) {
51 enum UseType *marker;
52 if (DensityType >=0 && DensityType < MaxDensityTypes) {
53 if (re_im == real)
54 marker = &Dens->LockArray[DensityType];
55 else
56 marker = &Dens->LockCArray[DensityType];
57 if (*marker == InUse) {
58 fprintf(stderr,"Regarding %i array of type %i (0=real, 1=imag): %i\n",DensityType,re_im, *marker);
59 Error(SomeError,"Array is already locked!");
60 } else {
61 *marker = InUse;
62 //fprintf(stderr,"Locking %i (0=real, 1=imag) array of type %i ... \n",re_im,DensityType);
63 }
64 } else {
65 fprintf(stderr,"LockDensityArray(): ILLEGAL Type %i ... \n",DensityType);
66 }
67}
68
69/** Marks one array as not in use.
70 * \param *Dens pointer to Density structure
71 * \param DensityType DensityType
72 * \param re_im 0 - Density#DensityArray, 1 - Density#DensityCArray
73 */
74void UnLockDensityArray(struct Density *Dens, enum UseType DensityType, enum complex re_im) {
75 enum UseType *marker;
76 if (DensityType >=0 && DensityType < MaxDensityTypes) {
77 if (re_im == real)
78 marker = &Dens->LockArray[DensityType];
79 else
80 marker = &Dens->LockCArray[DensityType];
81 if (*marker == NotInUse) {
82 fprintf(stderr,"Regarding %i array of type %i (0=real, 1=imag): %i\n",DensityType,re_im, *marker);
83 Error(SomeError,"Array was not locked!");
84 } else {
85 *marker = NotInUse;
86 //fprintf(stderr,"UnLocking %i (0=real, 1=imag) array of type %i ... \n",re_im,DensityType);
87 }
88 } else {
89 fprintf(stderr,"LockDensityArray(): ILLEGAL Type %i ... \n",DensityType);
90 }
91}
92
93/** Calculation of naive initial density.
94 * \a *densR is summed up over all points on the grid (divided by RiemannTensor::DensityR if used),
95 * the sum times \a factor is summed up among all processes and divived over the number of points on
96 * the mesh LatticeLevel::MaxN returned.
97 * \param *P Problem at hand, contains Lattice::RiemannTensor
98 * \param *Lev LatticeLevel structure
99 * \param *densR \f$n_i\f$, real density array for every point i on the mesh
100 * \param factor additional factor (such as volume element)
101 * \return \f$\frac{\sum^N_i n_i}{N}\f$
102 */
103double CalculateNativeIntDens(const struct Problem *P, const struct LatticeLevel *Lev, fftw_real *densR, const double factor)
104{
105 int i;
106 double Sum = 0.0, res;
107 fftw_real *RTFactor = NULL;
108 switch (P->Lat.RT.ActualUse) {
109 case inactive:
110 case standby:
111 for (i=0; i < Lev->Dens->LocalSizeR; i++)
112 Sum += densR[i];
113 break;
114 case active:
115 RTFactor = P->Lat.RT.DensityR[RTADetPreRT];
116 for (i=0; i < Lev->Dens->LocalSizeR; i++)
117 Sum += densR[i]/fabs(RTFactor[i]);
118 break;
119 }
120 Sum *= factor;
121 MPI_Allreduce(&Sum , &res, 1, MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_Psi );
122 return(res/Lev->MaxN);
123}
124
125/** Permutation of wave function coefficients before LevelUp FFT.
126 * \f[
127 * N^{up}_z (z + N_z (L_y + N^{up}_y (y + N_y ( L_x + N^{up}_x \cdot x))))
128 * \quad \rightarrow \quad
129 * N^{up}_z ( L_y + N^{up}_y ( L_x + N^{up}_x (z + N_z (y + N_y \cdot x))))
130 * \f]
131 * In the first part each mesh point (x,y,z) is a 2x2x2 cube, whereas in the last
132 * case there is a 2x2x2 alignment of the cubes of all mesh points (x,y,z). (Here
133 * assumed that LevelUp doubles the mesh's finesse)
134 * \param *Lev LatticeLevel, contains LevelPlan::local_nx and LatticeLevel::N
135 * \param *source source real coefficients array
136 * \param *dest destination real coefficients array
137 * \sa CalculateOneDensityR() - used there.
138 */
139void DensityRTransformPos(const struct LatticeLevel *Lev, fftw_real *source, fftw_real *dest)
140{
141 int es = Lev->NUp[2];
142 unsigned int cpyes = sizeof(fftw_real)*es;
143 int nx=Lev->Plan0.plan->local_nx,ny=Lev->N[1],nz=Lev->N[2],Nx=Lev->NUp[0],Ny=Lev->NUp[1];
144 int lx,ly,z,Lx,Ly;
145 for(lx=0; lx < nx; lx++)
146 for(Lx=0; Lx < Nx; Lx++)
147 for(ly=0; ly < ny; ly++)
148 for(Ly=0; Ly < Ny; Ly++)
149 for(z=0; z < nz; z++) {
150 memcpy( &dest[es*(z+nz*(Ly+Ny*(ly+ny*(Lx+Nx*lx))))],
151 &source[es*(Ly+Ny*(Lx+Nx*(z+nz*(ly+ny*lx))))],
152 cpyes);
153 }
154}
155
156/*int GetOtherIndex(const struct fft_plan_3d *plan, const int Level, int Index)
157{
158 int N = Index;
159 int x,yz,Y,Z,YZ,y,z;
160 int Nx = plan->Levplan[Level].nx;
161 int Ny = plan->Levplan[Level].local_ny ;
162 int Nz = plan->Levplan[Level].nz;
163 int Nyz = plan->Levplan[Level].ny*Nz;
164 int NZ = plan->NLSR[2]/2+1;
165 int YY;
166 x = N%Nx;
167 N /= Nx;
168 z = N%Nz;
169 y = N/Nz;
170 Y = (y+plan->myPE*Ny)/plan->Levplan[Level].LevelFactor;
171 YY = (y+plan->myPE*Ny)%plan->Levplan[Level].LevelFactor;
172 Z = z/plan->Levplan[Level].LevelFactor;
173 YZ = Z+NZ*Y;
174 YZ = plan->pw[YZ].Index;
175 Z = (YZ%NZ)*plan->Levplan[Level].LevelFactor+(z)%plan->Levplan[Level].LevelFactor;
176 yz = Z+Nz*(((YZ/NZ)*plan->Levplan[Level].LevelFactor+YY));
177 return(yz+Nyz*x);
178}
179*/
180
181/** Calculates the real density of one wave function orbit.
182 * In order to evaluate densities from the wave function coefficients there is a reoccurring pattern:
183 * First of all, the (finer) cubic grid of coefficients must be built. Therefore we go through all reciprocal
184 * grid vectors G up to LatticeLevel::MaxG (N), through all possible nodes up to LatticeLevel::MaxNUp (8) in the
185 * upper level, multiply each complex coefficient \a source[G] with the pulled out LatticeLevel::PosFactorUp[pos]
186 * and store in the temporal array Density::DensityArray[DensityTypes#TempDensity].
187 * The symmetry condition \f$c_{i,G}^\ast = - c_{i,G}\f$ on the (z=0)-plane up to LatticeLevel::MaxDoubleG
188 * is applied.
189 * Then follows the complex to real fftransformation fft_3d_complex_to_real() and finally a permutation by
190 * calling DensityRTransformPos().\n
191 * The resulting density is stored in Density::DensityCArray[DensityTypes::ActualPsiDensity] if desired. In any
192 * case the return array is \a *destR, each entry multiplied by \a Factor and in RiemannTensor case by an
193 * additional \a RTFactor.
194 * \param *Lat Lattice structure
195 * \param *Lev LatticeLevel structure
196 * \param *Dens Density structure, contains Density::DensityCArray and Density::DensityArray
197 * \param *source complex wave function coefficients
198 * \param *destR where the density is returned
199 * \param Factor returned density is multiplied by this factor (e.g. occupation number)
200 * \param StorePsi Whether the Psi should be stored in Density::DensityCArray[DoubleDensityTypes#ActualPsiDensity] or not
201 */
202void CalculateOneDensityR(const struct Lattice *Lat, const struct LatticeLevel *Lev, const struct Density *Dens, const fftw_complex *source, fftw_real *destR, const double Factor, int StorePsi)
203{
204 int Index,i,pos;
205 struct fft_plan_3d *plan = Lat->plan;
206 fftw_complex *work = (fftw_complex *)Dens->DensityCArray[TempDensity];
207 fftw_complex *tempdestRC = (fftw_complex *)Dens->DensityArray[TempDensity];
208 fftw_complex *posfac, *destpos, *destRCS, *destRCD;
209 fftw_real *RTFactor = NULL;
210 fftw_real *Psic = (fftw_real *)Dens->DensityCArray[ActualPsiDensity];
211 if (Lat->RT.ActualUse == active)
212 RTFactor = Lat->RT.DensityR[RTADetPreRT];
213 SetArrayToDouble0((double *)tempdestRC, Dens->TotalSize*2); // set array to zero
214 // the density in the upper level is created by filling the 2x2x2 block with the coefficient times the position factor
215 for (i=0;i<Lev->MaxG;i++) {
216 Index = Lev->GArray[i].Index;
217 posfac = &Lev->PosFactorUp[Lev->MaxNUp*i]; // jump to the specific 2x2x2 block for the position factor (taken from upper level!)
218 destpos = &tempdestRC[Lev->MaxNUp*Index]; // jump to the speficif 2x2x2 block for the destination values (resorted with Index)
219 for (pos=0; pos < Lev->MaxNUp; pos++) { // complex: destpos = source * postfac
220 destpos[pos].re = source[i].re*posfac[pos].re-source[i].im*posfac[pos].im;
221 destpos[pos].im = source[i].re*posfac[pos].im+source[i].im*posfac[pos].re;
222 }
223 }
224 // symmetry condition is applied to the (z=0)-plane
225 for (i=0; i<Lev->MaxDoubleG; i++) {
226 destRCS = &tempdestRC[Lev->DoubleG[2*i]*Lev->MaxNUp];
227 destRCD = &tempdestRC[Lev->DoubleG[2*i+1]*Lev->MaxNUp];
228 for (pos=0; pos < Lev->MaxNUp; pos++) {
229 //if (isnan(destRCD[pos].re)) fprintf(stderr,"CalculateOneDensityR: destRCD.re NaN!\n");
230 //if (isnan(destRCD[pos].im)) fprintf(stderr,"CalculateOneDensityR: destRCD.im NaN!\n");
231 destRCD[pos].re = destRCS[pos].re;
232 destRCD[pos].im = -destRCS[pos].im;
233 }
234 }
235 fft_3d_complex_to_real(plan, Lev->LevelNo, FFTNFUp, tempdestRC, work);
236 DensityRTransformPos(Lev,(fftw_real*)tempdestRC,destR);
237
238 if (StorePsi)
239 for (i=0; i < Dens->LocalSizeR; i++) {
240 Psic[i] = destR[i]; /* FIXME RT */
241 //if (isnan(Psic[i])) fprintf(stderr,"CalculateOneDensityR: Psic NaN!\n");
242 }
243
244 switch (Lat->RT.ActualUse) {
245 case inactive:
246 case standby:
247 for (i=0; i < Dens->LocalSizeR; i++)
248 destR[i] *= destR[i]*Factor;
249 break;
250 case active:
251 for (i=0; i < Dens->LocalSizeR; i++)
252 destR[i] *= destR[i]*Factor*fabs(RTFactor[i]);
253 break;
254 }
255}
256
257/** Calculates the real density of one wave function orbit with negative symmetry.
258 * In order to evaluate densities from the wave function coefficients there is a reoccurring pattern:
259 * First of all, the (finer) cubic grid of coefficients must be built. Therefore we go through all reciprocal
260 * grid vectors G up to LatticeLevel::MaxG (N), through all possible nodes up to LatticeLevel::MaxNUp (8) in the
261 * upper level, multiply each complex coefficient \a source[G] with the pulled out LatticeLevel::PosFactorUp[pos]
262 * and store in the temporal array Density::DensityArray[DensityTypes#TempDensity].
263 * The symmetry condition \f$c_{i,G}^\ast = - c_{i,G}\f$ on the (z=0)-plane up to LatticeLevel::MaxDoubleG
264 * is applied.
265 * Then follows the complex to real fftransformation fft_3d_complex_to_real() and finally a permutation by
266 * calling DensityRTransformPos().\n
267 * The resulting density is stored in Density::DensityCArray[DensityTypes::ActualPsiDensity] if desired. In any
268 * case the return array is \a *destR, each entry multiplied by \a Factor and in RiemannTensor case by an
269 * additional \a RTFactor.
270 * \param *Lat Lattice structure
271 * \param *Lev LatticeLevel structure
272 * \param *Dens Density structure, contains Density::DensityCArray and Density::DensityArray
273 * \param *source complex wave function coefficients
274 * \param *destR where the density is returned
275 * \param Factor returned density is multiplied by this factor (e.g. occupation number)
276 * \param StorePsi Whether the Psi should be stored in Density::DensityCArray[DoubleDensityTypes#ActualPsiDensity] or not
277 */
278void CalculateOneDensityImR(const struct Lattice *Lat, const struct LatticeLevel *Lev, const struct Density *Dens, fftw_complex *source, fftw_real *destR, const double Factor, int StorePsi)
279{
280 int Index,i,pos;
281 struct fft_plan_3d *plan = Lat->plan;
282 fftw_complex *work = (fftw_complex *)Dens->DensityCArray[TempDensity];
283 fftw_complex *tempdestRC = (fftw_complex *)Dens->DensityArray[TempDensity];
284 fftw_complex *posfac, *destpos, *destRCS, *destRCD;
285 fftw_real *RTFactor = NULL;
286 fftw_real *Psic = (fftw_real *)Dens->DensityCArray[ActualPsiDensity];
287 if (Lat->RT.ActualUse == active)
288 RTFactor = Lat->RT.DensityR[RTADetPreRT];
289 SetArrayToDouble0((double *)tempdestRC, Dens->TotalSize*2); // set array to zero
290 // the density in the upper level is created by filling the 2x2x2 block with the coefficient times the position factor
291 for (i=0;i<Lev->MaxG;i++) {
292 Index = Lev->GArray[i].Index;
293 posfac = &Lev->PosFactorUp[Lev->MaxNUp*i]; // jump to the specific 2x2x2 block for the position factor (taken from upper level!)
294 destpos = &tempdestRC[Lev->MaxNUp*Index]; // jump to the speficif 2x2x2 block for the destination values (resorted with Index)
295 for (pos=0; pos < Lev->MaxNUp; pos++) { // complex: destpos = source * postfac
296 destpos[pos].re = source[i].re*posfac[pos].re-source[i].im*posfac[pos].im;
297 destpos[pos].im = source[i].re*posfac[pos].im+source[i].im*posfac[pos].re;
298 }
299 }
300 // symmetry condition is applied to the (z=0)-plane
301 for (i=0; i<Lev->MaxDoubleG; i++) {
302 destRCS = &tempdestRC[Lev->DoubleG[2*i]*Lev->MaxNUp];
303 destRCD = &tempdestRC[Lev->DoubleG[2*i+1]*Lev->MaxNUp];
304 for (pos=0; pos < Lev->MaxNUp; pos++) {
305 //if (isnan(destRCD[pos].re)) fprintf(stderr,"CalculateOneDensityR: destRCD.re NaN!\n");
306 //if (isnan(destRCD[pos].im)) fprintf(stderr,"CalculateOneDensityR: destRCD.im NaN!\n");
307 destRCD[pos].re = -destRCS[pos].re;
308 destRCD[pos].im = destRCS[pos].im;
309 }
310 }
311 fft_3d_complex_to_real(plan, Lev->LevelNo, FFTNFUp, tempdestRC, work);
312 DensityRTransformPos(Lev,(fftw_real*)tempdestRC,destR);
313
314 if (StorePsi)
315 for (i=0; i < Dens->LocalSizeR; i++) {
316 Psic[i] = destR[i]; /* FIXME RT */
317 //if (isnan(Psic[i])) fprintf(stderr,"CalculateOneDensityR: Psic NaN!\n");
318 }
319
320 switch (Lat->RT.ActualUse) {
321 case inactive:
322 case standby:
323 for (i=0; i < Dens->LocalSizeR; i++)
324 destR[i] *= destR[i]*Factor;
325 break;
326 case active:
327 for (i=0; i < Dens->LocalSizeR; i++)
328 destR[i] *= destR[i]*Factor*fabs(RTFactor[i]);
329 break;
330 }
331}
332
333/** Calculates the complex density for one wave function.
334 * Copies given real coefficients from \a *srcR into \a *destC and performs the real to
335 * complex LevelUp-Transformation onto it, where Density::DensityCArray[TempDensity] is used
336 * as a temporal storage. The \a factor is later used on every density point on the grid.
337 * \param *Lat Lattice structure
338 * \param *Lev LatticeLevel structure
339 * \param *Dens Density structure
340 * \param *srcR one real wave function from which density is produced
341 * \param *destC complex density array to be calculated
342 * \param Factor
343 */
344void CalculateOneDensityC(const struct Lattice *Lat, const struct LatticeLevel *Lev, const struct Density *Dens, const fftw_real *srcR, fftw_complex *destC, const double Factor)
345{
346 int i;
347 struct LatticeLevel *LevUp = &Lat->Lev[Lev->LevelNo-1];
348 struct fft_plan_3d *plan = Lat->plan;
349 fftw_complex *work = (fftw_complex *)Dens->DensityCArray[TempDensity];
350 fftw_real *destCR = (fftw_real *)destC;
351 double factor = Factor/LevUp->MaxN;
352 // copy coefficients into destC
353 memcpy(destCR,srcR,sizeof(fftw_real)*Dens->LocalSizeR);
354 // fftransform
355 fft_3d_real_to_complex(plan, LevUp->LevelNo, FFTNF1, destC, work);
356 // and multiply by given factor
357 for (i=0; i<Dens->LocalSizeC; i++) {
358 destC[i].re *= factor;
359 destC[i].im *= factor;
360 }
361}
362
363/** Initialization of Density calculation.
364 * Set Density::DensityArray's to zero.\n
365 * Now for the standard level LevS for each local Psi calculate the real density times volume times
366 * occupation number (Psis::PsiFactor), build native initial density by adding up occupation numbers,
367 * and sum up DensityTypes::TotalLocalDensity to total DensityTypes::ActualDensity.
368 * The complex density is calculated from this (real) total local array, and depending on the SpinType
369 * results are gathered from each process by summation: real and complex DensityTypes::TotalLocalDensity
370 * and native initial density Psis::NIDensity.\n
371 * For the topmost level CalculateNativeIntDens() is called and the result compared to Psis::NIDensity.
372 * \param *P Problem at hand
373 */
374void InitDensityCalculation(struct Problem *P)
375{
376 int p,d,i, type;
377 struct Lattice *Lat = &P->Lat;
378 struct RunStruct *R = &P->R;
379 struct LatticeLevel *LevS = R->LevS;
380 struct LatticeLevel *Lev0 = R->Lev0;
381 struct LevelPsi *LPsi = LevS->LPsi;
382 struct Density *Dens = Lev0->Dens;
383 struct Psis *Psi = &Lat->Psi;
384 double factorDR = R->FactorDensityR;
385 double factorDC = R->FactorDensityC;
386 double NIDensity=0., NIDensityUp=0., NIDensityDown=0.;
387 fftw_real *Temp1R, *Temp2R, *Temp3R;
388 fftw_complex *Temp1C, *Temp2C, *Temp3C;
389 MPI_Status status;
390
391 if (P->Call.out[NormalOut]) fprintf(stderr, "(%i)InitDensityCalculation\n", P->Par.me);
392 // set arrays to zero if allocated
393 for (d=0; d < MaxInitDensityTypes; d++) {
394 if (Dens->DensityCArray[d] != NULL)
395 SetArrayToDouble0((double *)Dens->DensityCArray[d], Dens->TotalSize*2);
396 if (Dens->DensityArray[d] != NULL)
397 SetArrayToDouble0((double *)Dens->DensityArray[d], Dens->TotalSize*2);
398 }
399
400 // for each local Psi calculate the real density times volume times occupation number (PsiFactor), build naive initial density by adding up occupation number and sum up local density to total one
401 for (p=Psi->LocalNo-1; p >= 0; p--) {
402 //if (isnan(Dens->DensityArray[ActualDensity][0])) { fprintf(stderr,"(%i) WARNING in InitDensityCalculation(): ActualDensity_%i[%i] = NaN!\n", P->Par.me, p, 0); Error(SomeError, "NaN-Fehler!"); }
403 //if (P->Call.out[StepLeaderOut]) fprintf(stderr,"NIDensity: PsiType[%d] = %d\n",p, Psi->LocalPsiStatus[p].PsiType);
404 if (R->CurrentMin == Psi->LocalPsiStatus[p].PsiType) NIDensity += Psi->LocalPsiStatus[p].PsiFactor;
405 if (R->CurrentMin == Psi->LocalPsiStatus[p].PsiType || Psi->LocalPsiStatus[p].PsiType == Occupied) {
406 CalculateOneDensityR(Lat, LevS, Dens, LPsi->LocalPsi[p], Dens->DensityArray[ActualDensity], factorDR*Psi->LocalPsiStatus[p].PsiFactor, (p==Psi->TypeStartIndex[R->CurrentMin]));
407 if (Psi->LocalPsiStatus[p].PsiType == Occupied)
408 Temp1R = Dens->DensityArray[TotalLocalDensity];
409 else
410 Temp1R = Dens->DensityArray[GapLocalDensity];
411 Temp2R = Dens->DensityArray[ActualDensity];
412 for (i=0; i < Dens->LocalSizeR; i++)
413 Temp1R[i] += Temp2R[i];
414 }
415 }
416
417 CalculateOneDensityR(Lat, LevS, Dens, LPsi->LocalPsi[Psi->TypeStartIndex[R->CurrentMin]], Dens->DensityArray[ActualDensity], factorDR*Psi->LocalPsiStatus[Psi->TypeStartIndex[R->CurrentMin]].PsiFactor, (Psi->TypeStartIndex[R->CurrentMin]));
418 /* CalculateOneDensityC(Lat, LevS, Dens, Dens->DensityArray[ActualDensity], Dens->DensityCArray[ActualDensity], factorDC); */
419 // calculate complex density from the (real) total local array
420 CalculateOneDensityC(Lat, LevS, Dens, Dens->DensityArray[TotalLocalDensity], Dens->DensityCArray[TotalLocalDensity], factorDC);
421 CalculateOneDensityC(Lat, LevS, Dens, Dens->DensityArray[GapLocalDensity], Dens->DensityCArray[GapLocalDensity], factorDC);
422 // depending on SpinType gather results: real and complex DensityTypes::TotalLocalDensity and native initial density
423 switch (Psi->PsiST) {
424 case SpinDouble:
425 //fprintf(stderr,"(%i) InitDensity SpinDouble\n",P->Par.me);
426 if (R->CurrentMin == Occupied) { // occupied states
427 MPI_Allreduce(Dens->DensityArray[TotalLocalDensity] ,Dens->DensityArray[TotalDensity] ,Dens->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
428 MPI_Allreduce(Dens->DensityCArray[TotalLocalDensity] ,Dens->DensityCArray[TotalDensity] ,Dens->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
429 } else {// unoccupied
430 MPI_Allreduce(Dens->DensityArray[GapLocalDensity] ,Dens->DensityArray[GapDensity] ,Dens->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
431 MPI_Allreduce(Dens->DensityCArray[GapLocalDensity] ,Dens->DensityCArray[GapDensity] ,Dens->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
432 }
433
434 // naive density
435 MPI_Allreduce(&NIDensity ,&Psi->NIDensity[R->CurrentMin] , 1 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
436 break;
437 case SpinUp:
438 //fprintf(stderr,"(%i) InitDensity SpinUp\n",P->Par.me);
439 if (R->CurrentMin == Occupied) { // occupied states
440 MPI_Allreduce(Dens->DensityArray[TotalLocalDensity] ,Dens->DensityArray[TotalUpDensity] ,Dens->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
441 MPI_Allreduce(Dens->DensityCArray[TotalLocalDensity] ,Dens->DensityCArray[TotalUpDensity] ,Dens->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
442 // exchange up and down densities
443 MPI_Sendrecv( Dens->DensityCArray[TotalUpDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag1,
444 Dens->DensityCArray[TotalDownDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag2,
445 P->Par.comm_STInter, &status );
446 MPI_Sendrecv( Dens->DensityArray[TotalUpDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag3,
447 Dens->DensityArray[TotalDownDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag4,
448 P->Par.comm_STInter, &status );
449 Temp1R = Dens->DensityArray[TotalDensity];
450 Temp2R = Dens->DensityArray[TotalUpDensity];
451 Temp3R = Dens->DensityArray[TotalDownDensity];
452 Temp1C = Dens->DensityCArray[TotalDensity];
453 Temp2C = Dens->DensityCArray[TotalUpDensity];
454 Temp3C = Dens->DensityCArray[TotalDownDensity];
455 } else { // unoccupied or perturbed states
456 MPI_Allreduce(Dens->DensityArray[GapLocalDensity] ,Dens->DensityArray[GapUpDensity] ,Dens->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
457 MPI_Allreduce(Dens->DensityCArray[GapLocalDensity] ,Dens->DensityCArray[GapUpDensity] ,Dens->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
458 // exchange up and down densities
459 MPI_Sendrecv( Dens->DensityCArray[GapUpDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag7,
460 Dens->DensityCArray[GapDownDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag8,
461 P->Par.comm_STInter, &status );
462 MPI_Sendrecv( Dens->DensityArray[GapUpDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag9,
463 Dens->DensityArray[GapDownDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag0,
464 P->Par.comm_STInter, &status );
465 Temp1R = Dens->DensityArray[GapDensity];
466 Temp2R = Dens->DensityArray[GapUpDensity];
467 Temp3R = Dens->DensityArray[GapDownDensity];
468 Temp1C = Dens->DensityCArray[GapDensity];
469 Temp2C = Dens->DensityCArray[GapUpDensity];
470 Temp3C = Dens->DensityCArray[GapDownDensity];
471 }
472
473 for (i=0; i < Dens->LocalSizeR; i++)
474 Temp1R[i] = Temp2R[i]+Temp3R[i];
475 for (i=0; i < Dens->LocalSizeC; i++) {
476 Temp1C[i].re = Temp2C[i].re+Temp3C[i].re;
477 Temp1C[i].im = Temp2C[i].im+Temp3C[i].im;
478 }
479
480 // we are up, so have naive spinup density
481 MPI_Allreduce(&NIDensity ,&Psi->NIDensityUp[R->CurrentMin] ,1 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
482 MPI_Sendrecv( Psi->NIDensityUp, Extra, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag5,
483 Psi->NIDensityDown, Extra, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag6,
484 P->Par.comm_STInter, &status );
485 for (type=Occupied;type<Extra;type++)
486 Psi->NIDensity[type] = Psi->NIDensityUp[type] + Psi->NIDensityDown[type];
487 break;
488 case SpinDown:
489 //fprintf(stderr,"(%i) InitDensity SpinDown\n",P->Par.me);
490 if (R->CurrentMin == Occupied) { // occupied states
491 MPI_Allreduce(Dens->DensityArray[TotalLocalDensity] ,Dens->DensityArray[TotalDownDensity] ,Dens->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
492 MPI_Allreduce(Dens->DensityCArray[TotalLocalDensity] ,Dens->DensityCArray[TotalDownDensity] ,Dens->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
493 // exchange up and down densities
494 MPI_Sendrecv( Dens->DensityCArray[TotalDownDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag2,
495 Dens->DensityCArray[TotalUpDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag1,
496 P->Par.comm_STInter, &status );
497 MPI_Sendrecv( Dens->DensityArray[TotalDownDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag4,
498 Dens->DensityArray[TotalUpDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag3,
499 P->Par.comm_STInter, &status );
500
501 Temp1R = Dens->DensityArray[TotalDensity];
502 Temp2R = Dens->DensityArray[TotalUpDensity];
503 Temp3R = Dens->DensityArray[TotalDownDensity];
504 Temp1C = Dens->DensityCArray[TotalDensity];
505 Temp2C = Dens->DensityCArray[TotalUpDensity];
506 Temp3C = Dens->DensityCArray[TotalDownDensity];
507 } else { // unoccupied or perturbed states
508 MPI_Allreduce(Dens->DensityArray[GapLocalDensity] ,Dens->DensityArray[GapDownDensity] ,Dens->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
509 MPI_Allreduce(Dens->DensityCArray[GapLocalDensity] ,Dens->DensityCArray[GapDownDensity] ,Dens->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
510 // exchange up and down densities
511 MPI_Sendrecv( Dens->DensityCArray[GapDownDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag8,
512 Dens->DensityCArray[GapUpDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag7,
513 P->Par.comm_STInter, &status );
514 MPI_Sendrecv( Dens->DensityArray[GapDownDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag0,
515 Dens->DensityArray[GapUpDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag9,
516 P->Par.comm_STInter, &status );
517
518 Temp1R = Dens->DensityArray[GapDensity];
519 Temp2R = Dens->DensityArray[GapUpDensity];
520 Temp3R = Dens->DensityArray[GapDownDensity];
521 Temp1C = Dens->DensityCArray[GapDensity];
522 Temp2C = Dens->DensityCArray[GapUpDensity];
523 Temp3C = Dens->DensityCArray[GapDownDensity];
524 }
525
526 for (i=0; i < Dens->LocalSizeR; i++)
527 Temp1R[i] = Temp2R[i]+Temp3R[i];
528 for (i=0; i < Dens->LocalSizeC; i++) {
529 Temp1C[i].re = Temp2C[i].re+Temp3C[i].re;
530 Temp1C[i].im = Temp2C[i].im+Temp3C[i].im;
531 }
532
533 // we are up, so have naive spinup density
534 MPI_Allreduce(&NIDensity ,&Psi->NIDensityDown[R->CurrentMin] , 1, MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
535
536 MPI_Sendrecv( Psi->NIDensityDown, Extra, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag6,
537 Psi->NIDensityUp, Extra, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag5,
538 P->Par.comm_STInter, &status );
539 for (type=Occupied;type<Extra;type++)
540 Psi->NIDensity[type] = Psi->NIDensityUp[type] + Psi->NIDensityDown[type];
541 break;
542 }
543 switch (R->CurrentMin) {
544 case Occupied:
545 NIDensity = CalculateNativeIntDens(P, Lev0, Dens->DensityArray[TotalDensity], 1./factorDR);
546 if (Psi->PsiST != SpinDouble) {
547 NIDensityUp = CalculateNativeIntDens(P, Lev0, Dens->DensityArray[TotalUpDensity], 1./factorDR);
548 NIDensityDown = CalculateNativeIntDens(P, Lev0, Dens->DensityArray[TotalDownDensity], 1./factorDR);
549 }
550 break;
551 default:
552 case UnOccupied:
553 NIDensity = CalculateNativeIntDens(P, Lev0, Dens->DensityArray[GapDensity], 1./factorDR);
554 if (Psi->PsiST != SpinDouble) {
555 NIDensityUp = CalculateNativeIntDens(P, Lev0, Dens->DensityArray[GapUpDensity], 1./factorDR);
556 NIDensityDown = CalculateNativeIntDens(P, Lev0, Dens->DensityArray[GapDownDensity], 1./factorDR);
557 }
558 break;
559 }
560 if (P->Call.out[LeaderOut] && (P->Par.me == 0)) {
561 if (fabs(NIDensity - Psi->NIDensity[R->CurrentMin]) >= MYEPSILON) {
562 fprintf(stderr, "NativeDensity(L(%i)[%i]) = %g != %g eps (%g >= %g)\n",R->LevSNo,R->CurrentMin,NIDensity,Psi->NIDensity[R->CurrentMin],fabs(NIDensity - Psi->NIDensity[R->CurrentMin]),MYEPSILON);
563 } else {
564 fprintf(stderr, "NativeDensity(L(%i)[%i]) = %g Ok !\n",R->LevSNo,R->CurrentMin,NIDensity);
565 }
566 if (Psi->PsiST != SpinDouble) {
567 if (fabs(NIDensityUp - Psi->NIDensityUp[R->CurrentMin]) >= MYEPSILON) {
568 fprintf(stderr, "NativeDensityUp(L(%i)[%i]) = %g != %g eps (%g >= %g)\n",R->LevSNo,R->CurrentMin,NIDensityUp,Psi->NIDensityUp[R->CurrentMin],fabs(NIDensityUp - Psi->NIDensityUp[R->CurrentMin]),MYEPSILON);
569 } else {
570 fprintf(stderr, "NativeDensityUp(L(%i)[%i]) = %g Ok !\n",R->LevSNo,R->CurrentMin,NIDensityUp);
571 }
572 if (fabs(NIDensityDown - Psi->NIDensityDown[R->CurrentMin]) >= MYEPSILON) {
573 fprintf(stderr, "NativeDensityDown(L(%i)[%i]) = %g != %g eps (%g >= %g)\n",R->LevSNo,R->CurrentMin,NIDensityDown,Psi->NIDensityDown[R->CurrentMin],fabs(NIDensityDown - Psi->NIDensityDown[R->CurrentMin]),MYEPSILON);
574 } else {
575 fprintf(stderr, "NativeDensityDown(L(%i)[%i]) = %g Ok !\n",R->LevSNo,R->CurrentMin,NIDensityDown);
576 }
577 }
578 }
579}
580
581/** Recalculate real and complex density after the minimisation of a wave function.
582 * In Density::DensityArray DensityTypes#ActualDensity is subtracted from DensityTypes#TotalLocalDensity,
583 * recalculated by CalculateOneDensityR() for the last minimised Psi and the new value re-added.\n
584 * Afterwards, CalculateOneDensityR() for current minimised Psi is called and stored
585 * in Density::Types#ActualDensity.\n
586 * And CalculateOneDensityC() called to evaluate
587 * Density::DensityCArray[DensityTypes#TotalLocalDensity].\n
588 * Finally, Density::DensityArray and Density::DensityCArray are summed up among the processes
589 * into DensityTypes#TotalDensity.
590 *
591 * \param *P Problem at hand
592 * \sa InitDensityCalculation() - very similar procedure.
593 * \note ActualDensity is expected to be the old one before minimisation took place, as it is subtracted,
594 * the density recalculated (for the newly minimsed wave function) and added again.
595 */
596void UpdateDensityCalculation(struct Problem *P)
597{
598 int i;
599 struct Lattice *Lat = &P->Lat;
600 struct RunStruct *R = &P->R;
601 struct LatticeLevel *LevS = R->LevS;
602 struct LatticeLevel *Lev0 = R->Lev0;
603 struct LevelPsi *LPsi = LevS->LPsi;
604 struct Density *Dens = Lev0->Dens;
605 struct Psis *Psi = &Lat->Psi;
606 double factorDR = R->FactorDensityR;
607 double factorDC = R->FactorDensityC;
608 const int p = R->ActualLocalPsiNo;
609 const int p_old = R->OldActualLocalPsiNo;
610 fftw_real *Temp1R, *Temp2R, *Temp3R;
611 fftw_complex *Temp1C, *Temp2C, *Temp3C;
612 MPI_Status status;
613
614 // subtract actual density of last minimised Psi from total
615 if (R->CurrentMin == Psi->LocalPsiStatus[p_old].PsiType || Psi->LocalPsiStatus[p_old].PsiType == Occupied) {
616 if (Psi->LocalPsiStatus[p_old].PsiType == Occupied)
617 Temp1R = Dens->DensityArray[TotalLocalDensity];
618 else
619 Temp1R = Dens->DensityArray[GapLocalDensity];
620 Temp2R = Dens->DensityArray[ActualDensity];
621 for (i=0; i < Dens->LocalSizeR; i++)
622 Temp1R[i] -= Temp2R[i];
623 }
624
625 //SetArrayToDouble0((double *)Dens->DensityArray[ActualDensity], Dens->TotalSize*2); // zero actual density (of the current wave function)
626 // calculate density of last minimised Psi (but only store if same as current one)
627 CalculateOneDensityR(Lat, LevS, Dens, LPsi->LocalPsi[p_old], Dens->DensityArray[ActualDensity], factorDR*Psi->LocalPsiStatus[p_old].PsiFactor, (p == p_old));
628 //if (isnan(Dens->DensityArray[ActualDensity][0])) { fprintf(stderr,"(%i) WARNING in UpdateDensityCalculation(): ActualDensity_%i[%i] = NaN!\n", P->Par.me, p_old, 0); Error(SomeError, "NaN-Fehler!"); }
629
630 // calculate actual density for current minimised Psi and add up again
631 if (R->CurrentMin == Psi->LocalPsiStatus[p_old].PsiType || Psi->LocalPsiStatus[p_old].PsiType == Occupied) {
632 if (Psi->LocalPsiStatus[p_old].PsiType == Occupied)
633 Temp1R = Dens->DensityArray[TotalLocalDensity];
634 else
635 Temp1R = Dens->DensityArray[GapLocalDensity];
636 Temp2R = Dens->DensityArray[ActualDensity];
637 for (i=0; i < Dens->LocalSizeR; i++)
638 Temp1R[i] += Temp2R[i];
639 }
640
641 if (p != p_old) { // recalc actual density if step to next wave function was made
642 SetArrayToDouble0((double *)Dens->DensityArray[ActualDensity], Dens->TotalSize*2); // set to zero
643 CalculateOneDensityR(Lat, LevS, Dens, LPsi->LocalPsi[p], Dens->DensityArray[ActualDensity], factorDR*Psi->LocalPsiStatus[p].PsiFactor, 1);
644 }
645
646 // calculate complex density from the (real) total local array
647 CalculateOneDensityC(Lat, LevS, Dens, Dens->DensityArray[TotalLocalDensity], Dens->DensityCArray[TotalLocalDensity], factorDC);
648 CalculateOneDensityC(Lat, LevS, Dens, Dens->DensityArray[GapLocalDensity], Dens->DensityCArray[GapLocalDensity], factorDC);
649 // depending on SpinType gather results: real and complex DensityTypes::TotalLocalDensity and native initial density
650 switch (Psi->PsiST) {
651 case SpinDouble:
652 //fprintf(stderr,"(%i) InitDensity SpinDouble\n",P->Par.me);
653 if (Psi->LocalPsiStatus[p_old].PsiType == Occupied) { // occupied states
654 MPI_Allreduce(Dens->DensityArray[TotalLocalDensity] ,Dens->DensityArray[TotalDensity] ,Dens->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
655 MPI_Allreduce(Dens->DensityCArray[TotalLocalDensity] ,Dens->DensityCArray[TotalDensity] ,Dens->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
656 } else { // unoccupied or perturbed
657 MPI_Allreduce(Dens->DensityArray[GapLocalDensity] ,Dens->DensityArray[GapDensity] ,Dens->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
658 MPI_Allreduce(Dens->DensityCArray[GapLocalDensity] ,Dens->DensityCArray[GapDensity] ,Dens->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
659 }
660 break;
661 case SpinUp:
662 //fprintf(stderr,"(%i) InitDensity SpinUp\n",P->Par.me);
663 if (Psi->LocalPsiStatus[p_old].PsiType == Occupied) { // occupied states
664 MPI_Allreduce(Dens->DensityArray[TotalLocalDensity] ,Dens->DensityArray[TotalUpDensity] ,Dens->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
665 MPI_Allreduce(Dens->DensityCArray[TotalLocalDensity] ,Dens->DensityCArray[TotalUpDensity] ,Dens->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
666 // exchange up and down densities
667 MPI_Sendrecv( Dens->DensityCArray[TotalUpDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag1,
668 Dens->DensityCArray[TotalDownDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag2,
669 P->Par.comm_STInter, &status );
670 MPI_Sendrecv( Dens->DensityArray[TotalUpDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag3,
671 Dens->DensityArray[TotalDownDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag4,
672 P->Par.comm_STInter, &status );
673 Temp1R = Dens->DensityArray[TotalDensity];
674 Temp2R = Dens->DensityArray[TotalUpDensity];
675 Temp3R = Dens->DensityArray[TotalDownDensity];
676 Temp1C = Dens->DensityCArray[TotalDensity];
677 Temp2C = Dens->DensityCArray[TotalUpDensity];
678 Temp3C = Dens->DensityCArray[TotalDownDensity];
679 } else { // unoccupied or perturbed
680 MPI_Allreduce(Dens->DensityArray[GapLocalDensity] ,Dens->DensityArray[GapUpDensity] ,Dens->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
681 MPI_Allreduce(Dens->DensityCArray[GapLocalDensity] ,Dens->DensityCArray[GapUpDensity] ,Dens->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
682 // exchange up and down densities
683 MPI_Sendrecv( Dens->DensityCArray[GapUpDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag7,
684 Dens->DensityCArray[GapDownDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag8,
685 P->Par.comm_STInter, &status );
686 MPI_Sendrecv( Dens->DensityArray[GapUpDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag9,
687 Dens->DensityArray[GapDownDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag0,
688 P->Par.comm_STInter, &status );
689 Temp1R = Dens->DensityArray[GapDensity];
690 Temp2R = Dens->DensityArray[GapUpDensity];
691 Temp3R = Dens->DensityArray[GapDownDensity];
692 Temp1C = Dens->DensityCArray[GapDensity];
693 Temp2C = Dens->DensityCArray[GapUpDensity];
694 Temp3C = Dens->DensityCArray[GapDownDensity];
695 }
696
697 for (i=0; i < Dens->LocalSizeR; i++)
698 Temp1R[i] = Temp2R[i]+Temp3R[i];
699 for (i=0; i < Dens->LocalSizeC; i++) {
700 Temp1C[i].re = Temp2C[i].re+Temp3C[i].re;
701 Temp1C[i].im = Temp2C[i].im+Temp3C[i].im;
702 }
703 break;
704 case SpinDown:
705 //fprintf(stderr,"(%i) InitDensity SpinDown\n",P->Par.me);
706 if (Psi->LocalPsiStatus[p_old].PsiType == Occupied) { // occupied states
707 MPI_Allreduce(Dens->DensityArray[TotalLocalDensity] ,Dens->DensityArray[TotalDownDensity] ,Dens->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
708 MPI_Allreduce(Dens->DensityCArray[TotalLocalDensity] ,Dens->DensityCArray[TotalDownDensity] ,Dens->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
709 // exchange up and down densities
710 MPI_Sendrecv( Dens->DensityCArray[TotalDownDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag2,
711 Dens->DensityCArray[TotalUpDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag1,
712 P->Par.comm_STInter, &status );
713 MPI_Sendrecv( Dens->DensityArray[TotalDownDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag4,
714 Dens->DensityArray[TotalUpDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag3,
715 P->Par.comm_STInter, &status );
716 Temp1R = Dens->DensityArray[TotalDensity];
717 Temp2R = Dens->DensityArray[TotalUpDensity];
718 Temp3R = Dens->DensityArray[TotalDownDensity];
719 Temp1C = Dens->DensityCArray[TotalDensity];
720 Temp2C = Dens->DensityCArray[TotalUpDensity];
721 Temp3C = Dens->DensityCArray[TotalDownDensity];
722 } else { // unoccupied or perturbed
723 MPI_Allreduce(Dens->DensityArray[GapLocalDensity] ,Dens->DensityArray[GapDownDensity] ,Dens->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
724 MPI_Allreduce(Dens->DensityCArray[GapLocalDensity] ,Dens->DensityCArray[GapDownDensity] ,Dens->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
725 // exchange up and down densities
726 MPI_Sendrecv( Dens->DensityCArray[GapDownDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag8,
727 Dens->DensityCArray[GapUpDensity], Dens->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag7,
728 P->Par.comm_STInter, &status );
729 MPI_Sendrecv( Dens->DensityArray[GapDownDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag0,
730 Dens->DensityArray[GapUpDensity], Dens->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag9,
731 P->Par.comm_STInter, &status );
732 Temp1R = Dens->DensityArray[GapDensity];
733 Temp2R = Dens->DensityArray[GapUpDensity];
734 Temp3R = Dens->DensityArray[GapDownDensity];
735 Temp1C = Dens->DensityCArray[GapDensity];
736 Temp2C = Dens->DensityCArray[GapUpDensity];
737 Temp3C = Dens->DensityCArray[GapDownDensity];
738 }
739
740 for (i=0; i < Dens->LocalSizeR; i++)
741 Temp1R[i] = Temp2R[i]+Temp3R[i];
742 for (i=0; i < Dens->LocalSizeC; i++) {
743 Temp1C[i].re = Temp2C[i].re+Temp3C[i].re;
744 Temp1C[i].im = Temp2C[i].im+Temp3C[i].im;
745 }
746 break;
747 }
748 //if (isnan(c_re(Dens->DensityCArray[TotalDensity][0]))) { fprintf(stderr,"(%i) WARNING in UpdateDensityCalculation(): TotalDensity[%i] = NaN!\n", P->Par.me, 0); Error(SomeError, "NaN-Fehler!"); }
749 //if (isnan(c_re(Dens->DensityCArray[GapDensity][0]))) { fprintf(stderr,"(%i) WARNING in UpdateDensityCalculation(): GapDensity[%i] = NaN!\n", P->Par.me, 0); Error(SomeError, "NaN-Fehler!"); }
750}
751
752/** Prepares wave functions and densities for the LevelUp.
753 * Density::DensityArray's of all DensityTypes of the new level are set to zero. The density is
754 * calculated in the usual manner - see CalculateOneDensityR() - from the wave functions for the
755 * upper level. Then we have the real density in the upper level and by back-transformation
756 * via fft_3d_real_to_complex() we gain the wave function coefficient on the finer mesh.\n
757 * Finally, the new ActualDensity is calculated, summed up for all local coefficients and
758 * gathered afterwards from all processes - for the various spin cases - into the
759 * DensityTypes#TotalDensity.
760 * \param *P Problem at hand
761 */
762void ChangePsiAndDensToLevUp(struct Problem *P)
763{
764 struct RunStruct *R = &P->R;
765 struct Lattice *Lat = &P->Lat;
766 struct LatticeLevel *Lev0 = R->Lev0;
767 struct LatticeLevel *LevS = R->LevS;
768 struct Density *Dens = Lev0->Dens;
769 struct LatticeLevel *LevUp = &Lat->Lev[Lev0->LevelNo-1];
770 struct Density *DensUp = LevUp->Dens;
771 struct Psis *Psi = &Lat->Psi;
772 int Index,i,pos;
773 struct fft_plan_3d *plan = Lat->plan;
774 fftw_complex *work = (fftw_complex *)Dens->DensityCArray[TempDensity];
775 fftw_complex *tempdestRC = (fftw_complex *)Dens->DensityArray[TempDensity];
776 fftw_complex *posfac, *destpos, *destRCS, *destRCD;
777 fftw_complex *source, *source0;
778 double factorC = 1./Lev0->MaxN;
779 double factorDC = R->FactorDensityC;
780 double factorDR = R->FactorDensityR;
781 int p,g,d;
782 MPI_Status status;
783 fftw_real *Temp1R, *Temp2R, *Temp3R, *Temp4R, *Temp5R, *Temp6R;
784 fftw_complex *Temp1C, *Temp2C, *Temp3C, *Temp4C, *Temp5C, *Temp6C;
785
786 // set density arrays of the new level for all types to zero
787 for (d=0; d < (R->DoPerturbation ? MaxDensityTypes : MaxInitDensityTypes); d++) {
788 if (DensUp->DensityCArray[d] != NULL)
789 SetArrayToDouble0((double *)DensUp->DensityCArray[d], Dens->TotalSize*2);
790 if (DensUp->DensityArray[d] != NULL)
791 SetArrayToDouble0((double *)DensUp->DensityArray[d], Dens->TotalSize*2);
792 }
793 // for all local Psis do the usual transformation (completing coefficients for all grid vectors, fft, permutation)
794 for (p=Psi->LocalNo-1; p >= 0; p--) {
795 source = LevS->LPsi->LocalPsi[p];
796 source0 = Lev0->LPsi->LocalPsi[p];
797 SetArrayToDouble0((double *)tempdestRC, Dens->TotalSize*2);
798 for (i=0;i<LevS->MaxG;i++) {
799 Index = LevS->GArray[i].Index;
800 posfac = &LevS->PosFactorUp[LevS->MaxNUp*i];
801 destpos = &tempdestRC[LevS->MaxNUp*Index];
802 //if (isnan(source[i].re)) { fprintf(stderr,"(%i) WARNING in ChangePsiAndDensToLevUp(): source_%i[%i] = NaN!\n", P->Par.me, p, i); Error(SomeError, "NaN-Fehler!"); }
803 for (pos=0; pos < LevS->MaxNUp; pos++) {
804 destpos[pos].re = source[i].re*posfac[pos].re-source[i].im*posfac[pos].im;
805 destpos[pos].im = source[i].re*posfac[pos].im+source[i].im*posfac[pos].re;
806 }
807 }
808 for (i=0; i<LevS->MaxDoubleG; i++) {
809 destRCS = &tempdestRC[LevS->DoubleG[2*i]*LevS->MaxNUp];
810 destRCD = &tempdestRC[LevS->DoubleG[2*i+1]*LevS->MaxNUp];
811 for (pos=0; pos < LevS->MaxNUp; pos++) {
812 destRCD[pos].re = destRCS[pos].re;
813 destRCD[pos].im = -destRCS[pos].im;
814 }
815 }
816 fft_3d_complex_to_real(plan, LevS->LevelNo, FFTNFUp, tempdestRC, work);
817 DensityRTransformPos(LevS,(fftw_real*)tempdestRC,(fftw_real *)Dens->DensityCArray[ActualPsiDensity]);
818 // now we have density in the upper level, fft back to complex and store it as wave function coefficients
819 fft_3d_real_to_complex(plan, Lev0->LevelNo, FFTNF1, Dens->DensityCArray[ActualPsiDensity], work);
820 for (g=0; g < Lev0->MaxG; g++) {
821 Index = Lev0->GArray[g].Index;
822 source0[g].re = Dens->DensityCArray[ActualPsiDensity][Index].re*factorC;
823 source0[g].im = Dens->DensityCArray[ActualPsiDensity][Index].im*factorC;
824 //if (isnan(source0[g].re)) { fprintf(stderr,"(%i) WARNING in ChangePsiAndDensToLevUp(): source0_%i[%i] = NaN!\n", P->Par.me, p, g); Error(SomeError, "NaN-Fehler!"); }
825 }
826 if (Lev0->GArray[0].GSq == 0.0)
827 source0[g].im = 0.0;
828 // calculate real actual density in the new level and sum all up into TotalLocalDensity
829 CalculateOneDensityR(Lat, Lev0, DensUp, source0, DensUp->DensityArray[ActualDensity], factorDR*Psi->LocalPsiStatus[p].PsiFactor, 0);
830 if (R->CurrentMin == Psi->LocalPsiStatus[p].PsiType || Psi->LocalPsiStatus[p].PsiType == Occupied) {
831 if (Psi->LocalPsiStatus[p].PsiType == Occupied)
832 Temp1R = DensUp->DensityArray[TotalLocalDensity];
833 else
834 Temp1R = DensUp->DensityArray[GapLocalDensity];
835 Temp2R = DensUp->DensityArray[ActualDensity];
836 for (i=0; i < DensUp->LocalSizeR; i++)
837 Temp1R[i] += Temp2R[i];
838 }
839 }
840 /*if (R->CurrentMin > UnOccupied) // taken out as it makes no sense as Dens->PertMixed is updated not DensUp->... !
841 CalculatePertMixedDensity(P); // updates DensityArray[PertMixedDensity] and changes ActualDensity
842 */
843 source0 = Lev0->LPsi->LocalPsi[R->ActualLocalPsiNo];
844 CalculateOneDensityR(Lat, Lev0, DensUp, source0, DensUp->DensityArray[ActualDensity], factorDR*Psi->LocalPsiStatus[R->ActualLocalPsiNo].PsiFactor, 1);
845
846 CalculateOneDensityC(Lat, Lev0, DensUp, DensUp->DensityArray[TotalLocalDensity], DensUp->DensityCArray[TotalLocalDensity], factorDC);
847 CalculateOneDensityC(Lat, Lev0, DensUp, DensUp->DensityArray[GapLocalDensity], DensUp->DensityCArray[GapLocalDensity], factorDC);
848 // gather results from all processes for the various spin cases
849 switch (Psi->PsiST) {
850 case SpinDouble:
851 // occupied states
852 MPI_Allreduce(DensUp->DensityArray[TotalLocalDensity] ,DensUp->DensityArray[TotalDensity] ,DensUp->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
853 MPI_Allreduce(DensUp->DensityCArray[TotalLocalDensity] ,DensUp->DensityCArray[TotalDensity] ,DensUp->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
854 // unoccupied
855 MPI_Allreduce(DensUp->DensityArray[GapLocalDensity] ,DensUp->DensityArray[GapDensity] ,DensUp->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
856 MPI_Allreduce(DensUp->DensityCArray[GapLocalDensity] ,DensUp->DensityCArray[GapDensity] ,DensUp->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
857 break;
858 case SpinUp:
859 //fprintf(stderr,"(%i) InitDensity SpinUp\n",P->Par.me);
860 // occupied states
861 MPI_Allreduce(DensUp->DensityArray[TotalLocalDensity] ,DensUp->DensityArray[TotalUpDensity] ,DensUp->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
862 MPI_Allreduce(DensUp->DensityCArray[TotalLocalDensity] ,DensUp->DensityCArray[TotalUpDensity] ,DensUp->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
863 // unoccupied or perturbed states
864 MPI_Allreduce(DensUp->DensityArray[GapLocalDensity] ,DensUp->DensityArray[GapUpDensity] ,DensUp->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
865 MPI_Allreduce(DensUp->DensityCArray[GapLocalDensity] ,DensUp->DensityCArray[GapUpDensity] ,DensUp->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
866
867 // exchange up and down densities
868 MPI_Sendrecv( DensUp->DensityCArray[TotalUpDensity], DensUp->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag1,
869 DensUp->DensityCArray[TotalDownDensity], DensUp->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag2,
870 P->Par.comm_STInter, &status );
871 MPI_Sendrecv( DensUp->DensityArray[TotalUpDensity], DensUp->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag3,
872 DensUp->DensityArray[TotalDownDensity], DensUp->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag4,
873 P->Par.comm_STInter, &status );
874 MPI_Sendrecv( DensUp->DensityCArray[GapUpDensity], DensUp->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag7,
875 DensUp->DensityCArray[GapDownDensity], DensUp->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag8,
876 P->Par.comm_STInter, &status );
877 MPI_Sendrecv( DensUp->DensityArray[GapUpDensity], DensUp->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag9,
878 DensUp->DensityArray[GapDownDensity], DensUp->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag0,
879 P->Par.comm_STInter, &status );
880
881 Temp1R = DensUp->DensityArray[TotalDensity];
882 Temp2R = DensUp->DensityArray[TotalUpDensity];
883 Temp3R = DensUp->DensityArray[TotalDownDensity];
884 Temp4R = DensUp->DensityArray[GapDensity];
885 Temp5R = DensUp->DensityArray[GapUpDensity];
886 Temp6R = DensUp->DensityArray[GapDownDensity];
887 for (i=0; i < DensUp->LocalSizeR; i++) {
888 Temp1R[i] = Temp2R[i]+Temp3R[i];
889 Temp4R[i] = Temp5R[i]+Temp6R[i];
890 }
891 Temp1C = DensUp->DensityCArray[TotalDensity];
892 Temp2C = DensUp->DensityCArray[TotalUpDensity];
893 Temp3C = DensUp->DensityCArray[TotalDownDensity];
894 Temp4C = DensUp->DensityCArray[GapDensity];
895 Temp5C = DensUp->DensityCArray[GapUpDensity];
896 Temp6C = DensUp->DensityCArray[GapDownDensity];
897 for (i=0; i < DensUp->LocalSizeC; i++) {
898 Temp1C[i].re = Temp2C[i].re+Temp3C[i].re;
899 Temp1C[i].im = Temp2C[i].im+Temp3C[i].im;
900 Temp4C[i].re = Temp5C[i].re+Temp6C[i].re;
901 Temp4C[i].im = Temp5C[i].im+Temp6C[i].im;
902 }
903 break;
904 case SpinDown:
905 //fprintf(stderr,"(%i) InitDensity SpinDown\n",P->Par.me);
906 // occupied states
907 MPI_Allreduce(DensUp->DensityArray[TotalLocalDensity] ,DensUp->DensityArray[TotalDownDensity] ,DensUp->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
908 MPI_Allreduce(DensUp->DensityCArray[TotalLocalDensity] ,DensUp->DensityCArray[TotalDownDensity] ,DensUp->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
909 // unoccupied or perturbed states
910 MPI_Allreduce(DensUp->DensityArray[GapLocalDensity] ,DensUp->DensityArray[GapDownDensity] ,DensUp->LocalSizeR , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
911 MPI_Allreduce(DensUp->DensityCArray[GapLocalDensity] ,DensUp->DensityCArray[GapDownDensity] ,DensUp->LocalSizeC*2 , MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_PsiT);
912
913 // exchange up and down densities
914 MPI_Sendrecv( DensUp->DensityCArray[TotalDownDensity], DensUp->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag2,
915 DensUp->DensityCArray[TotalUpDensity], DensUp->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag1,
916 P->Par.comm_STInter, &status );
917 MPI_Sendrecv( DensUp->DensityArray[TotalDownDensity], DensUp->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag4,
918 DensUp->DensityArray[TotalUpDensity], DensUp->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag3,
919 P->Par.comm_STInter, &status );
920 MPI_Sendrecv( DensUp->DensityCArray[GapDownDensity], DensUp->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag8,
921 DensUp->DensityCArray[GapUpDensity], DensUp->LocalSizeC*2, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag7,
922 P->Par.comm_STInter, &status );
923 MPI_Sendrecv( DensUp->DensityArray[GapDownDensity], DensUp->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag0,
924 DensUp->DensityArray[GapUpDensity], DensUp->LocalSizeR, MPI_DOUBLE, P->Par.me_comm_ST, DensityTag9,
925 P->Par.comm_STInter, &status );
926
927 Temp1R = DensUp->DensityArray[TotalDensity];
928 Temp2R = DensUp->DensityArray[TotalUpDensity];
929 Temp3R = DensUp->DensityArray[TotalDownDensity];
930 Temp4R = DensUp->DensityArray[GapDensity];
931 Temp5R = DensUp->DensityArray[GapUpDensity];
932 Temp6R = DensUp->DensityArray[GapDownDensity];
933 for (i=0; i < DensUp->LocalSizeR; i++) {
934 Temp1R[i] = Temp2R[i]+Temp3R[i];
935 Temp4R[i] = Temp5R[i]+Temp6R[i];
936 }
937 Temp1C = DensUp->DensityCArray[TotalDensity];
938 Temp2C = DensUp->DensityCArray[TotalUpDensity];
939 Temp3C = DensUp->DensityCArray[TotalDownDensity];
940 Temp4C = DensUp->DensityCArray[GapDensity];
941 Temp5C = DensUp->DensityCArray[GapUpDensity];
942 Temp6C = DensUp->DensityCArray[GapDownDensity];
943 for (i=0; i < DensUp->LocalSizeC; i++) {
944 Temp1C[i].re = Temp2C[i].re+Temp3C[i].re;
945 Temp1C[i].im = Temp2C[i].im+Temp3C[i].im;
946 Temp4C[i].re = Temp5C[i].re+Temp6C[i].re;
947 Temp4C[i].im = Temp5C[i].im+Temp6C[i].im;
948 }
949 break;
950 }
951}
952
953/** Checks for deviation from Psis::NIDensity.
954 * Calculates NIDensity (sum over DensityTypes#TotalDensity and DensityTypes#PertMixedDensity over R)
955 * via CalculateNativeIntDens() and checks if it is within MYEPSILON to Psis::NIDensity. Note that sum must
956 * be equal to that over DensityTypes#TotalDensity alone, as summed up DensityTypes#PertMixedDensity must
957 * be zero (charge conservation).
958 * \param *P Problem at hand
959 */
960void ControlNativeDensity(struct Problem *P)
961{
962 double NIDensity=0., NIDensityUp=0., NIDensityDown=0.;
963 struct Lattice *Lat = &P->Lat;
964 struct RunStruct *R = &P->R;
965 struct LatticeLevel *Lev0 = R->Lev0;
966 struct Density *Dens = Lev0->Dens;
967 struct Psis *Psi = &Lat->Psi;
968 double factorDR = R->FactorDensityR;
969
970 switch (R->CurrentMin) {
971 case Occupied:
972 NIDensity = CalculateNativeIntDens(P, Lev0, Dens->DensityArray[TotalDensity], 1./factorDR);
973 if (Psi->PsiST != SpinDouble) {
974 NIDensityUp = CalculateNativeIntDens(P, Lev0, Dens->DensityArray[TotalUpDensity], 1./factorDR);
975 NIDensityDown = CalculateNativeIntDens(P, Lev0, Dens->DensityArray[TotalDownDensity], 1./factorDR);
976 }
977 break;
978 default:
979 case UnOccupied:
980 NIDensity = CalculateNativeIntDens(P, Lev0, Dens->DensityArray[GapDensity], 1./factorDR);
981 if (Psi->PsiST != SpinDouble) {
982 NIDensityUp = CalculateNativeIntDens(P, Lev0, Dens->DensityArray[GapUpDensity], 1./factorDR);
983 NIDensityDown = CalculateNativeIntDens(P, Lev0, Dens->DensityArray[GapDownDensity], 1./factorDR);
984 }
985 break;
986 }
987 if (P->Call.out[LeaderOut] && (P->Par.me == 0)) {
988 if (fabs(NIDensity - Psi->NIDensity[R->CurrentMin]) >= MYEPSILON) {
989 fprintf(stderr, "NativeDensity(L(%i)[%i]) = %g != %g eps (%g >= %g)\n",R->LevSNo,R->CurrentMin,NIDensity,Psi->NIDensity[R->CurrentMin],fabs(NIDensity - Psi->NIDensity[R->CurrentMin]),MYEPSILON);
990 } else {
991 if (P->Call.out[StepLeaderOut]) fprintf(stderr, "NativeDensity(L(%i) = %g Ok !\n",R->LevSNo,NIDensity);
992 }
993 if (Psi->PsiST != SpinDouble) {
994 if (fabs(NIDensityUp - Psi->NIDensityUp[R->CurrentMin]) >= MYEPSILON) {
995 fprintf(stderr, "NativeDensityUp(L(%i)[%i]) = %g != %g eps (%g >= %g)\n",R->LevSNo,R->CurrentMin,NIDensityUp,Psi->NIDensityUp[R->CurrentMin],fabs(NIDensityUp - Psi->NIDensityUp[R->CurrentMin]),MYEPSILON);
996 } else {
997 if (P->Call.out[StepLeaderOut]) fprintf(stderr, "NativeDensityUp(L(%i) = %g Ok !\n",R->LevSNo,NIDensityUp);
998 }
999 if (fabs(NIDensityDown - Psi->NIDensityDown[R->CurrentMin]) >= MYEPSILON) {
1000 fprintf(stderr, "NativeDensityDown(L(%i)[%i]) = %g != %g eps (%g >= %g)\n",R->LevSNo,R->CurrentMin,NIDensityDown,Psi->NIDensityDown[R->CurrentMin],fabs(NIDensityDown - Psi->NIDensityDown[R->CurrentMin]),MYEPSILON);
1001 } else {
1002 if (P->Call.out[StepLeaderOut]) fprintf(stderr, "NativeDensityDown(L(%i) = %g Ok !\n",R->LevSNo,NIDensityDown);
1003 }
1004 }
1005 }
1006}
1007
1008/** Initialization of Density structure.
1009 * Sets initial values for Density structure such as Density::TotalSize,
1010 * Density::LocalSizeC and Density::LocalSizeR, defines on SpinUpDown/SpinDouble which
1011 * densities shall be calculated in Density::DensityTypeUse, allocates in UseType::InUse case
1012 * memory for the density arrays, sets them to zero, otherwise to NULL.
1013 * \param *P Problem at hand
1014 */
1015void InitDensity(struct Problem *const P) {
1016 struct Lattice *Lat = &P->Lat;
1017 struct LatticeLevel *Lev, *LevDown;
1018 struct Density *Dens;
1019 int i,j,d;
1020 if (P->Call.out[NormalOut]) fprintf(stderr, "(%i)InitDensity\n", P->Par.me);
1021 for (i = 0; i < Lat->MaxLevel; i++) {
1022 Lev = &Lat->Lev[i];
1023 if (i<Lat->MaxLevel-1) {
1024 LevDown = &Lat->Lev[i+1];
1025 Lev->Dens = (struct Density *)
1026 Malloc(sizeof(struct Density),"InitDensity: Dens");
1027 Dens = Lev->Dens;
1028 Dens->TotalSize = LevDown->Plan0.plan->LocalSizeC*LevDown->MaxNUp;
1029 Dens->LocalSizeC = Lev->Plan0.plan->LocalSizeC;
1030 Dens->LocalSizeR = Lev->Plan0.plan->LocalSizeR;
1031 } else {
1032 Lev->Dens = (struct Density *)
1033 Malloc(sizeof(struct Density),"InitDensity: Dens");
1034 Dens = Lev->Dens;
1035 Dens->TotalSize = Lev->Plan0.plan->LocalSizeC;
1036 Dens->LocalSizeC = Lev->Plan0.plan->LocalSizeC;
1037 Dens->LocalSizeR = Lev->Plan0.plan->LocalSizeR;
1038 /*
1039 Lev->Dens = NULL;
1040 Dens = Lev->Dens;
1041 */
1042 }
1043 if (i == 0) {
1044 for (d=0; d < (P->R.DoPerturbation == 1 ? MaxDensityTypes : MaxInitDensityTypes); d++) {
1045 switch (Lat->Psi.Use) {
1046 case UseSpinDouble:
1047 switch (d) {
1048 case ActualDensity:
1049 Dens->DensityTypeUse[d] = InUse;
1050 break;
1051 case TotalDensity:
1052 Dens->DensityTypeUse[d] = InUse;
1053 break;
1054 case TotalLocalDensity:
1055 Dens->DensityTypeUse[d] = InUse;
1056 break;
1057 case TotalUpDensity:
1058 Dens->DensityTypeUse[d] = InUse;
1059 break;
1060 case TotalDownDensity:
1061 Dens->DensityTypeUse[d] = InUse;
1062 break;
1063 case CoreWaveDensity:
1064 Dens->DensityTypeUse[d] = InUse;
1065 break;
1066 case HGcDensity:
1067 Dens->DensityTypeUse[d] = InUse;
1068 break;
1069 case GapDensity:
1070 Dens->DensityTypeUse[d] = InUse;
1071 break;
1072 case GapUpDensity:
1073 Dens->DensityTypeUse[d] = InUse; // are needed for Wannier as well!
1074 break;
1075 case GapDownDensity:
1076 Dens->DensityTypeUse[d] = InUse; // are needed for Wannier as well!
1077 break;
1078 case GapLocalDensity:
1079 Dens->DensityTypeUse[d] = InUse;
1080 break;
1081 case CurrentDensity0:
1082 Dens->DensityTypeUse[d] = InUse;
1083 break;
1084 case CurrentDensity1:
1085 Dens->DensityTypeUse[d] = InUse;
1086 break;
1087 case CurrentDensity2:
1088 Dens->DensityTypeUse[d] = InUse;
1089 break;
1090 case CurrentDensity3:
1091 Dens->DensityTypeUse[d] = InUse;
1092 break;
1093 case CurrentDensity4:
1094 Dens->DensityTypeUse[d] = InUse;
1095 break;
1096 case CurrentDensity5:
1097 Dens->DensityTypeUse[d] = InUse;
1098 break;
1099 case CurrentDensity6:
1100 Dens->DensityTypeUse[d] = InUse;
1101 break;
1102 case CurrentDensity7:
1103 Dens->DensityTypeUse[d] = InUse;
1104 break;
1105 case CurrentDensity8:
1106 Dens->DensityTypeUse[d] = InUse;
1107 break;
1108 case TempDensity:
1109 Dens->DensityTypeUse[d] = InUse;
1110 break;
1111 case Temp2Density:
1112 Dens->DensityTypeUse[d] = InUse;
1113 break;
1114 }
1115 break;
1116 case UseSpinUpDown:
1117 switch (d) {
1118 case ActualDensity:
1119 Dens->DensityTypeUse[d] = InUse;
1120 break;
1121 case TotalDensity:
1122 Dens->DensityTypeUse[d] = InUse;
1123 break;
1124 case TotalLocalDensity:
1125 Dens->DensityTypeUse[d] = InUse;
1126 break;
1127 case TotalUpDensity:
1128 Dens->DensityTypeUse[d] = InUse;
1129 break;
1130 case TotalDownDensity:
1131 Dens->DensityTypeUse[d] = InUse;
1132 break;
1133 case CoreWaveDensity:
1134 Dens->DensityTypeUse[d] = InUse;
1135 break;
1136 case HGcDensity:
1137 Dens->DensityTypeUse[d] = InUse;
1138 break;
1139 case GapDensity:
1140 Dens->DensityTypeUse[d] = InUse;
1141 break;
1142 case GapUpDensity:
1143 Dens->DensityTypeUse[d] = InUse;
1144 break;
1145 case GapDownDensity:
1146 Dens->DensityTypeUse[d] = InUse;
1147 break;
1148 case GapLocalDensity:
1149 Dens->DensityTypeUse[d] = InUse;
1150 break;
1151 case CurrentDensity0:
1152 Dens->DensityTypeUse[d] = InUse;
1153 break;
1154 case CurrentDensity1:
1155 Dens->DensityTypeUse[d] = InUse;
1156 break;
1157 case CurrentDensity2:
1158 Dens->DensityTypeUse[d] = InUse;
1159 break;
1160 case CurrentDensity3:
1161 Dens->DensityTypeUse[d] = InUse;
1162 break;
1163 case CurrentDensity4:
1164 Dens->DensityTypeUse[d] = InUse;
1165 break;
1166 case CurrentDensity5:
1167 Dens->DensityTypeUse[d] = InUse;
1168 break;
1169 case CurrentDensity6:
1170 Dens->DensityTypeUse[d] = InUse;
1171 break;
1172 case CurrentDensity7:
1173 Dens->DensityTypeUse[d] = InUse;
1174 break;
1175 case CurrentDensity8:
1176 Dens->DensityTypeUse[d] = InUse;
1177 break;
1178 case TempDensity:
1179 Dens->DensityTypeUse[d] = InUse;
1180 break;
1181 case Temp2Density:
1182 Dens->DensityTypeUse[d] = InUse;
1183 break;
1184 }
1185 break;
1186 }
1187 if (Dens->DensityTypeUse[d] == InUse) {
1188 Dens->DensityArray[d] = (fftw_real *)
1189 Malloc(sizeof(fftw_complex)*Dens->TotalSize,"InitDensity: DensityArray");
1190 for (j=0; j < Dens->TotalSize*2; j++)
1191 Dens->DensityArray[d][j] = 0.0;
1192 Dens->DensityCArray[d] = (fftw_complex *)
1193 Malloc(sizeof(fftw_complex)*Dens->TotalSize,"InitDensity: DensityCArray");
1194 for (j=0; j < Dens->TotalSize; j++) {
1195 Dens->DensityCArray[d][j].re = 0.0;
1196 Dens->DensityCArray[d][j].im = 0.0;
1197 }
1198 } else {
1199 Dens->DensityArray[d] = NULL;
1200 Dens->DensityCArray[d] = NULL;
1201 }
1202 Dens->LockArray[d] = NotInUse;
1203 Dens->LockCArray[d] = NotInUse;
1204 }
1205 } else {
1206 if (Dens != NULL)
1207 for (d=0; d < (P->R.DoPerturbation == 1 ? MaxDensityTypes : MaxInitDensityTypes); d++) {
1208 Dens->DensityTypeUse[d] = Lat->Lev[i-1].Dens->DensityTypeUse[d];
1209 Dens->DensityArray[d] = Lat->Lev[i-1].Dens->DensityArray[d];
1210 Dens->DensityCArray[d] = Lat->Lev[i-1].Dens->DensityCArray[d];
1211 Dens->LockArray[d] = NotInUse;
1212 Dens->LockCArray[d] = NotInUse;
1213 }
1214 }
1215 }
1216}
Note: See TracBrowser for help on using the repository browser.