diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml new file mode 100644 index 0000000..652140b --- /dev/null +++ b/.github/workflows/build-and-test.yaml @@ -0,0 +1,69 @@ +# Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at +# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights +# reserved. See files LICENSE and NOTICE for details. +# +# This file is part of CEED, a collection of benchmarks, miniapps, software +# libraries and APIs for efficient high-order finite element and spectral +# element discretizations for exascale applications. For more information and +# source code availability see http://github.com/ceed. +# +# The CEED research is supported by the Exascale Computing Project (17-SC-20-SC) +# a collaborative effort of two U.S. Department of Energy organizations (Office +# of Science and the National Nuclear Security Administration) responsible for +# the planning and preparation of a capable exascale ecosystem, including +# software, applications, hardware, advanced system engineering and early +# testbed platforms, in support of the nation's exascale computing imperative. + +name: Build and test + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +env: + BUILD_C_FLAGS: -Wall -Wextra -pedantic -Werror + BUILD_CXX_FLAGS: -Wall -Wextra -pedantic -Werror + +jobs: + build-and-test: + runs-on: ${{matrix.os}} + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + build-type: [Debug, Release] + name: ${{matrix.os}}-${{matrix.build-type}} + + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + + - name: Configure + run: | + cmake \ + -B ${{github.workspace}}/build \ + -DCMAKE_BUILD_TYPE=${{matrix.build-type}} \ + -DFMS_ENABLE_TESTS=ON \ + -DCMAKE_C_FLAGS="$BUILD_C_FLAGS" \ + -DCMAKE_CXX_FLAGS="$BUILD_CXX_FLAGS" \ + -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install \ + -DCMAKE_VERBOSE_MAKEFILE=ON + + - name: Build + run: | + cmake \ + --build ${{github.workspace}}/build \ + --config ${{matrix.build-type}} + + - name: Install + run: | + cmake \ + --build ${{github.workspace}}/build \ + --config ${{matrix.build-type}} \ + --target install + + - name: Test + working-directory: ${{github.workspace}}/build + run: ctest -C ${{matrix.build-type}} --output-on-failure diff --git a/.github/workflows/check-style.yaml b/.github/workflows/check-style.yaml new file mode 100644 index 0000000..9cf1f92 --- /dev/null +++ b/.github/workflows/check-style.yaml @@ -0,0 +1,37 @@ +# Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at +# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights +# reserved. See files LICENSE and NOTICE for details. +# +# This file is part of CEED, a collection of benchmarks, miniapps, software +# libraries and APIs for efficient high-order finite element and spectral +# element discretizations for exascale applications. For more information and +# source code availability see http://github.com/ceed. +# +# The CEED research is supported by the Exascale Computing Project (17-SC-20-SC) +# a collaborative effort of two U.S. Department of Energy organizations (Office +# of Science and the National Nuclear Security Administration) responsible for +# the planning and preparation of a capable exascale ecosystem, including +# software, applications, hardware, advanced system engineering and early +# testbed platforms, in support of the nation's exascale computing imperative. + +name: Check style + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + check-style: + runs-on: ubuntu-20.04 + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Get astyle + run: sudo apt-get install astyle + + - name: Check style + run: ./apply-style.sh diff --git a/.gitignore b/.gitignore index c354e4a..84b7852 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,4 @@ data/ *.out # IDE directories -.vscode/ \ No newline at end of file +.vscode/ diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..b0403bc --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,24 @@ + ███████ ███ ███ ███████ + ██ ████ ████ ██ + █████ ██ ████ ██ ███████ + ██ ██ ██ ██ ██ + ██ ██ ██ ███████ + + CEED's high-order Field and Mesh Specification + + +Version 0.2, released on Sep 10, 2021 +===================================== + +- Added support for writing and reading FmsDataCollections both in ASCII and + binary format via Conduit. + +- Visualization for FMS files is available in VisIt v3.2, visit.llnl.gov. + +- Added regression and code styling. + + +Version 0.1, released on Jul 8, 2018 +==================================== + +- Initial release. diff --git a/CMakeLists.txt b/CMakeLists.txt index 82d6137..33a0ff8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at +# Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at # the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights # reserved. See files LICENSE and NOTICE for details. # @@ -17,8 +17,9 @@ # We use the C_STANDARD target property introduced in CMake 3.1 cmake_minimum_required (VERSION 3.1) -# Project name -project(FMS VERSION 0.1 LANGUAGES C) +# Project name and version. +# The version is also defined in the files: fms.h and Doxyfile. +project(FMS VERSION 0.2 LANGUAGES C) # Optional demo - see examples/README.md for more information option(FMS_ENABLE_DEMO "Enable the PUMI + MFEM demo" OFF) @@ -37,7 +38,8 @@ endif() # Setup thirdparty dependencies # Optional conduit implementation for IO functions if(CONDUIT_DIR) - find_package(Conduit 0.5.1 REQUIRED + enable_language(CXX) + find_package(Conduit 0.7.1 REQUIRED HINTS ${CONDUIT_DIR} NO_DEFAULT_PATH) set(FMS_HAVE_CONDUIT TRUE) @@ -67,9 +69,9 @@ if(FMS_ENABLE_DEMO) endif() if(PUMI_DIR) - find_package(SCOREC 2.1.0 REQUIRED - CONFIG - HINTS ${PUMI_DIR} + find_package(SCOREC 2.1.0 REQUIRED + CONFIG + HINTS ${PUMI_DIR} NO_DEFAULT_PATH) set(FMS_HAVE_PUMI TRUE) message(STATUS "Demo using PUMI: ${SCOREC_DIR}") diff --git a/Doxyfile b/Doxyfile index 83c53ad..c4aed0f 100644 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "FMS" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = v0.1 +PROJECT_NUMBER = v0.2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -2034,7 +2034,7 @@ PERLMOD_MAKEVAR_PREFIX = # C-preprocessor directives found in the sources and include files. # The default value is: YES. -ENABLE_PREPROCESSING = NO +ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names # in the source code. If set to NO, only conditional compilation will be diff --git a/LICENSE b/LICENSE index e5236e5..2c413c6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 2-Clause License -Copyright (c) 2017 Lawrence Livermore National Security, LLC. +Copyright (c) 2021 Lawrence Livermore National Security, LLC. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md index 06773c8..e97369d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,17 @@ -# FMS: CEED's high-order Field and Mesh Specification + ███████ ███ ███ ███████ + ██ ████ ████ ██ + █████ ██ ████ ██ ███████ + ██ ██ ██ ██ ██ + ██ ██ ██ ███████ + + CEED's high-order Field and Mesh Specification + [![License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg)](https://opensource.org/licenses/BSD-2-Clause) [![Documentation](https://codedocs.xyz/CEED/FMS.svg)](https://codedocs.xyz/CEED/FMS/) +[![Build and Test (GH Actions)](https://github.com/CEED/FMS/actions/workflows/build-and-test.yaml/badge.svg?branch=master)](https://github.com/CEED/FMS/actions?query=workflow%3Abuild-and-test) +[![Build and Test (GH Actions)](https://github.com/CEED/FMS/actions/workflows/check-style.yaml/badge.svg?branch=master)](https://github.com/CEED/FMS/actions?query=workflow%3Acheck-style) + ## High-Order Data Description @@ -16,6 +26,9 @@ solutions and meshes, as those depicted below, as well as non-standard finite elements, such as Nedelec and Raviart-Thomas elements. See the [FMS documentation](doc/fms.md) for more details. +Initial support for the FMS file formats is available in +[VisIt](https://visit.llnl.gov/) version 3.2. + ![High-order mesh and solution](doc/triple-pt-2x2.png) The following diagram illustrates the current and planned components of FMS. @@ -42,7 +55,8 @@ exchange and high-order visualization and data analysis. ## Building -You can get started with the default build configuration using the command line listed below. Checkout the [build documentation](doc/build.md) for more info. +You can get started with the default build configuration using the command line +listed below. Checkout the [build documentation](doc/build.md) for more info. ```console mkdir build @@ -61,7 +75,7 @@ or by leaving a comment in the [issue tracker](https://github.com/CEED/FMS/issue The following copyright applies to each file in the CEED software suite, unless otherwise stated in the file: -> Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at the +> Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at the > Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights reserved. See files LICENSE and NOTICE for details. diff --git a/apply-style.sh b/apply-style.sh new file mode 100755 index 0000000..e3fae07 --- /dev/null +++ b/apply-style.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +# Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at +# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights +# reserved. See files LICENSE and NOTICE for details. +# +# This file is part of CEED, a collection of benchmarks, miniapps, software +# libraries and APIs for efficient high-order finite element and spectral +# element discretizations for exascale applications. For more information and +# source code availability see http://github.com/ceed. +# +# The CEED research is supported by the Exascale Computing Project (17-SC-20-SC) +# a collaborative effort of two U.S. Department of Energy organizations (Office +# of Science and the National Nuclear Security Administration) responsible for +# the planning and preparation of a capable exascale ecosystem, including +# software, applications, hardware, advanced system engineering and early +# testbed platforms, in support of the nation's exascale computing imperative. + +function main() +{ + cd $(dirname "$0") + fms_astyle_file="fms.astylerc" + if [[ ! -r "${fms_astyle_file}" ]]; then + echo "FMS's astyle format file not found: '${fms_astyle_file}'. Stop." + exit 21 + fi + + find_astyle + + local old_IFS="${IFS}" + IFS=$'\n' + format_files=($(git ls-files "*.[ch]" "*.[ch]pp")) + if [[ "$?" -ne 0 ]]; then + echo "Error getting list of C/C++ source files from Git. Stop." + exit 22 + fi + IFS="${old_IFS}" + + if ${astyle_bin} --options="${fms_astyle_file}" "${format_files[@]}" | \ + grep "Formatted"; then + printf "\nPlease make sure the changes are committed.\n\n" + return 1 + else + printf "All source files are properly formatted.\n" + fi + return 0 +} # end of function 'main' + +function find_astyle() +{ + astyle_req_version="Artistic Style Version 3.1" + astyle_bin_list=("${ASTYLE_BIN:-astyle}" astyle-3.1) + for astyle_bin in "${astyle_bin_list[@]}"; do + if ! command -v "${astyle_bin}" > /dev/null 2>&1; then + continue + fi + astyle_version="$("${astyle_bin}" --version)" + if [[ "${astyle_version}" != "${astyle_req_version}" ]]; then + continue + fi + return 0 + done + echo "Required astyle version not found: '${astyle_req_version}'." + printf "Astyle commands tried:" + printf " '%s'" "${astyle_bin_list[@]}" + printf ".\n" + exit 23 +} # end of function 'find_astyle' + + +# Invoke the 'main' function +main "$@" diff --git a/doc/build.md b/doc/build.md index 536d1ef..4d4bccc 100644 --- a/doc/build.md +++ b/doc/build.md @@ -60,4 +60,4 @@ cd build cmake -DFMS_DIR=*fms/install/prefix* .. make ./main -``` \ No newline at end of file +``` diff --git a/doc/components.png b/doc/components.png index cb0bf80..633ee75 100644 Binary files a/doc/components.png and b/doc/components.png differ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f118ca8..8c8194f 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at +# Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at # the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights # reserved. See files LICENSE and NOTICE for details. # diff --git a/examples/demo_pumi_mfem/CMakeLists.txt b/examples/demo_pumi_mfem/CMakeLists.txt index c46ee79..6f4f758 100644 --- a/examples/demo_pumi_mfem/CMakeLists.txt +++ b/examples/demo_pumi_mfem/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at +# Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at # the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights # reserved. See files LICENSE and NOTICE for details. # diff --git a/examples/demo_pumi_mfem/demo_pumi_mfem.cpp b/examples/demo_pumi_mfem/demo_pumi_mfem.cpp index af13a52..4dff5f1 100644 --- a/examples/demo_pumi_mfem/demo_pumi_mfem.cpp +++ b/examples/demo_pumi_mfem/demo_pumi_mfem.cpp @@ -123,7 +123,7 @@ int main(int argc, char *argv[]) { } // Edges - FmsInt nvtxs = 2; + const FmsInt nvtxs = 2; FmsInt num_edges = 0; int edge[nvtxs]; itr = pumi_mesh->begin(1); @@ -157,7 +157,7 @@ int main(int argc, char *argv[]) { pumi_mesh->end(itr); // Define Face based on edge Id's - FmsInt nedges = 3; + const FmsInt nedges = 3; int face[nedges]; int num_triangles = 0; itr = pumi_mesh->begin(2); @@ -191,7 +191,7 @@ int main(int argc, char *argv[]) { pumi_mesh->end(itr); // Define Elem based on face Id's - FmsInt nfaces = 4; + const FmsInt nfaces = 4; FmsEntityReordering EntReord; int tetOrd[4] = {0,1,3,2}; // PUMI order for tet element faces EntReord[FMS_TETRAHEDRON] = &tetOrd[0]; diff --git a/examples/include-fms/main.cpp b/examples/include-fms/main.cpp index 3ace813..8690da7 100644 --- a/examples/include-fms/main.cpp +++ b/examples/include-fms/main.cpp @@ -6,4 +6,4 @@ int main(int, char**) { auto a = FmsMeshConstruct(&m); printf("Hello %d\n", a); return a; -} \ No newline at end of file +} diff --git a/examples/meshing/CMakeLists.txt b/examples/meshing/CMakeLists.txt index e6c2f3f..1833669 100644 --- a/examples/meshing/CMakeLists.txt +++ b/examples/meshing/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at +# Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at # the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights # reserved. See files LICENSE and NOTICE for details. # @@ -14,6 +14,10 @@ # software, applications, hardware, advanced system engineering and early # testbed platforms, in support of the nation's exascale computing imperative. +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) + add_executable(domains domains.c) target_link_libraries(domains PRIVATE fms) @@ -24,4 +28,4 @@ add_executable(quads quads.c) target_link_libraries(quads PRIVATE fms m) add_executable(simple_mesh simple_mesh.c) -target_link_libraries(simple_mesh PRIVATE fms) \ No newline at end of file +target_link_libraries(simple_mesh PRIVATE fms) diff --git a/examples/meshing/domains.c b/examples/meshing/domains.c index b6fbd5b..2b29804 100644 --- a/examples/meshing/domains.c +++ b/examples/meshing/domains.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at + Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights reserved. See files LICENSE and NOTICE for details. @@ -155,7 +155,7 @@ append_domain_coords_edge(int dom, int order, double *ptr, const int *global_index, const int *edges, int nedges) { int i, j, v0, v1; - double t, xoffset, yoffset, pt[2], travel = 0.02; + double t, xoffset = 0., yoffset = 0., pt[2], travel = 0.02; if(order > 1) { for(i = 0; i < nedges; ++i) { @@ -201,11 +201,11 @@ double * append_domain_coords_face(int dom, int order, double *ptr, const int *global_index, const int *edges, const int *tri, int ntri) { - int i,j,edge,v0,v1; - double pt[2], xoffset, yoffset, travel = 0.01; + int i,j,v0,v1; + double pt[2], xoffset = 0., yoffset = 0., travel = 0.01; if(order == 3) { for(i = 0; i < ntri; ++i) { - pt[0] = pt[1] = pt[2] = 0.; + pt[0] = pt[1] = 0.; for(j = 0; j < 3; ++j) { /* Current edge in tri*/ int edge = tri[3*i+j]; diff --git a/examples/meshing/hexes.c b/examples/meshing/hexes.c index 7e1bde6..a610c18 100644 --- a/examples/meshing/hexes.c +++ b/examples/meshing/hexes.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at + Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights reserved. See files LICENSE and NOTICE for details. @@ -15,6 +15,10 @@ software, applications, hardware, advanced system engineering and early testbed platforms, in support of the nation's exascale computing imperative. */ + +// We use drand48() - this is one way to get it: +#define _XOPEN_SOURCE + #include #include #include @@ -132,12 +136,12 @@ for orders 3+ look right on the faces. */ int * compute_faces(const int *dims, int *nfaces) { - int i,j,k,A,B,C,D, E1,E2,E3,F1,F2,F3, *faces, *f; + int i,j,k,A,B,C,D, E1,E2/*,E3*/,F1,F2,F3, *faces, *f; /* number of edges. */ E1 = (dims[0]-1) * (dims[1]) * (dims[2]); E2 = (dims[0]) * (dims[1]-1) * (dims[2]); - E3 = (dims[0]) * (dims[1]) * (dims[2]-1); + // E3 = (dims[0]) * (dims[1]) * (dims[2]-1); F1 = (dims[0]-1)*(dims[1]-1)*dims[2]; /* back/front */ F2 = (dims[0]-1)*(dims[1]) *(dims[2]-1); /* bottom/top */ @@ -251,7 +255,7 @@ compute_cells(const int *dims, int *ncells) { int F1 = (dims[0]-1)*(dims[1]-1)*dims[2]; /* back/front */ int F2 = (dims[0]-1)*(dims[1]) *(dims[2]-1); /* bottom/top */ - int F3 = (dims[0]) *(dims[1]-1)*(dims[2]-1); /* left/right */ + // int F3 = (dims[0]) *(dims[1]-1)*(dims[2]-1); /* left/right */ for(k = 0; k < dims[2]-1; k++) for(j = 0; j < dims[1]-1; j++) @@ -337,7 +341,7 @@ double * append_coord_dofs_face(int order, double *dest, const double *verts, const int *edges, const int *faces, int nfaces, double travel, int component) { - int i,j,ii,jj,edge,e0,e2,v0,v1,v2,v3; + int i,ii,jj,e0,e2,v0,v1,v2,v3; double value, r,s, *ptr = dest; if(order >= 2) { for(i = 0; i < nfaces; ++i) { @@ -377,7 +381,7 @@ append_coord_dofs_face(int order, double *dest, const double *verts, double * append_coord_dofs_cell(int order, double *dest, const int *dims, const double *verts, double travel, int component) { - int i,j,k,ii,jj,kk,edge,v0,v1; + int i,j,k,ii,jj,kk; double r,s,t,value, *ptr = dest; #ifdef ADD_CELLS if(order >= 2) { @@ -443,7 +447,7 @@ add_radial_scalar(FmsDataCollection dc, FmsComponent volume, const int *faces, int nfaces, int ncells) { int i, ndofs; - double *data, *coords, *cptr, *x, *y, *z; + double *data, *coords, *x, *y, *z; char fdname[100]; /* Create a field descriptor for the coordinates that live on "surface". */ diff --git a/examples/meshing/quads.c b/examples/meshing/quads.c index 57668a7..d8e3faa 100644 --- a/examples/meshing/quads.c +++ b/examples/meshing/quads.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at + Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights reserved. See files LICENSE and NOTICE for details. @@ -100,7 +100,7 @@ double * append_coords_edge(int order, double *ptr, const double *coords, const int *edges, int nedges, double travel) { int i, j, v0, v1; - double t, xoffset, yoffset, pt[2]; + double t, xoffset = 0., yoffset = 0., pt[2]; if(order > 1) { for(i = 0; i < nedges; ++i) { @@ -140,8 +140,8 @@ append_coords_edge(int order, double *ptr, const double *coords, double * append_coords_face(int order, double *ptr, const double *coords, const int *edges, const int *quads, int nquads, double travel) { - int i,j,ii,jj,edge,e0,e2,v0,v1,v2,v3; - double pt[2], xoffset, yoffset; + int i,ii,jj,e0,e2,v0,v1,v2,v3; + double pt[2], xoffset = 0., yoffset = 0.; float r,s; if(order >= 2) { for(i = 0; i < nquads; ++i) { @@ -264,7 +264,6 @@ add_doforder_scalar(FmsDataCollection dc, FmsComponent surface, const char *name, int nverts, int nedges, int nquads) { int i, order = 3, ndofs, nedge_data, nface_data; float *data, *ptr; - double x, y; char fdname[100]; /* Create a field descriptor for the coordinates that live on "surface". */ diff --git a/examples/meshing/simple_mesh.c b/examples/meshing/simple_mesh.c index 5cf4875..d960f1c 100644 --- a/examples/meshing/simple_mesh.c +++ b/examples/meshing/simple_mesh.c @@ -135,4 +135,4 @@ int main(int argc, const char *argv[]) { FmsDataCollectionDestroy(&dc); return 0; -} \ No newline at end of file +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 523ebb8..bacf1ec 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at +# Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at # the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights # reserved. See files LICENSE and NOTICE for details. # diff --git a/src/fms.c b/src/fms.c index 4222ebe..23eb65e 100644 --- a/src/fms.c +++ b/src/fms.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at + Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights reserved. See files LICENSE and NOTICE for details. @@ -225,8 +225,14 @@ static void FmsErrorDebug(int err_code, const char *func, const char *file, "Aborting ...\n\n", err_code, func, file, line); abort(); } -#ifndef _MSC_VER +// __PRETTY_FUNCTION__ is the same as the standard __func__ for most compilers, +// with the exception of clang. GCC 9.3.0 with -Wpedantic gives a warning about +// __PRETTY_FUNCTION__ not being standard, so we use __PRETTY_FUNCTION__ only +// with clang. +#if defined(__clang__) #define FMS_PRETTY_FUNCTION __PRETTY_FUNCTION__ +#elif !defined(_MSC_VER) +#define FMS_PRETTY_FUNCTION __func__ #else // for Visual Studio C++ #define FMS_PRETTY_FUNCTION __FUNCSIG__ #endif @@ -263,11 +269,12 @@ static void FmsAbortNotImplemented() { abort(); } - +#ifndef NDEBUG static void FmsInternalError() { fprintf(stderr, "\n\nFMS internal error detected! Aborting ...\n\n"); abort(); } +#endif static inline int FmsCopyString(const char *str, char **str_copy_p) { if (str == NULL) { *str_copy_p = NULL; return 0; } @@ -2044,7 +2051,6 @@ int FmsMetaDataSetIntegers(FmsMetaData mdata, const char *mdata_name, mdata->sub_type.int_type = int_type; mdata->num_entries = size; mdata->data = md_data; - memcpy(md_data, data, size*sizeof_int_type); *data = md_data; return 0; } @@ -2066,7 +2072,6 @@ int FmsMetaDataSetScalars(FmsMetaData mdata, const char *mdata_name, mdata->sub_type.scalar_type = scal_type; mdata->num_entries = size; mdata->data = md_data; - memcpy(md_data, data, size*sizeof_scal_type); *data = md_data; return 0; } @@ -2966,59 +2971,63 @@ static inline double FmsAbs(const double x) { } while(0) static inline FmsInt CompareScalarData(FmsScalarType stype, FmsInt size, - const void *lhs, const void *rhs) { + const void *lhs, const void *rhs) { if(lhs == rhs) return 0; if(!lhs) return 1; if(!rhs) return 1; FmsInt isDifferent = 0; switch(stype) { - case FMS_FLOAT: - COMPARE_SCALAR_DATA(float, lhs, rhs, size, isDifferent); - break; - case FMS_DOUBLE: - COMPARE_SCALAR_DATA(double, lhs, rhs, size, isDifferent); - break; - case FMS_COMPLEX_FLOAT: - COMPARE_SCALAR_DATA(float, lhs, rhs, size*2, isDifferent); - break; - case FMS_COMPLEX_DOUBLE: - COMPARE_SCALAR_DATA(double, lhs, rhs, size*2, isDifferent); - break; + case FMS_FLOAT: + COMPARE_SCALAR_DATA(float, lhs, rhs, size, isDifferent); + break; + case FMS_DOUBLE: + COMPARE_SCALAR_DATA(double, lhs, rhs, size, isDifferent); + break; + case FMS_COMPLEX_FLOAT: + COMPARE_SCALAR_DATA(float, lhs, rhs, size*2, isDifferent); + break; + case FMS_COMPLEX_DOUBLE: + COMPARE_SCALAR_DATA(double, lhs, rhs, size*2, isDifferent); + break; + default: + return 2; } return isDifferent; } static inline FmsInt CompareIntData(FmsIntType itype, FmsInt size, - const void *lhs, const void *rhs) { + const void *lhs, const void *rhs) { if(lhs == rhs) return 0; if(!lhs) return 1; if(!rhs) return 1; FmsInt isDifferent = 0; switch(itype) { - case FMS_INT8: - COMPARE_INT_DATA(int8_t, lhs, rhs, size, isDifferent); - break; - case FMS_INT16: - COMPARE_INT_DATA(int16_t, lhs, rhs, size, isDifferent); - break; - case FMS_INT32: - COMPARE_INT_DATA(int32_t, lhs, rhs, size, isDifferent); - break; - case FMS_INT64: - COMPARE_INT_DATA(int64_t, lhs, rhs, size, isDifferent); - break; - case FMS_UINT8: - COMPARE_INT_DATA(uint8_t, lhs, rhs, size, isDifferent); - break; - case FMS_UINT16: - COMPARE_INT_DATA(uint16_t, lhs, rhs, size, isDifferent); - break; - case FMS_UINT32: - COMPARE_INT_DATA(uint32_t, lhs, rhs, size, isDifferent); - break; - case FMS_UINT64: - COMPARE_INT_DATA(uint64_t, lhs, rhs, size, isDifferent); - break; + case FMS_INT8: + COMPARE_INT_DATA(int8_t, lhs, rhs, size, isDifferent); + break; + case FMS_INT16: + COMPARE_INT_DATA(int16_t, lhs, rhs, size, isDifferent); + break; + case FMS_INT32: + COMPARE_INT_DATA(int32_t, lhs, rhs, size, isDifferent); + break; + case FMS_INT64: + COMPARE_INT_DATA(int64_t, lhs, rhs, size, isDifferent); + break; + case FMS_UINT8: + COMPARE_INT_DATA(uint8_t, lhs, rhs, size, isDifferent); + break; + case FMS_UINT16: + COMPARE_INT_DATA(uint16_t, lhs, rhs, size, isDifferent); + break; + case FMS_UINT32: + COMPARE_INT_DATA(uint32_t, lhs, rhs, size, isDifferent); + break; + case FMS_UINT64: + COMPARE_INT_DATA(uint64_t, lhs, rhs, size, isDifferent); + break; + default: + return 2; } return isDifferent; } @@ -3052,8 +3061,7 @@ int FmsDataCollectionCompare(FmsDataCollection lhs, FmsDataCollection rhs) { FmsDataCollectionGetFieldDescriptors(rhs, &rhs_fds, &rhs_nfds); if(lhs_nfds != rhs_nfds) { diff += 100; - } - else { + } else { for(FmsInt i = 0; i < lhs_nfds; i++) { if(FmsFieldDescriptorCompare(lhs_fds[i], rhs_fds[i])) { diff += 100; @@ -3068,8 +3076,7 @@ int FmsDataCollectionCompare(FmsDataCollection lhs, FmsDataCollection rhs) { FmsDataCollectionGetFields(rhs, &rhs_fields, &rhs_nfields); if(lhs_nfds != rhs_nfds) { diff += 1000; - } - else { + } else { for(FmsInt i = 0; i < lhs_nfds; i++) { if(FmsFieldCompare(lhs_fields[i], rhs_fields[i])) { diff += 1000; @@ -3100,8 +3107,7 @@ int FmsMeshCompare(FmsMesh lhs, FmsMesh rhs) { // Compare domain names & domains if(lhs_ndnames != rhs_ndnames) { diff += 1; - } - else { + } else { for(FmsInt i = 0; i < lhs_ndnames; i++) { const char *lhs_dname = NULL, *rhs_dname = NULL; FmsInt lhs_ndomains = 0, rhs_ndomains = -1; @@ -3130,14 +3136,13 @@ int FmsMeshCompare(FmsMesh lhs, FmsMesh rhs) { FmsMeshGetNumComponents(rhs, &rhs_ncomponents); if(lhs_ncomponents != rhs_ncomponents) { diff += 1000; - } - else { + } else { for(FmsInt i = 0; i < lhs_ncomponents; i++) { FmsComponent lhs_component = NULL, rhs_component = NULL; FmsMeshGetComponent(lhs, i, &lhs_component); FmsMeshGetComponent(rhs, i, &rhs_component); if(FmsComponentCompare(lhs_component, rhs_component)) { - diff += 1000; + diff += 1000; } } } @@ -3148,8 +3153,7 @@ int FmsMeshCompare(FmsMesh lhs, FmsMesh rhs) { FmsMeshGetNumTags(rhs, &rhs_ntags); if(lhs_ntags != rhs_ntags) { diff += 10000; - } - else { + } else { for(FmsInt i = 0; i < lhs_ntags; i++) { FmsTag lhs_tag = NULL, rhs_tag = NULL; FmsMeshGetTag(lhs, i, &lhs_tag); @@ -3172,36 +3176,34 @@ int FmsFieldDescriptorCompare(FmsFieldDescriptor lhs, FmsFieldDescriptor rhs) { if(!lhs) return -1; if(!rhs) return -2; int diff = 0; - + if(strcmp(lhs->name, rhs->name)) { diff += 1; } if(lhs->descr_type != rhs->descr_type) { diff += 10; - } - else { + } else { if(lhs->descr_type == FMS_FIXED_ORDER) { // Make sure both of their fixed orders have been set if(lhs->descriptor.fixed_order && rhs->descriptor.fixed_order) { - if(lhs->descriptor.fixed_order->basis_type != rhs->descriptor.fixed_order->basis_type) { + if(lhs->descriptor.fixed_order->basis_type != + rhs->descriptor.fixed_order->basis_type) { diff += 100; } - if(lhs->descriptor.fixed_order->field_type != rhs->descriptor.fixed_order->field_type) { + if(lhs->descriptor.fixed_order->field_type != + rhs->descriptor.fixed_order->field_type) { diff += 1000; } if(lhs->descriptor.fixed_order->order != rhs->descriptor.fixed_order->order) { diff += 10000; } - } - else if(!lhs->descriptor.fixed_order) { + } else if(!lhs->descriptor.fixed_order) { diff += 20; - } - else if(!rhs->descriptor.fixed_order) { + } else if(!rhs->descriptor.fixed_order) { diff += 30; } - } - else { + } else { // TODO: Update this when it's possible to set a non fixed order. } } @@ -3218,13 +3220,11 @@ int FmsFieldDescriptorCompare(FmsFieldDescriptor lhs, FmsFieldDescriptor rhs) { if(strcmp(lhs->component->name, rhs->component->name)) { diff += 1000000; } - } - else if(!lhs->component->name) + } else if(!lhs->component->name) diff += 2000000; else if(!rhs->component->name) diff += 3000000; - } - else if(!lhs->component) + } else if(!lhs->component) diff += 4000000; else if(!rhs->component) diff += 5000000; @@ -3283,8 +3283,7 @@ int FmsMetaDataCompare(FmsMetaData lhs, FmsMetaData rhs) { if(lhs->name && rhs->name) { if(strcmp(lhs->name, rhs->name)) diff += 1; - } - else if(!lhs->name) + } else if(!lhs->name) diff += 2; else if(!rhs->name) diff += 3; @@ -3297,128 +3296,132 @@ int FmsMetaDataCompare(FmsMetaData lhs, FmsMetaData rhs) { // Only compare the data is everything has been the same so far if(diff == 0) { switch(lhs->md_type) { - case FMS_INTEGER: { - if(lhs->sub_type.int_type != rhs->sub_type.int_type) - diff += 100; + case FMS_INTEGER: { + if(lhs->sub_type.int_type != rhs->sub_type.int_type) + diff += 100; - if(lhs->num_entries != rhs->num_entries) - diff += 1000; + if(lhs->num_entries != rhs->num_entries) + diff += 1000; - if(diff == 0) { - if(CompareIntData(lhs->sub_type.int_type, lhs->num_entries, lhs->data, rhs->data)) - diff += 100000; - } - break; + if(diff == 0) { + if(CompareIntData(lhs->sub_type.int_type, lhs->num_entries, lhs->data, + rhs->data)) + diff += 100000; } - case FMS_SCALAR: { - if(lhs->sub_type.scalar_type != rhs->sub_type.scalar_type) - diff += 100; + break; + } + case FMS_SCALAR: { + if(lhs->sub_type.scalar_type != rhs->sub_type.scalar_type) + diff += 100; - if(lhs->num_entries != rhs->num_entries) - diff += 1000; + if(lhs->num_entries != rhs->num_entries) + diff += 1000; - if(diff == 0) { - if(CompareScalarData(lhs->sub_type.scalar_type, lhs->num_entries, lhs->data, rhs->data)) - diff += 100000; - } - break; - } - case FMS_STRING: { - if(lhs->data && rhs->data) { - if(strcmp(lhs->data, rhs->data)) - diff += 100000; - } - else if(!lhs->name) - diff += 100; - else if(!rhs->name) - diff += 200; - break; + if(diff == 0) { + if(CompareScalarData(lhs->sub_type.scalar_type, lhs->num_entries, lhs->data, + rhs->data)) + diff += 100000; } - case FMS_META_DATA: { - if(lhs->num_entries != rhs->num_entries) - diff += 100; + break; + } + case FMS_STRING: { + if(lhs->data && rhs->data) { + if(strcmp(lhs->data, rhs->data)) + diff += 100000; + } else if(!lhs->name) + diff += 100; + else if(!rhs->name) + diff += 200; + break; + } + case FMS_META_DATA: { + if(lhs->num_entries != rhs->num_entries) + diff += 100; - if(diff == 0) { - FmsMetaData *ldata = (FmsMetaData*)lhs->data; - FmsMetaData *rdata = (FmsMetaData*)rhs->data; - const FmsInt NE = lhs->num_entries; - for(FmsInt i = 0; i < NE; i++) { - diff += FmsMetaDataCompare(ldata[i], rdata[i]); - if(diff) - break; - } + if(diff == 0) { + FmsMetaData *ldata = (FmsMetaData*)lhs->data; + FmsMetaData *rdata = (FmsMetaData*)rhs->data; + const FmsInt NE = lhs->num_entries; + for(FmsInt i = 0; i < NE; i++) { + diff += FmsMetaDataCompare(ldata[i], rdata[i]); + if(diff) + break; } - break; } + break; + } + default: { + diff += 1000000; + break; + } } } return diff; } int FmsDomainCompare(FmsDomain lhs, FmsDomain rhs) { - if(lhs == rhs) return 0; - if(!lhs) return -1; - if(!rhs) return -2; - int diff = 0; - - // Compare names - if(lhs->name && rhs->name) { - if(strcmp(lhs->name, rhs->name)) - diff += 1; - } - else if(!lhs->name) - diff += 2; - else if(!rhs->name) - diff += 3; - - // Compare ids - if(lhs->id != rhs->id) - diff += 10; - - // Compare dimension - if(lhs->dim != rhs->dim) - diff += 100; + if(lhs == rhs) return 0; + if(!lhs) return -1; + if(!rhs) return -2; + int diff = 0; - // Compare num ents - for(int i = 0; i < FMS_NUM_ENTITY_TYPES; i++) { - if(lhs->num_entities[i] != rhs->num_entities[i]) { - diff += 1000; - break; - } + // Compare names + if(lhs->name && rhs->name) { + if(strcmp(lhs->name, rhs->name)) + diff += 1; + } else if(!lhs->name) + diff += 2; + else if(!rhs->name) + diff += 3; + + // Compare ids + if(lhs->id != rhs->id) + diff += 10; + + // Compare dimension + if(lhs->dim != rhs->dim) + diff += 100; + + // Compare num ents + for(int i = 0; i < FMS_NUM_ENTITY_TYPES; i++) { + if(lhs->num_entities[i] != rhs->num_entities[i]) { + diff += 1000; + break; } + } - // Make sure everything is stored using the same types - for(int i = 0; i < FMS_NUM_ENTITY_TYPES; i++) { - if(lhs->side_ids_type[i] != rhs->side_ids_type[i]) { - diff += 10000; - break; - } + // Make sure everything is stored using the same types + for(int i = 0; i < FMS_NUM_ENTITY_TYPES; i++) { + if(lhs->side_ids_type[i] != rhs->side_ids_type[i]) { + diff += 10000; + break; } + } - // Compare the entities - if(diff == 0) { - for(int i = 0; i < FMS_NUM_ENTITY_TYPES; i++) { - if(CompareIntData(lhs->side_ids_type[i], - lhs->num_entities[i]*FmsEntityNumSides[i], - lhs->entities[i], rhs->entities[i])) { - diff += 100000; - break; - } + // Compare the entities + if(diff == 0) { + for(int i = 0; i < FMS_NUM_ENTITY_TYPES; i++) { + if(CompareIntData(lhs->side_ids_type[i], + lhs->num_entities[i]*FmsEntityNumSides[i], + lhs->entities[i], rhs->entities[i])) { + diff += 100000; + break; } } + } - if(diff == 0) { - for(int i = 0; i < FMS_NUM_ENTITY_TYPES; i++) { - if(CompareIntData(FMS_ORIENTATION_INT_TYPE, - lhs->num_entities[i]*FmsEntityNumSides[i], - lhs->orientations[i], rhs->orientations[i])) { - diff += 1000000; - break; - } + if(diff == 0) { + for(int i = 0; i < FMS_NUM_ENTITY_TYPES; i++) { + if(CompareIntData(FMS_ORIENTATION_INT_TYPE, + lhs->num_entities[i]*FmsEntityNumSides[i], + lhs->orientations[i], rhs->orientations[i])) { + diff += 1000000; + break; } } + } - return diff; + return diff; } int FmsComponentCompare(FmsComponent lhs, FmsComponent rhs) { @@ -3430,8 +3433,7 @@ int FmsComponentCompare(FmsComponent lhs, FmsComponent rhs) { if(lhs->name && rhs->name) { if(strcmp(lhs->name, rhs->name)) diff += 1; - } - else if(!lhs->name) + } else if(!lhs->name) diff += 2; else if(!rhs->name) diff += 3; @@ -3470,8 +3472,8 @@ int FmsComponentCompare(FmsComponent lhs, FmsComponent rhs) { break; } if(CompareIntData(lpart->entities_ids_type[j], - lpart->num_entities[j], - lpart->entities_ids[j], rpart->entities_ids[j])) { + lpart->num_entities[j], + lpart->entities_ids[j], rpart->entities_ids[j])) { diff += 40000; break; } @@ -3482,7 +3484,8 @@ int FmsComponentCompare(FmsComponent lhs, FmsComponent rhs) { } if(diff == 0) { - if(CompareIntData(FMS_INT_TYPE, lhs->num_relations, lhs->relations, rhs->relations)) + if(CompareIntData(FMS_INT_TYPE, lhs->num_relations, lhs->relations, + rhs->relations)) diff += 50000; } @@ -3491,43 +3494,40 @@ int FmsComponentCompare(FmsComponent lhs, FmsComponent rhs) { if(FmsFieldCompare(lhs->coordinates, rhs->coordinates)) diff += 60000; } - + return diff; } int FmsTagCompare(FmsTag lhs, FmsTag rhs) { - if(lhs == rhs) return 0; - if(!lhs) return -1; - if(!rhs) return -2; - int diff = 0; + if(lhs == rhs) return 0; + if(!lhs) return -1; + if(!rhs) return -2; + int diff = 0; - if(lhs->name && rhs->name) { - if(strcmp(lhs->name, rhs->name)) - diff += 1; - } - else if(!lhs->name) - diff += 2; - else if(!rhs->name) - diff += 3; + if(lhs->name && rhs->name) { + if(strcmp(lhs->name, rhs->name)) + diff += 1; + } else if(!lhs->name) + diff += 2; + else if(!rhs->name) + diff += 3; - if(lhs->tag_type != rhs->tag_type) - diff += 10; + if(lhs->tag_type != rhs->tag_type) + diff += 10; - if(lhs->num_tag_descriptions != rhs->num_tag_descriptions) - diff += 20; + if(lhs->num_tag_descriptions != rhs->num_tag_descriptions) + diff += 20; - if(diff == 0) { - if(FmsComponentCompare(lhs->comp, rhs->comp)) - diff += 100; - } + if(diff == 0) { + if(FmsComponentCompare(lhs->comp, rhs->comp)) + diff += 100; + } - if(diff == 0) { - FmsInt ne = 0; - if(lhs->comp) - lhs->comp->num_main_entities; - if(CompareIntData(lhs->tag_type, ne, lhs->tags, rhs->tags)) - diff += 1000; - } - - return diff; + if(diff == 0) { + FmsInt ne = lhs->comp->num_main_entities; + if(CompareIntData(lhs->tag_type, ne, lhs->tags, rhs->tags)) + diff += 1000; + } + + return diff; } diff --git a/src/fms.h b/src/fms.h index 5d0d48c..7dd6cdd 100644 --- a/src/fms.h +++ b/src/fms.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at + Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights reserved. See files LICENSE and NOTICE for details. @@ -27,8 +27,17 @@ extern "C" { #endif +/// FMS version constant of the form: ((major*100 + minor)*100 + patch). +/** For example, value of 10203 means v1.2.3. + + The version is also defined in the files: CMakeLists.txt and Doxyfile. + + This macro was added in version: v0.2. */ +#define FMS_VERSION 200 + /// Interface version constant of the form: ((major*100 + minor)*100 + patch). -enum { FMS_INTERFACE_VERSION = 100 /* v0.1 */ }; +/** Since FMS v0.2, this value is the same as the macro FMS_VERSION. */ +enum { FMS_INTERFACE_VERSION = FMS_VERSION }; /// Type used by fms for representing and storing sizes and indices. typedef uint64_t FmsInt; @@ -56,26 +65,28 @@ typedef enum { extern const size_t FmsIntTypeSize[FMS_NUM_INT_TYPES]; +/// Added in version: v0.2. extern const char * const FmsIntTypeNames[FMS_NUM_INT_TYPES]; /// Get the enum representation of an int type from the string name. +/** Added in version: v0.2. */ int FmsGetIntTypeFromName(const char * const name, FmsIntType *type); /// TODO: dox /** A mesh consists of: - * mesh domains - * mesh components, described in terms of the domains - * mesh tags (attributes), defined on components. + - mesh domains + - mesh components, described in terms of the domains + - mesh tags (attributes), defined on components. The mesh is also assigned a partition id, e.g. an MPI rank. */ typedef struct FmsMesh_private *FmsMesh; /// TODO: dox /** Domains describe sets of interconnected mesh entities: - * 0d-entities / vertices - * 1d-entities / edges - * 2d-entities / faces: triangles, quads - * 3d-entities / volumes / regions: tets, hexes, wedges, pyramids. + - 0d-entities / vertices + - 1d-entities / edges + - 2d-entities / faces: triangles, quads + - 3d-entities / volumes / regions: tets, hexes, wedges, pyramids. All entities in a domain are enumerated within the domain. @@ -202,18 +213,18 @@ enum { FMS_INVALID_DIM = 127 }; For FMS_HEXAHEDRON, the faces (sides), "ABCDEF", the edges, "abcdefghijkl" and the vertices, "01234567", are ordered as follows: - z y - | / 7--g--6 - |/ /| /| - *--x / l / k z=0 z=1 y=0 y=1 x=0 x=1 - h | f | bottom top front back left right - / 3-/c--2 2--c--3 7--g--6 4--e--5 6--g--7 7--h--4 5--f--6 - / / / / | | | | | | | | | | | | - 4--e--5 / b A d h B f i C j k D l l E i j F k - | d | b | | | | | | | | | | | | - i / j / 1--a--0 4--e--5 0--a--1 2--c--3 3--d--0 1--b--2 - |/ |/ - 0--a--1 + z y + | / 7--g--6 + |/ /| /| + +--x / l / k z=0 z=1 y=0 y=1 x=0 x=1 + h | f | bottom top front back left right + / 3-/c--2 2--c--3 7--g--6 4--e--5 6--g--7 7--h--4 5--f--6 + / / / / | | | | | | | | | | | | + 4--e--5 / b A d h B f i C j k D l l E i j F k + | d | b | | | | | | | | | | | | + i / j / 1--a--0 4--e--5 0--a--1 2--c--3 3--d--0 1--b--2 + |/ |/ + 0--a--1 For example, vertex "0" has coordinates (x,y,z)=(0,0,0), vertex "6" has coordinates (1,1,1), etc. @@ -235,8 +246,11 @@ typedef enum { } FmsEntityType; /// String representations of each entity type. +/** Added in version: v0.2. */ extern const char * const FmsEntityTypeNames[FMS_NUM_ENTITY_TYPES]; +/// Convert an entity-type string to FmsEntityType value. +/** Added in version: v0.2. */ int FmsGetEntityTypeFromName(const char * const name, FmsEntityType *ent_type); /// Dimensions of the entity types. @@ -306,7 +320,7 @@ typedef uint8_t FmsOrientation; enum { FMS_ORIENTATION_UNKNOWN = 255 }; -/// TODO: dox +/// Scalar types supported by FMS: floating-point types, real and complex. typedef enum { FMS_FLOAT, FMS_DOUBLE, @@ -318,14 +332,16 @@ typedef enum { extern const size_t FmsScalarTypeSize[FMS_NUM_SCALAR_TYPES]; +/// Added in version: v0.2. extern const char * const FmsScalarTypeNames[FMS_NUM_SCALAR_TYPES]; /// Get the enum representation of an int type from the string name. +/** Added in version: v0.2. */ int FmsGetScalarTypeFromName(const char * const name, FmsScalarType *type); -/// TODO: dox +/// Field descriptor types supported by FMS, see FmsFieldDescriptor. typedef enum { - FMS_FIXED_ORDER + FMS_FIXED_ORDER ///< See FmsFieldDescriptorSetFixedOrder() } FmsFieldDescriptorType; /// TODO: dox @@ -360,70 +376,73 @@ typedef enum { FMS_SCALAR, FMS_STRING, FMS_META_DATA, - FMS_NUM_METADATA_TYPES + FMS_NUM_METADATA_TYPES ///< Added in version: v0.2 } FmsMetaDataType; +/// Added in version: v0.2. extern const char * const FmsMetaDataTypeNames[FMS_NUM_METADATA_TYPES]; +/// Convert a meta-data-type string to FmsMetaDataType value. +/** Added in version: v0.2. */ int FmsGetMetaDataTypeFromName(const char * const name, FmsMetaDataType *type); /// TODO: dox /** A meta-data structure contains: - * a meta-data type (FmsMetaDataType) - * a meta-data subtype, e.g. FmsIntType, FmsScalarType; TODO: for FMS_STRING + - a meta-data type (FmsMetaDataType) + - a meta-data subtype, e.g. FmsIntType, FmsScalarType; TODO: for FMS_STRING type define FmsEncoding subtype - * a meta-data name (const char *) - * number of entries in the data array (FmsInt); the type of the entries in + - a meta-data name (const char *) + - number of entries in the data array (FmsInt); the type of the entries in the data array is based on the meta-data type and subtype, when subtype is applicable; in the case of FMS_STRING, the entries are of type char (or some other type depending on the FmsEncoding subtype when introduced) - * a data array (void *) + - a data array (void *) */ typedef struct FmsMetaData_private *FmsMetaData; /// TODO: dox /** A field-descriptor structure contains: - * a field-descriptor name - * an associated mesh component (FmsComponent) - * a descriptor-type (FmsFieldDescriptorType) - * if descriptor-type == "fixed-order": + - a field-descriptor name + - an associated mesh component (FmsComponent) + - a descriptor-type (FmsFieldDescriptorType) + - if descriptor-type == "fixed-order": - a field type (FmsFieldType) - a basis-type (FmsBasisType) - an order - * total number of DOFs + - total number of DOFs The degrees of freedom are ordered part-by-part of the associated mesh component. Within each part, the dofs are ordered as follows: - * first, all DOFs on all vertices ordered according to the local (to the + - first, all DOFs on all vertices ordered according to the local (to the part) enumeration of the vertices - * second, all DOFs on all edges ordered according to the local (to the part) + - second, all DOFs on all edges ordered according to the local (to the part) enumeration of the edges - * similarly, continue adding DOFs for all remaining entity types in the + - similarly, continue adding DOFs for all remaining entity types in the order used by FmsEntityType. */ typedef struct FmsFieldDescriptor_private *FmsFieldDescriptor; -/// TODO: dox +/// Discrete field data type. /** A field structure contains: - * a field name - * meta-data - e.g. time (FmsMetaData, can be NULL) - * a field-descriptor (FmsFieldDescriptor) - * number of vector components (FmsInt) - * a layout type, i.e. ordering for the vector components (FmsLayoutType) - * a scalar type (FmsScalarType) - * a data array of the given scalar type. + - a field name + - meta-data - e.g. time (FmsMetaData, can be NULL) + - a field-descriptor (FmsFieldDescriptor) + - number of vector components (FmsInt) + - a layout type, i.e. ordering for the vector components (FmsLayoutType) + - a scalar type (FmsScalarType) + - a data array of the given scalar type. */ typedef struct FmsField_private *FmsField; -/// TODO: dox +/// Data collection type: contains a mesh, discrete fileds, meta-data, etc. /** A data collection structure contains: - * a name (const char *) - * meta-data (FmsMetaData, can be NULL) - * a mesh (FmsMesh) - * number of field-descriptors (FmsInt) - * an array of field-descriptors (FmsFieldDescriptor *) - * number of fields (FmsInt) - * an array of fields (FmsField *) + - a name (const char *) + - meta-data (FmsMetaData, can be NULL) + - a mesh (FmsMesh) + - number of field-descriptors (FmsInt) + - an array of field-descriptors (FmsFieldDescriptor *) + - number of fields (FmsInt) + - an array of fields (FmsField *) */ typedef struct FmsDataCollection_private *FmsDataCollection; @@ -477,7 +496,6 @@ int FmsMeshAddDomains(FmsMesh mesh, const char *domain_name, FmsInt num_domains, int FmsMeshAddComponent(FmsMesh mesh, const char *comp_name, FmsComponent *comp); -/// TODO: dox /** @brief Add a new tag to the mesh with the given name and return the new tag in @a tag. */ /** The tag should be set via the FmsTagSet* functions. */ @@ -783,15 +801,14 @@ int FmsTagGet(FmsTag tag, FmsIntType *tag_type, const void **ent_tags, int FmsTagGetDescriptions(FmsTag tag, FmsIntType *tag_type, const void **tags, const char *const **tag_descr, FmsInt *num_tags); -/// TODO: dox -/** -@brief Get the name of the data collection. -@param dc the data collection. -@param[out] name A char pointer that will be set to point to the name string. - The name is owned by the data collection so it should not be - freed or modified. -@return 0 on success, non-zero otherwise. -*/ +/// Get the name of the data collection. +/** @param dc the data collection. + @param[out] name A char pointer that will be set to point to the name + string. The name is owned by the data collection so it + should not be freed or modified. + @return 0 on success, non-zero otherwise. + + Added in version: v0.2. */ int FmsDataCollectionGetName(FmsDataCollection dc, const char **name); /// TODO: dox @@ -869,20 +886,35 @@ int FmsMetaDataGetMetaData(FmsMetaData mdata, const char **mdata_name, /// /// Return 0 if equivalent, not 0 otherwise +/** Added in version: v0.2. */ int FmsDataCollectionCompare(FmsDataCollection,FmsDataCollection); + /// Return 0 if equivalent, not 0 otherwise +/** Added in version: v0.2. */ int FmsMeshCompare(FmsMesh,FmsMesh); + /// Return 0 if equivalent, not 0 otherwise +/** Added in version: v0.2. */ int FmsFieldDescriptorCompare(FmsFieldDescriptor,FmsFieldDescriptor); + /// Return 0 if equivalent, not 0 otherwise +/** Added in version: v0.2. */ int FmsFieldCompare(FmsField,FmsField); + /// Return 0 if equivalent, not 0 otherwise +/** Added in version: v0.2. */ int FmsMetaDataCompare(FmsMetaData,FmsMetaData); + /// Return 0 if equivalent, not 0 otherwise +/** Added in version: v0.2. */ int FmsDomainCompare(FmsDomain,FmsDomain); + /// Return 0 if equivalent, not 0 otherwise +/** Added in version: v0.2. */ int FmsComponentCompare(FmsComponent,FmsComponent); + /// Return 0 if equivalent, not 0 otherwise +/** Added in version: v0.2. */ int FmsTagCompare(FmsTag,FmsTag); #ifdef __cplusplus diff --git a/src/fmsio.c b/src/fmsio.c index 1e05c48..62afdee 100644 --- a/src/fmsio.c +++ b/src/fmsio.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at + Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights reserved. See files LICENSE and NOTICE for details. @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef FMS_HAVE_CONDUIT #include @@ -42,23 +43,27 @@ do { \ // NOTE: If set to 1 the last line will still have 2 entries. #define FMS_ELE_PER_LINE 3u -#if UINT_MAX == ULONG_MAX -#define FMS_LD "%lld" -#define FMS_LU "%llu" +// printf format string for FmsInt +#define FMS_LU "%" PRIu64 + +// Routine used for converting a string to FmsInt +#if UINT64_MAX == ULLONG_MAX +#define StrToFmsInt strtoull +#elif UINT64_MAX == ULONG_MAX +#define StrToFmsInt strtoul #else -#define FMS_LD "%ld" -#define FMS_LU "%lu" +#error "unknown conversion routine for FmsInt" #endif #define FOR_EACH_INT_TYPE(macro) \ - macro(FMS_INT8, int8_t, "%d") \ - macro(FMS_INT16, int16_t, "%d") \ - macro(FMS_INT32, int32_t, "%d") \ - macro(FMS_INT64, int64_t, FMS_LD) \ - macro(FMS_UINT8, uint8_t, "%u") \ - macro(FMS_UINT16, uint16_t, "%u") \ - macro(FMS_UINT32, uint32_t, "%u") \ - macro(FMS_UINT64, uint64_t, FMS_LU) + macro(FMS_INT8, int8_t, "%" PRId8) \ + macro(FMS_INT16, int16_t, "%" PRId16) \ + macro(FMS_INT32, int32_t, "%" PRId32) \ + macro(FMS_INT64, int64_t, "%" PRId64) \ + macro(FMS_UINT8, uint8_t, "%" PRIu8) \ + macro(FMS_UINT16, uint16_t, "%" PRIu16) \ + macro(FMS_UINT32, uint32_t, "%" PRIu32) \ + macro(FMS_UINT64, uint64_t, "%" PRIu64) #define FOR_EACH_SCALAR_TYPE(macro) \ macro(FMS_FLOAT, float, "%f") \ @@ -82,8 +87,14 @@ static void FmsErrorDebug(int err_code, const char *func, const char *file, /*"Aborting ...\n\n"*/, err_code, func, file, line); // abort(); } -#ifndef _MSC_VER +// __PRETTY_FUNCTION__ is the same as the standard __func__ for most compilers, +// with the exception of clang. GCC 9.3.0 with -Wpedantic gives a warning about +// __PRETTY_FUNCTION__ not being standard, so we use __PRETTY_FUNCTION__ only +// with clang. +#if defined(__clang__) #define FMS_PRETTY_FUNCTION __PRETTY_FUNCTION__ +#elif !defined(_MSC_VER) +#define FMS_PRETTY_FUNCTION __func__ #else // for Visual Studio C++ #define FMS_PRETTY_FUNCTION __FUNCSIG__ #endif @@ -105,7 +116,9 @@ static inline int FmsIOCopyString(const char *str, char **str_copy_p) { } // Make sure dst is large enough to hold N + 1 chars. N should be strlen(str) to convert an entire string. -static inline int FmsIOStringToLower(const char *src, const size_t N, char *dst) { +#ifdef FMS_HAVE_CONDUIT +static inline int FmsIOStringToLower(const char *src, const size_t N, + char *dst) { if(!dst) return 1; if(!src) dst[0] = '\0'; for(size_t i = 0; i < N; i++) @@ -113,13 +126,7 @@ static inline int FmsIOStringToLower(const char *src, const size_t N, char *dst) dst[N] = '\0'; return 0; } - -// Return m=2^k, k-integer, such that: m >= n > m/2 -static inline FmsInt NextPow2(FmsInt n) { - FmsInt m = 1; - while (m < n) { m *= 2; } - return m; -} +#endif /** Data structures. @@ -173,7 +180,7 @@ typedef struct { union { FmsIntType i_type; FmsScalarType s_type; - }; + } subtype; const char *name; FmsInt size; void *data; @@ -520,7 +527,6 @@ FmsIOReadKeyValue(FmsIOContext *ctx, char *key, char *value) { // After the ':' is a space then the value starts if(value) { - N = 0; N = strlen(key_end+2); if(N >= FMS_BUFFER_SIZE) E_RETURN(5); @@ -535,7 +541,6 @@ FmsIOReadKeyValue(FmsIOContext *ctx, char *key, char *value) { static int FmsIOHasPath(FmsIOContext *ctx, const char *path) { int err = 0; - long curr_loc = 0; char k[FMS_BUFFER_SIZE]; if(!ctx) E_RETURN(1); if(!path) E_RETURN(2); @@ -582,20 +587,12 @@ FmsIOGetInt(FmsIOContext *ctx, const char *path, FmsInt *value) { if(strcmp(k, path)) E_RETURN(5); -#if UINT_MAX == ULONG_MAX - *value = strtoull(v, NULL, 10); -#else - *value = strtoul(v, NULL, 10); -#endif + *value = StrToFmsInt(v, NULL, 10); - // Potential error - if(value == 0) { - if(errno == EINVAL) - E_RETURN(6); + // Potential errors + if (errno == ERANGE) { E_RETURN(6); } + if (errno == EINVAL) { E_RETURN(7); } - if(errno == ERANGE) - E_RETURN(7); - } return 0; } @@ -631,16 +628,10 @@ FmsIOGetTypedIntArray(FmsIOContext *ctx, const char *path, FmsIntType *type, if(err) E_RETURN(7); -#if UINT_MAX == ULONG_MAX - *n = strtoull(v, NULL, 10); -#else - *n = strtoul(v, NULL, 10); -#endif + *n = StrToFmsInt(v, NULL, 10); - if(*n == 0) { - if(errno == EINVAL) E_RETURN(8); - if(errno == ERANGE) E_RETURN(9); - } + if (errno == ERANGE) { E_RETURN(8); } + if (errno == EINVAL) { E_RETURN(9); } } { @@ -677,15 +668,15 @@ do { \ DEST_T *data = malloc(sizeof(DEST_T) * *n); \ FmsInt i = 0; \ while(1) { \ - FmsInt len = strlen(v); \ + size_t len = strlen(v); \ char *off = v, *newoff = NULL; \ if(off[0] == '[') \ off++; \ while(len && i < *n) { \ data[i++] = (DEST_T)FUNC(off, &newoff, 10); \ newoff++; \ - if(*newoff = ' ') newoff++; /* Current flaw in the file format, last element has no trialing space */ \ - if(newoff - v >= len) break; \ + if(*newoff == ' ') newoff++; /* Current flaw in the file format, last element has no trialing space */ \ + if(newoff >= v + len) break; \ off = newoff; \ } \ if(strchr(v, ']')) break; \ @@ -694,46 +685,36 @@ do { \ *values = (void*)data; \ } while(0) -#if UINT_MAX == ULONG_MAX -#define UNSIGNED_FUNC strtoull -#define SIGNED_FUNC strtoll -#else -#define UNSIGNED_FUNC strtoul -#define SIGNED_FUNC strtol -#endif - switch(*type) { case FMS_INT8: - READ_ARRAY_DATA(int8_t, SIGNED_FUNC); + READ_ARRAY_DATA(int8_t, strtoimax); break; case FMS_INT16: - READ_ARRAY_DATA(int16_t, SIGNED_FUNC); + READ_ARRAY_DATA(int16_t, strtoimax); break; case FMS_INT32: - READ_ARRAY_DATA(int32_t, SIGNED_FUNC); + READ_ARRAY_DATA(int32_t, strtoimax); break; case FMS_INT64: - READ_ARRAY_DATA(int64_t, SIGNED_FUNC); + READ_ARRAY_DATA(int64_t, strtoimax); break; case FMS_UINT8: - READ_ARRAY_DATA(uint8_t, UNSIGNED_FUNC); + READ_ARRAY_DATA(uint8_t, strtoumax); break; case FMS_UINT16: - READ_ARRAY_DATA(uint16_t, UNSIGNED_FUNC); + READ_ARRAY_DATA(uint16_t, strtoumax); break; case FMS_UINT32: - READ_ARRAY_DATA(uint32_t, UNSIGNED_FUNC); + READ_ARRAY_DATA(uint32_t, strtoumax); break; case FMS_UINT64: - READ_ARRAY_DATA(uint64_t, UNSIGNED_FUNC); + READ_ARRAY_DATA(uint64_t, strtoumax); break; default: E_RETURN(16); break; } #undef READ_ARRAY_DATA -#undef UNSIGNED_FUNC -#undef SIGNED_FUNC return 0; } @@ -770,16 +751,10 @@ FmsIOGetScalarArray(FmsIOContext *ctx, const char *path, FmsScalarType *type, if(err) E_RETURN(7); -#if UINT_MAX == ULONG_MAX - *n = strtoull(v, NULL, 10); -#else - *n = strtoul(v, NULL, 10); -#endif + *n = StrToFmsInt(v, NULL, 10); - if(*n == 0) { - if(errno == EINVAL) E_RETURN(8); - if(errno == ERANGE) E_RETURN(9); - } + if (errno == ERANGE) { E_RETURN(8); } + if (errno == EINVAL) { E_RETURN(9); } } { @@ -817,15 +792,15 @@ do { \ DEST_T *data = malloc(sizeof(DEST_T) * SIZE); \ FmsInt i = 0; \ while(1) { \ - FmsInt len = strlen(v); \ + size_t len = strlen(v); \ char *off = v, *newoff = NULL; \ if(off[0] == '[') \ off++; \ while(len && i < SIZE) { \ data[i++] = (DEST_T)FUNC(off, &newoff); \ newoff++; \ - if(*newoff = ' ') newoff++; /* Current flaw in the file format, last element has no trialing space */ \ - if(newoff - v >= len) break; \ + if(*newoff == ' ') newoff++; /* Current flaw in the file format, last element has no trialing space */ \ + if(newoff >= v + len) break; \ off = newoff; \ } \ if(strchr(v, ']')) break; \ @@ -886,11 +861,14 @@ FmsIOGetString(FmsIOContext *ctx, const char *path, const char **value) { return 0; } +// This function is not used, for now. +#if 0 static int FmsIOGetStringArray(FmsIOContext *ctx, const char *path, const char ***values, FmsInt *n) { E_RETURN(1); // TODO: Implement } +#endif /** @brief This function initializes the IO context . @@ -987,7 +965,7 @@ FmsIOAddIntConduit(FmsIOContext *ctx, const char *path, FmsInt value) { static int FmsIOAddIntArrayConduit(FmsIOContext *ctx, const char *path, - const FmsInt *values, size_t n) { + const FmsInt *values, FmsInt n) { if(!ctx) E_RETURN(1); if(!path) E_RETURN(2); @@ -1593,12 +1571,12 @@ FmsIOWriteFmsMetaData(FmsIOContext *ctx, FmsIOFunctions *io, const char *key, kname = join_keys(key, "Name"); err = (*io->add_string)(ctx, kname, mdata_name); FREE(kname); + if (err) { E_RETURN(4); } kdata = join_keys(key, "Data"); err = (*io->add_typed_int_array)(ctx, kdata, int_type, data, size); FREE(kdata); - if(err) - E_RETURN(4); + if (err) { E_RETURN(5); } break; } case FMS_SCALAR: { @@ -1609,17 +1587,17 @@ FmsIOWriteFmsMetaData(FmsIOContext *ctx, FmsIOFunctions *io, const char *key, const void *data = NULL; if(FmsMetaDataGetScalars(mdata, &mdata_name, &scalar_type, &size, &data)) - E_RETURN(5); + E_RETURN(6); kname = join_keys(key, "Name"); err = (*io->add_string)(ctx, kname, mdata_name); FREE(kname); + if (err) { E_RETURN(7); } kdata = join_keys(key, "Data"); err = (*io->add_scalar_array)(ctx, kdata, scalar_type, data, size); FREE(kdata); - if(err) - E_RETURN(6); + if (err) { E_RETURN(8); } break; } case FMS_STRING: { @@ -1628,17 +1606,17 @@ FmsIOWriteFmsMetaData(FmsIOContext *ctx, FmsIOFunctions *io, const char *key, const char *data = NULL; if(FmsMetaDataGetString(mdata, &mdata_name, &data)) - E_RETURN(7); + E_RETURN(9); kname = join_keys(key, "Name"); err = (*io->add_string)(ctx, kname, mdata_name); FREE(kname); + if (err) { E_RETURN(10); } kdata = join_keys(key, "Data"); err = (*io->add_string)(ctx, kdata, data); FREE(kdata); - if(err) - E_RETURN(8); + if (err) { E_RETURN(11); } break; } case FMS_META_DATA: { @@ -1648,18 +1626,19 @@ FmsIOWriteFmsMetaData(FmsIOContext *ctx, FmsIOFunctions *io, const char *key, FmsMetaData *data = NULL; if(FmsMetaDataGetMetaData(mdata, &mdata_name, &size, &data)) - E_RETURN(9); + E_RETURN(12); - if(!data) - E_RETURN(10); + if (!data) { E_RETURN(13); } kname = join_keys(key, "Name"); err = (*io->add_string)(ctx, kname, mdata_name); FREE(kname); + if (err) { E_RETURN(14); } ksize = join_keys(key, "Size"); err = (*io->add_int)(ctx, ksize, size); FREE(ksize); + if (err) { E_RETURN(15); } kdata = join_keys(key, "Data"); // Recursive? @@ -1669,15 +1648,16 @@ FmsIOWriteFmsMetaData(FmsIOContext *ctx, FmsIOFunctions *io, const char *key, tk = join_keys(kdata, temp); err = FmsIOWriteFmsMetaData(ctx, io, tk, data[i]); FREE(tk); + if (err) { + FREE(kdata); + E_RETURN(16); + } } FREE(kdata); - - if(err) - E_RETURN(11); break; } default: - E_RETURN(12); + E_RETURN(17); break; } return 0; @@ -1713,8 +1693,8 @@ FmsIOReadFmsMetaData(FmsIOContext *ctx, FmsIOFunctions *io, const char *key, case FMS_INTEGER: { // Get DataArray char *kdata = join_keys(key, "Data"); - err = (*io->get_typed_int_array)(ctx, kdata, &mdinfo->i_type, &mdinfo->data, - &mdinfo->size); + err = (*io->get_typed_int_array)(ctx, kdata, &mdinfo->subtype.i_type, + &mdinfo->data, &mdinfo->size); FREE(kdata); if(err) E_RETURN(5); @@ -1723,8 +1703,8 @@ FmsIOReadFmsMetaData(FmsIOContext *ctx, FmsIOFunctions *io, const char *key, case FMS_SCALAR: { // Get data array char *kdata = join_keys(key, "Data"); - err = (*io->get_scalar_array)(ctx, kdata, &mdinfo->s_type, &mdinfo->data, - &mdinfo->size); + err = (*io->get_scalar_array)(ctx, kdata, &mdinfo->subtype.s_type, + &mdinfo->data, &mdinfo->size); FREE(kdata); if(err) E_RETURN(6); @@ -2034,7 +2014,7 @@ FmsIOWriteComponent(FmsIOContext *ctx, FmsIOFunctions *io, const char *key, sprintf(temp, "%d", (int)i); kpart = join_keys(kparts, temp); FmsDomain dom; - if(FmsComponentGetPart(comp, i, 0, &dom, NULL, NULL, NULL, NULL)) + if(FmsComponentGetPart(comp, i, FMS_VERTEX, &dom, NULL, NULL, NULL, NULL)) E_RETURN(6); if(dom) { @@ -2219,7 +2199,7 @@ FmsIOReadFmsComponent(FmsIOContext *ctx, FmsIOFunctions *io, const char *key, char *k = join_keys(kpart, FmsEntityTypeNames[et]); if((*io->has_path)(ctx, k)) { // Now we have to populate the entitiy info - comp_info->parts[i].entities[et].ent_type = et; + comp_info->parts[i].entities[et].ent_type = (FmsEntityType)et; // Get nents { @@ -3085,19 +3065,22 @@ FmsIOBuildFmsMetaData(FmsMetaData md, FmsIOMetaDataInfo *minfo) { switch(minfo->mdtype) { case FMS_INTEGER: { void *data = NULL; - FmsMetaDataSetIntegers(md, minfo->name, minfo->i_type, minfo->size, + FmsMetaDataSetIntegers(md, minfo->name, minfo->subtype.i_type, minfo->size, &data); if(data) - memcpy(data, minfo->data, FmsIntTypeSize[minfo->i_type]*minfo->size); + memcpy(data, minfo->data, + FmsIntTypeSize[minfo->subtype.i_type]*minfo->size); else E_RETURN(3); break; } case FMS_SCALAR: { void *data = NULL; - FmsMetaDataSetScalars(md, minfo->name, minfo->s_type, minfo->size, &data); + FmsMetaDataSetScalars(md, minfo->name, minfo->subtype.s_type, minfo->size, + &data); if(data) - memcpy(data, minfo->data, FmsScalarTypeSize[minfo->s_type]*minfo->size); + memcpy(data, minfo->data, + FmsScalarTypeSize[minfo->subtype.s_type]*minfo->size); else E_RETURN(4); break; @@ -3114,8 +3097,7 @@ FmsIOBuildFmsMetaData(FmsMetaData md, FmsIOMetaDataInfo *minfo) { if(child) { for(i = 0; i < minfo->size; ++i) FmsIOBuildFmsMetaData(child[i], &mds[i]); - } - else + } else E_RETURN(5); } break; @@ -3265,8 +3247,9 @@ FmsIOBuildFmsDataCollection(FmsIODataCollectionInfo *dc_info, break; } } - FmsFieldDescriptorSetFixedOrder(fd, fd_info->fixed_order[0], - fd_info->fixed_order[1], fd_info->fixed_order[2]); + FmsFieldDescriptorSetFixedOrder(fd, (FmsFieldType)fd_info->fixed_order[0], + (FmsBasisType)fd_info->fixed_order[1], + fd_info->fixed_order[2]); // TODO: Check ndofs & type against what was serialized? } } @@ -3330,6 +3313,7 @@ FmsIOBuildFmsDataCollection(FmsIODataCollectionInfo *dc_info, FmsMetaData md = NULL; FmsDataCollectionAttachMetaData(*dc, &md); err = FmsIOBuildFmsMetaData(md, dc_info->md); + (void)err; // TODO: error handling } return 0; @@ -3377,8 +3361,6 @@ static int FmsIODestroyFmsIODataCollectionInfo(FmsIODataCollectionInfo *dc_info) { if(!dc_info) E_RETURN(1); - int err = 0; - // Destroy DomainNameInfos & DomainInfos const FmsInt ndomnames = dc_info->mesh_info->ndomain_names; if(ndomnames) { @@ -3515,7 +3497,9 @@ FmsIOWrite(const char *filename, const char *protocol, FmsDataCollection dc) { /* "open" the file. */ if((*io.open)(&ctx, filename, "wt") == 0) { - if((*io.add_int)(&ctx, "FMS", (int)FMS_INTERFACE_VERSION) != 0) { + // FMS format version of this writer: 100 = v0.1 + const FmsInt fms_format_version = 100; + if((*io.add_int)(&ctx, "FMS", fms_format_version) != 0) { /* "close" the file. */ (*io.close)(&ctx); E_RETURN(6); @@ -3599,6 +3583,7 @@ FmsIORead(const char *filename, const char *protocol, FmsDataCollection *dc) { E_RETURN(5); } #else + (void)protocol; FmsIOContextInitialize(&ctx); FmsIOFunctionsInitialize(&io); #endif @@ -3609,8 +3594,10 @@ FmsIORead(const char *filename, const char *protocol, FmsDataCollection *dc) { FmsInt version = 0; FmsIODataCollectionInfo *dc_info; FmsIOConstructFmsIODataCollectionInfo(&dc_info); + // FMS format version of this reader: 100 = v0.1 + const FmsInt fms_format_version = 100; err = (*io.get_int)(&ctx, "FMS", &version); - if(err != 0 || version != (int)FMS_INTERFACE_VERSION) { + if(err != 0 || version != fms_format_version) { /* "close" the file. */ (*io.close)(&ctx); E_RETURN(6); diff --git a/src/fmsio.h b/src/fmsio.h index 246561d..bce6615 100644 --- a/src/fmsio.h +++ b/src/fmsio.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at + Copyright (c) 2021, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights reserved. See files LICENSE and NOTICE for details. @@ -16,6 +16,10 @@ testbed platforms, in support of the nation's exascale computing imperative. */ +/** @file fmsio.h + FMS file I/O functions. + Header file added in version: v0.2. */ + #ifndef FMS_IO_HEADER #define FMS_IO_HEADER #include @@ -28,14 +32,16 @@ extern "C" { @brief Writes the provided FmsDataCollection to a file. @param filename The name of the file to save. If the filename does not include an appropriate file extension, one may be added. -@param protocol The type of file to be saved. By default, the protocol - should be "ascii". If FMS is compiled with Conduit support then - the protocol can match the supported Conduit protocols, which - can include: "json", "yaml", "conduit_bin", "hdf5". +@param protocol The type of file to be saved. By default, the protocol should be + "ascii". If FMS is compiled with Conduit support then the + protocol can match the supported Conduit protocols, which can + include: "json", "yaml", "conduit_bin", "hdf5". @param dc The FMS object that will be written to the file. -@return The function returns 0 on success and non-zero for failure. - If Conduit support is enabled then a return value of 2 indicates the +@return The function returns 0 on success and non-zero for failure. + If Conduit support is enabled then a return value of 2 indicates the given protocol is unsupported by the Conduit runtime. + +Added in version: v0.2. */ int FmsIOWrite(const char *filename, const char *protocol, FmsDataCollection dc); @@ -43,17 +49,20 @@ int FmsIOWrite(const char *filename, const char *protocol, /** @brief Reads an FmsDataCollection from a file. @param filename The name of the file to read. -@param protocol The type of file to be read. By default, the protocol - should be "ascii". If FMS is compiled with Conduit support then - the protocol can match the supported Conduit protocols, which - can include: "json", "yaml", "conduit_bin", "hdf5". Adding a protocol - will help FMS and Conduit decide which method is appropriate for - reading the file. If Conduit support is enabled and protocol is NULL - an educated guess will be made for which protocol to use. +@param protocol The type of file to be read. By default, the protocol should be + "ascii". If FMS is compiled with Conduit support then the + protocol can match the supported Conduit protocols, which can + include: "json", "yaml", "conduit_bin", "hdf5". Adding a + protocol will help FMS and Conduit decide which method is + appropriate for reading the file. If Conduit support is enabled + and protocol is NULL an educated guess will be made for which + protocol to use. @param[out] dc The FMS object that was read from the file. @return The function returns 0 on success and non-zero for failure. - If Conduit support is enabled then a return value of 2 indicates the + If Conduit support is enabled then a return value of 2 indicates the given protocol is unsupported by the Conduit runtime. + +Added in version: v0.2. */ int FmsIORead(const char *filename, const char *protocol, FmsDataCollection *dc); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d2dddf0..0ad10eb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -45,6 +45,10 @@ function(fms_add_cpp_test) endfunction() # ------------------------------------------------------------------------ +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + # Add FmsBaselines add_library(fms_testing_common STATIC fmstesting.hpp fmstesting.cpp) target_link_libraries(fms_testing_common PUBLIC fms) @@ -58,4 +62,4 @@ fms_add_cpp_test( fms_add_cpp_test( TEST t_fmsio -) \ No newline at end of file +) diff --git a/tests/fmstesting.cpp b/tests/fmstesting.cpp index 6d0fbd2..ed7674f 100644 --- a/tests/fmstesting.cpp +++ b/tests/fmstesting.cpp @@ -1,4 +1,4 @@ -#include +#include "fmstesting.hpp" #include // #define PRINT_DATASETS @@ -7,324 +7,328 @@ #endif int Construct2DData0(FmsDataCollection *out_dc) { - if(!out_dc) return 1; - // Taken from examples/meshing/simple_mesh.c - FmsMesh mesh; - FmsMeshConstruct(&mesh); - FmsMeshSetPartitionId(mesh, 0, 1); - - FmsDomain *domain; - FmsMeshAddDomains(mesh, "domains", 1, &domain); - FmsDomainSetNumVertices(domain[0], 4); - FmsDomainSetNumEntities(domain[0], FMS_EDGE, FMS_INT32, 4); - FmsDomainSetNumEntities(domain[0], FMS_QUADRILATERAL, FMS_INT32, 1); - - const int edge_vert[] = {0,1, 1,2, 2,3, 3,0}; - FmsDomainAddEntities(domain[0], FMS_EDGE, NULL, FMS_INT32, edge_vert, 4); - - const int quad_edge[] = {0, 1, 2, 3}; - FmsDomainAddEntities(domain[0], FMS_QUADRILATERAL, NULL, - FMS_INT32, quad_edge, 1); - - FmsComponent volume; - FmsMeshAddComponent(mesh, "volume", &volume); - FmsComponentAddDomain(volume, domain[0]); - - FmsComponent boundary; - FmsMeshAddComponent(mesh, "boundary", &boundary); - FmsInt part_id; - FmsComponentAddPart(boundary, domain[0], &part_id); - const int bdr_edge[] = {2}; - FmsComponentAddPartEntities(boundary, part_id, FMS_EDGE, FMS_INT32, - FMS_INT32, FMS_INT32, NULL, bdr_edge, NULL, 1); - - FmsComponentAddRelation(volume, 1); // 1 = index of "boundary" component - - // Mesh Tags - FmsTag material; - FmsMeshAddTag(mesh, "material", &material); - FmsTagSetComponent(material, volume); - const int material_tags[] = {1}; - FmsTagSet(material, FMS_INT32, FMS_INT32, material_tags, 1); - - int tvs[1] = {1}; - const char * const descriptions[] = {"Test"}; - FmsTagAddDescriptions(material, FMS_INT32, tvs, descriptions, 1); - - FmsMeshFinalize(mesh); - FmsMeshValidate(mesh); - - FmsDataCollection dc; - FmsDataCollectionCreate(mesh, "data collection", &dc); - - FmsFieldDescriptor coords_fd; - FmsDataCollectionAddFieldDescriptor(dc, "coords descriptor", &coords_fd); - FmsFieldDescriptorSetComponent(coords_fd, volume); - FmsInt coords_order = 1; - FmsFieldDescriptorSetFixedOrder(coords_fd, FMS_CONTINUOUS, - FMS_NODAL_GAUSS_CLOSED, coords_order); - - FmsField coords; - FmsDataCollectionAddField(dc, "coords", &coords); - const double coords_data[] = { + if(!out_dc) return 1; + // Taken from examples/meshing/simple_mesh.c + FmsMesh mesh; + FmsMeshConstruct(&mesh); + FmsMeshSetPartitionId(mesh, 0, 1); + + FmsDomain *domain; + FmsMeshAddDomains(mesh, "domains", 1, &domain); + FmsDomainSetNumVertices(domain[0], 4); + FmsDomainSetNumEntities(domain[0], FMS_EDGE, FMS_INT32, 4); + FmsDomainSetNumEntities(domain[0], FMS_QUADRILATERAL, FMS_INT32, 1); + + const int edge_vert[] = {0,1, 1,2, 2,3, 3,0}; + FmsDomainAddEntities(domain[0], FMS_EDGE, NULL, FMS_INT32, edge_vert, 4); + + const int quad_edge[] = {0, 1, 2, 3}; + FmsDomainAddEntities(domain[0], FMS_QUADRILATERAL, NULL, + FMS_INT32, quad_edge, 1); + + FmsComponent volume; + FmsMeshAddComponent(mesh, "volume", &volume); + FmsComponentAddDomain(volume, domain[0]); + + FmsComponent boundary; + FmsMeshAddComponent(mesh, "boundary", &boundary); + FmsInt part_id; + FmsComponentAddPart(boundary, domain[0], &part_id); + const int bdr_edge[] = {2}; + FmsComponentAddPartEntities(boundary, part_id, FMS_EDGE, FMS_INT32, + FMS_INT32, FMS_INT32, NULL, bdr_edge, NULL, 1); + + FmsComponentAddRelation(volume, 1); // 1 = index of "boundary" component + + // Mesh Tags + FmsTag material; + FmsMeshAddTag(mesh, "material", &material); + FmsTagSetComponent(material, volume); + const int material_tags[] = {1}; + FmsTagSet(material, FMS_INT32, FMS_INT32, material_tags, 1); + + int tvs[1] = {1}; + const char * const descriptions[] = {"Test"}; + FmsTagAddDescriptions(material, FMS_INT32, tvs, descriptions, 1); + + FmsMeshFinalize(mesh); + FmsMeshValidate(mesh); + + FmsDataCollection dc; + FmsDataCollectionCreate(mesh, "data collection", &dc); + + FmsFieldDescriptor coords_fd; + FmsDataCollectionAddFieldDescriptor(dc, "coords descriptor", &coords_fd); + FmsFieldDescriptorSetComponent(coords_fd, volume); + FmsInt coords_order = 1; + FmsFieldDescriptorSetFixedOrder(coords_fd, FMS_CONTINUOUS, + FMS_NODAL_GAUSS_CLOSED, coords_order); + + FmsField coords; + FmsDataCollectionAddField(dc, "coords", &coords); + const double coords_data[] = { 0.,0., 1.,0., 1.,1., 0.,1. - }; - FmsInt sdim = 2; // A 2D mesh embedded in "sdim"-dimensional space. - FmsFieldSet(coords, coords_fd, sdim, FMS_BY_VDIM, FMS_DOUBLE, coords_data); + }; + FmsInt sdim = 2; // A 2D mesh embedded in "sdim"-dimensional space. + FmsFieldSet(coords, coords_fd, sdim, FMS_BY_VDIM, FMS_DOUBLE, coords_data); - FmsComponentSetCoordinates(volume, coords); - *out_dc = dc; + FmsComponentSetCoordinates(volume, coords); + *out_dc = dc; #ifdef PRINT_DATASETS - FmsIOWrite("2DData0.fms", "ascii", dc); + FmsIOWrite("2DData0.fms", "ascii", dc); #endif - return 0; + return 0; } int Construct2DData1(FmsDataCollection *out_dc) { - if(!out_dc) return 1; - // Taken from examples/meshing/simple_mesh.c - FmsMesh mesh; - FmsMeshConstruct(&mesh); - FmsMeshSetPartitionId(mesh, 0, 1); - - FmsDomain *domain = NULL; - FmsMeshAddDomains(mesh, "domains", 1, &domain); - FmsDomainSetNumVertices(domain[0], 3); - FmsDomainSetNumEntities(domain[0], FMS_EDGE, FMS_INT32, 3); - FmsDomainSetNumEntities(domain[0], FMS_TRIANGLE, FMS_INT32, 1); - - const int edge_vert[] = {0,1, 1,2, 2,0}; - FmsDomainAddEntities(domain[0], FMS_EDGE, NULL, FMS_INT32, edge_vert, 3); - - const int tri_edge[] = {0, 1, 2}; - FmsDomainAddEntities(domain[0], FMS_TRIANGLE, NULL, - FMS_INT32, tri_edge, 1); - - FmsComponent volume; - FmsMeshAddComponent(mesh, "volume", &volume); - FmsComponentAddDomain(volume, domain[0]); - - FmsComponent boundary; - FmsMeshAddComponent(mesh, "boundary", &boundary); - FmsInt part_id; - FmsComponentAddPart(boundary, domain[0], &part_id); - const int bdr_edge[] = {2}; - FmsComponentAddPartEntities(boundary, part_id, FMS_EDGE, FMS_INT32, - FMS_INT32, FMS_INT32, NULL, bdr_edge, NULL, 1); - - FmsComponentAddRelation(volume, 1); // 1 = index of "boundary" component - - // Mesh Tags - FmsTag material; - FmsMeshAddTag(mesh, "material", &material); - FmsTagSetComponent(material, volume); - const int material_tags[] = {1}; - FmsTagSet(material, FMS_INT32, FMS_INT32, material_tags, 1); - - int tvs[1] = {1}; - const char * const descriptions[] = {"Test"}; - FmsTagAddDescriptions(material, FMS_INT32, tvs, descriptions, 1); - - FmsMeshFinalize(mesh); - FmsMeshValidate(mesh); - - FmsDataCollection dc; - FmsDataCollectionCreate(mesh, "data collection", &dc); - - FmsFieldDescriptor coords_fd; - FmsDataCollectionAddFieldDescriptor(dc, "coords descriptor", &coords_fd); - FmsFieldDescriptorSetComponent(coords_fd, volume); - FmsInt coords_order = 1; - FmsFieldDescriptorSetFixedOrder(coords_fd, FMS_CONTINUOUS, - FMS_NODAL_GAUSS_CLOSED, coords_order); - - FmsField coords; - FmsDataCollectionAddField(dc, "coords", &coords); - const double coords_data[] = { - 0.,0., - 1.,0., - 0.,1. - }; - FmsInt sdim = 2; // A 2D mesh embedded in "sdim"-dimensional space. - FmsFieldSet(coords, coords_fd, sdim, FMS_BY_VDIM, FMS_DOUBLE, coords_data); + if(!out_dc) return 1; + // Taken from examples/meshing/simple_mesh.c + FmsMesh mesh; + FmsMeshConstruct(&mesh); + FmsMeshSetPartitionId(mesh, 0, 1); + + FmsDomain *domain = NULL; + FmsMeshAddDomains(mesh, "domains", 1, &domain); + FmsDomainSetNumVertices(domain[0], 3); + FmsDomainSetNumEntities(domain[0], FMS_EDGE, FMS_INT32, 3); + FmsDomainSetNumEntities(domain[0], FMS_TRIANGLE, FMS_INT32, 1); + + const int edge_vert[] = {0,1, 1,2, 2,0}; + FmsDomainAddEntities(domain[0], FMS_EDGE, NULL, FMS_INT32, edge_vert, 3); + + const int tri_edge[] = {0, 1, 2}; + FmsDomainAddEntities(domain[0], FMS_TRIANGLE, NULL, + FMS_INT32, tri_edge, 1); + + FmsComponent volume; + FmsMeshAddComponent(mesh, "volume", &volume); + FmsComponentAddDomain(volume, domain[0]); + + FmsComponent boundary; + FmsMeshAddComponent(mesh, "boundary", &boundary); + FmsInt part_id; + FmsComponentAddPart(boundary, domain[0], &part_id); + const int bdr_edge[] = {2}; + FmsComponentAddPartEntities(boundary, part_id, FMS_EDGE, FMS_INT32, + FMS_INT32, FMS_INT32, NULL, bdr_edge, NULL, 1); + + FmsComponentAddRelation(volume, 1); // 1 = index of "boundary" component + + // Mesh Tags + FmsTag material; + FmsMeshAddTag(mesh, "material", &material); + FmsTagSetComponent(material, volume); + const int material_tags[] = {1}; + FmsTagSet(material, FMS_INT32, FMS_INT32, material_tags, 1); + + int tvs[1] = {1}; + const char * const descriptions[] = {"Test"}; + FmsTagAddDescriptions(material, FMS_INT32, tvs, descriptions, 1); + + FmsMeshFinalize(mesh); + FmsMeshValidate(mesh); + + FmsDataCollection dc; + FmsDataCollectionCreate(mesh, "data collection", &dc); + + FmsFieldDescriptor coords_fd; + FmsDataCollectionAddFieldDescriptor(dc, "coords descriptor", &coords_fd); + FmsFieldDescriptorSetComponent(coords_fd, volume); + FmsInt coords_order = 1; + FmsFieldDescriptorSetFixedOrder(coords_fd, FMS_CONTINUOUS, + FMS_NODAL_GAUSS_CLOSED, coords_order); + + FmsField coords; + FmsDataCollectionAddField(dc, "coords", &coords); + const double coords_data[] = { + 0.,0., + 1.,0., + 0.,1. + }; + FmsInt sdim = 2; // A 2D mesh embedded in "sdim"-dimensional space. + FmsFieldSet(coords, coords_fd, sdim, FMS_BY_VDIM, FMS_DOUBLE, coords_data); - FmsComponentSetCoordinates(volume, coords); - *out_dc = dc; + FmsComponentSetCoordinates(volume, coords); + *out_dc = dc; #ifdef PRINT_DATASETS - FmsIOWrite("2DData1.fms", "ascii", dc); + FmsIOWrite("2DData1.fms", "ascii", dc); #endif - return 0; + return 0; } // 1 element hex mesh int Construct3DData0(FmsDataCollection *out_dc) { - if(!out_dc) return 1; - FmsMesh mesh; - FmsMeshConstruct(&mesh); - FmsMeshSetPartitionId(mesh, 0, 1); - FmsDomain *domain; - FmsMeshAddDomains(mesh, "domains", 1, &domain); - FmsDomainSetNumVertices(domain[0], 8); - const int edge_vert[] = {0,1, 2,3, 4,5, 6,7, - 0,2, 1,3, 4,6, 5,7, - 0,4, 1,5, 2,6, 3,7}; - FmsDomainSetNumEntities(domain[0], FMS_EDGE, FMS_INT32, 12); - FmsDomainAddEntities(domain[0], FMS_EDGE, NULL, FMS_INT32, edge_vert, 12); - const int quad_edge[] = {0,5,1,4, 2,7,3,6, 0,9,2,8, 1,10,3,11, 4,8,6,10, 5,11,7,9}; - FmsDomainSetNumEntities(domain[0], FMS_QUADRILATERAL, FMS_INT32, 6); - FmsDomainAddEntities(domain[0], FMS_QUADRILATERAL, NULL, - FMS_INT32, quad_edge, 6); - const int hex_face[] = {0,1,2,3,4,5}; - FmsDomainSetNumEntities(domain[0], FMS_HEXAHEDRON, FMS_INT32, 1); - FmsDomainAddEntities(domain[0], FMS_HEXAHEDRON, NULL, FMS_INT32, hex_face, 1); - FmsComponent volume; - FmsMeshAddComponent(mesh, "volume", &volume); - FmsComponentAddDomain(volume, domain[0]); - FmsComponent boundary; - FmsMeshAddComponent(mesh, "boundary", &boundary); - FmsInt part_id; - FmsComponentAddPart(boundary, domain[0], &part_id); - const int bdr_face[] = {0,2,4}; - FmsComponentAddPartEntities(boundary, part_id, FMS_QUADRILATERAL, FMS_INT32, - FMS_INT32, FMS_INT32, NULL, bdr_face, NULL, 3); - FmsComponentAddRelation(volume, 1); // 1 = index of "boundary" component - // Mesh Tags - FmsTag material; - FmsMeshAddTag(mesh, "material", &material); - FmsTagSetComponent(material, volume); - const int material_tags[] = {1}; - FmsTagSet(material, FMS_INT32, FMS_INT32, material_tags, 1); - int tvs[1] = {1}; - const char * const descriptions[] = {"Test"}; - FmsTagAddDescriptions(material, FMS_INT32, tvs, descriptions, 1); - FmsMeshFinalize(mesh); - FmsMeshValidate(mesh); - FmsDataCollection dc; - FmsDataCollectionCreate(mesh, "data collection", &dc); - FmsFieldDescriptor coords_fd; - FmsDataCollectionAddFieldDescriptor(dc, "coords descriptor", &coords_fd); - FmsFieldDescriptorSetComponent(coords_fd, volume); - FmsInt coords_order = 1; - FmsFieldDescriptorSetFixedOrder(coords_fd, FMS_CONTINUOUS, - FMS_NODAL_GAUSS_CLOSED, coords_order); - FmsField coords; - FmsDataCollectionAddField(dc, "coords", &coords); - const double coords_data[] = { - -1,-1,-1, 1,-1,-1, -1,1,-1, 1,1,-1, - -1,-1,1, 1,-1,1, -1,1,1, 1,1,1}; - FmsInt sdim = 3; - FmsFieldSet(coords, coords_fd, sdim, FMS_BY_VDIM, FMS_DOUBLE, coords_data); - FmsComponentSetCoordinates(volume, coords); - *out_dc = dc; + if(!out_dc) return 1; + FmsMesh mesh; + FmsMeshConstruct(&mesh); + FmsMeshSetPartitionId(mesh, 0, 1); + FmsDomain *domain; + FmsMeshAddDomains(mesh, "domains", 1, &domain); + FmsDomainSetNumVertices(domain[0], 8); + const int edge_vert[] = {0,1, 2,3, 4,5, 6,7, + 0,2, 1,3, 4,6, 5,7, + 0,4, 1,5, 2,6, 3,7 + }; + FmsDomainSetNumEntities(domain[0], FMS_EDGE, FMS_INT32, 12); + FmsDomainAddEntities(domain[0], FMS_EDGE, NULL, FMS_INT32, edge_vert, 12); + const int quad_edge[] = {0,5,1,4, 2,7,3,6, 0,9,2,8, 1,10,3,11, 4,8,6,10, 5,11,7,9}; + FmsDomainSetNumEntities(domain[0], FMS_QUADRILATERAL, FMS_INT32, 6); + FmsDomainAddEntities(domain[0], FMS_QUADRILATERAL, NULL, + FMS_INT32, quad_edge, 6); + const int hex_face[] = {0,1,2,3,4,5}; + FmsDomainSetNumEntities(domain[0], FMS_HEXAHEDRON, FMS_INT32, 1); + FmsDomainAddEntities(domain[0], FMS_HEXAHEDRON, NULL, FMS_INT32, hex_face, 1); + FmsComponent volume; + FmsMeshAddComponent(mesh, "volume", &volume); + FmsComponentAddDomain(volume, domain[0]); + FmsComponent boundary; + FmsMeshAddComponent(mesh, "boundary", &boundary); + FmsInt part_id; + FmsComponentAddPart(boundary, domain[0], &part_id); + const int bdr_face[] = {0,2,4}; + FmsComponentAddPartEntities(boundary, part_id, FMS_QUADRILATERAL, FMS_INT32, + FMS_INT32, FMS_INT32, NULL, bdr_face, NULL, 3); + FmsComponentAddRelation(volume, 1); // 1 = index of "boundary" component + // Mesh Tags + FmsTag material; + FmsMeshAddTag(mesh, "material", &material); + FmsTagSetComponent(material, volume); + const int material_tags[] = {1}; + FmsTagSet(material, FMS_INT32, FMS_INT32, material_tags, 1); + int tvs[1] = {1}; + const char * const descriptions[] = {"Test"}; + FmsTagAddDescriptions(material, FMS_INT32, tvs, descriptions, 1); + FmsMeshFinalize(mesh); + FmsMeshValidate(mesh); + FmsDataCollection dc; + FmsDataCollectionCreate(mesh, "data collection", &dc); + FmsFieldDescriptor coords_fd; + FmsDataCollectionAddFieldDescriptor(dc, "coords descriptor", &coords_fd); + FmsFieldDescriptorSetComponent(coords_fd, volume); + FmsInt coords_order = 1; + FmsFieldDescriptorSetFixedOrder(coords_fd, FMS_CONTINUOUS, + FMS_NODAL_GAUSS_CLOSED, coords_order); + FmsField coords; + FmsDataCollectionAddField(dc, "coords", &coords); + const double coords_data[] = { + -1,-1,-1, 1,-1,-1, -1,1,-1, 1,1,-1, + -1,-1,1, 1,-1,1, -1,1,1, 1,1,1 + }; + FmsInt sdim = 3; + FmsFieldSet(coords, coords_fd, sdim, FMS_BY_VDIM, FMS_DOUBLE, coords_data); + FmsComponentSetCoordinates(volume, coords); + *out_dc = dc; #ifdef PRINT_DATASETS - FmsIOWrite("3DData0.fms", "ascii", dc); + FmsIOWrite("3DData0.fms", "ascii", dc); #endif - return 0; + return 0; } // 1 element tet mesh int Construct3DData1(FmsDataCollection *out_dc) { - if(!out_dc) return 1; - // Taken from examples/meshing/simple_mesh.c - FmsMesh mesh; - FmsMeshConstruct(&mesh); - FmsMeshSetPartitionId(mesh, 0, 1); - FmsDomain *domain; - FmsMeshAddDomains(mesh, "domains", 1, &domain); - FmsDomainSetNumVertices(domain[0], 4); - const int edge_vert[] = {0,1, 0,2, 1,2, 0,3, 1,3, 2,3}; - FmsDomainSetNumEntities(domain[0], FMS_EDGE, FMS_INT32, 6); - FmsDomainAddEntities(domain[0], FMS_EDGE, NULL, FMS_INT32, edge_vert, 6); - const int tri_edge[] = {0,2,1, 1,3,5, 0,4,3, 2,5,4}; - FmsDomainSetNumEntities(domain[0], FMS_TRIANGLE, FMS_INT32, 4); - FmsDomainAddEntities(domain[0], FMS_TRIANGLE, NULL, - FMS_INT32, tri_edge, 4); - const int tet_faces[] = {0,1,2,3}; - FmsDomainSetNumEntities(domain[0], FMS_TETRAHEDRON, FMS_INT32, 1); - FmsDomainAddEntities(domain[0], FMS_TETRAHEDRON, NULL, FMS_INT32, tet_faces, 1); - FmsComponent volume; - FmsMeshAddComponent(mesh, "volume", &volume); - FmsComponentAddDomain(volume, domain[0]); - FmsComponent boundary; - FmsMeshAddComponent(mesh, "boundary", &boundary); - FmsInt part_id; - FmsComponentAddPart(boundary, domain[0], &part_id); - const int bdr_face[] = {0,1,2}; - FmsComponentAddPartEntities(boundary, part_id, FMS_TRIANGLE, FMS_INT32, - FMS_INT32, FMS_INT32, NULL, bdr_face, NULL, 3); - FmsComponentAddRelation(volume, 1); // 1 = index of "boundary" component - // Mesh Tags - FmsTag material; - FmsMeshAddTag(mesh, "material", &material); - FmsTagSetComponent(material, volume); - const int material_tags[] = {1}; - FmsTagSet(material, FMS_INT32, FMS_INT32, material_tags, 1); - int tvs[1] = {1}; - const char * const descriptions[] = {"Test"}; - FmsTagAddDescriptions(material, FMS_INT32, tvs, descriptions, 1); - FmsMeshFinalize(mesh); - FmsMeshValidate(mesh); - FmsDataCollection dc; - FmsDataCollectionCreate(mesh, "data collection", &dc); - FmsFieldDescriptor coords_fd; - FmsDataCollectionAddFieldDescriptor(dc, "coords descriptor", &coords_fd); - FmsFieldDescriptorSetComponent(coords_fd, volume); - FmsInt coords_order = 1; - FmsFieldDescriptorSetFixedOrder(coords_fd, FMS_DISCONTINUOUS, - FMS_NODAL_GAUSS_CLOSED, coords_order); - FmsField coords; - FmsDataCollectionAddField(dc, "coords", &coords); - const double coords_data[] = { - -1,-1,-1, 1,-1,-1, -1,1,-1, -1,-1,1}; - FmsInt sdim = 3; - FmsFieldSet(coords, coords_fd, sdim, FMS_BY_VDIM, FMS_DOUBLE, coords_data); - FmsComponentSetCoordinates(volume, coords); - FmsMetaData mdata = NULL; - FmsDataCollectionAttachMetaData(dc, &mdata); - void *cycle = nullptr; - FmsMetaDataSetIntegers(mdata, "cycle", FMS_UINT8, 1, &cycle); - *static_cast(cycle) = 1u; - *out_dc = dc; + if(!out_dc) return 1; + // Taken from examples/meshing/simple_mesh.c + FmsMesh mesh; + FmsMeshConstruct(&mesh); + FmsMeshSetPartitionId(mesh, 0, 1); + FmsDomain *domain; + FmsMeshAddDomains(mesh, "domains", 1, &domain); + FmsDomainSetNumVertices(domain[0], 4); + const int edge_vert[] = {0,1, 0,2, 1,2, 0,3, 1,3, 2,3}; + FmsDomainSetNumEntities(domain[0], FMS_EDGE, FMS_INT32, 6); + FmsDomainAddEntities(domain[0], FMS_EDGE, NULL, FMS_INT32, edge_vert, 6); + const int tri_edge[] = {0,2,1, 1,3,5, 0,4,3, 2,5,4}; + FmsDomainSetNumEntities(domain[0], FMS_TRIANGLE, FMS_INT32, 4); + FmsDomainAddEntities(domain[0], FMS_TRIANGLE, NULL, + FMS_INT32, tri_edge, 4); + const int tet_faces[] = {0,1,2,3}; + FmsDomainSetNumEntities(domain[0], FMS_TETRAHEDRON, FMS_INT32, 1); + FmsDomainAddEntities(domain[0], FMS_TETRAHEDRON, NULL, FMS_INT32, tet_faces, 1); + FmsComponent volume; + FmsMeshAddComponent(mesh, "volume", &volume); + FmsComponentAddDomain(volume, domain[0]); + FmsComponent boundary; + FmsMeshAddComponent(mesh, "boundary", &boundary); + FmsInt part_id; + FmsComponentAddPart(boundary, domain[0], &part_id); + const int bdr_face[] = {0,1,2}; + FmsComponentAddPartEntities(boundary, part_id, FMS_TRIANGLE, FMS_INT32, + FMS_INT32, FMS_INT32, NULL, bdr_face, NULL, 3); + FmsComponentAddRelation(volume, 1); // 1 = index of "boundary" component + // Mesh Tags + FmsTag material; + FmsMeshAddTag(mesh, "material", &material); + FmsTagSetComponent(material, volume); + const int material_tags[] = {1}; + FmsTagSet(material, FMS_INT32, FMS_INT32, material_tags, 1); + int tvs[1] = {1}; + const char * const descriptions[] = {"Test"}; + FmsTagAddDescriptions(material, FMS_INT32, tvs, descriptions, 1); + FmsMeshFinalize(mesh); + FmsMeshValidate(mesh); + FmsDataCollection dc; + FmsDataCollectionCreate(mesh, "data collection", &dc); + FmsFieldDescriptor coords_fd; + FmsDataCollectionAddFieldDescriptor(dc, "coords descriptor", &coords_fd); + FmsFieldDescriptorSetComponent(coords_fd, volume); + FmsInt coords_order = 1; + FmsFieldDescriptorSetFixedOrder(coords_fd, FMS_DISCONTINUOUS, + FMS_NODAL_GAUSS_CLOSED, coords_order); + FmsField coords; + FmsDataCollectionAddField(dc, "coords", &coords); + const double coords_data[] = { + -1,-1,-1, 1,-1,-1, -1,1,-1, -1,-1,1 + }; + FmsInt sdim = 3; + FmsFieldSet(coords, coords_fd, sdim, FMS_BY_VDIM, FMS_DOUBLE, coords_data); + FmsComponentSetCoordinates(volume, coords); + FmsMetaData mdata = NULL; + FmsDataCollectionAttachMetaData(dc, &mdata); + void *cycle = nullptr; + FmsMetaDataSetIntegers(mdata, "cycle", FMS_UINT8, 1, &cycle); + *static_cast(cycle) = 1u; + *out_dc = dc; #ifdef PRINT_DATASETS - FmsIOWrite("3DData1.fms", "ascii", dc); + FmsIOWrite("3DData1.fms", "ascii", dc); #endif - return 0; + return 0; } int ConstructAllDataCollections(FmsInt *size, FmsDataCollection **out_dcs) { - if(!size) return 1; - if(!out_dcs) return 2; - FmsDataCollection *dcs = static_cast(std::calloc(sizeof(FmsDataCollection), 4)); - if(Construct2DData0(&dcs[0])) { - if(dcs[0]) FmsDataCollectionDestroy(&dcs[0]); - std::free(dcs); - return 3; - } - if(Construct2DData1(&dcs[1])) { - FmsDataCollectionDestroy(&dcs[0]); - if(dcs[1]) FmsDataCollectionDestroy(&dcs[1]); - std::free(dcs); - return 4; - } - if(Construct3DData0(&dcs[2])) { - FmsDataCollectionDestroy(&dcs[0]); - FmsDataCollectionDestroy(&dcs[1]); - if(dcs[2]) FmsDataCollectionDestroy(&dcs[2]); - std::free(dcs); - return 5; - } - if(Construct3DData1(&dcs[3])) { - FmsDataCollectionDestroy(&dcs[0]); - FmsDataCollectionDestroy(&dcs[1]); - FmsDataCollectionDestroy(&dcs[2]); - if(dcs[3]) FmsDataCollectionDestroy(&dcs[3]); - std::free(dcs); - return 6; - } - *out_dcs = dcs; - *size = 4; - return 0; -} \ No newline at end of file + if(!size) return 1; + if(!out_dcs) return 2; + FmsDataCollection *dcs = static_cast(std::calloc(sizeof( + FmsDataCollection), 4)); + if(Construct2DData0(&dcs[0])) { + if(dcs[0]) FmsDataCollectionDestroy(&dcs[0]); + std::free(dcs); + return 3; + } + if(Construct2DData1(&dcs[1])) { + FmsDataCollectionDestroy(&dcs[0]); + if(dcs[1]) FmsDataCollectionDestroy(&dcs[1]); + std::free(dcs); + return 4; + } + if(Construct3DData0(&dcs[2])) { + FmsDataCollectionDestroy(&dcs[0]); + FmsDataCollectionDestroy(&dcs[1]); + if(dcs[2]) FmsDataCollectionDestroy(&dcs[2]); + std::free(dcs); + return 5; + } + if(Construct3DData1(&dcs[3])) { + FmsDataCollectionDestroy(&dcs[0]); + FmsDataCollectionDestroy(&dcs[1]); + FmsDataCollectionDestroy(&dcs[2]); + if(dcs[3]) FmsDataCollectionDestroy(&dcs[3]); + std::free(dcs); + return 6; + } + *out_dcs = dcs; + *size = 4; + return 0; +} diff --git a/tests/t_fms.cpp b/tests/t_fms.cpp index dc026da..c4a8379 100644 --- a/tests/t_fms.cpp +++ b/tests/t_fms.cpp @@ -1,386 +1,409 @@ #include -#include +#include "fmstesting.hpp" #include TEST(Fms, Version) { - FmsInt v = 0; - ASSERT_EQ(FmsGetInterfaceVersion(&v), 0); - EXPECT_EQ(FMS_INTERFACE_VERSION, v); + FmsInt v = 0; + ASSERT_EQ(FmsGetInterfaceVersion(&v), 0); + EXPECT_EQ(FMS_INTERFACE_VERSION, v); } // Compare interface TEST(Fms, DataCollectionCompare) { - FmsDataCollection *dcs0 = NULL; - FmsDataCollection *dcs1 = NULL; - FmsInt size0 = 0, size1 = -1; - ASSERT_EQ(ConstructAllDataCollections(&size0, &dcs0), 0); - ASSERT_TRUE(dcs0); - ASSERT_TRUE(size0); - ASSERT_EQ(ConstructAllDataCollections(&size1, &dcs1), 0); - ASSERT_TRUE(dcs1); - ASSERT_TRUE(size1); - ASSERT_EQ(size0, size1); - for(FmsInt i = 0; i < size0; i++) { - ASSERT_TRUE(dcs0[i]); - EXPECT_EQ(FmsDataCollectionCompare(dcs0[i], dcs0[i]), 0); - for(FmsInt j = 0; j < size1; j++) { - ASSERT_TRUE(dcs1[j]); - ASSERT_NE(dcs0[i], dcs1[j]); - EXPECT_EQ(FmsDataCollectionCompare(dcs1[j], dcs1[j]), 0); - if(i == j) { - EXPECT_EQ(FmsDataCollectionCompare(dcs0[i], dcs1[j]), 0) - << "DataCollection " << i << " compared not equal to " << j << "."; - } - else { - EXPECT_NE(FmsDataCollectionCompare(dcs0[i], dcs1[j]), 0) - << "DataCollection " << i << " compared equal to " << j << "."; - } - } + FmsDataCollection *dcs0 = NULL; + FmsDataCollection *dcs1 = NULL; + FmsInt size0 = 0, size1 = 0; + ASSERT_EQ(ConstructAllDataCollections(&size0, &dcs0), 0); + ASSERT_TRUE(dcs0); + ASSERT_TRUE(size0); + ASSERT_EQ(ConstructAllDataCollections(&size1, &dcs1), 0); + ASSERT_TRUE(dcs1); + ASSERT_TRUE(size1); + ASSERT_EQ(size0, size1); + for(FmsInt i = 0; i < size0; i++) { + ASSERT_TRUE(dcs0[i]); + EXPECT_EQ(FmsDataCollectionCompare(dcs0[i], dcs0[i]), 0); + for(FmsInt j = 0; j < size1; j++) { + ASSERT_TRUE(dcs1[j]); + ASSERT_NE(dcs0[i], dcs1[j]); + EXPECT_EQ(FmsDataCollectionCompare(dcs1[j], dcs1[j]), 0); + if(i == j) { + EXPECT_EQ(FmsDataCollectionCompare(dcs0[i], dcs1[j]), 0) + << "DataCollection " << i << " compared not equal to " << j << "."; + } else { + EXPECT_NE(FmsDataCollectionCompare(dcs0[i], dcs1[j]), 0) + << "DataCollection " << i << " compared equal to " << j << "."; + } } - for(FmsInt i = 0; i < size0; i++) { - EXPECT_EQ(FmsDataCollectionDestroy(&dcs0[i]), 0); - EXPECT_EQ(FmsDataCollectionDestroy(&dcs1[i]), 0); - } - std::free(dcs0); - std::free(dcs1); + } + for(FmsInt i = 0; i < size0; i++) { + EXPECT_EQ(FmsDataCollectionDestroy(&dcs0[i]), 0); + EXPECT_EQ(FmsDataCollectionDestroy(&dcs1[i]), 0); + } + std::free(dcs0); + std::free(dcs1); } TEST(Fms, MetaDataCompare) { - // First we need to create a mesh and a datacollection to attach the metadata to - FmsMesh mesh = NULL; - ASSERT_EQ(FmsMeshConstruct(&mesh), 0); - ASSERT_TRUE(mesh); - ASSERT_EQ(FmsMeshFinalize(mesh), 0); - FmsDataCollection dc = NULL; - ASSERT_EQ(FmsDataCollectionCreate(mesh, "MetaDataCompareDC", &dc), 0); - ASSERT_TRUE(dc); + // First we need to create a mesh and a datacollection to attach the metadata to + FmsMesh mesh = NULL; + ASSERT_EQ(FmsMeshConstruct(&mesh), 0); + ASSERT_TRUE(mesh); + ASSERT_EQ(FmsMeshFinalize(mesh), 0); + FmsDataCollection dc = NULL; + ASSERT_EQ(FmsDataCollectionCreate(mesh, "MetaDataCompareDC", &dc), 0); + ASSERT_TRUE(dc); - // Now start creating and comparing MetaData - FmsMetaData toplevel_md = NULL; - ASSERT_EQ(FmsDataCollectionAttachMetaData(dc, &toplevel_md), 0); - ASSERT_TRUE(toplevel_md); - FmsMetaData *mds = NULL; - ASSERT_EQ(FmsMetaDataSetMetaData(toplevel_md, "MetaDataCompareDC", 8, &mds), 0); - ASSERT_TRUE(mds); + // Now start creating and comparing MetaData + FmsMetaData toplevel_md = NULL; + ASSERT_EQ(FmsDataCollectionAttachMetaData(dc, &toplevel_md), 0); + ASSERT_TRUE(toplevel_md); + FmsMetaData *mds = NULL; + ASSERT_EQ(FmsMetaDataSetMetaData(toplevel_md, "MetaDataCompareDC", 8, &mds), 0); + ASSERT_TRUE(mds); - // Compare integer mds - FmsInt *data0 = NULL; - ASSERT_EQ(FmsMetaDataSetIntegers(mds[0], "Ints", FMS_INT_TYPE, 3, (void**)&data0), 0); - ASSERT_TRUE(data0); - data0[0] = 3; data0[1] = 5; data0[2] = 1; - EXPECT_EQ(FmsMetaDataCompare(mds[0], mds[0]), 0); - // First make sure that they compare equal when equal - FmsInt *data1 = NULL; - ASSERT_EQ(FmsMetaDataSetIntegers(mds[1], "Ints", FMS_INT_TYPE, 3, (void**)&data1), 0); - data1[0] = 3; data1[1] = 5; data1[2] = 1; - ASSERT_NE(mds[0], mds[1]); - EXPECT_EQ(FmsMetaDataCompare(mds[0], mds[1]), 0); - EXPECT_EQ(FmsMetaDataCompare(mds[1], mds[0]), 0); - // Compare different names - ASSERT_EQ(FmsMetaDataSetIntegers(mds[1], "Ints1", FMS_INT_TYPE, 3, (void**)&data1), 0); - ASSERT_TRUE(data1); - data1[0] = 3; data1[1] = 5; data1[2] = 1; - EXPECT_NE(FmsMetaDataCompare(mds[0], mds[1]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[1], mds[0]), 0); - // Compare different sizes - ASSERT_EQ(FmsMetaDataSetIntegers(mds[1], "Ints", FMS_INT_TYPE, 4, (void**)&data1), 0); - ASSERT_TRUE(data1); - data1[0] = 3; data1[1] = 5; data1[2] = 1; data1[3] = 0; - EXPECT_NE(FmsMetaDataCompare(mds[0], mds[1]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[1], mds[0]), 0); - // Compare different contents - ASSERT_EQ(FmsMetaDataSetIntegers(mds[1], "Ints", FMS_INT_TYPE, 3, (void**)&data1), 0); - data1[0] = 2; data1[1] = 5; data1[2] = 1; - EXPECT_NE(FmsMetaDataCompare(mds[0], mds[1]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[1], mds[0]), 0); - data1[0] = 3; data1[1] = 0; - EXPECT_NE(FmsMetaDataCompare(mds[0], mds[1]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[1], mds[0]), 0); - data1[1] = 5; data1[2] = 0; - EXPECT_NE(FmsMetaDataCompare(mds[0], mds[1]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[1], mds[0]), 0); - data1[2] = 1; - EXPECT_EQ(FmsMetaDataCompare(mds[0], mds[1]), 0); - EXPECT_EQ(FmsMetaDataCompare(mds[1], mds[0]), 0); - data1 = NULL; - // Compare different int types - uint16_t *data11 = NULL; - ASSERT_EQ(FmsMetaDataSetIntegers(mds[1], "Ints", FMS_UINT16, 3, (void**)&data11), 0); - ASSERT_TRUE(data11); - data11[0] = 3; data11[1] = 5; data11[2] = 1; - EXPECT_NE(FmsMetaDataCompare(mds[0], mds[1]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[1], mds[0]), 0); + // Compare integer mds + FmsInt *data0 = NULL; + ASSERT_EQ(FmsMetaDataSetIntegers(mds[0], "Ints", FMS_INT_TYPE, 3, + (void**)&data0), 0); + ASSERT_TRUE(data0); + data0[0] = 3; data0[1] = 5; data0[2] = 1; + EXPECT_EQ(FmsMetaDataCompare(mds[0], mds[0]), 0); + // First make sure that they compare equal when equal + FmsInt *data1 = NULL; + ASSERT_EQ(FmsMetaDataSetIntegers(mds[1], "Ints", FMS_INT_TYPE, 3, + (void**)&data1), 0); + data1[0] = 3; data1[1] = 5; data1[2] = 1; + ASSERT_NE(mds[0], mds[1]); + EXPECT_EQ(FmsMetaDataCompare(mds[0], mds[1]), 0); + EXPECT_EQ(FmsMetaDataCompare(mds[1], mds[0]), 0); + // Compare different names + ASSERT_EQ(FmsMetaDataSetIntegers(mds[1], "Ints1", FMS_INT_TYPE, 3, + (void**)&data1), 0); + ASSERT_TRUE(data1); + data1[0] = 3; data1[1] = 5; data1[2] = 1; + EXPECT_NE(FmsMetaDataCompare(mds[0], mds[1]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[1], mds[0]), 0); + // Compare different sizes + ASSERT_EQ(FmsMetaDataSetIntegers(mds[1], "Ints", FMS_INT_TYPE, 4, + (void**)&data1), 0); + ASSERT_TRUE(data1); + data1[0] = 3; data1[1] = 5; data1[2] = 1; data1[3] = 0; + EXPECT_NE(FmsMetaDataCompare(mds[0], mds[1]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[1], mds[0]), 0); + // Compare different contents + ASSERT_EQ(FmsMetaDataSetIntegers(mds[1], "Ints", FMS_INT_TYPE, 3, + (void**)&data1), 0); + data1[0] = 2; data1[1] = 5; data1[2] = 1; + EXPECT_NE(FmsMetaDataCompare(mds[0], mds[1]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[1], mds[0]), 0); + data1[0] = 3; data1[1] = 0; + EXPECT_NE(FmsMetaDataCompare(mds[0], mds[1]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[1], mds[0]), 0); + data1[1] = 5; data1[2] = 0; + EXPECT_NE(FmsMetaDataCompare(mds[0], mds[1]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[1], mds[0]), 0); + data1[2] = 1; + EXPECT_EQ(FmsMetaDataCompare(mds[0], mds[1]), 0); + EXPECT_EQ(FmsMetaDataCompare(mds[1], mds[0]), 0); + data1 = NULL; + // Compare different int types + uint16_t *data11 = NULL; + ASSERT_EQ(FmsMetaDataSetIntegers(mds[1], "Ints", FMS_UINT16, 3, + (void**)&data11), 0); + ASSERT_TRUE(data11); + data11[0] = 3; data11[1] = 5; data11[2] = 1; + EXPECT_NE(FmsMetaDataCompare(mds[0], mds[1]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[1], mds[0]), 0); - // Compare scalar mds - double *data2 = NULL; - ASSERT_EQ(FmsMetaDataSetScalars(mds[2], "Ints", FMS_DOUBLE, 4, (void**)&data2), 0); - ASSERT_TRUE(data2); - data2[0] = 3.; data2[1] = 5.; data2[2] = 1.; data2[3] = 10.; - EXPECT_EQ(FmsMetaDataCompare(mds[2], mds[2]), 0); - // Compare different metadata type - EXPECT_NE(FmsMetaDataCompare(mds[0], mds[2]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[2], mds[0]), 0); - ASSERT_EQ(FmsMetaDataSetScalars(mds[2], "Scalars", FMS_DOUBLE, 4, (void**)&data2), 0); - ASSERT_TRUE(data2); - data2[0] = 3.; data2[1] = 5.; data2[2] = 1.; data2[3] = 10.; - // Compare different contents - double *data3 = NULL; - ASSERT_EQ(FmsMetaDataSetScalars(mds[3], "Scalars", FMS_DOUBLE, 4, (void**)&data3), 0); - ASSERT_TRUE(data3); - data3[0] = 13.; data3[1] = 5.; data3[2] = 1.; data3[3] = 10.; - EXPECT_NE(FmsMetaDataCompare(mds[3], mds[2]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[2], mds[3]), 0); - data3[0] = 3.; data3[1] = 13.; - EXPECT_NE(FmsMetaDataCompare(mds[3], mds[2]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[2], mds[3]), 0); - data3[1] = 5.; data3[2] = 13.; - EXPECT_NE(FmsMetaDataCompare(mds[3], mds[2]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[2], mds[3]), 0); - data3[2] = 1.; data3[3] = 13.; - EXPECT_NE(FmsMetaDataCompare(mds[3], mds[2]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[2], mds[3]), 0); - data3[3] = 10.; - EXPECT_EQ(FmsMetaDataCompare(mds[3], mds[2]), 0); - EXPECT_EQ(FmsMetaDataCompare(mds[2], mds[3]), 0); - // Compare different sizes - ASSERT_EQ(FmsMetaDataSetScalars(mds[3], "Scalars", FMS_DOUBLE, 3, (void**)&data3), 0); - ASSERT_TRUE(data3); - data3[0] = 3.; data3[1] = 5.; data3[2] = 1.; - EXPECT_NE(FmsMetaDataCompare(mds[3], mds[2]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[2], mds[3]), 0); - data3 = NULL; - // Compare different scalar type - float *data31 = NULL; - ASSERT_EQ(FmsMetaDataSetScalars(mds[3], "Scalars", FMS_FLOAT, 4, (void**)&data31), 0); - ASSERT_TRUE(data31); - data31[0] = 3.f; data31[1] = 5.f; data31[2] = 1.f; data31[3] = 10.f; - EXPECT_NE(FmsMetaDataCompare(mds[3], mds[2]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[2], mds[3]), 0); + // Compare scalar mds + double *data2 = NULL; + ASSERT_EQ(FmsMetaDataSetScalars(mds[2], "Ints", FMS_DOUBLE, 4, (void**)&data2), + 0); + ASSERT_TRUE(data2); + data2[0] = 3.; data2[1] = 5.; data2[2] = 1.; data2[3] = 10.; + EXPECT_EQ(FmsMetaDataCompare(mds[2], mds[2]), 0); + // Compare different metadata type + EXPECT_NE(FmsMetaDataCompare(mds[0], mds[2]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[2], mds[0]), 0); + ASSERT_EQ(FmsMetaDataSetScalars(mds[2], "Scalars", FMS_DOUBLE, 4, + (void**)&data2), 0); + ASSERT_TRUE(data2); + data2[0] = 3.; data2[1] = 5.; data2[2] = 1.; data2[3] = 10.; + // Compare different contents + double *data3 = NULL; + ASSERT_EQ(FmsMetaDataSetScalars(mds[3], "Scalars", FMS_DOUBLE, 4, + (void**)&data3), 0); + ASSERT_TRUE(data3); + data3[0] = 13.; data3[1] = 5.; data3[2] = 1.; data3[3] = 10.; + EXPECT_NE(FmsMetaDataCompare(mds[3], mds[2]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[2], mds[3]), 0); + data3[0] = 3.; data3[1] = 13.; + EXPECT_NE(FmsMetaDataCompare(mds[3], mds[2]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[2], mds[3]), 0); + data3[1] = 5.; data3[2] = 13.; + EXPECT_NE(FmsMetaDataCompare(mds[3], mds[2]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[2], mds[3]), 0); + data3[2] = 1.; data3[3] = 13.; + EXPECT_NE(FmsMetaDataCompare(mds[3], mds[2]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[2], mds[3]), 0); + data3[3] = 10.; + EXPECT_EQ(FmsMetaDataCompare(mds[3], mds[2]), 0); + EXPECT_EQ(FmsMetaDataCompare(mds[2], mds[3]), 0); + // Compare different sizes + ASSERT_EQ(FmsMetaDataSetScalars(mds[3], "Scalars", FMS_DOUBLE, 3, + (void**)&data3), 0); + ASSERT_TRUE(data3); + data3[0] = 3.; data3[1] = 5.; data3[2] = 1.; + EXPECT_NE(FmsMetaDataCompare(mds[3], mds[2]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[2], mds[3]), 0); + data3 = NULL; + // Compare different scalar type + float *data31 = NULL; + ASSERT_EQ(FmsMetaDataSetScalars(mds[3], "Scalars", FMS_FLOAT, 4, + (void**)&data31), 0); + ASSERT_TRUE(data31); + data31[0] = 3.f; data31[1] = 5.f; data31[2] = 1.f; data31[3] = 10.f; + EXPECT_NE(FmsMetaDataCompare(mds[3], mds[2]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[2], mds[3]), 0); - // Compare string mds - const char *data4 = "Hello"; - ASSERT_EQ(FmsMetaDataSetString(mds[4], "String", data4), 0); - EXPECT_EQ(FmsMetaDataCompare(mds[4], mds[4]), 0); - // Compare equal strings - const char *data5 = "Hello"; - ASSERT_EQ(FmsMetaDataSetString(mds[5], "String", data5), 0); - EXPECT_EQ(FmsMetaDataCompare(mds[4], mds[5]), 0); - EXPECT_EQ(FmsMetaDataCompare(mds[5], mds[4]), 0); - // Compare different contents - const char *data51 = "World"; - ASSERT_EQ(FmsMetaDataSetString(mds[5], "String", data51), 0); - EXPECT_NE(FmsMetaDataCompare(mds[4], mds[5]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[5], mds[4]), 0); + // Compare string mds + const char *data4 = "Hello"; + ASSERT_EQ(FmsMetaDataSetString(mds[4], "String", data4), 0); + EXPECT_EQ(FmsMetaDataCompare(mds[4], mds[4]), 0); + // Compare equal strings + const char *data5 = "Hello"; + ASSERT_EQ(FmsMetaDataSetString(mds[5], "String", data5), 0); + EXPECT_EQ(FmsMetaDataCompare(mds[4], mds[5]), 0); + EXPECT_EQ(FmsMetaDataCompare(mds[5], mds[4]), 0); + // Compare different contents + const char *data51 = "World"; + ASSERT_EQ(FmsMetaDataSetString(mds[5], "String", data51), 0); + EXPECT_NE(FmsMetaDataCompare(mds[4], mds[5]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[5], mds[4]), 0); - FmsMetaData *data6 = NULL; - ASSERT_EQ(FmsMetaDataSetMetaData(mds[6], "MetaDatas", 2, &data6), 0); - ASSERT_TRUE(data6); - int32_t *data61 = NULL; - ASSERT_EQ(FmsMetaDataSetIntegers(data6[0], "Int", FMS_INT32, 1, (void**)&data61), 0); - ASSERT_TRUE(data61); - data61[0] = 7; - double *data62 = NULL; - ASSERT_EQ(FmsMetaDataSetScalars(data6[1], "Scalars", FMS_DOUBLE, 3, (void**)&data62), 0); - ASSERT_TRUE(data62); - data62[0] = 3.; data62[1] = 5.; data62[2] = 1.; + FmsMetaData *data6 = NULL; + ASSERT_EQ(FmsMetaDataSetMetaData(mds[6], "MetaDatas", 2, &data6), 0); + ASSERT_TRUE(data6); + int32_t *data61 = NULL; + ASSERT_EQ(FmsMetaDataSetIntegers(data6[0], "Int", FMS_INT32, 1, + (void**)&data61), 0); + ASSERT_TRUE(data61); + data61[0] = 7; + double *data62 = NULL; + ASSERT_EQ(FmsMetaDataSetScalars(data6[1], "Scalars", FMS_DOUBLE, 3, + (void**)&data62), 0); + ASSERT_TRUE(data62); + data62[0] = 3.; data62[1] = 5.; data62[2] = 1.; - // Compare everything so far to unset md - for(int i = 0; i < 7; i++) { - EXPECT_NE(FmsMetaDataCompare(mds[i], mds[7]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[7], mds[i]), 0); - } + // Compare everything so far to unset md + for(int i = 0; i < 7; i++) { + EXPECT_NE(FmsMetaDataCompare(mds[i], mds[7]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[7], mds[i]), 0); + } - // Compare md of mds - // Compare equal - FmsMetaData *data7 = NULL; - ASSERT_EQ(FmsMetaDataSetMetaData(mds[7], "MetaDatas", 2, &data7), 0); - ASSERT_TRUE(data7); - int32_t *data71 = NULL; - ASSERT_EQ(FmsMetaDataSetIntegers(data7[0], "Int", FMS_INT32, 1, (void**)&data71), 0); - ASSERT_TRUE(data71); - data71[0] = 7; - double *data72 = NULL; - ASSERT_EQ(FmsMetaDataSetScalars(data7[1], "Scalars", FMS_DOUBLE, 3, (void**)&data72), 0); - ASSERT_TRUE(data72); - data72[0] = 3.; data72[1] = 5.; data72[2] = 1.; - EXPECT_EQ(FmsMetaDataCompare(mds[6], mds[7]), 0); - EXPECT_EQ(FmsMetaDataCompare(mds[7], mds[6]), 0); - data7 = NULL; - data71 = NULL; - data72 = NULL; - // Compare different sizes - ASSERT_EQ(FmsMetaDataSetMetaData(mds[7], "MetaDatas", 1, &data7), 0); - ASSERT_TRUE(data7); - ASSERT_EQ(FmsMetaDataSetIntegers(data7[0], "Int", FMS_INT32, 1, (void**)&data71), 0); - ASSERT_TRUE(data71); - data71[0] = 7; - EXPECT_NE(FmsMetaDataCompare(mds[6], mds[7]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[7], mds[6]), 0); - data7 = NULL; - data71 = NULL; - // Compare different content - ASSERT_EQ(FmsMetaDataSetMetaData(mds[7], "MetaDatas", 2, &data7), 0); - ASSERT_TRUE(data7); - ASSERT_EQ(FmsMetaDataSetScalars(data7[0], "Scalars", FMS_DOUBLE, 3, (void**)&data72), 0); - ASSERT_TRUE(data72); - data72[0] = 3.; data72[1] = 5.; data72[2] = 1.; - ASSERT_EQ(FmsMetaDataSetIntegers(data7[1], "Int", FMS_INT32, 1, (void**)&data71), 0); - ASSERT_TRUE(data71); - data71[0] = 7; - EXPECT_NE(FmsMetaDataCompare(mds[6], mds[7]), 0); - EXPECT_NE(FmsMetaDataCompare(mds[7], mds[6]), 0); - // Make them equal again - FmsMetaData temp = data7[0]; - data7[0] = data7[1]; data7[1] = temp; - EXPECT_EQ(FmsMetaDataCompare(mds[6], mds[7]), 0); - EXPECT_EQ(FmsMetaDataCompare(mds[7], mds[6]), 0); + // Compare md of mds + // Compare equal + FmsMetaData *data7 = NULL; + ASSERT_EQ(FmsMetaDataSetMetaData(mds[7], "MetaDatas", 2, &data7), 0); + ASSERT_TRUE(data7); + int32_t *data71 = NULL; + ASSERT_EQ(FmsMetaDataSetIntegers(data7[0], "Int", FMS_INT32, 1, + (void**)&data71), 0); + ASSERT_TRUE(data71); + data71[0] = 7; + double *data72 = NULL; + ASSERT_EQ(FmsMetaDataSetScalars(data7[1], "Scalars", FMS_DOUBLE, 3, + (void**)&data72), 0); + ASSERT_TRUE(data72); + data72[0] = 3.; data72[1] = 5.; data72[2] = 1.; + EXPECT_EQ(FmsMetaDataCompare(mds[6], mds[7]), 0); + EXPECT_EQ(FmsMetaDataCompare(mds[7], mds[6]), 0); + data7 = NULL; + data71 = NULL; + data72 = NULL; + // Compare different sizes + ASSERT_EQ(FmsMetaDataSetMetaData(mds[7], "MetaDatas", 1, &data7), 0); + ASSERT_TRUE(data7); + ASSERT_EQ(FmsMetaDataSetIntegers(data7[0], "Int", FMS_INT32, 1, + (void**)&data71), 0); + ASSERT_TRUE(data71); + data71[0] = 7; + EXPECT_NE(FmsMetaDataCompare(mds[6], mds[7]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[7], mds[6]), 0); + data7 = NULL; + data71 = NULL; + // Compare different content + ASSERT_EQ(FmsMetaDataSetMetaData(mds[7], "MetaDatas", 2, &data7), 0); + ASSERT_TRUE(data7); + ASSERT_EQ(FmsMetaDataSetScalars(data7[0], "Scalars", FMS_DOUBLE, 3, + (void**)&data72), 0); + ASSERT_TRUE(data72); + data72[0] = 3.; data72[1] = 5.; data72[2] = 1.; + ASSERT_EQ(FmsMetaDataSetIntegers(data7[1], "Int", FMS_INT32, 1, + (void**)&data71), 0); + ASSERT_TRUE(data71); + data71[0] = 7; + EXPECT_NE(FmsMetaDataCompare(mds[6], mds[7]), 0); + EXPECT_NE(FmsMetaDataCompare(mds[7], mds[6]), 0); + // Make them equal again + FmsMetaData temp = data7[0]; + data7[0] = data7[1]; data7[1] = temp; + EXPECT_EQ(FmsMetaDataCompare(mds[6], mds[7]), 0); + EXPECT_EQ(FmsMetaDataCompare(mds[7], mds[6]), 0); - FmsDataCollectionDestroy(&dc); + FmsDataCollectionDestroy(&dc); } TEST(Fms, FieldDescriptorCompare) { - // We need a DataCollection to attach the FDs to - FmsDataCollection dc = NULL; - ASSERT_EQ(Construct2DData0(&dc), 0); - ASSERT_TRUE(dc); - FmsMesh mesh = NULL; - ASSERT_EQ(FmsDataCollectionGetMesh(dc, &mesh), 0); - ASSERT_TRUE(mesh); - FmsComponent volume = NULL, boundary = NULL; - ASSERT_EQ(FmsMeshGetComponent(mesh, 0, &volume), 0); - ASSERT_EQ(FmsMeshGetComponent(mesh, 1, &boundary), 0); - ASSERT_TRUE(volume); ASSERT_TRUE(boundary); - ASSERT_NE(volume, boundary); + // We need a DataCollection to attach the FDs to + FmsDataCollection dc = NULL; + ASSERT_EQ(Construct2DData0(&dc), 0); + ASSERT_TRUE(dc); + FmsMesh mesh = NULL; + ASSERT_EQ(FmsDataCollectionGetMesh(dc, &mesh), 0); + ASSERT_TRUE(mesh); + FmsComponent volume = NULL, boundary = NULL; + ASSERT_EQ(FmsMeshGetComponent(mesh, 0, &volume), 0); + ASSERT_EQ(FmsMeshGetComponent(mesh, 1, &boundary), 0); + ASSERT_TRUE(volume); ASSERT_TRUE(boundary); + ASSERT_NE(volume, boundary); - // Compare equal FDs - FmsDataCollection dc1 = NULL; - ASSERT_EQ(Construct2DData0(&dc1), 0); - ASSERT_TRUE(dc1); - FmsInt dc_nfds = 0, dc1_nfds = -1; - FmsFieldDescriptor *dc_fds = NULL, *dc1_fds = NULL; - ASSERT_EQ(FmsDataCollectionGetFieldDescriptors(dc, &dc_fds, &dc_nfds), 0); - ASSERT_EQ(FmsDataCollectionGetFieldDescriptors(dc1, &dc1_fds, &dc1_nfds), 0); - ASSERT_TRUE(dc_fds); ASSERT_TRUE(dc1_fds); - ASSERT_TRUE(dc_nfds); ASSERT_TRUE(dc1_nfds); - ASSERT_EQ(dc_nfds, dc1_nfds); - for(FmsInt i = 0; i < dc_nfds; i++) { - ASSERT_TRUE(dc_fds[i]); ASSERT_TRUE(dc1_fds[i]); - ASSERT_NE(dc_fds[i], dc1_fds[i]); - EXPECT_EQ(FmsFieldDescriptorCompare(dc_fds[i], dc1_fds[i]), 0) - << "The FD at index " << i << " did not compare equal."; - } - FmsDataCollectionDestroy(&dc1); + // Compare equal FDs + FmsDataCollection dc1 = NULL; + ASSERT_EQ(Construct2DData0(&dc1), 0); + ASSERT_TRUE(dc1); + FmsInt dc_nfds = 0, dc1_nfds = 0; + FmsFieldDescriptor *dc_fds = NULL, *dc1_fds = NULL; + ASSERT_EQ(FmsDataCollectionGetFieldDescriptors(dc, &dc_fds, &dc_nfds), 0); + ASSERT_EQ(FmsDataCollectionGetFieldDescriptors(dc1, &dc1_fds, &dc1_nfds), 0); + ASSERT_TRUE(dc_fds); ASSERT_TRUE(dc1_fds); + ASSERT_TRUE(dc_nfds); ASSERT_TRUE(dc1_nfds); + ASSERT_EQ(dc_nfds, dc1_nfds); + for(FmsInt i = 0; i < dc_nfds; i++) { + ASSERT_TRUE(dc_fds[i]); ASSERT_TRUE(dc1_fds[i]); + ASSERT_NE(dc_fds[i], dc1_fds[i]); + EXPECT_EQ(FmsFieldDescriptorCompare(dc_fds[i], dc1_fds[i]), 0) + << "The FD at index " << i << " did not compare equal."; + } + FmsDataCollectionDestroy(&dc1); - // Compare different combinations of basis type - // NOTE: Might need to use the two identical datacollection from above because it might - // not always be okay to have two FDs with the same name in the same DataCollection - for(int i = 0; i < 7; i++) { - FmsFieldDescriptor fdi = NULL; - ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdi), 0); - ASSERT_TRUE(fdi); - ASSERT_EQ(FmsFieldDescriptorSetComponent(fdi, volume), 0); - ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdi, FMS_CONTINUOUS, static_cast(i), 10), 0); - for(int j = 0; j < 7; j++){ - FmsFieldDescriptor fdj = NULL; - ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdj), 0); - ASSERT_EQ(FmsFieldDescriptorSetComponent(fdj, volume), 0); - ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdj, FMS_CONTINUOUS, static_cast(j), 10), 0); - if(i == j) { - EXPECT_EQ(FmsFieldDescriptorCompare(fdi, fdj), 0) - << "FDs compared not equal with basistype " << i; - EXPECT_EQ(FmsFieldDescriptorCompare(fdj, fdi), 0) - << "FDs compared not equal with basistype " << i;; - } - else { - EXPECT_NE(FmsFieldDescriptorCompare(fdi, fdj), 0) - << "FDs compared equal with basistypes " << i << " " << j; - EXPECT_NE(FmsFieldDescriptorCompare(fdj, fdi), 0) - << "FDs compared equal with basistypes " << i << " " << j; - } - } + // Compare different combinations of basis type + // NOTE: Might need to use the two identical datacollection from above because it might + // not always be okay to have two FDs with the same name in the same DataCollection + for(int i = 0; i < 7; i++) { + FmsFieldDescriptor fdi = NULL; + ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdi), 0); + ASSERT_TRUE(fdi); + ASSERT_EQ(FmsFieldDescriptorSetComponent(fdi, volume), 0); + ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdi, FMS_CONTINUOUS, + static_cast(i), 10), 0); + for(int j = 0; j < 7; j++) { + FmsFieldDescriptor fdj = NULL; + ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdj), 0); + ASSERT_EQ(FmsFieldDescriptorSetComponent(fdj, volume), 0); + ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdj, FMS_CONTINUOUS, + static_cast(j), 10), 0); + if(i == j) { + EXPECT_EQ(FmsFieldDescriptorCompare(fdi, fdj), 0) + << "FDs compared not equal with basistype " << i; + EXPECT_EQ(FmsFieldDescriptorCompare(fdj, fdi), 0) + << "FDs compared not equal with basistype " << i;; + } else { + EXPECT_NE(FmsFieldDescriptorCompare(fdi, fdj), 0) + << "FDs compared equal with basistypes " << i << " " << j; + EXPECT_NE(FmsFieldDescriptorCompare(fdj, fdi), 0) + << "FDs compared equal with basistypes " << i << " " << j; + } } + } - // Compare different combinations of FieldType - // TODO: Update this when HCURL is implemented - for(int i = 0; i < 5; i++) { - if(static_cast(i) == FMS_HCURL) continue; - FmsFieldDescriptor fdi = NULL; - ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdi), 0); - ASSERT_TRUE(fdi); - ASSERT_EQ(FmsFieldDescriptorSetComponent(fdi, volume), 0); - ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdi, static_cast(i), FMS_NODAL_GAUSS_CLOSED, 10), 0); - for(int j = 0; j < 5; j++){ - if(static_cast(j) == FMS_HCURL) continue; - FmsFieldDescriptor fdj = NULL; - ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdj), 0); - ASSERT_EQ(FmsFieldDescriptorSetComponent(fdj, volume), 0); - ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdj, static_cast(j), FMS_NODAL_GAUSS_CLOSED, 10), 0); - ASSERT_NE(fdi, fdj); - if(i == j) { - EXPECT_EQ(FmsFieldDescriptorCompare(fdi, fdj), 0) - << "FDs compared not equal with fieldtype " << i; - EXPECT_EQ(FmsFieldDescriptorCompare(fdj, fdi), 0) - << "FDs compared not equal with fieldtype " << i;; - } - else { - EXPECT_NE(FmsFieldDescriptorCompare(fdi, fdj), 0) - << "FDs compared equal with fieldtypes " << i << " " << j; - EXPECT_NE(FmsFieldDescriptorCompare(fdj, fdi), 0) - << "FDs compared equal with fieldtypes " << i << " " << j; - } - } + // Compare different combinations of FieldType + // TODO: Update this when HCURL is implemented + for(int i = 0; i < 5; i++) { + if(static_cast(i) == FMS_HCURL) continue; + FmsFieldDescriptor fdi = NULL; + ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdi), 0); + ASSERT_TRUE(fdi); + ASSERT_EQ(FmsFieldDescriptorSetComponent(fdi, volume), 0); + ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdi, static_cast(i), + FMS_NODAL_GAUSS_CLOSED, 10), 0); + for(int j = 0; j < 5; j++) { + if(static_cast(j) == FMS_HCURL) continue; + FmsFieldDescriptor fdj = NULL; + ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdj), 0); + ASSERT_EQ(FmsFieldDescriptorSetComponent(fdj, volume), 0); + ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdj, static_cast(j), + FMS_NODAL_GAUSS_CLOSED, 10), 0); + ASSERT_NE(fdi, fdj); + if(i == j) { + EXPECT_EQ(FmsFieldDescriptorCompare(fdi, fdj), 0) + << "FDs compared not equal with fieldtype " << i; + EXPECT_EQ(FmsFieldDescriptorCompare(fdj, fdi), 0) + << "FDs compared not equal with fieldtype " << i;; + } else { + EXPECT_NE(FmsFieldDescriptorCompare(fdi, fdj), 0) + << "FDs compared equal with fieldtypes " << i << " " << j; + EXPECT_NE(FmsFieldDescriptorCompare(fdj, fdi), 0) + << "FDs compared equal with fieldtypes " << i << " " << j; + } } + } - // Compare different orders - for(int i = 1; i < 5; i++) { - FmsFieldDescriptor fdi = NULL; - ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdi), 0); - ASSERT_TRUE(fdi); - ASSERT_EQ(FmsFieldDescriptorSetComponent(fdi, volume), 0); - ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdi, FMS_CONTINUOUS, FMS_NODAL_GAUSS_CLOSED, i), 0); - for(int j = 1; j < 5; j++){ - if(static_cast(j) == FMS_HCURL) continue; - FmsFieldDescriptor fdj = NULL; - ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdj), 0); - ASSERT_EQ(FmsFieldDescriptorSetComponent(fdj, volume), 0); - ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdj, FMS_CONTINUOUS, FMS_NODAL_GAUSS_CLOSED, j), 0); - ASSERT_NE(fdi, fdj); - if(i == j) { - EXPECT_EQ(FmsFieldDescriptorCompare(fdi, fdj), 0) - << "FDs compared not equal with order " << i; - EXPECT_EQ(FmsFieldDescriptorCompare(fdj, fdi), 0) - << "FDs compared not equal with order " << i;; - } - else { - EXPECT_NE(FmsFieldDescriptorCompare(fdi, fdj), 0) - << "FDs compared equal with orders " << i << " " << j; - EXPECT_NE(FmsFieldDescriptorCompare(fdj, fdi), 0) - << "FDs compared equal with orders " << i << " " << j; - } - } + // Compare different orders + for(int i = 1; i < 5; i++) { + FmsFieldDescriptor fdi = NULL; + ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdi), 0); + ASSERT_TRUE(fdi); + ASSERT_EQ(FmsFieldDescriptorSetComponent(fdi, volume), 0); + ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdi, FMS_CONTINUOUS, + FMS_NODAL_GAUSS_CLOSED, i), 0); + for(int j = 1; j < 5; j++) { + if(static_cast(j) == FMS_HCURL) continue; + FmsFieldDescriptor fdj = NULL; + ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdj), 0); + ASSERT_EQ(FmsFieldDescriptorSetComponent(fdj, volume), 0); + ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdj, FMS_CONTINUOUS, + FMS_NODAL_GAUSS_CLOSED, j), 0); + ASSERT_NE(fdi, fdj); + if(i == j) { + EXPECT_EQ(FmsFieldDescriptorCompare(fdi, fdj), 0) + << "FDs compared not equal with order " << i; + EXPECT_EQ(FmsFieldDescriptorCompare(fdj, fdi), 0) + << "FDs compared not equal with order " << i;; + } else { + EXPECT_NE(FmsFieldDescriptorCompare(fdi, fdj), 0) + << "FDs compared equal with orders " << i << " " << j; + EXPECT_NE(FmsFieldDescriptorCompare(fdj, fdi), 0) + << "FDs compared equal with orders " << i << " " << j; + } } + } - // Compare different components - FmsFieldDescriptor fdv = NULL, fdb = NULL; - ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdv), 0); - ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdb), 0); - ASSERT_TRUE(fdv); ASSERT_TRUE(fdb); - ASSERT_EQ(FmsFieldDescriptorSetComponent(fdv, volume), 0); - ASSERT_EQ(FmsFieldDescriptorSetComponent(fdb, boundary), 0); - ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdv, FMS_CONTINUOUS, FMS_NODAL_GAUSS_CLOSED, 3), 0); - ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdb, FMS_CONTINUOUS, FMS_NODAL_GAUSS_CLOSED, 3), 0); - ASSERT_NE(fdv, fdb); - EXPECT_NE(FmsFieldDescriptorCompare(fdv, fdb), 0); - EXPECT_NE(FmsFieldDescriptorCompare(fdb, fdv), 0); + // Compare different components + FmsFieldDescriptor fdv = NULL, fdb = NULL; + ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdv), 0); + ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "FD", &fdb), 0); + ASSERT_TRUE(fdv); ASSERT_TRUE(fdb); + ASSERT_EQ(FmsFieldDescriptorSetComponent(fdv, volume), 0); + ASSERT_EQ(FmsFieldDescriptorSetComponent(fdb, boundary), 0); + ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdv, FMS_CONTINUOUS, + FMS_NODAL_GAUSS_CLOSED, 3), 0); + ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(fdb, FMS_CONTINUOUS, + FMS_NODAL_GAUSS_CLOSED, 3), 0); + ASSERT_NE(fdv, fdb); + EXPECT_NE(FmsFieldDescriptorCompare(fdv, fdb), 0); + EXPECT_NE(FmsFieldDescriptorCompare(fdb, fdv), 0); - // Compare different names - FmsFieldDescriptor diff_name = NULL; - ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "DiffName", &diff_name), 0); - ASSERT_TRUE(diff_name); - ASSERT_EQ(FmsFieldDescriptorSetComponent(diff_name, volume), 0); - ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(diff_name, FMS_CONTINUOUS, FMS_NODAL_GAUSS_CLOSED, 3), 0); - EXPECT_NE(FmsFieldDescriptorCompare(fdv, diff_name), 0); - EXPECT_NE(FmsFieldDescriptorCompare(diff_name, fdv), 0); + // Compare different names + FmsFieldDescriptor diff_name = NULL; + ASSERT_EQ(FmsDataCollectionAddFieldDescriptor(dc, "DiffName", &diff_name), 0); + ASSERT_TRUE(diff_name); + ASSERT_EQ(FmsFieldDescriptorSetComponent(diff_name, volume), 0); + ASSERT_EQ(FmsFieldDescriptorSetFixedOrder(diff_name, FMS_CONTINUOUS, + FMS_NODAL_GAUSS_CLOSED, 3), 0); + EXPECT_NE(FmsFieldDescriptorCompare(fdv, diff_name), 0); + EXPECT_NE(FmsFieldDescriptorCompare(diff_name, fdv), 0); - FmsDataCollectionDestroy(&dc); + FmsDataCollectionDestroy(&dc); } diff --git a/tests/t_fmsio.cpp b/tests/t_fmsio.cpp index 29a3220..3a37672 100644 --- a/tests/t_fmsio.cpp +++ b/tests/t_fmsio.cpp @@ -1,133 +1,133 @@ #include #include -#include +#include "fmstesting.hpp" #include TEST(FmsIO, WriteReadAscii) { - FmsInt size = 0; - FmsDataCollection *dcs = NULL; - ASSERT_EQ(ConstructAllDataCollections(&size, &dcs), 0); - ASSERT_TRUE(dcs); - ASSERT_TRUE(size); - for(FmsInt i = 0; i < size; i++) { - ASSERT_TRUE(dcs[i]); - ASSERT_EQ(FmsIOWrite("TestAscii.fms", "ascii", dcs[i]), 0); - FmsDataCollection read_dc = NULL; - ASSERT_EQ(FmsIORead("TestAscii.fms", "ascii", &read_dc), 0); - ASSERT_TRUE(read_dc); - EXPECT_EQ(FmsDataCollectionCompare(dcs[i], read_dc), 0); - ASSERT_EQ(FmsDataCollectionDestroy(&dcs[i]), 0); - ASSERT_EQ(FmsDataCollectionDestroy(&read_dc), 0); - } - std::free(dcs); + FmsInt size = 0; + FmsDataCollection *dcs = NULL; + ASSERT_EQ(ConstructAllDataCollections(&size, &dcs), 0); + ASSERT_TRUE(dcs); + ASSERT_TRUE(size); + for(FmsInt i = 0; i < size; i++) { + ASSERT_TRUE(dcs[i]); + ASSERT_EQ(FmsIOWrite("TestAscii.fms", "ascii", dcs[i]), 0); + FmsDataCollection read_dc = NULL; + ASSERT_EQ(FmsIORead("TestAscii.fms", "ascii", &read_dc), 0); + ASSERT_TRUE(read_dc); + EXPECT_EQ(FmsDataCollectionCompare(dcs[i], read_dc), 0); + ASSERT_EQ(FmsDataCollectionDestroy(&dcs[i]), 0); + ASSERT_EQ(FmsDataCollectionDestroy(&read_dc), 0); + } + std::free(dcs); } TEST(FmsIO, WriteReadYaml) { - FmsInt size = 0; - FmsDataCollection *dcs = NULL; - ASSERT_EQ(ConstructAllDataCollections(&size, &dcs), 0); - ASSERT_TRUE(dcs); - ASSERT_TRUE(size); - for(FmsInt i = 0; i < size; i++) { - ASSERT_TRUE(dcs[i]); - ASSERT_EQ(FmsIOWrite("TestYaml.fms", "yaml", dcs[i]), 0); - FmsDataCollection read_dc = NULL; - ASSERT_EQ(FmsIORead("TestYaml.fms", "yaml", &read_dc), 0); - ASSERT_TRUE(read_dc); - EXPECT_EQ(FmsDataCollectionCompare(dcs[i], read_dc), 0); - ASSERT_EQ(FmsDataCollectionDestroy(&dcs[i]), 0); - ASSERT_EQ(FmsDataCollectionDestroy(&read_dc), 0); - } - std::free(dcs); + FmsInt size = 0; + FmsDataCollection *dcs = NULL; + ASSERT_EQ(ConstructAllDataCollections(&size, &dcs), 0); + ASSERT_TRUE(dcs); + ASSERT_TRUE(size); + for(FmsInt i = 0; i < size; i++) { + ASSERT_TRUE(dcs[i]); + ASSERT_EQ(FmsIOWrite("TestYaml.fms", "yaml", dcs[i]), 0); + FmsDataCollection read_dc = NULL; + ASSERT_EQ(FmsIORead("TestYaml.fms", "yaml", &read_dc), 0); + ASSERT_TRUE(read_dc); + EXPECT_EQ(FmsDataCollectionCompare(dcs[i], read_dc), 0); + ASSERT_EQ(FmsDataCollectionDestroy(&dcs[i]), 0); + ASSERT_EQ(FmsDataCollectionDestroy(&read_dc), 0); + } + std::free(dcs); } TEST(FmsIO, WriteReadJson) { - FmsInt size = 0; - FmsDataCollection *dcs = NULL; - ASSERT_EQ(ConstructAllDataCollections(&size, &dcs), 0); - ASSERT_TRUE(dcs); - ASSERT_TRUE(size); - for(FmsInt i = 0; i < size; i++) { - ASSERT_TRUE(dcs[i]); - ASSERT_EQ(FmsIOWrite("TestJson.fms", "json", dcs[i]), 0); - FmsDataCollection read_dc = NULL; - ASSERT_EQ(FmsIORead("TestJson.fms", "json", &read_dc), 0); - ASSERT_TRUE(read_dc); - EXPECT_EQ(FmsDataCollectionCompare(dcs[i], read_dc), 0); - ASSERT_EQ(FmsDataCollectionDestroy(&dcs[i]), 0); - ASSERT_EQ(FmsDataCollectionDestroy(&read_dc), 0); - } - std::free(dcs); + FmsInt size = 0; + FmsDataCollection *dcs = NULL; + ASSERT_EQ(ConstructAllDataCollections(&size, &dcs), 0); + ASSERT_TRUE(dcs); + ASSERT_TRUE(size); + for(FmsInt i = 0; i < size; i++) { + ASSERT_TRUE(dcs[i]); + ASSERT_EQ(FmsIOWrite("TestJson.fms", "json", dcs[i]), 0); + FmsDataCollection read_dc = NULL; + ASSERT_EQ(FmsIORead("TestJson.fms", "json", &read_dc), 0); + ASSERT_TRUE(read_dc); + EXPECT_EQ(FmsDataCollectionCompare(dcs[i], read_dc), 0); + ASSERT_EQ(FmsDataCollectionDestroy(&dcs[i]), 0); + ASSERT_EQ(FmsDataCollectionDestroy(&read_dc), 0); + } + std::free(dcs); } TEST(FmsIO, WriteReadHdf5) { - FmsInt size = 0; - FmsDataCollection *dcs = NULL; - ASSERT_EQ(ConstructAllDataCollections(&size, &dcs), 0); - ASSERT_TRUE(dcs); - ASSERT_TRUE(size); - int isNotSupported = 0; - for(FmsInt i = 0; i < size; i++) { - ASSERT_TRUE(dcs[i]); - // It's possible that Conduit is compiled without hdf5 support - int retval = FmsIOWrite("TestHdf5.fms", "hdf5", dcs[i]); - if(retval == 2) { - isNotSupported = 1; - break; - } - ASSERT_EQ(retval, 0); - FmsDataCollection read_dc = NULL; - ASSERT_EQ(FmsIORead("TestHdf5.fms", "hdf5", &read_dc), 0); - ASSERT_TRUE(read_dc); - EXPECT_EQ(FmsDataCollectionCompare(dcs[i], read_dc), 0); - FmsDataCollectionDestroy(&read_dc); + FmsInt size = 0; + FmsDataCollection *dcs = NULL; + ASSERT_EQ(ConstructAllDataCollections(&size, &dcs), 0); + ASSERT_TRUE(dcs); + ASSERT_TRUE(size); + int isNotSupported = 0; + for(FmsInt i = 0; i < size; i++) { + ASSERT_TRUE(dcs[i]); + // It's possible that Conduit is compiled without hdf5 support + int retval = FmsIOWrite("TestHdf5.fms", "hdf5", dcs[i]); + if(retval == 2) { + isNotSupported = 1; + break; } - for(FmsInt i = 0; i < size; i++) { - FmsDataCollectionDestroy(&dcs[i]); - } - std::free(dcs); - if(isNotSupported) GTEST_SKIP(); + ASSERT_EQ(retval, 0); + FmsDataCollection read_dc = NULL; + ASSERT_EQ(FmsIORead("TestHdf5.fms", "hdf5", &read_dc), 0); + ASSERT_TRUE(read_dc); + EXPECT_EQ(FmsDataCollectionCompare(dcs[i], read_dc), 0); + FmsDataCollectionDestroy(&read_dc); + } + for(FmsInt i = 0; i < size; i++) { + FmsDataCollectionDestroy(&dcs[i]); + } + std::free(dcs); + if(isNotSupported) GTEST_SKIP(); } TEST(FmsIO, WriteReadConduitBin) { - FmsInt size = 0; - FmsDataCollection *dcs = NULL; - ASSERT_EQ(ConstructAllDataCollections(&size, &dcs), 0); - ASSERT_TRUE(dcs); - ASSERT_TRUE(size); - for(FmsInt i = 0; i < size; i++) { - ASSERT_TRUE(dcs[i]); - ASSERT_EQ(FmsIOWrite("TestConduitBin.fms", "conduit_bin", dcs[i]), 0); - FmsDataCollection read_dc = NULL; - ASSERT_EQ(FmsIORead("TestConduitBin.fms", "conduit_bin", &read_dc), 0); - ASSERT_TRUE(read_dc); - EXPECT_EQ(FmsDataCollectionCompare(dcs[i], read_dc), 0); - ASSERT_EQ(FmsDataCollectionDestroy(&dcs[i]), 0); - ASSERT_EQ(FmsDataCollectionDestroy(&read_dc), 0); - } - std::free(dcs); + FmsInt size = 0; + FmsDataCollection *dcs = NULL; + ASSERT_EQ(ConstructAllDataCollections(&size, &dcs), 0); + ASSERT_TRUE(dcs); + ASSERT_TRUE(size); + for(FmsInt i = 0; i < size; i++) { + ASSERT_TRUE(dcs[i]); + ASSERT_EQ(FmsIOWrite("TestConduitBin.fms", "conduit_bin", dcs[i]), 0); + FmsDataCollection read_dc = NULL; + ASSERT_EQ(FmsIORead("TestConduitBin.fms", "conduit_bin", &read_dc), 0); + ASSERT_TRUE(read_dc); + EXPECT_EQ(FmsDataCollectionCompare(dcs[i], read_dc), 0); + ASSERT_EQ(FmsDataCollectionDestroy(&dcs[i]), 0); + ASSERT_EQ(FmsDataCollectionDestroy(&read_dc), 0); + } + std::free(dcs); } TEST(FmsIO, WriteReadAutoDetect) { - FmsDataCollection dc = NULL; - ASSERT_EQ(Construct2DData0(&dc), 0); - ASSERT_TRUE(dc); - const char *protocols[5] = { - "ascii", "json", "yaml", "hdf5", "conduit_bin" - }; - for(int i = 0; i < 5; i++) { - int retval = FmsIOWrite("TestAuto.fms", protocols[i], dc); - // Sometimes hdf5 will not be supported by conduit - if(retval == 2 && strcmp("hdf5", protocols[i]) == 0) { - continue; - } - ASSERT_EQ(retval, 0); - FmsDataCollection read_dc = NULL; - ASSERT_EQ(FmsIORead("TestAuto.fms", NULL, &read_dc), 0); - ASSERT_TRUE(read_dc); - EXPECT_EQ(FmsDataCollectionCompare(dc, read_dc), 0); - EXPECT_EQ(FmsDataCollectionCompare(read_dc, dc), 0); - FmsDataCollectionDestroy(&read_dc); + FmsDataCollection dc = NULL; + ASSERT_EQ(Construct2DData0(&dc), 0); + ASSERT_TRUE(dc); + const char *protocols[5] = { + "ascii", "json", "yaml", "hdf5", "conduit_bin" + }; + for(int i = 0; i < 5; i++) { + int retval = FmsIOWrite("TestAuto.fms", protocols[i], dc); + // Sometimes hdf5 will not be supported by conduit + if(retval == 2 && strcmp("hdf5", protocols[i]) == 0) { + continue; } - FmsDataCollectionDestroy(&dc); + ASSERT_EQ(retval, 0); + FmsDataCollection read_dc = NULL; + ASSERT_EQ(FmsIORead("TestAuto.fms", NULL, &read_dc), 0); + ASSERT_TRUE(read_dc); + EXPECT_EQ(FmsDataCollectionCompare(dc, read_dc), 0); + EXPECT_EQ(FmsDataCollectionCompare(read_dc, dc), 0); + FmsDataCollectionDestroy(&read_dc); + } + FmsDataCollectionDestroy(&dc); }