diff --git a/applications/solvers/additiveFoam/Allwclean b/applications/solvers/additiveFoam/Allwclean
index 0be4d4a..2cf860f 100755
--- a/applications/solvers/additiveFoam/Allwclean
+++ b/applications/solvers/additiveFoam/Allwclean
@@ -3,7 +3,7 @@ cd ${0%/*} || exit 1 # Run from this directory
rm -rf Make/gitInfo.H
-wclean libso functionObjects/ExaCA
+wclean libso functionObjects
wclean libso movingHeatSource
wclean
diff --git a/applications/solvers/additiveFoam/Allwmake b/applications/solvers/additiveFoam/Allwmake
index 15956c7..e54e7e1 100755
--- a/applications/solvers/additiveFoam/Allwmake
+++ b/applications/solvers/additiveFoam/Allwmake
@@ -27,7 +27,7 @@ export ADDITIVEFOAM_BUILD_FLAGS="-DGIT_MODULE_ENABLED=1"
#------------------------------------------------------------------------------
# Build libraries and solver
-wmake $targetType functionObjects/ExaCA
+wmake $targetType functionObjects
wmake $targetType movingHeatSource
wmake $targetType
diff --git a/applications/solvers/additiveFoam/functionObjects/ExaCA/Make/files b/applications/solvers/additiveFoam/functionObjects/ExaCA/Make/files
deleted file mode 100644
index 79b17f9..0000000
--- a/applications/solvers/additiveFoam/functionObjects/ExaCA/Make/files
+++ /dev/null
@@ -1,3 +0,0 @@
-ExaCA.C
-
-LIB = $(FOAM_USER_LIBBIN)/libExaCAFunctionObject
diff --git a/applications/solvers/additiveFoam/functionObjects/Make/files b/applications/solvers/additiveFoam/functionObjects/Make/files
new file mode 100644
index 0000000..194ab9e
--- /dev/null
+++ b/applications/solvers/additiveFoam/functionObjects/Make/files
@@ -0,0 +1,4 @@
+ExaCA/ExaCA.C
+solidificationData/solidificationData.C
+
+LIB = $(FOAM_USER_LIBBIN)/libadditiveFoamFunctionObjects
diff --git a/applications/solvers/additiveFoam/functionObjects/ExaCA/Make/options b/applications/solvers/additiveFoam/functionObjects/Make/options
similarity index 100%
rename from applications/solvers/additiveFoam/functionObjects/ExaCA/Make/options
rename to applications/solvers/additiveFoam/functionObjects/Make/options
diff --git a/applications/solvers/additiveFoam/functionObjects/solidificationData/solidificationData.C b/applications/solvers/additiveFoam/functionObjects/solidificationData/solidificationData.C
new file mode 100644
index 0000000..47e589a
--- /dev/null
+++ b/applications/solvers/additiveFoam/functionObjects/solidificationData/solidificationData.C
@@ -0,0 +1,231 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2023 Oak Ridge National Laboratory
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenFOAM. If not, see .
+
+\*---------------------------------------------------------------------------*/
+
+#include "solidificationData.H"
+#include "Time.H"
+#include "fvMesh.H"
+#include "addToRunTimeSelectionTable.H"
+#include "volFields.H"
+#include "fvc.H"
+#include "OFstream.H"
+#include "OSspecific.H"
+#include "labelVector.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace functionObjects
+{
+ defineTypeNameAndDebug(solidificationData, 0);
+
+ addToRunTimeSelectionTable
+ (
+ functionObject,
+ solidificationData,
+ dictionary
+ );
+}
+}
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+Foam::functionObjects::solidificationData::solidificationData
+(
+ const word& name,
+ const Time& runTime,
+ const dictionary& dict
+)
+:
+ fvMeshFunctionObject(name, runTime, dict),
+ T_(mesh_.lookupObject>("T")),
+ R_
+ (
+ IOobject
+ (
+ "R",
+ mesh_.time().timeName(),
+ mesh_,
+ IOobject::NO_READ,
+ IOobject::NO_WRITE
+ ),
+ fvc::ddt(T_)
+ ),
+ searchEngine_(mesh_, polyMesh::CELL_TETS)
+{
+ read(dict);
+
+ setOverlapCells();
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
+
+Foam::functionObjects::solidificationData::~solidificationData()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+bool Foam::functionObjects::solidificationData::read(const dictionary& dict)
+{
+ box_ = dict.lookup("box");
+ isoValue_ = dict.lookup("isoValue");
+
+ return true;
+}
+
+void Foam::functionObjects::solidificationData::setOverlapCells()
+{
+ // create a compact cell-stencil using the overlap sub-space
+ const pointField& points = mesh_.points();
+
+ boundBox procBb(points);
+
+ const vector extend = 1e-10*vector::one;
+
+ if (procBb.overlaps(box_))
+ {
+ forAll(mesh_.cells(), celli)
+ {
+ boundBox cellBb(point::max, point::min);
+
+ const labelList& vertices = mesh_.cellPoints()[celli];
+
+ forAll(vertices, i)
+ {
+ cellBb.min() = min(cellBb.min(), points[vertices[i]] - extend);
+ cellBb.max() = max(cellBb.max(), points[vertices[i]] + extend);
+ }
+
+ if (cellBb.overlaps(box_))
+ {
+ overlapCells.append(celli);
+ }
+ }
+ }
+
+ overlapCells.shrink();
+}
+
+
+Foam::wordList Foam::functionObjects::solidificationData::fields() const
+{
+ return wordList::null();
+}
+
+
+bool Foam::functionObjects::solidificationData::execute()
+{
+ //- Get current time
+ const scalar& time = mesh_.time().value();
+
+ //- Get the temperature at the previous time
+ const volScalarField& T0_ = T_.oldTime();
+
+ //- Calculate the thermal gradient
+ const volScalarField G("G", mag(fvc::grad(T_)));
+
+ forAll(overlapCells, i)
+ {
+ label celli = overlapCells[i];
+
+ // Cooled below specified isotherm
+ if ((T0_[celli] > isoValue_) && (T_[celli] <= isoValue_))
+ {
+ const scalar Ri = mag(R_[celli]);
+ const scalar Gi = max(G[celli], small);
+
+ const vector pt = mesh_.C()[celli];
+
+ List event(7);
+
+ event[0] = pt[0];
+ event[1] = pt[1];
+ event[2] = pt[2];
+ event[3] = time;
+ event[4] = Ri;
+ event[5] = Gi;
+ event[6] = Ri / Gi;
+
+ events.append(event);
+ }
+ }
+
+ //- Update cooling rate
+ R_ = fvc::ddt(T_);
+
+ return true;
+}
+
+bool Foam::functionObjects::solidificationData::end()
+{
+ Info<< "Number of solidification events: "
+ << returnReduce(events.size(), sumOp()) << endl;
+
+ const fileName filePath
+ (
+ mesh_.time().rootPath()
+ /mesh_.time().globalCaseName()
+ /"solidificationData"
+ );
+
+ mkDir(filePath);
+
+ OFstream os
+ (
+ filePath + "/" + "data_" + Foam::name(Pstream::myProcNo()) + ".csv"
+ );
+
+ os << "x,y,z,t,R,G,V" << endl;
+
+ for(int i=0; i < events.size(); i++)
+ {
+ int n = events[i].size() - 1;
+
+ for(int j=0; j < n; j++)
+ {
+ os << events[i][j] << ",";
+ }
+ os << events[i][n] << "\n";
+ }
+
+ Info<< "Successfully wrote solidification data in: "
+ << returnReduce(mesh_.time().cpuTimeIncrement(), maxOp()) << " s"
+ << endl << endl;
+
+ return true;
+}
+
+
+bool Foam::functionObjects::solidificationData::write()
+{
+ return true;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/solvers/additiveFoam/functionObjects/solidificationData/solidificationData.H b/applications/solvers/additiveFoam/functionObjects/solidificationData/solidificationData.H
new file mode 100644
index 0000000..519c0ae
--- /dev/null
+++ b/applications/solvers/additiveFoam/functionObjects/solidificationData/solidificationData.H
@@ -0,0 +1,135 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2023 Oak Ridge National Laboratory
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenFOAM. If not, see .
+
+Class
+ Foam::functionObjects::solidificationData
+
+SourceFiles
+ solidificationData.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef solidificationData_H
+#define solidificationData_H
+
+#include "fvMeshFunctionObject.H"
+#include "volFields.H"
+#include "meshSearch.H"
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace functionObjects
+{
+
+/*---------------------------------------------------------------------------*\
+ Class solidificationData Declaration
+\*---------------------------------------------------------------------------*/
+
+class solidificationData
+:
+ public fvMeshFunctionObject
+{
+ // Private Data
+
+ const volScalarField& T_;
+
+ volScalarField R_;
+
+ DynamicList