Select Git revision
Order2AcousticSolver.cpp
GmshReader.cpp 28.68 KiB
#include <GmshReader.hpp>
#include <iostream>
#include <fstream>
#include <set>
#include <rang.hpp>
#include <Connectivity2D.hpp>
#include <Mesh.hpp>
#include <map>
template<typename T>
inline std::string stringify(const T & t)
{
std::ostringstream oss;
oss << t;
return oss.str();
}
template<>
inline std::string stringify<std::string>(const std::string& t)
{
return t;
}
class ErrorHandler
{
public:
enum Type {
asked, /**< execution request by the user*/
compilation, /**< syntax error in a language */
normal, /**< normal error due to a bad use of ff3d */
unexpected /**< Unexpected execution error */
};
private:
const std::string __filename; /**< The source file name where the error occured */
const size_t __lineNumber; /**< The line number where exception was raised */
const std::string __errorMessage; /**< The reporting message */
const Type __type; /**< the type of the error */
public:
/**
* Prints the error message
*
*/
virtual void writeErrorMessage();
/**
* The copy constructor
*
* @param e an handled error
*/
ErrorHandler(const ErrorHandler& e)
: __filename(e.__filename),
__lineNumber(e.__lineNumber),
__errorMessage(e.__errorMessage),
__type(e.__type)
{
;
}
/**
* Constructor
*
* @param filename the source file name
* @param lineNumber the source line
* @param errorMessage the reported message
* @param type the type of the error
*/
ErrorHandler(const std::string& filename,
const size_t& lineNumber,
const std::string& errorMessage,
const Type& type);
/**
* The destructor
*
*/
virtual ~ErrorHandler()
{
;
}
};
void ErrorHandler::writeErrorMessage()
{
switch(__type) {
case asked: {
std::cerr << "\nremark: exit command explicitly called\n";
}
case normal: {
std::cerr << '\n' << __filename << ':' << __lineNumber
<< ":remark: emitted the following message\n";
std::cerr << "error: " << __errorMessage << '\n';
break;
}
case compilation: {
std::cerr << "\nline " << __lineNumber << ':' << __errorMessage << '\n';
break;
}
case unexpected: {
std::cerr << '\n' << __filename << ':' << __lineNumber << ":\n" << __errorMessage << '\n';
std::cerr << "\nUNEXPECTED ERROR: this should not occure, please report it\n";
std::cerr << "\nBUG REPORT: Please send bug reports to:\n"
<< " ff3d-dev@nongnu.org or freefem@ann.jussieu.fr\n"
<< "or better, use the Bug Tracking System:\n"
<< " http://savannah.nongnu.org/bugs/?group=ff3d\n";
break;
}
default: {
std::cerr << __filename << ':' << __lineNumber << ": " << __errorMessage << '\n';
std::cerr << __FILE__ << ':' << __LINE__ << ":remark: error type not implemented!\n";
}
}
}
ErrorHandler::
ErrorHandler(const std::string& filename,
const size_t& lineNumber,
const std::string& errorMessage,
const Type& type)
: __filename(filename),
__lineNumber(lineNumber),
__errorMessage(errorMessage),
__type(type)
{
;
}
GmshReader::GmshReader(const std::string& filename)
: m_filename(filename)
{
try {
m_fin.open(m_filename);
if (not m_fin) {
std::cerr << "cannot read file '" << m_filename << "'\n";
std::exit(0);
}
// gmsh 2.2 format keywords
__keywordList["$MeshFormat"] = MESHFORMAT;
__keywordList["$EndMeshFormat"] = ENDMESHFORMAT;
__keywordList["$Nodes"] = NODES;
__keywordList["$EndNodes"] = ENDNODES;
__keywordList["$Elements"] = ELEMENTS;
__keywordList["$EndElements"] = ENDELEMENTS;
__numberOfPrimitiveNodes.resize(16);
__numberOfPrimitiveNodes[ 0] = 2; // edge
__numberOfPrimitiveNodes[ 1] = 3; // triangle
__numberOfPrimitiveNodes[ 2] = 4; // quadrangle
__numberOfPrimitiveNodes[ 3] = 4; // Tetrahedron
__numberOfPrimitiveNodes[ 4] = 8; // Hexaredron
__numberOfPrimitiveNodes[ 5] = 6; // Prism
__numberOfPrimitiveNodes[ 6] = 5; // Pyramid
__numberOfPrimitiveNodes[ 7] = 3; // second order edge
__numberOfPrimitiveNodes[ 8] = 6; // second order triangle
__numberOfPrimitiveNodes[ 9] = 9; // second order quadrangle
__numberOfPrimitiveNodes[10] = 10; // second order tetrahedron
__numberOfPrimitiveNodes[11] = 27; // second order hexahedron
__numberOfPrimitiveNodes[12] = 18; // second order prism
__numberOfPrimitiveNodes[13] = 14; // second order pyramid
__numberOfPrimitiveNodes[14] = 1; // point
__primitivesNames[0] = "edges";
__supportedPrimitives[0] = true;
__primitivesNames[1] = "triangles";
__supportedPrimitives[1] = true;
__primitivesNames[2] = "quadrangles";
__supportedPrimitives[2] = true;
__primitivesNames[3] = "tetrahedra";
__supportedPrimitives[3] = true;
__primitivesNames[4] = "hexahedra";
__supportedPrimitives[4] = true;
__primitivesNames[5] = "prisms";
__supportedPrimitives[5] = false;
__primitivesNames[6] = "pyramids";
__supportedPrimitives[6] = false;
__primitivesNames[7] = "second order edges";
__supportedPrimitives[7] = false;
__primitivesNames[8] = "second order triangles";
__supportedPrimitives[8] = false;
__primitivesNames[9] = "second order quadrangles";
__supportedPrimitives[9] = false;
__primitivesNames[10] = "second order tetrahedra";
__supportedPrimitives[10]= false;
__primitivesNames[11] = "second order hexahedra";
__supportedPrimitives[11]= false;
__primitivesNames[12] = "second order prisms";
__supportedPrimitives[12]= false;
__primitivesNames[13] = "second order pyramids";
__supportedPrimitives[13]= false;
__primitivesNames[14] = "point";
__supportedPrimitives[14]= false;
std::cout << "Reading file '" << m_filename << "'\n";
// Getting vertices list
GmshReader::Keyword kw = this->__nextKeyword();
switch(kw.second) {
// case NOD: {
// this->__readGmsh1();
// break;
// }
case MESHFORMAT: {
double fileVersion = this->_getReal();
if (fileVersion != 2.2) {
throw ErrorHandler(__FILE__,__LINE__,
"Cannot read Gmsh format '"+stringify(fileVersion)+"'",
ErrorHandler::normal);
}
int fileType = this->_getInteger();
__binary = (fileType == 1);
if ((fileType < 0) or (fileType > 1)) {
throw ErrorHandler(__FILE__,__LINE__,
"Cannot read Gmsh file type '"+stringify(fileType)+"'",
ErrorHandler::normal);
}
int dataSize = this->_getInteger();
if (dataSize != sizeof(double)) {
throw ErrorHandler(__FILE__,__LINE__,
"Data size not supported '"+stringify(dataSize)+"'",
ErrorHandler::normal);
}
if (__binary) {
// int one=0;
// fseek(__ifh,1L,SEEK_CUR);
// fread(reinterpret_cast<char*>(&one),sizeof(int),1,__ifh);
// if (one == 1) {
// __convertEndian = false;
// } else {
// invertEndianess(one);
// if (one == 1) {
// __convertEndian = true;
// } else {
// throw ErrorHandler(__FILE__,__LINE__,
// "Cannot determine endianess",
// ErrorHandler::normal);
// }
// }
// std::cout << "- Binary format: ";
// #ifdef WORDS_BIGENDIAN
// if (not __convertEndian) {
// std::cout << "big endian\n";
// } else {
// std::cout << "little endian\n";
// }
// #else // WORDS_BIGENDIAN
// if (not __convertEndian) {
// std::cout << "little endian\n";
// } else {
// std::cout << "big endian\n";
// }
// #endif // WORDS_BIGENDIAN
}
kw = this->__nextKeyword();
if (kw.second != ENDMESHFORMAT) {
throw ErrorHandler(__FILE__,__LINE__,
"reading file '"+m_filename
+"': expecting $EndMeshFormat, '"+kw.first+"' was found",
ErrorHandler::normal);
}
this->__readGmshFormat2_2();
break;
}
default: {
throw ErrorHandler(__FILE__,__LINE__,
"cannot determine format version of '"+m_filename+"'",
ErrorHandler::normal);
}
}
this->__proceedData();
// this->__createMesh();
}
catch(ErrorHandler e) {
e.writeErrorMessage();
std::exit(0);
}
}
void GmshReader::__readVertices()
{
const int numberOfVerices = this->_getInteger();
std::cout << "- Number Of Vertices: " << numberOfVerices << '\n';
if (numberOfVerices<0) {
throw ErrorHandler(__FILE__,__LINE__,
"reading file '"+this->m_filename
+"': number of vertices is negative",
ErrorHandler::normal);
}
__verticesNumbers.resize(numberOfVerices);
__vertices = Kokkos::View<R3*>("vertices",numberOfVerices);
if (not __binary) {
for (int i=0; i<numberOfVerices; ++i) {
__verticesNumbers[i] = this->_getInteger();
const double x = this->_getReal();
const double y = this->_getReal();
const double z = this->_getReal();
__vertices[i] = TinyVector<3, double>(x,y,z);
}
} else {
// fseek(m_fin.file()__ifh,1L,SEEK_CUR);
// for (int i=0; i<numberOfVerices; ++i) {
// int number = 0;
// fread(reinterpret_cast<char*>(&number),sizeof(int),1,__ifh);
// __verticesNumbers[i] = number;
// TinyVector<3,double> x;
// fread(reinterpret_cast<char*>(&(x[0])),sizeof(double),3,__ifh);
// for (size_t j=0; j<3; ++j) {
// __vertices[i][j] = x[j];
// }
// }
// if (__convertEndian) {
// for (int i=0; i<numberOfVerices; ++i) {
// invertEndianess(__verticesNumbers[i]);
// for (size_t j=0; j<3; ++j) {
// invertEndianess(vertices[i][j]);
// }
// }
// }
}
}
// void
// GmshReader::__readElements1()
// {
// const int numberOfElements = this->_getInteger();
// std::cout << "- Number Of Elements: " << numberOfElements << '\n';
// if (numberOfElements<0) {
// throw ErrorHandler(__FILE__,__LINE__,
// "reading file '"+m_filename
// +"': number of elements is negative",
// ErrorHandler::normal);
// }
// __elementType.resize(numberOfElements);
// __references.resize(numberOfElements);
// __elementVertices.resize(numberOfElements);
// for (int i=0; i<numberOfElements; ++i) {
// this->_getInteger(); // drops element number
// const int elementType = this->_getInteger()-1;
// if ((elementType < 0) or (elementType > 14)) {
// throw ErrorHandler(__FILE__,__LINE__,
// "reading file '"+m_filename
// +"': unknown element type '"+stringify(elementType)+"'",
// ErrorHandler::normal);
// }
// __elementType[i] = elementType;
// __references[i] = this->_getInteger(); // physical reference
// this->_getInteger(); // drops entity reference
// const int numberOfVertices = this->_getInteger();
// if (numberOfVertices != __numberOfPrimitiveNodes[elementType]) {
// std::stringstream errorMsg;
// errorMsg << "reading file '" <<m_filename
// << "':number of vertices (" << numberOfVertices
// << ") does not match expected ("
// << __numberOfPrimitiveNodes[elementType] << ")" << std::ends;
// throw ErrorHandler(__FILE__,__LINE__,
// errorMsg.str(),
// ErrorHandler::normal);
// }
// __elementVertices[i].resize(numberOfVertices);
// for (int j=0; j<numberOfVertices; ++j) {
// __elementVertices[i][j] = this->_getInteger();
// }
// }
// }
void
GmshReader::__readElements2_2()
{
const int numberOfElements = this->_getInteger();
std::cout << "- Number Of Elements: " << numberOfElements << '\n';
if (numberOfElements<0) {
throw ErrorHandler(__FILE__,__LINE__,
"reading file '"+m_filename
+"': number of elements is negative",
ErrorHandler::normal);
}
__elementType.resize(numberOfElements);
__references.resize(numberOfElements);
__elementVertices.resize(numberOfElements);
if (not __binary) {
for (int i=0; i<numberOfElements; ++i) {
this->_getInteger(); // drops element number
const int elementType = this->_getInteger()-1;
if ((elementType < 0) or (elementType > 14)) {
throw ErrorHandler(__FILE__,__LINE__,
"reading file '"+m_filename
+"': unknown element type '"+stringify(elementType)+"'",
ErrorHandler::normal);
}
__elementType[i] = elementType;
const int numberOfTags = this->_getInteger();
__references[i] = this->_getInteger(); // physical reference
for (int tag=1; tag<numberOfTags; ++tag) {
this->_getInteger(); // drops remaining tags
}
const int numberOfVertices = __numberOfPrimitiveNodes[elementType];
__elementVertices[i].resize(numberOfVertices);
for (int j=0; j<numberOfVertices; ++j) {
__elementVertices[i][j] = this->_getInteger();
}
}
} else {
// fseek(__ifh,1L,SEEK_CUR);
// int i=0;
// for (;i<numberOfElements;) {
// int elementType = 0;
// fread(reinterpret_cast<char*>(&elementType),sizeof(int),1,__ifh);
// if (__convertEndian) {
// invertEndianess(elementType);
// }
// --elementType;
// if ((elementType < 0) or (elementType > 14)) {
// throw ErrorHandler(__FILE__,__LINE__,
// "reading file '"+m_filename
// +"': unknown element type '"+stringify(elementType)+"'",
// ErrorHandler::normal);
// }
// int elementTypeNumber = 0;
// fread(reinterpret_cast<char*>(&elementTypeNumber),sizeof(int),1,__ifh);
// if (__convertEndian) {
// invertEndianess(elementTypeNumber);
// }
// int numberOfTags = 0;
// fread(reinterpret_cast<char*>(&numberOfTags),sizeof(int),1,__ifh);
// if (__convertEndian) {
// invertEndianess(numberOfTags);
// }
// for (int k=0; k<elementTypeNumber; ++k) {
// __elementType[i] = elementType;
// int elementNumber = 0;
// fread(reinterpret_cast<char*>(&elementNumber),sizeof(int),1,__ifh);
// int reference = 0;
// fread(reinterpret_cast<char*>(&reference),sizeof(int),1,__ifh);
// __references[i] = reference; // physical reference
// for (int tag=1; tag<numberOfTags; ++tag) {
// int t;
// fread(reinterpret_cast<char*>(&t),sizeof(int),1,__ifh);
// }
// const int numberOfVertices = __numberOfPrimitiveNodes[elementType];
// __elementVertices[i].resize(numberOfVertices);
// fread(reinterpret_cast<char*>(&(__elementVertices[i][0])),sizeof(int),numberOfVertices,__ifh);
// ++i;
// }
// }
// if (__convertEndian) {
// for (size_t i=0; i<__references.size(); ++i) {
// invertEndianess(__references[i]);
// }
// for (size_t i=0; i<__elementVertices.size(); ++i) {
// for (size_t j=0; j<__elementVertices[i].size(); ++i) {
// invertEndianess(__elementVertices[i][j]);
// }
// }
// }
}
}
void
GmshReader::__proceedData()
{
TinyVector<15,int> elementNumber = zero;
std::vector<std::set<size_t> > elementReferences(15);
for (size_t i=0; i<__elementType.size(); ++i) {
const int elementType = __elementType[i];
elementNumber[elementType]++;
elementReferences[elementType].insert(__references[i]);
}
for (size_t i=0; i<elementNumber.dimension(); ++i) {
if (elementNumber[i]>0) {
std::cout << " - Number of "
<< __primitivesNames[i]
<< ": " << elementNumber[i];
if (not(__supportedPrimitives[i])) {
std::cout << " [IGNORED]";
} else {
std::cout << " references: ";
for(std::set<size_t>::const_iterator iref
= elementReferences[i].begin();
iref != elementReferences[i].end(); ++iref) {
if (iref != elementReferences[i].begin()) std::cout << ',';
std::cout << *iref;
}
switch (i) {
// Supported entities
case 0: { // edges
__edges
= Kokkos::View<Edge*>("edges",
elementNumber[i]);
__edges_ref.resize(elementNumber[i]);
break;
}
case 1: { // triangles
__triangles
= Kokkos::View<Triangle*>("triangles",
elementNumber[i]);
__triangles_ref.resize(elementNumber[i]);
break;
}
case 2: { // quadrangles
__quadrangles
= Kokkos::View<Quadrangle*>("quadrangles",
elementNumber[i]);
__quadrangles_ref.resize(elementNumber[i]);
break;
}
case 3: { // tetrahedra
__tetrahedra
= Kokkos::View<Tetrahedron*>("tetrahedra",
elementNumber[i]);
__tetrahedra_ref.resize(elementNumber[i]);
break;
}
case 4: {// hexahedra
__hexahedra
= Kokkos::View<Hexahedron*>("hexahedra",
elementNumber[i]);
__hexahedra_ref.resize(elementNumber[i]);
}
// Ignored entities
case 14: {// point
break;
}
// Unsupported entities
case 5: // prism
case 6: // pyramid
case 7: // second order edge
case 8: // second order triangle
case 9: // second order quadrangle
case 10: // second order tetrahedron
case 11: // second order hexahedron
case 12: // second order prism
case 13: // second order pyramid
default: {
throw ErrorHandler(__FILE__,__LINE__,
"reading file '"+m_filename
+"': ff3d cannot read this kind of element",
ErrorHandler::normal);
}
}
}
std::cout << '\n';
}
}
std::cout << "- Building correspondance table\n";
int minNumber = std::numeric_limits<int>::max();
int maxNumber = std::numeric_limits<int>::min();
for (size_t i=0; i<__verticesNumbers.size(); ++i) {
const int& vertexNumber = __verticesNumbers[i];
minNumber = std::min(minNumber,vertexNumber);
maxNumber = std::max(maxNumber,vertexNumber);
}
if (minNumber<0) {
throw ErrorHandler(__FILE__,__LINE__,
"reading file '"+m_filename
+"': ff3d does not implement negative vertices number",
ErrorHandler::normal);
}
// A value of -1 means that the vertex is unknown
__verticesCorrepondance.resize(maxNumber+1,-1);
for (size_t i=0; i<__verticesNumbers.size(); ++i) {
__verticesCorrepondance[__verticesNumbers[i]] = i;
}
// reset element number to count them while filling structures
elementNumber = zero;
// Element structures filling
for (size_t i=0; i<__elementType.size(); ++i) {
std::vector<int>& elementVertices = __elementVertices[i];
switch (__elementType[i]) {
// Supported entities
case 0: { // edge
int& edgeNumber = elementNumber[0];
const int a = __verticesCorrepondance[elementVertices[0]];
const int b = __verticesCorrepondance[elementVertices[1]];
if ((a<0) or (b<0)) {
throw ErrorHandler(__FILE__,__LINE__,
"reading file '"+m_filename
+"': error reading element "+stringify(i)
+" [bad vertices definition]",
ErrorHandler::normal);
}
__edges[edgeNumber]
= Edge(a, b);
__edges_ref[edgeNumber] = __references[i];
edgeNumber++; // one more edge
break;
}
case 1: { // triangles
int& triangleNumber = elementNumber[1];
const int a = __verticesCorrepondance[elementVertices[0]];
const int b = __verticesCorrepondance[elementVertices[1]];
const int c = __verticesCorrepondance[elementVertices[2]];
if ((a<0) or (b<0) or (c<0)) {
throw ErrorHandler(__FILE__,__LINE__,
"reading file '"+m_filename
+"': error reading element "+stringify(i)
+" [bad vertices definition]",
ErrorHandler::normal);
}
__triangles[triangleNumber]
= Triangle(a, b, c);
__triangles_ref[triangleNumber] = __references[i];
triangleNumber++; // one more triangle
break;
}
case 2: { // quadrangle
int& quadrilateralNumber = elementNumber[2];
const int a = __verticesCorrepondance[elementVertices[0]];
const int b = __verticesCorrepondance[elementVertices[1]];
const int c = __verticesCorrepondance[elementVertices[2]];
const int d = __verticesCorrepondance[elementVertices[3]];
if ((a<0) or (b<0) or (c<0) or (d<0)) {
throw ErrorHandler(__FILE__,__LINE__,
"reading file '"+m_filename
+"': error reading element "+stringify(i)
+" [bad vertices definition]",
ErrorHandler::normal);
}
__quadrangles[quadrilateralNumber] = Quadrangle(a,b,c,d);
__quadrangles_ref[quadrilateralNumber] = __references[i];
quadrilateralNumber++; // one more quadrangle
break;
}
case 3: { // tetrahedra
int& tetrahedronNumber = elementNumber[3];
const int a = __verticesCorrepondance[elementVertices[0]];
const int b = __verticesCorrepondance[elementVertices[1]];
const int c = __verticesCorrepondance[elementVertices[2]];
const int d = __verticesCorrepondance[elementVertices[3]];
if ((a<0) or (b<0) or (c<0) or (d<0)) {
throw ErrorHandler(__FILE__,__LINE__,
"reading file '"+m_filename
+"': error reading element "+stringify(i)
+" [bad vertices definition]",
ErrorHandler::normal);
}
__tetrahedra[tetrahedronNumber] = Tetrahedron(a, b, c, d);
__tetrahedra_ref[tetrahedronNumber] = __references[i];
tetrahedronNumber++; // one more tetrahedron
break;
}
case 4: { // hexaredron
int& hexahedronNumber = elementNumber[4];
const int a = __verticesCorrepondance[elementVertices[0]];
const int b = __verticesCorrepondance[elementVertices[1]];
const int c = __verticesCorrepondance[elementVertices[2]];
const int d = __verticesCorrepondance[elementVertices[3]];
const int e = __verticesCorrepondance[elementVertices[4]];
const int f = __verticesCorrepondance[elementVertices[5]];
const int g = __verticesCorrepondance[elementVertices[6]];
const int h = __verticesCorrepondance[elementVertices[7]];
if ((a<0) or (b<0) or (c<0) or (d<0) or (e<0) or (f<0) or (g<0) or (h<0)) {
throw ErrorHandler(__FILE__,__LINE__,
"reading file '"+m_filename
+"': error reading element "+stringify(i)
+" [bad vertices definition]",
ErrorHandler::normal);
}
__hexahedra[hexahedronNumber]
= Hexahedron(a, b, c, d,
e, f, g, h);
__hexahedra_ref[hexahedronNumber] = __references[i];
hexahedronNumber++; // one more hexahedron
break;
}
// Unsupported entities
case 14:{// point
break;
}
case 5: // prism
case 6: // pyramid
case 7: // second order edge
case 8: // second order triangle
case 9: // second order quadrangle
case 10: // second order tetrahedron
case 11: // second order hexahedron
case 12: // second order prism
case 13:{// second order pyramid
}
default: {
throw ErrorHandler(__FILE__,__LINE__,
"reading file '"+m_filename
+"': ff3d cannot read this kind of element",
ErrorHandler::normal);
}
}
}
TinyVector<15,int> dimension0_mask = zero;
dimension0_mask[14]=1;
TinyVector<15,int> dimension1_mask = zero;
dimension1_mask[0]=1;
dimension1_mask[7]=1;
TinyVector<15,int> dimension2_mask = zero;
dimension2_mask[1]=1;
dimension2_mask[2]=1;
dimension2_mask[8]=1;
dimension2_mask[9]=1;
TinyVector<15,int> dimension3_mask = zero;
dimension3_mask[3]=1;
dimension3_mask[4]=1;
dimension3_mask[5]=1;
dimension3_mask[6]=1;
dimension3_mask[10]=1;
dimension3_mask[11]=1;
dimension3_mask[12]=1;
dimension3_mask[13]=1;
std::cout << "- dimension 0 entities : " << (dimension0_mask, elementNumber) << '\n';
std::cout << "- dimension 1 entities : " << (dimension1_mask, elementNumber) << '\n';
std::cout << "- dimension 2 entities : " << (dimension2_mask, elementNumber) << '\n';
std::cout << "- dimension 3 entities : " << (dimension3_mask, elementNumber) << '\n';
if ((dimension3_mask, elementNumber)>0) {
std::cerr << "*** using a 3d mesh (NIY)\n";
std::exit(0);
} else if ((dimension2_mask, elementNumber)>0) {
const size_t nb_cells = (dimension2_mask, elementNumber);
size_t max_nb_node_per_cell=3;
if (elementNumber[2] > 0) {
max_nb_node_per_cell = 4;
}
const Kokkos::View<unsigned int**> cell_nodes("cell_nodes", nb_cells, max_nb_node_per_cell);
const size_t nb_triangles = __triangles.extent(0);
for (size_t j=0; j<nb_triangles; ++j) {
cell_nodes(j,0) = __triangles[j][0];
cell_nodes(j,1) = __triangles[j][1];
cell_nodes(j,2) = __triangles[j][2];
}
const size_t nb_quadrangles = __quadrangles.extent(0);
for (size_t j=0; j<nb_quadrangles; ++j) {
const size_t jq = j+nb_triangles;
cell_nodes(jq,0) = __quadrangles[j][0];
cell_nodes(jq,1) = __quadrangles[j][1];
cell_nodes(jq,2) = __quadrangles[j][2];
cell_nodes(jq,3) = __quadrangles[j][3];
}
const Kokkos::View<unsigned short*> cell_nb_nodes("cell_nb_nodes", nb_cells);
for (size_t j=0; j<nb_triangles; ++j) {
cell_nb_nodes[j] = 3;
}
for (size_t j=nb_triangles; j<nb_triangles+nb_quadrangles; ++j) {
cell_nb_nodes[j] = 4;
}
m_connectivity = new Connectivity2D(cell_nb_nodes, cell_nodes);
Connectivity2D& connectivity = *m_connectivity;
std::map<unsigned int, std::vector<unsigned int>> ref_faces_map;
for (unsigned int e=0; e<__edges.extent(0); ++e) {
const unsigned int edge_number = connectivity.getFaceNumber(__edges[e][0], __edges[e][1]);
const unsigned int ref = __edges_ref[e];
ref_faces_map[ref].push_back(edge_number);
}
for (const auto& ref_face_list : ref_faces_map) {
connectivity.addFaceBoundary(ref_face_list.first,
ref_face_list.second);
}
const Kokkos::View<const unsigned int**> face_nodes = connectivity.faceNodes();
for (size_t i=0; i<connectivity.numberOfFaceBoundaries(); ++i) {
const Connectivity2D::FacesBoundary& faces_boundary
= connectivity.facesBoundary(i);
const unsigned int ref = faces_boundary.first;
std::set<unsigned int> node_id_set;
const Kokkos::View<const unsigned int*> face_ids
= faces_boundary.second;
for (unsigned int l=0; l<face_ids.extent(0); ++l) {
for (unsigned short r=0; r<2; ++r) {
node_id_set.insert(face_nodes(face_ids[l],r));
}
}
Kokkos::View<unsigned int*> node_id_list("node_ids", node_id_set.size());
{
int r=0;
for (auto node_id : node_id_set) {
node_id_list[r] = node_id;
++r;
}
}
connectivity.addNodeBoundary(ref, node_id_list);
}
typedef Mesh<Connectivity2D> MeshType;
typedef TinyVector<2, double> Rd;
Kokkos::View<Rd*> xr("xr", __vertices.extent(0));
for (size_t i=0; i<__vertices.extent(0); ++i) {
xr[i][0] = __vertices[i][0];
xr[i][1] = __vertices[i][1];
}
m_mesh = new MeshType(connectivity, xr);
MeshType& mesh = *m_mesh;
std::ofstream gnuplot("mesh.gnu");
for (size_t j=0; j<mesh.numberOfCells(); ++j) {
for (int r=0; r<mesh.connectivity().cellNbNodes()[j]; ++r) {
const Rd& x = mesh.xr()[mesh.connectivity().cellNodes()(j,r)];
gnuplot << x[0] << ' ' << x[1] << '\n';
}
const Rd& x = mesh.xr()[mesh.connectivity().cellNodes()(j,0)];
gnuplot << x[0] << ' ' << x[1] << "\n\n";
}
gnuplot.close();
} else if ((dimension1_mask, elementNumber)>0) {
std::cerr << "*** using a 1d mesh (NIY)\n";
std::exit(0);
} else {
std::cerr << "*** using a dimension 0 mesh is forbidden!\n";
std::exit(0);
}
}
GmshReader::Keyword
GmshReader::__nextKeyword()
{
GmshReader::Keyword kw;
std::cerr << "warning: " << rang::fg::red << __PRETTY_FUNCTION__ << rang::fg::reset << " keyword validity not checked!\n";
int retval = 1;
std::string aKeyword;
m_fin >> aKeyword;
if (retval < 0) {
kw.second = EndOfFile;
return kw;
} else if (retval == 0) {
kw.second = Unknown;
return kw;
}
KeywordList::iterator i = __keywordList.find(aKeyword.c_str());
if (i != __keywordList.end()) {
kw.first = (*i).first;
kw.second = (*i).second;
return kw;
}
// throw ErrorHandler(__FILE__,__LINE__,
// "reading file '"+m_filename
// +"': unknown keyword '"+aKeyword+"'",
// ErrorHandler::normal);
kw.first = aKeyword;
kw.second = Unknown;
return kw;
}
void GmshReader::
__readGmshFormat2_2()
{
std::cout << "- Reading Gmsh format 2.2\n";
GmshReader::Keyword kw;
kw = this->__nextKeyword();
if (kw.second != NODES) {
// throw ErrorHandler(__FILE__,__LINE__,
// "reading file '"+m_filename
// +"': expecting $Nodes, '"+kw.first+"' was found",
// ErrorHandler::normal);
}
this->__readVertices();
kw = this->__nextKeyword();
if (kw.second != ENDNODES) {
// throw ErrorHandler(__FILE__,__LINE__,
// "reading file '"+m_filename
// +"': expecting $EndNodes, '"+kw.first+"' was found",
// ErrorHandler::normal);
}
// Getting elements list
kw = this->__nextKeyword();
if (kw.second != ELEMENTS) {
// throw ErrorHandler(__FILE__,__LINE__,
// "reading file '"+m_filename
// +"': expecting $Elements, '"+kw.first+"' was found",
// ErrorHandler::normal);
}
this->__readElements2_2();
kw = this->__nextKeyword();
if (kw.second != ENDELEMENTS) {
// throw ErrorHandler(__FILE__,__LINE__,
// "reading file '"+m_filename
// +"': expecting $EndElements, '"+kw.first+"' was found",
// ErrorHandler::normal);
}
}