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