Phase Field
See also:
PhaseFieldclass API reference — for the method-by-method interface of thePhaseFieldC++ class.
The phase-field model is used to simulate processes that can be described by the evolution of domain-level order parameters — solidification, solid-state transformations, grain growth, and related problems. It represents interfaces between sub-domains
Phase fields
The phase fields satisfy the constraint:
at every point
The following sections present a detailed description of the multiphase-field model as implemented in OpenPhase.
The phase-field model in OpenPhase describes the evolution of phase fields
where:
is the interface mobility between phase fields and , is the total free energy, given by:
The number of phase fields contributing at a given position
with the active set of phase fields at
The interfacial free energy density is defined as:
Here:
is the interface width, is the interfacial energy between phases and .
Defining the interface term:
the grain boundary contribution to the phase evolution becomes:
An alternative form:
Or, in terms of interface fields
Here,
Computational Efficiency
A naive implementation of the phase-field equation would have computational complexity
To address this, active parameter tracking was introduced to reduce computation by discarding insignificant phase field contributions. In models using a double-well potential, the phase-field profile is governed by a
However, for models using a double-obstacle potential (with
Remark 1: If both
and , then phase does not contribute to .
This allows safe omission of these terms without affecting results.
Remark 2: It is still possible for
even when both and . This signifies the nucleation of a new phase, which is handled separately in the nucleation section.
Incorporating this into the evolution equation, we obtain:
Here, the indicator function
This optimization allows the solver to skip unnecessary computations while preserving accuracy.
Normal Grain Growth Example
A basic example for the multiphase-field method is the simulation of grain growth, it only considers the interface energies and not other contributions to the driving force. Minimizing the interface energy results in large grains to grow and small grains to shrink. Here is a basic example code for a grain growth simulation
#include "Settings.h"
#include "RunTimeControl.h"
#include "DoubleObstacle.h"
#include "PhaseField.h"
#include "Initializations.h"
#include "BoundaryConditions.h"
#include "InterfaceProperties.h"
#include "Tools/TimeInfo.h"
#include "Tools/MicrostructureAnalysis.h"
using namespace std;
using namespace openphase;
int main(int argc, char *argv[])
{
std::string InputFile;
if(argc > 1)
{
InputFile = argv[1];
}
else
{
std::cerr << "No Inputfile provided, trying to use default ProjectInput.opi" << std::endl;
InputFile = "ProjectInput.opi";
}
Settings OPSettings;
OPSettings.ReadInput(InputFile);
RunTimeControl RTC(OPSettings, InputFile);
PhaseField Phi(OPSettings, InputFile);
DoubleObstacle DO(OPSettings, InputFile);
InterfaceProperties IP(OPSettings, InputFile);
BoundaryConditions BC(OPSettings, InputFile);
//generating initial grain structure using Voronoi algorithm
int number_of_grains = 200;
size_t GrainsPhase = 0;
Initializations::VoronoiTessellation(Phi, BC, number_of_grains, GrainsPhase);
std::cout << "Entering the Time Loop!!!" << std::endl;
for(RTC.tStep = RTC.tStart; RTC.tStep <= RTC.nSteps; RTC.IncrementTimeStep())
{
IP.Set(Phi, BC);
DO.CalculatePhaseFieldIncrements(Phi, IP);
Phi.NormalizeIncrements(BC, RTC.dt);
Phi.MergeIncrements(BC, RTC.dt);
/// Output to VTK file
if (RTC.WriteVTK())
{
Phi.WriteVTK(OPSettings, RTC.tStep);
MicrostructureAnalysis::WriteGrainsStatistics(Phi,RTC.tStep);
}
/// Output raw data
if (RTC.WriteRawData())
{
Phi.Write(OPSettings, RTC.tStep);
}
/// Output to screen
if (RTC.WriteToScreen())
{
double I_En = DO.AverageEnergyDensity(Phi, IP);
std::string message = ConsoleOutput::GetStandard("Interface energy density", I_En);
ConsoleOutput::WriteTimeStep(RTC, message);
}
}
return EXIT_SUCCESS;
}This example shows how to setup a simple simulation using the OpenPhase library. The path to input file (*.opi) for this simulation can be given as an argument when calling the executable of this example. The input file should contain the following information:
@RunTimeControl
$SimTtl Simulation Title : Normal grain growth
$nSteps Number of Time Steps : 2000
$FTime Output to disk every (tSteps) : 100
$STime Output to screen every (tSteps) : 100
$LUnits Units of length : m
$TUnits Units of time : s
$MUnits Units of mass : kg
$EUnits Energy units : J
$dt Initial Time Step : 1e-5
$nOMP Number of OpenMP Threads : 1
$Restrt Restart switch (Yes/No) : No
$tStart Restart at time step : 0
$tRstrt Restart output every (tSteps) : 10000
@GridParameters
$Nx System Size in X Direction : 101
$Ny System Size in Y Direction : 101
$Nz System Size in Z Direction : 101
$dx Grid Spacing : 1e-6
$IWidth Interface Width (in grid points) : 5.0
@Settings
$Phase_0 Name of Phase 0 : Phase1
@InterfaceProperties
$EnergyModel_0_0 Interface energy model : ISO
$Sigma_0_0 Interface energy : 0.24
$MobilityModel_0_0 Interface energy model : ISO
$Mu_0_0 Interface mobility : 1.0e-7
@BoundaryConditions
$BC0X X axis beginning boundary condition : Periodic
$BCNX X axis far end boundary condition : Periodic
$BC0Y Y axis beginning boundary condition : Periodic
$BCNY Y axis far end boundary condition : Periodic
$BC0Z Z axis beginning boundary condition : Periodic
$BCNZ Z axis far end boundary condition : PeriodicIn this RunTimeControl controls anything related to time and time steps, such as the time step dt, the total number of timesteps nSteps as well as the frequency of output to files FTime and to screen STime. The functions RTC.WriteVTK() and RTC.WriteRawData() will return true if and only if
same for RTC.WriteToScreen() and STime. Gridparameters is a subclass of Settings and the input is automatically read when the input of Settings is read, therefore Gridparameters does not appear in the c++-code explicitly, but is used by all other classes that contain storages. This is the reason why Settings needs call ReadInput before all other classes are constructed as information such as domain size needs to passed to each class so that the storages of the appropriate size can be allocated in the memory. Settings itself only contains the name of the one phase in this simulation, in general it contains the names of all phases and elements. InterfaceProperties is used to define the interface energy and mobility and their anisotropy, for the simulation of normal grain growth the interface energy and mobility are both isotropic. For this simulation we also use periodic boundary conditions in all directions. Instead of
RunTimeControl RTC(OPSettings, InputFile);it also possible to create an object with the default constructor and then call the functions Initialize(Settings& settings) and ReadInput(std::string InputFile) like this
RunTimeControl RTC;
RTC.Initialize(OPSettings);
RTC.ReadInput(InputFile);this can be done for all classes in the OpenPhase library that have an Initialize function with Settings as an argument. The initializations class offers a variety of static functions that produce an initialize arrangement of phases for the simulation, in this we use a Voronoi Tesselation. In the timeloop
IP.Set(Phi, BC);
DO.CalculatePhaseFieldIncrements(Phi, IP);
Phi.NormalizeIncrements(BC, RTC.dt);
Phi.MergeIncrements(BC, RTC.dt);the function IP.Set calculates the interface energy and mobility in each interface point. As this is a simulation with isotropic interface energy and mobility the calculation is trivial. In further simulation anisotropy and temperature dependence of the interface properties will be discussed. DO.CalculatePhaseFieldIncrements calculates the increments
See also: examples
In OpenPhase-main/examples/:
NormalGG— the canonical normal-grain-growth simulation; the worked example on this page is built from it.FacetedGG— grain growth with faceted anisotropy.Pearlite,PrecipitationNiTi,Superalloys— solid-state phase transformations.SolidificationFeCetc. — solidification (combinePhaseFieldwithCompositionandEquilibriumPartitionBinary).HeatDiffusion,LatentHeat— phase-field with a coupled thermal field.
Driving Forces
The free energy in the phase-field model can be extended by including additional energy contributions, such as an additional driving force term
Using a variational derivation, the phase-field evolution equation is extended to:
with the driving force:
A key strength of the phase-field model in OpenPhase is its rigorous treatment of interface properties. A fundamental assumption of the model is that a steady phase-field contour along the interface normal is maintained throughout the simulation. This ensures a constant interface width, which is essential for correctly modeling interface properties and kinetics.
Depending on the origin of the driving force
To enforce this,
This form guarantees that the driving force contribution is independent of spatial discretization, similar to the curvature term. Integrating the traveling wave solution of the phase-field equation yields the final expression:
This can be decomposed into:
or:
and finally: