cloudy  trunk
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cont_ipoint.cpp
Go to the documentation of this file.
1 /* This file is part of Cloudy and is copyright (C)1978-2008 by Gary J. Ferland and
2  * others. For conditions of distribution and use see copyright notice in license.txt */
3 /*ipoint returns pointer to any energy within energy mesh */
4 /*ipFineCont returns array index within fine energy mesh */
5 /*ipContEnergy generate unique pointer to energy within continuum array
6  * continuum energy in Rydbergs */
7 /*ipLineEnergy generate unique pointer to line energy within energy mesh
8  * line energy in Rydbergs */
9 #include "cddefines.h"
10 #include "continuum.h"
11 #include "prt.h"
12 #include "rfield.h"
13 #include "ipoint.h"
14 
15 /*ipoint returns pointer to any energy within energy mesh */
16 long ipoint(double energy_ryd)
17 {
18  long int i,
19  ipoint_v;
20 
21  DEBUG_ENTRY( "ipoint()" );
22 
23  if( energy_ryd < continuum.filbnd[0] || energy_ryd > continuum.filbnd[continuum.nrange] )
24  {
25  fprintf( ioQQQ, " ipoint:\n" );
26  fprintf( ioQQQ, " The energy_ryd array is not defined at nu=%11.3e. The bounds are%11.3e%11.3e\n",
27  energy_ryd, continuum.filbnd[0], continuum.filbnd[continuum.nrange] );
28  fprintf( ioQQQ, " ipoint is aborting to get trace, to find how this happened\n" );
29  ShowMe();
30  cdEXIT(EXIT_FAILURE);
31  }
32 
33  for( i=0; i < continuum.nrange; i++ )
34  {
35  if( energy_ryd >= continuum.filbnd[i] && energy_ryd <= continuum.filbnd[i+1] )
36  {
37 
38  /* this is on the Fortran scale of array index counting, so is one above the
39  * c scale. later the -1 will appear on any index references */
40  ipoint_v = (long int)(log10(energy_ryd/continuum.filbnd[i])/continuum.fildel[i] +
41  1.0 + continuum.ifill0[i]);
42 
43  ASSERT( ipoint_v >= 0 );
44  /* recall on F scale */
45  ipoint_v = MIN2( rfield.nupper , ipoint_v );
46  return ipoint_v;
47  }
48  }
49 
50  /* this exit not possible, here to shut up some compilers */
51  fprintf( ioQQQ, " IPOINT logic error, energy=%.2e\n",
52  energy_ryd );
53  cdEXIT(EXIT_FAILURE);
54 }
55 
56 /*ipContEnergy generate unique pointer to energy within continuum array */
58  /* continuum energy in Rydbergs */
59  double energy,
60  /* 4 char label for continuum, like those returned by chLineLbl */
61  const char *chLabel)
62 {
63  long int ipConSafe_v;
64 
65  DEBUG_ENTRY( "ipContEnergy()" );
66 
67  ipConSafe_v = ipoint(energy);
68 
69  /* write label in this cell if not anything there yet */
70  if( strcmp(rfield.chContLabel[ipConSafe_v-1]," ") == 0 )
71  {
72  strcpy( rfield.chContLabel[ipConSafe_v-1], chLabel );
73  }
74 
75  /* this is a quick way to find all continua that occur within a given cell,
76  * recall the off-by-one aspect of C */
77  {
78  enum {DEBUG_LOC=false};
79  if( DEBUG_LOC )
80  {
81  /* recall the off-by-one aspect of C - the number below is
82  * on the physics scale because this returns the index
83  * on that scale, so the first is 1 for [0] */
84  if( ipConSafe_v == 23 )
85  fprintf(ioQQQ,"%s\n", chLabel );
86  }
87  }
88  return ipConSafe_v;
89 }
90 
91 /*ipLineEnergy generate unique pointer to line energy within energy mesh
92  * line energy in Rydbergs -
93  * return value is array index on the physics or Fortran scale, counting from 1 */
94 long ipLineEnergy(double energy,
95  /* 4 char label for line, like those returned by chLineLbl */
96  const char *chLabel ,
97  /* will make sure energy is < this array index if greater than 0, does nothing if <= 0*/
98  long ipIonEnergy )
99 {
100  long int ipLine_ret;
101 
102  DEBUG_ENTRY( "ipLineEnergy()" );
103 
104  ipLine_ret = ipoint(energy);
105  ASSERT( ipLine_ret );
106  /* make sure pointer is below next higher continuum if positive */
107  if( ipIonEnergy > 0 )
108  {
109  ipLine_ret = MIN2( ipLine_ret , ipIonEnergy-1 );
110  }
111 
112  ASSERT( ipLine_ret > 0 );
113  /* stuff in a label if none there,
114  * note that this is offset one below actual number to be on C scale of arrays */
115  /* >>chng 06 nov 23, faster to use line_count index rather than checking 5 chars
116  * first call will have zero so false */
117  /*if( strcmp(rfield.chLineLabel[ipLine_ret-1]," ")==0 )*/
118  if( !rfield.line_count[ipLine_ret-1] )
119  {
120  strcpy( rfield.chLineLabel[ipLine_ret-1], chLabel );
121  }
122  /* this keeps track of the number of lines within this cell */
123  ++rfield.line_count[ipLine_ret-1];
124 
125  /* this is a quick way to find all lines that occur within a given cell,
126  * recall the off-by-one aspect of C */
127  {
128  enum {DEBUG_LOC=false};
129  if( DEBUG_LOC )
130  {
131  /* recall the off-by-one aspect of C - the numbers is one more
132  * than the index on the C scale */
133  if( ipLine_ret == 23 )
134  fprintf(ioQQQ,"%s\n", chLabel );
135  }
136  }
137 
138  /* this implements the print continuum indices command */
139  if( prt.lgPrtContIndices )
140  {
141  /* print header if first time */
142  static bool lgFirst = true;
143  if( lgFirst )
144  {
145  /* print header and set flag so do not do again */
146  fprintf(ioQQQ , "\n\noutput from print continuum indices command follows.\n");
147  fprintf(ioQQQ , "cont ind (F scale)\tenergy(ryd)\tlabel\n");
148  lgFirst = false;
149  }
150  if( energy >= prt.lgPrtContIndices_lo_E && energy <= prt.lgPrtContIndices_hi_E )
151  {
152  /* use varying formats depending on order of magnitude of energy
153  * NB - the ipLine_ret is the index on the physical or Fortran scale,
154  * and is 1 greater than the array element used in the code, which is
155  * on the C scale */
156  if( energy < 1. )
157  {
158  fprintf(ioQQQ , "%li\t%.3e\t%s\n" , ipLine_ret , energy , chLabel);
159  }
160  else if( energy < 10. )
161  {
162  fprintf(ioQQQ , "%li\t%.3f\t%s\n" , ipLine_ret , energy , chLabel);
163  }
164  else if( energy < 100. )
165  {
166  fprintf(ioQQQ , "%li\t%.2f\t%s\n" , ipLine_ret , energy , chLabel);
167  }
168  else
169  {
170  fprintf(ioQQQ , "%li\t%.1f\t%s\n" , ipLine_ret , energy , chLabel);
171  }
172  }
173  }
174 
175  if( prt.lgPrnLineCell )
176  {
177  /* print line cell option - number on command line is cell on Physics scale */
178  if( prt.nPrnLineCell == ipLine_ret )
179  {
180  static bool lgMustPrintHeader = true;
181  if( lgMustPrintHeader )
182  fprintf(ioQQQ, "Lines within cell %li\n",prt.nPrnLineCell );
183  lgMustPrintHeader = false;
184  fprintf(ioQQQ,"**>%s<**\n" , chLabel );
185  }
186  }
187  return ipLine_ret;
188 }
189 
190 /*ipFineCont returns array index within fine energy mesh */
192  /* energy in Ryd */
193  double energy_ryd )
194 {
195  long int ipoint_v;
196 
197  DEBUG_ENTRY( "ipFineCont()" );
198 
199  if( energy_ryd < rfield.fine_ener_lo || energy_ryd > rfield.fine_ener_hi )
200  {
201  return -1;
202  }
203 
204  /* this is on the Fortran scale of array index counting, so is one above the
205  * c scale. later the -1 will appear on any index references
206  *
207  * 07 Jun 22 testing done to confirm that energy grid is correct: did
208  * same sim with standard fine continuum resolution, and another with 200x
209  * finer resolution, and confirmed that these line up correctly. */
210  ipoint_v = (long int)(log10(energy_ryd*(1.-rfield.fine_resol/2.) /
211  rfield.fine_ener_lo)/log10(1.+rfield.fine_resol));
212 
213  ASSERT( ipoint_v >= 0 && ipoint_v< rfield.nfine_malloc );
214  return ipoint_v;
215 }

Generated for cloudy by doxygen 1.8.1.2