source: pcp/src/run.c@ ccd028

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

CallOptions#ReadSrcFile is now enumerated ParseSrcDensities

This is done to distinguish between when only Occ are parsed (i.e. when StructOpt has been done before and now we do perturbed run), all or we pare and minimise subsequently.

  • Property mode set to 100644
File size: 80.9 KB
Line 
1/** \file run.c
2 * Initialization of levels and calculation super-functions.
3 *
4 * Most important functions herein are CalculateForce() and CalculateMD(), which calls various
5 * functions in order to perfom the Molecular Dynamics simulation. MinimiseOccupied() and MinimiseUnOccupied()
6 * call various functions to perform the actual minimisation for the occupied and unoccupied wave functions.
7 * CalculateMinimumStop() evaluates the stop condition for desired precision or step count (or external signals).
8 *
9 * Minor functions are ChangeToLevUp() (which takes the calculation to the next finer level),
10 * UpdateActualPsiNo() (next Psi is minimized and an additional orthonormalization takes place) and UpdateToNewWaves()
11 * (which reinitializes density calculations after the wave functions have changed due to the ionic motion).
12 * OccupyByFermi() re-occupies orbitals according to Fermi distribution if calculated with additional orbitals.
13 * InitRun() and InitRunLevel() prepare the RunStruct with starting values. UpdateIon_PRCG() implements a CG
14 * algorithm to minimize the ionic forces and thus optimize the structure.
15 *
16 *
17 Project: ParallelCarParrinello
18 \author Jan Hamaekers
19 \date 2000
20
21 File: run.c
22 $Id: run.c,v 1.101.2.2 2007-04-21 13:01:13 foo Exp $
23*/
24
25#include <signal.h>
26#include <stdlib.h>
27#include <stdio.h>
28#include <string.h>
29#include <math.h>
30#include <gsl/gsl_multimin.h>
31#include <gsl/gsl_vector.h>
32#include <gsl/gsl_errno.h>
33#include <gsl/gsl_math.h>
34#include <gsl/gsl_min.h>
35#include <gsl/gsl_randist.h>
36#include "mpi.h"
37#include "data.h"
38#include "errors.h"
39#include "helpers.h"
40#include "init.h"
41#include "opt.h"
42#include "myfft.h"
43#include "gramsch.h"
44#include "output.h"
45#include "energy.h"
46#include "density.h"
47#include "ions.h"
48#include "run.h"
49#include "riemann.h"
50#include "mymath.h"
51#include "pcp.h"
52#include "perturbed.h"
53#include "wannier.h"
54
55
56/** Initialization of the (initial) zero and simulation levels in RunStruct structure.
57 * RunStruct::InitLevS is set onto the STANDARTLEVEL in Lattice::Lev[], RunStruct::InitLev0 on
58 * level 0, RunStruct::LevS onto Lattice::MaxLevel-1 (maximum level) and RunStruct::Lev0 onto
59 * Lattice::MaxLevel-2 (one below).
60 * In case of RiemannTensor use an additional Riemann level is intertwined.
61 * \param *P Problem at hand
62 */
63void InitRunLevel(struct Problem *P)
64{
65 struct Lattice *Lat = &P->Lat;
66 struct RunStruct *R = &P->R;
67 struct RiemannTensor *RT = &Lat->RT;
68 int d,i;
69
70 switch (Lat->RT.Use) {
71 case UseNotRT:
72 R->InitLevSNo = STANDARTLEVEL;
73 R->InitLev0No = 0;
74 R->InitLevS = &P->Lat.Lev[R->InitLevSNo];
75 R->InitLev0 = &P->Lat.Lev[R->InitLev0No];
76 R->LevSNo = Lat->MaxLevel-1;
77 R->Lev0No = Lat->MaxLevel-2;
78 R->LevS = &P->Lat.Lev[R->LevSNo];
79 R->Lev0 = &P->Lat.Lev[R->Lev0No];
80 break;
81 case UseRT:
82 R->InitLevSNo = STANDARTLEVEL;
83 R->InitLev0No = 0;
84 R->InitLevS = &P->Lat.Lev[R->InitLevSNo];
85 R->InitLev0 = &P->Lat.Lev[R->InitLev0No];
86
87 /* R->LevSNo = Lat->MaxLevel-1;
88 R->Lev0No = Lat->MaxLevel-2;*/
89 R->LevSNo = Lat->MaxLevel-2;
90 R->Lev0No = Lat->MaxLevel-3;
91
92 R->LevRNo = P->Lat.RT.RiemannLevel;
93 R->LevRSNo = STANDARTLEVEL;
94 R->LevR0No = 0;
95 R->LevS = &P->Lat.Lev[R->LevSNo];
96 R->Lev0 = &P->Lat.Lev[R->Lev0No];
97 R->LevR = &P->Lat.Lev[R->LevRNo];
98 R->LevRS = &P->Lat.Lev[R->LevRSNo];
99 R->LevR0 = &P->Lat.Lev[R->LevR0No];
100 for (d=0; d<NDIM; d++) {
101 RT->NUpLevRS[d] = 1;
102 for (i=R->LevRNo-1; i >= R->LevRSNo; i--)
103 RT->NUpLevRS[d] *= Lat->LevelSizes[i];
104 RT->NUpLevR0[d] = 1;
105 for (i=R->LevRNo-1; i >= R->LevR0No; i--)
106 RT->NUpLevR0[d] *= Lat->LevelSizes[i];
107 }
108 break;
109 }
110}
111
112
113/** Initialization of RunStruct structure.
114 * Most of the actual entries in the RunStruct are set to their starter no-nonsense
115 * values (init if LatticeLevel is not STANDARTLEVEL otherwise normal max): FactorDensity,
116 * all Steps, XCEnergyFactor and HGcFactor, current and archived energie values are zeroed.
117 * \param *P problem at hand
118 */
119void InitRun(struct Problem *P)
120{
121 struct Lattice *Lat = &P->Lat;
122 struct RunStruct *R = &P->R;
123 struct Psis *Psi = &Lat->Psi;
124 int i,j;
125
126#ifndef SHORTSPEED
127 R->MaxMinStepFactor = Psi->AllMaxLocalNo;
128#else
129 R->MaxMinStepFactor = SHORTSPEED;
130#endif
131 if (R->LevSNo == STANDARTLEVEL) {
132 R->ActualMaxMinStep = R->MaxMinStep*R->MaxPsiStep*R->MaxMinStepFactor;
133 R->ActualRelEpsTotalEnergy = R->RelEpsTotalEnergy;
134 R->ActualRelEpsKineticEnergy = R->RelEpsKineticEnergy;
135 R->ActualMaxMinStopStep = R->MaxMinStopStep;
136 R->ActualMaxMinGapStopStep = R->MaxMinGapStopStep;
137 } else {
138 R->ActualMaxMinStep = R->MaxInitMinStep*R->MaxPsiStep*R->MaxMinStepFactor;
139 R->ActualRelEpsTotalEnergy = R->InitRelEpsTotalEnergy;
140 R->ActualRelEpsKineticEnergy = R->InitRelEpsKineticEnergy;
141 R->ActualMaxMinStopStep = R->InitMaxMinStopStep;
142 R->ActualMaxMinGapStopStep = R->InitMaxMinGapStopStep;
143 }
144
145 R->FactorDensityR = 1./Lat->Volume;
146 R->FactorDensityC = Lat->Volume;
147
148 R->OldActualLocalPsiNo = R->ActualLocalPsiNo = 0;
149 R->UseForcesFile = 0;
150 R->UseOldPsi = 1;
151 R->MinStep = 0;
152 R->PsiStep = 0;
153 R->AlphaStep = 0;
154 R->DoCalcCGGauss = 0;
155 R->CurrentMin = Occupied;
156
157 R->MinStopStep = 0;
158
159 R->ScanPotential = 0; // in order to deactivate, simply set this to 0
160 R->ScanAtStep = 6; // must not be set to same as ScanPotential (then gradient is never calculated)
161 R->ScanDelta = 0.01; // step size on advance
162 R->ScanFlag = 0; // flag telling that we are scanning
163
164 //R->DoBrent = 0; // InitRun() occurs after ReadParameters(), thus this deactivates DoBrent line search
165
166 /* R->MaxOuterStep = 1;
167 R->MeanForceEps = 0.0;*/
168
169 R->NewRStep = 1;
170 /* Factor */
171 R->XCEnergyFactor = 1.0/R->FactorDensityR;
172 R->HGcFactor = 1.0/Lat->Volume;
173
174 /* Sollte auch geaendert werden */
175 /*Grad->GradientArray[GraSchGradient] = LevS->LPsi->LocalPsi[Psi->LocalNo];*/
176
177 for (j=Occupied;j<Extra;j++)
178 for (i=0; i < RUNMAXOLD; i++) {
179 R->TE[j][i] = 0;
180 R->KE[j][i] = 0;
181 }
182
183 R->MinimisationName = (char **) Malloc((perturbations+3)*(sizeof(char *)), "InitRun: *MinimisationName");
184 for (j=Occupied;j<=Extra;j++)
185 R->MinimisationName[j] = (char *) MallocString(6*(sizeof(char)), "InitRun: MinimisationName[]");
186 strncpy(R->MinimisationName[0],"Occ",6);
187 strncpy(R->MinimisationName[1],"UnOcc",6);
188 strncpy(R->MinimisationName[2],"P0",6);
189 strncpy(R->MinimisationName[3],"P1",6);
190 strncpy(R->MinimisationName[4],"P2",6);
191 strncpy(R->MinimisationName[5],"RxP0",6);
192 strncpy(R->MinimisationName[6],"RxP1",6);
193 strncpy(R->MinimisationName[7],"RxP2",6);
194 strncpy(R->MinimisationName[8],"Extra",6);
195}
196
197/** Re-occupy orbitals according to Fermi (bottom-up energy-wise).
198 * All OnePsiElementAddData#PsiFactor's are set to zero. \a electrons is set to Psi#Use-dependent
199 * Psis#GlobalNo.
200 * Then we go through OnePsiElementAddData#Lambda, find biggest, put one or two electrons into
201 * its PsiFactor, withdraw from \a electrons. Go on as long as there are \a electrons left.
202 * \param *P Problem at hand
203 */
204void OccupyByFermi(struct Problem *P) {
205 struct Lattice *Lat = &P->Lat;
206 struct Psis *Psi = &Lat->Psi;
207 int i, index, electrons = 0;
208 double lambda, electronsperorbit;
209
210 for (i=0; i< Psi->LocalNo; i++) {// set all PsiFactors to zero
211 Psi->LocalPsiStatus[i].PsiFactor = 0.0;
212 Psi->LocalPsiStatus[i].PsiType = UnOccupied;
213 //Psi->LocalPsiStatus[i].PsiGramSchStatus = (R->DoSeparated) ? NotUsedToOrtho : NotOrthogonal;
214 }
215
216 electronsperorbit = (Psi->Use == UseSpinUpDown) ? 1 : 2;
217 switch (Psi->PsiST) { // how many electrons may we re-distribute
218 case SpinDouble:
219 electrons = Psi->GlobalNo[PsiMaxNoDouble];
220 break;
221 case SpinUp:
222 electrons = Psi->GlobalNo[PsiMaxNoUp];
223 break;
224 case SpinDown:
225 electrons = Psi->GlobalNo[PsiMaxNoDown];
226 break;
227 }
228 while (electrons > 0) {
229 lambda = 0.0;
230 index = 0;
231 for (i=0; i< Psi->LocalNo; i++) // seek biggest unoccupied one
232 if ((lambda < Psi->AddData[i].Lambda) && (Psi->LocalPsiStatus[i].PsiFactor == 0.0)) {
233 index = i;
234 lambda = Psi->AddData[i].Lambda;
235 }
236 Psi->LocalPsiStatus[index].PsiFactor = electronsperorbit; // occupy state
237 Psi->LocalPsiStatus[index].PsiType = Occupied;
238 electrons--; // one electron less
239 }
240 for (i=0; i< Psi->LocalNo; i++) // set all PsiFactors to zero
241 if (Psi->LocalPsiStatus[i].PsiType == UnOccupied) Psi->LocalPsiStatus[i].PsiFactor = 1.0;
242
243 SpeedMeasure(P, DensityTime, StartTimeDo);
244 UpdateDensityCalculation(P);
245 SpeedMeasure(P, DensityTime, StopTimeDo);
246 InitPsiEnergyCalculation(P,Occupied); // goes through all orbitals calculating kinetic and non-local
247 CalculateDensityEnergy(P, 0);
248 EnergyAllReduce(P);
249// SetCurrentMinState(P,UnOccupied);
250// InitPsiEnergyCalculation(P,UnOccupied); /* STANDARTLEVEL */
251// CalculateGapEnergy(P); /* STANDARTLEVEL */
252// EnergyAllReduce(P);
253// SetCurrentMinState(P,Occupied);
254}
255
256/** Use next local Psi: Update RunStruct::ActualLocalPsiNo.
257 * Increases OnePsiElementAddData::Step, RunStruct::MinStep and RunStruct::PsiStep.
258 * RunStruct::OldActualLocalPsiNo is set to current one and this distributed
259 * (UpdateGramSchOldActualPsiNo()) among process.
260 * Afterwards RunStruct::ActualLocalPsiNo is increased (modulo Psis::LocalNo of
261 * this process) and again distributed (UpdateGramSchActualPsiNo()).
262 * Due to change in the GramSchmidt-Status, GramSch() is called for Orthonormalization.
263 * \param *P Problem at hand#
264 * \param IncType skip types PsiTypeTag#UnOccupied or PsiTypeTag#Occupied we only want next(thus we can handily advance only through either type)
265 */
266void UpdateActualPsiNo(struct Problem *P, enum PsiTypeTag IncType)
267{
268 struct RunStruct *R = &P->R;
269 if (R->CurrentMin != IncType) {
270 SetCurrentMinState(P,IncType);
271 R->PsiStep = R->MaxPsiStep; // force step to next Psi
272 }
273 P->Lat.Psi.AddData[R->ActualLocalPsiNo].Step++;
274 R->MinStep++;
275 R->PsiStep++;
276 if (R->OldActualLocalPsiNo != R->ActualLocalPsiNo) {
277 R->OldActualLocalPsiNo = R->ActualLocalPsiNo;
278 UpdateGramSchOldActualPsiNo(P, &P->Lat.Psi);
279 }
280 if (R->PsiStep >= R->MaxPsiStep) {
281 R->PsiStep=0;
282 do {
283 R->ActualLocalPsiNo++;
284 R->ActualLocalPsiNo %= P->Lat.Psi.LocalNo;
285 } while (P->Lat.Psi.AllPsiStatus[R->ActualLocalPsiNo].PsiType != IncType);
286 UpdateGramSchActualPsiNo(P, &P->Lat.Psi);
287 //fprintf(stderr,"(%i) ActualLocalNo: %d\n", P->Par.me, R->ActualLocalPsiNo);
288 }
289 if ((R->UseAddGramSch == 1 && (R->OldActualLocalPsiNo != R->ActualLocalPsiNo || P->Lat.Psi.NoOfPsis == 1)) || R->UseAddGramSch == 2) {
290 if (P->Lat.Psi.LocalPsiStatus[R->OldActualLocalPsiNo].PsiGramSchStatus != NotUsedToOrtho) // don't reset by accident last psi of former minimisation run
291 SetGramSchOldActualPsi(P, &P->Lat.Psi, NotOrthogonal);
292 SpeedMeasure(P, GramSchTime, StartTimeDo);
293 //OrthogonalizePsis(P);
294 if (R->CurrentMin <= UnOccupied)
295 GramSch(P, R->LevS, &P->Lat.Psi, Orthonormalize);
296 else
297 GramSch(P, R->LevS, &P->Lat.Psi, Orthogonalize); //Orthogonalize
298 SpeedMeasure(P, GramSchTime, StopTimeDo);
299 }
300}
301
302/** Resets all OnePsiElement#DoBrent.\
303 * \param *P Problem at hand
304 * \param *Psi pointer to wave functions
305 */
306void ResetBrent(struct Problem *P, struct Psis *Psi) {
307 int i;
308 for (i=0; i< Psi->LocalNo; i++) {// set all PsiFactors to zero
309 //fprintf(stderr,"(%i) DoBrent[%i] = %i\n", P->Par.me, i, Psi->LocalPsiStatus[i].DoBrent);
310 if (Psi->LocalPsiStatus[i].PsiType == Occupied) Psi->LocalPsiStatus[i].DoBrent = 4;
311 }
312}
313
314/** Sets current minimisation state.
315 * Stores given \a state in RunStruct#CurrentMin and sets pointer Lattice#E accordingly.
316 * \param *P Problem at hand
317 * \param state given PsiTypeTag state
318 */
319void SetCurrentMinState(struct Problem *P, enum PsiTypeTag state) {
320 P->R.CurrentMin = state;
321 P->R.TotalEnergy = &(P->R.TE[state][0]);
322 P->R.KineticEnergy = &(P->R.KE[state][0]);
323 P->R.ActualRelTotalEnergy = &(P->R.ActualRelTE[state][0]);
324 P->R.ActualRelKineticEnergy = &(P->R.ActualRelKE[state][0]);
325 P->Lat.E = &(P->Lat.Energy[state]);
326}
327/*{
328 struct RunStruct *R = &P->R;
329 struct Lattice *Lat = &P->Lat;
330 struct Psis *Psi = &Lat->Psi;
331 P->Lat.Psi.AddData[R->ActualLocalPsiNo].Step++;
332 R->MinStep++;
333 R->PsiStep++;
334 if (R->OldActualLocalPsiNo != R->ActualLocalPsiNo) { // remember old actual local number
335 R->OldActualLocalPsiNo = R->ActualLocalPsiNo;
336 UpdateGramSchOldActualPsiNo(P, &P->Lat.Psi);
337 }
338 if (R->PsiStep >= R->MaxPsiStep) { // done enough minimisation steps for this orbital?
339 R->PsiStep=0;
340 do { // step on as long as we are still on a SkipType orbital
341 R->ActualLocalPsiNo++;
342 R->ActualLocalPsiNo %= P->Lat.Psi.LocalNo;
343 } while ((P->Lat.Psi.LocalPsiStatus[R->ActualLocalPsiNo].PsiType == SkipType));
344 UpdateGramSchActualPsiNo(P, &P->Lat.Psi);
345 if (R->UseAddGramSch >= 1) {
346 SetGramSchOldActualPsi(P,Psi,NotOrthogonal);
347 // setze von OldActual bis bla auf nicht orthogonal
348 GramSch(P, R->LevS, &P->Lat.Psi, Orthonormalize);
349 }
350 } else if (R->UseAddGramSch == 2) {
351 SetGramSchOldActualPsi(P, &P->Lat.Psi, NotOrthogonal);
352 //if (SkipType == UnOccupied)
353 //ResetGramSch(P,Psi);
354 //fprintf(stderr,"UpdateActualPsiNo: GramSch() for %i\n",R->OldActualLocalPsiNo);
355 GramSch(P, R->LevS, &P->Lat.Psi, Orthonormalize);
356 }
357}*/
358
359/** Upgrades the calculation to the next finer level.
360 * If we are below the initial level,
361 * ChangePsiAndDensToLevUp() prepares density and Psi coefficients.
362 * Then the level change is made as RunStruct::LevSNo and RunStruct::Lev0No are decreased.
363 * The RunStruct::OldActualLocalPsi is set to current one and both are distributed
364 * (UpdateGramSchActualPsiNo(), UpdateGramSchOldActualPsiNo()).
365 * The PseudoPot'entials adopt the level up by calling ChangePseudoToLevUp().
366 * Now we are prepared to reset Energy::PsiEnergy and local and total density energy and
367 * recalculate them: InitPsiEnergyCalculation(), CalculateDensityEnergy() and CalculateIonsEnergy().
368 * Results are gathered EnergyAllReduce() and the output made EnergyOutput().
369 * Finally, the stop condition are reset for the new level (depending if it's the STANDARTLEVEL or
370 * not).
371 * \param *P Problem at hand
372 * \param *Stop is set to zero if we are below or equal to init level (see CalculateForce())
373 * \sa UpdateToNewWaves() very similar in the procedure, only the update of the Psis and density
374 * (ChangePsiAndDensToLevUp()) is already made there.
375 * \bug Missing TotalEnergy shifting for other PsiTypeTag's!
376 */
377static void ChangeToLevUp(struct Problem *P, int *Stop)
378{
379 struct RunStruct *R = &P->R;
380 struct Lattice *Lat = &P->Lat;
381 struct Psis *Psi = &Lat->Psi;
382 struct Energy *E = Lat->E;
383 struct RiemannTensor *RT = &Lat->RT;
384 int i;
385 if (R->LevSNo <= R->InitLevSNo) {
386 if (P->Call.out[LeaderOut] && (P->Par.me == 0))
387 fprintf(stderr, "(%i) ChangeLevUp: LevSNo(%i) <= InitLevSNo(%i)\n", P->Par.me, R->LevSNo, R->InitLevSNo);
388 *Stop = 1;
389 return;
390 }
391 if (P->Call.out[LeaderOut] && (P->Par.me == 0))
392 fprintf(stderr, "(0) ChangeLevUp: LevSNo(%i) InitLevSNo(%i)\n", R->LevSNo, R->InitLevSNo);
393 *Stop = 0;
394 P->Speed.LevUpSteps++;
395 SpeedMeasure(P, SimTime, StopTimeDo);
396 SpeedMeasure(P, InitSimTime, StartTimeDo);
397 SpeedMeasure(P, InitDensityTime, StartTimeDo);
398 ChangePsiAndDensToLevUp(P);
399 SpeedMeasure(P, InitDensityTime, StopTimeDo);
400 R->LevSNo--;
401 R->Lev0No--;
402 if (RT->ActualUse == standby && R->LevSNo == STANDARTLEVEL) {
403 P->Lat.RT.ActualUse = active;
404 CalculateRiemannTensorData(P);
405 Error(SomeError, "Calculate RT: Not further implemented");
406 }
407 R->LevS = &P->Lat.Lev[R->LevSNo];
408 R->Lev0 = &P->Lat.Lev[R->Lev0No];
409 R->OldActualLocalPsiNo = R->ActualLocalPsiNo;
410 UpdateGramSchActualPsiNo(P, &P->Lat.Psi);
411 UpdateGramSchOldActualPsiNo(P, &P->Lat.Psi);
412 ResetBrent(P, &P->Lat.Psi);
413 R->PsiStep=0;
414 R->MinStep=0;
415 P->Grad.GradientArray[GraSchGradient] = R->LevS->LPsi->LocalPsi[Psi->LocalNo];
416 ChangePseudoToLevUp(P);
417 for (i=0; i<MAXALLPSIENERGY; i++)
418 SetArrayToDouble0(E->PsiEnergy[i], Psi->LocalNo);
419 SetArrayToDouble0(E->AllLocalDensityEnergy, MAXALLDENSITYENERGY);
420 SetArrayToDouble0(E->AllTotalDensityEnergy, MAXALLDENSITYENERGY);
421 for (i=MAXOLD-1; i > 0; i--) {
422 E->TotalEnergy[i] = E->TotalEnergy[i-1];
423 Lat->Energy[UnOccupied].TotalEnergy[i] = Lat->Energy[UnOccupied].TotalEnergy[i-1];
424 }
425 InitPsiEnergyCalculation(P,Occupied);
426 CalculateDensityEnergy(P,1);
427 CalculateIonsEnergy(P);
428 EnergyAllReduce(P);
429/* SetCurrentMinState(P,UnOccupied);
430 InitPsiEnergyCalculation(P,UnOccupied);
431 CalculateGapEnergy(P);
432 EnergyAllReduce(P);
433 SetCurrentMinState(P,Occupied);*/
434 EnergyOutput(P,0);
435 if (R->LevSNo == STANDARTLEVEL) {
436 R->ActualMaxMinStep = R->MaxMinStep*R->MaxPsiStep*R->MaxMinStepFactor;
437 R->ActualRelEpsTotalEnergy = R->RelEpsTotalEnergy;
438 R->ActualRelEpsKineticEnergy = R->RelEpsKineticEnergy;
439 R->ActualMaxMinStopStep = R->MaxMinStopStep;
440 R->ActualMaxMinGapStopStep = R->MaxMinGapStopStep;
441 } else {
442 R->ActualMaxMinStep = R->MaxInitMinStep*R->MaxPsiStep*R->MaxMinStepFactor;
443 R->ActualRelEpsTotalEnergy = R->InitRelEpsTotalEnergy;
444 R->ActualRelEpsKineticEnergy = R->InitRelEpsKineticEnergy;
445 R->ActualMaxMinStopStep = R->InitMaxMinStopStep;
446 R->ActualMaxMinGapStopStep = R->InitMaxMinGapStopStep;
447 }
448 R->MinStopStep = 0;
449 SpeedMeasure(P, InitSimTime, StopTimeDo);
450 SpeedMeasure(P, SimTime, StartTimeDo);
451 if (P->Call.out[LeaderOut] && (P->Par.me == 0))
452 fprintf(stderr, "(0) ChangeLevUp: LevSNo(%i) InitLevSNo(%i) Done\n", R->LevSNo, R->InitLevSNo);
453}
454
455/** Updates after the wave functions have changed (e.g.\ Ion moved).
456 * Old and current RunStruct::ActualLocalPsiNo are zeroed and distributed among the processes.
457 * InitDensityCalculation() is called, afterwards the pseudo potentials update to the new
458 * wave functions UpdatePseudoToNewWaves().
459 * Energy::AllLocalDensityEnergy, Energy::AllTotalDensityEnergy, Energy::AllTotalIonsEnergy and
460 * Energy::PsiEnergy[i] are set to zero.
461 * We are set to recalculate all of the following energies: Psis InitPsiEnergyCalculation(), density
462 * CalculateDensityEnergy(), ionic CalculateIonsEnergy() and ewald CalculateEwald().
463 * Results are gathered from all processes EnergyAllReduce() and EnergyOutput() is called.
464 * Finally, the various conditons in the RunStruct for stopping the calculation are set: number of
465 * minimisation steps, relative total or kinetic energy change or how often stop condition was
466 * evaluated.
467 * \param *P Problem at hand
468 */
469static void UpdateToNewWaves(struct Problem *P)
470{
471 struct RunStruct *R = &P->R;
472 struct Lattice *Lat = &P->Lat;
473 struct Psis *Psi = &Lat->Psi;
474 struct Energy *E = Lat->E;
475 int i;//,type;
476 R->OldActualLocalPsiNo = R->ActualLocalPsiNo = 0;
477 //if (isnan((double)R->LevS->LPsi->LocalPsi[R->OldActualLocalPsiNo][0].re)) { fprintf(stderr,"(%i) WARNING in UpdateGramSchActualPsiNo(): LPsi->LocalPsi[%i]_[%i] = NaN!\n", P->Par.me, R->OldActualLocalPsiNo, 0); Error(SomeError, "NaN-Fehler!"); }
478 UpdateGramSchActualPsiNo(P, &P->Lat.Psi);
479 UpdateGramSchOldActualPsiNo(P, &P->Lat.Psi);
480 R->PsiStep=0;
481 R->MinStep=0;
482 SpeedMeasure(P, InitDensityTime, StartTimeDo);
483 //if (isnan((double)R->LevS->LPsi->LocalPsi[R->OldActualLocalPsiNo][0].re)) { fprintf(stderr,"(%i) WARNING in Update../InitDensityCalculation(): LPsi->LocalPsi[%i]_[%i] = NaN!\n", P->Par.me, R->OldActualLocalPsiNo, 0); Error(SomeError, "NaN-Fehler!"); }
484 InitDensityCalculation(P);
485 SpeedMeasure(P, InitDensityTime, StopTimeDo);
486 UpdatePseudoToNewWaves(P);
487 for (i=0; i<MAXALLPSIENERGY; i++)
488 SetArrayToDouble0(E->PsiEnergy[i], Psi->LocalNo);
489 SetArrayToDouble0(E->AllLocalDensityEnergy, MAXALLDENSITYENERGY);
490 SetArrayToDouble0(E->AllTotalDensityEnergy, MAXALLDENSITYENERGY);
491 SetArrayToDouble0(E->AllTotalIonsEnergy, MAXALLIONSENERGY);
492 InitPsiEnergyCalculation(P,Occupied);
493 CalculateDensityEnergy(P,1);
494 CalculateIonsEnergy(P);
495 CalculateEwald(P, 0);
496 EnergyAllReduce(P);
497/* if (R->DoUnOccupied) {
498 SetCurrentMinState(P,UnOccupied);
499 InitPsiEnergyCalculation(P,UnOccupied);
500 CalculateGapEnergy(P);
501 EnergyAllReduce(P);
502 }
503 if (R->DoPerturbation)
504 for(type=Perturbed_P0;type <=Perturbed_RxP2;type++) {
505 SetCurrentMinState(P,type);
506 InitPerturbedEnergyCalculation(P,1);
507 EnergyAllReduce(P);
508 }
509 SetCurrentMinState(P,Occupied);*/
510 E->TotalEnergyOuter[0] = E->TotalEnergy[0];
511 EnergyOutput(P,0);
512 R->ActualMaxMinStep = R->MaxMinStep*R->MaxPsiStep*R->MaxMinStepFactor;
513 R->ActualRelEpsTotalEnergy = R->RelEpsTotalEnergy;
514 R->ActualRelEpsKineticEnergy = R->RelEpsKineticEnergy;
515 R->ActualMaxMinStopStep = R->MaxMinStopStep;
516 R->ActualMaxMinGapStopStep = R->MaxMinGapStopStep;
517 R->MinStopStep = 0;
518}
519
520/** Evaluates the stop condition and returns 0 or 1 for occupied states.
521 * Stop is set when:
522 * - SuperStop at best possible point (e.g.\ LevelChange): RunStruct::PsiStep == 0 && SuperStop == 1
523 * - RunStruct::PsiStep && RunStruct::MinStopStep modulo RunStruct::ActualMaxMinStopStep == 0
524 * - To many minimisation steps: RunStruct::MinStep > RunStruct::ActualMaxMinStopStep
525 * - below relative rate of change:
526 * - Remember old values: Shift all RunStruct::TotalEnergy and RunStruct::KineticEnergy by
527 * one and transfer current one from Energy::TotalEnergy and Energy::AllTotalPsiEnergy[KineticEnergy].
528 * - if more than one minimisation step was made, calculate the relative changes of total
529 * energy and kinetic energy and store them in RunStruct::ActualRelTotalEnergy and
530 * RunStruct::ActualRelKineticEnergy and check them against the sought for minimum
531 * values RunStruct::ActualRelEpsTotalEnergy and RunStruct::ActualRelEpsKineticEnergy.
532 * - if RunStruct::PsiStep is zero (default), increase RunStruct::MinStopStep
533 * \param *P Problem at hand
534 * \param SuperStop 1 - external signal: ceasing calculation, 0 - no signal
535 * \return Stop: 1 - stop, 0 - continue
536 */
537int CalculateMinimumStop(struct Problem *P, int SuperStop)
538{
539 int Stop = 0, i;
540 struct RunStruct *R = &P->R;
541 struct Energy *E = P->Lat.E;
542 if (R->PsiStep == 0 && SuperStop) Stop = 1;
543 if (R->PsiStep == 0 && ((R->MinStopStep % R->ActualMaxMinStopStep == 0 && R->CurrentMin != UnOccupied) || (R->MinStopStep % R->ActualMaxMinGapStopStep == 0 && R->CurrentMin == UnOccupied))) {
544 if (R->MinStep >= R->ActualMaxMinStep) Stop = 1;
545 for (i=RUNMAXOLD-1; i > 0; i--) {
546 R->TotalEnergy[i] = R->TotalEnergy[i-1];
547 R->KineticEnergy[i] = R->KineticEnergy[i-1];
548 }
549 R->TotalEnergy[0] = E->TotalEnergy[0];
550 R->KineticEnergy[0] = E->AllTotalPsiEnergy[KineticEnergy];
551 if (R->MinStopStep) {
552 //if (R->TotalEnergy[1] < MYEPSILON) fprintf(stderr,"CalculateMinimumStop: R->TotalEnergy[1] = %lg\n",R->TotalEnergy[1]);
553 R->ActualRelTotalEnergy[0] = fabs((R->TotalEnergy[0]-R->TotalEnergy[1])/R->TotalEnergy[1]);
554 //if (R->KineticEnergy[1] < MYEPSILON) fprintf(stderr,"CalculateMinimumStop: R->KineticEnergy[1] = %lg\n",R->KineticEnergy[1]);
555 //if (R->CurrentMin < Perturbed_P0)
556 R->ActualRelKineticEnergy[0] = fabs((R->KineticEnergy[0]-R->KineticEnergy[1])/R->KineticEnergy[1]);
557 //else R->ActualRelKineticEnergy[0] = 0.;
558 if (P->Call.out[LeaderOut] && (P->Par.me == 0))
559 switch (R->CurrentMin) {
560 default:
561 fprintf(stderr, "ARelTE: %e\tARelKE: %e\n", R->ActualRelTotalEnergy[0], R->ActualRelKineticEnergy[0]);
562 break;
563 case UnOccupied:
564 fprintf(stderr, "ARelTGE: %e\tARelKGE: %e\n", R->ActualRelTotalEnergy[0], R->ActualRelKineticEnergy[0]);
565 break;
566 }
567 //fprintf(stderr, "(%i) Comparing TE: %lg < %lg\tKE: %lg < %lg?\n", P->Par.me, R->ActualRelTotalEnergy[0], R->ActualRelEpsTotalEnergy, R->ActualRelKineticEnergy[0], R->ActualRelEpsKineticEnergy);
568 if ((R->ActualRelTotalEnergy[0] < R->ActualRelEpsTotalEnergy) &&
569 (R->ActualRelKineticEnergy[0] < R->ActualRelEpsKineticEnergy))
570 Stop = 1;
571 }
572 }
573 if (R->PsiStep == 0)
574 R->MinStopStep++;
575 if (P->Call.WriteSrcFiles == 2)
576 OutputVisSrcFiles(P, R->CurrentMin);
577 return(Stop);
578}
579
580/** Evaluates the stop condition and returns 0 or 1 for gap energies.
581 * Stop is set when:
582 * - SuperStop at best possible point (e.g.\ LevelChange): RunStruct::PsiStep == 0 && SuperStop == 1
583 * - RunStruct::PsiStep && RunStruct::MinStopStep modulo RunStruct::ActualMaxMinStopStep == 0
584 * - To many minimisation steps: RunStruct::MinStep > RunStruct::ActualMaxMinStopStep
585 * - below relative rate of change:
586 * - Remember old values: Shift all RunStruct::TotalEnergy and RunStruct::KineticEnergy by
587 * one and transfer current one from Energy::TotalEnergy and Energy::AllTotalPsiEnergy[KineticEnergy].
588 * - if more than one minimisation step was made, calculate the relative changes of total
589 * energy and kinetic energy and store them in RunStruct::ActualRelTotalEnergy and
590 * RunStruct::ActualRelKineticEnergy and check them against the sought for minimum
591 * values RunStruct::ActualRelEpsTotalEnergy and RunStruct::ActualRelEpsKineticEnergy.
592 * - if RunStruct::PsiStep is zero (default), increase RunStruct::MinStopStep
593 * \param *P Problem at hand
594 * \param SuperStop 1 - external signal: ceasing calculation, 0 - no signal
595 * \return Stop: 1 - stop, 0 - continue
596 * \sa CalculateMinimumStop() - same procedure for occupied states
597 *//*
598static double CalculateGapStop(struct Problem *P, int SuperStop)
599{
600 int Stop = 0, i;
601 struct RunStruct *R = &P->R;
602 struct Lattice *Lat = &P->Lat;
603 struct Energy *E = P->Lat.E;
604 if (R->PsiStep == 0 && SuperStop) Stop = 1;
605 if (R->PsiStep == 0 && (R->MinStopStep % R->ActualMaxMinGapStopStep) == 0) {
606 if (R->MinStep >= R->ActualMaxMinStep) Stop = 1;
607 for (i=RUNMAXOLD-1; i > 0; i--) {
608 R->TotalGapEnergy[i] = R->TotalGapEnergy[i-1];
609 R->KineticGapEnergy[i] = R->KineticGapEnergy[i-1];
610 }
611 R->TotalGapEnergy[0] = Lat->Energy[UnOccupied].TotalEnergy[0];
612 R->KineticGapEnergy[0] = E->AllTotalPsiEnergy[GapPsiEnergy];
613 if (R->MinStopStep) {
614 if (R->TotalGapEnergy[1] < MYEPSILON) fprintf(stderr,"CalculateMinimumStop: R->TotalGapEnergy[1] = %lg\n",R->TotalGapEnergy[1]);
615 R->ActualRelTotalGapEnergy[0] = fabs((R->TotalGapEnergy[0]-R->TotalGapEnergy[1])/R->TotalGapEnergy[1]);
616 if (R->KineticGapEnergy[1] < MYEPSILON) fprintf(stderr,"CalculateMinimumStop: R->KineticGapEnergy[1] = %lg\n",R->KineticGapEnergy[1]);
617 R->ActualRelKineticGapEnergy[0] = fabs((R->KineticGapEnergy[0]-R->KineticGapEnergy[1])/R->KineticGapEnergy[1]);
618 if (P->Call.out[LeaderOut] && (P->Par.me == 0))
619 fprintf(stderr, "(%i) -------------------------> ARelTGE: %e\tARelKGE: %e\n", P->Par.me, R->ActualRelTotalGapEnergy[0], R->ActualRelKineticGapEnergy[0]);
620 if ((R->ActualRelTotalGapEnergy[0] < R->ActualRelEpsTotalGapEnergy) &&
621 (R->ActualRelKineticGapEnergy[0] < R->ActualRelEpsKineticGapEnergy))
622 Stop = 1;
623 }
624 }
625 if (R->PsiStep == 0)
626 R->MinStopStep++;
627
628 return(Stop);
629}*/
630
631#define StepTolerance 1e-4
632
633static void CalculateEnergy(struct Problem *P) {
634 SpeedMeasure(P, DensityTime, StartTimeDo);
635 UpdateDensityCalculation(P);
636 SpeedMeasure(P, DensityTime, StopTimeDo);
637 UpdatePsiEnergyCalculation(P);
638 CalculateDensityEnergy(P, 0);
639 //CalculateIonsEnergy(P);
640 EnergyAllReduce(P);
641}
642
643/** Energy functional depending on one parameter \a x (for a certain Psi in a certain conjugate direction).
644 * \param x parameter for the which the function must be minimized
645 * \param *params additional params
646 * \return total energy if Psi is changed according to the given parameter
647 */
648static double fn1 (double x, void * params) {
649 struct Problem *P = (struct Problem *)(params);
650 struct RunStruct *R = &P->R;
651 struct Lattice *Lat = &P->Lat;
652 struct LatticeLevel *LevS = R->LevS;
653 int ElementSize = (sizeof(fftw_complex) / sizeof(double));
654 int i=R->ActualLocalPsiNo;
655 double ret;
656
657 //fprintf(stderr,"(%i) Evaluating fnl at %lg ...\n",P->Par.me, x);
658 //TestForOrth(P,R->LevS,P->Grad.GradientArray[GraSchGradient]);
659 CalculateNewWave(P, &x); // also stores Psi to oldPsi
660 //TestGramSch(P,R->LevS,&P->Lat.Psi,Occupied);
661 //fprintf(stderr,"(%i) Testing for orthogonality of %i against ...\n",P->Par.me, R->ActualLocalPsiNo);
662 //TestForOrth(P, LevS, LevS->LPsi->LocalPsi[R->ActualLocalPsiNo]);
663 //UpdateActualPsiNo(P, Occupied);
664 //UpdateEnergyArray(P);
665 CalculateEnergy(P);
666 ret = Lat->E->TotalEnergy[0];
667 memcpy(LevS->LPsi->LocalPsi[i], LevS->LPsi->OldLocalPsi[i], ElementSize*LevS->MaxG*sizeof(double)); // restore old Psi from OldPsi
668 //fprintf(stderr,"(%i) Psi %i at %p retrieved from OldPsi at %p: Old[0] %lg+i%lg\n", P->Par.me, R->ActualLocalPsiNo, LevS->LPsi->LocalPsi[R->ActualLocalPsiNo], LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo], LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo][0].re, LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo][0].im);
669 CalculateEnergy(P);
670 //fprintf(stderr,"(%i) fnl(%lg) = %lg\n", P->Par.me, x, ret);
671 return ret;
672}
673
674#ifdef HAVE_INLINE
675inline void flip(double *a, double *b) {
676#else
677void flip(double *a, double *b) {
678#endif
679 double tmp = *a;
680 *a = *b;
681 *b = tmp;
682}
683
684
685/** Minimise PsiType#Occupied orbitals.
686 * It is checked whether CallOptions#ReadSrcFiles is set and thus coefficients for the level have to be
687 * read from file and afterwards initialized.
688 *
689 * Then follows the main loop, until a stop condition is met:
690 * -# CalculateNewWave()\n
691 * Over a conjugate gradient method the next (minimal) wave function is sought for.
692 * -# UpdateActualPsiNo()\n
693 * Switch local Psi to next one.
694 * -# UpdateEnergyArray()\n
695 * Shift archived energy values to make space for next one.
696 * -# UpdateDensityCalculation(), SpeedMeasure()'d in DensityTime\n
697 * Calculate TotalLocalDensity of LocalPsis and gather results as TotalDensity.
698 * -# UpdatePsiEnergyCalculation()\n
699 * Calculate kinetic and non-local energy contributons from the Psis.
700 * -# CalculateDensityEnergy()\n
701 * Calculate remaining energy contributions from the Density and adds \f$V_xc\f$ onto DensityTypes#HGDensity.
702 * -# CalculateIonsEnergy()\n
703 * Calculate the Gauss self energy of the Ions.
704 * -# EnergyAllReduce()\n
705 * Gather PsiEnergy results from all processes and sum up together with all other contributions to TotalEnergy.
706 * -# CheckCPULIM()\n
707 * Check if external signal has been received (e.g. end of time slit on cluster), break operation at next possible moment.
708 * -# CalculateMinimumStop()\n
709 * Evaluates stop condition if desired precision or steps or ... have been reached. Otherwise go to
710 * CalculateNewWave().
711 *
712 * Before return orthonormality is tested.
713 * \param *P Problem at hand
714 * \param *Stop flag to determine if epsilon stop conditions have met
715 * \param *SuperStop flag to determinte whether external signal's required end of calculations
716 * \bug ResetGramSch() not allowed after reading orthonormal values from file
717 */
718static void MinimiseOccupied(struct Problem *P, int *Stop, int *SuperStop)
719{
720 struct RunStruct *R = &P->R;
721 struct Lattice *Lat = &P->Lat;
722 struct Psis *Psi = &Lat->Psi;
723 //struct FileData *F = &P->Files;
724// int i;
725// double norm;
726 //double dEdt0,ddEddt0,HartreeddEddt0,XCddEddt0, d[4], D[4],ConDirHConDir;
727 struct LatticeLevel *LevS = R->LevS;
728 int ElementSize = (sizeof(fftw_complex) / sizeof(double));
729 int iter = 0, status, max_iter=10;
730 const gsl_min_fminimizer_type *T;
731 gsl_min_fminimizer *s;
732 double m, a, b;
733 double f_m = 0., f_a, f_b;
734 double dcos, dsin;
735 int g;
736 fftw_complex *ConDir = P->Grad.GradientArray[ConDirGradient];
737 fftw_complex *source = NULL, *oldsource = NULL;
738 gsl_function F;
739 F.function = &fn1;
740 F.params = (void *) P;
741 T = gsl_min_fminimizer_brent;
742 s = gsl_min_fminimizer_alloc (T);
743 int DoBrent, StartLocalPsiNo;
744
745 ResetBrent(P,Psi);
746 *Stop = 0;
747 if (P->Call.ReadSrcFiles != DoNotParse) {
748 if (!ReadSrcPsiDensity(P,Occupied,1, R->LevSNo)) { // if file for level exists and desired, read from file
749 P->Call.ReadSrcFiles = DoNotParse; // -r was bogus, remove it, have to start anew
750 if(P->Call.out[MinOut]) fprintf(stderr,"(%i) Re-initializing, files are missing/corrupted...\n", P->Par.me);
751 InitPsisValue(P, Psi->TypeStartIndex[Occupied], Psi->TypeStartIndex[Occupied+1]); // initialize perturbed array for this run
752 ResetGramSchTagType(P, Psi, Occupied, NotOrthogonal); // loaded values are orthonormal
753 } else {
754 SpeedMeasure(P, InitSimTime, StartTimeDo);
755 if(P->Call.out[MinOut]) fprintf(stderr, "(%i) Re-initializing %s psi array from source file of recent calculation\n", P->Par.me, R->MinimisationName[R->CurrentMin]);
756 ReadSrcPsiDensity(P, Occupied, 0, R->LevSNo);
757 //ResetGramSchTagType(P, Psi, Occupied, IsOrthonormal); // loaded values are orthonormal
758 // note: this did not work and is currently not clear why not (as TestGramSch says: OK, but minimisation goes awry without the following GramSch)
759 }
760 SpeedMeasure(P, InitGramSchTime, StartTimeDo);
761 GramSch(P, R->LevS, Psi, Orthonormalize);
762 SpeedMeasure(P, InitGramSchTime, StopTimeDo);
763 SpeedMeasure(P, InitDensityTime, StartTimeDo);
764 InitDensityCalculation(P);
765 SpeedMeasure(P, InitDensityTime, StopTimeDo);
766 InitPsiEnergyCalculation(P, Occupied); // go through all orbitals calculating kinetic and non-local
767 StartLocalPsiNo = R->ActualLocalPsiNo;
768 do { // otherwise OnePsiElementAddData#Lambda is calculated only for current Psi not for all
769 CalculateDensityEnergy(P, 0);
770 UpdateActualPsiNo(P, Occupied);
771 } while (R->ActualLocalPsiNo != StartLocalPsiNo);
772 CalculateIonsEnergy(P);
773 EnergyAllReduce(P);
774 SpeedMeasure(P, InitSimTime, StopTimeDo);
775 R->LevS->Step++;
776 EnergyOutput(P,0);
777 }
778 if ((P->Call.ReadSrcFiles != DoReadAllSrcDensities) && (P->Call.ReadSrcFiles != DoReadOccupiedSrcDensities)) { // otherwise minimise oneself
779 if(P->Call.out[LeaderOut]) fprintf(stderr,"(%i)Beginning minimisation of type %s ...\n", P->Par.me, R->MinimisationName[Occupied]);
780 while (*Stop != 1) { // loop testing condition over all Psis
781 // in the following loop, we have two cases:
782 // 1) still far away and just guessing: Use the normal CalculateNewWave() to improve Psi
783 // 2) closer (DoBrent=-1): use brent line search instead
784 // and due to these two cases, we also have two ifs inside each in order to catch stepping from one case
785 // to the other - due to decreasing DoBrent and/or stepping to the next Psi (which may not yet be DoBrent==1)
786
787 // case 1)
788 if (Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent != 1) {
789 //SetArrayToDouble0((double *)LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo],LevS->MaxG*2);
790 if (R->DoBrent == 1) {
791 memcpy(LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo], LevS->LPsi->LocalPsi[R->ActualLocalPsiNo], ElementSize*LevS->MaxG*sizeof(double)); // restore old Psi from OldPsi
792 //fprintf(stderr,"(%i) Psi %i at %p stored in OldPsi at %p: Old[0] %lg+i%lg\n", P->Par.me, R->ActualLocalPsiNo, LevS->LPsi->LocalPsi[R->ActualLocalPsiNo], LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo], LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo][0].re, LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo][0].im);
793 f_m = P->Lat.E->TotalEnergy[0]; // grab first value
794 m = 0.;
795 }
796 CalculateNewWave(P,NULL);
797 if ((R->DoBrent == 1) && (fabs(Lat->E->delta[0]) < M_PI/4.))
798 Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent--;
799 if (Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent != 1) {
800 UpdateActualPsiNo(P, Occupied);
801 UpdateEnergyArray(P);
802 CalculateEnergy(P); // just to get a sensible delta
803 if ((R->ActualLocalPsiNo != R->OldActualLocalPsiNo) && (Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent == 1)) {
804 R->OldActualLocalPsiNo = R->ActualLocalPsiNo;
805 // if we stepped on to a new Psi, which is already down at DoBrent=1 unlike the last one,
806 // then an up-to-date gradient is missing for the following Brent line search
807 if(P->Call.out[MinOut]) fprintf(stderr,"(%i) We stepped on to a new Psi, which is already in the Brent regime ...re-calc delta\n", P->Par.me);
808 memcpy(LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo], LevS->LPsi->LocalPsi[R->ActualLocalPsiNo], ElementSize*LevS->MaxG*sizeof(double)); // restore old Psi from OldPsi
809 //fprintf(stderr,"(%i) Psi %i at %p stored in OldPsi at %p: Old[0] %lg+i%lg\n", P->Par.me, R->ActualLocalPsiNo, LevS->LPsi->LocalPsi[R->ActualLocalPsiNo], LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo], LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo][0].re, LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo][0].im);
810 f_m = P->Lat.E->TotalEnergy[0]; // grab first value
811 m = 0.;
812 DoBrent = Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent;
813 Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent = 2;
814 CalculateNewWave(P,NULL);
815 Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent = DoBrent;
816 }
817 //fprintf(stderr,"(%i) fnl(%lg) = %lg\n", P->Par.me, m, f_m);
818 }
819 }
820
821 // case 2)
822 if (Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent == 1) {
823 R->PsiStep=R->MaxPsiStep; // no more fresh gradients from this point for current ActualLocalPsiNo
824 a = b = 0.5*fabs(Lat->E->delta[0]);
825 // we have a meaningful first minimum guess from above CalculateNewWave() resp. from end of this if of last step: Lat->E->delta[0]
826 source = LevS->LPsi->LocalPsi[R->ActualLocalPsiNo];
827 oldsource = LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo];
828 //SetArrayToDouble0((double *)source,LevS->MaxG*2);
829 do {
830 a -= fabs(Lat->E->delta[0]) == 0 ? 0.1 : fabs(Lat->E->delta[0]);
831 if (a < -M_PI/2.) a = -M_PI/2.;// for this to work we need the pre-estimation which leads us into a nice regime (without gradient being the better _initial_ guess for a Psi)
832 dcos = cos(a);
833 dsin = sin(a);
834 for (g = 0; g < LevS->MaxG; g++) { // Here all coefficients are updated for the new found wave function
835 //if (isnan(ConDir[g].re)) { fprintf(stderr,"WARNGING: CalculateLineSearch(): ConDir_%i(%i) = NaN!\n", R->ActualLocalPsiNo, g); Error(SomeError, "NaN-Fehler!"); }
836 c_re(source[g]) = c_re(oldsource[g])*dcos + c_re(ConDir[g])*dsin;
837 c_im(source[g]) = c_im(oldsource[g])*dcos + c_im(ConDir[g])*dsin;
838 }
839 CalculateEnergy(P);
840 f_a = P->Lat.E->TotalEnergy[0]; // grab second value at left border
841 //fprintf(stderr,"(%i) fnl(%lg) = %lg, Check ConDir[0] = %lg+i%lg, source[0] = %lg+i%lg, oldsource[0] = %lg+i%lg, TotDens[0] = %lg\n", P->Par.me, a, f_a, ConDir[0].re, ConDir[0].im, source[0].re, source[0].im, oldsource[0].re, oldsource[0].im, R->Lev0->Dens->DensityArray[TotalDensity][0]);
842 } while (f_a < f_m);
843
844 //SetArrayToDouble0((double *)source,LevS->MaxG*2);
845 do {
846 b += fabs(Lat->E->delta[0]) == 0 ? 0.1 : fabs(Lat->E->delta[0]);
847 if (b > M_PI/2.) b = M_PI/2.;
848 dcos = cos(b);
849 dsin = sin(b);
850 for (g = 0; g < LevS->MaxG; g++) { // Here all coefficients are updated for the new found wave function
851 //if (isnan(ConDir[g].re)) { fprintf(stderr,"WARNGING: CalculateLineSearch(): ConDir_%i(%i) = NaN!\n", R->ActualLocalPsiNo, g); Error(SomeError, "NaN-Fehler!"); }
852 c_re(source[g]) = c_re(oldsource[g])*dcos + c_re(ConDir[g])*dsin;
853 c_im(source[g]) = c_im(oldsource[g])*dcos + c_im(ConDir[g])*dsin;
854 }
855 CalculateEnergy(P);
856 f_b = P->Lat.E->TotalEnergy[0]; // grab second value at left border
857 //fprintf(stderr,"(%i) fnl(%lg) = %lg\n", P->Par.me, b, f_b);
858 } while (f_b < f_m);
859
860 memcpy(source, oldsource, ElementSize*LevS->MaxG*sizeof(double)); // restore old Psi from OldPsi
861 //fprintf(stderr,"(%i) Psi %i at %p retrieved from OldPsi at %p: Old[0] %lg+i%lg\n", P->Par.me, R->ActualLocalPsiNo, LevS->LPsi->LocalPsi[R->ActualLocalPsiNo], LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo], LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo][0].re, LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo][0].im);
862 CalculateEnergy(P);
863
864 if(P->Call.out[ValueOut]) fprintf(stderr,"(%i) Preparing brent with f(a) (%lg,%lg)\t f(b) (%lg,%lg)\t f(m) (%lg,%lg) ...\n", P->Par.me,a,f_a,b,f_b,m,f_m);
865 iter=0;
866 gsl_min_fminimizer_set_with_values (s, &F, m, f_m, a, f_a, b, f_b);
867 if(P->Call.out[ValueOut]) fprintf (stderr,"(%i) using %s method\n",P->Par.me, gsl_min_fminimizer_name (s));
868 if(P->Call.out[ValueOut]) fprintf (stderr,"(%i) %5s [%9s, %9s] %9s %9s\n",P->Par.me, "iter", "lower", "upper", "min", "err(est)");
869 if(P->Call.out[ValueOut]) fprintf (stderr,"(%i) %5d [%.7f, %.7f] %.7f %.7f\n",P->Par.me, iter, a, b, m, b - a);
870 do {
871 iter++;
872 status = gsl_min_fminimizer_iterate (s);
873
874 m = gsl_min_fminimizer_x_minimum (s);
875 a = gsl_min_fminimizer_x_lower (s);
876 b = gsl_min_fminimizer_x_upper (s);
877
878 status = gsl_min_test_interval (a, b, 0.001, 0.0);
879
880 if (status == GSL_SUCCESS)
881 if(P->Call.out[ValueOut]) fprintf (stderr,"(%i) Converged:\n",P->Par.me);
882
883 if(P->Call.out[ValueOut]) fprintf (stderr,"(%i) %5d [%.7f, %.7f] %.7f %.7f\n",P->Par.me,
884 iter, a, b, m, b - a);
885 } while (status == GSL_CONTINUE && iter < max_iter);
886 CalculateNewWave(P,&m);
887 TestGramSch(P,LevS,Psi,Occupied);
888 UpdateActualPsiNo(P, Occupied); // step on due setting to MaxPsiStep further above
889 UpdateEnergyArray(P);
890 CalculateEnergy(P);
891 //fprintf(stderr,"(%i) Final value for Psi %i: %lg\n", P->Par.me, R->ActualLocalPsiNo, P->Lat.E->TotalEnergy[0]);
892 R->MinStopStep = R->ActualMaxMinStopStep; // check stop condition every time
893 if (*SuperStop != 1)
894 *SuperStop = CheckCPULIM(P);
895 *Stop = CalculateMinimumStop(P, *SuperStop);
896 R->OldActualLocalPsiNo = R->ActualLocalPsiNo;
897 if (Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent == 1) { // new wave function means new gradient!
898 DoBrent = Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent;
899 Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent = 2;
900 //SetArrayToDouble0((double *)LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo],LevS->MaxG*2);
901 memcpy(LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo], LevS->LPsi->LocalPsi[R->ActualLocalPsiNo], ElementSize*LevS->MaxG*sizeof(double)); // restore old Psi from OldPsi
902 //fprintf(stderr,"(%i) Psi %i at %p stored in OldPsi at %p: Old[0] %lg+i%lg\n", P->Par.me, R->ActualLocalPsiNo, LevS->LPsi->LocalPsi[R->ActualLocalPsiNo], LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo], LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo][0].re, LevS->LPsi->OldLocalPsi[R->ActualLocalPsiNo][0].im);
903 f_m = P->Lat.E->TotalEnergy[0]; // grab first value
904 m = 0.;
905 CalculateNewWave(P,NULL);
906 Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent = DoBrent;
907 }
908 }
909
910 if (Lat->Psi.LocalPsiStatus[R->ActualLocalPsiNo].DoBrent != 1) { // otherwise the following checks eliminiate stop=1 from above
911 if (*SuperStop != 1)
912 *SuperStop = CheckCPULIM(P);
913 *Stop = CalculateMinimumStop(P, *SuperStop);
914 }
915 /*EnergyOutput(P, Stop);*/
916 P->Speed.Steps++;
917 R->LevS->Step++;
918 /*ControlNativeDensity(P);*/
919 //fprintf(stderr,"(%i) Stop %i\n",P->Par.me, Stop);
920 }
921 if (*SuperStop == 1) OutputVisSrcFiles(P, Occupied); // is now done after localization (ComputeMLWF())
922 }
923 TestGramSch(P,R->LevS,Psi, Occupied);
924}
925
926/** Minimisation of the PsiTagType#UnOccupied orbitals in the field of the occupied ones.
927 * Assuming RunStruct#ActualLocalPsiNo is currenlty still an occupied wave function, we stop onward to the first
928 * unoccupied and reset RunStruct#OldActualLocalPsiNo. Then it is checked whether CallOptions#ReadSrcFiles is set
929 * and thus coefficients for the level have to be read from file and afterwards initialized.
930 *
931 * Then follows the main loop, until a stop condition is met:
932 * -# CalculateNewWave()\n
933 * Over a conjugate gradient method the next (minimal) wave function is sought for.
934 * -# UpdateActualPsiNo()\n
935 * Switch local Psi to next one.
936 * -# UpdateEnergyArray()\n
937 * Shift archived energy values to make space for next one.
938 * -# UpdateDensityCalculation(), SpeedMeasure()'d in DensityTime\n
939 * Calculate TotalLocalDensity of LocalPsis and gather results as TotalDensity.
940 * -# UpdatePsiEnergyCalculation()\n
941 * Calculate kinetic and non-local energy contributons from the Psis.
942 * -# CalculateGapEnergy()\n
943 * Calculate Gap energies (Hartreepotential, Pseudo) and the gradient.
944 * -# EnergyAllReduce()\n
945 * Gather PsiEnergy results from all processes and sum up together with all other contributions to TotalEnergy.
946 * -# CheckCPULIM()\n
947 * Check if external signal has been received (e.g. end of time slit on cluster), break operation at next possible moment.
948 * -# CalculateMinimumStop()\n
949 * Evaluates stop condition if desired precision or steps or ... have been reached. Otherwise go to
950 * CalculateNewWave().
951 *
952 * Afterwards, the coefficients are written to file by OutputVisSrcFiles() if desired. Orthonormality is tested, we step
953 * back to the occupied wave functions and the densities are re-initialized.
954 * \param *P Problem at hand
955 * \param *Stop flag to determine if epsilon stop conditions have met
956 * \param *SuperStop flag to determinte whether external signal's required end of calculations
957 */
958static void MinimiseUnoccupied (struct Problem *P, int *Stop, int *SuperStop) {
959 struct RunStruct *R = &P->R;
960 struct Lattice *Lat = &P->Lat;
961 struct Psis *Psi = &Lat->Psi;
962 int StartLocalPsiNo;
963
964 *Stop = 0;
965 R->PsiStep = R->MaxPsiStep; // in case it's zero from CalculateForce()
966 UpdateActualPsiNo(P, UnOccupied); // step on to next unoccupied one
967 R->OldActualLocalPsiNo = R->ActualLocalPsiNo; // reset, otherwise OldActualLocalPsiNo still points to occupied wave function
968 UpdateGramSchOldActualPsiNo(P,Psi);
969 if ((P->Call.ReadSrcFiles == DoReadAllSrcDensities) && ReadSrcPsiDensity(P,UnOccupied,1, R->LevSNo)) {
970 SpeedMeasure(P, InitSimTime, StartTimeDo);
971 if(P->Call.out[MinOut]) fprintf(stderr, "(%i) Re-initializing %s psi array from source file of recent calculation\n", P->Par.me, R->MinimisationName[R->CurrentMin]);
972 ReadSrcPsiDensity(P, UnOccupied, 0, R->LevSNo);
973 if (P->Call.ReadSrcFiles < DoReadAndMinimise) {
974 ResetGramSchTagType(P, Psi, UnOccupied, IsOrthonormal); // loaded values are orthonormal
975 SpeedMeasure(P, DensityTime, StartTimeDo);
976 InitDensityCalculation(P);
977 SpeedMeasure(P, DensityTime, StopTimeDo);
978 InitPsiEnergyCalculation(P,UnOccupied); // go through all orbitals calculating kinetic and non-local
979 //CalculateDensityEnergy(P, 0);
980 StartLocalPsiNo = R->ActualLocalPsiNo;
981 do { // otherwise OnePsiElementAddData#Lambda is calculated only for current Psi not for all
982 CalculateGapEnergy(P);
983 UpdateActualPsiNo(P, Occupied);
984 } while (R->ActualLocalPsiNo != StartLocalPsiNo);
985 EnergyAllReduce(P);
986 }
987 SpeedMeasure(P, InitSimTime, StopTimeDo);
988 }
989 if (P->Call.ReadSrcFiles != DoReadAllSrcDensities) {
990 SpeedMeasure(P, InitSimTime, StartTimeDo);
991 ResetGramSchTagType(P, Psi, UnOccupied, NotOrthogonal);
992 SpeedMeasure(P, GramSchTime, StartTimeDo);
993 GramSch(P, R->LevS, Psi, Orthonormalize);
994 SpeedMeasure(P, GramSchTime, StopTimeDo);
995 SpeedMeasure(P, InitDensityTime, StartTimeDo);
996 InitDensityCalculation(P);
997 SpeedMeasure(P, InitDensityTime, StopTimeDo);
998 InitPsiEnergyCalculation(P,UnOccupied); // go through all orbitals calculating kinetic and non-local
999 //CalculateDensityEnergy(P, 0);
1000 CalculateGapEnergy(P);
1001 EnergyAllReduce(P);
1002 SpeedMeasure(P, InitSimTime, StopTimeDo);
1003 R->LevS->Step++;
1004 EnergyOutput(P,0);
1005 if(P->Call.out[LeaderOut]) fprintf(stderr,"(%i)Beginning minimisation of type %s ...\n", P->Par.me, R->MinimisationName[R->CurrentMin]);
1006 while (*Stop != 1) {
1007 CalculateNewWave(P,NULL);
1008 UpdateActualPsiNo(P, UnOccupied);
1009 /* New */
1010 UpdateEnergyArray(P);
1011 SpeedMeasure(P, DensityTime, StartTimeDo);
1012 UpdateDensityCalculation(P);
1013 SpeedMeasure(P, DensityTime, StopTimeDo);
1014 UpdatePsiEnergyCalculation(P);
1015 //CalculateDensityEnergy(P, 0);
1016 CalculateGapEnergy(P); //calculates XC, HGDensity, afterwards gradient, where V_xc is added upon HGDensity
1017 EnergyAllReduce(P);
1018 if (*SuperStop != 1)
1019 *SuperStop = CheckCPULIM(P);
1020 *Stop = CalculateMinimumStop(P, *SuperStop);
1021 /*EnergyOutput(P, Stop);*/
1022 P->Speed.Steps++;
1023 R->LevS->Step++;
1024 /*ControlNativeDensity(P);*/
1025 }
1026 OutputVisSrcFiles(P, UnOccupied);
1027// if (!TestReadnWriteSrcDensity(P,UnOccupied))
1028// Error(SomeError,"TestReadnWriteSrcDensity failed!");
1029 }
1030 TestGramSch(P,R->LevS,Psi, UnOccupied);
1031 ResetGramSchTagType(P, Psi, UnOccupied, NotUsedToOrtho);
1032 // re-calculate Occupied values (in preparation for perturbed ones)
1033 UpdateActualPsiNo(P, Occupied); // step on to next occupied one
1034 SpeedMeasure(P, DensityTime, StartTimeDo);
1035 InitDensityCalculation(P); // re-init densities to occupied standard
1036 SpeedMeasure(P, DensityTime, StopTimeDo);
1037// InitPsiEnergyCalculation(P,Occupied);
1038// CalculateDensityEnergy(P, 0);
1039// EnergyAllReduce(P);
1040}
1041
1042
1043/** Calculate the forces.
1044 * From RunStruct::LevSNo downto RunStruct::InitLevSNo the following routines are called in a loop:
1045 * -# In case of RunStruct#DoSeparated another loop begins for the unoccupied states with some reinitalization
1046 * before and afterwards. The loop however is much the same as the one above.
1047 * -# ChangeToLevUp()\n
1048 * Repeat the loop or when the above stop is reached, the level is changed and the loop repeated.
1049 *
1050 * Afterwards comes the actual force and energy calculation by calling:
1051 * -# ControlNativeDensity()\n
1052 * Checks if the density still reproduces particle number.
1053 * -# CalculateIonLocalForce(), SpeedMeasure()'d in LocFTime\n
1054 * Calculale local part of force acting on Ions.
1055 * -# CalculateIonNonLocalForce(), SpeedMeasure()'d in NonLocFTime\n
1056 * Calculale local part of force acting on Ions.
1057 * -# CalculateEwald()\n
1058 * Calculate Ewald force acting on Ions.
1059 * -# CalculateIonForce()\n
1060 * Sum up those three contributions.
1061 * -# CorrectForces()\n
1062 * Shifts center of gravity of all forces for each Ion, so that the cell itself remains at rest.
1063 * -# GetOuterStop()
1064 * Calculates a mean force per Ion.
1065 * \param *P Problem at hand
1066 * \return 1 - cpulim received, break operation, 0 - continue as normal
1067 */
1068int CalculateForce(struct Problem *P)
1069{
1070 struct RunStruct *R = &P->R;
1071 struct Lattice *Lat = &P->Lat;
1072 struct Psis *Psi = &Lat->Psi;
1073 struct LatticeLevel *LevS = R->LevS;
1074 struct FileData *F = &P->Files;
1075 struct Ions *I = &P->Ion;
1076 int Stop=0, SuperStop = 0, OuterStop = 0;
1077 //int i, j;
1078 SpeedMeasure(P, SimTime, StartTimeDo);
1079 if ((F->DoOutVis == 2) || (P->Call.ForcesFile == NULL)) { // if we want to draw those pretty density pictures, we have to solve the ground state in any case
1080 while ((R->LevSNo > R->InitLevSNo) || (!Stop && R->LevSNo == R->InitLevSNo)) {
1081 // occupied
1082 R->PsiStep = R->MaxPsiStep; // reset in-Psi-minimisation-counter, so that we really advance to the next wave function
1083 R->OldActualLocalPsiNo = R->ActualLocalPsiNo; // reset OldActualLocalPsiNo, as it might still point to a perturbed wave function from last level
1084 UpdateGramSchOldActualPsiNo(P,Psi);
1085 ControlNativeDensity(P);
1086 MinimiseOccupied(P, &Stop, &SuperStop);
1087 if (!I->StructOpt) {
1088 if (((P->Call.ReadSrcFiles != DoReadAllSrcDensities) || (P->Call.ReadSrcFiles != DoReadOccupiedSrcDensities)) || (!ParseWannierFile(P))) { // only localize and store if they have just been minimised (hence don't come solely from file), otherwise read stored values from file (if possible)
1089 SpeedMeasure(P, WannierTime, StartTimeDo);
1090 ComputeMLWF(P); // localization of orbitals
1091 SpeedMeasure(P, WannierTime, StopTimeDo);
1092 OutputVisSrcFiles(P, Occupied); // rewrite now localized orbitals
1093 // if (!TestReadnWriteSrcDensity(P,Occupied))
1094 // Error(SomeError,"TestReadnWriteSrcDensity failed!");
1095 }
1096
1097// // plot psi cuts
1098// for (i=0; i < Psi->MaxPsiOfType; i++) // go through all wave functions (here without the extra ones for each process)
1099// if ((Psi->AllPsiStatus[i].PsiType == Occupied) && (Psi->AllPsiStatus[i].my_color_comm_ST_Psi == P->Par.my_color_comm_ST_Psi))
1100// for (j=0;j<NDIM;j++) {
1101// //fprintf(stderr,"(%i) Plotting Psi %i/%i cut axis %i at coordinate %lg \n",P->Par.me, i, Psi->AllPsiStatus[i].MyGlobalNo, j, Lat->Psi.AddData[Psi->AllPsiStatus[i].MyLocalNo].WannierCentre[j]);
1102// CalculateOneDensityR(Lat, R->LevS, R->Lev0->Dens, R->LevS->LPsi->LocalPsi[Psi->AllPsiStatus[i].MyLocalNo], R->Lev0->Dens->DensityArray[ActualDensity], R->FactorDensityR, 0);
1103// PlotSrcPlane(P, j, Lat->Psi.AddData[Psi->AllPsiStatus[i].MyLocalNo].WannierCentre[j], Psi->AllPsiStatus[i].MyGlobalNo, R->Lev0->Dens->DensityArray[ActualDensity]);
1104// }
1105
1106 // unoccupied calc
1107 if (R->DoUnOccupied) {
1108 MinimiseUnoccupied(P, &Stop, &SuperStop);
1109 }
1110 // hamiltonian
1111 CalculateHamiltonian(P); // lambda_{kl} needed (and for bandgap after UnOccupied)
1112
1113 //TestSawtooth(P, 0);
1114 //TestSawtooth(P, 1);
1115 //TestSawtooth(P, 2);
1116
1117 // perturbed calc
1118 if ((R->DoPerturbation)) { // && R->LevSNo <= R->InitLevSNo) {
1119 AllocCurrentDensity(R->Lev0->Dens);// lock current density arrays
1120 MinimisePerturbed(P, &Stop, &SuperStop); // herein InitDensityCalculation() is called, thus no need to call it beforehand
1121
1122 SpeedMeasure(P, CurrDensTime, StartTimeDo);
1123 if (SuperStop != 1) {
1124 if ((R->DoFullCurrent == 1) || ((R->DoFullCurrent == 2) && (CheckOrbitalOverlap(P) == 1))) { //test to check whether orbitals have mutual overlap and thus \\DeltaJ_{xc} must not be dropped
1125 R->DoFullCurrent = 1; // set to 1 if it was 2 but Check...() yielded necessity
1126 //debug(P,"Filling with Delta j ...");
1127 FillDeltaCurrentDensity(P);
1128 }
1129 }
1130 SpeedMeasure(P, CurrDensTime, StopTimeDo);
1131 TestCurrent(P,0);
1132 TestCurrent(P,1);
1133 TestCurrent(P,2);
1134 if (F->DoOutCurr && R->Lev0->LevelNo == 0) // only output in uppermost level)
1135 OutputCurrentDensity(P);
1136 if (R->VectorPlane != -1)
1137 PlotVectorPlane(P,R->VectorPlane,R->VectorCut);
1138 CalculateMagneticSusceptibility(P);
1139 debug(P,"Normal calculation of shielding over R-space");
1140 CalculateMagneticMoment(P);
1141 CalculateChemicalShieldingByReciprocalCurrentDensity(P);
1142 SpeedMeasure(P, CurrDensTime, StopTimeDo);
1143 DisAllocCurrentDensity(R->Lev0->Dens); // unlock current density arrays
1144 } // end of if perturbation
1145 InitDensityCalculation(P); // all unperturbed(!) wave functions've "changed" from ComputeMLWF(), thus reinit density
1146 } else // end of if StructOpt or MaxOuterStep
1147 OutputVisSrcFiles(P, Occupied); // in structopt or MD write for every level
1148
1149 if ((!I->StructOpt) && (!R->MaxOuterStep)) // print intermediate levels energy results if we don't do MD or StructOpt
1150 EnergyOutput(P, 1);
1151 // next level
1152 ChangeToLevUp(P, &Stop);
1153 //if (isnan(LevS->LPsi->LocalPsi[R->ActualLocalPsiNo][0].re)) { fprintf(stderr,"(%i) WARNING in ChangeToLevUp(): LPsi->LocalPsi[%i]_[%i] = NaN!\n", P->Par.me, R->ActualLocalPsiNo, 0); Error(SomeError, "NaN-Fehler!"); }
1154 LevS = R->LevS; // re-set pointer that's changed from LevUp
1155 }
1156 SpeedMeasure(P, SimTime, StopTimeDo);
1157 ControlNativeDensity(P);
1158 TestGramSch(P,LevS,Psi, Occupied);
1159 // necessary for correct ionic forces ...
1160 SpeedMeasure(P, LocFTime, StartTimeDo);
1161 CalculateIonLocalForce(P);
1162 SpeedMeasure(P, LocFTime, StopTimeDo);
1163 SpeedMeasure(P, NonLocFTime, StartTimeDo);
1164 CalculateIonNonLocalForce(P);
1165 SpeedMeasure(P, NonLocFTime, StopTimeDo);
1166 CalculateEwald(P, 1);
1167 CalculateIonForce(P);
1168 }
1169 if (P->Call.ForcesFile != NULL) { // if we parse forces from file, values are written over (in case of DoOutVis)
1170 fprintf(stderr, "Parsing Forces from file.\n");
1171 ParseIonForce(P);
1172 //CalculateIonForce(P);
1173 }
1174 CorrectForces(P);
1175 // ... on output of densities
1176 if (F->DoOutOrbitals) { // output of each orbital
1177 debug(P,"OutputVisAllOrbital");
1178 OutputVisAllOrbital(P,0,1,Occupied);
1179 }
1180 //OutputNorm(P);
1181 //fprintf(stderr,"(%i) DoubleG: %p, CArray[22]: %p, OldLocalPsi: %p\n", P->Par.me, R->LevS->DoubleG, R->Lev0->Dens->DensityCArray[22], R->LevS->LPsi->OldLocalPsi);
1182 //OutputVis(P, P->R.Lev0->Dens->DensityArray[TotalDensity]);
1183 /*TestGramSch(P, R->LevS, &P->Lat.Psi); */
1184 GetOuterStop(P);
1185 //fprintf(stderr,"(%i) DoubleG: %p, CArray[22]: %p, OldLocalPsi: %p\n", P->Par.me, R->LevS->DoubleG, R->Lev0->Dens->DensityCArray[22], R->LevS->LPsi->OldLocalPsi);
1186 if (SuperStop) OuterStop = 1;
1187 return OuterStop;
1188}
1189
1190/** Checks whether the given positions \a *v have changed wrt stored in IonData structure.
1191 * \param *P Problem at hand
1192 * \param *v gsl_vector storing new positions
1193 */
1194int CheckForChangedPositions(struct Problem *P, const gsl_vector *v)
1195{
1196 struct Ions *I = &P->Ion;
1197 int is,ia,k, index=0;
1198 int diff = 0;
1199 double *R_ion;
1200 for (is=0; is < I->Max_Types; is++) // for all elements
1201 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { // for all ions of element
1202 R_ion = &I->I[is].R[NDIM*ia];
1203 for (k=0;k<NDIM;k++) { // for all dimensions
1204 if (fabs(R_ion[k] - gsl_vector_get (v, index++)) > MYEPSILON)
1205 diff++;
1206 }
1207 }
1208 return diff;
1209}
1210
1211/** Wrapper for CalculateForce() for simplex minimisation of total energy.
1212 * \param *v vector with degrees of freedom
1213 * \param *params additional arguments, here Problem at hand
1214 */
1215double StructOpt_func(const gsl_vector *v, void *params)
1216{
1217 struct Problem *P = (struct Problem *)params;
1218 struct RunStruct *R = &P->R;
1219 struct Ions *I = &P->Ion;
1220 struct Energy *E = P->Lat.E;
1221 int i;
1222 double *R_ion, *R_old, *R_old_old;//, *FIon;
1223 //double norm = 0.;
1224 int is,ia,k,index = 0;
1225 int OuterStop;
1226 double diff = 0., tmp;
1227 debug (P, "StructOpt_func");
1228 if (CheckForChangedPositions(P,v)) {
1229 // update ion positions from vector coordinates
1230 for (is=0; is < I->Max_Types; is++) // for all elements
1231 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { // for all ions of element
1232 R_ion = &I->I[is].R[NDIM*ia];
1233 R_old = &I->I[is].R_old[NDIM*ia];
1234 R_old_old = &I->I[is].R_old_old[NDIM*ia];
1235 tmp = 0.;
1236 for (k=0;k<NDIM;k++) { // for all dimensions
1237 R_old_old[k] = R_old[k];
1238 R_old[k] = R_ion[k];
1239 tmp += (R_ion[k]-gsl_vector_get (v, index))*(R_ion[k]-gsl_vector_get (v, index));
1240 R_ion[k] = gsl_vector_get (v, index++);
1241 }
1242 diff += sqrt(tmp);
1243 }
1244 if (P->Call.out[ValueOut]) fprintf(stderr,"(%i) Summed Difference to former position %lg\n", P->Par.me, diff);
1245 // recalculate ionic forces (do electronic minimisation)
1246 R->OuterStep++;
1247 R->NewRStep++;
1248 UpdateWaveAfterIonMove(P);
1249 for (i=MAXOLD-1; i > 0; i--) // store away old energies
1250 E->TotalEnergyOuter[i] = E->TotalEnergyOuter[i-1];
1251 UpdateToNewWaves(P);
1252 E->TotalEnergyOuter[0] = E->TotalEnergy[0];
1253 OuterStop = CalculateForce(P);
1254 //UpdateIonsU(P);
1255 //CorrectVelocity(P);
1256 //CalculateEnergyIonsU(P);
1257 /* if ((P->R.ScaleTempStep > 0) && ((R->OuterStep-1) % P->R.ScaleTempStep == 0))
1258 ScaleTemp(P);*/
1259 if ((R->OuterStep-1) % P->R.OutSrcStep == 0)
1260 OutputVisSrcFiles(P, Occupied);
1261 if ((R->OuterStep-1) % P->R.OutVisStep == 0) {
1262 /* // recalculate density for the specific wave function ...
1263 CalculateOneDensityR(Lat, LevS, Dens0, PsiDat, Dens0->DensityArray[ActualDensity], R->FactorDensityR, 0);
1264 // ... and output (wherein ActualDensity is used instead of TotalDensity)
1265 OutputVis(P);
1266 OutputIonForce(P);
1267 EnergyOutput(P, 1);*/
1268 }
1269 }
1270 if (P->Par.me == 0) fprintf(stderr,"(%i) TE %e\n",P->Par.me, E->TotalEnergy[0]);
1271 return E->TotalEnergy[0];
1272}
1273
1274/** Wrapper for CalculateForce() for simplex minimisation of ionic forces.
1275 * \param *v vector with degrees of freedom
1276 * \param *params additional arguments, here Problem at hand
1277 */
1278double StructOpt_f(const gsl_vector *v, void *params)
1279{
1280 struct Problem *P = (struct Problem *)params;
1281 struct RunStruct *R = &P->R;
1282 struct Ions *I = &P->Ion;
1283 struct Energy *E = P->Lat.E;
1284 int i;
1285 double *R_ion, *R_old, *R_old_old;//, *FIon;
1286 //double norm = 0.;
1287 int is,ia,k,index = 0;
1288 int OuterStop;
1289 double diff = 0., tmp;
1290 //debug (P, "StructOpt_f");
1291 if (CheckForChangedPositions(P,v)) {
1292 // update ion positions from vector coordinates
1293 for (is=0; is < I->Max_Types; is++) // for all elements
1294 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { // for all ions of element
1295 R_ion = &I->I[is].R[NDIM*ia];
1296 R_old = &I->I[is].R_old[NDIM*ia];
1297 R_old_old = &I->I[is].R_old_old[NDIM*ia];
1298 tmp = 0.;
1299 for (k=0;k<NDIM;k++) { // for all dimensions
1300 R_old_old[k] = R_old[k];
1301 R_old[k] = R_ion[k];
1302 tmp += (R_ion[k]-gsl_vector_get (v, index))*(R_ion[k]-gsl_vector_get (v, index));
1303 R_ion[k] = gsl_vector_get (v, index++);
1304 }
1305 diff += sqrt(tmp);
1306 }
1307 if (P->Call.out[ValueOut]) fprintf(stderr,"(%i) Summed Difference to former position %lg\n", P->Par.me, diff);
1308 // recalculate ionic forces (do electronic minimisation)
1309 //R->OuterStep++;
1310 R->NewRStep++;
1311 UpdateWaveAfterIonMove(P);
1312 for (i=MAXOLD-1; i > 0; i--) // store away old energies
1313 E->TotalEnergyOuter[i] = E->TotalEnergyOuter[i-1];
1314 UpdateToNewWaves(P);
1315 E->TotalEnergyOuter[0] = E->TotalEnergy[0];
1316 OuterStop = CalculateForce(P);
1317 //UpdateIonsU(P);
1318 //CorrectVelocity(P);
1319 //CalculateEnergyIonsU(P);
1320 /* if ((P->R.ScaleTempStep > 0) && ((R->OuterStep-1) % P->R.ScaleTempStep == 0))
1321 ScaleTemp(P);*/
1322 if ((R->OuterStep-1) % P->R.OutSrcStep == 0)
1323 OutputVisSrcFiles(P, Occupied);
1324 /*if ((R->OuterStep-1) % P->R.OutVisStep == 0) {
1325 // recalculate density for the specific wave function ...
1326 CalculateOneDensityR(Lat, LevS, Dens0, PsiDat, Dens0->DensityArray[ActualDensity], R->FactorDensityR, 0);
1327 // ... and output (wherein ActualDensity is used instead of TotalDensity)
1328 OutputVis(P);
1329 OutputIonForce(P);
1330 EnergyOutput(P, 1);
1331 }*/
1332 }
1333 GetOuterStop(P);
1334 //if (P->Call.out[LeaderOut] && (P->Par.me == 0)) fprintf(stderr,"(%i) Absolute Force summed over all Ions %e\n",P->Par.me, norm);
1335 return R->MeanForce[0];
1336 //if (P->Call.out[LeaderOut] && (P->Par.me == 0)) fprintf(stderr,"(%i) Struct_optf returning: %lg\n",P->Par.me,E->TotalEnergy[0]);
1337 //return E->TotalEnergy[0];
1338}
1339
1340void StructOpt_df(const gsl_vector *v, void *params, gsl_vector *df)
1341{
1342 struct Problem *P = (struct Problem *)params;
1343 struct Ions *I = &P->Ion;
1344 double *FIon;
1345 int is,ia,k, index=0;
1346 //debug (P, "StructOpt_df");
1347 // look through coordinate vector if positions have changed sind last StructOpt_f call
1348 if (CheckForChangedPositions(P,v)) {// if so, recalc to update forces
1349 debug (P, "Calling StructOpt_f to update");
1350 StructOpt_f(v, params);
1351 }
1352 for (is=0; is < I->Max_Types; is++) // for all elements
1353 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { // for all ions of element
1354 FIon = &I->I[is].FIon[NDIM*ia];
1355 for (k=0;k<NDIM;k++) { // for all dimensions
1356 gsl_vector_set (df, index++, FIon[k]);
1357 }
1358 }
1359 if (P->Call.out[LeaderOut] && (P->Par.me == 0)) {
1360 fprintf(stderr,"(%i) Struct_Optdf returning",P->Par.me);
1361 gsl_vector_fprintf(stderr, df, "%lg");
1362 }
1363}
1364
1365void StructOpt_fdf (const gsl_vector *x, void *params, double *f, gsl_vector *df)
1366{
1367 *f = StructOpt_f(x, params);
1368 StructOpt_df(x, params, df);
1369}
1370
1371
1372/** CG implementation for the structure optimization.
1373 * We follow the example from the GSL manual.
1374 * \param *P Problem at hand
1375 */
1376void UpdateIon_PRCG(struct Problem *P)
1377{
1378 //struct RunStruct *Run = &P->R;
1379 struct Ions *I = &P->Ion;
1380 size_t np = NDIM*I->Max_TotalIons; // d.o.f = number of ions times number of dimensions
1381 int is, ia, k, index;
1382 double *R;
1383
1384 const gsl_multimin_fdfminimizer_type *T;
1385 gsl_multimin_fdfminimizer *s;
1386 gsl_vector *x;
1387 gsl_multimin_function_fdf minex_func;
1388
1389 size_t iter = 0;
1390 int status;
1391
1392 /* Starting point */
1393 x = gsl_vector_alloc (np);
1394 //fprintf(stderr,"(%i) d.o.f. = %i\n", P->Par.me, (int)np);
1395
1396 index=0;
1397 for (is=0; is < I->Max_Types; is++) // for all elements
1398 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { // for all ions of element
1399 R = &I->I[is].R[NDIM*ia];
1400 for (k=0;k<NDIM;k++) // for all dimensions
1401 gsl_vector_set (x, index++, R[k]);
1402 }
1403
1404 /* Initialize method and iterate */
1405 minex_func.f = &StructOpt_f;
1406 minex_func.df = &StructOpt_df;
1407 minex_func.fdf = &StructOpt_fdf;
1408 minex_func.n = np;
1409 minex_func.params = (void *)P;
1410
1411 T = gsl_multimin_fdfminimizer_conjugate_pr;
1412 s = gsl_multimin_fdfminimizer_alloc (T, np);
1413
1414 gsl_multimin_fdfminimizer_set (s, &minex_func, x, 0.1, 0.001);
1415
1416 fprintf(stderr,"(%i) Commencing Structure optimization with PRCG: dof %d\n", P->Par.me,(int)np);
1417 do {
1418 iter++;
1419 status = gsl_multimin_fdfminimizer_iterate(s);
1420
1421 if (status)
1422 break;
1423
1424 status = gsl_multimin_test_gradient (s->gradient, 1e-2);
1425
1426 if (status == GSL_SUCCESS)
1427 if (P->Par.me == 0) fprintf (stderr,"(%i) converged to minimum at\n", P->Par.me);
1428
1429 if (P->Call.out[NormalOut]) fprintf(stderr,"(%i) Commencing '%s' step %i ... \n",P->Par.me, gsl_multimin_fdfminimizer_name(s), P->R.StructOptStep);
1430 if ((P->Call.out[NormalOut]) && (P->Par.me == 0)) fprintf (stderr, "(%i) %5d %10.5f\n", P->Par.me, (int)iter, s->f);
1431 //gsl_vector_fprintf(stderr, s->dx, "%lg");
1432 OutputVis(P, P->R.Lev0->Dens->DensityArray[TotalDensity]);
1433 OutputIonCoordinates(P, 0);
1434 P->R.StructOptStep++;
1435 } while ((status == GSL_CONTINUE) && (P->R.StructOptStep < P->R.MaxStructOptStep));
1436
1437 gsl_vector_free(x);
1438 gsl_multimin_fdfminimizer_free (s);
1439}
1440
1441/** Simplex implementation for the structure optimization.
1442 * We follow the example from the GSL manual.
1443 * \param *P Problem at hand
1444 */
1445void UpdateIon_Simplex(struct Problem *P)
1446{
1447 struct RunStruct *Run = &P->R;
1448 struct Ions *I = &P->Ion;
1449 size_t np = NDIM*I->Max_TotalIons; // d.o.f = number of ions times number of dimensions
1450 int is, ia, k, index;
1451 double *R;
1452
1453 const gsl_multimin_fminimizer_type *T;
1454 gsl_multimin_fminimizer *s;
1455 gsl_vector *x, *ss;
1456 gsl_multimin_function minex_func;
1457
1458 size_t iter = 0;
1459 int status;
1460 double size;
1461
1462 ss = gsl_vector_alloc (np);
1463 gsl_vector_set_all(ss, .2);
1464 /* Starting point */
1465 x = gsl_vector_alloc (np);
1466 //fprintf(stderr,"(%i) d.o.f. = %i\n", P->Par.me, (int)np);
1467
1468 index=0;
1469 for (is=0; is < I->Max_Types; is++) // for all elements
1470 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) { // for all ions of element
1471 R = &I->I[is].R[NDIM*ia];
1472 for (k=0;k<NDIM;k++) // for all dimensions
1473 gsl_vector_set (x, index++, R[k]);
1474 }
1475
1476 /* Initialize method and iterate */
1477 minex_func.f = &StructOpt_f;
1478 minex_func.n = np;
1479 minex_func.params = (void *)P;
1480
1481 T = gsl_multimin_fminimizer_nmsimplex;
1482 s = gsl_multimin_fminimizer_alloc (T, np);
1483
1484 gsl_multimin_fminimizer_set (s, &minex_func, x, ss);
1485
1486 fprintf(stderr,"(%i) Commencing Structure optimization with NM simplex: dof %d\n", P->Par.me, (int)np);
1487 do {
1488 iter++;
1489 status = gsl_multimin_fminimizer_iterate(s);
1490
1491 if (status)
1492 break;
1493
1494 size = gsl_multimin_fminimizer_size (s);
1495 status = gsl_multimin_test_size (size, 1e-4);
1496
1497 if (status == GSL_SUCCESS)
1498 if (P->Par.me == 0) fprintf (stderr,"(%i) converged to minimum at\n", P->Par.me);
1499
1500 if (P->Call.out[MinOut]) fprintf(stderr,"(%i) Commencing '%s' step %i ... \n",P->Par.me, gsl_multimin_fminimizer_name(s), P->R.StructOptStep);
1501 if ((P->Call.out[MinOut]) && (P->Par.me == 0)) fprintf (stderr, "(%i) %5d %10.5f %10.5f\n", P->Par.me, (int)iter, s->fval, size);
1502 OutputVis(P, P->R.Lev0->Dens->DensityArray[TotalDensity]);
1503 OutputIonCoordinates(P, 0);
1504 P->R.StructOptStep++;
1505 } while ((status == GSL_CONTINUE) && (Run->OuterStep < Run->MaxOuterStep));
1506
1507 gsl_vector_free(x);
1508 gsl_vector_free(ss);
1509 gsl_multimin_fminimizer_free (s);
1510}
1511
1512/** Implementation of various thermostats.
1513 * All these thermostats apply an additional force which has the following forms:
1514 * -# Woodcock
1515 * \f$p_i \rightarrow \sqrt{\frac{T_0}{T}} \cdot p_i\f$
1516 * -# Gaussian
1517 * \f$ \frac{ \sum_i \frac{p_i}{m_i} \frac{\partial V}{\partial q_i}} {\sum_i \frac{p^2_i}{m_i}} \cdot p_i\f$
1518 * -# Langevin
1519 * \f$p_{i,n} \rightarrow \sqrt{1-\alpha^2} p_{i,0} + \alpha p_r\f$
1520 * -# Berendsen
1521 * \f$p_i \rightarrow \left [ 1+ \frac{\delta t}{\tau_T} \left ( \frac{T_0}{T} \right ) \right ]^{\frac{1}{2}} \cdot p_i\f$
1522 * -# Nose-Hoover
1523 * \f$\zeta p_i \f$ with \f$\frac{\partial \zeta}{\partial t} = \frac{1}{M_s} \left ( \sum^N_{i=1} \frac{p_i^2}{m_i} - g k_B T \right )\f$
1524 * These Thermostats either simply rescale the velocities, thus Thermostats() should be called after UpdateIonsU(), and/or
1525 * have a constraint force acting additionally on the ions. In the latter case, the ion speeds have to be modified
1526 * belatedly and the constraint force set.
1527 * \param *P Problem at hand
1528 * \param i which of the thermostats to take: 0 - none, 1 - Woodcock, 2 - Gaussian, 3 - Langevin, 4 - Berendsen, 5 - Nose-Hoover
1529 * \sa InitThermostat()
1530 */
1531void Thermostats(struct Problem *P, enum thermostats i)
1532{
1533 struct FileData *Files = &P->Files;
1534 struct Ions *I = &P->Ion;
1535 int is, ia, d;
1536 double *U;
1537 double a, ekin = 0.;
1538 double E = 0., F = 0.;
1539 double delta_alpha = 0.;
1540 const int delta_t = P->R.delta_t;
1541 double ScaleTempFactor;
1542 double sigma;
1543 gsl_rng * r;
1544 const gsl_rng_type * T;
1545
1546 // calculate current temperature
1547 CalculateEnergyIonsU(P); // Temperature now in I->ActualTemp
1548 ScaleTempFactor = P->R.TargetTemp/I->ActualTemp;
1549 //if ((P->Par.me == 0) && (I->ActualTemp < MYEPSILON)) fprintf(stderr,"Thermostat: (1) I->ActualTemp = %lg",I->ActualTemp);
1550 if (Files->MeOutMes) fprintf(Files->TemperatureFile, "%d\t%lg",P->R.OuterStep, I->ActualTemp);
1551
1552 // differentating between the various thermostats
1553 switch(i) {
1554 case None:
1555 debug(P, "Applying no thermostat...");
1556 break;
1557 case Woodcock:
1558 if ((P->R.ScaleTempStep > 0) && ((P->R.OuterStep-1) % P->R.ScaleTempStep == 0)) {
1559 debug(P, "Applying Woodcock thermostat...");
1560 for (is=0; is < I->Max_Types; is++) {
1561 a = 0.5*I->I[is].IonMass;
1562 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) {
1563 U = &I->I[is].U[NDIM*ia];
1564 if (I->I[is].IMT[ia] == MoveIon) // even FixedIon moves, only not by other's forces
1565 for (d=0; d<NDIM; d++) {
1566 U[d] *= sqrt(ScaleTempFactor);
1567 ekin += 0.5*I->I[is].IonMass * U[d]*U[d];
1568 }
1569 }
1570 }
1571 }
1572 break;
1573 case Gaussian:
1574 debug(P, "Applying Gaussian thermostat...");
1575 for (is=0; is < I->Max_Types; is++) { // sum up constraint constant
1576 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) {
1577 U = &I->I[is].U[NDIM*ia];
1578 if (I->I[is].IMT[ia] == MoveIon) // even FixedIon moves, only not by other's forces
1579 for (d=0; d<NDIM; d++) {
1580 F += U[d] * I->I[is].FIon[d+NDIM*ia];
1581 E += U[d]*U[d]*I->I[is].IonMass;
1582 }
1583 }
1584 }
1585 if (P->Call.out[ValueOut]) fprintf(stderr, "(%i) Gaussian Least Constraint constant is %lg\n", P->Par.me, F/E);
1586 for (is=0; is < I->Max_Types; is++) { // apply constraint constant on constraint force and on velocities
1587 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) {
1588 U = &I->I[is].U[NDIM*ia];
1589 if (I->I[is].IMT[ia] == MoveIon) // even FixedIon moves, only not by other's forces
1590 for (d=0; d<NDIM; d++) {
1591 I->I[is].FConstraint[d+NDIM*ia] = (F/E) * (U[d]*I->I[is].IonMass);
1592 U[d] += delta_t/I->I[is].IonMass * (I->I[is].FConstraint[d+NDIM*ia]);
1593 ekin += 0.5*I->I[is].IonMass * U[d]*U[d];
1594 }
1595 }
1596 }
1597 break;
1598 case Langevin:
1599 debug(P, "Applying Langevin thermostat...");
1600 // init random number generator
1601 gsl_rng_env_setup();
1602 T = gsl_rng_default;
1603 r = gsl_rng_alloc (T);
1604 // Go through each ion
1605 for (is=0; is < I->Max_Types; is++) {
1606 sigma = sqrt(P->R.TargetTemp/I->I[is].IonMass); // sigma = (k_b T)/m (Hartree/atomicmass = atomiclength/atomictime)
1607 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) {
1608 U = &I->I[is].U[NDIM*ia];
1609 // throw a dice to determine whether it gets hit by a heat bath particle
1610 if (((((rand()/(double)RAND_MAX))*P->R.TempFrequency) < 1.)) { // (I->I[is].IMT[ia] == MoveIon) && even FixedIon moves, only not by other's forces
1611 if (P->Par.me == 0) fprintf(stderr,"(%i) Particle %i,%i was hit (sigma %lg): %lg -> ", P->Par.me, is, ia, sigma, sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]));
1612 // pick three random numbers from a Boltzmann distribution around the desired temperature T for each momenta axis
1613 for (d=0; d<NDIM; d++) {
1614 U[d] = gsl_ran_gaussian (r, sigma);
1615 }
1616 if (P->Par.me == 0) fprintf(stderr,"%lg\n", sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]));
1617 }
1618 for (d=0; d<NDIM; d++)
1619 ekin += 0.5*I->I[is].IonMass * U[d]*U[d];
1620 }
1621 }
1622 break;
1623 case Berendsen:
1624 debug(P, "Applying Berendsen-VanGunsteren thermostat...");
1625 for (is=0; is < I->Max_Types; is++) {
1626 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) {
1627 U = &I->I[is].U[NDIM*ia];
1628 if (I->I[is].IMT[ia] == MoveIon) // even FixedIon moves, only not by other's forces
1629 for (d=0; d<NDIM; d++) {
1630 U[d] *= sqrt(1+(P->R.delta_t/P->R.TempFrequency)*(ScaleTempFactor-1));
1631 ekin += 0.5*I->I[is].IonMass * U[d]*U[d];
1632 }
1633 }
1634 }
1635 break;
1636 case NoseHoover:
1637 debug(P, "Applying Nose-Hoover thermostat...");
1638 // dynamically evolve alpha (the additional degree of freedom)
1639 delta_alpha = 0.;
1640 for (is=0; is < I->Max_Types; is++) { // sum up constraint constant
1641 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) {
1642 U = &I->I[is].U[NDIM*ia];
1643 if (I->I[is].IMT[ia] == MoveIon) // even FixedIon moves, only not by other's forces
1644 for (d=0; d<NDIM; d++) {
1645 delta_alpha += U[d]*U[d]*I->I[is].IonMass;
1646 }
1647 }
1648 }
1649 delta_alpha = (delta_alpha - (3.*I->Max_TotalIons+1.) * P->R.TargetTemp)/(P->R.HooverMass*Units2Electronmass);
1650 P->R.alpha += delta_alpha*delta_t;
1651 if (P->Par.me == 0) fprintf(stderr,"(%i) alpha = %lg * %i = %lg\n", P->Par.me, delta_alpha, delta_t, P->R.alpha);
1652 // apply updated alpha as additional force
1653 for (is=0; is < I->Max_Types; is++) { // apply constraint constant on constraint force and on velocities
1654 for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) {
1655 U = &I->I[is].U[NDIM*ia];
1656 if (I->I[is].IMT[ia] == MoveIon) // even FixedIon moves, only not by other's forces
1657 for (d=0; d<NDIM; d++) {
1658 I->I[is].FConstraint[d+NDIM*ia] = - P->R.alpha * (U[d] * I->I[is].IonMass);
1659 U[d] += delta_t/I->I[is].IonMass * (I->I[is].FConstraint[d+NDIM*ia]);
1660 ekin += (0.5*I->I[is].IonMass) * U[d]*U[d];
1661 }
1662 }
1663 }
1664 break;
1665 }
1666 I->EKin = ekin;
1667 I->ActualTemp = (2./(3.*I->Max_TotalIons)*I->EKin);
1668 //if ((P->Par.me == 0) && (I->ActualTemp < MYEPSILON)) fprintf(stderr,"Thermostat: (2) I->ActualTemp = %lg",I->ActualTemp);
1669 if (Files->MeOutMes) { fprintf(Files->TemperatureFile, "\t%lg\n", I->ActualTemp); fflush(Files->TemperatureFile); }
1670}
1671
1672/** Does the Molecular Dynamics Calculations.
1673 * All of the following is SpeedMeasure()'d in SimTime.
1674 * Initialization by calling:
1675 * -# CorrectVelocity()\n
1676 * Shifts center of gravity of Ions momenta, so that the cell itself remains at rest.
1677 * -# CalculateEnergyIonsU(), SpeedMeasure()'d in TimeTypes#InitSimTime\n
1678 * Calculates kinetic energy of "movable" Ions.
1679 * -# CalculateForce()\n
1680 * Does the minimisation, calculates densities, then energies and finally the forces.
1681 * -# OutputVisSrcFiles()\n
1682 * If desired, so-far made calculations are stored to file for later restarting.
1683 * -# OutputIonForce()\n
1684 * Write ion forces to file.
1685 * -# EnergyOutput()\n
1686 * Write calculated energies to screen or file.
1687 *
1688 * The simulation phase begins:
1689 * -# UpdateIonsR()\n
1690 * Move Ions according to the calculated force.
1691 * -# UpdateWaveAfterIonMove()\n
1692 * Update wave functions by averaging LocalPsi coefficients after the Ions have been shifted.
1693 * -# UpdateToNewWaves()\n
1694 * Update after wave functions have changed.
1695 * -# CalculateForce()\n
1696 * Does the minimisation, calculates densities, then energies and finally the forces.
1697 * -# UpdateIonsU()\n
1698 * Change ion's velocities according to the calculated acting force.
1699 * -# CorrectVelocity()\n
1700 * Shifts center of gravity of Ions momenta, so that the cell itself remains at rest.
1701 * -# CalculateEnergyIonsU()\n
1702 * Calculates kinetic energy of "movable" Ions.
1703 * -# ScaleTemp()\n
1704 * The temperature is scaled, so the systems energy remains constant (they must not gain momenta out of nothing)
1705 * -# OutputVisSrcFiles()\n
1706 * If desired, so-far made calculations are stored to file for later restarting.
1707 * -# OutputVis()\n
1708 * Visulization data for OpenDX is written at certain steps if desired.
1709 * -# OutputIonForce()\n
1710 * Write ion forces to file.
1711 * -# EnergyOutput()\n
1712 * Write calculated energies to screen or file.
1713 *
1714 * After the ground state is found:
1715 * -# CalculateUnOccupied()\n
1716 * Energies of unoccupied orbitals - that have been left out completely so far -
1717 * are calculated.
1718 * -# TestGramSch()\n
1719 * Test if orbitals are still orthogonal.
1720 * -# CalculateHamiltonian()\n
1721 * Construct Hamiltonian and calculate Eigenvalues.
1722 * -# ComputeMLWF()\n
1723 * Localize orbital wave functions.
1724 *
1725 * \param *P Problem at hand
1726 */
1727void CalculateMD(struct Problem *P)
1728{
1729 struct RunStruct *R = &P->R;
1730 struct Ions *I = &P->Ion;
1731 struct Energy *E = P->Lat.E;
1732 int OuterStop = 0;
1733 int i;
1734
1735 SpeedMeasure(P, SimTime, StartTimeDo);
1736 // initial calculations (bring density on BO surface and output start energies, coordinates, densities, ...)
1737 SpeedMeasure(P, InitSimTime, StartTimeDo);
1738 R->OuterStep = 0;
1739 CorrectVelocity(P);
1740 CalculateEnergyIonsU(P);
1741 OuterStop = CalculateForce(P);
1742 //R->OuterStep++;
1743 P->Speed.InitSteps++;
1744 SpeedMeasure(P, InitSimTime, StopTimeDo);
1745
1746 OutputIonCoordinates(P, 1);
1747 OutputVis(P, P->R.Lev0->Dens->DensityArray[TotalDensity]);
1748 OutputIonForce(P);
1749 EnergyOutput(P, 1);
1750
1751 // if desired perform beforehand a structure relaxation/optimization
1752 if (I->StructOpt) {
1753 debug(P,"Commencing minimisation on ionic structure ...");
1754 R->StructOptStep = 0;
1755 //UpdateIon_PRCG(P);
1756 //UpdateIon_Simplex(P);
1757 while ((R->MeanForce[0] > 1e-4) && (R->StructOptStep < R->MaxStructOptStep)) {
1758 R->StructOptStep++;
1759 OutputIonCoordinates(P, 1);
1760 UpdateIons(P);
1761 UpdateWaveAfterIonMove(P);
1762 for (i=MAXOLD-1; i > 0; i--) // store away old energies
1763 E->TotalEnergyOuter[i] = E->TotalEnergyOuter[i-1];
1764 UpdateToNewWaves(P);
1765 E->TotalEnergyOuter[0] = E->TotalEnergy[0];
1766 OuterStop = CalculateForce(P);
1767 CalculateEnergyIonsU(P);
1768 if ((R->StructOptStep-1) % P->R.OutSrcStep == 0)
1769 OutputVisSrcFiles(P, Occupied);
1770 if ((R->StructOptStep-1) % P->R.OutVisStep == 0) {
1771 OutputVis(P, P->R.Lev0->Dens->DensityArray[TotalDensity]);
1772 OutputIonForce(P);
1773 EnergyOutput(P, 1);
1774 }
1775 if (P->Par.me == 0) fprintf(stderr,"(%i) Mean force is %lg\n", P->Par.me, R->MeanForce[0]);
1776 }
1777 OutputIonCoordinates(P, 1);
1778 }
1779 if (I->StructOpt && !OuterStop) {
1780 I->StructOpt = 0;
1781 OuterStop = CalculateForce(P);
1782 }
1783
1784 // and now begin with the molecular dynamics simulation
1785 debug(P,"Commencing MD simulation ...");
1786 while (!OuterStop && R->OuterStep < R->MaxOuterStep) {
1787 R->OuterStep++;
1788 if (P->Par.me == 0) {
1789 if (R->OuterStep > 1) fprintf(stderr,"\b\b\b\b\b\b\b\b\b\b\b\b");
1790 fprintf(stderr,"Time: %f fs\r", R->t*Atomictime2Femtoseconds);
1791 fflush(stderr);
1792 }
1793 OuterStop = CalculateForce(P);
1794 P->R.t += P->R.delta_t; // increase current time by delta_t
1795 R->NewRStep++;
1796
1797 UpdateIonsU(P);
1798 CorrectVelocity(P);
1799 Thermostats(P, I->Thermostat);
1800 CalculateEnergyIonsU(P);
1801
1802 UpdateIonsR(P);
1803 OutputIonCoordinates(P, 1);
1804
1805 UpdateWaveAfterIonMove(P);
1806 for (i=MAXOLD-1; i > 0; i--) // store away old energies
1807 E->TotalEnergyOuter[i] = E->TotalEnergyOuter[i-1];
1808 UpdateToNewWaves(P);
1809 E->TotalEnergyOuter[0] = E->TotalEnergy[0];
1810 //if ((P->R.ScaleTempStep > 0) && ((R->OuterStep-1) % P->R.ScaleTempStep == 0))
1811 // ScaleTemp(P);
1812 if ((R->OuterStep-1) % P->R.OutSrcStep == 0)
1813 OutputVisSrcFiles(P, Occupied);
1814 if ((R->OuterStep-1) % P->R.OutVisStep == 0) {
1815 OutputVis(P, P->R.Lev0->Dens->DensityArray[TotalDensity]);
1816 OutputIonForce(P);
1817 EnergyOutput(P, 1);
1818 }
1819 ResetForces(P);
1820 }
1821 SpeedMeasure(P, SimTime, StopTimeDo);
1822 CloseOutputFiles(P);
1823}
Note: See TracBrowser for help on using the repository browser.