diff --git a/doc/modules/changes/20260604_FrancescoRadica_dynamic_core_single_core_data_owner b/doc/modules/changes/20260604_FrancescoRadica_dynamic_core_single_core_data_owner
new file mode 100644
index 00000000000..36d61eb2c05
--- /dev/null
+++ b/doc/modules/changes/20260604_FrancescoRadica_dynamic_core_single_core_data_owner
@@ -0,0 +1,6 @@
+Changed: The dynamic core statistics postprocessor no longer stores or
+serializes a separate copy of the dynamic core state. It now reads the current
+core data directly from the dynamic core boundary temperature plugin, making the
+boundary temperature plugin the single owner of the restart state.
+
+(Francesco Radica, 2026/06/04)
diff --git a/include/aspect/postprocess/core_statistics.h b/include/aspect/postprocess/core_statistics.h
index 9ce2e1d3005..a0a9c69aa75 100644
--- a/include/aspect/postprocess/core_statistics.h
+++ b/include/aspect/postprocess/core_statistics.h
@@ -24,7 +24,6 @@
#include
#include
-#include
namespace aspect
@@ -41,7 +40,6 @@ namespace aspect
class CoreStatistics : public Interface, public ::aspect::SimulatorAccess
{
public:
- CoreStatistics ();
/**
* Declare the parameters this class takes through input files.
*/
@@ -61,31 +59,6 @@ namespace aspect
std::pair
execute (TableHandler &statistics) override;
- /**
- * Export core data stored in this object. Doing this only because the boundary
- * temperature doesn't allowed to store restart data there. So we store the data needed
- * for restart here and exported to boundary temperature object if required.
- */
- const BoundaryTemperature::internal::CoreData &
- get_core_data() const;
-
- /**
- * Serialize the contents of this class as far as they are not read
- * from input parameter files.
- */
- template
- void serialize (Archive &ar, const unsigned int version);
-
- /**
- * Save the state of this object.
- */
- void save (std::map &status_strings) const override;
-
- /**
- * Restore the state of the object.
- */
- void load (const std::map &status_strings) override;
-
private:
/**
* Controls whether output the total excess entropy or the individual entropy terms
@@ -93,11 +66,6 @@ namespace aspect
* and adiabatic contribution).
*/
bool excess_entropy_only;
-
- /**
- * Stores the core data from boundary temperature.
- */
- BoundaryTemperature::internal::CoreData core_data;
};
}
}
diff --git a/source/boundary_temperature/dynamic_core.cc b/source/boundary_temperature/dynamic_core.cc
index 2844033ff54..b950b77f3df 100644
--- a/source/boundary_temperature/dynamic_core.cc
+++ b/source/boundary_temperature/dynamic_core.cc
@@ -21,7 +21,6 @@
#include
-#include
#include
#include
#include
@@ -86,27 +85,8 @@ namespace aspect
core_data.dt = this->get_timestep();
core_data.H = compute_radioheating_rate();
- // It's a bit tricky here.
- // Didn't use the initialize() function instead because the postprocess is initialized after boundary temperature.
- // It is not available at the time initialize() function of boundary temperature is called.
if (is_first_call==true)
{
- AssertThrow(this->get_postprocess_manager().template has_matching_active_plugin>(),
- ExcMessage ("Dynamic core boundary condition has to work with dynamic core statistics postprocessor."));
-
- const Postprocess::CoreStatistics &core_statistics
- = this->get_postprocess_manager().template get_matching_active_plugin>();
- const internal::CoreData &postprocessor_core_data = core_statistics.get_core_data();
- const bool restored_core_data = postprocessor_core_data.is_initialized;
-
- // The restart data is stored in 'core statistics' postprocessor.
- // If restart from checkpoint, extract data from there.
- // In a fresh run, the postprocessor has not seen valid dynamic core
- // data yet, so keep the boundary model's CoreData object and
- // initialize it from the parameter file below.
- if (restored_core_data)
- core_data = postprocessor_core_data;
-
// Read data of other energy source
read_data_OES();
@@ -127,10 +107,8 @@ namespace aspect
else
dTa = 0.;
- // Setup initial core data from prm input.
- // If resumed from checkpoint, core_data is read from postprocess instead of set from prm file.
- // (The boundary_temperature doesn't seem to support restart/resume, the data has to passed and
- // stored in the postprocessor 'core statistics')
+ // Setup initial core data from prm input. On restart, core_data has
+ // already been restored by DynamicCore::load().
if (!core_data.is_initialized)
{
core_data.Ti = inner_temperature + dTa;
@@ -156,7 +134,7 @@ namespace aspect
<get_pcout() << output.str();
}
- else if (restored_core_data)
+ else
{
core_data.dt = this->get_timestep();
core_data.H = compute_radioheating_rate();
@@ -1245,7 +1223,7 @@ namespace aspect
ASPECT_REGISTER_BOUNDARY_TEMPERATURE_MODEL(DynamicCore,
"dynamic core",
"This is a boundary temperature model working only with spherical "
- "shell geometry and core statistics postprocessor. The temperature "
+ "shell geometry. The temperature "
"at the top is constant, and the core mantle boundary temperature "
"is dynamically evolving through time by calculating the heat flux "
"into the core and solving the core energy balance. The formulation "
diff --git a/source/postprocess/core_statistics.cc b/source/postprocess/core_statistics.cc
index 22848f3f002..97d6d57664c 100644
--- a/source/postprocess/core_statistics.cc
+++ b/source/postprocess/core_statistics.cc
@@ -32,15 +32,6 @@ namespace aspect
{
namespace Postprocess
{
- template
- CoreStatistics::CoreStatistics()
- :
- // leave the core_data variable in its uninitialized state
- core_data()
- {}
-
-
-
template
std::pair
CoreStatistics::execute (TableHandler &statistics)
@@ -52,7 +43,7 @@ namespace aspect
const BoundaryTemperature::DynamicCore &dynamic_core =
this->get_boundary_temperature_manager().template get_matching_active_plugin>();
- core_data = dynamic_core.get_core_data();
+ const BoundaryTemperature::internal::CoreData &core_data = dynamic_core.get_core_data();
// now add core mantle boundary heat flux to the statistics object
// and create a single string that can be output to the screen
@@ -185,61 +176,6 @@ namespace aspect
- template
- const BoundaryTemperature::internal::CoreData &
- CoreStatistics::get_core_data() const
- {
- return core_data;
- }
-
-
-
- template
- template
- void CoreStatistics::serialize (Archive &ar, const unsigned int)
- {
- ar &(core_data.Ti);
- ar &(core_data.Ri);
- ar &(core_data.Xi);
- ar &(core_data.Q);
- ar &(core_data.dR_dt);
- ar &(core_data.dT_dt);
- ar &(core_data.dX_dt);
- ar &(core_data.is_initialized);
- }
-
-
-
- template
- void CoreStatistics::save (std::map &status_strings) const
- {
- // Serialize into a stringstream. Put the following into a code
- // block of its own to ensure the destruction of the 'oa'
- // archive triggers a flush() on the stringstream so we can
- // query the completed string below.
- std::ostringstream os;
- {
- aspect::oarchive oa (os);
- oa << (*this);
- }
-
- status_strings["CoreStatistics"] = os.str();
- }
-
-
-
- template
- void CoreStatistics::load (const std::map &status_strings)
- {
- // see if something was saved
- if (status_strings.find("CoreStatistics") != status_strings.end())
- {
- std::istringstream is (status_strings.find("CoreStatistics")->second);
- aspect::iarchive ia (is);
- ia >> (*this);
- }
- }
-
}
}