Commit 624313f1 authored by Stenger, Florian's avatar Stenger, Florian
Browse files

Merge branch 'feature/lagrange_binary_etc' into 'master'

Feature/lagrange binary etc

See merge request spraetor/dune-gmsh4!1
parents 6c928b3d 11469f05
......@@ -4,8 +4,8 @@
#Name of the module
Module: dune-gmsh4
Version: 0.1
Version: 0.2
Maintainer: simon.praetorius@tu-dresden.de
#depending on
Depends: dune-grid
Suggests: dune-uggrid dune-alugrid
Suggests: dune-alugrid dune-foamgrid dune-vtk dune-curvedsurfacegrid
add_subdirectory(grid)
add_subdirectory(common)
\ No newline at end of file
add_subdirectory(gmsh4)
#include "filesystem.hh"
#ifdef _WIN32
#include <direct.h> // _mkdir
#define GET_CURRENT_DIR _getcwd
#else
#include <unistd.h>
#define GET_CURRENT_DIR getcwd
#endif
#include <errno.h> // errno, ENOENT, EEXIST
#include <stdio.h> // defines FILENAME_MAX
#include <sys/stat.h>
#include <sys/types.h>
#include <cctype>
#include <iostream>
#include <fstream>
#include <string>
template <class... Args>
void inline _ignore_(Args&&...) {}
namespace Dune { namespace Filesystem {
std::string Path::string() const
{
if (empty())
return ".";
auto it = begin();
auto result = *it;
for (++it; it != end(); ++it)
result += preferred_separator + *it;
return result;
}
void Path::split(std::string p)
{
std::string separators = "/\\";
bool relative = true;
trim(p);
Dune::split(p.begin(), p.end(), separators.begin(), separators.end(),
[this,&relative](auto first, auto end)
{
auto token = std::string(first, end);
if ((!token.empty() && token != "." && token != "..") || (token.empty() && this->empty())) {
this->push_back(token);
relative = false;
} else if (token == "..") {
if (relative || this->empty()) {
this->push_back(token);
}
else {
this->pop_back();
}
}
});
}
Path Path::stem() const
{
auto f = filename().string();
auto pos = f.find_last_of('.');
if (f == "." || f == ".." || pos == std::string::npos)
return {f};
else
return {f.substr(0,pos)};
}
Path Path::extension() const
{
auto f = filename().string();
auto pos = f.find_last_of('.');
if (f == "." || f == ".." || pos == std::string::npos)
return {};
else
return {f.substr(pos)};
}
bool Path::is_absolute(std::string p)
{
if (p[0] == '/')
return true;
// c:\ or z:/
if (std::isalpha(p[0]) && p[1] == ':' && (p[2] == '/' || p[2] == '\\'))
return true;
return false;
}
Path& Path::operator/=(Path const& p)
{
insert(end(), p.begin(), p.end());
original += preferred_separator + p.original;
return *this;
}
bool Path::is_file() const
{
std::string p = this->string();
struct stat info;
return stat(p.c_str(), &info) == 0 && (info.st_mode & S_IFREG) != 0;
}
bool Path::is_directory() const
{
std::string p = this->string();
struct stat info;
return stat(p.c_str(), &info) == 0 && (info.st_mode & S_IFDIR) != 0;
}
Path current_path()
{
char cwd_[FILENAME_MAX];
_ignore_(GET_CURRENT_DIR(cwd_, sizeof(cwd_)));
std::string cwd(cwd_);
return { trim(cwd) };
}
bool exists(Path const& p)
{
return p.is_file() || p.is_directory();
}
bool create_directories(Path const& p)
{
if (p.is_directory())
return true;
auto parent = p.parent_path();
if (!parent.empty() && !parent.is_directory())
create_directories(parent);
#ifdef _WIN32
int ret = _mkdir(p.string().c_str());
#else
mode_t mode = 0755;
int ret = mkdir(p.string().c_str(), mode);
#endif
if (ret == 0)
return true;
switch (errno)
{
case ENOENT:
std::cerr << "parent didn't exist. Should not happen, since parent directory created before!\n";
std::abort();
return false;
break;
case EEXIST:
return true;
break;
default:
return false;
}
}
Path relative(Path const& a, Path const& b)
{
// find common base path
auto a_it = a.begin();
auto b_it = b.begin();
for (; a_it != a.end() && b_it != b.end(); ++a_it, ++b_it) {
if (*a_it != *b_it)
break;
}
// combine remaining parts of a to result path
Path rel(".");
for (; a_it != a.end(); ++a_it)
rel /= *a_it;
return rel;
}
} } // end namespace Dune::Filesystem
#pragma once
#include <algorithm>
#include <cctype>
#include <locale>
#include <sstream>
#include <string>
namespace Dune
{
/// convert all characters in a string to upper case
inline std::string to_upper(std::string input)
{
for (auto& c : input)
c = toupper(c);
return input;
}
/// convert all characters in a string to upper case
inline std::string to_lower(std::string input)
{
for (auto& c : input)
c = tolower(c);
return input;
}
/// trim a string from the left
inline std::string& ltrim(std::string& str)
{
auto it = std::find_if(str.begin(), str.end(), [](char ch)
{
return !std::isspace<char>(ch, std::locale::classic());
});
str.erase(str.begin() , it);
return str;
}
/// trim a string from the right
inline std::string& rtrim(std::string& str)
{
auto it = std::find_if(str.rbegin(), str.rend(), [](char ch)
{
return !std::isspace<char>(ch, std::locale::classic());
});
str.erase(it.base(), str.end());
return str;
}
/// trim a string from both sides
inline std::string& trim(std::string& str)
{
return ltrim(rtrim(str));
}
/// trim a (copy of the) string from both sides
inline std::string trim_copy(std::string const& str)
{
auto s = str;
return trim(s);
}
template <class InputIter, class T, class Func>
void split(InputIter first, InputIter end, T const& t, Func f)
{
if (first == end)
return;
while (true) {
InputIter found = std::find(first, end, t);
f(first, found);
if (found == end)
break;
first = ++found;
}
}
template <class InputIter, class SeparatorIter, class Func>
void split(InputIter first, InputIter end, SeparatorIter s_first, SeparatorIter s_end, Func f)
{
if (first == end)
return;
while (true) {
InputIter found = std::find_first_of(first, end, s_first, s_end);
f(first, found);
if (found == end)
break;
first = ++found;
}
}
/// Replace all occurences of substring `from` with `to` in source `str`.
inline void replaceAll(std::string& str, std::string const& from, std::string const& to)
{
if (from.empty())
return;
std::size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos)
{
str.replace(start_pos, from.length(), to);
start_pos += to.length();
}
}
template <class InputIter>
std::string join (InputIter first, InputIter end, std::string sep = " ")
{
if (first == end)
return "";
std::ostringstream os;
os << *first++;
while (first != end)
os << sep << *first++;
return os.str();
}
} // end namspace Dune
dune_add_library("gmsh4types" OBJECT
types.cc)
#install headers
install(FILES
filereader.hh
forward.hh
reader.hh
reader.impl.hh
gridcreatorinterface.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/grid/io/file/gmsh4)
types.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/gmsh4)
add_subdirectory(gridcreators)
add_subdirectory(utility)
#pragma once
#include <memory>
#include <string>
#include <utility>
#include <dune/common/exceptions.hh>
#include <dune/grid/common/gridfactory.hh>
namespace Dune
{
namespace Gmsh4
{
template <class Grid, class FilerReaderImp>
class FileReader
{
private:
// type of underlying implementation, for internal use only
using Implementation = FilerReaderImp;
/// \brief An accessor class to call protected members of reader implementations.
struct Accessor : public Implementation
{
template <class... Args>
static std::unique_ptr<Grid> createGridFromFileImpl (Args&&... args)
{
return Implementation::createGridFromFileImpl(std::forward<Args>(args)...);
}
template <class... Args>
static void fillFactoryImpl (Args&&... args)
{
return Implementation::fillFactoryImpl(std::forward<Args>(args)...);
}
};
public:
/// Reads the grid from a file with filename and returns a unique_ptr to the created grid.
/// Redirects to concrete implementation of derivated class.
template <class... Args>
static std::unique_ptr<Grid> createGridFromFile (const std::string &filename, Args&&... args)
{
return Accessor::createGridFromFileImpl(filename, std::forward<Args>(args)...);
}
/// Reads the grid from a file with filename into a grid-factory.
/// Redirects to concrete implementation of derivated class.
template <class... Args>
static void fillFactory (GridFactory<Grid> &factory, const std::string &filename, Args&&... args)
{
Accessor::fillFactoryImpl(factory, filename, std::forward<Args>(args)...);
}
protected: // default implementations
// Default implementation, redirects to factory read implementation.
template <class... Args>
static std::unique_ptr<Grid> createGridFromFileImpl (const std::string &filename, Args&&... args)
{
GridFactory<Grid> factory;
fillFactory(factory, filename, std::forward<Args>(args)...);
return std::unique_ptr<Grid>{ factory.createGrid() };
}
// Default implementation for reading into grid-factory: produces a runtime-error.
template <class... Args>
static void fillFactoryImpl (GridFactory<Grid> &/*factory*/, const std::string &/*filename*/,
Args&&... /*args*/)
{
DUNE_THROW(NotImplemented,
"GridReader using a factory argument not implemented for concrete reader implementation.");
}
};
} // end namespace Gmsh4
} // end namespace Dune
......@@ -4,7 +4,7 @@
namespace Dune
{
namespace Gmsh
namespace Gmsh4
{
template <class Grid, class Derived>
class GridCreatorInterface;
......@@ -19,6 +19,9 @@ namespace Dune
template <class Grid>
struct DiscontinuousGridCreator;
template <class Grid>
struct LagrangeGridCreator;
template <class Grid>
struct ParallelGridCreator;
......@@ -26,9 +29,9 @@ namespace Dune
struct SerialGridCreator;
// @} gridcreators
} // end namespace Gmsh
} // end namespace Gmsh4
template <class Grid, class GridCreator = Gmsh::ContinuousGridCreator<Grid>, class size_type = std::size_t>
template <class Grid, class GridCreator = Gmsh4::ContinuousGridCreator<Grid>, class size_type = std::size_t>
class Gmsh4Reader;
} // end namespace Dune
......@@ -7,15 +7,15 @@
#include <dune/common/version.hh>
#include <dune/grid/common/gridfactory.hh>
#include "forward.hh"
#include <dune/gmsh4/forward.hh>
namespace Dune
{
namespace Gmsh
namespace Gmsh4
{
/// Base class for grid creators in a CRTP style.
/**
* Construct a grid from data read from VTK files.
* Construct a grid from data read from Gmsh files.
*
* \tparam GridView Model of Dune::GridView
* \tparam Derived Implementation of a concrete GridCreator.
......@@ -64,6 +64,12 @@ namespace Dune
return *factory_;
}
/// Return the associated (const) GridFactory
GridFactory<Grid> const& factory () const
{
return *factory_;
}
/// Return the mpi collective communicator
auto comm () const
{
......@@ -110,5 +116,5 @@ namespace Dune
GridFactory<Grid>* factory_;
};
} // end namespace Gmsh
} // end namespace Gmsh4
} // end namespace Dune
......@@ -4,6 +4,7 @@ install(FILES
continuousgridcreator.hh
derivedgridcreator.hh
discontinuousgridcreator.hh
lagrangegridcreator.hh
parallelgridcreator.hh
serialgridcreator.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/grid/io/file/gmsh4/gridcreators)
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/gmsh4/gridcreators)
#pragma once
#include <type_traits>
namespace Dune
{
namespace Gmsh4
{
template <class Factory, class... Args>
using HasInsertVertex = decltype( std::declval<Factory>().insertVertex(std::declval<Args>()...) );
namespace Impl
{
template <class GF, class = void>
struct VertexIdType { using type = unsigned int; };
template <class GF>
struct VertexIdType<GF, typename GF::VertexId> { using type = typename GF::VertexId; };
}
template <class GF>
using VertexId_t = typename Impl::VertexIdType<GF>::type;
} // end namespace Gmsh4
} // end namespace Dune
......@@ -9,12 +9,12 @@
#include <dune/common/hybridutilities.hh>
#include <dune/grid/common/gridfactory.hh>
#include <dune/grid/io/file/gmsh4/types.hh>
#include <dune/grid/io/file/gmsh4/gridcreatorinterface.hh>
#include <dune/gmsh4/types.hh>
#include <dune/gmsh4/gridcreatorinterface.hh>
namespace Dune
{
namespace Gmsh
namespace Gmsh4
{
// Create a grid where the input points and connectivity is already
// connected correctly.
......@@ -24,6 +24,7 @@ namespace Dune
{
using Super = GridCreatorInterface<Grid, ContinuousGridCreator<Grid>>;
using GlobalCoordinate = typename Super::GlobalCoordinate;
using Nodes = std::vector<GlobalCoordinate>;
ContinuousGridCreator (GridFactory<Grid>& factory)
: Super(factory)
......@@ -36,23 +37,22 @@ namespace Dune
std::pair<std::size_t,std::size_t> nodeTagRange,
std::vector<NodeAttributes> const& entityBlocks)
{
GlobalCoordinate p;
vertexMap_.resize(nodeTagRange.second - nodeTagRange.first + 1);
vertexShift_ = nodeTagRange.first;
nodes_.resize(numNodes);
GlobalCoordinate p;
size_t vertexIndex = 0;
std::size_t i = 0;
for (auto const& entityBlock : entityBlocks) {
for (auto const& node : entityBlock.nodes) {
assert(node.xyz.size() >= p.size());
for (std::size_t j = 0; j < p.size(); ++j)
p[j] = node.xyz[j];
factory().insertVertex(p);
vertexMap_[node.tag - nodeTagRange.first] = i++;
nodes_[vertexIndex] = p;
vertexMap_[node.tag - vertexShift_] = vertexIndex++;
}
}
}
template <class ElementAttributes, class BoundaryEntities>
void insertElementsImpl (std::size_t numElements,
std::pair<std::size_t,std::size_t> elementTagRange,
......@@ -60,16 +60,17 @@ namespace Dune
BoundaryEntities const& boundaryEntities)
{
std::vector<unsigned int> connectivity;
elementMap_.resize(elementTagRange.second - elementTagRange.first + 1);
elementShift_ = elementTagRange.first;
std::size_t cornerIndex = 0;
std::vector<std::int64_t> cornerVertices(nodes_.size(), -1);
std::size_t i = 0;
for (auto const& entityBlock : entityBlocks) {
if (entityBlock.entityDim < Grid::dimension-1)
continue;
CellType cell{entityBlock.elementType};
if (entityBlock.entityDim == Grid::dimension-1) {
auto type = Gmsh4::to_geometry(entityBlock.elementType);
Gmsh4::CellType cell{type};
//this segment was probably added due to a misunderstanding about gmsh's boundary-handling
/*if (entityBlock.entityDim == Grid::dimension-1) { //boundary
if (boundaryEntities.count(entityBlock.entityTag)) {
auto refElem = referenceElement<double,Grid::dimension-1>(cell.type());
connectivity.resize(refElem.size(Grid::dimension-1));
......@@ -83,29 +84,37 @@ namespace Dune
}
}
}
else if (entityBlock.entityDim == Grid::dimension) {