diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index beee2a032..f5671c14f 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) # Set the version -project(Basix VERSION "0.6.0.0" LANGUAGES CXX) +project(Basix VERSION "0.6.0.0" LANGUAGES CXX C) include(GNUInstallDirs) if(SKBUILD) @@ -62,7 +62,8 @@ set(HEADERS_basix ${CMAKE_CURRENT_SOURCE_DIR}/basix/e-hermite.h ${CMAKE_CURRENT_SOURCE_DIR}/basix/mdspan.hpp ${CMAKE_CURRENT_SOURCE_DIR}/basix/docs.h - ${CMAKE_CURRENT_BINARY_DIR}/basix/version.h) + ${CMAKE_CURRENT_BINARY_DIR}/basix/version.h + ${CMAKE_CURRENT_SOURCE_DIR}/basix/cwrapper.h) target_sources(basix PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/basix/cell.cpp @@ -87,10 +88,12 @@ target_sources(basix PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/basix/e-crouzeix-raviart.cpp ${CMAKE_CURRENT_SOURCE_DIR}/basix/e-bubble.cpp ${CMAKE_CURRENT_SOURCE_DIR}/basix/e-hermite.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/basix/e-serendipity.cpp) + ${CMAKE_CURRENT_SOURCE_DIR}/basix/e-serendipity.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/basix/cwrapper.cpp) # Configure the library set_target_properties(basix PROPERTIES PUBLIC_HEADER basix/finite-element.h) +set_target_properties(basix PROPERTIES PUBLIC_HEADER basix/cwrapper.h) set_target_properties(basix PROPERTIES PRIVATE_HEADER "${HEADERS_basix}") target_include_directories(basix PUBLIC $ diff --git a/cpp/basix/cwrapper.cpp b/cpp/basix/cwrapper.cpp new file mode 100644 index 000000000..a69c9787c --- /dev/null +++ b/cpp/basix/cwrapper.cpp @@ -0,0 +1,61 @@ +// Copyright (c) 2022 Susanne Claus +// FEniCS Project +// SPDX-License-Identifier: MIT + +// This file defines the C-API functions listed in cwrapper.h +// This is a C++ file that defines C calls +#include +#include +#include +#include "cwrapper.h" + +extern "C" { + +basix_element* basix_element_create(const int basix_family, const int basix_cell_type, const int degree, + const int lagrange_variant, const int dpc_variant, const bool discontinuous) +{ + //Specify which element is needed + basix::element::family family = static_cast(basix_family); + basix::cell::type cell_type = static_cast(basix_cell_type); + int k = degree; + basix::element::lagrange_variant lvariant = static_cast(lagrange_variant); + basix::element::dpc_variant dvariant = static_cast(dpc_variant); + + //Create C++ basix element object + basix::FiniteElement finite_element = basix::create_element(family, cell_type, k, lvariant,dvariant,discontinuous); + + basix_element* element = reinterpret_cast(new basix::FiniteElement(finite_element)); + + return element; +} + +void basix_element_destroy(basix_element *element) +{ + delete reinterpret_cast(element); +} + +void basix_element_tabulate_shape(basix_element *element, const unsigned int num_points, + const int nd, int* cshape) +{ + //Determine shape of tabulated values to allocate sufficient memory + std::array shape = reinterpret_cast(element)->tabulate_shape(nd, num_points); + + //Copy shape values + std::copy(shape.begin(),shape.end(),cshape); +} + +void basix_element_tabulate(basix_element *element, const unsigned int gdim, const double* points, + const unsigned int num_points, const int nd, + double* table_data, long unsigned int table_data_size) +{ + basix::FiniteElement* finite_element = reinterpret_cast(element); + + //Create span views on points and table values + std::span points_view{points,num_points*gdim}; + std::span basis{table_data, table_data_size}; + std::array xshape{num_points,gdim}; + + finite_element->tabulate(nd, points_view, xshape, basis); +} + +} diff --git a/cpp/basix/cwrapper.h b/cpp/basix/cwrapper.h new file mode 100644 index 000000000..a6e3867d7 --- /dev/null +++ b/cpp/basix/cwrapper.h @@ -0,0 +1,43 @@ +// Copyright (c) 2022 Susanne Claus +// FEniCS Project +// SPDX-License-Identifier: MIT + +// Declares a simple C API wrapper around C++. + +#ifndef CWRAPPER_H_ +#define CWRAPPER_H_ + +#include + +#ifdef __cplusplus +// extern C indicates to C++ compiler that the following code +// is meant to be called by a C compiler +// i.e. tells the compiler that C naming conventions etc should be used +extern "C" { +#endif + +//@todo Could this be replaced by ufcx_finite_element? +/// Basix element structure to map c basix element to C++ basix finite_element +/// The following int values indicate the position of the values in the corresponding +/// enum classes in basix +typedef struct basix_element basix_element; + +basix_element* basix_element_create(const int basix_family, const int basix_cell_type, const int degree, + const int lagrange_variant, const int dpc_variant, const bool discontinuous); + +void basix_element_destroy(basix_element *element); + +void basix_element_tabulate_shape(basix_element *element, const unsigned int num_points, + const int nd, int* cshape); + +void basix_element_tabulate(basix_element *element, const unsigned int gdim, const double* points, + const unsigned int num_points, const int nd, + double* table_data, long unsigned int table_data_size); + + +#ifdef __cplusplus +} +#endif + + +#endif /*CWRAPPER_H_*/