spectralDNS / shenfun

High performance computational platform in Python for the spectral Galerkin method

Home Page:http://shenfun.readthedocs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Two questions about the Legendre-Galerkin method for the Cahn-Hilliard equation

liqihao2000 opened this issue · comments

commented

Dear Mikael,

For the Allen-Cahn equation with homogeneous Neumann and periodic boundary conditions, I implement the code with Legendre and Fourier Galerkin method. Now, I have two questions about the Legendre-Galerkin method for the Cahn-Hilliard equation:

  1. In the case of the Fourier-Galerkin for the periodic boundary condition, the code with shenfun has been implemented. But I do not know how to implement the Legendre-Galerkin method for the Cahn-Hilliard equation in the case of the homogeneous Neumann boundary condition.
  2. How to impose boundary conditions in shenfun so that the Cahn-Hilliard equation can be solved in the following two weak forms?

Cahn-Hilliard equation

The Cahn-Hilliard equation is a parabolic equation and is typically used to model phase separation in binary mixtures. It involves first-order time derivatives, and second- and fourth-order spatial derivatives. The equation reads:

$$ \begin{align} \frac{\partial \phi}{\partial t} - \nabla \cdot M \left(\nabla\left(f(\phi) - \epsilon^2 \Delta\phi\right)\right) &= 0 \quad {\rm in} \ \Omega, \\ \nabla\left(f(\phi) - \epsilon^2 \Delta\phi\right) \cdot {n} &= 0 \quad {\rm on} \ \partial\Omega, \\ \nabla \phi \cdot {n} &= 0 \quad {\rm on} \ \partial\Omega, \end{align} $$

with initial data $\phi({x},0) = \phi^0({x})\ {\rm in} \ \Omega,$
where $\phi$ is the unknown field, the function $f$ is usually non-convex in $\phi$ (a fourth-order polynomial is commonly used), ${n}$ is the outward directed boundary normal, and $M$ is a scalar parameter.

1. Direct solver

Time discretisation

$$ \begin{align} \frac{\phi^{n+1} - \phi^n}{\delta t} - \nabla \cdot M \nabla\left(-\epsilon^2 \Delta\phi^{n+1} +S(\phi^{n+1}-\phi^n) + f(\phi^n) \right) &= 0. \end{align} $$

where $S>0$ is a stabilization parameter.

Weak formulation

$$ \begin{align} \left(\frac{\phi^{n+1} - \phi^n}{\delta t M},\psi \right)+ \left( \nabla\left(-\epsilon^2 \Delta\phi^{n+1} +S(\phi^{n+1}-\phi^n) + f(\phi^n)\right), \nabla\psi \right) &= 0, \end{align} $$

$\Rightarrow$

$$ \begin{align} \frac{1}{\delta t M}\left(\phi^{n+1} - \phi^n,\psi \right)+ \epsilon^2( \Delta\phi^{n+1}, \Delta\psi) +S\left(\nabla(\phi^{n+1}-\phi^n), \nabla\psi \right) + (\nabla f(\phi^n), \nabla\psi) &= 0. \end{align} $$

2. Mixed solver

Mixed form

A solution is to rephrase the problem as two coupled second-order equations:

$$ \begin{align} \frac{\partial \phi}{\partial t} - \nabla \cdot M \nabla\mu &= 0 \quad {\rm in} \ \Omega, \\ \mu + \epsilon^2 \Delta\phi - f(\phi) &= 0 \quad {\rm in} \ \Omega, \\ \nabla \mu \cdot {n} &= 0 \quad {\rm on} \ \partial\Omega, \\ \nabla \phi \cdot {n} &= 0 \quad {\rm on} \ \partial\Omega.\\ \end{align} $$

Time discretisation

$$ \begin{align} \frac{\phi^{n+1} - \phi^n}{\delta t M} - \nabla \cdot \nabla\mu^{n+1} &= 0, \\ \mu^{n+1} + \epsilon^2 \Delta\phi^{n+1} -S(\phi^{n+1}-\phi^n)- f(\phi^n) &= 0, \end{align} $$

where $S>0$ is a stabilization parameter.

Weak formulation

$$ \begin{align} \left(\frac{\phi^{n+1} - \phi^n}{\delta t M},\psi \right)+ \left( \nabla\mu, \nabla\psi \right) &= 0,\\ (\mu^{n+1},v) - \epsilon^2 (\nabla\phi^{n+1},\nabla v) -S\left((\phi^{n+1}-\phi^n),v\right)- (f(\phi^n),v) &= 0. \end{align} $$

Demo parameters

The following domains, functions and time stepping parameters are used in this demo:

  • $\Omega = (0, 2) \times (0, 1),$
  • $F(\phi) = \frac{1}{4}(\phi^2-1)^2,$
  • $f(\phi) = \frac{d F}{d \phi} = \phi^3-\phi,$
  • $\epsilon = 1 \times 10^{-2},$
  • $M = 1 \times 10^{-2},$
  • $dt = 0.001,$
  • $S = 3,$
  • $[0, T] = [0, 5],$
  • $\phi^0({x}) = \cos(2 \pi x) + 0.001 \cos(16\pi x).$

Hi
Looking at your problem you seem to need a biharmonic basis with only Neumann boundary conditions. You can create such a space with

from shenfun import *
N = 10
D = FunctionSpace(N, 'L', bc={'left': {'N': 0, 'N3': 0}, 'right': {'N': 0, 'N3': 0}} )

The space has not been precomputed, so it will take some time to find the correct stencil. You should probably implement the space with hardcoded stencil, like this:

from shenfun.legendre.bases import CompositeBase
class MyBiharmonic(CompositeBase):
    def __init__(self, N, quad="LG", bc=(0,)*8, domain=(-1, 1), dtype=float,
                 padding_factor=1, dealias_direct=False, coordinates=None, **kw):
        CompositeBase.__init__(self, N, quad=quad, domain=domain, dtype=dtype, bc=bc,
                               padding_factor=padding_factor, dealias_direct=dealias_direct,
                               coordinates=coordinates)
        from shenfun.utilities import n
        self._stencil = {
            0: 1,
            2: -2*n*(2*n**2 + 7*n + 5)/(2*n**3 + 21*n**2 + 67*n + 63),
           4: n*(2*n**4 + 11*n**3 + 16*n**2 + 4*n - 3)/(2*n**5 + 39*n**4 + 296*n**3 + 1086*n**2 + 1907*n + 1260)
        }
       
    @staticmethod
    def boundary_condition():
        return 'Biharmonic N1N3'

    @staticmethod
    def short_name():
        return 'B3'

and then use it instead of the FunctionSpace, like

N = 10
D = MyBiharmonic(N, bc={'left': {'N': 0, 'N3': dfdx}, 'right': {'N': 0, 'N3': dfdx}})

where dfdx is the nonhomogeneous function you want to use for the boundary condition. Not quite sure how this should be, but you can compute dfdx from the Function phi.

Regarding the time discretization I recommend using the IMEX integrators in utilities.integrators (IMEXRK222, IMEXRK3, IMEXRK443). In ChannelFlow2D I solve a time-dependent biharmonic equation this way. Please have a look and see if you can copy this approach.

Hope this helps. I have never tried this basis before, and you may run into some unanticipated trouble. In that case, please let me know:-)

commented

@mikaem Thanks for your useful comment. In the first stage, I implemented my code for the Cahn-Hilliard equation with the mixed solver. It works very well!