Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature new for hybrid #768

Open
wants to merge 57 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
b8e3dd4
Add cmesh uniform bounds for hybrid meshes.
Sep 23, 2022
553747c
Add all missing functions to make code compilable
Sep 23, 2022
4616091
Add example
Sep 23, 2022
a853e40
move is_irregular function and use hybrid_bounds only when a forest r…
Sep 23, 2022
6021fe4
Some optimization
Sep 23, 2022
c4d4b3b
use t8_cmesh_uniform_bounds_hybrid in cmesh_partition
Sep 23, 2022
f271d06
Update variables according to their scope and made them const
Sep 23, 2022
9e103cc
Merge branch 'main' into feature-New_for_hybrid
Nov 2, 2022
d15062e
Update to current main and indentation
Nov 3, 2022
f026cde
Merge remote-tracking branch 'origin/main' into feature-New_for_hybrid
Mar 20, 2023
c6d505e
Merge Clean-up
Mar 20, 2023
b95c49a
Merge remote-tracking branch 'origin/main' into feature-New_for_hybrid
Davknapp Apr 13, 2023
104da7c
Merge remote-tracking branch 'origin/main' into feature-New_for_hybrid
Davknapp Sep 25, 2023
7c90788
Add missing \ to Makefile
Davknapp Sep 25, 2023
ce05a7d
Update headers used in example
Davknapp Sep 25, 2023
4add0d6
Use hybrid_bounds algorithms
Davknapp Sep 25, 2023
18ebd66
Merge remote-tracking branch 'origin/main' into feature-New_for_hybrid
Davknapp Oct 23, 2023
1ef18ed
WIP: Debugging cmesh_uniform_bounds_hybrid
Davknapp Oct 23, 2023
58892c8
Fix special cases for empty procs
lukasdreyer Oct 25, 2023
8ce611e
Reintroduce cmeshes with pyramids
lukasdreyer Oct 26, 2023
cbbb980
Fix number of vertices for pyramid cmesh
lukasdreyer Oct 26, 2023
4c26c2f
Fix compiler warnings
lukasdreyer Oct 26, 2023
255fea7
Fix more compiler errors
lukasdreyer Oct 26, 2023
a8314dc
Clean-up
Davknapp Oct 26, 2023
7b22fa0
Merge remote-tracking branch 'origin/main' into feature-New_for_hybrid
Davknapp Oct 26, 2023
1a2fbef
Added comment to refinement criterion
Davknapp Nov 13, 2023
69fdaf0
Explain formulas in adapt-criterion
Davknapp Nov 13, 2023
916cfdf
Comment adaptation criterion
Davknapp Nov 13, 2023
6cda8b8
Add description
Davknapp Nov 13, 2023
f71b9d1
Update description
Davknapp Nov 13, 2023
2402031
Comment and clean up
Davknapp Nov 13, 2023
2ce5b2c
Apply suggestions from code review
Davknapp Nov 13, 2023
49fb50c
WIP: Minimize example
Davknapp Nov 14, 2023
b2f81b9
Added description to t8_cmesh_uniform_bounds_hybrid
Davknapp Nov 16, 2023
800b716
More const
Davknapp Nov 16, 2023
bf2ca8d
Merge remote-tracking branch 'origin/main' into feature-New_for_hybrid
Davknapp Nov 16, 2023
a49cbc8
Merge
Davknapp Jan 26, 2024
408954d
Rename function, add assertion
Davknapp Jan 26, 2024
d0539e6
refactor function
Davknapp Jan 26, 2024
69aae13
Apply suggestions from code review
Davknapp Jan 29, 2024
229a1dc
Indentation
Davknapp Jan 29, 2024
f7abc12
Merge remote-tracking branch 'origin/main' into feature-New_for_hybrid
Davknapp Feb 13, 2024
cf728e8
Resolve merge errors
Davknapp Feb 13, 2024
b92817d
Typo fix
Davknapp Feb 13, 2024
fa967f6
Rename t8_cmesh_uniform_bounds_hybrid
Davknapp Feb 13, 2024
294f50c
Merge remote-tracking branch 'origin/main' into feature-New_for_hybrid
Davknapp Feb 14, 2024
f8b39d5
Remove comment
Davknapp Feb 14, 2024
ce649eb
Update to main
Davknapp Feb 14, 2024
ef97012
Clean-up
Davknapp Feb 14, 2024
24ca4e9
Simplification of determining send_first
Davknapp Feb 14, 2024
e78a262
break off uniform_bound_from_partition
Davknapp Feb 14, 2024
1cddf65
Seperate sending start message
Davknapp Feb 14, 2024
6ab9dfa
update cmesh_bounds_send_start
Davknapp Feb 15, 2024
1a6df19
Merge remote-tracking branch 'origin/main' into feature-New_for_hybrid
Davknapp Feb 15, 2024
14af446
Merge remote-tracking branch 'origin/main' into feature-New_for_hybrid
Davknapp Apr 2, 2024
27da81d
Merge remote-tracking branch 'origin/main' into feature-New_for_hybrid
Davknapp Apr 4, 2024
621969d
Merge remote-tracking branch 'origin/main' into feature-New_for_hybrid
Davknapp May 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions example/cmesh/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ bin_PROGRAMS += \
example/cmesh/t8_cmesh_partition \
example/cmesh/t8_cmesh_create_partitioned \
example/cmesh/t8_cmesh_refine \
example/cmesh/t8_cmesh_hybrid_new \
example/cmesh/t8_cmesh_set_join_by_vertices \
example/cmesh/t8_cmesh_geometry_examples \
example/cmesh/t8_cmesh_hypercube_pad
Expand All @@ -15,4 +16,6 @@ example_cmesh_t8_cmesh_refine_SOURCES = example/cmesh/t8_cmesh_refine.cxx
example_cmesh_t8_cmesh_set_join_by_vertices_SOURCES = example/cmesh/t8_cmesh_set_join_by_vertices.cxx
example_cmesh_t8_cmesh_geometry_examples_SOURCES = example/cmesh/t8_cmesh_geometry_examples.cxx
example_cmesh_t8_cmesh_create_partitioned_SOURCES = example/cmesh/t8_cmesh_create_partitioned.cxx
example_cmesh_t8_cmesh_hybrid_new_SOURCES = example/cmesh/t8_cmesh_hybrid_new.cxx
example_cmesh_t8_cmesh_hypercube_pad_SOURCES = example/cmesh/t8_cmesh_hypercube_pad.cxx

327 changes: 327 additions & 0 deletions example/cmesh/t8_cmesh_hybrid_new.cxx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment to the file what this example demonstrates.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still open

Original file line number Diff line number Diff line change
@@ -0,0 +1,327 @@
/*
This file is part of t8code.
t8code is a C library to manage a collection (a forest) of multiple
connected adaptive space-trees of general element types in parallel.

Copyright (C) 2015 the developers

t8code is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

t8code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with t8code; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include <sc_options.h>
#include <sc_flops.h>
#include <sc_refcount.h>
#include <t8_schemes/t8_default/t8_default_cxx.hxx>
#include <t8_schemes/t8_default/t8_default_tet/t8_dtet.h>
#include <t8_schemes/t8_default/t8_default_prism/t8_dprism.h>
#include <t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid.h>
#include <t8_forest/t8_forest.h>
#include <t8_cmesh/t8_cmesh_examples.h>
#include <t8_cmesh/t8_cmesh_partition.h>
#include <t8_cmesh_readmshfile.h>
#include <t8_cmesh_vtk_writer.h>
#include <sc_statistics.h>

holke marked this conversation as resolved.
Show resolved Hide resolved
static int
t8_basic_hybrid_refine (t8_forest_t forest, t8_forest_t forest_from, t8_locidx_t which_tree, t8_locidx_t lelement_id,
t8_eclass_scheme_c *ts, int is_family, int num_elements, t8_element_t *elements[])
{
int level, id;
level = ts->t8_element_level (elements[0]);
if (level >= *(int *) t8_forest_get_user_data (forest)) {
return 0;
}
else {
switch (ts->t8_element_shape (elements[0])) {
case T8_ECLASS_HEX:
id = ts->t8_element_child_id (elements[0]);
return id % 2 == 0 ? 1 : 0;
case T8_ECLASS_TET:
id = ts->t8_element_child_id (elements[0]);
return id % 2 == 0 ? 1 : 0;
case T8_ECLASS_PRISM:
id = ts->t8_element_child_id (elements[0]);
return id % 2 == 0 ? 1 : 0;
holke marked this conversation as resolved.
Show resolved Hide resolved
case T8_ECLASS_PYRAMID:
return 1;
default:
return 1;
}
}
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment what this function does.

static int
t8_basic_cake_refine (t8_forest_t forest, t8_forest_t forest_from, t8_locidx_t which_tree, t8_locidx_t lelement_id,
t8_eclass_scheme_c *ts, int is_family, int num_elements, t8_element_t *elements[])
{
int level, type;
level = ts->t8_element_level (elements[0]);
if (level >= *(int *) t8_forest_get_user_data (forest)) {
return 0;
}
else {
int32_t h = T8_DPYRAMID_LEN (level);
switch (ts->t8_element_shape (elements[0])) {
case T8_ECLASS_TET:
type = ((t8_dtet_t *) elements[0])->type;
if (type == 0 || type == 2 || type == 4) {
return 1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please comment.
What is happening here?

}
else {
return 0;
}
case T8_ECLASS_PYRAMID:

if (!(((t8_dpyramid_t *) elements[0])->pyramid.x & h)) {
type = ((t8_dpyramid_t *) elements[0])->pyramid.type;
return type == 6 ? 1 : 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment

}
else {
return 0;
}
default:
return 1;
}
}
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this function do? Comment

static int
t8_basic_only_pyramid (t8_forest_t forest, t8_forest_t forest_from, t8_locidx_t which_tree, t8_locidx_t lelement_id,
t8_eclass_scheme_c *ts, int is_family, int num_elements, t8_element_t *elements[])
{
int level;
level = ts->t8_element_level (elements[0]);
if (level >= *(int *) t8_forest_get_user_data (forest)) {
return 0;
}
else if (ts->t8_element_shape (elements[0]) == T8_ECLASS_PYRAMID) {
return 1;
}
else {
return 0;
}
}

static void
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function seems very long and full of features.
Are they all necessary to demonstrate the hybrid_new function?
Can we shorten this function or write a shorter example?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example: Do we really need a switch for cmesh partition or can we just stick to one mode in this example.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I slimmed down the example

t8_basic_hybrid (int level, int endlvl, int do_vtk, t8_eclass_t eclass, int num_elements, int mesh, int balance,
Copy link
Collaborator

@holke holke Nov 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please comment the code.
This function has over 130 lines and only a single comment.

const char *prefix, int part)
{
t8_forest_t forest, forest_adapt, forest_partition;
t8_cmesh_t cmesh, cmesh_partition;
char vtuname[BUFSIZ], cmesh_file[BUFSIZ];
int mpirank, mpiret;
double new_time = 0, adapt_time = 0, ghost_time = 0, partition_time = 0, total_time = 0, balance_time = 0;
sc_statinfo_t times[6];
int procs_sent, balance_rounds;
t8_locidx_t ghost_sent;
sc_stats_init (&times[0], "new");
sc_stats_init (&times[1], "adapt");
sc_stats_init (&times[2], "ghost");
sc_stats_init (&times[3], "partition");
sc_stats_init (&times[4], "balance");
sc_stats_init (&times[5], "total");
total_time -= sc_MPI_Wtime ();
switch (mesh) {
case 0:
t8_global_productionf ("Constructing cake mesh with %i pyramids.\n", num_elements);
cmesh = t8_cmesh_new_pyramid_cake (sc_MPI_COMM_WORLD, num_elements);
break;
case 1:
t8_global_productionf ("Constructing full hybrid mesh.\n");
cmesh = t8_cmesh_new_full_hybrid (sc_MPI_COMM_WORLD);
break;
case 2:
t8_global_productionf ("Constructing long brick out of %i pyramids.\n", num_elements);
cmesh = t8_cmesh_new_long_brick_pyramid (sc_MPI_COMM_WORLD, num_elements);
break;
case 3:
t8_global_productionf ("Constructing mesh from: %s.\n", prefix);
cmesh = t8_cmesh_from_msh_file ((char *) prefix, 0, sc_MPI_COMM_WORLD, 3, 0, 0);
break;
case 4:
t8_global_productionf ("Constructing bigmesh with %i elements.\n", num_elements);
cmesh = t8_cmesh_new_bigmesh (eclass, num_elements, sc_MPI_COMM_WORLD);
break;
case 5:
t8_global_productionf ("Constructing a single %s.\n", t8_eclass_to_string[eclass]);
cmesh = t8_cmesh_new_from_class (eclass, sc_MPI_COMM_WORLD);
break;
default:
SC_ABORT ("NO CMESH");
return;
}

mpiret = sc_MPI_Comm_rank (sc_MPI_COMM_WORLD, &mpirank);
SC_CHECK_MPI (mpiret);
if (part) {
t8_cmesh_init (&cmesh_partition);
t8_cmesh_set_derive (cmesh_partition, cmesh);
t8_cmesh_set_partition_uniform (cmesh_partition, level, t8_scheme_new_default_cxx ());
t8_cmesh_commit (cmesh_partition, sc_MPI_COMM_WORLD);
cmesh = cmesh_partition;
}
snprintf (cmesh_file, BUFSIZ, "cmesh_hybrid");
snprintf (vtuname, BUFSIZ, "cmesh_hybrid");
if (mesh != 4) {
t8_cmesh_save (cmesh, cmesh_file);
if (t8_cmesh_vtk_write_file (cmesh, vtuname, 1.0) == 0) {
t8_debugf ("Output to %s\n", vtuname);
}
else {
t8_debugf ("Error in output\n");
}
}

t8_debugf ("[D] start forest\n");
t8_forest_init (&forest);
t8_forest_set_profiling (forest, 1);
t8_forest_set_cmesh (forest, cmesh, sc_MPI_COMM_WORLD);
t8_forest_set_scheme (forest, t8_scheme_new_default_cxx ());
t8_forest_set_level (forest, level);
new_time -= sc_MPI_Wtime ();
t8_forest_commit (forest);
new_time += sc_MPI_Wtime ();
if (do_vtk) {
snprintf (vtuname, BUFSIZ, "forest_hybrid");
t8_forest_write_vtk (forest, vtuname);
t8_debugf ("[D] output to %s\n", vtuname);
}
t8_forest_init (&forest_adapt);
t8_forest_set_user_data (forest_adapt, &endlvl);
t8_forest_set_profiling (forest_adapt, 1);
if (eclass == T8_ECLASS_PYRAMID) {
t8_debugf ("Use cake-adapt\n");
t8_forest_set_adapt (forest_adapt, forest, t8_basic_cake_refine, 1);
}
else {
t8_forest_set_adapt (forest_adapt, forest, t8_basic_hybrid_refine, 1);
}
//t8_forest_set_ghost_ext(forest_adapt, 1, T8_GHOST_FACES, 2);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you delete this line?

adapt_time -= sc_MPI_Wtime ();
t8_forest_commit (forest_adapt);
adapt_time += sc_MPI_Wtime ();
//t8_debugf ("Successfully adapted forest.\n");
//snprintf (vtuname, BUFSIZ, "forest_hybrid_refine");
//t8_forest_write_vtk (forest_adapt, vtuname);
//t8_debugf ("Output to %s\n", vtuname);
//t8_forest_unref(&forest_adapt);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you delete these?

/* Ensure that the correct forest is passed to unref later */

t8_forest_init (&forest_partition);
t8_forest_set_partition (forest_partition, forest_adapt, 0);
t8_forest_set_ghost (forest_partition, 1, T8_GHOST_FACES);
if (balance) {
t8_forest_set_balance (forest_partition, forest_adapt, 1);
}
t8_forest_set_profiling (forest_partition, 1);
t8_forest_commit (forest_partition);
if (do_vtk) {
snprintf (vtuname, BUFSIZ, "forest_hybrid_partition");
t8_forest_write_vtk (forest_partition, vtuname);
t8_debugf ("Output to %s\n", vtuname);
}
t8_forest_print_profile (forest_partition);
partition_time += t8_forest_profile_get_partition_time (forest_partition, &procs_sent);
ghost_time += t8_forest_profile_get_ghost_time (forest_partition, &ghost_sent);
balance_time += t8_forest_profile_get_balance_time (forest_partition, &balance_rounds);
total_time += sc_MPI_Wtime ();

sc_stats_accumulate (&times[0], new_time);
sc_stats_accumulate (&times[1], adapt_time);
sc_stats_accumulate (&times[2], ghost_time);
sc_stats_accumulate (&times[3], partition_time);
sc_stats_accumulate (&times[4], balance_time);
sc_stats_accumulate (&times[5], total_time);
sc_stats_compute (sc_MPI_COMM_WORLD, 6, times);
sc_stats_print (t8_get_package_id (), SC_LP_ESSENTIAL, 6, times, 1, 1);

t8_forest_unref (&forest_partition);
}

int
main (int argc, char **argv)
{
int mpiret, parsed;
int level, endlvl, helpme, do_vtk, eclass_int, mesh, elements, balance, part;
t8_eclass_t eclass;
sc_options_t *opt;
char usage[BUFSIZ];
char help[BUFSIZ];
const char *file;

/* brief help message */
snprintf (usage, BUFSIZ,
"Usage:\t%s <OPTIONS>\n\t%s -h\t"
"for a brief overview of all options.",
basename (argv[0]), basename (argv[0]));

/* long help message */
snprintf (help, BUFSIZ, "ADD EXAMPLE DESCRIPTION.\n\n%s\n", usage);
mpiret = sc_MPI_Init (&argc, &argv);
SC_CHECK_MPI (mpiret);

sc_init (sc_MPI_COMM_WORLD, 1, 1, NULL, SC_LP_ESSENTIAL);
t8_init (SC_LP_DEFAULT);

opt = sc_options_new (argv[0]);
sc_options_add_switch (opt, 'h', "help", &helpme, "Display a short help message.");
sc_options_add_int (opt, 'l', "level", &level, 0, "The refinement level of the mesh.");
sc_options_add_int (opt, 'f', "final-level", &endlvl, 1, "The final refinement level of the mesh.");
sc_options_add_switch (opt, 'v', "vtk", &do_vtk, "Enable vtk-output.");
sc_options_add_switch (opt, 'b', "balance", &balance, "Enable balance");
sc_options_add_switch (opt, 'p', "partition", &part, "Enable cmesh-partition");
sc_options_add_int (opt, 'e', "element", &eclass_int, 4,
"Given an element-class, the program will "
" construct a single element of this class. Is ignored, if the option cake is chosen."
"The type of elements to use.\n"
"\t\t4 - hexahedron\n"
"\t\t5 - tetrahedron\n\t\t6 - prism\n\t\t7 - pyramid");
sc_options_add_int (opt, 'm', "mesh", &mesh, 5,
"A mesh to choose from."
" The meshes to chose from are: \n"
"\t\t0 - cake of pyramids\n\t\t1 - hybrid mesh with all 3D elements"
"\n\t\t2 - a long row of bricks out of pyramids"
"\n\t\t3 - user-specific mesh-file"
"\n\t\t4 - construct multiple elements of class given by -e"
"\n\t\t5 - a single element of class -e");
sc_options_add_int (opt, 'n', "num_elements", &elements, 3,
"The number of elements to use"
" if a m0 or m4 is build. Has to be larger than 2.");
sc_options_add_string (opt, 'g', "mshfile", &file, "NULL", "Prefix of the msh-file.");

parsed = sc_options_parse (t8_get_package_id (), SC_LP_DEFAULT, opt, argc, argv);
if (helpme) {
/* display help message and usage */
t8_global_productionf ("%s\n", help);
sc_options_print_usage (t8_get_package_id (), SC_LP_ERROR, opt, NULL);
}
else if (parsed >= 0 && 0 <= level && 4 <= eclass_int && eclass_int < T8_ECLASS_COUNT && elements >= 2 && 0 <= mesh
&& mesh < 6) {
eclass = (t8_eclass_t) eclass_int;
t8_basic_hybrid (level, endlvl, do_vtk, eclass, elements, mesh, balance, file, part);
}
else {
/* wrong usage */
t8_global_productionf ("\n\t ERROR: Wrong usage.\n\n");
sc_options_print_usage (t8_get_package_id (), SC_LP_ERROR, opt, NULL);
}
sc_options_destroy (opt);
sc_finalize ();

mpiret = sc_MPI_Finalize ();
SC_CHECK_MPI (mpiret);

return 0;
}
7 changes: 7 additions & 0 deletions src/t8.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,10 @@ t8_sc_array_index_locidx (sc_array_t *array, t8_locidx_t it)

return array->array + array->elem_size * (size_t) it;
}

void *
t8_sc_array_index_gloidx (sc_array_t *array, t8_gloidx_t it)
{
T8_ASSERT (it >= 0 && (size_t) it < array->elem_count);
return array->array + array->elem_size * (size_t) it;
}
11 changes: 11 additions & 0 deletions src/t8.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ typedef int64_t t8_gloidx_t;
#define T8_MPI_GLOIDX sc_MPI_LONG_LONG_INT
/** Macro to get the absolute value of a t8_gloidx_t */
#define T8_GLOIDX_ABS(x) ((t8_gloidx_t) llabs ((long long) (x)))
/** Maximum possible value of a t8_gloidx_t*/
#define T8_GLOIDX_MAX INT64_MAX
/** Comparison function for t8_gloidx_t */
#define t8_compare_gloidx(v, w) sc_int64_compare (v, w)

Expand Down Expand Up @@ -129,6 +131,8 @@ typedef enum {
T8_MPI_PARTITION_FOREST, /**< Used for forest partitioning */
T8_MPI_GHOST_FOREST, /**< Used for for ghost layer creation */
T8_MPI_GHOST_EXC_FOREST, /**< Used for ghost data exchange */
T8_MPI_CMESH_UNIFORM_BOUNDS_START, /**< Used for cmesh uniform bounds computation. */
T8_MPI_CMESH_UNIFORM_BOUNDS_END, /**< Used for cmesh uniform bounds computation. */
T8_MPI_TAG_LAST
} t8_MPI_tag_t;

Expand Down Expand Up @@ -266,6 +270,13 @@ t8_init (int log_threshold);
void *
t8_sc_array_index_locidx (sc_array_t *array, t8_locidx_t it);

/** Return a pointer to an array element indexed by a t8_gloidx_t.
* \param [in] index needs to be in [0]..[elem_count-1].
* \return A void * pointing to entry \a it in \a array.
*/
void *
t8_sc_array_index_gloidx (sc_array_t *array, t8_gloidx_t it);

/* call this at the end of a header file to match T8_EXTERN_C_BEGIN (). */
T8_EXTERN_C_END ();

Expand Down
Loading
Loading