cloudy  trunk
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  // option to cycle through grid multiple times, default is 1
51  ASSERT( grid.totNumModels > 1 );
52 
53  grid.paramNames = (char**)MALLOC(sizeof(char*)*(unsigned)(nInterpVars+grid.naddparm) );
54  grid.paramMethods = (long*)MALLOC(sizeof(long)*(unsigned)(nInterpVars+grid.naddparm) );
55  grid.paramRange = (realnum**)MALLOC(sizeof(realnum*)*(unsigned)(nInterpVars+grid.naddparm) );
56  grid.paramData = (realnum**)MALLOC(sizeof(realnum*)*(unsigned)(nInterpVars+grid.naddparm) );
57  grid.interpParameters = (realnum**)MALLOC(sizeof(realnum*)*(unsigned)(grid.totNumModels) );
58 
59  for( i=0; i<nInterpVars+grid.naddparm; i++ )
60  {
61  grid.paramNames[i] = (char*)MALLOC(sizeof(char)*(unsigned)(12) );
62  grid.paramRange[i] = (realnum*)MALLOC(sizeof(realnum)*(unsigned)(6) );
63  grid.paramData[i] = (realnum*)MALLOC(sizeof(realnum)*(unsigned)(grid.numParamValues[i]) );
64 
65  sprintf( grid.paramNames[i], "%s%ld", "PARAM", i+1 );
66  /* Method is 0 for linear, 1 for logarithmic */
67  grid.paramMethods[i] = 0;
68  /* Initial */
69  grid.paramRange[i][0] = xc[i]+grid.paramIncrements[i]*(grid.numParamValues[i]-1.f)/2.f;
70  /* Delta */
71  grid.paramRange[i][1] = grid.paramIncrements[i]/10.f;
72  /* Minimum */
73  grid.paramRange[i][2] = xc[i];
74  /* Bottom */
75  grid.paramRange[i][3] = xc[i]+grid.paramIncrements[i]/10.f;
76  /* Top */
77  grid.paramRange[i][4] = xc[i]+grid.paramIncrements[i]*(grid.numParamValues[i]-1.f)-grid.paramIncrements[i]/10.f;
78  /* Maximum */
79  grid.paramRange[i][5] = xc[i]+grid.paramIncrements[i]*(grid.numParamValues[i]-1.f);
80 
81  for( long j=0; j<grid.numParamValues[i]; j++ )
82  {
83  grid.paramData[i][j] = xc[i]+grid.paramIncrements[i]*j;
84  }
85  }
86 
87  for( i=0; i<grid.totNumModels; i++ )
88  {
89  grid.interpParameters[i] = (realnum*)MALLOC(sizeof(realnum)*(unsigned)(nInterpVars) );
90  }
91 
92  for( i=0; i< grid.totNumModels; i++ )
93  {
94  long j;
95  realnum variableVector[LIMPAR];
96 
97  for( j=0; j<nInterpVars; j++ )
98  {
99  int index;
100  long volumeOtherDimensions = 1;
101 
102  /* by "volume", we simply mean the product of the parameter dimensions
103  * AFTER the present index, i.e.:
104  * first "volume" is product of grid.numParamValues[1]*grid.numParamValues[2]*....grid.numParamValues[n]
105  * second "volume" is product of grid.numParamValues[2]*grid.numParamValues[3]*....grid.numParamValues[n]
106  * last "volume" is unity. */
107  for( long k=j+1; k<nInterpVars; k++ )
108  {
109  volumeOtherDimensions *= grid.numParamValues[k];
110  }
111 
112  /* For each successive parameter, the "volume" is less than the previous one.
113  * So the left-hand side of this modulus operation increases for each parameter,
114  * which causes the index of each parameter to be incremented more often than the
115  * index of the previous parameter. Thus, the last dimension is incremented
116  * every time, then the second to last dimension is incremented with each repeat
117  * of the last dimension. This repeats until, finally, the first dimension is
118  * incremented. For example, the indices of the parameter vectors for a 2x2x3
119  * box would be ordered as such:
120  * [0][0][0]
121  * [0][0][1]
122  * [0][0][2]
123  * [0][1][0]
124  * [0][1][1]
125  * [0][1][2]
126  * [1][0][0]
127  * [1][0][1]
128  * [1][0][2]
129  * [1][1][0]
130  * [1][1][1]
131  * [1][1][2]
132  */
133  index = (int)( (i/volumeOtherDimensions)%(grid.numParamValues[j]) );
134 
135  /* this prevents parameter incrementation for debugging purposes. */
136  if( grid.lgStrictRepeat )
137  variableVector[j] = xc[j];
138  else
139  variableVector[j] = xc[j] + grid.paramIncrements[j]*index;
140 
141  grid.interpParameters[i][j] = variableVector[j];
142 
144  variableVector[j] = log10(variableVector[j]);
145  }
146 
147  for( j=nInterpVars; j<LIMPAR; j++ )
148  {
149  variableVector[j] = xc[j];
150  }
151 
152  if( i == grid.totNumModels - 1 )
153  {
154  fixit(); // is this needed ??
155  called.lgTalk = cpu.i().lgMPI_talk();
157  prt.lgFaintOn = true;
158  grid.lgGridDone = true;
159  }
160 
161  (void)optimize_func(variableVector,i);
162  }
163  return;
164 }
165 
166 /*GridGatherInCloudy - gathers spectra for each grid calculation to save for end */
168 {
169  long i;
170 
171  DEBUG_ENTRY( "GridGatherInCloudy()" );
172 
173  ASSERT( grid.lgGrid );
174 
175  /* malloc some arrays if first call and save continuum energies. */
176  if( grid.Energies.empty() )
177  {
178  long i1, i2;
179 
180  // this will happen if we have more MPI ranks than grid points
181  // the highest ranks will not have executed any model
182  if( rfield.nupper <= 0 )
183  ContCreateMesh();
184 
185  if( grid.LoEnergy_keV == 0. )
186  grid.ipLoEnergy = 0;
187  else
188  grid.ipLoEnergy = ipoint( grid.LoEnergy_keV * 1000. / EVRYD );
189 
192  else
193  grid.ipHiEnergy = ipoint( grid.HiEnergy_keV * 1000. / EVRYD );
194 
196  ASSERT( grid.numEnergies > 0 );
197  grid.Energies.resize( grid.numEnergies );
199  for( i1=0; i1 < NUM_OUTPUT_TYPES; i1++ )
200  {
201  if( grid.lgOutputTypeOn[i1] )
202  {
204  for( i2=0; i2 < grid.totNumModels; i2++ )
205  {
207  }
208  }
209  }
210  grid.Spectra.alloc();
211  // this needs to be zeroed out for MPI runs
212  grid.Spectra.zero();
213 
214  for( i1=0; i1<grid.numEnergies; i1++ )
215  {
216  long j = grid.ipLoEnergy + i1;
217  grid.Energies[i1] = rfield.AnuOrg[j];
218  }
219  }
220 
222  {
223  ASSERT( optimize.nOptimiz >= 0 );
224 
225  for( i=0; i < NUM_OUTPUT_TYPES; i++ )
226  {
227  /* Grab spectrum for xspec printout
228  * at this point nOptimiz has already been incremented for first model */
229  if( grid.lgOutputTypeOn[i] )
231  &grid.Spectra[i][optimize.nOptimiz][0]);
232  }
233  }
234  else if( optimize.nOptimiz == grid.totNumModels )
235  {
236  if( cpu.i().lgMPI() )
237  {
238  multi_arr<realnum,3> Spectra_Copy = grid.Spectra;
239 
240  // combine the grid.Spectra data from all ranks. This is done by adding up
241  // the results from all ranks. All but one should be zero. This is needed
242  // because we do not know which rank calculated which grid point...
243  for( int i=0; i < NUM_OUTPUT_TYPES; ++i )
244  {
245  if( grid.lgOutputTypeOn[i] )
246  {
247  for( int j=0; j < grid.totNumModels; ++j )
248  {
249  MPI::COMM_WORLD.Reduce( &Spectra_Copy[i][j][0],
250  &grid.Spectra[i][j][0],
252  MPI::type(grid.Spectra[i][j][0]),
253  MPI::SUM,
254  0 );
255  }
256  }
257  }
258  MPI::COMM_WORLD.Barrier();
259  }
260  }
261  else
262  {
263  TotalInsanity();
264  }
265  return;
266 }
t_grid::paramData
realnum ** paramData
Definition: grid.h:30
t_grid::totNumModels
long totNumModels
Definition: grid.h:51
t_optimize::nOptimiz
long int nOptimiz
Definition: optimize.h:246
ContCreateMesh
void ContCreateMesh(void)
Definition: cont_createmesh.cpp:38
t_continuum::filbnd
realnum * filbnd
Definition: continuum.h:69
rfield
t_rfield rfield
Definition: rfield.cpp:8
t_grid::ipHiEnergy
long ipHiEnergy
Definition: grid.h:58
ioQQQ
FILE * ioQQQ
Definition: cddefines.cpp:7
realnum
float realnum
Definition: cddefines.h:103
rfield.h
multi_arr::reserve
void reserve(size_type i1)
Definition: container_classes.h:1080
grid
t_grid grid
Definition: grid.cpp:5
multi_arr< realnum, 3 >
gridXspec
void gridXspec(realnum xc[], long int nInterpVars)
Definition: grid_xspec.cpp:21
cpu
static t_cpu cpu
Definition: cpu.h:355
t_grid::LoEnergy_keV
realnum LoEnergy_keV
Definition: grid.h:59
t_grid::paramIncrements
realnum paramIncrements[LIMPAR]
Definition: grid.h:34
ipoint.h
grid.h
ASSERT
#define ASSERT(exp)
Definition: cddefines.h:578
t_grid::interpParameters
realnum ** interpParameters
Definition: grid.h:31
t_grid::lgStrictRepeat
bool lgStrictRepeat
Definition: grid.h:42
t_grid::Energies
vector< realnum > Energies
Definition: grid.h:25
ipoint
long ipoint(double energy_ryd)
Definition: cont_ipoint.cpp:16
t_grid::Spectra
multi_arr< realnum, 3 > Spectra
Definition: grid.h:26
cddrive.h
MPI::COMM_WORLD
t_MPI COMM_WORLD
Definition: mpi_utilities.cpp:13
cdSPEC2
void cdSPEC2(int Option, long int nEnergy, long int ipLoEnergy, long int ipHiEnergy, realnum ReturnedSpectrum[])
t_grid::nintparm
long nintparm
Definition: grid.h:47
optimize
t_optimize optimize
Definition: optimize.cpp:5
t_cpu::i
t_cpu_i & i()
Definition: cpu.h:347
EXIT_FAILURE
#define EXIT_FAILURE
Definition: cddefines.h:140
t_grid::paramMethods
long * paramMethods
Definition: grid.h:28
t_grid::lgLinearIncrements
bool lgLinearIncrements[LIMPAR]
Definition: grid.h:35
t_grid::numEnergies
long numEnergies
Definition: grid.h:49
prt
t_prt prt
Definition: prt.cpp:10
cddefines.h
optimize.h
TotalInsanity
NORETURN void TotalInsanity(void)
Definition: service.cpp:886
t_grid::paramRange
realnum ** paramRange
Definition: grid.h:29
multi_arr::alloc
void alloc()
Definition: container_classes.h:1116
t_called::lgTalk
bool lgTalk
Definition: called.h:12
t_rfield::AnuOrg
double * AnuOrg
Definition: rfield.h:62
MALLOC
#define MALLOC(exp)
Definition: cddefines.h:501
mpi_utilities.h
GridGatherInCloudy
void GridGatherInCloudy()
Definition: grid_xspec.cpp:167
t_grid::paramNames
char ** paramNames
Definition: grid.h:27
cdEXIT
#define cdEXIT(FAIL)
Definition: cddefines.h:434
save.h
t_rfield::nupper
long int nupper
Definition: rfield.h:46
t_continuum::nrange
long int nrange
Definition: continuum.h:77
t_cpu_i::lgMPI_talk
bool lgMPI_talk() const
Definition: cpu.h:328
prt.h
t_grid::lgGridDone
bool lgGridDone
Definition: grid.h:41
t_prt::lgFaintOn
bool lgFaintOn
Definition: prt.h:202
t_cpu_i::lgMPI
bool lgMPI() const
Definition: cpu.h:322
NUM_OUTPUT_TYPES
const int NUM_OUTPUT_TYPES
Definition: grid.h:21
multi_arr::zero
void zero()
Definition: container_classes.h:1051
t_optimize::lgOptimizeAsLinear
bool lgOptimizeAsLinear[LIMPAR]
Definition: optimize.h:180
t_grid::numParamValues
long numParamValues[LIMPAR]
Definition: grid.h:50
physconst.h
LIMPAR
const long LIMPAR
Definition: optimize.h:61
called
t_called called
Definition: called.cpp:5
optimize_func
chi2_type optimize_func(const realnum param[], int grid_index=-1)
Definition: optimize_func.cpp:20
fixit
void fixit(void)
Definition: service.cpp:991
t_grid::lgOutputTypeOn
bool lgOutputTypeOn[NUM_OUTPUT_TYPES]
Definition: grid.h:56
t_grid::nCycle
long nCycle
Definition: grid.h:54
t_grid::ipLoEnergy
long ipLoEnergy
Definition: grid.h:58
continuum
t_continuum continuum
Definition: continuum.cpp:5
called.h
continuum.h
t_grid::naddparm
long naddparm
Definition: grid.h:48
EVRYD
const UNUSED double EVRYD
Definition: physconst.h:189
warnings.h
t_called::lgTalkIsOK
bool lgTalkIsOK
Definition: called.h:23
t_grid::lgGrid
bool lgGrid
Definition: grid.h:40
DEBUG_ENTRY
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:684
t_grid::HiEnergy_keV
realnum HiEnergy_keV
Definition: grid.h:59