From 929d43339137a4c1a1653e4c7753ea7b87c83874 Mon Sep 17 00:00:00 2001
From: Thomas Witkowski <thomas.witkowski@gmx.de>
Date: Mon, 29 Sep 2008 11:28:02 +0000
Subject: [PATCH] * First version of SolutionDataStorage

---
 AMDiS/bin/Makefile.am            |   1 +
 AMDiS/bin/Makefile.in            |   4 +-
 AMDiS/src/AMDiS.h                |   1 +
 AMDiS/src/SolutionDataStorage.h  | 117 +++++++++++++++++++++++++++++++
 AMDiS/src/SolutionDataStorage.hh | 115 ++++++++++++++++++++++++++++++
 5 files changed, 237 insertions(+), 1 deletion(-)
 create mode 100644 AMDiS/src/SolutionDataStorage.h
 create mode 100644 AMDiS/src/SolutionDataStorage.hh

diff --git a/AMDiS/bin/Makefile.am b/AMDiS/bin/Makefile.am
index f68e1e49..db4664cc 100644
--- a/AMDiS/bin/Makefile.am
+++ b/AMDiS/bin/Makefile.am
@@ -230,6 +230,7 @@ $(SOURCE_DIR)/PeriodicInfo.h \
 $(SOURCE_DIR)/OpenMP.h \
 $(SOURCE_DIR)/ScalableQuadrature.h $(SOURCE_DIR)/ScalableQuadrature.cc \
 $(SOURCE_DIR)/SubElInfo.h $(SOURCE_DIR)/SubElInfo.cc \
+$(SOURCE_DIR)/SolutionDataStorage.h $(SOURCE_DIR)/SolutionDataStorage.hh \
 $(SOURCE_DIR)/parareal/ProblemBase.h \
 $(SOURCE_DIR)/parareal/AdaptParaReal.h $(SOURCE_DIR)/parareal/AdaptParaReal.cc
 
diff --git a/AMDiS/bin/Makefile.in b/AMDiS/bin/Makefile.in
index 4d8fb491..36ffced9 100644
--- a/AMDiS/bin/Makefile.in
+++ b/AMDiS/bin/Makefile.in
@@ -248,7 +248,8 @@ am__libamdis_la_SOURCES_DIST = $(PARALLEL_DIR)/ConditionalEstimator.h \
 	$(SOURCE_DIR)/VertexInfo.h $(SOURCE_DIR)/PeriodicInfo.h \
 	$(SOURCE_DIR)/OpenMP.h $(SOURCE_DIR)/ScalableQuadrature.h \
 	$(SOURCE_DIR)/ScalableQuadrature.cc $(SOURCE_DIR)/SubElInfo.h \
-	$(SOURCE_DIR)/SubElInfo.cc \
+	$(SOURCE_DIR)/SubElInfo.cc $(SOURCE_DIR)/SolutionDataStorage.h \
+	$(SOURCE_DIR)/SolutionDataStorage.hh \
 	$(SOURCE_DIR)/parareal/ProblemBase.h \
 	$(SOURCE_DIR)/parareal/AdaptParaReal.h \
 	$(SOURCE_DIR)/parareal/AdaptParaReal.cc
@@ -672,6 +673,7 @@ $(SOURCE_DIR)/PeriodicInfo.h \
 $(SOURCE_DIR)/OpenMP.h \
 $(SOURCE_DIR)/ScalableQuadrature.h $(SOURCE_DIR)/ScalableQuadrature.cc \
 $(SOURCE_DIR)/SubElInfo.h $(SOURCE_DIR)/SubElInfo.cc \
+$(SOURCE_DIR)/SolutionDataStorage.h $(SOURCE_DIR)/SolutionDataStorage.hh \
 $(SOURCE_DIR)/parareal/ProblemBase.h \
 $(SOURCE_DIR)/parareal/AdaptParaReal.h $(SOURCE_DIR)/parareal/AdaptParaReal.cc
 
diff --git a/AMDiS/src/AMDiS.h b/AMDiS/src/AMDiS.h
index 0b08c511..a8ce1710 100644
--- a/AMDiS/src/AMDiS.h
+++ b/AMDiS/src/AMDiS.h
@@ -85,6 +85,7 @@
 #include "RefinementManager2d.h"
 #include "RefinementManager3d.h"
 #include "RobinBC.h"
+#include "SolutionDataStorage.h"
 #include "SurfaceOperator.h"
 #include "SurfaceQuadrature.h"
 #include "SystemVector.h"
diff --git a/AMDiS/src/SolutionDataStorage.h b/AMDiS/src/SolutionDataStorage.h
new file mode 100644
index 00000000..5d5ff0ea
--- /dev/null
+++ b/AMDiS/src/SolutionDataStorage.h
@@ -0,0 +1,117 @@
+#ifndef AMDIS_SOLUTION_DATA_STORAGE_H
+#define AMDIS_SOLUTION_DATA_STORAGE_H
+
+#include <iostream>
+#include <vector>
+#include "DOFVector.h"
+#include "SystemVector.h"
+#include "Parameters.h"
+
+namespace AMDiS {
+
+  template<typename T>
+  struct SolutionHelper
+  {
+    typedef FiniteElemSpace* type;
+  };
+
+  template <>
+  struct SolutionHelper<SystemVector>
+  {
+    typedef std::vector<FiniteElemSpace*> type;
+  };
+  
+  template<typename T>
+  class SolutionDataStorage 
+  {
+  public:
+    SolutionDataStorage(std::string name);
+
+    ~SolutionDataStorage();
+
+    /** \brief
+     * Set one fix FE Space. All solutions are defined only on the given FE Space.     
+     */
+    void setFixFESpace(typename SolutionHelper<T>::type feSpace,
+		       bool cleanupFeSpace = false);
+
+    void push(T *solution,
+	      double timestamp,
+	      FiniteElemSpace *feSpace = NULL,
+	      bool cleanupSolution = true,
+	      bool cleanupFeSpace = true);
+
+    bool pop(T *solution,
+	     double *timestep,
+	     FiniteElemSpace *feSpace = NULL);
+
+  protected:
+    void cleanup();
+
+    /** \brief
+     * Number of MBytes of memory that can be used for solution storage.
+     */
+    int maxMemoryUsage;
+
+    /** \brief
+     * If true, it is allowed to write solutions also to disk.
+     */
+    bool useDisk;
+
+    /** \brief
+     * Directory, where solutions can be written temporarly.
+     */
+    std::string writeDirectory;
+
+    /** \brief
+     * If true, all solutions are defined only on one FE Space.
+     */
+    bool fixedFESpace;
+
+    /** \brief
+     * Here, all the solutions (i.e. either DOFVectors or SystemVectors)
+     * are stored.
+     */
+    std::vector<T> solutions;
+
+    /** \brief
+     * Stores to every solution its FE Space. If \ref fixedFESpace is set
+     * to true, only one entry exists. This is than the FE Space for all
+     * solutions.
+     */
+    std::vector< typename SolutionHelper<T>::type > feSpaces;
+
+    /** \brief
+     * Stores to every solutions the timestamp at which the solution was
+     * created in the adaption loop.
+     */
+    std::vector<double> timestamps;
+
+    /** \brief
+     * Stores to each solution, if the data storage is allowed to delete 
+     * the solution by itself.
+     */
+    std::vector<bool> cleanupSolutions;
+
+    /** \brief
+     * Stores to each fe space, if the data storage is allowed to delete
+     * the fe space by itself.
+     */
+    std::vector<bool> cleanupFeSpaces;
+
+    /** \brief
+     * Position of the latest valid solution.
+     */
+    int lastPos;
+
+    /** \brief
+     * If true, the last operation on the data storage was pop.
+     */
+    bool poped;
+  };
+
+}
+
+#include "SolutionDataStorage.hh"
+
+#endif // AMDIS_SOLUTION_DATA_STORAGE_H
diff --git a/AMDiS/src/SolutionDataStorage.hh b/AMDiS/src/SolutionDataStorage.hh
new file mode 100644
index 00000000..7472667c
--- /dev/null
+++ b/AMDiS/src/SolutionDataStorage.hh
@@ -0,0 +1,115 @@
+namespace AMDiS {
+
+  template<typename T>
+  SolutionDataStorage<T>::SolutionDataStorage(std::string name)
+    : maxMemoryUsage(100),
+      useDisk(true),
+      writeDirectory(""),
+      fixedFESpace(false),
+      lastPos(-1),
+      poped(false)
+  {
+    solutions.empty();
+    feSpaces.empty();
+    timestamps.empty();
+    cleanupSolutions.empty();
+    cleanupFeSpaces.empty();
+    
+    int tmp = 0;
+    GET_PARAMETER(0, name + "->memory usage", "%d", &maxMemoryUsage);
+    GET_PARAMETER(0, name + "->use disk", "%d", &tmp);
+    useDisk = (tmp == 0) ? false : true;
+    GET_PARAMETER(0, name + "->directory", &writeDirectory);
+  }
+
+  template<typename T>
+  SolutionDataStorage<T>::~SolutionDataStorage()
+  {
+    cleanup();
+  }
+
+  template<typename T>
+  void SolutionDataStorage<T>::setFixFESpace(typename SolutionHelper<T>::type feSpace,
+					     bool cleanupFeSpace)
+  {
+    FUNCNAME("SolutionDataStorage::setFixFESpace()");
+
+    TEST_EXIT(solutions.size() == 0)("Cannot set FE Space, if solutions already stored!\n");
+
+    fixedFESpace = true;
+    feSpaces.push_back(feSpace);
+    cleanupFeSpaces.push_back(cleanupFeSpace);
+  }
+
+  template<typename T>
+  void SolutionDataStorage<T>::push(T *solution,
+				    double timestamp,
+				    FiniteElemSpace *feSpace,
+				    bool cleanupSolution,
+				    bool cleanupFeSpace)
+  {
+    // If pop was the last operation, cleanup and reset the data storage.
+    if (poped) {
+      cleanup();
+      poped = false;
+    }
+
+    solutions.push_back(solution);
+    timestamps.push_back(timestamp);
+    cleanupSolutions.push_back(cleanupSolution);
+
+    // Store fe space only, if we do not have a fixed fe space.
+    if (!fixedFESpace) {
+      feSpaces.push_back(feSpace);
+      cleanupFeSpaces.push_back(cleanupFeSpace);
+    }
+
+    lastPos++;
+  }
+
+  template<typename T>
+  bool SolutionDataStorage<T>::pop(T *solution,
+				   double *timestamp,
+				   FiniteElemSpace *feSpace)
+  {
+    if (lastPos < 0) {
+      return false;
+    }
+
+    solution = solutions[lastPos];
+    *timestamp = timestamps[lastPos];
+    if (!fixedFESpace) {
+      feSpace = feSpaces[lastPos];
+    }
+
+    lastPos--;
+    poped = true;
+
+    return true;
+  }
+
+  template<typename T>
+  void SolutionDataStorage<T>::cleanup()
+  {
+    for (int i = 0; i < static_cast<int>(cleanupSolutions.size()); i++) {
+      if (cleanupSolutions[i]) {
+	DELETE solutions[i];
+      }
+    }
+
+    for (int i = 0; i < static_cast<int>(cleanupFeSpaces.size()); i++) {
+      if (cleanupFeSpaces[i]) {
+	DELETE feSpaces[i];
+      }
+    }
+
+    cleanupSolutions.empty();
+    cleanupFeSpaces.empty();
+    solutions.empty();
+    feSpaces.empty();
+    timestamps.empty();
+
+    lastPos = -1;
+  }
+  
+}
-- 
GitLab