4.2.5. Adaptivity

Aria supports several forms of mesh refinement:

  • Uniform refinement prior to the start of the simulation.

  • Transient refinement and un-refinement based on a marker field during a simulation

  • Transient conformal decomposition and refinement (TODO ref CDFEM + LS section)

4.2.5.1. Adaptivity Overview

Setting up a problem with mesh adaptivity generally requires defining three things:

  1. Indicators - Indicators are element fields that you define to use for deciding which elements should be refined and which should be un-refined.

  2. Markers - Once you have defined any required indicators, the next step is to define markers that use those indicators and mark elements for refinement or unrefinement. When defining multiple markers, refinement takes precedence over un-refinement, so if any marker marks an element for refinement, it will be refined even if another marker marks it for un-refinement.

  3. Solution Control - Finally, you must use solution control to control when you want adaptivity to be active (with the exception of simple uniform refinement, which Aria offers a shorthand syntax for). Solution control allows you to adjust the timing and frequency of the adaptivity - for example, turning it off during an initial time period, and on later in the simulation.

The following sections will show how to use these three components to set up flexible adaptivity problems. For the complete list of adaptivity commands, check the adaptivity command reference.

4.2.5.2. Uniform Refinement

When using only uniform initial refinement, there is a shorthand syntax available to simply refine all elements in the mesh. This can be requested in the Aria Region without setting up any indicators, markers, or solution control steps

Begin Aria Region myRegion
  Initial Uniform Refinement for 2 iterations

  ...
End

Alternately, you could use a uniform marker with a max level of 2 and use solution control to achieve the same thing. The advantage of this approach is that can be extended to define different uniform refinement markers on different blocks, each with its own maximum refinement level. For example, to use uniform refinement of 2 levels on all blocks except block_3, where you need 3 levels of uniform refinement, you could do:

Begin adaptivity options my_adapt
  begin uniform marker my_marker_a
    maximum refinement level = 2
    location = all_blocks
  end
  begin uniform marker my_marker_b
    maximum refinement level = 3
    location = block_3
  end
End

# in solution control
Begin System Main
  # Start by running the adapt loop some number of
  # steps (equal to the max refinement level)
  Begin AdaptiveLoop adaptive_loop
    Adapt mesh for MyAriaRegion using my_adapt
  End

  # Then run a transient case without adaptivity
  Begin Transient TimeBlock
    Advance MyAriaRegion
  End
End

Begin Parameters For AdaptiveLoop adaptive_loop
  Number Of Adaptivity Steps Is 3
End

Note

Note that restart is fully supported for adaptivity. For initial refinement, though, one should modify the given input to ensure that the adaptive loop is not executed on restart runs

Begin AdaptiveLoop adaptive_loop
  Adapt mesh for MyAriaRegion using my_adapt when "current_time == 0.0"
End

4.2.5.3. Runtime Adaptive Refinement

4.2.5.3.1. Defining Markers and Indicators

To use runtime adaptivity, you will typically want to define a more complex set of indicators and markers. These could include uniform refinement on some blocks, and one or more indicators or markers on other blocks.

Begin Adaptivity Options my_adapt
    Begin signed distance indicator ls_distance
        signed distance field = solution->Level_Set
        location = block_1
    End

    # Mark elements on block_1 less than 0.05 from the
    # level set interface to refine 2 levels
    Begin function marker ls_marker
        refine when "ls_distance < 0.05"
        unrefine when "ls_distance >= 0.05"
        Maximum refinement level = 2
        location = block_1
    End

    # Mark all elements inside a geometric shape to be refined
    # 3 levels across two blocks
    Begin function marker plug_marker
        refine when "(z > 0) && (sqrt(x^2 + y^2) < 0.3)"
        Maximum refinement level = 3
        location = block_2 block_3
    End

    # Mark all elements on block_2 to be refined 1 level
    begin uniform marker case_marker
        maximum refinement level = 1
        location = block_2
    end
End

4.2.5.3.2. Solution Control Integration

To enable a single adapt before each time step, add an Adapt Mesh command inside the Begin Transient block.

Begin System Main
  Begin Transient TimeBlockMain
    Adapt Mesh for MyAriaRegion Using my_adapt
    Advance MyAriaRegion
  End
End

The use of an AdaptiveLoop block allows multiple passes of mesh refinement per time step. To enable multiple adaptivity passes before each time step, add a nested AdaptiveLoop block to run multiple back-to-back adaptivity cycles at the start of each time step.

Begin System Main
  Begin Transient TimeBlockMain
    Begin AdaptiveLoop adaptive_loop
      Adapt mesh for MyAriaRegion using my_adapt
    End
    Advance MyAriaRegion
  End
End

Begin Parameters For AdaptiveLoop adaptive_loop
  Number Of Adaptivity Steps Is 2
End

Alternately, you may want each time step to take multiple Adapt-Step iterations. To achieve that, move the Advance inside the adaptive loop. When using this combination, it will repeat the adapt-step iteration at that same time step how ever many times you have requested. This may provide better error control since the adaptivity indicators can use the updated solution fields, but comes at the cost of evaluating additional time steps with their full linear assembly and solve. Additionally, you can include an extra Advance call before the adaptive loop so that the first adapt step uses the updated solution fields.

For example, if the current time step is from 2 s to 3 s, the adaptive loop below (with 2 iterations) would:

  1. (optional initial Advance) Step from 2 to 3 s and update the solution fields

  2. Calculate indicators and markers using the current (updated or from the prior step) solution fields and adapt the mesh

  3. Step from 2 to 3 s and update the solution fields

  4. Calculate indicators and markers using the updated solution fields and adapt the mesh

  5. Step from 2 to 3 s and update the solution fields

If there were more than 2 iterations requested, it would continue to repeat this cycle as many times as requested. The solution control input for this scheme would look like:

Begin System Main
  Begin Transient TimeBlockMain
    # Optional: initial advance so first adapt uses this time step solution
    Advance MyAriaRegion

    Begin AdaptiveLoop adaptive_loop
      Adapt mesh for MyAriaRegion using my_adapt
      Advance MyAriaRegion
    End
  End
End

Begin Parameters For AdaptiveLoop adaptive_loop
  Number Of Adaptivity Steps Is 2
End

Note

When doing adaptive loops within a time step, advancing the region multiple times in a single time step may not be desirable due to computational expense. If the indicator field is a function only of postprocessed values (such as a source in an equation system), the adaptive loop can include only a postprocessor call e.g.

Begin System Main
  Begin Transient TimeBlockMain
    Begin AdaptiveLoop adaptive_loop
      Postprocess Aria region MyAriaRegion
      Adapt mesh for MyAriaRegion using my_adapt
    End
    Advance MyAriaRegion
  End
End
...
Begin Aria region MyAriaRegion
  ...
  EQ Energy for Temperature on all_blocks using Q1 with lumped_mass Diff src
  Source for Energy on all_blocks = Scalar_String_Function F = "..."

  postprocess value of expression energy_source on all_blocks as source_field
End

4.2.5.3.3. Adaptivity Considerations

There are a few usability inconveniences to be aware of when enabling transient adaptivity:

  • When using adaptivity, it is usually necessary to activate rebalance to achieve good performance, otherwise some ranks can end up with substantially more work than others.

  • Due to limitations in the Exodus file format each time the mesh changes Aria will create a new output file. These output files will have “-sNNNN” appended to the initial file name where “NNNN” is an increasing number corresponding to the order of the files. So for example if the output database name was initially “output.e” then a run where adaptivity was performed 3 times would have 4 output files: “output.e”, “output.e-s0001”, “output.e-s0002”, and “output.e-s0003”. If running in parallel and the default file-per-processor output format is being used a new one of these files will be created for every MPI rank. Fortunately visualization tools like Paraview understand this file name convention and will visualize the full set of files as a single result, but the number of files created in long-running simulations with adaptivity can make file management a nuisance.

  • Each time the mesh is modified during the simulation run Aria needs to reinitialize a number of data structures that are associated with the mesh. Most notable of these is that the viewfactors for all enclosures in the problem must be recomputed (even if the enclosure surface geometry was not impacted by the adaptivity). This can significantly increase the cost of simulations using adaptivity with enclosure radiation.