18 double precision,
private :: He_abundance
21 double precision,
private :: rc_gamma
24 double precision,
private :: rc_gamma_1
27 double precision,
private :: invgam
32 integer,
intent(in) :: ixI^L, ixO^L
33 double precision,
intent(in) :: w(ixI^S,nw)
34 double precision,
intent(in) :: x(ixI^S,1:ndim)
35 double precision,
intent(out):: res(ixI^S)
41 double precision :: rad_cut_hgt
42 double precision :: rad_cut_dey
45 double precision,
allocatable :: tcool(:), lcool(:), dldtcool(:)
46 double precision,
allocatable :: yc(:)
47 double precision :: tref, lref, tcoolmin,tcoolmax
48 double precision :: lgtcoolmin, lgtcoolmax, lgstep
52 double precision,
allocatable :: y_ppl(:), t_ppl(:), l_ppl(:), a_ppl(:)
55 double precision :: tlow
74 logical :: isppl = .false.
79 logical :: has_equi = .false.
81 logical :: subtract_equi = .false.
84 character(len=std_len) :: coolcurve
86 procedure(
get_subr1),
pointer,
nopass :: get_rho => null()
87 procedure(
get_subr1),
pointer,
nopass :: get_rho_equi => null()
88 procedure(
get_subr1),
pointer,
nopass :: get_pthermal => null()
89 procedure(
get_subr1),
pointer,
nopass :: get_pthermal_equi => null()
90 procedure(
get_subr1),
pointer,
nopass :: get_var_rfactor => null()
91 procedure(
get_subr1),
pointer,
nopass :: get_temperature_equi => null()
100 double precision,
intent(in) :: phys_gamma,He_abund
103 he_abundance=he_abund
109 subroutine read_params(fl)
114 end subroutine read_params
119 double precision,
dimension(:),
allocatable :: t_table
120 double precision,
dimension(:),
allocatable :: L_table
121 double precision :: ratt, fact1, fact2, fact3, dL1, dL2
122 double precision :: tstep, Lstep
123 integer :: ntable, i, j
125 Character(len=65) :: PPL_curves(1:6)
128 fl%coolcurve=
'JCcorona'
134 fl%rad_cut_dey=0.15d0
137 if(fl%rc_split) any_source_split=.true.
140 ppl_curves = [
Character(len=65) ::
'Hildner',
'FM',
'Rosner',
'Klimchuk',
'SPEX_DM_rough',
'SPEX_DM_fine']
141 do i=1,
size(ppl_curves)
142 if (ppl_curves(i)==fl%coolcurve)
then
150 select case(fl%coolcurve)
154 print *,
'Use Hildner (1974) piecewise power law'
156 allocate(fl%t_PPL(1:fl%n_PPL+1), fl%l_PPL(1:fl%n_PPL+1))
157 allocate(fl%a_PPL(1:fl%n_PPL))
160 fl%l_PPL(1:fl%n_PPL) = 10.d0**
x_hildner(1:
n_hildner) * (10.d0**fl%t_PPL(1:fl%n_PPL))**fl%a_PPL(1:fl%n_PPL)
164 print *,
'Use Forbes and Malherbe (1991)-like piecewise power law'
166 allocate(fl%t_PPL(1:fl%n_PPL+1), fl%l_PPL(1:fl%n_PPL+1))
167 allocate(fl%a_PPL(1:fl%n_PPL))
168 fl%t_PPL(1:fl%n_PPL+1) =
t_fm(1:
n_fm+1)
170 fl%l_PPL(1:fl%n_PPL) = 10.d0**
x_fm(1:
n_fm) * (10.d0**fl%t_PPL(1:fl%n_PPL))**fl%a_PPL(1:fl%n_PPL)
174 print *,
'Use piecewise power law according to Rosner (1978)'
176 print *,
'and extended by Priest (1982) from Van Der Linden (1991)'
178 allocate(fl%t_PPL(1:fl%n_PPL+1), fl%l_PPL(1:fl%n_PPL+1))
179 allocate(fl%a_PPL(1:fl%n_PPL))
182 fl%l_PPL(1:fl%n_PPL) = 10.d0**
x_rosner(1:
n_rosner) * (10.d0**fl%t_PPL(1:fl%n_PPL))**fl%a_PPL(1:fl%n_PPL)
186 print *,
'Use Klimchuk (2008) piecewise power law'
188 allocate(fl%t_PPL(1:fl%n_PPL+1), fl%l_PPL(1:fl%n_PPL+1))
189 allocate(fl%a_PPL(1:fl%n_PPL))
192 fl%l_PPL(1:fl%n_PPL) = 10.d0**
x_klimchuk(1:
n_klimchuk) * (10.d0**fl%t_PPL(1:fl%n_PPL))**fl%a_PPL(1:fl%n_PPL)
194 case(
'SPEX_DM_rough')
196 print *,
'Use the rough piece wise power law fit to the SPEX_DM curve (2009)'
198 allocate(fl%t_PPL(1:fl%n_PPL+1), fl%l_PPL(1:fl%n_PPL+1))
199 allocate(fl%a_PPL(1:fl%n_PPL))
206 print *,
'Use the fine, detailed piece wise power law fit to the SPEX_DM curve (2009)'
208 allocate(fl%t_PPL(1:fl%n_PPL+1), fl%l_PPL(1:fl%n_PPL+1))
209 allocate(fl%a_PPL(1:fl%n_PPL))
215 call mpistop(
"This piecewise power law is unknown")
219 fl%t_PPL(1:fl%n_PPL+1) = 10.d0**fl%t_PPL(1:fl%n_PPL+1)
221 if (si_unit) fl%l_PPL(1:fl%n_PPL) = fl%l_PPL(1:fl%n_PPL) * 10.0d0**(-13)
224 fl%t_PPL(1:fl%n_PPL+1) = fl%t_PPL(1:fl%n_PPL+1) / unit_temperature
225 fl%l_PPL(1:fl%n_PPL) = fl%l_PPL(1:fl%n_PPL) * unit_numberdensity**2 * unit_time / unit_pressure * (1.d0+2.d0*he_abundance)
228 fl%l_PPL(fl%n_PPL+1) = fl%l_PPL(fl%n_PPL) * ( fl%t_PPL(fl%n_PPL+1) / fl%t_PPL(fl%n_PPL) )**fl%a_PPL(fl%n_PPL)
229 fl%lref = fl%l_PPL(fl%n_PPL+1)
230 fl%tref = fl%t_PPL(fl%n_PPL+1)
233 fl%tcoolmin = fl%t_PPL(1)
234 fl%tcoolmax = fl%t_PPL(fl%n_PPL+1)
236 if (fl%tlow==bigdouble) fl%tlow=fl%tcoolmin
243 allocate(fl%tcool(1:fl%ncool), fl%Lcool(1:fl%ncool), fl%dLdtcool(1:fl%ncool))
244 allocate(fl%Yc(1:fl%ncool))
246 fl%tcool(1:fl%ncool) = zero
247 fl%Lcool(1:fl%ncool) = zero
248 fl%dLdtcool(1:fl%ncool) = zero
251 select case(fl%coolcurve)
255 print *,
'Use Colgan & Feldman (2008) cooling curve'
257 print *,
'This version only till 10000 K, beware for floor T treatment'
259 allocate(t_table(1:ntable))
260 allocate(l_table(1:ntable))
266 print *,
'Use Dalgarno & McCray (1972) cooling curve'
268 allocate(t_table(1:ntable))
269 allocate(l_table(1:ntable))
275 write(*,
'(3a)')
'Use MacDonald & Bailey (1981) cooling curve '&
276 ,
'as implemented in ZEUS-3D, with the values '&
277 ,
'from Dalgarno & McCRay (1972) for low temperatures.'
279 allocate(t_table(1:ntable))
280 allocate(l_table(1:ntable))
281 t_table(1:ntable) =
t_dm(1:21)
282 l_table(1:ntable) =
l_dm(1:21)
288 print *,
'Use Mellema & Lundqvist (2002) cooling curve '&
289 ,
'for zero metallicity '
291 allocate(t_table(1:ntable))
292 allocate(l_table(1:ntable))
298 print *,
'Use Mellema & Lundqvist (2002) cooling curve '&
299 ,
'for WC-star metallicity '
301 allocate(t_table(1:ntable))
302 allocate(l_table(1:ntable))
308 print *,
'Use Mellema & Lundqvist (2002) cooling curve '&
309 ,
'for solar metallicity '
311 allocate(t_table(1:ntable))
312 allocate(l_table(1:ntable))
318 print *,
'Use Cloudy based cooling curve '&
319 ,
'for ism metallicity '
321 allocate(t_table(1:ntable))
322 allocate(l_table(1:ntable))
328 print *,
'Use Cloudy based cooling curve '&
329 ,
'for solar metallicity '
331 allocate(t_table(1:ntable))
332 allocate(l_table(1:ntable))
338 print *,
'Use SPEX cooling curve (Schure et al. 2009) '&
339 ,
'for solar metallicity '
341 allocate(t_table(1:ntable))
342 allocate(l_table(1:ntable))
348 print *,
'Use SPEX cooling curve for solar metallicity above 10^4 K. '
349 print *,
'At lower temperatures,use Dalgarno & McCray (1972), '
350 print *,
'with a pre-set ionization fraction of 10^-3. '
351 print *,
'as described by Schure et al. (2009). '
354 allocate(t_table(1:ntable))
355 allocate(l_table(1:ntable))
363 print *,
'Use Dere (2009) cooling curve for solar corona'
365 allocate(t_table(1:ntable))
366 allocate(l_table(1:ntable))
370 case(
'Dere_corona_DM')
372 print *,
'Combination of Dere_corona (2009) for high temperatures and'
374 print *,
'Dalgarno & McCray (1972), DM2, for low temperatures'
376 allocate(t_table(1:ntable))
377 allocate(l_table(1:ntable))
385 print *,
'Use Dere (2009) cooling curve for solar photophere'
387 allocate(t_table(1:ntable))
388 allocate(l_table(1:ntable))
392 case(
'Dere_photo_DM')
394 print *,
'Combination of Dere_photo (2009) for high temperatures and'
396 print *,
'Dalgarno & McCray (1972), DM2, for low temperatures'
398 allocate(t_table(1:ntable))
399 allocate(l_table(1:ntable))
407 print *,
'Use Colgan (2008) cooling curve'
409 allocate(t_table(1:ntable))
410 allocate(l_table(1:ntable))
416 print *,
'Combination of Colgan (2008) for high temperatures and'
418 print *,
'Dalgarno & McCray (1972), DM2, for low temperatures'
420 allocate(t_table(1:ntable))
421 allocate(l_table(1:ntable))
428 call mpistop(
"This coolingcurve is unknown")
432 fl%tcoolmax = t_table(ntable)
433 fl%tcoolmin = t_table(1)
434 ratt = (fl%tcoolmax-fl%tcoolmin)/( dble(fl%ncool-1) + smalldouble)
436 fl%tcool(1) = fl%tcoolmin
437 fl%Lcool(1) = l_table(1)
439 fl%tcool(fl%ncool) = fl%tcoolmax
440 fl%Lcool(fl%ncool) = l_table(ntable)
443 fl%tcool(i) = fl%tcool(i-1)+ratt
447 if(fl%tcool(i) < t_table(j+1))
then
448 if(j.eq. ntable-1 )
then
449 fact1 = (fl%tcool(i)-t_table(j+1)) &
450 /(t_table(j)-t_table(j+1))
451 fact2 = (fl%tcool(i)-t_table(j)) &
452 /(t_table(j+1)-t_table(j))
453 fl%Lcool(i) = l_table(j)*fact1 + l_table(j+1)*fact2
456 dl1 = l_table(j+1)-l_table(j)
457 dl2 = l_table(j+2)-l_table(j+1)
458 jump =(max(dabs(dl1),dabs(dl2)) > 2*min(dabs(dl1),dabs(dl2)))
461 fact1 = (fl%tcool(i)-t_table(j+1)) &
462 /(t_table(j)-t_table(j+1))
463 fact2 = (fl%tcool(i)-t_table(j)) &
464 /(t_table(j+1)-t_table(j))
465 fl%Lcool(i) = l_table(j)*fact1 + l_table(j+1)*fact2
468 fact1 = ((fl%tcool(i)-t_table(j+1)) &
469 * (fl%tcool(i)-t_table(j+2))) &
470 / ((t_table(j)-t_table(j+1)) &
471 * (t_table(j)-t_table(j+2)))
472 fact2 = ((fl%tcool(i)-t_table(j)) &
473 * (fl%tcool(i)-t_table(j+2))) &
474 / ((t_table(j+1)-t_table(j)) &
475 * (t_table(j+1)-t_table(j+2)))
476 fact3 = ((fl%tcool(i)-t_table(j)) &
477 * (fl%tcool(i)-t_table(j+1))) &
478 / ((t_table(j+2)-t_table(j)) &
479 * (t_table(j+2)-t_table(j+1)))
480 fl%Lcool(i) = l_table(j)*fact1 + l_table(j+1)*fact2 &
489 fl%tcool(1:fl%ncool) = 10.0d0**fl%tcool(1:fl%ncool)
490 fl%Lcool(1:fl%ncool) = 10.0d0**fl%Lcool(1:fl%ncool)
493 if (si_unit) fl%Lcool(1:fl%ncool) = fl%Lcool(1:fl%ncool) * 10.0d0**(-13)
496 fl%tcool(1:fl%ncool) = fl%tcool(1:fl%ncool) / unit_temperature
497 fl%Lcool(1:fl%ncool) = fl%Lcool(1:fl%ncool) * unit_numberdensity**2 * unit_time / unit_pressure * (1.d0+2.d0*he_abundance)
499 fl%tcoolmin = fl%tcool(1)+smalldouble
501 if (fl%tlow==bigdouble) fl%tlow=fl%tcoolmin
502 fl%tcoolmax = fl%tcool(fl%ncool)
503 fl%lgtcoolmin = dlog10(fl%tcoolmin)
504 fl%lgtcoolmax = dlog10(fl%tcoolmax)
505 fl%lgstep = (fl%lgtcoolmax-fl%lgtcoolmin) * 1.d0 / (fl%ncool-1)
506 fl%dLdtcool(1) = (fl%Lcool(2)-fl%Lcool(1))/(fl%tcool(2)-fl%tcool(1))
507 fl%dLdtcool(fl%ncool) = (fl%Lcool(fl%ncool)-fl%Lcool(fl%ncool-1))/(fl%tcool(fl%ncool)-fl%tcool(fl%ncool-1))
510 fl%dLdtcool(i) = (fl%Lcool(i+1)-fl%Lcool(i-1))/(fl%tcool(i+1)-fl%tcool(i-1))
516 fl%tref = fl%tcoolmax
517 fl%lref = fl%Lcool(fl%ncool)
518 fl%Yc(fl%ncool) = zero
519 do i=fl%ncool-1, 1, -1
520 fl%Yc(i) = fl%Yc(i+1)
522 tstep = 1.0d-2*(fl%tcool(i+1)-fl%tcool(i))
523 call findl(fl%tcool(i+1)-j*tstep, lstep, fl)
524 fl%Yc(i) = fl%Yc(i) + fl%lref/fl%tref*tstep/lstep
529 rc_gamma_1=rc_gamma-1.d0
530 invgam = 1.d0/rc_gamma_1
540 double precision :: y_extra, factor
543 allocate(fl%y_PPL(1:fl%n_PPL+1))
545 fl%y_PPL(1:fl%n_PPL+1) = zero
548 factor = fl%l_PPL(fl%n_PPL+1) * fl%t_PPL(i) / (fl%l_PPL(i) * fl%t_PPL(fl%n_PPL+1))
549 if (fl%a_PPL(i) == 1.d0)
then
550 y_extra = log( fl%t_PPL(i) / fl%t_PPL(i+1) )
552 y_extra = 1 / (1 - fl%a_PPL(i)) * (1 - ( fl%t_PPL(i) / fl%t_PPL(i+1) )**(fl%a_PPL(i)-1) )
554 fl%y_PPL(i) = fl%y_PPL(i+1) - factor*y_extra
565 integer,
intent(in) :: ixI^L,ixO^L
566 double precision,
intent(in) :: x(ixI^S,1:ndim)
567 double precision :: w(ixI^S,1:nw)
568 double precision,
intent(out):: coolrate(ixI^S)
571 double precision :: pth(ixI^S),rho(ixI^S)
572 double precision :: L1,Te(ixI^S),Rfactor(ixI^S)
575 call fl%get_pthermal(w,x,ixi^l,ixo^l,pth)
576 call fl%get_rho(w,x,ixi^l,ixo^l,rho)
577 call fl%get_var_Rfactor(w,x,ixi^l,ixo^l,rfactor)
578 te(ixo^s) = pth(ixo^s) / (rho(ixo^s)*rfactor(ixo^s))
580 {
do ix^db = ixo^lim^db\}
582 if(te(ix^d) <= fl%tcoolmin)
then
584 else if(te(ix^d) >= fl%tcoolmax)
then
588 call findl(te(ix^d),l1,fl)
591 if(
slab_uniform .and. fl%rad_cut .and. x(ix^d,ndim) .le. fl%rad_cut_hgt)
then
592 l1 = l1*exp(-(x(ix^d,ndim)-fl%rad_cut_hgt)**2/fl%rad_cut_dey**2)
602 integer,
intent(in) :: ixI^L, ixO^L
603 double precision,
intent(in) :: qdt, x(ixI^S, 1:ndim), wCT(ixI^S, 1:nw)
604 double precision :: w(ixI^S, 1:nw)
605 double precision,
intent(out) :: coolrate(ixI^S)
607 double precision :: y1, y2, l1, tlocal2
608 double precision :: Te(ixI^S), pnew(ixI^S), rho(ixI^S), rhonew(ixI^S)
609 double precision :: emin, Lmax, fact, Rfactor(ixI^S), pth(ixI^S)
612 call fl%get_pthermal(wct, x, ixi^l, ixo^l, pth)
613 call fl%get_rho(wct, x, ixi^l, ixo^l, rho)
614 call fl%get_var_Rfactor(wct,x,ixi^l,ixo^l,rfactor)
615 te(ixo^s)=pth(ixo^s)/(rho(ixo^s)*rfactor(ixo^s))
617 call fl%get_pthermal(w, x, ixi^l, ixo^l, pnew)
618 call fl%get_rho(w, x, ixi^l, ixo^l, rhonew)
620 fact=fl%lref*qdt/fl%tref
622 {
do ix^db = ixo^lim^db\}
623 emin = rhonew(ix^d) * fl%tlow * rfactor(ix^d) * invgam
624 lmax = max(zero, ( pnew(ix^d)*invgam - emin ) / qdt)
628 if( te(ix^d)<= fl%tcoolmin)
then
630 else if( te(ix^d)>= fl%tcoolmax )
then
632 l1 = l1 * rho(ix^d)**2
635 call findy(te(ix^d), y1, fl)
636 y2 = y1 + fact * rho(ix^d)*rc_gamma_1
637 call findt(tlocal2, y2, fl)
638 if( tlocal2 <= fl%tcoolmin )
then
641 l1 = (te(ix^d)- tlocal2)*rho(ix^d)*rfactor(ix^d)*invgam/qdt
645 if(
slab_uniform .and. fl%rad_cut .and. x(ix^d,ndim) .le. fl%rad_cut_hgt)
then
646 l1 = l1*exp(-(x(ix^d,ndim)-fl%rad_cut_hgt)**2/fl%rad_cut_dey**2)
653 qsourcesplit,active,fl)
656 integer,
intent(in) :: ixI^L, ixO^L
657 double precision,
intent(in) :: qdt, x(ixI^S,1:ndim), wCT(ixI^S,1:nw), wCTprim(ixI^S,1:nw)
658 double precision,
intent(inout) :: w(ixI^S,1:nw)
659 logical,
intent(in) :: qsourcesplit
660 logical,
intent(inout) :: active
662 double precision,
allocatable,
dimension(:^D&) :: Lequi
664 if(qsourcesplit .eqv.fl%rc_split)
then
666 call cool_exact(qdt,ixi^l,ixo^l,wct,wctprim,w,x,fl)
667 if(fl%subtract_equi)
then
668 allocate(lequi(ixi^s))
670 w(ixo^s,fl%e_) = w(ixo^s,fl%e_)+lequi(ixo^s)
680 integer,
intent(in) :: ixI^L, ixO^L
681 double precision,
intent(in) :: qdt, x(ixI^S,1:ndim), wCT(ixI^S,1:nw)
682 double precision,
intent(inout) :: w(ixI^S,1:nw)
684 double precision :: etherm(ixI^S), rho(ixI^S), Rfactor(ixI^S),emin
687 call fl%get_pthermal(w,x,ixi^l,ixo^l,etherm)
688 call fl%get_rho(w,x,ixi^l,ixo^l,rho)
689 call fl%get_var_Rfactor(wct,x,ixi^l,ixo^l,rfactor)
690 {
do ix^db = ixo^lim^db\}
691 emin = rho(ix^d)*fl%tlow*rfactor(ix^d)
692 if(etherm(ix^d) < emin)
then
693 w(ix^d,fl%e_)=w(ix^d,fl%e_)+(emin-etherm(ix^d))*invgam
701 integer,
intent(in) :: ixI^L, ixO^L
702 double precision,
intent(in) :: qdt, x(ixI^S,1:ndim), wCT(ixI^S,1:nw)
703 double precision,
intent(inout) :: w(ixI^S,1:nw)
705 double precision,
intent(out) :: res(ixI^S)
707 double precision :: pth(ixI^S),rho(ixI^S),Rfactor(ixI^S),L1,Tlocal2
708 double precision :: Te(ixI^S)
709 double precision :: emin, Lmax
710 double precision :: Y1, Y2
711 double precision :: de, emax,fact
714 call fl%get_pthermal_equi(wct,x,ixi^l,ixo^l,pth)
715 call fl%get_rho_equi(wct,x,ixi^l,ixo^l,rho)
716 call fl%get_temperature_equi(wct,x,ixi^l,ixo^l,te)
717 rfactor(ixo^s)=pth(ixo^s)/(rho(ixo^s)*te(ixo^s))
721 fact = fl%lref*qdt/fl%tref
722 {
do ix^db = ixo^lim^db\}
723 emin = rho(ix^d)*fl%tlow*rfactor(ix^d)*invgam
724 lmax = max(zero,(pth(ix^d)*invgam-emin)/qdt)
725 emax = max(zero, pth(ix^d)*invgam-emin)
726 if( te(ix^d)<=fl%tcoolmin )
then
729 else if( te(ix^d)>=fl%tcoolmax )
then
733 if(te(ix^d)<
block%wextra(ix^d,fl%Tcoff_))
then
734 l1=l1*sqrt((te(ix^d)/
block%wextra(ix^d,fl%Tcoff_))**5)
740 call findy(te(ix^d),y1,fl)
741 y2 = y1 + fact * rho(ix^d)*rc_gamma_1
742 call findt(tlocal2,y2,fl)
743 if(tlocal2<=fl%tcoolmin)
then
746 de = (te(ix^d)-tlocal2)*rho(ix^d)*rfactor(ix^d)*invgam
749 if(te(ix^d)<
block%wextra(ix^d,fl%Tcoff_))
then
750 de=de*sqrt((te(ix^d)/
block%wextra(ix^d,fl%Tcoff_))**5)
762 integer,
intent(in) :: ixI^L, ixO^L
763 double precision,
intent(in) :: qdt, x(ixI^S,1:ndim), wCT(ixI^S,1:nw), wCTprim(ixI^S,1:nw)
764 double precision,
intent(inout) :: w(ixI^S,1:nw)
766 double precision :: Y1, Y2
767 double precision :: L1, pth(ixI^S), Tlocal2, pnew(ixI^S)
768 double precision :: rho(ixI^S), Te(ixI^S), rhonew(ixI^S), Rfactor(ixI^S)
769 double precision :: emin, Lmax, fact
770 double precision :: de, emax
773 call fl%get_rho(wct,x,ixi^l,ixo^l,rho)
774 call fl%get_var_Rfactor(wct,x,ixi^l,ixo^l,rfactor)
777 call fl%get_pthermal(wct,x,ixi^l,ixo^l,te)
778 te(ixo^s)=te(ixo^s)/(rho(ixo^s)*rfactor(ixo^s))
780 te(ixo^s)=wctprim(ixo^s,iw_e)/(rho(ixo^s)*rfactor(ixo^s))
782 call fl%get_pthermal(w,x,ixi^l,ixo^l,pnew)
783 call fl%get_rho(w,x,ixi^l,ixo^l,rhonew)
785 fact = fl%lref*qdt/fl%tref
787 {
do ix^db = ixo^lim^db\}
788 emin = rhonew(ix^d)*fl%tlow*rfactor(ix^d)*invgam
789 lmax = max(zero,pnew(ix^d)*invgam-emin)/qdt
790 emax = max(zero,pnew(ix^d)*invgam-emin)
791 if( te(ix^d)<=fl%tcoolmin )
then
793 else if( te(ix^d)>=fl%tcoolmax )
then
797 if(te(ix^d)<
block%wextra(ix^d,fl%Tcoff_))
then
798 l1=l1*sqrt((te(ix^d)/
block%wextra(ix^d,fl%Tcoff_))**5)
802 if(
slab_uniform .and. fl%rad_cut .and. x(ix^d,ndim) .le. fl%rad_cut_hgt)
then
803 l1 = l1*exp(-(x(ix^d,ndim)-fl%rad_cut_hgt)**2/fl%rad_cut_dey**2)
805 w(ix^d,fl%e_) = w(ix^d,fl%e_)-l1*qdt
807 call findy(te(ix^d),y1,fl)
808 y2 = y1 + fact*rho(ix^d)*rc_gamma_1
809 call findt(tlocal2,y2,fl)
810 if(tlocal2<=fl%tcoolmin)
then
813 de = (te(ix^d)-tlocal2)*rho(ix^d)*rfactor(ix^d)*invgam
816 if(te(ix^d)<
block%wextra(ix^d,fl%Tcoff_))
then
817 de=de*sqrt((te(ix^d)/
block%wextra(ix^d,fl%Tcoff_))**5)
821 if(
slab_uniform .and. fl%rad_cut .and. x(ix^d,ndim) .le. fl%rad_cut_hgt)
then
822 de = de*exp(-(x(ix^d,ndim)-fl%rad_cut_hgt)**2/fl%rad_cut_dey**2)
824 w(ix^d,fl%e_) = w(ix^d,fl%e_)-de
833 double precision,
intent(IN) :: tpoint
834 double precision,
intent(OUT) :: lpoint
838 lpoint =fl%l_PPL(fl%n_PPL) * ( tpoint / fl%t_PPL(fl%n_PPL) )**fl%a_PPL(fl%n_PPL)
840 lpoint = fl%Lcool(fl%ncool) * sqrt( tpoint / fl%tcoolmax)
849 double precision,
intent(IN) :: tpoint
850 double precision,
intent(OUT) :: Lpoint
853 double precision :: lgtp
857 i = maxloc(fl%t_PPL, dim=1, mask=fl%t_PPL<tpoint)
858 lpoint = fl%l_PPL(i) * (tpoint / fl%t_PPL(i))**fl%a_PPL(i)
860 lgtp = dlog10(tpoint)
861 jl = int((lgtp - fl%lgtcoolmin) /fl%lgstep) + 1
862 lpoint = fl%Lcool(jl)+ (tpoint-fl%tcool(jl)) &
863 * (fl%Lcool(jl+1)-fl%Lcool(jl)) &
864 / (fl%tcool(jl+1)-fl%tcool(jl))
873 double precision,
intent(IN) :: tpoint
874 double precision,
intent(OUT) :: Ypoint
877 double precision :: lgtp
878 double precision :: y_extra,factor
882 i = maxloc(fl%t_PPL, dim=1, mask=fl%t_PPL<tpoint)
883 factor = fl%l_PPL(fl%n_PPL+1) * fl%t_PPL(i) / (fl%l_PPL(i) * fl%t_PPL(fl%n_PPL+1))
884 if(fl%a_PPL(i)==1.d0)
then
885 y_extra = log( fl%t_PPL(i) / tpoint )
887 y_extra = 1 / (1 - fl%a_PPL(i)) * (1 - ( fl%t_PPL(i) / tpoint )**(fl%a_PPL(i)-1) )
889 ypoint = fl%y_PPL(i) + factor*y_extra
891 lgtp = dlog10(tpoint)
892 jl = int((lgtp - fl%lgtcoolmin) / fl%lgstep) + 1
893 ypoint = fl%Yc(jl)+ (tpoint-fl%tcool(jl)) &
894 * (fl%Yc(jl+1)-fl%Yc(jl)) &
895 / (fl%tcool(jl+1)-fl%tcool(jl))
907 double precision,
intent(OUT) :: tpoint
908 double precision,
intent(IN) :: Ypoint
911 double precision :: factor
912 integer :: jl,jc,jh,i
915 i = minloc(fl%y_PPL, dim=1, mask=fl%y_PPL>ypoint)
916 factor = fl%l_PPL(i) * fl%t_PPL(fl%n_PPL+1) / (fl%l_PPL(fl%n_PPL+1) * fl%t_PPL(i))
917 if(fl%a_PPL(i)==1.d0)
then
918 tpoint = fl%t_PPL(i) * exp( -1.d0 * factor * ( ypoint - fl%y_PPL(i)))
920 tpoint = fl%t_PPL(i) * (1 - (1 - fl%a_PPL(i)) * factor * (ypoint - fl%y_PPL(i)))**(1 / (1 - fl%a_PPL(i)))
923 if(ypoint >= fl%Yc(1))
then
925 else if (ypoint == fl%Yc(fl%ncool))
then
933 if(ypoint <= fl%Yc(jc))
then
940 tpoint = fl%tcool(jl)+ (ypoint-fl%Yc(jl)) &
941 * (fl%tcool(jl+1)-fl%tcool(jl)) &
942 / (fl%Yc(jl+1)-fl%Yc(jl))
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
This module contains definitions of global parameters and variables and some generic functions/subrou...
type(state), pointer block
Block pointer for using one block and its previous state.
integer, parameter unitpar
file handle for IO
character(len=std_len), dimension(:), allocatable par_files
Which par files are used as input.
logical phys_trac
Use TRAC for MHD or 1D HD.
logical slab_uniform
uniform Cartesian geometry or not (stretched Cartesian)
This module defines the procedures of a physics module. It contains function pointers for the various...
module radiative cooling – add optically thin radiative cooling
subroutine getvar_cooling(ixil, ixol, w, x, coolrate, fl)
subroutine radiative_cooling_init_params(phys_gamma, he_abund)
Radiative cooling initialization.
subroutine findl(tpoint, lpoint, fl)
subroutine get_cool_equi(qdt, ixil, ixol, wct, w, x, fl, res)
subroutine radiative_cooling_init(fl, read_params)
subroutine create_y_ppl(fl)
subroutine radiative_cooling_add_source(qdt, ixil, ixol, wct, wctprim, w, x, qsourcesplit, active, fl)
subroutine calc_l_extended(tpoint, lpoint, fl)
subroutine cool_exact(qdt, ixil, ixol, wct, wctprim, w, x, fl)
subroutine findt(tpoint, ypoint, fl)
subroutine floortemperature(qdt, ixil, ixol, wct, w, x, fl)
subroutine getvar_cooling_exact(qdt, ixil, ixol, wct, w, x, coolrate, fl)
subroutine findy(tpoint, ypoint, fl)
module containing all optically thin radiative cooling tables
double precision, dimension(1:101) l_dere_corona
double precision, dimension(1:71) t_mlsolar1
double precision, dimension(1:151) l_cl_solar
double precision, dimension(1:5) t_fm
double precision, dimension(1:14) a_spex_dm_fine
double precision, dimension(1:9) a_rosner
double precision, dimension(1:110) l_spex
double precision, dimension(1:51) l_mb
double precision, dimension(1:10) t_rosner
double precision, dimension(1:5) a_hildner
double precision, dimension(1:9) x_rosner
double precision, dimension(1:7) x_klimchuk
double precision, dimension(1:151) l_cl_ism
double precision, dimension(1:8) t_spex_dm_rough
double precision, dimension(1:110) nenh_spex
double precision, dimension(1:110) t_spex
double precision, dimension(1:76) l_dm_2
double precision, dimension(1:15) t_spex_dm_fine
double precision, dimension(1:7) x_spex_dm_rough
double precision, dimension(1:14) x_spex_dm_fine
double precision, dimension(1:71) l_mlsolar1
double precision, dimension(1:45) t_jccorona
double precision, dimension(1:5) x_hildner
double precision, dimension(1:71) t_mlcosmol
double precision, dimension(1:151) t_cl_ism
double precision, dimension(1:151) t_cl_solar
double precision, dimension(1:51) t_mb
double precision, dimension(1:8) t_klimchuk
double precision, dimension(1:55) t_colgan
double precision, dimension(1:55) l_colgan
double precision, dimension(1:4) a_fm
double precision, dimension(1:101) l_dere_photo
double precision, dimension(1:45) l_jccorona
double precision, dimension(1:71) l_mlwc
double precision, dimension(1:71) l_dm
double precision, dimension(1:71) t_mlwc
double precision, dimension(1:7) a_spex_dm_rough
double precision, dimension(1:71) t_dm
double precision, dimension(1:7) a_klimchuk
double precision, dimension(1:71) l_mlcosmol
double precision, dimension(1:76) t_dm_2
double precision, dimension(1:6) t_hildner
double precision, dimension(1:4) x_fm
double precision, dimension(1:101) t_dere