Material objects that internally derive from
DerivativeFunctionMaterialBase (Doxygen), like the materials for the Parsed Function Kernels are used to provide the free energy expressions for each phase.
The flexible multiphase model uses _n_ order parameters to control n phases while employing a Lagrange multiplier based constraint to enforce the sum of all phase contributions to be one at every point in the simulation cell.
For multiphase models with n phases
DerivativeMultiPhaseMaterial can be used to form the global free energy as
We need to enforce the constraint for
which ensures that the total weight of all phase free energy contributions at each point in the simulation volume is exactly unity (up to an ). This is achieved using either a hard or soft constraint enforcement method.
Check out the example input at
moose/modules/phase_field/examples/multiphase/DerivativeMultiPhaseMaterial.i to see it in action.
Lagrange multiplier constraint
As first (hard) method for constraint enforcement the Lagrange multiplier technique is available, where the Lagrange multiplier is a non-linear variable
With being the weak form (Allen-Cahn) residual for the th non-conserved order parameter, we need to find satisfying the boundary conditions and such that
holds for every test function and .
The Jacobian fill term introduces a small dependence in the constraint through a small factor (defaults to ), which results in an on-diagonal Jacobian value of in the kernel (it drops out in the kernel). This is necessary to force a Jacobian matrix with full rank, avoids "Zero pivot" PETSc-Errors, and greatly improves convergence. The cost is a violation of the constraint by about , however this constraint violation can be made as small as the convergence limits.
As an alternative (softer) constraint enforcement we provide the
SwitchingFunctionPenalty (Doxygen) kernel, which effectively adds a free energy penalty of (with ), where is the penalty prefactor (
penalty). The constraint is enforced approximately to a tolerance of (depending on the shape and units of the free energy).
An example material block looks like this (materials for phase field mobilities omitted for clarity).
[Materials] # Free energy for phase A [./free_energy_A] type = DerivativeParsedMaterial block = 0 f_name = Fa args = 'c' function = '(c-0.1)^2' third_derivatives = false enable_jit = true [../] # Free energy for phase B [./free_energy_B] type = DerivativeParsedMaterial f_name = Fb args = 'c' function = '(c-0.9)^2' third_derivatives = false enable_jit = true [../] [./switching] type = SwitchingFunctionMaterial eta = eta h_order = SIMPLE [../] [./barrier] type = BarrierFunctionMaterial eta = eta g_order = SIMPLE [../] # Total free energy F = h(phi)*Fb + (1-h(phi))*Fa [./free_energy] type = DerivativeTwoPhaseMaterial f_name = F # Name of the global free energy function (use this in the Parsed Function Kernels) fa_name = Fa # f_name of the phase A free energy function fb_name = Fb # f_name of the phase B free energy function args = 'c' eta = eta # order parameter that switches between A and B phase third_derivatives = false outputs = exodus [../] 
The phase free energies are single wells. The global free energy landscape will however have a double well character in this example.