19 integer,
protected,
public ::
u_ = 1
20 integer,
protected,
public ::
v_ = 2
21 integer,
protected,
public ::
w_ = 3
27 double precision,
public,
protected ::
dtreacpar = 0.5d0
31 integer :: number_of_species = 2
32 integer :: equation_type = 1
33 integer,
parameter :: eq_gray_scott = 1
34 integer,
parameter :: eq_schnakenberg = 2
35 integer,
parameter :: eq_brusselator = 3
36 integer,
parameter :: eq_logistic = 4
37 integer,
parameter :: eq_analyt_hunds = 5
38 integer,
parameter :: eq_belousov_fn = 6
39 integer,
parameter :: eq_ext_brusselator = 7
40 integer,
parameter :: eq_lorenz = 8
43 double precision,
public,
protected ::
d1 = 0.05d0
45 double precision,
public,
protected ::
d2 = 1.0d0
47 double precision,
public,
protected ::
d3 = 1.0d0
50 double precision,
public,
protected ::
sb_alpha = 0.1305d0
52 double precision,
public,
protected ::
sb_beta = 0.7695d0
54 double precision,
public,
protected ::
sb_kappa = 100.0d0
57 double precision,
public,
protected ::
gs_f = 0.046d0
59 double precision,
public,
protected ::
gs_k = 0.063d0
62 double precision,
public,
protected ::
br_a = 4.5d0
64 double precision,
public,
protected ::
br_b = 8.0d0
66 double precision,
public,
protected ::
br_c = 1.0d0
68 double precision,
public,
protected ::
br_d = 1.0d0
71 double precision,
public,
protected ::
lg_lambda = 1.0d0
76 double precision,
public,
protected ::
bzfn_delta = 1.0d0
80 double precision,
public,
protected ::
bzfn_mu = 1.0d0
83 double precision,
public,
protected ::
lor_r = 28.0d0
85 double precision,
public,
protected ::
lor_sigma = 10.0d0
87 double precision,
public,
protected ::
lor_b = 8.0d0 / 3.0d0
90 logical :: rd_source_split = .false.
93 type(mg_bc_t),
public ::
rd_mg_bc(3, mg_num_neighbors)
100 subroutine rd_params_read(files)
102 character(len=*),
intent(in) :: files(:)
110 do n = 1,
size(files)
111 open(
unitpar, file=trim(files(n)), status=
'old')
112 read(
unitpar, rd_list,
end=111)
118 equation_type = eq_gray_scott
119 number_of_species = 2
120 case (
"schnakenberg")
121 equation_type = eq_schnakenberg
122 number_of_species = 2
124 equation_type = eq_brusselator
125 number_of_species = 2
127 equation_type = eq_logistic
128 number_of_species = 1
129 case (
"analyt_hunds")
130 equation_type = eq_analyt_hunds
131 number_of_species = 1
132 case (
"belousov_fieldnoyes")
133 equation_type = eq_belousov_fn
134 number_of_species = 3
135 case (
"ext_brusselator")
136 equation_type = eq_ext_brusselator
137 number_of_species = 3
139 equation_type = eq_lorenz
140 number_of_species = 3
142 call mpistop(
"Unknown equation_name (valid: gray-scott, schnakenberg, ...)")
145 end subroutine rd_params_read
150 integer,
intent(in) :: fh
151 integer,
parameter :: n_par = 0
152 integer,
dimension(MPI_STATUS_SIZE) :: st
156 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
172 allocate(start_indices(number_species),stop_indices(number_species))
176 u_ = var_set_fluxvar(
"u",
"u")
177 if (number_of_species >= 2)
then
178 v_ = var_set_fluxvar(
"v",
"v")
180 if (number_of_species >= 3)
then
181 w_ = var_set_fluxvar(
"w",
"w")
188 stop_indices(1)=nwflux
215 integer :: n, i, iw, species_list(number_of_species)
219 call mpistop(
"mod_rd requires flux_scheme = source")
224 select case(number_of_species)
225 case(1); species_list = [
u_]
226 case(2); species_list = [
u_,
v_]
227 case(3); species_list = [
u_,
v_,
w_]
230 do i = 1, number_of_species
238 rd_mg_bc(i, n)%bc_type = mg_bc_neumann
242 rd_mg_bc(i, n)%bc_type = mg_bc_dirichlet
246 rd_mg_bc(i, n)%bc_type = mg_bc_neumann
251 if (.not.
associated(
rd_mg_bc(i, n)%boundary_cond))
then
252 write(*,
"(A,I0,A,I0,A)")
"typeboundary(", iw,
",", n, &
253 ") is 'special', but the corresponding method " // &
254 "rd_mg_bc(i, n)%boundary_cond is not set"
255 call mpistop(
"rd_mg_bc(i, n)%boundary_cond not set")
258 write(*,*)
"rd_check_params warning: unknown boundary type"
259 rd_mg_bc(i, n)%bc_type = mg_bc_dirichlet
270 integer,
intent(in) :: ixI^L, ixO^L
271 double precision,
intent(inout) :: w(ixI^S, nw)
272 double precision,
intent(in) :: x(ixI^S, 1:^ND)
279 integer,
intent(in) :: ixI^L, ixO^L
280 double precision,
intent(inout) :: w(ixI^S, nw)
281 double precision,
intent(in) :: x(ixI^S, 1:^ND)
288 integer,
intent(in) :: ixI^L, ixO^L, idim
289 double precision,
intent(in) :: w(ixI^S, nw), x(ixI^S, 1:^ND)
290 double precision,
intent(inout) :: cmax(ixI^S)
295 subroutine rd_get_cbounds(wLC, wRC, wLp, wRp, x, ixI^L, ixO^L, idim,Hspeed, cmax, cmin)
298 integer,
intent(in) :: ixI^L, ixO^L, idim
299 double precision,
intent(in) :: wLC(ixI^S, nw), wRC(ixI^S,nw)
300 double precision,
intent(in) :: wLp(ixI^S, nw), wRp(ixI^S,nw)
301 double precision,
intent(in) :: x(ixI^S, 1:^ND)
302 double precision,
intent(inout) :: cmax(ixI^S,1:number_species)
303 double precision,
intent(inout),
optional :: cmin(ixI^S,1:number_species)
304 double precision,
intent(in) :: Hspeed(ixI^S,1:number_species)
306 if (
present(cmin))
then
307 cmin(ixo^s,1) = 0.0d0
308 cmax(ixo^s,1) = 0.0d0
310 cmax(ixo^s,1) = 0.0d0
317 integer,
intent(in) :: ixI^L, ixO^L
318 double precision,
intent(in) :: dx^D, x(ixI^S, 1:^ND)
319 double precision,
intent(in) :: w(ixI^S, 1:nw)
320 double precision,
intent(inout) :: dtnew
321 double precision :: maxrate
322 double precision :: maxD
327 if (number_of_species >= 2)
then
330 if (number_of_species >= 3)
then
336 select case (equation_type)
338 maxrate = max(maxval(w(ixo^s,
v_))**2 +
gs_f, &
340 case (eq_schnakenberg)
341 maxrate = max(maxval(abs(w(ixo^s,
v_) * w(ixo^s,
u_) - 1)), &
342 maxval(w(ixo^s,
u_))**2)
343 case (eq_brusselator)
344 maxrate = max( maxval(w(ixo^s,
u_)*w(ixo^s,
v_) - (
br_b+1)), &
345 maxval(w(ixo^s,
u_)**2) )
346 case (eq_ext_brusselator)
347 maxrate = max( maxval(w(ixo^s,
u_)*w(ixo^s,
v_) - (
br_b+1)) +
br_c, &
348 maxval(w(ixo^s,
u_)**2) )
349 maxrate = max(maxrate,
br_d)
352 case (eq_analyt_hunds)
353 maxrate = maxval(w(ixo^s,
u_)*abs(1 - w(ixo^s,
u_))) /
d1
354 case (eq_belousov_fn)
364 call mpistop(
"Unknown equation type")
374 integer,
intent(in) :: ixI^L, ixO^L, idim
375 double precision,
intent(in) :: wC(ixI^S, 1:nw)
376 double precision,
intent(in) :: w(ixI^S, 1:nw)
377 double precision,
intent(in) :: x(ixI^S, 1:^ND)
378 double precision,
intent(out) :: f(ixI^S, nwflux)
384 subroutine rd_add_source(qdt,ixI^L,ixO^L,wCT,w,x,qsourcesplit,active,wCTprim)
386 integer,
intent(in) :: ixI^L, ixO^L
387 double precision,
intent(in) :: qdt
388 double precision,
intent(in) :: wCT(ixI^S, 1:nw), x(ixI^S, 1:ndim)
389 double precision,
intent(inout) :: w(ixI^S, 1:nw)
390 double precision :: lpl_u(ixO^S), lpl_v(ixO^S), lpl_w(ixO^S)
391 logical,
intent(in) :: qsourcesplit
392 logical,
intent(inout) :: active
393 double precision,
intent(in),
optional :: wCTprim(ixI^S, 1:nw)
396 if (qsourcesplit .eqv. rd_source_split)
then
399 if (number_of_species >= 2)
then
402 if (number_of_species >= 3)
then
412 select case (equation_type)
414 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u - &
415 wct(ixo^s,
u_) * wct(ixo^s,
v_)**2 + &
416 gs_f * (1 - wct(ixo^s,
u_)))
417 w(ixo^s,
v_) = w(ixo^s,
v_) + qdt * (
d2 * lpl_v + &
418 wct(ixo^s,
u_) * wct(ixo^s,
v_)**2 - &
420 case (eq_schnakenberg)
421 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
423 wct(ixo^s,
u_)**2 * wct(ixo^s,
v_)))
424 w(ixo^s,
v_) = w(ixo^s,
v_) + qdt * (
d2 * lpl_v &
426 case (eq_brusselator)
427 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
429 + wct(ixo^s,
u_)**2 * wct(ixo^s,
v_))
430 w(ixo^s,
v_) = w(ixo^s,
v_) + qdt * (
d2 * lpl_v &
431 +
br_b * wct(ixo^s,
u_) - wct(ixo^s,
u_)**2 * wct(ixo^s,
v_))
432 case (eq_ext_brusselator)
433 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
435 + wct(ixo^s,
u_)**2 * wct(ixo^s,
v_) &
437 w(ixo^s,
v_) = w(ixo^s,
v_) + qdt * (
d2 * lpl_v &
439 - wct(ixo^s,
u_)**2 * wct(ixo^s,
v_))
440 w(ixo^s,
w_) = w(ixo^s,
w_) + qdt * (
d3 * lpl_w &
443 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
445 case (eq_analyt_hunds)
446 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
447 + 1.0d0/
d1 * w(ixo^s,
u_)**2 * (1 - w(ixo^s,
u_)))
448 case (eq_belousov_fn)
449 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
451 - wct(ixo^s,
u_)*wct(ixo^s,
w_) + wct(ixo^s,
u_) &
452 - wct(ixo^s,
u_)**2))
453 w(ixo^s,
v_) = w(ixo^s,
v_) + qdt * (
d2 * lpl_v &
454 + wct(ixo^s,
u_) - wct(ixo^s,
v_))
455 w(ixo^s,
w_) = w(ixo^s,
w_) + qdt * (
d3 * lpl_w &
460 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
463 w(ixo^s,
v_) = w(ixo^s,
v_) + qdt * (
d2 * lpl_v &
464 +
lor_r * wct(ixo^s,
u_) - wct(ixo^s,
v_) &
465 - wct(ixo^s,
u_)*wct(ixo^s,
w_))
467 w(ixo^s,
w_) = w(ixo^s,
w_) + qdt * (
d3 * lpl_w &
468 + wct(ixo^s,
u_)*wct(ixo^s,
v_) -
lor_b * wct(ixo^s,
w_))
470 call mpistop(
"Unknown equation type")
483 integer,
intent(in) :: ixI^L, ixO^L
484 double precision,
intent(in) :: var(ixI^S)
485 double precision,
intent(out) :: lpl(ixO^S)
486 integer :: idir, jxO^L, hxO^L
487 double precision :: h_inv2
492 hxo^l=ixo^l-
kr(idir,^
d);
493 jxo^l=ixo^l+
kr(idir,^
d);
495 lpl(ixo^s) = lpl(ixo^s) + h_inv2 * &
496 (var(jxo^s) - 2 * var(ixo^s) + var(hxo^s))
499 call mpistop(
"rd_laplacian not implemented in this geometry")
506 integer,
intent(in) :: ixI^L, ixO^L
507 double precision,
intent(inout) :: w(ixI^S, 1:nw)
509 double precision :: lpl_u(ixO^S), lpl_v(ixO^S), lpl_w(ixO^S)
512 if (number_of_species >= 2)
then
515 if (number_of_species >= 3)
then
519 w(ixo^s,
u_) =
d1*lpl_u
520 if (number_of_species >= 2)
then
521 w(ixo^s,
v_) =
d2*lpl_v
523 if (number_of_species >= 3)
then
524 w(ixo^s,
w_) =
d3*lpl_w
532 type(state),
target :: psa(max_blocks)
533 double precision,
intent(in) :: qtC
535 integer :: iigrid, igrid, level
541 do iigrid=1,igridstail; igrid=igrids(iigrid);
554 type(state),
target :: psa(max_blocks)
555 type(state),
target :: psb(max_blocks)
556 double precision,
intent(in) :: qdt
557 double precision,
intent(in) :: qtC
558 double precision,
intent(in) :: dtfactor
561 double precision :: res, max_residual, lambda
563 integer :: iw_to,iw_from
564 integer :: iigrid, igrid, id
571 if (qdt <
dtmin)
then
573 print *,
'skipping implicit solve: dt too small!'
578 max_residual = 1
d-7/qdt
580 mg%operator_type = mg_helmholtz
581 call mg_set_methods(mg)
583 if (.not. mg%is_allocated)
call mpistop(
"multigrid tree not allocated yet")
586 lambda = 1/(dtfactor * qdt *
d1)
587 call helmholtz_set_lambda(lambda)
590 call mg_copy_to_tree(
u_, mg_irhs, factor=-lambda, state_from=psb)
591 call mg_copy_to_tree(
u_, mg_iphi, state_from=psb)
593 call mg_fas_fmg(mg, .true., max_res=res)
595 call mg_fas_vcycle(mg, max_res=res)
596 if (res < max_residual)
exit
599 call mg_copy_from_tree_gc(mg_iphi,
u_, state_to=psa)
603 if (number_of_species >= 2)
then
604 lambda = 1/(dtfactor * qdt *
d2)
605 call helmholtz_set_lambda(lambda)
608 call mg_copy_to_tree(
v_, mg_irhs, factor=-lambda, state_from=psb)
609 call mg_copy_to_tree(
v_, mg_iphi, state_from=psb)
611 call mg_fas_fmg(mg, .true., max_res=res)
613 call mg_fas_vcycle(mg, max_res=res)
614 if (res < max_residual)
exit
617 call mg_copy_from_tree_gc(mg_iphi,
v_, state_to=psa)
622 if (number_of_species >= 3)
then
623 lambda = 1/(dtfactor * qdt *
d3)
624 call helmholtz_set_lambda(lambda)
626 call mg_copy_to_tree(
w_, mg_irhs, factor=-lambda, state_from=psb)
627 call mg_copy_to_tree(
w_, mg_iphi, state_from=psb)
629 call mg_fas_fmg(mg, .true., max_res=res)
631 call mg_fas_vcycle(mg, max_res=res)
632 if (res < max_residual)
exit
635 call mg_copy_from_tree_gc(mg_iphi,
w_, state_to=psa)
subroutine mpistop(message)
Exit MPI-AMRVAC with an error message.
Module with basic grid data structures.
This module contains definitions of global parameters and variables and some generic functions/subrou...
double precision dtdiffpar
For resistive MHD, the time step is also limited by the diffusion time: .
integer, parameter unitpar
file handle for IO
integer, parameter bc_asymm
double precision global_time
The global simulation time.
logical use_imex_scheme
whether IMEX in use or not
integer, dimension(3, 3) kr
Kronecker delta tensor.
integer, dimension(:, :), allocatable typeboundary
Array indicating the type of boundary condition per variable and per physical boundary.
integer, parameter ndim
Number of spatial dimensions for grid variables.
logical use_particles
Use particles module or not.
character(len=std_len), dimension(:), allocatable par_files
Which par files are used as input.
integer mype
The rank of the current MPI task.
integer, dimension(:), allocatable, parameter d
integer ixm
the mesh range (within a block with ghost cells)
integer, dimension(:), allocatable flux_method
Which flux scheme of spatial discretization to use (per grid level)
logical slab
Cartesian geometry or not.
integer, parameter bc_periodic
integer, parameter bc_special
boundary condition types
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
integer, parameter bc_cont
integer, parameter bc_symm
logical fix_conserve_global
Whether to apply flux conservation at refinement boundaries.
logical use_multigrid
Use multigrid (only available in 2D and 3D)
double precision dtmin
Stop the simulation when the time step becomes smaller than this value.
integer, parameter fs_source
double precision, dimension(ndim) dxlevel
Module to couple the octree-mg library to AMRVAC. This file uses the VACPP preprocessor,...
Module containing all the particle routines.
subroutine particles_init()
Initialize particle data and parameters.
This module defines the procedures of a physics module. It contains function pointers for the various...
procedure(sub_convert), pointer phys_to_primitive
procedure(sub_write_info), pointer phys_write_info
procedure(sub_get_flux), pointer phys_get_flux
procedure(sub_evaluate_implicit), pointer phys_evaluate_implicit
logical phys_req_diagonal
Whether the physics routines require diagonal ghost cells, for example for computing a curl.
procedure(sub_get_cbounds), pointer phys_get_cbounds
procedure(sub_get_dt), pointer phys_get_dt
procedure(sub_check_params), pointer phys_check_params
procedure(sub_convert), pointer phys_to_conserved
character(len=name_len) physics_type
String describing the physics type of the simulation.
procedure(sub_implicit_update), pointer phys_implicit_update
procedure(sub_add_source), pointer phys_add_source
procedure(sub_get_cmax), pointer phys_get_cmax
logical phys_energy
Solve energy equation or not.
Reaction-diffusion module (physics routines)
subroutine rd_write_info(fh)
Write this module's parameters to a snapshot.
double precision, public, protected gs_f
Feed rate for Gray-Scott model.
double precision, public, protected lor_b
Parameter for Lorenz system (aspect ratio of the convection rolls)
integer, public, protected u_
double precision, public, protected bzfn_lambda
Parameter for the Field-Noyes model of the Belousov-Zhabotinsky reaction.
subroutine rd_add_source(qdt, ixIL, ixOL, wCT, w, x, qsourcesplit, active, wCTprim)
type(mg_bc_t), dimension(3, mg_num_neighbors), public rd_mg_bc
Boundary condition information for the multigrid method.
subroutine, public rd_phys_init()
subroutine rd_get_cmax(w, x, ixIL, ixOL, idim, cmax)
double precision, public, protected d3
Diffusion coefficient for third species (w) (if applicable)
logical, public, protected rd_particles
Whether particles module is added.
double precision, public, protected sb_kappa
Parameter for Schnakenberg model.
double precision, public, protected br_d
Parameter for extended Brusselator model.
double precision, public, protected gs_k
Kill rate for Gray-Scott model.
double precision, public, protected d2
Diffusion coefficient for second species (v) (if applicable)
subroutine rd_evaluate_implicit(qtC, psa)
inplace update of psa==>F_im(psa)
double precision, public, protected dtreacpar
Parameter with which to multiply the reaction timestep restriction.
integer, public, protected w_
For 3 or more equations.
subroutine rd_get_cbounds(wLC, wRC, wLp, wRp, x, ixIL, ixOL, idim, Hspeed, cmax, cmin)
double precision, public, protected bzfn_epsilon
Parameter for the Field-Noyes model of the Belousov-Zhabotinsky reaction.
double precision, public, protected d1
Diffusion coefficient for first species (u)
double precision, public, protected lg_lambda
Parameter for logistic model (Fisher / KPP equation)
integer, public, protected v_
For 2 or more equations.
double precision, public, protected sb_beta
Parameter for Schnakenberg model.
subroutine rd_get_dt(w, ixIL, ixOL, dtnew, dxD, x)
double precision, public, protected bzfn_mu
Parameter for the Field-Noyes model of the Belousov-Zhabotinsky reaction.
double precision, public, protected sb_alpha
Parameter for Schnakenberg model.
subroutine rd_check_params
subroutine rd_to_primitive(ixIL, ixOL, w, x)
subroutine rd_implicit_update(dtfactor, qdt, qtC, psa, psb)
Implicit solve of psa=psb+dtfactor*dt*F_im(psa)
double precision, public, protected bzfn_delta
Parameter for the Field-Noyes model of the Belousov-Zhabotinsky reaction.
double precision, public, protected lor_r
Parameter for Lorenz system (Rayleigh number)
subroutine put_laplacians_onegrid(ixIL, ixOL, w)
subroutine rd_to_conserved(ixIL, ixOL, w, x)
double precision, public, protected br_a
Parameter for Brusselator model.
subroutine rd_laplacian(ixIL, ixOL, var, lpl)
Compute the Laplacian using a standard second order scheme. For now this method only works in slab ge...
double precision, public, protected lor_sigma
Parameter for Lorenz system (Prandtl number)
subroutine rd_get_flux(wC, w, x, ixIL, ixOL, idim, f)
double precision, public, protected br_c
Parameter for extended Brusselator model.
character(len=20), public, protected equation_name
Name of the system to be solved.
double precision, public, protected br_b
Parameter for Brusselator model.
The data structure that contains information about a tree node/grid block.