MPI-AMRVAC 3.1
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_rd_phys.t
Go to the documentation of this file.
1!> Reaction-diffusion module (physics routines)
2!>
3!> Multiple reaction-diffusion systems are included: the Gray-Scott model, the
4!> Schnakenberg model, the Brusselator model, the diffusive logistic equation,
5!> an analytical testcase from "Numerical solution of time-dependent advection-
6!> diffusion-reaction equations" by Hundsdorfer & Verwer, the Oregonator model,
7!> the extended Brusselator model, and the diffusive Lorenz system. See the
8!> documentation of the reaction-diffusion module for more information.
9!>
10!> IMEX methods are also supported. The implicit system is solved by a
11!> multigrid solver coupled into MPI-AMRVAC.
12!>
15 use mod_comm_lib, only: mpistop
16
17
18 implicit none
19 private
20
21 integer, protected, public :: u_ = 1
22 integer, protected, public :: v_ = 2 !< For 2 or more equations
23 integer, protected, public :: w_ = 3 !< For 3 or more equations
24
25 !> Whether particles module is added
26 logical, public, protected :: rd_particles = .false.
27
28 !> Parameter with which to multiply the reaction timestep restriction
29 double precision, public, protected :: dtreacpar = 0.5d0
30
31 !> Name of the system to be solved
32 character(len=20), public, protected :: equation_name = "gray-scott"
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 ! Field-Noyes model, or Oregonator
41 integer, parameter :: eq_ext_brusselator = 7
42 integer, parameter :: eq_lorenz = 8
43
44 !> Diffusion coefficient for first species (u)
45 double precision, public, protected :: d1 = 0.05d0
46 !> Diffusion coefficient for second species (v) (if applicable)
47 double precision, public, protected :: d2 = 1.0d0
48 !> Diffusion coefficient for third species (w) (if applicable)
49 double precision, public, protected :: d3 = 1.0d0
50
51 !> Parameter for Schnakenberg model
52 double precision, public, protected :: sb_alpha = 0.1305d0
53 !> Parameter for Schnakenberg model
54 double precision, public, protected :: sb_beta = 0.7695d0
55 !> Parameter for Schnakenberg model
56 double precision, public, protected :: sb_kappa = 100.0d0
57
58 !> Feed rate for Gray-Scott model
59 double precision, public, protected :: gs_f = 0.046d0
60 !> Kill rate for Gray-Scott model
61 double precision, public, protected :: gs_k = 0.063d0
62
63 !> Parameter for Brusselator model
64 double precision, public, protected :: br_a = 4.5d0
65 !> Parameter for Brusselator model
66 double precision, public, protected :: br_b = 8.0d0
67 !> Parameter for extended Brusselator model
68 double precision, public, protected :: br_c = 1.0d0
69 !> Parameter for extended Brusselator model
70 double precision, public, protected :: br_d = 1.0d0
71
72 !> Parameter for logistic model (Fisher / KPP equation)
73 double precision, public, protected :: lg_lambda = 1.0d0
74
75 !> Parameter for the Field-Noyes model of the Belousov-Zhabotinsky reaction
76 double precision, public, protected :: bzfn_epsilon = 1.0d0
77 !> Parameter for the Field-Noyes model of the Belousov-Zhabotinsky reaction
78 double precision, public, protected :: bzfn_delta = 1.0d0
79 !> Parameter for the Field-Noyes model of the Belousov-Zhabotinsky reaction
80 double precision, public, protected :: bzfn_lambda = 1.0d0
81 !> Parameter for the Field-Noyes model of the Belousov-Zhabotinsky reaction
82 double precision, public, protected :: bzfn_mu = 1.0d0
83
84 !> Parameter for Lorenz system (Rayleigh number)
85 double precision, public, protected :: lor_r = 28.0d0
86 !> Parameter for Lorenz system (Prandtl number)
87 double precision, public, protected :: lor_sigma = 10.0d0
88 !> Parameter for Lorenz system (aspect ratio of the convection rolls)
89 double precision, public, protected :: lor_b = 8.0d0 / 3.0d0
90
91 !> Whether to handle the explicitly handled source term in split fashion
92 logical :: rd_source_split = .false.
93
94 !> Boundary condition information for the multigrid method
95 type(mg_bc_t), public :: rd_mg_bc(3, mg_num_neighbors)
96
97 ! Public methods
98 public :: rd_phys_init
99
100contains
101
102 subroutine rd_params_read(files)
104 character(len=*), intent(in) :: files(:)
105 integer :: n
106
107 namelist /rd_list/ d1, d2, d3, sb_alpha, sb_beta, sb_kappa, gs_f, gs_k, &
110 equation_name, rd_particles, rd_source_split, dtreacpar
111
112 do n = 1, size(files)
113 open(unitpar, file=trim(files(n)), status='old')
114 read(unitpar, rd_list, end=111)
115111 close(unitpar)
116 end do
117
118 select case (equation_name)
119 case ("gray-scott")
120 equation_type = eq_gray_scott
121 number_of_species = 2
122 case ("schnakenberg")
123 equation_type = eq_schnakenberg
124 number_of_species = 2
125 case ("brusselator")
126 equation_type = eq_brusselator
127 number_of_species = 2
128 case ("logistic")
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
140 case ("lorenz")
141 equation_type = eq_lorenz
142 number_of_species = 3
143 case default
144 call mpistop("Unknown equation_name (valid: gray-scott, schnakenberg, ...)")
145 end select
146
147 end subroutine rd_params_read
148
149 !> Write this module's parameters to a snapshot
150 subroutine rd_write_info(fh)
152 integer, intent(in) :: fh
153 integer, parameter :: n_par = 0
154 integer, dimension(MPI_STATUS_SIZE) :: st
155 integer :: er
156 integer :: idim
157
158 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
159 end subroutine rd_write_info
160
161 subroutine rd_phys_init()
163 use mod_physics
166
167 call rd_params_read(par_files)
168
169 physics_type = "rd"
170 phys_energy = .false.
172
173 allocate(start_indices(number_species),stop_indices(number_species))
174 ! set the index of the first flux variable for species 1
175 start_indices(1)=1
176 ! Use the first variable as a density
177 u_ = var_set_fluxvar("u", "u")
178 if (number_of_species >= 2) then
179 v_ = var_set_fluxvar("v", "v")
180 end if
181 if (number_of_species >= 3) then
182 w_ = var_set_fluxvar("w", "w")
183 end if
184
185 ! set number of variables which need update ghostcells
186 nwgc=nwflux
187
188 ! set the index of the last flux variable for species 1
189 stop_indices(1)=nwflux
190
191 ! Number of variables need reconstruction in w
192 nw_recon=nwflux
193
194 ! Disable flux conservation near AMR boundaries, since we have no fluxes
195 fix_conserve_global = .false.
196
197 phys_get_cmax => rd_get_cmax
198 phys_get_cbounds => rd_get_cbounds
199 phys_get_flux => rd_get_flux
200 phys_to_conserved => rd_to_conserved
201 phys_to_primitive => rd_to_primitive
202 phys_add_source => rd_add_source
203 phys_get_dt => rd_get_dt
204 phys_write_info => rd_write_info
205 phys_check_params => rd_check_params
206 phys_implicit_update => rd_implicit_update
207 phys_evaluate_implicit => rd_evaluate_implicit
208
209 ! Initialize particles module
210 if (rd_particles) then
211 call particles_init()
212 end if
213
214 end subroutine rd_phys_init
215
216 subroutine rd_check_params
218 integer :: n, i, iw, species_list(number_of_species)
219
220 if (any(flux_method /= fs_source)) then
221 ! there are no fluxes, only source terms in reaction-diffusion
222 call mpistop("mod_rd requires flux_scheme = source")
223 end if
224
225 if (use_imex_scheme) then
226 use_multigrid = .true.
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_]
231 end select
232
233 do i = 1, number_of_species
234 iw = species_list(i)
235
236 ! Set boundary conditions for the multigrid solver
237 do n = 1, 2*ndim
238 select case (typeboundary(iw, n))
239 case (bc_symm)
240 ! d/dx u = 0
241 rd_mg_bc(i, n)%bc_type = mg_bc_neumann
242 rd_mg_bc(i, n)%bc_value = 0.0_dp
243 case (bc_asymm)
244 ! u = 0
245 rd_mg_bc(i, n)%bc_type = mg_bc_dirichlet
246 rd_mg_bc(i, n)%bc_value = 0.0_dp
247 case (bc_cont)
248 ! d/dx u = 0
249 rd_mg_bc(i, n)%bc_type = mg_bc_neumann
250 rd_mg_bc(i, n)%bc_value = 0.0_dp
251 case (bc_periodic)
252 ! Nothing to do here
253 case (bc_special)
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")
259 end if
260 case default
261 write(*,*) "rd_check_params warning: unknown boundary type"
262 rd_mg_bc(i, n)%bc_type = mg_bc_dirichlet
263 rd_mg_bc(i, n)%bc_value = 0.0_dp
264 end select
265 end do
266 end do
267 end if
268
269 end subroutine rd_check_params
270
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)
276
277 ! Do nothing (primitive and conservative are equal for rd module)
278 end subroutine rd_to_conserved
279
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)
285
286 ! Do nothing (primitive and conservative are equal for rd module)
287 end subroutine rd_to_primitive
288
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)
294
295 cmax(ixo^s) = 0.0d0
296 end subroutine rd_get_cmax
297
298 subroutine rd_get_cbounds(wLC, wRC, wLp, wRp, x, ixI^L, ixO^L, idim,Hspeed, cmax, cmin)
300 use mod_variables
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)
305 double precision, intent(inout) :: cmax(ixi^s,1:number_species)
306 double precision, intent(inout), optional :: cmin(ixi^s,1:number_species)
307 double precision, intent(in) :: hspeed(ixi^s,1:number_species)
308
309 if (present(cmin)) then
310 cmin(ixo^s,1) = 0.0d0
311 cmax(ixo^s,1) = 0.0d0
312 else
313 cmax(ixo^s,1) = 0.0d0
314 end if
315
316 end subroutine rd_get_cbounds
317
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
326
327 ! dt < dx^2 / (2 * ndim * diffusion_coeff)
328 ! use dtdiffpar < 1 for explicit and > 1 for imex/split
329 maxd = d1
330 if (number_of_species >= 2) then
331 maxd = max(maxd, d2)
332 end if
333 if (number_of_species >= 3) then
334 maxd = max(maxd, d3)
335 end if
336 dtnew = dtdiffpar * minval([ dx^d ])**2 / (2 * ndim * maxd)
337
338 ! Estimate time step for reactions
339 select case (equation_type)
340 case (eq_gray_scott)
341 maxrate = max(maxval(w(ixo^s, v_))**2 + gs_f, &
342 maxval(w(ixo^s, v_) * w(ixo^s, u_)) - gs_f - gs_k)
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)
353 case (eq_logistic)
354 maxrate = lg_lambda*maxval(abs(1 - w(ixo^s, u_))) ! abs for safety, normally u < 1
355 case (eq_analyt_hunds)
356 maxrate = maxval(w(ixo^s, u_)*abs(1 - w(ixo^s, u_))) / d1
357 case (eq_belousov_fn)
358 maxrate = max(&
359 maxval(abs(1.0d0 - w(ixo^s, w_) - w(ixo^s, u_))) / bzfn_epsilon, &
360 maxval(bzfn_lambda + w(ixo^s, u_)) / bzfn_delta &
361 )
362 case (eq_lorenz)
363 ! det(J) = sigma(b(r-1) + x*(x*+y*))
364 maxrate = max(lor_sigma, 1.0d0, lor_b)
365 case default
366 maxrate = one
367 call mpistop("Unknown equation type")
368 end select
369
370 dtnew = min(dtnew, dtreacpar / maxrate)
371
372 end subroutine rd_get_dt
373
374 ! There is nothing to add to the transport flux in the transport equation
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)
382
383 f(ixo^s, :) = 0.0d0
384 end subroutine rd_get_flux
385
386 ! w[iw]= w[iw]+qdt*S[wCT, qtC, x] where S is the source based on wCT within ixO
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
396
397 ! here we add the reaction terms (always) and the diffusion if no imex is used
398 if (qsourcesplit .eqv. rd_source_split) then
399 if (.not.use_imex_scheme) 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)
403 end if
404 if (number_of_species >= 3) then
405 call rd_laplacian(ixi^l, ixo^l, wct(ixi^s, w_), lpl_w)
406 end if
407 else
408 ! for all IMEX scheme variants: only add the reactions
409 lpl_u = 0.0d0
410 lpl_v = 0.0d0
411 lpl_w = 0.0d0
412 end if
413
414 select case (equation_type)
415 case (eq_gray_scott)
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 - &
421 (gs_f + gs_k) * wct(ixo^s, v_))
422 case (eq_schnakenberg)
423 w(ixo^s, u_) = w(ixo^s, u_) + qdt * (d1 * lpl_u &
424 + sb_kappa * (sb_alpha - wct(ixo^s, u_) + &
425 wct(ixo^s, u_)**2 * wct(ixo^s, v_)))
426 w(ixo^s, v_) = w(ixo^s, v_) + qdt * (d2 * lpl_v &
427 + sb_kappa * (sb_beta - wct(ixo^s, u_)**2 * wct(ixo^s, v_)))
428 case (eq_brusselator)
429 w(ixo^s, u_) = w(ixo^s, u_) + qdt * (d1 * lpl_u &
430 + br_a - (br_b + 1) * wct(ixo^s, 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 &
436 + br_a - (br_b + 1) * wct(ixo^s, u_) &
437 + wct(ixo^s, u_)**2 * wct(ixo^s, v_) &
438 - br_c * wct(ixo^s, u_) + br_d * w(ixo^s, w_))
439 w(ixo^s, v_) = w(ixo^s, v_) + qdt * (d2 * lpl_v &
440 + br_b * wct(ixo^s, u_) &
441 - wct(ixo^s, u_)**2 * wct(ixo^s, v_))
442 w(ixo^s, w_) = w(ixo^s, w_) + qdt * (d3 * lpl_w &
443 + br_c * wct(ixo^s, u_) - br_d * w(ixo^s, w_))
444 case (eq_logistic)
445 w(ixo^s, u_) = w(ixo^s, u_) + qdt * (d1 * lpl_u &
446 + lg_lambda * w(ixo^s, u_) * (1 - w(ixo^s, 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 &
452 + 1.0d0/bzfn_epsilon * (bzfn_lambda * wct(ixo^s, 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 &
458 + 1.0d0/bzfn_delta * (-bzfn_lambda * wct(ixo^s, w_) &
459 - wct(ixo^s, u_)*wct(ixo^s, w_) + bzfn_mu * wct(ixo^s, v_)))
460 case (eq_lorenz)
461 ! xdot = sigma.(y-x)
462 w(ixo^s, u_) = w(ixo^s, u_) + qdt * (d1 * lpl_u &
463 + lor_sigma * (wct(ixo^s, v_) - wct(ixo^s, u_)))
464 ! ydot = r.x - y - x.z
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_))
468 ! zdot = x.y - b.z
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_))
471 case default
472 call mpistop("Unknown equation type")
473 end select
474
475 ! enforce getbc call after source addition
476 active = .true.
477 end if
478
479 end subroutine rd_add_source
480
481 !> Compute the Laplacian using a standard second order scheme. For now this
482 !> method only works in slab geometries. Requires one ghost cell only.
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
490
491 if (slab) then
492 lpl(ixo^s) = 0.0d0
493 do idir = 1, ndim
494 hxo^l=ixo^l-kr(idir,^d);
495 jxo^l=ixo^l+kr(idir,^d);
496 h_inv2 = 1/dxlevel(idir)**2
497 lpl(ixo^s) = lpl(ixo^s) + h_inv2 * &
498 (var(jxo^s) - 2 * var(ixo^s) + var(hxo^s))
499 end do
500 else
501 call mpistop("rd_laplacian not implemented in this geometry")
502 end if
503
504 end subroutine rd_laplacian
505
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)
510
511 double precision :: lpl_u(ixo^s), lpl_v(ixo^s), lpl_w(ixo^s)
512
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)
516 end if
517 if (number_of_species >= 3) then
518 call rd_laplacian(ixi^l, ixo^l, w(ixi^s, w_), lpl_w)
519 end if
520
521 w(ixo^s,u_) = d1*lpl_u
522 if (number_of_species >= 2) then
523 w(ixo^s,v_) = d2*lpl_v
524 end if
525 if (number_of_species >= 3) then
526 w(ixo^s,w_) = d3*lpl_w
527 end if
528
529 end subroutine put_laplacians_onegrid
530
531 !> inplace update of psa==>F_im(psa)
532 subroutine rd_evaluate_implicit(qtC,psa)
534 type(state), target :: psa(max_blocks)
535 double precision, intent(in) :: qtc
536
537 integer :: iigrid, igrid, level
538 integer :: ixo^l
539
540 !ixO^L=ixG^LL^LSUB1;
541 ixo^l=ixm^ll;
542 !$OMP PARALLEL DO PRIVATE(igrid)
543 do iigrid=1,igridstail; igrid=igrids(iigrid);
544 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
545 call put_laplacians_onegrid(ixg^ll,ixo^l,psa(igrid)%w)
546 end do
547 !$OMP END PARALLEL DO
548
549 end subroutine rd_evaluate_implicit
550
551 !> Implicit solve of psa=psb+dtfactor*dt*F_im(psa)
552 subroutine rd_implicit_update(dtfactor,qdt,qtC,psa,psb)
554 use mod_forest
555
556 type(state), target :: psa(max_blocks)
557 type(state), target :: psb(max_blocks)
558 double precision, intent(in) :: qdt
559 double precision, intent(in) :: qtc
560 double precision, intent(in) :: dtfactor
561
562 integer :: n
563 double precision :: res, max_residual, lambda
564
565 integer :: iw_to,iw_from
566 integer :: iigrid, igrid, id
567 integer :: nc, lvl
568 type(tree_node), pointer :: pnode
569 real(dp) :: fac
570
571 ! Avoid setting a very restrictive limit to the residual when the time step
572 ! is small (as the operator is ~ 1/(D * qdt))
573 if (qdt < dtmin) then
574 if(mype==0)then
575 print *,'skipping implicit solve: dt too small!'
576 print *,'Currently at time=',global_time,' time step=',qdt,' dtmin=',dtmin
577 endif
578 return
579 endif
580 max_residual = 1d-7/qdt
581
582 mg%operator_type = mg_helmholtz
583 call mg_set_methods(mg)
584
585 if (.not. mg%is_allocated) call mpistop("multigrid tree not allocated yet")
586
587 ! First handle the u variable ***************************************
588 lambda = 1/(dtfactor * qdt * d1)
589 call helmholtz_set_lambda(lambda)
590 mg%bc(:, mg_iphi) = rd_mg_bc(1, :)
591
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)
594
595 call mg_fas_fmg(mg, .true., max_res=res)
596 do n = 1, 10
597 call mg_fas_vcycle(mg, max_res=res)
598 if (res < max_residual) exit
599 end do
600
601 call mg_copy_from_tree_gc(mg_iphi, u_, state_to=psa)
602 ! Done with the u variable ***************************************
603
604 ! Next handle the v variable ***************************************
605 if (number_of_species >= 2) then
606 lambda = 1/(dtfactor * qdt * d2)
607 call helmholtz_set_lambda(lambda)
608 mg%bc(:, mg_iphi) = rd_mg_bc(2, :)
609
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)
612
613 call mg_fas_fmg(mg, .true., max_res=res)
614 do n = 1, 10
615 call mg_fas_vcycle(mg, max_res=res)
616 if (res < max_residual) exit
617 end do
618
619 call mg_copy_from_tree_gc(mg_iphi, v_, state_to=psa)
620 end if
621 ! Done with the v variable ***************************************
622
623 ! Next handle the w variable ***************************************
624 if (number_of_species >= 3) then
625 lambda = 1/(dtfactor * qdt * d3)
626 call helmholtz_set_lambda(lambda)
627
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)
630
631 call mg_fas_fmg(mg, .true., max_res=res)
632 do n = 1, 10
633 call mg_fas_vcycle(mg, max_res=res)
634 if (res < max_residual) exit
635 end do
636
637 call mg_copy_from_tree_gc(mg_iphi, w_, state_to=psa)
638 end if
639 ! Done with the w variable ***************************************
640
641 end subroutine rd_implicit_update
642
643end module mod_rd_phys
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module with basic grid data structures.
Definition mod_forest.t:2
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
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.
double precision, dimension(:,:), allocatable dx
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.
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...
Definition mod_physics.t:4
procedure(sub_convert), pointer phys_to_primitive
Definition mod_physics.t:55
procedure(sub_write_info), pointer phys_write_info
Definition mod_physics.t:77
procedure(sub_get_flux), pointer phys_get_flux
Definition mod_physics.t:64
procedure(sub_evaluate_implicit), pointer phys_evaluate_implicit
Definition mod_physics.t:83
procedure(sub_get_cbounds), pointer phys_get_cbounds
Definition mod_physics.t:63
procedure(sub_get_dt), pointer phys_get_dt
Definition mod_physics.t:67
procedure(sub_check_params), pointer phys_check_params
Definition mod_physics.t:52
procedure(sub_convert), pointer phys_to_conserved
Definition mod_physics.t:54
character(len=name_len) physics_type
String describing the physics type of the simulation.
Definition mod_physics.t:50
procedure(sub_implicit_update), pointer phys_implicit_update
Definition mod_physics.t:82
procedure(sub_add_source), pointer phys_add_source
Definition mod_physics.t:69
procedure(sub_get_cmax), pointer phys_get_cmax
Definition mod_physics.t:57
logical phys_energy
Solve energy equation or not.
Definition mod_physics.t:35
Reaction-diffusion module (physics routines)
Definition mod_rd_phys.t:13
double precision, public, protected gs_f
Feed rate for Gray-Scott model.
Definition mod_rd_phys.t:59
double precision, public, protected lor_b
Parameter for Lorenz system (aspect ratio of the convection rolls)
Definition mod_rd_phys.t:89
integer, public, protected u_
Definition mod_rd_phys.t:21
double precision, public, protected bzfn_lambda
Parameter for the Field-Noyes model of the Belousov-Zhabotinsky reaction.
Definition mod_rd_phys.t:80
type(mg_bc_t), dimension(3, mg_num_neighbors), public rd_mg_bc
Boundary condition information for the multigrid method.
Definition mod_rd_phys.t:95
subroutine, public rd_phys_init()
double precision, public, protected d3
Diffusion coefficient for third species (w) (if applicable)
Definition mod_rd_phys.t:49
logical, public, protected rd_particles
Whether particles module is added.
Definition mod_rd_phys.t:26
double precision, public, protected sb_kappa
Parameter for Schnakenberg model.
Definition mod_rd_phys.t:56
double precision, public, protected br_d
Parameter for extended Brusselator model.
Definition mod_rd_phys.t:70
double precision, public, protected gs_k
Kill rate for Gray-Scott model.
Definition mod_rd_phys.t:61
double precision, public, protected d2
Diffusion coefficient for second species (v) (if applicable)
Definition mod_rd_phys.t:47
double precision, public, protected dtreacpar
Parameter with which to multiply the reaction timestep restriction.
Definition mod_rd_phys.t:29
integer, public, protected w_
For 3 or more equations.
Definition mod_rd_phys.t:23
double precision, public, protected bzfn_epsilon
Parameter for the Field-Noyes model of the Belousov-Zhabotinsky reaction.
Definition mod_rd_phys.t:76
double precision, public, protected d1
Diffusion coefficient for first species (u)
Definition mod_rd_phys.t:45
double precision, public, protected lg_lambda
Parameter for logistic model (Fisher / KPP equation)
Definition mod_rd_phys.t:73
integer, public, protected v_
For 2 or more equations.
Definition mod_rd_phys.t:22
double precision, public, protected sb_beta
Parameter for Schnakenberg model.
Definition mod_rd_phys.t:54
double precision, public, protected bzfn_mu
Parameter for the Field-Noyes model of the Belousov-Zhabotinsky reaction.
Definition mod_rd_phys.t:82
double precision, public, protected sb_alpha
Parameter for Schnakenberg model.
Definition mod_rd_phys.t:52
double precision, public, protected bzfn_delta
Parameter for the Field-Noyes model of the Belousov-Zhabotinsky reaction.
Definition mod_rd_phys.t:78
double precision, public, protected lor_r
Parameter for Lorenz system (Rayleigh number)
Definition mod_rd_phys.t:85
double precision, public, protected br_a
Parameter for Brusselator model.
Definition mod_rd_phys.t:64
double precision, public, protected lor_sigma
Parameter for Lorenz system (Prandtl number)
Definition mod_rd_phys.t:87
double precision, public, protected br_c
Parameter for extended Brusselator model.
Definition mod_rd_phys.t:68
character(len=20), public, protected equation_name
Name of the system to be solved.
Definition mod_rd_phys.t:32
double precision, public, protected br_b
Parameter for Brusselator model.
Definition mod_rd_phys.t:66
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.
Definition mod_forest.t:11