HARM
harm and utilities
 All Data Structures Files Functions Variables Typedefs Macros Pages
image.c
Go to the documentation of this file.
1 
8 #include "decs.h"
9 
10 #define GAMMIESTARTI (0)
11 #define GAMMIEENDI (0)
12 
13 #define JONSTARTI (0)
14 #define JONENDI (NPRDUMP-1)
15 
16 #define NORMAL (0)
17 #define ZOOM (1)
18 // revert to only normal for now
19 //#define NUMLIMITS (2)
20 #define NUMLIMITS (1)
21 
22 #define LOG (0)
23 #define LINEAR (1)
24 #define NUMSCALE (2)
25 
26 #define DOCONS (1)
27 // whether to do (0=no, 1=yes) conserved quantities in image
28 
29 #define MINVECTOR (SMALL)
30 
31 
32 // OPENMPMARK: Assume imagedefs() image() only called by master thread
33 // global variables for this file
36 
37 
38 
40 int image_dump(long dump_cnt)
41 {
42  int startpl,endpl,starts,ends,startl,endl,startv,endv;
43  int whichpl,limits,scale,vartype;
44 
45  if(DOIMAGEDUMP==0) return(0);
46 
48  //
49  // Image Loop
50  //
52 
53  // STARTI=0 is normal
54  // ENDI=NPRDUMP is normal, but can be NPRDUMP+2 to get linear RHO/UU
55  if(PRODUCTION==0){
56  if(GAMMIEIMAGE){
57  startpl=GAMMIESTARTI;
58  endpl=GAMMIEENDI;
59  starts=0;
60  ends=1;
61  startl=0;
62  endl=0;
63  startv=0;
64  endv=0;
65  }
66  else{
67  startpl=JONSTARTI;
68  endpl=JONENDI;
69  starts=0;
70  ends=NUMSCALE-1;
71  startl=0;
72  endl=NUMLIMITS-1;
73  startv=0;
74  // endv=1;
75  endv=2; // including failures now
76  }
77  }
78  else{
79  // no special images for production mode, just basic log density
80  if(GAMMIEIMAGE){
81  if(DOEVOLVERHO){
82  startpl=0;
83  endpl=0;
84  }
85  else{
86  startpl=B1;
87  endpl=B1;
88  }
89  starts=0;
90  ends=0;
91  startl=0;
92  endl=0;
93  startv=0;
94  endv=0;
95  }
96  else{
97  if(DOEVOLVERHO){
98  startpl=0;
99  endpl=0;
100  }
101  else{
102  startpl=B1;
103  endpl=B1;
104  }
105  starts=0;
106  ends=0;
107  startl=0;
108  endl=0;
109  startv=0;
110  endv=0;
111  }
112  }
113 
114 
115 
116  for(vartype=startv;vartype<=endv;vartype++){
117  for(limits=startl;limits<=endl;limits++){
118  for(scale=starts;scale<=ends;scale++){
119  for (whichpl = startpl; whichpl <= endpl; whichpl++) {
120  if(
121  ((vartype<=1)||((vartype==2)&&(DODEBUG)&&(whichpl<=NUMFAILFLOORFLAGS-1)))||
122  ((limits==0)&&(scale==LINEAR)&&(vartype==2)&&(whichpl==4)&&DO_VORTICITY_IMAGE)
123  ){
124  if(image(dump_cnt,whichpl,scale,limits,vartype)>=1) return(1);
125  }
126  }
127  }
128  }
129  }
130 
131  return(0);
132 }
133 
135 int imagedefs(int whichpl, int scale, int limits, int vartype)
136 {
137  int i = 0, j = 0, k = 0, l = 0, col = 0, floor;
138  FILE *fp;
139  // whichpl : whichpl primitive variable
140  FTYPE pr,iq, liq, lmax;
141  unsigned char liqb;
142  FTYPE min,max,sum;
143  FTYPE minptr[NPR], maxptr[NPR], sumptr[NPR];
144  char truemyidtxt[MAXFILENAME];
145  FTYPE U[NPR];
146  struct of_state q;
147  FTYPE X[NDIM],V[NDIM],r,th;
148  FTYPE lmin,aa;
149  int compute_vorticity(FTYPE (*p)[NSTORE2][NSTORE3][NPR],FTYPE (*pvort)[NSTORE2][NSTORE3][NPR],int whichpl);
150  int pl,pliter;
151  struct of_geom geomdontuse;
152  struct of_geom *ptrgeom=&geomdontuse;
153 
154 
155 #if(USEOPENMP)
156  if(omp_in_parallel()){
157  dualfprintf(fail_file,"imagedefs() called in parallel region\n");
158  myexit(3487346);
159  }
160 #endif
161 
162 
164  //
165  // Image output setup/definition
166  //
167  // Purpose is to set pimage to correct variable type (primitive or conservative), limits, scale, and which k.
168  // Then image() outputs that one thing to file
169  //
171 
172  GLOBALPOINT(pimage)=GLOBALPOINT(dUgeomarray); // assume dUgeomarray is only used within each substep and not across substeps
173  if(limits==ZOOM){ // zoom in on dynamic range of values to see fine details
174  DUMPGENLOOP{ // diagnostic loop // OPENMPOPTMARK: Could optimize this, but not frequently done
175  if(vartype==0){
176  if(whichpl==RHO || whichpl==UU || pl==PRAD0 || SCALARPL(pl)){
177  bl_coord_ijk_2(i,j,k,CENT,X,V);
178  r=V[1];
179  th=V[2];
180  if(whichpl==0) GLOBALMACP0A1(pimage,i,j,k,whichpl)=GLOBALMACP0A1(pdump,i,j,k,whichpl)/(RHOMIN*pow(r,-1.5));
181  if(whichpl==1) GLOBALMACP0A1(pimage,i,j,k,whichpl)=GLOBALMACP0A1(pdump,i,j,k,whichpl)/(UUMIN*pow(r,-2.5));
182  }
183  else{
184  if(scale==LINEAR) GLOBALMACP0A1(pimage,i,j,k,whichpl)=GLOBALMACP0A1(pdump,i,j,k,whichpl);
185  else if(scale==LOG) GLOBALMACP0A1(pimage,i,j,k,whichpl)=fabs(GLOBALMACP0A1(pdump,i,j,k,whichpl))+MINVECTOR;
186  }
187  }
188  else if(vartype==1){// conserved quantity
189  // computes too much (all conserved quantites every time)
190  if(DOENOFLUX == NOENOFLUX){
191  get_geometry(i,j,k,CENT,ptrgeom) ;
192  if(!failed){
193  if(get_state(GLOBALMAC(pdump,i,j,k),ptrgeom,&q)>=1) return(1);
194  if(primtoU(UDIAG,GLOBALMAC(pdump,i,j,k),&q,ptrgeom,U, NULL)>=1) return(1);
195  }
196  }
197  else{
198  PALLLOOP(pl) U[pl]=GLOBALMACP0A1(udump,i,j,k,pl);
199  }
200  if(scale==LINEAR) GLOBALMACP0A1(pimage,i,j,k,whichpl)=U[whichpl];
201  else if(scale==LOG) GLOBALMACP0A1(pimage,i,j,k,whichpl)=fabs(U[whichpl]/ptrgeom->gdet)+MINVECTOR;
202  }
203  else if(vartype==2){ // failure quantity (no diff from below right now -- could zoom in on single failure regions)
204  if(whichpl<NUMFAILFLOORFLAGS){
205  floor=whichpl;
206  if(scale==LINEAR) GLOBALMACP0A1(pimage,i,j,k,whichpl)=(FTYPE)GLOBALMACP0A3(failfloorcount,i,j,k,0,IMAGETS,floor); // always finalstep==0
207  else if(scale==LOG) GLOBALMACP0A1(pimage,i,j,k,whichpl)=fabs((FTYPE)GLOBALMACP0A3(failfloorcount,i,j,k,0,IMAGETS,floor)+1); // always finalstep==0
208  }
209  }
210  }
211  }
212  else{ // normal image
213  DUMPGENLOOP{ // diagnostic loop // OPENMPOPTMARK: Could optimize this, but not frequently done
214  if(vartype==0){
215  if(whichpl==RHO || whichpl==UU || pl==PRAD0 || SCALARPL(pl)) GLOBALMACP0A1(pimage,i,j,k,whichpl)=GLOBALMACP0A1(pdump,i,j,k,whichpl);
216  else{
217  if(scale==LINEAR) GLOBALMACP0A1(pimage,i,j,k,whichpl)=GLOBALMACP0A1(pdump,i,j,k,whichpl);
218  else if(scale==LOG) GLOBALMACP0A1(pimage,i,j,k,whichpl)=fabs(GLOBALMACP0A1(pdump,i,j,k,whichpl))+MINVECTOR;
219  }
220  }
221  else if(vartype==1){// conserved quantity
222  // computes too much (all conserved quantites every time)
223  if(DOENOFLUX == NOENOFLUX){
224  get_geometry(i,j,k,CENT,ptrgeom) ;
225  if(!failed){
226  if(get_state(GLOBALMAC(pdump,i,j,k),ptrgeom,&q)>=1) return(1);
227  if(primtoU(UDIAG,GLOBALMAC(pdump,i,j,k),&q,ptrgeom,U, NULL)>=1) return(1);
228  }
229  }
230  else{
231  PALLLOOP(pl) U[pl]=GLOBALMACP0A1(udump,i,j,k,pl);
232  }
233  if(scale==LINEAR) GLOBALMACP0A1(pimage,i,j,k,whichpl)=U[whichpl];
234  else if(scale==LOG) GLOBALMACP0A1(pimage,i,j,k,whichpl)=fabs(U[whichpl]/ptrgeom->gdet)+MINVECTOR;
235  }
236  else if(vartype==2){ // failure quantity
237  if(whichpl<NUMFAILFLOORFLAGS){
238  floor=whichpl;
239  if(scale==LINEAR) GLOBALMACP0A1(pimage,i,j,k,whichpl)=(FTYPE)GLOBALMACP0A3(failfloorcount,i,j,k,0,IMAGETS,floor); // finalstep==0
240  else if(scale==LOG) GLOBALMACP0A1(pimage,i,j,k,whichpl)=fabs((FTYPE)GLOBALMACP0A3(failfloorcount,i,j,k,0,IMAGETS,floor)+1); // finalstep==0
241  }
242  }
243  }
244 #if(DO_VORTICITY_IMAGE)
245  if(vartype==2){
246  // overwrite vartype==2 with vorticity for whichpl==4
247  // e.g. !dr82 images/im4f1s0l0100.r8 for final vorticity
248  compute_vorticity(pglobal,pimage,4);
249  }
250 #endif
251  }
252 
253 
254 
256  //
257  // Image FILE open/initialize
258  //
260 
261 
262 
264  //
265  // Image paramters setup (whole purpose currently is to find lmin and aa)
266  //
268 
269  /* density mapping is logarithmic, in 255 steps between e^lmax and
270  e^lmin */
271 
272 #define ZOOMFACTOR (10000)
273 
274  prminmaxsum(GLOBALPOINT(pimage),whichpl,1,maxptr,minptr,sumptr);
275  if(limits==NORMAL){
276  max=maxptr[whichpl];
277  min=minptr[whichpl];
278  sum=sumptr[whichpl];
279 #ifdef TESTNUMBER
280 #if( DO_VORTICITY_IMAGE && (TESTNUMBER == 26 || TESTNUMBER == 27) )
281  if( vartype==2 && whichpl==4 && limits == 0 && scale == LINEAR ) {
282  //The exact vorticity should be changing between -5 & 10, so make the limits
283  //a bit larger than that to avoid "black" spots on the image
284  if( debugfail >= 1) trifprintf( "Vorticity: old: min = %lg, max = %lg", min, max );
285  min = -5.5 / coordparams.timescalefactor;
286  max = 10.5 / coordparams.timescalefactor;
287  if( debugfail >= 1) trifprintf( ", new: min = %lg, max = %lg\n", min, max );
288  }
289 #endif
290 #endif
291  }
292  else{
293  if(whichpl==RHO || whichpl==UU || pl==PRAD0 || SCALARPL(pl)){
294  max=maxptr[whichpl]/ZOOMFACTOR;
295  min=minptr[whichpl];
296  }
297  else{
298  if(scale==LINEAR){
299  max=maxptr[whichpl]/ZOOMFACTOR;
300  min=minptr[whichpl]/ZOOMFACTOR;
301  }
302  else{
303  max=maxptr[whichpl]/ZOOMFACTOR;
304  min=minptr[whichpl];
305  }
306  }
307  }
308  sum=sumptr[whichpl];
309  logsfprintf("whichpl: %d scale: %d limits: %d : min,max,avg: %21.15g %21.15g %21.15g\n",whichpl,scale,limits,min,max,sum/totalzones);
310 
311  if(scale==LOG){
312  lmax = log(max);
313  lmin = log(min);
314  } else if(scale==LINEAR) {
315  lmax = max;
316  lmin = min;
317  }
318  else{
319  dualfprintf(fail_file,"no such scale=%d\n",scale);
320  myexit(1);
321  }
322 
323  if (lmax != lmin)
324  aa = 256. / (lmax - lmin);
325  else
326  aa = 0;
327 
328 
329 
330  // set the only paramters needed to dump image
331  imageparms[ORIGIN]=aa;
332  imageparms[LMIN]=lmin;
333  // extra:
334  imageparms[LMAX]=lmax;
335 
336  return(0);
337 }
338 
339 
340 
342 int image(long dump_cnt, int whichpl, int scale, int limits, int vartype)
343 {
344  MPI_Datatype datatype;
345  int whichdump;
346  char fileprefix[MAXFILENAME]={'\0'};
347  char filesuffix[MAXFILENAME]={'\0'};
348  char fileformat[MAXFILENAME]={'\0'};
349 
350 
351 #if(USEOPENMP)
352  if(omp_in_parallel()){
353  dualfprintf(fail_file,"image() called in parallel region\n");
354  myexit(3487347);
355  }
356 #endif
357 
358 
359  trifprintf("begin dumping image# %ld whichpl: %d scale: %d limits: %d vartype: %d\n ",dump_cnt,whichpl,scale,limits,vartype);
360 
361  // global vars so can avoid passing through general functions
362  imagescale=scale;
363  imagevartype=vartype;
364  imagelimits=limits;
365  imagewhichpl=whichpl;
366 
367 
368 
369  whichdump=IMAGEDUMPTYPE;
370  datatype=MPI_UNSIGNED_CHAR;
371 
372  // actual prefix
374  sprintf(fileprefix, "images/im");
375  }
376  else{
377  if(vartype==0) sprintf(fileprefix, "images/im%1dp%1ds%1dl", whichpl, scale, limits);
378  else if(vartype==1) sprintf(fileprefix, "images/im%1dc%1ds%1dl", whichpl, scale, limits);
379  else if(vartype==2) sprintf(fileprefix, "images/im%1df%1ds%1dl", whichpl, scale, limits);
380  }
381  strcpy(fileformat,"%04ld"); // actual format
382  strcpy(filesuffix,".r8"); // actual suffix
383 
384  // setup the image definitions (min,max, what data, etc.)
385  if(imagedefs(whichpl,scale,limits,vartype)>=1) return(1);
386 
387 
388  // MIXEDOUTPUT tells dump_gen() to treat as .r8 file, with text header and binary dump
389  if(dump_gen(WRITEFILE,dump_cnt,MIXEDOUTPUT,whichdump,datatype,fileprefix,fileformat,filesuffix,image_header,image_content)>=1) return(1);
390 
391  trifprintf("end dumping image# %ld whichpl: %d scale: %d limits: %d vartype: %d\n ",dump_cnt,whichpl,scale,limits,vartype);
392 
393  return(0);
394 
395 }
396 
398 int image_header(int whichdump, int whichdumpversion, int numcolumns, int bintxt, FILE *headerptr)
399 {
400  int realtotalsize[NDIM];
401 
402 
403  realtotalsize[1]=totalsize[1]+2*EXTRADUMP1;
404  realtotalsize[2]=totalsize[2]+2*EXTRADUMP2;
405  realtotalsize[3]=totalsize[3]+2*EXTRADUMP3;
406 
408  //
409  // HEADER file open/initialize
410  //
412 
413  // write header
414  if(bintxt==TEXTOUTPUT){
415 
416  fprintf(headerptr, "RAW\n# t=%21.15g nstep=%ld vartype=%2d whichpl=%2d scale=%2d limits=%2d ",t, nstep, imagevartype, imagewhichpl, imagescale, imagelimits);
417  fprintf(headerptr, "aa=%g lmin=%g lmax=%g ",imageparms[ORIGIN],imageparms[LMIN],imageparms[LMAX]);
418  fprintf(headerptr,"\n");
419 
420  if( (realtotalsize[1]>1)&&(realtotalsize[2]>1)&&(realtotalsize[3]>1)){
421  fprintf(headerptr, "%i %i\n255\n", realtotalsize[1],realtotalsize[2]*realtotalsize[3]);
422  }
423  else{
424  if( (realtotalsize[2]>1)&&(realtotalsize[3]>1)){
425  fprintf(headerptr, "%i %i\n255\n", realtotalsize[2],realtotalsize[3]);
426  }
427  else if( (realtotalsize[1]>1)&&(realtotalsize[3]>1)){
428  fprintf(headerptr, "%i %i\n255\n", realtotalsize[1],realtotalsize[3]);
429  }
430  else if( (realtotalsize[1]>1)&&(realtotalsize[2]>1)){
431  fprintf(headerptr, "%i %i\n255\n", realtotalsize[1],realtotalsize[2]);
432  }
433  else{
434  if(realtotalsize[1]>1){
435  fprintf(headerptr, "%i %i\n255\n", realtotalsize[1],1);
436  }
437  else if(realtotalsize[2]>1){
438  fprintf(headerptr, "%i %i\n255\n", realtotalsize[2],1);
439  }
440  else if(realtotalsize[3]>1){
441  fprintf(headerptr, "%i %i\n255\n", realtotalsize[3],1);
442  }
443  else{
444  dualfprintf(fail_file,"Shouldn't reach here: %d %d %d\n",realtotalsize[1],realtotalsize[2],realtotalsize[3]);
445  myexit(248742);
446  }
447  }
448  }
449  }
450  else{
451  dualfprintf(fail_file,"Shouldn't be trying to write binary header to image file\n");
452  myexit(1);
453  }
454  fflush(headerptr);
455 
456  return(0);
457 }
458 
459 
460 
461 
462 
464 extern void set_image_content_dnumcolumns_dnumversion(int *numcolumns, int *numversion)
465 {
466 
467  // now setup the data output/input organization for chunking method for each number of columns
468  *numcolumns=1;
469 
470 
471  *numversion=0;
472 }
473 
474 
477 int image_content(int i, int j, int k, MPI_Datatype datatype,void *writebuf)
478 {
479  unsigned char liqb;
480  FTYPE pr,iq,liq;
481  FTYPE aa;
482  FTYPE lmin;
483 
484  aa=imageparms[ORIGIN];
485  lmin=imageparms[LMIN];
486 
487  pr=GLOBALMACP0A1(pimage,i,j,k,imagewhichpl);
488  if (imagescale==LOG) iq = log(pr);
489  else if(imagescale==LINEAR) iq = pr;
490 
491  liq = aa * (iq - lmin);
492  if (liq > 255.)
493  liq = 255.;
494  if (liq < 0.)
495  liq = 0.;
496 
497  liqb=(unsigned char)(liq);
498 
499  myset(datatype,&liqb,0,1,writebuf);
500 
501  return(0);
502 }