.. _amr: Static Mesh Refinement ======================= Static mesh refinement in Parthenon may be controlled via a set of input blocks. First you must enable mesh refinement by adding the following lines to the ```` block of your input file: .. code:: refinement = static # Enable static mesh refinement Then you may add any number of blocks named ````, where ``*`` is a number. Each block specifies a region parthenon will refine. You must specify the ranges in ``X`` and a refinement level. For example: .. code:: x1min = 0.25 x1max = 0.5 x2min = -0.1 x2max = 0.1 level = 3 This specifies the ragion for x1 between 0.25 and 0.5 and x2 between -0.1 and 0.1 will be :math:`2^3` more fine than the base mesh. Parthenon will refine adjacent blocks to enforce this constraint, such that well nesting--that is, adjacent blocks are no more than a factor of 2 different in resolution--is satisfied. ``x1min`` and ``x1max`` are always required. Bounds for ``x2`` and ``x3`` are assumed to be the whole domain unless you specify them. (Which is the desired behavior for 2D or 1D simulations.) Adaptive Mesh Refinement ======================== There are two ways to control AMR in parthenon. First, built-in refinemnt criteria can be activated at runtime via the input file. Second, package developers can create a package-specific refinement tagging function to allow for more tailored criteria of less generic applicability. Enable AMR ---------- To enable AMR, the following lines are required in the ```` block of your input file. .. code:: refinement = adaptive # enable adaptive mesh refinement numlevel = 5 # how many refined levels can parthenon produce Built-in -------- Parthenon includes the ability to tag cells for refinement/derefinement based on predefined criteria that can be enabled at runtime in the input file. Multiple criteria can be enabled simultaneously, in which case the most refined criteria wins. If ``refinement=adaptive`` has been specified as above, parthenon will initialize your AMR choices by looking for blocks with names ```` where ``*`` is any unique string per refinement criteria. It might look like this: .. code:: refinement = adaptive ... ... ... ... In each refinement block, you are required to provide a ``method`` which is a string that selects among the provided critera (listed below). Additionally, you are required to provide a ``field`` which must be a valid variable name in the application. Optionally, you can provide a ``refine_tol`` value (defaults to 0.5) indicating that a block should be tagged for refinement if the criteria selected evaluates to a value above this threshold anywhere on the block. Similarly, the ``derefine_tol`` value (default 0.05) determines when derefinement can occur (all values of the criteria function must be less than this). Finally, an integer ``max_level`` value can be specified that limits refinement triggered by this criteria to no greater than this level. The default is to allow each criteria to refine to ``numlevel``, which is the global maximum number of refinement levels specified in the ```` block. Predefined Criteria ~~~~~~~~~~~~~~~~~~~ The predefined refinement criteria are calculated in terms of the user selected variable :math:`q` as follows. Method: * ``magnitude``: The magnitude of the field. Note this criterion also supports an additional option, which is ``comparator``. ``comparator`` may be either ``greater_than`` or ``lesss_than`` which determines whether you refine on a large value or a small one. * ``derivative_order_1``: :math:`|\partial \ln q / \partial \ln x|` * ``derivative_order_2``: :math:`\frac{\delta x^2}{4\|q\|} \left\| \frac{\partial^2 q}{\partial x^2} \right\| = \frac{ \| q_{i-1} - 2 q_{i} + q_{i+1} \| }{ 2\| q_{i} \| + \| q_{i-1} + q_{i+1} \| }` Note that this quantity is bounded by :math:`[0,1]`. Package-specific Criteria ------------------------- As a package developer, you can define a tagging function that takes a ``Container`` as an argument and returns an integer in {-1,0,1} to indicate the block should be derefined, left alone, or refined, respectively. This function should be registered in a ``StateDescriptor`` object by assigning the ``CheckRefinement`` function pointer to point at the packages function. An example is demonstrated `here `__. Ensuring your data is consistent after re-meshing ------------------------------------------------- Remeshing is planned before the active mesh topology is changed. Effective ``AmrTag`` values are collected once, complete sibling groups are checked for derefinement, and refinement/proper-nesting changes are applied to an isolated forest clone. The resulting plan records every old-to-new relationship explicitly (unchanged block, refined child, or coarsened parent). Parthenon currently supports one AMR generation per remesh event. The initial ownership adapter keeps each rank's global block IDs contiguous. This preserves existing lookup and communication assumptions while topology and placement remain separate planning stages. Field restriction, prolongation, swarm redistribution, ownership reconciliation, boundary fills, and derived fills retain the ordering described below. When re-meshing happens, a few operations happen, which can be plugged in to in various ways. The operations performed (in order) are: - The function ``InitMeshBlockUserData`` is called. This function can be set by setting it in the ``ApplicationInputs`` field of the problem generator: .. code:: c++ void MyInitMeshBlockUserData(MeshBlock *pmb, ParameterInput *pin) { // Do something on a meshblock } pman.app_input.InitMeshBlockUserData = MyInitMeshBlockUserData; // continue with initialization... - When the mesh is being generated at initialization, the problem generator is called after every re-meshing. - Prolongation, restriction, physical boundaries, and ghost zone communication are performed - The ``FillDerived`` functions set per-package and per-application are called. If you have a function that you would like called every cycle, you may wish to put it in ``FillDerived``. If you have a function you would like performed only at re-meshing, you may wish to put it in ``InitMeshBlockUserData``. .. |formula| image:: https://render.githubusercontent.com/render/math?math=%7Cdlnq/dlnx%7C