| [a0bcf1] | 1 | /** \file output.c
 | 
|---|
 | 2 |  * Output of forces and energies, Visuals (density and ions for OpenDX).
 | 
|---|
 | 3 |  * 
 | 
|---|
 | 4 |  * Herein all the functions concerning the output of data are gathered:
 | 
|---|
 | 5 |  * Initialization of the FileData structure InitOutVisArray() and the files themselves 
 | 
|---|
 | 6 |  * InitOutputFiles(),
 | 
|---|
 | 7 |  * Saving of a calculated state OutputVisSrcFiles() - 1. Psis OutputSrcPsiDensity(), 2. Ions
 | 
|---|
 | 8 |  * OutSrcIons() - or retrieving Psis ReadSrcPsiDensity() and Ions ReadSrcIons(),
 | 
|---|
 | 9 |  * Preparation (in case of RiemannTensor use) CalculateOutVisDensityPos(), OutVisPosRTransformPosNFRto0(),
 | 
|---|
 | 10 |  * Output of visual data (for OpenDx explorer) OutputVis() - 1. OpenDX files CreateDensityOutputGeneral(),
 | 
|---|
 | 11 |  * 2. electronic densitiy data OutVisDensity() (uses MPI sending density coefficients OutputOutVisDensity()
 | 
|---|
 | 12 |  * and receiving and writing CombineOutVisDensity()), 3. ion data OutVisIons() -
 | 
|---|
 | 13 |  * Closing of files CloseOutputFiles().
 | 
|---|
 | 14 |  * 
 | 
|---|
 | 15 |  * There are some more routines: OutputCurrentDensity() outputs the current density for each magnetic field
 | 
|---|
 | 16 |  * direction, OutputVisAllOrbital() outputs all orbitals of a certain minimsation type and
 | 
|---|
 | 17 |  * TestReadnWriteSrcDensity() checks whether a certain minimisation group can be written and read again
 | 
|---|
 | 18 |  * correctly.
 | 
|---|
 | 19 |  * 
 | 
|---|
 | 20 |  * There are some helpers that open files with certain filenames, making extensive usage of all
 | 
|---|
 | 21 |  * the suffixes defined in here: OpenFile(), OpenFileNo(), OpenFileNo2(), OpenFileNoNo() and
 | 
|---|
 | 22 |  * OpenFileNoPost().
 | 
|---|
 | 23 |  *
 | 
|---|
 | 24 |  * 
 | 
|---|
 | 25 |   Project: ParallelCarParrinello
 | 
|---|
 | 26 |  \author Jan Hamaekers, Frederik Heber
 | 
|---|
 | 27 |  \date 2000, 2006
 | 
|---|
 | 28 | 
 | 
|---|
 | 29 |   File: output.c
 | 
|---|
 | 30 |   $Id: output.c,v 1.51.2.2 2007-04-21 12:55:50 foo Exp $
 | 
|---|
 | 31 | */
 | 
|---|
| [79290f] | 32 | 
 | 
|---|
 | 33 | #ifdef HAVE_CONFIG_H
 | 
|---|
 | 34 | #include <config.h>
 | 
|---|
 | 35 | #endif
 | 
|---|
 | 36 | 
 | 
|---|
| [a0bcf1] | 37 | #include<stdlib.h>
 | 
|---|
 | 38 | #include<stdio.h>
 | 
|---|
 | 39 | #include<string.h>
 | 
|---|
 | 40 | #include<math.h>
 | 
|---|
 | 41 | //#include<sys/time.h>
 | 
|---|
 | 42 | #include <time.h>
 | 
|---|
 | 43 | #include<unistd.h>
 | 
|---|
 | 44 | #include"data.h"
 | 
|---|
 | 45 | #include"density.h"
 | 
|---|
 | 46 | #include"errors.h"
 | 
|---|
 | 47 | #include"gramsch.h"
 | 
|---|
 | 48 | #include"helpers.h"
 | 
|---|
 | 49 | #include "init.h"
 | 
|---|
 | 50 | #include"myfft.h"
 | 
|---|
 | 51 | #include"mymath.h"
 | 
|---|
 | 52 | #include"output.h"
 | 
|---|
 | 53 | #include"pdbformat.h"
 | 
|---|
 | 54 | #include"perturbed.h"
 | 
|---|
 | 55 | 
 | 
|---|
 | 56 | 
 | 
|---|
 | 57 | /* Konvention: Rueckgabe 0 einer Funktion, bedeutet keinen Fehler (entsprechend exitcode 0) */ 
 | 
|---|
 | 58 | /* Oeffnet Datei P->mainname+"..." mit what*/
 | 
|---|
 | 59 | 
 | 
|---|
 | 60 | /** Opens a file with FileData::mainname+suffix.
 | 
|---|
 | 61 |  * Both the path under which the main programme resides and the path to the config file are
 | 
|---|
 | 62 |  * tried subsequently.
 | 
|---|
 | 63 |  * \param *P Problem at hand
 | 
|---|
 | 64 |  * \param **file file pointer array
 | 
|---|
 | 65 |  * \param *suffix suffix after mainname
 | 
|---|
 | 66 |  * \param *what access parameter for the file: r, w, rw, r+, w+ ...
 | 
|---|
 | 67 |  * \param verbose 1 - print status, 0 - don't print anything
 | 
|---|
 | 68 |  * \return 0 - could not open file, 1 - file is open
 | 
|---|
 | 69 |  */
 | 
|---|
 | 70 | int OpenFile(struct Problem *P, FILE** file, const char* suffix, const char* what, int verbose)
 | 
|---|
 | 71 | {
 | 
|---|
 | 72 |   char* name; /* Zu erzeugender Dateiname */
 | 
|---|
 | 73 |   name = (char*)
 | 
|---|
 | 74 |     Malloc(strlen(P->Files.default_path) + strlen(P->Files.mainname) + strlen(suffix) + 1,"OpenFile");
 | 
|---|
 | 75 |   sprintf(name, "%s%s%s", P->Files.default_path, P->Files.mainname, suffix);
 | 
|---|
 | 76 |   *file = fopen(name, what);
 | 
|---|
| [515271] | 77 |   if (*file == NULL) {
 | 
|---|
| [a0bcf1] | 78 |     fprintf(stderr,"(%i) Normal access failed: name %s, what %s\n", P->Par.me, name, what);
 | 
|---|
 | 79 |     /* hier default file ausprobieren, falls nur gelesen werden soll! */
 | 
|---|
 | 80 |     if(*what == 'r') {
 | 
|---|
 | 81 |       name = (char*)
 | 
|---|
 | 82 |              Realloc(name,strlen(P->Files.default_path) + strlen(suffix)+1,"OpenFile");
 | 
|---|
 | 83 |       sprintf(name, "%s%s", P->Files.default_path,suffix);
 | 
|---|
 | 84 |       *file = fopen(name,what);
 | 
|---|
| [515271] | 85 |       if (*file != NULL) {
 | 
|---|
| [a0bcf1] | 86 |         if (verbose) fprintf(stderr,"(%i) Default file is open: %s\n",P->Par.me,name);
 | 
|---|
| [64fa9e] | 87 |         Free(name, "OpenFile: name");
 | 
|---|
| [a0bcf1] | 88 |         return(1);
 | 
|---|
| [515271] | 89 |       } else {
 | 
|---|
| [41d75d] | 90 |         if (verbose) fprintf(stderr,"\n(%i)Error: Cannot open neither normal nor default file for reading: %s\n",P->Par.me,name);
 | 
|---|
| [515271] | 91 |         Free(name, "OpenFile: name");
 | 
|---|
 | 92 |         return(0);
 | 
|---|
| [a0bcf1] | 93 |       }
 | 
|---|
| [515271] | 94 |     } else {
 | 
|---|
| [41d75d] | 95 |       if (verbose) fprintf(stderr,"\n(%i)Error: Cannot open normal file for writing: %s\n",P->Par.me,name);
 | 
|---|
| [515271] | 96 |       Free(name, "OpenFile: name");
 | 
|---|
 | 97 |       return(0);
 | 
|---|
| [a0bcf1] | 98 |     }
 | 
|---|
 | 99 |   } else {
 | 
|---|
| [41d75d] | 100 |     if (verbose) if(verbose) fprintf(stderr,"(%i) File is open: %s\n",P->Par.me,name);
 | 
|---|
| [515271] | 101 |     Free(name, "OpenFile: name");
 | 
|---|
| [a0bcf1] | 102 |     return(1);
 | 
|---|
 | 103 |   }
 | 
|---|
 | 104 | }
 | 
|---|
 | 105 | 
 | 
|---|
 | 106 | /** Opens a file with FileData::mainname+suffix+"."+No (2 digits).
 | 
|---|
 | 107 |  * Both the path under which the main programme resides and the path to the config file are
 | 
|---|
 | 108 |  * tried subsequently.
 | 
|---|
 | 109 |  * \param *P Problem at hand
 | 
|---|
 | 110 |  * \param **file file pointer array
 | 
|---|
 | 111 |  * \param *suffix suffix after mainname
 | 
|---|
 | 112 |  * \param No the number with up to two digits
 | 
|---|
 | 113 |  * \param *what access parameter for the file: r, w, rw, r+, w+ ...
 | 
|---|
 | 114 |  * \param verbose 1 - print status, 0 - don't print anything
 | 
|---|
 | 115 |  * \return 0 - could not open file, 1 - file is open
 | 
|---|
 | 116 |  */
 | 
|---|
 | 117 | int OpenFileNo2(struct Problem *P, FILE** file, const char* suffix, int No, const char* what, int verbose)
 | 
|---|
 | 118 | {
 | 
|---|
 | 119 |   char* name; /* Zu erzeugender Dateiname */
 | 
|---|
 | 120 |   name = (char*)
 | 
|---|
 | 121 |     Malloc(strlen(P->Files.default_path) + strlen(P->Files.mainname) + strlen(suffix) + 4,"OpenFile");
 | 
|---|
 | 122 |   sprintf(name, "%s%s%s.%02i", P->Files.default_path, P->Files.mainname, suffix, No);
 | 
|---|
 | 123 |   *file = fopen(name, what);
 | 
|---|
| [515271] | 124 |   if (*file == NULL) {
 | 
|---|
| [a0bcf1] | 125 |     /* falls nur gelesen wird, auch default_path ausprobieren */
 | 
|---|
 | 126 |     if (*what == 'r') {
 | 
|---|
 | 127 |       name = (char*)
 | 
|---|
 | 128 |         Realloc(name,strlen(P->Files.default_path) + strlen(suffix) + 4,"OpenFileNo2");
 | 
|---|
 | 129 |       sprintf(name, "%s%s.%02i", P->Files.default_path, suffix, No);
 | 
|---|
 | 130 |       *file = fopen(name, what);
 | 
|---|
| [515271] | 131 |       if (*file != NULL) {
 | 
|---|
| [a0bcf1] | 132 |         if(verbose) fprintf(stderr,"(%i) Default file is open: %s\n", P->Par.me, name);
 | 
|---|
| [64fa9e] | 133 |         Free(name, "OpenFileNo2: name");
 | 
|---|
| [a0bcf1] | 134 |         return(1);
 | 
|---|
 | 135 |       }
 | 
|---|
 | 136 |     }
 | 
|---|
| [41d75d] | 137 |     if (verbose) fprintf(stderr,"\n(%i)Error: Cannot open file: %s\n", P->Par.me, name);
 | 
|---|
| [64fa9e] | 138 |     Free(name, "OpenFileNo2: name");
 | 
|---|
| [a0bcf1] | 139 |     return(0);
 | 
|---|
 | 140 |   } else {
 | 
|---|
 | 141 |     if(verbose) fprintf(stderr,"(%i) File is open: %s\n",P->Par.me, name);
 | 
|---|
| [64fa9e] | 142 |     Free(name, "OpenFileNo2: name");
 | 
|---|
| [a0bcf1] | 143 |     return(1);
 | 
|---|
 | 144 |   }
 | 
|---|
 | 145 | }
 | 
|---|
 | 146 | 
 | 
|---|
 | 147 | /* Oeffnet Datei P->Files.mainname+"...".Nr(4stellig) mit what*/
 | 
|---|
 | 148 | /** Opens a file with FileData::mainname+suffix+"."+No (4 digits).
 | 
|---|
 | 149 |  * Both the path under which the main programme resides and the path to the config file are
 | 
|---|
 | 150 |  * tried subsequently.
 | 
|---|
 | 151 |  * \param *P Problem at hand
 | 
|---|
 | 152 |  * \param **file file pointer array
 | 
|---|
 | 153 |  * \param *suffix suffix after mainname
 | 
|---|
 | 154 |  * \param No the number with up to four digits
 | 
|---|
 | 155 |  * \param *what access parameter for the file: r, w, rw, r+, w+ ...
 | 
|---|
 | 156 |  * \param verbose 1 - print status, 0 - don't print anything
 | 
|---|
 | 157 |  * \return 0 - could not open file, 1 - file is open
 | 
|---|
 | 158 |  */
 | 
|---|
 | 159 | int OpenFileNo(struct Problem *P, FILE** file, const char* suffix, int No, const char* what, int verbose)
 | 
|---|
 | 160 | {
 | 
|---|
 | 161 |   char* name; /* Zu erzeugender Dateiname */
 | 
|---|
 | 162 |   name = (char*)
 | 
|---|
 | 163 |     Malloc(strlen(P->Files.default_path) + strlen(P->Files.mainname) + strlen(suffix) + 6,"OpenFileNo");
 | 
|---|
 | 164 |   sprintf(name, "%s%s%s.%04i", P->Files.default_path, P->Files.mainname, suffix, No);
 | 
|---|
 | 165 |   *file = fopen(name, what);
 | 
|---|
| [515271] | 166 |   if (*file == NULL) {
 | 
|---|
| [a0bcf1] | 167 |     /* falls nur gelesen wird, auch default_path ausprobieren */
 | 
|---|
 | 168 |     if (*what == 'r') {
 | 
|---|
 | 169 |       name = (char*)
 | 
|---|
 | 170 |         Realloc(name,strlen(P->Files.default_path) + strlen(suffix) + 6,"OpenFileNo");
 | 
|---|
 | 171 |       sprintf(name, "%s%s.%04i", P->Files.default_path, suffix, No);
 | 
|---|
 | 172 |       *file = fopen(name, what);
 | 
|---|
| [515271] | 173 |       if (*file != NULL) {
 | 
|---|
| [a0bcf1] | 174 |         if(verbose) fprintf(stderr,"(%i) Default file is open: %s\n", P->Par.me, name);
 | 
|---|
| [64fa9e] | 175 |         Free(name, "OpenFileNo: name");
 | 
|---|
| [a0bcf1] | 176 |         return(1);
 | 
|---|
 | 177 |       }
 | 
|---|
 | 178 |     }
 | 
|---|
| [41d75d] | 179 |     if (verbose) fprintf(stderr,"\n(%i)Error: Cannot open file: %s\n", P->Par.me, name);
 | 
|---|
| [64fa9e] | 180 |     Free(name, "OpenFileNo: name");
 | 
|---|
| [a0bcf1] | 181 |     return(0);
 | 
|---|
 | 182 |   } else {
 | 
|---|
 | 183 |     if(verbose) fprintf(stderr,"(%i) File is open: %s\n", P->Par.me, name);
 | 
|---|
| [64fa9e] | 184 |     Free(name, "OpenFileNo: name");
 | 
|---|
| [a0bcf1] | 185 |     return(1);
 | 
|---|
 | 186 |   }
 | 
|---|
 | 187 | }
 | 
|---|
 | 188 | 
 | 
|---|
 | 189 | /* die nachfolgende Routine wird von seq und par benutzt!!! */
 | 
|---|
 | 190 | /* Oeffnet Datei P->Files.mainname+"...".No.postfix mit what*/
 | 
|---|
 | 191 | 
 | 
|---|
 | 192 | /** Opens a file with FileData::mainname+suffix+"."+No(4 digits)+postfix.
 | 
|---|
 | 193 |  * Only the path under which the main programme resides is tried.
 | 
|---|
 | 194 |  * \param *P Problem at hand
 | 
|---|
 | 195 |  * \param **file file pointer array
 | 
|---|
 | 196 |  * \param *suffix suffix after mainname
 | 
|---|
 | 197 |  * \param No the number with up to four digits
 | 
|---|
 | 198 |  * \param *postfix post-suffix at the end of filename
 | 
|---|
 | 199 |  * \param *what access parameter for the file: r, w, rw, r+, w+ ...
 | 
|---|
 | 200 |  * \param verbose 1 - print status, 0 - don't print anything
 | 
|---|
 | 201 |  * \return 0 - could not open file, 1 - file is open
 | 
|---|
 | 202 |  */
 | 
|---|
 | 203 | int OpenFileNoPost(struct Problem *P, FILE** file, const char* suffix, int No, const char* postfix, const char* what, int verbose)
 | 
|---|
 | 204 | {
 | 
|---|
 | 205 |   char* name; /* Zu erzeugender Dateiname */
 | 
|---|
 | 206 |   name = (char*)
 | 
|---|
 | 207 |     Malloc(strlen(P->Files.default_path) + strlen(P->Files.mainname) + strlen(postfix) + strlen(suffix) + 6,"OpenFileNoPost");
 | 
|---|
 | 208 |   sprintf(name, "%s%s%s.%04i%s", P->Files.default_path, P->Files.mainname, suffix, No, postfix);
 | 
|---|
 | 209 |   *file = fopen(name, what);
 | 
|---|
| [515271] | 210 |   if (*file == NULL) {
 | 
|---|
| [41d75d] | 211 |     if (verbose) fprintf(stderr,"\n(%i)Error: Cannot open file: %s\n", P->Par.me, name);
 | 
|---|
| [64fa9e] | 212 |     Free(name, "OpenFileNoPost: name");
 | 
|---|
| [a0bcf1] | 213 |     return(0);
 | 
|---|
 | 214 |   } else {
 | 
|---|
 | 215 |     if(verbose) fprintf(stderr,"(%i) File is open: %s\n", P->Par.me, name);
 | 
|---|
| [64fa9e] | 216 |     Free(name, "OpenFileNoPost: name");
 | 
|---|
| [a0bcf1] | 217 |     return(1);
 | 
|---|
 | 218 |   }
 | 
|---|
 | 219 | }
 | 
|---|
 | 220 | 
 | 
|---|
 | 221 | /** Opens a file with FileData::mainname+suffix+"."+No1(4 digits)+"."+No2(4 digits).
 | 
|---|
 | 222 |  * Only the path under which the main programme resides is tried.
 | 
|---|
 | 223 |  * \param *P Problem at hand
 | 
|---|
 | 224 |  * \param **file file pointer array
 | 
|---|
 | 225 |  * \param *suffix suffix after mainname
 | 
|---|
 | 226 |  * \param No1 first number with up to four digits
 | 
|---|
 | 227 |  * \param No2 second number with up to four digits
 | 
|---|
 | 228 |  * \param *what access parameter for the file: r, w, rw, r+, w+ ...
 | 
|---|
 | 229 |  * \param verbose 1 - print status, 0 - don't print anything
 | 
|---|
 | 230 |  * \return 0 - could not open file, 1 - file is open
 | 
|---|
 | 231 |  */
 | 
|---|
 | 232 | int OpenFileNoNo(struct Problem *P, FILE** file, const char* suffix, int No1, int No2, const char* what, int verbose)
 | 
|---|
 | 233 | { /* zuerst suffix; No1: lfd, No2: procId */
 | 
|---|
 | 234 |   char *name;
 | 
|---|
 | 235 |   name = (char*)
 | 
|---|
 | 236 |     Malloc(strlen(P->Files.default_path) + strlen(P->Files.mainname) + strlen(suffix) + 5 + 6 + 1,"OpenFileNoNo");
 | 
|---|
 | 237 |   sprintf(name,"%s%s%s.%04i.%04i", P->Files.default_path, P->Files.mainname, suffix, No1, No2);
 | 
|---|
 | 238 |   *file = fopen(name, what);
 | 
|---|
| [515271] | 239 |   if(*file == NULL) {
 | 
|---|
| [41d75d] | 240 |     if (verbose) fprintf(stderr,"\n(%i)Error: Cannot open file: %s\n", P->Par.me, name);
 | 
|---|
| [64fa9e] | 241 |     Free(name, "OpenFileNoNo: name");
 | 
|---|
| [a0bcf1] | 242 |     return(0);
 | 
|---|
 | 243 |   }
 | 
|---|
 | 244 |   if(verbose) fprintf(stderr,"(%i) File is open: %s\n", P->Par.me, name);
 | 
|---|
| [64fa9e] | 245 |   Free(name, "OpenFileNoNo: name");
 | 
|---|
| [a0bcf1] | 246 |   return(1);
 | 
|---|
 | 247 | }
 | 
|---|
 | 248 | 
 | 
|---|
 | 249 | /** Transformation of wave function of Riemann level to zeroth before output as Vis.
 | 
|---|
 | 250 |  * \param *RT RiemannTensor structure, contains RiemannTensor::LatticeLevel
 | 
|---|
 | 251 |  * \param *source source wave function array
 | 
|---|
 | 252 |  * \param *dest destination wave function array
 | 
|---|
 | 253 |  * \param NF dimensional factor (NDIM, generally 3)
 | 
|---|
 | 254 |  */
 | 
|---|
 | 255 | static void OutVisPosRTransformPosNFRto0(const struct RiemannTensor *RT, fftw_real *source, fftw_real *dest, const int NF)
 | 
|---|
 | 256 | {
 | 
|---|
 | 257 |   struct LatticeLevel *Lev = RT->LevR;
 | 
|---|
 | 258 |   int es = Lev->NUp0[2]*NF;
 | 
|---|
 | 259 |   unsigned int cpyes = sizeof(fftw_real)*es;
 | 
|---|
 | 260 |   int nx=Lev->Plan0.plan->local_nx,ny=Lev->N[1],nz=Lev->N[2],Nx=Lev->NUp0[0],Ny=Lev->NUp0[1];
 | 
|---|
 | 261 |   int lx,ly,z,Lx,Ly;
 | 
|---|
 | 262 |   for(lx=0; lx < nx; lx++)
 | 
|---|
 | 263 |     for(Lx=0; Lx < Nx; Lx++)
 | 
|---|
 | 264 |       for(ly=0; ly < ny; ly++)
 | 
|---|
 | 265 |         for(Ly=0; Ly < Ny; Ly++)
 | 
|---|
 | 266 |           for(z=0; z < nz; z++) {
 | 
|---|
 | 267 |             memcpy( &dest[es*(z+nz*(Ly+Ny*(ly+ny*(Lx+Nx*lx))))],
 | 
|---|
 | 268 |                     &source[es*(Ly+Ny*(Lx+Nx*(z+nz*(ly+ny*lx))))],
 | 
|---|
 | 269 |                     cpyes);
 | 
|---|
 | 270 |           }
 | 
|---|
 | 271 | }
 | 
|---|
 | 272 | 
 | 
|---|
 | 273 | 
 | 
|---|
 | 274 | /** prints Norm of each wave function to screen.
 | 
|---|
 | 275 |  * \param *out output destination (eg. stdout)
 | 
|---|
 | 276 |  * \param *P Problem at hand
 | 
|---|
 | 277 |  */
 | 
|---|
 | 278 | void OutputNorm (FILE *out, struct Problem *P) {
 | 
|---|
 | 279 |   struct Lattice *Lat = &P->Lat;
 | 
|---|
 | 280 |   struct Psis *Psi = &Lat->Psi;
 | 
|---|
 | 281 |   struct LatticeLevel *Lev = P->R.LevS;
 | 
|---|
 | 282 |   struct OnePsiElement *OnePsi, *LOnePsi;
 | 
|---|
 | 283 |   int i;
 | 
|---|
 | 284 |   
 | 
|---|
 | 285 |   for (i=0;i<Psi->MaxPsiOfType+P->Par.Max_me_comm_ST_PsiT;i++) {
 | 
|---|
 | 286 |     OnePsi =&Psi->AllPsiStatus[i];
 | 
|---|
 | 287 |     if (OnePsi->my_color_comm_ST_Psi == P->Par.my_color_comm_ST_Psi) { // local one
 | 
|---|
 | 288 |       LOnePsi = &Psi->LocalPsiStatus[OnePsi->MyLocalNo];
 | 
|---|
 | 289 |       fprintf(out,"(%i) Norm of Psi %i: %e\n", P->Par.me, OnePsi->MyGlobalNo, GramSchGetNorm2(P,Lev,Lev->LPsi->LocalPsi[OnePsi->MyLocalNo]));
 | 
|---|
 | 290 |     }
 | 
|---|
 | 291 |   }
 | 
|---|
 | 292 | }
 | 
|---|
 | 293 | 
 | 
|---|
 | 294 | /** Output of current Psis state of source level RunStruct::LevS's LevelPsi::LocalPsi to file \ref suffixsrcpsidat.
 | 
|---|
 | 295 |  * In case of process 0, the doc file is written in a parsable way with minimisation type RunStruct#CurrentMin, level number
 | 
|---|
 | 296 |  * LatticeLevel#LevelNo, and number of grid nodes LatticeLevel#N.
 | 
|---|
 | 297 |  * The two (three) different Psis::SpinType's are discerned and in case of SpinUpDown separate data files opened.
 | 
|---|
 | 298 |  *
 | 
|---|
 | 299 |  * Then for every global wave function of the desired type each coefficient of the reciprocal grid is copied into
 | 
|---|
 | 300 |  * Density::DensityCArray[TempDensity], fouriertransformed, copied into Density::DensityArray[TempDensity].
 | 
|---|
 | 301 |  * 
 | 
|---|
 | 302 |  * As the file output is only handled by process 0, all other coefficient shares are sent within the Psi group to which
 | 
|---|
 | 303 |  * the current global wave function belongs to process 0 of the Psi group and from there on to process 0 of all via
 | 
|---|
 | 304 |  * MPI.
 | 
|---|
 | 305 |  * \param *P Problem at hand
 | 
|---|
 | 306 |  * \param type Current minimisation state
 | 
|---|
| [1ce31f] | 307 |  * \return 0 - file written, 1 - unable to open files for writing
 | 
|---|
| [a0bcf1] | 308 |  * \note This serves as a backup file, when the process is terminated and one would like to restart it at the
 | 
|---|
 | 309 |  *       current calculation lateron, see ReadSrcPsiDensity(). Note also that it is not necessary to specify the
 | 
|---|
 | 310 |  *       same number of processes on later restart, any number may be used under the condition that the number of
 | 
|---|
 | 311 |  *       grid nodes match and that there 2 sharing wave functions in case of SpinUpDown.
 | 
|---|
 | 312 |  * \sa ReadSrcPsiDensity() - same for Reading the coefficients, TestReadnWriteSrcDensity() - checks both routines against
 | 
|---|
 | 313 |  *  each other
 | 
|---|
 | 314 |  */
 | 
|---|
| [1ce31f] | 315 | int OutputSrcPsiDensity(struct Problem *P, enum PsiTypeTag type) 
 | 
|---|
| [a0bcf1] | 316 | {
 | 
|---|
| [79290f] | 317 |   int i,j,k, Index, owner;
 | 
|---|
 | 318 |   size_t zahl;
 | 
|---|
| [a0bcf1] | 319 |   struct Lattice *Lat = &P->Lat;
 | 
|---|
 | 320 |   //struct RunStruct *R = &P->R;
 | 
|---|
 | 321 |   struct fft_plan_3d *plan = Lat->plan;
 | 
|---|
 | 322 |   struct LatticeLevel *LevS = P->R.LevS;
 | 
|---|
 | 323 |   struct Psis *Psi = &Lat->Psi;
 | 
|---|
 | 324 |   fftw_complex *work = (fftw_complex *)LevS->Dens->DensityArray[TempDensity];
 | 
|---|
 | 325 |   double *destpsiR = (double *)LevS->Dens->DensityArray[TempDensity];
 | 
|---|
 | 326 |   fftw_real *srcpsiR = (fftw_real *)LevS->Dens->DensityCArray[TempDensity];
 | 
|---|
 | 327 |   fftw_complex *srcpsiC = (fftw_complex *)LevS->Dens->DensityCArray[TempDensity];
 | 
|---|
 | 328 |   FILE *SrcPsiData, *SrcPsiDoc;
 | 
|---|
| [d3482a] | 329 |   char *suffixdat, *suffixdoc;
 | 
|---|
| [a0bcf1] | 330 |   MPI_Status status;
 | 
|---|
 | 331 |   struct OnePsiElement *OnePsiA, *LOnePsiA;
 | 
|---|
 | 332 |   fftw_complex *LPsiDatA;
 | 
|---|
 | 333 |   int Num = 0, colorNo = 0;
 | 
|---|
 | 334 |   int Sent = 0, sent = 0;
 | 
|---|
| [d3482a] | 335 |   
 | 
|---|
| [a0bcf1] | 336 |   SpeedMeasure(P,ReadnWriteTime,StartTimeDo);
 | 
|---|
| [c510a7] | 337 |   suffixdat = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "OutputSrcPsiDensity: *suffixdat");
 | 
|---|
 | 338 |   suffixdoc = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "OutputSrcPsiDensity: *suffixdoc");
 | 
|---|
| [a0bcf1] | 339 |   sprintf(suffixdat, ".%.254s.L%i", P->R.MinimisationName[type], LevS->LevelNo);
 | 
|---|
| [c510a7] | 340 |   strncpy (suffixdoc, suffixdat, MAXSTRINGSIZE);
 | 
|---|
| [a0bcf1] | 341 |   // for the various spin cases, output the doc-file if it's process 0
 | 
|---|
| [f50ab8] | 342 |   if (P->Par.me_comm_ST == 0) { // if we are process 0 of SpinDouble or SpinUp&-Down
 | 
|---|
| [a0bcf1] | 343 |     switch (Lat->Psi.PsiST) {
 | 
|---|
 | 344 |     case SpinDouble:
 | 
|---|
 | 345 |       colorNo = 0;
 | 
|---|
| [c510a7] | 346 |       strncat (suffixdat, suffixsrcpsidat, MAXSTRINGSIZE-strlen(suffixdat)); 
 | 
|---|
 | 347 |       strncat (suffixdoc, suffixsrcpsidoc, MAXSTRINGSIZE-strlen(suffixdoc));
 | 
|---|
| [a0bcf1] | 348 |       Num =  Lat->Psi.GlobalNo[PsiMaxNoDouble];
 | 
|---|
 | 349 |       break;
 | 
|---|
 | 350 |     case SpinUp:
 | 
|---|
 | 351 |       colorNo = 0;
 | 
|---|
| [c510a7] | 352 |       strncat (suffixdat, suffixsrcpsiupdat, MAXSTRINGSIZE-strlen(suffixdat)); 
 | 
|---|
 | 353 |       strncat (suffixdoc, suffixsrcpsiupdoc, MAXSTRINGSIZE-strlen(suffixdoc)); 
 | 
|---|
| [a0bcf1] | 354 |       Num = Lat->Psi.GlobalNo[PsiMaxNoUp];
 | 
|---|
 | 355 |       break;
 | 
|---|
 | 356 |     case SpinDown:
 | 
|---|
 | 357 |       colorNo = 1;
 | 
|---|
| [c510a7] | 358 |       strncat (suffixdat, suffixsrcpsidowndat, MAXSTRINGSIZE-strlen(suffixdat)); 
 | 
|---|
 | 359 |       strncat (suffixdoc, suffixsrcpsidowndoc, MAXSTRINGSIZE-strlen(suffixdoc)); 
 | 
|---|
| [a0bcf1] | 360 |       Num =  Lat->Psi.GlobalNo[PsiMaxNoDown];
 | 
|---|
 | 361 |       break;
 | 
|---|
 | 362 |     }
 | 
|---|
| [f50ab8] | 363 |     if (!OpenFileNo(P, &SrcPsiData, suffixdat, colorNo, "wb",P->Call.out[ReadOut])) { // open SourcePsiData as write binary
 | 
|---|
| [a0bcf1] | 364 |       fprintf(stderr,"(%i) Error opening file with suffix %s for writing!\n",P->Par.me, suffixdat);
 | 
|---|
| [f50ab8] | 365 |       return 1;
 | 
|---|
 | 366 |     }
 | 
|---|
 | 367 |         if (!OpenFile(P, &SrcPsiDoc, suffixdoc, "w",P->Call.out[ReadOut])) { // open the (text) doc file
 | 
|---|
 | 368 |       fprintf(stderr,"(%i) Error opening file with suffix %s for writing!\n",P->Par.me, suffixdoc);
 | 
|---|
 | 369 |       return 1;
 | 
|---|
| [a0bcf1] | 370 |     }
 | 
|---|
| [f50ab8] | 371 |         fprintf(SrcPsiDoc, "Mintype\t%i\n", (int)type);
 | 
|---|
 | 372 |     fprintf(SrcPsiDoc, "LevelNo\t%i\n", LevS->LevelNo);
 | 
|---|
 | 373 |     fprintf(SrcPsiDoc, "GridNodes\t%i\t%i\t%i\n", LevS->N[0], LevS->N[1], LevS->N[2]);
 | 
|---|
 | 374 |     fprintf(SrcPsiDoc, "PsiNo\t%i\t%i\n", Num, P->Lat.Psi.GlobalNo[PsiMaxAdd]);
 | 
|---|
 | 375 |     fprintf(SrcPsiDoc, "Epsilon\t%lg\t%lg\n", P->R.RelEpsTotalEnergy, P->R.RelEpsKineticEnergy);
 | 
|---|
 | 376 |         for (i = 0; i < P->Par.Max_my_color_comm_ST_Psi; i++) {
 | 
|---|
 | 377 |           fprintf(SrcPsiDoc, "\t%i", Lat->Psi.RealAllLocalNo[i]); // print number of local Psis
 | 
|---|
 | 378 |     }
 | 
|---|
 | 379 |     fprintf(SrcPsiDoc, "\n");
 | 
|---|
 | 380 |         fclose(SrcPsiDoc);
 | 
|---|
| [a0bcf1] | 381 |   }
 | 
|---|
| [d3482a] | 382 |   Free(suffixdat, "OutputSrcPsiDensity: *suffixdat");
 | 
|---|
 | 383 |   Free(suffixdoc, "OutputSrcPsiDensity: *suffixdoc");
 | 
|---|
| [a0bcf1] | 384 |   
 | 
|---|
 | 385 |   // send/receive around and write share of coefficient array of each wave function 
 | 
|---|
 | 386 |   MPI_Allreduce(&sent, &Sent, 1, MPI_INT, MPI_SUM, P->Par.comm_ST); // catch all at the starter line
 | 
|---|
| [1da479] | 387 |   if (P->Call.out[PsiOut]) fprintf(stderr,"(%i) me (%i/%i) \t Psi (%i/%i)\t PsiT (%i/%i)\n", P->Par.me, P->Par.me_comm_ST, P->Par.Max_me_comm_ST, P->Par.me_comm_ST_Psi, P->Par.Max_me_comm_ST_Psi, P->Par.me_comm_ST_PsiT, P->Par.Max_me_comm_ST_PsiT);
 | 
|---|
| [a0bcf1] | 388 |   k = -1;  // k is global PsiNo counter for the desired group
 | 
|---|
 | 389 |   for (j=0; j < Psi->MaxPsiOfType+P->Par.Max_me_comm_ST_PsiT; j++) {  // go through all wave functions (plus the extra one for each process)
 | 
|---|
 | 390 |   OnePsiA = &Psi->AllPsiStatus[j];    // grab OnePsiA
 | 
|---|
 | 391 |     if (OnePsiA->PsiType == type) { // only take desired minimisation group
 | 
|---|
 | 392 |       k++;
 | 
|---|
 | 393 |       owner = 0; // notes down in process 0 of each psi group the owner of the next coefficient share
 | 
|---|
 | 394 |       //fprintf(stderr,"(%i) ST_Psi: OnePsiA %i\tP->Par.me %i\n", P->Par.me,OnePsiA->my_color_comm_ST_Psi,P->Par.my_color_comm_ST_Psi);
 | 
|---|
 | 395 |       if (OnePsiA->my_color_comm_ST_Psi == P->Par.my_color_comm_ST_Psi) { // Belongs to my Psi group?
 | 
|---|
 | 396 |         LOnePsiA = &Psi->LocalPsiStatus[OnePsiA->MyLocalNo];
 | 
|---|
 | 397 |         LPsiDatA = LevS->LPsi->LocalPsi[OnePsiA->MyLocalNo];
 | 
|---|
 | 398 |         SetArrayToDouble0((double *)srcpsiR, LevS->Dens->TotalSize*2);   // zero DensityCArray[TempDensity]
 | 
|---|
 | 399 |         for (i=0;i<LevS->MaxG;i++) {    // for each every unique G grid vector
 | 
|---|
 | 400 |           Index = LevS->GArray[i].Index;
 | 
|---|
 | 401 |           srcpsiC[Index].re = LPsiDatA[i].re;  // copy real value
 | 
|---|
 | 402 |           srcpsiC[Index].im = LPsiDatA[i].im;  // copy imaginary value
 | 
|---|
 | 403 |         }
 | 
|---|
 | 404 |         for (i=0; i<LevS->MaxDoubleG; i++) {  // also for every doubly appearing G vector (symmetry savings)
 | 
|---|
 | 405 |           srcpsiC[LevS->DoubleG[2*i+1]].re = srcpsiC[LevS->DoubleG[2*i]].re;
 | 
|---|
 | 406 |           srcpsiC[LevS->DoubleG[2*i+1]].im = -srcpsiC[LevS->DoubleG[2*i]].im;
 | 
|---|
 | 407 |         }
 | 
|---|
 | 408 |         // do an fft transform from complex to real on these srcPsiR    
 | 
|---|
 | 409 |         fft_3d_complex_to_real(plan, LevS->LevelNo, FFTNF1, srcpsiC, work);
 | 
|---|
 | 410 |         
 | 
|---|
 | 411 |         for (i=0; i < LevS->Dens->LocalSizeR; i++)
 | 
|---|
 | 412 |           destpsiR[i] = (double)srcpsiR[i];
 | 
|---|
 | 413 |       } else 
 | 
|---|
 | 414 |          LOnePsiA = NULL;
 | 
|---|
 | 415 |   
 | 
|---|
 | 416 |       if (P->Par.me_comm_ST == 0) { // if we are process 0 of all, only we may access the file
 | 
|---|
 | 417 |         for (i=0; i<P->Par.Max_me_comm_ST_Psi;i++) { // for each share of the coefficient in the PsiGroup
 | 
|---|
 | 418 |           if (LOnePsiA == NULL) {   // if it's not local, receive coefficients from correct PsiGroup (process 0 within that group)
 | 
|---|
 | 419 |             if (MPI_Recv( destpsiR, LevS->Dens->LocalSizeR, MPI_DOUBLE, OnePsiA->my_color_comm_ST_Psi, OutputSrcPsiTag, P->Par.comm_ST_PsiT, &status ) != MPI_SUCCESS)
 | 
|---|
 | 420 |               Error(SomeError, "OutputSrcPsiDensity: MPI_Recv of loaded coefficients failed!");
 | 
|---|
 | 421 |             MPI_Get_count(&status, MPI_DOUBLE, &zahl);
 | 
|---|
| [79290f] | 422 |             if (zahl != (size_t)LevS->Dens->LocalSizeR) // check number of elements
 | 
|---|
| [a0bcf1] | 423 |               fprintf(stderr,"(%i)OutputSrcPsiDensity: MPI_Recv of loaded coefficients of GlobalNo %i, owner %i failed: Too few coefficients - %i instead of %i!\n", P->Par.me, k, i, zahl, LevS->Dens->LocalSizeR);
 | 
|---|
 | 424 |             //else        
 | 
|---|
 | 425 |               //fprintf(stderr,"(%i)OutputSrcPsiDensity: MPI_Recv of loaded coefficients of GlobalNo %i, owner %i succeeded!\n", P->Par.me, k, i);
 | 
|---|
 | 426 |           } else { // if it's local ...
 | 
|---|
 | 427 |             if (i != 0) { // but share of array not for us, receive from owner process within Psi group
 | 
|---|
 | 428 |               if (MPI_Recv( destpsiR, LevS->Dens->LocalSizeR, MPI_DOUBLE, i, OutputSrcPsiTag, P->Par.comm_ST_Psi, &status ) != MPI_SUCCESS)
 | 
|---|
 | 429 |                 Error(SomeError, "OutputSrcPsiDensity: MPI_Recv of loaded coefficients failed!");
 | 
|---|
 | 430 |               MPI_Get_count(&status, MPI_DOUBLE, &zahl);
 | 
|---|
| [79290f] | 431 |               if (zahl != (size_t)LevS->Dens->LocalSizeR) // check number of elements
 | 
|---|
| [a0bcf1] | 432 |                 fprintf(stderr,"(%i)OutputSrcPsiDensity: MPI_Recv of loaded coefficients of GlobalNo %i, owner %i failed: Too few coefficients - %i instead of %i!\n", P->Par.me, k, i, zahl, LevS->Dens->LocalSizeR);
 | 
|---|
 | 433 |               //else        
 | 
|---|
 | 434 |                 //fprintf(stderr,"(%i)OutputSrcPsiDensity: MPI_Recv of loaded coefficients of GlobalNo %i, owner %i succeeded!\n", P->Par.me, k, i);
 | 
|---|
 | 435 |             } // otherwise it was our share already 
 | 
|---|
 | 436 |           }
 | 
|---|
 | 437 |           // store the final share on disc
 | 
|---|
 | 438 |           if ((zahl = fwrite(destpsiR, sizeof(double), (size_t)(LevS->Dens->LocalSizeR), SrcPsiData)) != (size_t)(LevS->Dens->LocalSizeR)) {
 | 
|---|
 | 439 |             fclose(SrcPsiData);
 | 
|---|
 | 440 |             //if (P->Par.me == 0)
 | 
|---|
 | 441 |               fprintf(stderr, "(%i)OutputSrcPsiDensity: only %i bytes written instead of expected %i\n", P->Par.me, zahl, LevS->Dens->LocalSizeR);
 | 
|---|
 | 442 |             Error(SomeError,"OutputSrcPsiDensity: fwrite Error");
 | 
|---|
 | 443 |           }
 | 
|---|
 | 444 |         }
 | 
|---|
 | 445 |       } else { // if we are not process 0  of all, we are but a deliverer
 | 
|---|
 | 446 |         if (LOnePsiA != NULL) { // send if it's local
 | 
|---|
 | 447 |           if (P->Par.me_comm_ST_Psi == 0) { // if we are process 0 in the group, send final share to our process 0
 | 
|---|
 | 448 |             for (owner = 0; owner < P->Par.Max_me_comm_ST_Psi; owner++) { // for all processes of our Psi group             
 | 
|---|
 | 449 |               if (owner != 0) { // still not our share of coefficients, receive from owner in our Psi group (increasing owner)
 | 
|---|
 | 450 |                 if (MPI_Recv( destpsiR, LevS->Dens->LocalSizeR, MPI_DOUBLE, owner, OutputSrcPsiTag, P->Par.comm_ST_Psi, &status ) != MPI_SUCCESS)
 | 
|---|
 | 451 |                   Error(SomeError, "OutputSrcPsiDensity: MPI_Recv of loaded coefficients failed!");
 | 
|---|
 | 452 |                 MPI_Get_count(&status, MPI_DOUBLE, &zahl);
 | 
|---|
| [79290f] | 453 |                 if (zahl != (size_t)LevS->Dens->LocalSizeR) // check number of elements
 | 
|---|
| [a0bcf1] | 454 |                   fprintf(stderr,"(%i)OutputSrcPsiDensity: MPI_Recv of loaded coefficients of GlobalNo %i, owner %i failed: Too few coefficients - %i instead of %i!\n", P->Par.me, k, owner, zahl, LevS->Dens->LocalSizeR);
 | 
|---|
 | 455 |                 //else        
 | 
|---|
 | 456 |                   //fprintf(stderr,"(%i)OutputSrcPsiDensity: MPI_Recv of loaded coefficients of GlobalNo %i, owner %i succeeded!\n", P->Par.me, k, owner);
 | 
|---|
 | 457 |               } else sent++; // only count sent if it was our share 
 | 
|---|
 | 458 |               
 | 
|---|
 | 459 |               if (MPI_Send(destpsiR, LevS->Dens->LocalSizeR, MPI_DOUBLE, 0, OutputSrcPsiTag, P->Par.comm_ST_PsiT) != MPI_SUCCESS)
 | 
|---|
 | 460 |                 Error(SomeError, "OutputSrcPsiDensity: MPI_Send of loaded coefficients failed!");
 | 
|---|
 | 461 |               //else 
 | 
|---|
 | 462 |                 //fprintf(stderr,"(%i)OutputSrcPsiDensity: MPI_Send to process %i in PsiT group of loaded coefficients GlobalNo %i succeeded!\n", P->Par.me, 0, k);
 | 
|---|
 | 463 |             }
 | 
|---|
 | 464 |           } else {
 | 
|---|
 | 465 |             sent++;
 | 
|---|
 | 466 |             if (MPI_Send(destpsiR, LevS->Dens->LocalSizeR, MPI_DOUBLE, 0, OutputSrcPsiTag, P->Par.comm_ST_Psi) != MPI_SUCCESS)
 | 
|---|
 | 467 |               Error(SomeError, "OutputSrcPsiDensity: MPI_Send of loaded coefficients failed!");
 | 
|---|
 | 468 |             //else 
 | 
|---|
 | 469 |               //fprintf(stderr,"(%i)OutputSrcPsiDensity: MPI_Send to process %i in Psi group of loaded coefficients GlobalNo %i succeeded!\n", P->Par.me, 0, k);
 | 
|---|
 | 470 |           }
 | 
|---|
 | 471 |         }
 | 
|---|
 | 472 |         // otherwise we don't have anything to do with this
 | 
|---|
 | 473 |       }
 | 
|---|
 | 474 |     }
 | 
|---|
 | 475 |   }
 | 
|---|
 | 476 |   MPI_Allreduce(&sent, &Sent, 1, MPI_INT, MPI_SUM, P->Par.comm_ST); // catch all again at finish
 | 
|---|
| [1da479] | 477 |   if (P->Call.out[PsiOut]) fprintf(stderr,"(%i) Out of %i shares %i had to be sent in total, %i from this process alone.\n", P->Par.me, P->Par.Max_me_comm_ST_Psi*Psi->NoOfPsis, Sent, sent);
 | 
|---|
| [a0bcf1] | 478 |   if (!(P->Par.me_comm_ST))
 | 
|---|
 | 479 |     fclose(SrcPsiData);
 | 
|---|
 | 480 |   SpeedMeasure(P,ReadnWriteTime,StopTimeDo);
 | 
|---|
| [1ce31f] | 481 |   
 | 
|---|
 | 482 |   return 0;
 | 
|---|
| [a0bcf1] | 483 | }
 | 
|---|
 | 484 | 
 | 
|---|
 | 485 | /** Tests whether writing and successant reading of coefficient array is working correctly.
 | 
|---|
 | 486 |  * The local wave function array is written to a disc (\sa OutputSrcPsiDensity()), the by \a wavenr
 | 
|---|
 | 487 |  * specified coefficient array copied to OldPsiDat and afterwards read again via ReadSrcPsiDensity().
 | 
|---|
 | 488 |  * Comparison per process of each local coefficient shows incorrect read or writes.
 | 
|---|
 | 489 |  * \param *P Problem at hand
 | 
|---|
 | 490 |  * \param type minimisation type array to test for read and write
 | 
|---|
 | 491 |  * \return 1 - successful, 0 - test failed 
 | 
|---|
 | 492 |  */
 | 
|---|
 | 493 | int TestReadnWriteSrcDensity(struct Problem *P, enum PsiTypeTag type)
 | 
|---|
 | 494 | {
 | 
|---|
 | 495 |   struct RunStruct *R = &P->R;
 | 
|---|
 | 496 |   struct LatticeLevel *LevS = R->LevS;
 | 
|---|
 | 497 |   struct Lattice *Lat = &P->Lat;
 | 
|---|
 | 498 |   struct Psis *Psi = &Lat->Psi;
 | 
|---|
 | 499 |   int i,k;
 | 
|---|
 | 500 |   fftw_complex *destpsiC, *srcpsiC;
 | 
|---|
 | 501 |   
 | 
|---|
 | 502 |   //fprintf(stderr,"(%i)TestReadnWriteSrcDensity\n",P->Par.me); 
 | 
|---|
 | 503 |   // write whole array of type to disc
 | 
|---|
 | 504 |   OutputSrcPsiDensity(P,type);
 | 
|---|
| [1da479] | 505 |   debug(P,"array written");
 | 
|---|
| [a0bcf1] | 506 |   
 | 
|---|
 | 507 |   // copy specified array to OldPsiDat
 | 
|---|
 | 508 |   for (k=0; k < Lat->Psi.LocalNo; k++)  // for every local wave function of type, copy coefficients
 | 
|---|
 | 509 |     if (Psi->LocalPsiStatus[k].PsiType == type) {  // ... yet only for given type
 | 
|---|
 | 510 |       srcpsiC = LevS->LPsi->LocalPsi[k];
 | 
|---|
 | 511 |       destpsiC = LevS->LPsi->OldLocalPsi[k - Psi->TypeStartIndex[type]];
 | 
|---|
 | 512 |       for (i=0;i<LevS->MaxG;i++) {    // for each every unique G grid vector
 | 
|---|
 | 513 |         destpsiC[i].re = srcpsiC[i].re;  // copy real value
 | 
|---|
 | 514 |         destpsiC[i].im = srcpsiC[i].im;  // copy imaginary value
 | 
|---|
 | 515 |       }
 | 
|---|
 | 516 |     }
 | 
|---|
| [1da479] | 517 |   debug(P,"array copied");
 | 
|---|
| [a0bcf1] | 518 |     
 | 
|---|
 | 519 |   // read whole array again
 | 
|---|
 | 520 |   if (!ReadSrcPsiDensity(P,type,0,R->LevSNo))
 | 
|---|
 | 521 |     return 0;
 | 
|---|
| [1da479] | 522 |   debug(P,"array read");
 | 
|---|
| [a0bcf1] | 523 |   
 | 
|---|
 | 524 |   // compare with copied array
 | 
|---|
 | 525 |   for (k=0; k < Lat->Psi.LocalNo; k++)  // for every local wave function of type, compare coefficients
 | 
|---|
 | 526 |     if (Psi->LocalPsiStatus[k].PsiType == type) {  // ... yet only for given type
 | 
|---|
 | 527 |       srcpsiC = LevS->LPsi->LocalPsi[k];
 | 
|---|
 | 528 |       destpsiC = LevS->LPsi->OldLocalPsi[k - Psi->TypeStartIndex[type]];
 | 
|---|
 | 529 |       for (i=0;i<LevS->MaxG;i++) // for each every unique G grid vector
 | 
|---|
 | 530 |         if ((fabs(destpsiC[i].re - srcpsiC[i].re) >= MYEPSILON) ||(fabs(destpsiC[i].im - srcpsiC[i].im) >= MYEPSILON)) {
 | 
|---|
 | 531 |           fprintf(stderr,"(%i)TestReadnWriteSrcDensity: First difference at index %i - %lg+i%lg against loaded %lg+i%lg\n",P->Par.me, i, srcpsiC[i].re, srcpsiC[i].im,destpsiC[i].re,destpsiC[i].im); 
 | 
|---|
 | 532 |           return 0; 
 | 
|---|
 | 533 |         }
 | 
|---|
 | 534 |     }
 | 
|---|
| [1da479] | 535 |   debug(P,"array compared");
 | 
|---|
| [a0bcf1] | 536 |   fprintf(stderr,"(%i)TestReadnWriteSrcDensity: OK!\n",P->Par.me); 
 | 
|---|
 | 537 |   return 1;
 | 
|---|
 | 538 | }
 | 
|---|
 | 539 | 
 | 
|---|
 | 540 | 
 | 
|---|
 | 541 | /** Read Psis state from an earlier run.
 | 
|---|
 | 542 |  * The doc file is opened, mesh sizes LatticeLevel::N[], global number of Psis read and checked against the known
 | 
|---|
 | 543 |  * values in the inital level RunStruct::LevS. 
 | 
|---|
 | 544 |  * Note, only process 0 handles the files, all read coefficients are transfered to their respective owners via MPI
 | 
|---|
 | 545 |  * afterwards. Here, process 0 of a certain Psi group is used as a transferer for the coefficients of the other processes
 | 
|---|
 | 546 |  * in this Psi group. He receives them all from process 0 and sends them onward accordingly. The complete set of
 | 
|---|
 | 547 |  * coefficients on the real grid for one wave function in the Psi group are transformed into complex wave function
 | 
|---|
 | 548 |  * coefficients by the usual fft procedure (see ChangeToLevUp()).
 | 
|---|
 | 549 |  * 
 | 
|---|
 | 550 |  * \param *P Problem at hand
 | 
|---|
 | 551 |  * \param type minimisation type to read
 | 
|---|
 | 552 |  * \param test whether to just test for presence of files (1) or really read them (0)
 | 
|---|
 | 553 |  * \param LevSNo level number to be read
 | 
|---|
 | 554 |  * \note This is the counterpart to OutputSrcPsiDensity().
 | 
|---|
 | 555 |  * \return 1 - success, 0 - failure
 | 
|---|
 | 556 |  * \note It is not necessary to specify the same number of processes on later restart, any number may be used under
 | 
|---|
 | 557 |  *       the condition that the number of grid nodes match and that there at least 2 processes sharing wave functions
 | 
|---|
 | 558 |  *       in case of SpinUpDown.
 | 
|---|
 | 559 |  * \sa OutputSrcPsiDensity() - same for writing the coefficients, TestReadnWriteSrcDensity() - checks both routines against
 | 
|---|
 | 560 |  *  each other
 | 
|---|
 | 561 |  */
 | 
|---|
 | 562 | int ReadSrcPsiDensity(struct Problem *P, enum PsiTypeTag type, int test, int LevSNo)
 | 
|---|
 | 563 | {
 | 
|---|
 | 564 |   int i, j, k, Index, owner;
 | 
|---|
 | 565 |   struct RunStruct *R = &P->R;
 | 
|---|
 | 566 |   struct Lattice *Lat = &P->Lat;
 | 
|---|
 | 567 |   struct fft_plan_3d *plan = Lat->plan;
 | 
|---|
 | 568 |   struct LatticeLevel *LevS = R->LevS;  // keep open for LevelNo read from file
 | 
|---|
 | 569 |   struct Psis *Psi = &Lat->Psi;
 | 
|---|
 | 570 |   //struct Energy *E = Lat->E;
 | 
|---|
 | 571 |   fftw_complex *work;
 | 
|---|
 | 572 |   double *destpsiR;
 | 
|---|
 | 573 |   fftw_real *srcpsiR;
 | 
|---|
 | 574 |   fftw_complex *srcpsiC;
 | 
|---|
 | 575 |   FILE *SrcPsiData, *SrcPsiDoc;
 | 
|---|
 | 576 |   int N[NDIM], GlobalNo[2];
 | 
|---|
 | 577 |   int LevelNo, readnr=0;
 | 
|---|
| [79290f] | 578 |   int breaksignal = test ? 1 : 2; // 0 - ok, 1 - test failed, 2 - throw Error
 | 
|---|
 | 579 |   size_t zahl;
 | 
|---|
| [c510a7] | 580 |   char suffixdat[MAXSTRINGSIZE], suffixdoc[MAXSTRINGSIZE];
 | 
|---|
| [79290f] | 581 |   int Num = 0, colorNo = 0;
 | 
|---|
 | 582 |   enum PsiTypeTag read_type;
 | 
|---|
| [a0bcf1] | 583 |   char spin[20];
 | 
|---|
 | 584 |   double Eps[2];
 | 
|---|
 | 585 |   MPI_Status status;
 | 
|---|
 | 586 |   struct OnePsiElement *OnePsiA, *LOnePsiA;
 | 
|---|
 | 587 |   int Recv=0, recv=0;
 | 
|---|
 | 588 |   
 | 
|---|
 | 589 |   SpeedMeasure(P,ReadnWriteTime,StartTimeDo);
 | 
|---|
 | 590 |   sprintf(suffixdat, ".%.254s.L%i", P->R.MinimisationName[type], LevSNo);
 | 
|---|
| [c510a7] | 591 |   strncpy (suffixdoc, suffixdat, MAXSTRINGSIZE);
 | 
|---|
| [a0bcf1] | 592 |   // Depending on Psis::SpinType the source psi doc file is opened and header written
 | 
|---|
 | 593 |   switch (Lat->Psi.PsiST) {
 | 
|---|
 | 594 |   case SpinDouble:    
 | 
|---|
 | 595 |     colorNo = 0;
 | 
|---|
| [c510a7] | 596 |     strncat (suffixdat, suffixsrcpsidat, MAXSTRINGSIZE-strlen(suffixdat)); 
 | 
|---|
 | 597 |     strncat (suffixdoc, suffixsrcpsidoc, MAXSTRINGSIZE-strlen(suffixdoc));
 | 
|---|
| [a0bcf1] | 598 |     strncpy (spin, "GlobalNoSpinDouble", 20); 
 | 
|---|
 | 599 |     Num = Lat->Psi.GlobalNo[PsiMaxNoDouble];
 | 
|---|
 | 600 |     break;
 | 
|---|
 | 601 |   case SpinUp:
 | 
|---|
 | 602 |     colorNo = 0;
 | 
|---|
| [c510a7] | 603 |     strncat (suffixdat, suffixsrcpsiupdat, MAXSTRINGSIZE-strlen(suffixdat)); 
 | 
|---|
 | 604 |     strncat (suffixdoc, suffixsrcpsiupdoc, MAXSTRINGSIZE-strlen(suffixdoc)); 
 | 
|---|
| [a0bcf1] | 605 |     strncpy (spin, "GlobalNoSpinUp", 20); 
 | 
|---|
 | 606 |     Num = Lat->Psi.GlobalNo[PsiMaxNoUp];
 | 
|---|
 | 607 |     break;
 | 
|---|
 | 608 |   case SpinDown:
 | 
|---|
 | 609 |     colorNo = 1;
 | 
|---|
| [c510a7] | 610 |     strncat (suffixdat, suffixsrcpsidowndat, MAXSTRINGSIZE-strlen(suffixdat)); 
 | 
|---|
 | 611 |     strncat (suffixdoc, suffixsrcpsidowndoc, MAXSTRINGSIZE-strlen(suffixdoc)); 
 | 
|---|
| [a0bcf1] | 612 |     strncpy (spin, "GlobalNoSpinDown", 20); 
 | 
|---|
 | 613 |     Num = Lat->Psi.GlobalNo[PsiMaxNoDown];
 | 
|---|
 | 614 |     break;
 | 
|---|
 | 615 |   }
 | 
|---|
 | 616 |   // open doc file ...
 | 
|---|
 | 617 |   if (!(P->Par.me_comm_ST)) {
 | 
|---|
 | 618 |     if (!OpenFile(P, &SrcPsiDoc, suffixdoc, "r", test ? 0 : P->Call.out[ReadOut])) { // open doc file
 | 
|---|
 | 619 |       debug(P,"ReadSrcPsiDensity: doc file pointer NULL\n");
 | 
|---|
 | 620 |       if (test) {
 | 
|---|
| [79290f] | 621 |         if (MPI_Bcast(&breaksignal,1,MPI_INT,0,P->Par.comm_ST) != MPI_SUCCESS)
 | 
|---|
| [a0bcf1] | 622 |           Error(SomeError,"ReadSrcPsiDensity: Bcast of signal failed\n");
 | 
|---|
 | 623 |         return 0;
 | 
|---|
 | 624 |       }
 | 
|---|
| [79290f] | 625 |       if (MPI_Bcast(&breaksignal,1,MPI_INT,0,P->Par.comm_ST) != MPI_SUCCESS)
 | 
|---|
| [a0bcf1] | 626 |         Error(SomeError,"ReadSrcPsiDensity: Bcast of signal failed\n");
 | 
|---|
 | 627 |       Error(SomeError,"ReadSrcPsiDensity: cannot open doc file!");
 | 
|---|
 | 628 |     }
 | 
|---|
 | 629 |     // ... and parse critical ...
 | 
|---|
| [961b75] | 630 |     readnr += ParseForParameter(0,SrcPsiDoc,"Mintype",0,1,1,int_type,(int *)&read_type, 1, test ? optional : critical);
 | 
|---|
 | 631 |     readnr += ParseForParameter(0,SrcPsiDoc,"LevelNo",0,1,1,int_type,&LevelNo,1,  test ? optional : critical);
 | 
|---|
 | 632 |     readnr += 3*ParseForParameter(0,SrcPsiDoc,"GridNodes",0,3,1,row_int,&N[0], 1, test ? optional : critical);
 | 
|---|
 | 633 |     readnr += 2*ParseForParameter(0,SrcPsiDoc,"PsiNo",0,2,1,row_int,&GlobalNo[0], 1, test ? optional : critical);
 | 
|---|
| [a0bcf1] | 634 |     // and optional items ...
 | 
|---|
| [961b75] | 635 |     if (ParseForParameter(0,SrcPsiDoc,"Epsilon",0,2,1,row_double,&Eps[0],1,optional))
 | 
|---|
| [d6f7f3] | 636 |       if (((P->Call.ReadSrcFiles == DoReadAllSrcDensities) || (P->Call.ReadSrcFiles == DoReadOccupiedSrcDensities)) && ((Eps[1] < R->RelEpsKineticEnergy) || (Eps[0] < R->RelEpsTotalEnergy))) {
 | 
|---|
| [a0bcf1] | 637 |         //fprintf(stderr,"(%i) Eps %lg %lg\tRelEps %lg %lg\n", P->Par.me, Eps[0], Eps[1], R->RelEpsTotalEnergy, R->RelEpsKineticEnergy);
 | 
|---|
 | 638 |         fprintf(stderr,"(%i) NOTE: Doing minimization after source file parsing due to smaller specified epsilon stop conditions.\n",P->Par.me); 
 | 
|---|
| [d6f7f3] | 639 |         P->Call.ReadSrcFiles = DoReadAndMinimise; // do minimisation even after loading
 | 
|---|
| [a0bcf1] | 640 |       }
 | 
|---|
 | 641 |     if (readnr != 7) { // check number of items read
 | 
|---|
 | 642 |       debug(P, "ReadSrcPsiDensity: too few doc items in file\n");
 | 
|---|
 | 643 |       fclose(SrcPsiDoc);
 | 
|---|
 | 644 |       if (test) {
 | 
|---|
| [79290f] | 645 |         if (MPI_Bcast(&breaksignal,1,MPI_INT,0,P->Par.comm_ST) != MPI_SUCCESS)
 | 
|---|
| [a0bcf1] | 646 |           Error(SomeError,"ReadSrcPsiDensity: Bcast of signal failed\n");
 | 
|---|
 | 647 |         return 0;
 | 
|---|
 | 648 |       }
 | 
|---|
 | 649 |       fprintf(stderr,"ReadSrcPsiDensity: Only %i items read!\n",readnr);
 | 
|---|
| [79290f] | 650 |       if (MPI_Bcast(&breaksignal,1,MPI_INT,0,P->Par.comm_ST) != MPI_SUCCESS)
 | 
|---|
| [a0bcf1] | 651 |         Error(SomeError,"ReadSrcPsiDensity: Bcast of signal failed\n");
 | 
|---|
 | 652 |       Error(SomeError, "ReadSrcPsiDensity: read error");
 | 
|---|
 | 653 |     }
 | 
|---|
 | 654 |     // check if levels match
 | 
|---|
 | 655 |     if (LevSNo != LevelNo) { 
 | 
|---|
 | 656 |       debug(P,"ReadSrcPsiDensity: mismatching levels\n");
 | 
|---|
 | 657 |       fclose(SrcPsiDoc);
 | 
|---|
 | 658 |       if (test) {
 | 
|---|
| [79290f] | 659 |         if (MPI_Bcast(&breaksignal,1,MPI_INT,0,P->Par.comm_ST) != MPI_SUCCESS)
 | 
|---|
| [a0bcf1] | 660 |           Error(SomeError,"ReadSrcPsiDensity: Bcast of signal failed\n");
 | 
|---|
 | 661 |         return 0;
 | 
|---|
 | 662 |       }
 | 
|---|
| [79290f] | 663 |       if (MPI_Bcast(&breaksignal,1,MPI_INT,0,P->Par.comm_ST) != MPI_SUCCESS)
 | 
|---|
| [a0bcf1] | 664 |         Error(SomeError,"ReadSrcPsiDensity: Bcast of signal failed\n");
 | 
|---|
 | 665 |       Error(SomeError,"ReadSrcPsiDensity: Mismatching levels!");
 | 
|---|
 | 666 |     } else {
 | 
|---|
 | 667 |       LevS = &P->Lat.Lev[LevelNo];
 | 
|---|
 | 668 |     }
 | 
|---|
 | 669 |     
 | 
|---|
 | 670 |     // check if systems in memory and file match
 | 
|---|
 | 671 |     if ((read_type != R->CurrentMin) || (N[0] !=  LevS->N[0]) || (N[1] !=  LevS->N[1]) || (N[2] !=  LevS->N[2]) || (GlobalNo[0] != Num) || (GlobalNo[1] != Lat->Psi.GlobalNo[PsiMaxAdd])) { // check read system
 | 
|---|
 | 672 |       debug(P,"ReadSrcPsiDensity: srcpsi file does not fit to system\n");
 | 
|---|
 | 673 |       fclose(SrcPsiDoc);
 | 
|---|
 | 674 |       if (test) {
 | 
|---|
 | 675 |         fprintf(stderr,"(%i) Min\t N(x,y,z)\tPsiNo+AddNo\n file: %s\t %i %i %i\t %i + %i\nsystem: %s\t %d %d %d\t %d + %d\n",P->Par.me, R->MinimisationName[read_type], N[0], N[1], N[2], GlobalNo[0], GlobalNo[1], R->MinimisationName[R->CurrentMin], LevS->N[0] , LevS->N[1], LevS->N[2], Lat->Psi.GlobalNo[PsiMaxNoDouble], Lat->Psi.GlobalNo[PsiMaxAdd]);
 | 
|---|
| [79290f] | 676 |         if (MPI_Bcast(&breaksignal,1,MPI_INT,0,P->Par.comm_ST) != MPI_SUCCESS)
 | 
|---|
| [a0bcf1] | 677 |           Error(SomeError,"ReadSrcPsiDensity: Bcast of signal failed\n");
 | 
|---|
 | 678 |         return 0;
 | 
|---|
 | 679 |       }
 | 
|---|
 | 680 |       fprintf(stderr,"ReadSrcPsiDensity: Type %i != CurrentMin %i || N[0] %i != %i || N[1] %i != %i || N[2] %i != %i || %s %i + %i != %i + %i\n", read_type, R->CurrentMin, N[0], LevS->N[0], N[1], LevS->N[1], N[2], LevS->N[2], spin, GlobalNo[0], GlobalNo[1], Num, P->Lat.Psi.GlobalNo[PsiMaxAdd]);
 | 
|---|
| [79290f] | 681 |       if (MPI_Bcast(&breaksignal,1,MPI_INT,0,P->Par.comm_ST) != MPI_SUCCESS)
 | 
|---|
| [a0bcf1] | 682 |         Error(SomeError,"ReadSrcPsiDensity: Bcast of signal failed\n");
 | 
|---|
 | 683 |       Error(SomeError,"ReadSrcPsiDensity: srcpsi file does not fit to system");
 | 
|---|
 | 684 |     }
 | 
|---|
| [79290f] | 685 |     breaksignal = 0; // everything went alright, signal ok
 | 
|---|
 | 686 |     if (MPI_Bcast(&breaksignal,1,MPI_INT,0,P->Par.comm_ST) != MPI_SUCCESS)
 | 
|---|
| [a0bcf1] | 687 |       Error(SomeError,"ReadSrcPsiDensity: Bcast of signal failed\n");
 | 
|---|
 | 688 |   } else {  // others wait for signal from root process
 | 
|---|
| [79290f] | 689 |     if (MPI_Bcast(&breaksignal,1,MPI_INT,0,P->Par.comm_ST) != MPI_SUCCESS)
 | 
|---|
| [a0bcf1] | 690 |       Error(SomeError,"ReadSrcPsiDensity: Bcast of signal failed\n");
 | 
|---|
| [79290f] | 691 |     if (breaksignal == 1)
 | 
|---|
| [a0bcf1] | 692 |       return 0;
 | 
|---|
| [79290f] | 693 |     else if (breaksignal == 2)
 | 
|---|
| [a0bcf1] | 694 |       Error(SomeError, "ReadSrcPsiDensity: Something went utterly wrong, see root process");
 | 
|---|
| [1da479] | 695 |     else if (P->Call.out[PsiOut])
 | 
|---|
| [a0bcf1] | 696 |       fprintf(stderr,"(%i) ReadSrcPsiDensity: Everything went alright so far\n", P->Par.me);
 | 
|---|
 | 697 |   }
 | 
|---|
 | 698 |   if (MPI_Bcast(&LevelNo,1,MPI_INT,0,P->Par.comm_ST) != MPI_SUCCESS)
 | 
|---|
 | 699 |     Error(SomeError,"ReadSrcPsiDensity: Bcast of LevelNo failed\n");
 | 
|---|
 | 700 |   LevS = &P->Lat.Lev[LevelNo];
 | 
|---|
 | 701 |   //if (!test) fprintf(stderr,"(%i) LevelSNo %i\n", P->Par.me, LevS->LevelNo);
 | 
|---|
 | 702 | 
 | 
|---|
 | 703 |   if (!test) {
 | 
|---|
 | 704 |     // set some pointers for work to follow
 | 
|---|
 | 705 |     work = (fftw_complex *)LevS->Dens->DensityArray[TempDensity];
 | 
|---|
 | 706 |     destpsiR = (double *)LevS->Dens->DensityArray[TempDensity];
 | 
|---|
 | 707 |     srcpsiR = (fftw_real *)LevS->Dens->DensityCArray[TempDensity];
 | 
|---|
 | 708 |     srcpsiC = (fftw_complex *)LevS->Dens->DensityCArray[TempDensity];
 | 
|---|
 | 709 |   
 | 
|---|
 | 710 |     // read share of coefficient array for each wave function and send/receive around
 | 
|---|
 | 711 |     owner = 0;
 | 
|---|
 | 712 |     MPI_Allreduce (&recv, &Recv, 1, MPI_INT, MPI_SUM, P->Par.comm_ST);
 | 
|---|
 | 713 |     //fprintf(stderr,"(%i) me (%i/%i) \t Psi (%i/%i)\t PsiT (%i/%i)\n", P->Par.me, P->Par.me_comm_ST, P->Par.Max_me_comm_ST, P->Par.me_comm_ST_Psi, P->Par.Max_me_comm_ST_Psi, P->Par.me_comm_ST_PsiT, P->Par.Max_me_comm_ST_PsiT);
 | 
|---|
 | 714 |     k = -1;  // k is global PsiNo counter for the desired group
 | 
|---|
 | 715 |     for (j=0; j < Psi->MaxPsiOfType+P->Par.Max_me_comm_ST_PsiT; j++) {  // go through all wave functions (plus the extra one for each process)
 | 
|---|
 | 716 |       OnePsiA = &Psi->AllPsiStatus[j];    // grab OnePsiA
 | 
|---|
 | 717 |       if (OnePsiA->PsiType == type) { // only take desired minimisation group
 | 
|---|
 | 718 |         k++;
 | 
|---|
| [1da479] | 719 |         //fprintf(stderr,"(%i) ST_Psi: OnePsiA %i\tP->Par.my_color_comm_ST_Psi %i\n", P->Par.me,OnePsiA->my_color_comm_ST_Psi,P->Par.my_color_comm_ST_Psi);
 | 
|---|
| [a0bcf1] | 720 |         if (OnePsiA->my_color_comm_ST_Psi == P->Par.my_color_comm_ST_Psi) // Belongs to my Psi group?
 | 
|---|
 | 721 |            LOnePsiA = &Psi->LocalPsiStatus[OnePsiA->MyLocalNo];
 | 
|---|
 | 722 |         else 
 | 
|---|
 | 723 |            LOnePsiA = NULL;
 | 
|---|
 | 724 |     
 | 
|---|
 | 725 |         if (P->Par.me_comm_ST == 0) { // if we are process 0 of all, we may access file
 | 
|---|
 | 726 |           if (!OpenFileNo(P, &SrcPsiData, suffixdat, colorNo, "r", test ? 0 : P->Call.out[ReadOut])) {
 | 
|---|
 | 727 |             Error(SomeError,"ReadSrcPsiDensity: cannot open data file");
 | 
|---|
 | 728 |           }        
 | 
|---|
 | 729 |           for (i=P->Par.Max_me_comm_ST_Psi-1; i>=0;i--) { // load coefficients
 | 
|---|
 | 730 |             fseek( SrcPsiData, (long)((k*N[0]*N[1]*N[2]+i*((long)LevS->Dens->LocalSizeR))*sizeof(double)), SEEK_SET); // seek to beginning of this process' coefficients
 | 
|---|
 | 731 |             // readin 
 | 
|---|
 | 732 |             if ((zahl = fread(destpsiR, sizeof(double), (size_t)(LevS->Dens->LocalSizeR), SrcPsiData)) != (size_t)LevS->Dens->LocalSizeR) {
 | 
|---|
 | 733 |               fclose(SrcPsiData);
 | 
|---|
 | 734 |               fprintf(stderr, "(%i)ReadSrcPsiDensity: only %i bytes read instead of expected %i\n", P->Par.me, zahl, LevS->Dens->LocalSizeR);
 | 
|---|
 | 735 |               Error(SomeError,"ReadSrcPsiDensity: fread Error");
 | 
|---|
 | 736 |             }
 | 
|---|
 | 737 |             if (LOnePsiA == NULL) {   // if it's not local, send away coefficients to correct PsiGroup (process 0 within that group)
 | 
|---|
 | 738 |               if (MPI_Send(destpsiR, LevS->Dens->LocalSizeR, MPI_DOUBLE, OnePsiA->my_color_comm_ST_Psi, ReadSrcPsiTag, P->Par.comm_ST_PsiT) != MPI_SUCCESS)
 | 
|---|
 | 739 |                 Error(SomeError, "ReadSrcPsiDensity: MPI_Send of loaded coefficients failed!");
 | 
|---|
 | 740 |               //else 
 | 
|---|
 | 741 |                 //fprintf(stderr,"(%i)ReadSrcPsiDensity: MPI_Send to process %i of loaded coefficients GlobalNo %i, owner %i succeeded!\n", P->Par.me, OnePsiA->my_color_comm_ST_Psi, k, i); 
 | 
|---|
 | 742 |             } else { // if it's local ...
 | 
|---|
 | 743 |               if (i != 0) { // but share of array not for us, send to owner process within Psi group
 | 
|---|
 | 744 |                 if (MPI_Send(destpsiR, LevS->Dens->LocalSizeR, MPI_DOUBLE, i, ReadSrcPsiTag, P->Par.comm_ST_Psi) != MPI_SUCCESS)
 | 
|---|
 | 745 |                   Error(SomeError, "ReadSrcPsiDensity: MPI_Send within Psi group of loaded coefficients failed!");
 | 
|---|
 | 746 |                 //else 
 | 
|---|
 | 747 |                   //fprintf(stderr,"(%i)ReadSrcPsiDensity: MPI_Send to process %i within Psi group of loaded coefficients GlobalNo %i succeeded!\n", P->Par.me, i, k);
 | 
|---|
 | 748 |               } // otherwise it was our share already 
 | 
|---|
 | 749 |             }
 | 
|---|
 | 750 |           }
 | 
|---|
 | 751 |         } else {
 | 
|---|
 | 752 |           if (LOnePsiA != NULL) { // receive
 | 
|---|
 | 753 |             if (P->Par.me_comm_ST_Psi == 0) { // if we are process 0 in the group, receive share from process 0 of all
 | 
|---|
 | 754 |               for (owner = P->Par.Max_me_comm_ST_Psi -1; owner >=0; owner--) { // for all processes of our Psi group
 | 
|---|
 | 755 |                 if (MPI_Recv(destpsiR, LevS->Dens->LocalSizeR, MPI_DOUBLE, 0, ReadSrcPsiTag, P->Par.comm_ST_PsiT, &status) != MPI_SUCCESS)
 | 
|---|
 | 756 |                   Error(SomeError, "ReadSrcPsiDensity: MPI_Recv of loaded coefficients failed!");
 | 
|---|
 | 757 |                 MPI_Get_count(&status, MPI_DOUBLE, &zahl);
 | 
|---|
| [79290f] | 758 |                 if (zahl != (size_t)LevS->Dens->LocalSizeR) // check number of elements
 | 
|---|
| [a0bcf1] | 759 |                   fprintf(stderr,"(%i)ReadSrcPsiDensity: MPI_Recv from process 0 of loaded coefficients of GlobalNo %i, owner %i failed: Too few coefficients - %i instead of %i!\n", P->Par.me, k, owner, zahl, LevS->Dens->LocalSizeR);
 | 
|---|
 | 760 |                 //else        
 | 
|---|
 | 761 |                   //fprintf(stderr,"(%i)ReadSrcPsiDensity: MPI_Recv from process 0 of loaded coefficients of GlobalNo %i, owner %i succeeded!\n", P->Par.me, k, owner);
 | 
|---|
 | 762 |                 
 | 
|---|
 | 763 |                 if (owner != 0) { // not our share of coefficients, send to owner in our Psi group
 | 
|---|
 | 764 |                   if (MPI_Send(destpsiR, LevS->Dens->LocalSizeR, MPI_DOUBLE, owner, ReadSrcPsiTag, P->Par.comm_ST_Psi) != MPI_SUCCESS)
 | 
|---|
 | 765 |                     Error(SomeError, "ReadSrcPsiDensity: MPI_Send within Psi group of loaded coefficients failed!");
 | 
|---|
 | 766 |                   //else 
 | 
|---|
 | 767 |                     //fprintf(stderr,"(%i)ReadSrcPsiDensity: MPI_Send to process %i within Psi group of loaded coefficients GlobalNo %i succeeded!\n", P->Par.me, owner, k);
 | 
|---|
 | 768 |                 } else recv++;
 | 
|---|
 | 769 |               }
 | 
|---|
 | 770 |               // otherwise it's our share!
 | 
|---|
 | 771 |             } else {  // our share within Psi Group not belonging to process 0 of all
 | 
|---|
 | 772 |               recv++;
 | 
|---|
 | 773 |               if (MPI_Recv(destpsiR, LevS->Dens->LocalSizeR, MPI_DOUBLE, 0, ReadSrcPsiTag, P->Par.comm_ST_Psi, &status) != MPI_SUCCESS)
 | 
|---|
 | 774 |                 Error(SomeError, "ReadSrcPsiDensity: MPI_Recv of loaded coefficients failed!");
 | 
|---|
 | 775 |               MPI_Get_count(&status, MPI_DOUBLE, &zahl);
 | 
|---|
| [79290f] | 776 |               if (zahl != (size_t)LevS->Dens->LocalSizeR) // check number of elements
 | 
|---|
| [a0bcf1] | 777 |                 fprintf(stderr,"(%i)ReadSrcPsiDensity: MPI_Recv of loaded coefficients of GlobalNo %i, owner %i failed: Too few coefficients - %i instead of %i!\n", P->Par.me, k, P->Par.me_comm_ST_Psi, zahl, LevS->Dens->LocalSizeR);
 | 
|---|
 | 778 |               //else        
 | 
|---|
 | 779 |                 //fprintf(stderr,"(%i)ReadSrcPsiDensity: MPI_Recv of loaded coefficients of GlobalNo %i, owner %i succeeded!\n", P->Par.me, k, P->Par.me_comm_ST_Psi);
 | 
|---|
 | 780 |             } 
 | 
|---|
 | 781 |           }
 | 
|---|
 | 782 |           // otherwise we don't have anything to do with this
 | 
|---|
 | 783 |         }
 | 
|---|
 | 784 |         
 | 
|---|
 | 785 |         if (LOnePsiA != NULL) {
 | 
|---|
 | 786 |           SetArrayToDouble0((double *)srcpsiR, LevS->Dens->TotalSize*2);
 | 
|---|
 | 787 |           for (i=0; i < LevS->Dens->LocalSizeR; i++)  // copy dest to src
 | 
|---|
 | 788 |             srcpsiR[i] = (fftw_real)destpsiR[i];
 | 
|---|
 | 789 |     
 | 
|---|
 | 790 |           fft_3d_real_to_complex(plan, LevS->LevelNo, FFTNF1, srcpsiC, work); // fft transform
 | 
|---|
 | 791 |           //if (P->Call.out[PsiOut]) 
 | 
|---|
 | 792 |           //fprintf(stderr,"(%i) LevSNo %i\t LocalPsi %p\n", P->Par.me, LevS->LevelNo, LevS->LPsi->LocalPsi[LOnePsiA->MyLocalNo]);
 | 
|---|
 | 793 |           for (i=0;i<LevS->MaxG;i++) {  // and copy into wave functions coefficients
 | 
|---|
 | 794 |             Index = LevS->GArray[i].Index;
 | 
|---|
 | 795 |             LevS->LPsi->LocalPsi[LOnePsiA->MyLocalNo][i].re = srcpsiC[Index].re/LevS->MaxN;
 | 
|---|
 | 796 |             LevS->LPsi->LocalPsi[LOnePsiA->MyLocalNo][i].im = srcpsiC[Index].im/LevS->MaxN;
 | 
|---|
 | 797 |           }
 | 
|---|
 | 798 |         }
 | 
|---|
 | 799 |         if ((P->Par.me_comm_ST == 0) && (SrcPsiData != NULL)) fclose(SrcPsiData);
 | 
|---|
 | 800 |       }
 | 
|---|
 | 801 |     }
 | 
|---|
 | 802 |     MPI_Allreduce (&recv, &Recv, 1, MPI_INT, MPI_SUM, P->Par.comm_ST);
 | 
|---|
| [1da479] | 803 |     if (P->Call.out[PsiOut]) fprintf(stderr,"(%i) Out of %i shares %i had to be received in total, %i from this process alone.\n", P->Par.me, P->Par.Max_me_comm_ST_Psi*Psi->NoOfPsis, Recv, recv);
 | 
|---|
| [a0bcf1] | 804 |     SpeedMeasure(P,ReadnWriteTime,StopTimeDo);
 | 
|---|
 | 805 |   }
 | 
|---|
 | 806 |   return 1; // everything went well till the end
 | 
|---|
 | 807 | }
 | 
|---|
 | 808 | 
 | 
|---|
 | 809 | /** Creates the density \ref suffixdensdoc and \ref suffixdensdx files for OpenDx.
 | 
|---|
 | 810 |  * Opens \ref suffixdensdoc, fills (pos&data file name, byte order, max mesh points, matrix alignment, steps)
 | 
|---|
 | 811 |  * and closes it.
 | 
|---|
| [cc46b0] | 812 |  * Opens \ref suffixdensdx, then for every FileData::*OutVisStep a describing structure for DX is written and
 | 
|---|
| [a0bcf1] | 813 |  * the file closed again.
 | 
|---|
 | 814 |  * \param *P Problem at hand
 | 
|---|
 | 815 |  * \param me my process number in communicator Psi (0 - do nothing, else - do)
 | 
|---|
 | 816 |  */
 | 
|---|
 | 817 | static void CreateDensityOutputGeneral(struct Problem *P, const int me)
 | 
|---|
 | 818 | {
 | 
|---|
 | 819 |   FILE *DensityDoc, *DensityDx;
 | 
|---|
| [9bebe0] | 820 |   char *posname, *datname, *suffix; 
 | 
|---|
| [a0bcf1] | 821 |   struct LatticeLevel *Lev = &P->Lat.Lev[STANDARTLEVEL];
 | 
|---|
 | 822 |   unsigned int i, MaxPoints, N[NDIM];
 | 
|---|
 | 823 |   double *RB = P->Lat.RealBasis;
 | 
|---|
 | 824 |   if (me) return;
 | 
|---|
 | 825 |   N[0] = Lev->N[0]*Lev->NUp[0];
 | 
|---|
 | 826 |   N[1] = Lev->N[1]*Lev->NUp[1];
 | 
|---|
 | 827 |   N[2] = Lev->N[2]*Lev->NUp[2];
 | 
|---|
 | 828 |   MaxPoints = (N[0]+1)*(N[1]+1)*(N[2]+1);
 | 
|---|
 | 829 |   posname = (char*)
 | 
|---|
| [57a69b2] | 830 |     Malloc(strlen(P->Files.mainname) + strlen(suffixdenspos) + 3 + 1,"CreateDensityOutputGeneral: posname");
 | 
|---|
 | 831 |   sprintf(posname, "%s.L%i%s", P->Files.mainname, Lev->LevelNo, suffixdenspos);
 | 
|---|
| [a0bcf1] | 832 |   datname = (char*)
 | 
|---|
| [57a69b2] | 833 |     Malloc(strlen(P->Files.mainname) + strlen(suffixdensdat) + 3 + 1,"CreateDensityOutputGeneral: datname");
 | 
|---|
 | 834 |   sprintf(datname, "%s.L%i%s", P->Files.mainname, Lev->LevelNo, suffixdensdat);
 | 
|---|
| [a0bcf1] | 835 |   // write doc file
 | 
|---|
| [9bebe0] | 836 |   suffix = (char *)
 | 
|---|
 | 837 |     Malloc(strlen(suffixdensdoc) + 3 + 1,"CreateDensityOutputGeneral: suffix");
 | 
|---|
 | 838 |   sprintf(suffix, ".L%i%s", Lev->LevelNo, suffixdensdoc);
 | 
|---|
 | 839 |   OpenFile(P, &DensityDoc, suffix, "w",P->Call.out[ReadOut]);
 | 
|---|
| [a0bcf1] | 840 |   fprintf(DensityDoc,"DensityPositions file = %s.####\n", posname);
 | 
|---|
 | 841 |   fprintf(DensityDoc,"DensityData file = %s.####\n", datname);
 | 
|---|
 | 842 |   fprintf(DensityDoc,"format = ieee float (Bytes %lu) %s\n",(unsigned long) sizeof(float),msb);
 | 
|---|
 | 843 |   fprintf(DensityDoc,"points = %i\n", MaxPoints);
 | 
|---|
 | 844 |   fprintf(DensityDoc,"majority = row\n");
 | 
|---|
| [cc46b0] | 845 |   fprintf(DensityDoc,"TimeSeries = %i\n",P->Files.OutVisStep[Lev->LevelNo]+1);
 | 
|---|
| [a0bcf1] | 846 |   fclose(DensityDoc);
 | 
|---|
| [9bebe0] | 847 |   Free(suffix, "CreateDensityOutputGeneral: suffix");
 | 
|---|
| [a0bcf1] | 848 |   // write DX file
 | 
|---|
| [9bebe0] | 849 |   suffix = (char *)
 | 
|---|
 | 850 |     Malloc(strlen(suffixdensdx) + 3 + 1,"CreateDensityOutputGeneral: suffix");
 | 
|---|
 | 851 |   sprintf(suffix, ".L%i%s", Lev->LevelNo, suffixdensdx);
 | 
|---|
 | 852 |   OpenFile(P, &DensityDx, suffix, "w",P->Call.out[ReadOut]);
 | 
|---|
| [cc46b0] | 853 |   for (i=0; i < (unsigned int)P->Files.OutVisStep[Lev->LevelNo]+1; i++) { // for every OutVis step
 | 
|---|
| [a0bcf1] | 854 |     if (i==0) { 
 | 
|---|
 | 855 |       fprintf(DensityDx,"object \"gridcon\" class gridconnections counts %i %i %i\n\n",(N[0]+1),(N[1]+1),(N[2]+1));
 | 
|---|
 | 856 |       if (P->Files.OutputPosType[i] != active)
 | 
|---|
 | 857 |         fprintf(DensityDx, "object \"posdens\" class gridpositions counts %i %i %i\norigin 0.0  0.0  0.0\ndelta  %f  %f  %f\ndelta  %f  %f  %f\ndelta  %f  %f  %f\n\n",
 | 
|---|
 | 858 |                 (N[0]+1),(N[1]+1),(N[2]+1),
 | 
|---|
 | 859 |                 (float)(RB[0]/N[0]),(float)(RB[1]/N[0]),(float)RB[2]/N[0],
 | 
|---|
 | 860 |                 (float)(RB[3]/N[1]),(float)(RB[4]/N[1]),(float)RB[5]/N[1],
 | 
|---|
 | 861 |                 (float)(RB[6]/N[2]),(float)(RB[7]/N[2]),(float)RB[8]/N[2]);
 | 
|---|
 | 862 |       }
 | 
|---|
 | 863 |       if (P->Files.OutputPosType[i] == active) {
 | 
|---|
 | 864 |         fprintf(DensityDx,
 | 
|---|
 | 865 |               "object \"pos.%04u\" class array type float rank 1 shape 3 items %i %s binary\n",i,MaxPoints,msb); 
 | 
|---|
 | 866 |         fprintf(DensityDx,"data file %s.%04u,0\n",posname,i);
 | 
|---|
 | 867 |       }
 | 
|---|
 | 868 |       fprintf(DensityDx,"attribute \"dep\" string \"positions\"\n");
 | 
|---|
 | 869 |       fprintf(DensityDx,"# %lu - %lu Bytes\n\n",MaxPoints*i*(unsigned long)sizeof(float)*NDIM,MaxPoints*(i+1)*(unsigned long)sizeof(float)*NDIM-1);
 | 
|---|
 | 870 |   
 | 
|---|
 | 871 |       fprintf(DensityDx,"object \"dat.%04u\" class array type float rank 0 items %i %s binary\n",i,MaxPoints,msb);
 | 
|---|
 | 872 |       fprintf(DensityDx,"data file %s.%04u,0\n",datname,i);
 | 
|---|
 | 873 |       fprintf(DensityDx,"attribute \"dep\" string \"positions\"\n");
 | 
|---|
 | 874 |       fprintf(DensityDx,"# %lu - %lu Bytes\n\n",MaxPoints*i*(unsigned long)sizeof(float),MaxPoints*(i+1)*(unsigned long)sizeof(float)-1);
 | 
|---|
 | 875 |   
 | 
|---|
 | 876 |       fprintf(DensityDx,"object \"obj.%04u\" class field\n",i);
 | 
|---|
 | 877 |       if (P->Files.OutputPosType[i] == active)
 | 
|---|
 | 878 |         fprintf(DensityDx,"component \"positions\" \"pos.%04i\"\n",i);
 | 
|---|
 | 879 |       if (P->Files.OutputPosType[i] != active)
 | 
|---|
 | 880 |         fprintf(DensityDx,"component \"positions\" \"posdens\"\n");
 | 
|---|
 | 881 |       fprintf(DensityDx,"component \"connections\" \"gridcon\"\n");
 | 
|---|
 | 882 |       fprintf(DensityDx,"component \"data\" \"dat.%04i\"\n",i);
 | 
|---|
 | 883 |     }
 | 
|---|
 | 884 |   fprintf(DensityDx,"\nobject \"series\" class series\n");
 | 
|---|
| [cc46b0] | 885 |   for (i=0; i < (unsigned int)P->Files.OutVisStep[Lev->LevelNo]+1; i++) 
 | 
|---|
| [a0bcf1] | 886 |     fprintf(DensityDx,"member %i \"obj.%04u\" position %f\n",i,i,(float)i);
 | 
|---|
 | 887 |   fprintf(DensityDx,"end\n");
 | 
|---|
 | 888 |   fclose(DensityDx);
 | 
|---|
| [9bebe0] | 889 |   Free(suffix, "CreateDensityOutputGeneral: suffix");
 | 
|---|
 | 890 | 
 | 
|---|
| [64fa9e] | 891 |   Free(posname, "CreateDensityOutputGeneral: posname");
 | 
|---|
 | 892 |   Free(datname, "CreateDensityOutputGeneral: datname");
 | 
|---|
| [a0bcf1] | 893 | }
 | 
|---|
 | 894 | 
 | 
|---|
 | 895 | /** Calculates the OutVis density of the RiemannTensor level.
 | 
|---|
 | 896 |  * The usual pattern arises when a density is fftransformed:
 | 
|---|
 | 897 |  * -# over all grid vectors up to MaxG
 | 
|---|
 | 898 |  * -# over all doubly grid vectors up to MaxDoubleG
 | 
|---|
 | 899 |  * -# call to fft_3d_complex_to_real()
 | 
|---|
 | 900 |  * 
 | 
|---|
 | 901 |  * In this case here followed by call to OutVisPosRTransformPosNFRto0() and finally FileData::work
 | 
|---|
 | 902 |  * is copied to FileData::PosR.
 | 
|---|
 | 903 |  * \param *Lat Lattice structure, containing Lattice::plan and LatticeLevel
 | 
|---|
 | 904 |  * \param *F FileData structure, containing FileData::PosC, FileData::PosR, FileData::work, FileData::Totalsize, FileData::LocalSizeR
 | 
|---|
 | 905 |  */
 | 
|---|
 | 906 | static void CalculateOutVisDensityPos(struct Lattice *Lat, struct FileData *F/*, const double FactorC_R, const double FactorR_C*/) 
 | 
|---|
 | 907 | {
 | 
|---|
 | 908 |   struct  fft_plan_3d *plan = Lat->plan;
 | 
|---|
 | 909 |   struct RiemannTensor *RT = &Lat->RT;
 | 
|---|
 | 910 |   struct LatticeLevel *LevR = RT->LevR;
 | 
|---|
 | 911 |   fftw_complex *destC = F->PosC;
 | 
|---|
 | 912 |   fftw_real *destR = F->PosR;
 | 
|---|
 | 913 |   fftw_complex *work = F->work;
 | 
|---|
 | 914 |   fftw_real *workR = (fftw_real*)work;
 | 
|---|
 | 915 |   fftw_complex *PosFactor = F->PosFactor;
 | 
|---|
 | 916 |   fftw_complex *posfac, *destpos, *destRCS, *destRCD;
 | 
|---|
 | 917 |   fftw_complex *coeff;
 | 
|---|
 | 918 |   fftw_complex source;
 | 
|---|
 | 919 |   int i, Index, pos, n;
 | 
|---|
 | 920 |   int NF = NDIM, MaxNUp = F->MaxNUp, TotalSize = F->TotalSize, LocalSizeR = F->LocalSizeR;
 | 
|---|
 | 921 |   SetArrayToDouble0((double *)destC, TotalSize*2);
 | 
|---|
 | 922 |   for (i=0;i < LevR->MaxG;i++) {
 | 
|---|
 | 923 |     Index = LevR->GArray[i].Index;
 | 
|---|
 | 924 |     posfac = &PosFactor[MaxNUp*i];
 | 
|---|
 | 925 |     destpos = &destC[MaxNUp*Index*NF];
 | 
|---|
 | 926 |     coeff = &RT->Coeff[i];
 | 
|---|
 | 927 |     for (pos=0; pos < MaxNUp; pos++) {
 | 
|---|
 | 928 |       for (n=0; n < NF; n++) {
 | 
|---|
 | 929 |         source.re = coeff[n].re;
 | 
|---|
 | 930 |         source.im = coeff[n].im;
 | 
|---|
 | 931 |         destpos[n+NF*pos].re = source.re*posfac[pos].re-source.im*posfac[pos].im;
 | 
|---|
 | 932 |               destpos[n+NF*pos].im = source.re*posfac[pos].im+source.im*posfac[pos].re;
 | 
|---|
 | 933 |       }
 | 
|---|
 | 934 |     }
 | 
|---|
 | 935 |   }
 | 
|---|
 | 936 |   for (i=0; i < LevR->MaxDoubleG; i++) {
 | 
|---|
 | 937 |     destRCS = &destC[LevR->DoubleG[2*i]*MaxNUp*NF];
 | 
|---|
 | 938 |     destRCD = &destC[LevR->DoubleG[2*i+1]*MaxNUp*NF];
 | 
|---|
 | 939 |     for (pos=0; pos < MaxNUp; pos++) {
 | 
|---|
 | 940 |       for (n=0; n < NF; n++) {
 | 
|---|
 | 941 |         destRCD[n+NF*pos].re =  destRCS[n+NF*pos].re;
 | 
|---|
 | 942 |         destRCD[n+NF*pos].im = -destRCS[n+NF*pos].im;
 | 
|---|
 | 943 |       }
 | 
|---|
 | 944 |     }
 | 
|---|
 | 945 |   }
 | 
|---|
 | 946 |   fft_3d_complex_to_real(plan, LevR->LevelNo, FFTNFRVecUp0, destC, work);
 | 
|---|
 | 947 |   OutVisPosRTransformPosNFRto0(RT, destR, workR, NF);
 | 
|---|
 | 948 |   memcpy(destR,workR,sizeof(fftw_real)*LocalSizeR);
 | 
|---|
 | 949 | }
 | 
|---|
 | 950 | 
 | 
|---|
 | 951 | /** Prepare Density::DensityArray for output.
 | 
|---|
 | 952 |  * Into FileData::work subsequently each node (all z, all y, all x) is written as \f$\log(1+x)\f$,
 | 
|---|
 | 953 |  * where x is Density::DensityArray[TotalDensity]. In the end result is send to process 0 (yet not
 | 
|---|
 | 954 |  * received here, see CombineOutVisArray()). In  case of RiemannTensor use, some more complex calculations
 | 
|---|
 | 955 |  * are made: FileData::PosR is used, the coefficient offset'ed to the current node and the log taken there.
 | 
|---|
 | 956 |  * \param *P Problem at hand
 | 
|---|
 | 957 |  * \param myPE this ranks process in the Psi communcator ParallelSimulationData::me_comm_ST_Psi
 | 
|---|
 | 958 |  * \param *srcdens Pointer to DensityArray which is to be displayed
 | 
|---|
 | 959 |  */
 | 
|---|
 | 960 | static void OutputOutVisDensity(struct Problem *P, const int myPE, fftw_real *srcdens) 
 | 
|---|
 | 961 | {
 | 
|---|
 | 962 |   int N[NDIM], n[NDIM], pos[NDIM];
 | 
|---|
 | 963 |   int destpos = 0;
 | 
|---|
 | 964 |   double fac[NDIM], posd[NDIM];
 | 
|---|
 | 965 |   float posf[NDIM+1];
 | 
|---|
 | 966 |   struct Lattice *Lat = &P->Lat;
 | 
|---|
 | 967 |   struct LatticeLevel *Lev0 = &Lat->Lev[0];
 | 
|---|
 | 968 |   fftw_real *srcpos = P->Files.PosR;
 | 
|---|
 | 969 |   //fftw_real *srcdens = Lev0->Dens->DensityArray[ActualDensity]; //[TotalDensity]; trick to display single density
 | 
|---|
 | 970 |   float *dest = (float *)P->Files.work;
 | 
|---|
 | 971 |   int Nx = Lev0->Plan0.plan->N[0];
 | 
|---|
 | 972 |   int i;
 | 
|---|
 | 973 |   double min, max;
 | 
|---|
 | 974 | 
 | 
|---|
 | 975 |   N[0] = Lev0->Plan0.plan->local_nx;
 | 
|---|
 | 976 |   N[1] = Lev0->Plan0.plan->N[1];
 | 
|---|
 | 977 |   N[2] = Lev0->Plan0.plan->N[2];
 | 
|---|
 | 978 |   
 | 
|---|
 | 979 |   max = min = srcdens[0];
 | 
|---|
 | 980 |   for (i=1;i<P->R.Lev0->Dens->LocalSizeR;i++) {
 | 
|---|
 | 981 |     if (srcdens[i] < min) min = srcdens[i];
 | 
|---|
 | 982 |     if (srcdens[i] > max) max = srcdens[i];
 | 
|---|
 | 983 |   }
 | 
|---|
 | 984 |   if (P->Call.out[PsiOut]) fprintf(stderr,"(%i)OutputOutVisDensity: min %e\tmax %e\n",P->Par.me, min, max);
 | 
|---|
 | 985 |   
 | 
|---|
 | 986 |   // go through all nodes
 | 
|---|
 | 987 |   for (n[0]=0; n[0] < N[0]; n[0]++) {
 | 
|---|
 | 988 |     pos[0] = (n[0] == N[0] ? 0 : n[0]);
 | 
|---|
 | 989 |     for (n[1]=0; n[1] <= N[1]; n[1]++) {
 | 
|---|
 | 990 |       pos[1] = (n[1] == N[1] ? 0 : n[1]);
 | 
|---|
 | 991 |       for (n[2]=0; n[2] <= N[2]; n[2]++) {
 | 
|---|
 | 992 |         pos[2] = (n[2] == N[2] ? 0 : n[2]);
 | 
|---|
 | 993 |         // depending on RiemannTensor use, fill FileData::work
 | 
|---|
 | 994 |         switch (Lat->RT.ActualUse) {
 | 
|---|
 | 995 |         case inactive:
 | 
|---|
 | 996 |         case standby:
 | 
|---|
 | 997 |           if ((srcdens[pos[2]+N[2]*(pos[1]+N[1]*pos[0])]) > 0.)
 | 
|---|
 | 998 |             dest[destpos] = log(1.0+(srcdens[pos[2]+N[2]*(pos[1]+N[1]*pos[0])]));
 | 
|---|
 | 999 |           else 
 | 
|---|
 | 1000 |             dest[destpos] = 0.;
 | 
|---|
 | 1001 |           destpos++;
 | 
|---|
 | 1002 |           break;
 | 
|---|
 | 1003 |         case active:
 | 
|---|
 | 1004 |           posf[0] = srcpos[0+NDIM*(pos[2]+N[2]*(pos[1]+N[1]*pos[0]))];
 | 
|---|
 | 1005 |           posf[1] = srcpos[1+NDIM*(pos[2]+N[2]*(pos[1]+N[1]*pos[0]))];
 | 
|---|
 | 1006 |           posf[2] = srcpos[2+NDIM*(pos[2]+N[2]*(pos[1]+N[1]*pos[0]))];
 | 
|---|
 | 1007 |           fac[0] = ((n[0]+N[0]*myPE)/(double)Nx);
 | 
|---|
 | 1008 |           fac[1] = (n[1]/(double)N[1]);
 | 
|---|
 | 1009 |           fac[2] = (n[2]/(double)N[2]); 
 | 
|---|
 | 1010 |           RMat33Vec3(posd, Lat->RealBasis, fac);
 | 
|---|
 | 1011 |           posf[0] += posd[0];
 | 
|---|
 | 1012 |           posf[1] += posd[1];
 | 
|---|
 | 1013 |           posf[2] += posd[2];
 | 
|---|
 | 1014 |           if ((srcdens[pos[2]+N[2]*(pos[1]+N[1]*pos[0])]) > 0.)
 | 
|---|
 | 1015 |             posf[3] = log(1.0+(srcdens[pos[2]+N[2]*(pos[1]+N[1]*pos[0])]));
 | 
|---|
 | 1016 |           else 
 | 
|---|
 | 1017 |             posf[3] = 0.;
 | 
|---|
 | 1018 |           dest[destpos+0] = posf[0];
 | 
|---|
 | 1019 |           dest[destpos+1] = posf[1];
 | 
|---|
 | 1020 |           dest[destpos+2] = posf[2];
 | 
|---|
 | 1021 |           dest[destpos+3] = posf[3];
 | 
|---|
 | 1022 |           destpos += 4;
 | 
|---|
 | 1023 |           break;
 | 
|---|
 | 1024 |         }
 | 
|---|
 | 1025 |       }
 | 
|---|
 | 1026 |     }
 | 
|---|
 | 1027 |   }
 | 
|---|
 | 1028 |   if (myPE) MPI_Send(dest, destpos, MPI_FLOAT, 0, OutputDensTag, P->Par.comm_ST_Psi);
 | 
|---|
 | 1029 | }
 | 
|---|
 | 1030 | 
 | 
|---|
 | 1031 | /** Combines prepared electronic Psis density and output to file.
 | 
|---|
 | 1032 |  * If we are process 0, open file suffixdensdat (only when RiemannTensor is used) and suffixdenspos, receive
 | 
|---|
 | 1033 |  * FileData::work logarithmic coefficients sent by the other processes in OutputOutVisDensity(), go through all
 | 
|---|
 | 1034 |  * nodes and save the coefficient to file - again depending on RiemannTensor use - followed by FileData::PosTemp
 | 
|---|
 | 1035 |  * (for y and z nodes), close file(s).
 | 
|---|
 | 1036 |  * \param *P Problem at hand 
 | 
|---|
 | 1037 |  * \param me this ranks process in the Psi communcator ParallelSimulationData::me_comm_ST_Psi
 | 
|---|
 | 1038 |  * \param Maxme number of processes in this Psi communcator ParallelSimulationData::Max_me_comm_ST_Psi
 | 
|---|
 | 1039 |  */
 | 
|---|
 | 1040 | static void CombineOutVisDensity(struct Problem *P, const int me, const int Maxme)
 | 
|---|
 | 1041 | {
 | 
|---|
 | 1042 |   int i,n[NDIM], N[NDIM];
 | 
|---|
 | 1043 |   float posf[NDIM+1];
 | 
|---|
 | 1044 |   float *source = (float *)P->Files.work;
 | 
|---|
 | 1045 |   double posd[NDIM], fac[NDIM];
 | 
|---|
 | 1046 |   float *Temp = (float *)P->Files.PosTemp;
 | 
|---|
 | 1047 |   struct Lattice *Lat = &P->Lat;
 | 
|---|
 | 1048 |   struct LatticeLevel *Lev0 = &Lat->Lev[0];
 | 
|---|
| [cc46b0] | 1049 |   float step = P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo];
 | 
|---|
| [a0bcf1] | 1050 |   int No=0, destpos;
 | 
|---|
| [d3482a] | 1051 |   char *suffix;
 | 
|---|
| [a0bcf1] | 1052 |   FILE *DensityData, *DensityPos;
 | 
|---|
 | 1053 |   int Nx = Lev0->Plan0.plan->N[0]+1;
 | 
|---|
 | 1054 |   MPI_Status status;
 | 
|---|
 | 1055 |   if (me) return; // if we are process 0!
 | 
|---|
 | 1056 |   N[0] = Lev0->Plan0.plan->local_nx;
 | 
|---|
 | 1057 |   N[1] = Lev0->Plan0.plan->N[1]+1;
 | 
|---|
 | 1058 |   N[2] = Lev0->Plan0.plan->N[2]+1;
 | 
|---|
| [d3482a] | 1059 | 
 | 
|---|
| [a0bcf1] | 1060 |   // Open respective file depending on RiemannTensor use
 | 
|---|
| [c510a7] | 1061 |   suffix = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "CombineOutVisDensity: *suffix");
 | 
|---|
| [a0bcf1] | 1062 |   switch (Lat->RT.ActualUse) {
 | 
|---|
 | 1063 |   case active:
 | 
|---|
| [57a69b2] | 1064 |     sprintf(suffix, ".L%i%s", P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixdenspos);
 | 
|---|
| [f50ab8] | 1065 |     OpenFileNo(P, &DensityPos, suffix, (int)step, "wb",P->Call.out[ReadOut]);
 | 
|---|
| [a0bcf1] | 1066 |   case inactive:
 | 
|---|
 | 1067 |   case standby:
 | 
|---|
| [57a69b2] | 1068 |     sprintf(suffix, ".L%i%s", P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixdensdat);
 | 
|---|
| [f50ab8] | 1069 |     OpenFileNo(P, &DensityData, suffix, (int)step, "wb",P->Call.out[ReadOut]);
 | 
|---|
| [a0bcf1] | 1070 |     break;
 | 
|---|
 | 1071 |   }
 | 
|---|
 | 1072 |   // for all processes in the communicator
 | 
|---|
 | 1073 |   for (i=0; i< Maxme; i++) {
 | 
|---|
 | 1074 |     if (i) {  // if process != 0, receive from this process
 | 
|---|
 | 1075 |       /*      MPI_Probe( i, OutputDensTag, P->Par.comm_ST_Psi, &status );*/
 | 
|---|
 | 1076 |       switch (Lat->RT.ActualUse) {
 | 
|---|
 | 1077 |       case inactive:
 | 
|---|
 | 1078 |       case standby:
 | 
|---|
 | 1079 |         MPI_Recv( source, N[0]*N[1]*N[2], MPI_FLOAT, i, OutputDensTag, P->Par.comm_ST_Psi, &status );
 | 
|---|
 | 1080 |         break;
 | 
|---|
 | 1081 |       case active:
 | 
|---|
 | 1082 |         MPI_Recv( source, N[0]*N[1]*N[2]*4, MPI_FLOAT, i, OutputDensTag, P->Par.comm_ST_Psi, &status );
 | 
|---|
 | 1083 |         break;
 | 
|---|
 | 1084 |       }
 | 
|---|
 | 1085 |     }
 | 
|---|
 | 1086 |     destpos = 0;
 | 
|---|
 | 1087 |     // go through all nodes and save the coefficient to file DensityData, depending on RiemannTensor
 | 
|---|
 | 1088 |     for (n[0]=0; n[0] < N[0]; n[0]++) {
 | 
|---|
 | 1089 |       for (n[1]=0; n[1] < N[1]; n[1]++) {
 | 
|---|
 | 1090 |         for (n[2]=0; n[2] < N[2]; n[2]++) {
 | 
|---|
 | 1091 |           switch (Lat->RT.ActualUse) {
 | 
|---|
 | 1092 |           case inactive:
 | 
|---|
 | 1093 |           case standby:
 | 
|---|
 | 1094 |             posf[3] = source[destpos];
 | 
|---|
 | 1095 |             destpos++;
 | 
|---|
 | 1096 |             (void)fwrite(&posf[3], sizeof(float), (size_t)(1), DensityData);
 | 
|---|
 | 1097 |             No++;
 | 
|---|
 | 1098 |             if (i==0 && n[0] == 0) 
 | 
|---|
 | 1099 |               Temp[(n[2]+N[2]*(n[1]+N[1]*n[0]))] = posf[3];
 | 
|---|
 | 1100 |             break;
 | 
|---|
 | 1101 |           case active:
 | 
|---|
 | 1102 |             posf[0] = source[destpos+0];
 | 
|---|
 | 1103 |             posf[1] = source[destpos+1];
 | 
|---|
 | 1104 |             posf[2] = source[destpos+2];
 | 
|---|
 | 1105 |             posf[3] = source[destpos+3];
 | 
|---|
 | 1106 |             destpos += 4;
 | 
|---|
 | 1107 |             (void)fwrite(posf, sizeof(float), (size_t)(NDIM), DensityPos);
 | 
|---|
 | 1108 |             (void)fwrite(&posf[3], sizeof(float), (size_t)(1), DensityData);
 | 
|---|
 | 1109 |             No++;
 | 
|---|
 | 1110 |             if (i==0 && n[0] == 0) {
 | 
|---|
 | 1111 |               fac[0] = ((n[0]+N[0]*i)/(double)(Nx-1));
 | 
|---|
 | 1112 |               fac[1] = (n[1]/(double)(N[1]-1));
 | 
|---|
 | 1113 |               fac[2] = (n[2]/(double)(N[2]-1)); 
 | 
|---|
 | 1114 |               RMat33Vec3(posd, Lat->RealBasis, fac);
 | 
|---|
 | 1115 |               posf[0] -= posd[0];
 | 
|---|
 | 1116 |               posf[1] -= posd[1];
 | 
|---|
 | 1117 |               posf[2] -= posd[2];
 | 
|---|
 | 1118 |               fac[0] = ((Nx-1)/(double)(Nx-1));
 | 
|---|
 | 1119 |               fac[1] = (n[1]/(double)(N[1]-1));
 | 
|---|
 | 1120 |               fac[2] = (n[2]/(double)(N[2]-1)); 
 | 
|---|
 | 1121 |               RMat33Vec3(posd, Lat->RealBasis, fac);
 | 
|---|
 | 1122 |               posf[0] += posd[0];
 | 
|---|
 | 1123 |               posf[1] += posd[1];
 | 
|---|
 | 1124 |               posf[2] += posd[2];
 | 
|---|
 | 1125 |               Temp[0+(NDIM+1)*(n[2]+N[2]*(n[1]+N[1]*n[0]))] = posf[0]; 
 | 
|---|
 | 1126 |               Temp[1+(NDIM+1)*(n[2]+N[2]*(n[1]+N[1]*n[0]))] = posf[1]; 
 | 
|---|
 | 1127 |               Temp[2+(NDIM+1)*(n[2]+N[2]*(n[1]+N[1]*n[0]))] = posf[2]; 
 | 
|---|
 | 1128 |               Temp[3+(NDIM+1)*(n[2]+N[2]*(n[1]+N[1]*n[0]))] = posf[3]; 
 | 
|---|
 | 1129 |             }
 | 
|---|
 | 1130 |             break;
 | 
|---|
 | 1131 |           }
 | 
|---|
 | 1132 |         }
 | 
|---|
 | 1133 |       }
 | 
|---|
 | 1134 |     }
 | 
|---|
 | 1135 |   }
 | 
|---|
 | 1136 |   n[0] = N[0];
 | 
|---|
 | 1137 |   for (n[1]=0; n[1] < N[1]; n[1]++) {
 | 
|---|
 | 1138 |     for (n[2]=0; n[2] < N[2]; n[2]++) {
 | 
|---|
 | 1139 |       switch (Lat->RT.ActualUse) {
 | 
|---|
 | 1140 |       case inactive:
 | 
|---|
 | 1141 |       case standby:
 | 
|---|
 | 1142 |         (void)fwrite(&Temp[n[2]+N[2]*(n[1])], sizeof(float), (size_t)(1), DensityData);
 | 
|---|
 | 1143 |         No++;
 | 
|---|
 | 1144 |         break;
 | 
|---|
 | 1145 |       case active:
 | 
|---|
 | 1146 |         (void)fwrite(&Temp[(NDIM+1)*(n[2]+N[2]*(n[1]))], sizeof(float), (size_t)(NDIM), DensityPos);
 | 
|---|
 | 1147 |         (void)fwrite(&Temp[(NDIM+1)*(n[2]+N[2]*(n[1]))+3], sizeof(float), (size_t)(1), DensityData);
 | 
|---|
 | 1148 |         No++;
 | 
|---|
 | 1149 |         break;
 | 
|---|
 | 1150 |       }
 | 
|---|
 | 1151 |     }
 | 
|---|
 | 1152 |   }
 | 
|---|
 | 1153 |   if (No != Nx*N[1]*N[2]) Error(SomeError,"CombineOutVisDensity: No != points");
 | 
|---|
 | 1154 |   switch (Lat->RT.ActualUse) {
 | 
|---|
 | 1155 |   case active:
 | 
|---|
 | 1156 |     fclose(DensityPos);
 | 
|---|
 | 1157 |   case inactive:
 | 
|---|
 | 1158 |   case standby:
 | 
|---|
 | 1159 |     fclose(DensityData);
 | 
|---|
 | 1160 |     break;
 | 
|---|
 | 1161 |   }
 | 
|---|
| [d3482a] | 1162 |   Free(suffix, "CombineOutVisDensity: *suffix");
 | 
|---|
| [a0bcf1] | 1163 | }
 | 
|---|
 | 1164 | 
 | 
|---|
 | 1165 | /** Main output electronic Psis density for OpenDX.
 | 
|---|
 | 1166 |  * If FileData::MeOutVis is set, calls OutputOutVisDensity() followed by CombineOutVisDensity().
 | 
|---|
 | 1167 |  * Beforehand CalculateOutVisDensityPos() is called if RiemannTensor is used.
 | 
|---|
 | 1168 |  * \param *P Problem at hand 
 | 
|---|
 | 1169 |  * \param *src_dens Pointer to DensityArray which is to be displayed
 | 
|---|
 | 1170 |  */
 | 
|---|
 | 1171 | static void OutVisDensity(struct Problem *P, fftw_real *src_dens) 
 | 
|---|
 | 1172 | {
 | 
|---|
 | 1173 |   if (!P->Files.MeOutVis) return;
 | 
|---|
 | 1174 |   if (P->Lat.RT.ActualUse == active) CalculateOutVisDensityPos(&P->Lat, &P->Files/*, P->Lat.FactorDensityR, P->Lat.FactorDensityC*/); 
 | 
|---|
 | 1175 |   OutputOutVisDensity(P, P->Par.me_comm_ST_Psi, src_dens);
 | 
|---|
 | 1176 |   /* Achtung hier: P->Files.work (RT->TempC, Dens->DensityCArray[TempDensity]) fuer myPE == 0 nicht veraendern !!! */
 | 
|---|
 | 1177 |   CombineOutVisDensity(P, P->Par.me_comm_ST_Psi, P->Par.Max_me_comm_ST_Psi);
 | 
|---|
 | 1178 | } 
 | 
|---|
 | 1179 | 
 | 
|---|
 | 1180 | /** Opening and Initializing of output measurement files.
 | 
|---|
 | 1181 |  * If this is process 0, opens and writes top line of FileData::ForcesFile, FileData::EnergyFile.
 | 
|---|
 | 1182 |  * and sets FileData::MeOutVis and FileData::MeOutMes (if output desired) to 1, otherwise 0.
 | 
|---|
 | 1183 |  * \param *P Problem at hand
 | 
|---|
 | 1184 |  */
 | 
|---|
 | 1185 | void InitOutputFiles(struct Problem *P) 
 | 
|---|
 | 1186 | {
 | 
|---|
 | 1187 |   struct FileData *F = &P->Files;
 | 
|---|
 | 1188 |   F->ForcesFile = NULL;
 | 
|---|
 | 1189 |   F->EnergyFile = NULL;
 | 
|---|
 | 1190 |   F->HamiltonianFile = NULL;
 | 
|---|
 | 1191 |   F->MinimisationFile = NULL;
 | 
|---|
 | 1192 |   F->SpreadFile = NULL;
 | 
|---|
| [d8bb59] | 1193 |   F->ReciSpreadFile = NULL;
 | 
|---|
 | 1194 |   F->TemperatureFile = NULL;
 | 
|---|
| [a0bcf1] | 1195 |   // process 0 ?
 | 
|---|
 | 1196 |   F->MeOutVis = ((P->Par.my_color_comm_ST == 0 && P->Par.my_color_comm_ST_Psi == 0 && F->DoOutVis) ? 1 : 0);
 | 
|---|
 | 1197 |   F->MeOutCurr = ((P->Par.my_color_comm_ST == 0 && P->Par.my_color_comm_ST_Psi == 0 && F->DoOutCurr) ? 1 : 0);
 | 
|---|
 | 1198 |   F->MeOutMes = ((P->Par.me == 0 && F->DoOutMes) ? 1 : 0);
 | 
|---|
 | 1199 |   OpenFile(P, &F->HamiltonianFile, suffixhamiltonianall, "w",P->Call.out[ReadOut]);
 | 
|---|
 | 1200 | 
 | 
|---|
 | 1201 |   if (!F->MeOutMes) return;
 | 
|---|
 | 1202 |   OpenFile(P, &F->ForcesFile, suffixforcesall, "w",P->Call.out[ReadOut]);
 | 
|---|
 | 1203 |   if (F->ForcesFile == NULL) fprintf(stderr,"Error opening ForcesFile\n");
 | 
|---|
 | 1204 |   // write header of forces file
 | 
|---|
| [d8bb59] | 1205 |   fprintf(F->ForcesFile, "%s\t%s\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t%s\t%s\t%s\t\t%s\t\t%s\n",
 | 
|---|
| [a0bcf1] | 1206 |           "Type", "No",
 | 
|---|
 | 1207 |           "Pos0", "Pos1", "Pos2",
 | 
|---|
 | 1208 |           "Total0", "Total1", "Total2",
 | 
|---|
 | 1209 |           "Local0", "Local1", "Local2",
 | 
|---|
 | 1210 |           "NLocal0", "NLocal1", "NLocal2", 
 | 
|---|
| [d8bb59] | 1211 |     "Magnetic0", "Magnetic1", "Magnetic2", 
 | 
|---|
| [a0bcf1] | 1212 |           "Ewald0", "Ewald1", "Ewald2");
 | 
|---|
 | 1213 |   OpenFile(P, &F->EnergyFile, suffixenergyall, "w",P->Call.out[ReadOut]);
 | 
|---|
 | 1214 |   if (F->EnergyFile == NULL) fprintf(stderr,"Error opening EnergyFile\n");
 | 
|---|
 | 1215 |   // write header of energy file
 | 
|---|
 | 1216 |   if (P->R.DoUnOccupied) {
 | 
|---|
 | 1217 |     fprintf(F->EnergyFile, "%s\t\t%s\t\t%s\t%s\t\t%s\t%s\t\t%s\t%s\t%s\t\t%s\t\t%s\t%s\t\t%s\t\t%s\t\t%s\n",
 | 
|---|
 | 1218 |           "Time",
 | 
|---|
 | 1219 |           "Total",
 | 
|---|
 | 1220 |       "Total+Gap",
 | 
|---|
 | 1221 |           "Kinetic", "NonLocal",
 | 
|---|
 | 1222 |       "GapPsi",
 | 
|---|
 | 1223 |           "Correlation", "Exchange",
 | 
|---|
 | 1224 |           "Pseudo", "Hartree",
 | 
|---|
 | 1225 |       "GapDensity",
 | 
|---|
 | 1226 |           "-Gauss",
 | 
|---|
 | 1227 |           "Ewald",
 | 
|---|
 | 1228 |           "IonKin",
 | 
|---|
 | 1229 |           "ETotal");
 | 
|---|
 | 1230 |   } else {
 | 
|---|
 | 1231 |     fprintf(F->EnergyFile, "%s\t\t%s\t\t%s\t\t%s\t%s\t%s\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\n",
 | 
|---|
 | 1232 |       "Time",
 | 
|---|
 | 1233 |       "Total",
 | 
|---|
 | 1234 |       "Kinetic", "NonLocal",
 | 
|---|
 | 1235 |       "Correlation", "Exchange",
 | 
|---|
 | 1236 |       "Pseudo", "Hartree",
 | 
|---|
 | 1237 |       "-Gauss",
 | 
|---|
 | 1238 |       "Ewald",
 | 
|---|
 | 1239 |       "IonKin",
 | 
|---|
 | 1240 |       "ETotal");
 | 
|---|
 | 1241 |   }
 | 
|---|
 | 1242 |   OpenFile(P, &F->MinimisationFile, suffixminall, "w",P->Call.out[ReadOut]);
 | 
|---|
 | 1243 |   if (F->MinimisationFile == NULL) fprintf(stderr,"Error opening MinimsationFile\n");
 | 
|---|
 | 1244 |   // write header of minimsation file
 | 
|---|
 | 1245 |   fprintf(F->MinimisationFile, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n","Step", "Psi", "PsiStep", "TE", "ATE", "delta", "dEdt0", "ddEdtt0");
 | 
|---|
| [d8bb59] | 1246 | 
 | 
|---|
 | 1247 |   OpenFile(P, &F->TemperatureFile, suffixtempall, "w",P->Call.out[ReadOut]);
 | 
|---|
 | 1248 |   if (F->TemperatureFile == NULL) fprintf(stderr,"Error opening TemperatureFile\n");
 | 
|---|
| [4d4fc1] | 1249 |   // write header of minimsation file
 | 
|---|
| [a0bcf1] | 1250 | }
 | 
|---|
 | 1251 | 
 | 
|---|
 | 1252 | /** Closes all output measurement files.
 | 
|---|
 | 1253 |  * Closes FileData::ForcesFile and FileData::EnergyFile
 | 
|---|
 | 1254 |  * \param *P Problem at hand
 | 
|---|
 | 1255 |  */
 | 
|---|
 | 1256 | void CloseOutputFiles(struct Problem *P) 
 | 
|---|
 | 1257 | {
 | 
|---|
 | 1258 |   struct FileData *F = &P->Files;
 | 
|---|
 | 1259 |   if (!F->MeOutMes) return;
 | 
|---|
 | 1260 |   if (F->ForcesFile != NULL) fclose(F->ForcesFile); // only they've been opened (thus not pointing to NULL)
 | 
|---|
 | 1261 |   if (F->EnergyFile != NULL) fclose(F->EnergyFile);
 | 
|---|
 | 1262 |   if (F->HamiltonianFile != NULL) fclose(F->HamiltonianFile);
 | 
|---|
 | 1263 |   if (F->MinimisationFile != NULL) fclose(F->MinimisationFile);
 | 
|---|
 | 1264 |   if (F->SpreadFile != NULL) fclose(F->SpreadFile);
 | 
|---|
| [4d4fc1] | 1265 |   if (F->ReciSpreadFile != NULL) fclose(F->ReciSpreadFile);
 | 
|---|
 | 1266 |   if (F->TemperatureFile != NULL) fclose(F->TemperatureFile);
 | 
|---|
| [a0bcf1] | 1267 | }
 | 
|---|
 | 1268 | 
 | 
|---|
 | 1269 | /** Initialization of Problem::FileData structure for visual output.
 | 
|---|
 | 1270 |  * If this is process 0 (and OutVis desired), allocate memory for FileData::PosTemp, FileData::work,
 | 
|---|
 | 1271 |  * set the entries of FileData all to their corresponding values from RiemannTensor,
 | 
|---|
| [cc46b0] | 1272 |  * FileData::*OutVisStep to zero.
 | 
|---|
| [a0bcf1] | 1273 |  * \param *P Problem at hand
 | 
|---|
 | 1274 |  */
 | 
|---|
 | 1275 | void InitOutVisArray(struct Problem *P) 
 | 
|---|
 | 1276 | {
 | 
|---|
 | 1277 |   struct FileData *F = &P->Files;
 | 
|---|
 | 1278 |   struct Lattice *Lat = &P->Lat;
 | 
|---|
 | 1279 |   struct RiemannTensor *RT = &Lat->RT;
 | 
|---|
 | 1280 |   struct LatticeLevel *Lev0 = &Lat->Lev[0];
 | 
|---|
| [cc46b0] | 1281 |   int i;
 | 
|---|
| [a0bcf1] | 1282 |   F->OutputPosType = NULL;
 | 
|---|
 | 1283 |   if (!F->MeOutVis) return;
 | 
|---|
| [cc46b0] | 1284 | 
 | 
|---|
 | 1285 |   F->OutVisStep = Malloc(sizeof(int)*Lat->MaxLevel,"InitOutVisArray: OutVisStep");
 | 
|---|
 | 1286 |   for (i=0;i<Lat->MaxLevel;i++)
 | 
|---|
 | 1287 |     F->OutVisStep[i] = 0;
 | 
|---|
| [a0bcf1] | 1288 |   F->PosTemp = (fftw_complex *)
 | 
|---|
 | 1289 |     Malloc(sizeof(float)*(Lev0->Plan0.plan->N[1]+1)*(Lev0->Plan0.plan->N[2]+1)*
 | 
|---|
 | 1290 |            ((Lat->RT.Use != UseRT ? 0 : NDIM)+1), "InitOutVisArray: TempC");
 | 
|---|
 | 1291 |   F->work = (fftw_complex *)Lev0->Dens->DensityCArray[TempDensity];
 | 
|---|
 | 1292 |   if (Lat->RT.Use != UseRT) return;
 | 
|---|
 | 1293 |   F->TotalSize = RT->TotalSize[RTAIRT]/NDIM;
 | 
|---|
 | 1294 |   F->LocalSizeR = RT->LocalSizeR[RTAiGcg];
 | 
|---|
 | 1295 |   F->LocalSizeC = RT->LocalSizeC[RTAiGcg];
 | 
|---|
 | 1296 |   F->MaxNUp = RT->MaxNUp[RTPFRto0];
 | 
|---|
 | 1297 |   F->PosC = RT->DensityC[RTAiGcg];
 | 
|---|
 | 1298 |   F->PosR = (fftw_real *)F->PosC;
 | 
|---|
 | 1299 |   F->work = RT->TempC;
 | 
|---|
 | 1300 |   F->PosFactor = RT->PosFactor[RTPFRto0];
 | 
|---|
 | 1301 | }
 | 
|---|
 | 1302 | 
 | 
|---|
 | 1303 | static const char suffixionfor[] = ".ions.force";     //!< Suffix for ion forces file
 | 
|---|
 | 1304 | static const char suffixionZ[] = ".ions.datZ";        //!< Suffix for ion datZ file
 | 
|---|
 | 1305 | static const char suffixionpos[] = ".ions.pos";       //!< Suffix for ion positions file
 | 
|---|
 | 1306 | static const char suffixiondx[] = ".ions.dx";         //!< Suffix for ions dx file
 | 
|---|
 | 1307 | static const char suffixiondoc[] = ".ions.doc";       //!< Suffix for ions doc file
 | 
|---|
 | 1308 | static const char suffixsrciondoc[] = ".srcion.doc";  //!< Suffix for state ions doc file
 | 
|---|
 | 1309 | static const char suffixsrciondat[] = ".srcion.data"; //!< Suffix for state ions data file
 | 
|---|
 | 1310 | 
 | 
|---|
 | 1311 | /** Output current ions state.
 | 
|---|
 | 1312 |  * If this is process0, open file suffixsrciondoc for writing, output Ions::Max_Types and
 | 
|---|
 | 1313 |  * Ions::Max_IonsOfType of each type - each in a new line - closes it.
 | 
|---|
 | 1314 |  * Then opens suffixsrciondat for binary writing, outputs Lattice:RealBasis vectors and
 | 
|---|
 | 1315 |  * position IonType::R and speed IonType::U, closes it.
 | 
|---|
 | 1316 |  * \param *P Problem at hand
 | 
|---|
 | 1317 |  * \note This is the ionic counterpart to the elecontric OutputSrcPsiDensity(), storing a so far made
 | 
|---|
 | 1318 |  *       calculation to file.
 | 
|---|
 | 1319 |  */
 | 
|---|
 | 1320 | static void OutSrcIons(struct Problem *P) 
 | 
|---|
 | 1321 | {
 | 
|---|
 | 1322 |   struct Ions *I = &P->Ion;
 | 
|---|
 | 1323 |   double *U, *pos;
 | 
|---|
 | 1324 |   double data[2*NDIM];
 | 
|---|
 | 1325 |   int is,ia,i;
 | 
|---|
 | 1326 |   FILE *SrcIonDoc, *SrcIonData;
 | 
|---|
| [c510a7] | 1327 |   char *suffix = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "CombineOutVisDensity: *suffix");
 | 
|---|
| [a0bcf1] | 1328 | 
 | 
|---|
 | 1329 |   if (!(P->Par.me == 0)) return;
 | 
|---|
 | 1330 |   
 | 
|---|
 | 1331 |   // output of ion types and numbers per type
 | 
|---|
| [18d065] | 1332 |   sprintf(suffix, ".L%i%s", P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixsrciondoc);
 | 
|---|
 | 1333 |   OpenFile(P, &SrcIonDoc, suffix, "w",P->Call.out[ReadOut]);
 | 
|---|
| [a0bcf1] | 1334 |   fprintf(SrcIonDoc,"%i\n", I->Max_Types);
 | 
|---|
 | 1335 |   for (is=0; is < I->Max_Types; is++)
 | 
|---|
 | 1336 |     fprintf(SrcIonDoc,"%i\n", I->I[is].Max_IonsOfType);
 | 
|---|
 | 1337 |   fclose(SrcIonDoc);
 | 
|---|
 | 1338 | 
 | 
|---|
| [18d065] | 1339 |   sprintf(suffix, ".L%i%s", P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixsrciondat);
 | 
|---|
 | 1340 |   OpenFile(P, &SrcIonData, suffix, "wb",P->Call.out[ReadOut]);
 | 
|---|
| [a0bcf1] | 1341 |   (void)fwrite(P->Lat.RealBasis, sizeof(double), (size_t)(NDIM_NDIM), SrcIonData);
 | 
|---|
 | 1342 |   for (is=0; is < I->Max_Types; is++) {
 | 
|---|
 | 1343 |     for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) {
 | 
|---|
 | 1344 |       U = &I->I[is].U[NDIM*ia];
 | 
|---|
 | 1345 |       pos = &I->I[is].R[NDIM*ia];
 | 
|---|
 | 1346 |       for (i=0;i<NDIM;i++) {
 | 
|---|
 | 1347 |         data[i] = pos[i];
 | 
|---|
 | 1348 |         data[i+NDIM] = U[i];
 | 
|---|
 | 1349 |       }
 | 
|---|
 | 1350 |       (void)fwrite(&data, sizeof(double), (size_t)(2*NDIM), SrcIonData);
 | 
|---|
 | 1351 |     }
 | 
|---|
 | 1352 |   }
 | 
|---|
 | 1353 |   fclose(SrcIonData);
 | 
|---|
| [d3482a] | 1354 |   Free(suffix, "CombineOutVisDensity: *suffix");
 | 
|---|
| [a0bcf1] | 1355 | }
 | 
|---|
 | 1356 | 
 | 
|---|
 | 1357 | /** Read ions state from a file.
 | 
|---|
 | 1358 |  * Reads the suffixsrciondoc file and checks it against the current state in Ions regarding
 | 
|---|
 | 1359 |  * IonType::MaxTypes and IonType::Max_IonsOfType, closes it.
 | 
|---|
 | 1360 |  * Afterwards, opens suffixsrciondat for binary reading, retrieves the basis checking it against
 | 
|---|
 | 1361 |  * Problem::Lattice::RealBasis. If ok, reads position IonType::R and speed IonType::U, closes it.
 | 
|---|
 | 1362 |  * \param *P Problem at hand
 | 
|---|
 | 1363 |  * \return 1 - successful, 0 - failure
 | 
|---|
 | 1364 |  * \note This is the ionic counterpart to the electronic ReadSrcPsiDensity(), see also OutSrcIons().
 | 
|---|
 | 1365 |  */
 | 
|---|
 | 1366 | int ReadSrcIons(struct Problem *P) 
 | 
|---|
 | 1367 | {
 | 
|---|
 | 1368 |   struct Ions *I = &P->Ion;
 | 
|---|
 | 1369 |   double *U, *pos;
 | 
|---|
 | 1370 |   double data[2*NDIM];
 | 
|---|
 | 1371 |   int is,ia,i;
 | 
|---|
 | 1372 |   int Max_Types;
 | 
|---|
 | 1373 |   int *Max_IonsOfType = NULL;
 | 
|---|
 | 1374 |   double RealBasis[NDIM_NDIM];
 | 
|---|
 | 1375 |   FILE *SrcIonDoc, *SrcIonData;
 | 
|---|
| [18d065] | 1376 |   char *suffix;
 | 
|---|
| [da4244] | 1377 |   int flag = 0;
 | 
|---|
| [a0bcf1] | 1378 |   // read the doc file and check
 | 
|---|
| [da4244] | 1379 | 
 | 
|---|
 | 1380 |   if (!P->Par.me) { // process 0 reads and broadcasts ..
 | 
|---|
 | 1381 |           suffix = (char *)
 | 
|---|
 | 1382 |           Malloc(strlen(suffixsrciondoc) + 3 + 1,"ReadSrcIons: suffix");
 | 
|---|
 | 1383 |           sprintf(suffix, ".L%i%s", P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixsrciondoc);
 | 
|---|
 | 1384 |         if (OpenFile(P, &SrcIonDoc, suffix, "r",P->Call.out[ReadOut])) {
 | 
|---|
 | 1385 |         if (fscanf(SrcIonDoc,"%i", &Max_Types) != 1) {
 | 
|---|
 | 1386 |         //Error(SomeError, "ReadSrcIons: read error");
 | 
|---|
 | 1387 |               Free(suffix, "ReadSrcIons: suffix");
 | 
|---|
 | 1388 |         if (MPI_Bcast(&flag,1,MPI_INT,0,P->Par.comm) != MPI_SUCCESS)
 | 
|---|
 | 1389 |           Error(SomeError,"ReadSrcIons: Bcast of signal failed\n");
 | 
|---|
 | 1390 |         return flag;
 | 
|---|
| [18d065] | 1391 |             }
 | 
|---|
| [da4244] | 1392 |           if (Max_Types != I->Max_Types) {
 | 
|---|
 | 1393 |           //Error(SomeError, "ReadSrcIons: srcion file does not fit to system, MaxTypes");
 | 
|---|
 | 1394 |               Free(suffix, "ReadSrcIons: suffix");
 | 
|---|
 | 1395 |         if (MPI_Bcast(&flag,1,MPI_INT,0,P->Par.comm) != MPI_SUCCESS)
 | 
|---|
 | 1396 |           Error(SomeError,"ReadSrcIons: Bcast of signal failed\n");
 | 
|---|
 | 1397 |         return flag;
 | 
|---|
 | 1398 |             }
 | 
|---|
 | 1399 |           Max_IonsOfType = (int *) Malloc(Max_Types*sizeof(int), "ReadSrcIons: Max_IonsOfType");
 | 
|---|
 | 1400 |           for (is=0; is < Max_Types; is++) {
 | 
|---|
 | 1401 |               if (fscanf(SrcIonDoc,"%i", &Max_IonsOfType[is]) != 1) {
 | 
|---|
 | 1402 |               //Error(SomeError, "ReadSrcIons: read error");
 | 
|---|
 | 1403 |             Free(suffix, "ReadSrcIons: suffix");
 | 
|---|
 | 1404 |           Free(Max_IonsOfType, "ReadSrcIons: Max_IonsOfType");
 | 
|---|
 | 1405 |           if (MPI_Bcast(&flag,1,MPI_INT,0,P->Par.comm) != MPI_SUCCESS)
 | 
|---|
 | 1406 |             Error(SomeError,"ReadSrcIons: Bcast of signal failed\n");
 | 
|---|
 | 1407 |           return flag;
 | 
|---|
 | 1408 |         }
 | 
|---|
 | 1409 |         if (Max_IonsOfType[is] != I->I[is].Max_IonsOfType) {
 | 
|---|
 | 1410 |             //Error(SomeError, "ReadSrcIons: srcion file does not fit to system, Max_IonsOfType");
 | 
|---|
 | 1411 |           Free(suffix, "ReadSrcIons: suffix");
 | 
|---|
 | 1412 |           Free(Max_IonsOfType, "ReadSrcIons: Max_IonsOfType");
 | 
|---|
 | 1413 |           if (MPI_Bcast(&flag,1,MPI_INT,0,P->Par.comm) != MPI_SUCCESS)
 | 
|---|
 | 1414 |             Error(SomeError,"ReadSrcIons: Bcast of signal failed\n");
 | 
|---|
 | 1415 |           return flag;
 | 
|---|
 | 1416 |                     }
 | 
|---|
 | 1417 |             }
 | 
|---|
 | 1418 |       Free(Max_IonsOfType, "ReadSrcIons: Max_IonsOfType");
 | 
|---|
 | 1419 |             fclose(SrcIonDoc);
 | 
|---|
 | 1420 |         }
 | 
|---|
| [0b638d] | 1421 |     // check basis, then read positions and speeds of ions
 | 
|---|
 | 1422 |     suffix = (char *)
 | 
|---|
 | 1423 |       Realloc(suffix, strlen(suffixsrciondat) + 3 + 1,"ReadSrcIons: suffix");
 | 
|---|
 | 1424 |     sprintf(suffix, ".L%i%s", P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixsrciondat);
 | 
|---|
 | 1425 |     if (OpenFile(P, &SrcIonData, suffix, "rb",P->Call.out[ReadOut])) {
 | 
|---|
| [18d065] | 1426 |       if (fread(RealBasis, sizeof(double), (size_t)(NDIM_NDIM), SrcIonData) != NDIM_NDIM) {
 | 
|---|
| [a0bcf1] | 1427 |         //Error(SomeError, "ReadSrcIons: read error");
 | 
|---|
| [18d065] | 1428 |         Free(suffix, "ReadSrcIons: suffix");
 | 
|---|
| [da4244] | 1429 |         if (MPI_Bcast(&flag,1,MPI_INT,0,P->Par.comm) != MPI_SUCCESS)
 | 
|---|
 | 1430 |           Error(SomeError,"ReadSrcIons: Bcast of signal failed\n");
 | 
|---|
 | 1431 |         return flag;
 | 
|---|
| [18d065] | 1432 |       }
 | 
|---|
| [a0bcf1] | 1433 |       for (i=0; i < NDIM_NDIM; i++)
 | 
|---|
| [18d065] | 1434 |         if (RealBasis[i] != P->Lat.RealBasis[i]) {
 | 
|---|
| [a0bcf1] | 1435 |           //Error(SomeError, "ReadSrcIons: srcion file does not fit to system, RealBasis");
 | 
|---|
| [da4244] | 1436 |           Free(suffix, "ReadSrcIons: suffix");
 | 
|---|
 | 1437 |           if (MPI_Bcast(&flag,1,MPI_INT,0,P->Par.comm) != MPI_SUCCESS)
 | 
|---|
 | 1438 |             Error(SomeError,"ReadSrcIons: Bcast of signal failed\n");
 | 
|---|
 | 1439 |           return flag;
 | 
|---|
| [18d065] | 1440 |         }
 | 
|---|
| [a0bcf1] | 1441 |       for (is=0; is < I->Max_Types; is++) {
 | 
|---|
 | 1442 |         for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) {
 | 
|---|
| [18d065] | 1443 |           if (fread(&data, sizeof(double), (size_t)(2*NDIM), SrcIonData) != 2*NDIM) {
 | 
|---|
| [a0bcf1] | 1444 |                 //Error(SomeError, "ReadSrcIons: read error");
 | 
|---|
| [da4244] | 1445 |             Free(suffix, "ReadSrcIons: suffix");
 | 
|---|
 | 1446 |             if (MPI_Bcast(&flag,1,MPI_INT,0,P->Par.comm) != MPI_SUCCESS)
 | 
|---|
 | 1447 |               Error(SomeError,"ReadSrcIons: Bcast of signal failed\n");
 | 
|---|
 | 1448 |             return flag;
 | 
|---|
| [18d065] | 1449 |           }
 | 
|---|
| [a0bcf1] | 1450 |           U = &I->I[is].U[NDIM*ia];
 | 
|---|
 | 1451 |           pos = &I->I[is].R[NDIM*ia];
 | 
|---|
 | 1452 |           for (i=0;i<NDIM;i++) {
 | 
|---|
 | 1453 |                 pos[i] = data[i];
 | 
|---|
 | 1454 |                 U[i] = data[i+NDIM];
 | 
|---|
 | 1455 |           }
 | 
|---|
 | 1456 |         }
 | 
|---|
 | 1457 |       }
 | 
|---|
 | 1458 |       fclose(SrcIonData);
 | 
|---|
| [da4244] | 1459 |       flag = 1;
 | 
|---|
| [a0bcf1] | 1460 |     }
 | 
|---|
| [18d065] | 1461 |     Free(suffix, "ReadSrcIons: suffix");
 | 
|---|
| [da4244] | 1462 |   }
 | 
|---|
 | 1463 |   if (MPI_Bcast(&flag,1,MPI_INT,0,P->Par.comm) != MPI_SUCCESS)
 | 
|---|
 | 1464 |     Error(SomeError,"ReadSrcIons: Bcast of signal failed\n");
 | 
|---|
 | 1465 |   //fprintf(stderr, "(%i) Flag is %i\n", P->Par.me, flag);
 | 
|---|
 | 1466 |   if (flag) {
 | 
|---|
 | 1467 |     for (is=0; is < I->Max_Types; is++) {
 | 
|---|
 | 1468 |       if (MPI_Bcast(I->I[is].R, I->I[is].Max_IonsOfType*NDIM, MPI_DOUBLE, 0, P->Par.comm) != MPI_SUCCESS)
 | 
|---|
 | 1469 |         Error(SomeError,"ReadSrcIons: Bcast of I->I[is].R failed\n");       
 | 
|---|
 | 1470 |       if (MPI_Bcast(I->I[is].U, I->I[is].Max_IonsOfType*NDIM, MPI_DOUBLE, 0, P->Par.comm) != MPI_SUCCESS)
 | 
|---|
 | 1471 |         Error(SomeError,"ReadSrcIons: Bcast of I->I[is].U failed\n");
 | 
|---|
 | 1472 |     }
 | 
|---|
 | 1473 |   }
 | 
|---|
 | 1474 |   //fprintf(stderr, "(%i) ReadSrcIons done\n", P->Par.me);
 | 
|---|
 | 1475 |   return flag;
 | 
|---|
| [a0bcf1] | 1476 | }
 | 
|---|
 | 1477 | 
 | 
|---|
 | 1478 | /** Output of ion doc, dx, forces and positions file for OpenDX.
 | 
|---|
 | 1479 |  * If this is process 0,
 | 
|---|
 | 1480 |  * open, fill and close IonDoc file suffixiondoc,
 | 
|---|
| [cc46b0] | 1481 |  * open, fill for each FileData::*OutVisStep and close IonDX file suffixiondx
 | 
|---|
| [a0bcf1] | 1482 |  * for every
 | 
|---|
| [cc46b0] | 1483 |  * open suffixionfor, suffixionpos (and suffixionZ in case of only FileData::*OutVisStep), fill
 | 
|---|
| [a0bcf1] | 1484 |  * them with the ion forces IonType::FIon and positions IonType::R of each type and each ion per type,
 | 
|---|
 | 1485 |  * close them all.
 | 
|---|
 | 1486 |  * \param *P Problem at hand
 | 
|---|
 | 1487 |  */
 | 
|---|
 | 1488 | static void OutVisIons(struct Problem *P) 
 | 
|---|
 | 1489 | {
 | 
|---|
 | 1490 |   struct Ions *I = &P->Ion;
 | 
|---|
 | 1491 |   struct FileData *F = &P->Files;
 | 
|---|
| [57a69b2] | 1492 |   struct LatticeLevel *Lev = &P->Lat.Lev[STANDARTLEVEL];
 | 
|---|
| [a0bcf1] | 1493 |   int i,is,ia;
 | 
|---|
 | 1494 |   double *fion, *pos;
 | 
|---|
 | 1495 |   float data[6];      // holds temporarily twice NDIM values as write buffer
 | 
|---|
 | 1496 |   int Z;
 | 
|---|
| [d3482a] | 1497 |   char *datnamef, *datnameZ, *posname, *suffix;
 | 
|---|
| [a0bcf1] | 1498 |   FILE *IonsDataF, *IonsDataZ, *IonsPos, *IonsDoc, *IonsDx;
 | 
|---|
| [d3482a] | 1499 | 
 | 
|---|
| [a0bcf1] | 1500 |   if (!P->Files.MeOutVis && P->Par.me == 0) return;
 | 
|---|
| [d3482a] | 1501 | 
 | 
|---|
| [a0bcf1] | 1502 |   // generate file names
 | 
|---|
| [c510a7] | 1503 |   suffix = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "OutVisIons: * suffix");
 | 
|---|
| [a0bcf1] | 1504 |   datnamef = (char*)
 | 
|---|
 | 1505 |     malloc(strlen(P->Files.mainname)+strlen(suffixionfor) + 1);
 | 
|---|
| [57a69b2] | 1506 |   sprintf(datnamef, "%s.L%i%s", P->Files.mainname, P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixionfor);
 | 
|---|
| [a0bcf1] | 1507 |   datnameZ = (char*)
 | 
|---|
 | 1508 |     malloc(strlen(P->Files.mainname)+strlen(suffixionZ) + 1);
 | 
|---|
| [57a69b2] | 1509 |   sprintf(datnameZ, "%s.L%i%s", P->Files.mainname, P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixionZ);
 | 
|---|
| [a0bcf1] | 1510 |   posname = (char*)
 | 
|---|
 | 1511 |     malloc(strlen(P->Files.mainname)+strlen(suffixionpos) + 1);
 | 
|---|
| [57a69b2] | 1512 |   sprintf(posname, "%s.L%i%s", P->Files.mainname, P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixionpos);
 | 
|---|
| [a0bcf1] | 1513 |   // open, fill and close doc file
 | 
|---|
| [57a69b2] | 1514 |   sprintf(suffix, ".L%i%s", P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixiondoc);
 | 
|---|
| [0b638d] | 1515 |   if (OpenFile(P, &IonsDoc, suffix, "w",P->Call.out[ReadOut])) {
 | 
|---|
| [a0bcf1] | 1516 |     fprintf(IonsDoc,"IonsPos file = %s.####\n", posname);
 | 
|---|
 | 1517 |     fprintf(IonsDoc,"IonsForce file = %s.####\n", datnamef);
 | 
|---|
 | 1518 |     fprintf(IonsDoc,"format = ieee float (Bytes %lu) %s = Force(3)\n",(unsigned long) sizeof(float),msb);
 | 
|---|
 | 1519 |     fprintf(IonsDoc,"IonsZ file = %s.####\n", datnameZ);
 | 
|---|
 | 1520 |     fprintf(IonsDoc,"format = int (Bytes %lu) %s = Z(1)\n",(unsigned long) sizeof(int),msb);
 | 
|---|
 | 1521 |     fprintf(IonsDoc,"points = %i\n", I->Max_TotalIons);
 | 
|---|
 | 1522 |     fprintf(IonsDoc,"majority = row\n");
 | 
|---|
| [cc46b0] | 1523 |     fprintf(IonsDoc,"TimeSeries = %i\n",F->OutVisStep[Lev->LevelNo]+1);
 | 
|---|
| [a0bcf1] | 1524 |     fclose(IonsDoc);
 | 
|---|
 | 1525 |   }
 | 
|---|
 | 1526 |   // open dx file and fill it with each output step, close it
 | 
|---|
| [57a69b2] | 1527 |   sprintf(suffix, ".L%i%s", P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixiondx);
 | 
|---|
| [0b638d] | 1528 |   if (OpenFile(P, &IonsDx, suffix, "w",P->Call.out[ReadOut])) {
 | 
|---|
| [cc46b0] | 1529 |     for (i=0; i < F->OutVisStep[Lev->LevelNo]+1; i++) {
 | 
|---|
| [a0bcf1] | 1530 |       if (i==0) {
 | 
|---|
 | 1531 |         /*      fprintf(IonsDx,"object \"ioncon\" class array type int rank 1 shape 2 items 0 data follows\nattribute \"element type\" string \"lines\"\nattribute \"ref\" string \"positions\"\n\n"); */
 | 
|---|
 | 1532 |         fprintf(IonsDx,"object \"iondatZ\" class array type int rank 0 items %i %s binary\n",I->Max_TotalIons,msb);
 | 
|---|
 | 1533 |         fprintf(IonsDx,"data file %s,0\n",datnameZ);
 | 
|---|
 | 1534 |         fprintf(IonsDx,"attribute \"dep\" string \"positions\"\n\n");
 | 
|---|
 | 1535 |       }
 | 
|---|
 | 1536 |       
 | 
|---|
 | 1537 |       fprintf(IonsDx,"object \"ionpos.%04i\" class array type float rank 1 shape 3 items %i %s binary\n",i,I->Max_TotalIons,msb);
 | 
|---|
 | 1538 |       fprintf(IonsDx,"data file %s.%04i,0\n\n",posname,i);
 | 
|---|
 | 1539 |       
 | 
|---|
 | 1540 |       fprintf(IonsDx,"object \"iondatF.%04i\" class array type float rank 1 shape 3 items %i %s binary\n",i,I->Max_TotalIons,msb);
 | 
|---|
 | 1541 |       fprintf(IonsDx,"data file %s.%04i,0\n",datnamef,i);
 | 
|---|
 | 1542 |       fprintf(IonsDx,"attribute \"dep\" string \"positions\"\n\n");
 | 
|---|
 | 1543 |       
 | 
|---|
 | 1544 |       fprintf(IonsDx,"object \"ionobjF.%04i\" class field\n",i);
 | 
|---|
 | 1545 |       fprintf(IonsDx,"component \"positions\" \"ionpos.%04i\"\n",i);
 | 
|---|
 | 1546 |       fprintf(IonsDx,"component \"data\" \"iondatF.%04i\"\n",i);
 | 
|---|
 | 1547 |       /*fprintf(IonsDx,"component \"connections\" \"ioncon\"\n\n");*/
 | 
|---|
 | 1548 |       
 | 
|---|
 | 1549 |       fprintf(IonsDx,"object \"ionobjZ.%04i\" class field\n",i);
 | 
|---|
 | 1550 |       fprintf(IonsDx,"component \"positions\" \"ionpos.%04i\"\n",i);
 | 
|---|
 | 1551 |       fprintf(IonsDx,"component \"data\" \"iondatZ\"\n");
 | 
|---|
 | 1552 |       /*    fprintf(IonsDx,"component \"connections\" \"ioncon\"\n\n");*/
 | 
|---|
 | 1553 |     }
 | 
|---|
 | 1554 |     fprintf(IonsDx,"\nobject \"ionseriesF\" class series\n");
 | 
|---|
| [cc46b0] | 1555 |     for (i=0; i < F->OutVisStep[Lev->LevelNo]+1; i++) 
 | 
|---|
| [a0bcf1] | 1556 |       fprintf(IonsDx,"member %i \"ionobjF.%04i\" position %f\n",i,i,(float)i);
 | 
|---|
 | 1557 |     fprintf(IonsDx,"\nobject \"ionseriesZ\" class series\n");
 | 
|---|
| [cc46b0] | 1558 |     for (i=0; i < F->OutVisStep[Lev->LevelNo]+1; i++) 
 | 
|---|
| [a0bcf1] | 1559 |       fprintf(IonsDx,"member %i \"ionobjZ.%04i\" position %f\n",i,i,(float)i);
 | 
|---|
 | 1560 |     fprintf(IonsDx,"end\n");
 | 
|---|
 | 1561 |     fclose(IonsDx);
 | 
|---|
 | 1562 |   }
 | 
|---|
| [48cbc9] | 1563 |   Free(datnamef, "OutVisIons: datnamef");
 | 
|---|
 | 1564 |   Free(datnameZ, "OutVisIons: datnameZ");
 | 
|---|
 | 1565 |   Free(posname, "OutVisIons: posname");
 | 
|---|
| [a0bcf1] | 1566 |   // open IonForces, IonZ and IonPosition file, write forces respectively positions for each ion of each type, close them
 | 
|---|
| [57a69b2] | 1567 |   sprintf(suffix, ".L%i%s", P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixionfor);
 | 
|---|
| [cc46b0] | 1568 |   if (OpenFileNo(P, &IonsDataF, suffix, F->OutVisStep[Lev->LevelNo], "wb",P->Call.out[ReadOut])) {
 | 
|---|
 | 1569 |     if (F->OutVisStep[Lev->LevelNo] == 0) { 
 | 
|---|
| [57a69b2] | 1570 |       sprintf(suffix, ".L%i%s", P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixionZ);
 | 
|---|
| [0b638d] | 1571 |       OpenFile(P, &IonsDataZ, suffix, "wb",P->Call.out[ReadOut]);
 | 
|---|
 | 1572 |     }
 | 
|---|
| [57a69b2] | 1573 |     sprintf(suffix, ".L%i%s", P->Lat.Lev[STANDARTLEVEL].LevelNo, suffixionpos);
 | 
|---|
| [cc46b0] | 1574 |     if (OpenFileNo(P, &IonsPos, suffix, F->OutVisStep[Lev->LevelNo], "wb",P->Call.out[ReadOut])) {
 | 
|---|
| [a0bcf1] | 1575 |       for (is=0; is < I->Max_Types; is++) {
 | 
|---|
 | 1576 |         for (ia=0; ia < I->I[is].Max_IonsOfType; ia++) {
 | 
|---|
 | 1577 |           fion = &I->I[is].FIon[NDIM*ia];
 | 
|---|
 | 1578 |           pos = &I->I[is].R[NDIM*ia];
 | 
|---|
 | 1579 |           for (i=0;i<3;i++) {
 | 
|---|
 | 1580 |                 data[i+3] = fion[i];
 | 
|---|
 | 1581 |                 data[i] = pos[i];
 | 
|---|
 | 1582 |           }
 | 
|---|
 | 1583 |           Z = I->I[is].Z;
 | 
|---|
 | 1584 |           if (fwrite(&data[0],sizeof(float), (size_t)(3),IonsPos) != 3)
 | 
|---|
 | 1585 |             Error(FileOpenParams, "Error writing ion positions!");
 | 
|---|
| [cc46b0] | 1586 |           if (F->OutVisStep[Lev->LevelNo] == 0) (void)fwrite(&Z,sizeof(int), (size_t)(1),IonsDataZ);
 | 
|---|
| [a0bcf1] | 1587 |           if (fwrite(&data[3],sizeof(float), (size_t)(3),IonsDataF) != 3)
 | 
|---|
 | 1588 |             Error(FileOpenParams, "Error writing ionic forces!");
 | 
|---|
 | 1589 |         }
 | 
|---|
 | 1590 |       }
 | 
|---|
 | 1591 |       fclose(IonsPos);
 | 
|---|
 | 1592 |     }
 | 
|---|
| [cc46b0] | 1593 |     if (F->OutVisStep[Lev->LevelNo] == 0) 
 | 
|---|
| [a0bcf1] | 1594 |       fclose(IonsDataZ);
 | 
|---|
 | 1595 |     fclose(IonsDataF);
 | 
|---|
 | 1596 |   }
 | 
|---|
| [d3482a] | 1597 |   Free(suffix, "OutVisIons: *suffix");
 | 
|---|
| [a0bcf1] | 1598 | }
 | 
|---|
 | 1599 | 
 | 
|---|
 | 1600 | /** Output electronic density and ion state files with so far made calculations.
 | 
|---|
 | 1601 |  * If CallOptions::WriteSrcFiles is set, OutputSrcPsiDensity() and OutSrcIons() are called.
 | 
|---|
 | 1602 |  * \param *P Problem at hand
 | 
|---|
 | 1603 |  * \param type which PsiTypeTag should be put to file
 | 
|---|
 | 1604 |  */
 | 
|---|
 | 1605 | void OutputVisSrcFiles(struct Problem *P, enum PsiTypeTag type)
 | 
|---|
 | 1606 | {
 | 
|---|
 | 1607 |   if (P->Call.WriteSrcFiles) {
 | 
|---|
| [1da479] | 1608 |     if(P->Call.out[NormalOut]) fprintf(stderr,"(%i) Writing %s srcpsi to disk\n", P->Par.me, P->R.MinimisationName[type]);
 | 
|---|
| [a0bcf1] | 1609 |     OutputSrcPsiDensity(P, type);
 | 
|---|
| [1da479] | 1610 |     if(P->Call.out[NormalOut]) fprintf(stderr,"(%i) Writing srcion to disk\n", P->Par.me);
 | 
|---|
| [a0bcf1] | 1611 |     OutSrcIons(P);
 | 
|---|
 | 1612 |   } 
 | 
|---|
 | 1613 |   // if (!P->Files.MeOutVis) return;
 | 
|---|
 | 1614 |   // P->Files.OutputPosType = 
 | 
|---|
| [cc46b0] | 1615 |   //   Realloc(P->Files.OutputPosType,sizeof(enum ModeType)*(P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo]+1),"OutputVis");
 | 
|---|
 | 1616 |   // P->Files.OutputPosType[P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo]] = P->Lat.RT.ActualUse;
 | 
|---|
| [a0bcf1] | 1617 |   // CreateDensityOutputGeneral(P, P->Par.me_comm_ST_Psi);
 | 
|---|
 | 1618 |   // OutVisDensity(P);
 | 
|---|
 | 1619 |   // OutVisIons(P);
 | 
|---|
| [cc46b0] | 1620 |   // if(P->Call.out[NormalOut]) fprintf(stderr,"(%i) Written OutVisStep %i to disk\n", P->Par.me, P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo]);
 | 
|---|
 | 1621 |   // /* P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo]++; Genau ebend nicht hochzaehlen - wird immer ueberschrieben */
 | 
|---|
| [a0bcf1] | 1622 | }
 | 
|---|
 | 1623 | 
 | 
|---|
 | 1624 | /** Main output total electronic density and ion data for OpenDX.
 | 
|---|
 | 1625 |  * Calls subsequently preparing CreateDensityOutputGeneral(), then output of electronic
 | 
|---|
| [cc46b0] | 1626 |  * densities OutVisDensity() and ion data OutVisIons(), increasing finally FileData::*OutVisStep.
 | 
|---|
| [a0bcf1] | 1627 |  * \param *P Problem at hand
 | 
|---|
 | 1628 |   * \param *srcdens Pointer to DensityArray which is to be displayed
 | 
|---|
 | 1629 |  * \note Output is made only RunStruct::OutVisStep steps and if FileData::MeOutVis is set.
 | 
|---|
 | 1630 |  */
 | 
|---|
 | 1631 | void OutputVis(struct Problem *P, fftw_real *srcdens)
 | 
|---|
 | 1632 | {
 | 
|---|
 | 1633 |   if (!P->Files.MeOutVis) return;
 | 
|---|
| [cc46b0] | 1634 |   P->Files.OutputPosType = (enum ModeType *) Realloc(P->Files.OutputPosType,sizeof(enum ModeType)*(P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo]+1),"OutputVis");
 | 
|---|
 | 1635 |   P->Files.OutputPosType[P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo]] = P->Lat.RT.ActualUse;
 | 
|---|
| [a0bcf1] | 1636 |   
 | 
|---|
 | 1637 |   CreateDensityOutputGeneral(P, P->Par.me_comm_ST_Psi);
 | 
|---|
 | 1638 |   OutVisDensity(P, srcdens);
 | 
|---|
 | 1639 |   OutVisIons(P);
 | 
|---|
| [cc46b0] | 1640 |   if(P->Call.out[MinOut]) fprintf(stderr,"(%i) Written OutVisStep %i to disk\n", P->Par.me, P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo]);
 | 
|---|
 | 1641 |   P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo]++;
 | 
|---|
| [a0bcf1] | 1642 | }
 | 
|---|
 | 1643 | 
 | 
|---|
 | 1644 | /** Output of each current density component for OpenDX.
 | 
|---|
 | 1645 |  * \param *P Problem at hand
 | 
|---|
 | 1646 |  * \note Output is made only RunStruct::OutVisStep steps and if FileData::MeOutVis is set.
 | 
|---|
 | 1647 |  */
 | 
|---|
 | 1648 | void OutputCurrentDensity(struct Problem *P)
 | 
|---|
 | 1649 | {
 | 
|---|
 | 1650 |   int index, i, r;
 | 
|---|
 | 1651 |   fftw_real *density = P->R.Lev0->Dens->DensityArray[ActualDensity];
 | 
|---|
 | 1652 |   fftw_real *CurrentDensity[NDIM*NDIM];
 | 
|---|
 | 1653 |   if (!P->Files.MeOutCurr) return;
 | 
|---|
 | 1654 | 
 | 
|---|
| [f50ab8] | 1655 |   if(P->Call.out[NormalOut]) fprintf(stderr,"(%i)Output of Current Density (Vis)\n", P->Par.me);
 | 
|---|
 | 1656 | 
 | 
|---|
| [cc46b0] | 1657 |   P->Files.OutputPosType = (enum ModeType *) Realloc(P->Files.OutputPosType,sizeof(enum ModeType)*(P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo]+(1)*NDIM),"OutputVis");
 | 
|---|
| [a0bcf1] | 1658 |   for (i=0;i<(1)*NDIM;i++)
 | 
|---|
| [cc46b0] | 1659 |     P->Files.OutputPosType[P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo]+i] = P->Lat.RT.ActualUse;
 | 
|---|
 | 1660 |   if(P->Call.out[PsiOut]) fprintf(stderr,"(%i) OutVisStep %i, OutputPosType %p\n",P->Par.me, P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo], P->Files.OutputPosType);
 | 
|---|
| [a0bcf1] | 1661 |   
 | 
|---|
 | 1662 |   // due to preprocessor values we can't put the following stuff into a loop
 | 
|---|
 | 1663 |   CurrentDensity[0] = (fftw_real *) P->R.Lev0->Dens->DensityArray[CurrentDensity0];
 | 
|---|
 | 1664 |   CurrentDensity[1] = (fftw_real *) P->R.Lev0->Dens->DensityArray[CurrentDensity1];
 | 
|---|
 | 1665 |   CurrentDensity[2] = (fftw_real *) P->R.Lev0->Dens->DensityArray[CurrentDensity2];
 | 
|---|
 | 1666 |   CurrentDensity[3] = (fftw_real *) P->R.Lev0->Dens->DensityArray[CurrentDensity3];
 | 
|---|
 | 1667 |   CurrentDensity[4] = (fftw_real *) P->R.Lev0->Dens->DensityArray[CurrentDensity4];
 | 
|---|
 | 1668 |   CurrentDensity[5] = (fftw_real *) P->R.Lev0->Dens->DensityArray[CurrentDensity5];
 | 
|---|
 | 1669 |   CurrentDensity[6] = (fftw_real *) P->R.Lev0->Dens->DensityArray[CurrentDensity6];
 | 
|---|
 | 1670 |   CurrentDensity[7] = (fftw_real *) P->R.Lev0->Dens->DensityArray[CurrentDensity7];
 | 
|---|
 | 1671 |   CurrentDensity[8] = (fftw_real *) P->R.Lev0->Dens->DensityArray[CurrentDensity8];
 | 
|---|
 | 1672 |   
 | 
|---|
 | 1673 |   // output current density, not vector component
 | 
|---|
 | 1674 |   for (index=0;index<NDIM;index++) {
 | 
|---|
 | 1675 |     // evaluate euclidian norm for given B component
 | 
|---|
 | 1676 |     SetArrayToDouble0((double *)density,P->R.Lev0->Dens->TotalSize*2); // reset
 | 
|---|
 | 1677 |     for (r=0;r<P->R.Lev0->Dens->LocalSizeR;r++) {
 | 
|---|
 | 1678 |       for (i=0;i<NDIM;i++)
 | 
|---|
 | 1679 |         density[r] += CurrentDensity[i + index*NDIM][r]*CurrentDensity[i + index*NDIM][r];
 | 
|---|
 | 1680 |       density[r] = sqrt(density[r]);      
 | 
|---|
 | 1681 |     }
 | 
|---|
 | 1682 |     // output
 | 
|---|
 | 1683 |     CreateDensityOutputGeneral(P, P->Par.me_comm_ST_Psi);
 | 
|---|
 | 1684 |     OutVisDensity(P, density);
 | 
|---|
 | 1685 |     OutVisIons(P);
 | 
|---|
| [cc46b0] | 1686 |     if(P->Call.out[NormalOut]) fprintf(stderr,"(%i) Written OutVisStep %i to disk\n", P->Par.me, P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo]);
 | 
|---|
 | 1687 |     P->Files.OutVisStep[P->Lat.Lev[STANDARTLEVEL].LevelNo]++;
 | 
|---|
| [a0bcf1] | 1688 |   }
 | 
|---|
 | 1689 | }
 | 
|---|
 | 1690 | 
 | 
|---|
 | 1691 | /** Output each orbital in a certain step order for OpenDX.
 | 
|---|
 | 1692 |  * \param *P Problem at hand
 | 
|---|
 | 1693 |  * \param offset from which step do we start
 | 
|---|
 | 1694 |  * \param increment by which increment do we advance step-wise
 | 
|---|
 | 1695 |  * \param type Only PsiTypeTag orbitals are displayed 
 | 
|---|
 | 1696 |  */
 | 
|---|
 | 1697 | void OutputVisAllOrbital(struct Problem *P, int offset, int increment, enum PsiTypeTag type) {
 | 
|---|
 | 1698 |   struct Lattice *Lat = &P->Lat;
 | 
|---|
 | 1699 |   struct Psis *Psi = &Lat->Psi;
 | 
|---|
 | 1700 |   struct RunStruct *R = &P->R;
 | 
|---|
 | 1701 |   struct LatticeLevel *LevS = R->LevS;
 | 
|---|
| [cc46b0] | 1702 |   struct LatticeLevel *Lev = &P->Lat.Lev[STANDARTLEVEL];
 | 
|---|
| [a0bcf1] | 1703 |   struct LatticeLevel *Lev0 = R->Lev0;
 | 
|---|
 | 1704 |   struct Density *Dens0 = Lev0->Dens;
 | 
|---|
 | 1705 |   struct OnePsiElement *OnePsiA, *LOnePsiA;
 | 
|---|
 | 1706 |   MPI_Status status;
 | 
|---|
 | 1707 |   int ElementSize = (sizeof(fftw_complex) / sizeof(double));
 | 
|---|
 | 1708 |   fftw_complex *LPsiDatA;  
 | 
|---|
 | 1709 |   int i, p, RecvSource;
 | 
|---|
 | 1710 |   int Num = Psi->NoOfPsis;
 | 
|---|
 | 1711 | 
 | 
|---|
 | 1712 |   if (!P->Files.MeOutVis) return;
 | 
|---|
 | 1713 | 
 | 
|---|
| [cc46b0] | 1714 |   fprintf(stderr,"(%i) Realloc OutputPosType: %li to %i\n",P->Par.me,sizeof(P->Files.OutputPosType), P->Files.OutVisStep[Lev->LevelNo]+(Num));
 | 
|---|
 | 1715 |   P->Files.OutputPosType = (enum ModeType *) Realloc(P->Files.OutputPosType,sizeof(enum ModeType)*(P->Files.OutVisStep[Lev->LevelNo]+(Num)),"OutputVis");
 | 
|---|
| [a0bcf1] | 1716 |   
 | 
|---|
| [cc46b0] | 1717 |   P->Files.OutVisStep[Lev->LevelNo] += offset;
 | 
|---|
 | 1718 |   //P->Files.OutputPosType[P->Files.OutVisStep[Lev->LevelNo]] = P->Lat.RT.ActualUse;  
 | 
|---|
| [a0bcf1] | 1719 |   for (i=0; i < Psi->MaxPsiOfType+P->Par.Max_me_comm_ST_PsiT; i++) {  // go through all wave functions (plus the extra one for each process)
 | 
|---|
 | 1720 |     OnePsiA = &Psi->AllPsiStatus[i];    // grab the desired OnePsiA
 | 
|---|
 | 1721 |     if (OnePsiA->PsiType == type) {   // drop if extra one
 | 
|---|
 | 1722 |       if (OnePsiA->my_color_comm_ST_Psi == P->Par.my_color_comm_ST_Psi) // local?
 | 
|---|
 | 1723 |          LOnePsiA = &Psi->LocalPsiStatus[OnePsiA->MyLocalNo];
 | 
|---|
 | 1724 |       else 
 | 
|---|
 | 1725 |          LOnePsiA = NULL;
 | 
|---|
 | 1726 |       if (LOnePsiA == NULL) {   // if it's not local ... receive it from respective process into TempPsi
 | 
|---|
 | 1727 |         RecvSource = OnePsiA->my_color_comm_ST_Psi;
 | 
|---|
 | 1728 |         MPI_Recv( LevS->LPsi->TempPsi, LevS->MaxG*ElementSize, MPI_DOUBLE, RecvSource, WannierTag1, P->Par.comm_ST_PsiT, &status );
 | 
|---|
 | 1729 |         LPsiDatA=LevS->LPsi->TempPsi;
 | 
|---|
 | 1730 |       } else {                  // .. otherwise send it to all other processes (Max_me... - 1)
 | 
|---|
 | 1731 |         for (p=0;p<P->Par.Max_me_comm_ST_PsiT;p++)
 | 
|---|
 | 1732 |           if (p != OnePsiA->my_color_comm_ST_Psi) 
 | 
|---|
 | 1733 |             MPI_Send( LevS->LPsi->LocalPsi[OnePsiA->MyLocalNo], LevS->MaxG*ElementSize, MPI_DOUBLE, p, WannierTag1, P->Par.comm_ST_PsiT);
 | 
|---|
 | 1734 |         LPsiDatA=LevS->LPsi->LocalPsi[OnePsiA->MyLocalNo];
 | 
|---|
 | 1735 |       } // LPsiDatA is now set to the coefficients of OnePsi either stored or MPI_Received
 | 
|---|
 | 1736 | 
 | 
|---|
| [cc46b0] | 1737 |       P->Files.OutputPosType[P->Files.OutVisStep[Lev->LevelNo]] = P->Lat.RT.ActualUse;
 | 
|---|
| [48cbc9] | 1738 |       // recalculate density for the specific wave function ...
 | 
|---|
 | 1739 |       CalculateOneDensityR(Lat, LevS, Dens0, LPsiDatA, Dens0->DensityArray[ActualDensity], R->FactorDensityR, 0);
 | 
|---|
 | 1740 |       // ... and output (wherein ActualDensity is used instead of TotalDensity)
 | 
|---|
 | 1741 |       //OutputVis(P);
 | 
|---|
 | 1742 |       CreateDensityOutputGeneral(P, P->Par.me_comm_ST_Psi);
 | 
|---|
 | 1743 |       OutVisDensity(P, Dens0->DensityArray[ActualDensity]);
 | 
|---|
 | 1744 |       OutVisIons(P);
 | 
|---|
| [cc46b0] | 1745 |       if(P->Call.out[NormalOut]) fprintf(stderr,"(%i) Written OutVisStep %i to disk\n", P->Par.me, P->Files.OutVisStep[Lev->LevelNo]);
 | 
|---|
 | 1746 |       P->Files.OutVisStep[Lev->LevelNo]+=increment;
 | 
|---|
 | 1747 |       //P->Files.OutputPosType[P->Files.OutVisStep[Lev->LevelNo]] = P->Lat.RT.ActualUse;  
 | 
|---|
| [a0bcf1] | 1748 |     }
 | 
|---|
 | 1749 |   }
 | 
|---|
 | 1750 | }
 | 
|---|
 | 1751 | 
 | 
|---|
 | 1752 | /** Read source files containing stored calculations.
 | 
|---|
 | 1753 |  * Calls ReadSrcPsiDensity() and ReadSrcIons().
 | 
|---|
 | 1754 |  * \param *P Problem at hand
 | 
|---|
 | 1755 |  */
 | 
|---|
 | 1756 | void ReadSrcFiles(struct Problem *P)
 | 
|---|
 | 1757 | {
 | 
|---|
 | 1758 |   if (P->Call.out[NormalOut]) fprintf(stderr, "(%i)ReadSrcPsiDensity\n", P->Par.me);
 | 
|---|
 | 1759 |   ReadSrcPsiDensity(P, Occupied, 0, P->R.LevSNo);
 | 
|---|
 | 1760 |   ReadSrcPsiDensity(P, UnOccupied, 0, P->R.LevSNo);
 | 
|---|
 | 1761 |   if (P->Call.out[NormalOut]) fprintf(stderr, "(%i)ReadSrcIons\n", P->Par.me);
 | 
|---|
 | 1762 |   ReadSrcIons(P);
 | 
|---|
 | 1763 | }
 | 
|---|
 | 1764 | 
 | 
|---|
 | 1765 | /** Plots a cut plane of the real density of one wave function.
 | 
|---|
 | 1766 |  * \param *P Problem at hand
 | 
|---|
 | 1767 |  * \param index index of axis (vector orthogonal to plane)
 | 
|---|
 | 1768 |  * \param node node specifying where to cut at the given axis
 | 
|---|
 | 1769 |  * \param wavenr global number of wave function
 | 
|---|
 | 1770 |  * \param *density density array to plot
 | 
|---|
 | 1771 |  * \sa PlotVectorPlane() - very similar 
 | 
|---|
 | 1772 |  */
 | 
|---|
 | 1773 | void PlotSrcPlane(struct Problem *P, int index, double node, int wavenr, fftw_real *density) 
 | 
|---|
 | 1774 | {
 | 
|---|
 | 1775 |   struct RunStruct *R = &P->R;
 | 
|---|
 | 1776 |   struct Lattice *Lat = &P->Lat;
 | 
|---|
 | 1777 |   struct LatticeLevel *Lev0 = R->Lev0;
 | 
|---|
 | 1778 |   const int myPE = P->Par.me_comm_ST_Psi;
 | 
|---|
| [d3482a] | 1779 |   char *filename, spin[12];
 | 
|---|
| [a0bcf1] | 1780 |   char *suchpointer;
 | 
|---|
 | 1781 |   FILE *PlotFile = NULL;
 | 
|---|
 | 1782 |   time_t seconds; 
 | 
|---|
 | 1783 |   
 | 
|---|
 | 1784 |   time(&seconds); // get current time
 | 
|---|
 | 1785 | 
 | 
|---|
| [c510a7] | 1786 |   filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "PlotSrcPlane: *filename");
 | 
|---|
| [a0bcf1] | 1787 |   switch (Lat->Psi.PsiST) {
 | 
|---|
| [d3482a] | 1788 |     case SpinDouble:    
 | 
|---|
 | 1789 |       sprintf(&filename[0], ".psi%i_cut%i.csv", wavenr, index);
 | 
|---|
 | 1790 |       strncat(spin,"SpinDouble",12);
 | 
|---|
 | 1791 |       break;
 | 
|---|
 | 1792 |     case SpinUp:
 | 
|---|
 | 1793 |       sprintf(&filename[0], ".psi%i_cut%i_up.csv", wavenr, index);
 | 
|---|
 | 1794 |       strncat(spin,"SpinUp",12);
 | 
|---|
 | 1795 |       break;
 | 
|---|
 | 1796 |     case SpinDown:
 | 
|---|
 | 1797 |       sprintf(&filename[0], ".psi%i_cut%i_down.csv", wavenr, index);
 | 
|---|
 | 1798 |       strncat(spin,"SpinDown",12);
 | 
|---|
 | 1799 |       break;
 | 
|---|
| [a0bcf1] | 1800 |   }
 | 
|---|
 | 1801 |   
 | 
|---|
 | 1802 |   if (!myPE) { // only process 0 writes to file
 | 
|---|
 | 1803 |     OpenFile(P, &PlotFile, filename, "w", P->Call.out[ReadOut]);
 | 
|---|
 | 1804 |     strcpy(filename, ctime(&seconds));
 | 
|---|
 | 1805 |     suchpointer = strchr(filename, '\n');
 | 
|---|
 | 1806 |     if (suchpointer != NULL)
 | 
|---|
 | 1807 |       *suchpointer = '\0';
 | 
|---|
 | 1808 |     if (PlotFile != NULL) { 
 | 
|---|
 | 1809 |       fprintf(PlotFile,"# Psi %i, type %s (real density) plot of plane perpendicular to direction e_%i at node %lg, seed %i, config %s, run on %s, #cpus %i", wavenr, spin, index, node, R->Seed, P->Files.default_path, filename, P->Par.Max_me_comm_ST_Psi);
 | 
|---|
 | 1810 |       fprintf(PlotFile,"\n");
 | 
|---|
 | 1811 |     } else { Error(SomeError, "PlotSrcPlane: Opening Plot File"); }
 | 
|---|
 | 1812 |   }
 | 
|---|
| [d3482a] | 1813 |   Free(filename, "PlotSrcPlane: *filename");
 | 
|---|
 | 1814 |   
 | 
|---|
| [a0bcf1] | 1815 |   // plot density
 | 
|---|
 | 1816 |   PlotRealDensity(P, Lev0, PlotFile, index, node, density, density);
 | 
|---|
 | 1817 | 
 | 
|---|
 | 1818 |   if (PlotFile != NULL) { 
 | 
|---|
 | 1819 |     // close file
 | 
|---|
 | 1820 |     fclose(PlotFile);
 | 
|---|
 | 1821 |   }
 | 
|---|
 | 1822 | }
 | 
|---|
 | 1823 | 
 | 
|---|
 | 1824 | /** plots a cut plane of a given 3d real density.
 | 
|---|
 | 1825 |  * \param *P Problem at hand, contains pointer to Lattice structure
 | 
|---|
 | 1826 |  * \param *Lev LatticeLevel of the real density
 | 
|---|
 | 1827 |  * \param PlotFile file pointer (already open and valid)
 | 
|---|
 | 1828 |  * \param index index of lattice axis
 | 
|---|
 | 1829 |  * \param n_orth position on lattice axis where to cut
 | 
|---|
 | 1830 |  * \param *density1 first real density array
 | 
|---|
 | 1831 |  * \param *density2 second real density array (point to \a *density1 if not needed)
 | 
|---|
 | 1832 |  */
 | 
|---|
 | 1833 | void PlotRealDensity(struct Problem *P, struct LatticeLevel *Lev, FILE *PlotFile, int index, double n_orth, fftw_real *density1, fftw_real *density2)
 | 
|---|
 | 1834 | {
 | 
|---|
 | 1835 |   struct Lattice *Lat = &P->Lat;
 | 
|---|
 | 1836 |   int n[NDIM], n0;
 | 
|---|
 | 1837 |   int N[NDIM];
 | 
|---|
 | 1838 |   N[0] = Lev->Plan0.plan->N[0];
 | 
|---|
 | 1839 |   N[1] = Lev->Plan0.plan->N[1];
 | 
|---|
 | 1840 |   N[2] = Lev->Plan0.plan->N[2];
 | 
|---|
 | 1841 |   const int N0 = Lev->Plan0.plan->local_nx;
 | 
|---|
 | 1842 |   const int myPE = P->Par.me_comm_ST_Psi;
 | 
|---|
 | 1843 |   double fac[NDIM], x[NDIM];
 | 
|---|
 | 1844 |   int i0, i = 0;
 | 
|---|
 | 1845 |   int PE, zahl;
 | 
|---|
 | 1846 |   double *buffer;
 | 
|---|
 | 1847 |   MPI_Status status;
 | 
|---|
 | 1848 |   int sizes[P->Par.Max_me_comm_ST_Psi], c0, c1;
 | 
|---|
| [e24bbb] | 1849 |   double nodes[NDIM], node[NDIM];
 | 
|---|
 | 1850 |   
 | 
|---|
 | 1851 |   for(i=0;i<NDIM;i++) {
 | 
|---|
 | 1852 |     nodes[i] = (i == index) ? n_orth : 0.;
 | 
|---|
 | 1853 |     node[i] = 0.;
 | 
|---|
 | 1854 |   }
 | 
|---|
 | 1855 |   RMat33Vec3(node, Lat->ReciBasis, nodes);  // transform cartesian coordinates into cell coordinates [0,1]^3
 | 
|---|
 | 1856 |   for(i=0;i<NDIM;i++) // now N^3 within node range of discrete grid
 | 
|---|
 | 1857 |     node[i] = (int)(node[i]*N[i]/(2.*PI));
 | 
|---|
 | 1858 |   fprintf(stderr,"(%i) n_orth %lg, index %i converted to plane offset vector (%lg, %lg, %lg).\n", P->Par.me, n_orth, index, node[0], node[1], node[2]);
 | 
|---|
| [a0bcf1] | 1859 |   
 | 
|---|
 | 1860 |   switch (index) {
 | 
|---|
 | 1861 |     case 0:
 | 
|---|
 | 1862 |         zahl = 4*N[1]*N[2];
 | 
|---|
 | 1863 |       break;
 | 
|---|
 | 1864 |     case 1:
 | 
|---|
 | 1865 |         zahl = 4*N0*N[2];
 | 
|---|
 | 1866 |       break;
 | 
|---|
 | 1867 |     case 2:
 | 
|---|
 | 1868 |         zahl = 4*N0*N[1];
 | 
|---|
 | 1869 |       break;
 | 
|---|
 | 1870 |   } 
 | 
|---|
| [e24bbb] | 1871 |   fprintf(stderr,"(%i) buffer size %i\n", P->Par.me, zahl);
 | 
|---|
| [a0bcf1] | 1872 |   buffer = Malloc(sizeof(double)*zahl,"PlotRealDensity: buffer");
 | 
|---|
 | 1873 |   
 | 
|---|
 | 1874 |   c0 = cross(index,0);
 | 
|---|
 | 1875 |   c1 = cross(index,1);
 | 
|---|
 | 1876 |   // then for every point on the grid in real space ...
 | 
|---|
| [e24bbb] | 1877 |   i=0;
 | 
|---|
| [a0bcf1] | 1878 |   for (n0=0;n0<N0;n0++)  // only local points on x axis
 | 
|---|
 | 1879 |     for (n[1]=0;n[1]<N[1];n[1]++)
 | 
|---|
 | 1880 |       for (n[2]=0;n[2]<N[2];n[2]++) {
 | 
|---|
 | 1881 |         n[0]=n0 + N0*myPE; // global relative coordinate: due to partitoning of x-axis in PEPGamma>1 case
 | 
|---|
| [e24bbb] | 1882 |         if (n[index] == (int)node[index]) { // only on the correct plane orthogonal to desired axis and at desired node ...
 | 
|---|
| [a0bcf1] | 1883 |           fac[0] = (double)n[0]/(double)N[0];
 | 
|---|
 | 1884 |           fac[1] = (double)n[1]/(double)N[1];
 | 
|---|
 | 1885 |           fac[2] = (double)n[2]/(double)N[2];
 | 
|---|
 | 1886 |           RMat33Vec3(x, Lat->RealBasis, fac); // relative coordinate times basis matrix gives absolute ones
 | 
|---|
 | 1887 |           i0 = n[2]+N[2]*(n[1]+N[1]*n0);  // index to local density array
 | 
|---|
 | 1888 | 
 | 
|---|
 | 1889 |           buffer[i++] = x[c0];  // fill buffer
 | 
|---|
 | 1890 |           buffer[i++] = x[c1];
 | 
|---|
 | 1891 |           buffer[i++] = density1[i0];
 | 
|---|
 | 1892 |           buffer[i++] = density2[i0];
 | 
|---|
 | 1893 |           if (i > zahl) Error(SomeError, "PlotRealDensity: buffer too small!");
 | 
|---|
 | 1894 |         }
 | 
|---|
 | 1895 |       }
 | 
|---|
 | 1896 |   // exchange sizes of each buffer
 | 
|---|
 | 1897 |   MPI_Allgather(&i, 1, MPI_INT, sizes, 1, MPI_INT, P->Par.comm_ST_Psi);   
 | 
|---|
 | 1898 |   if (myPE == 0) {
 | 
|---|
 | 1899 |     for (PE=0; PE < P->Par.Max_me_comm_ST_Psi; PE++) {
 | 
|---|
 | 1900 |       if (PE != 0) {  
 | 
|---|
 | 1901 |         // receive them
 | 
|---|
 | 1902 |         if (MPI_Recv(buffer, sizes[PE], MPI_DOUBLE, PE, PlotRealDensityTag, P->Par.comm_ST_Psi, &status) != MPI_SUCCESS)
 | 
|---|
 | 1903 |           Error(SomeError, "PlotRealDensity: MPI_Recv failure!");
 | 
|---|
 | 1904 |         MPI_Get_count(&status, MPI_DOUBLE, &zahl);
 | 
|---|
 | 1905 |         if (zahl != sizes[PE]) 
 | 
|---|
 | 1906 |           Error(SomeError, "PlotRealDensity: received unexpected amount of elements!");
 | 
|---|
 | 1907 |       }
 | 
|---|
 | 1908 |       //write them: local one (still in buffer) and received ones
 | 
|---|
 | 1909 |       for (i0 = 0; i0 < sizes[PE];) {
 | 
|---|
 | 1910 |         fprintf(PlotFile,"%e", buffer[(i0)++]);
 | 
|---|
 | 1911 |         if ((i0 % 4) == 0) {
 | 
|---|
 | 1912 |           fprintf(PlotFile,"\n");
 | 
|---|
 | 1913 |         } else {
 | 
|---|
 | 1914 |           fprintf(PlotFile,"\t");
 | 
|---|
 | 1915 |         }
 | 
|---|
 | 1916 |       }
 | 
|---|
 | 1917 |     }
 | 
|---|
 | 1918 |   } else { // send them
 | 
|---|
 | 1919 |     if (MPI_Send(buffer, i, MPI_DOUBLE, 0, PlotRealDensityTag, P->Par.comm_ST_Psi) != MPI_SUCCESS)
 | 
|---|
 | 1920 |       Error(SomeError, "PlotRealDensity: MPI_Send failure!"); 
 | 
|---|
 | 1921 |   }
 | 
|---|
| [64fa9e] | 1922 |   Free(buffer, "PlotRealDensity: buffer");
 | 
|---|
| [a0bcf1] | 1923 | }
 | 
|---|