cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
grid_xspec.cpp
Go to the documentation of this file.
1 /* This file is part of Cloudy and is copyright (C)1978-2013 by Gary J. Ferland and
2  * others. For conditions of distribution and use see copyright notice in license.txt */
3 /*gridXspec handles all grid calculations, called by griddo */
4 /*gridFunc */
5 /*GridGatherInCloudy - gathers spectra for each grid calculation to save for end */
6 #include "cddefines.h"
7 #include "save.h"
8 #include "warnings.h"
9 #include "optimize.h"
10 #include "cddrive.h"
11 #include "continuum.h"
12 #include "rfield.h"
13 #include "grid.h"
14 #include "ipoint.h"
15 #include "called.h"
16 #include "physconst.h"
17 #include "prt.h"
18 #include "mpi_utilities.h"
19 
20 /*gridXspec handles all grid calculations, called by grid_do */
21 void gridXspec(realnum xc[], long int nInterpVars)
22 {
23  long int i;
24 
25  DEBUG_ENTRY( "gridXspec()" );
26 
27  if( nInterpVars > LIMPAR )
28  {
29  fprintf( ioQQQ, "grid_do: too many parameters are varied, increase LIMPAR\n" );
31  }
32 
33  optimize.nOptimiz = 0;
34  grid.nintparm = nInterpVars;
35 
36  /* if this is changed there must be some change made to actually
37  * stuff the additional parameter information. */
38  grid.naddparm = 0;
39 
41 
42  grid.totNumModels = 1;
43  /* >>chng 06 aug 21, allow the number of parameter values to be different for different parameters. */
44  for( i=0; i<nInterpVars; i++ )
45  {
46  /* >>chng 06 sep 4, use grid variable instead of passing to routine. */
48  }
49  /* grid.totNumModels = (long)pow((double)nParVals, (double)nInterpVars); */
50  ASSERT( grid.totNumModels > 1 );
51 
52  grid.paramNames = (char**)MALLOC(sizeof(char*)*(unsigned)(nInterpVars+grid.naddparm) );
53  grid.paramMethods = (long*)MALLOC(sizeof(long)*(unsigned)(nInterpVars+grid.naddparm) );
54  grid.paramRange = (realnum**)MALLOC(sizeof(realnum*)*(unsigned)(nInterpVars+grid.naddparm) );
55  grid.paramData = (realnum**)MALLOC(sizeof(realnum*)*(unsigned)(nInterpVars+grid.naddparm) );
56  grid.interpParameters = (realnum**)MALLOC(sizeof(realnum*)*(unsigned)(grid.totNumModels) );
57 
58  for( i=0; i<nInterpVars+grid.naddparm; i++ )
59  {
60  grid.paramNames[i] = (char*)MALLOC(sizeof(char)*(unsigned)(12) );
61  grid.paramRange[i] = (realnum*)MALLOC(sizeof(realnum)*(unsigned)(6) );
62  grid.paramData[i] = (realnum*)MALLOC(sizeof(realnum)*(unsigned)(grid.numParamValues[i]) );
63 
64  sprintf( grid.paramNames[i], "%s%ld", "PARAM", i+1 );
65  /* Method is 0 for linear, 1 for logarithmic */
66  grid.paramMethods[i] = grid.lgLinearIncrements[i] ? 0 : 1;
67  /* Initial */
68  grid.paramRange[i][0] = xc[i]+grid.paramIncrements[i]*(grid.numParamValues[i]-1.f)/2.f;
69  /* Delta */
70  grid.paramRange[i][1] = grid.paramIncrements[i]/10.f;
71  /* Minimum */
72  grid.paramRange[i][2] = xc[i];
73  /* Bottom */
74  grid.paramRange[i][3] = xc[i]+grid.paramIncrements[i]/10.f;
75  /* Top */
76  grid.paramRange[i][4] = xc[i]+grid.paramIncrements[i]*(grid.numParamValues[i]-1.f)-grid.paramIncrements[i]/10.f;
77  /* Maximum */
78  grid.paramRange[i][5] = xc[i]+grid.paramIncrements[i]*(grid.numParamValues[i]-1.f);
79 
80  for( long j=0; j<grid.numParamValues[i]; j++ )
81  {
82  grid.paramData[i][j] = xc[i]+grid.paramIncrements[i]*j;
83  }
84  }
85 
86  for( i=0; i<grid.totNumModels; i++ )
87  {
88  grid.interpParameters[i] = (realnum*)MALLOC(sizeof(realnum)*(unsigned)(nInterpVars) );
89  }
90 
91  for( i=0; i< grid.totNumModels; i++ )
92  {
93  long j;
94  realnum variableVector[LIMPAR];
95 
96  for( j=0; j<nInterpVars; j++ )
97  {
98  int index;
99  long volumeOtherDimensions = 1;
100 
101  /* by "volume", we simply mean the product of the parameter dimensions
102  * AFTER the present index, i.e.:
103  * first "volume" is product of grid.numParamValues[1]*grid.numParamValues[2]*....grid.numParamValues[n]
104  * second "volume" is product of grid.numParamValues[2]*grid.numParamValues[3]*....grid.numParamValues[n]
105  * last "volume" is unity. */
106  for( long k=j+1; k<nInterpVars; k++ )
107  {
108  volumeOtherDimensions *= grid.numParamValues[k];
109  }
110 
111  /* For each successive parameter, the "volume" is less than the previous one.
112  * So the left-hand side of this modulus operation increases for each parameter,
113  * which causes the index of each parameter to be incremented more often than the
114  * index of the previous parameter. Thus, the last dimension is incremented
115  * every time, then the second to last dimension is incremented with each repeat
116  * of the last dimension. This repeats until, finally, the first dimension is
117  * incremented. For example, the indices of the parameter vectors for a 2x2x3
118  * box would be ordered as such:
119  * [0][0][0]
120  * [0][0][1]
121  * [0][0][2]
122  * [0][1][0]
123  * [0][1][1]
124  * [0][1][2]
125  * [1][0][0]
126  * [1][0][1]
127  * [1][0][2]
128  * [1][1][0]
129  * [1][1][1]
130  * [1][1][2]
131  */
132  index = (int)( (i/volumeOtherDimensions)%(grid.numParamValues[j]) );
133 
134  /* this prevents parameter incrementation for debugging purposes. */
135  if( grid.lgStrictRepeat )
136  variableVector[j] = xc[j];
137  else
138  variableVector[j] = xc[j] + grid.paramIncrements[j]*index;
139 
140  grid.interpParameters[i][j] = variableVector[j];
141 
143  variableVector[j] = log10(variableVector[j]);
144  }
145 
146  for( j=nInterpVars; j<LIMPAR; j++ )
147  {
148  variableVector[j] = xc[j];
149  }
150 
151  if( i == grid.totNumModels - 1 )
152  {
153  fixit(); // is this needed ??
154  called.lgTalk = cpu.i().lgMPI_talk();
156  prt.lgFaintOn = true;
157  grid.lgGridDone = true;
158  }
159 
160  (void)optimize_func(variableVector,i);
161  }
162  return;
163 }
164 
165 /*GridGatherInCloudy - gathers spectra for each grid calculation to save for end */
167 {
168  long i;
169 
170  DEBUG_ENTRY( "GridGatherInCloudy()" );
171 
172  ASSERT( grid.lgGrid );
173 
174  /* malloc some arrays if first call and save continuum energies. */
175  if( grid.Energies.empty() )
176  {
177  long i1, i2;
178 
179  // this will happen if we have more MPI ranks than grid points
180  // the highest ranks will not have executed any model
181  if( rfield.nupper <= 0 )
182  ContCreateMesh();
183 
184  if( grid.LoEnergy_keV == 0. )
185  grid.ipLoEnergy = 0;
186  else
187  grid.ipLoEnergy = ipoint( grid.LoEnergy_keV * 1000. / EVRYD );
188 
191  else
192  grid.ipHiEnergy = ipoint( grid.HiEnergy_keV * 1000. / EVRYD );
193 
195  ASSERT( grid.numEnergies > 0 );
196  grid.Energies.resize( grid.numEnergies );
198  for( i1=0; i1 < NUM_OUTPUT_TYPES; i1++ )
199  {
200  if( grid.lgOutputTypeOn[i1] )
201  {
203  for( i2=0; i2 < grid.totNumModels; i2++ )
204  {
206  }
207  }
208  }
209  grid.Spectra.alloc();
210  // this needs to be zeroed out for MPI runs
211  grid.Spectra.zero();
212 
213  for( i1=0; i1<grid.numEnergies; i1++ )
214  {
215  long j = grid.ipLoEnergy + i1;
216  grid.Energies[i1] = rfield.AnuOrg[j];
217  }
218  }
219 
221  {
222  ASSERT( optimize.nOptimiz >= 0 );
223 
224  for( i=0; i < NUM_OUTPUT_TYPES; i++ )
225  {
226  /* Grab spectrum for xspec printout
227  * at this point nOptimiz has already been incremented for first model */
228  if( grid.lgOutputTypeOn[i] )
230  &grid.Spectra[i][optimize.nOptimiz][0]);
231  }
232  }
233  else if( optimize.nOptimiz == grid.totNumModels )
234  {
235  if( cpu.i().lgMPI() )
236  {
237  multi_arr<realnum,3> Spectra_Copy = grid.Spectra;
238 
239  // combine the grid.Spectra data from all ranks. This is done by adding up
240  // the results from all ranks. All but one should be zero. This is needed
241  // because we do not know which rank calculated which grid point...
242  for( int i=0; i < NUM_OUTPUT_TYPES; ++i )
243  {
244  if( grid.lgOutputTypeOn[i] )
245  {
246  for( int j=0; j < grid.totNumModels; ++j )
247  {
248  MPI::COMM_WORLD.Reduce( &Spectra_Copy[i][j][0],
249  &grid.Spectra[i][j][0],
251  MPI::type(grid.Spectra[i][j][0]),
252  MPI::SUM,
253  0 );
254  }
255  }
256  }
257  MPI::COMM_WORLD.Barrier();
258  }
259  }
260  else
261  {
262  TotalInsanity();
263  }
264  return;
265 }
realnum HiEnergy_keV
Definition: grid.h:56
NORETURN void TotalInsanity(void)
Definition: service.cpp:886
long numEnergies
Definition: grid.h:47
realnum ** paramData
Definition: grid.h:30
bool lgGrid
Definition: grid.h:40
bool lgGridDone
Definition: grid.h:40
t_cpu_i & i()
Definition: cpu.h:334
vector< realnum > Energies
Definition: grid.h:25
chi2_type optimize_func(const realnum param[], int grid_index=-1)
realnum LoEnergy_keV
Definition: grid.h:56
long int nOptimiz
Definition: optimize.h:246
long * paramMethods
Definition: grid.h:28
long ipHiEnergy
Definition: grid.h:55
long ipLoEnergy
Definition: grid.h:55
bool lgStrictRepeat
Definition: grid.h:40
FILE * ioQQQ
Definition: cddefines.cpp:7
bool lgTalk
Definition: called.h:12
void cdSPEC2(int Option, long int nEnergy, long int ipLoEnergy, long int ipHiEnergy, realnum ReturnedSpectrum[])
t_MPI COMM_WORLD
long int nupper
Definition: rfield.h:46
realnum ** interpParameters
Definition: grid.h:31
long nintparm
Definition: grid.h:47
#define MALLOC(exp)
Definition: cddefines.h:505
long int nrange
Definition: continuum.h:75
long totNumModels
Definition: grid.h:47
const double EVRYD
Definition: physconst.h:189
long ipoint(double energy_ryd)
Definition: cont_ipoint.cpp:16
long numParamValues[LIMPAR]
Definition: grid.h:47
t_continuum continuum
Definition: continuum.cpp:5
t_rfield rfield
Definition: rfield.cpp:8
void GridGatherInCloudy(void)
Definition: grid_xspec.cpp:166
float realnum
Definition: cddefines.h:107
realnum * filbnd
Definition: continuum.h:69
const int NUM_OUTPUT_TYPES
Definition: grid.h:21
#define EXIT_FAILURE
Definition: cddefines.h:144
void ContCreateMesh(void)
bool lgFaintOn
Definition: prt.h:202
#define cdEXIT(FAIL)
Definition: cddefines.h:438
bool lgMPI_talk() const
Definition: cpu.h:315
const long LIMPAR
Definition: optimize.h:61
multi_arr< realnum, 3 > Spectra
Definition: grid.h:26
t_optimize optimize
Definition: optimize.cpp:5
t_grid grid
Definition: grid.cpp:5
t_prt prt
Definition: prt.cpp:10
bool lgOptimizeAsLinear[LIMPAR]
Definition: optimize.h:180
bool lgLinearIncrements[LIMPAR]
Definition: grid.h:35
#define ASSERT(exp)
Definition: cddefines.h:582
void reserve(size_type i1)
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:688
bool lgMPI() const
Definition: cpu.h:309
bool lgOutputTypeOn[NUM_OUTPUT_TYPES]
Definition: grid.h:53
double * AnuOrg
Definition: rfield.h:62
realnum paramIncrements[LIMPAR]
Definition: grid.h:34
void gridXspec(realnum *, long)
static t_cpu cpu
Definition: cpu.h:342
void fixit(void)
Definition: service.cpp:991
realnum ** paramRange
Definition: grid.h:29
t_called called
Definition: called.cpp:5
char ** paramNames
Definition: grid.h:27
bool lgTalkIsOK
Definition: called.h:23
long naddparm
Definition: grid.h:47