Commit 7f6405c6 authored by Thomas Witkowski's avatar Thomas Witkowski

Added spreadsheet writer and reader.

parent 5e754b04
...@@ -162,6 +162,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc ...@@ -162,6 +162,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
${SOURCE_DIR}/io/PngReader.cc ${SOURCE_DIR}/io/PngReader.cc
${SOURCE_DIR}/io/PngWriter.cc ${SOURCE_DIR}/io/PngWriter.cc
${SOURCE_DIR}/io/PovrayWriter.cc ${SOURCE_DIR}/io/PovrayWriter.cc
${SOURCE_DIR}/io/Spreadsheet.cc
${SOURCE_DIR}/io/ValueReader.cc ${SOURCE_DIR}/io/ValueReader.cc
${SOURCE_DIR}/io/ValueWriter.cc ${SOURCE_DIR}/io/ValueWriter.cc
${SOURCE_DIR}/io/VtkWriter.cc ${SOURCE_DIR}/io/VtkWriter.cc
......
...@@ -122,6 +122,7 @@ ...@@ -122,6 +122,7 @@
#include "io/MacroWriter.h" #include "io/MacroWriter.h"
#include "io/PngWriter.h" #include "io/PngWriter.h"
#include "io/PovrayWriter.h" #include "io/PovrayWriter.h"
#include "io/Spreadsheet.h"
#include "io/ValueReader.h" #include "io/ValueReader.h"
#include "io/ValueWriter.h" #include "io/ValueWriter.h"
#include "io/VtkWriter.h" #include "io/VtkWriter.h"
......
...@@ -16,7 +16,9 @@ ...@@ -16,7 +16,9 @@
namespace AMDiS { namespace AMDiS {
void DofWriter::writeFile(std::string filename, std::vector<DOFVector<double>*> &vec) using namespace std;
void DofWriter::writeFile(string filename, vector<DOFVector<double>*> &vec)
{ {
FUNCNAME("DofWriter::writeFile()"); FUNCNAME("DofWriter::writeFile()");
...@@ -25,13 +27,14 @@ namespace AMDiS { ...@@ -25,13 +27,14 @@ namespace AMDiS {
Mesh *mesh = feSpace->getMesh(); Mesh *mesh = feSpace->getMesh();
const BasisFunction* basFcts = feSpace->getBasisFcts(); const BasisFunction* basFcts = feSpace->getBasisFcts();
int nBasFcts = basFcts->getNumber(); int nBasFcts = basFcts->getNumber();
std::vector<DegreeOfFreedom> dofVec(nBasFcts); vector<DegreeOfFreedom> dofVec(nBasFcts);
TraverseStack stack; TraverseStack stack;
ElInfo *elInfo = ElInfo *elInfo =
stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS); stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
while (elInfo) { while (elInfo) {
basFcts->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), dofVec); basFcts->getLocalIndices(elInfo->getElement(),
feSpace->getAdmin(), dofVec);
for (int i = 0; i < nBasFcts; i++) { for (int i = 0; i < nBasFcts; i++) {
DimVec<double> *baryCoords = basFcts->getCoords(i); DimVec<double> *baryCoords = basFcts->getCoords(i);
elInfo->coordToWorld(*baryCoords, coordDof[dofVec[i]]); elInfo->coordToWorld(*baryCoords, coordDof[dofVec[i]]);
...@@ -40,7 +43,7 @@ namespace AMDiS { ...@@ -40,7 +43,7 @@ namespace AMDiS {
elInfo = stack.traverseNext(elInfo); elInfo = stack.traverseNext(elInfo);
} }
std::ofstream outfile; ofstream outfile;
outfile.open(filename.c_str()); outfile.open(filename.c_str());
outfile.precision(10); outfile.precision(10);
...@@ -53,7 +56,7 @@ namespace AMDiS { ...@@ -53,7 +56,7 @@ namespace AMDiS {
for (unsigned int i = 0; i < vec.size(); i++) for (unsigned int i = 0; i < vec.size(); i++)
outfile << (*(vec[i]))[it.getDOFIndex()] << " "; outfile << (*(vec[i]))[it.getDOFIndex()] << " ";
outfile << std::endl; outfile << endl;
} }
outfile.close(); outfile.close();
......
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.
#include <algorithm>
#include <fstream>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include "Spreadsheet.h"
#include "Global.h"
namespace AMDiS {
using namespace std;
using namespace boost;
using boost::lexical_cast;
void Spreadsheet::write(string filename)
{
int nRows = static_cast<int>(data.size());
int maxDataLength = 0;
for (int i = 0; i < nRows; i++)
maxDataLength = std::max(maxDataLength, static_cast<int>(data[i].size()));
for (int i = 0; i < nRows; i++)
data[i].resize(maxDataLength, 0.0);
ofstream file;
file.open(filename.c_str());
for (int i = 0; i < nRows; i++) {
for (int j = 0; j < maxDataLength; j++) {
file << data[i][j];
if (j + 1 < maxDataLength)
file << " ";
else
file << "\n";
}
}
file.close();
}
void Spreadsheet::read(string filename)
{
data.clear();
string line;
vector<string> lineSplit;
ifstream file;
file.open(filename.c_str());
while (!file.eof()) {
getline(file, line);
split(lineSplit, line, is_any_of(" ,"));
if (lineSplit.size() == 0)
continue;
if ((lineSplit.size() == 1) && (lineSplit[0] == ""))
continue;
if (lineSplit[0].find("#") == 0)
continue;
vector<double> lineData(lineSplit.size());
for (unsigned int i = 0; i < lineSplit.size(); i++)
lineData[i] = lexical_cast<double>(lineSplit[i]);
data.push_back(lineData);
}
file.close();
}
}
// ============================================================================
// == ==
// == Amdis - Adaptive multidimensional simulations ==
// == ==
// == http://www.amdis-fem.org ==
// == ==
// ============================================================================
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.
/** \file Spreadsheet.h */
#ifndef AMDIS_SPREADSHEET_H
#define AMDIS_SPREADSHEET_H
#include <vector>
#include <string>
namespace AMDiS {
using namespace std;
/**
* \brief
* Implements basic support to read and write tables of data (all are
* assumed to be of type double. The files are written in ASCII mode and
* allow to use comments (lines that start with #).
*/
class Spreadsheet
{
public:
typedef vector<vector<double> > DataType;
Spreadsheet()
: data(0)
{}
void addData(vector<double> &d)
{
data.push_back(d);
}
void addData(DataType &d)
{
data.insert(data.end(), d.begin(), d.end());
}
void setData(DataType &d)
{
data = d;
}
DataType& getData()
{
return data;
}
void write(string filename);
void read(string filename);
protected:
DataType data;
};
}
#endif
...@@ -168,26 +168,11 @@ namespace AMDiS { ...@@ -168,26 +168,11 @@ namespace AMDiS {
return feSpaces; return feSpaces;
} }
/** \brief /// Returns the number of DOFs in rank's domain for a given FE space.
* Returns the number of DOFs in rank's domain for a given FE space. inline int getNumberRankDofs(const FiniteElemSpace *feSpace)
*
* \param[in] feSpace If the FE space is defined, the function returns
* the number of DOFs for this FE space. If this
* parameter is not specified, the function assumes
* that there is only one FE space and returns the
* number of DOFs for this one.
*/
inline int getNumberRankDofs(const FiniteElemSpace *feSpace = NULL)
{ {
FUNCNAME("MeshDistributor::getNumberRankDofs()"); FUNCNAME("MeshDistributor::getNumberRankDofs()");
if (feSpace == NULL) {
TEST_EXIT_DBG(dofFeData.size() == 1)
("More than one FE space defined!\n");
return dofFeData.begin()->second.nRankDofs;
}
TEST_EXIT_DBG(dofFeData.count(feSpace))("Should not happen!\n"); TEST_EXIT_DBG(dofFeData.count(feSpace))("Should not happen!\n");
return dofFeData[feSpace].nRankDofs; return dofFeData[feSpace].nRankDofs;
...@@ -232,26 +217,11 @@ namespace AMDiS { ...@@ -232,26 +217,11 @@ namespace AMDiS {
return result; return result;
} }
/** \brief /// Returns the global number of DOFs for a given FE space.
* Returns the global number of DOFs for a given FE space. inline int getNumberOverallDofs(const FiniteElemSpace *feSpace)
*
* \param[in] feSpace If the FE space is defined, the function returns
* the number of DOFs for this FE space. If this
* parameter is not specified, the function assumes
* that there is only one FE space and returns the
* number of DOFs for this one.
*/
inline int getNumberOverallDofs(const FiniteElemSpace *feSpace = NULL)
{ {
FUNCNAME("MeshDistributor::getNumberOverallDofs()"); FUNCNAME("MeshDistributor::getNumberOverallDofs()");
if (feSpace == NULL) {
TEST_EXIT_DBG(dofFeData.size() == 1)
("More than one FE space defined!\n");
return dofFeData.begin()->second.nOverallDofs;
}
TEST_EXIT_DBG(dofFeData.count(feSpace))("Should not happen!\n"); TEST_EXIT_DBG(dofFeData.count(feSpace))("Should not happen!\n");
return dofFeData[feSpace].nOverallDofs; return dofFeData[feSpace].nOverallDofs;
......
...@@ -228,8 +228,19 @@ namespace AMDiS { ...@@ -228,8 +228,19 @@ namespace AMDiS {
TEST_EXIT_DBG(meshLevel + 1 == meshDistributor->getMeshLevelData().getLevelNumber()) TEST_EXIT_DBG(meshLevel + 1 == meshDistributor->getMeshLevelData().getLevelNumber())
("Mesh hierarchy does not contain %d levels!\n", meshLevel + 1); ("Mesh hierarchy does not contain %d levels!\n", meshLevel + 1);
if (subDomainSolver == NULL) if (subDomainSolver == NULL) {
subDomainSolver = new SubDomainSolver(meshDistributor, mpiComm, mpiSelfComm); if (meshLevel == 0) {
subDomainSolver =
new SubDomainSolver(meshDistributor, mpiComm, mpiSelfComm);
} else {
MeshLevelData& levelData = meshDistributor->getMeshLevelData();
subDomainSolver =
new SubDomainSolver(meshDistributor,
levelData.getMpiComm(meshLevel - 1),
levelData.getMpiComm(meshLevel));
}
}
primalDofMap.init(mpiComm, feSpaces, meshDistributor->getFeSpaces(), primalDofMap.init(mpiComm, feSpaces, meshDistributor->getFeSpaces(),
true, true); true, true);
...@@ -375,10 +386,8 @@ namespace AMDiS { ...@@ -375,10 +386,8 @@ namespace AMDiS {
for (DofComm::Iterator it(meshDistributor->getSendDofs(), meshLevel, feSpace); for (DofComm::Iterator it(meshDistributor->getSendDofs(), meshLevel, feSpace);
!it.end(); it.nextRank()) !it.end(); it.nextRank())
for (; !it.endDofIter(); it.nextDof()) for (; !it.endDofIter(); it.nextDof())
if (!isPrimal(feSpace, it.getDofIndex())) { if (!isPrimal(feSpace, it.getDofIndex()))
MSG("SEND TO RANK %d\n", it.getRank());
stdMpi.getSendData(it.getRank()).push_back(boundaryDofRanks[feSpace][it.getDofIndex()]); stdMpi.getSendData(it.getRank()).push_back(boundaryDofRanks[feSpace][it.getDofIndex()]);
}
stdMpi.updateSendDataSize(); stdMpi.updateSendDataSize();
...@@ -388,7 +397,6 @@ namespace AMDiS { ...@@ -388,7 +397,6 @@ namespace AMDiS {
for (; !it.endDofIter(); it.nextDof()) { for (; !it.endDofIter(); it.nextDof()) {
if (!isPrimal(feSpace, it.getDofIndex())) { if (!isPrimal(feSpace, it.getDofIndex())) {
recvFromRank = true; recvFromRank = true;
MSG("RECV FROM RANK %d\n", it.getRank());
break; break;
} }
} }
......
...@@ -83,11 +83,21 @@ namespace AMDiS { ...@@ -83,11 +83,21 @@ namespace AMDiS {
return primalDofMap.getOverallDofs(); return primalDofMap.getOverallDofs();
} }
int getNumberOfRankPrimals()
{
return primalDofMap.getRankDofs();
}
int getNumberOfDuals() int getNumberOfDuals()
{ {
return dualDofMap.getOverallDofs(); return dualDofMap.getOverallDofs();
} }
int getNumberOfRankDuals()
{
return dualDofMap.getRankDofs();
}
protected: protected:
/// Defines which boundary nodes are primal. Creates global index of /// Defines which boundary nodes are primal. Creates global index of
/// the primal variables. /// the primal variables.
......
...@@ -36,6 +36,41 @@ BOOST_AUTO_TEST_CASE(amdis_mpi_feti) ...@@ -36,6 +36,41 @@ BOOST_AUTO_TEST_CASE(amdis_mpi_feti)
BOOST_REQUIRE(feti.getNumberOfPrimals() == 21); BOOST_REQUIRE(feti.getNumberOfPrimals() == 21);
BOOST_REQUIRE(feti.getNumberOfDuals() == 48); BOOST_REQUIRE(feti.getNumberOfDuals() == 48);
Spreadsheet sheet;
sheet.read("data/data0002a");
vector<double> data = sheet.getData()[MPI::COMM_WORLD.Get_rank()];
const FiniteElemSpace *feSpace = ellipt.getFeSpace(0);
vector<double> testData;
testData.push_back(feti.getNumberOfRankPrimals());
testData.push_back(feti.getNumberOfRankDuals());
testData.push_back(meshDist->getNumberRankDofs(feSpace));
testData.push_back(meshDist->getStartDofs(feSpace));
testData.push_back(meshDist->getNumberOverallDofs(feSpace));
BOOST_REQUIRE(data.size() - 1 == testData.size());
BOOST_REQUIRE(equal(data.begin() + 1, data.end(), testData.begin()));
ellipt.getRefinementManager()->globalRefine(mesh, 6);
meshDist->checkMeshChange();
feti.createFetiData();
sheet.read("data/data0002b");
data = sheet.getData()[MPI::COMM_WORLD.Get_rank()];
testData.clear();
testData.push_back(feti.getNumberOfRankPrimals());
testData.push_back(feti.getNumberOfRankDuals());
testData.push_back(meshDist->getNumberRankDofs(feSpace));
testData.push_back(meshDist->getStartDofs(feSpace));
testData.push_back(meshDist->getNumberOverallDofs(feSpace));
BOOST_REQUIRE(data.size() - 1 == testData.size());
BOOST_REQUIRE(equal(data.begin() + 1, data.end(), testData.begin()));
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment