CA-PanGrainStructure — User Guide
CA-PanGrainStructure is the product name of the cellular-automaton (CA) grain-structure
plugin for Pandat / PanPhaseField. Its technical plugin identifier, which appears in the
console, the log and the licence check, remains CA_SOLIDIFICATION (DLL
CA_Solidification.dll).
This guide is for running the CA_SOLIDIFICATION plugin (CA-PanGrainStructure) from Pandat /
PanPhaseField and editing its input files. It tells you what you can change, where it lives, and what it means.
You do not need the source code for anything in this guide.
Prerequisite: a Pandat installation with the plugin DLL in the PanPhaseField_Plugins
folder (see Installation), and the Al_Demo.rtdb thermodynamic database
(shipped with the Pandat examples — copy it next to your .pbfx file; it is not bundled here).
Summary and features
CA-PanGrainStructure — 3-D grain structure prediction during solidification. Predict grain size, morphology, crystallographic orientation and the columnar-to-equiaxed transition (CET) of real multicomponent alloys. CA-PanGrainStructure couples a fast 3-D cellular-automaton grain-growth engine to Pandat's CALPHAD thermodynamics, so undercooling, liquidus and solute partitioning come from your alloy's database rather than fitted curves. Set up a run with two small text files, use every core with OpenMP, and inspect the microstructure in ParaView. Suited to casting, directional solidification and additive-manufacturing studies, and to screening how composition, cooling rate and nucleation conditions change the final grain structure.
CA-PanGrainStructure (plugin CA_SOLIDIFICATION) simulates grain-scale solidification of
multicomponent alloys in 3-D with a cellular automaton (CA) model. The liquid-to-solid
transformation is driven by a Pandat CALPHAD database, so liquidus, solute partitioning and
undercooling follow the real thermodynamics of your alloy rather than a hand-fitted phase
diagram. It is aimed at predicting grain structure (grain size, morphology, orientation and
columnar-to-equiaxed transition) under casting, directional-solidification and similar
conditions.
Features
- CALPHAD-coupled — thermodynamic and kinetic quantities for any alloy in the database
(e.g. Al-Si-Mg from
Al_Demo.rtdb, binary up to quinary) are evaluated through Pandat. - 3-D grain growth — dendritic/octahedral grain growth with capture, on a regular cell grid, with random crystallographic orientation for each grain.
- Stochastic nucleation — Gaussian critical-undercooling distribution and a configurable site density; a fixed random seed gives a bit-for-bit reproducible microstructure.
- Flexible initial microstructure — all-liquid with bulk nucleation, a single crystal at
a chosen orientation, a spherical seed, columnar-to-equiaxed (
cet) and pre-grown chill zone (chill) modes. - Prescribed thermal field — linear temperature gradient plus cooling rate, or a
measured
T(z,t)table. - Solute diffusion and pore/CET handling — solute redistribution in the liquid, optional solid back-diffusion, and a columnar-to-equiaxed check each step.
- Parallel — OpenMP multi-threading (
number_of_threads). - Results — VTK snapshots (grain colour/ID, fraction solid, temperature, composition)
for ParaView, a Pandat result table (
fsvs time/temperature), and a text log that records every parameter used. - Two-file setup — a
.pbfx(calculation) plus a.pfdb(CA model parameters), with sensible compiled-in defaults for anything you leave out. - Ready-to-run examples — equiaxed, single crystal, sphere seed and CET cases in
examples/.
Installation
1. Copy the plugin DLL into the PanPhaseField_Plugins folder of the Pandat installation
that you actually launch:
<Pandat>\bin\PanPhaseField_Plugins\CA_Solidification.dll
Copy only CA_Solidification.dll (any accompanying .lib/.pdb files are not needed at
run time). Replace the existing file if you are upgrading, with Pandat closed. Pandat loads
every plugin in that folder at start-up, and the console reports that the plugin named
CA_SOLIDIFICATION was loaded — that is the confirmation it was picked up.
If you build the plugin yourself, the Release|x64 post-build step copies the DLL into
$(SolutionDir)\bin\windows\PanPhaseField_Pluginsautomatically.
2. Copy the example files from guide\examples (the .pbfx files and AlSiMg.pfdb) to
a working folder, and copy Al_Demo.rtdb from the Pandat examples next to them.
3. Unpack to a SHORT path, for example C:\ca_solid\. Long paths can break the creation
of the results directory and Pandat's database cache, and the failure shows up as an
unrelated-looking error at start-up.
4. Licensing. Two things matter: the Pandat licence (HASP dongle), without which Pandat
will not run a phase-field calculation at all, and the plugin entitlement on that dongle,
checked under the plugin name CA_SOLIDIFICATION. If the plugin loads but the run is
refused, check the console message for the licence reason.
5. Verify by running Example 1 (see Running the examples) and checking that the console shows the solid fraction climbing.
A run is defined by two files:
| File | Role |
|---|---|
.pbfx |
The calculation: alloy, composition, domain, thermal schedule, initial microstructure mode, output requests. Opened/run from the Pandat GUI, or passed to PanPhaseField_ConsoleMode.exe. |
.pfdb |
The model parameters: everything CA-specific (nucleation undercooling, site density, timestep, gradients, switches) as a Custom Parameters table. Referenced by name from the .pbfx. |
How values are decided (precedence): compiled defaults → .pbfx → .pfdb. Anything you
don't set keeps its compiled-in default, and every parameter read is echoed to the run's log
file (0__<calc_name>.txt) as supplied or defaulted — check the log when in doubt about
what a run actually used. The full parameter table with all keys, units, and defaults is in
docs/CA_PFDB_PARAMETERS.md.
The worked example
Example 1 (examples/CA_ex1_equiaxed.pbfx + examples/AlSiMg.pfdb) is the baseline run this
guide annotates. The numbered callouts map to the task sections below.
<databases>
<database type="rtdb" file_name="Al_Demo.rtdb" /> <!-- [1] thermodynamic database -->
<database type="pfdb" file_name="AlSiMg.pfdb" /> <!-- model-parameter file -->
</databases>
...
<components>
<component name="Al" status="Selected" /> <!-- [1] alloy elements -->
<component name="Mg" status="Selected" />
<component name="Si" status="Selected" />
</components>
<phases>
<phase name="*" status="Suspended" />
<phase name="Fcc" status="Entered" /> <!-- [1] phases allowed to form -->
<phase name="Liquid" status="Entered" />
</phases>
...
<statespace>
<T value="650" /> <P value="1" />
<n component="Si" value="0.08" /> <!-- [1] composition (mole fraction) -->
<n component="Al" value="" /> <!-- [1] "" = balance element -->
<n component="Mg" value="0.001" />
</statespace>
...
<thermal_history>
<node time="0" T="607.28" /> <!-- [3] start T and cooling path -->
<node time="0.3023" T="577.05" /> <!-- [6] last node time = run duration -->
</thermal_history>
<phasefield>
<number_of_grids_x value="30" /> <!-- [2] domain size in cells -->
<number_of_grids_y value="50" />
<number_of_grids_z value="50" />
<length_scale value="1e-05" /> <!-- [2] cell size (m) -->
<number_of_threads value="4" /> <!-- [7] OpenMP threads -->
<initial_mode value="multi_crystal"> <!-- [5] initial microstructure -->
<input_folder_path value="" /> <!-- [3] thermal-profile CSV (advanced) -->
</initial_mode>
<num_of_profile_outputs value="20" /> <!-- [6] number of VTK snapshots -->
</phasefield>
And the .pfdb side (AlSiMg.pfdb, abridged):
<ParameterTable type="custom" name="Custom Parameters">
<Parameter name="Use_SDK_Thermo" value="1" /> <!-- [7] 1 = CALPHAD-coupled (keep 1) -->
<Parameter name="Temp_Gradient" value="0.0,0.0,0.0" /> <!-- [3] (Gx,Gy,Gz) K/m -->
<Parameter name="Ref_Origin" value="0.0,0.0,0.0" /> <!-- [3] where T = anchor (m) -->
<Parameter name="Nucli_Temp_Dist" value="8.0,3.0" /> <!-- [4] undercooling (mean,dev) K -->
<Parameter name="Nucli_Density" value="0.0" /> <!-- [4] sites per m^3; 0 = default -->
<Parameter name="Time_Step_s" value="2.5e-4" /> <!-- [6] CA timestep (s) - tripwire -->
<Parameter name="RNG_Seed" value="12345" /> <!-- [4] change for a new realization -->
<Parameter name="Nucli_Substrate_Frac" value="0.0" /> <!-- [4] bottom no-nucleation band -->
<Parameter name="Use_Rate_Based_Nucleation" value="0" /> <!-- [4] keep 0 (site-threshold) -->
</ParameterTable>
[1] Change the alloy and composition
Where: .pbfx — <components>, <statespace>, <phases>, <databases>.
- Add/remove elements in
<components>and give each a mole fraction in<statespace>(<n component="Si" value="0.08"/>= 8 at.%). Exactly one component carriesvalue=""— that is the balance element, which absorbs the rest to sum to 1. - The database must contain your elements.
Al_Demo.rtdbcarries Al, Cu, Mg, Si, Zn — any alloy inside that set (binary up to quinary) needs no new database. - Keep
<phase name="Liquid">and one solid phase (Fcc)Entered, the restSuspended. The model grows one primary solid phase. - The solvent (matrix) element is chosen automatically as the majority element; to name it
explicitly add
<solvent value="Al"/>inside<phasefield>. The log prints>> [PF setting] Ref element (...)— confirm the right element was picked.
Tripwire: the nucleation undercooling window [4] is alloy-specific. If you change the alloy substantially and get zero grains, your
Nucli_Temp_Distmean is probably outside the new alloy's liquidus-to-eutectic window (that is exactly whyAlSiMg.pfdbuses 8 K, not the compiled 42.5 K default).
[2] Change the domain size and resolution
Where: .pbfx — number_of_grids_x/y/z, length_scale.
number_of_grids_*is the cell count per axis;length_scaleis the cell edge in metres (1e-05= 10 µm). Physical size = count × cell size.- Runtime and memory scale with the cell count; the examples (~50–120k cells) run in minutes.
Tripwire — cell size is a calibration constant, not a free knob. The model's growth rate intrinsically depends on the cell size (and timestep). Refining the mesh does not converge to a mesh-independent growth velocity; compare runs only at the same
length_scaleandTime_Step_sunless you know what you are doing (see ADR-0021).
[3] Change the thermal conditions
Where: .pbfx <thermal_history>; .pfdb Temp_Gradient, Ref_Origin, Cooling_Rate,
Init_Temp.
- The simplest control is the
<thermal_history>nodes: start temperature, end temperature, and duration. Temperature in the domain is prescribed (no latent-heat release): a linear fieldT = anchor + G·(x−origin) − rate·t. - A spatial gradient comes from the
.pfdb:Temp_Gradient(Gx,Gy,Gz)in K/m, anchored atRef_Origin.(0,0,1e4)= cold bottom, hot top, 10 K/mm. .pfdbCooling_Rate(K/s) overrides the slope of the thermal history;Init_Temp(K) overrides the starting anchor. Use them when you want the.pfdbto carry the full thermal recipe (as the CET example does).- Advanced: a measured
T(z,t)table (CSV named in<input_folder_path>) replaces the entire analytic field — every key above is then ignored. See ADR-0017 before using this.
Tripwire — run duration is set before
Cooling_Rateapplies. The number of timesteps is derived from the thermal-history node times, before the.pfdbCooling_Rateoverride is seen. If you lower the cooling rate via the.pfdbbut keep a short thermal history, the run silently ends before solidification finishes. Size the last node'stimefrom the real rate and gradient (coldest-to-hottest sweep of the domain), not from the nominal slope.
[4] Change nucleation
Where: .pfdb — Nucli_Temp_Dist, Nucli_Density, RNG_Seed, Nucli_Substrate_Frac,
Enable_Bulk_Nucleation.
Nucli_Temp_Dist = mean,dev(K): each potential grain gets a critical undercooling drawn from this Gaussian at t=0 and fires when its cell first exceeds it. Lower mean → earlier, more numerous grains. The mean must lie inside the alloy's liquidus-to-eutectic window (see the tripwire in [1]).Nucli_Density(m⁻³): number of potential sites per volume.0uses the compiled default (3×10¹² m⁻³); any value> 0is used directly. This is the primary grain-size knob: more sites → finer grains.RNG_Seed: same seed = same microstructure, bit for bit. Change it to get an independent statistical realization of the same physical setup.Nucli_Substrate_Frac: fraction of the domain height at the bottom where nucleation is suppressed (0 = nucleate everywhere). Ignored incet:/chill:modes, which own the bottom.Enable_Bulk_Nucleation = 0turns bulk nucleation off entirely (seed-only runs do this implicitly). LeaveUse_Rate_Based_Nucleation = 0— the legacy rate-based model exists for validation only.
[5] Change the initial microstructure
Where: .pbfx — the initial_mode value. One tag selects the mode; extra settings ride
in (key,value) pairs. The whole string must stay under 64 characters — longer tags are
silently cut off and the lost keys fall back to defaults.
| Tag | Meaning | Example file |
|---|---|---|
multi_crystal |
All liquid; grains appear by bulk nucleation [4]. The default choice. | CA_ex1_equiaxed.pbfx |
single_crystal:(angle_a,30):(angle_b,30):(angle_c,30) |
One seed at the domain centre, bulk nucleation off. Euler angles in degrees set the crystal orientation. | CA_ex2_single_crystal.pbfx |
circle:R:(angle_a,0):... |
Like single_crystal but the seed is a solid sphere of radius R cells (circle:1 = single cell). |
CA_ex3_sphere_seed.pbfx |
cet:(thickness_frac,0.1):(bnd_dt_mean,3):(bnd_dt_dev,1.5) |
Columnar-to-equiaxed: the bottom band (here 10% of height) nucleates easily (its own undercooling Gaussian); the bulk uses [4]. Pair with a directional gradient [3]. | CA_ex4_cet.pbfx |
chill:(thickness_layers,15) |
A pre-grown solid chill zone is built in the bottom N layers before the run starts. Mutually exclusive with cet:. |
— |
- Band thickness (for
cet:/chill:) can be given asthickness_layers(cells),thickness_frac(fraction of height), orthickness_m(metres) — use exactly one. - In CET mode, an unset
Init_Tempanchors the cold bottom at the liquidus — usually what you want, since it makes the whole domain start just above melting.
[6] Change run length and output cadence
Where: .pbfx <thermal_history> last node + num_of_profile_outputs; .pfdb
Time_Step_s.
- Run duration = the last thermal-history node's
time. Steps = duration /Time_Step_s. The run also stops early, automatically, once the whole domain has cooled below the eutectic temperature (primary solidification finished everywhere) — a long duration wastes nothing. num_of_profile_outputs: how many VTK snapshots are written across the run (plus t=0).- Results: VTK files (grain colour/ID, fraction solid, temperature, composition) for ParaView,
the Pandat result table (
fsvstime/T), and the text log0__<calc_name>.txt.
Tripwire —
Time_Step_sis the other calibration constant. Changing it changes not only the step count but the predicted growth rate (see [2]). Keep it fixed across runs you intend to compare.
[7] Performance switches
number_of_threads(.pbfx): OpenMP threads; 4 is a good default.Conservation_Debug(.pfdb): per-step solute-accounting diagnostic, on by default and costly — set0for production runs.Use_SDK_Thermo = 1is the CALPHAD-coupled model and the mode everything current uses;0is a legacy linear Al-Si path kept for regression testing.Enable_Solid_Diffusion(.pfdb, default 0): adds solid-state back-diffusion at real cost; leave off unless you specifically need it.
Running the examples
From the Pandat GUI: Batch Calc → load the .pbfx. Headless:
& "<Pandat>\PanPhaseField_ConsoleMode.exe" "CA_ex1_equiaxed.pbfx"
(with Al_Demo.rtdb copied next to the .pbfx). Each example's header comment states what it
demonstrates and what to expect. Start with Example 1 and change one thing at a time.