Commit 493f4b49 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

* The last Christmas update

parent 5a1acd54
...@@ -32,6 +32,9 @@ namespace AMDiS { ...@@ -32,6 +32,9 @@ namespace AMDiS {
init(); init();
} }
DOFAdmin::~DOFAdmin()
{}
void DOFAdmin::init() void DOFAdmin::init()
{ {
firstHole = 0; firstHole = 0;
...@@ -336,10 +339,6 @@ namespace AMDiS { ...@@ -336,10 +339,6 @@ namespace AMDiS {
nr0DOF[i] = v; nr0DOF[i] = v;
} }
DOFAdmin::~DOFAdmin()
{
}
int DOFAdmin::calcMemoryUsage() int DOFAdmin::calcMemoryUsage()
{ {
return sizeof(DOFAdmin); return sizeof(DOFAdmin);
......
...@@ -74,7 +74,6 @@ namespace AMDiS { ...@@ -74,7 +74,6 @@ namespace AMDiS {
if (feSpace && feSpace->getAdmin()) { if (feSpace && feSpace->getAdmin()) {
(feSpace->getAdmin())->addDOFIndexed(this); (feSpace->getAdmin())->addDOFIndexed(this);
} }
this->boundaryManager = NEW BoundaryManager(f); this->boundaryManager = NEW BoundaryManager(f);
} }
......
...@@ -11,7 +11,8 @@ namespace AMDiS { ...@@ -11,7 +11,8 @@ namespace AMDiS {
FiniteElemSpace::FiniteElemSpace(DOFAdmin* admin_, FiniteElemSpace::FiniteElemSpace(DOFAdmin* admin_,
const BasisFunction* bas_fcts_, const BasisFunction* bas_fcts_,
Mesh* aMesh, const std::string& aString) Mesh* aMesh,
const std::string& aString)
: name(aString), : name(aString),
admin(admin_), admin(admin_),
basFcts(bas_fcts_), basFcts(bas_fcts_),
...@@ -47,12 +48,10 @@ namespace AMDiS { ...@@ -47,12 +48,10 @@ namespace AMDiS {
} }
FiniteElemSpace::FiniteElemSpace() FiniteElemSpace::FiniteElemSpace()
{ {}
}
FiniteElemSpace::~FiniteElemSpace() FiniteElemSpace::~FiniteElemSpace()
{ {}
}
FiniteElemSpace& FiniteElemSpace::operator=(const FiniteElemSpace& feSpace) FiniteElemSpace& FiniteElemSpace::operator=(const FiniteElemSpace& feSpace)
{ {
......
...@@ -71,37 +71,32 @@ namespace AMDiS { ...@@ -71,37 +71,32 @@ namespace AMDiS {
Mesh *mesh, Mesh *mesh,
const std::string& name_ = ""); const std::string& name_ = "");
/** \brief /// Destructor.
* destructor
*/
~FiniteElemSpace(); ~FiniteElemSpace();
FiniteElemSpace& operator=(const FiniteElemSpace& feSpace); FiniteElemSpace& operator=(const FiniteElemSpace& feSpace);
/** \brief /// Returns \ref name.
* Returns \ref name
*/
inline std::string getName() const { inline std::string getName() const {
return name; return name;
} }
/** \brief /// Returns \ref admin.
* Returns \ref admin
*/
inline DOFAdmin* getAdmin() const { inline DOFAdmin* getAdmin() const {
return admin; return admin;
} }
/** \brief /// Set a new DOF admin.
* Returns \ref basFcts inline void setAdmin(DOFAdmin* a) {
*/ admin = a;
}
/// Returns \ref basFcts
inline const BasisFunction* getBasisFcts() const { inline const BasisFunction* getBasisFcts() const {
return basFcts; return basFcts;
} }
/** \brief /// Returns \ref mesh
* Returns \ref mesh
*/
inline Mesh* getMesh() const { inline Mesh* getMesh() const {
return mesh; return mesh;
} }
......
...@@ -41,15 +41,15 @@ namespace AMDiS { ...@@ -41,15 +41,15 @@ namespace AMDiS {
problem_(problem), problem_(problem),
tsModulo_(1), tsModulo_(1),
timestepNumber_(-1) timestepNumber_(-1)
{ {
GET_PARAMETER(0, problem_->getName() + "->output->serialization filename", GET_PARAMETER(0, problem_->getName() + "->output->serialization filename",
&name_); &name_);
GET_PARAMETER(0, problem_->getName() + "->output->write every i-th timestep", GET_PARAMETER(0, problem_->getName() + "->output->write every i-th timestep",
"%d", &tsModulo_); "%d", &tsModulo_);
TEST_EXIT(name_ != "")("no filename\n"); TEST_EXIT(name_ != "")("no filename\n");
}; }
virtual ~Serializer() {}; virtual ~Serializer() {}
virtual void writeFiles(AdaptInfo *adaptInfo, virtual void writeFiles(AdaptInfo *adaptInfo,
bool force, bool force,
...@@ -73,13 +73,13 @@ namespace AMDiS { ...@@ -73,13 +73,13 @@ namespace AMDiS {
out.close(); out.close();
MSG("problem serialized to %s \n", name_.c_str()); MSG("problem serialized to %s \n", name_.c_str());
}; }
void writeDelayedFiles() {}; void writeDelayedFiles() {}
bool isWritingDelayed() { bool isWritingDelayed() {
return false; return false;
}; }
protected: protected:
/** \brief /** \brief
...@@ -108,28 +108,27 @@ namespace AMDiS { ...@@ -108,28 +108,27 @@ namespace AMDiS {
public: public:
static void serializeInt(std::ostream &out, int* ptrInt) { static void serializeInt(std::ostream &out, int* ptrInt) {
out.write(reinterpret_cast<const char*>(ptrInt), sizeof(int)); out.write(reinterpret_cast<const char*>(ptrInt), sizeof(int));
}; }
static void serializeDouble(std::ostream &out, double* ptrInt) { static void serializeDouble(std::ostream &out, double* ptrInt) {
out.write(reinterpret_cast<const char*>(ptrInt), sizeof(double)); out.write(reinterpret_cast<const char*>(ptrInt), sizeof(double));
}; }
static void serializeBool(std::ostream &out, bool* ptrBool) { static void serializeBool(std::ostream &out, bool* ptrBool) {
out.write(reinterpret_cast<const char*>(ptrBool), sizeof(bool)); out.write(reinterpret_cast<const char*>(ptrBool), sizeof(bool));
} }
static void deserializeInt(std::istream &in, int* ptrInt) { static void deserializeInt(std::istream &in, int* ptrInt) {
in.read(reinterpret_cast<char*>(ptrInt), sizeof(int)); in.read(reinterpret_cast<char*>(ptrInt), sizeof(int));
}; }
static void deserializeDouble(std::istream &in, double* ptrInt) { static void deserializeDouble(std::istream &in, double* ptrInt) {
in.read(reinterpret_cast<char*>(ptrInt), sizeof(double)); in.read(reinterpret_cast<char*>(ptrInt), sizeof(double));
}; }
static void deserializeBool(std::istream &in, bool* ptrBool) { static void deserializeBool(std::istream &in, bool* ptrBool) {
in.read(reinterpret_cast<char*>(ptrBool), sizeof(bool)); in.read(reinterpret_cast<char*>(ptrBool), sizeof(bool));
}; }
}; };
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define AMDIS_SOLUTION_DATA_STORAGE_H #define AMDIS_SOLUTION_DATA_STORAGE_H
#include <iostream> #include <iostream>
#include <fstream>
#include <vector> #include <vector>
#include <map> #include <map>
#include "DOFVector.h" #include "DOFVector.h"
...@@ -23,107 +24,320 @@ namespace AMDiS { ...@@ -23,107 +24,320 @@ namespace AMDiS {
}; };
class DataContainer
{
public:
};
/** \brief
* Class to store solution data for one timestep.
*
* Within this class, the solution data for one timestep is stored. The
* type of the solution data is the typename of the class, i.e., either
* DOFVector or SystemVector. The class is resonsible for serialization
* and deserialization of the solution.
*
* The class is used only from class \ref SolutionDataStorage, and must
* not be used by the user in other context.
*/
template<typename T> template<typename T>
class SolutionDataStorage class SolutionData
{ {
public: public:
/** \brief
* The constructor requires already the data. So no empty data class
* can be created.
*/
SolutionData(T* sol,
typename SolutionHelper<T>::type fes,
double ts,
int i)
: solution(sol),
feSpace(fes),
timestamp(ts),
id(i),
serialized(false),
filename("")
{}
/** \brief /** \brief
* * The destructor either deletes the data files or deletes the pointers
* to the data.
*/ */
SolutionDataStorage(std::string name); ~SolutionData()
{
if (!serialized) {
DELETE solution;
deleteFeSpace(feSpace);
}
}
/// Serialize the data to a file.
void serialize(std::string fn)
{
std::ofstream out(fn.c_str());
serializeFeSpace(out, feSpace);
solution->serialize(out);
out.close();
serialized = true;
filename = fn;
DELETE solution;
deleteFeSpace(feSpace);
}
/// Deserialize the data from file.
void deserialize()
{
std::string feName = "";
int dim = 0;
int degree = 0;
std::ifstream in(filename.c_str());
deserializeFeSpace(in, feSpace);
solution = new T("", feSpace, 0);
solution->deserialize(in);
in.close();
serialized = false;
filename = "";
}
/** \brief /** \brief
* Returns the data. In the case the data was serialized to the disk,
* it will be first deserialized from the corresponding file.
*/
void getData(T** ptrSolution, double *ptrTimestamp)
{
if (serialized) {
deserialize();
}
*ptrSolution = solution;
*ptrTimestamp = timestamp;
}
/// Returns \ref serialized.
bool isSerialized() {
return serialized;
}
protected:
/// Serialize a fe space to a file.
void serializeFeSpace(std::ofstream &out, FiniteElemSpace* fe)
{
// Write the mesh to file.
out << fe->getMesh()->getName() << "\n";
int dim = fe->getMesh()->getDim();
out.write(reinterpret_cast<const char*>(&dim), sizeof(int));
fe->getMesh()->serialize(out);
// Then, write all other fe space data to file.
dim = fe->getBasisFcts()->getDim();
int degree = fe->getBasisFcts()->getDegree();
out << ((fe->getName() != "") ? fe->getName() : "noname") << "\n";
out.write(reinterpret_cast<const char*>(&dim), sizeof(int));
out.write(reinterpret_cast<const char*>(&degree), sizeof(int));
}
/** \brief
* Serialize a vector of fe spaces to a file.
* *
* Takes special care about multiple fe space pointers, pointing to the
* same fe space. In this case, only the first fe space is serialized
* completely.
*/ */
~SolutionDataStorage(); void serializeFeSpace(std::ofstream &out, std::vector<FiniteElemSpace*>& fe)
{
int size = fe.size();
out.write(reinterpret_cast<const char*>(&size), sizeof(int));
for (int i = 0; i < size; i++) {
// Check, if the pointer points to an fe space serialized before.
int found = -1;
for (int j = 0; j < i; j++) {
if (fe[j] == fe[i]) {
found = j;
break;
}
}
out.write(reinterpret_cast<const char*>(&found), sizeof(int));
// Only in case this fe space was not serialized before, write it to the file.
if (found == -1) {
serializeFeSpace(out, fe[i]);
}
}
}
void deserializeFeSpace(std::ifstream &in, FiniteElemSpace** fe)
{
std::string name = "";
int dim = 0;
int degree = 0;
in >> name;
in.get();
in.read(reinterpret_cast<char*>(&dim), sizeof(int));
Mesh *mesh = new Mesh(name, dim);
mesh->deserialize(in);
in >> name;
in.get();
in.read(reinterpret_cast<char*>(&dim), sizeof(int));
in.read(reinterpret_cast<char*>(&degree), sizeof(int));
*fe = FiniteElemSpace::provideFESpace(NULL,
Lagrange::getLagrange(dim, degree),
mesh,
name);
(*fe)->setAdmin(const_cast<DOFAdmin*>(&(mesh->getDOFAdmin(0))));
}
void deserializeFeSpace(std::ifstream &in, std::vector<FiniteElemSpace*>& fe)
{
int size;
in.read(reinterpret_cast<char*>(&size), sizeof(int));
fe.resize(size);
for (int i = 0; i < size; i++) {
int found;
in.read(reinterpret_cast<char*>(&found), sizeof(int));
if (found == -1) {
deserializeFeSpace(in, &(fe[i]));
} else {
fe[i] = fe[found];
}
}
}
/// Remove one fe space from memory.
void deleteFeSpace(FiniteElemSpace* fe)
{
if (fe) {
DELETE fe->getMesh();
DELETE fe;
fe = NULL;
}
}
/// Remove a vector of fe spaces from memory.
void deleteFeSpace(std::vector<FiniteElemSpace*>& fe)
{
// Stores all pointers to fe spaces, that were deleted. This should
// avoid double deletion of pointer.
std::map<FiniteElemSpace*, bool> deletedFeSpaces;
for (int i = 0; i < static_cast<int>(fe.size()); i++) {
if (deletedFeSpaces.find(fe[i]) == deletedFeSpaces.end()) {
deleteFeSpace(fe[i]);
deletedFeSpaces[fe[i]] = true;
}
}
fe.clear();
}
public:
/** \brief /** \brief
* Set one fix FE Space. All solutions are defined only on the given FE Space. * Here, all the solutions (i.e. either DOFVectors or SystemVectors)
* are stored.
*/ */
void setFixFESpace(typename SolutionHelper<T>::type feSpace); T* solution;
/** \brief /** \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.
*/ */
void push(T *solution, typename SolutionHelper<T>::type feSpace;
double timestamp);
/** \brief /** \brief
* * Stores to every solutions the timestamp at which the solution was
* created in the adaption loop.
*/
double timestamp;
/** \brief
* If true, the solution data is serialied to disk and the pointers
* are not valid.
*/
bool serialized;
/// If solution data is serialied, here the corresponding filename is stored.
std::string filename;
int id;
};
/** \brief
* Storage for solution datas with optimization process.
*
* This class may be used to store solutions within an optimization process.
* Within the forward step, solutions are stored within this data storage, and
* are then used within the backward step. The storage supports serialization
* and deserialization of solutions (and the corresponding fe spaces) to save
* memory.
*
* The template typename must be the type of the solution data to be stored, i.e,
* either DOFVector<double> or SystemVector.
*/
template<typename T>
class SolutionDataStorage
{
public:
/** \brief
* Constructor. The parameter is a string that will be used to search for
* parameters of the storage within the init file.
*/ */
bool pop(T **solution, SolutionDataStorage(std::string name);
double *timestep);
/** \brief /** \brief
* Deletes all pointers and empties all internal vectors. * Destructor. Deletes all stored solutions and deletes all serialized files.
*/ */
~SolutionDataStorage();
/// Add a solution and its timestamp to the storage.
void push(T *solution, double timestamp);
/// Get solution data from storage. Returns true, if solution data is valid.
bool pop(T **solution, double *timestep);
/// Delete all pointers and empties all internal vectors.
void clear(); void clear();
/** \brief /** \brief
* Returns for a given solution number the corresponding fe Space. If the * Return for a given solution number the corresponding fe Space. If the
* the fe Space is fixed, the fe Space for all solutions is stored at * the fe Space is fixed, the fe Space for all solutions is stored at
* position 0. * position 0.
*/ */
typename SolutionHelper<T>::type getFeSpace(int i = 0) { typename SolutionHelper<T>::type getFeSpace(int i = 0) {
return feSpaces[i]; return solutions[i]->feSpace;
} }
/** \brief /// Returns \ref poped.
*
*/
bool isPoped() { bool isPoped() {
return poped; return poped;
} }
/** \brief /// Add a new container to the storage.
*
*/
void addContainer(std::string name); void addContainer(std::string name);
/** \brief /// Add value to a container.