21 integer,
protected,
public ::
u_ = 1
22 integer,
protected,
public ::
v_ = 2
23 integer,
protected,
public ::
w_ = 3
29 double precision,
public,
protected ::
dtreacpar = 0.5d0
33 integer :: number_of_species = 2
34 integer :: equation_type = 1
35 integer,
parameter :: eq_gray_scott = 1
36 integer,
parameter :: eq_schnakenberg = 2
37 integer,
parameter :: eq_brusselator = 3
38 integer,
parameter :: eq_logistic = 4
39 integer,
parameter :: eq_analyt_hunds = 5
40 integer,
parameter :: eq_belousov_fn = 6
41 integer,
parameter :: eq_ext_brusselator = 7
42 integer,
parameter :: eq_lorenz = 8
45 double precision,
public,
protected ::
d1 = 0.05d0
47 double precision,
public,
protected ::
d2 = 1.0d0
49 double precision,
public,
protected ::
d3 = 1.0d0
52 double precision,
public,
protected ::
sb_alpha = 0.1305d0
54 double precision,
public,
protected ::
sb_beta = 0.7695d0
56 double precision,
public,
protected ::
sb_kappa = 100.0d0
59 double precision,
public,
protected ::
gs_f = 0.046d0
61 double precision,
public,
protected ::
gs_k = 0.063d0
64 double precision,
public,
protected ::
br_a = 4.5d0
66 double precision,
public,
protected ::
br_b = 8.0d0
68 double precision,
public,
protected ::
br_c = 1.0d0
70 double precision,
public,
protected ::
br_d = 1.0d0
73 double precision,
public,
protected ::
lg_lambda = 1.0d0
78 double precision,
public,
protected ::
bzfn_delta = 1.0d0
82 double precision,
public,
protected ::
bzfn_mu = 1.0d0
85 double precision,
public,
protected ::
lor_r = 28.0d0
87 double precision,
public,
protected ::
lor_sigma = 10.0d0
89 double precision,
public,
protected ::
lor_b = 8.0d0 / 3.0d0
92 logical :: rd_source_split = .false.
95 type(mg_bc_t),
public ::
rd_mg_bc(3, mg_num_neighbors)
102 subroutine rd_params_read(files)
104 character(len=*),
intent(in) :: files(:)
112 do n = 1,
size(files)
113 open(
unitpar, file=trim(files(n)), status=
'old')
114 read(
unitpar, rd_list,
end=111)
120 equation_type = eq_gray_scott
121 number_of_species = 2
122 case (
"schnakenberg")
123 equation_type = eq_schnakenberg
124 number_of_species = 2
126 equation_type = eq_brusselator
127 number_of_species = 2
129 equation_type = eq_logistic
130 number_of_species = 1
131 case (
"analyt_hunds")
132 equation_type = eq_analyt_hunds
133 number_of_species = 1
134 case (
"belousov_fieldnoyes")
135 equation_type = eq_belousov_fn
136 number_of_species = 3
137 case (
"ext_brusselator")
138 equation_type = eq_ext_brusselator
139 number_of_species = 3
141 equation_type = eq_lorenz
142 number_of_species = 3
144 call mpistop(
"Unknown equation_name (valid: gray-scott, schnakenberg, ...)")
147 end subroutine rd_params_read
150 subroutine rd_write_info(fh)
152 integer,
intent(in) :: fh
153 integer,
parameter :: n_par = 0
154 integer,
dimension(MPI_STATUS_SIZE) :: st
158 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
159 end subroutine rd_write_info
173 allocate(start_indices(number_species),stop_indices(number_species))
177 u_ = var_set_fluxvar(
"u",
"u")
178 if (number_of_species >= 2)
then
179 v_ = var_set_fluxvar(
"v",
"v")
181 if (number_of_species >= 3)
then
182 w_ = var_set_fluxvar(
"w",
"w")
189 stop_indices(1)=nwflux
216 subroutine rd_check_params
218 integer :: n, i, iw, species_list(number_of_species)
222 call mpistop(
"mod_rd requires flux_scheme = source")
227 select case(number_of_species)
228 case(1); species_list = [
u_]
229 case(2); species_list = [
u_,
v_]
230 case(3); species_list = [
u_,
v_,
w_]
233 do i = 1, number_of_species
241 rd_mg_bc(i, n)%bc_type = mg_bc_neumann
245 rd_mg_bc(i, n)%bc_type = mg_bc_dirichlet
249 rd_mg_bc(i, n)%bc_type = mg_bc_neumann
254 if (.not.
associated(
rd_mg_bc(i, n)%boundary_cond))
then
255 write(*,
"(A,I0,A,I0,A)")
"typeboundary(", iw,
",", n, &
256 ") is 'special', but the corresponding method " // &
257 "rd_mg_bc(i, n)%boundary_cond is not set"
258 call mpistop(
"rd_mg_bc(i, n)%boundary_cond not set")
261 write(*,*)
"rd_check_params warning: unknown boundary type"
262 rd_mg_bc(i, n)%bc_type = mg_bc_dirichlet
269 end subroutine rd_check_params
271 subroutine rd_to_conserved(ixI^L, ixO^L, w, x)
273 integer,
intent(in) :: ixi^
l, ixo^
l
274 double precision,
intent(inout) :: w(ixi^s, nw)
275 double precision,
intent(in) :: x(ixi^s, 1:^nd)
278 end subroutine rd_to_conserved
280 subroutine rd_to_primitive(ixI^L, ixO^L, w, x)
282 integer,
intent(in) :: ixi^
l, ixo^
l
283 double precision,
intent(inout) :: w(ixi^s, nw)
284 double precision,
intent(in) :: x(ixi^s, 1:^nd)
287 end subroutine rd_to_primitive
289 subroutine rd_get_cmax(w, x, ixI^L, ixO^L, idim, cmax)
291 integer,
intent(in) :: ixi^
l, ixo^
l, idim
292 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s, 1:^nd)
293 double precision,
intent(inout) :: cmax(ixi^s)
296 end subroutine rd_get_cmax
298 subroutine rd_get_cbounds(wLC, wRC, wLp, wRp, x, ixI^L, ixO^L, idim,Hspeed, cmax, cmin)
301 integer,
intent(in) :: ixi^
l, ixo^
l, idim
302 double precision,
intent(in) :: wlc(ixi^s,
nw), wrc(ixi^s,
nw)
303 double precision,
intent(in) :: wlp(ixi^s,
nw), wrp(ixi^s,
nw)
304 double precision,
intent(in) :: x(ixi^s, 1:^nd)
306 double precision,
intent(inout),
optional :: cmin(ixi^s,1:
number_species)
309 if (
present(cmin))
then
310 cmin(ixo^s,1) = 0.0d0
311 cmax(ixo^s,1) = 0.0d0
313 cmax(ixo^s,1) = 0.0d0
316 end subroutine rd_get_cbounds
318 subroutine rd_get_dt(w, ixI^L, ixO^L, dtnew, dx^D, x)
320 integer,
intent(in) :: ixi^
l, ixo^
l
321 double precision,
intent(in) ::
dx^
d, x(ixi^s, 1:^nd)
322 double precision,
intent(in) :: w(ixi^s, 1:nw)
323 double precision,
intent(inout) :: dtnew
324 double precision :: maxrate
325 double precision :: maxd
330 if (number_of_species >= 2)
then
333 if (number_of_species >= 3)
then
339 select case (equation_type)
341 maxrate = max(maxval(w(ixo^s,
v_))**2 +
gs_f, &
343 case (eq_schnakenberg)
344 maxrate = max(maxval(abs(w(ixo^s,
v_) * w(ixo^s,
u_) - 1)), &
345 maxval(w(ixo^s,
u_))**2)
346 case (eq_brusselator)
347 maxrate = max( maxval(w(ixo^s,
u_)*w(ixo^s,
v_) - (
br_b+1)), &
348 maxval(w(ixo^s,
u_)**2) )
349 case (eq_ext_brusselator)
350 maxrate = max( maxval(w(ixo^s,
u_)*w(ixo^s,
v_) - (
br_b+1)) +
br_c, &
351 maxval(w(ixo^s,
u_)**2) )
352 maxrate = max(maxrate,
br_d)
355 case (eq_analyt_hunds)
356 maxrate = maxval(w(ixo^s,
u_)*abs(1 - w(ixo^s,
u_))) /
d1
357 case (eq_belousov_fn)
367 call mpistop(
"Unknown equation type")
372 end subroutine rd_get_dt
375 subroutine rd_get_flux(wC, w, x, ixI^L, ixO^L, idim, f)
377 integer,
intent(in) :: ixi^
l, ixo^
l, idim
378 double precision,
intent(in) :: wc(ixi^s, 1:nw)
379 double precision,
intent(in) :: w(ixi^s, 1:nw)
380 double precision,
intent(in) :: x(ixi^s, 1:^nd)
381 double precision,
intent(out) :: f(ixi^s, nwflux)
384 end subroutine rd_get_flux
387 subroutine rd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
389 integer,
intent(in) :: ixi^
l, ixo^
l
390 double precision,
intent(in) :: qdt, dtfactor
391 double precision,
intent(in) :: wct(ixi^s, 1:nw),wctprim(ixi^s,1:nw),x(ixi^s, 1:
ndim)
392 double precision,
intent(inout) :: w(ixi^s, 1:nw)
393 double precision :: lpl_u(ixo^s), lpl_v(ixo^s), lpl_w(ixo^s)
394 logical,
intent(in) :: qsourcesplit
395 logical,
intent(inout) :: active
398 if (qsourcesplit .eqv. rd_source_split)
then
400 call rd_laplacian(ixi^
l, ixo^
l, wct(ixi^s,
u_), lpl_u)
401 if (number_of_species >= 2)
then
402 call rd_laplacian(ixi^
l, ixo^
l, wct(ixi^s,
v_), lpl_v)
404 if (number_of_species >= 3)
then
405 call rd_laplacian(ixi^
l, ixo^
l, wct(ixi^s,
w_), lpl_w)
414 select case (equation_type)
416 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u - &
417 wct(ixo^s,
u_) * wct(ixo^s,
v_)**2 + &
418 gs_f * (1 - wct(ixo^s,
u_)))
419 w(ixo^s,
v_) = w(ixo^s,
v_) + qdt * (
d2 * lpl_v + &
420 wct(ixo^s,
u_) * wct(ixo^s,
v_)**2 - &
422 case (eq_schnakenberg)
423 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
425 wct(ixo^s,
u_)**2 * wct(ixo^s,
v_)))
426 w(ixo^s,
v_) = w(ixo^s,
v_) + qdt * (
d2 * lpl_v &
428 case (eq_brusselator)
429 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
431 + wct(ixo^s,
u_)**2 * wct(ixo^s,
v_))
432 w(ixo^s,
v_) = w(ixo^s,
v_) + qdt * (
d2 * lpl_v &
433 +
br_b * wct(ixo^s,
u_) - wct(ixo^s,
u_)**2 * wct(ixo^s,
v_))
434 case (eq_ext_brusselator)
435 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
437 + wct(ixo^s,
u_)**2 * wct(ixo^s,
v_) &
439 w(ixo^s,
v_) = w(ixo^s,
v_) + qdt * (
d2 * lpl_v &
441 - wct(ixo^s,
u_)**2 * wct(ixo^s,
v_))
442 w(ixo^s,
w_) = w(ixo^s,
w_) + qdt * (
d3 * lpl_w &
445 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
447 case (eq_analyt_hunds)
448 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
449 + 1.0d0/
d1 * w(ixo^s,
u_)**2 * (1 - w(ixo^s,
u_)))
450 case (eq_belousov_fn)
451 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
453 - wct(ixo^s,
u_)*wct(ixo^s,
w_) + wct(ixo^s,
u_) &
454 - wct(ixo^s,
u_)**2))
455 w(ixo^s,
v_) = w(ixo^s,
v_) + qdt * (
d2 * lpl_v &
456 + wct(ixo^s,
u_) - wct(ixo^s,
v_))
457 w(ixo^s,
w_) = w(ixo^s,
w_) + qdt * (
d3 * lpl_w &
462 w(ixo^s,
u_) = w(ixo^s,
u_) + qdt * (
d1 * lpl_u &
465 w(ixo^s,
v_) = w(ixo^s,
v_) + qdt * (
d2 * lpl_v &
466 +
lor_r * wct(ixo^s,
u_) - wct(ixo^s,
v_) &
467 - wct(ixo^s,
u_)*wct(ixo^s,
w_))
469 w(ixo^s,
w_) = w(ixo^s,
w_) + qdt * (
d3 * lpl_w &
470 + wct(ixo^s,
u_)*wct(ixo^s,
v_) -
lor_b * wct(ixo^s,
w_))
472 call mpistop(
"Unknown equation type")
479 end subroutine rd_add_source
483 subroutine rd_laplacian(ixI^L,ixO^L,var,lpl)
485 integer,
intent(in) :: ixi^
l, ixo^
l
486 double precision,
intent(in) :: var(ixi^s)
487 double precision,
intent(out) :: lpl(ixo^s)
488 integer :: idir, jxo^
l, hxo^
l
489 double precision :: h_inv2
494 hxo^
l=ixo^
l-
kr(idir,^
d);
495 jxo^
l=ixo^
l+
kr(idir,^
d);
497 lpl(ixo^s) = lpl(ixo^s) + h_inv2 * &
498 (var(jxo^s) - 2 * var(ixo^s) + var(hxo^s))
501 call mpistop(
"rd_laplacian not implemented in this geometry")
504 end subroutine rd_laplacian
506 subroutine put_laplacians_onegrid(ixI^L,ixO^L,w)
508 integer,
intent(in) :: ixi^
l, ixo^
l
509 double precision,
intent(inout) :: w(ixi^s, 1:nw)
511 double precision :: lpl_u(ixo^s), lpl_v(ixo^s), lpl_w(ixo^s)
513 call rd_laplacian(ixi^
l, ixo^
l, w(ixi^s,
u_), lpl_u)
514 if (number_of_species >= 2)
then
515 call rd_laplacian(ixi^
l, ixo^
l, w(ixi^s,
v_), lpl_v)
517 if (number_of_species >= 3)
then
518 call rd_laplacian(ixi^
l, ixo^
l, w(ixi^s,
w_), lpl_w)
521 w(ixo^s,
u_) =
d1*lpl_u
522 if (number_of_species >= 2)
then
523 w(ixo^s,
v_) =
d2*lpl_v
525 if (number_of_species >= 3)
then
526 w(ixo^s,
w_) =
d3*lpl_w
529 end subroutine put_laplacians_onegrid
532 subroutine rd_evaluate_implicit(qtC,psa)
535 double precision,
intent(in) :: qtc
537 integer :: iigrid, igrid, level
543 do iigrid=1,igridstail; igrid=igrids(iigrid);
545 call put_laplacians_onegrid(ixg^
ll,ixo^
l,psa(igrid)%w)
549 end subroutine rd_evaluate_implicit
552 subroutine rd_implicit_update(dtfactor,qdt,qtC,psa,psb)
558 double precision,
intent(in) :: qdt
559 double precision,
intent(in) :: qtc
560 double precision,
intent(in) :: dtfactor
563 double precision :: res, max_residual, lambda
565 integer :: iw_to,iw_from
566 integer :: iigrid, igrid, id
573 if (qdt <
dtmin)
then
575 print *,
'skipping implicit solve: dt too small!'
580 max_residual = 1
d-7/qdt
582 mg%operator_type = mg_helmholtz
583 call mg_set_methods(mg)
585 if (.not. mg%is_allocated)
call mpistop(
"multigrid tree not allocated yet")
588 lambda = 1/(dtfactor * qdt *
d1)
589 call helmholtz_set_lambda(lambda)
592 call mg_copy_to_tree(
u_, mg_irhs, factor=-lambda, state_from=psb)
593 call mg_copy_to_tree(
u_, mg_iphi, state_from=psb)
595 call mg_fas_fmg(mg, .true., max_res=res)
597 call mg_fas_vcycle(mg, max_res=res)
598 if (res < max_residual)
exit
601 call mg_copy_from_tree_gc(mg_iphi,
u_, state_to=psa)
605 if (number_of_species >= 2)
then
606 lambda = 1/(dtfactor * qdt *
d2)
607 call helmholtz_set_lambda(lambda)
610 call mg_copy_to_tree(
v_, mg_irhs, factor=-lambda, state_from=psb)
611 call mg_copy_to_tree(
v_, mg_iphi, state_from=psb)
613 call mg_fas_fmg(mg, .true., max_res=res)
615 call mg_fas_vcycle(mg, max_res=res)
616 if (res < max_residual)
exit
619 call mg_copy_from_tree_gc(mg_iphi,
v_, state_to=psa)
624 if (number_of_species >= 3)
then
625 lambda = 1/(dtfactor * qdt *
d3)
626 call helmholtz_set_lambda(lambda)
628 call mg_copy_to_tree(
w_, mg_irhs, factor=-lambda, state_from=psb)
629 call mg_copy_to_tree(
w_, mg_iphi, state_from=psb)
631 call mg_fas_fmg(mg, .true., max_res=res)
633 call mg_fas_vcycle(mg, max_res=res)
634 if (res < max_residual)
exit
637 call mg_copy_from_tree_gc(mg_iphi,
w_, state_to=psa)
641 end subroutine rd_implicit_update
subroutine, public 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.
double precision, dimension(:), allocatable, parameter d
integer ixm
the mesh range of a physical block without 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
double precision, dimension(:,:), allocatable dx
integer, parameter bc_symm
logical fix_conserve_global
Whether to apply flux conservation at refinement boundaries.
double precision, dimension(^nd) dxlevel
store unstretched cell size of current level
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 max_blocks
The maximum number of grid blocks in a processor.
integer, parameter fs_source
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
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)
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.
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()
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)
double precision, public, protected dtreacpar
Parameter with which to multiply the reaction timestep restriction.
integer, public, protected w_
For 3 or more equations.
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.
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.
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)
double precision, public, protected br_a
Parameter for Brusselator model.
double precision, public, protected lor_sigma
Parameter for Lorenz system (Prandtl number)
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.
integer nw
Total number of variables.
integer number_species
number of species: each species has different characterictic speeds and should be used accordingly in...
The data structure that contains information about a tree node/grid block.