Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 82 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)

### Define the project
project(MEPHIT LANGUAGES C CXX Fortran)
include(CTest)

### Define options
option(WITH_MFEM "Compile with MFEM" FALSE)
option(WITH_FORTFEM "Use FortFEM for supported finite-element operations" FALSE)

### Specify paths
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
Expand Down Expand Up @@ -58,11 +60,18 @@ find_package(FFTW REQUIRED COMPONENTS DOUBLE_LIB)

include(ExternalProject)
include(SetupCODE)
include(SetupTriangle)
if(WITH_FORTFEM)
include(SetupFortfem)
else()
include(SetupTriangle)
endif()
if(WITH_MFEM)
include(SetupMFEM)
add_definitions(-DUSE_MFEM)
endif()
if(WITH_FORTFEM)
add_definitions(-DUSE_FORTFEM)
endif()
include(Util)
find_or_fetch(libneo)

Expand Down Expand Up @@ -108,6 +117,9 @@ set(MEPHIT_C_SRC_FILES
src/mephit_fem.c
src/hyper1F1.c
)
if(WITH_FORTFEM)
list(APPEND MEPHIT_C_SRC_FILES src/mephit_fortfem.c)
endif()
set(MEPHIT_CPP_SRC_FILES
src/mephit_fem.cpp
)
Expand All @@ -117,8 +129,15 @@ if(WITH_MFEM)
src/miscellaneous.cpp
)
endif()
set_source_files_properties(src/mephit_run.c ${MEPHIT_C_SRC_FILES} ${MEPHIT_CPP_SRC_FILES}
PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DREAL=double -I${TRIANGLE_INCLUDE_DIR} -I${SUITESPARSE_INCLUDE_DIRS} -L${TRIANGLE_LIB_DIR}")
set(MEPHIT_C_DEPENDENCY_FLAGS "-I${SUITESPARSE_INCLUDE_DIRS}")
if(NOT WITH_FORTFEM)
string(APPEND MEPHIT_C_DEPENDENCY_FLAGS
" -I${TRIANGLE_INCLUDE_DIR} -L${TRIANGLE_LIB_DIR}")
endif()
set_source_files_properties(
src/mephit_run.c ${MEPHIT_C_SRC_FILES} ${MEPHIT_CPP_SRC_FILES}
PROPERTIES COMPILE_FLAGS
"${CMAKE_C_FLAGS} -DREAL=double ${MEPHIT_C_DEPENDENCY_FLAGS}")


### Define library
Expand All @@ -129,28 +148,37 @@ add_library(mephit SHARED
${MEPHIT_C_SRC_FILES}
${MEPHIT_CPP_SRC_FILES}
)
add_dependencies(mephit TRIANGLE)
if(NOT WITH_FORTFEM)
add_dependencies(mephit TRIANGLE)
endif()
target_include_directories(mephit PUBLIC
${magfie_include_dir}
${TRIANGLE_INCLUDE_DIR}
${FFTW_INCLUDE_DIRS}
)
if(NOT WITH_FORTFEM)
target_include_directories(mephit PUBLIC ${TRIANGLE_INCLUDE_DIR})
endif()
set(MEPHIT_LIBS
GSL::gsl
BLAS::BLAS
LAPACK::LAPACK
${FFTW_LIBRARIES}
${triangle_lib}
LIBNEO::magfie
LIBNEO::odeint
LIBNEO::hdf5_tools
)
if(NOT WITH_FORTFEM)
list(APPEND MEPHIT_LIBS ${triangle_lib})
endif()
target_link_libraries(mephit ${MEPHIT_LIBS})
if(LEGACY_SUITESPARSE)
target_link_libraries(mephit ${SUITESPARSE_LIBRARIES})
else()
target_link_libraries(mephit SuiteSparse::umfpack)
endif()
if(WITH_FORTFEM)
target_link_libraries(mephit fortfem::capi)
endif()
if(WITH_MFEM)
add_dependencies(mephit MFEM)
target_include_directories(mephit PUBLIC ${MFEM_INCLUDE_DIRS})
Expand All @@ -165,11 +193,56 @@ target_link_libraries(mephit_run.x mephit)
target_link_libraries(mephit_test.x mephit)
target_link_libraries(mephit_post.x mephit)

if(WITH_FORTFEM AND BUILD_TESTING)
add_executable(test_fortfem_adapter
test/test_fortfem_adapter.c
src/mephit_fortfem.c)
target_include_directories(test_fortfem_adapter PRIVATE src)
target_link_libraries(test_fortfem_adapter PRIVATE fortfem::capi m)
add_test(NAME fortfem_adapter COMMAND test_fortfem_adapter)

add_executable(test_fortfem_production_mesh
test/test_fortfem_production_mesh.c
src/mephit_fortfem.c)
target_include_directories(test_fortfem_production_mesh PRIVATE src)
target_link_libraries(test_fortfem_production_mesh PRIVATE fortfem::capi m)
add_test(
NAME fortfem_production_mesh
COMMAND test_fortfem_production_mesh)

add_executable(test_fortfem_dispatch
test/test_fortfem_dispatch.c)
target_include_directories(test_fortfem_dispatch PRIVATE src)
target_link_libraries(test_fortfem_dispatch PRIVATE mephit)
add_test(NAME fortfem_dispatch COMMAND test_fortfem_dispatch)

add_test(
NAME fortfem_no_daemon
COMMAND
${CMAKE_COMMAND}
-DMEPHIT_RUN=$<TARGET_FILE:mephit_run.x>
-DTEST_TEMP=${PROJECT_BINARY_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/test/test_fortfem_no_daemon.cmake)

add_test(
NAME fortfem_no_triangle
COMMAND
${CMAKE_COMMAND}
-DC_COMPILER=${CMAKE_C_COMPILER}
-DMEPHIT_INCLUDE=${CMAKE_CURRENT_SOURCE_DIR}/src
-DFORTFEM_INCLUDE=$<TARGET_PROPERTY:fortfem::capi,INTERFACE_INCLUDE_DIRECTORIES>
-DMEPHIT_FEM_SOURCE=${CMAKE_CURRENT_SOURCE_DIR}/src/mephit_fem.c
-DTEST_OBJECT=${PROJECT_BINARY_DIR}/test_fortfem_no_triangle.o
-P ${CMAKE_CURRENT_SOURCE_DIR}/test/test_fortfem_no_triangle.cmake)
endif()

### Add helper script to binaries
configure_file(scripts/mephit.bash ${PROJECT_BINARY_DIR}/scripts/mephit.bash @ONLY)
configure_file(scripts/ff-mephit.bash ${PROJECT_BINARY_DIR}/scripts/ff-mephit.bash COPYONLY)
configure_file(scripts/maxwell_daemon.edp ${PROJECT_BINARY_DIR}/scripts/maxwell_daemon.edp COPYONLY)
configure_file(scripts/extmesh.edp ${PROJECT_BINARY_DIR}/scripts/extmesh.edp COPYONLY)
if(NOT WITH_FORTFEM)
configure_file(scripts/ff-mephit.bash ${PROJECT_BINARY_DIR}/scripts/ff-mephit.bash COPYONLY)
configure_file(scripts/maxwell_daemon.edp ${PROJECT_BINARY_DIR}/scripts/maxwell_daemon.edp COPYONLY)
configure_file(scripts/extmesh.edp ${PROJECT_BINARY_DIR}/scripts/extmesh.edp COPYONLY)
endif()
configure_file(scripts/mephit.gdb ${PROJECT_BINARY_DIR}/scripts/mephit.gdb COPYONLY)
configure_file(data/convexwall_asdex.dat ${PROJECT_BINARY_DIR}/data/convexwall_asdex.dat COPYONLY)
configure_file(data/convexwall_kilca.dat ${PROJECT_BINARY_DIR}/data/convexwall_kilca.dat COPYONLY)
Expand Down
31 changes: 25 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ Prerequisites from external sources for running MEPHIT are as follows.
- [SuiteSparse](https://github.com/DrTimothyAldenDavis/SuiteSparse)
- [GSL](https://www.gnu.org/software/gsl/)
- [FFTW3](http://fftw.org/)
- [Triangle](https://www.cs.cmu.edu/~quake/triangle.html)
- [Boost](https://www.boost.org/)
- [FreeFem++](https://github.com/FreeFem/FreeFem-sources)
- [FortFEM](https://github.com/lazy-fortran/fortfem) for the native
finite-element backend
- [Triangle](https://www.cs.cmu.edu/~quake/triangle.html) and
[FreeFem++](https://github.com/FreeFem/FreeFem-sources) only for the legacy
finite-element backend
- [MFEM](https://mfem.org/) is optional
- [zlib](https://zlib.net/) for Fortio's compressed NetCDF-4/HDF5 subset;
Fortio itself is fetched transitively through libneo
Expand All @@ -38,6 +41,21 @@ export MEPHIT_DIR="$(git rev-parse --show-toplevel)/build"
export MEPHIT_RUN_DIR="$(git rev-parse --show-toplevel)/run"
```

To use the native FortFEM backend, configure MEPHIT with:

```bash
cmake -S . -B build \
-DWITH_FORTFEM=ON
cmake --build build
```

The build fetches FortFEM at the pinned revision in
[`cmake/SetupFortfem.cmake`](cmake/SetupFortfem.cmake). For local development,
pass `-DFORTFEM_PATH=/path/to/fortfem`; to use an installed package instead,
pass `-DFORTFEM_FETCH=OFF -DCMAKE_PREFIX_PATH=/path/to/fortfem/install`.
This configuration does not fetch or link Triangle and does not launch
FreeFem++. Omitting `WITH_FORTFEM` retains the legacy backend.

### Coil geometry

In order to use the default configuration in `mephit.in` (see below) for pre-computed Fourier modes for the vacuum field, i.e., `config%vac_src = 2`, you need to generate a coil file once to be used for `config%coil_file`. **Create a namelist file for `coil_field`, like [libneo](https://github.com/itpplasma/libneo)'s `tools/vacfield_AUG.in`**, and run `vacfield.x`. The build fetches and builds libneo from source, so `vacfield.x` is at `$MEPHIT_DIR/libneo/vacfield.x`; set `LIBNEO_DIR` to that directory. To generate the coil file for ASDEX Upgrade at ITPcp, run:
Expand Down Expand Up @@ -101,7 +119,8 @@ Simulations consist of three phases:

Each phase can be run separately by specifying the corresponding command line switch; if none are given, all phases are run by default. For testing and debugging, there are additionally three mutually exclusive flags:

- `--debug` starts a [GDB](https://www.gnu.org/software/gdb) session, using [a script](scripts/mephit.gdb) to navigate to the entry point of the main Fortran subroutine,
- `--debug` starts a [GDB](https://www.gnu.org/software/gdb) session, using
[a script](scripts/mephit.gdb) that stops at the main Fortran subroutine,
- `--memcheck` runs [Valgrind's Memcheck](https://valgrind.org/info/tools.html#memcheck),
- `--test` runs internal tests (expensive, ignores phases).

Expand All @@ -111,9 +130,9 @@ The following files are generated for `mephit*.in`, with `*` a possible suffix:

- `mephit*.h5` contains all relevant numerical results,
- `mephit*.log` contains the text output also displayed on the screen,
- `core_plasma*.msh`, `outer*.msh`, and `maxwell*.msh` contain the meshes for the core plasma, the surrounding elliptical boundary for imposition of boundary conditions, and the union of the two, for use with FreeFem++,
- `edgemap*.dat` contains the mapping of edge degrees of freedom between MEPHIT and FreeFem++,
- `fglut_dump*` contains graphics generated by FreeFem++ which can be viewed with the command `ffglut`.
- legacy-backend runs also produce `core_plasma*.msh`, `outer*.msh`, and
`maxwell*.msh` for FreeFem++, `edgemap*.dat` for edge-degree-of-freedom
transfer, and `fglut_dump*` graphics viewable with `ffglut`.

### Plotting results

Expand Down
2 changes: 1 addition & 1 deletion cmake/SetupCODE.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
# -DLIBNEO_PATH=<dir> local libneo source directory (empty = fetch from git)
# -DTRIANGLE_DIR=<dir> prebuilt Triangle directory (see SetupTriangle)
# -DMFEM_DIR=<dir> prebuilt MFEM directory (see SetupMFEM)
set(LIBNEO_REF "f3f241dea2c7dc25cf29731bb0a1328ff98f48c8" CACHE STRING
set(LIBNEO_REF "f05e4f20ce32dbb0b9e4b5e3c433fe6a2b8ce770" CACHE STRING
"libneo branch, tag, or SHA to fetch")
set(LIBNEO_PATH "" CACHE PATH "local libneo source directory (empty = fetch from git)")
44 changes: 44 additions & 0 deletions cmake/SetupFortfem.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Configure the native FortFEM backend from a reproducible source revision.
# A local source tree is useful for development; disabling the fetch keeps the
# installed-package workflow available for downstream builds.
include(FetchContent)

set(FORTFEM_REF "605dc7f056aa9b15cf8e0673eaa13b13ce12a273" CACHE STRING
"fortfem commit to fetch")
set(FORTFEM_PATH "" CACHE PATH
"local fortfem source directory (empty = fetch or find package)")
option(FORTFEM_FETCH "Fetch the pinned FortFEM source when no local path is set" ON)

if(FORTFEM_PATH)
add_subdirectory(${FORTFEM_PATH} ${CMAKE_CURRENT_BINARY_DIR}/fortfem EXCLUDE_FROM_ALL)
elseif(FORTFEM_FETCH)
if(CMAKE_VERSION VERSION_LESS 3.22)
message(FATAL_ERROR
"WITH_FORTFEM=ON with source fetching requires CMake 3.22 or newer")
endif()
FetchContent_Declare(fortfem
GIT_REPOSITORY https://github.com/lazy-fortran/fortfem.git
GIT_TAG ${FORTFEM_REF}
GIT_SHALLOW FALSE)
FetchContent_MakeAvailable(fortfem)
else()
find_package(fortfem CONFIG REQUIRED)
endif()

if(NOT TARGET fortfem::capi)
message(FATAL_ERROR "FortFEM was configured without the fortfem::capi target")
endif()

# MEPHIT uses -fno-realloc-lhs for its legacy Fortran sources. FortFEM and
# its in-tree FortSparse dependency use standard allocatable assignment, so
# restore the standard GNU behavior for those targets only.
if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
if(TARGET fortfem_capi)
target_compile_options(fortfem_capi PRIVATE
"$<$<COMPILE_LANGUAGE:Fortran>:-frealloc-lhs>")
endif()
if(TARGET fortsparse)
target_compile_options(fortsparse PRIVATE
"$<$<COMPILE_LANGUAGE:Fortran>:-frealloc-lhs>")
endif()
endif()
10 changes: 7 additions & 3 deletions scripts/mephit.bash
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ mephit_run() {
"$config" \
"$suffix" \
"$tmpdir" \
"$scriptdir/ff-mephit.bash" \
"${fem_backend_args[@]}" \
2>&1 | tee -a "$log"
lasterr=$?
;;
Expand All @@ -236,7 +236,7 @@ mephit_run() {
"$config" \
"$suffix" \
"$tmpdir" \
"$scriptdir/ff-mephit.bash"
"${fem_backend_args[@]}"
lasterr=$?
;;
*)
Expand All @@ -245,7 +245,7 @@ mephit_run() {
"$config" \
"$suffix" \
"$tmpdir" \
"$scriptdir/ff-mephit.bash" \
"${fem_backend_args[@]}" \
2>&1 | tee -a "$log"
lasterr=$?
;;
Expand All @@ -269,6 +269,10 @@ scriptdir=$(dirname "$0")
scriptdir=$(realpath "$scriptdir")
bindir=$(realpath -m "$scriptdir/../bin")
datadir=$(realpath -m "$scriptdir/../data")
fem_backend_args=()
if [ "@WITH_FORTFEM@" != "ON" ]; then
fem_backend_args=( "$scriptdir/ff-mephit.bash" )
fi
if [ -d "@tmpdir@" ]; then
tmpdir=@tmpdir@
else
Expand Down
Loading