The MPI - Adaptive Mesh Refinement - Versatile Advection Code
Setting up an new problem

Table of Contents


This document describes how users can create new problems. It explains how to set initial conditions, and how to perform other customizations.

Creating a New Setup

User code for a new problem should go into a file called either:

A template for this file is available in src/mod_usr_template.t. To create a new 1D/2D/3D setup, run one of these commands: -d=1 -d=2 -d=3

This will copy an AMRVAC makefile and specify the problem dimension in it. If no user code is found, it will ask whether you want to copy the default template. Alternatively, you can look for an existing problem (look in tests/) and customize its mod_usr.t or mod_usr.f file to get started. To create a normal Fortran file from mod_usr.t, you can type make mod_usr.f. Specify other user routines, for a list see mod_usr_methods.t

Structure of mod_usr.t

!> This is a template for a new user problem
module mod_usr
! Include a physics module
use mod_hd
implicit none
! Custom variables can be defined here
! ...
!> This routine should set user methods, and activate the physics module
subroutine usr_init()
! Choose coordinate system as 2D Cartesian with three components for vectors
call set_coordinate_system("Cartesian_2.5D")
! A routine for initial conditions is always required
usr_init_one_grid => initial_conditions
! Specify other user routines, for a list see mod_usr_methods.t
! ...
! Choose independent normalization units if using dimensionless variables.
unit_length = 1.d9 ! cm
unit_temperature = 1.d6 ! K
unit_numberdensity = 1.d9 ! cm^-3
! Active the physics module
call hd_activate()
end subroutine usr_init
!> A routine for specifying initial conditions
subroutine initial_conditions(ixI^L, ixO^L, w, x)
integer, intent(in) :: ixi^l, ixo^l
double precision, intent(in) :: x(ixi^s,1:ndim)
double precision, intent(inout) :: w(ixi^s,1:nw)
! Set initial values for w
! w(ixO^S, rho_) = ...
end subroutine initial_conditions
! Extra routines can be placed here
! ...
end module mod_usr

Special boundary

When the predefined boundary types provided by MPI-AMRVAC are not sufficient , a pointed usr_special_bc subroutine can solve the problem. It is called for each boundary region and all variable in the boundary region typeboundary_min1=8*'special'... is selected.

Special source

There are lots of possible physical source terms for the same basic equation. Rather than writing a new physics module for each, it is simpler to define a problem dependent source term in the user module.

A pointed usr_source subroutine will be called at least once in every time step. The number of calls depends on the time integration scheme defined by time_integrator, the parameter source_split_usr and also on the number of dimensions if the parameter dimsplit=T.

In any case the subroutine should integrate w from time qt to qt+qdt for the variables listed in iw^LIM in the region ixO^S. The source terms should be evaluated for the wCT array, which corresponds to the physical time qtC. In case of explicit time dependence, qtC should be used as time. Only elements within ixI^S can be used from wCT.

A pointed usr_get_dt subroutine can limit dt for numerical stability if the source term requires that.

A pointed usr_special_resistivity subroutine is used for MHD to set the resistivity array eta when it is not constant in time and/or space.

A pointed usr_refine_grid subroutine allows to add user controlled (de)refinement, by setting the integers refine,coarsen. You have all info available to do this refining (grid level, physical values in w, coordinates in x, time in qt). Similarly, a usr_var_for_errest subroutine allows to compute a (local) new variable, to be stored in var, on which you can then base refinement as well.

Special output and analysis

The default log-file may be altered, for which you need to code up the a usr_print_log subroutine. For parallel execution, this invariably means the use of MPI constructs, so you should copy in the default version printlog_default from src/amrvacio/mod_input_output.t and then study it, and modify accordingly.

A pointed usr_aux_output is extremely handy to compute variables from the actually computed conserved variables, that can then be visualized directly. It is only used in combination with the conversion subroutines. e.g., one may here compute current density components using the actual code discretizations for computing a curl, and then visualize those with any of the visualization tools applicable. You then also need to specify a name for each variable, in a pointed usr_add_aux_names.

A pointed usr_process_grid and a pointed usr_process_global are subroutines called in each iteration, which allow to compute auxiliary variables which happen to be non-local (like div v), and are in no way used for flux computations. As auxiliaries, they are also not advanced. This functionality was added to allow e.g. for separate particle treatments using stochastic differential equations, where the particle dynamics is only relying on local compression values.