Skip to content
Snippets Groups Projects
Commit ef4b58ae authored by webmanue's avatar webmanue
Browse files

Merge remote-tracking branch 'origin/master' into...

Merge remote-tracking branch 'origin/master' into 72-implement-consistent-and-lumped-mass-matrix-for-timoshenko-beam-element
parents 9916d46c c15f1ae5
No related branches found
No related tags found
No related merge requests found
Pipeline #139086 passed
Showing
with 171 additions and 180 deletions
{
"name": "ae108-dev-real",
"settings": {
"cmake.sourceDirectory": "${workspaceFolder}",
"cmake.buildDirectory": "${workspaceFolder}/build"
},
"extensions": [
"ms-vscode.cpptools",
"ms-vscode.cmake-tools",
"ms-python.vscode-pylance",
"ms-azuretools.vscode-docker",
"gitlab.gitlab-workflow"
],
"dockerComposeFile": "../docker-compose.yml",
"service": "dev-real",
"workspaceFolder": "/mnt/io",
"remoteEnv": {
"OMPI_ALLOW_RUN_AS_ROOT": "1",
"OMPI_ALLOW_RUN_AS_ROOT_CONFIRM": "1",
"OMPI_MCA_btl_vader_single_copy_mechanism": "none"
}
}
\ No newline at end of file
......@@ -65,7 +65,8 @@ build-image-docu:
check-code-format:
stage: analyze
image: $CI_REGISTRY_IMAGE/dev:$CI_COMMIT_REF_SLUG
needs: ["build-image-dev-real"]
image: $CI_REGISTRY_IMAGE/dev-real:$CI_COMMIT_REF_SLUG
script:
- >
find . \
......@@ -77,28 +78,32 @@ check-code-format:
check-license-header:
stage: analyze
image: $CI_REGISTRY_IMAGE/dev:$CI_COMMIT_REF_SLUG
needs: ["build-image-dev-real"]
image: $CI_REGISTRY_IMAGE/dev-real:$CI_COMMIT_REF_SLUG
script:
- >
! grep \
grep \
--recursive \
--exclude-dir='.git' \
--exclude='*.json' \
--exclude='*.txt' \
--exclude='*.vtu' \
--files-without-match "Apache License" \
.
check-script:
stage: analyze
image: $CI_REGISTRY_IMAGE/dev:$CI_COMMIT_REF_SLUG
needs: ["build-image-dev-real"]
image: $CI_REGISTRY_IMAGE/dev-real:$CI_COMMIT_REF_SLUG
script:
- find . -name "*.py" -print0 | xargs -0 python3 -m black --check
- find . -name "*.py" -print0 | xargs -0 python3 -m pylint
- find . -name "*.py" -print0 | xargs -0 python3 -m pylint --generated-members=vtk.*
- find . -name "*.py" -print0 | xargs -0 python3 -m mypy --python-version 3.7 --ignore-missing
- find . -name "*.py" -print0 | xargs -0 python3 -m doctest
.build-library: &build-library
stage: build
coverage: '/^lines:\s*\d+\.\d+\%/'
script:
- useradd developer
- mkdir build
......@@ -114,16 +119,20 @@ check-script:
'
artifacts:
reports:
cobertura: build/coverage.xml
coverage_report:
coverage_format: cobertura
path: build/coverage.xml
junit: build/*/test/gtest-results.xml
when: always
build-library-real:
image: $CI_REGISTRY_IMAGE/dev-real:$CI_COMMIT_REF_SLUG
needs: ["build-image-dev-real"]
<<: *build-library
build-library-complex:
image: $CI_REGISTRY_IMAGE/dev-complex:$CI_COMMIT_REF_SLUG
needs: ["build-image-dev-complex"]
<<: *build-library
.install-library: &install-library
......@@ -146,14 +155,17 @@ build-library-complex:
install-library-real:
image: $CI_REGISTRY_IMAGE/dev-real:$CI_COMMIT_REF_SLUG
needs: ["build-image-dev-real"]
<<: *install-library
install-library-complex:
image: $CI_REGISTRY_IMAGE/dev-complex:$CI_COMMIT_REF_SLUG
needs: ["build-image-dev-complex"]
<<: *install-library
build-documentation:
stage: build
needs: ["build-image-docu"]
image: $CI_REGISTRY_IMAGE/docu:$CI_COMMIT_REF_SLUG
script:
- mkdir build
......
......@@ -45,6 +45,7 @@ install(FILES
install(FILES
cmake/modules/FindAE108_PETSc.cmake
cmake/modules/FindAE108_SLEPc.cmake
cmake/modules/AE108_PETSc.cc
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/modules"
)
......
......@@ -56,27 +56,26 @@ The project uses [CMake](https://cmake.org) as its build system generator. The f
- [Google Test](https://github.com/google/googletest): version 1.8.1
- [HDF5](https://www.hdfgroup.org/solutions/hdf5/): version 1.10
- [MPI](https://cmake.org/cmake/help/latest/module/FindMPI.html): version 3.1
- [PETSc](https://www.mcs.anl.gov/petsc/): version 3.12
- [Range-v3](https://github.com/ericniebler/range-v3): version 0.10
- [SLEPc](https://slepc.upv.es/): version 3.12
- [PETSc](https://www.mcs.anl.gov/petsc/): version 3.15
- [Range-v3](https://github.com/ericniebler/range-v3): version 0.11
- [SLEPc](https://slepc.upv.es/): version 3.15
Of course, these libraries are covered by their own license terms. Since PETSc and SLEPc do not provide a CMake configuration file, these libraries are found using the provided find modules in ```cmake/modules/```, which in turn are based on ```pkg-config```.
Once you have installed these libraries, run CMake to build the project, choosing a location to install the library to by specifying ```CMAKE_INSTALL_PREFIX```; see the following example. Of course, depending on your setup, you might need to add a ```-DCMAKE_PREFIX_PATH='...'``` parameter to tell CMake the location of the third party library installations.
```bash
mkdir build
cd build
cmake \
-S . \
-B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX='install/to/path' \
..
-DCMAKE_INSTALL_PREFIX='install/to/path'
```
Now run ```make``` to build and install:
Now use ```cmake``` to build and install:
```bash
make -j$(nproc) install
cmake --build build --target install -- -j$(nproc)
```
## Usage
......
......@@ -34,7 +34,6 @@ add_library(${PROJECT_NAME}-assembly
./FeaturePlugins.cc
./HasUniqueTypeTrait.cc
./IsSingleUniqueType.cc
./StaticLooper.cc
./UpdateInternalVariablesPlugin.cc
./deserialize.cc
./groupElementDataPerVertex.cc
......@@ -54,6 +53,6 @@ target_link_libraries(${PROJECT_NAME}-assembly
PUBLIC Eigen3::Eigen
)
target_compile_features(${PROJECT_NAME}-assembly PUBLIC cxx_std_11)
target_compile_features(${PROJECT_NAME}-assembly PUBLIC cxx_std_17)
ae108_install_library(assembly)
......@@ -66,7 +66,7 @@ public:
/**
* @param args Are used to construct the plugins.
*/
template <class... Args> explicit Assembler(Args &&... args);
template <class... Args> explicit Assembler(Args &&...args);
using ElementView = typename cpppetsc::LocalElementView<mesh_type>;
......@@ -82,7 +82,7 @@ public:
* constructor.
*/
template <class... Args>
void emplaceElement(ElementView view, Args &&... constructorArguments);
void emplaceElement(ElementView view, Args &&...constructorArguments);
/**
* @brief Returns a range of iterators pointing to a struct with two methods:
......@@ -191,13 +191,13 @@ namespace assembly {
template <class Element, class Plugins, class Policy>
template <class... Args>
Assembler<Element, Plugins, Policy>::Assembler(Args &&... args)
Assembler<Element, Plugins, Policy>::Assembler(Args &&...args)
: PluginBase(std::forward<Args>(args)...) {}
template <class Element, class Plugins, class Policy>
template <class... Args>
void Assembler<Element, Plugins, Policy>::emplaceElement(
ElementView view, Args &&... constructorArguments) {
ElementView view, Args &&...constructorArguments) {
_elements.emplace_back(std::move(view),
std::forward<Args>(constructorArguments)...);
}
......@@ -220,7 +220,7 @@ public:
* @param args Are used to construct in-place the element instance.
*/
template <class... Args>
explicit AnnotatedElement(ElementView view, Args &&... args)
explicit AnnotatedElement(ElementView view, Args &&...args)
: _meshView(std::move(view)), _instance(std::forward<Args>(args)...) {}
const ElementView &meshView() const { return _meshView; }
......
......@@ -37,22 +37,30 @@ class AssemblerGroup : public DerivePluginsUniquely<
AssemblerGroup<SingleElementAssemblers...>,
typename ConcatenatePlugins<typename PluginTypeTrait<
SingleElementAssemblers>::type...>::type> {
template <std::size_t N>
using member_assembler_type =
typename MemberTypeTrait<AssemblerGroup, N>::type;
public:
template <class... Args> explicit AssemblerGroup(Args &&... args);
template <class... Args> explicit AssemblerGroup(Args &&...args);
/**
* @brief Get the Nth member assembler.
*/
template <std::size_t N> const member_assembler_type<N> &get() const;
template <std::size_t N> const auto &get() const & {
return std::get<N>(_assemblers);
}
/**
* @brief Get the Nth member assembler.
*/
template <std::size_t N> member_assembler_type<N> &get();
template <std::size_t N> auto &get() & { return std::get<N>(_assemblers); }
/**
* @brief Return the tuple of assemblers.
*/
const auto &assemblers() const &noexcept { return _assemblers; }
/**
* @brief Return the tuple of assemblers.
*/
auto &assemblers() &noexcept { return _assemblers; }
private:
using tuple_type = std::tuple<SingleElementAssemblers...>;
......@@ -138,25 +146,6 @@ template <class... SingleElementAssemblers>
struct IsGroupTypeTrait<AssemblerGroup<SingleElementAssemblers...>>
: std::true_type {};
/**
* @brief Specialization: The number of assemblers in the group is the number of
* SingleElementAssemblers-template-parameters.
*/
template <class... SingleElementAssemblers>
struct NumberOfMembersTypeTrait<AssemblerGroup<SingleElementAssemblers...>>
: std::integral_constant<std::size_t, sizeof...(SingleElementAssemblers)> {
};
/**
* @brief Specialization: The Nth member is the Nth element of
* SingleElementAssemblers.
*/
template <std::size_t N, class... SingleElementAssemblers>
struct MemberTypeTrait<AssemblerGroup<SingleElementAssemblers...>, N> {
using type =
typename std::tuple_element<N,
std::tuple<SingleElementAssemblers...>>::type;
};
} // namespace assembly
} // namespace ae108
......@@ -169,24 +158,8 @@ namespace assembly {
template <class... SingleElementAssemblers>
template <class... Args>
AssemblerGroup<SingleElementAssemblers...>::AssemblerGroup(Args &&... args)
AssemblerGroup<SingleElementAssemblers...>::AssemblerGroup(Args &&...args)
: _assemblers(std::forward<Args>(args)...) {}
template <class... SingleElementAssemblers>
template <std::size_t N>
const typename AssemblerGroup<
SingleElementAssemblers...>::template member_assembler_type<N> &
AssemblerGroup<SingleElementAssemblers...>::get() const {
return std::get<N>(_assemblers);
}
template <class... SingleElementAssemblers>
template <std::size_t N>
typename AssemblerGroup<
SingleElementAssemblers...>::template member_assembler_type<N> &
AssemblerGroup<SingleElementAssemblers...>::get() {
return std::get<N>(_assemblers);
}
} // namespace assembly
} // namespace ae108
......@@ -71,17 +71,5 @@ template <class Assembler> struct PluginTypeTrait {};
* (designed for the nongroup case) the value is false.
*/
template <class Assembler> struct IsGroupTypeTrait : std::false_type {};
/**
* @brief Deduces the number of member assemblers. By default (designed for the
* nongroup case) this number is undefined.
*/
template <class Assembler> struct NumberOfMembersTypeTrait {};
/**
* @brief Deduces the type of the member assembler at a given index. By default
* (designed for the nongroup case) this type is undefined.
*/
template <class Assembler, std::size_t> struct MemberTypeTrait {};
} // namespace assembly
} // namespace ae108
......@@ -16,11 +16,26 @@
#pragma once
#include "ae108/assembly/AssemblerTypeTraits.h"
#include <functional>
#include <tuple>
#include <utility>
#define DEFINE_ASSEMBLER_METHOD_BASE(methodName, cvQualifiers) \
template <class... Args> void methodName(Args &&... args) cvQualifiers { \
this->dispatch(std::forward<Args>(args)...); \
#define DEFINE_ASSEMBLER_METHOD_BASE(PluginName, methodName, cvQualifiers) \
template <class... Args> void methodName(Args &&...args) cvQualifiers { \
if constexpr (!::ae108::assembly::IsGroupTypeTrait< \
typename PluginName::assembler_type>::value) { \
execute(std::forward<Args>(args)...); \
} else { \
const auto conditionalCall = [&](auto &a) { \
using A = std::decay_t<decltype(a)>; \
if constexpr (std::is_base_of_v<PluginName<A>, A>) { \
static_cast<cvQualifiers PluginName<A> &>(a).execute(args...); \
} \
}; \
std::apply( \
[&](auto &...as) { (..., std::invoke(conditionalCall, as)); }, \
this->assembler().assemblers()); \
} \
}
#define DEFINE_ASSEMBLER_PLUGIN_BASE(PluginName, methodName, methodArguments, \
......@@ -28,6 +43,7 @@
template <class Assembler> \
class PluginName \
: public ::ae108::assembly::FeaturePlugin<Assembler, PluginName> { \
using assembler_type = Assembler; \
using element_type = \
typename ::ae108::assembly::ElementTypeTrait<Assembler>::type; \
using matrix_type = \
......@@ -45,7 +61,7 @@
\
public: \
void execute methodArguments cvQualifiers; \
DEFINE_ASSEMBLER_METHOD_BASE(methodName, cvQualifiers) \
DEFINE_ASSEMBLER_METHOD_BASE(PluginName, methodName, cvQualifiers) \
\
protected: \
~PluginName() = default; \
......@@ -63,29 +79,21 @@
namespace ae108 {
namespace assembly {
template <class Assembler, template <class> class Plugin> class FeaturePlugin {
template <class Assembler_, template <class> class Plugin_>
class FeaturePlugin {
using assembler_type = Assembler_;
template <class T> using plugin_type = Plugin_<T>;
protected:
/**
* @brief Returns a reference to the Assembler base class.
*/
Assembler &assembler();
assembler_type &assembler();
/**
* @brief Returns a reference to the Assembler base class.
*/
const Assembler &assembler() const;
/**
* @brief Calls execute with the given parameters for all (member) assemblers
* that have the plugin (const version).
*/
template <class... Args> void dispatch(Args &&... args) const;
/**
* @brief Calls execute with the given parameters for all (member) assemblers
* that have the plugin (nonconst version).
*/
template <class... Args> void dispatch(Args &&... args);
const assembler_type &assembler() const;
~FeaturePlugin() = default;
};
......@@ -96,65 +104,9 @@ protected:
* implementations
*******************************************************************/
#include "ae108/assembly/utilities/StaticLooper.h"
#include <type_traits>
namespace ae108 {
namespace assembly {
namespace detail {
template <class Assembler, template <class> class Plugin>
using HasPlugin = std::is_base_of<Plugin<Assembler>, Assembler>;
template <class Assembler, template <class> class Plugin>
using PluginType = Plugin<typename std::remove_const<Assembler>::type>;
template <class Assembler, template <class> class Plugin>
using CastType =
typename std::conditional<std::is_const<Assembler>::value,
const PluginType<Assembler, Plugin> &,
PluginType<Assembler, Plugin> &>::type;
template <template <class> class Plugin> struct Executor {
template <class Assembler, class... Args>
void operator()(Assembler &assembler, Args &&... args) const {
operatorImpl(
HasPlugin<typename std::remove_const<Assembler>::type, Plugin>{},
assembler, std::forward<Args>(args)...);
}
private:
template <class Assembler, class... Args>
void operatorImpl(std::true_type, Assembler &assembler,
Args &&... args) const {
static_cast<CastType<Assembler, Plugin>>(assembler).execute(
std::forward<Args>(args)...);
}
template <class Assembler, class... Args>
void operatorImpl(std::false_type, Assembler &, Args &&...) const {}
};
/**
* @brief Implementation of dispatch for the assembler-group case.
*/
template <template <class> class Plugin, class Assembler, class... Args>
void dispatchImpl(std::true_type, Assembler &assembler, Args &&... args) {
utilities::StaticLooper<NumberOfMembersTypeTrait<typename std::remove_const<
Assembler>::type>::value>::run(detail::Executor<Plugin>{}, assembler,
std::forward<Args>(args)...);
}
/**
* @brief Implementation of dispatch for the non-assembler-group case.
*/
template <template <class> class Plugin, class Assembler, class... Args>
void dispatchImpl(std::false_type, Assembler &assembler, Args &&... args) {
static_cast<CastType<Assembler, Plugin>>(assembler).execute(
std::forward<Args>(args)...);
}
} // namespace detail
template <class Assembler, template <class> class Plugin>
Assembler &FeaturePlugin<Assembler, Plugin>::assembler() {
return static_cast<Assembler &>(static_cast<Plugin<Assembler> &>(*this));
......@@ -165,19 +117,5 @@ const Assembler &FeaturePlugin<Assembler, Plugin>::assembler() const {
return static_cast<const Assembler &>(
static_cast<const Plugin<Assembler> &>(*this));
}
template <class Assembler, template <class> class Plugin>
template <class... Args>
void FeaturePlugin<Assembler, Plugin>::dispatch(Args &&... args) const {
detail::dispatchImpl<Plugin>(IsGroupTypeTrait<Assembler>{}, assembler(),
std::forward<Args>(args)...);
}
template <class Assembler, template <class> class Plugin>
template <class... Args>
void FeaturePlugin<Assembler, Plugin>::dispatch(Args &&... args) {
detail::dispatchImpl<Plugin>(IsGroupTypeTrait<Assembler>{}, assembler(),
std::forward<Args>(args)...);
}
} // namespace assembly
} // namespace ae108
......@@ -29,7 +29,7 @@ DEFINE_CONST_ASSEMBLER_PLUGIN(AssembleConsistentMassMatrixPlugin,
std::vector<value_type> outputBuffer;
for (const auto &meshElement : this->assembler().meshElements()) {
const auto matrix = meshElement.instance().computeConsistentMassMatrix();
const auto matrix = compute_consistent_mass_matrix(meshElement.instance());
outputBuffer.resize(matrix.rows() * matrix.cols());
utilities::serialize(matrix, outputBuffer.begin());
......
......@@ -29,7 +29,7 @@ DEFINE_CONST_ASSEMBLER_PLUGIN(AssembleLumpedMassMatrixPlugin,
std::vector<value_type> outputBuffer;
for (const auto &meshElement : this->assembler().meshElements()) {
const auto matrix = meshElement.instance().computeLumpedMassMatrix();
const auto matrix = compute_lumped_mass_matrix(meshElement.instance());
outputBuffer.resize(matrix.rows() * matrix.cols());
utilities::serialize(matrix, outputBuffer.begin());
......
......@@ -27,7 +27,7 @@ DEFINE_CONST_ASSEMBLER_PLUGIN(AssembleMassMatrixPlugin, assembleMassMatrix,
std::vector<value_type> outputBuffer;
for (const auto &meshElement : this->assembler().meshElements()) {
const auto matrix = meshElement.instance().computeMassMatrix();
const auto matrix = compute_mass_matrix(meshElement.instance());
outputBuffer.resize(matrix.rows() * matrix.cols());
utilities::serialize(matrix, outputBuffer.begin());
......
......@@ -68,12 +68,13 @@ OutputIterator serialize(const std::vector<ValueType> &vector,
template <class OutputIterator, class ValueType, int Rows, int Cols>
OutputIterator serialize(const Eigen::Matrix<ValueType, Rows, Cols> &vector,
OutputIterator bufferBegin) {
std::array<ValueType, Rows * Cols> buffer;
Eigen::Map<Eigen::Matrix<ValueType, Rows, Cols,
Cols == 1 ? Eigen::ColMajor : Eigen::RowMajor>>
wrappedBuffer(buffer.data(), vector.rows(), vector.cols());
wrappedBuffer = vector;
return std::copy(buffer.begin(), buffer.end(), bufferBegin);
for (Eigen::Index i = 0; i < vector.rows(); ++i) {
for (Eigen::Index j = 0; j < vector.cols(); ++j) {
*bufferBegin = vector(i, j);
bufferBegin++;
}
}
return bufferBegin;
}
/**
......
......@@ -140,7 +140,7 @@ MATCHER_P(IsWrappedSingleValue, value,
std::string(negation ? "not " : "") + "wrapped single value " +
PrintToString(value)) {
return ::testing::ExplainMatchResult(SizeIs(1), arg, result_listener) &&
::testing::ExplainMatchResult(SizeIs(1), arg[0], result_listener) &&
::testing::ExplainMatchResult(Eq(1), arg[0].size(), result_listener) &&
::testing::ExplainMatchResult(ScalarEq(value), arg[0](0),
result_listener);
}
......
......@@ -21,9 +21,9 @@ add_executable(${PROJECT_NAME}-AssemblyTests
./ConcatenateFeaturePlugins_Test.cc
./DerivePluginsUniquely_Test.cc
./DeriveUniquely_Test.cc
./FeaturePlugin_Test.cc
./HasUniqueTypeTrait_Test.cc
./IsSingleTypeTrait_Test.cc
./StaticLooper_Test.cc
./deserialize_Test.cc
./resizeIfPossible_Test.cc
./serialize_Test.cc
......
// © 2022 ETH Zurich, Mechanics and Materials Lab
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
#include "ae108/assembly/FeaturePlugin.h"
namespace {
DEFINE_ASSEMBLER_PLUGIN(TestPlugin, testMethod, (double)) {}
DEFINE_CONST_ASSEMBLER_PLUGIN(TestPluginConst, testMethodConst, (double)) {}
} // namespace
namespace ae108 {
namespace assembly {
namespace {
DEFINE_ASSEMBLER_PLUGIN(TestPlugin, testMethod, (double)) {}
DEFINE_CONST_ASSEMBLER_PLUGIN(TestPluginConst, testMethodConst, (double)) {}
} // namespace
} // namespace assembly
} // namespace ae108
......@@ -50,6 +50,17 @@ template <class ValueType_> struct Element {
MOCK_METHOD2_T(updateInternalVariables,
void(const NodalDisplacements &, const double));
};
template <class ValueType_>
auto compute_consistent_mass_matrix(const Element<ValueType_> &element) {
return element.computeConsistentMassMatrix();
}
template <class ValueType_>
auto compute_lumped_mass_matrix(const Element<ValueType_> &element) {
return element.computeLumpedMassMatrix();
}
} // namespace test
} // namespace assembly
} // namespace ae108
......@@ -69,6 +69,20 @@ TEST_F(serialize_Test, serializing_eigen_matrix_works) {
DoubleEq(0.)));
}
TEST_F(serialize_Test, serializing_dynamically_sized_eigen_matrix_works) {
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> values(3, 2);
values << 1, 2, 3, 4, 5, 6;
std::vector<double> buffer(7);
const auto result = serialize(values, buffer.begin());
EXPECT_THAT(result, Eq(buffer.begin() + 6));
EXPECT_THAT(buffer, ElementsAre(DoubleEq(1.), DoubleEq(2.), DoubleEq(3.),
DoubleEq(4.), DoubleEq(5.), DoubleEq(6.),
DoubleEq(0.)));
}
TEST_F(serialize_Test, serializing_eigen_vector_works) {
Eigen::Vector3d values;
values << 1, 2, 3;
......
......@@ -20,10 +20,10 @@ find_dependency(Boost 1.67 COMPONENTS program_options REQUIRED)
find_dependency(Eigen3 3.3 CONFIG REQUIRED)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules")
find_dependency(AE108_PETSc MODULE 3.12)
find_dependency(AE108_PETSc MODULE 3.15)
find_dependency(range-v3 0.10.0 CONFIG REQUIRED)
find_dependency(range-v3 0.11.0 CONFIG REQUIRED)
foreach(AE108_LIBRARY elements cpppetsc assembly solve cmdline)
foreach(AE108_LIBRARY elements cpppetsc cppslepc assembly solve cmdline)
include("${CMAKE_CURRENT_LIST_DIR}/ae108-${AE108_LIBRARY}-export.cmake")
endforeach()
......@@ -51,6 +51,7 @@ if(AE108_PETSc_FOUND AND NOT TARGET ae108::external::petsc)
endif()
try_compile_with_petsc("-DAE108_PETSC_COMPLEX")
set(AE108_PETSC_COMPLEX ${AE108_PETSc_COMPILE_RESULT} CACHE BOOL "ae108: PETSc with complex scalar type")
if(AE108_PETSc_COMPILE_RESULT)
target_compile_definitions(ae108::external::petsc
INTERFACE AE108_PETSC_COMPLEX=1
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment