pf-UBC Logo

Welcome to pf-UBC

The Phase-Field Grain-Growth Toolkit

pf-UBC is a powerful and easy-to-use simulation tool designed to model grain growth in polycrystalline materials using the phase-field method. Built with researchers, students, and materials engineers in mind, it enables users to generate microstructures, simulate grain evolution, and visualize results with minimal setup. If you're studying grain boundary motion—including the effects of fine, non-scalable particle pinning — pf-UBC offers a flexible and efficient platform to explore complex grain growth phenomena with scientific accuracy and a user-friendly design.


This application was developed at The University of British Columbia, Vancouver, Canada

  • Credits:
  • Dr. Ashish Dhole:
  • Dr. Matthias Militzer:

Grain Growth Model

The movement of grain boundaries (GBs) plays a fundamental role in the microstructural evolution of materials, as it enables the system to lower its total free energy. This energy reduction is influenced by several factors, including internal stresses, dislocation structures, and the energy associated with the grain boundaries themselves. To understand and predict this behavior, researchers have employed a variety of computational models.

Among the available techniques, the phase-field method stands out for its ability to simulate complex boundary interactions and morphological changes without explicitly tracking interfaces. Leveraging this approach, pf-UBC incorporates a multiphase grain growth model rooted in the pioneering studies by Chen and Yang (1994), Chen (1995), and refined further by Moelans et al. (2008). In this formulation, each grain is represented by an evolving order parameter that responds to energy gradients in the system. The temporal evolution of these parameters follows the Allen–Cahn equation, capturing the physics of grain boundary motion, given by :

$$ \frac{\partial \eta_i}{\partial t} \;=\; -L \frac{\delta F}{\delta \eta_i} $$

where $F$ is the free energy functional, $L$ is the order‐parameter mobility, and the $\delta$ operator represents a variational derivative.

$$ F = \int_{V}^{} f_{loc}(\eta_0, \eta_1,..., \eta_N) + f_{add}+\kappa\sum_{i}^{N}\left| \nabla \eta_i \right|^2 $$

where $N$ is the total number of order parameters, $f_{loc}$​ represents the local free energy density, and $f_{add}$​ represents any additional sources of energy density. $f_{loc}$ consists of two parts: (i) variation of local energy across the interface ($f_0$) and (ii) a contribution due to the internal bulk energy of the grains ($f_d$).

$$ f_{loc} = f_{0} + f_{d} $$

Here f0 is chosen to have a minimum of 0 inside each grain and a maximum at the interface resembling a double-well shape. Based on the formulation of Chen and Yang (1994), $f_0$ is proposed as:

$$ f_0 = m\left( \sum_{i=1}^{N}\frac{{\eta_i}^4}{4} - \sum_{i=1}^{N}\frac{{\eta_i}^2}{2} + \frac{3}{2}\sum_{i=1}^{N}\sum_{j\neq 1}^{N}{\eta_i}^2 {\eta_j}^2 + \frac{1}{4}\right) $$

where $m$ is a constant that determines the height of the energy peaks between each minima. Following Allen-Cahn dynamics, the evolution of the system results in a set of partial differential equation (PDEs):

$$ \frac{\partial{\eta_i}}{\partial t} = -L\frac{\delta{F}}{\delta{\eta_i}} = -L\left( \frac{\partial{f_0}}{\partial \eta_i} - \kappa\nabla^2\eta_i \right) \\[1.5em] \frac{\partial{\eta_i}}{\partial t} = -L\left[ m\left( {\eta_i}^3 - {\eta_i} + 3\eta_i \sum_{j\neq i}^{N} {\eta_j}^2\right) - \kappa\nabla^2 \eta_i\right] $$

References

  • Chen, Long-Qing, and Wei Yang. “Computer simulation of the domain dynamics of a quenched system with a large number of nonconserved order parameters: The grain-growth kinetics.” Physical Review B 50, no. 21 (1994): 15752.
  • Chen, Long-Qing. “A novel computer simulation for modeling grain growth.” Scripta Metallurgica et Materialia 32, no. 1 (1995).
  • Moelans, Nele; Bart Blanpain; Patrick Wollants. “Quantitative analysis of grain boundary properties in a generalized phase field model for grain growth in anisotropic systems.” Physical Review B 78, no. 2 (2008): 024113.

Friction Pressure

Second phase particles and solute atoms have been used as an important constituent to design materials and processes due to their ability to control motion of grain boundaries. These particles limit motion of grain boundaries by the particle pinning mechanism. in pf-UBC, a model on an energetic approach to include the drag pressure (Friction Pressure) directly into the phase-field equation. It avoids the phenomenological modification of the grain-boundary kinetics through mobility.

The bulk energy of grain $i$, $G_i$ is considered in comparison with a standard state. In a case where bulk energy of all grains is equal ($G_i = G_j$), $f_d = const$. and the driving pressure for grain-boundary movement is only due to its curvature. However, in a case of different bulk energies, $G_i \neq G_j$ , there is an additional driving pressure of $\Delta G_{ij} = G_j − G_i$ on the grain boundaries. In this situation, $f_d$ interpolates the bulk energy of each grain across the grain boundary. For two order parameters the contribution to the local energy density due to the bulk energy is written as:

$$ f_d = 3\sum_{i=1}^{2}\sum_{j \neq i}^{2}\left( \frac{\phi^2_{ij}}{2} - \frac{\phi^3_{ij}}{3}\right) \Delta G_{ij} + \frac{1}{2}\sum_{i=1}^{2} G_i \\[2em] \phi_{ij} = \frac{\eta_i - \eta_j +1}{2} $$

The derivation of $f_d$ can be simplified as

$$ \frac{\partial f_d}{\partial \eta_i} = 3 \eta_i \eta_j \Delta G_{ij} $$

Each pair of order parameters between ηi and ηj has a contribution to the $\frac{\partial f_d}{\partial eta_i}$ term. Therefore, a set of evolution PDEs are obtained by generalizing equation over all order parameter pairs:

$$ \frac{\partial{\eta_i}}{\partial t} = -L\frac{\delta{F}}{\delta{\eta_i}} = -L\left( \frac{\partial{f_0}}{\partial \eta_i} + \frac{\partial{f_d}}{\partial \eta_i}- \kappa\nabla^2\eta_i \right) \\[1.5em] \frac{\partial{\eta_i}}{\partial t} = -L\left[ m\left( {\eta_i}^3 - {\eta_i} + 3\eta_i \sum_{j\neq i}^{N} {\eta_j}^2\right) - 3 \eta_i \sum_{j \neq i}^{N} \eta_j \Delta G_{ij} - \kappa\nabla^2 \eta_i\right] $$

Condition for pinning in th presence of friction pressure is given by following condition:

$$ f_i' = \frac{\partial f_0}{\partial \eta_i} - \kappa\nabla^2 \eta_i $$
$$ \frac{\partial f_d}{\partial \eta_i} = \begin{cases} 3 \eta_i(1-\eta_i)sgn(f_i')P_z & \text{if } |f_i'| > |3\eta_i(1-\eta_i)P_z| \\ f_i' & \text{if } |f_i'| \leqslant |3\eta_i(1-\eta_i)P_z| \end{cases} $$

The detailed literature on friction pressure was presented by S. Shahandeh et al. (2012)

References

  • Chen, Long-Qing, and Wei Yang. “Computer simulation of the domain dynamics of a quenched system with a large number of nonconserved order parameters: The grain-growth kinetics.” Physical Review B 50, no. 21 (1994): 15752.
  • Shahandeh, S.; M. Greenwood; Matthias Militzer. “Friction pressure method for simulating solute drag and particle pinning in a multiphase-field model.” Modelling and Simulation in Materials Science and Engineering 20, no. 6 (2012): 065008.

Abnormal Grain Growth

This module of abnormal grain growth is based on the note on grain size dependent pinning given by Y. Bréchet and M. Militzer (2005).

When the grains are sufficiently small, i.e. smaller or comparable to the particle spacing, the number of triple junctions and quadruple points in a grain structure is much larger than the number of pinning particles, it is intuitively possible to position the special locations on the pinning particles at virtually no capillary cost. Then, the statistical argument used for the classical derivation of the Zener force no longer holds. As a result, the net pinning force per unit grain boundary area de- pends on grain size.

$$ P = \begin{cases} \displaystyle \frac{P_m}{L} D + P_r, & \text{for } D < L \\[10pt] \displaystyle (P_m - P_z) \exp\left(-\frac{D - L}{l}\right) + P_z + P_r, & \text{for } D> L \end{cases} $$

Where $l$ is the characteristic length, $L$ is the grain size where pinning is maximum ($P_{max} = P_m + P_r$), $P_m$ zener pinning due to large precipitates and $P_r$ is zener pinning due to fine precipitates. D is the grain size calculated at each time steps in the code.

References

  • Bréchet, Y.; M. Militzer. “A note on grain size dependent pinning.” Scripta Materialia 52, no. 12 (2005): 1299–1303.

Real Parameters

The code calculates the phase field parameter's $mobility, m, and kappa$ for the grain growth based on the model expressed by Moelans et al. (2008). Assuming Isotropic grain boundary properties, the parameters are calculated based on the grain boundary energy ($\sigma$), grain boundary mobility ($M_{GB}$) and the phase field interface width ($wGB$) as follows:

$$ L = \frac{4}{3} \frac{M_{GB}}{wGB} \\[1.5em] m = 6 \frac{\sigma}{wGB} \\[1.5em] kappa = \frac{3}{4} \sigma wGB \\[1.5em] $$

The grain boundary mobility can be defined in terms of the temperature ($T$) usinf Arhenius expression

$$ M_{GB} = GBmob_0 \exp \left( -\frac{Q}{k_b T}\right) $$

where $GBmob_0​$ is the mobility prefactor, $Q$ is the activation energy, and $k_b$​ is the Boltzmann constant.

References

  • Moelans, Nele; Bart Blanpain; Patrick Wollants. “Quantitative analysis of grain boundary properties in a generalized phase field model for grain growth in anisotropic systems.” Physical Review B 78, no. 2 (2008): 024113.

Getting Started

Contents of the package

The pf-UBC (Phase-Field at UBC) simulation toolkit is structured for clarity, modularity, and ease of use. Below is an annotated breakdown of the directory hierarchy:

                           ┌─ pf-UBC
                           |  ├─ Makefile
                           |  ├─ launcher
                           |  ├─ bin
                           │     ├─ generate_micro.sh
                           │     ├─ generate_micro_3d.sh
                           │     ├─ gg_run.sh
                           │     ├─ grain_growth.cpp
                           │     ├─ abnormal_gg_run.sh
               root_folder │     ├─ abnormal_grain_growth.cpp
                           │     ├─ real_gg_run.sh
                           │     ├─ real_grain_growth.cpp
                           │     ├─ gg_run_3d.sh
                           │     └─ grain_growth_3d.cpp
                           |  ├─ cluster_install.sh
                           |  ├─ submit.sh
                           |  ├─ real_submit.sh
                           |  ├─ abnormal_submit.sh
                           |  └─ submit_3d.sh
              

Summary of pf-UBC Directory Structure

--> bin/ — Simulation Scripts & Executables Contains all executable scripts and C++ simulation code, organized by simulation type (2D, 3D, abnormal, realistic):

  • grain_growth.cpp → 2D simulation
  • grain_growth_3d.cpp → 3D simulation
  • abnormal_grain_growth.cpp → Abnormal grain growth
  • real_grain_growth.cpp → Realistic grain growth
  • Accompanied .sh scripts for each type automate execution

--> Makefile — Build Automation Simplifies compilation of all simulation binaries with a single command:

--> launcher — Intractive launch execution launcher serves as the entry point or interface script to guide users through simulation setup.

--> shell sripts — Cluster submission scripts Cluster support is integrated via the submit.sh scripts and cluster_install.sh, making the package suitable for both local and high-performance computing environments.


Installation

After downloading the simulation toolkit folder from the repository, follow the folling command inside the pf-UBC folder

make install

This will check for all the required packages and if any on them are not installed already it will prompt the user to install on the local system. cluster_install.sh make all the shell scripts executable for smooth operation of the toolkit.

To install pf-UBC on windows, run PF-UBC setup file as an administrator.
Note: Simulation output will be saved in the installation directory. Choose the installation directory based on your usage and preference.


Running Condition

pf-UBC runs on all threads by default. The actual number of threads to use can be set at run stage, using the `OMP_NUM_THREADS` environment variable, as in

export OMP_NUM_THREADS=8

The environment variable is unset by default.


Launching the Toolkit

Once the toolkit is successfully installed, you can start the toolkit using launcher file.

./launcher

You will see the following screen on the terminal.


              ░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░
              
                      Phase-Field Grain-Growth Toolkit        
              
              ░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░
              
              Generate Microstructure 
               1) Generate 2d microstructure
               2) Generate 3d microstructure
              
               Generate Input Files 
               3) Create model input file
               4) Create real input file
              
               Grain Growth Models 
               5) Run model grain-growth simulation
               6) Run model 3d-grain-growth simulation
               7) Run abnormal grain-growth simulation
               8) Run real grain-growth simulation
              
               Exit! 
               9) Exit
              
              ░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░
              
              Enter choice [1-9]: 
              
              

You will observe that there are three sections in the launcher

  • Generate Microstructure
  • Generate Input Files
  • Grain Growth Models
Each section perform the operation as mentioned. The toolkit is made in such a way that you don't have to strictly follow the steps. For example, if you already have a microstructure and an input file ready, you can straight away perform the required grain growth simulation by choosing between 5-6. After every operation, the launcher will show main screen again unless 9) Exit is chosen.


Generate Microstructure

Generate Microstructure is a python based tool to create a microstructure of desired domain size and number of grains. By default the domain follows periodic boundary conditions in all directions and cannot be changed from the toolkit. But interested users can do madification in bin/generate_micro.sh or bin/generate_micro_3d.sh files.
This section has two sub-sections

                Generate Microstructure 
                1) Generate 2d microstructure
                2) Generate 3d microstructure
              
In Generate 2d microstructure, three files are generated, micro.txt (Grain ID map — each element in the array represents a grain label (an integer) at a grid point.), micro.png and friction.txt (A scalar field file representing the spatial distribution of friction pressure or drag resistance, used to control the local evolution of grain boundaries or transformation fronts.). Seed will asked down the line for repeatability.

In Generate 3d microstructure, only one vtk file will be generated.

Note: You can use the Generate 3D microstructure option to create both 2D and 3D initial microstructures by selecting the appropriate configuration. This gives users the flexibility to choose the output format—either .png or .vti — which will be saved in the results/ folder once the simulation begins.

If the user wishes to use another method to generate the initial microstructure, they may do so. However, they must convert it into a Grain ID map, where each element in the array represents a grain label (an integer) at a grid point. The file must be renamed to micro.txt (or micro.vtk) and saved in the root folder of the toolkit. The toolkit reads only micro.txt or micro.vtk as valid microstructure inputs.


Generate Input Files

The toolkit offers two different input generation. The model input file prompts user to enter the model grain growth parameters ($mobility, m, kappa$), whereas the real input file takes materials properties (grain boundary energy, temperature, etc. more can be found in the introduction section).

A model input file consists of following lines:

              nx [100]                         = #(number of mesh points in x direction)
              ny [100]                         = #(number of mesh points in y direction)
              nz [100 (1 if 2D)]               = #(number of mesh points in z direction)
              ngrains [100]                    = #(total number of initial grains)
              dx [1.0]                         = #(size of mesh in x direction)
              dy [1.0]                         = #(size of mesh in y direction)
              dz [1.0]                         = #(size of mesh in z direction)
              dt [0.05]                        = #(time step, \leqslant 0.05)
              kappa [3.0]                      = #(gradient multiplier)
              mobility [1.0]                   = #(mobility)
              m [2.0]                          = #(free energy prefactor)
              Pz [0.00]                        = #(pinning pressure)
              start_time [0]                   = #(time step to start the simulation)
              nsteps [10000]                   = #(totla number of simulation steps)
              output_interval [500]            = #(frequecy of images/vti output)
              data_interval [100]              = #(frequency of data output)
              engage_time [0]                  = #(start time for time dependent Pz)
              Pz_rate [0]                      = #(rate of change of Pz)
              l [0]                            = #(characteristic length)
              L [0]                            = #(limiting grain size with maximumum pinning)
              Pm [0]                           = #(pinning due to large precipitates)
              Pr [0]                           = #(pinning due to small precipitates)
              restart [0]                      = #(restart option)
              
There are some default values attached to these parameters. user can look at `./launcher` if they wih to learn more or make changes to it. This same option is used to make input script for both 2D and 3D simulations.
In case of real input file, the rest of the parameters are similar except $kappa, mobility$ and $m$. Following additional parameters are added :

              length_scale                    = #(convert mesh into physical length)
              time_scale                      = #(convert time step into physical time)
              GBmob0                          = #(mobility prefactor, m^4/(J*s))
              T                               = #(temperature, K)
              Q                               = #(activation energy, eV)
              GBenergy                        = #(grain boundary energy, J/m^2)
              wGB                             = #(phase field interfacial width, length scale)
              
More details on the calculation of the required grain growth parameters are explained in the Introduction section.

Note: The values inside [ ] are the default values.


Running Simulation

Once the input files and initial microstructures are ready in the root folder, we are all set to run the desired simulation. Select the choice between 5-8 to run the grain growth simulations.

The prompt will initiate the code compilation and finally start the simulation. In the root/ folder a results/ folder will be generated where the frames of each timestep (according to selected outut frequency in the input script). By default the simulation will also generate a data file containing time vs avg. grain size data in /results/grain_size.csv.


Examples

Grain Growth with Uniform Constant Friction Pressure

Grain growth results

2000 x 2000 with 6000 grains. mobility = 1, m = 2, kappa = 3m, dt = 0.05, dx = 1


Grain Growth with Non-Uniform Constant Friction Pressure

Grain growth results

2000 x 2000 with 6000 grains. mobility = 1, m = 2, kappa = 3m, dt = 0.05, dx = 1. The friction.txt was generated externally representing the non ubniform friction pressure.


Abnormal Grain Growth

Grain growth results

2000 x 2000 with 6000 grains. mobility = 1, m = 2, kappa = 3m, dt = 0.05, dx = 1, Pz = 0, Pm = 0.01, Pr = 0.03, l = 30, L = 30. The friction.txt was generated externally representing the non ubniform friction pressure.


3D Grain Growth


300 x 300 x 300 with 1000 grains. mobility = 1, m = 2, kappa = 3m, dt = 0.05, dx = dy = dz = 1.