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

* The last Christmas update

parent 5a1acd54
......@@ -32,6 +32,9 @@ namespace AMDiS {
init();
}
DOFAdmin::~DOFAdmin()
{}
void DOFAdmin::init()
{
firstHole = 0;
......@@ -336,10 +339,6 @@ namespace AMDiS {
nr0DOF[i] = v;
}
DOFAdmin::~DOFAdmin()
{
}
int DOFAdmin::calcMemoryUsage()
{
return sizeof(DOFAdmin);
......
......@@ -74,7 +74,6 @@ namespace AMDiS {
if (feSpace && feSpace->getAdmin()) {
(feSpace->getAdmin())->addDOFIndexed(this);
}
this->boundaryManager = NEW BoundaryManager(f);
}
......
......@@ -11,7 +11,8 @@ namespace AMDiS {
FiniteElemSpace::FiniteElemSpace(DOFAdmin* admin_,
const BasisFunction* bas_fcts_,
Mesh* aMesh, const std::string& aString)
Mesh* aMesh,
const std::string& aString)
: name(aString),
admin(admin_),
basFcts(bas_fcts_),
......@@ -47,12 +48,10 @@ namespace AMDiS {
}
FiniteElemSpace::FiniteElemSpace()
{
}
{}
FiniteElemSpace::~FiniteElemSpace()
{
}
{}
FiniteElemSpace& FiniteElemSpace::operator=(const FiniteElemSpace& feSpace)
{
......
......@@ -71,37 +71,32 @@ namespace AMDiS {
Mesh *mesh,
const std::string& name_ = "");
/** \brief
* destructor
*/
/// Destructor.
~FiniteElemSpace();
FiniteElemSpace& operator=(const FiniteElemSpace& feSpace);
/** \brief
* Returns \ref name
*/
/// Returns \ref name.
inline std::string getName() const {
return name;
}
/** \brief
* Returns \ref admin
*/
/// Returns \ref admin.
inline DOFAdmin* getAdmin() const {
return admin;
}
/** \brief
* Returns \ref basFcts
*/
/// Set a new DOF admin.
inline void setAdmin(DOFAdmin* a) {
admin = a;
}
/// Returns \ref basFcts
inline const BasisFunction* getBasisFcts() const {
return basFcts;
}
/** \brief
* Returns \ref mesh
*/
/// Returns \ref mesh
inline Mesh* getMesh() const {
return mesh;
}
......
......@@ -41,15 +41,15 @@ namespace AMDiS {
problem_(problem),
tsModulo_(1),
timestepNumber_(-1)
{
{
GET_PARAMETER(0, problem_->getName() + "->output->serialization filename",
&name_);
GET_PARAMETER(0, problem_->getName() + "->output->write every i-th timestep",
"%d", &tsModulo_);
TEST_EXIT(name_ != "")("no filename\n");
};
}
virtual ~Serializer() {};
virtual ~Serializer() {}
virtual void writeFiles(AdaptInfo *adaptInfo,
bool force,
......@@ -73,13 +73,13 @@ namespace AMDiS {
out.close();
MSG("problem serialized to %s \n", name_.c_str());
};
}
void writeDelayedFiles() {};
void writeDelayedFiles() {}
bool isWritingDelayed() {
return false;
};
}
protected:
/** \brief
......@@ -108,28 +108,27 @@ namespace AMDiS {
public:
static void serializeInt(std::ostream &out, int* ptrInt) {
out.write(reinterpret_cast<const char*>(ptrInt), sizeof(int));
};
}
static void serializeDouble(std::ostream &out, double* ptrInt) {
out.write(reinterpret_cast<const char*>(ptrInt), sizeof(double));
};
}
static void serializeBool(std::ostream &out, bool* ptrBool) {
out.write(reinterpret_cast<const char*>(ptrBool), sizeof(bool));
}
static void deserializeInt(std::istream &in, int* ptrInt) {
in.read(reinterpret_cast<char*>(ptrInt), sizeof(int));
};
}
static void deserializeDouble(std::istream &in, double* ptrInt) {
in.read(reinterpret_cast<char*>(ptrInt), sizeof(double));
};
}
static void deserializeBool(std::istream &in, bool* ptrBool) {
in.read(reinterpret_cast<char*>(ptrBool), sizeof(bool));
};
}
};
}
......
......@@ -2,6 +2,7 @@
#define AMDIS_SOLUTION_DATA_STORAGE_H
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include "DOFVector.h"
......@@ -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>
class SolutionDataStorage
class SolutionData
{
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
*
* 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
* 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
* 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
*
* 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,
double timestamp);
typename SolutionHelper<T>::type feSpace;
/** \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,
double *timestep);
SolutionDataStorage(std::string name);
/** \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();
/** \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
* position 0.
*/
typename SolutionHelper<T>::type getFeSpace(int i = 0) {
return feSpaces[i];
return solutions[i]->feSpace;
}
/** \brief
*
*/
/// Returns \ref poped.
bool isPoped() {
return poped;
}
/** \brief
*
*/
/// Add a new container to the storage.
void addContainer(std::string name);
/** \brief
*
*/
/// Add value to a container.
void push(std::string name, WorldVector<double> value);
/** \brief
*
*/
/// Get value from a container.
void pop(std::string name, WorldVector<double> &value);
/** \brief
*
*/
/// Reset, , a container/
void reset(std::string name);
/** \brief
*
*/
/// Clear, i.e. delete all values, a container.
void clear(std::string name);
protected:
/** \brief
* Deletes the fe space and all it content, i.e., also the dof admin,
* mesh, etc.
*/
void deleteFeSpace(FiniteElemSpace* feSpace);
/** \brief
* Deletes a list of fe spaces.
*/
void deleteFeSpace(std::vector<FiniteElemSpace*> feSpaces) {
for (int i = 0; i < static_cast<int>(feSpaces.size()); i++) {
deleteFeSpace(feSpaces[i]);
}
feSpaces.clear();
}
/** \brief
*
*/
......@@ -161,30 +375,6 @@ namespace AMDiS {
*/
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
* Position of the latest valid solution.
*/
......@@ -200,6 +390,12 @@ namespace AMDiS {
*/
int memoryUsage;
/** \brief
* Storage for the solutions, i.e., the DOFVector, the FESpace and the
* corresponding timestep.
*/
std::vector<SolutionData<T>* > solutions;
/** \brief
*
*/
......@@ -209,6 +405,8 @@ namespace AMDiS {
*
*/
std::map<std::string, int> containersPos;
int idcounter;
};
}
......
#include <iostream>
#include <sstream>
namespace AMDiS {
template<typename T>
......@@ -5,14 +8,12 @@ namespace AMDiS {
: maxMemoryUsage(100),
useDisk(true),
writeDirectory(""),
fixedFESpace(false),
lastPos(-1),
poped(false),
memoryUsage(0)
memoryUsage(0),
idcounter(0)
{
solutions.empty();