HARM
harm and utilities
 All Data Structures Files Functions Variables Typedefs Macros Pages
sources.c
Go to the documentation of this file.
1 
8 #include "decs.h"
9 
10 
11 
14 int sourcephysics(FTYPE *pi, FTYPE *pr, FTYPE *pf, int *didreturnpf, int *eomtype, struct of_geom *ptrgeom, struct of_state *q, FTYPE *Ugeomfreei, FTYPE *Ugeomfreef, FTYPE *CUf, FTYPE *CUimp, FTYPE dissmeasure, FTYPE *dUother, FTYPE (*dUcomp)[NPR])
15 {
16  int coolfunc_thindisk(FTYPE h_over_r, FTYPE *pr, struct of_geom *ptrgeom, struct of_state *q,FTYPE (*dUcomp)[NPR]);
17  int coolfunc_neutrino(FTYPE *pr, struct of_geom *ptrgeom, struct of_state *q,FTYPE (*dUcomp)[NPR]);
18  int coolfunc_rebecca_thindisk(FTYPE h_over_r, FTYPE *pr, struct of_geom *geom, struct of_state *q,FTYPE (*dUcomp)[NPR]);
19  extern int koral_source_rad(int whichsourcemethod, FTYPE *pi, FTYPE *pr, FTYPE *pf, int *didreturnpf, int *eomtype, FTYPE *Ui, FTYPE *Uf, FTYPE *CUf, FTYPE *CUimp, struct of_geom *geom, struct of_state *q, FTYPE dissmeasure, FTYPE *dUother, FTYPE (*dUcomp)[NPR]);
20 
21  //default
22  *didreturnpf=0;
23 
24 
25  // SCLOOP(sc) PLOOP(pliter,k) dUcomptmp[sc][k] = 0.; // use when duplicating source type (sc) in dUcomp[sc][k]
26  // currently all are unique so can overlap
27 
28  // cooling function returns energy density per unit time in coordinate frame, typically computed in comoving frame inside the cooling function
30  return(coolfunc_thindisk(h_over_r, pr, ptrgeom, q,dUcomp));
31  }
32  else if(cooling==COOLEOSGENERAL){
33  // return(coolfunc_neutrino(pr, ptrgeom, q,dUcomp));
34  // more general use of EOS version of sources
35  return(compute_sources_EOS(WHICHEOS,GLOBALMAC(EOSextraglobal,ptrgeom->i,ptrgeom->j,ptrgeom->k),pr, ptrgeom, q, Ugeomfreei, dUother, dUcomp));
36  }
37  else if(cooling==COOLREBECCATHINDISK){
38  return(coolfunc_rebecca_thindisk(h_over_r, pr, ptrgeom, q,dUcomp));
39  }
40  else if(cooling==COOLUSER){
41  // cooling function defined by user
42  return(coolfunc_user(h_over_r, pr, ptrgeom, q,dUcomp));
43  }
44  else if(cooling==NOCOOLING){
45  // cooling turned off.
46  }
47  else if(cooling==KORAL){
48  return(koral_source_rad(WHICHRADSOURCEMETHOD, pi, pr, pf, didreturnpf, eomtype, Ugeomfreei, Ugeomfreef, CUf, CUimp, ptrgeom, q, dissmeasure, dUother, dUcomp));
49  }
50  else{
51  dualfprintf(fail_file,"cooling=%d does not exist in sourcephysics()\n",cooling);
52  myexit(763252772);
53  }
54 
55  // random physics
56  //misc_source(ph, geom, &q, dU, Dt) ;
57 
58  return(0);
59 }
60 
61 
62 
63 
64 
65 
66 
67 /* JON: here's the cooling function, w/ two parameters */
68 
69 #define THETACOOL (h_over_r) /* should be same as h_over_r */
70 #define TAUCOOL (1.0) /* cooling time in number of rotational times : really TAUCOOL=2*M_PI would be 1 rotational time */
71 #define NOCOOLTHETAFACT (3.0) /* this times h_over_r and no more cooling there*/
72 #define COOLTAPER1(th) (exp(-pow((th)-M_PI*0.5,2.0)/(2.0*pow(nocoolthetafactor*h_over_r,2.0))))
73 #define SLOPE2 (1.0/(M_PI*0.5-nocoolthetafactor*h_over_r))
74 #define COOLTAPER2(th) (((th)<M_PI*0.5-nocoolthetafactor*h_over_r) ? (SLOPE2*(th)) : ( ((th)>M_PI*0.5+nocoolthetafactor*h_over_r) ? (-SLOPE2*((th)-M_PI)) : 1.0 ) )
75 #define SLOPE3 (1.0/(nocoolthetafactor*h_over_r))
76 #define WIDTHTAPER (nocoolthetafactor*h_over_r)
77 #define TAPERPOS1 (M_PI*0.5-nocoolthetafactor*h_over_r-WIDTHTAPER)
78 #define TAPERPOS2 (M_PI*0.5-nocoolthetafactor*h_over_r)
79 #define TAPERPOS3 (M_PI*0.5+nocoolthetafactor*h_over_r)
80 #define TAPERPOS4 (M_PI*0.5+nocoolthetafactor*h_over_r+WIDTHTAPER)
81 #define TAPERFUN1(th) (0.0)
82 #define TAPERFUN2(th) (SLOPE3*((th)-TAPERPOS1))
83 #define TAPERFUN3(th) (1.0)
84 #define TAPERFUN4(th) (-SLOPE3*((th)-TAPERPOS4))
85 #define TAPERFUN5(th) (0.0)
86 #define COOLTAPER3(th) (((th)<TAPERPOS1 ? TAPERFUN1(th) : ( ((th)<TAPERPOS2) ? TAPERFUN2(th) : ( ((th)<TAPERPOS3) ? TAPERFUN3(th): ( ((th)<TAPERPOS4) ? TAPERFUN4(th) : TAPERFUN5(th) )))) )
87 /* cooling function, if any */
88 
89 
90 int coolfunc_thindisk(FTYPE h_over_r, FTYPE *pr, struct of_geom *geom, struct of_state *q,FTYPE (*dUcomp)[NPR])
91 {
92  FTYPE X[NDIM],V[NDIM],r,th,R,Wcirc,cs_circ,rho,u,P,w,wcirc,dUcool;
93  FTYPE taper0;
94  int ii,jj, kk,pp;
95  int j;
96  FTYPE pressure;
97  FTYPE rincool;
98  FTYPE nocoolthetafactor,thetacool,taucool;
99 
100 
101  // setup for macros
102  nocoolthetafactor=NOCOOLTHETAFACT;
103  thetacool=THETACOOL;
104  taucool=TAUCOOL;
105 
106  ii=geom->i;
107  jj=geom->j;
108  kk=geom->k;
109  pp=geom->p;
110 
111  /* cooling function for maintaining fixed H/R */
112  rho = pr[RHO] ;
113  u = pr[UU] ;
114  P=pressure_rho0_u_simple(ii,jj,kk,pp,rho,u);
115  w = rho + u + P ;
116 
117  bl_coord_ijk_2(ii,jj,kk,pp,X, V) ;
118 
119  r=V[1];
120  th=V[2];
121  R = r*sin(th) ;
122 
123 
124  rincool = (1. + h_over_r)*Risco;
125 
126  /* crude approximation */
127  Wcirc = pow(R,-1.5) ;
128  cs_circ = thetacool/sqrt(R) ;
129  // wcirc = rho*(1. + cs_circ*cs_circ/(gam - 1.)) ;
130  wcirc = rho*(1. + cs_circ*cs_circ) ;
131 
132  DLOOPA(j){
133  if(t > 0.){
134  // below assumes taucool in lab-frame
135  dUcool = -(Wcirc/taucool)*( (w - wcirc)*(q->ucon[TT])*(q->ucov[j])) ;
136  // shape function to avoid problems near pole
137  //taper0=COOLTAPER(0);
138  //dUcool*=1./(1.-1./taper0)+1./(1.-taper0)*COOLTAPER(th);
139  //dUcool*=COOLTAPER2(th);
140  dUcool*=COOLTAPER3(th);
141  // below maybe approximates photon capture effects near horizon
142  dUcool*=taper_func(R,Rhor); // don't cool inside horizon
143  // dUcool = (R>Rhor) ? dUcool : 0.0; // hard cut to not cool inside horizon
144  }
145  else{
146  dUcool = 0. ;
147  }
148 
149  dUcomp[RADSOURCE][j+1]=dUcool; // j+1 because j=0 is RHO since dUcomp in PLOOP form, not DLOOPA form
150  }
151 
152  return(0) ;
153 }
154 
155 
156 
157 
158 
159 
160 
161 
162 
163 #define REBECCATHETACOOL (h_over_r) /* should be same as h_over_r */
164 #define REBECCATAUCOOL (2.0*M_PI) /* cooling time in number of rotational times : really REBECCATAUCOOL=2*M_PI would be 1 rotational time */
165 #define REBECCANOCOOLTHETAFACT (1.0) /* this times h_over_r and no more cooling there*/
166 
167 
169 int coolfunc_rebecca_thindisk(FTYPE h_over_r, FTYPE *pr, struct of_geom *geom, struct of_state *q,FTYPE (*dUcomp)[NPR])
170 {
171  FTYPE X[NDIM],V[NDIM],r,th,R,Wcirc,cs_circ,rho,u,P,w,wcirc,dUcool;
172  FTYPE taper0;
173  int ii,jj, kk, pp;
174  FTYPE pressure;
175  FTYPE enk, enk0;
176 
177  FTYPE rpho;
178  FTYPE photoncapture;
179  FTYPE rincool;
180  FTYPE nocoolthetafactor,thetacool,taucool;
181 
182 
183 
184  // setup for macros
185  nocoolthetafactor=REBECCANOCOOLTHETAFACT;
186  thetacool=REBECCATHETACOOL;
187  taucool=REBECCATAUCOOL;
188 
189  ii=geom->i;
190  jj=geom->j;
191  kk=geom->k;
192  pp=geom->p;
193 
194  /* cooling function for maintaining fixed H/R */
195  rho = pr[RHO] ;
196  u = pr[UU] ;
197  P=pressure_rho0_u_simple(ii,jj,kk,pp,rho,u);
198  w = rho + u + P ;
199 
200  bl_coord_ijk_2(ii,jj,kk,CENT,X, V) ;
201  r=V[1];
202  th=V[2];
203 
204  rpho=2.0*(1.0+cos(2.0/3.0*(acos(-a))));
205 
206  // trifprintf("rphoton=%lf\n", rpho);
207  if(1 || r>rpho){ //SASMARK: cool always, including inside photon orbit
208  photoncapture=1.0 ;
209  // trifprintf("r=%lf, photoncapture=%lf, rph=%lf \ n", r, photoncapture, rpho);
210  }
211  else{
212  photoncapture=0.0 ;
213  }
214 
215 
216  R = r*sin(th) ;
217  enk=u*(gam-1.)/(pow(rho, gam));
218  //enk0 = 1.e-3; //same as kappa in init.fishmon.c -- somehow wrong, is it because of wrong gam?!
219  enk0 = 0.0043; //as read from ic's for thick torus
220  //enk0=0.00016; //Rebecca's version
221  // enk0=0.00161;
222  // rin = (1. + h_over_r)*Risco;
223  rincool=10.;
224  /* crude approximation */
225  Wcirc = 1./(a + pow(R,1.5)) ;
226  cs_circ = thetacool/sqrt(R) ;
227  // wcirc = rho*(1. + cs_circ*cs_circ/(gam - 1.)) ;
228 
229  wcirc = rho*(1. + cs_circ*cs_circ/(gam - 1.)) ;
230 
231 
232 
233  // trifprintf("photoncapture=%lf, r=%lf, rpho=%lf \n", photoncapture, r, rpho);
234 
235  // if(t > 0.){
236  // dUcool = -(Wcirc/taucool)*( (w - wcirc)*(q->ucon[TT])) ;
237  // if(t > 0.){
238 
239 
240  if(t > 0. && dt < taucool/Wcirc && log(enk/enk0) > 0.) {
241 
242  // dUcool = -(Wcirc/taucool)*( (w - wcirc)*(q->ucon[TT])*(q->ucov[TT])) ;
243 
244 
245 
246 
247  // dUcool=-u*(Wcirc/taucool)*log(enk/enk0)*(q->ucon[TT])*photoncapture;
248 
249 
250 
251  dUcool=-u*(Wcirc/taucool)*log(enk/enk0)*photoncapture;
252 
253  // dUcool*=COOLTAPER1(th);
254  // dUcool*=taper_func(R,Rhor);
255 
256  // shape function to avoid problems near pole
257  //taper0=COOLTAPER(0);
258  //dUcool*=1./(1.-1./taper0)+1./(1.-taper0)*COOLTAPER(th);
259  //dUcool*=COOLTAPER2(th);
260  // dUcool*=COOLTAPER3(th);
261  // dUcool*=taper_func(R,Rhor); // don't cool inside horizon
262  }
263  else{
264  dUcool = 0. ;
265  // dUcool = (-u*log(enk/enk0)/dt)*(q->ucon[TT]) ;
266 
267  }
268 
269  // dUcomp[RADSOURCE][UU]=dUcool;
270 
271 
272  dUcomp[RADSOURCE][UU]=dUcool*(q->ucov[TT]);
273  dUcomp[RADSOURCE][U1]=dUcool*(q->ucov[RR]);
274  dUcomp[RADSOURCE][U2]=dUcool*(q->ucov[TH]);
275  dUcomp[RADSOURCE][U3]=dUcool*(q->ucov[PH]);
276 
277  // trifprintf("ducomps are %g %g %g %g \n", dUcomp[RADSOURCE][UU], dUcomp[RADSOURCE][U1], dUcomp[RADSOURCE][U2], dUcomp[RADSOURCE][U3]);
278  return(0) ;
279 }
280 
281 
282 
283 
284 
285 
286 
287 
288 
290 int coolfunc_neutrino_old(FTYPE *pr, struct of_geom *geom, struct of_state *q,FTYPE (*dUcomp)[NPR])
291 {
292  FTYPE X[NDIM],V[NDIM],r,th,R,w,rho,u,P,dUcool ;
293  FTYPE rhocode,ucode,Pcode,Rcode,Tcode;
294  int ii,jj,kk,pp;
295  int j;
296  FTYPE swsq,cv,ca,cvp,cap,mue,nf,ca2,cv2,cvp2,cap2;
297  FTYPE Tk,Tmev,lambda,xi,lambdap5,lambda2,lambda3,lambda4,lambda6,lambda8,lambda9;
298  FTYPE xi2,xi3,Tk2,lgTk,lgden;
299  FTYPE a0,a1,a2,b1,b2,b3,c1;
300  FTYPE phys2code;
301  FTYPE glambda,fpair,qpair,Qpair,Qpaircode;
302  FTYPE pgam2,pgam,pgamp5,pgam3o2,pgam7o2,pgam6;
303  FTYPE ft,fl,xp,yp,minfun,minf,fxy2,fxy,Qv,Qplasma,Qplasmacode;
304  FTYPE xnucode,Qecap,etae,Qecapcode,Qbrem,Qbremcode;
305  FTYPE Ev,Tv,Tvp,Kt,HOR,ntau,EXT;
306  FTYPE Qntot,cofactor;
307  FTYPE Tfeok,height,zhere,ztogo;
308 
309 
310 
311  ii=geom->i;
312  jj=geom->j;
313  kk=geom->k;
314  pp=geom->p;
315 
316  rhocode = pr[RHO];
317  ucode = pr[UU];
318  Pcode=pressure_rho0_u_simple(ii,jj,kk,pp,rhocode,ucode);
319  Tcode=Pcode/rhocode;
320 
321  bl_coord_ijk_2(ii,jj,kk,pp,X, V) ;
322 
323  r=V[1];
324  th=V[2];
325  Rcode = r*sin(th) ;
326 
327 
328  // for all processes Itoh 1989/1996
329  swsq=0.2319;
330  cv=0.5+2.*swsq;
331  ca=0.5;
332  cvp=1.0-cv;
333  cap=1.0-ca;
334  mue=2.0; // like most normal matter, including n+p+e
335  nf=2.0; // flavors conditioned
336 
337 
338  // go ahead and scale primitives used below
339  R=Rcode*Lunit;
340  rho=rhocode*rhounit;
341  u=ucode*rhounit;
342  P=Pcode*Pressureunit;
343  Tk=Tcode*Tempunit;
344  Tmev=kb*Tk/ergPmev;
345  // from Itoh 1983 or Itoh 2002
346  Tfeok=5.9302E9*(pow(1.+1.018*pow(rho/1E6/mue,2./3.),0.5)-1.0)/Tk; // degen e, then Tfeok >>1
347 
348  // should solve for electron chemical potential from Kuhri & Mineshige 2002 in deg, ultrarel. e- case.
349 
350  // now should all be dimensional cgs units except for final code result output for each cooling process
351 
352 
353  ca2=ca*ca;
354  cv2=cv*cv;
355  cvp2=cvp*cvp;
356  cap2=cap*cap;
357 
358 
359  lambda=Tk/(5.9302E9);
360  xi=pow(rho*rhounit/mue/1E9,1.0/3.0)/lambda;
361 
362  lambdap5=sqrt(lambda);
363  lambda2=lambda*lambda;
364  lambda3=lambda2*lambda;
365  lambda4=lambda2*lambda2;
366  lambda6=lambda2*lambda4;
367  lambda8=lambda4*lambda4;
368  lambda9=lambda8*lambda;
369 
370  xi2=xi*xi;
371  xi3=xi2*xi;
372 
373  Tk2=Tk*Tk;
374  lgTk=log10(Tk);
375  lgden=log10(2.0*rho/mue);
376 
377  phys2code=1.0/(edotunit/pow(Lunit,3.0));
378 
379  if(Tfeok<1.0){ // then not e. degen and pair process important ala Korhi
380 
381  // for pair capture on neutrons
382  a0=6.002E19;
383  a1=2.084E20;
384  a2=1.872E21;
385  b1=(Tk<1E10) ? 9.383E-1 : 1.2383;
386  b2=(Tk<1E10) ? -4.141E-1 : -0.8141;
387  b3=(Tk<1E10) ? 5.829E-2 : 0.0;
388  c1=(Tk<1E10) ? 5.5924 : 4.9924;
389 
390 
391 
392  glambda=1.0-13.04*lambda2+133.5*lambda4+1534.0*lambda6+918.6*lambda8;
393  fpair=(a0+a1*xi+a2*xi2)*exp(-c1*xi)/(xi3+b1/lambda+b2/lambda2+b3/lambda3);
394  qpair=pow(10.7480*lambda2+0.3967*lambdap5+1.0050,(-1.00))*pow(1.0+(rho*rhounit/mue)*pow(7.692E7*lambda3+9.715E6*lambdap5,(-1.0)),(-0.3));
395  Qpair=0.5*((cv2+ca2)+nf*(cvp2+cap2))*(1.0+((cv2-ca2)+nf*(cvp2+cap2))*qpair/((cv2+ca2)+nf*(cvp2+cap2)))*glambda*exp(-2.0/lambda)*fpair;
396  Qpaircode=Qpair*phys2code;
397  // qpairtot=-SUM(gdet*dV*Qpaircode*ud0*uu0)*edotunit;
398  }
399  else Qpaircode=0;
400 
401  if(Tfeok>1.0){ // then e. degen and plasma process important and formula applicable ala Korhi,Itoh
402 
403  // for plasma process, valid only in high electron degeneracy limit
404  pgam2=1.1095E11*rho/mue/(Tk2*pow(1+pow(1.019E-6*rho/mue,(2./3.)),(1./2.)));
405  pgam=sqrt(pgam2);
406  pgamp5=sqrt(pgam);
407  pgam3o2=pow(pgamp5,3.0);
408  pgam7o2=pow(pgamp5,7.0);
409  pgam6=pgam2*pgam2*pgam2;
410 
411  ft=2.4+0.6*pgamp5+0.51*pgam+1.25*pgam3o2;
412  fl=(8.6*pgam2+1.35*pgam7o2)/(225.-17.*pgam+pgam2);
413  xp=1./6.*(+17.5+lgden-3.*lgTk);
414  yp=1./6.*(-24.5+lgden+3.*lgTk);
415  minfun=yp-1.6+1.25*xp;
416  minf=(minfun>0.0) ? 0.0 : minfun;
417  fxy2=1.05+(0.39-1.25*xp-0.35*sin(4.5*xp)-0.3*exp(-pow(4.5*xp+0.9,2.0)))*exp(-pow(minf/(0.57-0.25*xp),2.0));
418  fxy=(fabs(xp)>0.7 || yp<0) ? 1.0 : fxy2;
419  Qv=3.00E21*lambda9*pgam6*exp(-pgam)*(ft+fl)*fxy;
420  Qplasma=(cv2+nf*cvp2)*Qv;
421  Qplasmacode=Qplasma*phys2code;
422  //qplasmatot=-SUM(gdet*dV*Qplasmacode*ud0*uu0)*edotunit;
423  }
424  else Qplasmacode=0;
425 
427  // electron capture
428 
429  // fraction of free nucleons
430  // xnucode=26.0*pow(Tk*kb/ergPmev,9.0/8.0)/pow(rho*rhounit/1.E10,3.0/4.0)*exp(-7.074/(Tk*kb/ergPmev));
431  xnucode=30.97*pow(Tk/1E10,9.0/8.0)*pow(rho*rhounit/1.E10,-3.0/4.0)*exp(-6.096/(Tk/1E10));
432  if(xnucode>1.0) xnucode=1.0;
433 
434  if(Tfeok<1.0){ // then not e. degen and e cap process important and formula applicable ala Korhi,Itoh,PWF99
435  Qecap=9.2E33*(rho/1E10)*pow(Tk/1E11,6.0); // PWF99 or Kohri
436  }
437  else{ // then otherwise use Korhi's eq46
438  etae=Tfeok; // this is WRONG, made up, but best guess
439  Qecap=1.1E31*pow(etae*Tk/1E11,9.0);
440  }
441  Qecapcode=Qecap*xnucode*phys2code; // final code answer
442 
444  // n-n scattering
445  if(Tfeok>1.0){ // degen
446  Qbrem=3.4E33*pow(Tk/1E11,8.0)*pow(rho/1E13,1.0/3.0);
447  }
448  else Qbrem=1.5E33*pow(Tk/1E11,5.5)*pow(rho/1E13,2.0); // non degen
449  Qbremcode=Qbrem*phys2code; // final code answer
450 
452  // consider optical depth
453 
454  // my estimate from Fryer & Meszaros 2003
455  /*
456  Ev=44.0*pow(rho/1E12/mue,1.0/3.0)*ergPmev;
457  Tv=Ev/(21.0*kb);
458  Tvp=Tv*kb/ergPmev;
459  Kt=1.5E-17*(rho)*pow(Tvp*0.25,2.0);
460  HOR=0.26;
461  ntau=Kt*HOR*R;
462  */
463 
464  // from Di Matteo, Perna, Narayan 2002
465  // simplified, should use full form, as like also in Popham & Narayan 1995
466  // should use HOR calculator rather than fixed value, but per radius!! and limited to disk, not plunging region
467  // consider flavor counting? not sure what to do there
468  HOR=0.26;
469  zhere=fabs(R*cos(th));
470  ztogo=HOR*fabs(R);
471  height=fabs(ztogo-zhere);
472  ntau=2.5E-7*pow(Tk/1E11,5.0)*height;
473  ntau+=(4.5E-7*xnucode+2.7E-7)*pow(Tk/1E11,2.0)*(rho/1E10)*height;
474  // extinction of neutrinos (should add pressure due to neutrinos, but small anyways)
475  EXT=exp(-ntau);
476 
477  // should perhaps use emission from surface of neutrinosphere ala eq15 of Di Matteo, Perna, Narayan 2002. nah...just let EXT handle that.
478 
479  // include cooling due to photodisintegration, which should then be included in the pressure/internal energy
480  // dXdr is radial derivative of Xnuc, must be determined numerically, say using the same method to interpolate, then just use dq/dr. Might avoid numerical problems in dXdr
481  //qphoto=1E29*pow(rho/1E10)*(q->ucon[RR])/(q->ucon[TT])*dXdr;
482 
483 
485  // comoving cooling factor
486 
487  // cofactor=-(q->ucon[TT])*(q->ucov[TT]) ;
488 
489  DLOOPA(j){
490  if(t > 0.){
491  // provide energy density per second cooled
492  // multiplying by -uu0*ud0 gives the conserved energy at infinity
493  // no, source term has: \detg dU/d\tau u_\mu
494  cofactor=-(q->ucov[j]) ;
495  // dUcomp[NEUTRINOANN][j]=Qpaircode*cofactor*EXT;
496  // dUcomp[NEUTRINOPLASMA][j]=Qplasmacode*cofactor*EXT;
497  // dUcomp[NEUTRINOECAP][j]=Qecapcode*cofactor*EXT;
498  // dUcomp[NEUTRINOBREM][j]=Qbremcode*cofactor*EXT;
499  }
500  else{
501  // dUcomp[NEUTRINOANN][UU]=0;
502  // dUcomp[NEUTRINOPLASMA][UU]=0;
503  // dUcomp[NEUTRINOECAP][UU]=0;
504  // dUcomp[NEUTRINOBREM][UU]=0;
505  }
506  }
507  // rho>~ 10^(11) g/cm^3, optically thick to neutrinos
508 
509  // consider limiting dt based upon cooling time scale, or at
510  // least to limit changes in internal energy to less than few
511  // percent per time step (MW99 265, 2nd to last paragraph)
512  // Woosley&Baron 1992: neutrino energy of 15MeV.
513  // assumed isotropic emission in comoving frame, so no momentum change
514  // mass-energy (rho) is lost?
515 
516 
517  // consider mass and momentum losses?!
518  // see M99 page266, just before section 4.
519 
520  // add pair annihilation? MW265 last paragraph
521 
522  // why is MW99's and Korhi's approximations so bad?
523  // MW99 off by factors of 2-3X for Xnuc=1.
524 
525  // what is the effect of Xnuc in MW99?
526 
527  // What about Woosley&Baron1992
528  // affect on internal energy
529  // 1) added energy by v capture on nucleons (eq4) in optically thin limit outside the neutrinosphere (0 inside)
530  // 2) added by electron scatter of neutrinos (eq7)
531  // 3) added by v v* annihilation
532 
533 
534  return(0) ;
535 }
536 
537 
538 
539 
540 int coolfunc_neutrino(FTYPE *pr, struct of_geom *geom, struct of_state *q,FTYPE (*dUcomp)[NPR])
541 {
542  int ii,jj,kk,pp;
543  int j;
544  FTYPE X[NDIM],V[NDIM],r,th,R;
545  FTYPE rho,u;
546  FTYPE cofactor;
547  FTYPE dUdtau;
548  FTYPE rph,photoncapture;
549 
550 
551 
552  ii=geom->i;
553  jj=geom->j;
554  kk=geom->k;
555  pp=geom->p;
556 
557  bl_coord_ijk_2(ii,jj,kk,pp,X, V) ;
558 
559  r=V[1];
560  th=V[2];
561  R = r*sin(th) ;
562  rho = pr[RHO];
563  u = pr[UU];
564 
565  // approximately account for photon capture by black hole
566  // 50% of masslesss particles from **stationary** isotropic emitters are captured by black hole
567  // See Shapiro & Teukolsky (1983) and equation 2.81 and 2.82 in Shibata, Sekiguchi, Takahashi (2007)
568  // Note that if MBH=0 then rph=0, so works for NS
569  rph = 2.0*MBH*(1.0 + cos(2.0/3.0*(acos(-a/MBH))));
570  photoncapture = (r>rph) ? 1.0 : 0.0;
571 
572  // volume rate from EOS
573  dUdtau = compute_qdot_simple(ii,jj,kk,pp,rho,u);
574 
575 
576  DLOOPA(j){
577  // provide energy density per second cooled
578  // source term has: \detg dU/d\tau u_\mu
579  // (*dUcomp)[j+1] because j=0 implies UU as required (i.e. dUcomp in NPR form, not NDIM form)
580  if(t > 0.){
581  cofactor=(q->ucov[j]) ;
582  dUcomp[RADSOURCE][j+1]=-dUdtau*cofactor;
583  dUcomp[RADSOURCE2][j+1]=-dUdtau*cofactor*photoncapture;
584  }
585  else{
586  dUcomp[RADSOURCE][j+1]=0;
587  dUcomp[RADSOURCE2][j+1]=0.0;
588  }
589  }
590  // why is MW99's and Korhi's approximations so bad?
591  // MW99 off by factors of 2-3X for Xnuc=1.
592 
593 
594 
595  return(0) ;
596 }
597 
598 
599 
600 
601 #define TRELAX 0.05
602 
603 void misc_source(FTYPE *pr, struct of_geom *geom,
604  struct of_state *q, FTYPE *dU, FTYPE Dt)
605 {
606  FTYPE X[NDIM],V[NDIM],r,th ;
607  FTYPE rhoscal,uuscal ;
608  FTYPE drhodt,dudt,W,isqr,ir ;
609  FTYPE ucon_norm[NDIM],ucov_norm[NDIM],alpha ;
610  int ii,jj,kk,pp,j ;
611  FTYPE dpdrho0,dpdu;
612 
613 
614  ii=geom->i;
615  jj=geom->j;
616  kk=geom->k;
617  pp=geom->p;
618 
619  bl_coord_ijk_2(ii,jj,kk,pp,X, V) ;
620 
621  r=V[1];
622  th=V[2];
623 
624  ir = 1./r ;
625  isqr = 1./sqrt(r) ;
626  rhoscal = ir*isqr ;
627  uuscal = rhoscal*ir ;
628 
629  /* set up normal observer four-velocities, if needed */
630  if(pr[RHO] < RHOMIN*rhoscal || pr[UU] < UUMIN*uuscal) {
631  alpha = 1./sqrt(-geom->gcon[GIND(0,0)]) ;
632  ucon_norm[TT] = 1./alpha ;
633  SLOOPA(j) ucon_norm[j] = geom->gcon[GIND(0,j)]*alpha ;
634  ucov_norm[TT] = -alpha ;
635  SLOOPA(j) ucov_norm[j] = 0. ;
636  }
637 
638  if(pr[RHO] < RHOMIN*rhoscal) {
639  drhodt = -0.05*(pr[RHO] - RHOMIN*rhoscal)/dt ;
640 
641  dpdrho0 = dpdrho0_rho0_u_simple(ii,jj,kk,pp,pr[RHO],pr[UU]);
642 
643  dU[RHO] += (ucon_norm[TT]) *drhodt ;
644  dU[UU] += (((1.0+dpdrho0)*ucon_norm[TT]*ucov_norm[TT]) + dpdrho0) *drhodt ;
645  dU[U1] += ((1.0+dpdrho0)*ucon_norm[TT]*ucov_norm[1] ) *drhodt ;
646  dU[U2] += ((1.0+dpdrho0)*ucon_norm[TT]*ucov_norm[2] ) *drhodt ;
647  dU[U3] += ((1.0+dpdrho0)*ucon_norm[TT]*ucov_norm[3] ) *drhodt ;
648  }
649 
650  if(pr[UU] < UUMIN*uuscal) {
651  dudt = -0.05*(pr[UU] - UUMIN*uuscal)/dt ;
652 
653  dpdu = dpdu_rho0_u_simple(ii,jj,kk,pp,pr[RHO],pr[UU]);
654 
655  dU[UU] += ((1.0+dpdu)*ucon_norm[TT]*ucov_norm[TT] + dpdu) * dudt ;
656  dU[U1] += ((1.0+dpdu)*ucon_norm[TT]*ucov_norm[1]) * dudt ;
657  dU[U2] += ((1.0+dpdu)*ucon_norm[TT]*ucov_norm[2]) * dudt ;
658  dU[U3] += ((1.0+dpdu)*ucon_norm[TT]*ucov_norm[3]) * dudt ;
659  }
660 }