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

Created a component test for vtk writer and reader #1361

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7a483e4
Created a component test for vtk writer and reader
tunxu Jan 29, 2025
8777830
Merge branch 'main' into feature-vtk_meshreader
tunxu Jan 30, 2025
9f91688
Merged with main
tunxu Jan 30, 2025
af47744
Fixed indentation
tunxu Jan 30, 2025
f962762
search partition: add interface for replicated partition search
hannesbrandt Oct 30, 2024
5e96f63
search partition: add author file
hannesbrandt Nov 5, 2024
d9b7f60
search partition: const forest and comments
hannesbrandt Nov 5, 2024
75861d1
Design a C++ interface for search
holke Nov 8, 2024
ee06683
Add C Interface for search C++
holke Nov 8, 2024
118f8ba
Add documentation
Davknapp Nov 8, 2024
6b9a928
started implementation of search-class
Davknapp Nov 8, 2024
3e4afc4
Add file for search-implementation
Davknapp Nov 11, 2024
fc2f9b1
bug fixes
Davknapp Nov 11, 2024
4dff9fc
compiling, but buggy
Davknapp Nov 11, 2024
fa0f499
Fixed bug.
Davknapp Nov 11, 2024
9e74658
minimize example to fix memory bug
Davknapp Nov 11, 2024
aee133f
Fix Memory bug.
Davknapp Nov 12, 2024
40e1d39
Delete obsolete code
Davknapp Nov 12, 2024
3791f71
More documentation
Davknapp Nov 12, 2024
29f8a79
reorder initializer list
Davknapp Nov 12, 2024
3d4f8c5
Should be implicitly installed via installed directories
Davknapp Nov 12, 2024
f29be47
Test search without queries seperatly.
Davknapp Nov 12, 2024
639356e
Merge remote-tracking branch 'origin/feature-vtk_meshreader' into fea…
tunxu Jan 31, 2025
df9ceda
Removed unused variable
tunxu Jan 31, 2025
914893a
Merge branch 'main' into feature-vtk_meshreader
tunxu Jan 31, 2025
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
2 changes: 1 addition & 1 deletion benchmarks/t8_time_partition.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ t8_time_cmesh_translate_coordinates (t8_cmesh_t cmesh, double x, sc_MPI_Comm com
SC_CHECK_MPI (mpiret);
for (itree = 0; itree < t8_cmesh_get_num_local_trees (cmesh); itree++) {
/* loop over all trees and get a pointer to their vertices */
vertices = (double *) t8_cmesh_get_attribute (cmesh, t8_get_package_id (), 0, itree);
vertices = (double *) t8_cmesh_get_attribute (cmesh, t8_get_package_id (), T8_CMESH_VERTICES_ATTRIBUTE_KEY, itree);
eclass = t8_cmesh_get_tree_class (cmesh, itree);
for (ivertex = 0; ivertex < t8_eclass_num_vertices[eclass]; ivertex++) {
/* For each tree vertex, translate its x-coordinate */
Expand Down
34 changes: 12 additions & 22 deletions src/t8_cmesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,31 +99,16 @@ int
t8_cmesh_is_committed (const t8_cmesh_t cmesh);

#ifdef T8_ENABLE_DEBUG
/** Check the geometry of the mesh for validity.
* \param [in] cmesh This cmesh is examined.
* \return True if the geometry of the cmesh is valid.
/** Check the geometry of the mesh for validity, this means checking if trees and their geometries
* are compatible and if they have negative volume.
* \param [in] cmesh This cmesh is examined.
* \param [in] check_for_negative_volume Enable the negative volume check.
* \return True if the geometry of the cmesh is valid.
*/
int
t8_cmesh_validate_geometry (const t8_cmesh_t cmesh);
t8_cmesh_validate_geometry (const t8_cmesh_t cmesh, const int check_for_negative_volume);
#endif

/** Given a set of vertex coordinates for a tree of a given eclass.
* Query whether the geometric volume of the tree with this coordinates
* would be negative.
* \param [in] eclass The eclass of a tree.
* \param [in] vertices The coordinates of the tree's vertices.
* \param [in] num_vertices The number of vertices. \a vertices must hold
* 3 * \a num_vertices many doubles.
* \a num_vertices must match \ref t8_eclass_num_vertices[\a eclass]
* \return True if the geometric volume describe by \a vertices is negative.
* False otherwise.
* Returns true if a tree of the given eclass with the given vertex
* coordinates does have negative volume.
*/
/* TODO: write a test for this function */
int
t8_cmesh_tree_vertices_negative_volume (const t8_eclass_t eclass, const double *vertices, const int num_vertices);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think that we should remove this function entirely. Even though it is not used internally at the moment this still can be a handy function for others.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@Davknapp and I had a chat about that and it is fine that we removed it :)


/* TODO: Currently it is not possible to destroy set_from before
* cmesh is destroyed. */
/** This function sets a cmesh to be derived from.
Expand Down Expand Up @@ -350,13 +335,18 @@ t8_cmesh_set_profiling (t8_cmesh_t cmesh, int set_profiling);
* Orders, sequences, equivalences?
* This function works on committed and uncommitted cmeshes.
*/

int
t8_cmesh_is_equal (t8_cmesh_t cmesh_a, t8_cmesh_t cmesh_b);
t8_cmesh_is_equal_ext (const t8_cmesh_t cmesh_a, const t8_cmesh_t cmesh_b, const int same_tree_order);

/** Check whether a cmesh is empty on all processes.
* \param [in] cmesh A committed cmesh.
* \return True (non-zero) if and only if the cmesh has trees at all.
*/

int
t8_cmesh_is_equal (const t8_cmesh_t cmesh_a, const t8_cmesh_t cmesh_b);

int
t8_cmesh_is_empty (t8_cmesh_t cmesh);

Expand Down
186 changes: 55 additions & 131 deletions src/t8_cmesh/t8_cmesh.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ t8_cmesh_is_committed (const t8_cmesh_t cmesh)

#if T8_ENABLE_DEBUG
int
t8_cmesh_validate_geometry (const t8_cmesh_t cmesh)
t8_cmesh_validate_geometry (const t8_cmesh_t cmesh, const int check_for_negative_volume)
{
/* After a cmesh is committed, check whether all trees in a cmesh are compatible
* with their geometry and if they have positive volume.
Expand All @@ -150,7 +150,7 @@ t8_cmesh_validate_geometry (const t8_cmesh_t cmesh)
t8_debugf ("Detected incompatible geometry for tree %li\n", (long) itree);
return false;
}
if (geometry_compatible) {
else if (check_for_negative_volume) {
/* Check for negative volume. This only makes sense if the geometry is valid for the tree. */
const int negative_volume
= cmesh->geometry_handler->tree_negative_volume (cmesh, t8_cmesh_get_global_id (cmesh, itree));
Expand Down Expand Up @@ -509,107 +509,6 @@ t8_cmesh_set_tree_class (t8_cmesh_t cmesh, const t8_gloidx_t gtree_id, const t8_
#endif
}

/* Given a set of vertex coordinates for a tree of a given eclass.
* Query whether the geometric volume of the tree with this coordinates
* would be negative.
* Returns true if a tree of the given eclass with the given vertex
* coordinates does have negative volume.
*/
int
t8_cmesh_tree_vertices_negative_volume (const t8_eclass_t eclass, const double *vertices, const int num_vertices)
{
T8_ASSERT (num_vertices == t8_eclass_num_vertices[eclass]);

/* Points and lines do not have a volume orientation. */
if (t8_eclass_to_dimension[eclass] < 2) {
return 0;
}

T8_ASSERT (eclass == T8_ECLASS_TRIANGLE || eclass == T8_ECLASS_QUAD || eclass == T8_ECLASS_TET
|| eclass == T8_ECLASS_HEX || eclass == T8_ECLASS_PRISM || eclass == T8_ECLASS_PYRAMID);

/* Skip negative volume check (orientation of face normal) of 2D elements
* when z-coordinates are not (almost) zero. */
if (t8_eclass_to_dimension[eclass] < 3) {
for (int ivert = 0; ivert < num_vertices; ivert++) {
const double z_coordinate = vertices[3 * ivert + 2];
if (std::abs (z_coordinate) > 10 * T8_PRECISION_EPS) {
return false;
}
}
}

/*
* z For 2D meshes we enforce the right-hand-rule in terms
* | of node ordering. The volume is defined by the parallelepiped
* | 2- - -(3) spanned by the vectors between nodes 0:1 and 0:2 as well as the
* |/____ / unit vector in z-direction. This definition works for both triangles and quads.
* 0 1
*
* 6 ______ 7 For Hexes and pyramids, if the vertex 4 is below the 0-1-2-3 plane,
* /| / the volume is negative. This is the case if and only if
* 4 /_____5/| the scalar product of v_4 with the cross product of v_1 and v_2 is
* | | _ |_| smaller 0:
* | 2 | / 3 < v_4, v_1 x v_2 > < 0
* |/____|/
* 0 1
*
*
* For tets/prisms, if the vertex 3 is below/above the 0-1-2 plane, the volume
* is negative. This is the case if and only if
* the scalar product of v_3 with the cross product of v_1 and v_2 is
* greater 0:
*
* < v_3, v_1 x v_2 > > 0
*
*/

/* Build the vectors v_i as vertices_i - vertices_0. */
double v_1[3], v_2[3], v_j[3], cross[3], sc_prod;

if (eclass == T8_ECLASS_TRIANGLE || eclass == T8_ECLASS_QUAD) {
for (int i = 0; i < 3; i++) {
v_1[i] = vertices[3 + i] - vertices[i];
v_2[i] = vertices[6 + i] - vertices[i];
}

/* Unit vector in z-direction. */
v_j[0] = 0.0;
v_j[1] = 0.0;
v_j[2] = 1.0;

/* Compute cross = v_1 x v_2. */
t8_vec_cross (v_1, v_2, cross);
/* Compute sc_prod = <v_j, cross>. */
sc_prod = t8_vec_dot (v_j, cross);

T8_ASSERT (sc_prod != 0);
return sc_prod < 0;
}

int j;
if (eclass == T8_ECLASS_TET || eclass == T8_ECLASS_PRISM) {
/* In the tet/prism case, the third vector is v_3 */
j = 3;
}
else {
/* For pyramids and Hexes, the third vector is v_4 */
j = 4;
}
for (int i = 0; i < 3; i++) {
v_1[i] = vertices[3 + i] - vertices[i];
v_2[i] = vertices[6 + i] - vertices[i];
v_j[i] = vertices[3 * j + i] - vertices[i];
}
/* compute cross = v_1 x v_2 */
t8_vec_cross (v_1, v_2, cross);
/* Compute sc_prod = <v_j, cross> */
sc_prod = t8_vec_dot (v_j, cross);

T8_ASSERT (sc_prod != 0);
return eclass == T8_ECLASS_TET ? sc_prod > 0 : sc_prod < 0;
}

void
t8_cmesh_set_tree_vertices (t8_cmesh_t cmesh, const t8_gloidx_t gtree_id, const double *vertices,
const int num_vertices)
Expand Down Expand Up @@ -672,56 +571,81 @@ t8_cmesh_set_profiling (t8_cmesh_t cmesh, const int set_profiling)
}
}

/* returns true if cmesh_a equals cmesh_b */
int
t8_cmesh_is_equal (const t8_cmesh_t cmesh_a, const t8_cmesh_t cmesh_b)
{
return t8_cmesh_is_equal_ext (cmesh_a, cmesh_b, 1);
};

/* returns true if cmesh_a equals cmesh_b */
int
t8_cmesh_is_equal_ext (const t8_cmesh_t cmesh_a, const t8_cmesh_t cmesh_b, const int same_tree_order)
/* TODO: rewrite */
{
int is_equal;
T8_ASSERT (cmesh_a != NULL && cmesh_b != NULL);

if (cmesh_a == cmesh_b) {
return 1;
}
/* check entries that are numbers */
is_equal = cmesh_a->committed != cmesh_b->committed || cmesh_a->dimension != cmesh_b->dimension
|| cmesh_a->set_partition != cmesh_b->set_partition || cmesh_a->mpirank != cmesh_b->mpirank
|| cmesh_a->mpisize != cmesh_b->mpisize || cmesh_a->num_trees != cmesh_b->num_trees
|| cmesh_a->num_local_trees != cmesh_b->num_local_trees || cmesh_a->num_ghosts != cmesh_b->num_ghosts
|| cmesh_a->first_tree != cmesh_b->first_tree;
if (is_equal != 0) {
if (cmesh_a->committed != cmesh_b->committed || cmesh_a->dimension != cmesh_b->dimension
|| cmesh_a->set_partition != cmesh_b->set_partition || cmesh_a->mpirank != cmesh_b->mpirank
|| cmesh_a->mpisize != cmesh_b->mpisize || cmesh_a->num_trees != cmesh_b->num_trees
|| cmesh_a->num_local_trees != cmesh_b->num_local_trees || cmesh_a->num_ghosts != cmesh_b->num_ghosts
|| cmesh_a->first_tree != cmesh_b->first_tree) {
return 0;
}
/* check arrays */
is_equal
= memcmp (cmesh_a->num_trees_per_eclass, cmesh_b->num_trees_per_eclass, T8_ECLASS_COUNT * sizeof (t8_gloidx_t));
is_equal = is_equal
|| memcmp (cmesh_a->num_local_trees_per_eclass, cmesh_b->num_local_trees_per_eclass,
T8_ECLASS_COUNT * sizeof (t8_locidx_t));

/* check tree_offsets */
if (cmesh_a->tree_offsets != NULL) {
if (cmesh_b->tree_offsets == NULL) {
return 0;
}
else {
is_equal = is_equal || !t8_shmem_array_is_equal (cmesh_a->tree_offsets, cmesh_b->tree_offsets);
}
if (memcmp (cmesh_a->num_trees_per_eclass, cmesh_b->num_trees_per_eclass, T8_ECLASS_COUNT * sizeof (t8_gloidx_t))) {
return 0;
}
if (is_equal != 0) {

if (memcmp (cmesh_a->num_local_trees_per_eclass, cmesh_b->num_local_trees_per_eclass,
T8_ECLASS_COUNT * sizeof (t8_locidx_t))) {
return 0;
}

if (same_tree_order) {
/* check tree_offsets */
if (cmesh_a->tree_offsets != NULL) {
if (cmesh_b->tree_offsets == NULL) {
return 0;
}
else {
if (!t8_shmem_array_is_equal (cmesh_a->tree_offsets, cmesh_b->tree_offsets))
return 0;
}
}
}
/* check trees */
if (cmesh_a->committed && !t8_cmesh_trees_is_equal (cmesh_a, cmesh_a->trees, cmesh_b->trees)) {
/* if we have committed check tree arrays */
return 0;
if (same_tree_order) {
if (cmesh_a->committed && !t8_cmesh_trees_is_equal (cmesh_a, cmesh_a->trees, cmesh_b->trees, 1)) {
/* if we have committed check tree arrays */
t8_global_productionf ("Failed on equal trees");
return 0;
}
else {
if (!cmesh_a->committed && !t8_stash_is_equal (cmesh_a->stash, cmesh_b->stash)) {
/* if we have not committed check stash arrays */
return 0;
}
}
}
else {
if (!cmesh_a->committed && !t8_stash_is_equal (cmesh_a->stash, cmesh_b->stash)) {
/* if we have not committed check stash arrays */
if (cmesh_a->committed && !t8_cmesh_trees_is_equal (cmesh_a, cmesh_a->trees, cmesh_b->trees, 0)) {
/* if we have committed check tree arrays */
t8_global_productionf ("Failed on equal trees %i",
t8_cmesh_trees_is_equal (cmesh_a, cmesh_a->trees, cmesh_b->trees, 0));
return 0;
}
else {
if (!cmesh_a->committed && !t8_stash_is_equal (cmesh_a->stash, cmesh_b->stash)) {
/* if we have not committed check stash arrays */
return 0;
}
}
}

return 1;
}

Expand Down
2 changes: 1 addition & 1 deletion src/t8_cmesh/t8_cmesh_commit.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ t8_cmesh_commit (t8_cmesh_t cmesh, sc_MPI_Comm comm)
(long) cmesh->num_local_trees, (long long) cmesh->num_trees, (long) cmesh->num_ghosts);

T8_ASSERT (t8_cmesh_is_committed (cmesh));
T8_ASSERT (t8_cmesh_validate_geometry (cmesh));
T8_ASSERT (t8_cmesh_validate_geometry (cmesh, 0));
/* If profiling is enabled, we measure the runtime of commit. */
if (cmesh->profile != NULL) {
cmesh->profile->commit_runtime = sc_MPI_Wtime () - cmesh->profile->commit_runtime;
Expand Down
Loading
Loading