26#include <taskflow/taskflow/taskflow.hpp>
27#include <taskflow/taskflow/algorithm/for_each.hpp>
32 : d_numNodes(0), d_numElems(0), d_eType(1), d_eNumVertex(0), d_numDofs(0),
33 d_h(0.), d_dim(dim), d_encDataPopulated(false), d_needEncData(false),
37 : d_numNodes(0), d_numElems(0), d_eType(1), d_eNumVertex(0), d_numDofs(0),
38 d_h(0.), d_dim(modelDeck->d_dim),
39 d_spatialDiscretization(modelDeck->d_spatialDiscretization),
40 d_filename(meshDeck->d_filename), d_encDataPopulated(false),
41 d_needEncData(modelDeck->d_populateElementNodeConnectivity),
49 throw std::runtime_error(
"Spatial discretization type " +
d_spatialDiscretization +
" not known. Check input data.");
52 if (d_dim < 0 or d_dim > 3) {
53 throw std::runtime_error(
55 <<
"Error: Check Dimension in input data.\n");
59 throw std::runtime_error(
61 <<
"Error: Filename for mesh data not specified.\n");
84 throw std::runtime_error(
86 <<
"Error: Currently only '.csv', '.msg', and '.vtu' "
87 "files are supported for reading mesh.\n");
92 throw std::runtime_error(
95 <<
" .vtu or .msh mesh file is required.\n");
106 else if (file_type == 1) {
111 else if (file_type == 2) {
127 bool found_volume_data =
false;
133 if (!found_volume_data)
140 if (!is_fd || !found_volume_data) {
159 d_fix = std::vector<uint8_t>(
d_nodes.size(), uint8_t(0));
164 bool compute_vol =
false;
165 if (is_fd and
d_vol.empty()) compute_vol =
true;
173 compute_vol, std::string(
"mesh filename = ") + filename);
177 std::vector<size_t> enc,
181 if (enc.size() % 3 != 0)
182 throw std::runtime_error(
183 "Mesh::loadFromTriangleElements2D: connectivity length must be a multiple of 3.");
186 d_enc = std::move(enc);
201 for (
unsigned k = 0; k < 3; ++k) {
202 size_t nid =
d_enc[3 * e + k];
203 d_nec[nid].push_back(e);
211 "(in-memory triangle mesh)");
215 std::vector<size_t> enc,
219 if (enc.size() % 4 != 0)
220 throw std::runtime_error(
221 "Mesh::loadFromTetraElements3D: connectivity length must be a multiple of 4.");
224 d_enc = std::move(enc);
239 for (
unsigned k = 0; k < 4; ++k) {
240 size_t nid =
d_enc[4 * e + k];
241 d_nec[nid].push_back(e);
249 "(in-memory tetrahedron mesh)");
253 bool compute_vol_from_elements,
const std::string &volume_error_note) {
257 if (compute_vol_from_elements) {
265 for (
const auto &v :
d_vol) {
267 if (v < 0.01 * std::pow(
d_h,
d_dim)) {
269 std::cerr <<
"Error: Check nodal volume " << v
270 <<
" is less than " << 0.01 * std::pow(
d_h,
d_dim)
271 <<
", Node = " << counter <<
" at position = "
272 <<
d_nodes[counter].printStr() <<
"\n";
273 if (!volume_error_note.empty())
274 std::cerr << volume_error_note <<
"\n";
275 throw std::runtime_error(
294 util::io::log(
"Mesh: Reading element-node connectivity data.\n");
305 throw std::runtime_error(
307 <<
"Error: Currently only '.csv', '.msg', and '.vtu' "
308 "files are supported for reading mesh.\n");
311 if (file_type == 0) {
312 throw std::runtime_error(
314 <<
"Error: readElementData() requires file to be either "
315 ".vtu or .msh mesh file.\n");
318 if (file_type == 1) {
328 else if (file_type == 2) {
343 auto *quads_p = quads.get();
348 throw std::runtime_error(
350 <<
"Error: Can not compute nodal volume for given finite "
351 "element mesh as the element-node connectivity data is "
358 std::cout <<
"\n-------- Node data ----------\n";
360 std::cout <<
"\n-------- Element data ----------\n";
370 tf::Taskflow taskflow;
372 taskflow.for_each_index(
373 (std::size_t) 0, this->
d_numNodes, (std::size_t) 1, [
this, quads_p](std::size_t i) {
376 for (
auto e : this->
d_nec[i]) {
382 for (
size_t l = 0; l < e_ns.size(); l++)
387 throw std::runtime_error(
389 <<
"Error: Check node element connectivity.\n");
393 std::vector<util::Point> e_nodes;
395 e_nodes.emplace_back(this->d_nodes[k]);
398 double vol = quads_p->elemSize(e_nodes);
403 std::vector<fe::QuadData> qds = quads_p->getQuadDatas(e_nodes);
407 v += qd.d_shapes[loc_i] * factor * qd.d_w;
415 executor.run(taskflow).get();
426 std::vector<double> p1(3,0.);
427 std::vector<double> p2(3,0.);
428 for (
const auto& x :
d_nodes) {
443 d_bbox = std::make_pair(p1, p2);
455 for (
size_t i = 0; i <
d_nodes.size(); i++)
456 for (
size_t j = 0; j <
d_nodes.size(); j++)
462 std::cout <<
"Check nodes are too close = "
463 << util::io::printStr<util::Point>({
d_nodes[i],
466 std::cout <<
"Distance = " << val <<
", guess = " << guess <<
"\n";
487 flag ? (
d_fix[i] |= 1UL << dof) : (
d_fix[i] &= ~(1UL << dof));
491 d_enc.shrink_to_fit();
494 d_nec.shrink_to_fit();
500 std::ostringstream oss;
501 oss << tabS <<
"------- Mesh --------" << std::endl << std::endl;
502 oss << tabS <<
"Dimension = " <<
d_dim << std::endl;
504 oss << tabS <<
"Mesh size = " <<
d_h << std::endl;
505 oss << tabS <<
"Num nodes = " <<
d_numNodes << std::endl;
506 oss << tabS <<
"Num elements = " <<
d_numElems << std::endl;
507 oss << tabS <<
"Element type = " <<
d_eType << std::endl;
508 oss << tabS <<
"Num nodes per element = " <<
d_eNumVertex << std::endl;
509 oss << tabS <<
"Num nodal vol = " <<
d_vol.size() << std::endl;
510 oss << tabS <<
"Bounding box: " << std::endl;
512 oss << tabS << std::endl;
std::vector< size_t > getElementConnectivity(const size_t &i) const
Get the connectivity of element.
bool d_needEncData
Flag that indicates whether we need enc data (set by input mesh deck in constructor)
void clearElementData()
Clear element-node connectivity data.
std::string d_filename
Filename to read mesh data.
std::string printStr(int nt=0, int lvl=0) const
Returns the string containing printable information about the object.
std::vector< size_t > d_enc
Element-node connectivity data.
Mesh(size_t dim=0)
Constructor.
std::pair< std::vector< double >, std::vector< double > > d_bbox
Bounding box.
std::vector< util::Point > d_nodes
Vector of initial (reference) coordinates of nodes.
bool d_encDataPopulated
Flag that indicates whether element-node connectivity data is read from file.
size_t d_numElems
Number of elements.
bool readElementData(const std::string &filename)
Reads element-node connectivity data from file. This function is meant for cases when mesh was create...
void computeMeshSize()
Compute the mesh size.
size_t d_eType
Element type.
size_t d_numNodes
Number of nodes.
size_t d_dim
Dimension of the mesh.
std::string d_spatialDiscretization
Tag for spatial discretization type.
void finalizeMeshDerivedFieldsFromCurrentNodes(bool compute_vol_from_elements, const std::string &volume_error_note)
After nodes, enc, nec, and dof-related fields are set: 2D z clear, bbox, optional nodal volume,...
void setZCoordinateZero()
For , set on all reference nodes (x–y plane). Call before computeBBox() when nodes may carry numeric...
std::vector< uint8_t > d_fix
Vector of fixity mask of each node.
size_t d_numDofs
Number of dofs = (dimension) times (number of nodes)
void setFixity(const size_t &i, const unsigned int &dof, const bool &flag)
Set the fixity to free (0) or fixed (1)
void computeVol()
Compute the nodal volume.
std::vector< double > d_vol
Vector of volume of each node.
void loadFromTetraElements3D(std::vector< util::Point > nodes, std::vector< size_t > enc, const inp::MeshDeck *meshDeck, const inp::ModelDeck *modelDeck)
Populate mesh from 3D tetrahedron data (0-based node indices in enc) without reading a file.
void loadFromTriangleElements2D(std::vector< util::Point > nodes, std::vector< size_t > enc, const inp::MeshDeck *meshDeck, const inp::ModelDeck *modelDeck)
Populate mesh from 2D triangle data (0-based node indices in enc) without reading a file.
void computeBBox()
Compute the bounding box from d_nodes (after setZCoordinateZero() for 2D if applicable).
size_t d_eNumVertex
Number of vertex per element.
void print(int nt=0, int lvl=0) const
Prints the information about the object.
void createData(const std::string &filename, bool ref_config=false)
Reads mesh data from the file and populates other data.
std::vector< std::vector< size_t > > d_nec
Node-element connectivity data.
double d_h
Characteristic mesh spacing (minimum nodal distance); always from computeMeshSize() after nodes exist...
Collects a message with stream syntax for use in an exception.
static int vtk_map_element_to_num_nodes[16]
Map from element type to number of nodes (for vtk)
static const int vtk_type_triangle
Integer flag for triangle element.
static const int vtk_type_tetra
Integer flag for tetrahedron element.
std::unique_ptr< BaseElem > elem(size_t type, size_t order)
Collection of methods and data related to finite element and mesh.
void readVtuFileCells(const std::string &filename, size_t dim, size_t &element_type, size_t &num_elem, std::vector< size_t > *enc, std::vector< std::vector< size_t > > *nec)
Reads cell data, i.e. element-node connectivity and node-element connectivity.
void readMshFileCells(const std::string &filename, size_t dim, size_t &element_type, size_t &num_elem, std::vector< size_t > *enc, std::vector< std::vector< size_t > > *nec)
Reads cell data, i.e. element-node connectivity and node-element connectivity.
bool readVtuFilePointData(const std::string &filename, const std::string &tag, std::vector< uint8_t > *data)
Reads data of specified tag from the vtu file.
void readVtuFileNodes(const std::string &filename, size_t dim, std::vector< util::Point > *nodes, bool ref_config=false)
Reads nodal coordinates.
void readCsvFile(const std::string &filename, size_t dim, std::vector< util::Point > *nodes, std::vector< double > *volumes)
Reads mesh data into node file and element file.
void readMshFile(const std::string &filename, size_t dim, std::vector< util::Point > *nodes, size_t &element_type, size_t &num_elem, std::vector< size_t > *enc, std::vector< std::vector< size_t > > *nec, std::vector< double > *volumes, bool is_fd=false)
Reads mesh data into node file and element file.
std::string printBoxStr(const std::pair< util::Point, util::Point > &box, int nt=print_default_tab)
Returns formatted string for output.
std::string getTabS(int nt)
Returns tab spaces of a given size.
std::string printStr(const T &msg, int nt=print_default_tab)
Returns formatted string for output.
std::string getExtensionFromFile(std::string const &filename)
Get extension from the filename.
void log(std::ostringstream &oss, bool screen_out=false, int printMpiRank=print_default_mpi_rank)
Global method to log the message.
unsigned int getNThreads()
Get number of threads to be used by taskflow.
bool isLess(const double &a, const double &b)
Returns true if a < b.
Structure to read and store mesh related input data.
std::string d_filename
Filename to read mesh data.
Structure to read and store model related input data.
bool d_populateElementNodeConnectivity
Flag to indicate if we should populate element-node connectivity data in meshes.
std::string d_spatialDiscretization
Tag for spatial discretization.