commit 82fb7a980b0a90b7ee3b9a106324f4336910e16d
parent 7137530d59a5ba18c6f1d75d437ce4c5fc4f06eb
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 14 Mar 2022 16:20:00 +0100
Test the load API
Diffstat:
2 files changed, 257 insertions(+), 1 deletion(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -82,7 +82,7 @@ if(NOT NO_TEST)
endfunction()
new_test(test_smsh)
- #new_test(test_smsh_load)
+ new_test(test_smsh_load)
endif()
################################################################################
diff --git a/src/test_smsh_load.c b/src/test_smsh_load.c
@@ -0,0 +1,256 @@
+/* Copyright (C) 2020, 2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "smsh.h"
+
+#include <rsys/double3.h>
+#include <rsys/math.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/rsys.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+check_smsh_desc
+ (const struct smsh_desc* desc,
+ const uint64_t nnodes,
+ const uint64_t ncells,
+ const uint64_t dnode,
+ const uint64_t dcell)
+{
+ size_t i, j;
+ CHK(desc);
+ CHK(nnodes);
+ CHK(ncells);
+ CHK(dnode);
+ CHK(dcell);
+
+ CHK(desc->nnodes == nnodes);
+ CHK(desc->ncells == ncells);
+ CHK(desc->dnode == dnode);
+ CHK(desc->dcell == dcell);
+
+ FOR_EACH(i, 0, nnodes) {
+ const double* node0 = desc->nodes + i*dnode;
+ const double* node1 = smsh_desc_get_node(desc, i);
+ FOR_EACH(j, 0, dnode) {
+ CHK(node0[j] == node1[j]);
+ CHK(node0[j] == (double)i + (double)j*0.1);
+ }
+ }
+
+ FOR_EACH(i, 0, ncells) {
+ const uint64_t* cell0 = desc->cells + i*dcell;
+ const uint64_t* cell1 = smsh_desc_get_cell(desc, i);
+ FOR_EACH(j, 0, dcell) {
+ CHK(cell0[j] == cell1[j]);
+ CHK(cell0[j] == (i*dcell+j)%nnodes);
+ }
+ }
+}
+
+static void
+test_load_tetrahedra(struct smsh* smsh)
+{
+ struct smsh_desc desc = SMSH_DESC_NULL;
+ FILE* fp = NULL;
+ const char* filename = "test_file.smsh";
+ const uint64_t pagesize = 16384;
+ const uint64_t nnodes = 287;
+ const uint64_t ncells = 192;
+ const unsigned dnode = 3;
+ const unsigned dcell = 3;
+ size_t i;
+ char byte = 0;
+ ASSERT(smsh);
+
+ fp = fopen(filename, "w+");
+ CHK(fp);
+
+ /* Write file header */
+ CHK(fwrite(&pagesize, sizeof(pagesize), 1, fp) == 1);
+ CHK(fwrite(&nnodes, sizeof(nnodes), 1, fp) == 1);
+ CHK(fwrite(&ncells, sizeof(ncells), 1, fp) == 1);
+ CHK(fwrite(&dnode, sizeof(dnode), 1, fp) == 1);
+ CHK(fwrite(&dcell, sizeof(dcell), 1, fp) == 1);
+
+ /* Padding */
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET) == 0);
+
+ /* Write vertex nodes */
+ FOR_EACH(i, 0, nnodes) {
+ double pos[3];
+ pos[0] = (double)i + 0.0;
+ pos[1] = (double)i + 0.1;
+ pos[2] = (double)i + 0.2;
+ CHK(fwrite(pos, sizeof(*pos), 3, fp) == 3);
+ }
+
+ /* Padding */
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET) == 0);
+
+ /* Write tetrahedra */
+ FOR_EACH(i, 0, ncells) {
+ uint64_t ids[4];
+ ids[0] = (i*4 + 0) % nnodes;
+ ids[1] = (i*4 + 1) % nnodes;
+ ids[2] = (i*4 + 2) % nnodes;
+ ids[3] = (i*4 + 3) % nnodes;
+ CHK(fwrite(ids, sizeof(*ids), 4, fp) == 4);
+ }
+
+ /* Padding. Write one char to position the EOF indicator */
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize)-1, SEEK_SET) == 0);
+ CHK(fwrite(&byte, sizeof(byte), 1, fp) == 1);
+
+ rewind(fp);
+ CHK(smsh_load_stream(NULL, fp, filename) == RES_BAD_ARG);
+ CHK(smsh_load_stream(smsh, NULL, filename) == RES_BAD_ARG);
+ CHK(smsh_load_stream(smsh, fp, NULL) == RES_OK);
+ CHK(smsh_get_desc(NULL, &desc) == RES_BAD_ARG);
+ CHK(smsh_get_desc(smsh, NULL) == RES_BAD_ARG);
+ CHK(smsh_get_desc(smsh, &desc) == RES_OK);
+ check_smsh_desc(&desc, nnodes, ncells, dnode, dcell);
+
+ rewind(fp);
+ CHK(smsh_load_stream(smsh, fp, filename) == RES_OK);
+ check_smsh_desc(&desc, nnodes, ncells, dnode, dcell);
+
+ CHK(smsh_load(NULL, filename) == RES_BAD_ARG);
+ CHK(smsh_load(smsh, NULL) == RES_BAD_ARG);
+ CHK(smsh_load(smsh, "nop") == RES_IO_ERR);
+ CHK(smsh_load(smsh, filename) == RES_OK);
+ check_smsh_desc(&desc, nnodes, ncells, dnode, dcell);
+
+ fclose(fp);
+}
+
+static void
+test_load_fail(struct smsh* smsh)
+{
+ const char byte = 0;
+ FILE* fp = NULL;
+ uint64_t pagesize;
+ uint64_t nnodes;
+ uint64_t ncells;
+ unsigned dnode;
+ unsigned dcell;
+
+ /* Wrong pagesize */
+ fp = tmpfile();
+ CHK(fp);
+ pagesize = 1023;
+ nnodes = 10;
+ ncells = 10;
+ dnode = 3;
+ dcell = 4;
+ CHK(fwrite(&pagesize, sizeof(pagesize), 1, fp) == 1);
+ CHK(fwrite(&nnodes, sizeof(nnodes), 1, fp) == 1);
+ CHK(fwrite(&ncells, sizeof(ncells), 1, fp) == 1);
+ CHK(fwrite(&dnode, sizeof(dnode), 1, fp) == 1);
+ CHK(fwrite(&dcell, sizeof(dcell), 1, fp) == 1);
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET) == 0);
+ CHK(fseek(fp, (long)(sizeof(double[3])*nnodes), SEEK_CUR) == 0);
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET) == 0);
+ CHK(fseek(fp, (long)(sizeof(uint64_t[4])*ncells), SEEK_CUR) == 0);
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize)-1, SEEK_SET) == 0);
+ CHK(fwrite(&byte, sizeof(byte), 1, fp) == 1);
+ rewind(fp);
+ CHK(smsh_load_stream(smsh, fp, NULL) == RES_BAD_ARG);
+ fclose(fp);
+
+ /* Wrong size */
+ fp = tmpfile();
+ CHK(fp);
+ pagesize = (uint64_t)sysconf(_SC_PAGESIZE);
+ nnodes = 10;
+ ncells = 10;
+ dnode = 3;
+ dcell = 4;
+ CHK(fwrite(&pagesize, sizeof(pagesize), 1, fp) == 1);
+ CHK(fwrite(&nnodes, sizeof(nnodes), 1, fp) == 1);
+ CHK(fwrite(&ncells, sizeof(ncells), 1, fp) == 1);
+ CHK(fwrite(&dnode, sizeof(dnode), 1, fp) == 1);
+ CHK(fwrite(&dcell, sizeof(dcell), 1, fp) == 1);
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET) == 0);
+ CHK(fseek(fp, (long)(sizeof(double[3])*nnodes), SEEK_CUR) == 0);
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET) == 0);
+ CHK(fseek(fp, (long)(sizeof(uint64_t[4])*ncells), SEEK_CUR) == 0);
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize)-2, SEEK_SET) == 0);
+ CHK(fwrite(&byte, sizeof(byte), 1, fp) == 1);
+ rewind(fp);
+ CHK(smsh_load_stream(smsh, fp, NULL) == RES_IO_ERR);
+ fclose(fp);
+}
+
+static void
+test_load_files(struct smsh* smsh, int argc, char** argv)
+{
+ int i;
+ CHK(smsh);
+ FOR_EACH(i, 1, argc) {
+ struct smsh_desc desc = SMSH_DESC_NULL;
+ size_t inode;
+ size_t icell;
+
+ printf("Load %s\n", argv[i]);
+ CHK(smsh_load(smsh, argv[i]) == RES_OK);
+ CHK(smsh_get_desc(smsh, &desc) == RES_OK);
+
+ FOR_EACH(inode, 0, desc.nnodes) {
+ const double* pos = smsh_desc_get_node(&desc, inode);
+ CHK(pos[0] == pos[0]); /* !NaN */
+ CHK(pos[1] == pos[1]); /* !NaN */
+ CHK(pos[2] == pos[2]); /* !NaN */
+ CHK(!IS_INF(pos[0]));
+ CHK(!IS_INF(pos[1]));
+ CHK(!IS_INF(pos[2]));
+ }
+ FOR_EACH(icell, 0, desc.ncells) {
+ const uint64_t* ids = smsh_desc_get_cell(&desc, icell);
+ /* Check non degenerated tetrahedron */
+ CHK(ids[0] != ids[1]);
+ CHK(ids[0] != ids[2]);
+ CHK(ids[0] != ids[3]);
+ CHK(ids[1] != ids[2]);
+ CHK(ids[1] != ids[3]);
+ CHK(ids[2] != ids[3]);
+ }
+ }
+}
+
+/*******************************************************************************
+ * Main function
+ ******************************************************************************/
+int
+main(int argc, char** argv)
+{
+ struct smsh_create_args args = SMSH_CREATE_ARGS_DEFAULT;
+ struct smsh* smsh = NULL;
+ (void)argc, (void)argv;
+
+ CHK(smsh_create(&args, &smsh) == RES_OK);
+
+ test_load_tetrahedra(smsh);
+ test_load_fail(smsh);
+ test_load_files(smsh, argc, argv);
+
+ CHK(smsh_ref_put(smsh) == RES_OK);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}