Skip to content

Introduction

In this step, we will try to solve the CahnHilliard equation for the spinodal decomposition problem.

The CahnHilliard equation

The CahnHilliard equation can be read as follows: $$ \begin{equation} \frac{\partial c}{\partial t}=\nabla\cdot(M(c)\nabla\mu) \label{eq:ch-c} \tag{1} \end{equation} $$ and $$ \begin{equation} \mu=\frac{\delta f}{\delta c} \label{eq:ch-mu} \tag{2} \end{equation} $$ where \(c\) and \(\mu\) denote the concentration and chemical potential, respectively. \(M(c)\) is the concentration dependent mobility, in this model we use \(M(c)=Dc(1-c)\), where \(D\) is the diffusion coefficient.

Free energy

In this model, we use the following free energy: $$ \begin{equation} f=c\ln(c)+(1-c)\ln(1-c)+\chi c(1-c)+\kappa|\nabla c|^{2} \label{eq:free-energy} \tag{3} \end{equation} $$ thereby, the chemical potential \(\mu\) can be expressed as: $$ \begin{equation} \mu=\ln(c)-\ln(1-c)+\chi(1-c)-\kappa\nabla^{2}c \label{eq:mu} \tag{4} \end{equation} $$ where \(\chi\) denotes the interaction between two phases. \(\kappa\) represents the interface energy contribution, which is proportional to the thickness of the phase interface.

The related boundary conditions can be read as: $$ \begin{equation} -D\nabla c\cdot\vec{n}=0\qquad\mathrm{on}\quad\partial\Omega_{N} \label{eq:flux} \tag{5} \end{equation} $$ where the zero flux (Neumann) boundary condition is assumed in Eq.\(\eqref{eq:flux}\).

Define the mesh

We use a square domain here for our calculation, and then the [mesh] block can be given as:

[mesh]
  type=asfem
  dim=2
  xmax=4.0
  ymax=4.0
  nx=100
  ny=100
  meshtype=quad4
[end]

where a \(4\times4\) mesh is defined.

Gauss point integration (optional)

If one wants to use second order mesh, for instance meshtype=quad9, then one need to use a higher order gauss points. This can be implemented via:

[qpoint]
  type=gauss
  order=3
[end]

Normally, you don't need this block!

Define the DoFs

In order to solve the 4th order equation, we split the CH equation into two second-order equations. Therefore, the DoFs used in this step are the concentration \(c\) and the chemical potential \(\mu\). Then the [dofs] block can be read as:

[dofs]
name=c mu
[end]

Element for the CahnHilliard equation

The model in Eq.\(\eqref{eq:ch-c}\) and \(\eqref{eq:ch-mu}\) can be applied in the following lines

[elmts]
  [mych]
    type=cahnhilliard
    dofs=c mu
    mate=myf
  [end]
[end]

where type=cahnhilliard option specifies the element we want to use for the CahnHilliard equation. Moreover, we will use the free energy(\(F\)), the first order derivative of free energy(\(\frac{\partial F}{\partial c}\)), and the second order derivative of free energy(\(\frac{\partial^{2}f}{\partial c^{2}}\)) material properties. Therefore, the related material definition will be given in myf block.

free energy material

Via the following lines in your [mates] block, the material properties, i.e. \(F\), \(\frac{\partial F}{\partial c}\), and \(\frac{\partial^{2}F}{\partial c^{2}}\) can be easily defined:

[mates]
  [myf]
    type=cahnhilliard
    params=1.0 2.5 0.005
  [end]
[end]

where type=cahnhilliard specifies constant diffusivity material type. Don't worry, here we used the same name as the type= in [elmts] block. But AsFem knows that they belong to two different blocks, so it's fine. params= defines the diffusivity \(D=1.0\), the phase interaction constant \(\chi=2.5\), and the interface parameter \(\kappa=0.02\). If you are using a coarse mesh, please increase \(\kappa\) to a larger value, i.e. 0.02 or even higher.

Boundary conditions

Since the zero flux boundary condition is applied, we don't need any [bcs] block. If Eq.\(\eqref{eq:flux}\) is nonzero, then you will definitely need the [bcs] block.

Transient analysis

Again, we need a [job] block to start the FEM calculation, which can be given as follows:

[job]
  type=transient
  debug=dep
[end]

Timestepping

In this case, we will use the adaptive time stepping to speed up our simulation. The layout of our [timestepping] block looks like below:

[timestepping]
  type=be
  dt=1.0e-5
  time=1.0e3
  adaptive=true
  optiters=3
  growthfactor=1.1
  cutfactor=0.85
[end]

where type=be specifies the Backward-Euler (be) method for implicit time integration. dt=1.0e-5 defines that the initial \(\Delta_{t}\) and time=1.0e3 means the final time is 1000.0. adaptive=true enables the adaptive time stepping. optiters=3 indicates that if the nonlinear iterations is not greater than 3, then AsFem will increase the new delta t to be \(\Delta_{t}=\Delta_{t,\mathrm{old}}*\alpha_{\mathrm{growth}}\). Otherwise, the new delta t will be reduced as \(\Delta_{t}=\Delta_{t,\mathrm{old}}*\alpha_{\mathrm{cut}}\). growthfactor and cutfactor represent \(\alpha_{\mathrm{growth}}\) and \(\alpha_{\mathrm{cut}}\), respectively.

Initial condition

Now, in order to allow the phase separation to take place, we must add the random value to the concentration. As follows, the random concentration value can be applied through the'[ics]' block:

[ics]
  [ic1]
    type=random
    dof=c
    params=0.6 0.66
  [end]
[end]

where the random value is applied via the type=random option. dof= indicates which DoF will be used. params= represent the parameters used in the initial condition calculation. For the type=random case, 0.6 and 0.66 are the min and max value of the random numbers.

Parallel solver

In order to further speed up our simulation, we involve the parallel solver from either mumps or superlu_dist. This can be defined via the [nonlinearsolver] block:

[nonlinearsolver]
  type=nr
  solver=superlu
[end]

where type=nr indicates the newton-raphson method. solver= determines the name of the parallel solver, in this case, the superlu_dist solver is used. It should be noted that, if external solvers, i.e. mumps and superlu, are not compiled within your PETSc, then you can only use the built-in solver. In short, this option doesn’t make sense to you.

Run it in AsFem

Now, let's try your fourth example in AsFem. You can create a new text file and name it as step5.i or whatever you like. Then copy the following lines into your input file:

[mesh]
  type=asfem
  dim=2
  xmax=4.0
  ymax=4.0
  nx=100
  ny=100
  meshtype=quad4
[end]

[dofs]
name=c mu
[end]

[elmts]
  [mych]
    type=cahnhilliard
    dofs=c mu
    mate=myf
  [end]
[end]

[mates]
  [myf]
    type=cahnhilliard
    params=1.0 2.5 0.005
    //     D   Chi Kappa
  [end]
[end]

[timestepping]
  type=be
  dt=1.0e-5
  time=3.0e3
  adaptive=true
  optiters=3
  growthfactor=1.1
  cutfactor=0.85
[end]

[nonlinearsolver]
  type=nr
  solver=superlu
[end]

[ics]
  [ic1]
    type=random
    dof=c
    params=0.6 0.66
  [end]
[end]

[job]
  type=transient
  debug=dep
[end]

You can also find the complete input file in examples/tutorial/step5.i.

If everything goes well, you can see the following image in your Paraview: middle

final