Prismspf User Guide

User Manual: Pdf

Open the PDF directly: View PDF PDF.
Page Count: 47

PRISMS-PF!
An Open-Source Phase Field Modeling Framework!
PRISMS-PF User Guide (v2.0.2)
Stephen DeWitt (prismsphasefield.dev@umich.edu)
February 1, 2018
Contents
1 Overview 2
2 Downloading deal.II and PRISMS-PF 2
2.1 Installing deal.II for Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Installing deal.II for Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2.1 Traditional Installation (Recommended assuming no package is available) 3
2.2.2 Usingcandi................................... 4
2.3 DownloadingPRISMS-PF............................... 4
3 Running the Example Applications 5
3.1 TheExampleApplications............................... 5
3.2 Compiling the Core PRISMS-PF Library . . . . . . . . . . . . . . . . . . . . . . 6
3.3 Running the Allen-Cahn Example Application . . . . . . . . . . . . . . . . . . . 6
3.4 WhatCanGoWrong ................................. 9
3.5 Visualizing the Results of the Simulation . . . . . . . . . . . . . . . . . . . . . . . 12
3.6 Running the Other Example Applications . . . . . . . . . . . . . . . . . . . . . . 16
3.7 Running in Release Mode and with Multple Processors . . . . . . . . . . . . . . . 16
4 Structure of a PRISMS-PF Application 16
4.1 Files in the Application Directories . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5 The Input File: parameters.in 17
6 The Application Files: equations.h, ICs and BCs.h, postprocess.h, nucleation.h, cus-
tomPDE.h, and main.cc 26
6.1 equations.h ....................................... 26
6.1.1 loadVariableAttributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
6.1.2 residualRHS................................... 30
6.1.3 residualLHS................................... 32
6.2 ICandBCs.h...................................... 34
6.2.1 InitialCondition and InitialConditionVec . . . . . . . . . . . . . . . . . . . 34
6.2.2 NonUniformDirichletBC and NonUniformDirichletBCVec . . . . . . . . . 36
6.3 postprocess.h ...................................... 36
6.3.1 loadPostProcessorVariableAttributes . . . . . . . . . . . . . . . . . . . . . 37
6.3.2 postProcessedFields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
6.4 nucleation.h....................................... 38
6.5 customPDE.h...................................... 39
6.6 main.cc ......................................... 40
7 Tests 41
8 Creating Custom Applications 41
9 Appendix I: The userInputs Object 41
1
1 Overview
PRISMS-PF is an open-source finite element simulation framework with a focus on solving equa-
tions from phase field models. It is being developed as part of the PRISMS Center at the
University of Michigan. PRISMS-PF is built on top of the popular and powerful deal.II finite
element library. PRISMS-PF was developed to make high performance phase field simulation
capabilities available to the wider scientific community with an easy-to-use and easy-to-learn in-
terface. Benchmark tests show that even without its adaptive meshing capabilities PRISMS-PF
is competitive with specialized finite difference codes written in Fortran with MPI parallelization
in terms performance, and in some cases runs several times faster. PRISMS-PF can be used
to solve a wide variety of systems of coupled parabolic partial differential equations (e.g. the
diffusion equation) and elliptic partial differential equations (e.g. Poisson’s equation). With
PRISMS-PF, you have access to adaptive meshing and parallelization that has been demon-
strated on over a thousand processors. Moreover, the matrix-free framework from deal.II allows
much larger than typical finite element programs – PRISMS-PF has been used for calculations
with over one billion degrees of freedom.
This user guide starts with instructions for downloading PRISMS-PF and install the necessary
prerequisites. Next are instructions for running the built-in example applications and visualizing
the results. A detailed look at the input files follows, and the guide finishes with some instructions
on how to create your own PRISMS-PF applications.
If you run into any issues not covered by this guide, or have any questions, please send an email
to the PRISMS-PF email list: prisms-pf-users@googlegroups.com. If you’d like to contact the
PRISMS-PF developers directly, send an email to: prismsphaseField.dev@umich.edu.
PRISMS-PF was developed as part of the PRedictive Integrated Structural Materials Science
(PRISMS) Center at University of Michigan which is supported by the U.S. Department of
Energy (DOE), Office of Basic Energy Sciences, Division of Materials Sciences and Engineering
under Award #DE-SC0008637.
2 Downloading deal.II and PRISMS-PF
Before downloading PRISMS-PF itself, one should install CMake and deal.II. CMake can be
downloaded at: https://cmake.org/download, which also has installation instructions. Be sure
to add CMake to your path by entering:
$ $ PATH=”/path / t o /cmake / Con tents / bi n ” : ”$PATH”
filling in the path to the installation of CMake (for example, on Mac OS, the default installation
path is /Applications/CMake.app/Contents/bin). For convience, we recommend adding this line
to your bash profile. Your bash profile can be opened via the following terminal command
$ vi ˜ / . p r o f i l e
Deal.II can be downloaded at https://www.dealii.org/download.html, which also has instruc-
tions. The deal.II installation process depends on your operating system. PRISMS-PF has been
tested with Deal.II versions 8.3.0 through 8.5.0. We recommend using deal.II 8.4.2, if possible.
If you use deal.II 8.5.0, expect to recieve a number of warnings during compilation (discussed in
Sec. 3) about functions used in PRISMS-PF that are deprecated in deal.II 8.5.0.
2
2.1 Installing deal.II for Mac OS X
A binary package for version 8.4.2 (and other versions) is available at https://github.com/dealii/dealii/releases.
The binary package includes all the libraries that you need (excluding CMake). To install deal.II
open the .dmg file and drag “deal.II.app” into your Applications folder. Then, open “deal.II.app”,
which will open a Terminal window and set the necessary environment variables. You may need
to modify your security settings so that your operating system will let you open the application
(in System Preferences, select Security & Privacy, then under the general tab choose to allow
apps downloaded from anywhere; don’t click “Open deal.II.app anyway”, we have found that
doing so doesn’t actually launch deal.II.app).
In some cases, deal.II.app will not open, possibly freezing at the “Verifying...” stage. If this
happens, right click on it and select “Show Package Contents”. Then go to “/Contents/Re-
sources/bin/” and launch “dealii-terminal”. This should launch the Terminal window that sets
the environment variables.
We have found that for some older versions of Mac OS are incompatible with deal.II version
8.4.2 (due to the version of the Clang compiler that is installed by default). In those cases we
recommend downloading this version 8.3.0 package:
https://github.com/dealii/dealii/releases/download/v8.3.0/dealii-8.3.0.nocxx14.dmg.
2.2 Installing deal.II for Linux
Unfortunately, on a Linux machine you will likely have to compile and install deal.II from the
source. The source code for version 8.4.2 can be downloaded at https://github.com/dealii/dealii/releases.
Detailed installation directions can be found at https://www.dealii.org/8.5.0/readme.html. For
some versions of Linux, packages are available (Gentoo, Debian testing (stretch), and Ubuntu
16.10+). See https://www.dealii.org/download.html for details.
Below we list instructions for installing deal.II and its prerequisites both manually and using
candi, an automatic deal.II installation script. For now, we recomend the traditional route,
because we haven’t been able to get candi to consistently work. Recently, deal.II has been made
available on Linuxbrew. We have not tried this yet, but it may be a good option. Details can
be found at https://github.com/dealii/dealii/wiki/deal.II-on-Homebrew—Linuxbrew.
2.2.1 Traditional Installation (Recommended assuming no package is available)
Before building deal.II, you will need to install two libraries, MPI and p4est. Make sure you have
both libraries installed before installing deal.II, or else you will have to reinstall deal.II! Many
computing clusters already have these libraries installed. MPI libraries (such as MPICH2) are
often available through package managers (e.g. yum, apt, pkg add, port, brew), installing it using
your package manager of choice is likely the simplest option. If not, you can find binaries and the
source code at http://www.mpich.org/downloads/, as well as instructions for installation. The
p4est library may also be available through your package manager. If not, you can download the
latest release tarball at http://www.p4est.org/. To install, unzip the archive, move to the p4est
root directory and enter the following commands at the command line:
$ . / c o n f i g u r e enablempi ; make ; make i n s t a l l
3
Users have found that this approach works better than the setup script “p4est-setup.sh” that is
on the deal.ii website. More detailed installation instructions can be found in the “INSTALL”
and “README” files in the p4est root directory.
With MPI and p4est installed, you are ready to install deal.II. Open the archive you downloaded
from the deal.II website. From the root deal.II directory enter the following commands:
$ mkdir b u i l d
$ cd b u i l d
$ cmake DP4EST DIR=/path / to / i n s t a l l a t i o n / d ir DDEAL II WITH P4EST=ON
DDEAL II WITH MPI=ON DCMAKE INSTALL PREFIX=/path / to / i n s t a l l / d i r
$ make i n s t a l l
where “/path/to/install/dir” is the path to where you want to install deal.II. After installa-
tion is complete (which can take take up to an hour), open the file “summary.log”. The sec-
ond section of the log file lists the configured features. Ensure that DEAL II WITH MPI and
DEAL II WITH P4EST say either “set up with bundled packages” or “set up with external de-
pendences”. If either is listed as “OFF”, then deal.II was unable to find MPI or p4est. If this is
the case, double check that MPI and p4est were installed correctly.
2.2.2 Using candi
An alternative route is to use the following candi (compile and install) script to install deal.II
and its prerequisites:
https://github.com/koecher/candi
If it works, it should be much simpler than the traditional route described above. However in
limited attempts, we have not been able to successfully install deal.II with candi. After more
testing and/or consultation with the developer, we hope to make this a plausible option.
2.3 Downloading PRISMS-PF
PRISMS-PF is available for download at our GitHub site: https://github.com/prisms-center/phaseField.
The recommended method for downloading the PRISMS-PF source code is through git. Using
a Linux/Unix terminal, go to the directory where you want PRISMS-PF to be located. To clone
the repository, type:
$ g i t c l o n e h t tp s : / / g it hu b . com/ pr is ms c e n t e r / p h as e F ie l d . g i t
Git will then download the PRISMS-PF source code into a directory entitled “phaseField”. A
resource for learning to use Git can be found at:
https://git-scm.com/book.
If you prefer not to use Git, a zip file containing the PRISMS-PF source code can be downloaded
at:
https://github.com/prisms-center/phaseField/releases.
4
3 Running the Example Applications
3.1 The Example Applications
After deal.II and PRISMS-PF are downloaded, you can run the pre-built PRISMS-PF example
applications. At this time, the example applications include:
allenCahn: An implementation of the Allen-Cahn equation for two phases. (2D)
allenCahn pfield: Like allenCahn, but loads in initial conditions using PRISMS Integra-
tionTools. (2D)
cahnHilliard: An implementation of the Cahn-Hilliard equation for two phases. (2D)
cahnHilliardWithAdaptivity: Like cahnHilliard, but with adaptive meshing enabled. (2D)
coupledCahnHilliardAllenCahn: An implementation of the coupled Cahn-Hilliard/Allen-
Cahn set of equations. (2D)
CHAC anisotropy: Coupled Cahn-Hilliard/Allen-Cahn equations with weakly anisotropic
interfacial energy. (2D)
CHAC anisotropyRegularized: Like CHAC anisotropy, but with a regularization term to
permit strongly anisotropic interfacial energy. (2D)
anisotropyFacet: A different strong anisotropy formation than in CHAC anisotropyRegularized
that is easier to specify particular facets in the Wulff shape. (2D)
fickianDiffusion: An implementation of the diffusion equation with a time-dependent source
term. (2D)
mechanics: An implementation of linear elasticity for a material in uniaxial tension. (3D)
CHiMaD benchmark1a: An implementation of the CHiMaD spinodal decomposition bench-
mark problem. (2D)
CHiMaD benchmark2a: An implementation of the CHiMaD Ostwald ripening benchmark
problem. (2D)
CHiMaD benchmark6a: An implementation of the CHiMaD electrochemistry benchmark
problem. (2D)
CHiMaD benchmark6b: An implementation of the CHiMaD electrochemistry benchmark
problem with a curved domain. (2D)
dendriticSolidification: An implementation of a solidification model for a pure material
resulting in the growth of a dendrite. (2D)
eshelbyInclusion: An implementation of linear elasticity for a spherical inclusion. (3D)
grainGrowth: An implementation of ten coupled Allen-Cahn equations simulating grain
growth in two dimensions. (2D)
precipiateEvolution: An implementation of the coupled Cahn-Hilliard/Allen-Cahn/Linear
Elasticity equations often used in phase field simulation of precipitate evolution. (2D)
precipiateEvolution pfunction: Like precipitateEvolution, but loads inputs using PRISMS
IntegrationTools. (2D)
5
singlePrecipitateKKS: Similar to precipiateEvolution, but uses the KKS model rather than
the WBM model for the free energy functional. (3D)
nucleationModel: KKS precipitation model that makes use of the PRISMS-PF explicit
nucleation capabilities. (2D)
preferential nucleationModel: Like nucleationModel, but with a zone with an increased
nucleation rate to simulate a grain boundary. (2D)
A directory for each of these applications can be found in the applications directory (i.e. phase-
Field/applications). The applications contain a formulation file giving the governing equations.
In addition to the 21 applications listed above, some application names may be preceded by an
underscore. The underscore is used to denote applications that are still under active development.
3.2 Compiling the Core PRISMS-PF Library
After downloading PRISMS-PF, we recommend that you compile the core library (see note at
the end of this section). To do so, enter the root PRISMS-PF directory from the directory where
you downloaded it to, run CMake, and then compile the library:
$ cd phaseField
$ cmake .
$ make j 8
In the last command, the number following “-j” is the number of threads used during compilation.
The general rule of thumb is to pick a number 1.5×the number of processors available. This
process should take a minute or two and will compile both the “debug” and “release” versions
of the core PRISMS-PF library (see 3.7).
Note: This step can be skipped and the core library will be compiled the first time that you
compile one of the applications. However, the compilation will be on a single thread and thus
will take much longer than if you follow the instructions above and use multiple threads.
3.3 Running the Allen-Cahn Example Application
From the “phaseField” directory one can run the Allen-Cahn example application through to
following terminal commands:
$ cd a p p l i c a t i o n s / allenCahn /
$ cmake .
$ make debug
$ mpirun n 1 main
The first command moves from the “phaseField” directory to the directory of the Allen-Cahn
example. The second command checks that core PRISMS-PF library has been compiled, (re-
)compiles it if necessary, and creates a makefile using CMake. The third command compiles the
executable in “debug” mode, which enables a number of exception checks in the code and adds
debugging information that can be used by a debugger (e.g. gdb). The fourth command runs
the program using a single processor.
6
As the program runs, information from each time step outputs to the terminal window. After
the simulation is complete, a summary the time taken in a few major sections of the code and
the total wall time is printed to the terminal window.
Here is a screenshot of typical output from CMake as you create the makefile:
Don’t worry if the output isn’t exactly the same as what you see, the details of some of the mes-
sages depend on your operating system and which compilers you have installed. The important
part is that the bottom three messages are “Configuring done”, “Generating done”, and “Build
files have been written to: ...”. In the future, entering “$ cmake .” will result in a shorter set
of messages because CMake caches some variables from the last time it was run. As a result,
you can omit the CMake step for future simulations as long as the path name to your current
directory is unchanged and your installation of deal.II is unchanged.
Here is a screenshot of typical output from the compiler as you compile the executable:
7
Depending on your version of deal.II, different warnings may appear as you compile. Common
warnings include the use of functions that deal.II has marked as depricated (as in the screenshot
above) and unused type definitions. In this case, PRISMS-PF uses these functions for backward
compatability with deal.II version 8.4.x. We will switch to the updated functions in the near
future.
Once the simultation is complete, the terminal output at the end of the simulation should look
like:
8
3.4 What Can Go Wrong
If you were able to enter all of the commands in the previous section and get output similar
to the screenshots, congratulations! you just ran your first PRISMS-PF simulation. If not, you
may be experiencing one of the common issues listed below.
If CMake gives an error message like this:
9
Then you likely forgot the period at the end of the command “$ cmake .”.
If CMake gives an error message like this:
10
CMake cannot find your installation of deal.ii. This issue is probably caused by the lack of an
environment variable pointing to the directory containing your deal.II library. You can check
this with the following command:
$ echo $DEAL II DIR
The terminal should then output the path to the deal.II library. For example in Mac OS, the
deal.II directory may be “/Applications/deal.II.app/Resources”. If DEAL II DIR contains a
path, go there to see if deal.II is actually installed there. If DEAL II DIR is incorrect or empty,
you should set it to the directory of the correct path of your deal.II installation with the following
command:
$ e x port DEAL II DIR=/path / to / d e a l i i
Environment variables are erased when you close your shell. To have this path set every time you
open a shell (i.e. every time you open a new terminal window), you can add the command above
to your shell profile (e.g. .bashrc if you use a bash shell). If you are still having problems, there
may be an issue with your deal.II installation. Please consult the deal.II website for instructions.
If CMake cannot successfully detect a C++ compiler, it will generate an error message. The
most common cause for this is that the machine runs the Mac OS operating system with an
outdated version of the Clang compiler. Upgrading your OS to version 10.11 or newer, updating
Xcode, and (re)installing the Xcode command line tools may help. Alternatively, you can install
a certain version of the deal.II package that was developed to sidestep this issue:
https://github.com/dealii/dealii/releases/download/v8.3.0/dealii-8.3.0.nocxx14.dmg
Most of issues users have had are during the CMake step. If the fixes suggested above don’t
work for your or you have an issue not covered by this list, please contact the PRISMS-PF
users list: prisms-pf-users@googlegroups.com. If you are not already on the list, please submit
a join request through Google Groups or send an email with “SUBSCRIBE” in the subject line
11
to prismsphasefield.dev@umich.edu. As users come across new issues, we will add them (and
suggested fixes) to this section.
3.5 Visualizing the Results of the Simulation
Once you have successfully run a simulation, you will likely want to visualize the results.
PRISMS-PF output files are generated in the popular VTK format, as a series of *.vtu and
*.pvtu files. Two common open-soure, multi-platform visualization tools for these types of files
are VisIt and ParaView. Instructions for downloading this software can be found at their respec-
tive websites:
VisIt: https://wci.llnl.gov/simulation/computer-codes/visit/
ParaView: http://www.paraview.org/
To get you started, here is a brief tutorial on how to use VisIt to visualize your simulation results.
For more detailed instructions, please consult the VisIt manual:
https://wci.llnl.gov/simulation/computer-codes/visit/manuals
After launching the VisIt application, click “Open” and find the directory for the Allen Cahn
example:
and select “solution-*.pvtu:
12
Next, click “Add”, hover over “Pseudocolor”, and select “n”:
Next, click “Draw” to make a plot:
13
The VisIt window will now have a plot of the initial condition of the order parameter:
The result at other time steps can be visualized by dragging the time bar, or using the controls
directly below the time bar. Dragging the time bar to the end will display the final result of the
simulation:
14
VisIt has a wide variety of capabilities for visualizing 1D, 2D, and 3D data, including postpro-
cessing of output fields (e.g. to obtain derivatives of output fields or the result of mathematical
expressions involving one or more output field). VisIt also has a powerful Python interface to
provide scripting capabilities. More more instructions on how to use these, and other, features
of VisIt, please consult the VisIt manual.
15
3.6 Running the Other Example Applications
Running the other example applications is as simple as going to the directory for the application
of interest and repeating the steps in Section 3.3. For example, to run the Cahn-Hilliard example
application, when you are currently in the directory for the Allen-Cahn example application, you
would type the following commands:
$ cd . . / c a h n H i l l i a r d /
$ cmake .
$ make debug
$ mpirun n 1 main
3.7 Running in Release Mode and with Multple Processors
Once you are sure that your code works as expected, you can compile it in “Release Mode”,
which is approximately 10x faster than “Debug Mode”. However, no exceptions are checked in
Release Mode and therefore the code may compile and run even if it contains several errors.
Therefore, we strongly recommend that all new code is tested in Debug Mode before switching
to Release Mode. To compile in Release mode, replace “$ make debug” with “$ make release”.
One of the strengths of PRISMS-PF is that it can be run in parallel with almost no extra effort
from the user. To run a simulation in parallel, replace the “1” in the “mpirun” command with
the desired number of processor cores. The deal.II packages on their website already contain the
MPI library, so no extra software has to be downloaded to use multiple cores.
From the directory of an example application, a simulation can be run in Release Mode on 4
cores using the following commands:
$ cmake .
$ make r e l e a s e
$ mpirun n 4 main
4 Structure of a PRISMS-PF Application
4.1 Files in the Application Directories
Each of the example application directories should contain at least eight files:
parameters.in
equations.h
ICs and BCs.h
postprocess.h
customPDE.h
main.cc
formulation.pdf
16
CMakeLists.txt
It may contain two other files:
postprocess.h
nucleation.h
The following section (Sec. 5) will discuss the structure and options for the input file, param-
eters.h. Users who do not need to change the governing equations or make other fundamental
changes to the application will only need to modify this file.
Section 6 discusses the structure of the files that define an application: equations.h, ICs and BCs.h,
postprocess.h, nucleation.h, customPDE.h, and main.cc. Users who want to substantially modify
existing PRISMS-PF applications or create their own will find this section useful.
The final two files in each application directory are formulation.pdf and CMakeLists.txt. The file
formulation.pdf describes the mathematical formulation of the problem solved by the application.
Finally, the file CMakeLists.txt is used by CMake to generate the makefile. Most users will not
have any reason to change CMakeLists.txt.
5 The Input File: parameters.in
Most PRISMS-PF users will spend the majority of their time interacting with the input file,
parameters.h. This file allows users to specify the computational domain, the mesh, the time
step parameters, the boundary conditions, the output, and model constants (and more). This
file is read as a text file, so modifications to it do not require recompilation of the application.
Here is an example of an input file from the allenCahn application:
# Parameter l i s t f o r th e All enCahn example a p p l i c a t i o n
# R e f e r t o t h e PRISMSPF manual f o r u s e o f t h e s e p ar a me t er s i n t h e s o u r c e c od e .
# =================================================================================
# Se t t he number o f d im e n si o n s ( 2 or 3 f o r a 2D o r 3D c a l c u l a t i o n )
# =================================================================================
s e t Number o f d i m e n s i o n s = 2
# =================================================================================
# S e t t h e l e n g t h o f t h e doma in i n a l l t h r e e d i m e n s i o n s
# ( Domain s i z e Z i g n o r e d i n 2D)
# =================================================================================
# Each a x e s sp a n s from z e ro to t h e s p e c i f i e d l e ng t h
s e t Domain s i z e X = 100
s e t Domain s i z e Y = 100
s e t Domain s i z e Z = 100
# =================================================================================
# Se t t h e el e m ent p a r a m e t ers
# =================================================================================
# The number o f e l e m e n t s i n e a ch d i r e c t i o n i s 2 ˆ ( r e f i n e F a c t o r ) s u b d i v i s i o n s
# S u b d i v i s i o n s Z i gn o r e d i n 2D
# For o pt im a l pe rf or man ce , us e r e f i n e F a c t o r p r i m a r i l y t o d et er mi ne t he e le me nt s i z e
s e t S u b d i v i s i o n s X = 1
s e t S u b d i v i s i o n s Y = 1
s e t S u b d i v i s i o n s Z = 1
s e t R e f i n e f a c t o r = 8
# S et t he p o l yn o mi al d e gr e e o f t he e le me nt ( a l l ow e d v a l u e s : 1 , 2 , o r 3 )
s e t E lement d e g r e e = 1
# =================================================================================
17
# S et t he ti me s t e p p a ra m et e rs
# =================================================================================
# The s i z e o f t h e t im e s t e p
s e t Time s t e p = 1 . 0 e2
# The s i m u l a t i o n en ds when e i t h e r t he number o f t im e s t e p s i s r ea c he d o r th e
# s i m u l a t i o n ti me i s r e ac h ed .
s e t Number o f ti me s t e p s = 5000
# =================================================================================
# Se t t he boundary c o n d i t i o n s
# =================================================================================
# Se t t he bou ndary c o n d i t i o n f o r ea ch v a r i a b l e , w here ea ch v a r i a b l e i s g i ve n by
# i t s name , a s d e f i n e d i n e q u a t i o n s . h . The f o u r bounda ry c o n d i t i o n
# t y p e s a r e NATURAL, DIRICHLET , NON UNIFORM DIRICHLET and PERIODIC . I f a l l
# o f t h e b o u n d a r i e s h av e t he same b oundar y c o n d i t i o n , o n l y one bo un dary c o n d i t i o n
# t yp e n ee ds t o be g i v en . I f m u l t i p l e b oundary c o n d i t i o n t y p es a re needed , g i v e a
# commas e p a r a t e d l i s t o f t he t y p e s . The o r d e r i s t he miniumum o f x , maximum o f x ,
# minimum o f y , maximum o f y , minimum o f z , maximum o f z ( i . e l e f t , r i g h t , bottom ,
# t op i n 2D and l e f t , r i g h t , bottom , t op , f r o n t , b ac k i n 3D) . The v a l u e o f a
# D i r i c h l e t BC i s s p e c f i e d i n t he f o l l o w i n g way DIRCHILET : v a l where ’ v al i s
# th e d e s i r e d v a l ue . I f t he boundary c o n d i t i o n i s NON UNIFORM DIRICHLET, t he
# boundary c o n d i t i o n s ho ul d be s p e c i f i e d i n t he a p p r o p ri a t e f u n c t i o n i n I Cs an d BCs . h .
# Example 1 : A l l p e r i o d i c BCs f o r v a r i a b l e c
# s e t Boundary c o nd i t i o n f o r v a r i a b l e c = PERIODIC
# Example 2 : Zerod e r i v a t i v e BCs on th e l e f t and r i gh t , D i r i c h l e t BCs w it h v a l ue
# 1 . 5 on th e top and bottom f o r v a r i a b l e ’ n i n 2D
# s e t Boundary c o nd i t i o n f o r v a r i a b l e n = NATURAL, NATURAL, DIRICHLET : 1 . 5 , DIRICHLET : 1 . 5
s e t Boundary c o n d i t i o n f o r v a r i a b l e n = NATURAL
# =================================================================================
# S et t he model c o n s t a n t s
# =================================================================================
# Set the userd e f i n e d mode l c o n s t a n t s , w hi ch must have a c o un t er p a r t g i v e n i n
# customPDE . h . These a r e most o f t e n u se d i n t h e r e s i d u a l e q u a t i o n s i n e q u a t i o n s . h ,
# but may a l s o be us ed f o r i n i t i a l c o n d i t i o n s and n u c l e a t i o n c a l c u l a t i o n s . The t ype
# o p t io n s c u r r e n t l y a re DOUBLE, INT , BOOL, TENSOR, and [ symmetry ] ELASTIC CONSTANTS
# whe re [ symmetry ] i s ISOTROPIC , TRANSVERSE, ORTHOTROPIC, o r ANISOTROPIC .
# The m o b i l i t y , MnV i n e q u a t i o n s . h
s e t Model c o n s t a n t MnV = 1 . 0 , DOUBLE
# The g r a d ie n t ene r g y c o e f f i c i e n t , KnV i n e qu at i on s . h
s e t Model c o n s t a n t KnV = 2 . 0 , DOUBLE
# =================================================================================
# Se t t h e outp ut p a r a mete r s
# =================================================================================
# Type o f s p a c i n g b et wee n o ut p u ts ( ”EQUAL SPACING , ”LOG SPACING , ”N PER DECADE ,
# o r LIST ” )
s e t Output c o n d i t i o n = EQUAL SPACING
# Number o f t i m e s t he program o u t p u ts th e f i e l d s ( t o t a l number f o r ”EQUAL SPACING”
# and ”LOG SPACING ” , number p e r d ec ad e f o r ”N PER DECADE , i g n o r e d f o r LIST ” )
s e t Number o f ou tp uts = 5
# The number o f t ime s t e p s betw een up da te s b ei n g p r i n t e d t o th e s c r e e n
s e t Sk ip p r i n t s t e p s = 100 0
The syntax for setting each input parameter is:
s e t [ parameter name ] = [ parameter val ue ]
The pound symbol (#) is used for comments, and any text after it is ignored by the file parser.
The following table lists all of the input parameters, seperated into the same groupings in the
input file above:
18
Dimensionality
Name Options Required Default Description
Number of dimensions 2, 3 yes n/a The number of dimensions for the
simulation.
Compuational Domain
Name Options Required Default Description
Domain size X Any positive real
number
yes n/a The size of the domain in the x
direction.
Domain size Y Any positive real
number
yes n/a The size of the domain in the y
direction.
Domain size Z Any positive real
number
yes n/a The size of the domain in the z
direction.
Element Parameters
Name Options Required Default Description
Subdivisions X Any positive inte-
ger
no 1 The number of mesh subdivisions
in the x direction to control the el-
ement aspect ratio. The mesh size
is 2(RefineF actor)×Subdivisions
in each direction.
Subdivisions Y Any positive inte-
ger
no 1 The number of mesh subdivisions
in the y direction to control the el-
ement aspect ratio.The mesh size
is 2(RefineF actor)×Subdivisions
in each direction.
Subdivisions Z Any positive inte-
ger
no 1 The number of mesh subdivisions
in the z direction to control the el-
ement aspect ratio. The mesh size
is 2(RefineF actor)×Subdivisions
in each direction.
Refine factor Any non-negative
integer
yes n/a The number of initial refinements
of the mesh. The mesh size is
2(RefineF actor)×Subdivisions in
each direction. While in princi-
ple the mesh could be entirely con-
trolled by the number of subdivi-
sons, computational performance
is best when the majority of the
refinement is done via the Refine
factor.
Element degree 1, 2, 3 no 1 The polynomial order of the ele-
ments. The spatial order of accu-
racy is one plus the degree.
19
Mesh Adaptivity (Optional)
Name Options Required Default Description
Mesh adaptivity Boolean no false Controls whether mesh adaptivity
is enabled.
Max refinement level Any non-negative
integer
no -1 The maximum number of local re-
finements during adaptive mesh-
ing. This parameter does not need
to be specified if mesh adaptivity
is disabled, but the default value
will cause an error if mesh adap-
tivity is enabled.
Min refinement level Any non-negative
integer
no -1 The minimum number of local re-
finements during adaptive mesh-
ing. This parameter does not need
to be specified if mesh adaptivity
is disabled, but the default value
will cause an error if mesh adap-
tivity is enabled.
Refinement criteria
fields
Comma separated
list of variable
names
no 0 The indices of the variables that
will determine the mesh refine-
ment. The variable names are de-
termined by the names given in
equations.h.
Refinement window
max
Comma separated
list of real numbers
no The mesh refines where the spec-
ified variables are between an up-
per and lower bound. This speci-
fies the upper bound.
Refinement window
min
Comma separated
list of real numbers
no The mesh refines where the spec-
ified variables are between an up-
per and lower bound. This speci-
fies the lower bound.
Steps between remesh-
ing operations
Positive integer no 1 The number of time steps between
mesh refinement operations.
Time Stepping
Name Options Required Default Description
Time step Any positive real
number
yes n/a The time step size for the simula-
tion.
Number of time steps Any non-negative
integer
no -1 The number of time steps until the
simulation stops. Either this or
the simulation end time must be
specified. If both are specified, the
simulation will end when the first
condition is reached.
Simulation end time Any non-negative
real number
no -0.1 The simulated time when until the
simulation stops. Either this or
the number of time steps must be
specified. If both are specified, the
simulation will end when the first
condition is reached.
20
Elliptic Solver Parameters (Optional)
Name Options Required Default Description
Linear solver SolverCG no SolverCG Currently the only option is the
deal.II conjugate gradient solver.
Use absolute conver-
gence tolerance
Boolean no false Sets whether to use an absolute
tolerance for the linear solver (ver-
sus a relative tolerance).
Solver tolerance value Any positive real
number
no 1e-3 The tolerance for the linear solver.
If an absolute tolerance is used,
the iterative solver stops when the
L2 norm of the residual drops be-
low the tolerance. If a relative tol-
erance is used, the iterative solver
stops when the L2 norm of the
residual has dropped by a factor
equal to the tolerance.
Maximum allowed
solver iterations
Any positive inte-
ger
no 10000 The maximum number of itera-
tions for the linear solver, if this
number of iterations is reached,
the solver stops regardless of the
tolerance value.
21
Output (Optional)
Name Options Required Default Description
Output condition EQUAL SPACING,
LOG SPACING,
N PER DECADE,
LIST
no EQUAL
SPACING
This sets the spacing between
the times the simulation out-
puts the model variables.
EQUAL SPACING spaces them
equally, LOG SPACING spaces
them 10n/(outputs) log(timesteps),
N PER DECADE allows the
user to set how many times the
simulation outputs per power of
ten iterations, and LIST outputs
at a user-given list of time step
numbers.
Number of outputs Any non-negative
integer
no 10 The number of inputs if
the output condition is
EQUAL SPACING. The number
of outputs if the output condition
is N PER DECADE. Ignored for
the other output conditions.
List of time steps to
output
Comma-separated
list of non-negative
integers
no 0 The list of time steps to output,
used for the LIST output condi-
tion and ignored for the others.
Output file name
(base)
String no solution The name for the output file, be-
fore the time step and processor
info are added.
Output file type vtu, vtk no vtu The output file type (currently
limited to either vtu or vtk).
Output separate files
per process
Boolean no false Whether to output separate vtu
files for each process in a paral-
lel calculation (automatically set
to true for vtk files). Separate files
may decrease the time spent out-
putting results but may increase
file tranfer times, as well as clut-
tering directories.
Skip print steps Any positive inte-
ger
no 1 The number of time steps between
updates to the terminal window (1
is every time step).
22
Checkpoints (Optional)
Name Options Required Default Description
Load from a check-
point
Boolean no false Whether to start the simulation
from the checkpoint of another
simulation. See Note 2 be-
low for the details of the check-
point/restart system.
Checkpoint condition EQUAL SPACING,
LOG SPACING,
N PER DECADE,
LIST
no EQUAL
SPACING
This sets the spacing between
the times the simulation out-
puts the model variables.
EQUAL SPACING spaces them
equally, LOG SPACING spaces
them 10n/(outputs) log(timesteps),
N PER DECADE allows the
user to set how many times the
simulation outputs per power of
ten iterations, and LIST outputs
at a user-given list of time step
numbers.
Number of checkpoints Any non-negative
integer
no 1 The number of inputs if
the output condition is
EQUAL SPACING. The number
of outputs if the output condition
is N PER DECADE. Ignored for
the other output conditions.
List of time steps to
save checkpoints
Comma-separated
list of non-negative
integers
no 0 The list of time steps to create
checkpoints, used for the LIST
output condition and ignored for
the others.
Boundary Conditions
Name Options Required Default Description
Boundary condition
for variable [variable
name]
NATURAL,
DIRICHLET,
NON UNIFORM
DIRICHLET,
PERIODIC
yes n/a Sets the boundary condition for
each scalar variable, using the
variable name from equations.h.
One line is required for each scalar
variable. See Note 1 below for de-
tails.
Boundary condition
for variable [variable
name], component
[direction]
NATURAL,
DIRICHLET,
NON UNIFORM
DIRICHLET,
PERIODIC
yes n/a Sets the boundary condition for
each vector variable, using the
variable name from equations.h.
One line is required for each vec-
tor variable. See Note 1 below for
details.
23
Loading Initial Conditions from File (Optional)
Name Options Required Default Description
Load initial conditions Comma-separated
list of booleans
no false One true/false flag for each vari-
able for whether the initial condi-
tion should be loaded from a vtk
file. Currently, only scalar fields
can be read in. See Note 3 below
for details.
Load parallel file Comma-separated
list of booleans
no false One true/false flag for each vari-
able for whether each processor
should read the initial conditions
from a seperate file. See Note 3
below for details.
File names Comma-separated
list of strings
no The name of the vtk file to be read
for each variable, ignored for vari-
ables where the initial conditions
isn’t read in from a file. Often, all
of the variables will read from the
same vtk file. See Note 3 below
for details.
Variable names in the
files
Comma-separated
list of strings
no What each variable is named in
the file being loaded. See Note 3
below for details.
Shared Nucleation Parameters (Optional)
Name Options Required Default Description
Time steps between
nucleation attempts
Any positive inte-
ger
no 100 The number of time steps between
nucleation attempts. This param-
eter is shared among all nucleating
variables. See Note 4 below for de-
tails.
Minimum allowed dis-
tance between nuclei
Any non-negative
real number
no 2×the
largest
nucleus
semiaxis
The minimum allowed distance
between nuclei centers during a
single nucleation attempt. This
parameter is shared among all nu-
cleating variables. See Note 4 be-
low for details.
Order parameter cut-
off value
Any non-negative
real number
no 0.01 The minimum allowed value of
the sum of all nucleating vari-
able fields where nucleation is al-
lowed to occur. Implemented to
prevent nucleation inside exist-
ing particles. This parameter is
shared among all nucleating vari-
ables. See Note 4 below for de-
tails.
Any positive inte-
ger
no 100 The number of time steps between
nucleation attempts. This param-
eter is shared among all nucleating
variables. See Note 4 below for de-
tails.
24
Nucleation Parameters for Each Nucleating Variable (Optional)
Name Options Required Default Description
Nucleus semiaxes (x, y
,z)
Three positive real
numbers
no The semiaxes of the ellipsoidal nu-
clei to be seeded. See Note 4 below
for details.
Nucleus rotation in de-
grees (x, y, z)
Three real numbers no The rotation of the nuclei placed
with the explicit nucleation algo-
rithm. The rotations are given
with respect to the normal di-
rection using intrinsic Tait-Bryan
angles. Positive rotations corre-
spond to a counter-clockwise rota-
tion when looking along the posi-
tive axis of interest. All three an-
gles must be specified regardless of
problem dimension.
Freeze zone semiaxes
(x, y ,z)
Three positive real
numbers
no The semiaxes for the ellipsoidal re-
gion where the nucleus is frozen
after seeding. See Note 4 below
for details.
Freeze time following
nucleation
Any non-negative
real number
no 0 The amount of time the nucleus is
frozen after seeding. See Note 4
below for details.
Nucleation-free border
thickness
Any non-negative
real number
no 0 The size of the buffer region where
nucleation is not allowed unless
the boundary conditions are peri-
odic. See Note 4 below for details.
Model constants (Optional)
Name Options Required Default Description
Model constant [con-
stant name]
value followed by a
comma then a type
no Sets the value of a constant
defined for that particular appli-
cation. The allowed types are
DOUBLE, INT, BOOL, TEN-
SOR, and [symmetry] ELASTIC
CONSTANTS where [symme-
try] is ISOTROPIC, TRANS-
VERSE, ORTHOTROPIC, or
ANISOTROPIC. See Note 5
below for details.
Note 1 (Boundary Conditions):
The boundary condition must be set for each variable, where each variable is given by its name,
as defined in equations.h. The four boundary condition types are NATURAL, DIRICHLET,
NON UNIFORM DIRICHLET and PERIODIC. If all of the boundaries have the same boundary
condition, only one boundary condition type needs to be given. If multiple boundary condition
types are needed, give a comma-separated list of the types. The order is the miniumum of x,
maximum of x, minimum of y, maximum of y, minimum of z, maximum of z (i.e left, right,
bottom, top in 2D and left, right, bottom, top, front, back in 3D). The value of a Dirichlet
BC is specfied in the following way – DIRCHILET: val – where ’val’ is the desired value. If
the boundary condition is NON UNIFORM DIRICHLET, the boundary condition should be
specified in the appropriate function in ’ICs and BCs.h’. For vector variables, one boundary
condition should be specified for each component.
25
Example 1: All periodic BCs for variable ’c’
s e t Boundary c o nd it i on f o r v a r i a b l e c = PERIODIC
Example 2: Zero-derivative BCs on the left and right, Dirichlet BCs with value 1.5 on the top
and bottom for variable ’n’ in 2D
s e t Boundary c o nd it i on f o r v a r i a b l e n = NATURAL, NATURAL, DIRICHLET : 1 . 5 ,
DIRICHLET : 1 . 5
Example 3: All periodic BCs for the y component of the vector variable ’u’
s e t Boundary c o nd it i on f o r v a r i a b l e u , component y = PERIODIC
Note 2 (Checkpoint/Restart):
The checkpoint/restart simulation allows one to continue from a previous simulation by loading
the mesh and variable values from that previous simulation. One use of this system is to continue
a simulation that stopped part of the way through, due to a hardware failure, running out of
the allotted time on a cluster, etc. A second use is to use one simulation as the initial condition
for another. Note that the simulated time carries over from the checkpoint. Thus if one ran a
simulation to completion but wanted to see further evolution, one could load from the checkpoint
created at the end of that simulation, but the desired number of time steps or simulation end
time would have to be increased. Currently, the checkpoint system always read from files named
“restart.mesh”, “restart.mesh.info”, and “restart.time.info”. When a checkpoint is created, the
previous checkpoint files have “.old” appended to their file names. To load from these older
checkpoint files, the newer ones should be deleted (or moved) and the “.old” should be deleted
from the names of the older files. An example of using the checkpoint/restart system can be
seen in the ‘dendriticSolidification’ application.
Note 3 (Loading Initial Conditions from File):
Currently, initial conditions can only be read from vtk files (not vtu files). Some variables can
have initial conditions read from file and others can be specified in ICs and BCs.h in the same
application. For each variable, the user must set whether the file(s) to be read are in serial
format, where all processors read from the same file, or parallel format, where all processors
read from different files. If parallel format is selected, the desired domain decomposition must
between the files and the simulation to be run. For non-adaptive meshes this will be true if the
same number of cores is the same between the simulation that generated the vtk files and the
simulation reading the vtk files. For adaptive meshes, obtaining the same domain decomposition
may be difficult and merging parallel vtk files into a single file is likely the best approach. This
process is planned to be cleaner in future versions of PRISMS-PF. An example of loading inital
conditions from file can be seen in the ‘allenCahn pfield’ application.
Note 4 (Nucleation):
PRISMS-PF includes the capability for explicitly placing nuclei over the course of a simulation
using an approach similar to the one described in the following publication:
Jokisaari, Permann, and Thornton, A nucleation algorithm for the coupled conserved-nonconserved
phase field model, Computational Materials Science, 112, (2016).
A nucleus of an non-conserved order parameter is placed within the computational domain deter-
mined by a probability given by the ‘getNucleationProbability’ function in the ‘nucleation.h’ file.
The variables that are allowed to nucleate are specified in the ‘loadVariableAttributes’ function
in the ‘equations.h’ file, as are the variable values needed to calculate the nucleation probability.
The determination of when and where a nucleus should be seeded is determined in the core
26
PRISMS-PF library, but the actual placement of the nucleus by modifying one of the model
fields is expected to be performed in the ‘residualRHS’ function in the ‘equations.h’ file. The
placement of the nucleus is aided by the ‘weightedDistanceFromNucleusCenter’ function in the
core library. The mobility for the nucleated field should be set to zero in the region surrounding
the nucleus (the “freeze zone”) for a specified amount of time (the “freeze time”). Examples
of nucleating particles can be found in the nucleationModel and preferential nucleationModel
applications.
Currently, the nucleation parameters are the only place where the ‘subsection’ command is
used in ‘parameters.in’. This command is used to set nucleation parameters seperately for each
nucleating variable. Each subsection is opened by “subsection Nucleation parameters:” followed
by the variable name as set in ‘equations.h’. The end of each subsection block is concluded with
the ‘end’ command. For example, if there are two nucleating order parameters n1 and n2, the
nucleation parameters section could look as follows:
# =================================================================================
# Se t t he n u c l e a t i o n p ar am et er s
# =================================================================================
s e t Time s t e p s bet ween n u c l e a t i o n a tt emp ts = 30
s e t Minimum a ll o we d d i s t a n c e bet ween n u c l e i = 5 0 . 0
s e t O rd er p a ra m et e r c u t o f f v a l u e = 0 . 0 1
s u b s e c t i o n N uc l e at i o n pa ra m et er s : n1
s e t N uc l eus s e m i a x e s ( x , y , z ) = 1 0 , 5 , 5
s e t N uc le us r o t a t i o n i n d e g r e e s ( x , y , z ) = 0 , 0 , 6 0
s e t F r e e z e z o ne s e m i a x e s ( x , y , z ) = 1 5 , 7 . 5 , 7 . 5
s e t F ree z e ti me f o l l o w i n g n u c l e a t i o n = 20
s e t Nucleat io nf r e e b or der t h i c k n e s s = 15
end
s u b s e c t i o n N uc l e at i o n pa ra m et er s : n2
s e t N uc l eus s e m i a x e s ( x , y , z ) = 2 0 , 1 0 , 10
s e t N uc le us r o t a t i o n i n d e g r e e s ( x , y , z ) = 0 , 0 , 0
s e t F r e e z e z o ne s e m i a x e s ( x , y , z ) = 3 0 , 1 5 , 15
s e t F ree z e ti me f o l l o w i n g n u c l e a t i o n = 40
s e t Nucleat io nf r e e b or der t h i c k n e s s = 30
end
The first three lines set the shared nucleation parameters. Next comes the subsection block for
the variable n1 and the subsection block for the variable n2.
Note 5 (Model constants):
Each application specifies its own set of model constants. These are most often used in the
residual equations in the ‘equations.h’ file, although they may also be used to specify initial
conditions, non-uniform Dirichlet boundary conditions, nucleation probabilties, etc. Currently,
five types of model constants are accepted: DOUBLE, INT, BOOL, TENSOR, and ELASTIC
CONSTANTS. The use of these different types is as follows:
DOUBLE: For individual real numbers
INT: For individual integers
BOOL: For individual booleans (true/false)
TENSOR: For either rank 1 tensors (i.e. vectors) or rank 2 tensors (i.e. matrices) with a
size of the number of dimensions. These are assumed to be real numbers. Each row should
be given by a comma-separated list in parentheses. For example, a 3D vector would be
given as “(2.5, 1.2, 0.1)” and a 2D matrix would be given as: “((4.1, 2.0),(1.6, 5.2))”.
[symmetry] ELASTIC CONSTANTS: For sets of elastic constants, given as a vector. The
symmetry options are ISOTROPIC, TRANSVERSE, ORTHOTROPIC, or ANISOTROPIC.
27
The number of entries for the different symmetries are given below. PRISMS-PF converts
these sets of elastic constants into a stiffness matrix.
The number and order of the entries for the elastic constants are (where Cij are entries in the
stiffness matrix):
ISOTROPIC (2D/3D): 2 constants (Young’s Modulus, Poisson’s Ratio)
TRANSVERSE (3D): 5 constants (C11, C33, C44, C12, C13)
ORTHOTROPIC (3D): 9 constants (C11, C22, C33, C44, C55, C66, C12, C13, C23)
ANISOTROPIC (2D/3D): 21 constants (C11, C22, C33, C44, C55, C66, C12, C13, C14, C15,
C16, C23, C24, C25, C26, C34, C35, C36, C45, C46, C56)
Each model constant in ‘parameters.in’ must have a counterpart in the appropriate section of
the ‘customPDE.h’ file.
6 The Application Files: equations.h, ICs and BCs.h, postprocess.h,
nucleation.h, customPDE.h, and main.cc
This section details the files that define each application. The norm is that substantial mod-
ifications to these files consistute a new application (in contrast to simply making changes to
‘parameters.in’. Modifying these files may require some knowledge of C++.
A very brief description of the purpose of each of these files is below, an in-depth discussion can
be found in the following subsections:
equations.h: Specifies the attributes of the model variables and the model’s residual equa-
tions
ICs and BCs.h: Specifies the initial conditions for each variable (unless the initial condition
is read from file) and non-uniform Dirichlet boundary conditions, if applicable.
postprocess.h: Specifies variable other than the primary model variables to output, as well
as the expressions to derive these variables.
nucleation.h: Contains the function that determines the probability density of nucleation.
customPDE.h: Contains the prototypes of the functions for the application, also contains
declarations of the model constants given in ‘parameters.h’.
main.cc: Main C++ function that controls the flow of the simulation. Identical for all the
example applications and it is unlikely that users will need to modify it.
In all of these files, the user can access user inputs from parameters.in via the “userInputs”
object (e.g. the domain size, the time step size). See Appendix I for a table of variable names
inside “userInputs”.
6.1 equations.h
The file “equations.h” contains a list of the variables in the model equations and their attributes
as well as the residuals for the model equations. The file contains three functions: loadVari-
28
ableAttributes,residualRHS, and residualLHS.
To modify the functions in this file, one needs to be familar with the weak form of the governing
equations (hereafter referred to as the residual equations). In PRISMS-PF, the residual equations
are expressed in two terms. The first is the part of the integrand that is multiplied by the test
function. The second is the part of the integrand that multipled by the gradient of the test
function. For the coupled Cahn-Hilliard/Allen-Cahn system, the residual equations are
Z
wηn+1 dV =Z
w
ηntMη((fn
β,c fn
α,c)Hn
)
| {z }
rη
+w·(tMηκ)ηn
| {z }
rηx
dV (1)
and
Z
wcn+1 dV =Z
w cn
|{z}
rc
(2)
+w(tMc) [ (fn
α,cc(1 Hn+1) + fn
β,ccHn+1)c+ ((fn
β,c fn
α,c)Hn+1
η)]
| {z }
rcx
dV
(3)
for the Allen-Cahn and Cahn-Hilliard equation, respectively. Each of the residual terms is
marked with an underbrace. The terms multiplied by the test function are referred to as the
value residual terms and the terms multiplied by the gradient of the test function are referred to
as the gradient residual terms.
6.1.1 loadVariableAttributes
Here is the loadVariableAttributes function for the coupled Allen-Cahn/Cahn-Hilliard example
application:
// =================================================================================
// S et th e a t t r i b u t e s o f t h e p ri ma ry f i e l d v a r i a b l e s
// =================================================================================
v oi d v a r i a b l e A t t r i b u t e L o a d e r : : l o a d V a r i a b l e A t t r i b u t e s ( ) {
// Variable 0
s e t v a r i a b l e n a m e ( 0 , c ) ;
s e t v a r i a b l e t y p e ( 0 ,SCALAR ) ;
s e t v a r i a b l e e q u a t i o n t y p e (0 ,PARABOLIC) ;
s e t n e e d v a l u e ( 0 , tr ue ) ;
set n e e d g r a d i e n t (0 , tr u e ) ;
s e t n e e d h e s s i a n ( 0 , f a l s e ) ;
s e t n e e d v a l u e r e s i d u a l t e r m ( 0 , t r ue ) ;
s e t n e e d g r a d i e n t r e s i d u a l t e r m ( 0 , t ru e ) ;
// Variable 1
s e t v a r i a b l e n a m e ( 1 , ’ n ) ;
s e t v a r i a b l e t y p e ( 1 ,SCALAR ) ;
s e t v a r i a b l e e q u a t i o n t y p e (1 ,PARABOLIC) ;
s e t n e e d v a l u e ( 1 , tr ue ) ;
s e t n e e d g r a d i e n t (1 , t r ue ) ;
s e t n e e d h e s s i a n ( 1 , f a l s e ) ;
s e t n e e d v a l u e r e s i d u a l t e r m ( 1 , t r ue ) ;
s e t n e e d g r a d i e n t r e s i d u a l t e r m ( 1 , t ru e ) ;
}
29
This function specifies the model variables and their attributes. In this case, the two model
variables are the concentration, “c”, and the order parameter, “n”. Here, “c” is listed as the
zeroth variable and “n” is listed as the first. For each variable, a series of attributes are set using
a series of C++ function calls. The following table lists the functions and a description of the
attributes they set:
30
Function Options Required Default Description
set variable name String no var Sets the name of the variable.
This name is used in ‘parame-
ters.in’ as well as during output.
set variable type SCALAR,
VECTOR
no SCALAR Sets whether the variable is a
scalar or a vector.
set variable equation type PARABOLIC,
ELLIPTIC
no PARABOLIC Sets whether the govenring equa-
tion for the variable is a parabolic
or ellpitic PDE.
set need value Boolean no true Sets whether the value of the
variable is needed in the function
residualRHS below.
set need gradient Boolean no true Sets whether the gradient of the
variable is needed in the function
residualRHS below.
set need hessian Boolean no false Sets whether the hessian of the
variable is needed in the function
residualRHS below.
set need need value
residual term
Boolean no false Sets whether the residual equa-
tion has a value residual term.
set need need gradient
residual term
Boolean no false Sets whether the residual equa-
tion has a gradient residual term.
set need value LHS Boolean no false Sets whether the value of the
variable is needed in the func-
tion residualLHS below. (Only
needed for elliptic PDEs).
set need gradient LHS Boolean no false Sets whether the gradient of the
variable is needed in the func-
tion residualLHS below. (Only
needed for elliptic PDEs).
set need hessian LHS Boolean no false Sets whether the hessian of the
variable is needed in the func-
tion residualLHS below. (Only
needed for elliptic PDEs).
set need need value
residual term LHS
Boolean no false Sets whether the LHS residual
equation has a value residual
term. (Only needed for elliptic
PDEs).
set need need gradient
residual term LHS
Boolean no false Sets whether the LHS residual
equation has a gradient residual
term. (Only needed for elliptic
PDEs).
set allowed to nucleate Boolean no false Sets whether the nucleation al-
gorithms should be activated for
this variable. (Only needed when
nucleation is desired).
set need value nucleation Boolean no false Sets whether the value of the
variable is needed to calculate
the nucleation probability in the
‘nucleation.h’ file. (Only needed
when nucleation is desired).
31
Function Options Required Default Description
set need value pp Boolean no true Sets whether the value of the
variable is needed in the function
postProcessedFields in ‘postpro-
cess.h’.
set need gradient pp Boolean no true Sets whether the gradient of the
variable is needed in the function
postProcessedFields in ‘postpro-
cess.h’.
set need hessian pp Boolean no true Sets whether the hessian of the
variable is needed in the function
postProcessedFields in ‘postpro-
cess.h’.
Some of these function calls are not present in the ‘equations.h’ file for the coupledCahn-
HilliardAllenCahn application. Use of the LHS function calls can be found in the preciptia-
teEvolution application (among others) and use the nucleation function calls can be found the
nucleationModel and preferential nucleationModel applications.
6.1.2 residualRHS
Here is the residualRHS function for the coupled Allen-Cahn/Cahn-Hilliard example application:
// =================================================================================
// r e si d ual RHS
// =================================================================================
// T hi s f u n c t i o n c a l c u l a t e s t h e r e s i d u a l e q u a t i o n s f o r e ac h v a r i a b l e . I t t a k e s
// v a r i a b l e l i s t a s an i npu t , which i s a l i s t o f t h e v a lu e and d e r i v a t i v e s o f
// each o f the v a r i a b l e s at a s p e c i f i c q u a d r a t u r e p o i nt . The ( x , y , z ) l o c a t i o n o f
// th a t q u a d r a t u r e p oi n t i s gi ve n by q p o i n t l o c ” . The f u n c t i o n o ut p u t s r e s i d u a l s
// t o v a r i a b l e l i s t . The i n d e x f o r ea ch v a r i a b l e i n t h i s l i s t c o r r e s p o n d s to
// t h e i n d ex g i v e n a t t h e t op o f t h i s f i l e .
template <i n t dim , i n t d eg ree >
void customPDE<dim , de g r e e >: : r e si d ua l RH S (
variableContainer<dim , d egr e e , d e a l i i : : Ve c t o r i z e d A r r a y <double> > & variable list ,
d e a l i i : : P oin t<dim , d e a l i i : : Ve c t o r i z e d A r r a y <double> > q p o i n t l o c ) c o n s t {
// c
s c a l a r v a l u e T y p e c = v a r i a b l e l i s t . g e t s c a l a r v a l u e ( 0 ) ;
s c a l a rg r ad T yp e cx = v a r i a b l e l i s t . g e t s c a l a r g r a d i e n t ( 0 ) ;
// n
s c a l a r v a l u e T y p e n = v a r i a b l e l i s t . g e t s c a l a r v a l u e ( 1 ) ;
s c a l a rg r ad T yp e nx = v a r i a b l e l i s t . g e t s c a l a r g r a d i e n t ( 1 ) ;
// F re e ene rg y f o r eac h p ha se and t h e i r f i r s t and se co nd d e r i v a t i v e s
scalarvalueType faV = (1.67044.776c +5.1622cc2.7375ccc +1.3687cccc ) ;
scalarvalueType facV = (4. 77 6 + 1 0 . 3 2 4 4 c8 . 2 1 2 5 cc + 5 . 4 7 4 8 ccc ) ;
s c a l a r v a l u e T y p e f ac c V = (1 0 .3 2 44 1 6 . 4 25c+16.4244cc ) ;
scalarvalueType fbV = (5.0cc5.9746c1 . 5 9 2 4 ) ;
s c a l a r v a l u e T y p e f bcV = ( 1 0 . 0 c5.9746);
s c a l a r v a l u e T y p e fb cc V = c on st V ( 1 0 . 0 ) ;
// I n t e r p o l a t i o n f u n c t i o n and i t s d e r i v a t i v e
scalarvalueType hV = (10.0nnn15.0nnnn+6.0nnnnn ) ;
s c a l a r v a l u e T y p e hnV = ( 3 0 . 0 nn60.0nnn +30.0nnnn ) ;
// R e s id u a l e q u a t i o n s
s c a l a r g r a d T y p e muxV = ( cx (( 1.0 hV)fa cc V+hVfbc cV ) + nx ( ( fbcVfacV )hnV) ) ;
scalarvalueType rcV = c ;
s c a l a r g r a d T y p e rc xV = ( c on st V (McVu s e r I n p u t s . d tV al ue ) muxV ) ;
scalarvalueType rnV = (nc ons tV ( u s e r I n p u t s . d tV alu e MnV) ( fbVfaV ) hnV ) ;
s c a l a r g r a d T y p e rnxV = ( c on st V (u s e r I n p u t s . d tVa lu e KnVMnV)nx ) ;
// R e s i d u al s f o r t h e e q u at i on to e v o l ve t he c o n c e n t r a t i o n
32
v a r i a b l e l i s t . s e t s c a l a r v a l u e r e s i d u a l t e r m ( 0 , rcV ) ;
v a r i a b l e l i s t . s e t s c a l a r g r a d i e n t r e s i d u a l t e r m ( 0 , rcxV ) ;
// R e s i d u a l s f o r t h e e q u a t i o n t o e v o l v e t h e o r d e r p a ra m et e r
v a r i a b l e l i s t . s e t s c a l a r v a l u e r e s i d u a l t e r m ( 1 , rnV ) ;
v a r i a b l e l i s t . s e t s c a l a r g r a d i e n t r e s i d u a l t e r m ( 1 , rnxV ) ;
}
In this function the residuals at a particular quadrature point are calculated. The inputs to
this function are a list of the model variable values and derivatives, variable list and a point
giving access to (x,y,z) coordinates, q point loc. The residual terms are added to variable list
as the output. The first few lines of the function set more convienent names for the variables
and their derivatives. By convention, the value of the variable is denoted by the variable name
(cfor the concentration and nfor the structural order parameter in this case), the list of first
derivatives is denoted by the variable name followed by an “x”, and second derivatives are
denoted by the variable name followed by “xx”. Each variable in variable can be accessed by
the index it was given in loadVariableAttributes. The variable value and the derivatives can be
accessed through the get scalar value,get scalar gradient, and get scalar hessian object members
for scalar variables and the get vector value,get vector gradient, and get vector hessian functions.
The data type for the value of a scalar variable is scalarvalueType (a scalar), the data type for the
first derivatives of a scalar variable is scalargradType (a vector with a length equal to the number
of dimensions), and the data type for the second derivatives of a scalar variable is scalarhessType
(a matrix with a size equal to the number of dimensions by the number of dimensions). For
vector variables, the data types are vectorvalueType (a vector with length equal to the number
of dimensions), vectorgradType (a matrix with a size equal to the number of dimensions by the
number of dimensions), and vectorgradType (a rank-three tensor with a size in each direction
equal to the number of dimensions).
After the nicknames for the field variables are set, the residual terms are calculated (including
some intermediate variables, such as the free energies and the interpolation functions in the
example above). These use the same six data types discussed in the preceding paragraph. The
model variables given in ‘parameters.h’ can be used to define the residual terms.
Finally, the residuals for the governing equations are submitted to variable list, using the func-
tions set scalar value residual term,set scalar gradient residual term,set vector value residual term,
and set vector gradient residual term, once again referring the variables by their index.
The nickname step can be skipped, if desired, although the code is generally more readable
with nicknames (and the performance overhead is minimal). An example without nicknames for
the fields can be found in the grainGrowth application, where loops over the ten variables are
easier to construct when not declaring all of the variables at once. One word of caution, though:
calling set scalar value residual term and set scalar gradient residual term overwrites the value
and gradient of the variable, respectively (and same for the variants for vectors). Thus, either the
residuals need to be cached and then set after all the residuals have been calculated (as is done
in the grainGrowth application) or the values and gradients need to be cached before setting the
residuals (as is done with the standard nicknaming approach).
33
A Note on Types: The deal.II library uses a data structure called a VectorizedArray to
store the variable values and their derivatives. This data structured in optimized for modern
vectorized processors, giving a substantial speedup in some cases. However, this data structure
can complicate things slightly. One complicating factor is that VectorizedArrays can’t always
be added, subtracted, multiplied, or divided with more standard data types like doubles. For
this reason, you will see the “constV(arguement)” function scattered throughout the code. This
function turns a non-VectorizedArray into a VectorizedArray. To be safe, you can always encase
non-VectorizedArrays with “constV()” when they share an operation with a VectorizedArray.
A second complication is that not all of the standard mathematical operations are available
for VectorizedArrays. The basic trigonometric functions are available, as are exponentials and
square roots. However, hyperbolic tangents are not. If needed, they must be constructed from
exponents. A third complication is that conditional statements involving VectorizedArrays are
not allowed. VectorizedArrays contain data from multiple points that the processor operates on
at once. Under normal conditions a conditional statement could only be applied to one of the
points in the VectorizedArray. There are possible ways to break up the VectorizedArrays and
work on the pieces of data individually, but this approach is not recommended for most users.
Clever use of “max” and “min” functions (which do exist for VectorizedArrays) may be able
to take the place of a conditional statement. For more details on the deal.II implementation of
VectorizedArrays (including a list of mathematical operations that are allowed), please visit:
https://www.dealii.org/8.4.0/doxygen/deal.II/classVectorizedArray.html
6.1.3 residualLHS
In the coupledCahnHilliardAllenCahn, the residualLHS function is empty because it is only
needed for elliptic PDEs (or more specifically, when a non-trivial matrix inversion needs to be
performed). Here is the residualLHS function from the precipitateEvolution application, where
the equation for mechanical equilibrium is elliptic.
From the formulation file in the precipitateEvolution application, the residual equation for the
mechanical displacement is:
R=Z
w:C(η1, η2, η3) : 0(c, η1, η2, η3)dV = 0 (4)
To turn this equation into a matrix inversion problem, we can linearize it with Newton’s method.
(It can also be directly written as a matrix inversion problem. For historical purposes we do
the linearization and for some mundane reasons, non-zero Dirichlet boundary conditions do not
currently work with that approach. Therefore, for the meantime, we recommend the approach
below.) The solution uis found through the following expression, given an initial guess u0:
0 = R(u) = R(u0+ ∆u) (5)
where ∆u=uu0. Then, applying the discretization that u=PiNiUi, where Niis the ith
shape function, we can write the following linearization:
δR(u)
δu U=R(u0) (6)
The discretized form of this equation can be written as a matrix inversion problem. However,
in PRISMS-PF, we only care about the product δR(u)
δu U. Taking the variational derivative of
34
R(u) yields:
δR(u)
δu =d
Z
w:C:(u+αw)0dV
α=0
(7)
=Z
w:C:1
2
d
(u+αw) + (u+αw)T0dV
α=0
(8)
=Z
w:C:d
(u+αw)0dV
α=0
(due to the symmetry of C) (9)
=Z
w:C:w dV (10)
In its discretized form δR(u)
δu Uis:
δR(u)
δu U=X
iX
jZ
Ni:C:NjdV Uj(11)
Moving back to the non-discretized form yields:
δR(u)
δu U=Z
w:C:(∆u)dV (12)
Thus, the full equation relating u0and ∆uis:
Z
w:C:(∆u)
| {z }
rLHS
ux
dV =Z
w: (0)
| {z }
rux
dV (13)
The above values of rLHS
ux and rux are used to define the residuals in the equations.h file. A
similar process can be undertaken for other elliptic problems.
The residualLHS function from the preciptiateEvolution application is:
// =================================================================================
// r e s i d u al L H S ( n ee de d o n l y i f a t l e a s t one e q u a t i o n i s e l l i p t i c )
// =================================================================================
// T hi s f u n c t i o n c a l c u l a t e s t h e r e s i d u a l e q u a t i o n s f o r t h e i t e r a t i v e s o l v e r f o r
// e l l i p t i c e q u a t i o n s . f o r e ach v a r i a b l e . I t t a k e s m o d e l V a r i a b l e s L i s t a s an in pu t ,
// which i s a l i s t o f t h e v al ue and d e r i v a t i v e s o f ea ch o f t he v a r i a b l e s a t a
// s p e c i f i c q u a d r at u r e p o i n t . The ( x , y , z ) l o c a t i o n o f t h a t q u ad r a tu r e p o i n t i s g i v e n
// by q p o i n t l o c ” . The f u n c t i o n o ut p ut s ” modelRes , th e v al u e and g r a d i e n t t erm s o f
// f o r th e l e f t hands i d e o f t h e r e s i d u a l e q u a t i o n f o r t h e i t e r a t i v e s o l v e r . The
// i n d ex f o r e ac h v a r i a b l e i n t h e s e l i s t s c o r r e s p o n d s t o t h e o r d e r i t i s d e f i n e d a t
// t he t op o f t h i s f i l e ( s t a r t i n g a t 0 ) , n ot c ou nt in g v a r i a b l e s t ha t have
// n ee d va l L HS , ” n ee d g ra d L HS , and ” n ee d he ss L HS a l l s e t t o f a l s e ” . I f t h e r e
// a r e m u l t i pl e e l l i p t i c e qu at io n s , c o n d i t i o n a l s ta te me nt s sh ou ld be us ed to e ns ur e
// th a t t he c o r r e c t r e s i d u a l i s b ei ng s ub mitt ed . The i n d e x o f t he f i e l d b ei ng s o l v e d
// can be a c c e s s e d by t h i s >currentFieldIndex ”.
template <i n t dim , i n t d eg ree >
void customPDE<dim , de g r e e >:: residualLHS (
variableContainer<dim , d egr e e , d e a l i i : : Ve c t o r i z e d A r r a y <double> > & variable list ,
d e a l i i : : P oin t<dim , d e a l i i : : Ve c t o r i z e d A r r a y <double> > q p o i n t l o c ) c o n s t {
// n1
s c a l a r v a l u e T y p e n1 = v a r i a b l e l i s t . g e t s c a l a r v a l u e ( 1 ) ;
// n2
s c a l a r v a l u e T y p e n2 = v a r i a b l e l i s t . g e t s c a l a r v a l u e ( 2 ) ;
// n3
s c a l a r v a l u e T y p e n3 = v a r i a b l e l i s t . g e t s c a l a r v a l u e ( 3 ) ;
35
// u
ve ctor grad Type ux = v a r i a b l e l i s t . g e t v e c t o r g r a d i e n t ( 4 ) ;
ve c t org r a dTy p e ruxV ;
// I n t e r p o l a t i o n f u n c t i o n s
s c a l a r v a l u e T y p e h1V = ( 1 0 . 0 n1n1n1 15.0n1n1n1 n1 + 6.0n1n1n1n1 n1 ) ;
s c a l a r v a l u e T y p e h2V = ( 1 0 . 0 n2n2n2 15.0n2n2n2 n2 + 6.0n2n2n2n2 n2 ) ;
s c a l a r v a l u e T y p e h3V = ( 1 0 . 0 n3n3n3 15.0n3n3n3 n3 + 6.0n3n3n3n3 n3 ) ;
// Take a dv a nt a ge o f E b e i n g s i m p l y 0 . 5 ( ux + t r a n s p o s e ( ux ) ) and us e t h e d e a l i i ” s ym me tr iz e ” f u n c t i o n
d e a l i i : : Tensor <2, dim , d e a l i i : : V e c t orized A r r a y <double> > E ;
E = s ymm et ri ze ( ux ) ;
// Compute s t r e s s t e n so r ( which i s e qu a l t o t he r e s i d u a l , Rux)
i f ( n d e p e n d e n t s t i f f n e s s == tr u e ) {
d e a l i i : : Tensor <2, C I J t e n s o r s i z e , d e a l i i : : Ve ct or iz ed Ar ra y<double> > CIJ c omb ine d ;
CIJ comb in ed = CIJ Mg ( constV ( 1.0 ) h1Vh2Vh3V) + CIJ Beta (h1V+h2V+h3V ) ;
computeStress<dim>( CIJ combined , E , ruxV ) ;
}
e l s e {
computeStress<dim>(CIJ Mg , E , ruxV ) ;
}
v a r i a b l e l i s t . s e t v e c t o r g r a d i e n t r e s i d u a l t e r m ( 4 , ruxV ) ;
}
Like residualRHS,residualLHS takes variables list and q point loc as inputs. However, because
only one elliptic equation is solved at a time, the output are the residual terms for a single
residual. As in residualRHS, the model variable values and derivatives are given convienent
names at the start of the file. Similar to residualRHS, the value of ruxV is set and then used to
set the appropriate residual for variables list (in this case the vector residual term for the fourth
variable).
If multiple elliptic equations need to be solved, you will need to use conditional statements to
calculate the proper residual depending on the elliptic equation being solved. The index of the
field being solved can be accessed using the “this->currentFieldIndex” statement.
6.2 IC and BCs.h
The ‘ICs and BCs.h’ file contains four functions: InitialCondition,InitialConditionVec,NonUni-
formDirichletBC, and NonUniformDirichletBCVec. The first two functions in the file are used to
set the initial conditions for scalar and vector variables, respectively, while the third and fourth
functions set non-uniform Dirichlet boundary conditions for scalar and vector variables, respec-
tively. For all of these functions, most users should only need to modify the sections between
the lines.
6.2.1 InitialCondition and InitialConditionVec
Here’s a look at the InitialCondition function for the coupled Allen-Cahn/Cahn-Hilliard example
application:
template <i n t dim>
do ub le I n i t i a l C o n d i t i o n <dim >: : v a l u e ( c o n s t P oi nt <dim>&p , c o n s t u n si g n ed i n t com ponen t ) c o n s t
{
do ub le s c a l a r I C = 0 ;
//
36
// ENTER THE INITIAL CONDITIONS HERE FOR SCALAR FIELDS
//
// Enter th e f u n c t i o n d e s c r i b i n g c o n d i t i o n s f o r t he f i e l d s at p o in t p ” .
// Use i f s t at e m en t s t o s e t t he i n i t i a l c o n d i t i o n f o r e ac h v a r i a b l e
// a cc o rd in g t o i t s v a r i a b l e i ndex .
// The i n i t i a l c o n d i t i o n i s two c i r c l e s / s p h e r e s d e f i n e d
// by a h y p e r b o l i c t a ng en t f u n c t i o n . The c e n t e r o f ea ch c i r c l e / s p he r e i s
// g i v e n by c e n t e r and i t s r a d i u s i s g i v e n by ” r a d .
do u b l e c e n t e r [ 2 ] [ 3 ] = { { 1.0/3.0 ,1.0/3.0 ,1.0/3.0},{3.0/4.0 ,3.0/4.0 ,3.0/4.0} } ;
do u b l e r ad [ 1 2 ] = {u s e r I n p u t s . d o m a i n s i z e [ 0 ] / 5 . 0 , u s e r I n p u t s . d o m a i n s i z e [ 0 ] / 1 2 . 0 };
do uble d i s t ;
s c a l a r I C = 0 ;
i f ( i n d e x == 0 ){
s c a l a r I C = 0 . 0 0 9 ;
}
f o r ( un si gn e d i n t i =0; i <2; i ++){
d i s t = 0 . 0 ;
f o r ( u ns ig ned i n t d i r = 0 ; d i r <dim ; d i r ++){
d i s t += ( p [ d i r ]c e n t e r [ i ] [ d i r ] u s e r I n p u t s . d o m a i n s i z e [ d i r ] )
( p [ d i r ]c e n t e r [ i ] [ d i r ] u s e r I n p u t s . d o m a i n s i z e [ d i r ] ) ;
}
d i s t = st d : : s q r t ( d i s t ) ;
// I n i t i a l c o n d i t i o n f o r t he c o n c e n t r a t i o n f i e l d
i f ( i n d e x == 0 ){
s c a l a r I C += 0. 5( 0 . 1 2 5 ) ( 1 . 0 s t d : : t an h ( ( d i s t ra d [ i ] ) / ( 1 . 0 ) ) ) ;
}
e l s e {
s c a l a r I C += 0 .5 (1.0 s t d : : t an h ( ( d i s t ra d [ i ] ) / ( 1 . 0 ) ) ) ;
}
}
//
r et ur n s c a l a r I C ;
}
In this function, the variable scalarIC should be set to the desired intitial condition. The (x,y,z)
coordinates can be accessed by the pvariable, with indices zero through 2. For example, if you
wanted to initialize a field to 5xy, you would enter:
s c a l a r I C = 5 . 0 p [ 0 ] p [ 1 ] ;
The initial conditions given above are a bit more complicated. They set the initial conditions for
two circular (spherical in 3D) particles. The initial condition for different variables is set using
conditional statements and the index variable. The index variable refers to the variable index
from the top of the “equations.h”. This example uses conditional statements to set the initial
conditions differently for the concentration (index ==0) and the structural order parameter (in-
dex ==0). The initial conditions for both fields are calculated using hyperbolic tangent functions
that make use of the distance between the centers of the particles and the point p.
The model constants defined in ‘parameters.in’ can be used in the intial condition or boundary
condition functions. However, the syntax is the same as in ‘customPDE.h’, not as in the residual
functions. That is, they have to be extracted from the userInputs object. An example of this is
in the dendriticSolidification application, where deltaV is set using one of the model constants.
Similarly, the initial conditions for vector fields are set in InitialConditionsVec. Here is the (some-
what trivial) InitialConditionVec function for the precipitateEvolution example application:
template <i n t dim>
void InitialConditionVec<dim >:: vector value (
c o n st d e a l i i : : Po int<dim>&p ,
d e a l i i : : V ector<double>&v e c t o r I C ) c o n s t
37
{
//
// ENTER THE INITIAL CONDITIONS HERE FOR VECTOR FIELDS
//
// Enter th e f u n c t i o n d e s c r i b i n g c o n d i t i o n s f o r t he f i e l d s at p o in t p ” .
// Use i f s t at e m en t s t o s e t t he i n i t i a l c o n d i t i o n f o r e ac h v a r i a b l e
// a cc o rd in g t o i t s v a r i a b l e i ndex .
i f ( i n d e x ==4){
v e c t o r I C ( 0 ) = 0 . 0 ;
v e c t o r I C ( 1 ) = 0 . 0 ;
i f ( dim == 3 ){
v e c t o r I C ( 2 ) = 0 . 0 ;
}
}
//
}
The initial condition for each component is set using the vector IC variable, where parentheses
are used to select the x, y, or z component.
6.2.2 NonUniformDirichletBC and NonUniformDirichletBCVec
These functions are needed when one or more boundaries are set to NON UNIFORM DIRICHLET.
These functions are very similar to the initial condition functions above, the user sets an expres-
sion for scalar BC or vector BC at point p. Once again, the variable index is used to differentiate
between variables based on their index from the top of the ‘equations.h’ file. For Dirichlet bound-
ary conditions that vary in time, the current time can be accessed via the variable time.
Currently, the one of the only two applications that use a non-uniform Dirichlet boundary con-
dition is CHiMaD benchmark6a (the other is CHiMaD benchmark6b). Here is the NonUnifor-
mDirichletBC function from CHiMaD benchmark6a:
template <i n t dim>
do u b l e Non Uni for mDi richletBC<dim >: : v a l u e (
c o n st d e a l i i : : Po int<dim>&p ,
c o n s t u n s ig n e d i n t c om ponent ) c o n s t
{
d o u bl e s c a l a r B C =0 ;
//
// ENTER THE NONUNIFORM DIRICHLET BOUNDARY CONDITIONS HERE FOR SCALAR FIELDS
//
// Enter th e f u n c t i o n d e s c r i b i n g c o n d i t i o n s f o r t he f i e l d s at p o in t p ” .
// Use i f s t at e m en t s t o s e t t he boun dary c o n d i t i o n f o r ea ch v a r i a b l e
// a cc o rd in g t o i t s v a r i a b l e i ndex . T hi s f u n c ti o n can be l e f t blan k i f t h er e
// a r e no nonunif orm D i r i c h l e t boundary c o n d i t i o n s .
i f ( i n d e x == 2 ){
i f ( d i r e c t i o n == 1 ){
do u b l e x=p [ 0 ] ;
do u b l e y=p [ 1 ] ;
s c a l a r B C=s t d : : s i n ( y / 7 . 0 ) ;
}
}
//
r e t u r n s c a l a r B C ;
}
6.3 postprocess.h
Unlike the files discussed so far in this section, the ‘postprocess.h’ file is optional. This file
allows users to specify fields other than the primary model variable to output. It also includes
38
an option to integrate over a field variable (e.g. to check conservation of a field). In the example
problems, this file is often used to calculate the total free energy of the system, which should
be monotonically decreasing for most phase field problems. It also is convienent for calculating
somewhat complicated expressions such as chemical potentials, stresses, and strains.
Note: Two restrictions are currently in place for the postprocessor. First, postprocessing vari-
ables can only be scalars, not vectors. Second, the postprocessor won’t work if the primary
model variable with index zero is a vector. (This is because postprocessor uses the mesh of the
zeroth primary variable to calculate and output the postprocessed field.) These restrictions will
be lifted in future versions of PRISMS-PF.
6.3.1 loadPostProcessorVariableAttributes
Similar to the ‘equations.h’ file, ‘postprocess.h’ begins with a function called loadPostProcessor-
VariableAttributes, which sets the attributes of the postprocessing variables. Here is the load-
PostProcessorVariableAttributes function from the coupledCahnHilliardAllenCahn application,
where the postprocessed field is “f tot”, the total free energy:
v oi d v a r i a b l e A t t r i b u t e L o a de r : : l o a d P o s t P r o c e s s o r V a r i a b l e A t t r i b u t e s ( ) {
// Variable 0
s e t v a r i a b l e n a m e (0 , ” f t o t ” ) ;
s e t v a r i a b l e t y p e ( 0 ,SCALAR ) ;
s e t n e e d v a l u e r e s i d u a l t e r m ( 0 , t r ue ) ;
s e t n e e d g r a d i e n t r e s i d u a l t e r m ( 0 , f a l s e ) ;
s e t o u t p u t i n t e g r a l ( 0 , t r ue ) ;
}
As in ‘equations.h’, a series of attributes for each variable are set using a series of C++ function
calls. The following table lists the functions and a description of the attributes they set:
Function Options Required Default Description
set variable name String no var Sets the name of the variable.
set variable type SCALAR,
VECTOR
no SCALAR Sets whether the variable is a
scalar or a vector (Currently only
scalar fields are allowed).
set need need value
residual term
Boolean no false Sets whether the expression for
the postprocessed field has a
value residual term.
set need need gradient
residual term
Boolean no false Sets whether the expression for
the postprocessed field has a gra-
dient residual term.
set output integral Boolean no false Sets whether the integrated value
of the postprocessed field is cal-
culated. The integrated value
is output to the file ‘integrated-
Fields.txt’.
6.3.2 postProcessedFields
The second function in the ‘postprocess.h’ file is similar to the residual functions in ‘equations.h’.
The primary difference is that, while the primary model fields are read in from variable list, the
39
residuals are submitted to pp variable list. Otherwise, the structure is similar and expressions
can be copied from one function to another.
Here is the postProcessedFields from the coupledCahnHilliardAllenCahn application:
template <i n t dim , i n t degr ee >
void customPDE<dim , de g r e e >:: p o s t P r o c e s s e d F i e l d s ( c o n st v a r i ab l e C o n ta i n e r <dim , de gre e , d e a l i i : : Vecto r i z e d A r r a y <double> > & variable list ,
variableContainer<dim , d egr e e , d e a l i i : : Ve c t o r i z e d A r r a y <double> > & p p v a r i a b l e l i s t ,
c o n st d e a l i i : : Po int<dim , d e a l i i : : Ve c t o r i z e d A r r a y <double> > q p o i n t l o c ) c o n s t {
// c
s c a l a r v a l u e T y p e c = v a r i a b l e l i s t . g e t s c a l a r v a l u e ( 0 ) ;
// n
s c a l a r v a l u e T y p e n = v a r i a b l e l i s t . g e t s c a l a r v a l u e ( 1 ) ;
s c a l a rg r ad T yp e nx = v a r i a b l e l i s t . g e t s c a l a r g r a d i e n t ( 1 ) ;
// F re e ene rg y f o r ea ch phas e
scalarvalueType faV = (1.67044.776c +5.1622cc2.7375ccc +1.3687cccc ) ;
scalarvalueType fbV = (5.0cc5.9746c1 . 5 9 2 4 ) ;
// I n t e r p o l a t i o n f u n c t i o n
scalarvalueType hV = (10.0nnn15.0nnnn+6.0nnnnn ) ;
// The homogenous f r e e e n e rgy
s c a l a r v a l u e T y p e f c he m = ( c on st V ( 1. 0 ) hV)faV + hVfbV ;
// The g r a d i e n t f r e e e n er gy
s c a l a r v a l u e T y p e f g r a d = co ns tV ( 0 . 5 KnV)nxnx ;
// The t o t a l f r e e ener gy
scalarvalueType f tot ;
f t o t = f c he m + f g r a d ;
// R e s i d u a l s f o r t h e e q u a t i o n t o e v o l v e t h e o r d e r p a ra m et e r
p p v a r i a b l e l i s t . s e t s c a l a r v a l u e r e s i d u a l t e r m ( 0 , f t o t ) ;
}
6.4 nucleation.h
The ‘nucleation.h’ file is also an optional file that is only needed when explcit nucleation is
needed for the application. It contains the function getNucleationProbability, which calculates
the probability of nucleation in a given volume element dV at a particular point in space pat
time this->currentTime. Please refer to Note 3 in Sec. 5 for a description of the nucleation
model in PRISMS-PF.
The values of the primary field variables can be accessed through the variable value input, using
the variable index from ‘equations.h’. Only variables where set need value nucleation was set to
true the loadVariableAttributes function in ‘equations.h’ can be accessed.
Here is getNucleationProbability from the nucleationModel application:
template <i n t dim , i n t d eg ree >
double customPDE<dim , deg r e e >: : g e t N u c l e a t i o n P r o b a b i l i t y ( v a r i a b l e V a l u e C o n t a i n e r v a r i a b l e v a l u e , d ou bl e dV , d e a l i i : : P oin t<dim>p) const
{
// S u p e r s a t u r a t i o n f a c t o r
do u b l e s s f ;
i f ( dim ==2) s s f =v a r i a b l e v a l u e (0) calmin ;
i f ( dim ==3) s s f =( v a r i a b l e v a l u e (0) calmin )( v a r i a b l e v a l u e (0) ca l mi n ) ;
// C a l c u la t e th e n u c l e a t i o n r a t e
do u b l e J=k1exp(k 2 / ( s t d : : max( s s f , 1 . 0 e 6)))exp(ta u / ( t h i s >c urr ent Tim e ) ) ;
d ou b le r et Pr o b =1.0exp(Ju s e r I n p u t s . dt Va lue ((double) userInputs . steps between nucleation attempts)dV ) ;
40
r e t u r n r e tP r ob ;
}
6.5 customPDE.h
The final header file in each application folder is ‘customPDE.h’. This file contains the declara-
tions for all of the functions and variables specific to the application. In C++ terminology, it is
the declaration for the customPDE class, which is a subclass of MatrixFreePDE. For most users,
the relevant section is labeled as “Model constants specific to this subclass”, which is where
the model constants from ‘parameters.in’ are extracted from the userInputs object. There is a
separate function to extract constants of each type. These are:
get model constant double
get model constant int
get model constant bool
get model constant rank 1 tensor
get model constant rank 2 tensor
get model constant elasticity tensor
Each of these take the variable name from ‘parameters.in’ as an input and output the appropriate
type.
Here is ‘customPDE.h’ from the preciptiateEvolution application, where all of the different types
of constants are used:
#i n c l u d e . . / . . / i n c l u d e / matrixFreePDE . h
template <i n t dim , i n t d eg ree >
c l a s s customPDE : p u b l i c MatrixFreePDE<dim , d eg r e e >
{
p u b l i c :
customPDE( userInputParameters<dim>u s e r I n p u t s ) :
MatrixFreePDE<dim , de gre e >( u s e r I n p u t s ) , u s e r I n pu t s ( u s e r I n p u t s ) { } ;
p r i v a t e :
#i n c l u d e . . / . . / i n c l u d e / t yp eD e fs . h
const userInputParameters<dim>userInputs ;
// Pure v i r t u a l method i n MatrixFreePDE
void re si d ual RHS (
variableContainer<dim , d egr e e , d e a l i i : : Ve c t o r i z e d A r r a y <double> > & variable list ,
d e a l i i : : P oin t<dim , d e a l i i : : Ve c t o r i z e d A r r a y <double> > q p o i n t l o c ) c o n s t ;
// Pure v i r t u a l method i n MatrixFreePDE
void residualLHS(
variableContainer<dim , d egr e e , d e a l i i : : Ve c t o r i z e d A r r a y <double> > & variable list ,
d e a l i i : : P oin t<dim , d e a l i i : : Ve c t o r i z e d A r r a y <double> > q p o i n t l o c ) c o n s t ;
// V i r t u al method i n MatrixFreePDE t ha t we o v e r r i d e i f we need p o s t p r o c e s s i n g
#i f d e f POSTPROCESS FILE EXISTS
void postProcessedFields (
c o n s t v a r i a b l e C o n t a i n e r <dim , de g ree , d e a l i i : : V e c t orize d A r r a y <double> > & variable list ,
variableContainer<dim , d egr e e , d e a l i i : : Ve c t o r i z e d A r r a y <double> > & p p v a r i a b l e l i s t ,
c o n st d e a l i i : : Po int<dim , d e a l i i : : Ve c t o r i z e d A r r a y <double> > q p o i n t l o c ) c o n s t ;
#e n d i f
// V i r t u a l method i n MatrixFreePDE t ha t we o v e r r i d e i f we need n u c l e a t i o n
#i f d e f NUCLEATION FILE EXISTS
d ou bl e g e t N u c l e a t i o n P r o b a b i l i t y ( v a r i a b l e V a l u e C o n t a i n e r v a r i a b l e v a l u e , d o ub le dV) c o n s t ;
41
#e n d i f
// ================================================================
// Methods s p e c i f i c t o t h i s s u b c l a s s
// ================================================================
// ================================================================
// Model c o n s t a n t s s p e c i f i c to t h i s s u b c l a s s
// ================================================================
d ou bl e McV = u s e r I n p u t s . g e t m o d e l c o n s t a n t d o u b l e ( ”McV ) ;
d ou bl e Mn1V = u s e r I n p u t s . g e t m o d e l c o n s t a n t d o u b l e ( ”Mn1V ” ) ;
d ou bl e Mn2V = u s e r I n p u t s . g e t m o d e l c o n s t a n t d o u b l e ( ”Mn2V ” ) ;
d ou bl e Mn3V = u s e r I n p u t s . g e t m o d e l c o n s t a n t d o u b l e ( ”Mn3V ” ) ;
d e a l i i : : Tensor <2,dim>Kn1 = u se r In p u t s . g e t m o d e l c o n s t an t r a n k 2 t e n s o r ( ”Kn1 ” ) ;
d e a l i i : : Tensor <2,dim>Kn2 = u se r In p u t s . g e t m o d e l c o n s t an t r a n k 2 t e n s o r ( ”Kn2 ” ) ;
d e a l i i : : Tensor <2,dim>Kn3 = u se r In p u t s . g e t m o d e l c o n s t an t r a n k 2 t e n s o r ( ”Kn3 ” ) ;
b o o l n d e p e n d e n t s t i f f n e s s = u se rI n pu ts . g et m o d el co n s t a n t b o ol ( n d e p e n d e n t s t i f f n e s s ) ;
d e a l i i : : Tensor <2,dim>s f t s l i n e a r 1 = u s er I n p ut s . g e t m o d e l c o n s t a n t r a n k 2 t e n s o r ( s f t s l i n e a r 1 ” ) ;
d e a l i i : : Tensor <2,dim>s f t s c o n s t 1 = u se r In p u t s . g e t m o d e l c o n s t a n t r a n k 2 t e n s o r ( ” s f t s c o n s t 1 ” ) ;
d e a l i i : : Tensor <2,dim>s f t s l i n e a r 2 = u s er I n p ut s . g e t m o d e l c o n s t a n t r a n k 2 t e n s o r ( s f t s l i n e a r 2 ” ) ;
d e a l i i : : Tensor <2,dim>s f t s c o n s t 2 = u se r In p u t s . g e t m o d e l c o n s t a n t r a n k 2 t e n s o r ( ” s f t s c o n s t 2 ” ) ;
d e a l i i : : Tensor <2,dim>s f t s l i n e a r 3 = u s er I n p ut s . g e t m o d e l c o n s t a n t r a n k 2 t e n s o r ( s f t s l i n e a r 3 ” ) ;
d e a l i i : : Tensor <2,dim>s f t s c o n s t 3 = u se r In p u t s . g e t m o d e l c o n s t a n t r a n k 2 t e n s o r ( ” s f t s c o n s t 3 ” ) ;
d ou bl e A4 = u s e r I n p u ts . g e t m o d e l c o n s t a n t d o u b l e ( ”A4 ” ) ;
d ou bl e A3 = u s e r I n p u ts . g e t m o d e l c o n s t a n t d o u b l e ( ”A3 ” ) ;
d ou bl e A2 = u s e r I n p u ts . g e t m o d e l c o n s t a n t d o u b l e ( ”A2 ” ) ;
d ou bl e A1 = u s e r I n p u ts . g e t m o d e l c o n s t a n t d o u b l e ( ”A1 ” ) ;
d ou bl e A0 = u s e r I n p u ts . g e t m o d e l c o n s t a n t d o u b l e ( ”A0 ” ) ;
d ou bl e B2 = u s e r I n p u t s . g e t m o d e l c o n s t a n t d ou b l e (” B2 ” ) ;
d ou bl e B1 = u s e r I n p u t s . g e t m o d e l c o n s t a n t d ou b l e (” B1 ” ) ;
d ou bl e B0 = u s e r I n p u t s . g e t m o d e l c o n s t a n t d ou b l e (” B0 ” ) ;
c o ns t s t a t i c u ns i g n e d i n t C I J t e n s o r s i z e =2dim1+dim / 3 ;
d e a l i i : : Tensor <2,CIJ tensor size>CIJ Mg =
u se r I np u t s . g e t m o d e l c o n s t a n t e l a s t i c i t y t e n s o r (” CIJ Mg ” ) ;
d e a l i i : : Tensor <2,CIJ tensor size>CI J Be ta =
u se r I np u t s . g e t m o d e l c o n s t a n t e l a s t i c i t y t e n s o r ( CIJ Beta ” ) ;
// ================================================================
};
This file can also be used to declare new member functions for the application. One example of
this is the seedNucleus function in the nucleationModel application.
Furthermore, for advanced users, the customPDE class can be used to override MatrixFreePDE
functions from the core PRISMS-PF library. One example of this is in the CHiMaD benchmark6b
application, where the makeTriangulation function is overridden to create a non-square mesh.
6.6 main.cc
The final file in the application directory is the C++ ‘main.cc’ file. This file controls the overall
flow of the code and is unlikely to be modified by most users. For all of the example applications,
‘main.cc’ is identical. One situation where a user may want to modify ‘main.cc’ is if they wanted
to run several simulations with different parameter sets for one execution of the code.
42
7 Tests
The ‘tests’ folder in the root directory contains some tests to ensure that PRISMS-PF is working
properly. A battery of automated tests can be found in the ‘automated tests’ directory. These
can be run by running the python script ‘run automatic tests.py’. This will run a series of unit
and regression tests, printing a summary of the results to the screen and writing to the file
‘test results.txt’. This python file can also be used as an example of automating PRISMS-PF
simulations.
The ‘unit tests’ directory contains a driver for a series of unit tests. To run them enter:
$ cmake .
$ make debug
$ mpirun n 1 main
A summary of the tests will print to the screen.
8 Creating Custom Applications
You can create your own PRISMS-PF applications by making simple modifications to the input
files described in the previous section. To create a new application, simply create a new folder
in the applications directory and copy the files from a related example application. Currently,
the new application folder must be in the applications directory, otherwise it will not be able to
find the required files in the core PRISMS-PF library. If the file “CMakeCache.txt” exists,
delete it (this file contains paths to the original application, and if left would cause the compiler
to compile the code from the original application). Then, make your desired modifications
(changing the initial or boundary conditions, changing the residual equations, etc.) and compile
and run your application the same way you would one of the example applications.
Once your have your own applications running, we’d love to help you share them with the
community. Please contact us at prismsphasefield.dev@umich.edu if you need help using GitHub
to generate a pull request so that we can add your work to the public repository.
9 Appendix I: The userInputs Object
In all of the application files, the user has access to an object called “userInputs”. This object
contains all of the input parameters from parameters.in and the variable attributes from the top
of equations.h and postprocess.h. The following table lists the member variable names to access
these parameters (excluding a few that are only useful in the core code). Using standard C++
syntax, all of these can be accessed using the following syntax: userInputs.exampleVariable,
where “exampleVariable” is the member variable name.
43
userInputs Member Variables
Variable Name Type parameters.in Text Description
domain size std::vector<double>Domain size X, Do-
main size Y, Domain
size Z
A vector containing the di-
mensions of the domain.
subdivisions std::vector<unsigned
int>
Subdivisions X, Sub-
divisions Y, Subdivi-
sions Z
A vector containing the num-
ber of subdivisions of the do-
main.
refine factor unsigned int Refine factor Directly from parameters.in.
degree unsigned int Element degree Directly from parameters.in.
h adaptivity bool Mesh adaptivity Directly from parameters.in.
max refinement level unsigned int Max refinement level Directly from parameters.in.
min refinement level unsigned int Min refinement level Directly from parameters.in.
refine criterion fields std::vector<unsigned
int>
Refinement criteria
fields
Converts variable names to
their variable index.
refine window max std::vector<double>Refinement window
max
Directly from parameters.in.
refine window min std::vector<double>Refinement window
min
Directly from parameters.in.
skip remeshing steps unsigned int Steps between
remeshing opera-
tions
Directly from parameters.in.
dtValue double Time step Directly from parameters.in.
finalTime double Simulation end time,
Number of time steps
End time for the simulation,
set based whichever will hap-
pen first, the specified time
or number of time steps.
totalIncrements double Simulation end time,
Number of time steps
Number of time steps for
the simulation, set based
whichever will happen first,
the specified time or number
of time steps.
output file type std::string Output file type Directly from parameters.in.
output file name std::string Output file name Directly from parameters.in.
outputTimeStepList std::vector<unsigned
int>
List of time steps to
output
Holds the list of time steps
to output for all output con-
ditions, not just LIST.
skip print steps unsigned int Skip print steps Directly from parameters.in.
44
userInputs Member Variables
Variable Name Type parameters.in Text Description
solverType std::string Linear solver Directly from parameters.in.
abs tol bool Use absolute con-
vergence tolerance
Directly from parameters.in.
solver tolerance double Solver tolerance
value
Directly from parameters.in.
max solver iterations unsigned int Maximum allowed
solver iterations
Directly from parameters.in.
load ICs std::vector<bool>Load intial condi-
tions
Directly from parameters.in.
load parallel file std::vector<bool>Load parallel file Directly from parameters.in.
load file name std::vector<std::string>File names Directly from parameters.in.
load field name std::vector<std::string>Variable names in
the files
Directly from parameters.in.
BC list std::vector<
varBCs<dim>>
Boundary condi-
tions for variable
[variable name]
Vector of one object per com-
ponent of each variable that
stores the BCs.
nucleus semiaxes std::vector<double>Nucleus semiaxes
(x,y,z)
Directly from parameters.in.
order parameter
freeze semiaxes
std::vector<double>Freeze zone semi-
axes (x,y,z)
Directly from parameters.in.
no nucleation
border thickness
double Nucleation-free
border thickness
Directly from parameters.in.
nucleus hold time double Freeze time follow-
ing nucleation
Directly from parameters.in.
min distance between
nuclei
double Minimum allowed
distance between
nuclei
Directly from parameters.in.
nucleation order
parameter cutoff
double Order parameter
cutoff value
Directly from parameters.in.
steps between
nucleation attempts
double Time steps be-
tween nucleation
attempts
Directly from parameters.in.
45
userInputs Member Variables
Variable Name Type parameters.in
Text
Description
number of variables unsigned int Counts the number of variables in
loadVariableAttributes in equa-
tions.h.
var name std::vector<std::string>Vector of the variable names from
loadVariableAttributes in equa-
tions.h.
var type std::vector<fieldType>Vector of the variable types from
loadVariableAttributes in equa-
tions.h.
var eq type std::vector<PDEType>Vector of the variable equa-
tion types from loadVariableAt-
tributes in equations.h.
nucleation occurs bool Set true if any variables are set
to nucleate in loadVariableAt-
tributes in equations.h.
nucleating
variable indices
std::vector<unsigned
int>
Vector of the variable indices for
variables that are set to nucle-
ate in loadVariableAttributes in
equations.h.
nucleation need value std::vector<unsigned
int>
Vector of the variable indices for
variables that are set to be needed
in the nucleation calculation in
loadVariableAttributes in equa-
tions.h.
pp number of variables unsigned int Counts the number of variables
in loadPostProcessorVariableAt-
tributes in postprocess.h.
num integrated fields unsigned int Counts the number of vari-
ables marked to be integrated
in loadPostProcessorVariableAt-
tributes in postprocess.h.
pp var name std::vector<std::string>Vector of the variable names from
loadPostProcessorVariableAt-
tributes in postprocess.h.
pp var type std::vector<fieldType>Vector of the variable types from
loadPostProcessorVariableAt-
tributes in postprocess.h.
46

Navigation menu