source: pcp/src/density.c@ f70c2a

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

Merge branch 'ConcaveHull' of ../espack2 into ConcaveHull

Conflicts:

molecuilder/src/boundary.cpp
molecuilder/src/boundary.hpp
molecuilder/src/builder.cpp
molecuilder/src/linkedcell.cpp
molecuilder/src/linkedcell.hpp
molecuilder/src/vector.cpp
molecuilder/src/vector.hpp
util/src/NanoCreator.c

Basically, this resulted from a lot of conversions two from spaces to one tab, which is my standard indentation. The mess was caused by eclipse auto-indenting. And in espack2:ConcaveHull was the new stuff, so all from ConcaveHull was replaced in case of doubt.
Additionally, vector had ofstream << operator instead ostream << ...

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