Constant Velocity Circle
One of the simplest problems for demonstrating the level set equation is to apply a constant velocity field to an initial field, in this case a circle in two dimensions. The following example assumes that you have a compiled and working level set module executable and is based on the content in the moose/modules/level_set/circle
directory.
Create Input File
This example begins by defining a minimal input file for solving the level set equation. The input file that is used initially is (modules/level_set/examples/circle/circle_16.i).
Mesh
First, the Mesh must be defined, which for this simple problem is a rectangular two-dimensional domain ranging from 0 to 1 in the x and y directions.
[Mesh]
type = GeneratedMesh
dim = 2
xmin = 0
xmax = 1
ymin = 0
ymax = 1
nx = 16
ny = 16
[]
(modules/level_set/examples/circle/circle_16.i)Variables
The unknown that will be solved is defined ("phi") as well as the auxiliary variables that will define the velocity input to the level set equation. Notice that when the velocity variables are defined (vel_x
and vel_y
) each is defined an initial condition of 3. For this problem the velocity will remain constant, the value of which is defined by the initial condition.
[Variables]
[./phi]
[../]
[]
[AuxVariables]
[./velocity]
family = LAGRANGE_VEC
[../]
[]
(modules/level_set/examples/circle/circle_16.i)Initial Condition
The initial condition for the auxiliary variables was defined via a short-cut syntax in the previous section; however, the "phi" variable must also be initialized. This will be accomplished by using the LevelSetOlssonBubble function that is a part of the level set module. In this case, a circle with a radius of 0.15 is defined at the midpoint of the domain.
[ICs]
[./phi_ic]
type = FunctionIC
function = phi_exact
variable = phi
[../]
[./vel_ic]
type = VectorFunctionIC
variable = velocity
function = velocity_func
[]
[]
[Functions]
[./phi_exact]
type = LevelSetOlssonBubble
epsilon = 0.05
center = '0.5 0.5 0'
radius = 0.15
[../]
[./velocity_func]
type = ParsedVectorFunction
expression_x = '3'
expression_y = '3'
[../]
[]
(modules/level_set/examples/circle/circle_16.i)Boundary Conditions
This problem assigns periodic boundary conditions for the "phi" in the x an y directions, which is easily accomplished within MOOSE.
[BCs]
[./Periodic]
[./all]
variable = phi
auto_direction = 'x y'
[../]
[../]
[]
(modules/level_set/examples/circle/circle_16.i)Kernels
The level set equation (see Theory) may be defined in MOOSE using two Kernel objects: TimeDerivative and LevelSetAdvection.
Notice, that the LevelSetAdvection requires that the unknown to be solved for ("phi") to be assigned in the "variable" parameters as well as the two velocity variables in the "velocity_x" and "velocity_y" parameters.
[Kernels]
[./time]
type = TimeDerivative
variable = phi
[../]
[./advection]
type = LevelSetAdvection
velocity = velocity
variable = phi
[../]
[]
(modules/level_set/examples/circle/circle_16.i)Postprocessors
In this example a single Postprocessors is defined. The LevelSetCFLCondition is used to define the minimum timestep that should be used when executing the solve of this equation, as discussed in the following section.
[Postprocessors]
[./cfl]
type = LevelSetCFLCondition
velocity = velocity
execute_on = 'initial'
[../]
[]
(modules/level_set/examples/circle/circle_16.i)Execution
This example is a transient problem, hence the Transient execution is used. The other important aspect to illustrate in the Executioner block is the use of the PostprocessorDT time stepper, which allows for the LevelSetCFLCondition postprocessor to govern the timestepping for this problem.
[Executioner]
type = Transient
solve_type = PJFNK
start_time = 0
end_time = 1
scheme = crank-nicolson
petsc_options_iname = '-pc_type -pc_sub_type'
petsc_options_value = 'asm ilu'
[./TimeStepper]
type = PostprocessorDT
postprocessor = cfl
scale = 0.8
[../]
[]
(modules/level_set/examples/circle/circle_16.i)Output
Finally, the Outputs defines a single types of output. The exodus output contains the mesh and field data for the simulation.
[Outputs]
csv = true
exodus = true
[]
(modules/level_set/examples/circle/circle_16.i)Results
Figure 1 show the results of the simulation defined by executing the (modules/level_set/examples/circle/circle_16.i) input file, which can be done using the following commands.
cd ~/projects/moose/modules/level_set/examples/circle
../../level_set-opt -i circle_16.i
Given the constant velocity of 3 in the input file for the x and y directions the initial circle translates at a 45 degree angle and performs three complete transects of the domain, more or less cycles could be achieved by altering the end time in the Executioner block.
Ideally, the circle would maintain it shape throughout the simulation since it is simply being advected by a constant velocity. This is not the case in the results shown in Figure 1, which clearly shows the initial circle being deformed during the simulation.
One method to improve the solution is to increase the number of finite elements in the mesh, which can be done from the command line:
../../level_set-opt -i circle_16.i Mesh/uniform_refine=2
This will cause two uniform refinements of the mesh. Doing this increases the problem size dramatically due to the increased number of elements and for this problem it also causes the time step to decrease because the timestep is a function of the element size (see LevelSetCFLCondition). For this simple example, the increased number of timesteps and the increased problem size are noticeable but do not cause an intractable increase of run time.
Figure 2 shows the results from running (modules/level_set/examples/circle/circle_16.i) with two uniform refinements applied, the improvement in the solution is drastic and for this simple example may be adequate.