From a6c5eefe3904037daaf4b8e29f5165f5fb70ae4b Mon Sep 17 00:00:00 2001
From: "Peter W. Draper" <p.w.draper@durham.ac.uk>
Date: Thu, 18 Jan 2018 12:44:18 +0000
Subject: [PATCH] Add dump functions to remaining engine data

---
 src/cooling.c            | 28 ++++++++++++++++++
 src/cooling.h            |  4 +++
 src/engine.c             | 64 +++++++++++++++++++++++++++-------------
 src/gravity_properties.c | 24 +++++++++++++++
 src/gravity_properties.h |  5 ++++
 src/hydro_properties.c   | 24 +++++++++++++++
 src/hydro_properties.h   |  5 ++++
 src/parser.c             | 26 ++++++++++++++++
 src/parser.h             |  5 ++++
 src/physical_constants.c |  6 ++--
 src/potential.c          | 28 ++++++++++++++++++
 src/potential.h          |  4 +++
 src/restart.c            | 25 ++++++++++------
 src/restart.h            |  7 ++++-
 src/sourceterms.c        | 26 ++++++++++++++++
 src/sourceterms.h        |  5 ++++
 src/space.c              |  4 +++
 17 files changed, 255 insertions(+), 35 deletions(-)

diff --git a/src/cooling.c b/src/cooling.c
index 9452857117..b6450615e4 100644
--- a/src/cooling.c
+++ b/src/cooling.c
@@ -22,6 +22,7 @@
 
 /* This object's header. */
 #include "cooling.h"
+#include "restart.h"
 
 /**
  * @brief Initialises the cooling properties.
@@ -52,3 +53,30 @@ void cooling_print(const struct cooling_function_data* cooling) {
 
   cooling_print_backend(cooling);
 }
+
+/**
+ * @brief Write a hydro_props struct to the given FILE as a stream of bytes.
+ *
+ * @param p the struct
+ * @param stream the file stream
+ */
+void cooling_struct_dump(const struct cooling_function_data* cooling, 
+                         FILE *stream) {
+    restart_write_blocks((void *) cooling, 
+                         sizeof(struct cooling_function_data),
+                         1, stream, "cooling function");
+}
+
+
+/**
+ * @brief Restore a hydro_props struct from the given FILE as a stream of
+ * bytes.
+ *
+ * @param p the struct
+ * @param stream the file stream
+ */
+void cooling_struct_restore(const struct cooling_function_data* cooling,
+                            FILE *stream) {
+    restart_read_blocks((void *)cooling, sizeof(struct cooling_function_data),
+                        1, stream, "cooling function");
+}
diff --git a/src/cooling.h b/src/cooling.h
index 3d50658b9b..979bcb6044 100644
--- a/src/cooling.h
+++ b/src/cooling.h
@@ -48,4 +48,8 @@ void cooling_init(const struct swift_params* parameter_file,
 
 void cooling_print(const struct cooling_function_data* cooling);
 
+/* Dump/restore. */
+void cooling_struct_dump(const struct cooling_function_data* cooling, FILE *stream);
+void cooling_struct_restore(const struct cooling_function_data* cooling, FILE *stream);
+
 #endif /* SWIFT_COOLING_H */
diff --git a/src/engine.c b/src/engine.c
index 74459541ec..d217e6e90d 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -52,6 +52,7 @@
 #include "atomic.h"
 #include "cell.h"
 #include "clocks.h"
+#include "cooling.h"
 #include "cycle.h"
 #include "debug.h"
 #include "error.h"
@@ -69,6 +70,7 @@
 #include "serial_io.h"
 #include "single_io.h"
 #include "sort_part.h"
+#include "sourceterms.h"
 #include "statistics.h"
 #include "timers.h"
 #include "tools.h"
@@ -5635,25 +5637,28 @@ void engine_clean(struct engine *e) {
  */
 void engine_struct_dump(struct engine *e, FILE *stream) {
 
-  /* The engine. */
+  /* Dump our signature and version. */
+  restart_write_blocks(SWIFT_RESTART_SIGNATURE,strlen(SWIFT_RESTART_SIGNATURE), 
+                       1, stream, "SWIFT signature");
+  restart_write_blocks((void *)package_version(), strlen(package_version()), 1,
+                       stream, "SWIFT version");
+
+  /* Now the engine. */
   restart_write_blocks(e, sizeof(struct engine), 1, stream, "engine struct");
 
-  /* Now for the other pointers, these use their own save functions. */
+  /* And all the engine pointed data, these use their own dump functions. */
   space_struct_dump(e->s, stream);
   e->s->e = e;
   units_struct_dump(e->internal_units, stream);
   units_struct_dump(e->snapshotUnits, stream);
   partition_struct_dump(e->reparttype, stream);
   phys_const_struct_dump(e->physical_constants, stream);
-
-  /* hydro props */
-  /* gravity props */
-  /* external potential props */
-  /* cooling props */
-  /* sourceterm props */
-  /* parameters */
-
-
+  hydro_props_struct_dump(e->hydro_properties, stream);
+  gravity_props_struct_dump(e->gravity_properties, stream);
+  potential_struct_dump(e->external_potential, stream);
+  cooling_struct_dump(e->cooling_func, stream);
+  sourceterms_struct_dump(e->sourceterms, stream);
+  parser_struct_dump(e->parameter_file, stream);
 }
 
 /**
@@ -5665,10 +5670,26 @@ void engine_struct_dump(struct engine *e, FILE *stream) {
  */
 void engine_struct_restore(struct engine *e, FILE *stream) {
 
-  /* The engine. */
+  /* Get our version and signature back. These should match. */
+  char signature[10];
+  restart_write_blocks(signature, strlen(SWIFT_RESTART_SIGNATURE), 1, stream,
+                       "SWIFT signature");
+  if (strcmp(signature, SWIFT_RESTART_SIGNATURE) != 0)
+    error("Do not recognise this as a SWIFT restart file");
+
+  char version[200];
+  restart_read_blocks(version, strlen(package_version()), 1, stream,
+                      "SWIFT version");
+  /* XXX error or warning, it might work! */
+  if (strcmp(version, package_version()) != 0)
+    message("WARNING: restoring from a different version of SWIFT. You have:"
+            " %s, and the restarts file where created using: %s. This may fail"
+            " badly", version, package_version());
+
+  /* Now the engine. */
   restart_read_blocks(e, sizeof(struct engine), 1, stream, "engine struct");
 
-  /* Re-initializations as necessary. */
+  /* XXX Re-initializations as necessary. XXX */
   /* runners */
   /* scheduler */
   /* threadpool */
@@ -5683,19 +5704,20 @@ void engine_struct_restore(struct engine *e, FILE *stream) {
   /* links */
 
 
-  /* Now for the other pointers, these use their own save functions. */
+  /* Now for the other pointers, these use their own restore functions. */
+  /* XXX struct leaky memory allocations, or need static decls from main.c,
+   * like engine_init() */
   space_struct_restore(e->s, stream);
   units_struct_restore(e->internal_units, stream);
   units_struct_restore(e->snapshotUnits, stream);
   partition_struct_restore(e->reparttype, stream);
   phys_const_struct_restore(e->physical_constants, stream);
-
-  /* hydro props */
-  /* gravity props */
-  /* external potential props */
-  /* cooling props */
-  /* sourceterm props */
-  /* parameters */
+  hydro_props_struct_restore(e->hydro_properties, stream);
+  gravity_props_struct_restore(e->gravity_properties, stream);
+  potential_struct_restore(e->external_potential, stream);
+  cooling_struct_restore(e->cooling_func, stream);
+  sourceterms_struct_restore(e->sourceterms, stream);
+  parser_struct_restore(e->parameter_file, stream);
 
   /* Want to force a rebuild before using this engine. Wait to repartition.*/
   e->forcerebuild = 1;
diff --git a/src/gravity_properties.c b/src/gravity_properties.c
index 27a5de0a41..ce0bf1581e 100644
--- a/src/gravity_properties.c
+++ b/src/gravity_properties.c
@@ -96,3 +96,27 @@ void gravity_props_print_snapshot(hid_t h_grpgrav,
   io_write_attribute_f(h_grpgrav, "Mesh r_cut_min", p->r_cut_min);
 }
 #endif
+
+/**
+ * @brief Write a gravity_props struct to the given FILE as a stream of bytes.
+ *
+ * @param p the struct
+ * @param stream the file stream
+ */
+void gravity_props_struct_dump(const struct gravity_props *p, FILE *stream) {
+    restart_write_blocks((void *) p, sizeof(struct gravity_props),
+                         1, stream, "gravity props");
+}
+
+
+/**
+ * @brief Restore a gravity_props struct from the given FILE as a stream of
+ * bytes.
+ *
+ * @param p the struct
+ * @param stream the file stream
+ */
+void gravity_props_struct_restore(const struct gravity_props *p, FILE *stream) {
+    restart_read_blocks((void *)p, sizeof(struct gravity_props),
+                        1, stream, "gravity props");
+}
diff --git a/src/gravity_properties.h b/src/gravity_properties.h
index f7b9950052..826ffd0de0 100644
--- a/src/gravity_properties.h
+++ b/src/gravity_properties.h
@@ -28,6 +28,7 @@
 
 /* Local includes. */
 #include "parser.h"
+#include "restart.h"
 
 /**
  * @brief Contains all the constants and parameters of the self-gravity scheme
@@ -79,4 +80,8 @@ void gravity_props_print_snapshot(hid_t h_grpsph,
                                   const struct gravity_props *p);
 #endif
 
+/* Dump/restore. */
+void gravity_props_struct_dump(const struct gravity_props *p, FILE *stream);
+void gravity_props_struct_restore(const struct gravity_props *p, FILE *stream);
+
 #endif /* SWIFT_GRAVITY_PROPERTIES */
diff --git a/src/hydro_properties.c b/src/hydro_properties.c
index 995610acb2..dbbbed6455 100644
--- a/src/hydro_properties.c
+++ b/src/hydro_properties.c
@@ -127,3 +127,27 @@ void hydro_props_print_snapshot(hid_t h_grpsph, const struct hydro_props *p) {
                        p->max_smoothing_iterations);
 }
 #endif
+
+/**
+ * @brief Write a hydro_props struct to the given FILE as a stream of bytes.
+ *
+ * @param p the struct
+ * @param stream the file stream
+ */
+void hydro_props_struct_dump(const struct hydro_props *p, FILE *stream) {
+    restart_write_blocks((void *) p, sizeof(struct hydro_props),
+                         1, stream, "hydro props");
+}
+
+
+/**
+ * @brief Restore a hydro_props struct from the given FILE as a stream of
+ * bytes.
+ *
+ * @param p the struct
+ * @param stream the file stream
+ */
+void hydro_props_struct_restore(const struct hydro_props *p, FILE *stream) {
+    restart_read_blocks((void *)p, sizeof(struct hydro_props),
+                        1, stream, "hydro props");
+}
diff --git a/src/hydro_properties.h b/src/hydro_properties.h
index a887ccb6df..6d325c35d6 100644
--- a/src/hydro_properties.h
+++ b/src/hydro_properties.h
@@ -33,6 +33,7 @@
 
 /* Local includes. */
 #include "parser.h"
+#include "restart.h"
 
 /**
  * @brief Contains all the constants and parameters of the hydro scheme
@@ -71,4 +72,8 @@ void hydro_props_init(struct hydro_props *p, const struct swift_params *params);
 void hydro_props_print_snapshot(hid_t h_grpsph, const struct hydro_props *p);
 #endif
 
+/* Dump/restore. */
+void hydro_props_struct_dump(const struct hydro_props *p, FILE *stream);
+void hydro_props_struct_restore(const struct hydro_props *p, FILE *stream);
+
 #endif /* SWIFT_HYDRO_PROPERTIES */
diff --git a/src/parser.c b/src/parser.c
index 0b608b2926..f7355d4a4a 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -33,6 +33,7 @@
 /* Local headers. */
 #include "common_io.h"
 #include "error.h"
+#include "restart.h"
 
 #define PARSER_COMMENT_STRING "#"
 #define PARSER_COMMENT_CHAR '#'
@@ -784,3 +785,28 @@ void parser_write_params_to_hdf5(const struct swift_params *params, hid_t grp) {
     io_write_attribute_s(grp, params->data[i].name, params->data[i].value);
 }
 #endif
+
+
+/**
+ * @brief Write a swift_params struct to the given FILE as a stream of bytes.
+ *
+ * @param p the struct
+ * @param stream the file stream
+ */
+void parser_struct_dump(const struct swift_params *params, FILE *stream) {
+    restart_write_blocks((void *) params, sizeof(struct swift_params),
+                         1, stream, "parameters");
+}
+
+
+/**
+ * @brief Restore a swift_params struct from the given FILE as a stream of
+ * bytes.
+ *
+ * @param p the struct
+ * @param stream the file stream
+ */
+void parser_struct_restore(const struct swift_params *params, FILE *stream) {
+    restart_read_blocks((void *)params, sizeof(struct swift_params),
+                        1, stream, "parameters");
+}
diff --git a/src/parser.h b/src/parser.h
index bab6d8b25f..e22a456dbc 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -83,4 +83,9 @@ void parser_get_opt_param_string(const struct swift_params *params,
 void parser_write_params_to_hdf5(const struct swift_params *params, hid_t grp);
 #endif
 
+/* Dump/restore. */
+void parser_struct_dump(const struct swift_params *params, FILE *stream);
+void parser_struct_restore(const struct swift_params *params, FILE *stream);
+
+
 #endif /* SWIFT_PARSER_H */
diff --git a/src/physical_constants.c b/src/physical_constants.c
index 8d1460b67a..06c53d4ea0 100644
--- a/src/physical_constants.c
+++ b/src/physical_constants.c
@@ -132,8 +132,7 @@ void phys_const_print(struct phys_const* internal_const) {
 void phys_const_struct_dump(const struct phys_const *internal_const,
                             FILE *stream) {
     restart_write_blocks((void *) internal_const, sizeof(struct phys_const),
-                         1, stream,
-                       "phys_const params");
+                         1, stream, "phys_const params");
 }
 
 
@@ -147,6 +146,5 @@ void phys_const_struct_dump(const struct phys_const *internal_const,
 void phys_const_struct_restore(const struct phys_const *internal_const,
                                FILE *stream) {
     restart_read_blocks((void *)internal_const, sizeof(struct phys_const),
-                        1, stream,
-                      "phys_const params");
+                        1, stream, "phys_const params");
 }
diff --git a/src/potential.c b/src/potential.c
index 94c2a6cc94..72950721f8 100644
--- a/src/potential.c
+++ b/src/potential.c
@@ -23,6 +23,7 @@
 
 /* This object's header. */
 #include "potential.h"
+#include "restart.h"
 
 /**
  * @brief Initialises the external potential properties in the internal system
@@ -51,3 +52,30 @@ void potential_print(const struct external_potential* potential) {
 
   potential_print_backend(potential);
 }
+
+
+/**
+ * @brief Write an external_potential struct to the given FILE as a stream of bytes.
+ *
+ * @param potential the struct
+ * @param stream the file stream
+ */
+void potential_struct_dump(const struct external_potential *potential,
+                           FILE *stream) {
+  restart_write_blocks((void *) potential, sizeof(struct external_potential),
+                       1, stream, "external potential");
+}
+
+
+/**
+ * @brief Restore a external_potential struct from the given FILE as a stream of
+ * bytes.
+ *
+ * @param p the struct
+ * @param stream the file stream
+ */
+void potential_struct_restore(const struct external_potential *potential,
+                              FILE *stream) {
+  restart_read_blocks((void *) potential, sizeof(struct external_potential),
+                      1, stream, "external potential");
+}
diff --git a/src/potential.h b/src/potential.h
index e6ab9a5bd6..b09c1417b7 100644
--- a/src/potential.h
+++ b/src/potential.h
@@ -50,4 +50,8 @@ void potential_init(const struct swift_params* parameter_file,
 
 void potential_print(const struct external_potential* potential);
 
+/* Dump/restore. */
+void potential_struct_dump(const struct external_potential* potential, FILE *stream);
+void potential_struct_restore(const struct external_potential* potential, FILE *stream);
+
 #endif /* SWIFT_POTENTIAL_H */
diff --git a/src/restart.c b/src/restart.c
index 0545410b8c..cf32e82f47 100644
--- a/src/restart.c
+++ b/src/restart.c
@@ -34,6 +34,7 @@
 
 #include "engine.h"
 #include "error.h"
+#include "restart.h"
 
 /**
  * @brief generate a name for a restart file.
@@ -131,7 +132,8 @@ void restart_read(struct engine *e, const char *filename) {
 }
 
 /* @brief Read blocks of memory from a file stream into a memory location.
- *        Exits the application if the read fails.
+ *        Exits the application if the read fails and does nothing
+ *        if the size is zero.
  *
  * @param ptr pointer to the memory
  * @param size size of a block
@@ -141,14 +143,17 @@ void restart_read(struct engine *e, const char *filename) {
  */
 void restart_read_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream,
                          const char *errstr) {
-  size_t nread = fread(ptr, size, nblocks, stream);
-  if (nread != nblocks)
-    error("Failed to restore %s from restart file (%s)", errstr,
-          ferror(stream) ? strerror(errno) : "unexpected end of file");
+  if (size > 0) {
+    size_t nread = fread(ptr, size, nblocks, stream);
+    if (nread != nblocks)
+      error("Failed to restore %s from restart file (%s)", errstr,
+            ferror(stream) ? strerror(errno) : "unexpected end of file");
+  }
 }
 
 /* @brief Write blocks of memory to a file stream from a memory location.
- *        Exits the application if the write fails.
+ *        Exits the application if the write fails and does nothing
+ *        if the size is zero.
  *
  * @param ptr pointer to the memory
  * @param size the blocks
@@ -158,7 +163,9 @@ void restart_read_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream,
  */
 void restart_write_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream,
                           const char *errstr) {
-  size_t nwrite = fwrite(ptr, size, nblocks, stream);
-  if (nwrite != nblocks)
-    error("Failed to save %s to restart file (%s)", errstr, strerror(errno));
+  if (size > 0) {
+    size_t nwrite = fwrite(ptr, size, nblocks, stream);
+    if (nwrite != nblocks)
+      error("Failed to save %s to restart file (%s)", errstr, strerror(errno));
+  }
 }
diff --git a/src/restart.h b/src/restart.h
index 124c5f425f..e75776eb99 100644
--- a/src/restart.h
+++ b/src/restart.h
@@ -21,7 +21,12 @@
 
 #include <stdio.h>
 
-#include "engine.h"
+struct engine;
+
+/* The signature for restart files. */
+#ifndef SWIFT_RESTART_SIGNATURE
+#define SWIFT_RESTART_SIGNATURE "SWIFT-restart-file"
+#endif
 
 void restart_write(struct engine *e, const char *filename);
 void restart_read(struct engine *e, const char *filename);
diff --git a/src/sourceterms.c b/src/sourceterms.c
index f12071cf91..8d438e8ffe 100644
--- a/src/sourceterms.c
+++ b/src/sourceterms.c
@@ -58,3 +58,29 @@ void sourceterms_print(struct sourceterms* source) {
   supernova_print(source);
 #endif /* SOURCETERMS_SN_FEEDBACK */
 };
+
+/**
+ * @brief Write a sourceterms struct to the given FILE as a stream of bytes.
+ *
+ * @param sourceterms the struct
+ * @param stream the file stream
+ */
+void sourceterms_struct_dump(const struct sourceterms *sourceterms,
+                             FILE *stream) {
+    restart_write_blocks((void *) sourceterms, sizeof(struct sourceterms),
+                         1, stream, "sourceterms");
+}
+
+
+/**
+ * @brief Restore a sourceterms struct from the given FILE as a stream of
+ * bytes.
+ *
+ * @param sourceterms the struct
+ * @param stream the file stream
+ */
+void sourceterms_struct_restore(const struct sourceterms *sourceterms,
+                                FILE *stream) {
+    restart_read_blocks((void *)sourceterms, sizeof(struct sourceterms),
+                        1, stream, "sourceterms");
+}
diff --git a/src/sourceterms.h b/src/sourceterms.h
index 1445bcb777..361c53be9a 100644
--- a/src/sourceterms.h
+++ b/src/sourceterms.h
@@ -45,6 +45,11 @@ void sourceterms_init(const struct swift_params* parameter_file,
                       struct unit_system* us, struct sourceterms* source);
 void sourceterms_print(struct sourceterms* source);
 
+/* Dump/restore. */
+void sourceterms_struct_dump(const struct sourceterms *source, FILE *stream);
+void sourceterms_struct_restore(const struct sourceterms *source, FILE *stream);
+
+
 /**
  * @brief Routines related to source terms
  * @param cell_min: corner of cell to test
diff --git a/src/space.c b/src/space.c
index 0680bb9310..a4fbd1f4ea 100644
--- a/src/space.c
+++ b/src/space.c
@@ -3317,4 +3317,8 @@ void space_struct_restore(struct space *s, FILE *stream) {
 
     restart_read_blocks(s->sparts, s->nr_sparts, sizeof(struct spart), stream, "sparts");
   }
+
+  /* XXX need to reconnect the gravity parts to their hydro and star particles. XXX */
+
+
 }
-- 
GitLab