7 #ifndef WONTON_SIMPLE_MESH_H_ 8 #define WONTON_SIMPLE_MESH_H_ 64 double x1,
double y1,
double z1,
65 int nx,
int ny,
int nz) :
66 nx_(nx), ny_(ny), nz_(nz),
67 x0_(x0), y0_(y0), z0_(z0),
68 x1_(x1), y1_(y1), z1_(z1) {
70 num_cells_ = nx*ny*nz;
71 num_nodes_ = (nx+1)*(ny+1)*(nz+1);
72 num_faces_ = (nx_+1)*ny_*nz_ + nx_*(ny_+1)*nz_ + nx_*ny_*(nz_+1);
77 cells_per_node_aug_ = 9;
80 build_node_coords_3d();
83 build_cfn_adjacencies_3d();
86 nodeids_owned_.resize(num_nodes_);
87 for (
int i(0); i < num_nodes_; ++i)
88 nodeids_owned_[i] = i;
90 cellids_owned_.resize(num_cells_);
91 for (
int i(0); i < num_cells_; ++i)
92 cellids_owned_[i] = i;
94 faceids_owned_.resize(num_faces_);
95 for (
int i(0); i < num_faces_; ++i)
96 faceids_owned_[i] = i;
111 double x1,
double y1,
118 num_nodes_ = (nx+1)*(ny+1);
119 num_faces_ = (nx_+1)*ny_ + nx_*(ny_+1);
124 cells_per_node_aug_ = 5;
127 build_node_coords_2d();
130 build_cfn_adjacencies_2d();
133 nodeids_owned_.resize(num_nodes_);
134 for (
int i(0); i < num_nodes_; ++i)
135 nodeids_owned_[i] = i;
137 cellids_owned_.resize(num_cells_);
138 for (
int i(0); i < num_cells_; ++i)
139 cellids_owned_[i] = i;
141 faceids_owned_.resize(num_faces_);
142 for (
int i(0); i < num_faces_; ++i)
143 faceids_owned_[i] = i;
169 return nodeids_owned_.size();
175 return nodeids_owned_.size();
182 return cellids_owned_.size();
188 return cellids_owned_.size();
195 return faceids_owned_.size();
201 return faceids_owned_.size();
219 std::vector<ID> *faces,
220 std::vector<int> *fdirs)
const {
221 auto offset = faces_per_cell_*cellid;
224 for (
int i(0); i < faces_per_cell_; ++i) {
225 faces->push_back(cell_to_face_[i+offset]);
226 fdirs->push_back(cell_face_dirs_[i+offset]);
236 std::vector<ID> *nodes)
const {
237 auto offset = nodes_per_cell_*cellid;
239 for (
int i(0); i < nodes_per_cell_; ++i)
240 nodes->push_back(cell_to_node_[i+offset]);
248 std::vector<ID> *nodes)
const {
249 auto offset = nodes_per_face_*faceid;
251 for (
int i(0); i < nodes_per_face_; ++i)
252 nodes->push_back(face_to_node_[i+offset]);
261 std::vector<ID> *cells)
const {
262 auto offset = cells_per_node_aug_*nodeid;
264 for (
int i(0); i < node_to_cell_[offset]; ++i) {
265 cells->push_back(node_to_cell_[i+offset+1]);
298 std::vector<ID> node_indices;
304 for (
int node_id: node_indices){
306 ccoords->push_back(node_coords);
323 assert(affine.rows() == D);
324 assert(affine.columns() == D+1);
325 for (
int i=0; i<num_nodes_; i++) {
327 node_get_coordinates<D>(i, &node);
328 std::vector<double> nodex(D+1);
329 for (
int j=0; j<D; j++) nodex[j] = node[j];
331 std::vector<double> newnodev;
332 newnodev = affine*nodex;
334 node_set_coordinates<D>(i, &newnode);
363 void build_node_coords_3d() {
364 coordinates3d_.clear();
366 double hx = (x1_ - x0_)/nx_;
367 double hy = (y1_ - y0_)/ny_;
368 double hz = (z1_ - z0_)/nz_;
370 for (
int iz(0); iz <= nz_; ++iz)
371 for (
int iy(0); iy <= ny_; ++iy)
372 for (
int ix(0); ix <= nx_; ++ix) {
373 coordinates3d_.emplace_back(x0_+ix*hx,
382 void build_cfn_adjacencies_3d() {
384 cell_to_node_.resize(nodes_per_cell_*num_cells_);
385 cell_to_face_.resize(faces_per_cell_*num_cells_);
386 cell_face_dirs_.resize(faces_per_cell_*num_cells_);
387 face_to_node_.resize(nodes_per_face_*num_faces_);
389 node_to_cell_.resize(cells_per_node_aug_*num_nodes_);
390 face_to_cell_.resize(2*num_faces_, -1);
393 for (
int iz(0); iz < nz_; ++iz)
394 for (
int iy(0); iy < ny_; ++iy)
395 for (
int ix(0); ix < nx_; ++ix) {
396 auto thisCell = cell_index_(ix, iy, iz);
397 auto cstart = nodes_per_cell_ * thisCell;
398 auto fstart = faces_per_cell_ * thisCell;
411 cell_to_node_[cstart ] = node_index_(ix, iy, iz);
412 cell_to_node_[cstart+1] = node_index_(ix+1, iy, iz);
413 cell_to_node_[cstart+2] = node_index_(ix+1, iy+1, iz);
414 cell_to_node_[cstart+3] = node_index_(ix, iy+1, iz);
415 cell_to_node_[cstart+4] = node_index_(ix, iy, iz+1);
416 cell_to_node_[cstart+5] = node_index_(ix+1, iy, iz+1);
417 cell_to_node_[cstart+6] = node_index_(ix+1, iy+1, iz+1);
418 cell_to_node_[cstart+7] = node_index_(ix, iy+1, iz+1);
423 for (
int iiz(iz); iiz <= iz+1; ++iiz)
424 for (
int iiy(iy); iiy <= iy+1; ++iiy)
425 for (
int iix(ix); iix <= ix+1; ++iix) {
426 auto thisNode = node_index_(iix, iiy, iiz);
427 auto cnstart = cells_per_node_aug_ * thisNode;
428 auto & c_at_n = node_to_cell_[cnstart];
429 node_to_cell_[cnstart+c_at_n+1] = thisCell;
449 cell_to_face_[fstart ] = xzface_index_(ix, iy, iz);
450 cell_face_dirs_[fstart ] = 1;
451 cell_to_face_[fstart+1] = yzface_index_(ix+1, iy, iz);
452 cell_face_dirs_[fstart+1] = 1;
453 cell_to_face_[fstart+2] = xzface_index_(ix, iy+1, iz);
454 cell_face_dirs_[fstart+2] = -1;
455 cell_to_face_[fstart+3] = yzface_index_(ix, iy, iz);
456 cell_face_dirs_[fstart+3] = -1;
457 cell_to_face_[fstart+4] = xyface_index_(ix, iy, iz);
458 cell_face_dirs_[fstart+4] = -1;
459 cell_to_face_[fstart+5] = xyface_index_(ix, iy, iz+1);
460 cell_face_dirs_[fstart+5] = 1;
464 auto cfstart = 2*xzface_index_(ix, iy, iz) + 1;
465 face_to_cell_[cfstart] = thisCell;
466 cfstart = 2*yzface_index_(ix+1, iy, iz);
467 face_to_cell_[cfstart] = thisCell;
468 cfstart = 2*xzface_index_(ix, iy+1, iz);
469 face_to_cell_[cfstart] = thisCell;
470 cfstart = 2*yzface_index_(ix, iy, iz) + 1;
471 face_to_cell_[cfstart] = thisCell;
472 cfstart = 2*xyface_index_(ix, iy, iz) + 1;
473 face_to_cell_[cfstart] = thisCell;
474 cfstart = 2*xyface_index_(ix, iy, iz+1);
475 face_to_cell_[cfstart] = thisCell;
485 for (
int iz(0); iz <= nz_; ++iz)
486 for (
int iy(0); iy < ny_; ++iy)
487 for (
int ix(0); ix < nx_; ++ix) {
488 auto thisFace = xyface_index_(ix, iy, iz);
489 auto nstart = nodes_per_face_ * thisFace;
490 face_to_node_[nstart ] = node_index_(ix, iy, iz);
491 face_to_node_[nstart+1] = node_index_(ix+1, iy, iz);
492 face_to_node_[nstart+2] = node_index_(ix+1, iy+1, iz);
493 face_to_node_[nstart+3] = node_index_(ix, iy+1, iz);
502 for (
int iz(0); iz < nz_; ++iz)
503 for (
int iy(0); iy <= ny_; ++iy)
504 for (
int ix(0); ix < nx_; ++ix) {
505 auto thisFace = xzface_index_(ix, iy, iz);
506 auto nstart = nodes_per_face_ * thisFace;
507 face_to_node_[nstart ] = node_index_(ix, iy, iz);
508 face_to_node_[nstart+1] = node_index_(ix+1, iy, iz);
509 face_to_node_[nstart+2] = node_index_(ix+1, iy, iz+1);
510 face_to_node_[nstart+3] = node_index_(ix, iy, iz+1);
522 for (
int iz(0); iz < nz_; ++iz)
523 for (
int iy(0); iy < ny_; ++iy)
524 for (
int ix(0); ix <= nx_; ++ix) {
525 auto thisFace = yzface_index_(ix, iy, iz);
526 auto nstart = nodes_per_face_ * thisFace;
527 face_to_node_[nstart ] = node_index_(ix, iy, iz);
528 face_to_node_[nstart+1] = node_index_(ix, iy+1, iz);
529 face_to_node_[nstart+2] = node_index_(ix, iy+1, iz+1);
530 face_to_node_[nstart+3] = node_index_(ix, iy, iz+1);
539 void build_node_coords_2d() {
540 coordinates2d_.clear();
542 double hx = (x1_ - x0_)/nx_;
543 double hy = (y1_ - y0_)/ny_;
545 for (
int iy(0); iy <= ny_; ++iy)
546 for (
int ix(0); ix <= nx_; ++ix) {
547 coordinates2d_.emplace_back(x0_+ix*hx,
555 void build_cfn_adjacencies_2d() {
557 cell_to_node_.resize(nodes_per_cell_*num_cells_);
558 cell_to_face_.resize(faces_per_cell_*num_cells_);
559 cell_face_dirs_.resize(faces_per_cell_*num_cells_);
560 face_to_node_.resize(nodes_per_face_*num_faces_);
562 node_to_cell_.resize(cells_per_node_aug_*num_nodes_);
563 face_to_cell_.resize(2*num_faces_, -1);
566 for (
int iy(0); iy < ny_; ++iy)
567 for (
int ix(0); ix < nx_; ++ix) {
568 auto thisCell = cell_index_(ix, iy, 0);
569 auto cstart = nodes_per_cell_ * thisCell;
570 auto fstart = faces_per_cell_ * thisCell;
582 cell_to_node_[cstart ] = node_index_(ix, iy, 0);
583 cell_to_node_[cstart+1] = node_index_(ix+1, iy, 0);
584 cell_to_node_[cstart+2] = node_index_(ix+1, iy+1, 0);
585 cell_to_node_[cstart+3] = node_index_(ix, iy+1, 0);
591 for (
int iiy(iy); iiy <= iy+1; ++iiy)
592 for (
int iix(ix); iix <= ix+1; ++iix) {
593 auto thisNode = node_index_(iix, iiy, 0);
594 auto cnstart = cells_per_node_aug_ * thisNode;
595 auto & c_at_n = node_to_cell_[cnstart];
596 node_to_cell_[cnstart+c_at_n+1] = thisCell;
616 cell_to_face_[fstart ] = xface_index_(ix, iy);
617 cell_face_dirs_[fstart ] = 1;
618 cell_to_face_[fstart+1] = yface_index_(ix+1, iy);
619 cell_face_dirs_[fstart+1] = 1;
620 cell_to_face_[fstart+2] = xface_index_(ix, iy+1);
621 cell_face_dirs_[fstart+2] = -1;
622 cell_to_face_[fstart+3] = yface_index_(ix, iy);
623 cell_face_dirs_[fstart+3] = -1;
628 auto cfstart = 2*xface_index_(ix, iy);
629 face_to_cell_[cfstart] = thisCell;
630 cfstart = 2*xface_index_(ix, iy+1)+1;
631 face_to_cell_[cfstart] = thisCell;
632 cfstart = 2*yface_index_(ix+1, iy)+1;
633 face_to_cell_[cfstart] = thisCell;
634 cfstart = 2*yface_index_(ix, iy) ;
635 face_to_cell_[cfstart] = thisCell;
641 for (
int iy(0); iy <= ny_; ++iy)
642 for (
int ix(0); ix < nx_; ++ix) {
643 auto thisFace = xface_index_(ix, iy);
644 auto nstart = nodes_per_face_ * thisFace;
645 face_to_node_[nstart ] = node_index_(ix, iy, 0);
646 face_to_node_[nstart+1] = node_index_(ix+1, iy, 0);
649 for (
int iy(0); iy < ny_; ++iy)
650 for (
int ix(0); ix <= nx_; ++ix) {
651 auto thisFace = yface_index_(ix, iy);
652 auto nstart = nodes_per_face_ * thisFace;
653 face_to_node_[nstart ] = node_index_(ix, iy, 0);
654 face_to_node_[nstart+1] = node_index_(ix, iy+1, 0);
666 double x0_, y0_, z0_, x1_, y1_, z1_;
669 std::vector<Point<3>> coordinates3d_;
670 std::vector<Point<2>> coordinates2d_;
673 int nodes_per_face_ ;
674 int nodes_per_cell_ ;
675 int faces_per_cell_ ;
676 int cells_per_node_aug_ ;
684 std::vector<ID> cell_to_face_;
685 std::vector<int> cell_face_dirs_;
686 std::vector<ID> cell_to_node_;
687 std::vector<ID> face_to_node_;
688 std::vector<ID> face_to_cell_;
689 std::vector<ID> node_to_cell_;
692 std::vector<ID> nodeids_owned_;
693 std::vector<ID> faceids_owned_;
694 std::vector<ID> cellids_owned_;
697 ID node_index_(
int i,
int j,
int k)
const {
698 return i + j*(nx_+1) + k*(nx_+1)*(ny_+1);
700 ID cell_index_(
int i,
int j,
int k)
const {
701 return i + j*nx_ + k*nx_*ny_;
704 ID xface_index_(
int i,
int j)
const {
707 ID yface_index_(
int i,
int j)
const {
708 return i + j*(nx_+1) + xface_index_(0, ny_+1);
711 ID xyface_index_(
int i,
int j,
int k)
const {
712 return i + j*nx_ + k*nx_*ny_;
714 ID xzface_index_(
int i,
int j,
int k)
const {
715 return i + j*nx_ + k*nx_*(ny_+1) + xyface_index_(0, 0, nz_+1);
717 ID yzface_index_(
int i,
int j,
int k)
const {
718 return i + j*(nx_+1) + k*(nx_+1)*ny_ + xzface_index_(0, 0, nz_);
731 void Simple_Mesh::node_get_coordinates<3>(
const ID nodeid,
733 assert(spacedim_ == 3);
734 *pp = coordinates3d_[nodeid];
739 void Simple_Mesh::node_get_coordinates<2>(
const ID nodeid,
741 assert(spacedim_ == 2);
742 *pp = coordinates2d_[nodeid];
747 void Simple_Mesh::node_set_coordinates<3>(
const ID nodeid,
749 assert(spacedim_ == 3);
750 coordinates3d_[nodeid] = *pp;
755 void Simple_Mesh::node_set_coordinates<2>(
const ID nodeid,
757 assert(spacedim_ == 2);
758 coordinates2d_[nodeid] = *pp;
764 #endif // WONTON_SIMPLE_MESH_H_
Simple_Mesh & operator=(const Simple_Mesh &)=delete
Assignment operator (disabled).
int num_entities(const Entity_kind kind, const Entity_type type) const
Determine the number of a specific mesh entity.
Definition: simple_mesh.h:163
~Simple_Mesh()
Destructor.
Definition: simple_mesh.h:150
Factorize a number N into D equal (or nearly equal) factors.
Definition: adaptive_refinement_mesh.h:31
std::vector< T > vector
Definition: wonton.h:285
void node_get_cells(const ID nodeid, std::vector< ID > *cells) const
For a given node, get all the cells attached to this node.
Definition: simple_mesh.h:260
int space_dimension() const
Spatial dimension of the mesh.
Definition: simple_mesh.h:153
Entity_type
The parallel type of a given entity.
Definition: wonton.h:124
Represents a point in an N-dimensional space.
Definition: Point.h:50
void cell_get_faces_and_dirs(const ID cellid, std::vector< ID > *faces, std::vector< int > *fdirs) const
For a given cell, get the list of faces and the direction of their normals.
Definition: simple_mesh.h:218
Simple_Mesh(double x0, double y0, double x1, double y1, int nx, int ny)
Constructor for creating a serial, 2D Cartesian mesh.
Definition: simple_mesh.h:110
A very light-weight, serial, 2D/3D Cartesian mesh.
Definition: simple_mesh.h:47
Entity_kind
The type of mesh entity.
Definition: wonton.h:81
void node_set_coordinates(const ID nodeid, Point< D > *pp)
Set the coordinates of a node.
Definition: simple_mesh.h:353
void cell_get_coordinates(const ID cellid, std::vector< Point< D >> *ccoords) const
Definition: simple_mesh.h:294
void face_get_nodes(const ID faceid, std::vector< ID > *nodes) const
For a given face, get the list of nodes.
Definition: simple_mesh.h:247
void node_get_coordinates(const ID nodeid, Point< D > *pp) const
Get the coordinates of a node.
Definition: simple_mesh.h:280
void transform(const Matrix &affine)
Perform an affine transform on the coordinates of the mesh.
Definition: simple_mesh.h:321
void cell_get_nodes(const ID cellid, std::vector< ID > *nodes) const
For a given cell, get the list of nodes.
Definition: simple_mesh.h:235
Simple_Mesh(double x0, double y0, double z0, double x1, double y1, double z1, int nx, int ny, int nz)
Constructor for creating a serial, 3D Cartesian mesh.
Definition: simple_mesh.h:63