cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cool_save.cpp
Go to the documentation of this file.
1 /* This file is part of Cloudy and is copyright (C)1978-2017 by Gary J. Ferland and
2  * others. For conditions of distribution and use see copyright notice in license.txt */
3 /*CoolSave save coolants */
4 #include "cddefines.h"
5 #include "thermal.h"
6 #include "dynamics.h"
7 #include "radius.h"
8 #include "conv.h"
9 #include "phycon.h"
10 #include "save.h"
11 #include "grainvar.h"
12 #include "hmi.h"
13 #include "coolheavy.h"
14 
15 
16 /* this is limit to number of coolants to print out */
17 static const int IPRINT = 100;
18 
19 /*CoolSave save coolants */
20 void CoolSave(FILE * io, const char chJob[])
21 {
22  long int i,
23  ip,
24  is;
25 
26  int nFail;
27 
28  double cset,
29  cool_total,
30  heat_total;
31 
32  DEBUG_ENTRY( "CoolSave()" );
33 
34  /* cannot do one-time init since thermal.ncltot can change */
35  vector<long>index(thermal.ncltot);
36  vector<realnum>csav(thermal.ncltot),
37  sgnsav(thermal.ncltot);
38 
39  cool_total = thermal.ctot;
40  heat_total = thermal.htot;
41 
42  /* >>chng 06 mar 17, comment out following block and replace with this
43  * removing dynamics heating & cooling and report only physical
44  * heating and cooling
45  * NB the heating and cooling as punched no longer need be
46  * equal for a converged model */
47  cool_total -= dynamics.Cool();
48  heat_total -= dynamics.Heat();
49 # if 0
50  if(dynamics.Cool > dynamics.Heat())
51  {
52  cool_total -= dynamics.Heat();
53  heat_total -= dynamics.Heat();
54  }
55  else
56  {
57  cool_total -= dynamics.Cool;
58  heat_total -= dynamics.Cool;
59  }
60 # endif
61 
62  /* cset will be weakest cooling to consider
63  * WeakHeatCool set with 'set weakheatcool' command
64  * default is 0.05 */
65  cset = cool_total*save.WeakHeatCool;
66 
67  /* first find all strong lines, both + and - sign */
68  ip = thermal.ncltot;
69 
70  for( i=0; i < ip; i++ )
71  {
72  csav[i] = (realnum)( safe_div( MAX2(thermal.cooling[i],thermal.heatnt[i]), cool_total, 0. ));
73 
74  /* save sign to remember if heating or cooling line */
75  if( thermal.heatnt[i] == 0. )
76  {
77  sgnsav[i] = 1.;
78  }
79  else
80  {
81  sgnsav[i] = -1.;
82  }
83  }
84 
85  /* order strongest to weakest */
86  /* now sort by decreasing importance */
87  /*spsort netlib routine to sort array returning sorted indices */
88  spsort(
89  /* input array to be sorted */
90  &csav[0],
91  /* number of values in x */
92  ip,
93  /* permutation output array */
94  &index[0],
95  /* flag saying what to do - 1 sorts into increasing order, not changing
96  * the original routine */
97  -1,
98  /* error condition, should be 0 */
99  &nFail);
100 
101  /* warn if tcovergence failure occurred */
102  if( !conv.lgConvTemp )
103  {
104  fprintf( io, "#>>>> Temperature not converged.\n" );
105  }
106  else if( !conv.lgConvEden )
107  {
108  fprintf( io, "#>>>> Electron density not converged.\n" );
109  }
110  else if( !conv.lgConvIoniz() )
111  {
112  fprintf( io, "#>>>> Ionization not converged.\n" );
113  }
114  else if( !conv.lgConvPres )
115  {
116  fprintf( io, "#>>>> Pressure not converged.\n" );
117  }
118 
119  if( strcmp(chJob,"EACH") == 0 )
120  {
121  /* begin the print out with zone number, total heating and cooling */
122  fprintf( io, "%.5e\t%.4e\t%.4e",
124  phycon.te,
125  cool_total );
126  double debug_ctot = 0.;
127 
128  for( int i=0 ; i < LIMELM ; i++)
129  {
130  fprintf( io, "\t%.4e", thermal.elementcool[i]+thermal.heavycollcool[i]);
131  debug_ctot += (thermal.elementcool[i]+thermal.heavycollcool[i]);
132  }
133 
134  /* molecular cooling, except those who are listed separately */
135  fprintf( io, "\t%.4e", thermal.elementcool[LIMELM]);
136  debug_ctot += thermal.elementcool[LIMELM];
137 
138  /* dust */
139  fprintf( io, "\t%.4e", MAX2(0.,gv.GasCoolColl) );
140  debug_ctot += MAX2(0.,gv.GasCoolColl);
141 
142  /* H2cX - H2 molecule cooling*/
143  fprintf( io, "\t%.4e", MAX2(0.,-hmi.HeatH2Dexc_used) );
144  debug_ctot += MAX2(0.,-hmi.HeatH2Dexc_used);
145 
146  /* CT C - charge transfering cooling*/
147  fprintf( io, "\t%.4e", thermal.char_tran_cool );
148  debug_ctot += thermal.char_tran_cool;
149 
150  /* H-fb - H + e -> H- + h*niu*/
151  fprintf( io, "\t%.4e", hmi.hmicol );
152  debug_ctot += hmi.hmicol;
153 
154  /* H2ln - line cooling within simple H2 molecule (rotation) */
155  fprintf( io, "\t%.4e", CoolHeavy.h2line );
156  debug_ctot += CoolHeavy.h2line;
157 
158  /* HDro - HD cooling*/
159  fprintf( io, "\t%.4e", CoolHeavy.HD );
160  debug_ctot += CoolHeavy.HD;
161 
162  /* H2+ - H + H+ -> H2+ cooling*/
163  fprintf( io, "\t%.4e", CoolHeavy.H2PlsCool );
164  debug_ctot += CoolHeavy.H2PlsCool;
165 
166  /* FFcm, splite into FF_H and FF_M */
167  /*fprintf( io, "\t%.4e", MAX2(0.,CoolHeavy.brems_cool_net) );
168  debug_ctot += MAX2(0.,CoolHeavy.brems_cool_net); */
169 
170  /* Due to the calculation of bremsstrahlung heating, FF_H and FF_M result may not reliable when CoolHeavy.brems_cool_metals is not far more than bremsstrahlung heating */
171  if( CoolHeavy.brems_cool_net > 0. )
172  {
173  /* FF_H, free-free cooling from H and He */
176  /* FF_M, free-free cooling from metal */
179  }
180  else
181  {
182  double zero = 0.;
183  fprintf( io, "\t%.4e", zero );
184  fprintf( io, "\t%.4e", zero );
185  }
186 
187  /* NB - heavy element recombination cooling (hvFB, CoolHeavy.heavfb) has been splited into each element*/
188 
189  /* eeff - electron electron bremsstrahlung cooling */
190  fprintf( io, "\t%.4e", CoolHeavy.eebrm );
191  debug_ctot += CoolHeavy.eebrm;
192 
193  /* adve - dynamics cooling, do not add this to debug_ctot because cool_total does not contain this term */
194  fprintf( io, "\t%.4e", dynamics.Cool() );
195 
196  /* comp - Compton cooling*/
197  fprintf( io, "\t%.4e", CoolHeavy.tccool );
198  debug_ctot += CoolHeavy.tccool;
199 
200  /* Extr - extra cooling, set with CEXTRA command*/
201  fprintf( io, "\t%.4e", CoolHeavy.cextxx );
202  debug_ctot += CoolHeavy.cextxx;
203 
204  /* Expn - wind expansion cooling*/
205  fprintf( io, "\t%.4e", CoolHeavy.expans );
206  debug_ctot += CoolHeavy.expans;
207 
208  /* Cycl - cyclotron cooling*/
209  fprintf( io, "\t%.4e", CoolHeavy.cyntrn );
210  debug_ctot += CoolHeavy.cyntrn;
211 
212  /* Hvin - heavy element collisional ionization cooling (CoolHeavy.colmet), splited into each element */
213 
214  /* dima - report, but don't add Dima cooling;
215  * already included in elementcool through atom_level2() */
216  fprintf( io, "\t%.4e", thermal.dima );
217 
218  fprintf( io, " \n" );
219 
220  {
221  enum{ DEBUG_COOLING = false };
222  if( DEBUG_COOLING )
223  {
224  fprintf( ioQQQ, "DEBUG COOLING:\t"
225  "recomputed: %6e\t"
226  "should be: %.6e\t"
227  "fractional diff: %.4e\n",
228  debug_ctot,
229  cool_total,
230  debug_ctot / cool_total - 1. );
231  }
232  }
233 
234  /* check if all coolants are added together */
235  if( fabs( (debug_ctot - cool_total)/cool_total ) > 1e-10 )
236  {
237  fprintf( ioQQQ , "PROBLEM with the SAVE EACH COOLING output\n" );
238  fprintf( ioQQQ , "PROBLEM One or more coolants have been lost, the sum of the reported cooling is %.4e\n", debug_ctot );
239  fprintf( ioQQQ , "PROBLEM The total cooling is %.4e\n", cool_total );
240  fprintf( ioQQQ , "PROBLEM The difference is %.4e\n", cool_total - debug_ctot );
242  }
243  }
244  else if( strcmp(chJob,"COOL") == 0 )
245  {
246  /*>>chng 06 jun 06, change start of save to give same info as heating
247  * as per comment by Yumihiko Tsuzuki */
248  /* begin the print out with zone number, total heating and cooling */
249  fprintf( io, "%.5e\t%.4e\t%.4e\t%.4e",
251  phycon.te,
252  heat_total,
253  cool_total );
254 
255  /* print only up to IPRINT, which is defined above */
256  ip = MIN2( ip , IPRINT );
257 
258  /* now print the coolants
259  * keep sign of coolant, for strong negative cooling
260  * order is ion, wavelength, fraction of total */
261  for( is=0; is < ip; is++ )
262  {
263  if(is > 4 && (thermal.cooling[index[is]] < cset && thermal.heatnt[index[is]] < cset))
264  break;
265  fprintf( io, "\t%s %.1f\t%.7f",
266  thermal.chClntLab[index[is]],
267  thermal.collam[index[is]],
268  sign(csav[index[is]],sgnsav[index[is]]) );
269  }
270  fprintf( io, " \n" );
271  }
272  else
273  TotalInsanity();
274 
275  return;
276 }
277 
bool lgConvEden
Definition: conv.h:197
double hmicol
Definition: hmi.h:33
double htot
Definition: thermal.h:169
t_thermal thermal
Definition: thermal.cpp:6
void CoolSave(FILE *io, const char chJob[])
Definition: cool_save.cpp:20
double Cool()
Definition: dynamics.cpp:2205
double heavycollcool[LIMELM]
Definition: thermal.h:115
NORETURN void TotalInsanity(void)
Definition: service.cpp:1067
double expans
Definition: coolheavy.h:18
double GasCoolColl
Definition: grainvar.h:546
bool lgConvPres
Definition: conv.h:194
t_conv conv
Definition: conv.cpp:5
T sign(T x, T y)
Definition: cddefines.h:846
double brems_cool_he
Definition: coolheavy.h:36
t_phycon phycon
Definition: phycon.cpp:6
double cooling[NCOLNT]
Definition: thermal.h:104
t_CoolHeavy CoolHeavy
Definition: coolheavy.cpp:5
double char_tran_cool
Definition: thermal.h:166
FILE * ioQQQ
Definition: cddefines.cpp:7
double HeatH2Dexc_used
Definition: hmi.h:140
bool lgConvIoniz() const
Definition: conv.h:108
void zero(void)
Definition: zero.cpp:43
t_dynamics dynamics
Definition: dynamics.cpp:42
double eebrm
Definition: coolheavy.h:18
#define MIN2(a, b)
Definition: cddefines.h:807
double tccool
Definition: coolheavy.h:18
double brems_cool_net
Definition: coolheavy.h:36
double Heat()
Definition: dynamics.cpp:2191
realnum H2PlsCool
Definition: coolheavy.h:47
realnum WeakHeatCool
Definition: save.h:470
char chClntLab[NCOLNT][NCOLNT_LAB_LEN+1]
Definition: thermal.h:108
double brems_cool_h
Definition: coolheavy.h:36
double cextxx
Definition: coolheavy.h:18
float realnum
Definition: cddefines.h:124
#define EXIT_FAILURE
Definition: cddefines.h:168
#define cdEXIT(FAIL)
Definition: cddefines.h:484
double brems_heat_total
Definition: coolheavy.h:36
double dima
Definition: thermal.h:118
sys_float safe_div(sys_float x, sys_float y, sys_float res_0by0)
Definition: cddefines.h:1015
double depth_mid_zone
Definition: radius.h:31
t_radius radius
Definition: radius.cpp:5
double brems_cool_hminus
Definition: coolheavy.h:36
double brems_cool_metals
Definition: coolheavy.h:36
long int ncltot
Definition: thermal.h:106
realnum collam[NCOLNT]
Definition: thermal.h:103
bool lgConvTemp
Definition: conv.h:191
const int LIMELM
Definition: cddefines.h:307
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:729
double elementcool[LIMELM+1]
Definition: thermal.h:111
#define MAX2(a, b)
Definition: cddefines.h:828
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1217
GrainVar gv
Definition: grainvar.cpp:5
t_hmi hmi
Definition: hmi.cpp:5
t_save save
Definition: save.cpp:5
double te
Definition: phycon.h:21
double h2line
Definition: coolheavy.h:18
double heatnt[NCOLNT]
Definition: thermal.h:104
double cyntrn
Definition: coolheavy.h:18
double HD
Definition: coolheavy.h:18
void spsort(realnum x[], long int n, long int iperm[], int kflag, int *ier)
Definition: service.cpp:1318
double ctot
Definition: thermal.h:130
static const int IPRINT
Definition: cool_save.cpp:17