Hi,

I have recently been working on an application of Cahn-Hilliard to a 
ternary system, and in the process of implementing the model, I have 
stumbled upon two main questions.

Firstly, I would like to know if the known problems of the coupled 
implementation will prevent me from developing the model. My system of 
equations is formed by two coupled sets of two equations each, so 4 eqs in 
total, with two of them solving for (following the example's notation) 
phi1, psi1, and the other set solving for phi2, psi2. However, the 
equations for phi1 and psi1 also depend on phi2 and psi2, respectively, and 
vice versa. 

I have seen that Pysparse seems to take too much memory (is this the 
default solver?) and Trillinos cannot solve the coupled system, so I 
understand my best shot is PETSc (since my equations aren't in vector 
form). How would the implementation of this method be different from the 
code below?

############
c=0
while elapsed < duration:
    res = 1.0
    phi1.updateOld()
    phi2.updateOld()
    phi3.value = 1.0 - phi1 - phi2   # Unimportant variable, does not 
appear in the equations at all

    psi1.updateOld()
    psi2.updateOld()

    dt = min(100, numerix.exp(dexp))
    elapsed += dt
    dexp += 0.01

    while res > 1.0e-3:
        res = eq.sweep(dt=dt)
        print(res)
############

And secondly, about the evolution of phi in a binary system: I decided to 
work from the tutorial (link) towards my equation, as implementing my model 
directly led to issues. One of the first steps I took was, for the system 
in 1D, changing the ICs from gaussian noise with the mean in 0.5 to 
two-layered ones, with phi = 0.9999 at one side of the mesh, and phi = 0.2 
in the other.  Full code for this described change is at the end.

Since these are very close to the minima displayed by the free energy 
density (same one as in the tutorial), I expected the system to just smooth 
out the interface a bit, with the bulk concentrations staying mainly where 
they were. However, what I have seen instead is, for some reason, the 
concentrations increasing/decreasing along the interface, going into values 
>1 before stabilising in the expected profile (see images below). If one of 
the ICs defines phi as 0.0001, the phi in that section of the mesh goes 
into values <0 before stabilising.

[image: ICs_phi.png][image: snapshot_phi_0.006737946999085467.png][image: 
snapshot_phi_0.19907123629213125.png][image: 
snapshot_phi_449.7430549622601.png]
where the three first images correspond to the ICs and the very beginning 
of the simulation, and the last image is the final profile reached.

Since the free energy density used in the tutorial is a polynomial, it 
doesn't have any singularities, and therefore I understand that phi 
technically can go below 0 or above 1. In this case, is there a way to 
constrain the values the solver can accept in the solution? Would this be 
an acceptable fix, or would it interfere with the dynamics? Would a better 
approach be to use a log form in the free energy? 

Thank you very much in advance.

Kind regards,
Irene


#######################################################################
from fipy import CellVariable, Grid1D, GaussianNoiseVariable, 
DiffusionTerm, TransientTerm, ImplicitSourceTerm, Viewer
from fipy.tools import numerix
import numpy as np

nx = 20
mesh = Grid1D(nx=nx, dx=0.25)
lx = 0.25 * nx
height = mesh.cellCenters[0]

D = 1.
a = 1.
epsilon = 0.5

phi = CellVariable(name=r"$\phi$", mesh=mesh)
psi = CellVariable(name=r"$\psi$", mesh=mesh)

phi[:] = 1.0
phi[height > lx/2] = 0.2

psi.value[:] = a**2 * phi.value[:] * (1 - phi.value[:]) * (1 - 2 * 
phi.value[:])

viewer_phi = Viewer(vars=(phi,), datamin=-0.05, datamax=1.05)
viewer_psi = Viewer(vars=(psi,), datamin=-0.05, datamax=3.0)

viewer_phi.plot(f'ICs_phi.png')
viewer_psi.plot(f'ICs_psi.png')

dfdphi = a**2 * phi * (1 - phi) * (1 - 2 * phi)
d2fdphi2 = a**2 * (1 - 6 * phi * (1 - phi))

eq1 = (TransientTerm(var=phi) == DiffusionTerm(coeff=D, var=psi))
eq2 = (ImplicitSourceTerm(coeff=1., var=psi)
       == ImplicitSourceTerm(coeff=d2fdphi2, var=phi) - d2fdphi2 * phi + 
dfdphi
       - DiffusionTerm(coeff=epsilon**2, var=phi))

eq = eq1 & eq2

dexp = -5
elapsed = 0.
duration = 500.
c=0

while elapsed < duration:
    dt = min(100, numerix.exp(dexp))
    elapsed += dt
    dexp += 0.01
    eq.solve(dt=dt)
    if c % 25 == 0:
        viewer_phi.plot(f'snapshot_phi_{elapsed}.png')
        viewer_psi.plot(f'snapshot_psi_{elapsed}.png')
    c +=1
#######################################################################

-- 
To unsubscribe from this group, send email to [email protected]

View this message at https://list.nist.gov/fipy
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].

Reply via email to