MPI-AMRVAC 3.1
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_ffhd_phys.t
Go to the documentation of this file.
1!> Frozen-field hydrodynamics module
3
4#include "amrvac.h"
5
6 use mod_global_parameters, only: std_len, const_c
10 use mod_physics
11 use mod_comm_lib, only: mpistop
12
13 implicit none
14 private
15
16 !> Whether an energy equation is used
17 logical, public, protected :: ffhd_energy = .true.
18
19 !> Whether thermal conduction is used
20 logical, public, protected :: ffhd_thermal_conduction = .false.
21 !> Whether hyperbolic type thermal conduction is used
22 logical, public, protected :: ffhd_hyperbolic_thermal_conduction = .false.
23 !> type of fluid for thermal conduction
24 type(tc_fluid), public, allocatable :: tc_fl
25 !> type of fluid for thermal emission synthesis
26 type(te_fluid), public, allocatable :: te_fl_ffhd
27
28 !> Whether radiative cooling is added
29 logical, public, protected :: ffhd_radiative_cooling = .false.
30 !> type of fluid for radiative cooling
31 type(rc_fluid), public, allocatable :: rc_fl
32
33 !> Whether viscosity is added
34 logical, public, protected :: ffhd_viscosity = .false.
35
36 !> Whether gravity is added
37 logical, public, protected :: ffhd_gravity = .false.
38
39 !> Whether TRAC method is used
40 logical, public, protected :: ffhd_trac = .false.
41
42 !> Which TRAC method is used
43 integer, public, protected :: ffhd_trac_type=1
44
45 !> Height of the mask used in the TRAC method
46 double precision, public, protected :: ffhd_trac_mask = 0.d0
47
48 !> Distance between two adjacent traced magnetic field lines (in finest cell size)
49 integer, public, protected :: ffhd_trac_finegrid=4
50
51 !> Whether plasma is partially ionized
52 logical, public, protected :: ffhd_partial_ionization = .false.
53
54 !> Index of the density (in the w array)
55 integer, public, protected :: rho_
56
57 !> Indices of the momentum density
58 integer, allocatable, public, protected :: mom(:)
59
60 !> Index of the energy density (-1 if not present)
61 integer, public, protected :: e_
62
63 !> Index of the gas pressure (-1 if not present) should equal e_
64 integer, public, protected :: p_
65
66 !> Indices of temperature
67 integer, public, protected :: te_
68
69 !> Index of the cutoff temperature for the TRAC method
70 integer, public, protected :: tcoff_
71 integer, public, protected :: tweight_
72 integer, public, protected :: q_
73
74 !> The adiabatic index
75 double precision, public :: ffhd_gamma = 5.d0/3.0d0
76
77 !> The adiabatic constant
78 double precision, public :: ffhd_adiab = 1.0d0
79
80 !> The small_est allowed energy
81 double precision, protected :: small_e
82
83 !> The thermal conductivity kappa in hyperbolic thermal conduction
84 double precision, public :: hypertc_kappa
85
86 !> Helium abundance over Hydrogen
87 double precision, public, protected :: he_abundance=0.1d0
88 !> Ionization fraction of H
89 !> H_ion_fr = H+/(H+ + H)
90 double precision, public, protected :: h_ion_fr=1d0
91 !> Ionization fraction of He
92 !> He_ion_fr = (He2+ + He+)/(He2+ + He+ + He)
93 double precision, public, protected :: he_ion_fr=1d0
94 !> Ratio of number He2+ / number He+ + He2+
95 !> He_ion_fr2 = He2+/(He2+ + He+)
96 double precision, public, protected :: he_ion_fr2=1d0
97 ! used for eq of state when it is not defined by units,
98 ! the units do not contain terms related to ionization fraction
99 ! and it is p = RR * rho * T
100 double precision, public, protected :: rr=1d0
101 ! remove the below flag and assume default value = .false.
102 ! when eq state properly implemented everywhere
103 ! and not anymore through units
104 logical, public, protected :: eq_state_units = .true.
105
106 !> gamma minus one and its inverse
107 double precision :: gamma_1, inv_gamma_1
108
109 !define the function interface for the kinetic energy
110 abstract interface
111
112 function fun_kin_en(w, ixI^L, ixO^L, inv_rho) result(ke)
113 use mod_global_parameters, only: nw, ndim,block
114 integer, intent(in) :: ixi^l, ixo^l
115 double precision, intent(in) :: w(ixi^s, nw)
116 double precision :: ke(ixo^s)
117 double precision, intent(in), optional :: inv_rho(ixo^s)
118 end function fun_kin_en
119
120 end interface
121
122 procedure(sub_convert), pointer :: ffhd_to_primitive => null()
123 procedure(sub_convert), pointer :: ffhd_to_conserved => null()
124 procedure(sub_small_values), pointer :: ffhd_handle_small_values => null()
125 procedure(sub_get_pthermal), pointer :: ffhd_get_pthermal => null()
126 procedure(sub_get_pthermal), pointer :: ffhd_get_rfactor => null()
127 procedure(sub_get_pthermal), pointer :: ffhd_get_temperature => null()
128 procedure(sub_get_v), pointer :: ffhd_get_v => null()
129 procedure(fun_kin_en), pointer :: ffhd_kin_en => null()
130 ! Public methods
131 public :: ffhd_phys_init
132 public :: ffhd_kin_en
133 public :: ffhd_get_pthermal
134 public :: ffhd_get_temperature
135 public :: ffhd_get_v
136 public :: ffhd_get_rho
137 public :: ffhd_get_v_idim
138 public :: ffhd_to_conserved
139 public :: ffhd_to_primitive
140 public :: ffhd_get_csound2
141 public :: ffhd_e_to_ei
142 public :: ffhd_ei_to_e
143
144contains
145
146 subroutine ffhd_read_params(files)
148 use mod_particles, only: particles_eta, particles_etah
149 character(len=*), intent(in) :: files(:)
150 integer :: n
151
152 namelist /ffhd_list/ ffhd_energy, ffhd_gamma, ffhd_adiab, &
156
157 do n = 1, size(files)
158 open(unitpar, file=trim(files(n)), status="old")
159 read(unitpar, ffhd_list, end=111)
160111 close(unitpar)
161 end do
162 end subroutine ffhd_read_params
163
164 !> Write this module's parameters to a snapsoht
165 subroutine ffhd_write_info(fh)
167 integer, intent(in) :: fh
168 integer, parameter :: n_par = 1
169 double precision :: values(n_par)
170 character(len=name_len) :: names(n_par)
171 integer, dimension(MPI_STATUS_SIZE) :: st
172 integer :: er
173
174 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
175
176 names(1) = "gamma"
177 values(1) = ffhd_gamma
178 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
179 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
180 end subroutine ffhd_write_info
181
182 subroutine ffhd_phys_init()
187 use mod_gravity, only: gravity_init
192 integer :: itr, idir
193
194 call ffhd_read_params(par_files)
195
196 if(.not. ffhd_energy) then
199 if(mype==0) write(*,*) 'WARNING: set ffhd_thermal_conduction=F when ffhd_energy=F'
200 end if
203 if(mype==0) write(*,*) 'WARNING: set ffhd_hyperbolic_thermal_conduction=F when ffhd_energy=F'
204 end if
207 if(mype==0) write(*,*) 'WARNING: set ffhd_radiative_cooling=F when ffhd_energy=F'
208 end if
209 if(ffhd_trac) then
210 ffhd_trac=.false.
211 if(mype==0) write(*,*) 'WARNING: set ffhd_trac=F when ffhd_energy=F'
212 end if
215 if(mype==0) write(*,*) 'WARNING: set ffhd_partial_ionization=F when ffhd_energy=F'
216 end if
217 end if
218 if(.not.eq_state_units) then
221 if(mype==0) write(*,*) 'WARNING: set ffhd_partial_ionization=F when eq_state_units=F'
222 end if
223 end if
224
227 if(mype==0) write(*,*) 'WARNING: turn off parabolic TC when using hyperbolic TC'
228 end if
229
230 physics_type = "ffhd"
231 phys_energy=ffhd_energy
232 phys_internal_e=.false.
235 phys_partial_ionization=ffhd_partial_ionization
236
237 phys_gamma = ffhd_gamma
238 phys_total_energy=ffhd_energy
240
241 {^ifoned
242 if(ffhd_trac .and. ffhd_trac_type .gt. 2) then
244 if(mype==0) write(*,*) 'WARNING: reset ffhd_trac_type=1 for 1D simulation'
245 end if
246 }
247 if(ffhd_trac .and. ffhd_trac_type .le. 4) then
248 ffhd_trac_mask=bigdouble
249 if(mype==0) write(*,*) 'WARNING: set ffhd_trac_mask==bigdouble for global TRAC method'
250 end if
252
253 allocate(start_indices(number_species),stop_indices(number_species))
254 start_indices(1)=1
255 ! Determine flux variables
256 rho_ = var_set_rho()
257
258 allocate(mom(1))
259 mom(:) = var_set_momentum(1)
260
261 ! Set index of energy variable
262 if(ffhd_energy) then
263 e_ = var_set_energy() ! energy density
264 p_ = e_ ! gas pressure
265 else
266 e_ = -1
267 p_ = -1
268 end if
269
271 q_ = var_set_q()
272 need_global_cs2max=.true.
273 else
274 q_=-1
275 end if
276
277 ! set number of variables which need update ghostcells
278 nwgc=nwflux
279
280 ! set the index of the last flux variable for species 1
281 stop_indices(1)=nwflux
282
283 ! set temperature as an auxiliary variable to get ionization degree
285 te_ = var_set_auxvar('Te','Te')
286 else
287 te_ = -1
288 end if
289
290 ! set cutoff temperature when using the TRAC method, as well as an auxiliary weight
291 tweight_ = -1
292 if(ffhd_trac) then
293 tcoff_ = var_set_wextra()
294 iw_tcoff=tcoff_
295 if(ffhd_trac_type .ge. 3) then
296 tweight_ = var_set_wextra()
297 iw_tweight=tweight_
298 end if
299 else
300 tcoff_ = -1
301 end if
302
303 nvector = 0 ! No. vector vars
304
305 ! Check whether custom flux types have been defined
306 if(.not. allocated(flux_type)) then
307 allocate(flux_type(ndir, nwflux))
308 flux_type = flux_default
309 else if(any(shape(flux_type) /= [ndir, nwflux])) then
310 call mpistop("phys_check error: flux_type has wrong shape")
311 end if
312
313 phys_get_dt => ffhd_get_dt
314 phys_get_cmax => ffhd_get_cmax_origin
315 phys_get_a2max => ffhd_get_a2max
316 phys_get_cs2max => ffhd_get_cs2max
317 phys_get_tcutoff => ffhd_get_tcutoff
318 phys_get_cbounds => ffhd_get_cbounds
319 phys_to_primitive => ffhd_to_primitive_origin
320 ffhd_to_primitive => ffhd_to_primitive_origin
321 phys_to_conserved => ffhd_to_conserved_origin
322 ffhd_to_conserved => ffhd_to_conserved_origin
323 phys_get_flux => ffhd_get_flux
324 phys_get_v => ffhd_get_v_origin
325 ffhd_get_v => ffhd_get_v_origin
326 phys_get_rho => ffhd_get_rho
327 ffhd_kin_en => ffhd_kin_en_origin
328 phys_add_source_geom => ffhd_add_source_geom
329 phys_add_source => ffhd_add_source
330 phys_check_params => ffhd_check_params
331 phys_write_info => ffhd_write_info
332 phys_handle_small_values => ffhd_handle_small_values_origin
333 ffhd_handle_small_values => ffhd_handle_small_values_origin
334 phys_check_w => ffhd_check_w_origin
335
336 if(.not.ffhd_energy) then
337 phys_get_pthermal => ffhd_get_pthermal_iso
338 ffhd_get_pthermal => ffhd_get_pthermal_iso
339 else
340 phys_get_pthermal => ffhd_get_pthermal_origin
341 ffhd_get_pthermal => ffhd_get_pthermal_origin
342 end if
343
344 ! choose Rfactor in ideal gas law
346 ffhd_get_rfactor=>rfactor_from_temperature_ionization
347 phys_update_temperature => ffhd_update_temperature
348 else if(associated(usr_rfactor)) then
349 ffhd_get_rfactor=>usr_rfactor
350 else
351 ffhd_get_rfactor=>rfactor_from_constant_ionization
352 end if
353
355 ffhd_get_temperature => ffhd_get_temperature_from_te
356 else
357 ffhd_get_temperature => ffhd_get_temperature_from_etot
358 end if
359
360 ! derive units from basic units
361 call ffhd_physical_units()
362
365 end if
366 if(.not. ffhd_energy .and. ffhd_thermal_conduction) then
367 call mpistop("thermal conduction needs ffhd_energy=T")
368 end if
370 call mpistop("hyperbolic thermal conduction needs ffhd_energy=T")
371 end if
372 if(.not. ffhd_energy .and. ffhd_radiative_cooling) then
373 call mpistop("radiative cooling needs ffhd_energy=T")
374 end if
375
376 ! initialize thermal conduction module
378 call sts_init()
380
381 allocate(tc_fl)
382 call tc_get_hd_params(tc_fl,tc_params_read_ffhd)
383 call add_sts_method(ffhd_get_tc_dt_ffhd,ffhd_sts_set_source_tc_ffhd,e_,1,e_,1,.false.)
384 tc_fl%get_temperature_from_conserved => ffhd_get_temperature_from_etot
385 tc_fl%get_temperature_from_eint => ffhd_get_temperature_from_eint
387 call set_error_handling_to_head(ffhd_tc_handle_small_e)
388 tc_fl%get_rho => ffhd_get_rho
389 tc_fl%e_ = e_
390 tc_fl%Tcoff_ = tcoff_
391 end if
392
393 ! Initialize radiative cooling module
396 allocate(rc_fl)
397 call radiative_cooling_init(rc_fl,rc_params_read)
398 rc_fl%get_rho => ffhd_get_rho
399 rc_fl%get_pthermal => ffhd_get_pthermal
400 rc_fl%get_var_Rfactor => ffhd_get_rfactor
401 rc_fl%e_ = e_
402 rc_fl%Tcoff_ = tcoff_
403 rc_fl%has_equi = .false.
404 end if
405 allocate(te_fl_ffhd)
406 te_fl_ffhd%get_rho=> ffhd_get_rho
407 te_fl_ffhd%get_pthermal=> ffhd_get_pthermal
408 te_fl_ffhd%get_var_Rfactor => ffhd_get_rfactor
409{^ifthreed
410 phys_te_images => ffhd_te_images
411}
412 ! Initialize viscosity module
413 if(ffhd_viscosity) call viscosity_init(phys_wider_stencil)
414
415 ! Initialize gravity module
416 if(ffhd_gravity) then
417 call gravity_init()
418 end if
419
420 ! initialize ionization degree table
422 end subroutine ffhd_phys_init
423
424{^ifthreed
425 subroutine ffhd_te_images
428
429 select case(convert_type)
430 case('EIvtiCCmpi','EIvtuCCmpi')
432 case('ESvtiCCmpi','ESvtuCCmpi')
434 case('SIvtiCCmpi','SIvtuCCmpi')
436 case('WIvtiCCmpi','WIvtuCCmpi')
438 case default
439 call mpistop("Error in synthesize emission: Unknown convert_type")
440 end select
441 end subroutine ffhd_te_images
442}
443
444 subroutine ffhd_sts_set_source_tc_ffhd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
448 integer, intent(in) :: ixi^l, ixo^l, igrid, nflux
449 double precision, intent(in) :: x(ixi^s,1:ndim)
450 double precision, intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
451 double precision, intent(in) :: my_dt
452 logical, intent(in) :: fix_conserve_at_step
453 call sts_set_source_tc_mhd(ixi^l,ixo^l,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux,tc_fl)
454 end subroutine ffhd_sts_set_source_tc_ffhd
455
456 function ffhd_get_tc_dt_ffhd(w,ixI^L,ixO^L,dx^D,x) result(dtnew)
457 !Check diffusion time limit dt < dx_i**2/((gamma-1)*tc_k_para_i/rho)
458 !where tc_k_para_i=tc_k_para*B_i**2/B**2
459 !and T=p/rho
462
463 integer, intent(in) :: ixi^l, ixo^l
464 double precision, intent(in) :: dx^d, x(ixi^s,1:ndim)
465 double precision, intent(in) :: w(ixi^s,1:nw)
466 double precision :: dtnew
467
468 dtnew=get_tc_dt_mhd(w,ixi^l,ixo^l,dx^d,x,tc_fl)
469 end function ffhd_get_tc_dt_ffhd
470
471 subroutine ffhd_tc_handle_small_e(w, x, ixI^L, ixO^L, step)
473
474 integer, intent(in) :: ixi^l,ixo^l
475 double precision, intent(inout) :: w(ixi^s,1:nw)
476 double precision, intent(in) :: x(ixi^s,1:ndim)
477 integer, intent(in) :: step
478 character(len=140) :: error_msg
479
480 write(error_msg,"(a,i3)") "Thermal conduction step ", step
481 call ffhd_handle_small_ei(w,x,ixi^l,ixo^l,e_,error_msg)
482 end subroutine ffhd_tc_handle_small_e
483
484 subroutine tc_params_read_ffhd(fl)
486 type(tc_fluid), intent(inout) :: fl
487 integer :: n
488 ! list parameters
489 logical :: tc_saturate=.false.
490 double precision :: tc_k_para=0d0
491 character(len=std_len) :: tc_slope_limiter="MC"
492
493 namelist /tc_list/ tc_saturate, tc_slope_limiter, tc_k_para
494
495 do n = 1, size(par_files)
496 open(unitpar, file=trim(par_files(n)), status="old")
497 read(unitpar, tc_list, end=111)
498111 close(unitpar)
499 end do
500
501 fl%tc_saturate = tc_saturate
502 fl%tc_k_para = tc_k_para
503 select case(tc_slope_limiter)
504 case ('no','none')
505 fl%tc_slope_limiter = 0
506 case ('MC')
507 ! montonized central limiter Woodward and Collela limiter (eq.3.51h), a factor of 2 is pulled out
508 fl%tc_slope_limiter = 1
509 case('minmod')
510 ! minmod limiter
511 fl%tc_slope_limiter = 2
512 case ('superbee')
513 ! Roes superbee limiter (eq.3.51i)
514 fl%tc_slope_limiter = 3
515 case ('koren')
516 ! Barry Koren Right variant
517 fl%tc_slope_limiter = 4
518 case default
519 call mpistop("Unknown tc_slope_limiter, choose MC, minmod")
520 end select
521 end subroutine tc_params_read_ffhd
522
523 subroutine rc_params_read(fl)
525 use mod_constants, only: bigdouble
526 type(rc_fluid), intent(inout) :: fl
527 integer :: n
528 integer :: ncool = 4000
529 double precision :: cfrac=0.1d0
530
531 !> Name of cooling curve
532 character(len=std_len) :: coolcurve='JCcorona'
533
534 !> Name of cooling method
535 character(len=std_len) :: coolmethod='exact'
536
537 !> Fixed temperature not lower than tlow
538 logical :: tfix=.false.
539
540 !> Lower limit of temperature
541 double precision :: tlow=bigdouble
542
543 !> Add cooling source in a split way (.true.) or un-split way (.false.)
544 logical :: rc_split=.false.
545 logical :: rad_cut=.false.
546 double precision :: rad_cut_hgt=0.5d0
547 double precision :: rad_cut_dey=0.15d0
548
549 namelist /rc_list/ coolcurve, coolmethod, ncool, cfrac, tlow, tfix, rc_split, rad_cut, rad_cut_hgt, rad_cut_dey
550
551 do n = 1, size(par_files)
552 open(unitpar, file=trim(par_files(n)), status="old")
553 read(unitpar, rc_list, end=111)
554111 close(unitpar)
555 end do
556
557 fl%ncool=ncool
558 fl%coolcurve=coolcurve
559 fl%coolmethod=coolmethod
560 fl%tlow=tlow
561 fl%Tfix=tfix
562 fl%rc_split=rc_split
563 fl%cfrac=cfrac
564 fl%rad_cut=rad_cut
565 fl%rad_cut_hgt=rad_cut_hgt
566 fl%rad_cut_dey=rad_cut_dey
567 end subroutine rc_params_read
568
569 subroutine ffhd_check_params
573
574 gamma_1=ffhd_gamma-1.d0
575 if (.not. ffhd_energy) then
576 if (ffhd_gamma <= 0.0d0) call mpistop ("Error: ffhd_gamma <= 0")
577 if (ffhd_adiab < 0.0d0) call mpistop ("Error: ffhd_adiab < 0")
579 else
580 if (ffhd_gamma <= 0.0d0 .or. ffhd_gamma == 1.0d0) &
581 call mpistop ("Error: ffhd_gamma <= 0 or ffhd_gamma == 1")
582 inv_gamma_1=1.d0/gamma_1
583 small_e = small_pressure * inv_gamma_1
584 end if
585
586 if (number_equi_vars > 0 .and. .not. associated(usr_set_equi_vars)) then
587 call mpistop("usr_set_equi_vars has to be implemented in the user file")
588 end if
589 end subroutine ffhd_check_params
590
591 subroutine ffhd_physical_units()
593 double precision :: mp,kb
594 double precision :: a,b
595
596 if(si_unit) then
597 mp=mp_si
598 kb=kb_si
599 else
600 mp=mp_cgs
601 kb=kb_cgs
602 end if
603 if(eq_state_units) then
604 a=1d0+4d0*he_abundance
606 b=1d0+h_ion_fr+he_abundance*(he_ion_fr*(he_ion_fr2+1d0)+1d0)
607 else
608 b=2d0+3d0*he_abundance
609 end if
610 rr=1d0
611 else
612 a=1d0
613 b=1d0
614 rr=(1d0+h_ion_fr+he_abundance*(he_ion_fr*(he_ion_fr2+1d0)+1d0))/(1d0+4d0*he_abundance)
615 end if
616 if(unit_density/=1.d0 .or. unit_numberdensity/=1.d0) then
617 if(unit_density/=1.d0) then
619 else if(unit_numberdensity/=1.d0) then
621 end if
622 if(unit_temperature/=1.d0) then
625 if(unit_length/=1.d0) then
627 else if(unit_time/=1.d0) then
629 end if
630 else if(unit_pressure/=1.d0) then
633 if(unit_length/=1.d0) then
635 else if(unit_time/=1.d0) then
637 end if
638 else if(unit_velocity/=1.d0) then
641 if(unit_length/=1.d0) then
643 else if(unit_time/=1.d0) then
645 end if
646 else if(unit_time/=1.d0) then
650 end if
651 else if(unit_temperature/=1.d0) then
652 ! units of temperature and velocity are dependent
653 if(unit_pressure/=1.d0) then
657 if(unit_length/=1.d0) then
659 else if(unit_time/=1.d0) then
661 end if
662 end if
663 else if(unit_pressure/=1.d0) then
664 if(unit_velocity/=1.d0) then
668 if(unit_length/=1.d0) then
670 else if(unit_time/=1.d0) then
672 end if
673 else if(unit_time/=0.d0) then
678 end if
679 end if
681 end subroutine ffhd_physical_units
682
683 subroutine ffhd_check_w_origin(primitive,ixI^L,ixO^L,w,flag)
685 logical, intent(in) :: primitive
686 integer, intent(in) :: ixi^l, ixo^l
687 double precision, intent(in) :: w(ixi^s,nw)
688 double precision :: tmp(ixi^s)
689 logical, intent(inout) :: flag(ixi^s,1:nw)
690
691 flag=.false.
692 where(w(ixo^s,rho_) < small_density) flag(ixo^s,rho_) = .true.
693
694 if(ffhd_energy) then
695 if(primitive) then
696 where(w(ixo^s,e_) < small_pressure) flag(ixo^s,e_) = .true.
697 else
698 tmp(ixo^s)=w(ixo^s,e_)-ffhd_kin_en(w,ixi^l,ixo^l)
699 where(tmp(ixo^s) < small_e) flag(ixo^s,e_) = .true.
700 end if
701 end if
702 end subroutine ffhd_check_w_origin
703
704 subroutine ffhd_to_conserved_origin(ixI^L,ixO^L,w,x)
706 integer, intent(in) :: ixi^l, ixo^l
707 double precision, intent(inout) :: w(ixi^s, nw)
708 double precision, intent(in) :: x(ixi^s, 1:ndim)
709
710 if(ffhd_energy) then
711 w(ixo^s,e_)=w(ixo^s,p_)*inv_gamma_1+half*w(ixo^s,mom(1))**2*w(ixo^s,rho_)
712 end if
713 w(ixo^s,mom(1))=w(ixo^s,rho_)*w(ixo^s,mom(1))
714 end subroutine ffhd_to_conserved_origin
715
716 subroutine ffhd_to_primitive_origin(ixI^L,ixO^L,w,x)
718 integer, intent(in) :: ixi^l, ixo^l
719 double precision, intent(inout) :: w(ixi^s, nw)
720 double precision, intent(in) :: x(ixi^s, 1:ndim)
721
722 if(fix_small_values) then
723 call ffhd_handle_small_values(.false., w, x, ixi^l, ixo^l, 'ffhd_to_primitive_origin')
724 end if
725
726 w(ixo^s,mom(1)) = w(ixo^s,mom(1))/w(ixo^s,rho_)
727 if(ffhd_energy) then
728 w(ixo^s,p_)=gamma_1*(w(ixo^s,e_)-half*w(ixo^s,rho_)*w(ixo^s,mom(1))**2)
729 end if
730 end subroutine ffhd_to_primitive_origin
731
732 subroutine ffhd_ei_to_e(ixI^L,ixO^L,w,x)
734 integer, intent(in) :: ixi^l, ixo^l
735 double precision, intent(inout) :: w(ixi^s, nw)
736 double precision, intent(in) :: x(ixi^s, 1:ndim)
737
738 w(ixi^s,e_)=w(ixi^s,e_)+ffhd_kin_en(w,ixi^l,ixi^l)
739 end subroutine ffhd_ei_to_e
740
741 subroutine ffhd_e_to_ei(ixI^L,ixO^L,w,x)
743 integer, intent(in) :: ixi^l, ixo^l
744 double precision, intent(inout) :: w(ixi^s, nw)
745 double precision, intent(in) :: x(ixi^s, 1:ndim)
746
747 w(ixi^s,e_)=w(ixi^s,e_)-ffhd_kin_en(w,ixi^l,ixi^l)
748 if(fix_small_values) then
749 call ffhd_handle_small_ei(w,x,ixi^l,ixi^l,e_,'ffhd_e_to_ei')
750 end if
751 end subroutine ffhd_e_to_ei
752
753 subroutine ffhd_handle_small_values_origin(primitive, w, x, ixI^L, ixO^L, subname)
756 logical, intent(in) :: primitive
757 integer, intent(in) :: ixi^l,ixo^l
758 double precision, intent(inout) :: w(ixi^s,1:nw)
759 double precision, intent(in) :: x(ixi^s,1:ndim)
760 character(len=*), intent(in) :: subname
761
762 logical :: flag(ixi^s,1:nw)
763 double precision :: tmp2(ixi^s)
764
765 call phys_check_w(primitive, ixi^l, ixi^l, w, flag)
766
767 if(any(flag)) then
768 select case (small_values_method)
769 case ("replace")
770 where(flag(ixo^s,rho_)) w(ixo^s,rho_) = small_density
771 if(small_values_fix_iw(mom(1))) then
772 where(flag(ixo^s,rho_)) w(ixo^s, mom(1)) = 0.0d0
773 end if
774 if(ffhd_energy) then
775 if(primitive) then
776 where(flag(ixo^s,e_)) w(ixo^s,p_) = small_pressure
777 else
778 where(flag(ixo^s,e_))
779 w(ixo^s,e_) = small_e+ffhd_kin_en(w,ixi^l,ixo^l)
780 end where
781 end if
782 end if
783 case ("average")
784 call small_values_average(ixi^l, ixo^l, w, x, flag, rho_)
785 if(ffhd_energy) then
786 if(primitive) then
787 call small_values_average(ixi^l, ixo^l, w, x, flag, p_)
788 else
789 w(ixi^s,e_)=w(ixi^s,e_)-ffhd_kin_en(w,ixi^l,ixi^l)
790 call small_values_average(ixi^l, ixo^l, w, x, flag, e_)
791 w(ixi^s,e_)=w(ixi^s,e_)+ffhd_kin_en(w,ixi^l,ixi^l)
792 end if
793 end if
794 case default
795 if(.not.primitive) then
796 if(ffhd_energy) then
797 w(ixo^s,p_)=gamma_1*(w(ixo^s,e_)-ffhd_kin_en(w,ixi^l,ixo^l))
798 end if
799 w(ixo^s,mom(1))=w(ixo^s,mom(1))/w(ixo^s,rho_)
800 end if
801 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
802 end select
803 end if
804 end subroutine ffhd_handle_small_values_origin
805
806 subroutine ffhd_get_v_origin(w,x,ixI^L,ixO^L,v)
808 integer, intent(in) :: ixi^l, ixo^l
809 double precision, intent(in) :: w(ixi^s,nw), x(ixi^s,1:ndim)
810 double precision, intent(out) :: v(ixi^s,ndir)
811 double precision :: rho(ixi^s)
812 integer :: idir
813
814 call ffhd_get_rho(w,x,ixi^l,ixo^l,rho)
815 rho(ixo^s)=1.d0/rho(ixo^s)
816 do idir=1,ndir
817 v(ixo^s,ndir) = w(ixo^s,mom(1))*block%B0(ixo^s,idir,0)*rho(ixo^s)
818 end do
819 end subroutine ffhd_get_v_origin
820
821 subroutine ffhd_get_v_idim(w,x,ixI^L,ixO^L,idim,v)
823 integer, intent(in) :: ixi^l, ixo^l, idim
824 double precision, intent(in) :: w(ixi^s,nw), x(ixi^s,1:ndim)
825 double precision, intent(out) :: v(ixi^s)
826 double precision :: rho(ixi^s)
827
828 call ffhd_get_rho(w,x,ixi^l,ixo^l,rho)
829 v(ixo^s) = (w(ixo^s, mom(1))*block%B0(ixo^s,idim,0)) / rho(ixo^s)
830 end subroutine ffhd_get_v_idim
831
832 subroutine ffhd_get_cmax_origin(wprim,x,ixI^L,ixO^L,idim,cmax)
834 integer, intent(in) :: ixi^l, ixo^l, idim
835 ! w in primitive form
836 double precision, intent(in) :: wprim(ixi^s, nw), x(ixi^s,1:ndim)
837 double precision, intent(inout) :: cmax(ixi^s)
838
839 if(ffhd_energy) then
840 cmax(ixo^s)=dsqrt(ffhd_gamma*wprim(ixo^s,p_)/wprim(ixo^s,rho_))
841 else
842 cmax(ixo^s)=dsqrt(ffhd_gamma*ffhd_adiab*wprim(ixo^s,rho_)**gamma_1)
843 end if
844 cmax(ixo^s)=dabs(wprim(ixo^s,mom(1))*block%B0(ixo^s,idim,0))+cmax(ixo^s)
845
846 end subroutine ffhd_get_cmax_origin
847
848 subroutine ffhd_get_cs2max(w,x,ixI^L,ixO^L,cs2max)
850 integer, intent(in) :: ixi^l, ixo^l
851 double precision, intent(in) :: w(ixi^s, nw), x(ixi^s,1:ndim)
852 double precision, intent(inout) :: cs2max
853 double precision :: cs2(ixi^s)
854
855 call ffhd_get_csound2(w,x,ixi^l,ixo^l,cs2)
856 cs2max=maxval(cs2(ixo^s))
857 end subroutine ffhd_get_cs2max
858
859 subroutine ffhd_get_a2max(w,x,ixI^L,ixO^L,a2max)
861 use mod_geometry
862 integer, intent(in) :: ixi^l, ixo^l
863 double precision, intent(in) :: w(ixi^s, nw), x(ixi^s,1:ndim)
864 double precision, intent(inout) :: a2max(ndim)
865 double precision :: a2(ixi^s,ndim,nw)
866 integer :: gxo^l,hxo^l,jxo^l,kxo^l,i,j
867
868 if(.not.slab_uniform)then
869 call mpistop("subroutine get_a2max in mod_ffhd_phys adopts cartesian setting")
870 endif
871 a2=zero
872 do i = 1,ndim
873 !> 4th order
874 hxo^l=ixo^l-kr(i,^d);
875 gxo^l=hxo^l-kr(i,^d);
876 jxo^l=ixo^l+kr(i,^d);
877 kxo^l=jxo^l+kr(i,^d);
878 a2(ixo^s,i,1:nw)=dabs(-w(kxo^s,1:nw)+16.d0*w(jxo^s,1:nw)&
879 -30.d0*w(ixo^s,1:nw)+16.d0*w(hxo^s,1:nw)-w(gxo^s,1:nw))
880 a2max(i)=maxval(a2(ixo^s,i,1:nw))/12.d0/dxlevel(i)**2
881 end do
882 end subroutine ffhd_get_a2max
883
884 subroutine ffhd_get_tcutoff(ixI^L,ixO^L,w,x,Tco_local,Tmax_local)
886 use mod_geometry
887 integer, intent(in) :: ixi^l,ixo^l
888 double precision, intent(in) :: x(ixi^s,1:ndim)
889 double precision, intent(inout) :: w(ixi^s,1:nw)
890 double precision, intent(out) :: tco_local,tmax_local
891 double precision, parameter :: trac_delta=0.25d0
892 double precision :: tmp1(ixi^s),te(ixi^s),lts(ixi^s)
893 double precision, dimension(ixI^S,1:ndir) :: bunitvec
894 double precision, dimension(ixI^S,1:ndim) :: gradt
895 double precision :: bdir(ndim)
896 double precision :: ltrc,ltrp,altr(ixi^s)
897 integer :: idims,jxo^l,hxo^l,ixa^d,ixb^d
898 integer :: jxp^l,hxp^l,ixp^l,ixq^l
899 logical :: lrlt(ixi^s)
900
901 call ffhd_get_temperature(w,x,ixi^l,ixi^l,te)
902 tco_local=zero
903 tmax_local=maxval(te(ixo^s))
904
905 {^ifoned
906 select case(ffhd_trac_type)
907 case(0)
908 !> test case, fixed cutoff temperature
909 block%wextra(ixi^s,tcoff_)=2.5d5/unit_temperature
910 case(1)
911 hxo^l=ixo^l-1;
912 jxo^l=ixo^l+1;
913 lts(ixo^s)=0.5d0*dabs(te(jxo^s)-te(hxo^s))/te(ixo^s)
914 lrlt=.false.
915 where(lts(ixo^s) > trac_delta)
916 lrlt(ixo^s)=.true.
917 end where
918 if(any(lrlt(ixo^s))) then
919 tco_local=maxval(te(ixo^s), mask=lrlt(ixo^s))
920 end if
921 case(2)
922 !> iijima et al. 2021, LTRAC method
923 ltrc=1.5d0
924 ltrp=4.d0
925 ixp^l=ixo^l^ladd1;
926 hxo^l=ixo^l-1;
927 jxo^l=ixo^l+1;
928 hxp^l=ixp^l-1;
929 jxp^l=ixp^l+1;
930 lts(ixp^s)=0.5d0*dabs(te(jxp^s)-te(hxp^s))/te(ixp^s)
931 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
932 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
933 block%wextra(ixo^s,tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
934 case default
935 call mpistop("ffhd_trac_type not allowed for 1D simulation")
936 end select
937 }
938 {^nooned
939 select case(ffhd_trac_type)
940 case(0)
941 !> test case, fixed cutoff temperature
942 if(slab_uniform) then
943 !> assume cgs units
944 block%wextra(ixi^s,tcoff_)=max(min(3.d5/unit_temperature,6.d5/unit_temperature-3.d-4/unit_temperature*unit_length*x(ixi^s,ndim)),zero)
945 else
946 block%wextra(ixi^s,tcoff_)=2.5d5/unit_temperature
947 end if
948 case(1,4,6)
949 do idims=1,ndim
950 call gradient(te,ixi^l,ixo^l,idims,tmp1)
951 gradt(ixo^s,idims)=tmp1(ixo^s)
952 end do
953 bunitvec(ixo^s,:)=block%B0(ixo^s,:,0)
954 if(ffhd_trac_type .gt. 1) then
955 ! B direction at cell center
956 bdir=zero
957 {do ixa^d=0,1\}
958 ixb^d=(ixomin^d+ixomax^d-1)/2+ixa^d;
959 bdir(1:ndim)=bdir(1:ndim)+bunitvec(ixb^d,1:ndim)
960 {end do\}
961 if(sum(bdir(:)**2) .gt. zero) then
962 bdir(1:ndim)=bdir(1:ndim)/dsqrt(sum(bdir(:)**2))
963 end if
964 block%special_values(3:ndim+2)=bdir(1:ndim)
965 end if
966 tmp1(ixo^s)=dsqrt(sum(bunitvec(ixo^s,:)**2,dim=ndim+1))
967 where(tmp1(ixo^s)/=0.d0)
968 tmp1(ixo^s)=1.d0/tmp1(ixo^s)
969 else where
970 tmp1(ixo^s)=bigdouble
971 end where
972 ! b unit vector: magnetic field direction vector
973 do idims=1,ndim
974 bunitvec(ixo^s,idims)=bunitvec(ixo^s,idims)*tmp1(ixo^s)
975 end do
976 ! temperature length scale inversed
977 lts(ixo^s)=dabs(sum(gradt(ixo^s,1:ndim)*bunitvec(ixo^s,1:ndim),dim=ndim+1))/te(ixo^s)
978 ! fraction of cells size to temperature length scale
979 if(slab_uniform) then
980 lts(ixo^s)=minval(dxlevel)*lts(ixo^s)
981 else
982 lts(ixo^s)=minval(block%ds(ixo^s,:),dim=ndim+1)*lts(ixo^s)
983 end if
984 lrlt=.false.
985 where(lts(ixo^s) > trac_delta)
986 lrlt(ixo^s)=.true.
987 end where
988 if(any(lrlt(ixo^s))) then
989 block%special_values(1)=maxval(te(ixo^s), mask=lrlt(ixo^s))
990 else
991 block%special_values(1)=zero
992 end if
993 block%special_values(2)=tmax_local
994 case(2)
995 !> iijima et al. 2021, LTRAC method
996 ltrc=1.5d0
997 ltrp=4.d0
998 ixp^l=ixo^l^ladd2;
999 do idims=1,ndim
1000 ixq^l=ixp^l;
1001 hxp^l=ixp^l;
1002 jxp^l=ixp^l;
1003 select case(idims)
1004 {case(^d)
1005 ixqmin^d=ixqmin^d+1
1006 ixqmax^d=ixqmax^d-1
1007 hxpmax^d=ixpmin^d
1008 jxpmin^d=ixpmax^d
1009 \}
1010 end select
1011 call gradient(te,ixi^l,ixq^l,idims,gradt(ixi^s,idims))
1012 call gradientf(te,x,ixi^l,hxp^l,idims,gradt(ixi^s,idims),nghostcells,.true.)
1013 call gradientf(te,x,ixi^l,jxp^l,idims,gradt(ixi^s,idims),nghostcells,.false.)
1014 end do
1015 bunitvec(ixp^s,:)=block%B0(ixp^s,:,0)
1016 lts(ixp^s)=dabs(sum(gradt(ixp^s,1:ndim)*bunitvec(ixp^s,1:ndim),dim=ndim+1))/te(ixp^s)
1017 if(slab_uniform) then
1018 lts(ixp^s)=minval(dxlevel)*lts(ixp^s)
1019 else
1020 lts(ixp^s)=minval(block%ds(ixp^s,:),dim=ndim+1)*lts(ixp^s)
1021 end if
1022 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
1023
1024 altr=zero
1025 ixp^l=ixo^l^ladd1;
1026 do idims=1,ndim
1027 hxo^l=ixp^l-kr(idims,^d);
1028 jxo^l=ixp^l+kr(idims,^d);
1029 altr(ixp^s)=altr(ixp^s)+0.25d0*(lts(hxo^s)+two*lts(ixp^s)+lts(jxo^s))*bunitvec(ixp^s,idims)**2
1030 end do
1031 block%wextra(ixp^s,tcoff_)=te(ixp^s)*altr(ixp^s)**0.4d0
1032 case(3,5)
1033 !> do nothing here
1034 case default
1035 call mpistop("unknown ffhd_trac_type")
1036 end select
1037 }
1038 end subroutine ffhd_get_tcutoff
1039
1040 subroutine ffhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1042 integer, intent(in) :: ixi^l, ixo^l, idim
1043 double precision, intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1044 double precision, intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1045 double precision, intent(in) :: x(ixi^s,1:ndim)
1046 double precision, intent(inout) :: cmax(ixi^s,1:number_species)
1047 double precision, intent(inout), optional :: cmin(ixi^s,1:number_species)
1048 double precision, intent(in) :: hspeed(ixi^s,1:number_species)
1049 double precision :: wmean(ixi^s,nw)
1050 double precision, dimension(ixI^S) :: umean, dmean, csoundl, csoundr, tmp1,tmp2,tmp3
1051
1052 select case (boundspeed)
1053 case (1)
1054 ! This implements formula (10.52) from "Riemann Solvers and Numerical
1055 ! Methods for Fluid Dynamics" by Toro.
1056 tmp1(ixo^s)=dsqrt(wlp(ixo^s,rho_))
1057 tmp2(ixo^s)=dsqrt(wrp(ixo^s,rho_))
1058 tmp3(ixo^s)=1.d0/(tmp1(ixo^s)+tmp2(ixo^s))
1059 umean(ixo^s)=(wlp(ixo^s,mom(1))*tmp1(ixo^s)&
1060 +wrp(ixo^s,mom(1))*tmp2(ixo^s))*tmp3(ixo^s)
1061 umean(ixo^s)=umean(ixo^s)*block%B0(ixo^s,idim,idim)
1062 call ffhd_get_csound2(wlc,x,ixi^l,ixo^l,csoundl)
1063 call ffhd_get_csound2(wrc,x,ixi^l,ixo^l,csoundr)
1064 dmean(ixo^s)=(tmp1(ixo^s)*csoundl(ixo^s)+tmp2(ixo^s)*csoundr(ixo^s)) * &
1065 tmp3(ixo^s) + 0.5d0*tmp1(ixo^s)*tmp2(ixo^s)*tmp3(ixo^s)**2 * &
1066 ((wrp(ixo^s,mom(1))-wlp(ixo^s,mom(1)))*block%B0(ixo^s,idim,idim))**2
1067 dmean(ixo^s)=dsqrt(dmean(ixo^s))
1068 if(present(cmin)) then
1069 cmin(ixo^s,1)=umean(ixo^s)-dmean(ixo^s)
1070 cmax(ixo^s,1)=umean(ixo^s)+dmean(ixo^s)
1071 else
1072 cmax(ixo^s,1)=dabs(umean(ixo^s))+dmean(ixo^s)
1073 end if
1074 case (2)
1075 wmean(ixo^s,1:nwflux)=0.5d0*(wlc(ixo^s,1:nwflux)+wrc(ixo^s,1:nwflux))
1076 tmp1(ixo^s)=wmean(ixo^s,mom(1))*block%B0(ixo^s,idim,idim)/wmean(ixo^s,rho_)
1077 call ffhd_get_csound2(wmean,x,ixi^l,ixo^l,csoundr)
1078 csoundr(ixo^s) = dsqrt(csoundr(ixo^s))
1079 if(present(cmin)) then
1080 cmax(ixo^s,1)=max(tmp1(ixo^s)+csoundr(ixo^s),zero)
1081 cmin(ixo^s,1)=min(tmp1(ixo^s)-csoundr(ixo^s),zero)
1082 else
1083 cmax(ixo^s,1)=dabs(tmp1(ixo^s))+csoundr(ixo^s)
1084 end if
1085 case (3)
1086 ! Miyoshi 2005 JCP 208, 315 equation (67)
1087 call ffhd_get_csound2(wlc,x,ixi^l,ixo^l,csoundl)
1088 call ffhd_get_csound2(wrc,x,ixi^l,ixo^l,csoundr)
1089 csoundl(ixo^s)=max(dsqrt(csoundl(ixo^s)),dsqrt(csoundr(ixo^s)))
1090 if(present(cmin)) then
1091 cmin(ixo^s,1)=min(wlp(ixo^s,mom(1))*block%B0(ixo^s,idim,idim),&
1092 wrp(ixo^s,mom(1))*block%B0(ixo^s,idim,idim))-csoundl(ixo^s)
1093 cmax(ixo^s,1)=max(wlp(ixo^s,mom(1))*block%B0(ixo^s,idim,idim),&
1094 wrp(ixo^s,mom(1))*block%B0(ixo^s,idim,idim))+csoundl(ixo^s)
1095 else
1096 cmax(ixo^s,1)=max(wlp(ixo^s,mom(1))*block%B0(ixo^s,idim,idim),&
1097 wrp(ixo^s,mom(1))*block%B0(ixo^s,idim,idim))+csoundl(ixo^s)
1098 end if
1099 end select
1100 end subroutine ffhd_get_cbounds
1101
1102 subroutine ffhd_get_pthermal_iso(w,x,ixI^L,ixO^L,pth)
1104
1105 integer, intent(in) :: ixi^l, ixo^l
1106 double precision, intent(in) :: w(ixi^s,nw)
1107 double precision, intent(in) :: x(ixi^s,1:ndim)
1108 double precision, intent(out):: pth(ixi^s)
1109
1110 call ffhd_get_rho(w,x,ixi^l,ixo^l,pth)
1111 pth(ixo^s)=ffhd_adiab*pth(ixo^s)**ffhd_gamma
1112 end subroutine ffhd_get_pthermal_iso
1113
1114 subroutine ffhd_get_pthermal_origin(w,x,ixI^L,ixO^L,pth)
1117 integer, intent(in) :: ixi^l, ixo^l
1118 double precision, intent(in) :: w(ixi^s,nw)
1119 double precision, intent(in) :: x(ixi^s,1:ndim)
1120 double precision, intent(out):: pth(ixi^s)
1121 integer :: iw, ix^d
1122
1123 pth(ixo^s)=gamma_1*(w(ixo^s,e_)-ffhd_kin_en(w,ixi^l,ixo^l))
1124 if (fix_small_values) then
1125 {do ix^db= ixo^lim^db\}
1126 if(pth(ix^d)<small_pressure) then
1127 pth(ix^d)=small_pressure
1128 end if
1129 {end do^D&\}
1130 elseif(check_small_values) then
1131 {do ix^db= ixo^lim^db\}
1132 if(pth(ix^d)<small_pressure) then
1133 write(*,*) "Error: small value of gas pressure",pth(ix^d),&
1134 " encountered when call ffhd_get_pthermal"
1135 write(*,*) "Iteration: ", it, " Time: ", global_time
1136 write(*,*) "Location: ", x(ix^d,:)
1137 write(*,*) "Cell number: ", ix^d
1138 do iw=1,nw
1139 write(*,*) trim(cons_wnames(iw)),": ",w(ix^d,iw)
1140 end do
1141 ! use erroneous arithmetic operation to crash the run
1142 if(trace_small_values) write(*,*) dsqrt(pth(ix^d)-bigdouble)
1143 write(*,*) "Saving status at the previous time step"
1144 crash=.true.
1145 end if
1146 {end do^D&\}
1147 end if
1148 end subroutine ffhd_get_pthermal_origin
1149
1150 subroutine ffhd_get_temperature_from_te(w, x, ixI^L, ixO^L, res)
1152 integer, intent(in) :: ixi^l, ixo^l
1153 double precision, intent(in) :: w(ixi^s, 1:nw)
1154 double precision, intent(in) :: x(ixi^s, 1:ndim)
1155 double precision, intent(out):: res(ixi^s)
1156
1157 res(ixo^s) = w(ixo^s, te_)
1158 end subroutine ffhd_get_temperature_from_te
1159
1160 subroutine ffhd_get_temperature_from_eint(w, x, ixI^L, ixO^L, res)
1162 integer, intent(in) :: ixi^l, ixo^l
1163 double precision, intent(in) :: w(ixi^s, 1:nw)
1164 double precision, intent(in) :: x(ixi^s, 1:ndim)
1165 double precision, intent(out):: res(ixi^s)
1166 double precision :: r(ixi^s)
1167
1168 call ffhd_get_rfactor(w,x,ixi^l,ixo^l,r)
1169 res(ixo^s) = gamma_1 * w(ixo^s, e_)/(w(ixo^s,rho_)*r(ixo^s))
1170 end subroutine ffhd_get_temperature_from_eint
1171
1172 subroutine ffhd_get_temperature_from_etot(w, x, ixI^L, ixO^L, res)
1174 integer, intent(in) :: ixi^l, ixo^l
1175 double precision, intent(in) :: w(ixi^s, 1:nw)
1176 double precision, intent(in) :: x(ixi^s, 1:ndim)
1177 double precision, intent(out):: res(ixi^s)
1178
1179 double precision :: r(ixi^s)
1180
1181 call ffhd_get_rfactor(w,x,ixi^l,ixo^l,r)
1182 call ffhd_get_pthermal(w,x,ixi^l,ixo^l,res)
1183 res(ixo^s)=res(ixo^s)/(r(ixo^s)*w(ixo^s,rho_))
1184 end subroutine ffhd_get_temperature_from_etot
1185
1186 subroutine ffhd_get_csound2(w,x,ixI^L,ixO^L,csound2)
1188 integer, intent(in) :: ixi^l, ixo^l
1189 double precision, intent(in) :: w(ixi^s,nw)
1190 double precision, intent(in) :: x(ixi^s,1:ndim)
1191 double precision, intent(out) :: csound2(ixi^s)
1192 double precision :: rho(ixi^s)
1193
1194 call ffhd_get_rho(w,x,ixi^l,ixo^l,rho)
1195 if(ffhd_energy) then
1196 call ffhd_get_pthermal(w,x,ixi^l,ixo^l,csound2)
1197 csound2(ixo^s)=ffhd_gamma*csound2(ixo^s)/rho(ixo^s)
1198 else
1199 csound2(ixo^s)=ffhd_gamma*ffhd_adiab*rho(ixo^s)**gamma_1
1200 end if
1201 end subroutine ffhd_get_csound2
1202
1203 subroutine ffhd_get_flux(wC,w,x,ixI^L,ixO^L,idim,f)
1205 use mod_geometry
1206 integer, intent(in) :: ixi^l, ixo^l, idim
1207 ! conservative w
1208 double precision, intent(in) :: wc(ixi^s,nw)
1209 ! primitive w
1210 double precision, intent(in) :: w(ixi^s,nw)
1211 double precision, intent(in) :: x(ixi^s,1:ndim)
1212 double precision,intent(out) :: f(ixi^s,nwflux)
1213 double precision :: ptotal(ixo^s)
1214
1215 f(ixo^s,rho_)=w(ixo^s,mom(1))*w(ixo^s,rho_)*block%B0(ixo^s,idim,idim)
1216
1217 if(ffhd_energy) then
1218 ptotal(ixo^s)=w(ixo^s,p_)
1219 else
1220 ptotal(ixo^s)=ffhd_adiab*w(ixo^s,rho_)**ffhd_gamma
1221 end if
1222
1223 ! Get flux of momentum
1224 f(ixo^s,mom(1))=(wc(ixo^s,mom(1))*w(ixo^s,mom(1))+ptotal(ixo^s))*block%B0(ixo^s,idim,idim)
1225
1226 ! Get flux of energy
1227 if(ffhd_energy) then
1228 f(ixo^s,e_)=w(ixo^s,mom(1))*(wc(ixo^s,e_)+ptotal(ixo^s))*block%B0(ixo^s,idim,idim)
1230 f(ixo^s,e_)=f(ixo^s,e_)+w(ixo^s,q_)*block%B0(ixo^s,idim,idim)
1231 f(ixo^s,q_)=zero
1232 end if
1233 end if
1234 end subroutine ffhd_get_flux
1235
1236 subroutine ffhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
1241 integer, intent(in) :: ixi^l, ixo^l
1242 double precision, intent(in) :: qdt,dtfactor
1243 double precision, intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw), x(ixi^s,1:ndim)
1244 double precision, intent(inout) :: w(ixi^s,1:nw)
1245 logical, intent(in) :: qsourcesplit
1246 logical, intent(inout) :: active
1247
1248 if (.not. qsourcesplit) then
1249 active = .true.
1250 call add_punitb(qdt,ixi^l,ixo^l,wct,w,x,wctprim)
1252 call add_hypertc_source(qdt,ixi^l,ixo^l,wct,w,x,wctprim)
1253 end if
1254 end if
1255
1256 if(ffhd_radiative_cooling) then
1257 call radiative_cooling_add_source(qdt,ixi^l,ixo^l,wct,wctprim,&
1258 w,x,qsourcesplit,active, rc_fl)
1259 end if
1260
1261 if(ffhd_viscosity) then
1262 call viscosity_add_source(qdt,ixi^l,ixo^l,wct,&
1263 w,x,ffhd_energy,qsourcesplit,active)
1264 end if
1265
1266 if(ffhd_gravity) then
1267 call gravity_add_source(qdt,ixi^l,ixo^l,wct,wctprim,&
1268 w,x,ffhd_energy,.false.,qsourcesplit,active)
1269 end if
1270
1271 ! update temperature from new pressure, density, and old ionization degree
1273 if(.not.qsourcesplit) then
1274 active = .true.
1275 call ffhd_update_temperature(ixi^l,ixo^l,wct,w,x)
1276 end if
1277 end if
1278 end subroutine ffhd_add_source
1279
1280 subroutine add_punitb(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
1282 use mod_geometry
1283 integer, intent(in) :: ixi^l,ixo^l
1284 double precision, intent(in) :: qdt
1285 double precision, intent(in) :: wct(ixi^s,1:nw),x(ixi^s,1:ndim)
1286 double precision, intent(in) :: wctprim(ixi^s,1:nw)
1287 double precision, intent(inout) :: w(ixi^s,1:nw)
1288
1289 integer :: idims,hxo^l
1290 double precision :: divb(ixi^s)
1291 double precision :: rhovpar(ixi^s),gradrhov(ixi^s)
1292
1293 divb=zero
1294 if(slab_uniform) then
1295 do idims=1,ndim
1296 hxo^l=ixo^l-kr(idims,^d);
1297 divb(ixo^s)=divb(ixo^s)+(block%B0(ixo^s,idims,idims)-block%B0(hxo^s,idims,idims))/dxlevel(idims)
1298 end do
1299 else
1300 call divvector(block%B0(ixi^s,1:ndir,0),ixi^l,ixo^l,divb)
1301 end if
1302 w(ixo^s,mom(1))=w(ixo^s,mom(1))+qdt*wctprim(ixo^s,p_)*divb(ixo^s)
1303 end subroutine add_punitb
1304
1305 subroutine ffhd_get_rho(w,x,ixI^L,ixO^L,rho)
1307 integer, intent(in) :: ixi^l, ixo^l
1308 double precision, intent(in) :: w(ixi^s,1:nw),x(ixi^s,1:ndim)
1309 double precision, intent(out) :: rho(ixi^s)
1310
1311 rho(ixo^s) = w(ixo^s,rho_)
1312 end subroutine ffhd_get_rho
1313
1314 subroutine ffhd_handle_small_ei(w, x, ixI^L, ixO^L, ie, subname)
1317 integer, intent(in) :: ixi^l,ixo^l, ie
1318 double precision, intent(inout) :: w(ixi^s,1:nw)
1319 double precision, intent(in) :: x(ixi^s,1:ndim)
1320 character(len=*), intent(in) :: subname
1321 integer :: idir
1322 logical :: flag(ixi^s,1:nw)
1323 double precision :: rho(ixi^s)
1324
1325 flag=.false.
1326 where(w(ixo^s,ie)<small_e) flag(ixo^s,ie)=.true.
1327 if(any(flag(ixo^s,ie))) then
1328 select case (small_values_method)
1329 case ("replace")
1330 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e
1331 case ("average")
1332 call small_values_average(ixi^l, ixo^l, w, x, flag, ie)
1333 case default
1334 w(ixo^s,e_)=w(ixo^s,e_)*gamma_1
1335 call ffhd_get_rho(w,x,ixi^l,ixo^l,rho)
1336 w(ixo^s,mom(1)) = w(ixo^s,mom(1))/rho(ixo^s)
1337 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
1338 end select
1339 end if
1340 end subroutine ffhd_handle_small_ei
1341
1342 subroutine ffhd_update_temperature(ixI^L,ixO^L,wCT,w,x)
1345 integer, intent(in) :: ixi^l, ixo^l
1346 double precision, intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:ndim)
1347 double precision, intent(inout) :: w(ixi^s,1:nw)
1348 double precision :: iz_h(ixo^s),iz_he(ixo^s), pth(ixi^s)
1349
1350 call ionization_degree_from_temperature(ixi^l,ixo^l,wct(ixi^s,te_),iz_h,iz_he)
1351 call ffhd_get_pthermal(w,x,ixi^l,ixo^l,pth)
1352 w(ixo^s,te_)=(2.d0+3.d0*he_abundance)*pth(ixo^s)/(w(ixo^s,rho_)*(1.d0+iz_h(ixo^s)+&
1353 he_abundance*(iz_he(ixo^s)*(iz_he(ixo^s)+1.d0)+1.d0)))
1354 end subroutine ffhd_update_temperature
1355
1356 subroutine ffhd_get_dt(w,ixI^L,ixO^L,dtnew,dx^D,x)
1358 use mod_usr_methods
1361 use mod_gravity, only: gravity_get_dt
1362 integer, intent(in) :: ixi^l, ixo^l
1363 double precision, intent(inout) :: dtnew
1364 double precision, intent(in) :: dx^d
1365 double precision, intent(in) :: w(ixi^s,1:nw)
1366 double precision, intent(in) :: x(ixi^s,1:ndim)
1367
1368 dtnew = bigdouble
1369
1370 if(ffhd_radiative_cooling) then
1371 call cooling_get_dt(w,ixi^l,ixo^l,dtnew,dx^d,x,rc_fl)
1372 end if
1373
1374 if(ffhd_viscosity) then
1375 call viscosity_get_dt(w,ixi^l,ixo^l,dtnew,dx^d,x)
1376 end if
1377
1378 if(ffhd_gravity) then
1379 call gravity_get_dt(w,ixi^l,ixo^l,dtnew,dx^d,x)
1380 end if
1381 end subroutine ffhd_get_dt
1382
1383 subroutine ffhd_add_source_geom(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
1385 integer, intent(in) :: ixi^l, ixo^l
1386 double precision, intent(in) :: qdt, dtfactor,x(ixi^s,1:ndim)
1387 double precision, intent(inout) :: wct(ixi^s,1:nw), wprim(ixi^s,1:nw),w(ixi^s,1:nw)
1388
1389 ! no geometric source terms needed for ffhd, no divergences of tensors
1390 end subroutine ffhd_add_source_geom
1391
1392 function ffhd_kin_en_origin(w, ixI^L, ixO^L, inv_rho) result(ke)
1393 use mod_global_parameters, only: nw, ndim,block
1394 integer, intent(in) :: ixi^l, ixo^l
1395 double precision, intent(in) :: w(ixi^s, nw)
1396 double precision :: ke(ixo^s)
1397 double precision, intent(in), optional :: inv_rho(ixo^s)
1398
1399 if(present(inv_rho)) then
1400 ke(ixo^s)=0.5d0*w(ixo^s,mom(1))**2*inv_rho(ixo^s)
1401 else
1402 ke(ixo^s)=0.5d0*w(ixo^s,mom(1))**2/w(ixo^s,rho_)
1403 end if
1404 end function ffhd_kin_en_origin
1405
1406 subroutine rfactor_from_temperature_ionization(w,x,ixI^L,ixO^L,Rfactor)
1409 integer, intent(in) :: ixi^l, ixo^l
1410 double precision, intent(in) :: w(ixi^s,1:nw)
1411 double precision, intent(in) :: x(ixi^s,1:ndim)
1412 double precision, intent(out):: rfactor(ixi^s)
1413 double precision :: iz_h(ixo^s),iz_he(ixo^s)
1414
1415 call ionization_degree_from_temperature(ixi^l,ixo^l,w(ixi^s,te_),iz_h,iz_he)
1416 rfactor(ixo^s)=(1.d0+iz_h(ixo^s)+0.1d0*(1.d0+iz_he(ixo^s)*(1.d0+iz_he(ixo^s))))/(2.d0+3.d0*he_abundance)
1417 end subroutine rfactor_from_temperature_ionization
1418
1419 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
1421 integer, intent(in) :: ixi^l, ixo^l
1422 double precision, intent(in) :: w(ixi^s,1:nw)
1423 double precision, intent(in) :: x(ixi^s,1:ndim)
1424 double precision, intent(out):: rfactor(ixi^s)
1425
1426 rfactor(ixo^s)=rr
1427 end subroutine rfactor_from_constant_ionization
1428
1429 subroutine get_tau(ixI^L,ixO^L,w,Te,tau,sigT5)
1431 integer, intent(in) :: ixi^l, ixo^l
1432 double precision, dimension(ixI^S,1:nw), intent(in) :: w
1433 double precision, dimension(ixI^S), intent(in) :: te
1434 double precision, dimension(ixI^S), intent(out) :: tau,sigt5
1435 double precision :: taumin
1436 double precision, dimension(ixI^S) :: sigt7,eint
1437
1438 taumin=4.d0
1439 !> w supposed to be wCTprim here
1440 if(ffhd_trac) then
1441 where(te(ixo^s) .lt. block%wextra(ixo^s,tcoff_))
1442 sigt5(ixo^s)=hypertc_kappa*dsqrt(block%wextra(ixo^s,tcoff_)**5)
1443 sigt7(ixo^s)=sigt5(ixo^s)*block%wextra(ixo^s,tcoff_)
1444 else where
1445 sigt5(ixo^s)=hypertc_kappa*dsqrt(te(ixo^s)**5)
1446 sigt7(ixo^s)=sigt5(ixo^s)*te(ixo^s)
1447 end where
1448 else
1449 sigt5(ixo^s)=hypertc_kappa*dsqrt(te(ixo^s)**5)
1450 sigt7(ixo^s)=sigt5(ixo^s)*te(ixo^s)
1451 end if
1452 eint(ixo^s)=w(ixo^s,p_)*inv_gamma_1
1453 tau(ixo^s)=max(taumin*dt,sigt7(ixo^s)/eint(ixo^s)/cs2max_global)
1454 end subroutine get_tau
1455
1456 subroutine add_hypertc_source(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
1458 use mod_geometry
1459 integer, intent(in) :: ixi^l,ixo^l
1460 double precision, intent(in) :: qdt
1461 double precision, dimension(ixI^S,1:ndim), intent(in) :: x
1462 double precision, dimension(ixI^S,1:nw), intent(in) :: wct,wctprim
1463 double precision, dimension(ixI^S,1:nw), intent(inout) :: w
1464 integer :: idims
1465 integer :: hxc^l,hxo^l,ixc^l,jxc^l,jxo^l,kxc^l
1466 double precision :: invdx
1467 double precision, dimension(ixI^S) :: te,tau,sigt,htc_qsrc,tface,gradt
1468
1469 te(ixi^s)=wctprim(ixi^s,p_)/wct(ixi^s,rho_)
1470 call get_tau(ixi^l,ixo^l,wctprim,te,tau,sigt)
1471 htc_qsrc=zero
1472 select case (coordinate)
1473 case (cartesian)
1474 do idims=1,ndim
1475 invdx=1.d0/dxlevel(idims)
1476 ixc^l=ixo^l;
1477 ixcmin^d=ixomin^d-kr(idims,^d);ixcmax^d=ixomax^d;
1478 jxc^l=ixc^l+kr(idims,^d);
1479 kxc^l=jxc^l+kr(idims,^d);
1480 hxc^l=ixc^l-kr(idims,^d);
1481 hxo^l=ixo^l-kr(idims,^d);
1482 ! T_(i+1/2)=[7(T_i+T_i+1)-(T_i-1+T_i+2)]/12 or a 4-point weighted face-averaged value
1483 tface(ixc^s)=(7.d0*(te(ixc^s)+te(jxc^s))-(te(hxc^s)+te(kxc^s)))/12.d0
1484 htc_qsrc(ixo^s)=htc_qsrc(ixo^s)+sigt(ixo^s)*block%B0(ixo^s,idims,0)*(tface(ixo^s)-tface(hxo^s))*invdx
1485 end do
1486 case (cylindrical,spherical)
1487 do idims=1,ndim
1488 call gradient(te,ixi^l,ixo^l,idims,gradt)
1489 htc_qsrc(ixo^s)=htc_qsrc(ixo^s)+sigt(ixo^s)*block%B0(ixo^s,idims,0)*gradt(ixo^s)
1490 end do
1491 case default
1492 ! Cartesian_stretched and Cartesian_expansion not dealt with here
1493 call mpistop("unknown geometry in add_hypertc_source")
1494 end select
1495 htc_qsrc(ixo^s)=(htc_qsrc(ixo^s)+wct(ixo^s,q_))/tau(ixo^s)
1496 w(ixo^s,q_)=w(ixo^s,q_)-qdt*htc_qsrc(ixo^s)
1497 end subroutine add_hypertc_source
1498
1499end module mod_ffhd_phys
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for physical and numeric constants.
double precision, parameter bigdouble
A very large real number.
subroutine add_convert_method(phys_convert_vars, nwc, dataset_names, file_suffix)
Definition mod_convert.t:59
Frozen-field hydrodynamics module.
integer, public, protected te_
Indices of temperature.
integer, public, protected ffhd_trac_type
Which TRAC method is used.
double precision, public hypertc_kappa
The thermal conductivity kappa in hyperbolic thermal conduction.
integer, public, protected e_
Index of the energy density (-1 if not present)
double precision, public ffhd_gamma
The adiabatic index.
logical, public, protected eq_state_units
double precision, public ffhd_adiab
The adiabatic constant.
procedure(sub_get_pthermal), pointer, public ffhd_get_temperature
logical, public, protected ffhd_hyperbolic_thermal_conduction
Whether hyperbolic type thermal conduction is used.
type(rc_fluid), allocatable, public rc_fl
type of fluid for radiative cooling
integer, public, protected rho_
Index of the density (in the w array)
integer, public, protected tcoff_
Index of the cutoff temperature for the TRAC method.
procedure(sub_get_pthermal), pointer, public ffhd_get_pthermal
subroutine, public ffhd_get_rho(w, x, ixil, ixol, rho)
logical, public, protected ffhd_partial_ionization
Whether plasma is partially ionized.
procedure(sub_convert), pointer, public ffhd_to_conserved
integer, dimension(:), allocatable, public, protected mom
Indices of the momentum density.
double precision, public, protected h_ion_fr
Ionization fraction of H H_ion_fr = H+/(H+ + H)
procedure(fun_kin_en), pointer, public ffhd_kin_en
subroutine, public ffhd_phys_init()
procedure(sub_get_v), pointer, public ffhd_get_v
subroutine, public ffhd_get_csound2(w, x, ixil, ixol, csound2)
logical, public, protected ffhd_energy
Whether an energy equation is used.
double precision, public, protected rr
type(tc_fluid), allocatable, public tc_fl
type of fluid for thermal conduction
type(te_fluid), allocatable, public te_fl_ffhd
type of fluid for thermal emission synthesis
double precision, public, protected he_abundance
Helium abundance over Hydrogen.
logical, public, protected ffhd_viscosity
Whether viscosity is added.
logical, public, protected ffhd_radiative_cooling
Whether radiative cooling is added.
subroutine, public ffhd_get_v_idim(w, x, ixil, ixol, idim, v)
integer, public, protected q_
procedure(sub_convert), pointer, public ffhd_to_primitive
integer, public, protected tweight_
double precision, public, protected he_ion_fr2
Ratio of number He2+ / number He+ + He2+ He_ion_fr2 = He2+/(He2+ + He+)
logical, public, protected ffhd_trac
Whether TRAC method is used.
logical, public, protected ffhd_thermal_conduction
Whether thermal conduction is used.
subroutine, public ffhd_ei_to_e(ixil, ixol, w, x)
logical, public, protected ffhd_gravity
Whether gravity is added.
integer, public, protected p_
Index of the gas pressure (-1 if not present) should equal e_.
double precision, public, protected ffhd_trac_mask
Height of the mask used in the TRAC method.
double precision, public, protected he_ion_fr
Ionization fraction of He He_ion_fr = (He2+ + He+)/(He2+ + He+ + He)
integer, public, protected ffhd_trac_finegrid
Distance between two adjacent traced magnetic field lines (in finest cell size)
subroutine, public ffhd_e_to_ei(ixil, ixol, w, x)
Module for flux conservation near refinement boundaries.
Module with geometry-related routines (e.g., divergence, curl)
Definition mod_geometry.t:2
subroutine divvector(qvec, ixil, ixol, divq, nth_in)
integer coordinate
Definition mod_geometry.t:7
integer, parameter spherical
integer, parameter cartesian
Definition mod_geometry.t:8
integer, parameter cylindrical
subroutine gradient(q, ixil, ixol, idir, gradq, nth_in)
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.
double precision unit_time
Physical scaling factor for time.
double precision unit_density
Physical scaling factor for density.
integer, parameter unitpar
file handle for IO
double precision unit_mass
Physical scaling factor for mass.
integer, dimension(3, 3) kr
Kronecker delta tensor.
double precision unit_numberdensity
Physical scaling factor for number density.
character(len=std_len) convert_type
Which format to use when converting.
double precision unit_pressure
Physical scaling factor for pressure.
integer, parameter ndim
Number of spatial dimensions for grid variables.
double precision unit_length
Physical scaling factor for length.
character(len=std_len), dimension(:), allocatable par_files
Which par files are used as input.
integer mype
The rank of the current MPI task.
double precision, dimension(:), allocatable, parameter d
double precision dt
global time step
integer ndir
Number of spatial dimensions (components) for vector variables.
double precision unit_velocity
Physical scaling factor for velocity.
logical b0field
split magnetic field as background B0 field
logical need_global_cs2max
global value for csound speed
double precision unit_temperature
Physical scaling factor for temperature.
logical si_unit
Use SI units (.true.) or use cgs units (.false.)
double precision, dimension(:,:), allocatable dx
logical phys_trac
Use TRAC for MHD or 1D HD.
logical fix_small_values
fix small values with average or replace methods
double precision, dimension(^nd) dxlevel
store unstretched cell size of current level
double precision cs2max_global
global largest cs2 for hyperbolic thermal conduction
logical slab_uniform
uniform Cartesian geometry or not (stretched Cartesian)
integer boundspeed
bound (left/min and right.max) speed of Riemann fan
integer, parameter unitconvert
integer number_equi_vars
number of equilibrium set variables, besides the mag field
Module for including gravity in (magneto)hydrodynamics simulations.
Definition mod_gravity.t:2
subroutine gravity_get_dt(w, ixil, ixol, dtnew, dxd, x)
Definition mod_gravity.t:87
subroutine gravity_init()
Initialize the module.
Definition mod_gravity.t:26
subroutine gravity_add_source(qdt, ixil, ixol, wct, wctprim, w, x, energy, rhov, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
Definition mod_gravity.t:43
module ionization degree - get ionization degree for given temperature
subroutine ionization_degree_from_temperature(ixil, ixol, te, iz_h, iz_he)
Module containing all the particle routines.
This module defines the procedures of a physics module. It contains function pointers for the various...
Definition mod_physics.t:4
module radiative cooling – add optically thin radiative cooling for HD and MHD
subroutine radiative_cooling_init_params(phys_gamma, he_abund)
Radiative cooling initialization.
subroutine cooling_get_dt(w, ixil, ixol, dtnew, dxd, x, fl)
subroutine radiative_cooling_init(fl, read_params)
subroutine radiative_cooling_add_source(qdt, ixil, ixol, wct, wctprim, w, x, qsourcesplit, active, fl)
Module for handling problematic values in simulations, such as negative pressures.
subroutine, public small_values_average(ixil, ixol, w, x, w_flag, windex)
logical, public trace_small_values
trace small values in the source file using traceback flag of compiler
subroutine, public small_values_error(wprim, x, ixil, ixol, w_flag, subname)
logical, dimension(:), allocatable, public small_values_fix_iw
Whether to apply small value fixes to certain variables.
character(len=20), public small_values_method
How to handle small values.
Generic supertimestepping method 1) in amrvac.par in sts_list set the following parameters which have...
subroutine, public add_sts_method(sts_getdt, sts_set_sources, startvar, nflux, startwbc, nwbc, evolve_b)
subroutine which added programatically a term to be calculated using STS Params: sts_getdt function c...
subroutine, public set_conversion_methods_to_head(sts_before_first_cycle, sts_after_last_cycle)
Set the hooks called before the first cycle and after the last cycle in the STS update This method sh...
subroutine, public set_error_handling_to_head(sts_error_handling)
Set the hook of error handling in the STS update. This method is called before updating the BC....
subroutine, public sts_init()
Initialize sts module.
Thermal conduction for HD and MHD or RHD and RMHD or twofl (plasma-neutral) module Adaptation of mod_...
subroutine, public tc_get_hd_params(fl, read_hd_params)
Init TC coefficients: HD case.
double precision function, public get_tc_dt_mhd(w, ixil, ixol, dxd, x, fl)
Get the explicut timestep for the TC (mhd implementation)
subroutine tc_init_params(phys_gamma)
subroutine, public sts_set_source_tc_mhd(ixil, ixol, w, x, wres, fix_conserve_at_step, my_dt, igrid, nflux, fl)
anisotropic thermal conduction with slope limited symmetric scheme Sharma 2007 Journal of Computation...
subroutine get_euv_image(qunit, fl)
subroutine get_sxr_image(qunit, fl)
subroutine get_euv_spectrum(qunit, fl)
subroutine get_whitelight_image(qunit, fl)
Module with all the methods that users can customize in AMRVAC.
procedure(rfactor), pointer usr_rfactor
procedure(set_equi_vars), pointer usr_set_equi_vars
The module add viscous source terms and check time step.
subroutine viscosity_add_source(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
subroutine viscosity_init(phys_wider_stencil)
Initialize the module.
subroutine viscosity_get_dt(w, ixil, ixol, dtnew, dxd, x)