Example 06 : Transient Analysis

Problem Statement

We consider the transient diffusion equation on the 3D domain Ω\Omega: find uu such that u=20utΩ-\nabla \cdot \nabla u = 20\frac{\partial u}{\partial t} \in \Omega, u=0u = 0 on the bottom, u=1u = 1 on the top and with un^=0\nabla u \cdot \hat{n} = 0 on the remaining boundaries. The initial condition is u(t0)=0u(t_0) = 0 everywhere except on the top boundary where u=1u = 1.

The weak form of this equation, in inner-product notation, is given by: ϕi,uh=ϕi,20uhtϕi\nabla \phi_i, \nabla u_h = \phi_i, 20 \frac{\partial u_h}{\partial t} \quad \forall \phi_i, where ϕi\phi_i are the test functions and uhu_h is the finite element solution.

Constructing the Problem

First, we need a transient term to for our residual. We can create a time-dependent residual term by inheriting from the TimeDerivative class. For this example, we create a constant-scalable time-dependent residual along the lines of kernels created in the earlier examples:

#include "ExampleTimeDerivative.h"

#include "Material.h"

registerMooseObject("ExampleApp", ExampleTimeDerivative);

template <>
InputParameters
validParams<ExampleTimeDerivative>()
{
  InputParameters params = validParams<TimeDerivative>();
  params.addParam<Real>("time_coefficient", 1.0, "Time Coefficient");
  return params;
}

ExampleTimeDerivative::ExampleTimeDerivative(const InputParameters & parameters)
  : TimeDerivative(parameters),
    _time_coefficient(getParam<Real>("time_coefficient"))
{
}

Real
ExampleTimeDerivative::computeQpResidual()
{
  return _time_coefficient * TimeDerivative::computeQpResidual();
}

Real
ExampleTimeDerivative::computeQpJacobian()
{
  return _time_coefficient * TimeDerivative::computeQpJacobian();
}
(examples/ex06_transient/src/kernels/ExampleTimeDerivative.C)

The input file for this is very similar to the simple diffusion input file from example 1. We need to add the time derivative residual contribution:

[Kernels]
  [./diff]
    type = Diffusion
    variable = diffused
  [../]

  # Include our time derivative here
  [./euler]
    type = ExampleTimeDerivative
    variable = diffused
    time_coefficient = 20.0
  [../]
[]
(examples/ex06_transient/ex06.i)

And finally, we need to specify some transient related parameters:

[Executioner]
  type = Transient # Here we use the Transient Executioner (instead of steady)
  solve_type = 'PJFNK'
  num_steps = 75 # Run for 75 time steps, solving the system each step.
  dt = 1 # each time step will have duration "1"
[]
(examples/ex06_transient/ex06.i)

There are many more options available that are described in the Transient Executioner documentation. It is also common to use more sophisticated ways for time-stepping through simulations. Example 16 goes over some of this and details about specific time stepping schemes are provided in the Timestepper System documentation.

Outputs

Here are solution snapshots from the beginning and end times from running ex06-opt -i ex06.i:

Complete Source Files