Skip to content

Instantly share code, notes, and snippets.

@bgranzow
Last active March 2, 2018 15:16
Show Gist options
  • Save bgranzow/5a0d435ee9ff6086fa3813a07e964020 to your computer and use it in GitHub Desktop.
Save bgranzow/5a0d435ee9ff6086fa3813a07e964020 to your computer and use it in GitHub Desktop.
starting point to count new entities for AMR
#include <Omega_h_array_ops.hpp>
#include <Omega_h_build.hpp>
#include <Omega_h_library.hpp>
#include <Omega_h_file.hpp>
#include <Omega_h_hypercube.hpp>
#include <Omega_h_mark.hpp>
#include <Omega_h_mesh.hpp>
int main(int argc, char** argv) {
// initialize the osh library
auto lib = Omega_h::Library(&argc, &argv);
auto world = lib.world();
// inputs for a simple 2D mesh
double x = 1.0;
double y = 1.0;
double z = 0.0;
int dim = 2;
int nx = 3;
int ny = 3;
int nz = 0;
int nelems = nx*ny;
// build a simple mesh
auto type = OMEGA_H_HYPERCUBE;
Omega_h::Mesh mesh(&lib);
mesh = Omega_h::build_box(world, type, x, y, z, nx, ny, nz);
// create a simple refinement marking array and add it as a tag
Omega_h::Read<Omega_h::Byte> elem_mark(nelems);
Omega_h::Write<Omega_h::Byte> elem_mark_w(nelems, 0);
elem_mark_w[2] = 1;
elem_mark = elem_mark_w;
mesh.add_tag<Omega_h::Byte>(dim, "refine", 1, elem_mark);
// initialize counters for new entities
Omega_h::Int new_ent_counts[4] = {0, 0, 0, 0};
// loop through all possible split dimensions in the mesh
for (Omega_h::Int i = 1; i <= dim; ++i) {
// mark downward entities for splitting based on the elem marks
auto dim_mark = Omega_h::mark_down(&mesh, dim, i, elem_mark);
if (i != dim) mesh.add_tag<Omega_h::Byte>(i, "refine", 1, dim_mark);
// loop through all possible added entity (product) dimensions
for (Omega_h::Int j = 0; j <= i; ++j) {
// determine the number of new entites added by the entity split
auto deg = Omega_h::hypercube_split_degree(i, j);
std::cout << "parent dim: " << i << " child dim: " << j << " deg: " << deg << std::endl;
// determine the number of entities being split
// this may need a comm for MPI parallelism?
// how does a sum on bytes actually work?? i.e. why does this work?
auto nsplit = Omega_h::get_sum(dim_mark);
// sum to the total number of new mesh entity counts
new_ent_counts[j] += deg * nsplit;
}
// write the dimesnion specific mesh out to file
// to visualize marked and marked-down entities
std::string oname = "out_tree_" + std::to_string(i);
Omega_h::vtk::Writer writer(oname, &mesh, i);
writer.write();
}
// return the total number of new entities by dimension
std::cout << std::endl;
for (Omega_h::Int i = 0; i <= dim; ++i)
std::cout << "new_ent_counts[" << i << "]: " << new_ent_counts[i] << std::endl;
return 0;
}
@bgranzow
Copy link
Author

bgranzow commented Mar 2, 2018

Marks the center element in a 3x3 2D grid for refinement

output:

parent dim: 1 child dim: 0 deg: 1
parent dim: 1 child dim: 1 deg: 2
parent dim: 2 child dim: 0 deg: 1
parent dim: 2 child dim: 1 deg: 4
parent dim: 2 child dim: 2 deg: 4

new_ent_counts[0]: 5
new_ent_counts[1]: 12
new_ent_counts[2]: 4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment