Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d8952297f | ||
|
|
f5af06ecee | ||
|
|
b32f8c8959 | ||
|
|
e45f5f8595 | ||
|
|
03e64ea9b1 |
+43
-11
@@ -231,22 +231,53 @@ public:
|
||||
const std::vector<FieldDescriptor> ¶meters,
|
||||
const ParMesh &mesh);
|
||||
|
||||
/// MultLevel enum to indicate if the T->L Operators are used in the
|
||||
/// Mult method.
|
||||
enum MultLevel
|
||||
{
|
||||
TVECTOR,
|
||||
LVECTOR
|
||||
};
|
||||
|
||||
/// @brief Set the MultLevel mode for the DifferentiableOperator.
|
||||
/// The default is TVECTOR, which means that the Operator will use
|
||||
/// T->L before Mult and L->T Operators after.
|
||||
void SetMultLevel(MultLevel level)
|
||||
{
|
||||
mult_level = level;
|
||||
}
|
||||
|
||||
/// @brief Compute the action of the operator on a given vector.
|
||||
///
|
||||
/// @param solutions_t The solution vector in which to compute the action.
|
||||
/// This has to be a T-dof vector.
|
||||
/// @param result_t Result vector of the action of the operator on
|
||||
/// solutions_t. The result is a T-dof vector.
|
||||
void Mult(const Vector &solutions_t, Vector &result_t) const override
|
||||
/// @param solutions_in The solution vector in which to compute the action.
|
||||
/// This has to be a T-dof vector if MultLevel is set to TVECTOR, or L-dof
|
||||
/// Vector if MultLevel is set to LVECTOR.
|
||||
/// @param result_in Result vector of the action of the operator on
|
||||
/// solutions. The result is a T-dof vector or L-dof vector depending on
|
||||
/// the MultLevel.
|
||||
void Mult(const Vector &solutions_in, Vector &result_in) const override
|
||||
{
|
||||
MFEM_ASSERT(!action_callbacks.empty(), "no integrators have been set");
|
||||
prolongation(solutions, solutions_t, solutions_l);
|
||||
residual_l = 0.0;
|
||||
for (auto &action : action_callbacks)
|
||||
|
||||
if (mult_level == MultLevel::LVECTOR)
|
||||
{
|
||||
action(solutions_l, parameters_l, residual_l);
|
||||
get_lvectors(solutions, solutions_in, solutions_l);
|
||||
result_in = 0.0;
|
||||
for (auto &action : action_callbacks)
|
||||
{
|
||||
action(solutions_l, parameters_l, result_in);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prolongation(solutions, solutions_in, solutions_l);
|
||||
residual_l = 0.0;
|
||||
for (auto &action : action_callbacks)
|
||||
{
|
||||
action(solutions_l, parameters_l, residual_l);
|
||||
}
|
||||
prolongation_transpose(residual_l, result_in);
|
||||
}
|
||||
prolongation_transpose(residual_l, result_t);
|
||||
}
|
||||
|
||||
/// @brief Add a domain integrator to the operator.
|
||||
@@ -345,6 +376,8 @@ public:
|
||||
private:
|
||||
const ParMesh &mesh;
|
||||
|
||||
MultLevel mult_level = TVECTOR;
|
||||
|
||||
std::vector<action_t> action_callbacks;
|
||||
std::map<size_t,
|
||||
std::vector<derivative_action_t>> derivative_action_callbacks;
|
||||
@@ -354,7 +387,6 @@ private:
|
||||
std::vector<assemble_derivative_hypreparmatrix_callback_t>>
|
||||
assemble_derivative_hypreparmatrix_callbacks;
|
||||
|
||||
|
||||
std::vector<FieldDescriptor> solutions;
|
||||
std::vector<FieldDescriptor> parameters;
|
||||
// solutions and parameters
|
||||
|
||||
@@ -1076,6 +1076,24 @@ void prolongation(const std::vector<FieldDescriptor> fields,
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void get_lvectors(const std::vector<FieldDescriptor> fields,
|
||||
const Vector &x,
|
||||
std::vector<Vector> &fields_l)
|
||||
{
|
||||
int data_offset = 0;
|
||||
for (std::size_t i = 0; i < fields.size(); i++)
|
||||
{
|
||||
const int sz = GetVSize(fields[i]);
|
||||
fields_l[i].SetSize(sz);
|
||||
|
||||
const Vector x_i(const_cast<Vector&>(x), data_offset, sz);
|
||||
fields_l[i] = x_i;
|
||||
|
||||
data_offset += sz;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Get a transpose prolongation callback for a field descriptor.
|
||||
///
|
||||
/// In the special case of a one field operator, the transpose prolongation
|
||||
|
||||
+95
-94
@@ -20,6 +20,7 @@ set(UNIT_TESTS_SRCS
|
||||
dfem/test_diffusion.cpp
|
||||
dfem/test_divergence.cpp
|
||||
dfem/test_mass.cpp
|
||||
dfem/test_lvector_interface.cpp
|
||||
general/test_array.cpp
|
||||
general/test_reduction.cpp
|
||||
general/test_arrays_by_name.cpp
|
||||
@@ -144,11 +145,11 @@ set(UNIT_TESTS_SRCS
|
||||
# SERIAL CPU TESTS: unit_tests
|
||||
#-----------------------------------------------------------
|
||||
if (MFEM_USE_CUDA)
|
||||
set_property(SOURCE unit_test_main.cpp ${UNIT_TESTS_SRCS}
|
||||
set_property(SOURCE unit_test_main.cpp ${UNIT_TESTS_SRCS}
|
||||
PROPERTY LANGUAGE CUDA)
|
||||
endif()
|
||||
if (MFEM_USE_HIP)
|
||||
set_property(SOURCE unit_test_main.cpp ${UNIT_TESTS_SRCS}
|
||||
set_property(SOURCE unit_test_main.cpp ${UNIT_TESTS_SRCS}
|
||||
PROPERTY HIP_SOURCE_PROPERTY_FORMAT TRUE)
|
||||
endif()
|
||||
|
||||
@@ -175,7 +176,7 @@ COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
# make unit_tests
|
||||
# ctest -R unit_tests [-V]
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME unit_tests COMMAND unit_tests)
|
||||
add_test(NAME unit_tests COMMAND unit_tests)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------
|
||||
@@ -183,16 +184,16 @@ endif()
|
||||
#-----------------------------------------------------------
|
||||
# Create CUDA executable and test
|
||||
if (MFEM_USE_CUDA)
|
||||
# gpu_unit_tests
|
||||
set(GPU_UNIT_TESTS_SRCS gpu_unit_test_main.cpp)
|
||||
set_property(SOURCE ${GPU_UNIT_TESTS_SRCS} PROPERTY LANGUAGE CUDA)
|
||||
mfem_add_executable(gpu_unit_tests ${GPU_UNIT_TESTS_SRCS} ${UNIT_TESTS_SRCS})
|
||||
target_link_libraries(gpu_unit_tests mfem)
|
||||
add_dependencies(gpu_unit_tests copy_data)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} gpu_unit_tests)
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME gpu_unit_tests COMMAND gpu_unit_tests)
|
||||
endif()
|
||||
# gpu_unit_tests
|
||||
set(GPU_UNIT_TESTS_SRCS gpu_unit_test_main.cpp)
|
||||
set_property(SOURCE ${GPU_UNIT_TESTS_SRCS} PROPERTY LANGUAGE CUDA)
|
||||
mfem_add_executable(gpu_unit_tests ${GPU_UNIT_TESTS_SRCS} ${UNIT_TESTS_SRCS})
|
||||
target_link_libraries(gpu_unit_tests mfem)
|
||||
add_dependencies(gpu_unit_tests copy_data)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} gpu_unit_tests)
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME gpu_unit_tests COMMAND gpu_unit_tests)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------
|
||||
@@ -200,15 +201,15 @@ endif()
|
||||
#-----------------------------------------------------------
|
||||
# Create HIP 'gpu_unit_tests' executable and test
|
||||
if (MFEM_USE_HIP)
|
||||
# gpu_unit_tests
|
||||
set(GPU_UNIT_TESTS_SRCS gpu_unit_test_main.cpp)
|
||||
mfem_add_executable(gpu_unit_tests ${GPU_UNIT_TESTS_SRCS} ${UNIT_TESTS_SRCS})
|
||||
target_link_libraries(gpu_unit_tests mfem)
|
||||
add_dependencies(gpu_unit_tests copy_data)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} gpu_unit_tests)
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME gpu_unit_tests COMMAND gpu_unit_tests)
|
||||
endif()
|
||||
# gpu_unit_tests
|
||||
set(GPU_UNIT_TESTS_SRCS gpu_unit_test_main.cpp)
|
||||
mfem_add_executable(gpu_unit_tests ${GPU_UNIT_TESTS_SRCS} ${UNIT_TESTS_SRCS})
|
||||
target_link_libraries(gpu_unit_tests mfem)
|
||||
add_dependencies(gpu_unit_tests copy_data)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} gpu_unit_tests)
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME gpu_unit_tests COMMAND gpu_unit_tests)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------
|
||||
@@ -224,7 +225,7 @@ function(add_serial_miniapp_test name test_uvm)
|
||||
|
||||
set(${NAME}_TESTS_SRCS miniapps/test_${name}.cpp)
|
||||
if (MFEM_USE_CUDA)
|
||||
set_property(SOURCE ${${NAME}_TESTS_SRCS} PROPERTY LANGUAGE CUDA)
|
||||
set_property(SOURCE ${${NAME}_TESTS_SRCS} PROPERTY LANGUAGE CUDA)
|
||||
endif(MFEM_USE_CUDA)
|
||||
|
||||
mfem_add_executable(${name}_tests_cpu ${${NAME}_TESTS_SRCS})
|
||||
@@ -244,25 +245,25 @@ function(add_serial_miniapp_test name test_uvm)
|
||||
endif()
|
||||
|
||||
if (MFEM_USE_CUDA OR MFEM_USE_HIP)
|
||||
mfem_add_executable(${name}_tests_gpu ${${NAME}_TESTS_SRCS})
|
||||
target_compile_definitions(${name}_tests_gpu PUBLIC MFEM_${NAME}_DEVICE="gpu")
|
||||
target_link_libraries(${name}_tests_gpu mfem)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} ${name}_tests_gpu)
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME ${name}_tests_gpu COMMAND ${name}_tests_gpu)
|
||||
endif()
|
||||
mfem_add_executable(${name}_tests_gpu ${${NAME}_TESTS_SRCS})
|
||||
target_compile_definitions(${name}_tests_gpu PUBLIC MFEM_${NAME}_DEVICE="gpu")
|
||||
target_link_libraries(${name}_tests_gpu mfem)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} ${name}_tests_gpu)
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME ${name}_tests_gpu COMMAND ${name}_tests_gpu)
|
||||
endif()
|
||||
|
||||
if (test_uvm)
|
||||
mfem_add_executable(${name}_tests_gpu_uvm ${${NAME}_TESTS_SRCS})
|
||||
target_compile_definitions(${name}_tests_gpu_uvm PUBLIC
|
||||
if (test_uvm)
|
||||
mfem_add_executable(${name}_tests_gpu_uvm ${${NAME}_TESTS_SRCS})
|
||||
target_compile_definitions(${name}_tests_gpu_uvm PUBLIC
|
||||
MFEM_${NAME}_DEVICE="gpu:uvm")
|
||||
target_link_libraries(${name}_tests_gpu_uvm mfem)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME}
|
||||
target_link_libraries(${name}_tests_gpu_uvm mfem)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME}
|
||||
${name}_tests_gpu_uvm)
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME ${name}_tests_gpu_uvm COMMAND ${name}_tests_gpu_uvm)
|
||||
endif()
|
||||
endif()
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME ${name}_tests_gpu_uvm COMMAND ${name}_tests_gpu_uvm)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endfunction(add_serial_miniapp_test)
|
||||
|
||||
@@ -277,25 +278,25 @@ add_dependencies(tmop_pa_tests_cpu copy_miniapps_meshing_data)
|
||||
#-----------------------------------------------------------
|
||||
# Add 'ceed_tests' executable and test; add extra tests 'ceed_test_*'
|
||||
if (MFEM_USE_CEED)
|
||||
set(CEED_TESTS_SRCS
|
||||
set(CEED_TESTS_SRCS
|
||||
ceed/test_ceed.cpp
|
||||
ceed/test_ceed_main.cpp)
|
||||
if (MFEM_USE_CUDA)
|
||||
set_property(SOURCE ${CEED_TESTS_SRCS} PROPERTY LANGUAGE CUDA)
|
||||
endif(MFEM_USE_CUDA)
|
||||
mfem_add_executable(ceed_tests ${CEED_TESTS_SRCS})
|
||||
target_link_libraries(ceed_tests mfem)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} ceed_tests)
|
||||
# Add CEED tests
|
||||
add_test(NAME ceed_tests COMMAND ceed_tests)
|
||||
if (MFEM_USE_CUDA)
|
||||
add_test(NAME ceed_tests_cuda_ref
|
||||
if (MFEM_USE_CUDA)
|
||||
set_property(SOURCE ${CEED_TESTS_SRCS} PROPERTY LANGUAGE CUDA)
|
||||
endif(MFEM_USE_CUDA)
|
||||
mfem_add_executable(ceed_tests ${CEED_TESTS_SRCS})
|
||||
target_link_libraries(ceed_tests mfem)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} ceed_tests)
|
||||
# Add CEED tests
|
||||
add_test(NAME ceed_tests COMMAND ceed_tests)
|
||||
if (MFEM_USE_CUDA)
|
||||
add_test(NAME ceed_tests_cuda_ref
|
||||
COMMAND ceed_tests --device ceed-cuda:/gpu/cuda/ref)
|
||||
add_test(NAME ceed_tests_cuda_shared
|
||||
add_test(NAME ceed_tests_cuda_shared
|
||||
COMMAND ceed_tests --device ceed-cuda:/gpu/cuda/shared)
|
||||
add_test(NAME ceed_tests_cuda_gen
|
||||
add_test(NAME ceed_tests_cuda_gen
|
||||
COMMAND ceed_tests --device ceed-cuda:/gpu/cuda/gen)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------
|
||||
@@ -303,54 +304,54 @@ endif()
|
||||
#-----------------------------------------------------------
|
||||
# Define executables and tests
|
||||
if (MFEM_USE_MPI)
|
||||
# punit_tests
|
||||
if (MFEM_USE_CUDA)
|
||||
set_property(SOURCE punit_test_main.cpp PROPERTY LANGUAGE CUDA)
|
||||
endif()
|
||||
mfem_add_executable(punit_tests punit_test_main.cpp ${UNIT_TESTS_SRCS})
|
||||
target_link_libraries(punit_tests mfem)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} punit_tests)
|
||||
foreach(np 1 ${MFEM_MPI_NP})
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME punit_tests_np=${np}
|
||||
# punit_tests
|
||||
if (MFEM_USE_CUDA)
|
||||
set_property(SOURCE punit_test_main.cpp PROPERTY LANGUAGE CUDA)
|
||||
endif()
|
||||
mfem_add_executable(punit_tests punit_test_main.cpp ${UNIT_TESTS_SRCS})
|
||||
target_link_libraries(punit_tests mfem)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} punit_tests)
|
||||
foreach(np 1 ${MFEM_MPI_NP})
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME punit_tests_np=${np}
|
||||
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${np}
|
||||
${MPIEXEC_PREFLAGS} $<TARGET_FILE:punit_tests>
|
||||
${MPIEXEC_POSTFLAGS})
|
||||
endif()
|
||||
endforeach()
|
||||
if (MFEM_USE_CUDA)
|
||||
# pgpu_unit_tests
|
||||
set(PGPU_UNIT_TESTS_SRCS pgpu_unit_test_main.cpp)
|
||||
set_property(SOURCE ${PGPU_UNIT_TESTS_SRCS} PROPERTY LANGUAGE CUDA)
|
||||
mfem_add_executable(pgpu_unit_tests ${PGPU_UNIT_TESTS_SRCS} ${UNIT_TESTS_SRCS})
|
||||
add_dependencies(pgpu_unit_tests copy_data)
|
||||
target_link_libraries(pgpu_unit_tests mfem)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} pgpu_unit_tests)
|
||||
foreach(np 1 ${MFEM_MPI_NP})
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME pgpu_unit_tests_np=${np}
|
||||
endif()
|
||||
endforeach()
|
||||
if (MFEM_USE_CUDA)
|
||||
# pgpu_unit_tests
|
||||
set(PGPU_UNIT_TESTS_SRCS pgpu_unit_test_main.cpp)
|
||||
set_property(SOURCE ${PGPU_UNIT_TESTS_SRCS} PROPERTY LANGUAGE CUDA)
|
||||
mfem_add_executable(pgpu_unit_tests ${PGPU_UNIT_TESTS_SRCS} ${UNIT_TESTS_SRCS})
|
||||
add_dependencies(pgpu_unit_tests copy_data)
|
||||
target_link_libraries(pgpu_unit_tests mfem)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} pgpu_unit_tests)
|
||||
foreach(np 1 ${MFEM_MPI_NP})
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME pgpu_unit_tests_np=${np}
|
||||
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${np}
|
||||
${MPIEXEC_PREFLAGS} $<TARGET_FILE:pgpu_unit_tests>
|
||||
${MPIEXEC_POSTFLAGS})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
if (MFEM_USE_HIP)
|
||||
# pgpu_unit_tests
|
||||
set(PGPU_UNIT_TESTS_SRCS pgpu_unit_test_main.cpp)
|
||||
mfem_add_executable(pgpu_unit_tests ${PGPU_UNIT_TESTS_SRCS} ${UNIT_TESTS_SRCS})
|
||||
add_dependencies(pgpu_unit_tests copy_data)
|
||||
target_link_libraries(pgpu_unit_tests mfem)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} pgpu_unit_tests)
|
||||
foreach(np 1 ${MFEM_MPI_NP})
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME pgpu_unit_tests_np=${np}
|
||||
# pgpu_unit_tests
|
||||
set(PGPU_UNIT_TESTS_SRCS pgpu_unit_test_main.cpp)
|
||||
mfem_add_executable(pgpu_unit_tests ${PGPU_UNIT_TESTS_SRCS} ${UNIT_TESTS_SRCS})
|
||||
add_dependencies(pgpu_unit_tests copy_data)
|
||||
target_link_libraries(pgpu_unit_tests mfem)
|
||||
add_dependencies(${MFEM_ALL_TESTS_TARGET_NAME} pgpu_unit_tests)
|
||||
foreach(np 1 ${MFEM_MPI_NP})
|
||||
if (MFEM_USE_DOUBLE) # otherwise returns MFEM_SKIP_RETURN_VALUE
|
||||
add_test(NAME pgpu_unit_tests_np=${np}
|
||||
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${np}
|
||||
${MPIEXEC_PREFLAGS} $<TARGET_FILE:pgpu_unit_tests>
|
||||
${MPIEXEC_POSTFLAGS})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif(MFEM_USE_MPI)
|
||||
|
||||
#-----------------------------------------------------------
|
||||
@@ -424,8 +425,8 @@ endfunction(add_parallel_miniapp_test)
|
||||
|
||||
# Additional MPI unit tests
|
||||
if (MFEM_USE_MPI)
|
||||
add_parallel_miniapp_test(sedov TRUE)
|
||||
add_parallel_miniapp_test(tmop_pa FALSE)
|
||||
add_parallel_miniapp_test(sedov TRUE)
|
||||
add_parallel_miniapp_test(tmop_pa FALSE)
|
||||
endif(MFEM_USE_MPI)
|
||||
|
||||
#-----------------------------------------------------------
|
||||
@@ -434,10 +435,10 @@ endif(MFEM_USE_MPI)
|
||||
#-----------------------------------------------------------
|
||||
set(DEBUG_DEVICE_SRCS miniapps/test_debug_device.cpp)
|
||||
if (MFEM_USE_CUDA)
|
||||
set_property(SOURCE ${DEBUG_DEVICE_SRCS} PROPERTY LANGUAGE CUDA)
|
||||
set_property(SOURCE ${DEBUG_DEVICE_SRCS} PROPERTY LANGUAGE CUDA)
|
||||
endif()
|
||||
if (MFEM_USE_HIP)
|
||||
set_property(SOURCE ${DEBUG_DEVICE_SRCS}
|
||||
set_property(SOURCE ${DEBUG_DEVICE_SRCS}
|
||||
PROPERTY HIP_SOURCE_PROPERTY_FORMAT TRUE)
|
||||
endif()
|
||||
mfem_add_executable(debug_device_tests ${DEBUG_DEVICE_SRCS})
|
||||
|
||||
@@ -255,8 +255,8 @@ void DFemDiffusion(const char *filename, int p, const int r)
|
||||
DOperator dop_mf(vsol, {{Coords, mfes}}, pmesh);
|
||||
const auto mf_vector_diffusion_qf =
|
||||
[] MFEM_HOST_DEVICE (const tensor<dscalar_t, DIM, DIM> &dudxi,
|
||||
const tensor<real_t, DIM, DIM> &J,
|
||||
const real_t &w)
|
||||
const tensor<real_t, DIM, DIM> &J,
|
||||
const real_t &w)
|
||||
{
|
||||
const auto invJ = inv(J), TinJ = transpose(invJ);
|
||||
return tuple{ (dudxi * invJ) * TinJ * det(J) * w };
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
|
||||
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
|
||||
// LICENSE and NOTICE for details. LLNL-CODE-806117.
|
||||
//
|
||||
// This file is part of the MFEM library. For more information and source code
|
||||
// availability visit https://mfem.org.
|
||||
//
|
||||
// MFEM is free software; you can redistribute it and/or modify it under the
|
||||
// terms of the BSD-3 license. We welcome feedback and contributions, see file
|
||||
// CONTRIBUTING.md for details.
|
||||
|
||||
#include "../unit_tests.hpp"
|
||||
#include "mfem.hpp"
|
||||
#include <utility>
|
||||
|
||||
#ifdef MFEM_USE_MPI
|
||||
|
||||
using namespace mfem;
|
||||
using namespace mfem::future;
|
||||
using mfem::future::tensor;
|
||||
|
||||
constexpr int DIM = 3;
|
||||
|
||||
namespace kernels
|
||||
{
|
||||
struct MFApply
|
||||
{
|
||||
MFEM_HOST_DEVICE inline auto operator()(const tensor<real_t, DIM> &dudxi,
|
||||
const tensor<real_t, DIM, DIM> &J,
|
||||
const real_t &w) const
|
||||
{
|
||||
const auto invJ = inv(J);
|
||||
return tuple{ (dudxi * invJ) * transpose(invJ) * det(J) * w };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("DFEM L-Vector interface", "[Parallel][DFEM]")
|
||||
{
|
||||
constexpr int p = 2; // Polynomial order
|
||||
constexpr int r = 1;
|
||||
constexpr int q = 2 * p + r;
|
||||
|
||||
const auto filename = GENERATE("../../data/fichera.mesh");
|
||||
Mesh smesh(filename);
|
||||
ParMesh pmesh(MPI_COMM_WORLD, smesh);
|
||||
MFEM_VERIFY(pmesh.Dimension() == DIM, "Mesh dimension mismatch");
|
||||
|
||||
pmesh.EnsureNodes();
|
||||
auto *nodes = static_cast<ParGridFunction *>(pmesh.GetNodes());
|
||||
smesh.Clear();
|
||||
|
||||
Array<int> all_domain_attr;
|
||||
if (pmesh.attributes.Size() > 0)
|
||||
{
|
||||
all_domain_attr.SetSize(pmesh.attributes.Max());
|
||||
all_domain_attr = 1;
|
||||
}
|
||||
|
||||
H1_FECollection fec(p, DIM);
|
||||
ParFiniteElementSpace pfes(&pmesh, &fec);
|
||||
ParFiniteElementSpace *mfes = nodes->ParFESpace();
|
||||
|
||||
const auto *ir = &IntRules.Get(pmesh.GetTypicalElementGeometry(), q);
|
||||
|
||||
ParGridFunction x(&pfes), y(&pfes), z(&pfes);
|
||||
Vector X(pfes.GetTrueVSize()), Y(pfes.GetTrueVSize()), Z(pfes.GetTrueVSize());
|
||||
|
||||
X.Randomize(1);
|
||||
x.SetFromTrueDofs(X);
|
||||
|
||||
ParBilinearForm blf_fa(&pfes);
|
||||
blf_fa.AddDomainIntegrator(new DiffusionIntegrator(ir));
|
||||
blf_fa.Assemble();
|
||||
blf_fa.Finalize();
|
||||
|
||||
static constexpr int U = 0, Coords = 1;
|
||||
|
||||
const auto solution = std::vector{FieldDescriptor{U, &pfes}};
|
||||
DifferentiableOperator dop(solution, {{Coords, mfes}}, pmesh);
|
||||
|
||||
kernels::MFApply mf_apply_qf;
|
||||
dop.AddDomainIntegrator(mf_apply_qf,
|
||||
tuple{Gradient<U>{}, Gradient<Coords>{}, Weight{}},
|
||||
tuple{Gradient<U>{}}, *ir, all_domain_attr);
|
||||
|
||||
// Use the L-vector interface to multiply
|
||||
dop.SetMultLevel(DifferentiableOperator::MultLevel::LVECTOR);
|
||||
dop.SetParameters({nodes});
|
||||
dop.Mult(x, z);
|
||||
|
||||
blf_fa.Mult(x, y);
|
||||
|
||||
z -= y;
|
||||
REQUIRE(z.Normlinf() == MFEM_Approx(0.0));
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user