diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 107cb9efb..0c984a957 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -9,3 +9,6 @@ # apply inifix-format to all .ini files ac260f4af48221229aef4fc1f93ffbf9df450739 1ca7676fee7a578bd64e64ec9b6bdfbceb921775 + +# apply ruff format to all .py files +8d0437bf23d7d8007355fa35b9f094287f7de987 diff --git a/.github/workflows/actions/pre-install-py-packages/action.yml b/.github/workflows/actions/pre-install-py-packages/action.yml new file mode 100644 index 000000000..2be0d7afd --- /dev/null +++ b/.github/workflows/actions/pre-install-py-packages/action.yml @@ -0,0 +1,15 @@ +name: Install python packages + +description: "Action installing the Idefix python packages before running the tests." + +inputs: {} + +runs: + using: "composite" + steps: + - name: Create venv + shell: bash + run: | + python3 -m venv .venv + source .venv/bin/activate + python3 -m pip install -r ./test/python_requirements.txt diff --git a/.github/workflows/idefix-ci-doc.yml b/.github/workflows/idefix-ci-doc.yml index 7422be2f3..2d04e9e4e 100644 --- a/.github/workflows/idefix-ci-doc.yml +++ b/.github/workflows/idefix-ci-doc.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: install doxygen diff --git a/.github/workflows/idefix-ci-jobs.yml b/.github/workflows/idefix-ci-jobs.yml index 847ba3cbe..4c3b54715 100644 --- a/.github/workflows/idefix-ci-jobs.yml +++ b/.github/workflows/idefix-ci-jobs.yml @@ -28,16 +28,18 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: Sod test run: scripts/ci/run-tests $IDEFIX_DIR/test/HD/sod -all $TESTME_OPTIONS - name: Isothermal Sod test run: scripts/ci/run-tests $IDEFIX_DIR/test/HD/sod-iso -all $TESTME_OPTIONS - name: Mach reflection test - run: scripts/ci/run-tests $IDEFIX_DIR/test/HD//MachReflection -all $TESTME_OPTIONS + run: scripts/ci/run-tests $IDEFIX_DIR/test/HD/MachReflection -all $TESTME_OPTIONS - name: Sedov blast wave run: scripts/ci/run-tests $IDEFIX_DIR/test/HD/SedovBlastWave -all $TESTME_OPTIONS @@ -45,10 +47,12 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: Viscous flow past cylinder run: scripts/ci/run-tests $IDEFIX_DIR/test/HD/ViscousFlowPastCylinder -all $TESTME_OPTIONS - name: Viscous disk @@ -60,10 +64,12 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: MHD Sod test run: scripts/ci/run-tests $IDEFIX_DIR/test/MHD/sod -all $TESTME_OPTIONS - name: MHD Isothermal Sod test @@ -81,10 +87,12 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: Ambipolar C Shock run: scripts/ci/run-tests $IDEFIX_DIR/test/MHD/AmbipolarCshock -all $TESTME_OPTIONS - name: Ambipolar C Shock 3D @@ -101,10 +109,12 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: Fargo + planet run: scripts/ci/run-tests $IDEFIX_DIR/test/HD/FargoPlanet -all $TESTME_OPTIONS - name: Fargo MHD spherical @@ -115,10 +125,12 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: Hydro shearing box run: scripts/ci/run-tests $IDEFIX_DIR/test/HD/ShearingBox -all $TESTME_OPTIONS - name: MHD shearing box @@ -129,10 +141,12 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: Jeans Instability run: scripts/ci/run-tests $IDEFIX_DIR/test/SelfGravity/JeansInstability -all $TESTME_OPTIONS - name: Random sphere spherical @@ -149,10 +163,12 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: 3 body run: scripts/ci/run-tests $IDEFIX_DIR/test/Planet/Planet3Body -all $TESTME_OPTIONS - name: migration @@ -171,10 +187,12 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: Energy conservation run: scripts/ci/run-tests $IDEFIX_DIR/test/Dust/DustEnergy -all $TESTME_OPTIONS - name: Dusty wave @@ -185,10 +203,12 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: MTI run: scripts/ci/run-tests $IDEFIX_DIR/test/MHD/MTI -all $TESTME_OPTIONS - name: Spherical anisotropic diffusion @@ -203,10 +223,12 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: Run examples test run: cd test && ./checks_examples.sh $TEST_OPTIONS @@ -215,10 +237,12 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: Lookup table run: scripts/ci/run-tests $IDEFIX_DIR/test/utils/lookupTable -all $TESTME_OPTIONS - name: Dump Image @@ -231,10 +255,12 @@ jobs: runs-on: self-hosted steps: - name: Check out repo - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: recursive persist-credentials: false + - name: Prep python + uses: ./.github/workflows/actions/pre-install-py-packages - name: Restart dumps run: scripts/ci/run-tests $IDEFIX_DIR/test/IO/dump -all $TESTME_OPTIONS - name: Pydefix diff --git a/.github/workflows/idefix-ci.yml b/.github/workflows/idefix-ci.yml index 50fd26eee..8e1a03635 100644 --- a/.github/workflows/idefix-ci.yml +++ b/.github/workflows/idefix-ci.yml @@ -17,14 +17,14 @@ jobs: if: ${{ github.repository == 'idefix-code/idefix' || github.repository == 'glesur/idefix' }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/setup-python@7f4fc3e22c37d6ff65e88745f38bd3157c663f7c # v4.9.1 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: 3.x - - uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 # v3.0.0 - - uses: pre-commit-ci/lite-action@50143aaf27e2c42e75a5e06185a471d9582e89df # v1.0.0 + - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 + - uses: pre-commit-ci/lite-action@5d6cc0eb514c891a40562a58a8e71576c5c7fb43 # v1.1.0 if: always() icc-jobs: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8249b7b03..85672b3c4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,42 +28,40 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.9 + rev: v0.15.8 hooks: - - id: ruff - args: - - --quiet - - --fix - - --select - - F # pyflakes - - B # flake8-bugbear - - I # isort - - NPY # numpy-specific rules - - --ignore - - F405 - - --ignore - - F403 # ignore import * + - id: ruff-format + args: [--target-version=py310] + - id: ruff-check + args: [--target-version=py310, --quiet, --fix, --show-fixes] - - repo: https://github.com/neutrinoceros/inifix - rev: v6.1.2 + - repo: https://github.com/la-niche/inifix-pre-commit + rev: v1.0.0 hooks: - id: inifix-format - files: ^(test/).*\.(ini)$ # want to skip pytest.ini - - - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.5.5 - hooks: - - id: remove-tabs # auto-fix tab/space mixing - - id: insert-license - files: ^(src/).*\.(hpp|cpp)$ - args: - - --license-filepath - - src/license_header.txt - - --comment-style - - // - repo: https://gitlab.com/daverona/pre-commit/cpp rev: 0.8.0 hooks: - id: cpplint args: [--counting=detailed, --exclude=test/*] + + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.38.0 + hooks: + - id: check-jsonschema + files: ^test/.*/testme.json$ + args: ["--schemafile", "pytools/testme.schema.json"] + + - repo: local + hooks: + - id: pytest + name: testme.json validation + entry: ./test.py --validate-testme-jsons + language: python + files: ^test/.*/testme.json$ + pass_filenames: false + additional_dependencies: + - matplotlib >= 3.5.0 + - pytest >= 6.0 + - jsonschema >= 4.26.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bb7f979e..6008ba50b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,37 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.4.0] 2026-09-23 +### Changed + +- bump up Kokkos to 5.1. As a result, Idefix now requires a C++20-compatible compiler (#384) +- improve Kokkos 5 performances on AMD targets (#402) +- make MPI gpu-direct optional with a device-host fallback transfer path (#389) +- refactor communication packing/unpacking in Axis and ConstrainedTransport using Buffer and BoundingBox (#385) +- move CheckNan to the end of loop stages in TimeIntegrator (#403) +- keep inter-cell flux in every direction for analysis (#337) +- update CI/tooling and dependencies (#371,#372,#377,#383,#390,#392,#393,#400) +- update copyright headers across the project (#410) + +### Fixed + +- fix div(B) check robustness (#369) +- fix segfault when using UCT_HLL with DIMENSIONS < 3 (#386) +- fix coarsening + viscosity CFL condition violation (#397) +- fix issues when linking parallel HDF5 with CMake (#391) +- restore Ctrl-C handling when pydefix is active (#388) +- ensure shearing-box tests also analyse magnetic field B (#412) +- fix security settings in CI jobs (#373) + +### Added + +- enable parsing of 1D column data and interpolation in functional space using `LookupTable` (#401) +- add conservation tests to OT and OT3D (#407) +- add/improve `testme.json` validation in tests (#378, #394, #405) +- add documentation for pydefix usage in virtual environments (#365) +- add compiler informations in the logs and in stdout (#402) + + ## [2.3.0] 2026-04-21 ### Changed diff --git a/CMakeLists.txt b/CMakeLists.txt index 6698aaec6..e0206f4d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,32 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file CMakeLists.txt +# +# Last modified : 08/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2026) +# - Soufiane Baghdadi (IPAG/UGA/CNRS - 2021) +# - Alankar Dutta (MPA Garching - 2023 - 2026) +# - Nicolas Aunai (LPP - 2024) +# - Sébastien Valat (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + cmake_minimum_required(VERSION 3.16) if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) endif() -set (CMAKE_CXX_STANDARD 17) +set (CMAKE_CXX_STANDARD 20) set(Idefix_VERSION_MAJOR 2) -set(Idefix_VERSION_MINOR 3) +set(Idefix_VERSION_MINOR 4) set(Idefix_VERSION_PATCH 0) -project (idefix VERSION 2.3.0) +project (idefix VERSION 2.4.0) option(Idefix_MHD "enable MHD" OFF) option(Idefix_MPI "enable Message Passing Interface parallelisation" OFF) option(Idefix_HIGH_ORDER_FARGO "Force Fargo to use a PPM reconstruction scheme" OFF) @@ -16,6 +34,10 @@ option(Idefix_DEBUG "Enable Idefix debug features (makes the code very slow)" OF option(Idefix_RUNTIME_CHECKS "Enable runtime sanity checks" OFF) option(Idefix_WERROR "Treat compiler warnings as errors" OFF) option(Idefix_PYTHON "Enable python bindings (requires pybind11)" OFF) +option(Idefix_MPI_GPU_DIRECT "Enable usage of GPU direct to avoid CPU-GPU copies for MPI messages." ON) +option(Idefix_MPI_GPU_FORCE_COPY "When GPU_DIRECT is disabled, force using transfers for validation purpose." OFF) +mark_as_advanced(Idefix_MPI_GPU_FORCE_TRANSFERS) +option(Idefix_SUPPRESS_FMA "Disable FMA (fused multiply-add) contraction/codegen. Useful for code validation across architectures." OFF) set(Idefix_PROBLEM_DIR "${CMAKE_BINARY_DIR}" CACHE STRING "Problem directory to build for.") set(Idefix_CXX_FLAGS "" CACHE STRING "Additional compiler/linker flag") set(Idefix_DEFS "definitions.hpp" CACHE FILEPATH "Problem definition header file") @@ -35,6 +57,10 @@ set_property(CACHE Idefix_PRECISION PROPERTY STRINGS Double Single) set(Idefix_LOOP_PATTERN "Default" CACHE STRING "Loop pattern for idefix_for") set_property(CACHE Idefix_LOOP_PATTERN PROPERTY STRINGS Default SIMD Range MDRange TeamPolicy TeamPolicyInnerVector) +set(Idefix_MPI_MODE "Persistent" CACHE STRING "MPI communication mode to use.") +set_property(CACHE Idefix_MPI_MODE PROPERTY STRINGS Persistent Blocking NonBlocking) +mark_as_advanced(Idefix_MPI_MODE) + # load git revision tools list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") include(GetGitRevisionDescription) @@ -42,6 +68,8 @@ include(ReplaceIdefixSource) include(AddIdefixSource) include(SetIdefixProperty) include(SetRequiredBuildSettingsForGCC8) +include(CheckHdf5ParallelSupport) +include(SuppressFMA) #Idefix requires Cuda Lambdas (experimental) if(Kokkos_ENABLE_CUDA) @@ -57,6 +85,8 @@ include_directories(${Kokkos_INCLUDE_DIRS_RET}) # Add Idefix CXX Flags add_compile_options(${Idefix_CXX_FLAGS}) + + # Add filesystem libraries for GCC8 set_required_build_settings_for_GCC8() @@ -104,6 +134,10 @@ if(Idefix_MPI) add_subdirectory(src/mpi) endif() +if (Idefix_MPI_GPU_DIRECT) + add_compile_definitions("WITH_MPI_GPU_DIRECT") +endif() + if(Idefix_HDF5) add_compile_definitions("WITH_HDF5") if(Idefix_MPI) @@ -113,12 +147,25 @@ if(Idefix_HDF5) PUBLIC src/output/xdmf.cpp PUBLIC src/output/xdmf.hpp ) - find_package(HDF5 REQUIRED) - target_link_libraries(idefix "${HDF5_LIBRARIES}") + # Prefer imported targets (matches older working behavior), then fall back. + find_package(HDF5 QUIET COMPONENTS C) + if(NOT HDF5_FOUND) + find_package(HDF5 REQUIRED MODULE COMPONENTS C) + endif() + + set(_idefix_hdf5_link_items "${HDF5_LIBRARIES}") + if(TARGET hdf5::hdf5) + set(_idefix_hdf5_link_items hdf5::hdf5) + elseif(TARGET HDF5::HDF5) + set(_idefix_hdf5_link_items HDF5::HDF5) + endif() + + target_link_libraries(idefix ${_idefix_hdf5_link_items}) message(STATUS "Found HDF5 include directories: ${HDF5_INCLUDE_DIRS}") target_include_directories(idefix PUBLIC "${HDF5_INCLUDE_DIRS}") if(Idefix_MPI) - if(NOT HDF5_IS_PARALLEL) + CheckHdf5ParallelSupport("${_idefix_hdf5_link_items}") + if(NOT IDEFIX_HDF5_IS_PARALLEL) message(FATAL_ERROR "Parallel HDF5 required for Idefix_MPI but the found HDF5 library does not support it") endif() endif() @@ -167,15 +214,15 @@ endif() if(Idefix_EVOLVE_VECTOR_POTENTIAL) add_compile_definitions("EVOLVE_VECTOR_POTENTIAL") endif() -#update version.hpp if possible + +# determine idefix version from git git_describe(GIT_SHA1) set(Idefix_VERSION ${Idefix_VERSION_MAJOR}.${Idefix_VERSION_MINOR}.${Idefix_VERSION_PATCH}-${GIT_SHA1}) -file(WRITE ${CMAKE_SOURCE_DIR}/src/version.hpp "#define IDEFIX_GIT_COMMIT \"${GIT_SHA1}\"\n") -file(APPEND ${CMAKE_SOURCE_DIR}/src/version.hpp "#define IDEFIX_VERSION_MAJOR \"${Idefix_VERSION_MAJOR}\"\n") -file(APPEND ${CMAKE_SOURCE_DIR}/src/version.hpp "#define IDEFIX_VERSION_MINOR \"${Idefix_VERSION_MINOR}\"\n") -file(APPEND ${CMAKE_SOURCE_DIR}/src/version.hpp "#define IDEFIX_VERSION_PATCH \"${Idefix_VERSION_PATCH}\"\n") -file(APPEND ${CMAKE_SOURCE_DIR}/src/version.hpp "#define IDEFIX_VERSION \"${Idefix_VERSION}\"\n") - +configure_file( + ${CMAKE_SOURCE_DIR}/src/version.h.in + ${CMAKE_BINARY_DIR}/build/generated/version.h + @ONLY +) if(NOT ${Idefix_DEFS} STREQUAL "definitions.hpp") add_compile_definitions("DEFINITIONS_FILE=\"${Idefix_DEFS}\"") @@ -227,6 +274,20 @@ if(${Idefix_PRECISION} STREQUAL "Single") add_compile_definitions("SINGLE_PRECISION") endif() +# MPI mode +if(${Idefix_MPI_MODE} STREQUAL "Persistent") + add_compile_definitions("COMMUNICATION_MODE_PERSISTENT") +elseif(${Idefix_MPI_MODE} STREQUAL "NonBlocking") + add_compile_definitions("COMMUNICATION_MODE_NON_BLOCKING") +else(NOT ${Idefix_MPI_MODE} STREQUAL "Blocking") + message(ERROR "Unknown MPI communication mode : Idefix_MPI_MODE=${Idefix_MPI_MODE}") +endif() + +# GPU direct disabled and force transfers +if (${Idefix_MPI_GPU_FORCE_COPY}) + add_compile_definitions("WITH_GPU_FORCE_COPY") +endif() + target_include_directories(idefix PUBLIC "${Idefix_PROBLEM_DIR_ABS}" ) @@ -255,6 +316,21 @@ target_include_directories(idefix PUBLIC target_link_libraries(idefix Kokkos::kokkos) +# Generate header with compiler information (name, flags, path) +configure_file( + ${CMAKE_SOURCE_DIR}/src/compiler_info.h.in + ${CMAKE_BINARY_DIR}/build/generated/compiler_info.h + @ONLY +) +# Make sure the generated header is on the include path +target_include_directories(idefix PRIVATE ${CMAKE_BINARY_DIR}/build/generated) + +# disable FMA if needed +if(Idefix_SUPPRESS_FMA) + message(STATUS "FMA (fused multiply-add) contraction/codegen is disabled") + target_suppress_fma(idefix) +endif() + message(STATUS "Idefix final configuration") if(Idefix_EVOLVE_VECTOR_POTENTIAL) message(STATUS " MHD: ${Idefix_MHD} (Vector potential)") @@ -264,6 +340,7 @@ endif() message(STATUS " MPI: ${Idefix_MPI}") message(STATUS " HDF5: ${Idefix_HDF5}") message(STATUS " Python: ${Idefix_PYTHON}") +message(STATUS " GPU direct: ${Idefix_MPI_GPU_DIRECT}") message(STATUS " Reconstruction: ${Idefix_RECONSTRUCTION}") message(STATUS " Precision: ${Idefix_PRECISION}") message(STATUS " Version: ${Idefix_VERSION}") diff --git a/README.md b/README.md index 92e3e79da..b0857abdc 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ What is Idefix? --------------- -Idefix is a computational fluid dynamics code based on a finite-volume high-order Godunov method, originally designed for astrophysical fluid dynamics applications. Idefix is designed to be performance-portable, and uses the [Kokkos](https://github.com/kokkos/kokkos) framework to achieve this goal. This means that it can run both on your laptop's cpu and on the largest GPU Exascale clusters. More technically, Idefix can run in serial, use OpenMP and/or MPI (message passing interface) for parallelization, and use GPU acceleration when available (based on Nvidia Cuda, AMD HIP, etc...). All these capabilities are embedded within one single code, so the code relies on relatively abstracted classes and objects available in C++17, which are not necessarily +Idefix is a computational fluid dynamics code based on a finite-volume high-order Godunov method, originally designed for astrophysical fluid dynamics applications. Idefix is designed to be performance-portable, and uses the [Kokkos](https://github.com/kokkos/kokkos) framework to achieve this goal. This means that it can run both on your laptop's cpu and on the largest GPU Exascale clusters. More technically, Idefix can run in serial, use OpenMP and/or MPI (message passing interface) for parallelization, and use GPU acceleration when available (based on Nvidia Cuda, AMD HIP, etc...). All these capabilities are embedded within one single code, so the code relies on relatively abstracted classes and objects available in C++20, which are not necessarily familiar to astrophysicists. A large effort has been devoted to simplify this level of abstraction so that the code can be modified by researchers and students familiar with C and who are aware of basic object-oriented concepts. diff --git a/cmake/AddIdefixSource.cmake b/cmake/AddIdefixSource.cmake index 8991e4907..328ddcb0c 100644 --- a/cmake/AddIdefixSource.cmake +++ b/cmake/AddIdefixSource.cmake @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file cmake/AddIdefixSource.cmake +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + function(add_idefix_source _new_source) message(STATUS " Adding problem-specific source file ${_new_source}") target_sources(idefix PUBLIC ${_new_source}) diff --git a/cmake/CheckHdf5ParallelSupport.cmake b/cmake/CheckHdf5ParallelSupport.cmake new file mode 100644 index 000000000..262d086cd --- /dev/null +++ b/cmake/CheckHdf5ParallelSupport.cmake @@ -0,0 +1,64 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file cmake/CheckHdf5ParallelSupport.cmake +# +# Last modified : 08/2026 +# +# Copyright(C) by : +# - Alankar Dutta (MPA Garching - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + +include(CheckCSourceCompiles) + +# Check whether the HDF5 library found by find_package(HDF5) supports parallel +# (MPI-IO) access, and store the result in IDEFIX_HDF5_IS_PARALLEL in the +# caller's scope. +# +# Usage: CheckHdf5ParallelSupport() +# where is the list of HDF5 targets/libraries to link against. +# +# Some CMake/HDF5 combinations do not reliably set HDF5_IS_PARALLEL (e.g. when +# HDF5 is found via its CMake config package rather than the FindHDF5 module). +# Combine metadata checks with a compile+link probe for the MPI-IO symbols to +# reliably detect parallel HDF5. +function(CheckHdf5ParallelSupport hdf5_link_items) + set(_idefix_hdf5_is_parallel FALSE) + if(HDF5_IS_PARALLEL OR HDF5_C_IS_PARALLEL) + set(_idefix_hdf5_is_parallel TRUE) + endif() + + if(NOT _idefix_hdf5_is_parallel AND DEFINED HDF5_C_COMPILER_EXECUTABLE) + execute_process( + COMMAND "${HDF5_C_COMPILER_EXECUTABLE}" -showconfig + OUTPUT_VARIABLE _idefix_hdf5_showconfig + ERROR_QUIET + ) + if(_idefix_hdf5_showconfig MATCHES "Parallel HDF5:[ \t]*yes") + set(_idefix_hdf5_is_parallel TRUE) + endif() + endif() + + set(CMAKE_REQUIRED_INCLUDES ${HDF5_INCLUDE_DIRS} ${MPI_C_INCLUDE_DIRS}) + set(CMAKE_REQUIRED_LIBRARIES ${hdf5_link_items} MPI::MPI_C) + check_c_source_compiles( + "#include + #include + int main(void) { + hid_t plist = H5Pcreate(H5P_FILE_ACCESS); + H5Pset_fapl_mpio(plist, MPI_COMM_WORLD, MPI_INFO_NULL); + H5Pclose(plist); + return 0; + }" + IDEFIX_HDF5_HAS_MPI_IO + ) + + if(IDEFIX_HDF5_HAS_MPI_IO) + set(_idefix_hdf5_is_parallel TRUE) + endif() + + set(IDEFIX_HDF5_IS_PARALLEL ${_idefix_hdf5_is_parallel} PARENT_SCOPE) +endfunction() diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake index 81b5844be..0999f53bc 100644 --- a/cmake/GetGitRevisionDescription.cmake +++ b/cmake/GetGitRevisionDescription.cmake @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file cmake/GetGitRevisionDescription.cmake +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # - Returns a version string from Git # # These functions force a re-configure on each git commit so that you can diff --git a/cmake/GetGitRevisionDescription.cmake.in b/cmake/GetGitRevisionDescription.cmake.in index 66eee6377..1eee216c8 100644 --- a/cmake/GetGitRevisionDescription.cmake.in +++ b/cmake/GetGitRevisionDescription.cmake.in @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file cmake/GetGitRevisionDescription.cmake.in +# +# Last modified : 08/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # # Internal file for GetGitRevisionDescription.cmake # diff --git a/cmake/ReplaceIdefixSource.cmake b/cmake/ReplaceIdefixSource.cmake index 80000b0b3..d48f4cbab 100644 --- a/cmake/ReplaceIdefixSource.cmake +++ b/cmake/ReplaceIdefixSource.cmake @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file cmake/ReplaceIdefixSource.cmake +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + function(replace_idefix_source _old_source _new_source) get_target_property(fullsource idefix SOURCES) list(FILTER fullsource INCLUDE REGEX ${_old_source}) diff --git a/cmake/SetIdefixProperty.cmake b/cmake/SetIdefixProperty.cmake index 22c77c10c..dc32c5605 100644 --- a/cmake/SetIdefixProperty.cmake +++ b/cmake/SetIdefixProperty.cmake @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file cmake/SetIdefixProperty.cmake +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + function(set_idefix_property _property_name _property_value) message(STATUS " Explicitely setting ${_property_name} = ${_property_value}") set(${_property_name} ${_property_value} CACHE STRING "Overridden by custom setup in CMakeLists.txt" FORCE) diff --git a/cmake/SetRequiredBuildSettingsForGCC8.cmake b/cmake/SetRequiredBuildSettingsForGCC8.cmake index bb389298a..852fc0a4c 100644 --- a/cmake/SetRequiredBuildSettingsForGCC8.cmake +++ b/cmake/SetRequiredBuildSettingsForGCC8.cmake @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file cmake/SetRequiredBuildSettingsForGCC8.cmake +# +# Last modified : 11/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # The std::filesystem functions are part of the C++17 standard, but GCC8 # does not store them in libstdc++ but in libstdc++-fs. This function # ensure that we link to this additional library when using GCC8 diff --git a/cmake/SuppressFMA.cmake b/cmake/SuppressFMA.cmake new file mode 100644 index 000000000..e22399703 --- /dev/null +++ b/cmake/SuppressFMA.cmake @@ -0,0 +1,116 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file cmake/SuppressFMA.cmake +# +# Last modified : 08/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + +#[[============================================================================ + SuppressFMA.cmake + + Provides an option and a function to optionally disable fused + multiply-add (FMA) code generation / contraction for a Kokkos-based CXX + target. + + Kokkos wraps the real device compiler behind nvcc_wrapper (CUDA) or + hipcc (HIP), which makes CMAKE_CXX_COMPILER_ID report the *underlying + host* compiler (e.g. "GNU" or "Clang") instead of "NVIDIA" or "Clang + as HIP". Backend detection therefore relies on the Kokkos_ENABLE_* + variables exported by KokkosConfig.cmake / set by the Kokkos build, + and only falls back to CMAKE_CXX_COMPILER_ID for the plain host + compilers (no CUDA/HIP backend active): + + - Kokkos_ENABLE_HIP ON -> AMD HIP (hipcc, clang-based) : -ffp-contract=off + - Kokkos_ENABLE_CUDA ON -> NVIDIA nvcc (via nvcc_wrapper) : --fmad=false + - otherwise, CMAKE_CXX_COMPILER_ID selects among: + GNU : gcc/g++ + Intel : classic icc/icpc + IntelLLVM : Intel oneAPI icx/icpx + Clang : LLVM clang++ + AppleClang : Xcode clang++ + NVHPC : NVIDIA HPC SDK (nvc++), e.g. for OpenMPTarget/OpenACC + + Usage (after find_package(Kokkos) so Kokkos_ENABLE_* are defined): + include(SuppressFMA.cmake) + add_library(mylib source.cpp) + target_link_libraries(mylib PUBLIC Kokkos::kokkos) + target_suppress_fma(mylib) + +============================================================================]] + +include_guard(GLOBAL) + +# Determine the CXX FMA-suppression flags for the active Kokkos backend / +# CXX compiler. Returns the list of flags (possibly empty) via out_var. +function(_fma_suppression_flags_cxx out_var) + set(flags "") + set(id "${CMAKE_CXX_COMPILER_ID}") + + # Kokkos backend takes priority: nvcc_wrapper/hipcc hide the real + # device compiler from CMAKE_CXX_COMPILER_ID. + if(Kokkos_ENABLE_HIP) + set(flags "-ffp-contract=off") + + elseif(Kokkos_ENABLE_CUDA) + set(flags "--fmad=false") + + elseif(id STREQUAL "GNU") + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag("-mno-fma" IDEFIX_HAS_MNO_FMA) + set(flags "-ffp-contract=off") + if(IDEFIX_HAS_MNO_FMA) + list(APPEND flags "-mno-fma") + endif() + elseif(id MATCHES "^(Clang|AppleClang|CrayClang)$") + set(flags "-ffp-contract=off") + + elseif(id STREQUAL "Intel") + # Intel classic compiler + set(flags "-fp-model=precise" "-no-fma") + + elseif(id STREQUAL "IntelLLVM") + # Intel oneAPI compiler (clang-based) + set(flags "-ffp-contract=off" "-fp-model=strict") + + elseif(id STREQUAL "NVHPC") + # NVIDIA HPC SDK (formerly PGI), e.g. OpenMPTarget/OpenACC backend + set(flags "-Mnofma") # untested + endif() + + set(${out_var} "${flags}" PARENT_SCOPE) +endfunction() + +# target_suppress_fma() +# +# Applies compiler-specific FMA-suppression flags to 's CXX +# sources, but only when the SUPPRESS_FMA option is ON. Safe to call +# unconditionally. +function(target_suppress_fma target) + + if(NOT TARGET ${target}) + message(FATAL_ERROR "target_suppress_fma: '${target}' is not a target") + endif() + + _fma_suppression_flags_cxx(cxx_flags) + + if(cxx_flags) + foreach(flag IN LISTS cxx_flags) + target_compile_options(${target} PRIVATE + $<$:${flag}> + ) + endforeach() + else() + message(VERBOSE + "target_suppress_fma: no FMA-suppression flag known for " + "CXX compiler '${CMAKE_CXX_COMPILER_ID}' " + "(Kokkos_ENABLE_CUDA=${Kokkos_ENABLE_CUDA}, " + "Kokkos_ENABLE_HIP=${Kokkos_ENABLE_HIP}) (target ${target})") + endif() +endfunction() diff --git a/doc/Makefile b/doc/Makefile index d0c3cbf10..ac6f669e8 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file doc/Makefile +# +# Last modified : 09/2020 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # Minimal makefile for Sphinx documentation # diff --git a/doc/python_requirements.txt b/doc/python_requirements.txt index 28715fb71..991631e87 100644 --- a/doc/python_requirements.txt +++ b/doc/python_requirements.txt @@ -1,5 +1,5 @@ # Other requirements -# Python >= 3.7 +# Python >= 3.10 # Doxygen https://www.doxygen.nl/download.html # # Install Sphinx and required plugins with the following command diff --git a/doc/source/_static/my_theme.css b/doc/source/_static/my_theme.css index 827056226..961556641 100644 --- a/doc/source/_static/my_theme.css +++ b/doc/source/_static/my_theme.css @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file doc/source/_static/my_theme.css +// +// Last modified : 04/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + .wy-nav-content { max-width: 1024px !important; } diff --git a/doc/source/conf.py b/doc/source/conf.py index f47f6659c..e0598f65f 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -1,3 +1,18 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file doc/source/conf.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full @@ -18,13 +33,12 @@ # -- Project information ----------------------------------------------------- -project = 'Idefix' -copyright = 'Geoffroy Lesur et al.' -author = 'Geoffroy Lesur' +project = "Idefix" +copyright = "The Idefix Code contributors" +author = "Geoffroy Lesur" # The full version, including alpha/beta/rc tags -release = '2.3.0' - +release = "2.4.0" # -- General configuration --------------------------------------------------- @@ -34,20 +48,24 @@ # ones. extensions = [ "sphinx_rtd_theme", - 'sphinx_git', - 'matplotlib.sphinxext.plot_directive', + "sphinx_git", + "matplotlib.sphinxext.plot_directive", "breathe", "exhale", "m2r2", - "sphinx_copybutton" - ] + "sphinx_copybutton", +] source_suffix = [".rst", ".md"] -cpp_id_attributes=["KOKKOS_FORCEINLINE_FUNCTION","KOKKOS_INLINE_FUNCTION","KOKKOS_RESTRICT"] +cpp_id_attributes = [ + "KOKKOS_FORCEINLINE_FUNCTION", + "KOKKOS_INLINE_FUNCTION", + "KOKKOS_RESTRICT", +] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -60,45 +78,48 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] + def setup(app): - app.add_css_file('my_theme.css') + app.add_css_file("my_theme.css") + ############## # Breathe/Exhale options # Setup the breathe extension breathe_projects = { - "Idefix": "./xml" + "Idefix": "./xml", } breathe_default_project = "Idefix" # Setup the exhale extension exhale_args = { # These arguments are required - "containmentFolder": "./api", - "rootFileName": "library_root.rst", - "rootFileTitle": "Idefix API", + "containmentFolder": "./api", + "rootFileName": "library_root.rst", + "rootFileTitle": "Idefix API", # Suggested optional arguments - "createTreeView": False, + "createTreeView": False, # TIP: if using the sphinx-bootstrap-theme, you need # "treeViewIsBootstrap": True, "doxygenStripFromPath": "../../src", "exhaleExecutesDoxygen": True, - "exhaleDoxygenStdin": textwrap.dedent(''' + "exhaleDoxygenStdin": textwrap.dedent(""" INPUT = ../../src EXCLUDE = ../../src/kokkos - ''') + EXCLUDE += ../../src/kokkos-fft + """), } # Tell sphinx what the primary language being documented is. -primary_domain = 'cpp' +primary_domain = "cpp" # Tell sphinx what the pygments highlight language should be. -highlight_language = 'cpp' +highlight_language = "cpp" diff --git a/doc/source/faq.rst b/doc/source/faq.rst index 4dd198318..c1df8bdb9 100644 --- a/doc/source/faq.rst +++ b/doc/source/faq.rst @@ -27,6 +27,9 @@ I have a complex setup, and have written some functions in separate .cpp files. I want to run on the GPUs of xxx machine, how do I proceed? Check the examples in :ref:`setupExamples` +I don't have a CUDA or HIP aware MPI with GPU DIRECT support, how I can run *Idefix* ? + You can look at the compile option `-DIdefix_MPI_GPU_DIRECT=OFF` in :ref:`makefile` to disable GPU DIRECT usage. Note that this will decrease performances. + Compilation ----------- diff --git a/doc/source/index.rst b/doc/source/index.rst index d36ab39be..527689cfb 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -20,21 +20,21 @@ algorithm is essentially the same (but with some major modification to its struc ================ Requirements ================ -*Idefix* is written is standard C++17 and does not rely on any external library in serial (non MPI). +*Idefix* is written in standard C++20 and does not rely on any external library in serial (non MPI). Compiler - *Idefix* requires a C++17 compatible compiler. It has been tested successfully with GCC (>8), Intel compiler suite (>2018) and - Clang on both Intel and AMD CPUs. *Idefix* has also been tested on NVIDIA GPUs (Pascal, Volta and Ampere architectures) using the nvcc (>10) compiler, and on AMD GPUs (Radeon Mi50, Mi210, Mi250) using the hipcc compiler. + *Idefix* requires a C++20 compatible compiler. It has been tested successfully with GCC (>11), Intel compiler suite (>2022) and + Clang on both Intel and AMD CPUs. *Idefix* has also been tested on NVIDIA GPUs (Pascal, Volta and Ampere architectures) using the nvcc (>12) compiler, and on AMD GPUs (Radeon Mi50, Mi210, Mi250, Mi300) using the hipcc compiler. Kokkos library *Idefix* relies internally on the `Kokkos `_ library, which is bundled with *Idefix* as a git submodule and compiled on the fly, hence no external installation is required. MPI library - When using MPI parallelisation, *Idefix* relies on an external MPI library. *Idefix* has been tested successfully with OpenMPI and IntelMPI libraries. When used on GPU architectures, *Idefix* assumes that - the MPI library is GPU-Aware. If unsure, check this last point with your system administrator. + When using MPI parallelisation, *Idefix* relies on an external MPI library. *Idefix* has been tested successfully with OpenMPI, Mpich and IntelMPI libraries. When used on GPU architectures, *Idefix* assumes that + the MPI library is GPU-Aware by default. It is possible to fallback to a non-GPU-Aware mode if needed (check :ref:`configurationOptions`), at the cost of lower performances. If unsure, check this with your system administrator. Python - When using *Idefix* with its python interface through the module `Pydefix`, *Idefix* relies on an external python>=3.8 interpreter with the module `pybind11 `_ + When using *Idefix* with its python interface through the module `Pydefix`, *Idefix* relies on an external python>=3.10 interpreter with the module `pybind11 `_ installed. ================ @@ -90,6 +90,9 @@ Jean Kempf, Victor Reville, François Rincon Marc Coiffier Continuous integration, automatic benchmarking +Sébastien Valat + Continuous integration, MPI fallback + ======================== About this documentation ======================== diff --git a/doc/source/modules/pydefix.rst b/doc/source/modules/pydefix.rst index 0a8daf753..d02f34fa8 100644 --- a/doc/source/modules/pydefix.rst +++ b/doc/source/modules/pydefix.rst @@ -16,7 +16,7 @@ Before you start Pybind11 installation +++++++++++++++++++++ -In order to use pydefix, you need to be working in a python>=3.8 environement that includes `pybind11 `_. Follow the instruction of your package manager to install pybind11>=2.12. +In order to use pydefix, you need to be working in a python>=3.10 environment that includes `pybind11 `_. Follow the instructions of your package manager to install pybind11>=2.12. Pydefix usage ------------- @@ -104,6 +104,9 @@ The python script `pydefix_example.py` initializes the initial condition of the Troubleshooting --------------- +Pybind11 not found by cmake +++++++++++++++++++++++++++++ + It during configuration stage, you get:: CMake Error at CMakeLists.txt:122 (find_package): @@ -125,3 +128,19 @@ You can then exit the interpreter and set the pybind11_DIR environement variable export pybind11_DIR=env/lib/python3.10/site-packages/pybind11 you can then run cmake which should be able to find pybind11, and compile the code. + +Using pydefix in a virtual environment ++++++++++++++++++++++++++++++++++++++++ +If you use pydefix in a python virtual environment (venv), pydefix might not detect your environment and fail to find pybind11 or other +python packages in your venv. This typically results in a python error "xxxx module not found" when you run Idefix with pydefix. + +The fix is to force the following environement variables (replace XX by your python version) before launching Idefix: + +```bash +export PYTHONPATH=$(python3 -c "import sys; print(':'.join(x for x in sys.path if x))") +``` + +.. warning:: + This is a dirty patch to fix an issue actually caused by pybind11. A better solution would be to fix pybind11 to properly detect virtual environments. + Note that you *should never* set the PYTHONPATH variable globally in your system (i.e. in .bashrc), but only in the terminal where you launch Idefix with pydefix. + The reader may check the dedicated `pydefix PR for details `_. diff --git a/doc/source/plot_idefix_bench.py b/doc/source/plot_idefix_bench.py index 43482eb04..1d8896523 100644 --- a/doc/source/plot_idefix_bench.py +++ b/doc/source/plot_idefix_bench.py @@ -1,25 +1,43 @@ -import matplotlib.pyplot as plt +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file doc/source/plot_idefix_bench.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Marc Coiffier (IPAG/UGA/CNRS - 2025) +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + import json +import matplotlib.pyplot as plt + + def do_plot(title, bench_file, gpumodels): - with open(bench_file, 'r') as f: + with open(bench_file, "r") as f: benches = json.load(f) plt.figure() - xmax=0 - ymax=0 + xmax = 0 + ymax = 0 for gpumodel in gpumodels: - select = [bench for bench in benches if bench['gpumodel'] == gpumodel][-1] + select = [bench for bench in benches if bench["gpumodel"] == gpumodel][-1] - xs = [r['nbgpu'] for r in select['results']] - ys = [r['cell_updates'] for r in select['results']] - plt.plot(xs, ys,'o-',label=gpumodel) - xmax=max(xmax,max(xs)) - ymax=max(ymax,max(ys)) + xs = [r["nbgpu"] for r in select["results"]] + ys = [r["cell_updates"] for r in select["results"]] + plt.plot(xs, ys, "o-", label=gpumodel) + xmax = max(xmax, max(xs)) + ymax = max(ymax, max(ys)) plt.xscale("log", base=2) - plt.ylim(0,ymax*1.1) - plt.xlim(1,xmax*1.1) + plt.ylim(0, ymax * 1.1) + plt.xlim(1, xmax * 1.1) plt.legend() plt.xlabel("Number of GPUs/GCDs") plt.ylabel("Performance (cells / second / GPU)") diff --git a/doc/source/programmingguide.rst b/doc/source/programmingguide.rst index 4bd7c69f7..d8f989df7 100644 --- a/doc/source/programmingguide.rst +++ b/doc/source/programmingguide.rst @@ -355,13 +355,13 @@ fills the following arrays (essentially grid information) with data from its par .. code-block:: c++ - IdefixArray1D::HostMirror x[3]; // geometrical central points - IdefixArray1D::HostMirror xr[3]; // cell right interface - IdefixArray1D::HostMirror xl[3]; // cell left interface - IdefixArray1D::HostMirror dx[3]; // cell width + IdefixArray1D::host_mirror_type x[3]; // geometrical central points + IdefixArray1D::host_mirror_type xr[3]; // cell right interface + IdefixArray1D::host_mirror_type xl[3]; // cell left interface + IdefixArray1D::host_mirror_type dx[3]; // cell width - IdefixArray3D::HostMirror dV; // cell volume - IdefixArray3D::HostMirror A[3]; // cell right interface area + IdefixArray3D::host_mirror_type dV; // cell volume + IdefixArray3D::host_mirror_type A[3]; // cell right interface area Note however that the physics arrays are not automatically synchronized when ``DataBlockHost`` is @@ -369,17 +369,17 @@ created, that is: .. code-block:: c++ - IdefixArray4D::HostMirror Vc; // Main cell-centered primitive variables index - IdefixArray4D::HostMirror Vs; // Main face-centered primitive variables index - IdefixArray4D::HostMirror J; // Current (only when haveCurrent is enabled) - IdefixArray4D::HostMirror Uc; // Main cell-centered conservative variables - IdefixArray3D::HostMirror InvDt; + IdefixArray4D::host_mirror_type Vc; // Main cell-centered primitive variables index + IdefixArray4D::host_mirror_type Vs; // Main face-centered primitive variables index + IdefixArray4D::host_mirror_type J; // Current (only when haveCurrent is enabled) + IdefixArray4D::host_mirror_type Uc; // Main cell-centered conservative variables + IdefixArray3D::host_mirror_type InvDt; - IdefixArray3D::HostMirror Ex1; // x1 electric field - IdefixArray3D::HostMirror Ex2; // x2 electric field - IdefixArray3D::HostMirror Ex3; // x3 electric field + IdefixArray3D::host_mirror_type Ex1; // x1 electric field + IdefixArray3D::host_mirror_type Ex2; // x2 electric field + IdefixArray3D::host_mirror_type Ex3; // x3 electric field -need to be synchronized *manually*. These IdefixArrays are all defined as ``HostMirror``, implying that they are accessible +need to be synchronized *manually*. These IdefixArrays are all defined as ``host_mirror_type``, implying that they are accessible from the host only. If modifications are performed on the arrays of the parent ``DataBlock``, one can call ``DataBlockHost::SyncFromDevice()`` to refresh the host arrays, and inversely one can call ``DataBlockHost::SyncToDevice()`` to send data from ``DataBlockHost`` @@ -489,7 +489,36 @@ For the CSV constructor, ``nDim`` can only have the values 1 or 2. .. note:: The input CSV file is allowed to contain comments, starting with "#". Any character following - "#" is ignored by the ``LookupTable`` class. + "#" is ignored by the ``LookupTable`` class. Hence, a line starting with "#" is entirely ignored, + and so are empty lines and lines made only of white spaces. Comments and blank lines can therefore + be inserted anywhere in the file, including before the first line of the table. + +By default, the coordinates and the data are read as *lines* of the CSV file, as in the examples above. For 1D lookup +tables, they can also be read as *columns* of the CSV file, using the optional argument ``readColumns`` of the constructor: + +.. code-block:: c++ + + template + LookupTable::LookupTable(std::string filename, char delimiter, + bool errorIfOutOfBound, bool readColumns); + +With ``readColumns=true``, the 1D lookup table is read from the two first columns of the file, the first one +giving the coordinates and the second one the data: + +.. list-table:: example1D_col.csv + :widths: 25 25 + :header-rows: 0 + + * - x\ :sub:`1` + - data\ :sub:`1` + * - x\ :sub:`2` + - data\ :sub:`2` + * - x\ :sub:`3` + - data\ :sub:`3` + +.. note:: + ``readColumns`` is only available for 1D lookup tables. 2D lookup tables are always read as lines, + following the layout of ``example2D.csv`` above. Numpy constructor @@ -507,6 +536,60 @@ the constructor expects a vector of size ``nDim`` of .npy files for the 1D coord Note that the template parameter ``nDim`` should match the number of dimensions of the numpy array stored in the file ``dataSet``. +Interpolation in function space ++++++++++++++++++++++++++++++++ + +By default, ``LookupTable`` performs a multi-linear interpolation directly on the coordinates ``x`` and the data +of the table. For data spanning several orders of magnitude (cooling tables, opacity tables, etc...), it is often +more accurate to interpolate the data in *function space*, i.e. to interpolate ``func(data)`` as a function of +``func(x)``, and to transform the interpolated value back with the inverse function ``invFunc``. This is enabled with +the optional argument ``interpolateInFuncSpace`` accepted by each of the constructors: + +.. code-block:: c++ + + // 1D CSV table read as columns, interpolated in log space + LookupTable<1> table("cooling.csv", ',', true, true, true); + + // 3D numpy table, interpolated in log space + LookupTable<3> tablenpy(coordinates, "data.npy", true, true); + +When this option is enabled, ``func`` is applied to the coordinates and to the data when the table is constructed +(so that ``xinHost``, ``xinDev``, ``dataHost`` and ``dataDev`` all store transformed values), the interpolation is +performed in that space, and ``Get`` and ``GetHost`` return ``invFunc`` of the interpolated value. The coordinates +passed to ``Get`` and ``GetHost``, as well as the value they return, are therefore always expressed in the original +(untransformed) space. + +``func`` and ``invFunc`` default to the natural logarithm and the exponential (the functors ``LookupTableLog`` and +``LookupTableExp``). They can be changed when the lookup table is created, using the two optional template parameters +of ``LookupTable``, which expect functors defining ``operator()(const real)``. This operator should be decorated with +``KOKKOS_INLINE_FUNCTION``, so that the transformation can be used both on the host and on the device: + +.. code-block:: c++ + + // A user-defined transformation and its inverse + struct MyLog10 { + KOKKOS_INLINE_FUNCTION real operator() (const real x) const { + return(log10(x)); + } + }; + + struct MyPow10 { + KOKKOS_INLINE_FUNCTION real operator() (const real x) const { + return(pow(10.0,x)); + } + }; + + // A 1D CSV table interpolated in log10 space + LookupTable<1, MyLog10, MyPow10> table("cooling.csv", ',', true, true, true); + +Instances of these functors can also be given as the last two arguments of the constructors, which is useful when the +transformation carries a state (e.g. a tunable exponent). + +.. warning:: + The transformation is applied to every coordinate and to every element of the data. Since the default transformation + is the natural logarithm, the whole table should be strictly positive when the default ``func`` is used, otherwise + ``LookupTable`` triggers an error while it is being constructed. + Using the lookup table ++++++++++++++++++++++ @@ -536,6 +619,116 @@ The ``Get`` and ``GetHost`` functions expect a C array of size ``nDim`` and retu real result = csv.GetHost(y); +Accessing the neighbours used for the interpolation ++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In addition to the interpolated value, ``LookupTable`` can return the elements of the table which surround the +requested coordinates, i.e. the ones the interpolation is computed from. This is useful to implement a custom +interpolation or reconstruction (e.g. a power law between two nodes), to estimate a local slope, or simply to +check which part of the table is being used. Four methods are available, ``GetNeighbours`` and ``GetNeighboursIndx`` +on the device, and ``GetNeighboursHost`` and ``GetNeighboursIndxHost`` on the host: + +.. code-block:: c++ + + // Coordinates and data of the neighbours (device and host) + void GetNeighbours(const real x[nDim], real xN[2*nDim], real dataN[1 << nDim]); + void GetNeighboursHost(const real x[nDim], real xN[2*nDim], real dataN[1 << nDim]); + + // Indices of the same neighbours (device and host) + void GetNeighboursIndx(const real x[nDim], int idx[nDim], int dataIdx[1 << nDim]); + void GetNeighboursIndxHost(const real x[nDim], int idx[nDim], int dataIdx[1 << nDim]); + +These methods do not return anything, but they fill the arrays which are given to them: + +* ``xN[2*n]`` and ``xN[2*n+1]`` are the two coordinates of the table bracketing ``x[n]`` along the dimension ``n``. +* ``dataN[v]`` is the data on the vertex ``v`` of the cell surrounding ``x``. Since a cell of a ``nDim`` table has + ``2^nDim`` vertices, ``dataN`` has ``1 << nDim`` elements. The bit ``n`` of ``v`` tells whether the vertex is on + the right (1) or on the left (0) of the dimension ``n``: in 2D, ``dataN[0]``, ``dataN[1]``, ``dataN[2]`` and + ``dataN[3]`` are therefore the data in (x\ :sub:`i`, y\ :sub:`j`), (x\ :sub:`i+1`, y\ :sub:`j`), + (x\ :sub:`i`, y\ :sub:`j+1`) and (x\ :sub:`i+1`, y\ :sub:`j+1`). +* ``idx[n]`` is the index of the left neighbour along the dimension ``n`` (the right one being ``idx[n]+1``). +* ``dataIdx[v]`` is the index of the vertex ``v`` in the data array of the table, following the same convention as + ``dataN``, so that ``dataN[v]`` and ``dataHost(dataIdx[v])`` refer to the same element. + +For instance, the 2D table ``example2D.csv`` above, interpolated in (x=2.1, y=3.5), gives: + +.. code-block:: c++ + + real x[2]; + x[0] = 2.1; + x[1] = 3.5; + + real xN[4]; // 2 coordinates for each of the 2 dimensions + real dataN[4]; // 2^2 vertices + int idx[2]; + int dataIdx[4]; + + csv.GetNeighboursHost(x, xN, dataN); + csv.GetNeighboursIndxHost(x, idx, dataIdx); + + // xN[0] and xN[1] now bracket x[0], while xN[2] and xN[3] bracket x[1], and the interpolated + // value returned by csv.GetHost(x) can be recomputed from dataN: + real dx = (x[0]-xN[0])/(xN[1]-xN[0]); + real dy = (x[1]-xN[2])/(xN[3]-xN[2]); + real value = (1-dx)*(1-dy)*dataN[0] + dx*(1-dy)*dataN[1] + + (1-dx)*dy*dataN[2] + dx*dy*dataN[3]; + +The same methods without the ``Host`` suffix can be called from within an ``idefix_for`` loop, the arrays being then +local to the loop. + +Both ``Get`` and the methods above search the table for the cell surrounding the requested coordinates. When the +interpolated value *and* its neighbours are needed for the same coordinates, this search can be performed only once, +by handing the same ``LookupTableSearchCache`` structure to each of them: whichever is called first searches the +table and stores the result in the structure, and the ones called next reuse it instead of searching the table again. +The order in which they are called is irrelevant, ``Get`` can fill the structure for ``GetNeighbours`` and +``GetNeighboursIndx``, or the other way around. + +.. code-block:: c++ + + idefix_for("loop",0, 10, KOKKOS_LAMBDA (int i) { + real x[2]; + x[0] = 2.1; + x[1] = 3.5; + + // The search performed by Get is stored in neighbours... + LookupTableSearchCache<2> neighbours; + real value = csv.Get(x, neighbours); + + // ... and is reused by the two methods below, which do not search the table again + real xN[4]; + real dataN[4]; + int idx[2]; + int dataIdx[4]; + csv.GetNeighbours(x, neighbours, xN, dataN); + csv.GetNeighboursIndx(x, neighbours, idx, dataIdx); + }); + +The very same methods are available on the host, as ``GetHost``, ``GetNeighboursHost`` and ``GetNeighboursIndxHost``. +The structure gives access to the search itself, ``neighbours.idx[n]`` being the index of the left neighbour along +the dimension ``n``, and ``neighbours.delta[n]`` the elementary ratio used to weight the two neighbours of that +dimension. + +.. note:: + The stored search is only reused when the coordinates it was computed for are the ones being requested. Calling + ``GetNeighbours`` or ``GetNeighboursIndx`` with different coordinates simply searches the table again, and updates + the structure accordingly, so that a ``LookupTableSearchCache`` can be reused from one point to the next. + +.. warning:: + The ``LookupTableSearchCache`` structure is declared *per thread*, and not by the lookup table itself: when it is used inside an + ``idefix_for`` loop, it should be declared *inside* the loop, so that each thread has its own copy. A lookup table + is shared by all of the threads of a loop, and can therefore not store anything of the sort itself. + +.. note:: + When the table is interpolated in function space (see above), ``xN`` and ``dataN`` are returned in the original + space of the table, i.e. ``invFunc`` is applied to the values which are stored in ``xin`` and ``data``. The + indices returned by ``GetNeighboursIndx`` are of course not affected by the transformation. + +.. note:: + The search of the neighbours follows exactly the same rules as ``Get``: an out of bound coordinate triggers an + error when ``errorIfOutOfBound`` is enabled, and is otherwise clamped to the closest cell of the table. If one of + the requested coordinates is a nan, ``xN`` and ``dataN`` are filled with nans, and ``idx`` and ``dataIdx`` with -1. + + .. note:: Usage examples are provided in `test/utils/lookupTable`. diff --git a/doc/source/reference/makefile.rst b/doc/source/reference/makefile.rst index 8f58ceedb..5f86c66fe 100644 --- a/doc/source/reference/makefile.rst +++ b/doc/source/reference/makefile.rst @@ -1,3 +1,5 @@ +.. _makefile: + Code configuration with Cmake ============================= @@ -33,6 +35,10 @@ Several options can be enabled from the command line (or are accessible with ``c ``-D Idefix_MPI=ON`` Enable MPI parallelisation. Requires an MPI library. When used in conjonction with CUDA (Nvidia GPUs), a CUDA-aware MPI library is required by *Idefix*. +``-D Idefix_MPI_GPU_DIRECT=OFF`` + Disable the usage of MPI GPU direct for inter-process communication. In this case it uses a copy between GPU and CPU before and after making communications. + It is usefull if your MPI is not GPU-aware. Note that this option decreases performances. + ``-D Idefix_DEFS=foo.hpp`` Specify a particular filename to be used in place of the default problem file ``definitions.hpp`` diff --git a/doc/source/testing/testLauncher.rst b/doc/source/testing/testLauncher.rst index aea7f5c3d..33b8e7ba5 100644 --- a/doc/source/testing/testLauncher.rst +++ b/doc/source/testing/testLauncher.rst @@ -32,12 +32,12 @@ To run the test you can basically : # Run all tests ./test.py - # Run all tests in ./tests/HD - ./test.py -subdir=./tests/HD + # Run all tests in ./test/HD + ./test.py -subdir=./test/HD # Select in more details the tests containing the "single" keyword # See pytest documentation for the exact advanced semantic - ./test.py -subdir=./tests/HD -k single + ./test.py -subdir=./test/HD -k single # Run in verbose ./test.py -v @@ -144,7 +144,7 @@ For a single basic configuration one can use : .. code-block:: json { - "variants": { + "default": { "dumpname": "dump.0001.dmp", "ini": "idefix.ini", "vectPot": false, @@ -159,7 +159,7 @@ For a single basic configuration one can use : Available parameters -------------------- -The parameters in the ``variants`` dictionnary correspond to the options supported by the +The parameters in the ``default`` dictionnary correspond to the options supported by the :doc:`idfxTest ` script to configure the build and run of *Idefix*. In addition there is some extra keys which are dedicated to the json interpretation layer : @@ -191,26 +191,34 @@ In addition there is some extra keys which are dedicated to the json interpretat * - ``multirun`` - ``{}`` - See the multi-run section below. + * - ``callPyFunctionBefore`` + - + - Call a python function before executing the test (see dedicated section at the end of this file). + * - ``callPyFunctionAfter`` + - + - Call a python function after executing the test (see dedicated section at the end of this file). Looping over parameters ----------------------- -You might want to explore running Idefix within parameter ranges (configuration files, modes). -For this simply list the values you want as a list. The test script will automatically -generate all combinations. +You might want to explore running *Idefix* within parameter ranges (configuration files, modes). +For this simply list the values you want as a list in tha ``variants`` dictionnary. The test script +will automatically generate all combinations. .. code-block:: json { - "variants": { + "default": { "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-hll.ini"], - "vectPot": [false, true], "single": false, "reconstruction": 2, - "mpi": [false, true], "standardTest": false, "tolerance": 0 + }, + "variants": { + "ini": ["idefix.ini","idefix-hll.ini"], + "vectPot": [false, true], + "mpi": [false, true] } } @@ -245,25 +253,24 @@ can list several sets as a list. Here using single only on half of the modes. .. code-block:: json { + "default": { + "dumpname": "dump.0001.dmp", + "tolerance": 0 + "standardTest": false, + "reconstruction": 2 + }, "variants": [ { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], + "ini": "idefix.ini", "vectPot": false, "single": false, - "reconstruction": 2, "mpi": [false, true], - "standardTest": false, - "tolerance": 0 },{ - "dumpname": "dump.0001.dmp", - "ini": ["idefix-hll.ini"], + "ini": "idefix-hll.ini", "vectPot": true, "single": true, - "reconstruction": 2, "mpi": [false, true], - "standardTest": false, - "tolerance": 0 + } ] } @@ -284,15 +291,17 @@ the order you want to see them composing the test name. { "namings": "ini,single,mpi", - "variants": { + "default": { "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-hll.ini"], "vectPot": false, - "single": [false, true], "reconstruction": 2, - "mpi": [false, true], "standardTest": false, "tolerance": 0 + }, + "variants": { + "ini": ["idefix.ini","idefix-hll.ini"], + "single": [false, true], + "mpi": [false, true], } } @@ -309,16 +318,18 @@ It is just like if you used and IF statement. { "namings": "ini,single,mpi", - "variants": { + "default": { "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-hll.ini"], "vectPot": false, - "single": [false, true], "reconstruction": 2, - "mpi": [false, true], "standardTest": false, "tolerance": 0 }, + "variants": { + "ini": ["idefix.ini","idefix-hll.ini"], + "single": [false, true], + "mpi": [false, true], + }, "when": { "conditions": { "single": true @@ -348,9 +359,9 @@ They are described like : .. code-block:: json { - "variants": { + "default": { "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], + "ini": "idefix.ini", "vectPot": false, "single": false, "reconstruction": 2, @@ -369,6 +380,33 @@ They are described like : }, } +Calling a Python function +------------------------- + +In some cases (example in ``test/utils/lookupTable``) you might need to call a custom +python function before running the test to prepare the data or after the test to perform +some extra check. + +You can simply implement the functions you want to call in the python file in the test +directory (ideally named ``testmelib.py``) : + +.. code-block:: python + + def callMeAtStart(): + print("This is called at test start !") + + def callMeAtEnd(): + print("This is called at test end !") + +And add the keys in ``testme.json``: + +.. code-block:: json + + "default": { + "callPyFunctionBefore": "testmelib.py:callMeAtStart", + "callPyFunctionAfter": "testmelib.py:callMeAtEnd" + } + Using the idfxTest options -------------------------- diff --git a/make_tarballs.py b/make_tarballs.py index dfc1b55fa..79c64f35c 100644 --- a/make_tarballs.py +++ b/make_tarballs.py @@ -1,3 +1,18 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file make_tarballs.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Clément Robert (IPAG/UGA/CNRS - 2021 - 2026) +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + import argparse import os import subprocess @@ -89,7 +104,7 @@ def _make_self_contained_tarball(output_dir, *, suffix="", exclude_list=None): os.replace(os.path.join(work_dir, tarball), final_tarfile) filesize = os.path.getsize(final_tarfile) - print("Done ! Final file size is %.1f MB" % (filesize / 1024 ** 2)) + print("Done ! Final file size is %.1f MB" % (filesize / 1024**2)) def main(argv=None): diff --git a/pytest.ini b/pytest.ini index b3482664f..98983edc4 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,5 +2,5 @@ markers= default: Test to run by default. python_files="test_*.py" -junit_logging="system-out" -junit_log_passing_tests=false +junit_logging=all +junit_log_passing_tests=False diff --git a/pytools/dump_io.py b/pytools/dump_io.py index 4b258336f..a084a1f93 100644 --- a/pytools/dump_io.py +++ b/pytools/dump_io.py @@ -1,9 +1,25 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file pytools/dump_io.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# - Clément Robert (IPAG/UGA/CNRS - 2022 - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # -*- coding: utf-8 -*- """ Created on Fri Nov 27 22:07:47 2020 @author: lesurg """ + import os import re import struct @@ -59,7 +75,7 @@ def __init__(self, fh, byteorder="little"): self.ndims = int.from_bytes(fh.read(INT_SIZE), byteorder) dims = [] ntot = 1 - for dim in range(self.ndims): + for _ in range(self.ndims): dims.append(int.from_bytes(fh.read(INT_SIZE), byteorder)) ntot = ntot * dims[-1] raw = struct.unpack(str(ntot) + stringchar, fh.read(mysize * ntot)) @@ -119,6 +135,7 @@ def _read_fields(self, fh): def __repr__(self): return "DumpDataset('%s')" % self.filename + # public API def readDump(filename): return DumpDataset(filename) diff --git a/pytools/idfx_io.py b/pytools/idfx_io.py index 17dc62725..95f49b9a0 100644 --- a/pytools/idfx_io.py +++ b/pytools/idfx_io.py @@ -1,8 +1,23 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file pytools/idfx_io.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# - Clément Robert (IPAG/UGA/CNRS - 2022 - 2026) +# - Marc Van den Bossche (IAP Postdam - 2024) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + import struct import numpy as np - __all__ = ["readIdfxFile"] # Read .idfx files which are created # for debug purposes by DataBlock.DumpToFile(std::string&) @@ -14,9 +29,9 @@ HEADER_SIZE = 128 + # There is one .idfx file per processor class IdfxFileField(object): - def __init__(self, fh, byteorder="little"): # read entry name q = fh.read(NAME_SIZE) @@ -27,12 +42,13 @@ def __init__(self, fh, byteorder="little"): return self.ndims = int.from_bytes(fh.read(INT_SIZE), byteorder) dims = [] - for dim in range(self.ndims): + for _ in range(self.ndims): dims.append(int.from_bytes(fh.read(INT_SIZE), byteorder)) ntot = int(np.prod(dims)) raw = struct.unpack(str(ntot) + "d", fh.read(DOUBLE_SIZE * ntot)) self.array = np.asarray(raw).reshape(dims[::-1]) + class IdfxFileDataset(object): def __init__(self, filename): # identical to DumpDataset @@ -46,12 +62,11 @@ def _read_header(self, fh): # could easily be identical to DumpDataset headerSize = 128 q = fh.read(headerSize) - n = q.index(b'\x00') - self.header = q[:n].decode('utf-8') + n = q.index(b"\x00") + self.header = q[:n].decode("utf-8") self.metadata["byteorder"] = "little" - def _read_field(self, fh): # identical to DumpDataset if self.metadata["byteorder"] is None: diff --git a/pytools/idfx_test.py b/pytools/idfx_test.py index fd28ccb61..cf16deae1 100644 --- a/pytools/idfx_test.py +++ b/pytools/idfx_test.py @@ -1,655 +1,797 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file pytools/idfx_test.py +# +# Last modified : 09/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2026) +# - Sébastien Valat (IPAG/UGA/CNRS - 2026) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + import argparse +import json import os +import re import shutil import subprocess import sys -import re -import json -import numpy as np import matplotlib.pyplot as plt +import numpy as np from .dump_io import readDump -class bcolors: - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKCYAN = '\033[96m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - UNDERLINE = '\033[4m' -class idfxTest: - def __init__ (self, current_test_file, name=""): - parser = argparse.ArgumentParser() +class bcolors: + HEADER = "\033[95m" + OKBLUE = "\033[94m" + OKCYAN = "\033[96m" + OKGREEN = "\033[92m" + WARNING = "\033[93m" + FAIL = "\033[91m" + ENDC = "\033[0m" + BOLD = "\033[1m" + UNDERLINE = "\033[4m" - idefix_dir_env = os.getenv("IDEFIX_DIR") - parser.add_argument("-noplot", - dest="noplot", - help="disable plotting in standard tests", - action="store_false") - - parser.add_argument("-ploterr", - help="Enable plotting on error in regression tests", - action="store_true") - - parser.add_argument("-cmake", - default=[], - help="CMake options", - nargs='+') - - parser.add_argument("-definitions", - default="", - help="definitions.hpp file") - - parser.add_argument("-dec", - default="", - help="MPI domain decomposition", - nargs='+') - - parser.add_argument("-check", - help="Only perform regression tests without compilation", - action="store_true") - - parser.add_argument("-cuda", - help="Test on Nvidia GPU using CUDA", - action="store_true") - - parser.add_argument("-intel", - help="Test compiling with Intel OneAPI", - action="store_true") - - parser.add_argument("-hip", - help="Test on AMD GPU using HIP", - action="store_true") - - parser.add_argument("-single", - help="Enable single precision", - action="store_true") - - parser.add_argument("-vectPot", - help="Enable vector potential formulation", - action="store_true") - - parser.add_argument("-reconstruction", - type=int, - default=2, - help="set reconstruction scheme (2=PLM, 3=LimO3, 4=PPM)") - - parser.add_argument("-idefixDir", - default=idefix_dir_env, - help="Set directory for idefix source files (default $IDEFIX_DIR)") - - parser.add_argument("-mpi", - help="Enable MPI", - action="store_true") - - parser.add_argument("-all", - help="Do all test suite (otherwise, just do the test with the current configuration)", - action="store_true") - - parser.add_argument("-init", - help="Reinit reference files for non-regression tests (dangerous!)", - action="store_true") - - parser.add_argument("-Werror", - help="Consider warnings as errors", - action="store_true") - - parser.add_argument("-ccache", - help="Use ccache to reduce the build time over multiple run of the test suite.", - action="store_true") - - parser.add_argument("-restart", - help="Enable creating a restart from a checkpoint.", - action='store_true') - - parser.add_argument("-v", "--verbose", - help="Enable verbose mode, by not capturing the output.", - action="store_true") - - parser.add_argument("--help-pytest", - help="Display the options you can transmit directly to pytest in addition to the specific to idefix tests.", - action="store_true") - - parser.add_argument("-fake", - help="Make a fake run by just logging the actions to validate that we generate same command over refactoring.", - action="store_true") - - # this option is not used directly by direct users of idfxTest but by idx_test_gen - parser.add_argument("-subdir", - default="./test", - help="Select the test in the given subdir not to run all.", - type=str) - - args, unknown=parser.parse_known_args() - - # transform all arguments from args into attributes of this instance - self.__dict__.update(vars(args)) - # store the full path of problem directory - self.currentTestFile = current_test_file - self.currentTestName = name - self.problemDir=os.path.dirname(current_test_file) - self.referenceDirectory = os.path.join(idefix_dir_env,"reference") - # current directory relative to $IDEFIX_DIR/test (used to retrieve the path ot reference files) - self.testDir=os.path.relpath(self.problemDir,os.path.join(idefix_dir_env,"test")) - # build directory, currently inside the test named build-test - self.buildDir=os.path.join(self.problemDir,"build-test") - # remind what build we dit last - self.lastCmakeCmd="" - # subdir - self.filterSubdir=args.subdir - # save - self.cmdArgs = vars(args) - self.cmdArgs.update({ - "restart_no_overwrite": [], - }) - self.log=[] - # when making a restart we should not overrite those files (will be checked) - self.restart_no_overwrite=[] - - # forward args for pytest - if args.verbose: - unknown.append("--capture=no") - if args.help_pytest: - unknown.append("--help") - # remaining args - self.remainingArgs=unknown - - def addLog(self, entry): - if self.fake: - self.log.append(entry) - with open(os.path.join(self.problemDir,"testsuite.log.json"), "w+") as fp: - json.dump(self.log, fp, indent='\t') - - def applyConfig(self, config: dict={}): - # check args - for key, value in config.items(): - if key not in ['ini', 'testfile', 'testname', 'dumpname']: - assert key in self.cmdArgs, f"The given configuration overriding try to set an invalid paramater : {key}={value}" - - # override options - newArgs = {} - newArgs.update(self.cmdArgs) - newArgs.update(config) - - # replace in dict - self.__dict__.update(newArgs) - - def _genCmakeCommand(self,definitionFile=""): - comm=["cmake"] - # add source directory - comm.append(self.idefixDir) - - # we will build in ./build-test so problem dir is parent - comm.append("-DIdefix_PROBLEM_DIR="+self.problemDir) - - # add specific options - for opt in self.cmake: - comm.append("-D"+opt) - - if self.cuda: - comm.append("-DKokkos_ENABLE_CUDA=ON") - # disable fmad operations on Cuda to make it compatible with CPU arithmetics - comm.append("-DIdefix_CXX_FLAGS=--fmad=false") - # disable Async cuda malloc for tests performed on old UCX implementations - comm.append("-DKokkos_ENABLE_IMPL_CUDA_MALLOC_ASYNC=OFF") - - if self.intel: - # disable fmad operations on Cuda to make it compatible with CPU arithmetics - comm.append("-DIdefix_CXX_FLAGS=-fp-model=strict") - comm.append("-DCMAKE_CXX_COMPILER=icpx") - comm.append("-DCMAKE_C_COMPILER=icx") - - if self.hip: - comm.append("-DKokkos_ENABLE_HIP=ON") - # disable fmad operations on HIP to make it compatible with CPU arithmetics - comm.append("-DIdefix_CXX_FLAGS=-ffp-contract=off") - - #if we use single precision - if(self.single): - comm.append("-DIdefix_PRECISION=Single") - else: - comm.append("-DIdefix_PRECISION=Double") - - - if(self.vectPot): - comm.append("-DIdefix_EVOLVE_VECTOR_POTENTIAL=ON") - else: - comm.append("-DIdefix_EVOLVE_VECTOR_POTENTIAL=OFF") - - if(self.Werror): - comm.append("-DIdefix_WERROR=ON") - - # add a definition file if provided - if(definitionFile): - self.definitions=definitionFile - else: - self.definitions="definitions.hpp" - - comm.append("-DIdefix_DEFS="+os.path.join(self.problemDir, self.definitions)) - - if(self.mpi): - comm.append("-DIdefix_MPI=ON") - else: - comm.append("-DIdefix_MPI=OFF") - - if(self.reconstruction == 2): - comm.append("-DIdefix_RECONSTRUCTION=Linear") - elif(self.reconstruction==3): - comm.append("-DIdefix_RECONSTRUCTION=LimO3") - elif(self.reconstruction==4): - comm.append("-DIdefix_RECONSTRUCTION=Parabolic") - - # export ccache env - if self.ccache: - comm.append("-DCMAKE_CXX_COMPILER_LAUNCHER=ccache") - - # ok - return comm - - - def configure(self,definitionFile="", reuse_last_same_build=True, override: dict={}): - # log - self.addLog({"call": "configure", "args":{ - 'definitionFile': definitionFile, - 'reuse_last_same_build': reuse_last_same_build, - 'override': override - }}) - - # gen command - comm = self._genCmakeCommand(definitionFile) - - # log - print("***************** CALLING CMAKE *******************") - print(f"mkdir -p {self.buildDir}") - print(f"cd {self.buildDir}") - print(' '.join(comm)) - print("***************************************************") - - # not action needed if same command or force no rebuild - if reuse_last_same_build == True and self.lastCmakeCmd == ' '.join(comm): - print("SKIP ALREADY DONE") - return - - # run - try: - # do cleanup - self.clean() +class idfxTest: + def __init__(self, current_test_file, name=""): + parser = argparse.ArgumentParser() + + idefix_dir_env = os.getenv("IDEFIX_DIR") + + parser.add_argument( + "-noplot", + dest="noplot", + help="disable plotting in standard tests", + action="store_false", + ) + + parser.add_argument( + "-ploterr", + help="Enable plotting on error in regression tests", + action="store_true", + ) + + parser.add_argument("-cmake", default=[], help="CMake options", nargs="+") + + parser.add_argument("-definitions", default="", help="definitions.hpp file") + + parser.add_argument( + "-dec", default="", help="MPI domain decomposition", nargs="+" + ) + + parser.add_argument( + "-check", + help="Only perform regression tests without compilation", + action="store_true", + ) + + parser.add_argument( + "-cuda", help="Test on Nvidia GPU using CUDA", action="store_true" + ) + + parser.add_argument( + "-intel", help="Test compiling with Intel OneAPI", action="store_true" + ) + + parser.add_argument( + "-hip", help="Test on AMD GPU using HIP", action="store_true" + ) + + parser.add_argument( + "-single", help="Enable single precision", action="store_true" + ) + + parser.add_argument( + "-vectPot", help="Enable vector potential formulation", action="store_true" + ) + + parser.add_argument( + "-reconstruction", + type=int, + default=2, + help="set reconstruction scheme (2=PLM, 3=LimO3, 4=PPM)", + ) + + parser.add_argument( + "-idefixDir", + default=idefix_dir_env, + help="Set directory for idefix source files (default $IDEFIX_DIR)", + ) + + parser.add_argument("-mpi", help="Enable MPI", action="store_true") + + parser.add_argument( + "-mpiMode", + default="Persistent", + choices=["Default", "Persistent", "NonBlocking", "Blocking"], + help="MPI communication mode to use (Default)", + type=str, + ) + + parser.add_argument( + "-mpiGpuForceCopy", + action="store_true", + help="Disable MPI GPU direct and force memory transfers for validation purpose.", + ) + + parser.add_argument( + "-all", + help="Do all test suite (otherwise, just do the test with the current configuration)", + action="store_true", + ) + + parser.add_argument( + "-init", + help="Reinit reference files for non-regression tests (dangerous!)", + action="store_true", + ) + + parser.add_argument( + "-Werror", help="Consider warnings as errors", action="store_true" + ) + + parser.add_argument( + "-ccache", + help="Use ccache to reduce the build time over multiple run of the test suite.", + action="store_true", + ) + + parser.add_argument( + "-restart", + help="Enable creating a restart from a checkpoint.", + action="store_true", + ) + + parser.add_argument( + "-v", + "--verbose", + help="Enable verbose mode, by not capturing the output.", + action="store_true", + ) + + parser.add_argument( + "--validate-testme-jsons", + help="Only validate the testme.json files.", + action="store_true", + ) + + parser.add_argument( + "--help-pytest", + help="Display the options you can transmit directly to pytest in addition to the specific to idefix tests.", + action="store_true", + ) + + parser.add_argument( + "-fake", + help="Make a fake run by just logging the actions to validate that we generate same command over refactoring.", + action="store_true", + ) + + # this option is not used directly by direct users of idfxTest but by idx_test_gen + parser.add_argument( + "-subdir", + default="./test", + help="Select the test in the given subdir not to run all.", + type=str, + ) + + args, unknown = parser.parse_known_args() + + # transform all arguments from args into attributes of this instance + self.__dict__.update(vars(args)) + # store the full path of problem directory + self.currentTestFile = current_test_file + self.currentTestName = name + self.problemDir = os.path.dirname(current_test_file) + self.referenceDirectory = os.path.join(idefix_dir_env, "reference") + # current directory relative to $IDEFIX_DIR/test (used to retrieve the path ot reference files) + self.testDir = os.path.relpath( + self.problemDir, os.path.join(idefix_dir_env, "test") + ) + # build directory, currently inside the test named build-test + self.buildDir = os.path.join(self.problemDir, "build-test") + # remind what build we dit last + self.lastCmakeCmd = "" + # subdir + self.filterSubdir = args.subdir + # save + self.cmdArgs = vars(args) + self.cmdArgs.update({"restart_no_overwrite": []}) + self.log = [] + # when making a restart we should not overrite those files (will be checked) + self.restart_no_overwrite = [] + + # forward args for pytest + if args.verbose: + unknown.append("--capture=no") + if args.help_pytest: + unknown.append("--help") + # remaining args + self.remainingArgs = unknown + + def addLog(self, entry): + if self.fake: + self.log.append(entry) + with open(os.path.join(self.problemDir, "testsuite.log.json"), "w+") as fp: + json.dump(self.log, fp, indent="\t") + + def applyConfig(self, config: dict | None = None): + # check args + if config is None: + config = {} + for key, value in config.items(): + if key not in [ + "ini", + "testfile", + "testname", + "dumpname", + "check_file_produced", + ]: + assert key in self.cmdArgs, ( + f"The given configuration overriding try to set an invalid paramater : {key}={value}" + ) + + # override options + newArgs = {} + newArgs.update(self.cmdArgs) + newArgs.update(config) + + # replace in dict + self.__dict__.update(newArgs) + + def _genCmakeCommand(self, definitionFile=""): + comm = ["cmake"] + # add source directory + comm.append(self.idefixDir) + + # we will build in ./build-test so problem dir is parent + comm.append("-DIdefix_PROBLEM_DIR=" + self.problemDir) + + # add specific options + for opt in self.cmake: + comm.append("-D" + opt) + + if self.cuda: + comm.append("-DKokkos_ENABLE_CUDA=ON") + # disable Async cuda malloc for tests performed on old UCX implementations + comm.append("-DKokkos_ENABLE_IMPL_CUDA_MALLOC_ASYNC=OFF") + + if self.intel: + # disable fmad operations on Cuda to make it compatible with CPU arithmetics + comm.append("-DCMAKE_CXX_COMPILER=icpx") + comm.append("-DCMAKE_C_COMPILER=icx") + + if self.hip: + comm.append("-DKokkos_ENABLE_HIP=ON") + + # disable FMA for testing so that we have the same results on CPU and GPU (otherwise, the results are not bitwise identical) + comm.append("-DIdefix_SUPPRESS_FMA=ON") + + # if we use single precision + if self.single: + comm.append("-DIdefix_PRECISION=Single") + else: + comm.append("-DIdefix_PRECISION=Double") + + if self.vectPot: + comm.append("-DIdefix_EVOLVE_VECTOR_POTENTIAL=ON") + else: + comm.append("-DIdefix_EVOLVE_VECTOR_POTENTIAL=OFF") + + if self.Werror: + comm.append("-DIdefix_WERROR=ON") + + # add a definition file if provided + if definitionFile: + self.definitions = definitionFile + else: + self.definitions = "definitions.hpp" + + comm.append("-DIdefix_DEFS=" + os.path.join(self.problemDir, self.definitions)) + + if self.mpi: + comm.append("-DIdefix_MPI=ON") + else: + comm.append("-DIdefix_MPI=OFF") + + if self.mpiMode != "Default": + comm.append(f"-DIdefix_MPI_MODE={self.mpiMode}") + + if self.mpiGpuForceCopy: + comm.append("-DIdefix_MPI_GPU_DIRECT=OFF") + comm.append("-DIdefix_MPI_GPU_FORCE_COPY=ON") + + if self.reconstruction == 2: + comm.append("-DIdefix_RECONSTRUCTION=Linear") + elif self.reconstruction == 3: + comm.append("-DIdefix_RECONSTRUCTION=LimO3") + elif self.reconstruction == 4: + comm.append("-DIdefix_RECONSTRUCTION=Parabolic") + + # export ccache env + if self.ccache: + comm.append("-DCMAKE_CXX_COMPILER_LAUNCHER=ccache") + + # ok + return comm + + def configure( + self, + definitionFile="", + reuse_last_same_build=True, + override: dict | None = None, + ): + if override is None: + override = {} + # log + self.addLog( + { + "call": "configure", + "args": { + "definitionFile": definitionFile, + "reuse_last_same_build": reuse_last_same_build, + "override": override, + }, + } + ) + + # gen command + comm = self._genCmakeCommand(definitionFile) + + # log + print("***************** CALLING CMAKE *******************") + print(f"mkdir -p {self.buildDir}") + print(f"cd {self.buildDir}") + print(" ".join(comm)) + print("***************************************************") + # not action needed if same command or force no rebuild + if reuse_last_same_build == True and self.lastCmakeCmd == " ".join(comm): + print("SKIP ALREADY DONE") + return + + # run + try: + # do cleanup + self.clean() + + # log and in fake mode we do not execute + self.addLog({"command": comm}) + + # call cmake + if not self.fake: + cmake = subprocess.run(comm, cwd=os.path.abspath(self.buildDir)) + cmake.check_returncode() + except subprocess.CalledProcessError as e: + print(bcolors.FAIL + "***************************************************") + print("Cmake failed") + print("***************************************************" + bcolors.ENDC) + raise e + finally: + # remind for next time + self.lastCmakeCmd = " ".join(comm) + + def clean(self): # log and in fake mode we do not execute - self.addLog({"command": comm}) - - # call cmake - if not self.fake: - cmake=subprocess.run(comm, cwd=os.path.abspath(self.buildDir)) - cmake.check_returncode() - except subprocess.CalledProcessError as e: - print(bcolors.FAIL+"***************************************************") - print("Cmake failed") - print("***************************************************"+bcolors.ENDC) - raise e - finally: - # remind for next time - self.lastCmakeCmd = ' '.join(comm) - - def clean(self): - # log and in fake mode we do not execute - self.addLog({"call": "clean", "args":{}}) - if self.fake: - return - - # remove the build directory before re-creating it - if os.path.exists(self.buildDir): - shutil.rmtree(self.buildDir) - - # recreate - os.makedirs(self.buildDir, exist_ok=False) - - def compile(self,jobs=8): - self.addLog({"call": "compile", "args":{ - 'jobs': jobs, - }}) - - try: - comm = ["make","-j"+str(jobs)] - self.addLog({"command": comm}) + self.addLog({"call": "clean", "args": {}}) + if self.fake: + return + + # remove the build directory before re-creating it + if os.path.exists(self.buildDir): + shutil.rmtree(self.buildDir) + + # recreate + os.makedirs(self.buildDir, exist_ok=False) + + def compile(self, jobs=8): + self.addLog({"call": "compile", "args": {"jobs": jobs}}) + + try: + comm = ["make", "-j" + str(jobs)] + self.addLog({"command": comm}) + + print("***************************************************") + print(f"cd {os.getcwd()}") + print(" ".join(comm)) + print("***************************************************") + + if not self.fake: + make = subprocess.run(comm, cwd=os.path.abspath(self.buildDir)) + make.check_returncode() + except subprocess.CalledProcessError as e: + print(bcolors.FAIL + "***************************************************") + print("Compilation failed") + print("***************************************************" + bcolors.ENDC) + raise e + + def run(self, inputFile="", np=2, nowrite=False, restart=-1): + # log + self.addLog( + { + "call": "run", + "args": { + "np": np, + "nowrite": nowrite, + "restart": restart, + }, + } + ) + + comm = [os.path.join(self.buildDir, "idefix")] + if inputFile: + comm.append("-i") + comm.append(inputFile) + if self.mpi: + if self.dec: + np = 1 + for n in range(len(self.dec)): + np = np * int(self.dec[n]) + + comm.insert(0, "mpirun") + comm.insert(1, "-np") + comm.insert(2, str(np)) + if self.dec: + comm.append("-dec") + for n in range(len(self.dec)): + comm.append(str(self.dec[n])) + + if nowrite: + comm.append("-nowrite") + + if self.Werror: + comm.append("-Werror") + + if restart >= 0: + comm.append("-restart") + comm.append(str(restart)) print("***************************************************") print(f"cd {os.getcwd()}") - print(' '.join(comm)) + print(" ".join(comm)) print("***************************************************") - if not self.fake: - make=subprocess.run(comm, cwd=os.path.abspath(self.buildDir)) - make.check_returncode() - except subprocess.CalledProcessError as e: - print(bcolors.FAIL+"***************************************************") - print("Compilation failed") - print("***************************************************"+bcolors.ENDC) - raise e - - def run(self, inputFile="", np=2, nowrite=False, restart=-1): - # log - self.addLog({"call": "run", "args":{ - 'np': np, - 'nowrite': nowrite, - 'restart': restart, - }}) - - comm=[os.path.join(self.buildDir,"idefix")] - if inputFile: - comm.append("-i") - comm.append(inputFile) - if self.mpi: - if self.dec: - np=1 - for n in range(len(self.dec)): - np=np*int(self.dec[n]) - - comm.insert(0,"mpirun") - comm.insert(1,"-np") - comm.insert(2,str(np)) - if self.dec: - comm.append("-dec") - for n in range(len(self.dec)): - comm.append(str(self.dec[n])) - - if nowrite: - comm.append("-nowrite") - - if self.Werror: - comm.append("-Werror") - - if restart>=0: - comm.append("-restart") - comm.append(str(restart)) - - print("***************************************************") - print(f"cd {os.getcwd()}") - print(' '.join(comm)) - print("***************************************************") - - try: - self.addLog({"command": comm}) - if not self.fake: - make=subprocess.run(comm, cwd=self.problemDir) - make.check_returncode() - except subprocess.CalledProcessError as e: - print(bcolors.FAIL+"***************************************************") - print("Execution failed") - print("***************************************************"+bcolors.ENDC) - raise e - - self._readLog() - - def _readLog(self): - if self.fake: - return - - if not os.path.exists('./idefix.0.log'): - # When no idefix file is produced, we leave - return - - with open('./idefix.0.log','r') as file: - log = file.read() - - if "SINGLE PRECISION" in log: - self.single = True - else: - self.single = False - - if "Kokkos CUDA target ENABLED" in log: - self.cuda = True - else: - self.cuda = False - - if "Kokkos HIP target ENABLED" in log: - self.hip = True - else: - self.hip = False - - - self.reconstruction = 2 - if "3rd order (LimO3)" in log: - self.reconstruction = 3 - - if "4th order (PPM)" in log: - self.reconstruction = 4 - - self.mpi=False - if "MPI ENABLED" in log: - self.mpi=True - - - # Get input file from log - line = re.search('(?<=Input Parameters using input file )(.*)', log) - self.inifile=line.group(0)[:-1] - - # Get performances from log - line = re.search('Main: Perfs are (.*) cell', log) - self.perf=float(line.group(1)) - - def checkOnly(self, filename, tolerance=0): - # log - self.addLog({"call": "checkOnly", "args":{ - 'filename': filename, - 'tolerance': tolerance, - }}) - - # Assumes the code has been run manually using some configuration, so we simply - # do the test suite witout configure/compile/run - self._readLog() - self._showConfig() - if self.cuda or self.hip: - print(bcolors.WARNING+"***********************************************") - print("WARNING: Idefix guarantees floating point arithmetic accuracy") - print("ONLY when fmad instruction are explicitely disabled at compilation.") - print("Otheriwse, this test will likely fail.") - print("***********************************************"+bcolors.ENDC) - self.standardTest() - self.nonRegressionTest(filename, tolerance) - - def standardTest(self): - # log and in fake mode do not execute. - self.addLog({"call": "standardTest", "args":{}}) - if self.fake: - return - - if os.path.exists(os.path.join(self.problemDir, 'python', 'testidefix.py')): - oldPwd = os.getcwd() - os.chdir(os.path.join(self.problemDir, "python")) - comm = [sys.executable, "testidefix.py"] - if self.noplot: - comm.append("-noplot") - - print(bcolors.OKCYAN+"Running standard test...") - try: - make=subprocess.run(comm) - make.check_returncode() - except subprocess.CalledProcessError as e: - print(bcolors.FAIL+"***************************************************") - print("Standard test execution failed") - print("***************************************************"+bcolors.ENDC) - raise e - print(bcolors.OKCYAN+"Standard test succeeded"+bcolors.ENDC) - os.chdir(oldPwd) - else: - print(bcolors.WARNING+"No standard testidefix.py for this test"+bcolors.ENDC) - sys.stdout.flush() - - def nonRegressionTest(self, filename,tolerance=0): - # log and in fake mode do not execute. - self.addLog({"call": "nonRegressionTest", "args":{ - "filename": filename, - "tolerance": tolerance - }}) - if self.fake: - return - - fileref=os.path.join(self.referenceDirectory, self.testDir, self._getReferenceFilename()) - if not(os.path.exists(fileref)): - raise Exception("Reference file "+fileref+ " doesn't exist") - - filetest=filename - if not(os.path.exists(filetest)): - raise Exception("Test file "+filetest+ " doesn't exist") - - Vref=readDump(fileref) - Vtest=readDump(filetest) - error=self._computeError(Vref,Vtest) - if error > tolerance: - print(bcolors.FAIL+"Non-Regression test failed!") - self._showConfig() - print(bcolors.ENDC) - if self.ploterr: - self._plotDiff(Vref,Vtest) - assert error <= tolerance, bcolors.FAIL+"Error (%e) above tolerance (%e)"%(error,tolerance)+bcolors.ENDC - print(bcolors.OKGREEN+"Non-regression test succeeded with error=%e"%error+bcolors.ENDC) - sys.stdout.flush() - - def compareDump(self, file1, file2,tolerance=0): - self.addLog({"call": "compareDump", "args":{ - "file1": file1, - "file2": file2, - "tolerance": tolerance, - }}) - if self.fake: - return - - Vref=readDump(file1) - Vtest=readDump(file2) - error=self._computeError(Vref,Vtest) - if error > tolerance: - print(bcolors.FAIL+"Files are different !") - print(bcolors.ENDC) - - self._plotDiff(Vref,Vtest) - assert error <= tolerance, bcolors.FAIL+"Error (%e) above tolerance (%e)"%(error,tolerance)+bcolors.ENDC - print(bcolors.OKGREEN+"Files are identical up to error=%e"%error+bcolors.ENDC) - sys.stdout.flush() - - - def makeReference(self,filename): - # log and in fake mode do not execute. - self.addLog({"call": "compareDump", "args":{ - "filename": filename, - }}) - if self.fake: - return - - self._readLog() - targetDir = os.path.join(self.referenceDirectory,self.testDir) - if not os.path.exists(targetDir): - print("Creating reference directory") - os.makedirs(targetDir, exist_ok=True) - fileout = os.path.join(targetDir, self._getReferenceFilename()) - if(os.path.exists(fileout)): - ans=input(bcolors.WARNING+"This will overwrite already existing reference file:\n"+fileout+"\nDo you confirm? (type yes to continue): "+bcolors.ENDC) - if(ans != "yes"): - print(bcolors.WARNING+"Reference creation aborpted"+bcolors.ENDC) - return - - shutil.copy(filename,fileout) - print(bcolors.OKGREEN+"Reference file "+fileout+" created"+bcolors.ENDC) - sys.stdout.flush() - - def _showConfig(self): - print("**************************************************************") - if self.cuda: - print("Nvidia Cuda enabled.") - if self.hip: - print("AMD HIP enabled.") - print("CMake Opts: " +" ".join(self.cmake)) - print("Definitions file:"+self.definitions) - print("Input File: "+self.inifile) - if(self.single): - print("Precision: Single") - else: - print("Precision: Double") - if(self.reconstruction==2): - print("Reconstruction: PLM") - elif(self.reconstruction==3): - print("Reconstruction: LimO3") - elif(self.reconstruction==4): - print("Reconstruction: PPM") - if(self.vectPot): - print("Vector Potential: ON") - else: - print("Vector Potential: OFF") - if self.mpi: - print("MPI: ON") - else: - print("MPI: OFF") - - print("**************************************************************") - - def _getReferenceFilename(self): - strReconstruction="plm" - if self.reconstruction == 3: - strReconstruction = "limo3" - if self.reconstruction == 4: - strReconstruction= "ppm" - - strPrecision="double" - if self.single: - strPrecision="single" - - fileref='dump.ref.'+strPrecision+"."+strReconstruction+"."+self.inifile - if self.vectPot: - fileref=fileref+".vectPot" - - fileref=fileref+'.dmp' - return(fileref) - - def _computeError(self,Vref,Vtest): - ntested=0 - error=0 - for fld in Vtest.data.keys(): - if(Vtest.data[fld].ndim==3): - if fld in Vref.data.keys(): - #print("error in "+fld+" = "+str(np.sqrt(np.mean((Vref.data[fld]-Vtest.data[fld])**2)))) - error = error+np.sqrt(np.mean((Vref.data[fld]-Vtest.data[fld])**2)) - ntested=ntested+1 - - if ntested==0: - raise Exception(bcolors.FAIL+"There is no common field between the reference and current file"+bcolors.ENDC) - - error=error/ntested - return(error) - - def _plotDiff(self,Vref,Vtest): - - for fld in Vtest.data.keys(): - if(Vtest.data[fld].ndim==3): - if fld in Vref.data.keys(): - plt.figure() - plt.title(fld) - x1=Vref.x1 - if Vref.data[fld].shape[0] == Vref.x1.size+1: - x1=np.zeros(Vref.data[fld].shape[0]) - x1[:-1]=Vref.x1l - x1[-1]=Vref.x1r[-1] - x2=Vref.x2 - if Vref.data[fld].shape[1] == Vref.x2.size+1: - x2=np.zeros(Vref.data[fld].shape[1]) - x2[:-1]=Vref.x2l - x2[-1]=Vref.x2r[-1] - x3=Vref.x3 - if Vref.data[fld].shape[2] == Vref.x3.size+1: - x3=np.zeros(Vref.data[fld].shape[2]) - x3[:-1]=Vref.x3l - x3[-1]=Vref.x3r[-1] - if Vref.data[fld].shape[1]>1: - plt.pcolor(x1, x2, Vref.data[fld][:,:,0].T-Vtest.data[fld][:,:,0].T,cmap='seismic') - plt.xlabel("x1") - plt.ylabel("x2") - plt.colorbar() - else: - plt.plot(x1, Vref.data[fld][:,0,0]-Vtest.data[fld][:,0,0]) - plt.xlabel("x1") - plt.show() + try: + self.addLog({"command": comm}) + if not self.fake: + make = subprocess.run(comm, cwd=self.problemDir) + make.check_returncode() + except subprocess.CalledProcessError as e: + print(bcolors.FAIL + "***************************************************") + print("Execution failed") + print("***************************************************" + bcolors.ENDC) + raise e + + self._readLog() + + def _readLog(self): + if self.fake: + return + + if not os.path.exists("./idefix.0.log"): + # When no idefix file is produced, we leave + return + + with open("./idefix.0.log", "r") as file: + log = file.read() + + if "SINGLE PRECISION" in log: + self.single = True + else: + self.single = False + + if "Kokkos CUDA target ENABLED" in log: + self.cuda = True + else: + self.cuda = False + + if "Kokkos HIP target ENABLED" in log: + self.hip = True + else: + self.hip = False + + self.reconstruction = 2 + if "3rd order (LimO3)" in log: + self.reconstruction = 3 + + if "4th order (PPM)" in log: + self.reconstruction = 4 + + self.mpi = False + if "MPI ENABLED" in log: + self.mpi = True + + # Get input file from log + line = re.search("(?<=Input Parameters using input file )(.*)", log) + self.inifile = line.group(0)[:-1] + + # Get performances from log + line = re.search("Main: Perfs are (.*) cell", log) + self.perf = float(line.group(1)) + + def checkOnly(self, filename, tolerance=0): + # log + self.addLog( + { + "call": "checkOnly", + "args": { + "filename": filename, + "tolerance": tolerance, + }, + } + ) + + # Assumes the code has been run manually using some configuration, so we simply + # do the test suite witout configure/compile/run + self._readLog() + self._showConfig() + if self.cuda or self.hip: + print(bcolors.WARNING + "***********************************************") + print("WARNING: Idefix guarantees floating point arithmetic accuracy") + print("ONLY when fmad instruction are explicitely disabled at compilation.") + print("Otheriwse, this test will likely fail.") + print("***********************************************" + bcolors.ENDC) + self.standardTest() + self.nonRegressionTest(filename, tolerance) + + def standardTest(self): + # log and in fake mode do not execute. + self.addLog({"call": "standardTest", "args": {}}) + if self.fake: + return + + if os.path.exists(os.path.join(self.problemDir, "python", "testidefix.py")): + oldPwd = os.getcwd() + os.chdir(os.path.join(self.problemDir, "python")) + comm = [sys.executable, "testidefix.py"] + if self.noplot: + comm.append("-noplot") + + print(bcolors.OKCYAN + "Running standard test...") + try: + make = subprocess.run(comm) + make.check_returncode() + except subprocess.CalledProcessError as e: + print( + bcolors.FAIL + "***************************************************" + ) + print("Standard test execution failed") + print( + "***************************************************" + bcolors.ENDC + ) + raise e + print(bcolors.OKCYAN + "Standard test succeeded" + bcolors.ENDC) + os.chdir(oldPwd) + else: + print( + bcolors.WARNING + + "No standard testidefix.py for this test" + + bcolors.ENDC + ) + sys.stdout.flush() + + def nonRegressionTest(self, filename, tolerance=0): + # log and in fake mode do not execute. + self.addLog( + { + "call": "nonRegressionTest", + "args": {"filename": filename, "tolerance": tolerance}, + } + ) + if self.fake: + return + + fileref = os.path.join( + self.referenceDirectory, self.testDir, self._getReferenceFilename() + ) + if not (os.path.exists(fileref)): + raise Exception("Reference file " + fileref + " doesn't exist") + + filetest = filename + if not (os.path.exists(filetest)): + raise Exception("Test file " + filetest + " doesn't exist") + + Vref = readDump(fileref) + Vtest = readDump(filetest) + error = self._computeError(Vref, Vtest) + if error > tolerance: + print(bcolors.FAIL + "Non-Regression test failed!") + self._showConfig() + print(bcolors.ENDC) + if self.ploterr: + self._plotDiff(Vref, Vtest) + assert error <= tolerance, ( + bcolors.FAIL + + "Error (%e) above tolerance (%e)" % (error, tolerance) + + bcolors.ENDC + ) + print( + bcolors.OKGREEN + + "Non-regression test succeeded with error=%e" % error + + bcolors.ENDC + ) + sys.stdout.flush() + + def compareDump(self, file1, file2, tolerance=0): + self.addLog( + { + "call": "compareDump", + "args": { + "file1": file1, + "file2": file2, + "tolerance": tolerance, + }, + } + ) + if self.fake: + return + + Vref = readDump(file1) + Vtest = readDump(file2) + error = self._computeError(Vref, Vtest) + if error > tolerance: + print(bcolors.FAIL + "Files are different !") + print(bcolors.ENDC) + + self._plotDiff(Vref, Vtest) + assert error <= tolerance, ( + bcolors.FAIL + + "Error (%e) above tolerance (%e)" % (error, tolerance) + + bcolors.ENDC + ) + print( + bcolors.OKGREEN + + "Files are identical up to error=%e" % error + + bcolors.ENDC + ) + sys.stdout.flush() + + def makeReference(self, filename): + # log and in fake mode do not execute. + self.addLog( + { + "call": "compareDump", + "args": {"filename": filename}, + } + ) + if self.fake: + return + + self._readLog() + targetDir = os.path.join(self.referenceDirectory, self.testDir) + if not os.path.exists(targetDir): + print("Creating reference directory") + os.makedirs(targetDir, exist_ok=True) + fileout = os.path.join(targetDir, self._getReferenceFilename()) + if os.path.exists(fileout): + ans = input( + bcolors.WARNING + + "This will overwrite already existing reference file:\n" + + fileout + + "\nDo you confirm? (type yes to continue): " + + bcolors.ENDC + ) + if ans != "yes": + print(bcolors.WARNING + "Reference creation aborpted" + bcolors.ENDC) + return + + shutil.copy(filename, fileout) + print(bcolors.OKGREEN + "Reference file " + fileout + " created" + bcolors.ENDC) + sys.stdout.flush() + + def _showConfig(self): + print("**************************************************************") + if self.cuda: + print("Nvidia Cuda enabled.") + if self.hip: + print("AMD HIP enabled.") + print("CMake Opts: " + " ".join(self.cmake)) + print("Definitions file:" + self.definitions) + print("Input File: " + self.inifile) + if self.single: + print("Precision: Single") + else: + print("Precision: Double") + if self.reconstruction == 2: + print("Reconstruction: PLM") + elif self.reconstruction == 3: + print("Reconstruction: LimO3") + elif self.reconstruction == 4: + print("Reconstruction: PPM") + if self.vectPot: + print("Vector Potential: ON") + else: + print("Vector Potential: OFF") + if self.mpi: + print("MPI: ON") + else: + print("MPI: OFF") + + print("**************************************************************") + + def _getReferenceFilename(self): + strReconstruction = "plm" + if self.reconstruction == 3: + strReconstruction = "limo3" + if self.reconstruction == 4: + strReconstruction = "ppm" + + strPrecision = "double" + if self.single: + strPrecision = "single" + + fileref = ( + "dump.ref." + strPrecision + "." + strReconstruction + "." + self.inifile + ) + if self.vectPot: + fileref = fileref + ".vectPot" + + fileref = fileref + ".dmp" + return fileref + + def _computeError(self, Vref, Vtest): + ntested = 0 + error = 0 + for fld in Vtest.data.keys(): + if Vtest.data[fld].ndim == 3: + if fld in Vref.data.keys(): + # print("error in "+fld+" = "+str(np.sqrt(np.mean((Vref.data[fld]-Vtest.data[fld])**2)))) + error = error + np.sqrt( + np.mean((Vref.data[fld] - Vtest.data[fld]) ** 2) + ) + ntested = ntested + 1 + + if ntested == 0: + raise Exception( + bcolors.FAIL + + "There is no common field between the reference and current file" + + bcolors.ENDC + ) + + error = error / ntested + return error + + def _plotDiff(self, Vref, Vtest): + + for fld in Vtest.data.keys(): + if Vtest.data[fld].ndim == 3: + if fld in Vref.data.keys(): + plt.figure() + plt.title(fld) + x1 = Vref.x1 + if Vref.data[fld].shape[0] == Vref.x1.size + 1: + x1 = np.zeros(Vref.data[fld].shape[0]) + x1[:-1] = Vref.x1l + x1[-1] = Vref.x1r[-1] + x2 = Vref.x2 + if Vref.data[fld].shape[1] == Vref.x2.size + 1: + x2 = np.zeros(Vref.data[fld].shape[1]) + x2[:-1] = Vref.x2l + x2[-1] = Vref.x2r[-1] + x3 = Vref.x3 + if Vref.data[fld].shape[2] == Vref.x3.size + 1: + x3 = np.zeros(Vref.data[fld].shape[2]) + x3[:-1] = Vref.x3l + x3[-1] = Vref.x3r[-1] + if Vref.data[fld].shape[1] > 1: + plt.pcolor( + x1, + x2, + Vref.data[fld][:, :, 0].T - Vtest.data[fld][:, :, 0].T, + cmap="seismic", + ) + plt.xlabel("x1") + plt.ylabel("x2") + plt.colorbar() + else: + plt.plot(x1, Vref.data[fld][:, 0, 0] - Vtest.data[fld][:, 0, 0]) + plt.xlabel("x1") + plt.show() diff --git a/pytools/idfx_test_gen.py b/pytools/idfx_test_gen.py index e552c321d..324c85028 100644 --- a/pytools/idfx_test_gen.py +++ b/pytools/idfx_test_gen.py @@ -1,249 +1,287 @@ -##################################################################################### +###################################################################################### # Idefix MHD astrophysical code -# Copyright(C) Sébastien Valat +# +# Source file pytools/idfx_test_gen.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Sébastien Valat (IPAG/UGA/CNRS - 2026) +# - Clément Robert (IPAG/UGA/CNRS - 2026) # and other code contributors +# # Licensed under CeCILL 2.1 License, see COPYING for more information -##################################################################################### +###################################################################################### import copy + import pytest -DO_NOT_LOOP_ON = ['restart_no_overwrite', "dec", "multirun", "check_file_produced"] +DO_NOT_LOOP_ON = ["restart_no_overwrite", "dec", "multirun", "check_file_produced"] + class IdefixDirTestGenerator: - ''' - Class used to generate the various configuration to run by parsing the - files `testme.py` found in the hierarchy of the /test directory of Idefix. - ''' - - def __init__(self, currentTestFile: str, name: str = ""): - ''' - Constructor or the class. - - Args: - currentTestFile (str): - Path the the current python file. Normally you - simply pass __file__ to this parameter. - name (str): - Define a name for the test, can be empty. - ''' - - self.currentTestFile = currentTestFile - self.currentTestName = name - - # generate the list of configs to run - def genTestConfigs(self, names:str, params, whenClauses = {}) -> list: - ''' - Generate the the list of configurations as pytest parameters. - It will unpack the configuration set by looping on all combinations defined - by the given sets. - - Args: - names (str): - Comma separated list of variables do consider to build the - name of the file. - params (dict|list): - A configuration set as a dictionnary or a list of - configuration set. - whenCaluses (dict|list): - Provide a set of clauses to apply after unpacking - the configuration so we can patch some values depending on some others. - - Returns: - A list of pytest.param() ready to be fiven to parametrized pytest functions. - ''' - # get name ordering list - nameList = names.split(',') - - # gen list of complete configs - all_configs = [] - if isinstance(params, dict): - all_configs += self._genOneConfigSeries(names, params) - elif isinstance(params, list): - for p in params: - all_configs += self._genOneConfigSeries(names, p) - else: - raise Exception("Should never be called !") - - # convert as parametrize with nice name - result = [] - for config in all_configs: - # append the file - config['testfile'] = self.currentTestFile - config['testname'] = self.currentTestName - # gen name - nameParts = [self.currentTestName] - for name in nameList: - if isinstance(config[name], bool): - if config[name]: - nameParts.append(name) - elif isinstance(config[name], str): - nameParts.append(str(config[name])) + """ + Class used to generate the various configuration to run by parsing the + files `testme.py` found in the hierarchy of the /test directory of Idefix. + """ + + def __init__(self, currentTestFile: str, name: str = ""): + """ + Constructor or the class. + + Args: + currentTestFile (str): + Path the the current python file. Normally you + simply pass __file__ to this parameter. + name (str): + Define a name for the test, can be empty. + """ + + self.currentTestFile = currentTestFile + self.currentTestName = name + + # generate the list of configs to run + def genTestConfigs( + self, names: str, params, whenClauses=None, defaultConfig: dict | None = None + ) -> list: + """ + Generate the the list of configurations as pytest parameters. + It will unpack the configuration set by looping on all combinations defined + by the given sets. + + Args: + names (str): + Comma separated list of variables do consider to build the + name of the file. + params (dict|list): + A configuration set as a dictionnary or a list of + configuration set. + whenCaluses (dict|list): + Provide a set of clauses to apply after unpacking + the configuration so we can patch some values depending on some others. + defaultConfig (dict): + The default configuration on top of which to apply the variants. + + Returns: + A list of pytest.param() ready to be fiven to parametrized pytest functions. + """ + if defaultConfig is None: + defaultConfig = {} + if whenClauses is None: + whenClauses = {} + # get name ordering list + nameList = names.split(",") + if "" in nameList: + nameList.remove("") + + # gen list of complete configs + all_configs = [] + if isinstance(params, dict): + all_configs += self._genOneConfigSeries( + names, params, defaultConfig=defaultConfig + ) + elif isinstance(params, list): + for p in params: + all_configs += self._genOneConfigSeries( + names, p, defaultConfig=defaultConfig + ) else: - nameParts.append(f"{name}-{config[name]}") - confName = "-".join(nameParts) - - # apply when clause - config = self._applyWhen(config, whenClauses) - - result.append(pytest.param(config, id=confName)) - - # ok - return result - - def extractNamingParameters(self, params) -> list: - ''' - Loop on the parameters and check automatically what are the list of variable parameters. - - Args: - params (list|dict): - The list of configuration sets to scan or a single set. - - Returns: - The list of names of the variable parameters. - ''' - - # if not a list make a list - if not isinstance(params, list): - params = [params] - - # see params - seen = {} - variables = [] - - # loop - for param_set in params: - for key, value in param_set.items(): - if key in variables: - pass - elif key in DO_NOT_LOOP_ON: - pass - elif isinstance(value, list): - variables.append(key) - elif key in seen and seen[key] != value: - variables.append(key) - elif key not in seen: - seen[key] = value - - # by default sort by alphabetic order about var names - # TODO make something better by assigning a priority to vars - variables.sort() - - # ok - return ','.join(variables) - - def _genNextLevelCombinations(self, input: list, paramName: str, paramValues: list) -> list: - ''' - Take an input case list and unpack the given parameter to build the new combinations. - - Args: - input (list): - The incoming list of combinations already unpacked before this call. - paramName (str): - Name of the parameter to unpack. - paramValues (list): - The list of values to unpack and to build combinations for. - - Returns: - The updated list of run sets. - ''' - result = [] - for entry in input: - for value in paramValues: - v = copy.deepcopy(entry) - v[paramName] = value - result.append(v) - return result - - def _genOneConfigSeries(self, names: str, config: dict) -> list: - ''' - Generate the the list of configurations as pytest parameters. - It will unpack the configuration set by looping on all combinations defined - by the given sets. - - Args: - names (str): - Comma separated list of variables do consider to build the - name of the file. - config (dict): - A configuration set as a dictionnary. - - Returns: - A list of pytest.param() ready to be fiven to parametrized pytest functions. - ''' - # get name ordering list - nameList = names.split(',') - - # if there is ini in the list we put it at the end - loopOrder = nameList.copy() - if 'ini' in loopOrder: - loopOrder.remove('ini') - loopOrder.append('ini') - - # init core with everything not a list - core = {} - for key, value in config.items(): - if isinstance(value, list) and key not in DO_NOT_LOOP_ON: - assert key in nameList, f"All variable parameteres should be ordered in the names list, '{key}' is not." - else: - core[key] = copy.deepcopy(value) - - # at start we have only default core - result = [core] - - # loop - for key in loopOrder: - value = config[key] - assert isinstance(value, list), f"This parameter is marked as a list but is not a list : {key}={value} !" - result = self._genNextLevelCombinations(result, key, value) - - # ok - return result - - def _matchWhenClause(self, config: dict, when_clause: dict) -> bool: - ''' - Check the matching of a given when clause on the given configuration. - - Args: - config (dict): The configuration. - when_clause (dict): The when clause to check. - - Returns: - True if the clause, match, False otherwise. - ''' - for key, value in when_clause.items(): - if config[key] != value: - return False - return True - - def _applyWhen(self, config: dict, when: dict) -> dict: - ''' - Check if the when clause applies and apply if if any. - - Args: - config (dict): The configuration. - when_clause (dict): The when clause to check and apply. - - Returns: - The fixed config. - ''' - # nothing to do - if when == {}: - return config - - # clone - result = copy.deepcopy(config) - - # loop on when - if isinstance(when, list): - for clause in when: - if self._matchWhenClause(config, clause['conditions']): - result.update(clause['apply']) - elif isinstance(when, dict): - if self._matchWhenClause(config, when['conditions']): - result.update(when['apply']) - else: - raise Exception(f"Invalid type for 'when' : {when}") - - # ok - return result + raise Exception("Should never be called !") + + # convert as parametrize with nice name + result = [] + for config in all_configs: + # append the file + config["testfile"] = self.currentTestFile + config["testname"] = self.currentTestName + # gen name + nameParts = [self.currentTestName] + for name in nameList: + if isinstance(config[name], bool): + if config[name]: + nameParts.append(name) + elif isinstance(config[name], str): + nameParts.append(str(config[name])) + else: + nameParts.append(f"{name}-{config[name]}") + confName = "-".join(nameParts) + + # apply when clause + config = self._applyWhen(config, whenClauses) + + result.append(pytest.param(config, id=confName)) + + # ok + return result + + def extractNamingParameters(self, params) -> list: + """ + Loop on the parameters and check automatically what are the list of variable parameters. + + Args: + params (list|dict): + The list of configuration sets to scan or a single set. + + Returns: + The list of names of the variable parameters. + """ + + # if not a list make a list + if not isinstance(params, list): + params = [params] + + # see params + seen = {} + variables = [] + + # loop + for param_set in params: + for key, value in param_set.items(): + if key in variables: + pass + elif key in DO_NOT_LOOP_ON: + pass + elif isinstance(value, list): + variables.append(key) + elif key in seen and seen[key] != value: + variables.append(key) + elif key not in seen: + seen[key] = value + + # by default sort by alphabetic order about var names + # TODO make something better by assigning a priority to vars + variables.sort() + + # ok + return ",".join(variables) + + def _genNextLevelCombinations( + self, input: list, paramName: str, paramValues: list + ) -> list: + """ + Take an input case list and unpack the given parameter to build the new combinations. + + Args: + input (list): + The incoming list of combinations already unpacked before this call. + paramName (str): + Name of the parameter to unpack. + paramValues (list): + The list of values to unpack and to build combinations for. + + Returns: + The updated list of run sets. + """ + result = [] + for entry in input: + for value in paramValues: + v = copy.deepcopy(entry) + v[paramName] = value + result.append(v) + return result + + def _genOneConfigSeries( + self, names: str, config: dict, defaultConfig: dict | None = None + ) -> list: + """ + Generate the the list of configurations as pytest parameters. + It will unpack the configuration set by looping on all combinations defined + by the given sets. + + Args: + names (str): + Comma separated list of variables do consider to build the + name of the file. + config (dict): + A configuration set as a dictionnary. + defaultConfig (dict): + The default configuration to overload with the variant part. + + Returns: + A list of pytest.param() ready to be fiven to parametrized pytest functions. + """ + if defaultConfig is None: + defaultConfig = {} + # get name ordering list + nameList = names.split(",") + + # if there is ini in the list we put it at the end + loopOrder = nameList.copy() + if "ini" in loopOrder: + loopOrder.remove("ini") + loopOrder.append("ini") + if "" in loopOrder: + loopOrder.remove("") + + # init core with everything not a list + core = copy.deepcopy(defaultConfig) + for key, value in config.items(): + if isinstance(value, list) and key not in DO_NOT_LOOP_ON: + assert key in nameList, ( + f"All variable parameteres should be ordered in the names list, '{key}' is not." + ) + else: + core[key] = copy.deepcopy(value) + + # at start we have only default core + result = [core] + + # loop + for key in loopOrder: + value = config[key] + assert isinstance(value, list), ( + f"This parameter is marked as a list but is not a list : {key}={value} !" + ) + result = self._genNextLevelCombinations(result, key, value) + + # ok + return result + + def _matchWhenClause(self, config: dict, when_clause: dict) -> bool: + """ + Check the matching of a given when clause on the given configuration. + + Args: + config (dict): The configuration. + when_clause (dict): The when clause to check. + + Returns: + True if the clause, match, False otherwise. + """ + for key, value in when_clause.items(): + if config[key] != value: + return False + return True + + def _applyWhen(self, config: dict, when: dict) -> dict: + """ + Check if the when clause applies and apply if if any. + + Args: + config (dict): The configuration. + when_clause (dict): The when clause to check and apply. + + Returns: + The fixed config. + """ + # nothing to do + if when == {}: + return config + + # clone + result = copy.deepcopy(config) + + # loop on when + if isinstance(when, list): + for clause in when: + if self._matchWhenClause(config, clause["conditions"]): + result.update(clause["apply"]) + elif isinstance(when, dict): + if self._matchWhenClause(config, when["conditions"]): + result.update(when["apply"]) + else: + raise Exception(f"Invalid type for 'when' : {when}") + + # ok + return result diff --git a/pytools/idfx_test_run.py b/pytools/idfx_test_run.py index d14de0b41..f4cd4caa8 100644 --- a/pytools/idfx_test_run.py +++ b/pytools/idfx_test_run.py @@ -1,27 +1,40 @@ -##################################################################################### +###################################################################################### # Idefix MHD astrophysical code -# Copyright(C) Sébastien Valat +# +# Source file pytools/idfx_test_run.py +# +# Last modified : 09/2026 +# +# Copyright(C) by : +# - Sébastien Valat (IPAG/UGA/CNRS - 2026) +# - Clément Robert (IPAG/UGA/CNRS - 2026) # and other code contributors +# # Licensed under CeCILL 2.1 License, see COPYING for more information -##################################################################################### +###################################################################################### +import copy +import glob +import importlib +import json import os import sys -import json -import glob -import copy +from contextlib import contextmanager + +import jsonschema import pytest + # idefix test class import pytools.idfx_test as tst -from pytools.idfx_test_gen import IdefixDirTestGenerator -from contextlib import contextmanager +from pytools.idfx_test_gen import IdefixDirTestGenerator + @contextmanager def moveInDir(path): - ''' + """ Change current working dir for the given directoy for what is inside the with statement. - ''' + """ oldpwd = os.getcwd() os.chdir(path) try: @@ -29,229 +42,467 @@ def moveInDir(path): finally: os.chdir(oldpwd) + class IdexPytestRunner: - ''' - Implement the Idefix pytest runner to scan and run all the tests described by the files - testme.json into the /test directory of Idefix sources. - ''' - - def __init__(self, parentScriptFile: str): - self.currentTestFile="" - self.currentTestRunner: tst.idfxTest=None - self.parentScritFile=parentScriptFile - self.filterSubdir = os.environ.get("IDEFIX_TEST_FILTER_SUBDIR", "./test/") - - def _validateNaming(self, namings: str, autoExtracted: str, file: str): - names = namings.split(',') - for n in autoExtracted.split(','): - if not n in names: - raise Exception(f"Naming parameter list not match the auto-detectection, some are missinge. You gave : '{names}', detected '{autoExtracted}' into {file}") - - def _makeVariableArgAsList(self, namings: str, variants) -> list: - # make as a list - if isinstance(variants, list) == False: - variants = [variants] - - # split namings - namings = namings.split(",") - - # loop on each - for variant in variants: - for name in namings: - if name in variant and isinstance(variant[name], list) == False: - variant[name] = [variant[name]] - - def genTests(self) -> list: - sourceDir = os.path.dirname(self.parentScritFile) - - # loop over all tests - result = [] - with moveInDir(sourceDir): - # if missing / - if self.filterSubdir != "" and self.filterSubdir[-1] != "/": - self.filterSubdir += "/" - - # walk in test dir to find the tests & sort by name - testfiles = glob.glob(self.filterSubdir + "**/testme.json", recursive=True) - testfiles.sort() - - # loop over each - for testfile in testfiles: + """ + Implement the Idefix pytest runner to scan and run all the tests described by the files + testme.json into the /test directory of Idefix sources. + """ + + def __init__(self, parentScriptFile: str): + self.currentTestFile = "" + self.currentTestRunner: tst.idfxTest = None + self.parentScritFile = parentScriptFile + self.filterSubdir = os.environ.get("IDEFIX_TEST_FILTER_SUBDIR", "./test/") + self.testmeSchema = self._loadTestmeSchema() + + def _loadTestmeSchema(self) -> dict: + scriptDir = os.path.dirname(__file__) + schemaPath = os.path.join(scriptDir, "testme.schema.json") + with open(schemaPath, "r") as fp: + return json.load(fp) + + def _validateNaming(self, namings: str, autoExtracted: str, file: str): + names = namings.split(",") + names_sorted = namings.split(",") + autoNames = autoExtracted.split(",") + autoNames_sorted = autoExtracted.split(",") + + # quick compare + names_sorted.sort() + autoNames_sorted.sort() + + # check and if error check in details to report + if names_sorted != autoNames_sorted: + for n in autoNames: + if n not in names: + raise Exception( + f"Naming parameter list not match the auto-detectection, some are missing : '{n}'\n" + f"You gave : '{names}', detected '{autoNames}' into {file}" + ) + for n in names: + if n not in autoNames: + raise Exception( + f"Naming parameter list not match the auto-detectection, some are missing : '{n}'.\n" + f"You gave : '{names}', detected '{autoNames}' into {file}" + ) + + def _makeVariableArgAsList(self, namings: str, variants) -> list: + # make as a list + if isinstance(variants, list) == False: + variants = [variants] + + # split namings + namings = namings.split(",") + + # loop on each + for variant in variants: + for name in namings: + if name in variant and isinstance(variant[name], list) == False: + variant[name] = [variant[name]] + + def genTests(self) -> list: + sourceDir = os.path.dirname(self.parentScritFile) + + # loop over all tests + result = [] + with moveInDir(sourceDir): + # if missing / + if self.filterSubdir != "" and self.filterSubdir[-1] != "/": + self.filterSubdir += "/" + + # walk in test dir to find the tests & sort by name + testfiles = glob.glob(self.filterSubdir + "**/testme.json", recursive=True) + testfiles.sort() + + # loop over each + for testfile in testfiles: + try: + # calc some paths + testfileRelPath = os.path.relpath( + testfile, os.path.join(sourceDir, "test") + ) + testfilePath = os.path.abspath( + os.path.join("test", testfileRelPath) + ) + testfileDir = os.path.dirname(testfileRelPath) + + # load json & build the inner test combinations + with open(testfilePath, "r") as fp: + # load + test = json.load(fp) + + # validate via jsonschema + try: + jsonschema.validate(instance=test, schema=self.testmeSchema) + except jsonschema.ValidationError as e: + print() + print( + "--------------- testme.json format error ---------------" + ) + print(f"Invalid format for : {testfilePath}\n{e}") + print( + "--------------------------------------------------------" + ) + print() + raise Exception(f"{testfilePath} format error !") from e + + # build generator + idefixTestGenerator = IdefixDirTestGenerator( + testfilePath, testfileDir + ) + + # extract default config & when & variants + defaultConfig = test.get("default", {}) + whenClauses = test.get("when", {}) + variants = test.get("variants", {}) + + if "namings" in test: + namings = test["namings"] + autoExtracted = idefixTestGenerator.extractNamingParameters( + variants + ) + self._validateNaming(namings, autoExtracted, testfilePath) + else: + namings = idefixTestGenerator.extractNamingParameters( + variants + ) + + # required to simplify the algos later, if var is listed as variable, we need to loop over it. + self._makeVariableArgAsList(namings, variants) + + # gen + result += idefixTestGenerator.genTestConfigs( + namings, + variants, + whenClauses=whenClauses, + defaultConfig=defaultConfig, + ) + except Exception as e: + raise Exception( + f"Fail to generate tests from {testfileRelPath}.\n{e}" + ) from e + + # ok + return result + + def buildPyHooks(self, config: dict) -> dict: + # init + result = {} + key: str + + # extract and build dict + for key, value in config.items(): + if key.startswith("callPyFunction"): + when = key.replace("callPyFunction", "") + result[when] = value + + # ok + return result + + # https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly + def importFromPath(self, moduleName: str, filePath: str): + spec = importlib.util.spec_from_file_location(moduleName, filePath) + module = importlib.util.module_from_spec(spec) + # sys.modules[moduleName] = module + spec.loader.exec_module(module) + return module + + def callPyHook(self, dir: str, hooks: dict, name: str) -> None: + # nothing to do + if name not in hooks: + return + + # split file:funcName + params = hooks[name].split(":", 1) + filePath = params[0] + funcName = params[1] + + # complete + fileFullPath = os.path.join(dir, filePath) + + # log + print("************** CALLING PY FUNCTION ****************") + print(f"Hook: {name}") + print(f"HookValue: {hooks[name]}") + print(f"Import {fileFullPath}") + print(f"Call: {funcName}") + print("***************************************************") + + # import the module + module = self.importFromPath("idefix_test_py_hooks", fileFullPath) + + # get function + function = getattr(module, funcName) + + # call it + function() + + def run(self, config: dict) -> None: + # clone before modify to not modity for caller + config = copy.deepcopy(config) + + # print config + print("***************************************************") + print(json.dumps(config, indent="\t")) + print("***************************************************") + + # extract some infos for local usage + testfile = config["testfile"] + dumpname = config["dumpname"] + testname = config["testname"] + tolerance = config.get("tolerance", 0) + definitionFile = config.get("definitionFile", "") + standardTest = config.get("standardTest", True) + nonRegressionTest = config.get("nonRegressionTest", True) + nonRegressionTestIni = config.get("nonRegressionTestIni", None) + check_file_produced = config.get("check_file_produced", []) + problemDir = os.path.dirname(testfile) + pyHooks = self.buildPyHooks(config) + + # cleanup some keyword not handled at the + # level of idx_test so we don't perturbate it + del config["dumpname"] + if "definitionFile" in config: + del config["definitionFile"] + if "tolerance" in config: + del config["tolerance"] + if "standardTest" in config: + del config["standardTest"] + if "nonRegressionTest" in config: + del config["nonRegressionTest"] + if "nonRegressionTestIni" in config: + del config["nonRegressionTestIni"] + for hook in pyHooks: + del config[f"callPyFunction{hook}"] + + # call hook before + with moveInDir(problemDir): + self.callPyHook(problemDir, pyHooks, "Before") + + # if switch from test, rebuild the runner (a runner make for one dir) + if self.currentTestFile != testfile: + self.currentTestRunner = tst.idfxTest(testfile, name=testname) + self.currentTestFile = testfile + + # run + with moveInDir(problemDir): + self._runNonRegression( + dumpname, + config["ini"], + config, + tolerance=tolerance, + definitionFile=definitionFile, + standardTest=standardTest, + nonReg=nonRegressionTest, + nonRegIni=nonRegressionTestIni, + ) + + # check produced + with moveInDir(problemDir): + for file in check_file_produced: + if not os.path.exists(file) and not self.currentTestRunner.fake: + raise Exception( + f"Don't find expected file to be produced by the run : {file} !" + ) + + # call hook after + with moveInDir(problemDir): + self.callPyHook(problemDir, pyHooks, "After") + + def _runNonRegression( + self, + dumpname, + ini, + config_override, + tolerance=0, + definitionFile="", + nonReg=True, + nonRegIni=None, + standardTest=True, + first_run_ini=None, + first_run_dumpname=None, + configure_and_compile=True, + ): + if "multirun" in config_override: + self._runNonRegMultirun( + dumpname, + ini, + config_override, + tolerance=tolerance, + nonReg=nonReg, + nonRegIni=nonRegIni, + standardTest=standardTest, + configure_and_compile=configure_and_compile, + definitionFile=definitionFile, + first_run_ini=first_run_ini, + first_run_dumpname=first_run_dumpname, + ) + else: + # single basic run + self._runNonRegSingleRun( + dumpname, + ini, + config_override, + tolerance=tolerance, + nonReg=nonReg, + standardTest=standardTest, + configure_and_compile=configure_and_compile, + definitionFile=definitionFile, + first_run_ini=first_run_ini, + first_run_dumpname=first_run_dumpname, + ) + + def _runNonRegMultirun( + self, + dumpname, + ini, + config_override, + tolerance=0, + definitionFile="", + nonReg=True, + nonRegIni=None, + standardTest=True, + first_run_ini=None, + first_run_dumpname=None, + configure_and_compile=True, + ): + # check + assert "multirun" in config_override + + # loop over runs + for run in config_override["multirun"]: + # copy config + run_config = copy.deepcopy(config_override) + + # patch a bit + del run_config["multirun"] + run_config.update(run) + nonReg = run_config.get("nonRegressionTest", nonReg) + dumpname = run_config.get("dumpname", dumpname) + if "nonRegressionTest" in run_config: + del run_config["nonRegressionTest"] + standardTest = run_config.get("standardTest", standardTest) + if "standardTest" in run_config: + del run_config["standardTest"] + + # make single run + self._runNonRegSingleRun( + dumpname, + run_config["ini"], + run_config, + definitionFile=definitionFile, + tolerance=tolerance, + nonReg=nonReg, + nonRegIni=nonRegIni, + standardTest=standardTest, + ) + + def _runNonRegSingleRun( + self, + dumpname, + ini, + config_override, + tolerance=0, + definitionFile="", + nonReg=True, + nonRegIni=None, + standardTest=True, + first_run_ini=None, + first_run_dumpname=None, + configure_and_compile=True, + ): + # build the runner + idefixTest = self.currentTestRunner + + # handle special override which should not go into + # idefixTest because it is not supported by the idfx_test layer. + config_override = copy.deepcopy(config_override) + nonRegIni = config_override.get("nonRegressionTestIni", nonRegIni) + if "nonRegressionTestIni" in config_override: + del config_override["nonRegressionTestIni"] + + # apply config + idefixTest.applyConfig(config_override) + + # recompile if needed + if configure_and_compile: + idefixTest.configure( + override=config_override, definitionFile=definitionFile + ) + idefixTest.compile() + + if first_run_ini: + idefixTest.run(inputFile=first_run_ini) + if nonReg: + idefixTest.nonRegressionTest( + filename=first_run_dumpname, tolerance=tolerance + ) + + # Test the restart option + file_mtime = {} + if not idefixTest.fake: + for file in idefixTest.restart_no_overwrite: + file_mtime[file] = os.path.getmtime(file) + + # restart + if idefixTest.restart: + restart = 1 + else: + restart = -1 + + # run + idefixTest.run(inputFile=ini, restart=restart) + + # regen ref if needed + if idefixTest.init: + idefixTest.makeReference(filename=dumpname) + + # check outputs + if standardTest: + idefixTest.standardTest() + if nonReg: + if nonRegIni: + idefixTest.inifile = nonRegIni + idefixTest.nonRegressionTest(filename=dumpname, tolerance=tolerance) + + # check that we didn't overrite the file during the restart + if not idefixTest.fake: + for file in idefixTest.restart_no_overwrite: + assert file_mtime[file] == os.path.getmtime(file), ( + f"Dump file {file} was overwritten on restart" + ) + + def validateTestmeJsons(self) -> bool: try: - # calc some paths - testfileRelPath = os.path.relpath(testfile, os.path.join(sourceDir, 'test')) - testfilePath = os.path.abspath(os.path.join('test',testfileRelPath)) - testfileDir = os.path.dirname(testfileRelPath) - - # load json & build the inner test combinations - with open(testfilePath, 'r') as fp: - test = json.load(fp) - idefixTestGenerator=IdefixDirTestGenerator(testfilePath, testfileDir) - if 'namings' in test: - namings = test['namings'] - autoExtracted = idefixTestGenerator.extractNamingParameters(test['variants']) - self._validateNaming(namings, autoExtracted, testfilePath) - else: - namings = idefixTestGenerator.extractNamingParameters(test['variants']) - - # required to simplify the algos later, if var is listed as variable, we need to loop over it. - self._makeVariableArgAsList(namings, test['variants']) - - # gen - result += idefixTestGenerator.genTestConfigs(namings, test['variants'], test.get('when', {})) + self.genTests() except Exception as e: - raise Exception(f"Fail to generate tests from {testfileRelPath} : {e}") - - # ok - return result - - def run(self, config: dict) -> None: - # clone before modify to not modity for caller - config = copy.deepcopy(config) - - # print config - print("***************************************************") - print(json.dumps(config, indent='\t')) - print("***************************************************") - - # extract some infos for local usage - testfile = config["testfile"] - dumpname = config['dumpname'] - testname = config["testname"] - tolerance = config.get("tolerance", 0) - definitionFile = config.get("definitionFile", "") - standardTest = config.get("standardTest", True) - nonRegressionTest = config.get("nonRegressionTest", True) - nonRegressionTestIni = config.get("nonRegressionTestIni", None) - check_file_produced = config.get("check_file_produced", []) - problemDir = os.path.dirname(testfile) - - # cleanup some keyword not handled at the - # level of idx_test so we don't perturbate it - del config['dumpname'] - if 'definitionFile' in config: - del config['definitionFile'] - if 'tolerance' in config: - del config['tolerance'] - if 'standardTest' in config: - del config['standardTest'] - if 'nonRegressionTest' in config: - del config['nonRegressionTest'] - if 'nonRegressionTestIni' in config: - del config['nonRegressionTestIni'] - - # if switch from test, rebuild the runner (a runner make for one dir) - if self.currentTestFile != testfile: - self.currentTestRunner = tst.idfxTest(testfile, name=testname) - self.currentTestFile = testfile - - # run - with moveInDir(problemDir): - self._runNonRegression(dumpname, config['ini'], config, tolerance=tolerance, definitionFile=definitionFile, standardTest=standardTest, nonReg=nonRegressionTest, nonRegIni=nonRegressionTestIni) - - # check produced - for file in check_file_produced: - if not os.path.exists(file): - raise Exception(f"Don't find expected file to be produced by the run : {file} !") - - def _runNonRegression(self, dumpname, ini, config_override, tolerance=0, definitionFile="", nonReg=True, nonRegIni=None, standardTest=True, first_run_ini=None,first_run_dumpname=None,configure_and_compile=True): - if 'multirun' in config_override: - self._runNonRegMultirun(dumpname, ini, config_override, tolerance=tolerance, nonReg=nonReg, nonRegIni=nonRegIni, standardTest=standardTest, configure_and_compile=configure_and_compile, definitionFile=definitionFile, first_run_ini=first_run_ini, first_run_dumpname=first_run_dumpname) - else: - # single basic run - self._runNonRegSingleRun(dumpname, ini, config_override, tolerance=tolerance, nonReg=nonReg, standardTest=standardTest, configure_and_compile=configure_and_compile, definitionFile=definitionFile, first_run_ini=first_run_ini, first_run_dumpname=first_run_dumpname) - - def _runNonRegMultirun(self, dumpname, ini, config_override, tolerance=0, definitionFile="", nonReg=True, nonRegIni=None, standardTest=True, first_run_ini=None,first_run_dumpname=None,configure_and_compile=True): - # check - assert 'multirun' in config_override - - # loop over runs - for run in config_override['multirun']: - # copy config - run_config = copy.deepcopy(config_override) - - # patch a bit - del run_config['multirun'] - run_config.update(run) - nonReg=run_config.get('nonRegressionTest', nonReg) - dumpname=run_config.get('dumpname', dumpname) - if 'nonRegressionTest' in run_config: - del run_config['nonRegressionTest'] - standardTest=run_config.get('standardTest', standardTest) - if 'standardTest' in run_config: - del run_config['standardTest'] - - # make single run - self._runNonRegSingleRun(dumpname, run_config['ini'], run_config, definitionFile=definitionFile, tolerance=tolerance, nonReg=nonReg, nonRegIni=nonRegIni, standardTest=standardTest) - - def _runNonRegSingleRun(self, dumpname, ini, config_override, tolerance=0, definitionFile="", nonReg=True, nonRegIni=None, standardTest=True, first_run_ini=None,first_run_dumpname=None,configure_and_compile=True): - # build the runner - idefixTest = self.currentTestRunner - - # handle special override which should not go into - # idefixTest because it is not supported by the idfx_test layer. - config_override = copy.deepcopy(config_override) - nonRegIni = config_override.get("nonRegressionTestIni", nonRegIni) - if 'nonRegressionTestIni' in config_override: - del config_override['nonRegressionTestIni'] - - # apply config - idefixTest.applyConfig(config_override) - - # recompile if needed - if configure_and_compile: - idefixTest.configure(override=config_override, definitionFile=definitionFile) - idefixTest.compile() - - if first_run_ini: - idefixTest.run(inputFile=first_run_ini) - if nonReg: - idefixTest.nonRegressionTest(filename=first_run_dumpname, tolerance=tolerance) - - # Test the restart option - file_mtime={} - if not idefixTest.fake: - for file in idefixTest.restart_no_overwrite: - file_mtime[file] = os.path.getmtime(file) - - # restart - if idefixTest.restart: - restart = 1 - else: - restart = -1 - - # run - idefixTest.run(inputFile=ini, restart=restart) - - # regen ref if needed - if idefixTest.init: - idefixTest.makeReference(filename=dumpname) - - # check outputs - if standardTest: - idefixTest.standardTest() - if nonReg: - if nonRegIni: - idefixTest.inifile = nonRegIni - idefixTest.nonRegressionTest(filename=dumpname, tolerance=tolerance) - - # check that we didn't overrite the file during the restart - if not idefixTest.fake: - for file in idefixTest.restart_no_overwrite: - assert file_mtime[file] == os.path.getmtime(file), f"Dump file {file} was overwritten on restart" - - def main(self, all: bool = False): - if all: - sys.argv.append("-all") - idefixTest = tst.idfxTest(self.parentScritFile, name="main") - os.environ["IDEFIX_TEST_FILTER_SUBDIR"] = idefixTest.filterSubdir - - if idefixTest.all: - pytest.main(['-v', '--no-header', '--junit-xml=idefix-tests.junit.xml', '--tb=short'] + idefixTest.remainingArgs + [self.parentScritFile]) - else: - assert False, "Not yet supported !" - #elif self.check: - # idefixTest.checkOnly(filename=dumpname, tolerance=tolerance) - #else: - # for ini in ini_list: - # self.runNonRegression(dumpname, ini, {}, tolerance=tolerance) + print(f"{e}") + return False + return True + + def main(self, all: bool = False): + if all: + sys.argv.append("-all") + idefixTest = tst.idfxTest(self.parentScritFile, name="main") + os.environ["IDEFIX_TEST_FILTER_SUBDIR"] = idefixTest.filterSubdir + + if idefixTest.all: + status = pytest.main( + [ + "-v", + "--no-header", + "--junit-xml=idefix-tests.junit.xml", + "--tb=short", + ] + + idefixTest.remainingArgs + + [self.parentScritFile] + ) + sys.exit(status) + else: + raise NotImplementedError("Not yet supported !") + # elif self.check: + # idefixTest.checkOnly(filename=dumpname, tolerance=tolerance) + # else: + # for ini in ini_list: + # self.runNonRegression(dumpname, ini, {}, tolerance=tolerance) diff --git a/pytools/sod.py b/pytools/sod.py index 07a60d2cc..084317a45 100644 --- a/pytools/sod.py +++ b/pytools/sod.py @@ -1,3 +1,18 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file pytools/sod.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +# - Clément Robert (IPAG/UGA/CNRS - 2021 - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + """ Created on Thu Mar 5 11:27:16 2020 @@ -11,7 +26,7 @@ import scipy.optimize -def sound_speed(gamma, pressure, density, dustFrac=0.): +def sound_speed(gamma, pressure, density, dustFrac=0.0): """ Calculate sound speed, scaled by the dust fraction according to: @@ -21,27 +36,28 @@ def sound_speed(gamma, pressure, density, dustFrac=0.): Where :math:`\epsilon` is the dustFrac """ scale = np.sqrt(1 - dustFrac) - return np.sqrt(gamma * pressure/ density) * scale + return np.sqrt(gamma * pressure / density) * scale + -def shock_tube_function(p4, p1, p5, rho1, rho5, gamma, dustFrac=0.): +def shock_tube_function(p4, p1, p5, rho1, rho5, gamma, dustFrac=0.0): """ Shock tube equation """ - z = (p4 / p5 - 1.) + z = p4 / p5 - 1.0 c1 = sound_speed(gamma, p1, rho1, dustFrac) c5 = sound_speed(gamma, p5, rho5, dustFrac) - gm1 = gamma - 1. - gp1 = gamma + 1. - g2 = 2. * gamma + gm1 = gamma - 1.0 + gp1 = gamma + 1.0 + g2 = 2.0 * gamma - fact = gm1 / g2 * (c5 / c1) * z / np.sqrt(1. + gp1 / g2 * z) - fact = (1. - fact) ** (g2 / gm1) + fact = gm1 / g2 * (c5 / c1) * z / np.sqrt(1.0 + gp1 / g2 * z) + fact = (1.0 - fact) ** (g2 / gm1) return p1 * fact - p4 -def calculate_regions(pl, ul, rhol, pr, ur, rhor, gamma=1.4, dustFrac=0.): +def calculate_regions(pl, ul, rhol, pr, ur, rhor, gamma=1.4, dustFrac=0.0): """ Compute regions :rtype : tuple @@ -68,18 +84,18 @@ def calculate_regions(pl, ul, rhol, pr, ur, rhor, gamma=1.4, dustFrac=0.): p4 = scipy.optimize.fsolve(shock_tube_function, p1, (p1, p5, rho1, rho5, gamma))[0] # compute post-shock density and velocity - z = (p4 / p5 - 1.) + z = p4 / p5 - 1.0 c5 = sound_speed(gamma, p5, rho5, dustFrac) - gm1 = gamma - 1. - gp1 = gamma + 1. + gm1 = gamma - 1.0 + gp1 = gamma + 1.0 gmfac1 = 0.5 * gm1 / gamma gmfac2 = 0.5 * gp1 / gamma - fact = np.sqrt(1. + gmfac2 * z) + fact = np.sqrt(1.0 + gmfac2 * z) u4 = c5 * z / (gamma * fact) - rho4 = rho5 * (1. + gmfac2 * z) / (1. + gmfac1 * z) + rho4 = rho5 * (1.0 + gmfac2 * z) / (1.0 + gmfac1 * z) # shock speed w = c5 * fact @@ -87,11 +103,11 @@ def calculate_regions(pl, ul, rhol, pr, ur, rhor, gamma=1.4, dustFrac=0.): # compute values at foot of rarefaction p3 = p4 u3 = u4 - rho3 = rho1 * (p3 / p1)**(1. / gamma) + rho3 = rho1 * (p3 / p1) ** (1.0 / gamma) return (p1, rho1, u1), (p3, rho3, u3), (p4, rho4, u4), (p5, rho5, u5), w -def calc_positions(pl, pr, region1, region3, w, xi, t, gamma, dustFrac=0.): +def calc_positions(pl, pr, region1, region3, w, xi, t, gamma, dustFrac=0.0): """ :return: tuple of positions in the following order -> Head of Rarefaction: xhd, Foot of Rarefaction: xft, @@ -123,21 +139,39 @@ def region_states(pl, pr, region1, region3, region4, region5): where the value is a string, obviously """ if pl > pr: - return {'Region 1': region1, - 'Region 2': 'RAREFACTION', - 'Region 3': region3, - 'Region 4': region4, - 'Region 5': region5} + return { + "Region 1": region1, + "Region 2": "RAREFACTION", + "Region 3": region3, + "Region 4": region4, + "Region 5": region5, + } else: - return {'Region 1': region5, - 'Region 2': region4, - 'Region 3': region3, - 'Region 4': 'RAREFACTION', - 'Region 5': region1} - - -def create_arrays(pl, pr, xl, xr, positions, state1, state3, state4, state5, - npts, gamma, t, xi, dustFrac=0.): + return { + "Region 1": region5, + "Region 2": region4, + "Region 3": region3, + "Region 4": "RAREFACTION", + "Region 5": region1, + } + + +def create_arrays( + pl, + pr, + xl, + xr, + positions, + state1, + state3, + state4, + state5, + npts, + gamma, + t, + xi, + dustFrac=0.0, +): """ :return: tuple of x, p, rho and u values across the domain of interest """ @@ -146,8 +180,8 @@ def create_arrays(pl, pr, xl, xr, positions, state1, state3, state4, state5, p3, rho3, u3 = state3 p4, rho4, u4 = state4 p5, rho5, u5 = state5 - gm1 = gamma - 1. - gp1 = gamma + 1. + gm1 = gamma - 1.0 + gp1 = gamma + 1.0 x_arr = np.linspace(xl, xr, npts) rho = np.zeros(npts, dtype=float) @@ -161,10 +195,10 @@ def create_arrays(pl, pr, xl, xr, positions, state1, state3, state4, state5, p[i] = p1 u[i] = u1 elif x < xft: - u[i] = 2. / gp1 * (c1 + (x - xi) / t) - fact = 1. - 0.5 * gm1 * u[i] / c1 - rho[i] = rho1 * fact ** (2. / gm1) - p[i] = p1 * fact ** (2. * gamma / gm1) + u[i] = 2.0 / gp1 * (c1 + (x - xi) / t) + fact = 1.0 - 0.5 * gm1 * u[i] / c1 + rho[i] = rho1 * fact ** (2.0 / gm1) + p[i] = p1 * fact ** (2.0 * gamma / gm1) elif x < xcd: rho[i] = rho3 p[i] = p3 @@ -192,10 +226,10 @@ def create_arrays(pl, pr, xl, xr, positions, state1, state3, state4, state5, p[i] = p3 u[i] = -u3 elif x < xhd: - u[i] = -2. / gp1 * (c1 + (xi - x) / t) - fact = 1. + 0.5 * gm1 * u[i] / c1 - rho[i] = rho1 * fact ** (2. / gm1) - p[i] = p1 * fact ** (2. * gamma / gm1) + u[i] = -2.0 / gp1 * (c1 + (xi - x) / t) + fact = 1.0 + 0.5 * gm1 * u[i] / c1 + rho[i] = rho1 * fact ** (2.0 / gm1) + p[i] = p1 * fact ** (2.0 * gamma / gm1) else: rho[i] = rho1 p[i] = p1 @@ -204,8 +238,7 @@ def create_arrays(pl, pr, xl, xr, positions, state1, state3, state4, state5, return x_arr, p, rho, u -def solve(left_state, right_state, geometry, t, gamma=1.4, npts=500, - dustFrac=0.): +def solve(left_state, right_state, geometry, t, gamma=1.4, npts=500, dustFrac=0.0): """ Solves the Sod shock tube problem (i.e. riemann problem) of discontinuity across an interface. @@ -246,34 +279,57 @@ def solve(left_state, right_state, geometry, t, gamma=1.4, npts=500, # basic checking if xl >= xr: - print('xl has to be less than xr!') + print("xl has to be less than xr!") exit() if xi >= xr or xi <= xl: - print('xi has in between xl and xr!') + print("xi has in between xl and xr!") exit() # calculate regions - region1, region3, region4, region5, w = \ - calculate_regions(pl, ul, rhol, pr, ur, rhor, gamma, dustFrac) + region1, region3, region4, region5, w = calculate_regions( + pl, ul, rhol, pr, ur, rhor, gamma, dustFrac + ) regions = region_states(pl, pr, region1, region3, region4, region5) # calculate positions - x_positions = calc_positions(pl, pr, region1, region3, w, xi, t, gamma, - dustFrac) + x_positions = calc_positions(pl, pr, region1, region3, w, xi, t, gamma, dustFrac) - pos_description = ('Head of Rarefaction', 'Foot of Rarefaction', - 'Contact Discontinuity', 'Shock') - positions = dict(zip(pos_description, x_positions)) + pos_description = ( + "Head of Rarefaction", + "Foot of Rarefaction", + "Contact Discontinuity", + "Shock", + ) + positions = dict(zip(pos_description, x_positions, strict=True)) # create arrays - x, p, rho, u = create_arrays(pl, pr, xl, xr, x_positions, - region1, region3, region4, region5, - npts, gamma, t, xi, dustFrac) - - energy = p/(rho * (gamma - 1.0)) - rho_total = rho/(1.0 - dustFrac) - val_dict = {'x':x, 'p':p, 'rho':rho, 'u':u, 'energy':energy, - 'rho_total':rho_total} + x, p, rho, u = create_arrays( + pl, + pr, + xl, + xr, + x_positions, + region1, + region3, + region4, + region5, + npts, + gamma, + t, + xi, + dustFrac, + ) + + energy = p / (rho * (gamma - 1.0)) + rho_total = rho / (1.0 - dustFrac) + val_dict = { + "x": x, + "p": p, + "rho": rho, + "u": u, + "energy": energy, + "rho_total": rho_total, + } return positions, regions, val_dict diff --git a/pytools/testme.schema.json b/pytools/testme.schema.json new file mode 100644 index 000000000..7ea0b3872 --- /dev/null +++ b/pytools/testme.schema.json @@ -0,0 +1,157 @@ +{ + "title": "testme", + "description": "Schema to validate the testme.json files in the test suite of Idefix.", + "type": "object", + "properties": { + "namings": { + "type": "string" + }, + "default": { "$ref": "#/$defs/config" }, + "variants": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "ini": { + "anyOf": [ + { "type": "string" }, + { "type": "array", "items": { "type": "string" } } + ] + }, + "definitionFile": { + "anyOf": [ + { "type": "string" }, + { "type": "array", "items": { "type": "string" } } + ] + }, + "dumpname": { + "anyOf": [ + { "type": "string" }, + { "type": "array", "items": { "type": "string" } } + ] + }, + "tolerance": { + "anyOf": [ + { "type": "number" }, + { "type": "array", "items": { "type": "number" } } + ] + }, + "nonRegressionTest": { + "anyOf": [ + { "type": "boolean" }, + { "type": "array", "items": { "type": "boolean" } } + ] + }, + "standardTest": { + "anyOf": [ + { "type": "boolean" }, + { "type": "array", "items": { "type": "boolean" } } + ] + }, + "noplot": { + "anyOf": [ + { "type": "boolean" }, + { "type": "array", "items": { "type": "boolean" } } + ] + }, + "reconstruction": { + "anyOf": [ + { "type": "integer" }, + { "type": "array", "items": { "type": "integer" } } + ] + }, + "dec": { "type": "array", "items": { "type": "number"} }, + "single": { + "anyOf": [ + { "type": "boolean" }, + { "type": "array", "items": { "type": "boolean" } } + ] + }, + "vectPot": { + "anyOf": [ + { "type": "boolean" }, + { "type": "array", "items": { "type": "boolean" } } + ] + }, + "mpi": { + "anyOf": [ + { "type": "boolean" }, + { "type": "array", "items": { "type": "boolean" } } + ] + }, + "mpiGpuForceCopy": { + "anyOf": [ + { "type": "boolean" }, + { "type": "array", "items": { "type": "boolean" } } + ] + }, + "mpiMode": { + "anyOf": [ + { "enum": ["Default", "Persistent", "Blocking", "NonBlocking" ] }, + { "type": "array", "items": { "enum": ["Default", "Persistent", "Blocking", "NonBlocking" ] } } + ] + }, + "restart": { + "anyOf": [ + { "type": "boolean" }, + { "type": "array", "items": { "type": "boolean" } } + ] + }, + "callPyFunctionBefore": { + "anyOf": [ + { "type": "string" }, + { "type": "array", "items": { "type": "string" } } + ] + }, + "callPyFunctionAfter": { + "anyOf": [ + { "type": "string" }, + { "type": "array", "items": { "type": "string" } } + ] + }, + "check_file_produced": { "type": "array", "items": { "type": "string"} }, + "restart_no_overwrite": { "type": "array", "items": { "type": "string"} }, + "multirun": { + "type": "array", + "items": { "$ref": "#/$defs/config" } + } + } + } + } + }, + "when": { + "type": "object", + "properties": { + "condition": { "$ref": "#/$defs/config" }, + "apply": { "$ref": "#/$defs/config" } + } + }, + "$defs": { + "config": { + "type": "object", + "additionalProperties": false, + "properties": { + "ini": { "type": "string" }, + "definitionFile": { "type": "string" }, + "dumpname": { "type": "string" }, + "tolerance": { "type": "number" }, + "nonRegressionTest": { "type": "boolean" }, + "standardTest": { "type": "boolean" }, + "noplot": { "type": "boolean" }, + "reconstruction": { "type": "integer" }, + "dec": { "type": "array", "items": { "type": "number"} }, + "single": { "type": "boolean" }, + "vectPot": { "type": "boolean" }, + "mpi": { "type": "boolean" }, + "mpiGpuForceCopy": { "type": "boolean" }, + "mpiMode": { "enum": ["Default", "Persistent", "Blocking", "NonBlocking" ] }, + "restart": { "type": "boolean" }, + "callPyFunctionBefore": { "type": "string" }, + "callPyFunctionAfter": { "type": "string" }, + "check_file_produced": { "type": "array", "items": { "type": "string"} }, + "restart_no_overwrite": { "type": "array", "items": { "type": "string"} } + } + } + } +} diff --git a/pytools/tests/test/pb1/testme.json b/pytools/tests/test/pb1/testme.json index d8ddad44f..25e225f93 100644 --- a/pytools/tests/test/pb1/testme.json +++ b/pytools/tests/test/pb1/testme.json @@ -1,11 +1,13 @@ { + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "reconstruction": 2, + "tolerance": 1e-14 + }, "variants": [ { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-implicit.ini"], - "noplot": true, - "reconstruction": 2, - "tolerance": 1e-14 + "ini": ["idefix.ini","idefix-implicit.ini"] } ] } diff --git a/pytools/tests/test/pb2/testme.json b/pytools/tests/test/pb2/testme.json index 96c1753ab..6401a69cd 100644 --- a/pytools/tests/test/pb2/testme.json +++ b/pytools/tests/test/pb2/testme.json @@ -1,18 +1,18 @@ { + "default": { + "dumpname": "dump.0001.dmp", + "reconstruction": 2, + "tolerance": 1e-14 + }, "variants": [ { - "dumpname": "dump.0001.dmp", "ini": ["idefix.ini","idefix-implicit.ini"], - "noplot": true, - "reconstruction": 2, - "tolerance": 1e-14 + "noplot": true }, { "dumpname": "dump.0001.dmp", "ini": ["idefix.ini","idefix-implicit.ini"], - "noplot": false, - "reconstruction": 2, - "tolerance": 1e-14 + "noplot": false } ] } diff --git a/pytools/tests/test_idfx_test_gen.py b/pytools/tests/test_idfx_test_gen.py index fc4f6261e..ffa68494a 100644 --- a/pytools/tests/test_idfx_test_gen.py +++ b/pytools/tests/test_idfx_test_gen.py @@ -1,208 +1,218 @@ -##################################################################################### +###################################################################################### # Idefix MHD astrophysical code -# Copyright(C) Sébastien Valat +# +# Source file pytools/tests/test_idfx_test_gen.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Sébastien Valat (IPAG/UGA/CNRS - 2026) +# - Clément Robert (IPAG/UGA/CNRS - 2026) # and other code contributors +# # Licensed under CeCILL 2.1 License, see COPYING for more information -##################################################################################### +###################################################################################### -from ..idfx_test_gen import IdefixDirTestGenerator import pytest +from ..idfx_test_gen import IdefixDirTestGenerator + + def test_extractNamingParameters(): - # build generator - gen = IdefixDirTestGenerator(__file__, "unit-test") - - lst = gen.extractNamingParameters([ - { - "dec": [1,2,3], - "a": 10, - "b": 11, - "c": [True, False] - }, - { - "dec": [1,2,4], - "a": 10, - "b": 12, - "d": [True, False] - }, - ]) - - # valid - assert lst == 'b,c,d' + # build generator + gen = IdefixDirTestGenerator(__file__, "unit-test") + + lst = gen.extractNamingParameters( + [ + { + "dec": [1, 2, 3], + "a": 10, + "b": 11, + "c": [True, False], + }, + { + "dec": [1, 2, 4], + "a": 10, + "b": 12, + "d": [True, False], + }, + ] + ) + + # valid + assert lst == "b,c,d" + def test_genNextLevelCombinations(): - # build generator - gen = IdefixDirTestGenerator(__file__, "unit-test") - - # init with single element - core = {} - init = [core] - - # gen first set of combinations - lst1 = gen._genNextLevelCombinations(init, "mpi", [True, False]) - assert lst1 == [ - {"mpi": True}, - {"mpi": False}, - ] - - # gen first second set of combinations - lst3 = gen._genNextLevelCombinations(lst1, "name", ["a", "b"]) - assert lst3 == [ - {"mpi": True, "name": "a"}, - {"mpi": True, "name": "b"}, - {"mpi": False, "name": "a"}, - {"mpi": False, "name": "b"}, - ] + # build generator + gen = IdefixDirTestGenerator(__file__, "unit-test") + + # init with single element + core = {} + init = [core] + + # gen first set of combinations + lst1 = gen._genNextLevelCombinations(init, "mpi", [True, False]) + assert lst1 == [{"mpi": True}, {"mpi": False}] + + # gen first second set of combinations + lst3 = gen._genNextLevelCombinations(lst1, "name", ["a", "b"]) + assert lst3 == [ + {"mpi": True, "name": "a"}, + {"mpi": True, "name": "b"}, + {"mpi": False, "name": "a"}, + {"mpi": False, "name": "b"}, + ] + def test_genOneConfigSeries(): - # build generator - gen = IdefixDirTestGenerator(__file__, "unit-test") - - # gen - result = gen._genOneConfigSeries("mpi,name", { - "mpi": [True, False], - "name": ["a", "b"] - }) - - # check - assert result == [ - { - 'mpi': True, - 'name': 'a', - },{ - 'mpi': True, - 'name': 'b', - },{ - 'mpi': False, - 'name': 'a', - },{ - 'mpi': False, - 'name': 'b', - }, - ] + # build generator + gen = IdefixDirTestGenerator(__file__, "unit-test") + + # gen + result = gen._genOneConfigSeries( + "mpi,name", {"mpi": [True, False], "name": ["a", "b"]} + ) + + # check + assert result == [ + {"mpi": True, "name": "a"}, + {"mpi": True, "name": "b"}, + {"mpi": False, "name": "a"}, + {"mpi": False, "name": "b"}, + ] + def test_matchWhenClause_single(): - # build generator - gen = IdefixDirTestGenerator(__file__, "unit-test") + # build generator + gen = IdefixDirTestGenerator(__file__, "unit-test") + + # calls + assert gen._matchWhenClause({"a": 10, "b": 11}, {"a": 10}) == True + assert gen._matchWhenClause({"a": 10, "b": 11}, {"a": 11}) == False + assert gen._matchWhenClause({"a": 10, "b": 11}, {"b": 11}) == True + assert gen._matchWhenClause({"a": 10, "b": 11}, {"b": 10}) == False - # calls - assert gen._matchWhenClause({"a":10, "b": 11}, {"a":10}) == True - assert gen._matchWhenClause({"a":10, "b": 11}, {"a":11}) == False - assert gen._matchWhenClause({"a":10, "b": 11}, {"b":11}) == True - assert gen._matchWhenClause({"a":10, "b": 11}, {"b":10}) == False def test_matchWhenClause_and(): - # build generator - gen = IdefixDirTestGenerator(__file__, "unit-test") + # build generator + gen = IdefixDirTestGenerator(__file__, "unit-test") + + # calls + assert gen._matchWhenClause({"a": 10, "b": 11}, {"a": 10, "b": 11}) == True + assert gen._matchWhenClause({"a": 10, "b": 11}, {"a": 11, "b": 11}) == False - # calls - assert gen._matchWhenClause({"a":10, "b": 11}, {"a":10, "b":11}) == True - assert gen._matchWhenClause({"a":10, "b": 11}, {"a":11, "b":11}) == False def test_applyWhen_none(): - # build generator - gen = IdefixDirTestGenerator(__file__, "unit-test") + # build generator + gen = IdefixDirTestGenerator(__file__, "unit-test") - # call when clause - res = gen._applyWhen({ - "a": 10, - "b": 11 - }, when={}) + # call when clause + res = gen._applyWhen({"a": 10, "b": 11}, when={}) + + # check result + assert res == {"a": 10, "b": 11} - # check result - assert res == {"a": 10, "b": 11} def test_applyWhen_single_apply_yes(): - # build generator - gen = IdefixDirTestGenerator(__file__, "unit-test") - - # call when clause - res = gen._applyWhen({ - "a": 10, - "b": 11 - }, when={ - "conditions": { - "a": 10, - }, - "apply": { - "b": 12 - } - }) - - # check result - assert res == {"a": 10, "b": 12} + # build generator + gen = IdefixDirTestGenerator(__file__, "unit-test") + + # call when clause + res = gen._applyWhen( + {"a": 10, "b": 11}, + when={ + "conditions": {"a": 10}, + "apply": {"b": 12}, + }, + ) + + # check result + assert res == {"a": 10, "b": 12} + def test_applyWhen_single_apply_no(): - # build generator - gen = IdefixDirTestGenerator(__file__, "unit-test") - - # call when clause - res = gen._applyWhen({ - "a": 10, - "b": 11 - }, when={ - "conditions": { - "a": 9, - }, - "apply": { - "b": 12 - } - }) - - # check result - assert res == {"a": 10, "b": 11} + # build generator + gen = IdefixDirTestGenerator(__file__, "unit-test") + + # call when clause + res = gen._applyWhen( + {"a": 10, "b": 11}, + when={ + "conditions": {"a": 9}, + "apply": {"b": 12}, + }, + ) + + # check result + assert res == {"a": 10, "b": 11} + def test_applyWhen_list_apply_yes(): - # build generator - gen = IdefixDirTestGenerator(__file__, "unit-test") - - # call when clause - res = gen._applyWhen({ - "a": 10, - "b": 11 - }, when=[ - { - "conditions": { - "a": 10, - }, - "apply": { - "b": 12 - } - }, - { - "conditions": { - "a": 13, - }, - "apply": { - "b": 13 - } - } - ]) - - # check result - assert res == {"a": 10, "b": 12} + # build generator + gen = IdefixDirTestGenerator(__file__, "unit-test") + + # call when clause + res = gen._applyWhen( + {"a": 10, "b": 11}, + when=[ + { + "conditions": {"a": 10}, + "apply": {"b": 12}, + }, + { + "conditions": {"a": 13}, + "apply": {"b": 13}, + }, + ], + ) + + # check result + assert res == {"a": 10, "b": 12} + def test_gen_full(): - # build generator - gen = IdefixDirTestGenerator(__file__, "unit-test") - - # gen - result = gen.genTestConfigs("mpi,name", { - "mpi": [True, False], - "name": ["a", "b"] - }, { - "conditions": { - "mpi": True - }, - "apply": { - "extra": 10, - } - }) - - # check - assert result == [ - pytest.param({'mpi': True, 'name': 'a', 'testfile': __file__, 'testname': 'unit-test', 'extra': 10}, id='unit-test-mpi-a'), - pytest.param({'mpi': True, 'name': 'b', 'testfile': __file__, 'testname': 'unit-test', 'extra': 10}, id='unit-test-mpi-b'), - pytest.param({'mpi': False, 'name': 'a', 'testfile': __file__, 'testname': 'unit-test'}, id='unit-test-a'), - pytest.param({'mpi': False, 'name': 'b', 'testfile': __file__, 'testname': 'unit-test'}, id='unit-test-b'), - ] + # build generator + gen = IdefixDirTestGenerator(__file__, "unit-test") + + # gen + result = gen.genTestConfigs( + "mpi,name", + {"mpi": [True, False], "name": ["a", "b"]}, + { + "conditions": {"mpi": True}, + "apply": {"extra": 10}, + }, + ) + + # check + assert result == [ + pytest.param( + { + "mpi": True, + "name": "a", + "testfile": __file__, + "testname": "unit-test", + "extra": 10, + }, + id="unit-test-mpi-a", + ), + pytest.param( + { + "mpi": True, + "name": "b", + "testfile": __file__, + "testname": "unit-test", + "extra": 10, + }, + id="unit-test-mpi-b", + ), + pytest.param( + {"mpi": False, "name": "a", "testfile": __file__, "testname": "unit-test"}, + id="unit-test-a", + ), + pytest.param( + {"mpi": False, "name": "b", "testfile": __file__, "testname": "unit-test"}, + id="unit-test-b", + ), + ] diff --git a/pytools/tests/test_idfx_test_run.py b/pytools/tests/test_idfx_test_run.py index 8843705ee..da9702e9e 100644 --- a/pytools/tests/test_idfx_test_run.py +++ b/pytools/tests/test_idfx_test_run.py @@ -1,88 +1,111 @@ -##################################################################################### +###################################################################################### # Idefix MHD astrophysical code -# Copyright(C) Sébastien Valat +# +# Source file pytools/tests/test_idfx_test_run.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Sébastien Valat (IPAG/UGA/CNRS - 2026) +# - Clément Robert (IPAG/UGA/CNRS - 2026) # and other code contributors +# # Licensed under CeCILL 2.1 License, see COPYING for more information -##################################################################################### +###################################################################################### -from ..idfx_test_run import IdexPytestRunner -import pytest import os +import pytest + +from ..idfx_test_run import IdexPytestRunner + + def test_genTests(): - # build runner - runner = IdexPytestRunner(__file__) + # build runner + runner = IdexPytestRunner(__file__) - # dir - dir = os.path.dirname(__file__) + # dir + dir = os.path.dirname(__file__) - # generate - result = runner.genTests() - assert result == [ - pytest.param( - { - 'dumpname': 'dump.0001.dmp', - 'noplot': True, - 'reconstruction': 2, - 'tolerance': 1e-14, - 'ini': 'idefix.ini', - 'testfile': dir + '/test/pb1/testme.json', - 'testname': 'pb1' - }, marks=(), id='pb1-idefix.ini' - ), - pytest.param( - { - 'dumpname': 'dump.0001.dmp', - 'noplot': True, - 'reconstruction': 2, - 'tolerance': 1e-14, - 'ini': 'idefix-implicit.ini', - 'testfile': dir + '/test/pb1/testme.json', - 'testname': 'pb1' - }, marks=(), id='pb1-idefix-implicit.ini' - ), - pytest.param( - { - 'dumpname': 'dump.0001.dmp', - 'noplot': True, - 'reconstruction': 2, - 'tolerance': 1e-14, - 'ini': 'idefix.ini', - 'testfile': dir + '/test/pb2/testme.json', - 'testname': 'pb2' - }, marks=(), id='pb2-idefix.ini-noplot' - ), - pytest.param( - { - 'dumpname': 'dump.0001.dmp', - 'noplot': True, - 'reconstruction': 2, - 'tolerance': 1e-14, - 'ini': 'idefix-implicit.ini', - 'testfile': dir + '/test/pb2/testme.json', - 'testname': 'pb2' - }, marks=(), id='pb2-idefix-implicit.ini-noplot' - ), - pytest.param( - { - 'dumpname': 'dump.0001.dmp', - 'noplot': False, - 'reconstruction': 2, - 'tolerance': 1e-14, - 'ini': 'idefix.ini', - 'testfile': dir + '/test/pb2/testme.json', - 'testname': 'pb2' - }, marks=(), id='pb2-idefix.ini' - ), - pytest.param( - { - 'dumpname': 'dump.0001.dmp', - 'noplot': False, - 'reconstruction': 2, - 'tolerance': 1e-14, - 'ini': 'idefix-implicit.ini', - 'testfile': dir + '/test/pb2/testme.json', - 'testname': 'pb2' - }, marks=(), id='pb2-idefix-implicit.ini' - ), - ] + # generate + result = runner.genTests() + assert result == [ + pytest.param( + { + "dumpname": "dump.0001.dmp", + "noplot": True, + "reconstruction": 2, + "tolerance": 1e-14, + "ini": "idefix.ini", + "testfile": dir + "/test/pb1/testme.json", + "testname": "pb1", + }, + marks=(), + id="pb1-idefix.ini", + ), + pytest.param( + { + "dumpname": "dump.0001.dmp", + "noplot": True, + "reconstruction": 2, + "tolerance": 1e-14, + "ini": "idefix-implicit.ini", + "testfile": dir + "/test/pb1/testme.json", + "testname": "pb1", + }, + marks=(), + id="pb1-idefix-implicit.ini", + ), + pytest.param( + { + "dumpname": "dump.0001.dmp", + "noplot": True, + "reconstruction": 2, + "tolerance": 1e-14, + "ini": "idefix.ini", + "testfile": dir + "/test/pb2/testme.json", + "testname": "pb2", + }, + marks=(), + id="pb2-idefix.ini-noplot", + ), + pytest.param( + { + "dumpname": "dump.0001.dmp", + "noplot": True, + "reconstruction": 2, + "tolerance": 1e-14, + "ini": "idefix-implicit.ini", + "testfile": dir + "/test/pb2/testme.json", + "testname": "pb2", + }, + marks=(), + id="pb2-idefix-implicit.ini-noplot", + ), + pytest.param( + { + "dumpname": "dump.0001.dmp", + "noplot": False, + "reconstruction": 2, + "tolerance": 1e-14, + "ini": "idefix.ini", + "testfile": dir + "/test/pb2/testme.json", + "testname": "pb2", + }, + marks=(), + id="pb2-idefix.ini", + ), + pytest.param( + { + "dumpname": "dump.0001.dmp", + "noplot": False, + "reconstruction": 2, + "tolerance": 1e-14, + "ini": "idefix-implicit.ini", + "testfile": dir + "/test/pb2/testme.json", + "testname": "pb2", + }, + marks=(), + id="pb2-idefix-implicit.ini", + ), + ] diff --git a/pytools/update_file_headers.json b/pytools/update_file_headers.json new file mode 100644 index 000000000..dfe74083e --- /dev/null +++ b/pytools/update_file_headers.json @@ -0,0 +1,202 @@ +{ + "header_keys": { + "PROJECT": "Idefix MHD astrophysical code", + "DATE": "@LAST_EDIT_MONTH_YEAR@", + "LICENSE": "CeCILL-C" + }, + "message": [ + "@PROJECT@", + "", + "Source file @FILE@", + "", + "Last modified : @DATE@", + "", + "Copyright(C) by :", + "@COPYRIGHTS@", + "and other code contributors", + "", + "Licensed under CeCILL 2.1 License, see COPYING for more information" + ], + "width": 86, + "specific": { + }, + "extra_authors": [ + { + "name": "Gaylor Wafflard", + "mail": "gaylor.wafflard@univ-grenoble-alpes.fr", + "commits": [ + "158f2aa3a35148bb2a992ae24bb8f813a5965034", + "18c2b7301334a291b1acfcbed431b71607cb433d", + "1087e858d72fc99f1e37aa2276bfdb79b3007ac4", + "8d13e69a6193db9fd4cdb7ef292033790c54f457", + "d00a8eb17198dfa2b9bd924f1245f7fb00844b22" + ] + } + ], + "authors_name_fixes": { + "pre-commit-ci-lite[bot]": null, + "Geoffroy Lesur geoffroy.lesur@univ-grenoble-alpes.fr": "Geoffroy Lesur", + "nscepi": "Nicolas Scepi", + "Soufiane BAGHDADI": "Soufiane Baghdadi", + "vdbma": "Marc Van den Bossche", + "marc": "Marc Van den Bossche", + "Hal Bal": "Victor Réville" + }, + "replace_mails": { + "sebastien.valat.dev@orange.fr": "sebastien.valat@univ-grenoble-alpes.fr", + "63753204+nscepi@users.noreply.github.com": "nicolas.scepi@univ-grenoble-alpes.fr", + "nicolas.scepi@gmail.com": "nicolas.scepi@univ-grenoble-alpes.fr", + "geoffroy.lesur@obs.ujf-grenoble.fr": "geoffroy.lesur@univ-grenoble-alpes.fr", + "93188557+vdbma@users.noreply.github.com": "mbossche@aip.de", + "vandenbossche.marc@hotmail.com": "mbossche@aip.de", + "victorreville@gmail.com": "vreville@irap.omp.eu", + "cr52@protonmail.com": "clement.robert@univ-grenoble-alpes.fr", + "89980449+Anto6453@users.noreply.github.com": "antonin.borderies@ens-lyon.fr", + "lesur@": "geoffroy.lesur@univ-grenoble-alpes.fr", + "lesurg@": "geoffroy.lesur@univ-grenoble-alpes.fr", + "gelesur@": "geoffroy.lesur@univ-grenoble-alpes.fr", + "glesur@": "geoffroy.lesur@univ-grenoble-alpes.fr", + "glesurg@": "geoffroy.lesur@univ-grenoble-alpes.fr", + "geoffroy@": "geoffroy.lesur@univ-grenoble-alpes.fr", + "cmt.robert@univ-grenoble-alpes.fr": "clement.robert@univ-grenoble-alpes.fr", + "soufiane.baghdadi@meryntech.com": "soufiane.baghdadi@univ-grenoble-alpes.fr" + }, + "affiliation_domains": { + "@irap.omp.eu": "IRAP", + "@univ-grenoble-alpes.fr": "IPAG/UGA/CNRS", + "dutta.alankar@gmail.com": "MPA Garching", + "@aip.de": "IAP Postdam", + "@ens-lyon.fr": "ENS Lyon", + "@lpp.polytechnique.fr": "LPP" + }, + "allow_no_affiliation": false, + "exclude_hashes": [ + ], + "exclude_summary_regexps": [ + "^copyrights:" + ], + "lang": { + "shell": { + "max_line_length": 100, + "open_start": "##", + "open_end": "", + "repeat": "#", + "info_open": "# ", + "close_start": "##", + "close_end": "", + "apply_on": [ + "*.py", + "*.sh", + "*.cmake", + "*.cmake.in", + "*.spec", + "*.ebuild", + "*.sh.in", + "Dockerfile-*", + "CMakeLists.txt", + "options", + "configure", + "PKGBUILD", + "Makefile", + "makefile", + "makefile.rules", + "*.yml", + "*.toml", + "run-tests" + ] + }, + "c": { + "max_line_length": 100, + "open_start": "// ", + "open_end": "", + "repeat": "*", + "info_open": "// ", + "close_start": "// ", + "close_end": "", + "apply_on": [ + "*.c", + "*.cpp", + "*.cxx", + "*.h", + "*.hpp", + "*.hxx", + "*.h.in", + "*.js", + "*.css", + "*.rs", + "*.ts", + "*.scss" + ] + }, + "html": { + "max_line_length": 100, + "open_start": "", + "apply_on": [ + "*.html", + "*.vue" + ] + }, + "fortran": { + "max_line_length": 100, + "open_start": "!", + "open_end": "", + "repeat": "-", + "info_open": "! ", + "close_start": "!", + "close_end": "!", + "apply_on": [ + "*.f90", + "*.f", + "*.F90", + "*.F" + ] + } + }, + "exclude_files": [ + ".version", + "*.yml", + "*.yaml", + "*.gitignore", + ".gitignore", + "*.json", + "*.md", + "Doxyfile", + "*.txt", + "*.xmi", + "*.ini", + "*.bat", + "*.ico", + "*.ttf", + "*.bz2", + "*.ronn", + "*.bowerrc", + "*.png", + "*.webp", + "*.jpg", + "*.jpeg", + "*.jpeg", + "*.rst", + "*.svg", + "*.vtk", + "COPYING", + "CPPLINT.cfg", + ".gitmodules", + ".git-blame-ignore-revs", + "reference", + "src/kokkos", + "*/README", + "*.dmp", + "*.dat", + "*.csv", + "*.npy" + ], + "include_files": [ + "**/CMakeLists.txt", + "CMakeLists.txt" + ] +} diff --git a/pytools/update_file_headers.py b/pytools/update_file_headers.py new file mode 100755 index 000000000..55c61a77f --- /dev/null +++ b/pytools/update_file_headers.py @@ -0,0 +1,666 @@ +#!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file pytools/update_file_headers.py +# +# Last modified : 09/2026 +# +# Copyright(C) by : +# - Sebastien Valat (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + +############################################################ +# +# Imported and modified by Sébastien Valat (IPAG/CNRS) +# from MALT (Sébastien Valat) repository. +# +# Original licence is same than this project so it can be reused +# without problems. +# +# - https://github.com/memtt/malt/blob/v1.6.3/dev/update_file_headers.py +# - https://github.com/memtt/malt/blob/v1.6.3/dev/update_file_headers.json +# +############################################################ +# PROJECT : MALT (MALoc Tracker) +# DATE : 09/2025 +# LICENSE : CeCILL-C +# FILE : dev/update_file_headers.py +# ----------------------------------------------------------- +# AUTHOR : Sébastien Valat - 2024 +# AUTHOR : Sébastien Valat (INRIA) - 2025 +############################################################ + +# Usage : +# -------------------------------------------------------------------------------------------------- +# python3 -m venv venv +# source venv/bin/activate +# pip install gitpython +# ./dev/update_file_headers.py --git-all . +# -------------------------------------------------------------------------------------------------- + +############################################################ +# python +import argparse +import datetime +import fnmatch +import itertools +import json +import os +import pathlib +import re +import subprocess +import warnings + +# git +from git import Repo + + +############################################################ +class HeaderPatcher: + def __init__(self, config_file: str) -> None: + # vars + self.config_file = config_file + self.config = {} + + # load + self.load_config(config_file) + + def load_config(self, config_file: str) -> None: + with open(config_file, "r") as fp: + config = json.load(fp) + for id, entry in enumerate(config["exclude_summary_regexps"]): + config["exclude_summary_regexps"][id] = re.compile(entry) + self.config = config + + def get_manual_co_authors(self, commit_hash: str) -> list[dict]: + # get the manual infos + manual_authors: list[dict] = self.config.get("extra_authors", []) + + # build result list + result: list[dict] = [] + + # loop to scan + for author in manual_authors: + for commit in author["commits"]: + if commit == commit_hash: + result.append({"name": author["name"], "mail": author["mail"]}) + + # ok + return result + + def git_load_blame_log(self, file: str) -> list[dict]: + # open git repo + repo = Repo(pathlib.Path(".")) + assert not repo.bare + + # blame + blame = repo.git.blame("HEAD", file, "--porcelain").split("\n") + + # create log + log = [] + + # set default vars to track + commit_hash = "" + commiter_mail = "INIT" + commiter_name = "INIT" + commiter_time = "INIT" + commiter_zone = "INIT" + summary = "INIT" + + # loop on all entries to extract the infos + for entry in blame: + parts = entry.split(" ", maxsplit=1) + key = parts[0] + if len(key) == 40: + commit_hash = key + if key == "summary": + summary = parts[1] + elif key == "author-mail": + commiter_mail = parts[1] + if key == "author": + commiter_name = parts[1] + elif key == "author-time": + commiter_time = parts[1] + elif key == "filename": + commiter_zone = parts[1] + log.append( + { + "mail": commiter_mail, + "name": commiter_name, + "time": commiter_time, + "zone": commiter_zone, + "hash": commit_hash, + "summary": summary, + } + ) + + # search for co-authors to add to commit authors + co_authors = self.get_manual_co_authors(commit_hash) + for co_author in co_authors: + log.append( + { + "mail": "<" + co_author["mail"] + ">", + "name": co_author["name"], + "time": commiter_time, + "zone": commiter_zone, + "hash": commit_hash, + "summary": summary, + } + ) + + # reset vars for next scan + commit_hash = "" + commiter_mail = "INIT" + commiter_name = "INIT" + commiter_time = "INIT" + commiter_zone = "INIT" + summary = "INIT" + else: + # just ignore the other fields + pass + + # ok + return log + + def get_mail_affiliation(self, mail: str) -> str | None: + if mail == "": + return None + domain = "@" + mail.split("@")[1] + username = mail.split("@")[0] + "@" + affiliation_domains = self.config["affiliation_domains"] + if mail in affiliation_domains: + return affiliation_domains[mail] + elif domain in affiliation_domains: + return affiliation_domains[domain] + elif username in affiliation_domains: + return affiliation_domains[username] + else: + return None + + def replace_mail_by_pro_mail(self, mail: str, year: int) -> str: + # get the db entry in config + db: str | list[str] = self.config["replace_mails"] + username = mail.split("@")[0] + "@" + + # check if in + entry = None + if mail in db: + entry = db[mail] + elif username in db: + entry = db[username] + + # if need to replace + if entry is not None: + # direct definition or per year mode + if isinstance(entry, str): + return entry + elif isinstance(entry, list): + for epoc in entry: + started = epoc.get("from", 0) + ended = epoc.get("to", 9999) + if year >= started and year <= ended: + return epoc["mail"] + else: + raise Exception( + f"Invalid format for the field 'replace_mails' : {db[mail]}" + ) + + # ok keep as it is + return mail + + def fix_name(self, name: str) -> str: + authors_name_fixes = self.config["authors_name_fixes"] + if name in authors_name_fixes: + return authors_name_fixes[name] + else: + return name + + def need_skip_blame_entry(self, blame_entry: dict) -> bool: + exclude_hashes = self.config["exclude_hashes"] + + # skip some based on hash + if blame_entry["hash"] in exclude_hashes: + return True + + # skip based on summary (not to get commit which push file headers update) + for regexp in self.config["exclude_summary_regexps"]: + if regexp.match(blame_entry["summary"]): + return True + + # not found, so keep it + return False + + def git_extract_authors_from_history(self, blame_log: list) -> dict: + # build final storage + authors = {} + + # loop on all entries + for entry in itertools.filterfalse(self.need_skip_blame_entry, blame_log): + # extract name & skip if none + name = self.fix_name(entry["name"]) + if name is None: + continue + + # extract date infos + date = datetime.datetime.fromtimestamp(int(entry["time"])) + year = date.year + month = date.month + + # extract author infos + mail = entry["mail"][1:-1].strip() + mail = self.replace_mail_by_pro_mail(mail, year) + author = entry["mail"] + affiliation = self.get_mail_affiliation(mail) + full_name = f"{name} <{mail}>" + + # if no afficiation, warn + if affiliation is None: + if self.config.get("allow_no_affiliation", True): + warnings.warn(f"No affilication found for {entry}", stacklevel=1) + else: + raise Exception(f"No affilication found for {entry}") + + # inject it + if full_name not in authors: + authors[full_name] = { + "name": name, + "full-name": full_name, + "author": author, + "year-start": year, + "year-end": year, + "last-month": month, + "date-start": date, + "mail": mail, + "affiliation": affiliation, + } + + # set entry + auth_entry = authors[full_name] + auth_entry["year-start"] = min(auth_entry["year-start"], year) + auth_entry["year-end"] = max(auth_entry["year-end"], year) + auth_entry["date-start"] = min(auth_entry["date-start"], date) + + # ok + return authors + + def get_last_edit_month_year(self, blame_log: list[str]) -> str: + # vars + last_month = 0 + last_year = 0 + + # loop on all entries + for entry in blame_log: + # apply skip + if self.need_skip_blame_entry(entry): + continue + + date = datetime.datetime.fromtimestamp(int(entry["time"])) + year = date.year + month = date.month + if year > last_year: + last_year = year + last_month = month + elif year == last_year and month > last_month: + last_month = month + + # ok + return f"{last_month:02d}/{last_year:04d}" + + def build_infos(self, filename: str) -> dict: + # build default + infos = { + "header": self.config["header_keys"].copy(), + "origin": None, + "width": self.config["width"], + } + + # set file + infos["header"]["FILE"] = filename + + # apply specific for some files + if filename in self.config["specific"]: + specific = self.config["specific"][filename] + # has external origin + if "origin" in specific: + infos["origin"] = specific["origin"] + # override value (license....) + if "override" in specific: + for key, value in specific["override"].items(): + infos["header"][key] = value + if "width" in specific: + infos["width"] = specific["width"] + + # ok + return infos + + def build_new_file_header( + self, authors_list: list[dict], last_edit: str, infos: dict, lang: dict + ) -> list: + if "message" in self.config: + return self.build_new_file_header_by_message( + authors_list, last_edit, infos, lang + ) + else: + return self.build_new_file_header_by_keys( + authors_list, last_edit, infos, lang + ) + + def build_new_file_header_by_keys( + self, authors_list: list[dict], last_edit: str, infos: dict, lang: dict + ) -> list: + # pattern + info_open = lang["info_open"] + open_start = lang["open_start"] + open_end = lang["open_end"] + close_start = lang["close_start"] + close_end = lang["close_end"] + width = infos["width"] + line_start = ( + open_start + + lang["repeat"] * (width - len(open_start) - len(open_end)) + + open_end + ) + line_end = ( + close_start + + lang["repeat"] * (width - len(close_start) - len(close_end)) + + close_end + ) + + # build new header + header_script = [] + width = infos["width"] + header_script.append(f"{line_start}\n") + for key, value in infos["header"].items(): + fixed_value = value.replace("@LAST_EDIT_MONTH_YEAR@", last_edit) + header_script.append(f"{info_open} {key: <8} : {fixed_value}\n") + header_script.append(f"{info_open}{'-' * (width - len(info_open))}\n") + + # add authors + for author in authors_list: + full_name = author["full-name"] + start = author["year-start"] + end = author["year-end"] + if start == end: + years = str(start) + else: + years = f"{start} - {end}" + header_script.append(f"{info_open} AUTHOR : {full_name} - {years}\n") + + # origin + if infos["origin"]: + header_script.append(info_open + " ORIGIN ".center(width - 1, "-") + "\n") + for key, value in infos["origin"].items(): + header_script.append(f"{info_open} {key: <8} : {value}\n") + + # close + header_script.append(f"{line_end}\n") + + # ok + return header_script + + def build_new_file_header_by_message( + self, authors_list: list[dict], last_edit: str, infos: dict, lang: dict + ) -> list: + # pattern + max_line_length = lang["max_line_length"] + info_open = lang["info_open"] + open_start = lang["open_start"] + open_end = lang["open_end"] + close_start = lang["close_start"] + close_end = lang["close_end"] + width = infos["width"] + line_start = ( + open_start + + lang["repeat"] * (width - len(open_start) - len(open_end)) + + open_end + ) + line_end = ( + close_start + + lang["repeat"] * (width - len(close_start) - len(close_end)) + + close_end + ) + + # build new header + header_script = [] + width = infos["width"] + + # add authors + authors = [] + for author in authors_list: + name = author["name"] + start = author["year-start"] + end = author["year-end"] + email = author["mail"] + affiliation = author["affiliation"] + if start == end: + years = str(start) + else: + years = f"{start} - {end}" + if affiliation: + descr = f"- {name} <{email}> ({affiliation} - {years})" + if len(descr) <= max_line_length: + authors.append(descr) + else: + authors.append(f"- {name} <{email}>") + authors.append(f" ({affiliation} - {years})") + else: + authors.append(f"- {name} <{email}> ({years})") + + # replace in message + msg_line: str + header_script.append(f"{line_start}\n") + for msg_line in self.config["message"]: + for key, value in infos["header"].items(): + fixed_value = value.replace("@LAST_EDIT_MONTH_YEAR@", last_edit) + msg_line = msg_line.replace(f"@{key}@", fixed_value) + if msg_line == "@COPYRIGHTS@": + for author in authors: + header_script.append(f"{info_open}{author}\n") + else: + if msg_line == "": + header_script.append(f"{info_open.strip()}\n") + else: + header_script.append(f"{info_open}{msg_line}\n") + + # close + header_script.append(f"{line_end}\n") + + # ok + return header_script + + def calc_lang(self, filename: str) -> dict: + # get it + lang = self.config["lang"] + fname = os.path.basename(filename) + + # apply filters + for name, params in lang.items(): + apply_on = params["apply_on"] + for selector in apply_on: + if fnmatch.fnmatch(fname, selector): + print(f" - {filename} : apply type {name}") + return params + + # not found + raise Exception(f"Invalid file type : {filename}") + + def patch_header_lines( + self, origin_content: list, new_header: list, width: int, lang: dict + ) -> list: + # build patched + patched_content = None + + # pattern + info_open = lang["info_open"] + open_start = lang["open_start"] + open_end = lang["open_end"] + close_start = lang["close_start"] + close_end = lang["close_end"] + line_start = ( + open_start + + lang["repeat"] * (width - len(open_start) - len(open_end)) + + open_end + ) + line_end = ( + close_start + + lang["repeat"] * (width - len(close_start) - len(close_end)) + + close_end + ) + + # loop on content to find the start of header + for line, value in enumerate(origin_content): + if value == f"{line_start}\n" and ( + f"{info_open} {self.config['message'][0]}" + ): + count = 1 + while origin_content[line + count] != f"{line_end}\n": + count += 1 + del origin_content[line : line + count + 1] + patched_content = ( + origin_content[0:line] + new_header + origin_content[line:] + ) + break + elif line > 10: + break + + # add on top if not present + if len(origin_content) == 0: + patched_content = origin_content + elif not patched_content and origin_content[0][0:2] == "#!": + patched_content = origin_content[0:1] + new_header + origin_content[1:] + elif not patched_content: + patched_content = new_header + origin_content + + # ok + return patched_content + + def order_authors_by_date(self, authors: dict) -> list[dict]: + per_year = {} + for _key, author in authors.items(): + year = author["date-start"] + if not year in per_year: + per_year[year] = [] + per_year[year].append(author) + + result = [] + for year in sorted(per_year.keys()): + auths = sorted(per_year[year], key=lambda author: author["full-name"]) + for author in auths: + result.append(author) + + return result + + def patch_header(self, file: str) -> None: + # extract log + blame_log = self.git_load_blame_log(file) + + # extract authors + authors = self.git_extract_authors_from_history(blame_log) + last_edit = self.get_last_edit_month_year(blame_log) + + # as list + authors_list = self.order_authors_by_date(authors) + + # build infos + infos = self.build_infos(file) + + # get lang + lang = self.calc_lang(file) + + # build header as list of lines + header_script = self.build_new_file_header(authors_list, last_edit, infos, lang) + + # load file + with open(file, "r") as fp: + original_content = fp.readlines() + + # patch + patched_content = self.patch_header_lines( + original_content, header_script, infos["width"], lang + ) + + # save again + with open(file, "w+") as fp: + fp.writelines(patched_content) + + def is_in_include_files(self, filename: str) -> bool: + # check if included + for ipattern in self.config["include_files"]: + if ( + fnmatch.fnmatch(filename, ipattern) + or filename.startswith(ipattern) + or filename == ipattern + ): + return True + return False + + def patch_file(self, filename: str) -> None: + # if exclude + for pattern in self.config["exclude_files"]: + if fnmatch.fnmatch(filename, pattern) or filename.startswith(pattern): + if not self.is_in_include_files(filename): + print(f" - {filename} : EXCLUDED") + return + + # apply + self.patch_header(filename) + + def patch_all_git_files(self, git_dir: str) -> None: + files = subprocess.getoutput("git ls-files").split("\n") + for file in files: + self.patch_file(file) + + +############################################################ +def run_from_args(args): + # load + patcher = HeaderPatcher(args.config) + + # patch + if args.git_all: + patcher.patch_all_git_files(args.FILE) + else: + patcher.patch_file(args.FILE) + + +############################################################ +def config_arg_parser(parser: argparse.ArgumentParser) -> None: + # calc default config path + default_config = os.path.join(os.path.dirname(__file__), "update_file_headers.json") + + # add options + parser.add_argument("FILE", help="File to patch or source dir when using --git-all") + parser.add_argument( + "--git-all", + "-g", + help="Run on all file from GIT. FILE in this case give the GIT dir.", + action="store_true", + ) + parser.add_argument( + "--config", "-c", help="Config file to use", default=default_config + ) + + +############################################################ +def main() -> None: + # define arguments + parser = argparse.ArgumentParser() + config_arg_parser(parser) + + # parse + options = parser.parse_args() + + # run + run_from_args(options) + + # ok + return 0 + + +############################################################ +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/pytools/vtk_io.py b/pytools/vtk_io.py index eb5cf4125..061d64c22 100644 --- a/pytools/vtk_io.py +++ b/pytools/vtk_io.py @@ -1,13 +1,30 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file pytools/vtk_io.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2021) +# - Clément Robert (IPAG/UGA/CNRS - 2022 - 2026) +# - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + """ Created on Mon Nov 3 15:23:00 2014 @author: glesur """ -import warnings -import numpy as np import os import re +import warnings + +import numpy as np # restrict what's included with `import *` to public API __all__ = [ @@ -96,9 +113,11 @@ def _load_header(self, fh, geometry=None): self.periodicity = np.fromfile(fh, dtype=dint, count=3).astype(bool) elif NATIVE_COORDINATE_REGEXP.match(d): native_name, _ncomp, native_dim, _dtype = d.split() - self.native_coordinates[native_name] = np.fromfile(fh, dtype=dt, count=int(native_dim)) + self.native_coordinates[native_name] = np.fromfile( + fh, dtype=dt, count=int(native_dim) + ) else: - warnings.warn("Found unknown field %s" % d) + warnings.warn("Found unknown field %s" % d, stacklevel=3) fh.readline() # skip extra linefeed (empty line) if self.geometry is None: @@ -210,7 +229,6 @@ def _load_hydro(self, fh): # Reconstruct the polar coordinate system if self.geometry == "polar": - r = np.sqrt(xcart[:, 0, 0] ** 2 + ycart[:, 0, 0] ** 2) theta = np.unwrap(np.arctan2(ycart[0, :, 0], xcart[0, :, 0])) z = zcart[0, 0, :] @@ -376,6 +394,7 @@ def _setup_coordinates_from_native(self): def __repr__(self): return "VTKDataset('%s')" % self.filename + # ////// public API ////// def readVTK(filename, geometry=None): r"""Read a VTK file for any geometry. diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 000000000..b79a1d23e --- /dev/null +++ b/ruff.toml @@ -0,0 +1,28 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file ruff.toml +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + +target-version = "py310" + +[lint] +select = [ + "F", # pyflakes + "B", # flake8-bugbear + "I", # isort + "NPY", # numpy-specific rules +] +ignore = [ + # allow `import *` + "F403", # undefined-local-with-import-star + "F405", # undefined-local-with-import-star-usage +] diff --git a/scripts/ci/run-tests b/scripts/ci/run-tests index 329831029..81764353a 100755 --- a/scripts/ci/run-tests +++ b/scripts/ci/run-tests @@ -1,7 +1,43 @@ #!/usr/bin/env bash +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file scripts/ci/run-tests +# +# Last modified : 06/2026 +# +# Copyright(C) by : +# - Marc Coiffier (IPAG/UGA/CNRS - 2024) +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2026) +# - Sébastien Valat (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + +# load ICC compiler env if [ "$IDEFIX_COMPILER" == icc ]; then source /opt/intel/oneapi/setvars.sh fi + +# enable bash features set -ue -cd "$1" -./testme.py "${@:2}" + +# load python venv if present +if [ -d .venv ]; then + source .venv/bin/activate +fi + +# to get access to idefix ./pytools/ module in python code +if [[ -v PYTHONPATH ]]; then + export PYTHONPATH="${PWD}:${PYTHONPATH}" +else + export PYTHONPATH="${PWD}" +fi + +# run the test the old way (still possible up to now) +#cd "$1" +#./testme.py "${@:2}" + +# run the test the new way (via pytest) +./test.py -subdir "$@" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 08dd93c61..d0b714368 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/CMakeLists.txt +# +# Last modified : 04/2025 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2025) +# - Soufiane Baghdadi (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### add_subdirectory(fluid) add_subdirectory(dataBlock) diff --git a/src/arrays.hpp b/src/arrays.hpp index 8a8eaea32..6d8989bda 100644 --- a/src/arrays.hpp +++ b/src/arrays.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/arrays.hpp +// +// Last modified : 06/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2022) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/compiler_info.h.in b/src/compiler_info.h.in new file mode 100644 index 000000000..b14e4c400 --- /dev/null +++ b/src/compiler_info.h.in @@ -0,0 +1,24 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file src/compiler_info.h.in +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + +#ifndef COMPILER_INFO_H +#define COMPILER_INFO_H + +namespace CompilerInfo { + inline constexpr const char* name = "@CMAKE_CXX_COMPILER_ID@"; + inline constexpr const char* version = "@CMAKE_CXX_COMPILER_VERSION@"; + inline constexpr const char* path = "@CMAKE_CXX_COMPILER@"; +} + +#endif diff --git a/src/dataBlock/CMakeLists.txt b/src/dataBlock/CMakeLists.txt index c3410f41b..3ddf4016d 100644 --- a/src/dataBlock/CMakeLists.txt +++ b/src/dataBlock/CMakeLists.txt @@ -1,3 +1,19 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/dataBlock/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Soufiane Baghdadi (IPAG/UGA/CNRS - 2021) +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + add_subdirectory(planetarySystem) target_sources(idefix diff --git a/src/dataBlock/coarsen.cpp b/src/dataBlock/coarsen.cpp index 4c6b60ccd..f4b75b9dc 100644 --- a/src/dataBlock/coarsen.cpp +++ b/src/dataBlock/coarsen.cpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/coarsen.cpp +// +// Last modified : 03/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022 - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/dataBlock.cpp b/src/dataBlock/dataBlock.cpp index 2877a8346..3440facac 100644 --- a/src/dataBlock/dataBlock.cpp +++ b/src/dataBlock/dataBlock.cpp @@ -1,7 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/dataBlock.cpp +// +// Last modified : 12/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2025) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/dataBlock.hpp b/src/dataBlock/dataBlock.hpp index 89b745fa5..6d322e7e5 100644 --- a/src/dataBlock/dataBlock.hpp +++ b/src/dataBlock/dataBlock.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/dataBlock.hpp +// +// Last modified : 10/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020 - 2021) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/dataBlockHost.cpp b/src/dataBlock/dataBlockHost.cpp index c7811b391..0c3293b6a 100644 --- a/src/dataBlock/dataBlockHost.cpp +++ b/src/dataBlock/dataBlockHost.cpp @@ -1,7 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/dataBlockHost.cpp +// +// Last modified : 01/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2025) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2024) +// - Alankar Dutta (MPA Garching - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/dataBlockHost.hpp b/src/dataBlock/dataBlockHost.hpp index f7dc4041f..0bf4ccd86 100644 --- a/src/dataBlock/dataBlockHost.hpp +++ b/src/dataBlock/dataBlockHost.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/dataBlockHost.hpp +// +// Last modified : 09/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2024) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/dumpToFile.cpp b/src/dataBlock/dumpToFile.cpp index 51347e6ed..fdac2fb4f 100644 --- a/src/dataBlock/dumpToFile.cpp +++ b/src/dataBlock/dumpToFile.cpp @@ -1,7 +1,18 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/dumpToFile.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2026) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2024) +// - Marc Van den Bossche (IAP Postdam - 2024) +// - Alankar Dutta (MPA Garching - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -9,8 +20,8 @@ #include #include "../idefix.hpp" #include "dataBlock.hpp" -#include "version.hpp" #include "fluid.hpp" +#include "version.h" #define NAMESIZE 16 #define HEADERSIZE 128 @@ -45,13 +56,13 @@ void DataBlock::DumpToFile(std::string filebase) { // TODO(lesurg) Make datablock a friend of hydro to get the Riemann flux? - //IdefixArray4D::HostMirror locFlux = Kokkos::create_mirror_view(Kokkos::HostSpace(), + //IdefixArray4D::host_mirror_type locFlux = Kokkos::create_mirror_view(Kokkos::HostSpace(), // this->hydro->FluxRiemann); //Kokkos::deep_copy(locFlux, this->FluxRiemann); #if MHD == YES - IdefixArray4D::HostMirror locJ; + IdefixArray4D::host_mirror_type locJ; if(hydro->haveCurrent) { locJ = Kokkos::create_mirror_view(Kokkos::HostSpace(), this->hydro->J); Kokkos::deep_copy(locJ, this->hydro->J); @@ -78,11 +89,11 @@ void DataBlock::DumpToFile(std::string filebase) { // Write Header char header[HEADERSIZE]; - std::snprintf(header, HEADERSIZE, "Idefix %s Debug DataBlock", IDEFIX_VERSION); + std::snprintf(header, HEADERSIZE, "Idefix %s Debug DataBlock", VersionInfo::version); fwrite (header, sizeof(char), HEADERSIZE, fileHdl); // Write Vc - IdefixArray4D::HostMirror locVc = Kokkos::create_mirror_view(this->hydro->Vc); + IdefixArray4D::host_mirror_type locVc = Kokkos::create_mirror_view(this->hydro->Vc); Kokkos::deep_copy(locVc,this->hydro->Vc); dims[0] = this->np_tot[IDIR]; dims[1] = this->np_tot[JDIR]; @@ -94,7 +105,7 @@ void DataBlock::DumpToFile(std::string filebase) { WriteVariable(fileHdl, 4, dims, fieldName, locVc.data()); if (this->gravity->haveSelfGravityPotential) { - IdefixArray3D::HostMirror locPot = Kokkos::create_mirror_view(this->gravity->phiP); + IdefixArray3D::host_mirror_type locPot = Kokkos::create_mirror_view(this->gravity->phiP); Kokkos::deep_copy(locPot, this->gravity->phiP); dims[3] = 1; @@ -121,7 +132,7 @@ void DataBlock::DumpToFile(std::string filebase) { // Write Vs #if MHD == YES // Write Vs - IdefixArray4D::HostMirror locVs = Kokkos::create_mirror_view(Kokkos::HostSpace(), + IdefixArray4D::host_mirror_type locVs = Kokkos::create_mirror_view(Kokkos::HostSpace(), this->hydro->Vs); Kokkos::deep_copy(locVs,this->hydro->Vs); dims[0] = this->np_tot[IDIR]+IOFFSET; @@ -139,7 +150,7 @@ void DataBlock::DumpToFile(std::string filebase) { dims[2] = this->np_tot[KDIR]; std::snprintf(fieldName,NAMESIZE,"Ex3"); - IdefixArray3D::HostMirror locE = Kokkos::create_mirror_view(Kokkos::HostSpace(), + IdefixArray3D::host_mirror_type locE = Kokkos::create_mirror_view(Kokkos::HostSpace(), this->hydro->emf->ez); Kokkos::deep_copy(locE,this->hydro->emf->ez); WriteVariable(fileHdl, 3, dims, fieldName, locE.data()); @@ -155,7 +166,7 @@ void DataBlock::DumpToFile(std::string filebase) { if(hydro->haveCurrent) { - IdefixArray4D::HostMirror locJ = Kokkos::create_mirror_view(Kokkos::HostSpace(), + IdefixArray4D::host_mirror_type locJ = Kokkos::create_mirror_view(Kokkos::HostSpace(), this->hydro->J); Kokkos::deep_copy(locJ,this->hydro->J); dims[0] = this->np_tot[IDIR]; diff --git a/src/dataBlock/evolveStage.cpp b/src/dataBlock/evolveStage.cpp index c97c9f713..c00c44fec 100644 --- a/src/dataBlock/evolveStage.cpp +++ b/src/dataBlock/evolveStage.cpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/evolveStage.cpp +// +// Last modified : 02/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2025) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/fargo.cpp b/src/dataBlock/fargo.cpp index 7aa2d26a5..046a11d5f 100644 --- a/src/dataBlock/fargo.cpp +++ b/src/dataBlock/fargo.cpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/fargo.cpp +// +// Last modified : 12/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2025) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/fargo.hpp b/src/dataBlock/fargo.hpp index a1efcb2b6..9347f716f 100644 --- a/src/dataBlock/fargo.hpp +++ b/src/dataBlock/fargo.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/fargo.hpp +// +// Last modified : 12/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2025) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/makeGeometry.cpp b/src/dataBlock/makeGeometry.cpp index ddb9a2101..fc2b8624c 100644 --- a/src/dataBlock/makeGeometry.cpp +++ b/src/dataBlock/makeGeometry.cpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/makeGeometry.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/planetarySystem/CMakeLists.txt b/src/dataBlock/planetarySystem/CMakeLists.txt index 217cb7050..8be62f30a 100644 --- a/src/dataBlock/planetarySystem/CMakeLists.txt +++ b/src/dataBlock/planetarySystem/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/dataBlock/planetarySystem/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/planet.cpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/planet.hpp diff --git a/src/dataBlock/planetarySystem/planet.cpp b/src/dataBlock/planetarySystem/planet.cpp index ccbed14e6..a2808b2d2 100644 --- a/src/dataBlock/planetarySystem/planet.cpp +++ b/src/dataBlock/planetarySystem/planet.cpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/planetarySystem/planet.cpp +// +// Last modified : 03/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/planetarySystem/planet.hpp b/src/dataBlock/planetarySystem/planet.hpp index 46b701889..2542adac2 100644 --- a/src/dataBlock/planetarySystem/planet.hpp +++ b/src/dataBlock/planetarySystem/planet.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/planetarySystem/planet.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/planetarySystem/planetStructs.hpp b/src/dataBlock/planetarySystem/planetStructs.hpp index 3749a34d2..156fea612 100644 --- a/src/dataBlock/planetarySystem/planetStructs.hpp +++ b/src/dataBlock/planetarySystem/planetStructs.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/planetarySystem/planetStructs.hpp +// +// Last modified : 06/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -19,7 +26,7 @@ struct Force { real f_ex_inner[3]; real f_outer[3]; real f_ex_outer[3]; - KOKKOS_FUNCTION void operator+=(Force const volatile& f) volatile { + KOKKOS_FUNCTION void operator+=(const Force & f) { for (int i = 0; i < 3; ++i) { f_inner[i] += f.f_inner[i]; f_ex_inner[i] += f.f_ex_inner[i]; diff --git a/src/dataBlock/planetarySystem/planetarySystem.cpp b/src/dataBlock/planetarySystem/planetarySystem.cpp index 8d01118db..6370d4d00 100644 --- a/src/dataBlock/planetarySystem/planetarySystem.cpp +++ b/src/dataBlock/planetarySystem/planetarySystem.cpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/planetarySystem/planetarySystem.cpp +// +// Last modified : 10/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/planetarySystem/planetarySystem.hpp b/src/dataBlock/planetarySystem/planetarySystem.hpp index 436ad3d4e..6a2d4bfc8 100644 --- a/src/dataBlock/planetarySystem/planetarySystem.hpp +++ b/src/dataBlock/planetarySystem/planetarySystem.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/planetarySystem/planetarySystem.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/stateContainer.cpp b/src/dataBlock/stateContainer.cpp index 52fff9125..ac87a5cfe 100644 --- a/src/dataBlock/stateContainer.cpp +++ b/src/dataBlock/stateContainer.cpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/stateContainer.cpp +// +// Last modified : 11/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// - Clément Robert (IPAG/UGA/CNRS - 2022) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/stateContainer.hpp b/src/dataBlock/stateContainer.hpp index b8d9378c5..bb0bd4a78 100644 --- a/src/dataBlock/stateContainer.hpp +++ b/src/dataBlock/stateContainer.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/stateContainer.hpp +// +// Last modified : 11/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// - Clément Robert (IPAG/UGA/CNRS - 2022) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/dataBlock/validation.cpp b/src/dataBlock/validation.cpp index 9ee53e60e..f2819bf1a 100644 --- a/src/dataBlock/validation.cpp +++ b/src/dataBlock/validation.cpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/dataBlock/validation.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/error.cpp b/src/error.cpp index 5ea3006cf..868de2418 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/error.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/error.hpp b/src/error.hpp index 71cf09dd5..3661f16bc 100644 --- a/src/error.hpp +++ b/src/error.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/error.hpp +// +// Last modified : 11/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2021) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/CMakeLists.txt b/src/fluid/CMakeLists.txt index f849b22fc..b5d70be2c 100644 --- a/src/fluid/CMakeLists.txt +++ b/src/fluid/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/fluid/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + add_subdirectory(boundary) add_subdirectory(braginskii) add_subdirectory(constrainedTransport) diff --git a/src/fluid/RiemannSolver/CMakeLists.txt b/src/fluid/RiemannSolver/CMakeLists.txt index f9a018736..9099fea25 100644 --- a/src/fluid/RiemannSolver/CMakeLists.txt +++ b/src/fluid/RiemannSolver/CMakeLists.txt @@ -1,3 +1,16 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/fluid/RiemannSolver/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### add_subdirectory(MHDsolvers) add_subdirectory(HDsolvers) diff --git a/src/fluid/RiemannSolver/Dustsolvers/CMakeLists.txt b/src/fluid/RiemannSolver/Dustsolvers/CMakeLists.txt index 0cafdc8d6..6f5a7bb38 100644 --- a/src/fluid/RiemannSolver/Dustsolvers/CMakeLists.txt +++ b/src/fluid/RiemannSolver/Dustsolvers/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/fluid/RiemannSolver/Dustsolvers/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/hllDust.hpp ) diff --git a/src/fluid/RiemannSolver/Dustsolvers/hllDust.hpp b/src/fluid/RiemannSolver/Dustsolvers/hllDust.hpp index d55f0ceb7..2bc8da708 100644 --- a/src/fluid/RiemannSolver/Dustsolvers/hllDust.hpp +++ b/src/fluid/RiemannSolver/Dustsolvers/hllDust.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/Dustsolvers/hllDust.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/RiemannSolver/HDsolvers/CMakeLists.txt b/src/fluid/RiemannSolver/HDsolvers/CMakeLists.txt index 6d3ec5701..5d684e731 100644 --- a/src/fluid/RiemannSolver/HDsolvers/CMakeLists.txt +++ b/src/fluid/RiemannSolver/HDsolvers/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/fluid/RiemannSolver/HDsolvers/CMakeLists.txt +# +# Last modified : 09/2021 +# +# Copyright(C) by : +# - Soufiane Baghdadi (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/hllcHD.hpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/hllHD.hpp diff --git a/src/fluid/RiemannSolver/HDsolvers/hllHD.hpp b/src/fluid/RiemannSolver/HDsolvers/hllHD.hpp index 89d72d332..276f4e4ce 100644 --- a/src/fluid/RiemannSolver/HDsolvers/hllHD.hpp +++ b/src/fluid/RiemannSolver/HDsolvers/hllHD.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/HDsolvers/hllHD.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/RiemannSolver/HDsolvers/hllcHD.hpp b/src/fluid/RiemannSolver/HDsolvers/hllcHD.hpp index e79aac35f..2585fd7a4 100644 --- a/src/fluid/RiemannSolver/HDsolvers/hllcHD.hpp +++ b/src/fluid/RiemannSolver/HDsolvers/hllcHD.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/HDsolvers/hllcHD.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/RiemannSolver/HDsolvers/roeHD.hpp b/src/fluid/RiemannSolver/HDsolvers/roeHD.hpp index 416f99848..b985b40a2 100644 --- a/src/fluid/RiemannSolver/HDsolvers/roeHD.hpp +++ b/src/fluid/RiemannSolver/HDsolvers/roeHD.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/HDsolvers/roeHD.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/RiemannSolver/HDsolvers/tvdlfHD.hpp b/src/fluid/RiemannSolver/HDsolvers/tvdlfHD.hpp index 597dd0d12..7a389dd16 100644 --- a/src/fluid/RiemannSolver/HDsolvers/tvdlfHD.hpp +++ b/src/fluid/RiemannSolver/HDsolvers/tvdlfHD.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/HDsolvers/tvdlfHD.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/RiemannSolver/MHDsolvers/CMakeLists.txt b/src/fluid/RiemannSolver/MHDsolvers/CMakeLists.txt index 4fbac3d94..268318f84 100644 --- a/src/fluid/RiemannSolver/MHDsolvers/CMakeLists.txt +++ b/src/fluid/RiemannSolver/MHDsolvers/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/fluid/RiemannSolver/MHDsolvers/CMakeLists.txt +# +# Last modified : 09/2021 +# +# Copyright(C) by : +# - Soufiane Baghdadi (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/hlldMHD.hpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/hllMHD.hpp diff --git a/src/fluid/RiemannSolver/MHDsolvers/hllMHD.hpp b/src/fluid/RiemannSolver/MHDsolvers/hllMHD.hpp index 77253b727..ae4c4b6c3 100644 --- a/src/fluid/RiemannSolver/MHDsolvers/hllMHD.hpp +++ b/src/fluid/RiemannSolver/MHDsolvers/hllMHD.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/MHDsolvers/hllMHD.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020 - 2021) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/RiemannSolver/MHDsolvers/hlldMHD.hpp b/src/fluid/RiemannSolver/MHDsolvers/hlldMHD.hpp index fa2491c55..7d0237a6b 100644 --- a/src/fluid/RiemannSolver/MHDsolvers/hlldMHD.hpp +++ b/src/fluid/RiemannSolver/MHDsolvers/hlldMHD.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/MHDsolvers/hlldMHD.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020 - 2021) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/RiemannSolver/MHDsolvers/roeMHD.hpp b/src/fluid/RiemannSolver/MHDsolvers/roeMHD.hpp index 633c3ebd8..4395c202d 100644 --- a/src/fluid/RiemannSolver/MHDsolvers/roeMHD.hpp +++ b/src/fluid/RiemannSolver/MHDsolvers/roeMHD.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/MHDsolvers/roeMHD.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020 - 2021) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/RiemannSolver/MHDsolvers/storeFlux.hpp b/src/fluid/RiemannSolver/MHDsolvers/storeFlux.hpp index 921a312ac..d10bb19a9 100644 --- a/src/fluid/RiemannSolver/MHDsolvers/storeFlux.hpp +++ b/src/fluid/RiemannSolver/MHDsolvers/storeFlux.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/MHDsolvers/storeFlux.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2026) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -55,15 +63,15 @@ KOKKOS_FORCEINLINE_FUNCTION void K_StoreHLL( const int i, const int j, const int const IdefixArray3D &dL, const IdefixArray3D &dR) { EXPAND( , - constexpr int Xt = (DIR == IDIR ? MX2 : MX1); , - constexpr int Xb = (DIR == KDIR ? MX2 : MX3); ) + [[maybe_unused]] constexpr int Xt = (DIR == IDIR ? MX2 : MX1); , + [[maybe_unused]] constexpr int Xb = (DIR == KDIR ? MX2 : MX3); ) real ar = std::fmax(ZERO_F, sr); real al = std::fmin(ZERO_F, sl); real scrh = ONE_F/(ar - al); - #if COMPONENTS > 1 - EXPAND( Et(k,j,i) = -st*(ar*vL[Xt] - al*vR[Xt])*scrh; , + #if DIMENSIONS > 1 + D_EXPAND( Et(k,j,i) = -st*(ar*vL[Xt] - al*vR[Xt])*scrh; , , Eb(k,j,i) = -sb*(ar*vL[Xb] - al*vR[Xb])*scrh; ); #endif diff --git a/src/fluid/RiemannSolver/MHDsolvers/tvdlfMHD.hpp b/src/fluid/RiemannSolver/MHDsolvers/tvdlfMHD.hpp index b8435d3cd..743c6ada0 100644 --- a/src/fluid/RiemannSolver/MHDsolvers/tvdlfMHD.hpp +++ b/src/fluid/RiemannSolver/MHDsolvers/tvdlfMHD.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/MHDsolvers/tvdlfMHD.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020 - 2021) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/RiemannSolver/calcFlux.hpp b/src/fluid/RiemannSolver/calcFlux.hpp index ea5b18741..c23755b87 100644 --- a/src/fluid/RiemannSolver/calcFlux.hpp +++ b/src/fluid/RiemannSolver/calcFlux.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/calcFlux.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/RiemannSolver/extrapolateToFaces.hpp b/src/fluid/RiemannSolver/extrapolateToFaces.hpp index bb3c99587..c832bad9d 100644 --- a/src/fluid/RiemannSolver/extrapolateToFaces.hpp +++ b/src/fluid/RiemannSolver/extrapolateToFaces.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/extrapolateToFaces.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** #ifndef FLUID_RIEMANNSOLVER_EXTRAPOLATETOFACES_HPP_ diff --git a/src/fluid/RiemannSolver/flux.hpp b/src/fluid/RiemannSolver/flux.hpp index 9c5131d88..ee885c465 100644 --- a/src/fluid/RiemannSolver/flux.hpp +++ b/src/fluid/RiemannSolver/flux.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/flux.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/RiemannSolver/riemannSolver.hpp b/src/fluid/RiemannSolver/riemannSolver.hpp index abb70eed5..bffaaa43b 100644 --- a/src/fluid/RiemannSolver/riemannSolver.hpp +++ b/src/fluid/RiemannSolver/riemannSolver.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/riemannSolver.hpp +// +// Last modified : 09/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// - Marc Van den Bossche (IAP Postdam - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -70,7 +78,6 @@ class RiemannSolver { IdefixArray4D Vc; IdefixArray4D Vs; - IdefixArray4D Flux; IdefixArray3D cMax; Fluid* hydro; DataBlock *data; @@ -90,7 +97,6 @@ class RiemannSolver { template RiemannSolver::RiemannSolver(Input &input, Fluid* hydro) : Vc{hydro->Vc}, Vs{hydro->Vs}, - Flux{hydro->FluxRiemann}, cMax{hydro->cMax}, hydro{hydro}, data{hydro->data} @@ -148,8 +154,6 @@ RiemannSolver::RiemannSolver(Input &input, Fluid* hydro) : Vc{hydro- mySolver = HLL_DUST; } - - // Shock flattening this->haveShockFlattening = input.CheckEntry(std::string(Phys::prefix),"shockFlattening")>=0; // Init shock flattening diff --git a/src/fluid/RiemannSolver/shockFlattening.hpp b/src/fluid/RiemannSolver/shockFlattening.hpp index df68de766..454b7db06 100644 --- a/src/fluid/RiemannSolver/shockFlattening.hpp +++ b/src/fluid/RiemannSolver/shockFlattening.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/shockFlattening.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/RiemannSolver/slopeLimiter.hpp b/src/fluid/RiemannSolver/slopeLimiter.hpp index 082ed0894..5417eee28 100644 --- a/src/fluid/RiemannSolver/slopeLimiter.hpp +++ b/src/fluid/RiemannSolver/slopeLimiter.hpp @@ -1,9 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/RiemannSolver/slopeLimiter.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** + #ifndef FLUID_RIEMANNSOLVER_SLOPELIMITER_HPP_ #define FLUID_RIEMANNSOLVER_SLOPELIMITER_HPP_ diff --git a/src/fluid/addNonIdealMHDFlux.hpp b/src/fluid/addNonIdealMHDFlux.hpp index 52c281d2d..4bb3d785d 100644 --- a/src/fluid/addNonIdealMHDFlux.hpp +++ b/src/fluid/addNonIdealMHDFlux.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/addNonIdealMHDFlux.hpp +// +// Last modified : 06/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -19,8 +26,7 @@ void Fluid::AddNonIdealMHDFlux(const real t) { if constexpr(Phys::mhd) { int ioffset,joffset,koffset; - - IdefixArray4D Flux = this->FluxRiemann; + IdefixArray4D Flux = this->FluxRiemann[dir]; IdefixArray4D Vc = this->Vc; IdefixArray4D Vs = this->Vs; IdefixArray3D dMax = this->dMax; diff --git a/src/fluid/addSourceTerms.hpp b/src/fluid/addSourceTerms.hpp index e3f745868..0350fab0c 100644 --- a/src/fluid/addSourceTerms.hpp +++ b/src/fluid/addSourceTerms.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/addSourceTerms.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/boundary/CMakeLists.txt b/src/fluid/boundary/CMakeLists.txt index 35f30dff1..8c04f2b3c 100644 --- a/src/fluid/boundary/CMakeLists.txt +++ b/src/fluid/boundary/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/fluid/boundary/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/axis.cpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/axis.hpp diff --git a/src/fluid/boundary/axis.cpp b/src/fluid/boundary/axis.cpp index 47f0c2954..1b6ef30d0 100644 --- a/src/fluid/boundary/axis.cpp +++ b/src/fluid/boundary/axis.cpp @@ -1,7 +1,18 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/boundary/axis.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2025) +// - Marc Van den Bossche (IPAG/UGA/CNRS - 2023) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +// - Clément Robert (IPAG/UGA/CNRS - 2024) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -25,7 +36,7 @@ void Axis::ShowConfig() { void Axis::SymmetrizeEx1Side(int jref, IdefixArray3D Ex1) { #if DIMENSIONS == 3 - IdefixArray1D Ex1Avg = this->Ex1Avg; + auto Ex1Avg = this->Ex1Avg.deviceView(); idefix_for("Ex1_ini",0,data->np_tot[IDIR], KOKKOS_LAMBDA(int i) { @@ -40,7 +51,7 @@ void Axis::SymmetrizeEx1Side(int jref, IdefixArray3D Ex1) { #ifdef WITH_MPI Kokkos::fence(); // sum along all of the processes on the same r - MPI_Allreduce(MPI_IN_PLACE, Ex1Avg.data(), data->np_tot[IDIR], realMPI, + idfx::MPI_Allreduce(MPI_IN_PLACE, this->Ex1Avg, data->np_tot[IDIR], realMPI, MPI_SUM, data->mygrid->AxisComm); #endif } @@ -88,7 +99,8 @@ void Axis::RegularizeCurrentSide(int side) { jc = data->end[JDIR]-1; sign = -1; } - IdefixArray1D BAvg = this->Ex1Avg; + auto BAvg = this->Ex1Avg.deviceView(); + auto BAvgComm = this->Ex1Avg; IdefixArray1D x1 = data->x[IDIR]; IdefixArray1D dx3 = data->dx[KDIR]; IdefixArray1D dx2 = data->dx[JDIR]; @@ -107,7 +119,7 @@ void Axis::RegularizeCurrentSide(int side) { #ifdef WITH_MPI Kokkos::fence(); // sum along all of the processes on the same r - MPI_Allreduce(MPI_IN_PLACE, BAvg.data(), data->np_tot[IDIR], realMPI, + MPI_Allreduce(MPI_IN_PLACE, BAvgComm, data->np_tot[IDIR], realMPI, MPI_SUM, data->mygrid->AxisComm); #endif } @@ -169,7 +181,7 @@ void Axis::FixBx2sAxis(int side) { // Compute the values of Bx and By that are consistent with BX2 along the axis #if DIMENSIONS == 3 IdefixArray4D Vs = this->Vs; - IdefixArray2D BAvg = this->BAvg; + auto BAvg = this->BAvg.deviceView(); IdefixArray1D phi = data->x[KDIR]; int jin = 0; @@ -208,7 +220,7 @@ void Axis::FixBx2sAxis(int side) { Kokkos::fence(); #ifdef WITH_MPI // sum along all of the processes on the same r - MPI_Allreduce(MPI_IN_PLACE, BAvg.data(), 2*data->np_tot[IDIR], realMPI, + idfx::MPI_Allreduce(MPI_IN_PLACE, this->BAvg, 2*data->np_tot[IDIR], realMPI, MPI_SUM, data->mygrid->AxisComm); #endif } @@ -392,154 +404,140 @@ void Axis::ExchangeMPI(int side) { idfx::pushRegion("Axis::ExchangeMPI"); #ifdef WITH_MPI // Load the buffers with data - int ibeg,iend,jbeg,jend,kbeg,kend,offset; - int nx,ny,nz; - auto bufferSend = this->bufferSend; + int offset; + int ny; + Buffer bufferSend = this->bufferSend; IdefixArray1D map = this->mapVars; IdefixArray4D Vc = this->Vc; IdefixArray4D Vs = this->Vs; + //reset pointer + bufferSend.ResetPointer(); + // If MPI Persistent, start receiving even before the buffers are filled MPI_Status sendStatus; MPI_Status recvStatus; double tStart = MPI_Wtime(); - MPI_SAFE_CALL(MPI_Start(&recvRequest)); + MPI_SAFE_CALL(idfx::MPI_Start(&recvRequest)); idfx::mpiCallsTimer += MPI_Wtime() - tStart; // Coordinates of the ghost region which needs to be transfered - ibeg = 0; - iend = data->np_tot[IDIR]; - nx = data->np_tot[IDIR]; // Number of points in x - jbeg = 0; - jend = data->nghost[JDIR]; offset = data->end[JDIR]; // Distance between beginning of left and right ghosts ny = data->nghost[JDIR]; - kbeg = data->beg[KDIR]; - kend = data->end[KDIR]; - nz = kend - kbeg; + + // Create the base box to be patched by the ops + BoundingBox baseBox; + baseBox[IDIR][0] = 0; + baseBox[IDIR][1] = data->np_tot[IDIR]; + baseBox[JDIR][0] = 0; + baseBox[JDIR][1] = data->nghost[JDIR]; + baseBox[KDIR][0] = data->beg[KDIR]; + baseBox[KDIR][1] = data->end[KDIR]; + if(side==left) { - idefix_for("LoadBufferX2Vc",0,mapNVars,kbeg,kend,jbeg,jend,ibeg,iend, - KOKKOS_LAMBDA (int n, int k, int j, int i) { - bufferSend(i + (j-jbeg)*nx + (k-kbeg)*nx*ny + n*nx*ny*nz ) = - Vc(map(n),k,j+ny,i); - } - ); + //shift by NY + BoundingBox sendBoxVc = baseBox; + sendBoxVc[JDIR][0] += ny; + sendBoxVc[JDIR][1] += ny; + bufferSend.Pack(Vc, map, sendBoxVc); + if (haveMHD) { - int VsIndex = mapNVars*nx*ny*nz; - idefix_for("LoadBufferX2IDIR",kbeg,kend,jbeg,jend,ibeg,iend+1, - KOKKOS_LAMBDA (int k, int j, int i) { - bufferSend(i + (j-jbeg)*(nx+1) + (k-kbeg)*(nx+1)*ny + VsIndex ) = - Vs(IDIR,k,j+ny,i); - } - ); - VsIndex = mapNVars*nx*ny*nz + (nx+1)*ny*nz; - idefix_for("LoadBufferX2KDIR",kbeg,kend+1,jbeg,jend,ibeg,iend, - KOKKOS_LAMBDA (int k, int j, int i) { - bufferSend(i + (j-jbeg)*nx + (k-kbeg)*nx*ny + VsIndex ) = - Vs(KDIR,k,j+ny,i); - } - ); + //extend by one the end on idir + BoundingBox sendBoxVsIdir = sendBoxVc; + sendBoxVsIdir[IDIR][1] += 1; + bufferSend.Pack(Vs, IDIR, sendBoxVsIdir); + + //extend by one the end on kdir + BoundingBox sendBoxVsKdir = sendBoxVc; + sendBoxVsKdir[KDIR][1] += 1; + bufferSend.Pack(Vs, KDIR, sendBoxVsKdir); } // MHD } else if(side==right) { - idefix_for("LoadBufferX2Vc",0,mapNVars,kbeg,kend,jbeg,jend,ibeg,iend, - KOKKOS_LAMBDA (int n, int k, int j, int i) { - bufferSend(i + (j-jbeg)*nx + (k-kbeg)*nx*ny + n*nx*ny*nz ) = - Vc(map(n),k,j+offset-ny,i); - } - ); + //shift by offset - NY (to select the right part) + BoundingBox sendBoxVc = baseBox; + sendBoxVc[JDIR][0] += offset - ny; + sendBoxVc[JDIR][1] += offset - ny; + bufferSend.Pack(Vc, map, sendBoxVc); // Load face-centered field in the buffer if (haveMHD) { - int VsIndex = mapNVars*nx*ny*nz; - idefix_for("LoadBufferX2IDIR",kbeg,kend,jbeg,jend,ibeg,iend+1, - KOKKOS_LAMBDA (int k, int j, int i) { - bufferSend(i + (j-jbeg)*(nx+1) + (k-kbeg)*(nx+1)*ny + VsIndex ) = - Vs(IDIR,k,j+offset-ny,i); - } - ); - VsIndex = mapNVars*nx*ny*nz + (nx+1)*ny*nz; - - idefix_for("LoadBufferX2KDIR",kbeg,kend+1,jbeg,jend,ibeg,iend, - KOKKOS_LAMBDA (int k, int j, int i) { - bufferSend(i + (j-jbeg)*nx + (k-kbeg)*nx*ny + VsIndex ) = - Vs(KDIR,k,j+offset-ny,i); - } - ); + //extend by one the end on idir + take the right part or the mesh on jdir + BoundingBox sendBoxVsIdir = baseBox; + sendBoxVsIdir[IDIR][1] += 1; + sendBoxVsIdir[JDIR][0] += offset - ny; + sendBoxVsIdir[JDIR][1] += offset - ny; + bufferSend.Pack(Vs, IDIR, sendBoxVsIdir); + + //extend by one the end on kdir + take the right part or the mesh on jdir + BoundingBox sendBoxVsKdir = baseBox; + sendBoxVsKdir[KDIR][1] += 1; + sendBoxVsKdir[JDIR][0] += offset - ny; + sendBoxVsKdir[JDIR][1] += offset - ny; + bufferSend.Pack(Vs, KDIR, sendBoxVsKdir); } // MHD } // side==right Kokkos::fence(); tStart = MPI_Wtime(); - MPI_SAFE_CALL(MPI_Start(&sendRequest)); - MPI_Wait(&recvRequest,&recvStatus); + MPI_SAFE_CALL(idfx::MPI_Start(&sendRequest)); + idfx::MPI_Wait(&recvRequest,&recvStatus); idfx::mpiCallsTimer += MPI_Wtime() - tStart; // Unpack - auto bufferRecv=this->bufferRecv; + Buffer bufferRecv=this->bufferRecv; + bufferRecv.ResetPointer(); auto sVc = this->symmetryVc; if(side==left) { - idefix_for("StoreBufferAxis",0,mapNVars,kbeg,kend,jbeg,jend,ibeg,iend, - KOKKOS_LAMBDA (int n, int k, int j, int i) { - Vc(map(n),k,jend-(j-jbeg)-1,i) = - sVc(map(n))*bufferRecv(i + (j-jbeg)*nx + (k-kbeg)*nx*ny + n*nx*ny*nz ); - } - ); + //unpack Vc + BoundingBox recvBoxVc = baseBox; + bufferRecv.UnpackJDirSymetric(Vc, map, sVc, recvBoxVc); // Load face-centered field in the buffer if (haveMHD) { - int VsIndex = mapNVars*nx*ny*nz; auto sVs = this->symmetryVs; - idefix_for("StoreBufferX2IDIR",kbeg,kend,jbeg,jend,ibeg,iend+1, - KOKKOS_LAMBDA (int k, int j, int i) { - Vs(IDIR,k,jend-(j-jbeg)-1,i) = - sVs(IDIR)*bufferRecv(i + (j-jbeg)*(nx+1) + (k-kbeg)*(nx+1)*ny + VsIndex ); - } - ); - VsIndex = mapNVars*nx*ny*nz + (nx+1)*ny*nz; + //unpack Vs face-centered + BoundingBox recvBoxVsIdir = baseBox; + recvBoxVsIdir[IDIR][1] += 1; + bufferRecv.UnpackJDirSymetric(Vs, IDIR, sVs, recvBoxVsIdir); - idefix_for("StoreBufferX2KDIR",kbeg,kend+1,jbeg,jend,ibeg,iend, - KOKKOS_LAMBDA ( int k, int j, int i) { - Vs(KDIR,k,jend-(j-jbeg)-1,i) = - sVs(KDIR)*bufferRecv(i + (j-jbeg)*nx + (k-kbeg)*nx*ny + VsIndex ); - } - ); + //unpack Vs face-centered + BoundingBox recvBoxVsKdir = baseBox; + recvBoxVsKdir[KDIR][1] += 1; + bufferRecv.UnpackJDirSymetric(Vs, KDIR, sVs, recvBoxVsKdir); } } else if(side==right) { - idefix_for("StoreBufferAxis",0,mapNVars,kbeg,kend,jbeg,jend,ibeg,iend, - KOKKOS_LAMBDA (int n, int k, int j, int i) { - Vc(map(n),k,jend-(j-jbeg)-1+offset,i) = - sVc(map(n))*bufferRecv(i + (j-jbeg)*nx + (k-kbeg)*nx*ny + n*nx*ny*nz ); - } - ); + //unpack Vc on right part + BoundingBox recvBoxVc = baseBox; + recvBoxVc[JDIR][0] += offset; + recvBoxVc[JDIR][1] += offset; + bufferRecv.UnpackJDirSymetric(Vc, map, sVc, recvBoxVc); // Load face-centered field in the buffer if (haveMHD) { - int VsIndex = mapNVars*nx*ny*nz; auto sVs = this->symmetryVs; - idefix_for("StoreBufferX2IDIR",kbeg,kend,jbeg,jend,ibeg,iend+1, - KOKKOS_LAMBDA (int k, int j, int i) { - Vs(IDIR,k,jend-(j-jbeg)-1+offset,i) = - sVs(IDIR)*bufferRecv(i + (j-jbeg)*(nx+1) + (k-kbeg)*(nx+1)*ny + VsIndex ); - } - ); - VsIndex = mapNVars*nx*ny*nz + (nx+1)*ny*nz; - idefix_for("StoreBufferX2KDIR",kbeg,kend+1,jbeg,jend,ibeg,iend, - KOKKOS_LAMBDA ( int k, int j, int i) { - Vs(KDIR,k,jend-(j-jbeg)-1+offset,i) = - sVs(KDIR)*bufferRecv(i + (j-jbeg)*nx + (k-kbeg)*nx*ny + VsIndex ); - } - ); + //unpack Vs face-centered on right part + BoundingBox recvBoxVsIdir = baseBox; + recvBoxVsIdir[IDIR][1] += 1; + recvBoxVsIdir[JDIR][0] += offset; + recvBoxVsIdir[JDIR][1] += offset; + bufferRecv.UnpackJDirSymetric(Vs, IDIR, sVs, recvBoxVsIdir); + + //unpack Vs face-centered on right part + BoundingBox recvBoxVsKdir = baseBox; + recvBoxVsKdir[KDIR][1] += 1; + recvBoxVsKdir[JDIR][0] += offset; + recvBoxVsKdir[JDIR][1] += offset; + bufferRecv.UnpackJDirSymetric(Vs, KDIR, sVs, recvBoxVsKdir); } // MHD } - MPI_Wait(&sendRequest, &sendStatus); - + idfx::MPI_Wait(&sendRequest, &sendStatus); idfx::mpiCallsTimer += MPI_Wtime() - tStart; @@ -594,8 +592,9 @@ void Axis::InitMPI() { #endif // DIMENSIONS } - this->bufferRecv = IdefixArray1D("bufferRecvAxis", bufferSize); - this->bufferSend = IdefixArray1D("bufferSendAxis", bufferSize); + //build buffers + this->bufferRecv = Buffer(bufferSize); + this->bufferSend = Buffer(bufferSize); // init persistent communications // We receive from procRecv, and we send to procSend @@ -605,11 +604,11 @@ void Axis::InitMPI() { MPI_SAFE_CALL(MPI_Cart_shift(data->mygrid->AxisComm,0,data->mygrid->nproc[KDIR]/2, &procRecv,&procSend )); - MPI_SAFE_CALL(MPI_Send_init(bufferSend.data(), bufferSize, realMPI, procSend, - 650, data->mygrid->AxisComm, &sendRequest)); + MPI_SAFE_CALL(idfx::MPI_Send_init(bufferSend.commView(), bufferSend.Size(), + realMPI, procSend, 650, data->mygrid->AxisComm, &sendRequest)); - MPI_SAFE_CALL(MPI_Recv_init(bufferRecv.data(), bufferSize, realMPI, procRecv, - 650, data->mygrid->AxisComm, &recvRequest)); + MPI_SAFE_CALL(idfx::MPI_Recv_init(bufferRecv.commView(), bufferRecv.Size(), + realMPI, procRecv, 650, data->mygrid->AxisComm, &recvRequest)); #endif idfx::popRegion(); diff --git a/src/fluid/boundary/axis.hpp b/src/fluid/boundary/axis.hpp index 1a1227b61..eb92688e0 100644 --- a/src/fluid/boundary/axis.hpp +++ b/src/fluid/boundary/axis.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/boundary/axis.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2026) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -11,6 +19,7 @@ #include #include "idefix.hpp" #include "grid.hpp" +#include "buffer.hpp" // Forward class hydro declaration #include "physics.hpp" @@ -56,11 +65,11 @@ class Axis { enum {faceTop, faceBot}; #ifdef WITH_MPI - MPI_Request sendRequest; - MPI_Request recvRequest; + idfx::MPI_Request_1D sendRequest; + idfx::MPI_Request_1D recvRequest; - IdefixArray1D bufferSend; - IdefixArray1D bufferRecv; + Buffer bufferSend; + Buffer bufferRecv; int bufferSize; @@ -70,8 +79,8 @@ class Axis { #endif void InitMPI(); - IdefixArray1D Ex1Avg; - IdefixArray2D BAvg; + idfx::IdefixCommArray1D Ex1Avg; + idfx::IdefixCommArray2D BAvg; bool haveCurrent; IdefixArray2D JAvg; IdefixArray1D symmetryVc; @@ -126,7 +135,7 @@ Axis::Axis(Boundary *boundary) { // Init the symmetry array (used to flip the signs of arrays accross the axis) symmetryVc = IdefixArray1D("Axis:SymmetryVc",nVar); - IdefixArray1D::HostMirror symmetryVcHost = Kokkos::create_mirror_view(symmetryVc); + IdefixArray1D::host_mirror_type symmetryVcHost = Kokkos::create_mirror_view(symmetryVc); // Init the array for (int nv = 0; nv < nVar; nv++) { symmetryVcHost(nv) = 1; @@ -143,7 +152,7 @@ Axis::Axis(Boundary *boundary) { if constexpr(Phys::mhd) { symmetryVs = IdefixArray1D("Axis:SymmetryVs",DIMENSIONS); - IdefixArray1D::HostMirror symmetryVsHost = Kokkos::create_mirror_view(symmetryVs); + IdefixArray1D::host_mirror_type symmetryVsHost = Kokkos::create_mirror_view(symmetryVs); // Init the array for(int nv = 0; nv < DIMENSIONS; nv++) { symmetryVsHost(nv) = 1; @@ -154,8 +163,8 @@ Axis::Axis(Boundary *boundary) { } Kokkos::deep_copy(symmetryVs, symmetryVsHost); - this->Ex1Avg = IdefixArray1D("Axis:Ex1Avg",data->np_tot[IDIR]); - this->BAvg = IdefixArray2D("Axis:BxAvg",data->np_tot[IDIR],2); + this->Ex1Avg = idfx::IdefixCommArray1D("Axis:Ex1Avg",data->np_tot[IDIR]); + this->BAvg = idfx::IdefixCommArray2D("Axis:BxAvg",data->np_tot[IDIR],2); if(haveCurrent) { this->JAvg = IdefixArray2D("Axis:JAvg",data->np_tot[IDIR],3); } diff --git a/src/fluid/boundary/boundary.hpp b/src/fluid/boundary/boundary.hpp index 4065cc60d..56c7cac20 100644 --- a/src/fluid/boundary/boundary.hpp +++ b/src/fluid/boundary/boundary.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/boundary/boundary.hpp +// +// Last modified : 12/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2025) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/braginskii/CMakeLists.txt b/src/fluid/braginskii/CMakeLists.txt index 8e2198c23..8b6414014 100644 --- a/src/fluid/braginskii/CMakeLists.txt +++ b/src/fluid/braginskii/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/fluid/braginskii/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/bragThermalDiffusion.hpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/bragThermalDiffusion.cpp diff --git a/src/fluid/braginskii/bragThermalDiffusion.cpp b/src/fluid/braginskii/bragThermalDiffusion.cpp index f251d0b0c..6bd32d170 100644 --- a/src/fluid/braginskii/bragThermalDiffusion.cpp +++ b/src/fluid/braginskii/bragThermalDiffusion.cpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/braginskii/bragThermalDiffusion.cpp +// +// Last modified : 01/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// - Victor Réville (IRAP - 2024 - 2025) +// - Jean Kempf (IRAP - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/braginskii/bragThermalDiffusion.hpp b/src/fluid/braginskii/bragThermalDiffusion.hpp index 116ff9a03..065976614 100644 --- a/src/fluid/braginskii/bragThermalDiffusion.hpp +++ b/src/fluid/braginskii/bragThermalDiffusion.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/braginskii/bragThermalDiffusion.hpp +// +// Last modified : 01/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// - Victor Réville (IRAP - 2024 - 2025) +// - Jean Kempf (IRAP - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/braginskii/bragViscosity.cpp b/src/fluid/braginskii/bragViscosity.cpp index e53ab2c65..7f6d363b1 100644 --- a/src/fluid/braginskii/bragViscosity.cpp +++ b/src/fluid/braginskii/bragViscosity.cpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/braginskii/bragViscosity.cpp +// +// Last modified : 01/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// - Jean Kempf (IRAP - 2025) +// - Victor Réville (IRAP - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/braginskii/bragViscosity.hpp b/src/fluid/braginskii/bragViscosity.hpp index 5340110a8..4e7acfbb1 100644 --- a/src/fluid/braginskii/bragViscosity.hpp +++ b/src/fluid/braginskii/bragViscosity.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/braginskii/bragViscosity.hpp +// +// Last modified : 01/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// - Jean Kempf (IRAP - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/calcCurrent.hpp b/src/fluid/calcCurrent.hpp index 1f57560a0..14a47ade6 100644 --- a/src/fluid/calcCurrent.hpp +++ b/src/fluid/calcCurrent.hpp @@ -1,9 +1,20 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/calcCurrent.hpp +// +// Last modified : 03/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2024) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** + #ifndef FLUID_CALCCURRENT_HPP_ #define FLUID_CALCCURRENT_HPP_ diff --git a/src/fluid/calcParabolicFlux.hpp b/src/fluid/calcParabolicFlux.hpp index a8c6761c0..68e1c065e 100644 --- a/src/fluid/calcParabolicFlux.hpp +++ b/src/fluid/calcParabolicFlux.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/calcParabolicFlux.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** #ifndef FLUID_CALCPARABOLICFLUX_HPP_ @@ -42,7 +51,7 @@ void Fluid::CalcParabolicFlux(const real t) { if(data->haveFargo && viscosityStatus.isExplicit) { data->fargo->AddVelocityFluid(t,this); } - this->viscosity->AddViscousFlux(dir,t, this->FluxRiemann); + this->viscosity->AddViscousFlux(dir,t, this->FluxRiemann[dir]); // Remove back Fargo velocity if(data->haveFargo && viscosityStatus.isExplicit) { @@ -53,18 +62,18 @@ void Fluid::CalcParabolicFlux(const real t) { // Add thermal diffusion if( (thermalDiffusionStatus.isExplicit && (!data->rklCycle)) || (thermalDiffusionStatus.isRKL && data->rklCycle)) { - this->thermalDiffusion->AddDiffusiveFlux(dir,t, this->FluxRiemann); + this->thermalDiffusion->AddDiffusiveFlux(dir,t, this->FluxRiemann[dir]); } if( (bragViscosityStatus.isExplicit && (!data->rklCycle)) || (bragViscosityStatus.isRKL && data->rklCycle)) { - this->bragViscosity->AddBragViscousFlux(dir,t, this->FluxRiemann); + this->bragViscosity->AddBragViscousFlux(dir,t, this->FluxRiemann[dir]); } // Add braginskii thermal diffusion if( (bragThermalDiffusionStatus.isExplicit && (!data->rklCycle)) || (bragThermalDiffusionStatus.isRKL && data->rklCycle)) { - this->bragThermalDiffusion->AddBragDiffusiveFlux(dir,t, this->FluxRiemann); + this->bragThermalDiffusion->AddBragDiffusiveFlux(dir,t, this->FluxRiemann[dir]); } idfx::popRegion(); diff --git a/src/fluid/calcRightHandSide.hpp b/src/fluid/calcRightHandSide.hpp index 0a0d3e194..acbc66f03 100644 --- a/src/fluid/calcRightHandSide.hpp +++ b/src/fluid/calcRightHandSide.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/calcRightHandSide.hpp +// +// Last modified : 11/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2025) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -21,7 +29,7 @@ struct Fluid_CorrectFluxFunctor { explicit Fluid_CorrectFluxFunctor (Fluid *hydro, real dt) { Uc = hydro->Uc; Vc = hydro->Vc; - Flux = hydro->FluxRiemann; + Flux = hydro->FluxRiemann[dir]; A = hydro->data->A[dir]; dV = hydro->data->dV; x1m = hydro->data->xl[IDIR]; @@ -205,7 +213,7 @@ struct Fluid_CalcRHSFunctor { explicit Fluid_CalcRHSFunctor (Fluid *hydro, real dt) { Uc = hydro->Uc; Vc = hydro->Vc; - Flux = hydro->FluxRiemann; + Flux = hydro->FluxRiemann[dir]; A = hydro->data->A[dir]; dV = hydro->data->dV; x1m = hydro->data->xl[IDIR]; diff --git a/src/fluid/checkDivB.hpp b/src/fluid/checkDivB.hpp index 6e47d4c8c..f5ddcd67b 100644 --- a/src/fluid/checkDivB.hpp +++ b/src/fluid/checkDivB.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/checkDivB.hpp +// +// Last modified : 03/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2026) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/checkNan.hpp b/src/fluid/checkNan.hpp index 0e8890725..654e01eba 100644 --- a/src/fluid/checkNan.hpp +++ b/src/fluid/checkNan.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/checkNan.hpp +// +// Last modified : 01/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2024) +// - Alankar Dutta (MPA Garching - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/coarsenFlow.hpp b/src/fluid/coarsenFlow.hpp index b1bf79eaa..0ce030d9a 100644 --- a/src/fluid/coarsenFlow.hpp +++ b/src/fluid/coarsenFlow.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/coarsenFlow.hpp +// +// Last modified : 10/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/constrainedTransport/CMakeLists.txt b/src/fluid/constrainedTransport/CMakeLists.txt index 7d99b805c..d9ce0c658 100644 --- a/src/fluid/constrainedTransport/CMakeLists.txt +++ b/src/fluid/constrainedTransport/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/fluid/constrainedTransport/CMakeLists.txt +# +# Last modified : 12/2025 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2025) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/calcCornerEmf.hpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/calcNonidealEMF.hpp diff --git a/src/fluid/constrainedTransport/EMFexchange.hpp b/src/fluid/constrainedTransport/EMFexchange.hpp index f6e90f75a..fd6eb555c 100644 --- a/src/fluid/constrainedTransport/EMFexchange.hpp +++ b/src/fluid/constrainedTransport/EMFexchange.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/constrainedTransport/EMFexchange.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2025) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -30,12 +39,10 @@ void ConstrainedTransport::ExchangeX1(IdefixArray3D ey, IdefixArray3 // Load the buffers with data - int ileft,iright,jbeg,jend,kbeg,kend; - int ny; - [[maybe_unused]] int nz; + int ileft,iright,jbeg,jend; - IdefixArray1D BufferLeft=BufferSendX1[faceLeft]; - IdefixArray1D BufferRight=BufferSendX1[faceRight]; + Buffer BufferLeft=BufferSendX1[faceLeft]; + Buffer BufferRight=BufferSendX1[faceRight]; // If MPI Persistent, start receiving even before the buffers are filled @@ -43,7 +50,7 @@ void ConstrainedTransport::ExchangeX1(IdefixArray3D ey, IdefixArray3 MPI_Status recvStatus[2]; double tStart = MPI_Wtime(); - MPI_SAFE_CALL(MPI_Startall(2, recvRequestX1)); + MPI_SAFE_CALL(idfx::MPI_Startall(2, recvRequestX1)); idfx::mpiCallsTimer += MPI_Wtime() - tStart; BoundaryType lbound = data->lbound[IDIR]; @@ -54,35 +61,40 @@ void ConstrainedTransport::ExchangeX1(IdefixArray3D ey, IdefixArray3 iright = data->end[IDIR]; jbeg = data->beg[JDIR]; jend = data->end[JDIR]; - ny = jend - jbeg; - kbeg = data->beg[KDIR]; - kend = data->end[KDIR]; - nz = kend - kbeg; - - idefix_for("LoadBufferX1Emfz",kbeg,kend,jbeg,jend+1, - KOKKOS_LAMBDA (int k, int j) { - BufferRight( (j-jbeg) + (k-kbeg)*(ny+1) ) = ez(k,j,iright); - } - ); + + // Create the base box to be patched by the ops + BoundingBox baseBox; + baseBox[IDIR][0] = data->beg[IDIR]; + baseBox[IDIR][1] = data->end[IDIR]; + baseBox[JDIR][0] = data->beg[JDIR]; + baseBox[JDIR][1] = data->end[JDIR]; + baseBox[KDIR][0] = data->beg[KDIR]; + baseBox[KDIR][1] = data->end[KDIR]; + + //extend by one the end on jdir && take the ghost on i + BoundingBox sendBoxEz = baseBox; + sendBoxEz[JDIR][1] += 1; + sendBoxEz[IDIR][0] = iright; + sendBoxEz[IDIR][1] = iright + 1; + BufferRight.Pack(ez, sendBoxEz); #if DIMENSIONS == 3 - int Vsindex = (ny+1)*nz; - idefix_for("LoadBufferX1Emfy",kbeg,kend+1,jbeg,jend, - KOKKOS_LAMBDA (int k, int j) { - BufferRight( (j-jbeg) + (k-kbeg)*ny + Vsindex ) = ey(k,j,iright); - } - ); + //extend by one the end on kdir && take the ghost on i + BoundingBox sendBoxEy = baseBox; + sendBoxEy[KDIR][1] += 1; + sendBoxEy[IDIR][0] = iright; + sendBoxEy[IDIR][1] = iright + 1; + BufferRight.Pack(ey, sendBoxEy); #endif // Wait for completion before sending out everything Kokkos::fence(); tStart = MPI_Wtime(); - MPI_SAFE_CALL(MPI_Startall(2, sendRequestX1)); + MPI_SAFE_CALL(idfx::MPI_Startall(2, sendRequestX1)); // Wait for buffers to be received - - MPI_Waitall(2,recvRequestX1,recvStatus); - MPI_Waitall(2, sendRequestX1, sendStatus); + idfx::MPI_Waitall(2,recvRequestX1,recvStatus); + idfx::MPI_Waitall(2, sendRequestX1, sendStatus); idfx::mpiCallsTimer += MPI_Wtime() - tStart; // Unpack @@ -90,22 +102,22 @@ void ConstrainedTransport::ExchangeX1(IdefixArray3D ey, IdefixArray3 BufferRight=BufferRecvX1[faceRight]; // Erase the emf with the one coming from the left process - - idefix_for("StoreBufferX1Emfz",kbeg,kend,jbeg,jend+1, - KOKKOS_LAMBDA (int k, int j) { - if(lbound == internal || lbound == periodic) { - ez(k,j,ileft) = BufferLeft( (j-jbeg) + (k-kbeg)*(ny+1)); - } - }); + //extend by one the end on jdir && take the ghost revc zone on i + BoundingBox recvBoxEz = baseBox; + recvBoxEz[JDIR][1] += 1; + recvBoxEz[IDIR][0] = ileft; + recvBoxEz[IDIR][1] = ileft + 1; + if(lbound == internal || lbound == periodic) + BufferLeft.Unpack(ez, recvBoxEz); #if DIMENSIONS == 3 - Vsindex = (ny+1)*nz; - idefix_for("StoreBufferX1Emfy",kbeg,kend+1,jbeg,jend, - KOKKOS_LAMBDA (int k, int j) { - if(lbound == internal || lbound == periodic) { - ey(k,j,ileft) = BufferLeft( (j-jbeg) + (k-kbeg)*ny +Vsindex); - } - }); + //extend by one the end on kdir && take the ghost revc zone on i + BoundingBox recvBoxEy = baseBox; + recvBoxEy[KDIR][1] += 1; + recvBoxEy[IDIR][0] = ileft; + recvBoxEy[IDIR][1] = ileft + 1; + if(lbound == internal || lbound == periodic) + BufferLeft.Unpack(ey, recvBoxEy); #endif @@ -118,55 +130,57 @@ void ConstrainedTransport::ExchangeX2(IdefixArray3D ex, IdefixArray3 idfx::pushRegion("Emf::ExchangeX2"); // Load the buffers with data - int jleft,jright,ibeg,iend,kbeg,kend; - int nx; - [[maybe_unused]] int nz; - IdefixArray1D BufferLeft=BufferSendX2[faceLeft]; - IdefixArray1D BufferRight=BufferSendX2[faceRight]; + int jleft,jright; + Buffer BufferLeft=BufferSendX2[faceLeft]; + Buffer BufferRight=BufferSendX2[faceRight]; // If MPI Persistent, start receiving even before the buffers are filled double tStart = MPI_Wtime(); MPI_Status sendStatus[2]; MPI_Status recvStatus[2]; - MPI_SAFE_CALL(MPI_Startall(2, recvRequestX2)); + MPI_SAFE_CALL(idfx::MPI_Startall(2, recvRequestX2)); idfx::mpiCallsTimer += MPI_Wtime() - tStart; BoundaryType lbound = data->lbound[JDIR]; BoundaryType rbound = data->rbound[JDIR]; // Coordinates of the ghost region which needs to be transfered - ibeg = data->beg[IDIR]; - iend = data->end[IDIR]; - nx = iend - ibeg; jleft = data->beg[JDIR]; jright = data->end[JDIR]; - kbeg = data->beg[KDIR]; - kend = data->end[KDIR]; - nz = kend - kbeg; - - idefix_for("LoadBufferX2Emfz",kbeg,kend,ibeg,iend+1, - KOKKOS_LAMBDA (int k, int i) { - BufferRight( (i-ibeg) + (k-kbeg)*(nx+1) ) = ez(k,jright,i); - } - ); + + // Create the base box to be patched by the ops + BoundingBox baseBox; + baseBox[IDIR][0] = data->beg[IDIR]; + baseBox[IDIR][1] = data->end[IDIR]; + baseBox[JDIR][0] = data->beg[JDIR]; + baseBox[JDIR][1] = data->end[JDIR]; + baseBox[KDIR][0] = data->beg[KDIR]; + baseBox[KDIR][1] = data->end[KDIR]; + + //extend by one the end on idir && take the ghost on j + BoundingBox sendBoxEz = baseBox; + sendBoxEz[IDIR][1] += 1; + sendBoxEz[JDIR][0] = jright; + sendBoxEz[JDIR][1] = jright + 1; + BufferRight.Pack(ez, sendBoxEz); #if DIMENSIONS == 3 - int Vsindex = (nx+1)*nz; - idefix_for("LoadBufferX1Emfx",kbeg,kend+1,ibeg,iend, - KOKKOS_LAMBDA (int k, int i) { - BufferRight( (i-ibeg) + (k-kbeg)*nx + Vsindex ) = ex(k,jright,i); - } - ); + //extend by one the end on idir && take the ghost on j + BoundingBox sendBoxEx = baseBox; + sendBoxEx[KDIR][1] += 1; + sendBoxEx[JDIR][0] = jright; + sendBoxEx[JDIR][1] = jright + 1; + BufferRight.Pack(ex, sendBoxEx); #endif // Wait for completion before sending out everything Kokkos::fence(); tStart = MPI_Wtime(); - MPI_SAFE_CALL(MPI_Startall(2, sendRequestX2)); + MPI_SAFE_CALL(idfx::MPI_Startall(2, sendRequestX2)); // Wait for buffers to be received - MPI_Waitall(2,recvRequestX2,recvStatus); - MPI_Waitall(2, sendRequestX2, sendStatus); + idfx::MPI_Waitall(2, recvRequestX2, recvStatus); + idfx::MPI_Waitall(2, sendRequestX2, sendStatus); idfx::mpiCallsTimer += MPI_Wtime() - tStart; // Unpack @@ -174,20 +188,21 @@ void ConstrainedTransport::ExchangeX2(IdefixArray3D ex, IdefixArray3 BufferRight=BufferRecvX2[faceRight]; // We average the edge emfs zones - idefix_for("StoreBufferX2Emfz",kbeg,kend,ibeg,iend+1, - KOKKOS_LAMBDA (int k, int i) { - if(lbound == internal || lbound == periodic) { - ez(k,jleft,i) = BufferLeft( (i-ibeg) + (k-kbeg)*(nx+1) ); - } - }); + //extend by one the end on idir && take the ghost revc zone on j + BoundingBox recvBoxEz = baseBox; + recvBoxEz[IDIR][1] += 1; + recvBoxEz[JDIR][0] = jleft; + recvBoxEz[JDIR][1] = jleft + 1; + if(lbound == internal || lbound == periodic) + BufferLeft.Unpack(ez, recvBoxEz); #if DIMENSIONS == 3 - Vsindex = (nx+1)*nz; - idefix_for("StoreBufferX1Emfy",kbeg,kend+1,ibeg,iend, - KOKKOS_LAMBDA (int k, int i) { - if(lbound == internal || lbound == periodic) { - ex(k,jleft,i) = BufferLeft( (i-ibeg) + (k-kbeg)*nx +Vsindex); - } - }); + //extend by one the end on kdir && take the ghost revc zone on j + BoundingBox recvBoxEx = baseBox; + recvBoxEx[KDIR][1] += 1; + recvBoxEx[JDIR][0] = jleft; + recvBoxEx[JDIR][1] = jleft + 1; + if(lbound == internal || lbound == periodic) + BufferLeft.Unpack(ex, recvBoxEx); #endif @@ -201,57 +216,58 @@ void ConstrainedTransport::ExchangeX3(IdefixArray3D ex, IdefixArray3 // Load the buffers with data - int kleft,kright,ibeg,iend,jbeg,jend; - int nx,ny; - IdefixArray1D BufferLeft=BufferSendX3[faceLeft]; - IdefixArray1D BufferRight=BufferSendX3[faceRight]; - - int Vsindex = 0; - + int kleft,kright,jbeg,jend; + Buffer BufferLeft=BufferSendX3[faceLeft]; + Buffer BufferRight=BufferSendX3[faceRight]; // If MPI Persistent, start receiving even before the buffers are filled double tStart = MPI_Wtime(); MPI_Status sendStatus[2]; MPI_Status recvStatus[2]; - MPI_SAFE_CALL(MPI_Startall(2, recvRequestX3)); + MPI_SAFE_CALL(idfx::MPI_Startall(2, recvRequestX3)); idfx::mpiCallsTimer += MPI_Wtime() - tStart; BoundaryType lbound = data->lbound[KDIR]; BoundaryType rbound = data->rbound[KDIR]; // Coordinates of the ghost region which needs to be transfered - ibeg = data->beg[IDIR]; - iend = data->end[IDIR]; - nx = iend - ibeg; - jbeg = data->beg[JDIR]; jend = data->end[JDIR]; - ny = jend - jbeg; kleft = data->beg[KDIR]; kright = data->end[KDIR]; - idefix_for("LoadBufferX3Emfx",jbeg,jend+1,ibeg,iend, - KOKKOS_LAMBDA (int j, int i) { - BufferRight( (i-ibeg) + (j-jbeg)*nx ) = ex(kright,j,i); - } - ); - Vsindex = nx*(ny+1); - - idefix_for("LoadBufferX3Emfy",jbeg,jend,ibeg,iend+1, - KOKKOS_LAMBDA (int j, int i) { - BufferRight( (i-ibeg) + (j-jbeg)*(nx+1) + Vsindex ) = ey(kright,j,i); - } - ); + // Create the base box to be patched by the ops + BoundingBox baseBox; + baseBox[IDIR][0] = data->beg[IDIR]; + baseBox[IDIR][1] = data->end[IDIR]; + baseBox[JDIR][0] = data->beg[JDIR]; + baseBox[JDIR][1] = data->end[JDIR]; + baseBox[KDIR][0] = data->beg[KDIR]; + baseBox[KDIR][1] = data->end[KDIR]; + + //extend by one the end on jdir && take the ghost on k + BoundingBox sendBoxEx = baseBox; + sendBoxEx[JDIR][1] += 1; + sendBoxEx[KDIR][0] = kright; + sendBoxEx[KDIR][1] = kright + 1; + BufferRight.Pack(ex, sendBoxEx); + + //extend by one the end on idir && take the ghost on k + BoundingBox sendBoxEy = baseBox; + sendBoxEy[IDIR][1] += 1; + sendBoxEy[KDIR][0] = kright; + sendBoxEy[KDIR][1] = kright + 1; + BufferRight.Pack(ey, sendBoxEy); // Wait for completion before sending out everything Kokkos::fence(); tStart = MPI_Wtime(); - MPI_SAFE_CALL(MPI_Startall(2, sendRequestX3)); + MPI_SAFE_CALL(idfx::MPI_Startall(2, sendRequestX3)); // Wait for buffers to be received - MPI_Waitall(2,recvRequestX3,recvStatus); - MPI_Waitall(2, sendRequestX3, sendStatus); + idfx::MPI_Waitall(2, recvRequestX3, recvStatus); + idfx::MPI_Waitall(2, sendRequestX3, sendStatus); idfx::mpiCallsTimer += MPI_Wtime() - tStart; // Unpack @@ -259,20 +275,21 @@ void ConstrainedTransport::ExchangeX3(IdefixArray3D ex, IdefixArray3 BufferRight=BufferRecvX3[faceRight]; // We average the edge emfs zones - idefix_for("StoreBufferX3Emfx",jbeg,jend+1,ibeg,iend, - KOKKOS_LAMBDA (int j, int i) { - if(lbound == internal || lbound == periodic) { - ex(kleft,j,i) = BufferLeft( (i-ibeg) + (j-jbeg)*nx ); - } - }); - - Vsindex = nx*(ny+1); - idefix_for("StoreBufferX3Emfy",jbeg,jend,ibeg,iend+1, - KOKKOS_LAMBDA (int j, int i) { - if(lbound == internal || lbound == periodic) { - ey(kleft,j,i) = BufferLeft( (i-ibeg) + (j-jbeg)*(nx+1) + Vsindex ); - } - }); + //extend by one the end on jdir && take the ghost revc zone on k + BoundingBox recvBoxEx = baseBox; + recvBoxEx[JDIR][1] += 1; + recvBoxEx[KDIR][0] = kleft; + recvBoxEx[KDIR][1] = kleft + 1; + if(lbound == internal || lbound == periodic) + BufferLeft.Unpack(ex, recvBoxEx); + + //extend by one the end on idir && take the ghost revc zone on k + BoundingBox recvBoxEy = baseBox; + recvBoxEy[IDIR][1] += 1; + recvBoxEy[KDIR][0] = kleft; + recvBoxEy[KDIR][1] = kleft + 1; + if(lbound == internal || lbound == periodic) + BufferLeft.Unpack(ey, recvBoxEy); idfx::popRegion(); } diff --git a/src/fluid/constrainedTransport/calcCornerEmf.hpp b/src/fluid/constrainedTransport/calcCornerEmf.hpp index 0a998aa52..8b04ab2a8 100644 --- a/src/fluid/constrainedTransport/calcCornerEmf.hpp +++ b/src/fluid/constrainedTransport/calcCornerEmf.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/constrainedTransport/calcCornerEmf.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020 - 2021) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** #ifndef FLUID_CONSTRAINEDTRANSPORT_CALCCORNEREMF_HPP_ diff --git a/src/fluid/constrainedTransport/calcNonidealEMF.hpp b/src/fluid/constrainedTransport/calcNonidealEMF.hpp index 2253e33d1..2ca5834e1 100644 --- a/src/fluid/constrainedTransport/calcNonidealEMF.hpp +++ b/src/fluid/constrainedTransport/calcNonidealEMF.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/constrainedTransport/calcNonidealEMF.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/constrainedTransport/calcRiemannEmf.hpp b/src/fluid/constrainedTransport/calcRiemannEmf.hpp index 2779ffbab..5a56f0519 100644 --- a/src/fluid/constrainedTransport/calcRiemannEmf.hpp +++ b/src/fluid/constrainedTransport/calcRiemannEmf.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/constrainedTransport/calcRiemannEmf.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/constrainedTransport/constrainedTransport.hpp b/src/fluid/constrainedTransport/constrainedTransport.hpp index 24c317c09..6d53e86b6 100644 --- a/src/fluid/constrainedTransport/constrainedTransport.hpp +++ b/src/fluid/constrainedTransport/constrainedTransport.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/constrainedTransport/constrainedTransport.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2025) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2021) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -11,6 +20,7 @@ #include "idefix.hpp" #include "input.hpp" #include "riemannSolver.hpp" +#include "buffer.hpp" // Forward declarations #include "physics.hpp" @@ -67,9 +77,9 @@ class ConstrainedTransport { IdefixArray3D Ex3; // Helper arrays for shearing box - IdefixArray2D sbEyL; - IdefixArray2D sbEyR; - IdefixArray2D sbEyRL; + idfx::IdefixCommArray2D sbEyL; + idfx::IdefixCommArray2D sbEyR; + idfx::IdefixCommArray2D sbEyRL; // Range of existence @@ -122,12 +132,12 @@ class ConstrainedTransport { enum {faceRight, faceLeft}; // Buffers for MPI calls - IdefixArray1D BufferSendX1[2]; - IdefixArray1D BufferSendX2[2]; - IdefixArray1D BufferSendX3[2]; - IdefixArray1D BufferRecvX1[2]; - IdefixArray1D BufferRecvX2[2]; - IdefixArray1D BufferRecvX3[2]; + Buffer BufferSendX1[2]; + Buffer BufferSendX2[2]; + Buffer BufferSendX3[2]; + Buffer BufferRecvX1[2]; + Buffer BufferRecvX2[2]; + Buffer BufferRecvX3[2]; IdefixArray1D mapVars; @@ -136,12 +146,12 @@ class ConstrainedTransport { int bufferSizeX3; // Requests for MPI persistent communications - MPI_Request sendRequestX1[2]; - MPI_Request sendRequestX2[2]; - MPI_Request sendRequestX3[2]; - MPI_Request recvRequestX1[2]; - MPI_Request recvRequestX2[2]; - MPI_Request recvRequestX3[2]; + idfx::MPI_Request_1D sendRequestX1[2]; + idfx::MPI_Request_1D sendRequestX2[2]; + idfx::MPI_Request_1D sendRequestX3[2]; + idfx::MPI_Request_1D recvRequestX1[2]; + idfx::MPI_Request_1D recvRequestX2[2]; + idfx::MPI_Request_1D recvRequestX3[2]; Kokkos::Timer timer; // Internal MPI timer #endif @@ -187,9 +197,9 @@ ConstrainedTransport::ConstrainedTransport(Input &input, Fluid *hydr // Allocate shearing box arrays if(hydro->haveShearingBox == true) { - sbEyL = IdefixArray2D("EMF_sbEyL", data->np_tot[KDIR], data->np_tot[JDIR]); - sbEyR = IdefixArray2D("EMF_sbEyR", data->np_tot[KDIR], data->np_tot[JDIR]); - sbEyRL = IdefixArray2D("EMF_sbEyRL", data->np_tot[KDIR], data->np_tot[JDIR]); + sbEyL = idfx::IdefixCommArray2D("EMF_sbEyL", data->np_tot[KDIR], data->np_tot[JDIR]); + sbEyR = idfx::IdefixCommArray2D("EMF_sbEyR", data->np_tot[KDIR], data->np_tot[JDIR]); + sbEyRL = idfx::IdefixCommArray2D("EMF_sbEyRL", data->np_tot[KDIR], data->np_tot[JDIR]); } D_EXPAND( ez = IdefixArray3D("EMF_ez", @@ -286,10 +296,10 @@ ConstrainedTransport::ConstrainedTransport(Input &input, Fluid *hydr bufferSizeX1 += data->np_int[JDIR] * (data->np_int[KDIR]+KOFFSET); #endif - BufferRecvX1[faceLeft ] = IdefixArray1D("EmfRecvX1Left", bufferSizeX1); - BufferRecvX1[faceRight] = IdefixArray1D("EmfRecvX1Right",bufferSizeX1); - BufferSendX1[faceLeft ] = IdefixArray1D("EmfSendX1Left", bufferSizeX1); - BufferSendX1[faceRight] = IdefixArray1D("EmfSendX1Right",bufferSizeX1); + BufferRecvX1[faceLeft ] = Buffer(bufferSizeX1); + BufferRecvX1[faceRight] = Buffer(bufferSizeX1); + BufferSendX1[faceLeft ] = Buffer(bufferSizeX1); + BufferSendX1[faceRight] = Buffer(bufferSizeX1); // Number of cells in X2 boundary condition (only required when problem >2D): #if DIMENSIONS >= 2 @@ -301,10 +311,10 @@ ConstrainedTransport::ConstrainedTransport(Input &input, Fluid *hydr bufferSizeX2 += data->np_int[IDIR] * (data->np_int[KDIR]+KOFFSET); #endif - BufferRecvX2[faceLeft ] = IdefixArray1D("EmfRecvX2Left", bufferSizeX2); - BufferRecvX2[faceRight] = IdefixArray1D("EmfRecvX2Right",bufferSizeX2); - BufferSendX2[faceLeft ] = IdefixArray1D("EmfSendX2Left", bufferSizeX2); - BufferSendX2[faceRight] = IdefixArray1D("EmfSendX2Right",bufferSizeX2); + BufferRecvX2[faceLeft ] = Buffer(bufferSizeX2); + BufferRecvX2[faceRight] = Buffer(bufferSizeX2); + BufferSendX2[faceLeft ] = Buffer(bufferSizeX2); + BufferSendX2[faceRight] = Buffer(bufferSizeX2); #endif // Number of cells in X3 boundary condition (only required when problem is 3D): @@ -314,10 +324,10 @@ ConstrainedTransport::ConstrainedTransport(Input &input, Fluid *hydr // ey bufferSizeX3 += (data->np_int[IDIR]+IOFFSET) * data->np_int[JDIR]; - BufferRecvX3[faceLeft ] = IdefixArray1D("EmfRecvX3Left", bufferSizeX3); - BufferRecvX3[faceRight] = IdefixArray1D("EmfRecvX3Right",bufferSizeX3); - BufferSendX3[faceLeft ] = IdefixArray1D("EmfSendX3Left", bufferSizeX3); - BufferSendX3[faceRight] = IdefixArray1D("EmfSendX3Right",bufferSizeX3); + BufferRecvX3[faceLeft ] = Buffer(bufferSizeX3); + BufferRecvX3[faceRight] = Buffer(bufferSizeX3); + BufferSendX3[faceLeft ] = Buffer(bufferSizeX3); + BufferSendX3[faceRight] = Buffer(bufferSizeX3); #endif // DIMENSIONS // Init persistent MPI communications @@ -330,11 +340,11 @@ ConstrainedTransport::ConstrainedTransport(Input &input, Fluid *hydr if(data->rbound[IDIR] == shearingbox ) procSend = MPI_PROC_NULL; if(data->lbound[IDIR] == shearingbox ) procRecv = MPI_PROC_NULL; - MPI_SAFE_CALL(MPI_Send_init(BufferSendX1[faceRight].data(), bufferSizeX1, realMPI, procSend, 100, - mygrid->CartComm, &sendRequestX1[faceRight])); + MPI_SAFE_CALL(idfx::MPI_Send_init(BufferSendX1[faceRight].commView(), bufferSizeX1, + realMPI, procSend, 100, mygrid->CartComm, &sendRequestX1[faceRight])); - MPI_SAFE_CALL(MPI_Recv_init(BufferRecvX1[faceLeft].data(), bufferSizeX1, realMPI, procRecv, 100, - mygrid->CartComm, &recvRequestX1[faceLeft])); + MPI_SAFE_CALL(idfx::MPI_Recv_init(BufferRecvX1[faceLeft].commView(), bufferSizeX1, + realMPI, procRecv, 100, mygrid->CartComm, &recvRequestX1[faceLeft])); // Send to the left // We receive from procRecv, and we send to procSend @@ -343,52 +353,52 @@ ConstrainedTransport::ConstrainedTransport(Input &input, Fluid *hydr if(data->lbound[IDIR] == shearingbox ) procSend = MPI_PROC_NULL; if(data->rbound[IDIR] == shearingbox ) procRecv = MPI_PROC_NULL; - MPI_SAFE_CALL(MPI_Send_init(BufferSendX1[faceLeft].data(), bufferSizeX1, realMPI, procSend, 101, - mygrid->CartComm, &sendRequestX1[faceLeft])); + MPI_SAFE_CALL(idfx::MPI_Send_init(BufferSendX1[faceLeft].commView(), bufferSizeX1, + realMPI, procSend, 101, mygrid->CartComm, &sendRequestX1[faceLeft])); - MPI_SAFE_CALL(MPI_Recv_init(BufferRecvX1[faceRight].data(), bufferSizeX1, realMPI, procRecv, 101, - mygrid->CartComm, &recvRequestX1[faceRight])); + MPI_SAFE_CALL(idfx::MPI_Recv_init(BufferRecvX1[faceRight].commView(), bufferSizeX1, + realMPI, procRecv, 101, mygrid->CartComm, &recvRequestX1[faceRight])); #if DIMENSIONS >= 2 // We receive from procRecv, and we send to procSend MPI_SAFE_CALL(MPI_Cart_shift(mygrid->CartComm,1,1,&procRecv,&procSend )); - MPI_SAFE_CALL(MPI_Send_init(BufferSendX2[faceRight].data(), bufferSizeX2, realMPI, procSend, 200, - mygrid->CartComm, &sendRequestX2[faceRight])); + MPI_SAFE_CALL(idfx::MPI_Send_init(BufferSendX2[faceRight].commView(), bufferSizeX2, + realMPI, procSend, 200, mygrid->CartComm, &sendRequestX2[faceRight])); - MPI_SAFE_CALL(MPI_Recv_init(BufferRecvX2[faceLeft].data(), bufferSizeX2, realMPI, procRecv, 200, - mygrid->CartComm, &recvRequestX2[faceLeft])); + MPI_SAFE_CALL(idfx::MPI_Recv_init(BufferRecvX2[faceLeft].commView(), bufferSizeX2, + realMPI, procRecv, 200, mygrid->CartComm, &recvRequestX2[faceLeft])); // Send to the left // We receive from procRecv, and we send to procSend MPI_SAFE_CALL(MPI_Cart_shift(mygrid->CartComm,1,-1,&procRecv,&procSend )); - MPI_SAFE_CALL(MPI_Send_init(BufferSendX2[faceLeft].data(), bufferSizeX2, realMPI, procSend, 201, - mygrid->CartComm, &sendRequestX2[faceLeft])); + MPI_SAFE_CALL(idfx::MPI_Send_init(BufferSendX2[faceLeft].commView(), bufferSizeX2, + realMPI, procSend, 201, mygrid->CartComm, &sendRequestX2[faceLeft])); - MPI_SAFE_CALL(MPI_Recv_init(BufferRecvX2[faceRight].data(), bufferSizeX2, realMPI, procRecv, 201, - mygrid->CartComm, &recvRequestX2[faceRight])); + MPI_SAFE_CALL(idfx::MPI_Recv_init(BufferRecvX2[faceRight].commView(), bufferSizeX2, + realMPI, procRecv, 201, mygrid->CartComm, &recvRequestX2[faceRight])); #endif #if DIMENSIONS == 3 // We receive from procRecv, and we send to procSend MPI_SAFE_CALL(MPI_Cart_shift(mygrid->CartComm,2,1,&procRecv,&procSend )); - MPI_SAFE_CALL(MPI_Send_init(BufferSendX3[faceRight].data(), bufferSizeX3, realMPI, procSend, 300, - mygrid->CartComm, &sendRequestX3[faceRight])); + MPI_SAFE_CALL(idfx::MPI_Send_init(BufferSendX3[faceRight].commView(), bufferSizeX3, + realMPI, procSend, 300, mygrid->CartComm, &sendRequestX3[faceRight])); - MPI_SAFE_CALL(MPI_Recv_init(BufferRecvX3[faceLeft].data(), bufferSizeX3, realMPI, procRecv, 300, - mygrid->CartComm, &recvRequestX3[faceLeft])); + MPI_SAFE_CALL(idfx::MPI_Recv_init(BufferRecvX3[faceLeft].commView(), bufferSizeX3, + realMPI, procRecv, 300, mygrid->CartComm, &recvRequestX3[faceLeft])); // Send to the left // We receive from procRecv, and we send to procSend MPI_SAFE_CALL(MPI_Cart_shift(mygrid->CartComm,2,-1,&procRecv,&procSend )); - MPI_SAFE_CALL(MPI_Send_init(BufferSendX3[faceLeft].data(), bufferSizeX3, realMPI, procSend, 301, - mygrid->CartComm, &sendRequestX3[faceLeft])); + MPI_SAFE_CALL(idfx::MPI_Send_init(BufferSendX3[faceLeft].commView(), bufferSizeX3, + realMPI, procSend, 301, mygrid->CartComm, &sendRequestX3[faceLeft])); - MPI_SAFE_CALL(MPI_Recv_init(BufferRecvX3[faceRight].data(), bufferSizeX3, realMPI, procRecv, 301, - mygrid->CartComm, &recvRequestX3[faceRight])); + MPI_SAFE_CALL(idfx::MPI_Recv_init(BufferRecvX3[faceRight].commView(), bufferSizeX3, + realMPI, procRecv, 301, mygrid->CartComm, &recvRequestX3[faceRight])); #endif #endif // WITH_MPI @@ -408,17 +418,17 @@ ConstrainedTransport::~ConstrainedTransport() { // Properly clean up the mess idfx::cout << "Emf: Cleaning up MPI persistent communication channels" << std::endl; for(int i=0 ; i< 2; i++) { - MPI_Request_free( &sendRequestX1[i]); - MPI_Request_free( &recvRequestX1[i]); + idfx::MPI_Request_free( &sendRequestX1[i]); + idfx::MPI_Request_free( &recvRequestX1[i]); #if DIMENSIONS >= 2 - MPI_Request_free( &sendRequestX2[i]); - MPI_Request_free( &recvRequestX2[i]); + idfx::MPI_Request_free( &sendRequestX2[i]); + idfx::MPI_Request_free( &recvRequestX2[i]); #endif #if DIMENSIONS == 3 - MPI_Request_free( &sendRequestX3[i]); - MPI_Request_free( &recvRequestX3[i]); + idfx::MPI_Request_free( &sendRequestX3[i]); + idfx::MPI_Request_free( &recvRequestX3[i]); #endif } #endif diff --git a/src/fluid/constrainedTransport/enforceEMFBoundary.hpp b/src/fluid/constrainedTransport/enforceEMFBoundary.hpp index 9d3d6913f..3f2163850 100644 --- a/src/fluid/constrainedTransport/enforceEMFBoundary.hpp +++ b/src/fluid/constrainedTransport/enforceEMFBoundary.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/constrainedTransport/enforceEMFBoundary.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2025) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -108,9 +116,9 @@ void ConstrainedTransport::SymmetrizeEMFShearingBox() { idfx::pushRegion("Emf::EnforceEMFBoundary"); #if MHD == YES - IdefixArray2D sbEyL = this->sbEyL; - IdefixArray2D sbEyR = this->sbEyR; - IdefixArray2D sbEyRL = this->sbEyRL; + auto sbEyL = this->sbEyL.deviceView(); + auto sbEyR = this->sbEyR.deviceView(); + auto sbEyRL = this->sbEyRL.deviceView(); IdefixArray3D ey = this->ey; @@ -142,16 +150,16 @@ void ConstrainedTransport::SymmetrizeEMFShearingBox() { // We send to our left (which, by periodicity, is the right end of the domain) // our value of sbEyL and get Kokkos::fence(); - MPI_Sendrecv(sbEyL.data(), size, realMPI, procLeft, 2001, - sbEyR.data(), size, realMPI, procLeft, 2002, + idfx::MPI_Sendrecv(this->sbEyL, size, realMPI, procLeft, 2001, + this->sbEyR, size, realMPI, procLeft, 2002, data->mygrid->CartComm, &status ); } if(data->rbound[IDIR]==shearingbox) { Kokkos::fence(); // We send to our right (which, by periodicity, is the left end (=beginning) // of the domain) our value of sbEyR and get sbEyL - MPI_Sendrecv(sbEyR.data(), size, realMPI, procRight, 2002, - sbEyL.data(), size, realMPI, procRight, 2001, + idfx::MPI_Sendrecv(this->sbEyR, size, realMPI, procRight, 2002, + this->sbEyL, size, realMPI, procRight, 2001, data->mygrid->CartComm, &status ); } } diff --git a/src/fluid/constrainedTransport/enforceVectorPotentialBoundary.hpp b/src/fluid/constrainedTransport/enforceVectorPotentialBoundary.hpp index 3019edfd8..7d7b966be 100644 --- a/src/fluid/constrainedTransport/enforceVectorPotentialBoundary.hpp +++ b/src/fluid/constrainedTransport/enforceVectorPotentialBoundary.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/constrainedTransport/enforceVectorPotentialBoundary.hpp +// +// Last modified : 01/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025 - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/constrainedTransport/evolveMagField.hpp b/src/fluid/constrainedTransport/evolveMagField.hpp index 01aa8a6ec..0a013d8c1 100644 --- a/src/fluid/constrainedTransport/evolveMagField.hpp +++ b/src/fluid/constrainedTransport/evolveMagField.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/constrainedTransport/evolveMagField.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** #ifndef FLUID_CONSTRAINEDTRANSPORT_EVOLVEMAGFIELD_HPP_ diff --git a/src/fluid/constrainedTransport/evolveVectorPotential.hpp b/src/fluid/constrainedTransport/evolveVectorPotential.hpp index 0887d2e1e..ebd0a32f9 100644 --- a/src/fluid/constrainedTransport/evolveVectorPotential.hpp +++ b/src/fluid/constrainedTransport/evolveVectorPotential.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/constrainedTransport/evolveVectorPotential.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022 - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/convertConsToPrim.hpp b/src/fluid/convertConsToPrim.hpp index 45607b86f..3a201b61e 100644 --- a/src/fluid/convertConsToPrim.hpp +++ b/src/fluid/convertConsToPrim.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/convertConsToPrim.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/drag.cpp b/src/fluid/drag.cpp index 4cf879cdd..79464cdf4 100644 --- a/src/fluid/drag.cpp +++ b/src/fluid/drag.cpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/drag.cpp +// +// Last modified : 02/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** #include "drag.hpp" diff --git a/src/fluid/drag.hpp b/src/fluid/drag.hpp index 63b5e1bdb..786d48d6d 100644 --- a/src/fluid/drag.hpp +++ b/src/fluid/drag.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/drag.hpp +// +// Last modified : 10/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** #ifndef FLUID_DRAG_HPP_ diff --git a/src/fluid/enroll.hpp b/src/fluid/enroll.hpp index 77e8876fb..68406d56e 100644 --- a/src/fluid/enroll.hpp +++ b/src/fluid/enroll.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/enroll.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/eos/CMakeLists.txt b/src/fluid/eos/CMakeLists.txt index f939d9d55..14a2c484d 100644 --- a/src/fluid/eos/CMakeLists.txt +++ b/src/fluid/eos/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/fluid/eos/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/eos_adiabatic.hpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/eos_isothermal.hpp diff --git a/src/fluid/eos/eos.hpp b/src/fluid/eos/eos.hpp index 7e0a490a3..bff87f378 100644 --- a/src/fluid/eos/eos.hpp +++ b/src/fluid/eos/eos.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/eos/eos.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022 - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/eos/eos_adiabatic.hpp b/src/fluid/eos/eos_adiabatic.hpp index 88d4f0f66..49b35a4e8 100644 --- a/src/fluid/eos/eos_adiabatic.hpp +++ b/src/fluid/eos/eos_adiabatic.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/eos/eos_adiabatic.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/eos/eos_isothermal.hpp b/src/fluid/eos/eos_isothermal.hpp index 04efc9b2d..72ca0604f 100644 --- a/src/fluid/eos/eos_isothermal.hpp +++ b/src/fluid/eos/eos_isothermal.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/eos/eos_isothermal.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/eos/eos_template.hpp b/src/fluid/eos/eos_template.hpp index 3d6150817..df5e1c064 100644 --- a/src/fluid/eos/eos_template.hpp +++ b/src/fluid/eos/eos_template.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/eos/eos_template.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/evolveStage.hpp b/src/fluid/evolveStage.hpp index 31dae5b7d..44c61cf3e 100644 --- a/src/fluid/evolveStage.hpp +++ b/src/fluid/evolveStage.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/evolveStage.hpp +// +// Last modified : 02/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -14,20 +21,20 @@ template template void Fluid::LoopDir(const real t, const real dt) { // Step 2: compute the intercell flux with our Riemann solver, store the resulting InvDt - this->rSolver->template CalcFlux(this->FluxRiemann); + this->rSolver->template CalcFlux(this->FluxRiemann[dir]); // Step 2.5: compute intercell parabolic flux when needed if(haveExplicitParabolicTerms) CalcParabolicFlux(t); // If we have tracers, compute the tracer intercell flux if(haveTracer) { - this->tracer->template CalcFlux(this->FluxRiemann); + this->tracer->template CalcFlux(this->FluxRiemann[dir]); } // Step 3: compute the resulting evolution of the conserved variables, stored in Uc CalcRightHandSide(t,dt); if(haveTracer) { - this->tracer->template CalcRightHandSide(this->FluxRiemann,t ,dt); + this->tracer->template CalcRightHandSide(this->FluxRiemann[dir],t ,dt); } // Recursive: do next dimension diff --git a/src/fluid/fluid.hpp b/src/fluid/fluid.hpp index 44cace6bf..d32b074fc 100644 --- a/src/fluid/fluid.hpp +++ b/src/fluid/fluid.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/fluid.hpp +// +// Last modified : 02/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -67,7 +74,7 @@ class Fluid { void EvolveStage(const real, const real); void ResetStage(); void ShowConfig(); - IdefixArray4D GetFlux() {return this->FluxRiemann;} + IdefixArray4D GetFlux(int dir) {return this->FluxRiemann.at(dir);} int CheckNan(); // Our boundary conditions @@ -182,7 +189,7 @@ class Fluid { // Required by time integrator IdefixArray3D InvDt; - IdefixArray4D FluxRiemann; + std::array,DIMENSIONS> FluxRiemann; IdefixArray3D dMax; // Maximum diffusion speed std::unique_ptr> rSolver; @@ -539,8 +546,12 @@ Fluid::Fluid(Grid &grid, Input &input, DataBlock *datain, int n) { data->np_tot[KDIR], data->np_tot[JDIR], data->np_tot[IDIR]); dMax = IdefixArray3D(prefix+"_dMax", data->np_tot[KDIR], data->np_tot[JDIR], data->np_tot[IDIR]); - FluxRiemann = IdefixArray4D(prefix+"_FluxRiemann", Phys::nvar+nTracer, - data->np_tot[KDIR], data->np_tot[JDIR], data->np_tot[IDIR]); + + for(int i = 0 ; i < DIMENSIONS ; i++) { + FluxRiemann[i] = IdefixArray4D(prefix+"_FluxRiemann_X"+std::to_string(i), + Phys::nvar+nTracer, + data->np_tot[KDIR], data->np_tot[JDIR], data->np_tot[IDIR]); + } if constexpr(Phys::mhd) { Vs = IdefixArray4D(prefix+"_Vs", DIMENSIONS, diff --git a/src/fluid/fluid_defs.hpp b/src/fluid/fluid_defs.hpp index 3f68c9b49..9acf98fb2 100644 --- a/src/fluid/fluid_defs.hpp +++ b/src/fluid/fluid_defs.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/fluid_defs.hpp +// +// Last modified : 01/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// - Victor Réville (IRAP - 2024 - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/showConfig.hpp b/src/fluid/showConfig.hpp index f3a144304..069806553 100644 --- a/src/fluid/showConfig.hpp +++ b/src/fluid/showConfig.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/showConfig.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// - Alankar Dutta (MPA Garching - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -60,7 +68,7 @@ void Fluid::ShowConfig() { << ": Ohmic resistivity ENABLED with user-defined resistivity function." << std::endl; if(!ohmicDiffusivityFunc) { - IDEFIX_ERROR("No user-defined Ihmic resistivity function has been enrolled."); + IDEFIX_ERROR("No user-defined Ohmic resistivity function has been enrolled."); } } else { IDEFIX_ERROR("Unknown Ohmic resistivity mode"); diff --git a/src/fluid/thermalDiffusion.cpp b/src/fluid/thermalDiffusion.cpp index 344e0d168..b7abecb71 100644 --- a/src/fluid/thermalDiffusion.cpp +++ b/src/fluid/thermalDiffusion.cpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/thermalDiffusion.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022 - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/thermalDiffusion.hpp b/src/fluid/thermalDiffusion.hpp index cce827492..9f45221e7 100644 --- a/src/fluid/thermalDiffusion.hpp +++ b/src/fluid/thermalDiffusion.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/thermalDiffusion.hpp +// +// Last modified : 12/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/tracer/CMakeLists.txt b/src/fluid/tracer/CMakeLists.txt index cb8e35757..282ec7ddb 100644 --- a/src/fluid/tracer/CMakeLists.txt +++ b/src/fluid/tracer/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/fluid/tracer/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/tracer.cpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/tracer.hpp diff --git a/src/fluid/tracer/tracer.cpp b/src/fluid/tracer/tracer.cpp index 7ee95c6c7..7abd46999 100644 --- a/src/fluid/tracer/tracer.cpp +++ b/src/fluid/tracer/tracer.cpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/tracer/tracer.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/tracer/tracer.hpp b/src/fluid/tracer/tracer.hpp index 57889131e..9a460788e 100644 --- a/src/fluid/tracer/tracer.hpp +++ b/src/fluid/tracer/tracer.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/tracer/tracer.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/fluid/viscosity.cpp b/src/fluid/viscosity.cpp index 038976dd2..90df416eb 100644 --- a/src/fluid/viscosity.cpp +++ b/src/fluid/viscosity.cpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/viscosity.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2026) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -111,9 +119,9 @@ void Viscosity::AddViscousFlux(int dir, const real t, const IdefixArray4D IdefixArray1D x1l = this->data->xl[IDIR]; IdefixArray1D x2l = this->data->xl[JDIR]; IdefixArray1D x3l = this->data->xl[KDIR]; - IdefixArray1D dx1 = this->data->dx[IDIR]; - IdefixArray1D dx2 = this->data->dx[JDIR]; - IdefixArray1D dx3 = this->data->dx[KDIR]; + IdefixArray1D dx1Array = this->data->dx[IDIR]; + IdefixArray1D dx2Array = this->data->dx[JDIR]; + IdefixArray1D dx3Array = this->data->dx[KDIR]; // Fargo variables use to correct energy fluxes #if HAVE_ENERGY @@ -129,6 +137,14 @@ void Viscosity::AddViscousFlux(int dir, const real t, const IdefixArray4D IdefixArray1D tanx2m = this->data->tanx2m; #endif + // Coarsening parameters + bool haveGridCoarsening = data->haveGridCoarsening != GridCoarsening::disabled; + bool haveGridCoarseningX1 = data->coarseningDirection[IDIR]; + bool haveGridCoarseningX2 = data->coarseningDirection[JDIR]; + bool haveGridCoarseningX3 = data->coarseningDirection[KDIR]; + auto coarseningLevelX1 = data->coarseningLevel[IDIR]; + auto coarseningLevelX2 = data->coarseningLevel[JDIR]; + auto coarseningLevelX3 = data->coarseningLevel[KDIR]; HydroModuleStatus haveViscosity = this->status.status; @@ -201,18 +217,42 @@ void Viscosity::AddViscousFlux(int dir, const real t, const IdefixArray4D etaC2 = eta2 = eta2Constant; } - EXPAND( dVxi = D_DX_I(Vc,VX1)/dx1(i); , - dVyi = D_DX_I(Vc,VX2)/dx1(i); , - dVzi = D_DX_I(Vc,VX3)/dx1(i); ) + // Compute spacing + real dx1 = dx1Array(i); + real dx2 = dx2Array(j); + real dx3 = dx3Array(k); + + // Correct spacing for grid coarsening + + if(haveGridCoarsening) { + if(haveGridCoarseningX1) { + const int factor = 1 << (coarseningLevelX1(k,j) - 1); + dx1 *= factor; + } + + if(haveGridCoarseningX2) { + const int factor = 1 << (coarseningLevelX2(k,i) - 1); + dx2 *= factor; + } + + if(haveGridCoarseningX3) { + const int factor = 1 << (coarseningLevelX3(j,i) - 1); + dx3 *= factor; + } + } + + EXPAND( dVxi = D_DX_I(Vc,VX1)/dx1; , + dVyi = D_DX_I(Vc,VX2)/dx1; , + dVzi = D_DX_I(Vc,VX3)/dx1; ) #if DIMENSIONS >= 2 - EXPAND( dVxj = D_DY_I(Vc,VX1)/dx2(j); , - dVyj = D_DY_I(Vc,VX2)/dx2(j); , - dVzj = D_DY_I(Vc,VX3)/dx2(j); ) + EXPAND( dVxj = D_DY_I(Vc,VX1)/dx2; , + dVyj = D_DY_I(Vc,VX2)/dx2; , + dVzj = D_DY_I(Vc,VX3)/dx2; ) #if DIMENSIONS == 3 - dVxk = D_DZ_I(Vc,VX1)/dx3(k); - dVyk = D_DZ_I(Vc,VX2)/dx3(k); - dVzk = D_DZ_I(Vc,VX3)/dx3(k); + dVxk = D_DZ_I(Vc,VX1)/dx3; + dVyk = D_DZ_I(Vc,VX2)/dx3; + dVzk = D_DZ_I(Vc,VX3)/dx3; #endif #endif @@ -234,14 +274,14 @@ void Viscosity::AddViscousFlux(int dir, const real t, const IdefixArray4D tau_xy = eta1*(dVxj + dVyi); SELECT( , , - tau_xz = eta1*0.5*(x1(i)+x1(i-1))/dx1(i) + tau_xz = eta1*0.5*(x1(i)+x1(i-1))/dx1 *(Vc(VX3,k,j,i)/x1(i) - Vc(VX3,k,j,i-1)/x1(i-1)); ) tau_xz = eta1*(dVxk + dVzi); // compute tau_zz at cell center - divV = D_EXPAND( 0.5*(Vc(VX1,k,j,i+1) - Vc(VX1,k,j,i-1))/dx1(i) + Vc(VX1,k,j,i)/x1(i), - +0.5*(Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/dx2(j) , + divV = D_EXPAND( 0.5*(Vc(VX1,k,j,i+1) - Vc(VX1,k,j,i-1))/dx1 + Vc(VX1,k,j,i)/x1(i), + +0.5*(Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/dx2 , ); tau_zz = 2.0*etaC1*Vc(VX1,k,j,i)/x1(i) + (etaC2 - (2.0/3.0)*etaC1)*divV; @@ -269,14 +309,14 @@ void Viscosity::AddViscousFlux(int dir, const real t, const IdefixArray4D // compute tau_yy at cell center - divV = D_EXPAND( 0.5*(Vc(VX1,k,j,i+1) - Vc(VX1,k,j,i-1))/dx1(i) + Vc(VX1,k,j,i)/x1(i), - +0.5*(Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/dx2(j)/x1(i) , - +0.5*(Vc(VX3,k+1,j,i) - Vc(VX3,k-1,j,i))/dx3(k) ); + divV = D_EXPAND( 0.5*(Vc(VX1,k,j,i+1) - Vc(VX1,k,j,i-1))/dx1 + Vc(VX1,k,j,i)/x1(i), + +0.5*(Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/dx2/x1(i) , + +0.5*(Vc(VX3,k+1,j,i) - Vc(VX3,k-1,j,i))/dx3 ); #if DIMENSIONS == 1 tau_yy = 2.0*etaC1*( Vc(VX1,k,j,i)/x1(i)) + (etaC2 - (2.0/3.0)*etaC1)*divV; #else - tau_yy = 2.0*etaC1*( 0.5*(Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/dx2(j)/x1(i) + tau_yy = 2.0*etaC1*( 0.5*(Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/dx2/x1(i) + Vc(VX1,k,j,i)/x1(i)) + (etaC2 - (2.0/3.0)*etaC1)*divV; #endif @@ -325,14 +365,14 @@ void Viscosity::AddViscousFlux(int dir, const real t, const IdefixArray4D // Compute tau_yy and tau_zz at cell center - divV = D_EXPAND( 0.5*(Vc(VX1,k,j,i+1) - Vc(VX1,k,j,i-1))/dx1(i) + 2.0*Vc(VX1,k,j,i)/x1(i), - +0.5*(Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/dx2(j)/x1(i) + divV = D_EXPAND( 0.5*(Vc(VX1,k,j,i+1) - Vc(VX1,k,j,i-1))/dx1 + 2.0*Vc(VX1,k,j,i)/x1(i), + +0.5*(Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/dx2/x1(i) +Vc(VX2,k,j,i)/x1(i)*tan_1 , - +0.5*(Vc(VX3,k+1,j,i) - Vc(VX3,k-1,j,i))/dx3(k)/x1(i)*s_1 ); + +0.5*(Vc(VX3,k+1,j,i) - Vc(VX3,k-1,j,i))/dx3/x1(i)*s_1 ); tau_yy = Vc(VX1,k,j,i)/x1(i); #if DIMENSIONS >= 2 - tau_yy += 0.5*(Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/dx2(j)/x1(i); + tau_yy += 0.5*(Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/dx2/x1(i); #endif tau_yy = 2.0*etaC1*tau_yy + (etaC2-2.0/3.0*etaC1)*divV; @@ -341,7 +381,7 @@ void Viscosity::AddViscousFlux(int dir, const real t, const IdefixArray4D tau_zz += Vc(VX2,k,j,i)*tan_1/x1(i); #endif #if DIMENSIONS == 3 - tau_zz += 0.5*(Vc(VX3,k+1,j,i) - Vc(VX3,k-1,j,i))/dx3(k)/x1(i)*s_1; + tau_zz += 0.5*(Vc(VX3,k+1,j,i) - Vc(VX3,k-1,j,i))/dx3/x1(i)*s_1; #endif tau_zz = 2.0*etaC1*tau_zz + (etaC2-2.0/3.0*etaC1)*divV; @@ -426,18 +466,41 @@ void Viscosity::AddViscousFlux(int dir, const real t, const IdefixArray4D etaC2 = eta2 = eta2Constant; } - EXPAND( dVxi = D_DX_J(Vc,VX1)/dx1(i); , - dVyi = D_DX_J(Vc,VX2)/dx1(i); , - dVzi = D_DX_J(Vc,VX3)/dx1(i); ) + // Compute spacing + real dx1 = dx1Array(i); + real dx2 = dx2Array(j); + real dx3 = dx3Array(k); + + // Correct spacing for grid coarsening + if(haveGridCoarsening) { + if(haveGridCoarseningX1) { + const int factor = 1 << (coarseningLevelX1(k,j) - 1); + dx1 *= factor; + } - EXPAND( dVxj = D_DY_J(Vc,VX1)/dx2(j); , - dVyj = D_DY_J(Vc,VX2)/dx2(j); , - dVzj = D_DY_J(Vc,VX3)/dx2(j); ) + if(haveGridCoarseningX2) { + const int factor = 1 << (coarseningLevelX2(k,i) - 1); + dx2 *= factor; + } + + if(haveGridCoarseningX3) { + const int factor = 1 << (coarseningLevelX3(j,i) - 1); + dx3 *= factor; + } + } + + EXPAND( dVxi = D_DX_J(Vc,VX1)/dx1; , + dVyi = D_DX_J(Vc,VX2)/dx1; , + dVzi = D_DX_J(Vc,VX3)/dx1; ) + + EXPAND( dVxj = D_DY_J(Vc,VX1)/dx2; , + dVyj = D_DY_J(Vc,VX2)/dx2; , + dVzj = D_DY_J(Vc,VX3)/dx2; ) #if DIMENSIONS == 3 - dVxk = D_DZ_J(Vc,VX1)/dx3(k); - dVyk = D_DZ_J(Vc,VX2)/dx3(k); - dVzk = D_DZ_J(Vc,VX3)/dx3(k); + dVxk = D_DZ_J(Vc,VX1)/dx3; + dVyk = D_DZ_J(Vc,VX2)/dx3; + dVzk = D_DZ_J(Vc,VX3)/dx3; #endif #if GEOMETRY == CARTESIAN @@ -508,8 +571,8 @@ void Viscosity::AddViscousFlux(int dir, const real t, const IdefixArray4D + dVzk/x1(i)*s_1 ); // tau_xy is initially cell centered since it is involved in the source term - tau_xy = etaC1*( 0.5*(Vc(VX1,k,j+1,i)-Vc(VX1,k,j-1,i))/x1(i)/dx2(j) - +0.5*(Vc(VX2,k,j,i+1)-Vc(VX2,k,j,i-1))/dx1(i) + tau_xy = etaC1*( 0.5*(Vc(VX1,k,j+1,i)-Vc(VX1,k,j-1,i))/x1(i)/dx2 + +0.5*(Vc(VX2,k,j,i+1)-Vc(VX2,k,j,i-1))/dx1 - Vc(VX2,k,j,i)/x1(i)); tau_yy = 2.0*eta1*(dVyj/x1(i) + vx1i/x1(i)) + (eta2 - (2.0/3.0)*eta1)*divV; @@ -539,17 +602,17 @@ void Viscosity::AddViscousFlux(int dir, const real t, const IdefixArray4D s_1 = ONE_F/s_1; } - divV = D_EXPAND( 0.5*(Vc(VX1,k,j,i+1) - Vc(VX1,k,j,i-1))/dx1(i) + 2.0*Vc(VX1,k,j,i)/x1(i), - +0.5*(Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/dx2(j)/x1(i) + divV = D_EXPAND( 0.5*(Vc(VX1,k,j,i+1) - Vc(VX1,k,j,i-1))/dx1 + 2.0*Vc(VX1,k,j,i)/x1(i), + +0.5*(Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/dx2/x1(i) +Vc(VX2,k,j,i)/x1(i)*tan_1 , - +0.5*(Vc(VX3,k+1,j,i) - Vc(VX3,k-1,j,i))/dx3(k)/x1(i)*s_1 ); + +0.5*(Vc(VX3,k+1,j,i) - Vc(VX3,k-1,j,i))/dx3/x1(i)*s_1 ); tau_zz = Vc(VX1,k,j,i)/x1(i); #if COMPONENTS >= 2 tau_zz += Vc(VX2,k,j,i)/x1(i)*tan_1; #endif #if DIMENSIONS == 3 - tau_zz += 0.5*(Vc(VX3,k+1,j,i) - Vc(VX3,k-1,j,i))/dx3(k)/x1(i)*s_1; + tau_zz += 0.5*(Vc(VX3,k+1,j,i) - Vc(VX3,k-1,j,i))/dx3/x1(i)*s_1; #endif tau_zz = 2*eta1*tau_zz + (eta2-2.0/3.0*eta1)*divV; @@ -639,15 +702,38 @@ void Viscosity::AddViscousFlux(int dir, const real t, const IdefixArray4D etaC2 = eta2 = eta2Constant; } - dVxi = D_DX_K(Vc,VX1)/dx1(i); - dVyi = D_DX_K(Vc,VX2)/dx1(i); - dVzi = D_DX_K(Vc,VX3)/dx1(i); - dVxj = D_DY_K(Vc,VX1)/dx2(j); - dVyj = D_DY_K(Vc,VX2)/dx2(j); - dVzj = D_DY_K(Vc,VX3)/dx2(j); - dVxk = D_DZ_K(Vc,VX1)/dx3(k); - dVyk = D_DZ_K(Vc,VX2)/dx3(k); - dVzk = D_DZ_K(Vc,VX3)/dx3(k); + // Compute spacing + real dx1 = dx1Array(i); + real dx2 = dx2Array(j); + real dx3 = dx3Array(k); + + // Correct spacing for grid coarsening + if(haveGridCoarsening) { + if(haveGridCoarseningX1) { + const int factor = 1 << (coarseningLevelX1(k,j) - 1); + dx1 *= factor; + } + + if(haveGridCoarseningX2) { + const int factor = 1 << (coarseningLevelX2(k,i) - 1); + dx2 *= factor; + } + + if(haveGridCoarseningX3) { + const int factor = 1 << (coarseningLevelX3(j,i) - 1); + dx3 *= factor; + } + } + + dVxi = D_DX_K(Vc,VX1)/dx1; + dVyi = D_DX_K(Vc,VX2)/dx1; + dVzi = D_DX_K(Vc,VX3)/dx1; + dVxj = D_DY_K(Vc,VX1)/dx2; + dVyj = D_DY_K(Vc,VX2)/dx2; + dVzj = D_DY_K(Vc,VX3)/dx2; + dVxk = D_DZ_K(Vc,VX1)/dx3; + dVyk = D_DZ_K(Vc,VX2)/dx3; + dVzk = D_DZ_K(Vc,VX3)/dx3; #if GEOMETRY == CARTESIAN divV = dVxi + dVyj + dVzk; diff --git a/src/fluid/viscosity.hpp b/src/fluid/viscosity.hpp index 3f004c272..aae353a5b 100644 --- a/src/fluid/viscosity.hpp +++ b/src/fluid/viscosity.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/fluid/viscosity.hpp +// +// Last modified : 12/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/global.cpp b/src/global.cpp index 1ed33ba11..f47c76a54 100644 --- a/src/global.cpp +++ b/src/global.cpp @@ -1,7 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/global.cpp +// +// Last modified : 05/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2025) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/global.hpp b/src/global.hpp index c4de3926e..ae9439e12 100644 --- a/src/global.hpp +++ b/src/global.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/global.hpp +// +// Last modified : 12/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2025) +// - Clément Robert (IPAG/UGA/CNRS - 2022 - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/gravity/CMakeLists.txt b/src/gravity/CMakeLists.txt index ad2585791..1a643fa23 100644 --- a/src/gravity/CMakeLists.txt +++ b/src/gravity/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/gravity/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/gravity.hpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/gravity.cpp diff --git a/src/gravity/gravity.cpp b/src/gravity/gravity.cpp index a39b00063..ae15dfaab 100644 --- a/src/gravity/gravity.cpp +++ b/src/gravity/gravity.cpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/gravity/gravity.cpp +// +// Last modified : 04/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2025) +// - Antonin Borderies (ENS Lyon - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/gravity/gravity.hpp b/src/gravity/gravity.hpp index aa0184aa6..40c5732d4 100644 --- a/src/gravity/gravity.hpp +++ b/src/gravity/gravity.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/gravity/gravity.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/gravity/laplacian.cpp b/src/gravity/laplacian.cpp index 7ac329ea3..2c7dafb72 100644 --- a/src/gravity/laplacian.cpp +++ b/src/gravity/laplacian.cpp @@ -1,12 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/gravity/laplacian.cpp +// +// Last modified : 06/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** - - #include #include #include "laplacian.hpp" @@ -170,7 +175,7 @@ void Laplacian::InitInternalGrid() { }); // Check that all is well - IdefixArray1D::HostMirror xH = Kokkos::create_mirror_view(x1l); + IdefixArray1D::host_mirror_type xH = Kokkos::create_mirror_view(x1l); Kokkos::deep_copy(xH, x1l); if(xH(0)<0.0) { diff --git a/src/gravity/laplacian.hpp b/src/gravity/laplacian.hpp index 285724399..f3cd6a827 100644 --- a/src/gravity/laplacian.hpp +++ b/src/gravity/laplacian.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/gravity/laplacian.hpp +// +// Last modified : 10/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/gravity/selfGravity.cpp b/src/gravity/selfGravity.cpp index 43f764713..c3407ec61 100644 --- a/src/gravity/selfGravity.cpp +++ b/src/gravity/selfGravity.cpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/gravity/selfGravity.cpp +// +// Last modified : 10/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/gravity/selfGravity.hpp b/src/gravity/selfGravity.hpp index badd729ce..25534b826 100644 --- a/src/gravity/selfGravity.hpp +++ b/src/gravity/selfGravity.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/gravity/selfGravity.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/grid.cpp b/src/grid.cpp index ace5eb0ca..8d13f65a4 100644 --- a/src/grid.cpp +++ b/src/grid.cpp @@ -1,7 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/grid.cpp +// +// Last modified : 12/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2024) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2022) +// - Nicolas Scepi (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/grid.hpp b/src/grid.hpp index 947d05d12..c989cb21b 100644 --- a/src/grid.hpp +++ b/src/grid.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/grid.hpp +// +// Last modified : 01/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Alankar Dutta (MPA Garching - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/gridHost.cpp b/src/gridHost.cpp index 0c85d8e41..be36cfa6a 100644 --- a/src/gridHost.cpp +++ b/src/gridHost.cpp @@ -1,7 +1,18 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/gridHost.cpp +// +// Last modified : 01/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2024) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// - Jonah Mauxion (IPAG/UGA/CNRS - 2023) +// - Alankar Dutta (MPA Garching - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/gridHost.hpp b/src/gridHost.hpp index 55283a5c9..7600d8bf5 100644 --- a/src/gridHost.hpp +++ b/src/gridHost.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/gridHost.hpp +// +// Last modified : 12/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2024) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/idefix.hpp b/src/idefix.hpp index 7485f95f0..77b20fa7b 100644 --- a/src/idefix.hpp +++ b/src/idefix.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/idefix.hpp +// +// Last modified : 10/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2024) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2021) +// - Clément Robert (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/input.cpp b/src/input.cpp index 336414953..39fd44e9a 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/input.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2026) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -18,8 +26,9 @@ #include "idefix.hpp" #include "input.hpp" -#include "version.hpp" #include "profiler.hpp" +#include "version.h" +#include "compiler_info.h" // Flag will be set if a signal has been received bool Input::abortRequested = false; @@ -415,7 +424,10 @@ void Input::PrintOptions() { } void Input::PrintVersion() { - idfx::cout << " Idefix version " << IDEFIX_VERSION << std::endl; - idfx::cout << " Built against Kokkos " << KOKKOS_VERSION << std::endl; - idfx::cout << " Compiled on " << __DATE__ << " at " << __TIME__ << std::endl; + idfx::cout << "Idefix version " << VersionInfo::version << std::endl; + idfx::cout << "Built against Kokkos " << KOKKOS_VERSION << std::endl; + idfx::cout << "Compiled on " << __DATE__ << " at " << __TIME__ << std::endl; + idfx::cout << "Compiler name: " << CompilerInfo::name << std::endl; + idfx::cout << "Compiler version: " << CompilerInfo::version << std::endl; + idfx::cout << "Compiler path: " << CompilerInfo::path << std::endl; } diff --git a/src/input.hpp b/src/input.hpp index 18fcf2601..6f6c802cf 100644 --- a/src/input.hpp +++ b/src/input.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/input.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2022) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/kokkos b/src/kokkos index 09e775bfc..3ec81abe1 160000 --- a/src/kokkos +++ b/src/kokkos @@ -1 +1 @@ -Subproject commit 09e775bfc585840bb9ab1156cbd8d7d1c9e0cc6d +Subproject commit 3ec81abe1816109f6f62ac48cef41921f91a4d00 diff --git a/src/loop.hpp b/src/loop.hpp index 42192fa84..655513bd9 100644 --- a/src/loop.hpp +++ b/src/loop.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/loop.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2026) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -85,7 +94,7 @@ inline void idefix_for(const std::string & NAME, idfx::pushRegion("idefix_for("+NAME+")"); #endif const int NI = IE - IB; - Kokkos::parallel_for(NAME, NI, + Kokkos::parallel_for(NAME, Kokkos::RangePolicy>(0, NI), KOKKOS_LAMBDA (const int& IDX) { int i = IDX; i += IB; @@ -112,7 +121,7 @@ inline void idefix_for(const std::string & NAME, const int NJ = JE - JB; const int NI = IE - IB; const int NJNI = NJ * NI; - Kokkos::parallel_for(NAME, NJNI, + Kokkos::parallel_for(NAME, Kokkos::RangePolicy>(0, NJNI), KOKKOS_LAMBDA (const int& IDX) { int j = IDX / NI; int i = IDX - j*NI; @@ -172,7 +181,7 @@ inline void idefix_for(const std::string & NAME, const int NI = IE - IB; const int NKNJNI = NK*NJ*NI; const int NJNI = NJ * NI; - Kokkos::parallel_for(NAME,NKNJNI, + Kokkos::parallel_for(NAME,Kokkos::RangePolicy>(0, NKNJNI), KOKKOS_LAMBDA (const int& IDX) { int k = IDX / NJNI; int j = (IDX - k*NJNI) / NI; @@ -259,7 +268,7 @@ inline void idefix_for(const std::string & NAME, const int NNNKNJNI = NN*NK*NJ*NI; const int NKNJNI = NK*NJ*NI; const int NJNI = NJ * NI; - Kokkos::parallel_for(NAME,NNNKNJNI, + Kokkos::parallel_for(NAME,Kokkos::RangePolicy>(0, NNNKNJNI), KOKKOS_LAMBDA (const int& IDX) { int n = IDX / NKNJNI; int k = (IDX - n*NKNJNI) / NJNI; diff --git a/src/macros.hpp b/src/macros.hpp index 0df5f9430..99d39c684 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/macros.hpp +// +// Last modified : 10/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/main.cpp b/src/main.cpp index a2dcd630a..b46c8a434 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/main.cpp +// +// Last modified : 04/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2026) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -9,7 +19,7 @@ //@HEADER // ************************************************************************ // -// IDEFIX v 2.3.0 +// IDEFIX v 2.4.0 // // ************************************************************************ //@HEADER diff --git a/src/mpi/CMakeLists.txt b/src/mpi/CMakeLists.txt index 6042da654..8a9eef4d9 100644 --- a/src/mpi/CMakeLists.txt +++ b/src/mpi/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/mpi/CMakeLists.txt +# +# Last modified : 12/2025 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/buffer.hpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/exchanger.hpp diff --git a/src/mpi/buffer.hpp b/src/mpi/buffer.hpp index ff4dff146..d7607c536 100644 --- a/src/mpi/buffer.hpp +++ b/src/mpi/buffer.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/mpi/buffer.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -10,6 +18,7 @@ #include "idefix.hpp" #include "arrays.hpp" +#include "mpiWrapper.hpp" using BoundingBox = std::array,3>; @@ -17,7 +26,9 @@ using BoundingBox = std::array,3>; class Buffer { public: Buffer() = default; - explicit Buffer(size_t size): pointer{0}, array{IdefixArray1D("BufferArray",size)} {}; + explicit Buffer(size_t size) + : pointer{0} + , array{IdefixArray1D("BufferArray",size)} {} // Compute the size of a bounding box static size_t ComputeBoxSize(BoundingBox box) { @@ -27,12 +38,20 @@ class Buffer { return(ninjnk); } - void* data() { - return(array.data()); + void* deviceData() { + return(array.deviceView().data()); + } + + IdefixArray1D & deviceView(void) { + return this->array.deviceView(); + } + + idfx::IdefixCommArray1D & commView(void) { + return this->array; } int Size() { - return(array.size()); + return(array.deviceView().size()); } void ResetPointer() { @@ -51,7 +70,7 @@ class Buffer { const int kend = box[KDIR][1]; const int offset = this->pointer; - auto arr = this->array; + auto arr = this->array.deviceView(); idefix_for("LoadBuffer3D",kbeg,kend,jbeg,jend,ibeg,iend, KOKKOS_LAMBDA (int k, int j, int i) { arr(i-ibeg + (j-jbeg)*ni + (k-kbeg)*ninj + offset ) = in(k,j,i); @@ -75,7 +94,7 @@ class Buffer { const int kend = box[KDIR][1]; const int offset = this->pointer; - auto arr = this->array; + auto arr = this->array.deviceView(); idefix_for("LoadBuffer4D_var",kbeg,kend,jbeg,jend,ibeg,iend, KOKKOS_LAMBDA (int k, int j, int i) { arr(i-ibeg + (j-jbeg)*ni + (k-kbeg)*ninj + offset ) = in(var, k,j,i); @@ -98,7 +117,7 @@ class Buffer { const int jend = box[JDIR][1]; const int kend = box[KDIR][1]; const int offset = this->pointer; - auto arr = this->array; + auto arr = this->array.deviceView(); idefix_for("LoadBuffer4D_map",0,map.size(), kbeg,kend, @@ -124,7 +143,7 @@ class Buffer { const int jend = box[JDIR][1]; const int kend = box[KDIR][1]; const int offset = this->pointer; - auto arr = this->array; + auto arr = this->array.deviceView(); idefix_for("UnLoadBuffer3D",kbeg,kend,jbeg,jend,ibeg,iend, KOKKOS_LAMBDA (int k, int j, int i) { @@ -149,7 +168,7 @@ class Buffer { const int kend = box[KDIR][1]; const int offset = this->pointer; - auto arr = this->array; + auto arr = this->array.deviceView(); idefix_for("UnLoadBuffer4D_var",kbeg,kend,jbeg,jend,ibeg,iend, KOKKOS_LAMBDA (int k, int j, int i) { out(var,k,j,i) = arr(i-ibeg + (j-jbeg)*ni + (k-kbeg)*ninj + offset ); @@ -159,6 +178,34 @@ class Buffer { this->pointer += ninjnk; } + void UnpackJDirSymetric(IdefixArray4D& out, + const int var, + IdefixArray1D& SymMap, + BoundingBox box) { + const int ni = box[IDIR][1]-box[IDIR][0]; + const int ninj = (box[JDIR][1]-box[JDIR][0])*ni; + const int ninjnk = (box[KDIR][1]-box[KDIR][0])*ninj; + const int ibeg = box[IDIR][0]; + const int jbeg = box[JDIR][0]; + const int kbeg = box[KDIR][0]; + const int iend = box[IDIR][1]; + const int jend = box[JDIR][1]; + const int kend = box[KDIR][1]; + const int offset = this->pointer; + + auto arr = this->array.deviceView(); + idefix_for("UnLoadBuffer4D_var_sym",kbeg,kend,jbeg,jend,ibeg,iend, + KOKKOS_LAMBDA (int k, int j, int i) { + const int jinverted = jend-(j-jbeg)-1; + const int arrIndex = i-ibeg + (j-jbeg)*ni + (k-kbeg)*ninj + offset; + const int symMultiplier = SymMap(var); + out(var,k,jinverted,i) = symMultiplier * arr(arrIndex); + }); + + // Update pointer + this->pointer += ninjnk; + } + void Unpack(IdefixArray4D& out, IdefixArray1D& map, BoundingBox box) { @@ -173,7 +220,7 @@ class Buffer { const int kend = box[KDIR][1]; const int offset = this->pointer; - auto arr = this->array; + auto arr = this->array.deviceView(); idefix_for("UnLoadBuffer4D_map",0,map.size(), kbeg,kend, jbeg,jend, @@ -186,10 +233,39 @@ class Buffer { this->pointer += ninjnk*map.size(); } + void UnpackJDirSymetric(IdefixArray4D& out, + IdefixArray1D& map, + IdefixArray1D& SymMap, + BoundingBox box) { + const int ni = box[IDIR][1]-box[IDIR][0]; + const int ninj = (box[JDIR][1]-box[JDIR][0])*ni; + const int ninjnk = (box[KDIR][1]-box[KDIR][0])*ninj; + const int ibeg = box[IDIR][0]; + const int jbeg = box[JDIR][0]; + const int kbeg = box[KDIR][0]; + const int iend = box[IDIR][1]; + const int jend = box[JDIR][1]; + const int kend = box[KDIR][1]; + const int offset = this->pointer; + + auto arr = this->array.deviceView(); + idefix_for("UnLoadBuffer4D_map_sym",0,map.size(), + kbeg,kend, + jbeg,jend, + ibeg,iend, + KOKKOS_LAMBDA (int n, int k, int j, int i) { + const int jinverted = jend-(j-jbeg)-1; + const int arrIndex = i-ibeg + (j-jbeg)*ni + (k-kbeg)*ninj + n*ninjnk + offset; + out(map(n),k,jinverted,i) = SymMap(map(n)) * arr(arrIndex); + }); + + // Update pointer + this->pointer += ninjnk*map.size(); + } private: - size_t pointer; - IdefixArray1D array; + size_t pointer{0}; + idfx::IdefixCommArray1D array{}; }; #endif // MPI_BUFFER_HPP_ diff --git a/src/mpi/commArray.hpp b/src/mpi/commArray.hpp new file mode 100644 index 000000000..f6acc6c29 --- /dev/null +++ b/src/mpi/commArray.hpp @@ -0,0 +1,231 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file src/mpi/commArray.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + +#ifndef MPI_COMMARRAY_HPP_ +#define MPI_COMMARRAY_HPP_ + +//To enable to force transfers and validate that it is working in any conditions. +//#define WITH_GPU_FORCE_COPY + +#ifdef WITH_MPI + #include +#endif //WITH_MPI + +#include +#include +#include + +#include "idefix.hpp" + +namespace idfx { + +/** + * Provide a specific array used for MPI communications. It embeds the standard + * array as usual, and also optionally a communication copy on the host, depending + * if we have access to WITH_MPI_GPU_DIRECT or not. + */ +template +class IdefixCommArrayGpuDirect { + public: + template + explicit IdefixCommArrayGpuDirect(Args... args) + :deviceArray(args...) + {} + + /** + * Acces as a simple device view for use in kokkos kernels + * (because need to not carry the host part). + */ + T & deviceView(void) { + return this->deviceArray; + } + + /** + * Acces as a simple communication view for use in communication routines. + */ + T commView(void) { + return this->deviceArray; + } + + /** + * If needed, transfers the data from the device to the host to be ready to make + * a communication. + */ + void syncCommData(void) {} + + /** + * If needed, transfers the data from the device to the host to be ready to make + * a communication. + */ + void syncCommDataAsync(void) {} + + /** + * If needed, transerts the data to the device after a communication to be ready + * to use it. + */ + void syncDeviceData(void) {} + + /** + * If needed, transerts the data to the device after a communication to be ready + * to use it. + */ + void syncDeviceDataAsync(void) {} + + /** + * Get access to the communication array. It will be either on host or device + * depending on the WITH_MPI_GPU_DIRECT configuration. + */ + void * commData(void) { + return this->deviceArray.data(); + } + + private: + /** + * Device buffer containing the device side of the data to use for communications. + * This where the computation are done. Then it is transfered to/from the communication + * buffer if needed. + */ + T deviceArray; +}; + +/** + * Provide a specific array used for MPI communications. It embeds the standard + * array as usual, and also optionally a communication copy on the host, depending + * if we have access to WITH_MPI_GPU_DIRECT or not. + */ +template +class IdefixCommArrayNoGpuDirect { + public: + template + explicit IdefixCommArrayNoGpuDirect(Args... args) + :deviceArray(args...) + ,commArray(initCommArray(this->deviceArray)) + {} + + /** + * Acces as a simple device view for use in kokkos kernels + * (because need to not carry the host part). + */ + T & deviceView(void) { + return this->deviceArray; + } + + /** + * Acces as a simple communication view for use in communication routines. + */ + typename T::host_mirror_type & commView(void) { + return this->commArray; + } + + /** + * If needed, transfers the data from the device to the host to be ready to make + * a communication. + */ + void syncCommData(void) { + Kokkos::deep_copy(this->commArray, this->deviceArray); + } + + /** + * If needed, transfers the data from the device to the host to be ready to make + * a communication. + */ + void syncCommDataAsync(void) { + Kokkos::deep_copy(Kokkos::DefaultExecutionSpace(), this->commArray, this->deviceArray); + } + + /** + * If needed, transerts the data to the device after a communication to be ready + * to use it. + */ + void syncDeviceData(void) { + Kokkos::deep_copy(this->deviceArray, this->commArray); + } + + /** + * If needed, transerts the data to the device after a communication to be ready + * to use it. + */ + void syncDeviceDataAsync(void) { + Kokkos::deep_copy(Kokkos::DefaultExecutionSpace(), this->deviceArray, this->commArray); + } + + /** + * Get access to the communication array. It will be either on host or device + * depending on the WITH_MPI_GPU_DIRECT configuration. + */ + void * commData(void) { + return this->commArray.data(); + } + + private: + static typename T::host_mirror_type initCommArray(T & deviceArray) { + #ifdef WITH_GPU_FORCE_COPY + //for validation purpose, force the transfers by using a copy anytime. + return Kokkos::create_mirror(deviceArray); + #else + //if no GPU DIRECT, it creates a copy only if deviceArray is on GPU, + //if on host, it just reference it + return Kokkos::create_mirror_view(deviceArray); + #endif + } + + private: + /** + * Device buffer containing the device side of the data to use for communications. + * This where the computation are done. Then it is transfered to/from the communication + * buffer if needed. + */ + T deviceArray; + /** + * Buffer to contain a copy of the data on host if required. If WITH_MPI_GPU_DIRECT + * is enabled it directly points the device buffer as no copy is required. + */ + typename T::host_mirror_type commArray; +}; + +#ifdef WITH_MPI_GPU_DIRECT + template using IdefixCommArray = IdefixCommArrayGpuDirect; +#else + template using IdefixCommArray = IdefixCommArrayNoGpuDirect; +#endif + +/** Wrap the idefix 1D array to use it for communication purpose. */ +template using IdefixCommArray1D = IdefixCommArray< IdefixArray1D >; +/** Wrap the idefix 2D array to use it for communication purpose. */ +template using IdefixCommArray2D = IdefixCommArray< IdefixArray2D >; +/** Wrap the idefix 3D array to use it for communication purpose. */ +template using IdefixCommArray3D = IdefixCommArray< IdefixArray3D >; +/** Wrap the idefix 4D array to use it for communication purpose. */ +template using IdefixCommArray4D = IdefixCommArray< IdefixArray4D >; + +template +struct Idefix_MPI_Request { + IdefixCommArray commArray; + #ifdef WITH_MPI + MPI_Request request; + #endif //WITH_MPI +}; + +/** Wrap the idefix 1D array to use it for communication purpose. */ +template using MPI_Request_1D = Idefix_MPI_Request< IdefixArray1D >; +/** Wrap the idefix 2D array to use it for communication purpose. */ +template using MPI_Request_2D = Idefix_MPI_Request< IdefixArray2D >; +/** Wrap the idefix 3D array to use it for communication purpose. */ +template using MPI_Request_3D = Idefix_MPI_Request< IdefixArray3D >; +/** Wrap the idefix 4D array to use it for communication purpose. */ +template using MPI_Request_4D = Idefix_MPI_Request< IdefixArray4D >; + +} // namespace idfx + +#endif // MPI_COMMARRAY_HPP_ diff --git a/src/mpi/exchanger.cpp b/src/mpi/exchanger.cpp index 033ce4041..136e06ca6 100644 --- a/src/mpi/exchanger.cpp +++ b/src/mpi/exchanger.cpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/mpi/exchanger.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -12,8 +20,11 @@ #include "grid.hpp" #include "arrays.hpp" -//#define MPI_NON_BLOCKING -#define MPI_PERSISTENT +#if defined(COMMUNICATION_MODE_NON_BLOCKING) + #define MPI_NON_BLOCKING +#elif defined(COMMUNICATION_MODE_PERSISTENT) + #define MPI_PERSISTENT +#endif //COMMUNICATION_MODE_* int Exchanger::nInstances = 0; @@ -129,22 +140,22 @@ void Exchanger::Init( // X1-dir exchanges // We receive from procRecv, and we send to procSend - MPI_Send_init(BufferSend[faceRight].data(), bufferSizeSend[faceRight], realMPI, + idfx::MPI_Send_init(BufferSend[faceRight].commView(), bufferSizeSend[faceRight], realMPI, procSend[faceRight], thisInstance*2, grid->CartComm, &sendRequest[faceRight]); - MPI_Recv_init(BufferRecv[faceLeft].data(), bufferSizeRecv[faceLeft], realMPI, + idfx::MPI_Recv_init(BufferRecv[faceLeft].commView(), bufferSizeRecv[faceLeft], realMPI, procRecv[faceLeft],thisInstance*2, grid->CartComm, &recvRequest[faceLeft]); // Send to the left // We receive from procRecv, and we send to procSend - MPI_Send_init(BufferSend[faceLeft].data(), bufferSizeSend[faceLeft], realMPI, + idfx::MPI_Send_init(BufferSend[faceLeft].commView(), bufferSizeSend[faceLeft], realMPI, procSend[faceLeft],thisInstance*2+1, grid->CartComm, &sendRequest[faceLeft]); - MPI_Recv_init(BufferRecv[faceRight].data(), bufferSizeRecv[faceRight], realMPI, + idfx::MPI_Recv_init(BufferRecv[faceRight].commView(), bufferSizeRecv[faceRight], realMPI, procRecv[faceRight], thisInstance*2+1, grid->CartComm, &recvRequest[faceRight]); @@ -163,8 +174,8 @@ Exchanger::~Exchanger() { // Properly clean up the mess #ifdef MPI_PERSISTENT for(int i=0 ; i< 2; i++) { - MPI_Request_free( &sendRequest[i]); - MPI_Request_free( &recvRequest[i]); + idfx::MPI_Request_free( &sendRequest[i]); + idfx::MPI_Request_free( &recvRequest[i]); } #endif isInitialized = false; @@ -189,7 +200,7 @@ void Exchanger::Exchange(IdefixArray4D Vc, IdefixArray4D Vs) { MPI_Status sendStatus[2]; MPI_Status recvStatus[2]; - MPI_Startall(2, recvRequest); + idfx::MPI_Startall(2, recvRequest); idfx::mpiCallsTimer += MPI_Wtime() - tStart; #endif myTimer += MPI_Wtime(); @@ -211,65 +222,68 @@ void Exchanger::Exchange(IdefixArray4D Vc, IdefixArray4D Vs) { Kokkos::fence(); myTimer -= MPI_Wtime(); tStart = MPI_Wtime(); + #ifdef MPI_PERSISTENT - MPI_Startall(2, sendRequest); + idfx::MPI_Startall(2, sendRequest); // Wait for buffers to be received - MPI_Waitall(2,recvRequest,recvStatus); + idfx::MPI_Waitall(2, recvRequest, recvStatus); #else #ifdef MPI_NON_BLOCKING MPI_Status sendStatus[2]; MPI_Status recvStatus[2]; - MPI_Request sendRequest[2]; - MPI_Request recvRequest[2]; + idfx::MPI_Request_1D sendRequest[2]; + idfx::MPI_Request_1D recvRequest[2]; // We receive from procRecv, and we send to procSend - MPI_Isend(BufferSend[faceRight].data(), bufferSizeSend[faceRight], realMPI, - procSend[faceRight], 100, mygrid->CartComm, &sendRequest[0]); + idfx::MPI_Isend(BufferSend[faceRight].commView(), bufferSizeSend[faceRight], realMPI, + procSend[faceRight], 100, grid->CartComm, &sendRequest[0]); - MPI_Irecv(BufferRecv[faceLeft].data(), bufferSizeRecv[faceLeft], realMPI, - procRecv[faceLeft], 100, mygrid->CartComm, &recvRequest[0]); + idfx::MPI_Irecv(BufferRecv[faceLeft].commView(), bufferSizeRecv[faceLeft], realMPI, + procRecv[faceLeft], 100, grid->CartComm, &recvRequest[0]); // Send to the left // We receive from procRecv, and we send to procSend - MPI_Isend(BufferSend[faceLeft].data(), bufferSizeSend[faceLeft], realMPI, - procSend[faceLeft], 101, mygrid->CartComm, &sendRequest[1]); + idfx::MPI_Isend(BufferSend[faceLeft].commView(), bufferSizeSend[faceLeft], realMPI, + procSend[faceLeft], 101, grid->CartComm, &sendRequest[1]); - MPI_Irecv(BufferRecv[faceRight].data(), bufferSizeRecv[faceRight], realMPI, - procRecv[faceRight], 101, mygrid->CartComm, &recvRequest[1]); + idfx::MPI_Irecv(BufferRecv[faceRight].commView(), bufferSizeRecv[faceRight], realMPI, + procRecv[faceRight], 101, grid->CartComm, &recvRequest[1]); // Wait for recv to complete (we don't care about the sends) - MPI_Waitall(2, recvRequest, recvStatus); + idfx::MPI_Waitall(2, recvRequest, recvStatus); #else MPI_Status status; // Send to the right // We receive from procRecv, and we send to procSend - MPI_Sendrecv(BufferSend[faceRight].data(), bufferSizeSend[faceRight], realMPI, + idfx::MPI_Sendrecv(BufferSend[faceRight].commView(), bufferSizeSend[faceRight], realMPI, procSend[faceRight], 100, - BufferRecv[faceLeft].data(), bufferSizeRecv[faceLeft], realMPI, + BufferRecv[faceLeft].commView(), bufferSizeRecv[faceLeft], realMPI, procRecv[faceLeft], 100, grid->CartComm, &status); // Send to the left // We receive from procRecv, and we send to procSend - MPI_Sendrecv(BufferSend[faceLeft].data(), bufferSizeSend[faceLeft], realMPI, + idfx::MPI_Sendrecv(BufferSend[faceLeft].commView(), bufferSizeSend[faceLeft], realMPI, procSend[faceLeft], 101, - BufferRecv[faceRight].data(), bufferSizeRecv[faceRight], realMPI, + BufferRecv[faceRight].commView(), bufferSizeRecv[faceRight], realMPI, procRecv[faceRight], 101, grid->CartComm, &status); #endif #endif myTimer += MPI_Wtime(); -idfx::mpiCallsTimer += MPI_Wtime() - tStart; + // Unpack BufferLeft=BufferRecv[faceLeft]; BufferRight=BufferRecv[faceRight]; +idfx::mpiCallsTimer += MPI_Wtime() - tStart; + BufferLeft.ResetPointer(); BufferRight.ResetPointer(); @@ -292,11 +306,11 @@ if(recvRight) { myTimer -= MPI_Wtime(); #ifdef MPI_NON_BLOCKING // Wait for the sends if they have not yet completed - MPI_Waitall(2, sendRequest, sendStatus); + idfx::MPI_Waitall(2, sendRequest, sendStatus); #endif #ifdef MPI_PERSISTENT - MPI_Waitall(2, sendRequest, sendStatus); + idfx::MPI_Waitall(2, sendRequest, sendStatus); #endif myTimer += MPI_Wtime(); bytesSentOrReceived += (bufferSizeRecv[faceLeft] diff --git a/src/mpi/exchanger.hpp b/src/mpi/exchanger.hpp index 2e1affcb0..db370eda7 100644 --- a/src/mpi/exchanger.hpp +++ b/src/mpi/exchanger.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/mpi/exchanger.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -72,8 +80,8 @@ class Exchanger { bool haveVs{false}; // Requests for MPI persistent communications - MPI_Request sendRequest[2]; - MPI_Request recvRequest[2]; + idfx::MPI_Request_1D sendRequest[2]; + idfx::MPI_Request_1D recvRequest[2]; Grid *grid; }; diff --git a/src/mpi/mpi.cpp b/src/mpi/mpi.cpp index 36b4eb9a3..fae1b4680 100644 --- a/src/mpi/mpi.cpp +++ b/src/mpi/mpi.cpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/mpi/mpi.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -123,19 +131,21 @@ void Mpi::ExchangeX3(IdefixArray4D Vc, IdefixArray4D Vs) { void Mpi::CheckConfig() { idfx::pushRegion("Mpi::CheckConfig"); // compile time check - #ifdef KOKKOS_ENABLE_CUDA + #if defined(KOKKOS_ENABLE_CUDA) && defined(WITH_MPI_GPU_DIRECT) #if defined(MPIX_CUDA_AWARE_SUPPORT) && !MPIX_CUDA_AWARE_SUPPORT - #error Your MPI library is not CUDA Aware (check Idefix requirements). + #error Your MPI library is not CUDA Aware (check Idefix requirements). \ + You can look on Idefix cmake option -DIdefix_MPI_GPU_DIRECT=OFF to skip \ + this requirement (will be slower). #endif #endif /* MPIX_CUDA_AWARE_SUPPORT */ // Run-time check that we can do a reduce on device arrays - IdefixArray1D src("MPIChecksrc",1); - IdefixArray1D::HostMirror srcHost = Kokkos::create_mirror_view(src); + idfx::IdefixCommArray1D src("MPIChecksrc",1); + IdefixArray1D::host_mirror_type srcHost = Kokkos::create_mirror_view(src.deviceView()); if(idfx::prank == 0) { srcHost(0) = 0; - Kokkos::deep_copy(src, srcHost); + Kokkos::deep_copy(src.deviceView(), srcHost); } if(idfx::psize > 1) { @@ -155,15 +165,15 @@ void Mpi::CheckConfig() { MPI_Status status; int ierrSend, ierrRecv; if(idfx::prank == 0) { - ierrSend = MPI_Send(src.data(), 1, MPI_INT64_T, idfx::prank+1, 1, MPI_COMM_WORLD); - ierrRecv = MPI_Recv(src.data(), 1, MPI_INT64_T, idfx::psize-1, 1, MPI_COMM_WORLD, &status); + ierrSend = idfx::MPI_Send(src, 1, MPI_INT64_T, idfx::prank+1, 1, MPI_COMM_WORLD); + ierrRecv = idfx::MPI_Recv(src, 1, MPI_INT64_T, idfx::psize-1, 1, MPI_COMM_WORLD, &status); } else { - ierrRecv = MPI_Recv(src.data(), 1, MPI_INT64_T, idfx::prank-1, 1, MPI_COMM_WORLD, &status); + ierrRecv = idfx::MPI_Recv(src, 1, MPI_INT64_T, idfx::prank-1, 1, MPI_COMM_WORLD, &status); // Add our own rank to the data - Kokkos::deep_copy(srcHost, src); + Kokkos::deep_copy(srcHost, src.deviceView()); srcHost(0) += idfx::prank; - Kokkos::deep_copy(src, srcHost); - ierrSend = MPI_Send(src.data(), 1, MPI_INT64_T, (idfx::prank+1)%idfx::psize, 1, + Kokkos::deep_copy(src.deviceView(), srcHost); + ierrSend = idfx::MPI_Send(src, 1, MPI_INT64_T, (idfx::prank+1)%idfx::psize, 1, MPI_COMM_WORLD); } @@ -190,6 +200,12 @@ void Mpi::CheckConfig() { #else errmsg << "Check your MPI library configuration." << std::endl; #endif + #if defined(KOKKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP) + errmsg << "GPU-aware MPI is required to communicate GPU buffers directly. " + "You can disable this requirement by configuring Idefix with " + "-DIdefix_MPI_GPU_DIRECT=OFF, which falls back to staging " + "data through host memory (this will be slower)." << std::endl; + #endif errmsg << "Error: " << e.what() << std::endl; IDEFIX_ERROR(errmsg); } @@ -199,7 +215,7 @@ void Mpi::CheckConfig() { } // Check that we have the proper end result - Kokkos::deep_copy(srcHost, src); + Kokkos::deep_copy(srcHost, src.deviceView()); int64_t size = static_cast(idfx::psize); int64_t rank = static_cast(idfx::prank); int64_t result = rank == 0 ? size*(size-1)/2 : rank*(rank+1)/2; diff --git a/src/mpi/mpi.hpp b/src/mpi/mpi.hpp index b8f929326..d366b69cc 100644 --- a/src/mpi/mpi.hpp +++ b/src/mpi/mpi.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/mpi/mpi.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -17,6 +25,7 @@ #include "grid.hpp" #include "buffer.hpp" #include "exchanger.hpp" +#include "mpiWrapper.hpp" class DataBlock; diff --git a/src/mpi/mpiWrapper.hpp b/src/mpi/mpiWrapper.hpp new file mode 100644 index 000000000..0862aa415 --- /dev/null +++ b/src/mpi/mpiWrapper.hpp @@ -0,0 +1,512 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file src/mpi/mpiWrapper.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + +#ifndef MPI_MPIWRAPPER_HPP_ +#define MPI_MPIWRAPPER_HPP_ + +#ifdef WITH_MPI + #include +#endif //WITH_MPI + +#include +#include +#include + +#include "idefix.hpp" +#include "commArray.hpp" + +namespace idfx { + +#ifdef WITH_MPI + +/** + * Provide a wrapper of the standard MPI_Sendrecv by handling an idefix + * communication array. It will automate the process of transfering the data + * to the host if required (when WITH_MPI_GPU_DIRECT is disabled). + */ +template +int MPI_Sendrecv(IdefixCommArray & sendbuf, int sendcount, MPI_Datatype sendtype, + int dest, int sendtag, IdefixCommArray &recvbuf, int recvcount, + MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm, MPI_Status *status) { + //check size + assert(sendbuf.span() == sendcount); + assert(sendbuf.span_is_contiguous()); + assert(recvbuf.span() == sendcount); + assert(recvbuf.span_is_contiguous()); + + //make a local allocation if needed + sendbuf.syncCommData(); + + //make the communication + const int result = ::MPI_Sendrecv(sendbuf.commData(), sendcount, sendtype, dest, sendtag, + recvbuf.commData(), recvcount, recvtype, source, recvtag, + comm, status); + + //copy back if needed + recvbuf.syncDeviceData(); + + //ok + return result; +} + +/** + * Overlad the MPI_Send_init() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Send_init(IdefixCommArray & buf, int count, MPI_Datatype datatype, int dest, + int tag, MPI_Comm comm, Idefix_MPI_Request *request) { + //check + assert(request != nullptr); + assert(buf.span() == count); + assert(buf.span_is_contiguous()); + + //store the values + request->commArray = buf; + + //call MPI + const int result = ::MPI_Send_init(buf.commData(), count, datatype, + dest, tag, comm, &request->request); + + //ok + return result; +} + +/** + * Overlad the MPI_Recv_init() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Recv_init(IdefixCommArray & buf, int count, MPI_Datatype datatype, int + source, int tag, MPI_Comm comm, Idefix_MPI_Request* request) { + //check + assert(request != nullptr); + assert(buf.span() == count); + assert(buf.span_is_contiguous()); + + //store the values + request->commArray = buf; + + //call MPI + const int result = ::MPI_Recv_init(buf.commData(), count, datatype, + source, tag, comm, &request->request); + + //ok + return result; +} + +/** + * Overlad the MPI_Request_free() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Request_free(Idefix_MPI_Request* request) { + //check + assert(request != nullptr); + + //call MPI + return ::MPI_Request_free(&request->request); +} + +/** + * Overlad the MPI_Startall() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Startall(int count, Idefix_MPI_Request* request) { + //check + assert(request != nullptr); + assert(count >= 0); + + //sync the copies in async mode + for (size_t i = 0 ; i < count ; i++) { + request[i].commArray.syncCommDataAsync(); + } + + //wait transfers to be done + Kokkos::fence(); + + //launch the comms + int final_result = 0; + for (size_t i = 0 ; i < count ; i++) { + const int result = ::MPI_Start(&request[i].request); + if (result < 0) + final_result = result; + } + + //ok + return final_result; +} + +/** + * Overlad the MPI_Waitall() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Waitall(int count, Idefix_MPI_Request* request, + MPI_Status *array_of_statuses) { + //check + assert(request != nullptr); + assert(count >= 0); + + //wait the comms + int final_result = 0; + for (size_t i = 0 ; i < count ; i++) { + const int result = ::MPI_Wait(&request[i].request, &array_of_statuses[i]); + if (result < 0) + final_result = result; + } + + //sync the copies in async mode + for (size_t i = 0 ; i < count ; i++) { + request[i].commArray.syncDeviceDataAsync(); + } + + //wait transfers to be done + Kokkos::fence(); + + //ok + return final_result; +} + +/** + * Overlad the MPI_Start() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Start(Idefix_MPI_Request* request) { + //check + assert(request != nullptr); + + //sync the copies in async mode + request->commArray.syncCommData(); + + //call MPI + return ::MPI_Start(&request->request); +} + +/** + * Overlad the MPI_Wait() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Wait(Idefix_MPI_Request* request, MPI_Status *array_of_statuses) { + //check + assert(request != nullptr); + + //wait the comms + const int result = ::MPI_Wait(&request->request, array_of_statuses); + + //sync the copies in async mode + request->commArray.syncDeviceData(); + + //ok + return result; +} + +/** + * Overlad the MPI_Send() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Send(IdefixCommArray & buf, int count, MPI_Datatype datatype, int + dest, int tag, MPI_Comm comm) { + //check + assert(buf.span() == count); + assert(buf.span_is_contiguous()); + + //sync + buf.syncCommData(); + + //call MPI + const int result = ::MPI_Send(buf.commData(), count, datatype, + dest, tag, comm); + + //ok + return result; +} + +/** + * Overlad the MPI_Send() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Send(const std::array & buf, int count, MPI_Datatype datatype, + int dest, int tag, MPI_Comm comm) { + //call MPI + return ::MPI_Send(buf.data(), count, datatype, dest, tag, comm); +} + +/** + * Overlad the MPI_Send() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Send(const Kokkos::View & buf, int count, + MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) { + //check + assert(buf.span() == count); + assert(buf.span_is_contiguous()); + + //call MPI + return ::MPI_Send(buf.data(), count, datatype, dest, tag, comm); +} + +/** + * Overlad the MPI_Recv() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Recv(IdefixCommArray & buf, int count, MPI_Datatype datatype, int + source, int tag, MPI_Comm comm, MPI_Status * status) { + //check + assert(buf.span() == count); + assert(buf.span_is_contiguous()); + + //call MPI + const int result = ::MPI_Recv(buf.commData(), count, datatype, + source, tag, comm, status); + + //sync + buf.syncDeviceData(); + + //ok + return result; +} + +/** + * Overlad the MPI_Recv() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Recv(std::array & buf, int count, MPI_Datatype datatype, int + source, int tag, MPI_Comm comm, MPI_Status * status) { + //call MPI + return ::MPI_Recv(buf.data(), count, datatype, source, tag, comm, status); +} + +/** + * Overlad the MPI_Recv() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Recv(Kokkos::View & buf, int count, + MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status * status) { + //check + assert(buf.span() == count); + assert(buf.span_is_contiguous()); + + //call MPI + return ::MPI_Recv(buf.data(), count, datatype, source, tag, comm, status); +} + +/** + * Overlad the MPI_Isend() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Isend(IdefixCommArray & buf, int count, MPI_Datatype datatype, int + source, int tag, MPI_Comm comm, Idefix_MPI_Request* request) { + //check + assert(request != nullptr); + assert(buf.span() == count); + assert(buf.span_is_contiguous()); + + //store the values + request->commArray = buf; + + //sync + buf.syncCommData(); + + //call MPI + const int result = ::MPI_Isend(buf.commData(), count, datatype, + source, tag, comm, &request->request); + + //ok + return result; +} + +/** + * Overlad the MPI_Irecv() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Irecv(IdefixCommArray & buf, int count, MPI_Datatype datatype, int + source, int tag, MPI_Comm comm, Idefix_MPI_Request* request) { + //check + assert(request != nullptr); + assert(buf.span() == count); + assert(buf.span_is_contiguous()); + + //store the values + request->commArray = buf; + + //call MPI + const int result = ::MPI_Irecv(buf.commData(), count, datatype, + source, tag, comm, &request->request); + + //ok + return result; +} + +/** + * Overlad the MPI_Bcast() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Bcast(IdefixCommArray & buffer, int count, MPI_Datatype datatype, int root, + MPI_Comm comm) { + //check + assert(buffer.span() == count); + assert(buffer.span_is_contiguous()); + + //get current rank + int rank = -1; + const int status = ::MPI_Comm_rank(comm, &rank); + assert(status == MPI_SUCCESS); + + //sync + if (rank == root) + buffer.syncCommData(); + + //call MPI + const int result = ::MPI_Bcast(buffer.commData(), count, datatype, root, comm); + + //sync back + if (rank != root) + buffer.syncDeviceData(); + + //ok + return result; +} + +/** + * Overlad the MPI_Bcast() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Bcast(IdefixHostArray1D & buffer, int count, MPI_Datatype datatype, int root, + MPI_Comm comm) { + //check + assert(buffer.span() == count); + assert(buffer.span_is_contiguous()); + + //call MPI + const int result = ::MPI_Bcast(buffer.data(), count, datatype, root, comm); + + //ok + return result; +} + +/** + * Overlad the MPI_Allreduce() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Allreduce(IdefixCommArray & sendbuf, IdefixCommArray & recvbuf, int count, + MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) { + //check + assert(sendbuf.span() == count); + assert(sendbuf.span_is_contiguous()); + assert(recvbuf.span() == count); + assert(recvbuf.span_is_contiguous()); + + sendbuf.syncCommData(); + + //call MPI + const int result = ::MPI_Allreduce(sendbuf.commData(), recvbuf.commData(), count, datatype, + op, comm); + + //sync back + recvbuf.syncDeviceData(); + + //ok + return result; +} + +/** + * Overlad the MPI_Allreduce() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Allreduce(void * sendbuf, IdefixHostArray3D & recvbuf, int count, + MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) { + //check + assert(recvbuf.span() == count); + assert(recvbuf.span_is_contiguous()); + + //call MPI + const int result = ::MPI_Allreduce(sendbuf, recvbuf.data(), count, datatype, op, comm); + + //ok + return result; +} + +/** + * Overlad the MPI_Allreduce() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Allreduce(void * sendbuf, IdefixCommArray & recvbuf, int count, + MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) { + //check + assert(recvbuf.span() == count); + assert(recvbuf.span_is_contiguous()); + + //call MPI + const int result = ::MPI_Allreduce(sendbuf, recvbuf.commData(), count, datatype, op, comm); + + //sync back + recvbuf.syncDeviceData(); + + //ok + return result; +} + +/** + * Overlad the MPI_File_write_all() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_File_write_all(MPI_File fh, const IdefixHostArray4D & buf, int count, + MPI_Datatype datatype, MPI_Status* status) { + //check + assert(buf.span() == count); + assert(buf.span_is_contiguous()); + + //call MPI + const int result = ::MPI_File_write_all(fh, buf.data(), count, datatype, status); + + //ok + return result; +} + +/** + * Overlad the MPI_Gather() function to handle an idefix communication array. It will automate the + * CPU / GPU transfers if the array in on GPU and WITH_MPI_GPU_DIRECT is disabled. + */ +template +int MPI_Gather(const void* sendbuf, int sendcount, MPI_Datatype + sendtype, std::vector & recvbuf, int recvcount, MPI_Datatype recvtype, + int root, MPI_Comm comm) { + assert(recvcount <= recvbuf.size()); + return ::MPI_Gather(sendbuf, sendcount, sendtype, recvbuf.data(), recvcount, + recvtype, root, comm); +} + +#endif //WITH_MPI + +} // namespace idfx + +#endif // MPI_MPIWRAPPER_HPP_ diff --git a/src/output/CMakeLists.txt b/src/output/CMakeLists.txt index 8c54eaebc..17d19b549 100644 --- a/src/output/CMakeLists.txt +++ b/src/output/CMakeLists.txt @@ -1,3 +1,18 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/output/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Soufiane Baghdadi (IPAG/UGA/CNRS - 2021) +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/slice.cpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/slice.hpp diff --git a/src/output/dump.cpp b/src/output/dump.cpp index 96a40b548..4d0a63717 100644 --- a/src/output/dump.cpp +++ b/src/output/dump.cpp @@ -1,7 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/output/dump.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2026) +// - Clément Robert (IPAG/UGA/CNRS - 2020 - 2024) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -20,11 +30,11 @@ #include #include #include "dump.hpp" -#include "version.hpp" #include "dataBlockHost.hpp" #include "gridHost.hpp" #include "output.hpp" #include "fluid.hpp" +#include "version.h" // Max size of array name #define NAMESIZE 16 @@ -880,7 +890,7 @@ int Dump::Write(Output& output) { char header[HEADERSIZE]; std::snprintf(header, HEADERSIZE, "Idefix %s Dump Data %s endian", - IDEFIX_VERSION, endian.c_str()); + VersionInfo::version, endian.c_str()); WriteString(fileHdl, header, HEADERSIZE); for(int dir = 0; dir < 3 ; dir++) { diff --git a/src/output/dump.hpp b/src/output/dump.hpp index 87cb7a3ba..16dafbe11 100644 --- a/src/output/dump.hpp +++ b/src/output/dump.hpp @@ -1,7 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/output/dump.hpp +// +// Last modified : 01/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2024) +// - Clément Robert (IPAG/UGA/CNRS - 2020 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +// - Alankar Dutta (MPA Garching - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/output/output.cpp b/src/output/output.cpp index 9df188926..30e84b46f 100644 --- a/src/output/output.cpp +++ b/src/output/output.cpp @@ -1,7 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/output/output.cpp +// +// Last modified : 04/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2025) +// - Alankar Dutta (MPA Garching - 2023) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +// - Clément Robert (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/output/output.hpp b/src/output/output.hpp index 039ab1570..1f76aa940 100644 --- a/src/output/output.hpp +++ b/src/output/output.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/output/output.hpp +// +// Last modified : 10/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2024) +// - Alankar Dutta (MPA Garching - 2023) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/output/scalarField.hpp b/src/output/scalarField.hpp index 6cbb9dd40..a11be598b 100644 --- a/src/output/scalarField.hpp +++ b/src/output/scalarField.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/output/scalarField.hpp +// +// Last modified : 12/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/output/slice.cpp b/src/output/slice.cpp index 98caa5c21..eb83b650e 100644 --- a/src/output/slice.cpp +++ b/src/output/slice.cpp @@ -1,7 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/output/slice.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +// - Clément Robert (IPAG/UGA/CNRS - 2024) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -162,7 +172,7 @@ void Slice::CheckForWrite(DataBlock &data, bool force) { }}} #ifdef WITH_MPI Kokkos::fence(); - MPI_Allreduce(MPI_IN_PLACE, arrOut.data(), + idfx::MPI_Allreduce(MPI_IN_PLACE, arrOut, arrOut.extent(0)*arrOut.extent(1)*arrOut.extent(2)*arrOut.extent(3), realMPI, MPI_SUM, avgComm); #endif diff --git a/src/output/slice.hpp b/src/output/slice.hpp index ed19a3b21..2f72c7be2 100644 --- a/src/output/slice.hpp +++ b/src/output/slice.hpp @@ -1,11 +1,18 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/output/slice.hpp +// +// Last modified : 05/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** - #ifndef OUTPUT_SLICE_HPP_ #define OUTPUT_SLICE_HPP_ diff --git a/src/output/vtk.cpp b/src/output/vtk.cpp index 98e4c2577..a80c94d57 100644 --- a/src/output/vtk.cpp +++ b/src/output/vtk.cpp @@ -1,7 +1,19 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/output/vtk.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2026) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2024) +// - Alankar Dutta (MPA Garching - 2023) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -20,12 +32,12 @@ #else error "Missing the header." #endif -#include "version.hpp" #include "idefix.hpp" #include "dataBlock.hpp" #include "gridHost.hpp" #include "output.hpp" #include "fluid.hpp" +#include "version.h" #define VTK_RECTILINEAR_GRID 14 #define VTK_STRUCTURED_GRID 35 @@ -50,7 +62,7 @@ void Vtk::WriteHeaderNodes(IdfxFileHandler fvtk) { int size_int = static_cast(size); MPI_SAFE_CALL(MPI_File_set_view(fvtk, this->offset, MPI_FLOAT, this->nodeView, "native", MPI_INFO_NULL)); - MPI_SAFE_CALL(MPI_File_write_all(fvtk, node_coord.data(), size_int, + MPI_SAFE_CALL(idfx::MPI_File_write_all(fvtk, node_coord, size_int, MPI_FLOAT, MPI_STATUS_IGNORE)); this->offset += sizeof(float)*(nx1+ioffset)*(nx2+joffset)*(nx3+koffset)*3; #else @@ -385,7 +397,7 @@ void Vtk::WriteHeader(IdfxFileHandler fvtk, real time) { 2. Header ------------------------------------------- */ - ssheader << "Idefix " << IDEFIX_VERSION << " VTK Data" << std::endl; + ssheader << "Idefix " << VersionInfo::version << " VTK Data" << std::endl; /* ------------------------------------------ 3. File format diff --git a/src/output/vtk.hpp b/src/output/vtk.hpp index 1a55f67f5..bd9cc7149 100644 --- a/src/output/vtk.hpp +++ b/src/output/vtk.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/output/vtk.hpp +// +// Last modified : 11/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2024) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/output/xdmf.cpp b/src/output/xdmf.cpp index 4e7ff6843..aceda0379 100644 --- a/src/output/xdmf.cpp +++ b/src/output/xdmf.cpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/output/xdmf.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Alankar Dutta (MPA Garching - 2023 - 2026) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2026) +// - Clément Robert (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -21,11 +30,11 @@ #endif #include "xdmf.hpp" -#include "version.hpp" #include "idefix.hpp" #include "dataBlockHost.hpp" #include "gridHost.hpp" #include "output.hpp" +#include "version.h" // Whether or not we write the time in the XDMF file #define WRITE_TIME @@ -295,7 +304,7 @@ int Xdmf::Write() { #if DIMENSIONS == 1 [[maybe_unused]] int tot_dim = 1; #elif DIMENSIONS == 2 - int tot_dim = 2; + [[maybe_unused]] int tot_dim = 2; #elif DIMENSIONS == 3 [[maybe_unused]] int tot_dim = 3; #endif @@ -526,7 +535,7 @@ void Xdmf::WriteHeader( dimstr = 1; - ssheader << "Idefix " << IDEFIX_VERSION << " XDMF Data"; + ssheader << "Idefix " << VersionInfo::version << " XDMF Data"; strspace = H5Screate_simple(1, &dimstr, NULL); string_type = H5Tcopy(H5T_C_S1); H5Tset_size(string_type, strlen( ssheader.str().c_str() )); diff --git a/src/output/xdmf.hpp b/src/output/xdmf.hpp index 6c6fc15cc..8af8348f4 100644 --- a/src/output/xdmf.hpp +++ b/src/output/xdmf.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/output/xdmf.hpp +// +// Last modified : 10/2024 +// +// Copyright(C) by : +// - Alankar Dutta (MPA Garching - 2023) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/physics.hpp b/src/physics.hpp index e9b29c455..3cb51e7fe 100644 --- a/src/physics.hpp +++ b/src/physics.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/physics.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/profiler.cpp b/src/profiler.cpp index 04ff5f5cb..439d2c7e7 100644 --- a/src/profiler.cpp +++ b/src/profiler.cpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/profiler.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/profiler.hpp b/src/profiler.hpp index 49814dd3f..eba7f39bf 100644 --- a/src/profiler.hpp +++ b/src/profiler.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/profiler.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/pydefix.cpp b/src/pydefix.cpp index 1b8168088..241797f5a 100644 --- a/src/pydefix.cpp +++ b/src/pydefix.cpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/pydefix.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2026) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -13,6 +21,7 @@ #include // For STL vectors and containers #include #include +#include #include "idefix.hpp" #include "dataBlock.hpp" #include "dataBlockHost.hpp" @@ -95,15 +104,15 @@ py::array_t GatherIdefixArray(IdefixHostArray3D #ifdef WITH_MPI MPI_Status status; // Fetch the local array size - MPI_Recv(np_int.data(), 3, MPI_INT, rank, 010, MPI_COMM_WORLD, &status); - MPI_Recv(np_tot.data(), 3, MPI_INT, rank, 011, MPI_COMM_WORLD, &status); - MPI_Recv(beg.data(), 3, MPI_INT, rank, 012, MPI_COMM_WORLD, &status); - MPI_Recv(gbeg.data(), 3, MPI_INT, rank, 013, MPI_COMM_WORLD, &status); + idfx::MPI_Recv(np_int, 3, MPI_INT, rank, 010, MPI_COMM_WORLD, &status); + idfx::MPI_Recv(np_tot, 3, MPI_INT, rank, 011, MPI_COMM_WORLD, &status); + idfx::MPI_Recv(beg, 3, MPI_INT, rank, 012, MPI_COMM_WORLD, &status); + idfx::MPI_Recv(gbeg, 3, MPI_INT, rank, 013, MPI_COMM_WORLD, &status); buf = IdefixHostArray3D("pydefix::tempArray", np_tot[KDIR],np_tot[JDIR],np_tot[IDIR]); // Fetch data - MPI_Recv(buf.data(), np_tot[IDIR]*np_tot[JDIR]*np_tot[KDIR], + idfx::MPI_Recv(buf, np_tot[IDIR]*np_tot[JDIR]*np_tot[KDIR], realMPI, rank, 014, MPI_COMM_WORLD,&status); #else IDEFIX_ERROR("Can't deal with psize>1 without MPI."); @@ -146,11 +155,11 @@ py::array_t GatherIdefixArray(IdefixHostArray3D } #ifdef WITH_MPI // send the local array size - MPI_Send(np_int.data(), 3, MPI_INT, 0, 010, MPI_COMM_WORLD); - MPI_Send(np_tot.data(), 3, MPI_INT, 0, 011, MPI_COMM_WORLD); - MPI_Send(beg.data(), 3, MPI_INT, 0, 012, MPI_COMM_WORLD); - MPI_Send(gbeg.data(), 3, MPI_INT, 0, 013, MPI_COMM_WORLD); - MPI_Send(in.data(), np_tot[IDIR]*np_tot[JDIR]*np_tot[KDIR], realMPI, 0, 014, MPI_COMM_WORLD); + idfx::MPI_Send(np_int, 3, MPI_INT, 0, 010, MPI_COMM_WORLD); + idfx::MPI_Send(np_tot, 3, MPI_INT, 0, 011, MPI_COMM_WORLD); + idfx::MPI_Send(beg, 3, MPI_INT, 0, 012, MPI_COMM_WORLD); + idfx::MPI_Send(gbeg, 3, MPI_INT, 0, 013, MPI_COMM_WORLD); + idfx::MPI_Send(in, np_tot[IDIR]*np_tot[JDIR]*np_tot[KDIR], realMPI, 0, 014, MPI_COMM_WORLD); #else IDEFIX_ERROR("Can't deal with psize>1 without MPI."); #endif @@ -158,7 +167,7 @@ py::array_t GatherIdefixArray(IdefixHostArray3D // All is transfered #ifdef WITH_MPI if(broadcast) { - MPI_Bcast(out.data(), out.extent(0)*out.extent(1)*out.extent(2), realMPI, 0, MPI_COMM_WORLD); + idfx::MPI_Bcast(out, out.extent(0)*out.extent(1)*out.extent(2), realMPI, 0, MPI_COMM_WORLD); } #endif @@ -278,6 +287,7 @@ Pydefix::Pydefix(Input &input) { idfx::cout << "Pydefix: start Python interpreter." << std::endl; py::initialize_interpreter(); + std::signal(SIGINT, SIG_DFL); // restore "terminate on Ctrl-C" signal handler py::exec("import sys; print(f'Pydefix: Python Version: {sys.version}')"); py::exec("print(f'Pydefix: Executable Path: {sys.executable}')"); py::exec("print(f'Pydefix: Sys Path: {sys.path}')"); diff --git a/src/pydefix.hpp b/src/pydefix.hpp index a12086f82..ee292549b 100644 --- a/src/pydefix.hpp +++ b/src/pydefix.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/pydefix.hpp +// +// Last modified : 01/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/real_types.hpp b/src/real_types.hpp index 440c7aac9..bada79895 100644 --- a/src/real_types.hpp +++ b/src/real_types.hpp @@ -1,7 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/real_types.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2022) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020 - 2021) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// - Alankar Dutta (MPA Garching - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -33,6 +43,8 @@ #define TAN(x) tanf(x) #define SIN(x) sinf(x) #define COS(x) cosf(x) +#define LOG(x) logf(x) +#define EXP(x) expf(x) #define COPYSIGN(x,y) copysignf(x,y) #define ISNAN(x) isnanf(x) #define FMOD(x,y) fmodf(x,y) @@ -52,6 +64,8 @@ #define TAN(x) tan(x) #define SIN(x) sin(x) #define COS(x) cos(x) +#define LOG(x) log(x) +#define EXP(x) exp(x) #define COPYSIGN(x,y) copysign(x,y) #define ISNAN(x) isnan(x) #define FMOD(x,y) fmod(x,y) diff --git a/src/reduce.hpp b/src/reduce.hpp index 17ba6b04a..cc1e84db7 100644 --- a/src/reduce.hpp +++ b/src/reduce.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/reduce.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/rkl/CMakeLists.txt b/src/rkl/CMakeLists.txt index 245fe415e..865410265 100644 --- a/src/rkl/CMakeLists.txt +++ b/src/rkl/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/rkl/CMakeLists.txt +# +# Last modified : 09/2021 +# +# Copyright(C) by : +# - Soufiane Baghdadi (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/rkl.hpp ) diff --git a/src/rkl/rkl.hpp b/src/rkl/rkl.hpp index 6f22de6f5..61fa9047f 100644 --- a/src/rkl/rkl.hpp +++ b/src/rkl/rkl.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/rkl/rkl.hpp +// +// Last modified : 12/2025 +// +// Copyright(C) by : +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2021) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -30,7 +38,7 @@ class RKLegendre { RKLegendre(Input &, Fluid*); void Cycle(); void ResetStage(); - void ResetFlux(); + void ResetFlux(int dir); void EvolveStage(real); template void CalcParabolicRHS(real); void ComputeDt(); @@ -556,9 +564,9 @@ void RKLegendre::Cycle() { template -void RKLegendre::ResetFlux() { +void RKLegendre::ResetFlux(int dir) { idfx::pushRegion("RKLegendre::ResetFlux"); - IdefixArray4D Flux = hydro->FluxRiemann; + IdefixArray4D Flux = hydro->FluxRiemann[dir]; IdefixArray1D vars = this->varList; idefix_for("RKL_ResetFlux", 0,nvarRKL, @@ -577,7 +585,6 @@ template struct RKLegendre_ResetStageFunctor { explicit RKLegendre_ResetStageFunctor(RKLegendre *rkl) { dU = rkl->dU; - Flux = rkl->hydro->FluxRiemann; vars = rkl->varList; stage = rkl->stage; nvar = rkl->nvarRKL; @@ -597,7 +604,6 @@ struct RKLegendre_ResetStageFunctor { } IdefixArray4D dU; - IdefixArray4D Flux; IdefixArray1D vars; IdefixArray4D dA, dB; IdefixArray3D ex,ey,ez; @@ -681,7 +687,7 @@ void RKLegendre::ComputeDt() { template template void RKLegendre::LoopDir(real t) { - ResetFlux(); + ResetFlux(dir); // CalcParabolicFlux hydro->template CalcParabolicFlux(t); @@ -725,7 +731,7 @@ template void RKLegendre::CalcParabolicRHS(real t) { idfx::pushRegion("RKLegendre::CalcParabolicRHS"); - IdefixArray4D Flux = hydro->FluxRiemann; + IdefixArray4D Flux = hydro->FluxRiemann[dir]; IdefixArray3D A = data->A[dir]; IdefixArray3D dV = data->dV; IdefixArray1D x1m = data->xl[IDIR]; diff --git a/src/setup.cpp b/src/setup.cpp index b82f118f8..6713749b1 100644 --- a/src/setup.cpp +++ b/src/setup.cpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/setup.cpp +// +// Last modified : 03/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/setup.hpp b/src/setup.hpp index 8e1aa0eda..c25322605 100644 --- a/src/setup.hpp +++ b/src/setup.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/setup.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/timeIntegrator.cpp b/src/timeIntegrator.cpp index 6ffb6acfb..e5183df9f 100644 --- a/src/timeIntegrator.cpp +++ b/src/timeIntegrator.cpp @@ -1,7 +1,19 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/timeIntegrator.cpp +// +// Last modified : 09/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2026) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020 - 2021) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2022) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) +// - Nicolas Scepi (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -199,7 +211,7 @@ double TimeIntegrator::ComputeBalance() { #ifdef WITH_MPI const double allowedImbalance = 20.0; std::vector computeLogPerCore(idfx::psize); - MPI_Gather(&computeLastLog, 1, MPI_DOUBLE, computeLogPerCore.data(), 1, MPI_DOUBLE, 0, + idfx::MPI_Gather(&computeLastLog, 1, MPI_DOUBLE, computeLogPerCore, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); computeLastLog = 0; // reset timer for all cores if(idfx::prank==0) { @@ -219,24 +231,29 @@ double TimeIntegrator::ComputeBalance() { } computeMean /= idfx::psize; imbalance = (computeMax-computeMin)/computeMean*100; - - if(imbalance>allowedImbalance ) { - idfx::cout << "-------------------------------------------------------------"<< std::endl; - idfx::cout << "Warning: MPI imbalance found in this run " << std::endl; - idfx::cout << std::fixed; - for(int i = 0 ; i < idfx::psize ; i++) { - if(computeLogPerCore[i]/computeMean - 1> allowedImbalance/2/100) { - idfx::cout << "+" << 100*(computeLogPerCore[i]/computeMean-1) - << "% (proc " << i << ")" << std::endl; - } - if(1-computeLogPerCore[i]/computeMean > allowedImbalance/2/100) { - idfx::cout << "-" << 100*(1-computeLogPerCore[i]/computeMean) - << "% (proc " << i << ")" << std::endl; + // only show warnings if the imbalance is higher than 20%on GPUs + #if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP) || defined(KOKKOS_ENABLE_SYCL) + if(imbalance>allowedImbalance ) { + idfx::cout << "-------------------------------------------------------------" + << std::endl; + idfx::cout << "Warning: MPI imbalance found in this run " << std::endl; + idfx::cout << std::fixed; + for(int i = 0 ; i < idfx::psize ; i++) { + if(computeLogPerCore[i]/computeMean - 1> allowedImbalance/2/100) { + idfx::cout << "+" << 100*(computeLogPerCore[i]/computeMean-1) + << "% (proc " << i << ")" << std::endl; + } + if(1-computeLogPerCore[i]/computeMean > allowedImbalance/2/100) { + idfx::cout << "-" << 100*(1-computeLogPerCore[i]/computeMean) + << "% (proc " << i << ")" << std::endl; + } } + idfx::cout << "You should probably check these nodes are running properly." + << std::endl; + idfx::cout << "-------------------------------------------------------------" + << std::endl; } - idfx::cout << "You should probably check these nodes are running properly." << std::endl; - idfx::cout << "-------------------------------------------------------------"<< std::endl; - } + #endif } #endif return(imbalance); @@ -301,14 +318,6 @@ void TimeIntegrator::Cycle(DataBlock &data) { // evolve dt accordingly data.t += data.dt; - // Look for Nans every now and then (this actually cost a lot of time on GPUs - // because streams are divergent) - if(ncycles%checkNanPeriodicity==0) { - if(data.CheckNan()>0) { - throw std::runtime_error(std::string("Nan found after integration cycle")); - } - } - // Compute next time_step during first stage if(stage==0) { if(!haveFixedDt) { @@ -348,6 +357,7 @@ void TimeIntegrator::Cycle(DataBlock &data) { // Add back fargo velocity so that boundary conditions are applied on the total V if(data.haveFargo) data.fargo->AddVelocity(data.t); } + ///////////////////////////////////////////////// // END STAGES LOOP // ///////////////////////////////////////////////// @@ -376,6 +386,14 @@ void TimeIntegrator::Cycle(DataBlock &data) { // Launch user step last data.LaunchUserStepLast(); + // Look for Nans every now and then (this actually cost a lot of time on GPUs + // because streams are divergent) + if(ncycles%checkNanPeriodicity==0) { + if(data.CheckNan()>0) { + throw std::runtime_error(std::string("Nan found after integration cycle")); + } + } + // Update current time (should have already been done, but this gets rid of roundoff errors) data.t=t0+data.dt; diff --git a/src/timeIntegrator.hpp b/src/timeIntegrator.hpp index f83593724..fc8288898 100644 --- a/src/timeIntegrator.hpp +++ b/src/timeIntegrator.hpp @@ -1,7 +1,17 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/timeIntegrator.hpp +// +// Last modified : 03/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2024) +// - Soufiane Baghdadi (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/units.cpp b/src/units.cpp index 2baf97b1e..334ad5dca 100644 --- a/src/units.cpp +++ b/src/units.cpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/units.cpp +// +// Last modified : 04/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/units.hpp b/src/units.hpp index 525e44bc0..bb6f06d38 100644 --- a/src/units.hpp +++ b/src/units.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/units.hpp +// +// Last modified : 10/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index afb4f57d4..ef71c20c7 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/utils/CMakeLists.txt +# +# Last modified : 01/2025 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022 - 2025) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + add_subdirectory(iterativesolver) target_sources(idefix diff --git a/src/utils/bigEndian.hpp b/src/utils/bigEndian.hpp index 08bd73c04..d0f9f6baf 100644 --- a/src/utils/bigEndian.hpp +++ b/src/utils/bigEndian.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/bigEndian.hpp +// +// Last modified : 07/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/utils/column.cpp b/src/utils/column.cpp index 4657abc55..dee61c652 100644 --- a/src/utils/column.cpp +++ b/src/utils/column.cpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/column.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -16,6 +24,7 @@ #include "grid.hpp" #include "dataBlock.hpp" #include "dataBlockHost.hpp" +#include "mpiWrapper.hpp" Column::Column(int dir, int sign, DataBlock *data) : direction(dir), sign(sign) { @@ -35,13 +44,13 @@ Column::Column(int dir, int sign, DataBlock *data) // allocate helper array if(dir == IDIR) { - localSum = IdefixArray2D("localSum",np_tot[KDIR], np_tot[JDIR]); + localSum = idfx::IdefixCommArray2D("localSum",np_tot[KDIR], np_tot[JDIR]); } if(dir == JDIR) { - localSum = IdefixArray2D("localSum",np_tot[KDIR], np_tot[IDIR]); + localSum = idfx::IdefixCommArray2D("localSum",np_tot[KDIR], np_tot[IDIR]); } if(dir == KDIR) { - localSum = IdefixArray2D("localSum",np_tot[JDIR], np_tot[IDIR]); + localSum = idfx::IdefixCommArray2D("localSum",np_tot[JDIR], np_tot[IDIR]); } #ifdef WITH_MPI // Create sub-MPI communicator dedicated to scan @@ -78,7 +87,7 @@ void Column::ComputeColumn(IdefixArray4D in, const int var) { auto column = this->ColumnArray; auto dV = this->Volume; auto A = this->Area; - auto localSum = this->localSum; + auto localSum = this->localSum.deviceView(); if(direction==IDIR) { // Inspired from loop.hpp @@ -133,7 +142,7 @@ void Column::ComputeColumn(IdefixArray4D in, const int var) { MPI_Status status; // Get the cumulative sum from previous processes Kokkos::fence(); - MPI_Recv(localSum.data(), size, realMPI, src, 20, ColumnComm, &status); + idfx::MPI_Recv(this->localSum, size, realMPI, src, 20, ColumnComm, &status); // Add this to our cumulative sum idefix_for("Addsum",kb,ke,jb,je,ib,ie, KOKKOS_LAMBDA(int k, int j, int i) { @@ -164,7 +173,7 @@ void Column::ComputeColumn(IdefixArray4D in, const int var) { } // And send it Kokkos::fence(); - MPI_Send(localSum.data(),size, realMPI, dst, 20, ColumnComm); + idfx::MPI_Send(this->localSum,size, realMPI, dst, 20, ColumnComm); } // MPIrank small enough #endif // If we need it backwards @@ -194,7 +203,7 @@ void Column::ComputeColumn(IdefixArray4D in, const int var) { #ifdef WITH_MPI Kokkos::fence(); - MPI_Bcast(localSum.data(),size, realMPI, MPIsize-1, ColumnComm); + idfx::MPI_Bcast(this->localSum,size, realMPI, MPIsize-1, ColumnComm); #endif // All substract the local column from the full column diff --git a/src/utils/column.hpp b/src/utils/column.hpp index 43383cbe6..665b6e78a 100644 --- a/src/utils/column.hpp +++ b/src/utils/column.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/column.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -13,6 +21,7 @@ #include "idefix.hpp" #include "dataBlock.hpp" +#include "commArray.hpp" @@ -59,7 +68,7 @@ class Column { IdefixArray3D Area; IdefixArray3D Volume; - IdefixArray2D localSum; + idfx::IdefixCommArray2D localSum; #ifdef WITH_MPI Mpi mpi; // Mpi object when WITH_MPI is set MPI_Comm ColumnComm; diff --git a/src/utils/dumpImage.cpp b/src/utils/dumpImage.cpp index 04f413a7c..fd4222010 100644 --- a/src/utils/dumpImage.cpp +++ b/src/utils/dumpImage.cpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/dumpImage.cpp +// +// Last modified : 10/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +// - Clément Robert (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/utils/dumpImage.hpp b/src/utils/dumpImage.hpp index e13da5638..b37b29898 100644 --- a/src/utils/dumpImage.hpp +++ b/src/utils/dumpImage.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/dumpImage.hpp +// +// Last modified : 05/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/utils/iterativesolver/CMakeLists.txt b/src/utils/iterativesolver/CMakeLists.txt index c8367b3f4..f9cd84c6e 100644 --- a/src/utils/iterativesolver/CMakeLists.txt +++ b/src/utils/iterativesolver/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file src/utils/iterativesolver/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + target_sources(idefix PUBLIC ${CMAKE_CURRENT_LIST_DIR}/cg.hpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/minres.hpp diff --git a/src/utils/iterativesolver/bicgstab.hpp b/src/utils/iterativesolver/bicgstab.hpp index 0b3dbb1ba..326e95c52 100644 --- a/src/utils/iterativesolver/bicgstab.hpp +++ b/src/utils/iterativesolver/bicgstab.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/iterativesolver/bicgstab.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/utils/iterativesolver/cg.hpp b/src/utils/iterativesolver/cg.hpp index de75b7381..1bffed674 100644 --- a/src/utils/iterativesolver/cg.hpp +++ b/src/utils/iterativesolver/cg.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/iterativesolver/cg.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/utils/iterativesolver/iterativesolver.hpp b/src/utils/iterativesolver/iterativesolver.hpp index e128f7fff..41b7f33d8 100644 --- a/src/utils/iterativesolver/iterativesolver.hpp +++ b/src/utils/iterativesolver/iterativesolver.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/iterativesolver/iterativesolver.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/utils/iterativesolver/jacobi.hpp b/src/utils/iterativesolver/jacobi.hpp index 941415e48..15f5e55da 100644 --- a/src/utils/iterativesolver/jacobi.hpp +++ b/src/utils/iterativesolver/jacobi.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/iterativesolver/jacobi.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/utils/iterativesolver/minres.hpp b/src/utils/iterativesolver/minres.hpp index 148457e51..b157a6d47 100644 --- a/src/utils/iterativesolver/minres.hpp +++ b/src/utils/iterativesolver/minres.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/iterativesolver/minres.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/utils/lookupTable.hpp b/src/utils/lookupTable.hpp index 72d13a838..b16d9649d 100644 --- a/src/utils/lookupTable.hpp +++ b/src/utils/lookupTable.hpp @@ -1,7 +1,16 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/lookupTable.hpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022 - 2023) +// - Alankar Dutta (MPA Garching - 2026) +// - Sébastien Valat (IPAG/UGA/CNRS - 2026) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** @@ -14,18 +23,82 @@ #include "lookupTable.hpp" #include "npy.hpp" +// Default transformation (and its inverse) used when the lookup table interpolates in function +// space: the interpolation is then performed on log(x) and log(data), and the interpolated value +// is transformed back with exp. +// Any functor exposing a KOKKOS_INLINE_FUNCTION operator()(const real) can be used instead, so +// that the transformation is available both on the host and on the device. +struct LookupTableLog { + KOKKOS_INLINE_FUNCTION real operator() (const real x) const { + return(LOG(x)); + } +}; + +struct LookupTableExp { + KOKKOS_INLINE_FUNCTION real operator() (const real x) const { + return(EXP(x)); + } +}; + +// Neighbours of a point of a lookup table, as they are found by the search performed by Get: +// idx[n] is the index of the left neighbour along the dimension n, and delta[n] is the elementary +// ratio used to weight the two neighbours of that dimension. +// Get (and GetHost) fill this structure when it is given as an argument, and GetNeighbours and +// GetNeighboursIndx then reuse the search it contains instead of performing it a second time +// (which is only done when they are called with the same coordinates: they search the table again +// as usual when a different x is requested). +// This structure is kept by the caller, so that it is thread-private when it is declared inside +// an idefix_for loop. The lookup table itself is shared by all of the threads of a loop, and can +// therefore not be used to store anything of the sort. template +struct LookupTableSearchCache { + real x[kDim]; // coordinates for which the neighbours below were computed + int idx[kDim]; // index of the left neighbour along each dimension + real delta[kDim]; // elementary ratio between the two neighbours of each dimension + bool valid{false}; // whether the neighbours above have been successfully computed + + // Check whether this structure already holds the neighbours of the coordinates xIn. + // The comparison is a bit-exact "==" on purpose: this is meant to catch the case where the + // caller passes back literally the same x it just queried (e.g. Get then GetNeighbours on the + // same iteration), not to approximate "close enough" coordinates. Do not replace this with a + // tolerance-based comparison, or two distinct nearby queries could wrongly reuse a stale search. + KOKKOS_INLINE_FUNCTION + bool Matches(const real xIn[kDim]) const { + if(!valid) return(false); + for(int n = 0 ; n < kDim ; n++) { + if(x[n] != xIn[n]) return(false); + } + return(true); + } +}; + +template class LookupTable { public: LookupTable() = default; - LookupTable(std::string filename, char delimiter, bool errorIfOutOfBound = true); + // Constructor from a CSV/ASCII file. + // By default (readColumns=false), the arrays are read as *lines* of the input file: + // 1D: 1st line = coordinates (xinHost), 2nd line = data (dataHost) + // 2D: 1st line = coordinates of the 1st dimension, then each line starts with the + // coordinate of the 2nd dimension, followed by the data of that line. + // For 1D tables only, the arrays can also be read as *columns* of the input file by setting + // readColumns=true: + // 1st column = coordinates (xinHost), 2nd column = data (dataHost) + // All of the constructors accept the optional argument interpolateInFuncSpace: when it is set + // to true, the coordinates and the data are stored as func(x) and func(data), the interpolation + // is performed in that space, and Get returns invFunc of the interpolated value (see below). + LookupTable(std::string filename, char delimiter, bool errorIfOutOfBound = true, + bool readColumns = false, bool interpolateInFuncSpace = false, + TFunc func = TFunc(), TInvFunc invFunc = TInvFunc()); LookupTable(std::vector filenames, std::string dataSet, - bool errorIfOutOfBound = true); + bool errorIfOutOfBound = true, bool interpolateInFuncSpace = false, + TFunc func = TFunc(), TInvFunc invFunc = TInvFunc()); template LookupTable(Kokkos::View array, std::array,kDim>, - bool errorIfOutOfBound = true); + bool errorIfOutOfBound = true, bool interpolateInFuncSpace = false, + TFunc func = TFunc(), TInvFunc invFunc = TInvFunc()); IdefixArray1D dimensionsDev; IdefixArray1D offsetDev; // Actually sum_(n-1) (dimensions) @@ -40,20 +113,62 @@ class LookupTable { bool errorIfOutOfBound{true}; - // Generic getter for all kinds of input arrays + // When enabled, the table is interpolated in function space: xin and data store func(x) and + // func(data), and Get returns invFunc(interpolated value). func and invFunc are stored by + // value, so that they are available on the device as well as on the host. + bool interpolateInFuncSpace{false}; + TFunc func; + TInvFunc invFunc; + + // Transform the coordinates and the data of the table in function space. + // This is called on the host by the constructors, before the arrays are copied on the device. + void ToFuncSpace() { + for(int i = 0 ; i < xinHost.extent(0) ; i++) { + xinHost(i) = func(xinHost(i)); + if(!std::isfinite(xinHost(i))) { + IDEFIX_ERROR("LookupTable: the transformation of the coordinates in function space " + "produced invalid values (with the default log, the coordinates of the " + "table should all be strictly positive)"); + } + } + for(int i = 0 ; i < dataHost.extent(0) ; i++) { + dataHost(i) = func(dataHost(i)); + if(!std::isfinite(dataHost(i))) { + IDEFIX_ERROR("LookupTable: the transformation of the data in function space " + "produced invalid values (with the default log, the data of the " + "table should all be strictly positive)"); + } + } + } + + // --------------------------------------------------------------------------------------------- + // Implementation details below: these generic (Tint/Treal-templated) helpers are shared by the + // public Get/GetHost/GetNeighbours*/GetNeighboursIndx* entry points declared further down, which + // simply instantiate them with the device or host storage. They are not meant to be called + // directly, hence kept private; make this public again if another translation unit genuinely + // needs the generic (host-or-device) form directly. + // --------------------------------------------------------------------------------------------- + private: + // Search of the bracketing indices used by the interpolation, for all kinds of input arrays. + // On output, idx[n] is the index of the left neighbour along the dimension n (so that the + // interpolation is performed between xin(offset(n)+idx[n]) and xin(offset(n)+idx[n]+1)), and + // delta[n] is the elementary ratio used to weight these two neighbours. + // Returns false when the requested coordinates contain nans, and true otherwise. + // This is the only place that performs the actual search: Get, GetNeighbours and + // GetNeighboursIndx all reach it through GetIndices below, so that a bug fix here never + // needs to be duplicated elsewhere. template KOKKOS_INLINE_FUNCTION - real Get(const real x[kDim], Tint &dimensions, Tint &offset, Treal &xin, Treal &data) const { - // Fetch function that should be called inside idefix_loop - int idx[kDim]; - real delta[kDim]; - + bool GetIndices(const real x[kDim], Tint &dimensions, Tint &offset, Treal &xin, + int idx[kDim], real delta[kDim]) const { for(int n = 0 ; n < kDim ; n++) { real xstart = xin(offset(n)); real xend = xin(offset(n)+dimensions(n)-1); - real x_n = x[n]; + // When interpolating in function space, xin already stores func(x), so the coordinate + // we are looking for should be transformed accordingly + real x_n = interpolateInFuncSpace ? func(x[n]) : x[n]; - if(std::isnan(x_n)) return(NAN); + if(std::isnan(x_n)) return(false); // Compute index of closest element assuming even distribution int i; @@ -82,16 +197,20 @@ class LookupTable { // Check if resulting bounding elements are correct if(xin(offset(n) + i) > x_n || xin(offset(n) + i+1) < x_n) { // Nop, so the points are not evenly distributed - // Search for the correct index (a dicotomy would be more appropriate...) - - i = 0; - while(xin(offset(n) + i) < x_n && i < dimensions(n)-1 ) { - i++; + // Search for the correct index with a dichotomy + int ileft = 0; + int iright = dimensions(n)-1; + while(iright-ileft>1) { + int imid = (ileft + iright) / 2; + if(xin(offset(n) + imid) <= x_n) { + ileft = imid; + } else { + iright = imid; + } } - i = i-1; // i is overestimated by one + i = ileft; } } - // Store the index idx[n] = i; @@ -99,33 +218,190 @@ class LookupTable { delta[n] = (x_n - xin(offset(n) + i) ) / (xin(offset(n) + i+1) - xin(offset(n) + i)); } - // De a linear interpolation from the neightbouring points to get our value. + return(true); + } + + // Index in the data array of the vertex "vertex" of the neighbours. Each bit of "vertex" tells + // whether we are on the right (1) or on the left (0) of the corresponding dimension, so that + // there are 2^kDim vertices surrounding the point we are interpolating. + template + KOKKOS_INLINE_FUNCTION + int GetDataIndex(Tint &dimensions, const int idx[kDim], const unsigned int vertex) const { + int index = 0; + for(unsigned int m = 0 ; m < kDim ; m++) { + index = index * dimensions(m); + unsigned int myBit = 1 << m; + // If bit is set, we're doing the right vertex, otherwise we're doing the left vertex + if((vertex & myBit) > 0) { + index += idx[m]+1; + } else { + index += idx[m]; + } + } + return(index); + } + + // Fill "searchCache" with the neighbours of x, unless it already holds them (in which case the + // table is not searched again). This is what allows Get, GetNeighbours and GetNeighboursIndx to + // share a single search when they are called successively with the same coordinates. + template + KOKKOS_INLINE_FUNCTION + void SearchNeighbours(const real x[kDim], Tint &dimensions, Tint &offset, Treal &xin, + LookupTableSearchCache &searchCache) const { + // Nothing to do if the neighbours of these very coordinates are already known + if(searchCache.Matches(x)) return; + + searchCache.valid = GetIndices(x, dimensions, offset, xin, searchCache.idx, searchCache.delta); + for(int n = 0 ; n < kDim ; n++) { + searchCache.x[n] = x[n]; + } + } + + // Generic getter which stores in "searchCache" the elements of the table it used, so that a + // subsequent call to GetNeighbours or GetNeighboursIndx with the same coordinates does not + // search the table again + template + KOKKOS_INLINE_FUNCTION + real Get(const real x[kDim], Tint &dimensions, Tint &offset, Treal &xin, Treal &data, + LookupTableSearchCache &searchCache) const { + SearchNeighbours(x, dimensions, offset, xin, searchCache); + + if(!searchCache.valid) return(NAN); + + // Do a linear interpolation from the neightbouring points to get our value. real value = 0; // loop on all of the vertices of the neighbours for(unsigned int n = 0 ; n < (1 << kDim) ; n++) { - int index = 0; real weight = 1.0; for(unsigned int m = 0 ; m < kDim ; m++) { - index = index * dimensions(m); unsigned int myBit = 1 << m; // If bit is set, we're doing the right vertex, otherwise we're doing the left vertex if((n & myBit) > 0) { // We're on the right - weight = weight*delta[m]; - index += idx[m]+1; + weight = weight*searchCache.delta[m]; } else { // We're on the left - weight = weight*(1-delta[m]); - index += idx[m]; + weight = weight*(1-searchCache.delta[m]); } } - value = value + weight*data(index); + value = value + weight*data(GetDataIndex(dimensions, searchCache.idx, n)); } + // The interpolation was performed on func(data), so we transform the result back + if(interpolateInFuncSpace) value = invFunc(value); + return(value); } + // Generic getter for all kinds of input arrays. + // Implemented as a thin delegation to the neighbours-caching overload below, using a throwaway + // searchCache structure: LookupTableSearchCache is a small stack-only POD (no allocation), so + // this costs nothing extra while guaranteeing the two overloads can never disagree on the result. + template + KOKKOS_INLINE_FUNCTION + real Get(const real x[kDim], Tint &dimensions, Tint &offset, Treal &xin, Treal &data) const { + LookupTableSearchCache searchCache; + return Get(x, dimensions, offset, xin, data, searchCache); + } + + // Generic getter for the neighbours used by the interpolation, for all kinds of input arrays. + // On output, xN[2*n] and xN[2*n+1] are the coordinates bracketing x[n] along the dimension n, + // and dataN[v] is the data at the vertex v of these neighbours (see GetDataIndex for the + // convention on v). When the table is interpolated in function space, both are returned in the + // original space of the table (i.e. invFunc is applied to the values stored in the table). + // All of the outputs are set to nan when the requested coordinates contain nans. + template + KOKKOS_INLINE_FUNCTION + void GetNeighbours(const real x[kDim], Tint &dimensions, Tint &offset, Treal &xin, Treal &data, + real xN[2*kDim], real dataN[1 << kDim]) const { + LookupTableSearchCache searchCache; + GetNeighbours(x, dimensions, offset, xin, data, searchCache, xN, dataN); + } + + // Same as above, but the search is stored in (and reused from) "searchCache": the table is only + // searched again when "searchCache" does not already hold the neighbours of x, e.g. because it + // was filled by a previous call to Get with these very same coordinates. + template + KOKKOS_INLINE_FUNCTION + void GetNeighbours(const real x[kDim], Tint &dimensions, Tint &offset, Treal &xin, Treal &data, + LookupTableSearchCache &searchCache, + real xN[2*kDim], real dataN[1 << kDim]) const { + // Reuse GetNeighboursIndx for the search and the idx -> flat data offset bookkeeping, so that + // logic only lives in one place (GetDataIndex/GetNeighboursIndx). + int idx[kDim]; + int dataIdx[1 << kDim]; + GetNeighboursIndx(x, dimensions, offset, xin, searchCache, idx, dataIdx); + + if(!searchCache.valid) { + for(int n = 0 ; n < 2*kDim ; n++) xN[n] = NAN; + for(unsigned int n = 0 ; n < (1 << kDim) ; n++) dataN[n] = NAN; + return; + } + + // Coordinates of the neighbours along each dimension + for(int n = 0 ; n < kDim ; n++) { + xN[2*n] = xin(offset(n) + idx[n]); + xN[2*n+1] = xin(offset(n) + idx[n]+1); + if(interpolateInFuncSpace) { + xN[2*n] = invFunc(xN[2*n]); + xN[2*n+1] = invFunc(xN[2*n+1]); + } + } + + // Data on each vertex of the neighbours + for(unsigned int n = 0 ; n < (1 << kDim) ; n++) { + dataN[n] = data(dataIdx[n]); + if(interpolateInFuncSpace) dataN[n] = invFunc(dataN[n]); + } + } + + // Generic getter for the indices of the neighbours used by the interpolation, for all kinds of + // input arrays. On output, idx[n] is the index of the left neighbour along the dimension n + // (the right one being idx[n]+1), and dataIdx[v] is the index in the data array of the vertex v + // of these neighbours (see GetDataIndex for the convention on v). + // All of the outputs are set to -1 when the requested coordinates contain nans. + template + KOKKOS_INLINE_FUNCTION + void GetNeighboursIndx(const real x[kDim], Tint &dimensions, Tint &offset, Treal &xin, + LookupTableSearchCache &searchCache, + int idx[kDim], int dataIdx[1 << kDim]) const { + SearchNeighbours(x, dimensions, offset, xin, searchCache); + + if(!searchCache.valid) { + for(int n = 0 ; n < kDim ; n++) idx[n] = -1; + for(unsigned int n = 0 ; n < (1 << kDim) ; n++) dataIdx[n] = -1; + return; + } + + for(int n = 0 ; n < kDim ; n++) { + idx[n] = searchCache.idx[n]; + } + for(unsigned int n = 0 ; n < (1 << kDim) ; n++) { + dataIdx[n] = GetDataIndex(dimensions, searchCache.idx, n); + } + } + + +// Same as above, but the search is not stored in a caller-supplied structure: a throwaway +// LookupTableSearchCache is created and filled, and then discarded. + template + KOKKOS_INLINE_FUNCTION + void GetNeighboursIndx(const real x[kDim], Tint &dimensions, Tint &offset, Treal &xin, + int idx[kDim], int dataIdx[1 << kDim]) const { + LookupTableSearchCache searchCache; + GetNeighboursIndx(x, dimensions, offset, xin, searchCache, idx, dataIdx); + } + + + + // ----------------------------------------------------------------------------------------- + // Public interface: each of Get/GetNeighbours/GetNeighboursIndx below is a thin one-line + // dispatch to the generic (private) implementation above, selecting device or host storage, + // and optionally reusing a caller-supplied LookupTableSearchCache cache. None of them contains + // any interpolation logic of its own. + // ----------------------------------------------------------------------------------------- + public: // Getter on device KOKKOS_INLINE_FUNCTION real Get(const real x[kDim]) const { @@ -137,14 +413,86 @@ class LookupTable { real GetHost(const real x[kDim]) const { return(Get(x, dimensionsHost, offsetHost, xinHost, dataHost)); } + + // Getter for the neighbours used by the interpolation, on device + KOKKOS_INLINE_FUNCTION + void GetNeighbours(const real x[kDim], real xN[2*kDim], real dataN[1 << kDim]) const { + GetNeighbours(x, dimensionsDev, offsetDev, xinDev, dataDev, xN, dataN); + } + + // Getter for the neighbours used by the interpolation, on Host + KOKKOS_INLINE_FUNCTION + void GetNeighboursHost(const real x[kDim], real xN[2*kDim], real dataN[1 << kDim]) const { + GetNeighbours(x, dimensionsHost, offsetHost, xinHost, dataHost, xN, dataN); + } + + // Getter for the indices of the neighbours used by the interpolation, on device + KOKKOS_INLINE_FUNCTION + void GetNeighboursIndx(const real x[kDim], int idx[kDim], int dataIdx[1 << kDim]) const { + GetNeighboursIndx(x, dimensionsDev, offsetDev, xinDev, idx, dataIdx); + } + + // Getter for the indices of the neighbours used by the interpolation, on Host + KOKKOS_INLINE_FUNCTION + void GetNeighboursIndxHost(const real x[kDim], int idx[kDim], int dataIdx[1 << kDim]) const { + GetNeighboursIndx(x, dimensionsHost, offsetHost, xinHost, idx, dataIdx); + } + + // Getter on device, which stores the neighbours it used in "neighbours". Giving that same + // structure to GetNeighbours or GetNeighboursIndx below then avoids searching the table twice. + KOKKOS_INLINE_FUNCTION + real Get(const real x[kDim], LookupTableSearchCache &neighbours) const { + return(Get(x, dimensionsDev, offsetDev, xinDev, dataDev, neighbours)); + } + + // Getter on Host, which stores the neighbours it used in "neighbours" + KOKKOS_INLINE_FUNCTION + real GetHost(const real x[kDim], LookupTableSearchCache &neighbours) const { + return(Get(x, dimensionsHost, offsetHost, xinHost, dataHost, neighbours)); + } + + // Getter for the neighbours used by the interpolation, on device, reusing the search stored in + // "neighbours" when it was performed for these very same coordinates + KOKKOS_INLINE_FUNCTION + void GetNeighbours(const real x[kDim], LookupTableSearchCache &neighbours, + real xN[2*kDim], real dataN[1 << kDim]) const { + GetNeighbours(x, dimensionsDev, offsetDev, xinDev, dataDev, neighbours, xN, dataN); + } + + // Getter for the neighbours used by the interpolation, on Host, reusing the search stored in + // "neighbours" when it was performed for these very same coordinates + KOKKOS_INLINE_FUNCTION + void GetNeighboursHost(const real x[kDim], LookupTableSearchCache &neighbours, + real xN[2*kDim], real dataN[1 << kDim]) const { + GetNeighbours(x, dimensionsHost, offsetHost, xinHost, dataHost, neighbours, xN, dataN); + } + + // Getter for the indices of the neighbours, on device, reusing the search stored in + // "neighbours" when it was performed for these very same coordinates + KOKKOS_INLINE_FUNCTION + void GetNeighboursIndx(const real x[kDim], LookupTableSearchCache &searchCache, + int idx[kDim], int dataIdx[1 << kDim]) const { + GetNeighboursIndx(x, dimensionsDev, offsetDev, xinDev, searchCache, idx, dataIdx); + } + + // Getter for the indices of the neighbours, on Host, reusing the search stored in + // "neighbours" when it was performed for these very same coordinates + KOKKOS_INLINE_FUNCTION + void GetNeighboursIndxHost(const real x[kDim], LookupTableSearchCache &neighbours, + int idx[kDim], int dataIdx[1 << kDim]) const { + GetNeighboursIndx(x, dimensionsHost, offsetHost, xinHost, neighbours, idx, dataIdx); + } }; -template -LookupTable::LookupTable(std::vector filenames, +template +LookupTable::LookupTable(std::vector filenames, std::string dataSet, - bool errOOB) { + bool errOOB, bool funcSpace, TFunc funcIn, TInvFunc invFuncIn) { idfx::pushRegion("LookupTable::LookupTable"); this->errorIfOutOfBound = errOOB; + this->interpolateInFuncSpace = funcSpace; + this->func = funcIn; + this->invFunc = invFuncIn; std::vector shape; bool fortran_order; @@ -177,7 +525,7 @@ LookupTable::LookupTable(std::vector filenames, } // Allocate the required memory - //Allocate arrays so that the data fits in it + // Allocate arrays so that the data fits in it this->xinDev = IdefixArray1D ("Table_x", sizeTotal); this->dimensionsDev = IdefixArray1D ("Table_dim", kDim); this->offsetDev = IdefixArray1D ("Table_offset", kDim); @@ -233,6 +581,9 @@ LookupTable::LookupTable(std::vector filenames, } } + // Transform the table in function space if required + if(this->interpolateInFuncSpace) this->ToFuncSpace(); + // Copy to target Kokkos::deep_copy(this->xinDev ,xinHost); Kokkos::deep_copy(this->dimensionsDev, dimensionsHost); @@ -244,13 +595,23 @@ LookupTable::LookupTable(std::vector filenames, // Constructor from CSV file -template -LookupTable::LookupTable(std::string filename, char delimiter, bool errOOB) { +// The coordinates and the data are read as lines of the input file, unless readColumns is set +// to true, in which case they are read as columns of the input file (1D tables only, see the +// declaration of the class for a description of both layouts). +template +LookupTable::LookupTable(std::string filename, char delimiter, bool errOOB, + bool readColumns, bool funcSpace, TFunc funcIn, TInvFunc invFuncIn) { idfx::pushRegion("LookupTable::LookupTable"); this->errorIfOutOfBound = errOOB; + this->interpolateInFuncSpace = funcSpace; + this->func = funcIn; + this->invFunc = invFuncIn; if(kDim>2) { IDEFIX_ERROR("CSV files are only compatible with 1D and 2D tables"); } + if(kDim>1 && readColumns) { + IDEFIX_ERROR("CSV files can only be read as columns for 1D tables"); + } // Only 1 process loads the file // Size of the array int size[2]; @@ -265,21 +626,18 @@ LookupTable::LookupTable(std::string filename, char delimiter, bool errOOB if(file.is_open()) { std::string line, lineWithComments; - bool firstLine = true; - int nx = -1; + // Full content of the file, stored as a list of lines, each line being a list of values + std::vector> fileContent; while(std::getline(file, lineWithComments)) { // get rid of comments (starting with #) line = lineWithComments.substr(0, lineWithComments.find("#",0)); if (line.empty()) continue; // skip blank line - char firstChar = line.find_first_not_of(" "); + std::size_t firstChar = line.find_first_not_of(" "); if (firstChar == std::string::npos) continue; // line is all white space // Walk the line - bool firstColumn=true; - if(kDim == 1) firstColumn = false; - - std::vector dataLine; - dataLine.clear(); + std::vector lineVector; + lineVector.clear(); // make the line a string stream, and get all of the values separated by a delimiter std::stringstream str(line); std::string valueString; @@ -294,31 +652,62 @@ LookupTable::LookupTable(std::string filename, char delimiter, bool errOOB << "\" cannot be converted to real." << std::endl; IDEFIX_ERROR(errmsg); } - if(firstLine) { - xVector.push_back(value); - } else if(firstColumn) { - yVector.push_back(value); - firstColumn = false; - } else { - dataLine.push_back(value); - } + lineVector.push_back(value); } // We have finished the line - if(firstLine) { - nx = xVector.size(); - firstLine=false; - } else { - if(dataLine.size() != nx) { + fileContent.push_back(lineVector); + // When read as lines, a 1D table is fully described by the first two lines of the file, + // so we stop reading what's after them + if(kDim < 2 && !readColumns && fileContent.size() == 2) break; + } + file.close(); + // End of file reached + + if(fileContent.size() < 2) { + IDEFIX_ERROR("LookupTable: The input CSV file should contain at least two lines"); + } + + // Dispatch the content of the file in the coordinate and data containers. + // Note that dataVector is always indexed as dataVector[j][i], where i (resp. j) is the + // index along the 1st (resp. 2nd) dimension of the table. + if(readColumns) { + // (1D tables only) the coordinates are stored in the 1st column of the input file, + // while the data is stored in its 2nd column + dataVector.push_back(std::vector()); + for(int i = 0 ; i < fileContent.size() ; i++) { + if(fileContent[i].size() < 2) { + IDEFIX_ERROR("LookupTable: The input CSV file should have at least two columns " + "when the table is read as columns"); + } + xVector.push_back(fileContent[i][0]); + dataVector[0].push_back(fileContent[i][1]); + } + } else { + // (default) the arrays are stored as lines of the input file + // 1st line always gives the coordinates of the 1st dimension + xVector = fileContent[0]; + const int nx = xVector.size(); + if(kDim < 2) { + // 2nd line is the data + if(fileContent[1].size() != nx) { IDEFIX_ERROR("LookupTable: The number of columns in the input CSV " "file should be constant"); } - dataVector.push_back(dataLine); - firstLine = false; - if(kDim < 2) break; // Stop reading what's after the first two lines + dataVector.push_back(fileContent[1]); + } else { + // each of the following lines starts with the coordinate of the 2nd dimension, + // followed by the data of that line + for(int j = 1 ; j < fileContent.size() ; j++) { + if(fileContent[j].size() != nx+1) { + IDEFIX_ERROR("LookupTable: The number of columns in the input CSV " + "file should be constant"); + } + yVector.push_back(fileContent[j][0]); + dataVector.push_back(std::vector(fileContent[j].begin()+1, + fileContent[j].end())); + } } } - file.close(); - // End of file reached } else { std::stringstream errmsg; errmsg << "LookupTable: Unable to open file " << filename << std::endl; @@ -392,12 +781,15 @@ LookupTable::LookupTable(std::string filename, char delimiter, bool errOOB #ifdef WITH_MPI // Share with the others - MPI_Bcast(xinHost.data(), xinHost.extent(0), realMPI, 0, MPI_COMM_WORLD); - MPI_Bcast(dimensionsHost.data(), dimensionsHost.extent(0), MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(offsetHost.data(), offsetHost.extent(0), MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(dataHost.data(),dataHost.extent(0), realMPI, 0, MPI_COMM_WORLD); + idfx::MPI_Bcast(xinHost, xinHost.extent(0), realMPI, 0, MPI_COMM_WORLD); + idfx::MPI_Bcast(dimensionsHost, dimensionsHost.extent(0), MPI_INT, 0, MPI_COMM_WORLD); + idfx::MPI_Bcast(offsetHost, offsetHost.extent(0), MPI_INT, 0, MPI_COMM_WORLD); + idfx::MPI_Bcast(dataHost,dataHost.extent(0), realMPI, 0, MPI_COMM_WORLD); #endif + // Transform the table in function space if required + if(this->interpolateInFuncSpace) this->ToFuncSpace(); + // Copy to target Kokkos::deep_copy(this->xinDev ,xinHost); Kokkos::deep_copy(this->dimensionsDev, dimensionsHost); @@ -426,13 +818,16 @@ LookupTable::LookupTable(std::string filename, char delimiter, bool errOOB // Constructor from IdefixHostArray -template +template template -LookupTable::LookupTable(Kokkos::View array, +LookupTable::LookupTable(Kokkos::View array, std::array,kDim> x, - bool errOOB) { + bool errOOB, bool funcSpace, TFunc funcIn, TInvFunc invFuncIn) { idfx::pushRegion("LookupTable::LookupTable"); this->errorIfOutOfBound = errOOB; + this->interpolateInFuncSpace = funcSpace; + this->func = funcIn; + this->invFunc = invFuncIn; std::vector shape(kDim); for(int i = 0 ; i < kDim ; i++) shape[i] = x[i].extent(0); @@ -504,6 +899,9 @@ LookupTable::LookupTable(Kokkos::View array, } } + // Transform the table in function space if required + if(this->interpolateInFuncSpace) this->ToFuncSpace(); + // Copy to target Kokkos::deep_copy(this->xinDev ,xinHost); Kokkos::deep_copy(this->dimensionsDev, dimensionsHost); diff --git a/src/utils/npy.hpp b/src/utils/npy.hpp index edae82ee3..7c8867a15 100644 --- a/src/utils/npy.hpp +++ b/src/utils/npy.hpp @@ -1,7 +1,15 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/npy.hpp +// +// Last modified : 10/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// - Clément Robert (IPAG/UGA/CNRS - 2024) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/utils/vector.hpp b/src/utils/vector.hpp index 68c49eea7..daf2a9b03 100644 --- a/src/utils/vector.hpp +++ b/src/utils/vector.hpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file src/utils/vector.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/src/version.h.in b/src/version.h.in new file mode 100644 index 000000000..ee4dbb0e7 --- /dev/null +++ b/src/version.h.in @@ -0,0 +1,26 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file src/version.h.in +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + +#ifndef VERSION_H +#define VERSION_H + +namespace VersionInfo { + inline constexpr const char* gitCommit = "@GIT_SHA1@"; + inline constexpr const char* versionMajor = "@Idefix_VERSION_MAJOR@"; + inline constexpr const char* versionMinor = "@Idefix_VERSION_MINOR@"; + inline constexpr const char* versionPatch = "@Idefix_VERSION_PATCH@"; + inline constexpr const char* version = "@Idefix_VERSION@"; +} + +#endif diff --git a/test.py b/test.py index 6ded87fa0..2e00981b0 100755 --- a/test.py +++ b/test.py @@ -1,7 +1,22 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test.py +# +# Last modified : 09/2026 +# +# Copyright(C) by : +# - Sébastien Valat (IPAG/UGA/CNRS - 2026) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### import os import sys + import pytest # set IDEFIX_DIR @@ -16,11 +31,21 @@ # to build for each run if we just changed the ini file and run options. gblIdefixPytestRunner = IdexPytestRunner(__file__) + +# if called directly as a script +if __name__ == "__main__" and "--validate-testme-jsons" in sys.argv: + if gblIdefixPytestRunner.validateTestmeJsons(): + sys.exit(0) + else: + sys.exit(1) + + # define the pytest test @pytest.mark.parametrize("config", gblIdefixPytestRunner.genTests()) def test_idefix_build_run_check(config): - gblIdefixPytestRunner.run(config) + gblIdefixPytestRunner.run(config) + # if called directly as a script if __name__ == "__main__": - gblIdefixPytestRunner.main(all=True) + gblIdefixPytestRunner.main(all=True) diff --git a/test/Dust/DustEnergy/definitions.hpp b/test/Dust/DustEnergy/definitions.hpp index 498be97af..e64a63241 100644 --- a/test/Dust/DustEnergy/definitions.hpp +++ b/test/Dust/DustEnergy/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Dust/DustEnergy/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 1 #define DIMENSIONS 1 diff --git a/test/Dust/DustEnergy/python/testidefix.py b/test/Dust/DustEnergy/python/testidefix.py index d7d766a15..dc6a1e6da 100755 --- a/test/Dust/DustEnergy/python/testidefix.py +++ b/test/Dust/DustEnergy/python/testidefix.py @@ -1,57 +1,69 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Dust/DustEnergy/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Mon Mar 13 14:45:58 2023 @author: lesurg """ -import sys -import numpy as np + import argparse +import sys + import matplotlib.pyplot as plt +import numpy as np parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() # solve eq. A6 in Riols & Lesur (2018) +# load the dat file produced by the setup +raw = np.loadtxt("../timevol.dat", skiprows=1) +t = raw[:, 0] +Ekg = raw[:, 1] +Ekd = raw[:, 2] +Eth = raw[:, 3] +etot = Ekg + Ekd + Eth - -# load the dat file produced by the setup -raw=np.loadtxt('../timevol.dat',skiprows=1) -t=raw[:,0] -Ekg=raw[:,1] -Ekd=raw[:,2] -Eth=raw[:,3] - -etot=Ekg+Ekd+Eth - -if not(args.noplot): - plt.figure() - plt.plot(t,Ekg,label="Ek_g") - plt.plot(t,Ekd,label="Ek_d") - plt.plot(t,Eth,label="Eth") - plt.plot(t,etot,'--',label="Etot") - plt.legend() - plt.xlabel("t") - plt.ylabel("Flow energy") - plt.show() +if not (args.noplot): + plt.figure() + plt.plot(t, Ekg, label="Ek_g") + plt.plot(t, Ekd, label="Ek_d") + plt.plot(t, Eth, label="Eth") + plt.plot(t, etot, "--", label="Etot") + plt.legend() + plt.xlabel("t") + plt.ylabel("Flow energy") + plt.show() # Compute relative evolution of total energy -error=abs((etot[-1]-etot[0])/etot[0]) +error = abs((etot[-1] - etot[0]) / etot[0]) -print("error=%f"%error) -if(error<1e-4): - print("Success!") +print("error=%f" % error) +if error < 1e-4: + print("Success!") else: - print("Failure!") - sys.exit(1) + print("Failure!") + sys.exit(1) diff --git a/test/Dust/DustEnergy/setup.cpp b/test/Dust/DustEnergy/setup.cpp index cba900a09..4463300d7 100644 --- a/test/Dust/DustEnergy/setup.cpp +++ b/test/Dust/DustEnergy/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Dust/DustEnergy/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/Dust/DustEnergy/testme.json b/test/Dust/DustEnergy/testme.json index 9a78834b9..3465b5fdb 100644 --- a/test/Dust/DustEnergy/testme.json +++ b/test/Dust/DustEnergy/testme.json @@ -1,12 +1,14 @@ { "namings": "ini", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "reconstruction": 2, + "tolerance": 0 + }, "variants": [ { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-implicit.ini"], - "noplot": true, - "reconstruction": 2, - "tolerance": 0 + "ini": ["idefix.ini","idefix-implicit.ini"] } ] } diff --git a/test/Dust/DustEnergy/testme.py b/test/Dust/DustEnergy/testme.py index 12d476b66..33fbf1f9d 100755 --- a/test/Dust/DustEnergy/testme.py +++ b/test/Dust/DustEnergy/testme.py @@ -1,39 +1,56 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Dust/DustEnergy/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-implicit.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-implicit.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init: - test.makeReference(filename=name) - test.standardTest() - test.nonRegressionTest(filename=name) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init: + test.makeReference(filename=name) + test.standardTest() + test.nonRegressionTest(filename=name) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename=name) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name) + else: + testMe(test) else: - test.noplot = True - test.reconstruction=2 - testMe(test) + test.noplot = True + test.reconstruction = 2 + testMe(test) diff --git a/test/Dust/DustyShock/definitions.hpp b/test/Dust/DustyShock/definitions.hpp index cdbe23d6e..d15f31646 100644 --- a/test/Dust/DustyShock/definitions.hpp +++ b/test/Dust/DustyShock/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Dust/DustyShock/definitions.hpp +// +// Last modified : 02/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 1 #define DIMENSIONS 1 #define ISOTHERMAL diff --git a/test/Dust/DustyShock/python/testidefix.py b/test/Dust/DustyShock/python/testidefix.py index 8fca15a3f..8e831a74e 100755 --- a/test/Dust/DustyShock/python/testidefix.py +++ b/test/Dust/DustyShock/python/testidefix.py @@ -1,4 +1,19 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Dust/DustyShock/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # -*- coding: utf-8 -*- """ Created on Thu Mar 5 11:29:41 2020 @@ -8,88 +23,106 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK import argparse -import numpy as np + import matplotlib.pyplot as plt +import numpy as np from scipy.integrate import solve_ivp +from pytools.vtk_io import readVTK + parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() -V=readVTK('../data.0001.vtk', geometry='cartesian') +V = readVTK("../data.0001.vtk", geometry="cartesian") # Find where the shock starts -istart = np.argwhere(V.data['RHO'][:,0,0]>2.0)[0][0]-1 +istart = np.argwhere(V.data["RHO"][:, 0, 0] > 2.0)[0][0] - 1 # Compute analytical solution -M=2 # Mach number -K=np.asarray([1,3,5])/M # Drag coefficients +M = 2 # Mach number +K = np.asarray([1, 3, 5]) / M # Drag coefficients + # (56) from Benitez-Llambay 2018 def get_wg(Mach, wi): - coeff=[1,np.sum(wi-1)-1/Mach**2-1,1/Mach**2] - solution=np.roots(coeff) - return(np.min(solution)) + coeff = [1, np.sum(wi - 1) - 1 / Mach**2 - 1, 1 / Mach**2] + solution = np.roots(coeff) + return np.min(solution) + # (55) from Benitez-Llambay 2018 -def rhs(t,wi,Mach,K): - wg = get_wg(Mach,wi) - return K*(wg-wi) +def rhs(t, wi, Mach, K): + wg = get_wg(Mach, wi) + return K * (wg - wi) + -wi0=np.asarray([1.0,1.0,1.0]) -x=V.x[istart:] -arguments=M,K +wi0 = np.asarray([1.0, 1.0, 1.0]) +x = V.x[istart:] +arguments = M, K -sol = solve_ivp(rhs, t_span=[x[0],x[-1]], y0=wi0, t_eval=x,args=arguments) +sol = solve_ivp(rhs, t_span=[x[0], x[-1]], y0=wi0, t_eval=x, args=arguments) # compute gas velocity -wg=np.zeros(len(x)) -for i in range(0,len(wg)): - wg[i]=get_wg(M,sol.y[:,i]) +wg = np.zeros(len(x)) +for i in range(0, len(wg)): + wg[i] = get_wg(M, sol.y[:, i]) -if(not args.noplot): +if not args.noplot: plt.figure(1) - plt.plot(V.x,V.data['RHO'][:,0,0],'o',markersize=4,color='tab:purple') - plt.plot(x,1/wg,color='tab:purple') - plt.plot(V.x,V.data['Dust0_RHO'][:,0,0],'o',markersize=4,color='tab:orange') - plt.plot(x,1/sol.y[0,:],color='tab:orange') - plt.plot(V.x,V.data['Dust1_RHO'][:,0,0],'o',markersize=4,color='tab:blue') - plt.plot(x,1/sol.y[1,:],color='tab:blue') - plt.plot(V.x,V.data['Dust2_RHO'][:,0,0],'o',markersize=4,color='tab:green') - plt.plot(x,1/sol.y[2,:],color='tab:green') - plt.xlim([0,10]) - plt.title('Density') + plt.plot(V.x, V.data["RHO"][:, 0, 0], "o", markersize=4, color="tab:purple") + plt.plot(x, 1 / wg, color="tab:purple") + plt.plot(V.x, V.data["Dust0_RHO"][:, 0, 0], "o", markersize=4, color="tab:orange") + plt.plot(x, 1 / sol.y[0, :], color="tab:orange") + plt.plot(V.x, V.data["Dust1_RHO"][:, 0, 0], "o", markersize=4, color="tab:blue") + plt.plot(x, 1 / sol.y[1, :], color="tab:blue") + plt.plot(V.x, V.data["Dust2_RHO"][:, 0, 0], "o", markersize=4, color="tab:green") + plt.plot(x, 1 / sol.y[2, :], color="tab:green") + plt.xlim([0, 10]) + plt.title("Density") plt.figure(2) - plt.plot(V.x,V.data['VX1'][:,0,0],'o',markersize=4,color='tab:purple') - plt.plot(x,M*wg,color='tab:purple') - plt.plot(V.x[::4],V.data['Dust0_VX1'][::4,0,0],'o',markersize=4,color='tab:orange') - plt.plot(x,M*sol.y[0,:],color='tab:orange') - plt.plot(V.x[::4],V.data['Dust1_VX1'][::4,0,0],'o',markersize=4,color='tab:blue') - plt.plot(x,M*sol.y[1,:],color='tab:blue') - plt.plot(V.x[::4],V.data['Dust2_VX1'][::4,0,0],'o',markersize=4,color='tab:green') - plt.plot(x,M*sol.y[2,:],color='tab:green') - - plt.xlim([0,10]) - plt.title('Velocity') + plt.plot(V.x, V.data["VX1"][:, 0, 0], "o", markersize=4, color="tab:purple") + plt.plot(x, M * wg, color="tab:purple") + plt.plot( + V.x[::4], V.data["Dust0_VX1"][::4, 0, 0], "o", markersize=4, color="tab:orange" + ) + plt.plot(x, M * sol.y[0, :], color="tab:orange") + plt.plot( + V.x[::4], V.data["Dust1_VX1"][::4, 0, 0], "o", markersize=4, color="tab:blue" + ) + plt.plot(x, M * sol.y[1, :], color="tab:blue") + plt.plot( + V.x[::4], V.data["Dust2_VX1"][::4, 0, 0], "o", markersize=4, color="tab:green" + ) + plt.plot(x, M * sol.y[2, :], color="tab:green") + + plt.xlim([0, 10]) + plt.title("Velocity") plt.ioff() plt.show() # Compute the error on the dust densities -error=np.mean(np.fabs(V.data['Dust0_RHO'][istart:,0,0]-1/sol.y[0,:]) + np.fabs(V.data['Dust1_RHO'][istart:,0,0]-1/sol.y[1,:]) + np.fabs(V.data['Dust2_RHO'][istart:,0,0]-1/sol.y[2,:])) / 3 -print("Error=%e"%error) -if error<3.6e-2: +error = ( + np.mean( + np.fabs(V.data["Dust0_RHO"][istart:, 0, 0] - 1 / sol.y[0, :]) + + np.fabs(V.data["Dust1_RHO"][istart:, 0, 0] - 1 / sol.y[1, :]) + + np.fabs(V.data["Dust2_RHO"][istart:, 0, 0] - 1 / sol.y[2, :]) + ) + / 3 +) +print("Error=%e" % error) +if error < 3.6e-2: print("SUCCESS!") sys.exit(0) else: diff --git a/test/Dust/DustyShock/setup.cpp b/test/Dust/DustyShock/setup.cpp index f8632248a..7bf7d050e 100644 --- a/test/Dust/DustyShock/setup.cpp +++ b/test/Dust/DustyShock/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Dust/DustyShock/setup.cpp +// +// Last modified : 02/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/Dust/DustyShock/testme.json b/test/Dust/DustyShock/testme.json index d8ddad44f..25e225f93 100644 --- a/test/Dust/DustyShock/testme.json +++ b/test/Dust/DustyShock/testme.json @@ -1,11 +1,13 @@ { + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "reconstruction": 2, + "tolerance": 1e-14 + }, "variants": [ { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-implicit.ini"], - "noplot": true, - "reconstruction": 2, - "tolerance": 1e-14 + "ini": ["idefix.ini","idefix-implicit.ini"] } ] } diff --git a/test/Dust/DustyShock/testme.py b/test/Dust/DustyShock/testme.py index 622f34772..47692d3a4 100755 --- a/test/Dust/DustyShock/testme.py +++ b/test/Dust/DustyShock/testme.py @@ -1,39 +1,56 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Dust/DustyShock/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-implicit.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-implicit.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init: - test.makeReference(filename=name) - test.standardTest() - test.nonRegressionTest(filename=name,tolerance=1e-14) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init: + test.makeReference(filename=name) + test.standardTest() + test.nonRegressionTest(filename=name, tolerance=1e-14) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename=name) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name) + else: + testMe(test) else: - test.noplot = True - test.reconstruction=2 - testMe(test) + test.noplot = True + test.reconstruction = 2 + testMe(test) diff --git a/test/Dust/DustyWave/definitions.hpp b/test/Dust/DustyWave/definitions.hpp index cdbe23d6e..5160a2c98 100644 --- a/test/Dust/DustyWave/definitions.hpp +++ b/test/Dust/DustyWave/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Dust/DustyWave/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 1 #define DIMENSIONS 1 #define ISOTHERMAL diff --git a/test/Dust/DustyWave/python/testidefix.py b/test/Dust/DustyWave/python/testidefix.py index ad52d3306..ce2af493a 100755 --- a/test/Dust/DustyWave/python/testidefix.py +++ b/test/Dust/DustyWave/python/testidefix.py @@ -1,65 +1,83 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Dust/DustyWave/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- + """ Created on Mon Mar 13 14:45:58 2023 @author: lesurg """ -import sys -import numpy as np + import argparse +import sys + import matplotlib.pyplot as plt +import numpy as np parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() # solve eq. A6 in Riols & Lesur (2018) -cs=1.0 -chi=1.0 -kx=2.0*np.pi -taus=1.0 -poly=np.zeros(4,dtype=complex) -poly[0]=1 -poly[1]=1j/taus*(1+chi) -poly[2]=-kx**2*cs**2 -poly[3]=-1j*kx**2*cs**2/taus -sol=np.roots(poly) +cs = 1.0 +chi = 1.0 +kx = 2.0 * np.pi +taus = 1.0 +poly = np.zeros(4, dtype=complex) +poly[0] = 1 +poly[1] = 1j / taus * (1 + chi) +poly[2] = -(kx**2) * cs**2 +poly[3] = -1j * kx**2 * cs**2 / taus +sol = np.roots(poly) # Get the minimal decay rate (this should be the one that pops up) -tau=np.amax(np.imag(sol)) +tau = np.amax(np.imag(sol)) # load the dat file produced by the setup -raw=np.loadtxt('../timevol.dat',skiprows=1) -t=raw[:,0] -vx2=raw[:,1] -rho2=raw[:,2] +raw = np.loadtxt("../timevol.dat", skiprows=1) +t = raw[:, 0] +vx2 = raw[:, 1] +rho2 = raw[:, 2] -etot=vx2+rho2 +etot = vx2 + rho2 -if not(args.noplot): - plt.figure() - plt.semilogy(t,etot,label="idefix") - plt.semilogy(t,np.exp(2*tau*t)*etot[10],'--',label="theoretical decay rate") - plt.legend() - plt.xlabel("t") - plt.ylabel("Wave energy") - plt.show() +if not (args.noplot): + plt.figure() + plt.semilogy(t, etot, label="idefix") + plt.semilogy( + t, np.exp(2 * tau * t) * etot[10], "--", label="theoretical decay rate" + ) + plt.legend() + plt.xlabel("t") + plt.ylabel("Wave energy") + plt.show() # Compute decay rate: -tau_measured=t[-1]/(2*np.log(etot[-1]/etot[0])) +tau_measured = t[-1] / (2 * np.log(etot[-1] / etot[0])) # error on the decay rate: -error=np.abs((tau_measured-tau)/tau) +error = np.abs((tau_measured - tau) / tau) -print("error=%f"%error) -if(error<0.07): - print("Success!") +print("error=%f" % error) +if error < 0.07: + print("Success!") else: - print("Failure!") - sys.exit(1) + print("Failure!") + sys.exit(1) diff --git a/test/Dust/DustyWave/setup.cpp b/test/Dust/DustyWave/setup.cpp index 9cd5c66b9..ba4367058 100644 --- a/test/Dust/DustyWave/setup.cpp +++ b/test/Dust/DustyWave/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Dust/DustyWave/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/Dust/DustyWave/testme.json b/test/Dust/DustyWave/testme.json index 0050f364e..13309e266 100644 --- a/test/Dust/DustyWave/testme.json +++ b/test/Dust/DustyWave/testme.json @@ -1,12 +1,14 @@ { "namings": "ini", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "reconstruction": 2, + "tolerance": 1e-14 + }, "variants": [ { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-implicit.ini"], - "noplot": true, - "reconstruction": 2, - "tolerance": 1e-14 + "ini": ["idefix.ini","idefix-implicit.ini"] } ] } diff --git a/test/Dust/DustyWave/testme.py b/test/Dust/DustyWave/testme.py index 622f34772..8ca235fb5 100755 --- a/test/Dust/DustyWave/testme.py +++ b/test/Dust/DustyWave/testme.py @@ -1,39 +1,56 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Dust/DustyWave/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-implicit.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-implicit.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init: - test.makeReference(filename=name) - test.standardTest() - test.nonRegressionTest(filename=name,tolerance=1e-14) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init: + test.makeReference(filename=name) + test.standardTest() + test.nonRegressionTest(filename=name, tolerance=1e-14) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename=name) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name) + else: + testMe(test) else: - test.noplot = True - test.reconstruction=2 - testMe(test) + test.noplot = True + test.reconstruction = 2 + testMe(test) diff --git a/test/Dust/FargoPlanet/definitions.hpp b/test/Dust/FargoPlanet/definitions.hpp index deac509ae..c0de18420 100644 --- a/test/Dust/FargoPlanet/definitions.hpp +++ b/test/Dust/FargoPlanet/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Dust/FargoPlanet/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 2 diff --git a/test/Dust/FargoPlanet/setup.cpp b/test/Dust/FargoPlanet/setup.cpp index 8447efe0b..e2c115de6 100644 --- a/test/Dust/FargoPlanet/setup.cpp +++ b/test/Dust/FargoPlanet/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Dust/FargoPlanet/setup.cpp +// +// Last modified : 02/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2025) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include "idefix.hpp" #include "setup.hpp" diff --git a/test/Dust/StreamingInstability/definitions.hpp b/test/Dust/StreamingInstability/definitions.hpp index 486a4ea34..8bb8acd38 100644 --- a/test/Dust/StreamingInstability/definitions.hpp +++ b/test/Dust/StreamingInstability/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Dust/StreamingInstability/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 #define ISOTHERMAL diff --git a/test/Dust/StreamingInstability/setup.cpp b/test/Dust/StreamingInstability/setup.cpp index 410ab1349..339413292 100644 --- a/test/Dust/StreamingInstability/setup.cpp +++ b/test/Dust/StreamingInstability/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Dust/StreamingInstability/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/FargoPlanet/definitions.hpp b/test/HD/FargoPlanet/definitions.hpp index deac509ae..0112c0d36 100644 --- a/test/HD/FargoPlanet/definitions.hpp +++ b/test/HD/FargoPlanet/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/FargoPlanet/definitions.hpp +// +// Last modified : 03/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 2 diff --git a/test/HD/FargoPlanet/setup.cpp b/test/HD/FargoPlanet/setup.cpp index 314858bae..1fafd1e6d 100644 --- a/test/HD/FargoPlanet/setup.cpp +++ b/test/HD/FargoPlanet/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/FargoPlanet/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/FargoPlanet/testme.json b/test/HD/FargoPlanet/testme.json index e1d735828..4753035c3 100644 --- a/test/HD/FargoPlanet/testme.json +++ b/test/HD/FargoPlanet/testme.json @@ -1,15 +1,17 @@ { "namings": "ini,mpi", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "reconstruction": 2, + "single": false, + "dec": [2, 2], + "tolerance": 1e-13 + }, "variants": [ { - "dumpname": "dump.0001.dmp", "ini": ["idefix.ini", "idefix-rkl.ini"], - "noplot": true, - "reconstruction": 2, - "single": false, - "mpi": [false, true], - "dec": [2, 2], - "tolerance": 1e-13 + "mpi": [false, true] } ], "when": [ diff --git a/test/HD/FargoPlanet/testme.py b/test/HD/FargoPlanet/testme.py index b25a74bb0..74a13601c 100755 --- a/test/HD/FargoPlanet/testme.py +++ b/test/HD/FargoPlanet/testme.py @@ -1,47 +1,66 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/FargoPlanet/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -tolerance=1e-13 + +tolerance = 1e-13 + + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-rkl.ini"] - mytol=tolerance - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") - if ini == "idefix-rkl.ini": - mytol = 1e-12 - else: - mytol = tolerance - test.standardTest() - test.nonRegressionTest(filename="dump.0001.dmp",tolerance=mytol) + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-rkl.ini"] + mytol = tolerance + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") + if ini == "idefix-rkl.ini": + mytol = 1e-12 + else: + mytol = tolerance + test.standardTest() + test.nonRegressionTest(filename="dump.0001.dmp", tolerance=mytol) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2'] + test.dec = ["2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp",tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp", tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - - test.mpi=True - testMe(test) + test.noplot = True + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + + test.mpi = True + testMe(test) diff --git a/test/HD/KHI/definitions.hpp b/test/HD/KHI/definitions.hpp index 4c88d3387..631ec410d 100644 --- a/test/HD/KHI/definitions.hpp +++ b/test/HD/KHI/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/KHI/definitions.hpp +// +// Last modified : 02/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 2 #define ISOTHERMAL diff --git a/test/HD/KHI/setup.cpp b/test/HD/KHI/setup.cpp index fb6f35c28..0e797e44f 100644 --- a/test/HD/KHI/setup.cpp +++ b/test/HD/KHI/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/KHI/setup.cpp +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/MachReflection/definitions.hpp b/test/HD/MachReflection/definitions.hpp index 69f0c49e9..bfe306841 100644 --- a/test/HD/MachReflection/definitions.hpp +++ b/test/HD/MachReflection/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/MachReflection/definitions.hpp +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 2 diff --git a/test/HD/MachReflection/setup.cpp b/test/HD/MachReflection/setup.cpp index 7d7f2c55d..175ef4050 100644 --- a/test/HD/MachReflection/setup.cpp +++ b/test/HD/MachReflection/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/MachReflection/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/MachReflection/testme.json b/test/HD/MachReflection/testme.json index be2d8d950..c701471f3 100644 --- a/test/HD/MachReflection/testme.json +++ b/test/HD/MachReflection/testme.json @@ -1,15 +1,17 @@ { "namings": "ini,mpi", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "reconstruction": 2, + "single": false, + "dec": [2, 2], + "tolerance": 0 + }, "variants": [ { - "dumpname": "dump.0001.dmp", "ini": ["idefix.ini","idefix-hll.ini","idefix-hllc.ini","idefix-tvdlf.ini"], - "noplot": true, - "reconstruction": 2, - "single": false, - "mpi": [false, true], - "dec": [2, 2], - "tolerance": 0 + "mpi": [false, true] } ] } diff --git a/test/HD/MachReflection/testme.py b/test/HD/MachReflection/testme.py index 7e6121815..af210e660 100755 --- a/test/HD/MachReflection/testme.py +++ b/test/HD/MachReflection/testme.py @@ -1,43 +1,60 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/MachReflection/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-hll.ini","idefix-hllc.ini","idefix-tvdlf.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-hll.ini", "idefix-hllc.ini", "idefix-tvdlf.ini"] - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") - test.standardTest() - test.nonRegressionTest(filename="dump.0001.dmp") + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") + test.standardTest() + test.nonRegressionTest(filename="dump.0001.dmp") -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2'] + test.dec = ["2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp") - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp") + else: + testMe(test) else: - test.noplot = True - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - - test.mpi=True - testMe(test) + test.noplot = True + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + + test.mpi = True + testMe(test) diff --git a/test/HD/RWI-cavity/definitions.hpp b/test/HD/RWI-cavity/definitions.hpp index e97456095..40995d0e4 100644 --- a/test/HD/RWI-cavity/definitions.hpp +++ b/test/HD/RWI-cavity/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/RWI-cavity/definitions.hpp +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 2 diff --git a/test/HD/RWI-cavity/setup.cpp b/test/HD/RWI-cavity/setup.cpp index 726690e68..8baf68eff 100644 --- a/test/HD/RWI-cavity/setup.cpp +++ b/test/HD/RWI-cavity/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/RWI-cavity/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2022) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/SedovBlastWave/definitions-spherical.hpp b/test/HD/SedovBlastWave/definitions-spherical.hpp index 53b4f38e3..f2b4f579a 100644 --- a/test/HD/SedovBlastWave/definitions-spherical.hpp +++ b/test/HD/SedovBlastWave/definitions-spherical.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/SedovBlastWave/definitions-spherical.hpp +// +// Last modified : 10/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/HD/SedovBlastWave/definitions-unequal.hpp b/test/HD/SedovBlastWave/definitions-unequal.hpp index 3b581bd62..465d7f0c9 100644 --- a/test/HD/SedovBlastWave/definitions-unequal.hpp +++ b/test/HD/SedovBlastWave/definitions-unequal.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/SedovBlastWave/definitions-unequal.hpp +// +// Last modified : 08/2023 +// +// Copyright(C) by : +// - Alankar Dutta (MPA Garching - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/HD/SedovBlastWave/definitions.hpp b/test/HD/SedovBlastWave/definitions.hpp index 3b581bd62..57b411d3b 100644 --- a/test/HD/SedovBlastWave/definitions.hpp +++ b/test/HD/SedovBlastWave/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/SedovBlastWave/definitions.hpp +// +// Last modified : 10/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/HD/SedovBlastWave/python/1Dsolution/definitions.hpp b/test/HD/SedovBlastWave/python/1Dsolution/definitions.hpp index 3349b3ae7..9cb5b4604 100644 --- a/test/HD/SedovBlastWave/python/1Dsolution/definitions.hpp +++ b/test/HD/SedovBlastWave/python/1Dsolution/definitions.hpp @@ -1,3 +1,16 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/SedovBlastWave/python/1Dsolution/definitions.hpp +// +// Last modified : 10/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** #define COMPONENTS 1 #define DIMENSIONS 1 diff --git a/test/HD/SedovBlastWave/python/1Dsolution/setup.cpp b/test/HD/SedovBlastWave/python/1Dsolution/setup.cpp index 043fe5349..904525049 100644 --- a/test/HD/SedovBlastWave/python/1Dsolution/setup.cpp +++ b/test/HD/SedovBlastWave/python/1Dsolution/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/SedovBlastWave/python/1Dsolution/setup.cpp +// +// Last modified : 10/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/SedovBlastWave/python/testidefix.py b/test/HD/SedovBlastWave/python/testidefix.py index a78bc88e5..119fe9c15 100755 --- a/test/HD/SedovBlastWave/python/testidefix.py +++ b/test/HD/SedovBlastWave/python/testidefix.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/SedovBlastWave/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- + """ Created on Thu Mar 5 11:29:41 2020 @@ -8,71 +23,72 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK import argparse -import numpy as np + import matplotlib.pyplot as plt +import numpy as np from scipy.interpolate import interp1d -parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +from pytools.vtk_io import readVTK +parser = argparse.ArgumentParser() +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() -V=readVTK('../data.0001.vtk') -R=readVTK('1Dsolution/1Dsolution.vtk') +args, unknown = parser.parse_known_args() +V = readVTK("../data.0001.vtk") +R = readVTK("1Dsolution/1Dsolution.vtk") # Finally, let's plot solutions -p = R.data['PRS'][:,0,0] -x= R.r +p = R.data["PRS"][:, 0, 0] +x = R.r -if V.geometry=="cartesian": - [x3D, y3D, z3D]= np.meshgrid(V.x,V.y,V.z,indexing='ij') +if V.geometry == "cartesian": + [x3D, y3D, z3D] = np.meshgrid(V.x, V.y, V.z, indexing="ij") -elif V.geometry=="spherical": - [r, theta, phi] = np.meshgrid(V.r,V.theta,V.phi,indexing='ij') - x0=0.1 - y0=0 - z0=1.0 +elif V.geometry == "spherical": + [r, theta, phi] = np.meshgrid(V.r, V.theta, V.phi, indexing="ij") + x0 = 0.1 + y0 = 0 + z0 = 1.0 - x3D=r*np.sin(theta)*np.cos(phi)-x0 - y3D=r*np.sin(theta)*np.sin(phi)-y0 - z3D=r*np.cos(theta)-z0 + x3D = r * np.sin(theta) * np.cos(phi) - x0 + y3D = r * np.sin(theta) * np.sin(phi) - y0 + z3D = r * np.cos(theta) - z0 else: - print("Unknown geometry "+V.geometry) - sys.exit(1) + print("Unknown geometry " + V.geometry) + sys.exit(1) -r3D=np.sqrt(x3D**2+y3D**2+z3D**2).flatten() -p3D=V.data['PRS'].flatten() +r3D = np.sqrt(x3D**2 + y3D**2 + z3D**2).flatten() +p3D = V.data["PRS"].flatten() -index=np.argwhere((r3D>0.4) & (r3D<0.458)) +index = np.argwhere((r3D > 0.4) & (r3D < 0.458)) -solinterp=interp1d(x,p) +solinterp = interp1d(x, p) -if(not args.noplot): +if not args.noplot: plt.figure(1) - plt.plot(r3D.flatten(),p3D.flatten(),'+',markersize=2) - plt.plot(x,p) - plt.title('Pressure') + plt.plot(r3D.flatten(), p3D.flatten(), "+", markersize=2) + plt.plot(x, p) + plt.title("Pressure") plt.ioff() plt.show() -error=np.mean(np.fabs(p3D[index]-solinterp(r3D[index]))) -print("Error=%e"%error) +error = np.mean(np.fabs(p3D[index] - solinterp(r3D[index]))) +print("Error=%e" % error) erroref = 7.7e-2 if V.geometry == "spherical": erroref = 1.9e-1 -if error (IPAG/UGA/CNRS - 2022 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/SedovBlastWave/testme.json b/test/HD/SedovBlastWave/testme.json index 11327598b..ba77c4b7e 100644 --- a/test/HD/SedovBlastWave/testme.json +++ b/test/HD/SedovBlastWave/testme.json @@ -1,28 +1,23 @@ { "namings": "definitionFile,ini", + "default": { + "dumpname": "dump.0001.dmp", + "vectPot": false, + "reconstruction": 2, + "single": false, + "mpi": true, + "dec": [2, 2, 2 ], + "standardTest": false, + "nonRegressionTest": false, + "tolerance": 0 + }, "variants": [ { - "dumpname": "dump.0001.dmp", "definitionFile": "definitions.hpp", - "ini": ["idefix.ini"], - "vectPot": false, - "reconstruction": 2, - "single": false, - "mpi": true, - "dec": [2, 2, 2 ], - "standardTest": false, - "tolerance": 0 + "ini": ["idefix.ini"] },{ - "dumpname": "dump.0001.dmp", "definitionFile": "definitions-spherical.hpp", - "ini": ["idefix-spherical.ini"], - "vectPot": false, - "reconstruction": 2, - "single": false, - "mpi": true, - "dec": [2, 2, 2 ], - "standardTest": false, - "tolerance": 0 + "ini": ["idefix-spherical.ini"] } ] } diff --git a/test/HD/SedovBlastWave/testme.py b/test/HD/SedovBlastWave/testme.py index c3ef7025f..4f7055850 100755 --- a/test/HD/SedovBlastWave/testme.py +++ b/test/HD/SedovBlastWave/testme.py @@ -1,37 +1,53 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/SedovBlastWave/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2','2'] + test.dec = ["2", "2", "2"] if test.check: - test.standardTest() + test.standardTest() else: - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=True - # Cartesian validation - test.configure(definitionFile="definitions.hpp") - test.compile() - test.run(inputFile="idefix.ini") - test.standardTest() - - #Spherical validation - test.configure(definitionFile="definitions-spherical.hpp") - test.compile() - test.run(inputFile="idefix-spherical.ini") - test.standardTest() + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = True + # Cartesian validation + test.configure(definitionFile="definitions.hpp") + test.compile() + test.run(inputFile="idefix.ini") + test.standardTest() + + # Spherical validation + test.configure(definitionFile="definitions-spherical.hpp") + test.compile() + test.run(inputFile="idefix-spherical.ini") + test.standardTest() diff --git a/test/HD/ShearingBox/CMakeLists.txt b/test/HD/ShearingBox/CMakeLists.txt index f4b25bfde..9b5f5c3d6 100644 --- a/test/HD/ShearingBox/CMakeLists.txt +++ b/test/HD/ShearingBox/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/ShearingBox/CMakeLists.txt +# +# Last modified : 10/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # add specific source file to idefix build tree add_idefix_source(analysis.cpp) add_idefix_source(analysis.hpp) diff --git a/test/HD/ShearingBox/analysis.cpp b/test/HD/ShearingBox/analysis.cpp index dacf2a70c..d01c58a24 100644 --- a/test/HD/ShearingBox/analysis.cpp +++ b/test/HD/ShearingBox/analysis.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/ShearingBox/analysis.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "analysis.hpp" #include "idefix.hpp" #include "fluid.hpp" diff --git a/test/HD/ShearingBox/analysis.hpp b/test/HD/ShearingBox/analysis.hpp index 8b65c4317..1634a6329 100644 --- a/test/HD/ShearingBox/analysis.hpp +++ b/test/HD/ShearingBox/analysis.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/ShearingBox/analysis.hpp +// +// Last modified : 06/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #ifndef ANALYSIS_HPP_ #define ANALYSIS_HPP_ diff --git a/test/HD/ShearingBox/definitions.hpp b/test/HD/ShearingBox/definitions.hpp index 3b581bd62..592f215ec 100644 --- a/test/HD/ShearingBox/definitions.hpp +++ b/test/HD/ShearingBox/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/ShearingBox/definitions.hpp +// +// Last modified : 06/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/HD/ShearingBox/python/testidefix.py b/test/HD/ShearingBox/python/testidefix.py index 1a0c2509a..14da6db86 100755 --- a/test/HD/ShearingBox/python/testidefix.py +++ b/test/HD/ShearingBox/python/testidefix.py @@ -1,115 +1,139 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/ShearingBox/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- + """ Created on Mon Jun 21 15:42:19 2021 @author: lesurg """ + +import argparse import sys -import numpy as np + import matplotlib.pyplot as plt +import numpy as np from scipy.integrate import solve_ivp -import argparse -#compute theoretical solution (from Balbus & Hawley 2006, using notations from Lesur 2021) + +# compute theoretical solution (from Balbus & Hawley 2006, using notations from Lesur 2021) def rhs(t, y, Omega, q, k0x, k0y, k0z): - kx = k0x + q*Omega * t * k0y + kx = k0x + q * Omega * t * k0y ky = k0y kz = k0z - k2 = kx*kx+ky*ky+kz*kz + k2 = kx * kx + ky * ky + kz * kz vx = y[0] vy = y[1] - #vz = y[2] + # vz = y[2] + gxx = kx * kx / k2 + gxy = kx * ky / k2 + gyy = ky * ky / k2 + gyz = ky * kz / k2 + gxz = kx * kz / k2 + # gzz = kz*kz/k2 - gxx = kx*kx/k2 - gxy = kx*ky/k2 - gyy = ky*ky/k2 - gyz = ky*kz/k2 - gxz = kx*kz/k2 - #gzz = kz*kz/k2 + dvx = 2 * Omega * vy * (1 - gxx) + 2 * (1 - q) * Omega * gxy * vx + dvy = ( + -q * Omega * vx * gyy - (2 - q) * Omega * (1 - gyy) * vx - 2 * Omega * vy * gxy + ) + dvz = +2 * (1 - q) * Omega * vx * gyz - 2 * Omega * vy * gxz - dvx = 2*Omega*vy*(1-gxx) + 2*(1-q)*Omega*gxy*vx - dvy = - q*Omega*vx*gyy - (2-q)*Omega*(1-gyy)*vx - 2*Omega*vy*gxy - dvz= +2*(1-q)*Omega*vx*gyz-2*Omega*vy*gxz + return np.asarray([dvx, dvy, dvz]) - return np.asarray([dvx,dvy,dvz]) parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() -#initial condition: vr=1, rest is 0, mode initial is nx=0, ny=1, nz=4) -y=solve_ivp(rhs, [0,30], [1, 0, 0], args=(1, 1.5, 0, 2.0*np.pi, 8*np.pi), dense_output=True) +# initial condition: vr=1, rest is 0, mode initial is nx=0, ny=1, nz=4) +y = solve_ivp( + rhs, [0, 30], [1, 0, 0], args=(1, 1.5, 0, 2.0 * np.pi, 8 * np.pi), dense_output=True +) # read timevol file rep = "../" filename = "timevol.dat" -fid=open(rep+filename,"r") +fid = open(rep + filename, "r") -gamma=5/3 +gamma = 5 / 3 # read the first line to get data names -varnames=fid.readline().split() +varnames = fid.readline().split() fid.close() # load the bulk of the file -data=np.loadtxt(rep+filename,skiprows=1) +data = np.loadtxt(rep + filename, skiprows=1) # store this in our data structure -V={} +V = {} -i=0 +i = 0 for name in varnames: - V[name]=data[:,i] - i=i+1 + V[name] = data[:, i] + i = i + 1 # velocity normalisation -v0=V['vx'][0] +v0 = V["vx"][0] # compute L2 error norm -error=np.sqrt((V['vx']/v0-y.sol(V["t"])[0,:])**2 + (V['vy']/v0-y.sol(V["t"])[1,:])**2+ + (V['vz']/v0-y.sol(V["t"])[2,:])**2) - - - -if(not args.noplot): - # Comparison with exact solution - plt.rc('text', usetex=True) - plt.rc('font', family='serif') - plt.rc('font', size=16) - plt.close('all') - plt.figure(1) - plt.plot(V["t"],V['vx']/v0,'r-',label=r'$u_{R}$') - plt.plot(V["t"],y.sol(V["t"])[0,:],'r--') - plt.plot(V["t"],V['vy']/v0,'b-',label=r'$u_{\varphi}$') - plt.plot(V["t"],y.sol(V["t"])[1,:],'b--') - plt.plot(V["t"],V['vz']/v0,'g-',label=r'$u_{z}$') - plt.plot(V["t"],y.sol(V["t"])[2,:],'g--') - plt.legend() - plt.xlabel('t') - - # plot error - plt.figure() - plt.semilogy(V["t"],error) - plt.xlim([0,10]) - plt.ylim([1e-3,1]) - - plt.ioff() - plt.show() - -err=np.mean(error) -print("Error=",err) - -if(err<0.06): - print("SUCCESS") - sys.exit(0) +error = np.sqrt( + (V["vx"] / v0 - y.sol(V["t"])[0, :]) ** 2 + + (V["vy"] / v0 - y.sol(V["t"])[1, :]) ** 2 + + (V["vz"] / v0 - y.sol(V["t"])[2, :]) ** 2 +) + + +if not args.noplot: + # Comparison with exact solution + plt.rc("text", usetex=True) + plt.rc("font", family="serif") + plt.rc("font", size=16) + plt.close("all") + plt.figure(1) + plt.plot(V["t"], V["vx"] / v0, "r-", label=r"$u_{R}$") + plt.plot(V["t"], y.sol(V["t"])[0, :], "r--") + plt.plot(V["t"], V["vy"] / v0, "b-", label=r"$u_{\varphi}$") + plt.plot(V["t"], y.sol(V["t"])[1, :], "b--") + plt.plot(V["t"], V["vz"] / v0, "g-", label=r"$u_{z}$") + plt.plot(V["t"], y.sol(V["t"])[2, :], "g--") + plt.legend() + plt.xlabel("t") + + # plot error + plt.figure() + plt.semilogy(V["t"], error) + plt.xlim([0, 10]) + plt.ylim([1e-3, 1]) + + plt.ioff() + plt.show() + +err = np.mean(error) +print("Error=", err) + +if err < 0.06: + print("SUCCESS") + sys.exit(0) else: - print("FAILED") - sys.exit(1) + print("FAILED") + sys.exit(1) diff --git a/test/HD/ShearingBox/setup.cpp b/test/HD/ShearingBox/setup.cpp index e82701d0c..0be990299 100644 --- a/test/HD/ShearingBox/setup.cpp +++ b/test/HD/ShearingBox/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/ShearingBox/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" #include "analysis.hpp" diff --git a/test/HD/ShearingBox/testme.json b/test/HD/ShearingBox/testme.json index 3e473d0ba..b492bec19 100644 --- a/test/HD/ShearingBox/testme.json +++ b/test/HD/ShearingBox/testme.json @@ -1,15 +1,17 @@ { - "namings": "ini", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-fargo.ini"], - "noplot": true, - "reconstruction": 2, - "single": false, - "mpi": false, - "dec": ["2","1","2"], - "tolerance": 1e-15 - } - ] + "namings": "ini", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "reconstruction": 2, + "single": false, + "mpi": false, + "dec": [2,1,2], + "tolerance": 1e-15 + }, + "variants": [ + { + "ini": ["idefix.ini","idefix-fargo.ini"] + } + ] } diff --git a/test/HD/ShearingBox/testme.py b/test/HD/ShearingBox/testme.py index 18c792656..445f28218 100755 --- a/test/HD/ShearingBox/testme.py +++ b/test/HD/ShearingBox/testme.py @@ -1,40 +1,59 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/ShearingBox/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -tolerance=1e-15 + +tolerance = 1e-15 + + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-fargo.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-fargo.ini"] - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") - test.standardTest() - test.nonRegressionTest(filename="dump.0001.dmp",tolerance=tolerance) + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") + test.standardTest() + test.nonRegressionTest(filename="dump.0001.dmp", tolerance=tolerance) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','1','2'] + test.dec = ["2", "1", "2"] if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp",tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp", tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) + test.noplot = True + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) diff --git a/test/HD/VSI/definitions.hpp b/test/HD/VSI/definitions.hpp index 016442642..2fb48ee23 100644 --- a/test/HD/VSI/definitions.hpp +++ b/test/HD/VSI/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/VSI/definitions.hpp +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 2 diff --git a/test/HD/VSI/setup.cpp b/test/HD/VSI/setup.cpp index 19800e67d..e048dfc10 100644 --- a/test/HD/VSI/setup.cpp +++ b/test/HD/VSI/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/VSI/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/ViscousDisk/definitions.hpp b/test/HD/ViscousDisk/definitions.hpp index 016442642..97bf72ccb 100644 --- a/test/HD/ViscousDisk/definitions.hpp +++ b/test/HD/ViscousDisk/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/ViscousDisk/definitions.hpp +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 2 diff --git a/test/HD/ViscousDisk/python/testidefix.py b/test/HD/ViscousDisk/python/testidefix.py index 39e3666e1..d5309031a 100755 --- a/test/HD/ViscousDisk/python/testidefix.py +++ b/test/HD/ViscousDisk/python/testidefix.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/ViscousDisk/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# - Clément Robert (IPAG/UGA/CNRS - 2021 - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Thu Mar 5 11:29:41 2020 @@ -8,89 +22,95 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK -import numpy as np import argparse + import matplotlib.pyplot as plt +import numpy as np + +from pytools.vtk_io import readVTK parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() -V=readVTK('../data.0001.vtk', geometry='spherical') +V = readVTK("../data.0001.vtk", geometry="spherical") -iref=32 -alpha=0.002 -epsilon=0.1 +iref = 32 +alpha = 0.002 +epsilon = 0.1 # q and p following Fromang+2011 -q=-1 -p=-1.5 +q = -1 +p = -1.5 -vr=V.data['VX1'][iref,:,0] -vphi=V.data['VX3'][iref,:,0] -r=V.r[iref] -R=V.r[iref]*np.sin(V.theta) -Z=V.r[iref]*np.cos(V.theta) +vr = V.data["VX1"][iref, :, 0] +vphi = V.data["VX3"][iref, :, 0] +r = V.r[iref] +R = V.r[iref] * np.sin(V.theta) +Z = V.r[iref] * np.cos(V.theta) -Zh=Z/(epsilon*R) +Zh = Z / (epsilon * R) # Theoretical profile -ur=-alpha*epsilon**2*R**(q+1/2)*(3*p+2*q+6+(5*q+9)/2*Zh**2) -#uphi=R**(-0.5)*(1+1/2*epsilon**2*(p+q+q/2*Zh**2)) -uphi=R**(-0.5)*(R/r-2.5*epsilon*epsilon)**0.5 +ur = ( + -alpha + * epsilon**2 + * R ** (q + 1 / 2) + * (3 * p + 2 * q + 6 + (5 * q + 9) / 2 * Zh**2) +) +# uphi=R**(-0.5)*(1+1/2*epsilon**2*(p+q+q/2*Zh**2)) +uphi = R ** (-0.5) * (R / r - 2.5 * epsilon * epsilon) ** 0.5 # Compute error on accretion speed -error=np.mean(np.fabs(ur-vr))/np.max(np.fabs(ur)) +error = np.mean(np.fabs(ur - vr)) / np.max(np.fabs(ur)) -if(not args.noplot): +if not args.noplot: plt.figure() - plt.plot(Zh,vr,label='run') - plt.plot(Zh,ur,label='theoretical') - plt.xlabel('Z/h') - plt.ylabel('Vr') + plt.plot(Zh, vr, label="run") + plt.plot(Zh, ur, label="theoretical") + plt.xlabel("Z/h") + plt.ylabel("Vr") plt.legend() plt.figure() - plt.plot(Zh,vphi,label='run') - plt.plot(Zh,uphi,label='theoretical') - plt.xlabel('Z/h') - plt.ylabel('Vphi') + plt.plot(Zh, vphi, label="run") + plt.plot(Zh, uphi, label="theoretical") + plt.xlabel("Z/h") + plt.ylabel("Vphi") plt.legend() # check radial equibrium - n=V.theta.size//2 - rhomid=V.data['RHO'][:,n,0] - R=V.r*np.sin(V.theta[n]) - cs=epsilon*R**(-0.5) - Pmid=rhomid*cs*cs - Vmid=V.data['VX3'][:,n,0] - dV2=(Vmid**2-V.r**(-1))/R*rhomid - dP=(Pmid[2:]-Pmid[:-2])/(V.r[2]-V.r[0]) + n = V.theta.size // 2 + rhomid = V.data["RHO"][:, n, 0] + R = V.r * np.sin(V.theta[n]) + cs = epsilon * R ** (-0.5) + Pmid = rhomid * cs * cs + Vmid = V.data["VX3"][:, n, 0] + dV2 = (Vmid**2 - V.r ** (-1)) / R * rhomid + dP = (Pmid[2:] - Pmid[:-2]) / (V.r[2] - V.r[0]) plt.figure() - plt.plot(V.r[1:-1],dP,label="$d_r P$") - plt.plot(V.r,dV2,label="$(V^2-V_K^2)/R$") + plt.plot(V.r[1:-1], dP, label="$d_r P$") + plt.plot(V.r, dV2, label="$(V^2-V_K^2)/R$") plt.legend() - plt.xlabel('R') - plt.ylabel('Radial forces in the midplane') + plt.xlabel("R") + plt.ylabel("Radial forces in the midplane") plt.show() -#plt.figure() -#plt.plot(V.r,rhomid,V.r,R**(-1.5)) - +# plt.figure() +# plt.plot(V.r,rhomid,V.r,R**(-1.5)) -print("Error=%e"%error) -if error<1.1e-2: +print("Error=%e" % error) +if error < 1.1e-2: print("SUCCESS!") sys.exit(0) else: diff --git a/test/HD/ViscousDisk/setup.cpp b/test/HD/ViscousDisk/setup.cpp index 826b0dc9d..f03e6cb81 100644 --- a/test/HD/ViscousDisk/setup.cpp +++ b/test/HD/ViscousDisk/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/ViscousDisk/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/ViscousDisk/testme.json b/test/HD/ViscousDisk/testme.json index df8c19d86..6cba24198 100644 --- a/test/HD/ViscousDisk/testme.json +++ b/test/HD/ViscousDisk/testme.json @@ -1,15 +1,17 @@ { - "namings": "ini", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-rkl.ini"], - "noplot": true, - "reconstruction": 2, - "single": false, - "mpi": false, - "dec": ["2","1","2"], - "tolerance": 3e-15 - } - ] + "namings": "ini", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "reconstruction": 2, + "single": false, + "mpi": false, + "dec": [2,1,2], + "tolerance": 3e-15 + }, + "variants": [ + { + "ini": ["idefix.ini","idefix-rkl.ini"] + } + ] } diff --git a/test/HD/ViscousDisk/testme.py b/test/HD/ViscousDisk/testme.py index 34628fd80..8706b335a 100755 --- a/test/HD/ViscousDisk/testme.py +++ b/test/HD/ViscousDisk/testme.py @@ -1,41 +1,60 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/ViscousDisk/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -tolerance=3e-15 + +tolerance = 3e-15 + + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-rkl.ini"] - for ini in inifiles: - mytol=tolerance + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-rkl.ini"] + for ini in inifiles: + mytol = tolerance - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") - test.standardTest() - test.nonRegressionTest(filename="dump.0001.dmp",tolerance=mytol) + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") + test.standardTest() + test.nonRegressionTest(filename="dump.0001.dmp", tolerance=mytol) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2'] + test.dec = ["2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp",tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp", tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) + test.noplot = True + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) diff --git a/test/HD/ViscousFlowPastCylinder/definitions.hpp b/test/HD/ViscousFlowPastCylinder/definitions.hpp index 381b71f77..5f296e097 100644 --- a/test/HD/ViscousFlowPastCylinder/definitions.hpp +++ b/test/HD/ViscousFlowPastCylinder/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/ViscousFlowPastCylinder/definitions.hpp +// +// Last modified : 12/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 2 #define ISOTHERMAL diff --git a/test/HD/ViscousFlowPastCylinder/setup.cpp b/test/HD/ViscousFlowPastCylinder/setup.cpp index 1282ac0ce..0cddac102 100644 --- a/test/HD/ViscousFlowPastCylinder/setup.cpp +++ b/test/HD/ViscousFlowPastCylinder/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/ViscousFlowPastCylinder/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/ViscousFlowPastCylinder/testme.json b/test/HD/ViscousFlowPastCylinder/testme.json index 7b3763436..2fb79fda3 100644 --- a/test/HD/ViscousFlowPastCylinder/testme.json +++ b/test/HD/ViscousFlowPastCylinder/testme.json @@ -1,23 +1,25 @@ { - "namings": "ini,mpi", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-rkl.ini"], - "noplot": true, - "reconstruction": 2, - "single": false, - "mpi": [false, true], - "dec": ["2","2"], - "tolerance": 3e-14 - } - ], - "when": { - "conditions": { - "ini": "idefix-rkl.ini" - }, - "apply": { - "tolerance": 1e-8 - } + "namings": "ini,mpi", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "reconstruction": 2, + "single": false, + "dec": [2,2], + "tolerance": 3e-14 + }, + "variants": [ + { + "ini": ["idefix.ini","idefix-rkl.ini"], + "mpi": [false, true] } + ], + "when": { + "conditions": { + "ini": "idefix-rkl.ini" + }, + "apply": { + "tolerance": 1e-8 + } + } } diff --git a/test/HD/ViscousFlowPastCylinder/testme.py b/test/HD/ViscousFlowPastCylinder/testme.py index 832a80e56..cd0b0c90e 100755 --- a/test/HD/ViscousFlowPastCylinder/testme.py +++ b/test/HD/ViscousFlowPastCylinder/testme.py @@ -1,47 +1,66 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/ViscousFlowPastCylinder/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -tolerance=3e-14 + +tolerance = 3e-14 + + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-rkl.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-rkl.ini"] - for ini in inifiles: - test.run(inputFile=ini) - mytol=tolerance - if ini=="idefix-rkl.ini": - mytol=1e-8 + for ini in inifiles: + test.run(inputFile=ini) + mytol = tolerance + if ini == "idefix-rkl.ini": + mytol = 1e-8 - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") - test.standardTest() - test.nonRegressionTest(filename="dump.0001.dmp",tolerance=mytol) + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") + test.standardTest() + test.nonRegressionTest(filename="dump.0001.dmp", tolerance=mytol) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2'] + test.dec = ["2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp",tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp", tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - - test.mpi=True - testMe(test) + test.noplot = True + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + + test.mpi = True + testMe(test) diff --git a/test/HD/sod-iso/definitions.hpp b/test/HD/sod-iso/definitions.hpp index cdbe23d6e..fb40286e0 100644 --- a/test/HD/sod-iso/definitions.hpp +++ b/test/HD/sod-iso/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/sod-iso/definitions.hpp +// +// Last modified : 10/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 1 #define DIMENSIONS 1 #define ISOTHERMAL diff --git a/test/HD/sod-iso/python/testidefix.py b/test/HD/sod-iso/python/testidefix.py index ec91c63eb..d02f373c9 100755 --- a/test/HD/sod-iso/python/testidefix.py +++ b/test/HD/sod-iso/python/testidefix.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/sod-iso/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +# - Clément Robert (IPAG/UGA/CNRS - 2021 - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- + """ Created on Thu Mar 5 11:29:41 2020 @@ -8,24 +23,26 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK -from pytools import sod import argparse -import numpy as np + import matplotlib.pyplot as plt +import numpy as np from scipy.interpolate import interp1d +from pytools import sod +from pytools.vtk_io import readVTK + parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() -V=readVTK('../data.0002.vtk', geometry='cartesian') +V = readVTK("../data.0002.vtk", geometry="cartesian") gamma = 1.00000000001 npts = 5000 @@ -35,40 +52,44 @@ # t is the time evolution for which positions and states in tube should be calculated # gamma denotes specific heat # note that gamma and npts are default parameters (1.4 and 500) in solve function -positions, regions, values = sod.solve(left_state=(1, 1, 0), right_state=(0.125, 0.125, 0.), - geometry=(0., 1., 0.5), t=0.2, gamma=gamma, npts=npts) +positions, regions, values = sod.solve( + left_state=(1, 1, 0), + right_state=(0.125, 0.125, 0.0), + geometry=(0.0, 1.0, 0.5), + t=0.2, + gamma=gamma, + npts=npts, +) # Finally, let's plot solutions -p = values['p'] -rho = values['rho'] -u = values['u'] -x= values['x'] - - -solinterp=interp1d(x,u) +p = values["p"] +rho = values["rho"] +u = values["u"] +x = values["x"] -error=np.mean(np.fabs((V.data['VX1'][:,0,0]-solinterp(V.x)))) +solinterp = interp1d(x, u) +error = np.mean(np.fabs((V.data["VX1"][:, 0, 0] - solinterp(V.x)))) -if(not args.noplot): +if not args.noplot: plt.figure(1) - plt.plot(x,rho) - plt.plot(V.x,V.data['RHO'][:,0,0],'+',markersize=2) - plt.title('Density') + plt.plot(x, rho) + plt.plot(V.x, V.data["RHO"][:, 0, 0], "+", markersize=2) + plt.title("Density") plt.figure(2) - plt.plot(x,u) - plt.plot(V.x,V.data['VX1'][:,0,0],'+',markersize=2) - plt.title('Velocity') + plt.plot(x, u) + plt.plot(V.x, V.data["VX1"][:, 0, 0], "+", markersize=2) + plt.title("Velocity") plt.ioff() plt.show() -print("Error=%e"%error) -if error<5e-3: +print("Error=%e" % error) +if error < 5e-3: print("SUCCESS!") sys.exit(0) else: diff --git a/test/HD/sod-iso/setup.cpp b/test/HD/sod-iso/setup.cpp index a32365569..b62089615 100644 --- a/test/HD/sod-iso/setup.cpp +++ b/test/HD/sod-iso/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/sod-iso/setup.cpp +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2021) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/sod-iso/testme.json b/test/HD/sod-iso/testme.json index 5016415d6..480bc50d3 100644 --- a/test/HD/sod-iso/testme.json +++ b/test/HD/sod-iso/testme.json @@ -1,33 +1,25 @@ { - "namings": "ini,single,reconstruction", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-hll.ini","idefix-hllc.ini","idefix-tvdlf.ini"], - "vectPot": false, - "noplot": true, - "reconstruction": [2, 3], - "single": [false], - "mpi": false, - "tolerance": 0 - },{ - "dumpname": "dump.0001.dmp", - "ini": ["idefix-rk3.ini","idefix-hllc-rk3.ini"], - "vectPot": false, - "noplot": true, - "reconstruction": [4], - "single": [false], - "mpi": false, - "tolerance": 0 - },{ - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-hll.ini","idefix-hllc.ini","idefix-tvdlf.ini"], - "vectPot": false, - "noplot": true, - "reconstruction": [2], - "single": [true], - "mpi": false, - "tolerance": 0 - } - ] + "namings": "ini,single,reconstruction", + "default": { + "dumpname": "dump.0001.dmp", + "mpi": false, + "vectPot": false, + "noplot": true, + "tolerance": 0 + }, + "variants": [ + { + "ini": ["idefix.ini","idefix-hll.ini","idefix-hllc.ini","idefix-tvdlf.ini"], + "reconstruction": [2, 3], + "single": [false] + },{ + "ini": ["idefix-rk3.ini","idefix-hllc-rk3.ini"], + "reconstruction": [4], + "single": [false] + },{ + "ini": ["idefix.ini","idefix-hll.ini","idefix-hllc.ini","idefix-tvdlf.ini"], + "reconstruction": [2], + "single": [true] + } + ] } diff --git a/test/HD/sod-iso/testme.py b/test/HD/sod-iso/testme.py index 109109baf..96a194b3c 100755 --- a/test/HD/sod-iso/testme.py +++ b/test/HD/sod-iso/testme.py @@ -1,50 +1,67 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/sod-iso/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-hll.ini","idefix-hllc.ini","idefix-tvdlf.ini"] - if test.reconstruction==4: - inifiles=["idefix-rk3.ini","idefix-hllc-rk3.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-hll.ini", "idefix-hllc.ini", "idefix-tvdlf.ini"] + if test.reconstruction == 4: + inifiles = ["idefix-rk3.ini", "idefix-hllc-rk3.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init: - test.makeReference(filename=name) - test.standardTest() - test.nonRegressionTest(filename=name) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init: + test.makeReference(filename=name) + test.standardTest() + test.nonRegressionTest(filename=name) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename=name) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name) + else: + testMe(test) else: - test.noplot = True - for rec in range(2,5): - test.vectPot=False - test.single=False - test.reconstruction=rec - test.mpi=False - testMe(test) + test.noplot = True + for rec in range(2, 5): + test.vectPot = False + test.single = False + test.reconstruction = rec + test.mpi = False + testMe(test) - # test in single precision - test.reconstruction=2 - test.single=True - testMe(test) + # test in single precision + test.reconstruction = 2 + test.single = True + testMe(test) diff --git a/test/HD/sod/definitions.hpp b/test/HD/sod/definitions.hpp index 498be97af..ed56869e4 100644 --- a/test/HD/sod/definitions.hpp +++ b/test/HD/sod/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/sod/definitions.hpp +// +// Last modified : 03/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 1 #define DIMENSIONS 1 diff --git a/test/HD/sod/pydefix_example.py b/test/HD/sod/pydefix_example.py index 58d73642b..374c61521 100644 --- a/test/HD/sod/pydefix_example.py +++ b/test/HD/sod/pydefix_example.py @@ -1,19 +1,36 @@ -import pydefix as pdfx -import numpy as np +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/sod/pydefix_example.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2024) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + import matplotlib.pyplot as plt +import numpy as np +import pydefix as pdfx + def output(data): - plt.figure() - plt.plot(data.x[pdfx.IDIR],data.Vc[pdfx.VX1,0,0,:],label='VX1') - plt.plot(data.x[pdfx.IDIR],data.Vc[pdfx.RHO,0,0,:],label='RHO') - plt.legend() - plt.show() - #data.Vc[0,0,0,10] = 2.0 + plt.figure() + plt.plot(data.x[pdfx.IDIR], data.Vc[pdfx.VX1, 0, 0, :], label="VX1") + plt.plot(data.x[pdfx.IDIR], data.Vc[pdfx.RHO, 0, 0, :], label="RHO") + plt.legend() + plt.show() + # data.Vc[0,0,0,10] = 2.0 + def initflow(data): - # Initialize the flow - data.Vc[pdfx.RHO,0,0,:] = 1.0 - data.Vc[pdfx.PRS,0,0,:] = 2.0 - data.Vc[pdfx.VX1,0,0,:] = np.sin(2.0*np.pi*data.x[0][:]) + # Initialize the flow + data.Vc[pdfx.RHO, 0, 0, :] = 1.0 + data.Vc[pdfx.PRS, 0, 0, :] = 2.0 + data.Vc[pdfx.VX1, 0, 0, :] = np.sin(2.0 * np.pi * data.x[0][:]) diff --git a/test/HD/sod/python/testidefix.py b/test/HD/sod/python/testidefix.py index 899218b17..9256f916d 100755 --- a/test/HD/sod/python/testidefix.py +++ b/test/HD/sod/python/testidefix.py @@ -1,4 +1,19 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/sod/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +# - Clément Robert (IPAG/UGA/CNRS - 2021 - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # -*- coding: utf-8 -*- """ Created on Thu Mar 5 11:29:41 2020 @@ -8,24 +23,26 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK -from pytools import sod import argparse -import numpy as np + import matplotlib.pyplot as plt +import numpy as np from scipy.interpolate import interp1d +from pytools import sod +from pytools.vtk_io import readVTK + parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() -V=readVTK('../data.0002.vtk', geometry='cartesian') +V = readVTK("../data.0002.vtk", geometry="cartesian") gamma = 1.4 npts = 5000 @@ -35,42 +52,48 @@ # t is the time evolution for which positions and states in tube should be calculated # gamma denotes specific heat # note that gamma and npts are default parameters (1.4 and 500) in solve function -positions, regions, values = sod.solve(left_state=(1, 1, 0), right_state=(0.1, 0.125, 0.), - geometry=(0., 1., 0.5), t=0.2, gamma=gamma, npts=npts) +positions, regions, values = sod.solve( + left_state=(1, 1, 0), + right_state=(0.1, 0.125, 0.0), + geometry=(0.0, 1.0, 0.5), + t=0.2, + gamma=gamma, + npts=npts, +) # Finally, let's plot solutions -p = values['p'] -rho = values['rho'] -u = values['u'] -x= values['x'] +p = values["p"] +rho = values["rho"] +u = values["u"] +x = values["x"] -solinterp=interp1d(x,p) +solinterp = interp1d(x, p) -if(not args.noplot): +if not args.noplot: plt.figure(1) - plt.plot(x,rho) - plt.plot(V.x,V.data['RHO'][:,0,0],'+',markersize=2) - plt.title('Density') + plt.plot(x, rho) + plt.plot(V.x, V.data["RHO"][:, 0, 0], "+", markersize=2) + plt.title("Density") plt.figure(2) - plt.plot(x,u) - plt.plot(V.x,V.data['VX1'][:,0,0],'+',markersize=2) - plt.title('Velocity') + plt.plot(x, u) + plt.plot(V.x, V.data["VX1"][:, 0, 0], "+", markersize=2) + plt.title("Velocity") plt.figure(3) - plt.plot(x,p) - plt.plot(V.x,V.data['PRS'][:,0,0],'+',markersize=2) - plt.title('Pressure') + plt.plot(x, p) + plt.plot(V.x, V.data["PRS"][:, 0, 0], "+", markersize=2) + plt.title("Pressure") plt.ioff() plt.show() -error=np.mean(np.fabs(V.data['PRS'][:,0,0]-solinterp(V.x))) -print("Error=%e"%error) -if error<2e-3: +error = np.mean(np.fabs(V.data["PRS"][:, 0, 0] - solinterp(V.x))) +print("Error=%e" % error) +if error < 2e-3: print("SUCCESS!") sys.exit(0) else: diff --git a/test/HD/sod/setup.cpp b/test/HD/sod/setup.cpp index 92668f096..8e14984bc 100644 --- a/test/HD/sod/setup.cpp +++ b/test/HD/sod/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/sod/setup.cpp +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/sod/testme.json b/test/HD/sod/testme.json index 9128c08d4..d5d287c46 100644 --- a/test/HD/sod/testme.json +++ b/test/HD/sod/testme.json @@ -1,33 +1,25 @@ { - "namings": "ini,single,reconstruction", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-hll.ini","idefix-hllc.ini","idefix-tvdlf.ini"], - "noplot": true, - "vectPot": false, - "single": [false], - "reconstruction": [2,3], - "mpi": false, - "tolerance": 0 - },{ - "dumpname": "dump.0001.dmp", - "ini": ["idefix-rk3.ini","idefix-hllc-rk3.ini"], - "noplot": true, - "vectPot": false, - "single": [false], - "reconstruction": [4], - "mpi": false, - "tolerance": 0 - },{ - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-hll.ini","idefix-hllc.ini","idefix-tvdlf.ini"], - "noplot": true, - "vectPot": false, - "reconstruction": [2], - "mpi": false, - "single": [true], - "tolerance": 0 - } - ] + "namings": "ini,single,reconstruction", + "default": { + "dumpname": "dump.0001.dmp", + "mpi": false, + "noplot": true, + "vectPot": false, + "tolerance": 0 + }, + "variants": [ + { + "ini": ["idefix.ini","idefix-hll.ini","idefix-hllc.ini","idefix-tvdlf.ini"], + "single": [false], + "reconstruction": [2,3] + },{ + "ini": ["idefix-rk3.ini","idefix-hllc-rk3.ini"], + "single": [false], + "reconstruction": [4] + },{ + "ini": ["idefix.ini","idefix-hll.ini","idefix-hllc.ini","idefix-tvdlf.ini"], + "reconstruction": [2], + "single": [true] + } + ] } diff --git a/test/HD/sod/testme.py b/test/HD/sod/testme.py index 109109baf..55669c7a4 100755 --- a/test/HD/sod/testme.py +++ b/test/HD/sod/testme.py @@ -1,50 +1,67 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/sod/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-hll.ini","idefix-hllc.ini","idefix-tvdlf.ini"] - if test.reconstruction==4: - inifiles=["idefix-rk3.ini","idefix-hllc-rk3.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-hll.ini", "idefix-hllc.ini", "idefix-tvdlf.ini"] + if test.reconstruction == 4: + inifiles = ["idefix-rk3.ini", "idefix-hllc-rk3.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init: - test.makeReference(filename=name) - test.standardTest() - test.nonRegressionTest(filename=name) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init: + test.makeReference(filename=name) + test.standardTest() + test.nonRegressionTest(filename=name) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename=name) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name) + else: + testMe(test) else: - test.noplot = True - for rec in range(2,5): - test.vectPot=False - test.single=False - test.reconstruction=rec - test.mpi=False - testMe(test) + test.noplot = True + for rec in range(2, 5): + test.vectPot = False + test.single = False + test.reconstruction = rec + test.mpi = False + testMe(test) - # test in single precision - test.reconstruction=2 - test.single=True - testMe(test) + # test in single precision + test.reconstruction = 2 + test.single = True + testMe(test) diff --git a/test/HD/thermalDiffusion/definitions.hpp b/test/HD/thermalDiffusion/definitions.hpp index 3b581bd62..0f3db9bfc 100644 --- a/test/HD/thermalDiffusion/definitions.hpp +++ b/test/HD/thermalDiffusion/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/thermalDiffusion/definitions.hpp +// +// Last modified : 02/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/HD/thermalDiffusion/python/testidefix.py b/test/HD/thermalDiffusion/python/testidefix.py index 126c0be06..3562a5b37 100755 --- a/test/HD/thermalDiffusion/python/testidefix.py +++ b/test/HD/thermalDiffusion/python/testidefix.py @@ -1,52 +1,65 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/thermalDiffusion/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- -import sys -import numpy as np import argparse +import sys + import matplotlib.pyplot as plt +import numpy as np parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() # values from the setup to compute the decay rate -kappa=0.1 -gamma=1.4 -rho0=1.0 +kappa = 0.1 +gamma = 1.4 +rho0 = 1.0 -#diffusion coefficient -D=kappa*(gamma-1)/rho0 +# diffusion coefficient +D = kappa * (gamma - 1) / rho0 -k=2.0*np.pi +k = 2.0 * np.pi # decay rate of the temperature perturbation -gamma=-k**2*D - -raw=np.loadtxt('../analysis.dat',skiprows=1) -t=raw[:,0] -Tidfx=raw[:,1] +gamma = -(k**2) * D -Tth=Tidfx[0]*np.exp(gamma*t) -error=np.mean(Tidfx/Tth-1.0) +raw = np.loadtxt("../analysis.dat", skiprows=1) +t = raw[:, 0] +Tidfx = raw[:, 1] -if(not args.noplot): +Tth = Tidfx[0] * np.exp(gamma * t) +error = np.mean(Tidfx / Tth - 1.0) - plt.close('all') +if not args.noplot: + plt.close("all") plt.figure() - plt.plot(t,Tidfx/Tth-1.0) + plt.plot(t, Tidfx / Tth - 1.0) - print("Error=%e"%error) + print("Error=%e" % error) plt.ioff() plt.show() -if(error<2.5e-6): +if error < 2.5e-6: print("SUCCESS") sys.exit(0) else: diff --git a/test/HD/thermalDiffusion/setup.cpp b/test/HD/thermalDiffusion/setup.cpp index dab61a16f..508fb113c 100644 --- a/test/HD/thermalDiffusion/setup.cpp +++ b/test/HD/thermalDiffusion/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/HD/thermalDiffusion/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/HD/thermalDiffusion/testme.json b/test/HD/thermalDiffusion/testme.json index 2e89ad747..a62b140a9 100644 --- a/test/HD/thermalDiffusion/testme.json +++ b/test/HD/thermalDiffusion/testme.json @@ -1,15 +1,17 @@ { - "namings": "ini", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-rkl.ini"], - "noplot": true, - "reconstruction": 2, - "single": false, - "mpi": false, - "dec": ["2","1","2"], - "tolerance": 0 - } - ] + "namings": "ini", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "reconstruction": 2, + "single": false, + "mpi": false, + "dec": [2,1,2], + "tolerance": 0 + }, + "variants": [ + { + "ini": ["idefix.ini","idefix-rkl.ini"] + } + ] } diff --git a/test/HD/thermalDiffusion/testme.py b/test/HD/thermalDiffusion/testme.py index 1d1a181b0..9243703e8 100755 --- a/test/HD/thermalDiffusion/testme.py +++ b/test/HD/thermalDiffusion/testme.py @@ -1,38 +1,55 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/HD/thermalDiffusion/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-rkl.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-rkl.ini"] - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") - test.standardTest() - test.nonRegressionTest(filename="dump.0001.dmp") + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") + test.standardTest() + test.nonRegressionTest(filename="dump.0001.dmp") -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp") - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp") + else: + testMe(test) else: - test.noplot = True - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) + test.noplot = True + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) diff --git a/test/IO/dump/CMakeLists.txt b/test/IO/dump/CMakeLists.txt index 629aed2d1..aba9c2789 100644 --- a/test/IO/dump/CMakeLists.txt +++ b/test/IO/dump/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/IO/dump/CMakeLists.txt +# +# Last modified : 03/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/IO/dump/definitions.hpp b/test/IO/dump/definitions.hpp index a854ad9e3..79d63eea8 100644 --- a/test/IO/dump/definitions.hpp +++ b/test/IO/dump/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/IO/dump/definitions.hpp +// +// Last modified : 03/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 //#define DEBUG diff --git a/test/IO/dump/setup.cpp b/test/IO/dump/setup.cpp index 1db56f5b0..3b801a72c 100644 --- a/test/IO/dump/setup.cpp +++ b/test/IO/dump/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/IO/dump/setup.cpp +// +// Last modified : 03/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/IO/dump/testme.json b/test/IO/dump/testme.json index cb69f946f..39c575662 100644 --- a/test/IO/dump/testme.json +++ b/test/IO/dump/testme.json @@ -1,28 +1,23 @@ { - "namings": "ini,single,vectPot,mpi", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "vectPot": [false, true], - "reconstruction": 2, - "single": [false], - "mpi": [false, true], - "dec": ["2","2","2"], - "standardTest": false, - "nonRegressionTest": false, - "tolerance": 1e-13 - },{ - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "vectPot": [false], - "reconstruction": 2, - "mpi": [false, true], - "single": [true], - "dec": ["2","2","2"], - "standardTest": false, - "nonRegressionTest": false, - "tolerance": 1e-13 - } - ] + "default": { + "ini": "idefix.ini", + "dumpname": "dump.0001.dmp", + "tolerance": 1e-13, + "nonRegressionTest": false, + "standardTest": false, + "reconstruction": 2, + "dec": [2, 2, 2] + }, + "variants": [ + { + "single": false, + "vectPot": [false, true], + "mpi": [false, true] + }, { + + "vectPot": false, + "single": true, + "mpi": [false, true] + } + ] } diff --git a/test/IO/dump/testme.py b/test/IO/dump/testme.py index 25e84433b..622b89295 100755 --- a/test/IO/dump/testme.py +++ b/test/IO/dump/testme.py @@ -1,59 +1,76 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/IO/dump/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2026) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst # Whether we should reset our reference run (only do that on purpose!) -tolerance=1e-13 +tolerance = 1e-13 + def testMe(test): - test.configure() - test.compile() + test.configure() + test.compile() - # Check restarts - test.run("idefix.ini") + # Check restarts + test.run("idefix.ini") -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) # if no decomposition is specified, use that one if not test.dec: - test.dec=["2","2","2"] + test.dec = ["2", "2", "2"] if not test.all: testMe(test) else: - test.vectPot=False - test.reconstruction=2 - test.mpi=False - testMe(test) - # test in MPI mode - test.mpi=True - testMe(test) - - - # test with vector potential - test.mpi=False - test.vectPot=True - test.reconstruction=2 - testMe(test) - - test.mpi=True - testMe(test) - - # test with other precision - test.single=True - test.vectPot=False - test.reconstruction=2 - test.mpi=False - testMe(test) - # test in MPI mode - test.mpi=True - testMe(test) + test.vectPot = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + # test in MPI mode + test.mpi = True + testMe(test) + + # test with vector potential + test.mpi = False + test.vectPot = True + test.reconstruction = 2 + testMe(test) + + test.mpi = True + testMe(test) + + # test with other precision + test.single = True + test.vectPot = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + # test in MPI mode + test.mpi = True + testMe(test) diff --git a/test/IO/pydefix/CMakeLists.txt b/test/IO/pydefix/CMakeLists.txt index 83d16a526..a9d4c1509 100644 --- a/test/IO/pydefix/CMakeLists.txt +++ b/test/IO/pydefix/CMakeLists.txt @@ -1,2 +1,16 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/IO/pydefix/CMakeLists.txt +# +# Last modified : 10/2024 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2024) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) enable_idefix_property(Idefix_PYTHON) diff --git a/test/IO/pydefix/definitions.hpp b/test/IO/pydefix/definitions.hpp index 69f0c49e9..d3f5578d8 100644 --- a/test/IO/pydefix/definitions.hpp +++ b/test/IO/pydefix/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/IO/pydefix/definitions.hpp +// +// Last modified : 10/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2024) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 2 diff --git a/test/IO/pydefix/pydefix_example.py b/test/IO/pydefix/pydefix_example.py index a08e86464..d5a90d13c 100644 --- a/test/IO/pydefix/pydefix_example.py +++ b/test/IO/pydefix/pydefix_example.py @@ -1,33 +1,59 @@ -from pydefix import * -import numpy as np +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/IO/pydefix/pydefix_example.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2024) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + import matplotlib.pyplot as plt +import numpy as np +from pydefix import * + # The output function # the only argument is dataBlockHost python object, wrapping a dataBlockHost Idefix object -def output(data,grid,n): - # Note: if MPI is not enabled, GatherIdefixArray still works (but merely does a local copy) - pressure = GatherIdefixArray(data.Vc[PRS,:,:,:],data,broadcast=False,keepBoundaries=True) - # only process #0 performs the output - if prank==0: - plt.close() - plt.figure() - plt.pcolormesh(grid.x[IDIR],grid.x[JDIR],pressure[0,:,:],label='PRS',vmin=0.02,vmax=0.5,cmap='plasma') - plt.title("t=%.2f"%data.t) - plt.colorbar() - plt.savefig("PRS.%.4d.png"%n) +def output(data, grid, n): + # Note: if MPI is not enabled, GatherIdefixArray still works (but merely does a local copy) + pressure = GatherIdefixArray( + data.Vc[PRS, :, :, :], data, broadcast=False, keepBoundaries=True + ) + # only process #0 performs the output + if prank == 0: + plt.close() + plt.figure() + plt.pcolormesh( + grid.x[IDIR], + grid.x[JDIR], + pressure[0, :, :], + label="PRS", + vmin=0.02, + vmax=0.5, + cmap="plasma", + ) + plt.title("t=%.2f" % data.t) + plt.colorbar() + plt.savefig("PRS.%.4d.png" % n) def initflow(data): - # Field amplitude - B0 = 1/np.sqrt(4*np.pi) + # Field amplitude + B0 = 1 / np.sqrt(4 * np.pi) - [z,y,x] = np.meshgrid(data.x[KDIR], data.x[JDIR], data.x[IDIR], indexing='ij') + [z, y, x] = np.meshgrid(data.x[KDIR], data.x[JDIR], data.x[IDIR], indexing="ij") - # Initialize the flow - data.Vc[RHO,:,:,:] = 25/(36*np.pi) - data.Vc[PRS,:,:,:] = 5/(12*np.pi) - data.Vc[VX1,:,:,:] = -np.sin(2*np.pi*y) - data.Vc[VX2,:,:,:] = np.sin(2*np.pi*x) + # Initialize the flow + data.Vc[RHO, :, :, :] = 25 / (36 * np.pi) + data.Vc[PRS, :, :, :] = 5 / (12 * np.pi) + data.Vc[VX1, :, :, :] = -np.sin(2 * np.pi * y) + data.Vc[VX2, :, :, :] = np.sin(2 * np.pi * x) - data.Vs[BX1s,:,:-1,:-1] = -B0*np.sin(2*np.pi*y) - data.Vs[BX2s,:,:-1,:-1] = B0*np.sin(4*np.pi*x) + data.Vs[BX1s, :, :-1, :-1] = -B0 * np.sin(2 * np.pi * y) + data.Vs[BX2s, :, :-1, :-1] = B0 * np.sin(4 * np.pi * x) diff --git a/test/IO/pydefix/testme.json b/test/IO/pydefix/testme.json index 78760f724..d228245c0 100644 --- a/test/IO/pydefix/testme.json +++ b/test/IO/pydefix/testme.json @@ -1,17 +1,17 @@ { - "namings": "ini,single,vectPot,mpi", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "noplot": true, - "vectPot": false, - "reconstruction": 2, - "single": false, - "mpi": [false, true], - "dec": ["2","2"], - "standardTest": false, - "tolerance": 1e-12 - } - ] + "default": { + "ini": "idefix.ini", + "dumpname": "dump.0001.dmp", + "tolerance": 1e-12, + "dec": [2, 2], + "noplot": true, + "vectPot": false, + "single": false, + "reconstruction": 2 + }, + "variants": [ + { + "mpi": [false, true] + } + ] } diff --git a/test/IO/pydefix/testme.py b/test/IO/pydefix/testme.py index 2940e56dd..bb033a225 100755 --- a/test/IO/pydefix/testme.py +++ b/test/IO/pydefix/testme.py @@ -1,41 +1,60 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/IO/pydefix/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2026) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -tolerance=1e-12 + +tolerance = 1e-12 + + def testMe(test): - test.configure() - test.compile() + test.configure() + test.compile() - test.run(inputFile="idefix.ini") - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") + test.run(inputFile="idefix.ini") + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") - test.nonRegressionTest(filename="dump.0001.dmp",tolerance=tolerance) + test.nonRegressionTest(filename="dump.0001.dmp", tolerance=tolerance) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2'] + test.dec = ["2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp",tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp", tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.vectPot = False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - test.mpi=True - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + test.mpi = True + testMe(test) diff --git a/test/IO/xdmf/CMakeLists.txt b/test/IO/xdmf/CMakeLists.txt index 8ce9e0f4d..57298314e 100644 --- a/test/IO/xdmf/CMakeLists.txt +++ b/test/IO/xdmf/CMakeLists.txt @@ -1,2 +1,16 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/IO/xdmf/CMakeLists.txt +# +# Last modified : 03/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) enable_idefix_property(Idefix_HDF5) diff --git a/test/IO/xdmf/definitions.hpp b/test/IO/xdmf/definitions.hpp index a854ad9e3..26084767a 100644 --- a/test/IO/xdmf/definitions.hpp +++ b/test/IO/xdmf/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/IO/xdmf/definitions.hpp +// +// Last modified : 03/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 //#define DEBUG diff --git a/test/IO/xdmf/setup.cpp b/test/IO/xdmf/setup.cpp index 8cc40857f..c46bdaa09 100644 --- a/test/IO/xdmf/setup.cpp +++ b/test/IO/xdmf/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/IO/xdmf/setup.cpp +// +// Last modified : 03/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/IO/xdmf/testme.json b/test/IO/xdmf/testme.json index 8198bb7bb..42628d6d6 100644 --- a/test/IO/xdmf/testme.json +++ b/test/IO/xdmf/testme.json @@ -1,17 +1,12 @@ { - "namings": "ini,single,vectPot,mpi", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "vectPot": false, - "reconstruction": 2, - "single": false, - "mpi": false, - "dec": ["2","2","2"], - "standardTest": false, - "nonRegressionTest": false, - "check_file_produced": [ "data.0001.flt.xmf", "data.0001.flt.h5" ] - } - ] + "default": { + "ini": "idefix.ini", + "dumpname": "dump.0001.dmp", + "vectPot": false, + "single": false, + "mpi": false, + "nonRegressionTest": false, + "standardTest": false, + "check_file_produced": [ "data.0001.flt.xmf", "data.0001.flt.h5" ] + } } diff --git a/test/IO/xdmf/testme.py b/test/IO/xdmf/testme.py index 6273bbe0e..41c709930 100755 --- a/test/IO/xdmf/testme.py +++ b/test/IO/xdmf/testme.py @@ -1,45 +1,60 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/IO/xdmf/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2026) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + +test = tst.idfxTest(__file__) -test=tst.idfxTest(__file__) def check_xdmf_exists(): - # verify that the expected XDMF sidecar and data file exist. - xdmf_file = "data.0001.flt.xmf" - h5_file = "data.0001.flt.h5" + # verify that the expected XDMF sidecar and data file exist. + xdmf_file = "data.0001.flt.xmf" + h5_file = "data.0001.flt.h5" + if not os.path.exists(xdmf_file): + print("Missing expected XDMF output file: {}".format(xdmf_file)) + sys.exit(1) + if not os.path.exists(h5_file): + print("Missing expected XDMF data file: {}".format(h5_file)) + sys.exit(1) - if not os.path.exists(xdmf_file): - print("Missing expected XDMF output file: {}".format(xdmf_file)) - sys.exit(1) - if not os.path.exists(h5_file): - print("Missing expected XDMF data file: {}".format(h5_file)) - sys.exit(1) if not test.dec: - test.dec=['2','2','2'] - -if test.check: - check_xdmf_exists() - -else: - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - # Only check that the test runs. - test.configure(definitionFile="definitions.hpp") - test.compile() - test.run(inputFile="idefix.ini") - check_xdmf_exists + test.dec = ["2", "2", "2"] + +if not test.check: + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + # Only check that the test runs. + test.configure(definitionFile="definitions.hpp") + test.compile() + test.run(inputFile="idefix.ini") + +check_xdmf_exists() diff --git a/test/MHD/AmbipolarCshock/CMakeLists.txt b/test/MHD/AmbipolarCshock/CMakeLists.txt index 629aed2d1..b42e6deac 100644 --- a/test/MHD/AmbipolarCshock/CMakeLists.txt +++ b/test/MHD/AmbipolarCshock/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/AmbipolarCshock/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/AmbipolarCshock/definitions.hpp b/test/MHD/AmbipolarCshock/definitions.hpp index 3008864ea..31051165f 100644 --- a/test/MHD/AmbipolarCshock/definitions.hpp +++ b/test/MHD/AmbipolarCshock/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/AmbipolarCshock/definitions.hpp +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 1 #define ISOTHERMAL diff --git a/test/MHD/AmbipolarCshock/python/testidefix.py b/test/MHD/AmbipolarCshock/python/testidefix.py index 8c95dbb1a..c75a1b63d 100755 --- a/test/MHD/AmbipolarCshock/python/testidefix.py +++ b/test/MHD/AmbipolarCshock/python/testidefix.py @@ -1,117 +1,136 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/AmbipolarCshock/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +# - Clément Robert (IPAG/UGA/CNRS - 2021 - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Tue Sep 8 09:10:06 2020 @author: lesurg """ -import numpy as np -from scipy.integrate import ode -import matplotlib.pyplot as plt + import os import sys + +import matplotlib.pyplot as plt +import numpy as np +from scipy.integrate import ode + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK import argparse +from pytools.vtk_io import readVTK + parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() # Parameters from Maclow+ 1995 -theta=np.pi/4 -M=50 -b0=np.sin(theta) -A=10 -L=1 +theta = np.pi / 4 +M = 50 +b0 = np.sin(theta) +A = 10 +L = 1 + +xcut = 40.0 + -xcut=40.0 +def f(x, D): + b = np.sqrt(b0**2 + 2 * A**2 * (D - 1) * (1 / D - 1 / M**2)) + diff = (b - b0) / A**2 * np.cos(theta) ** 2 + np.sin(theta) + diff = (b - D * diff) / (b**2 + np.cos(theta) ** 2) + diff = (b / A) * diff / (L * (1 / D**2 - 1 / M**2)) -def f(x,D): - b=np.sqrt(b0**2+2*A**2*(D-1)*(1/D-1/M**2)) - diff=(b-b0)/A**2*np.cos(theta)**2+np.sin(theta) - diff=(b-D*diff)/(b**2+np.cos(theta)**2) - diff=(b/A)*diff/(L*(1/D**2-1/M**2)) + return diff - return(diff) # load solution -V=readVTK('../data.0001.vtk', geometry='cartesian') - -DSim=V.data['RHO'].flatten() -if(V.y.size>V.x.size): - x=V.y - bxSim=V.data['BX2'].flatten() - bySim=V.data['BX3'].flatten() -elif(V.z.size>V.x.size): - x=V.z - bxSim=V.data['BX3'].flatten() - bySim=V.data['BX1'].flatten() +V = readVTK("../data.0001.vtk", geometry="cartesian") + +DSim = V.data["RHO"].flatten() +if V.y.size > V.x.size: + x = V.y + bxSim = V.data["BX2"].flatten() + bySim = V.data["BX3"].flatten() +elif V.z.size > V.x.size: + x = V.z + bxSim = V.data["BX3"].flatten() + bySim = V.data["BX1"].flatten() else: - x=V.x - bxSim=V.data['BX1'].flatten() - bySim=V.data['BX2'].flatten() + x = V.x + bxSim = V.data["BX1"].flatten() + bySim = V.data["BX2"].flatten() -bSim=bySim/np.sqrt(bySim[0]**2+bxSim[0]**2) +bSim = bySim / np.sqrt(bySim[0] ** 2 + bxSim[0] ** 2) # Index where the two solutions are assumed to match -iref=np.argwhere(DSim>5.0)[0][0] +iref = np.argwhere(DSim > 5.0)[0][0] -#spatial index where we cut the solution -iend=np.argwhere(x>xcut)[0][0] +# spatial index where we cut the solution +iend = np.argwhere(x > xcut)[0][0] # compute analytical solution -r=ode(f).set_integrator('vode',rtol=1e-6) -r.set_initial_value(DSim[iref],x[iref]) +r = ode(f).set_integrator("vode", rtol=1e-6) +r.set_initial_value(DSim[iref], x[iref]) -Dth=np.zeros(x.shape) +Dth = np.zeros(x.shape) for i in range(x.size): - r.set_initial_value(DSim[iref],x[iref]) - Dth[i]=r.integrate(x[i]).item() - #print("Dth[%d]=%g"%(i,Dth[i])) + r.set_initial_value(DSim[iref], x[iref]) + Dth[i] = r.integrate(x[i]).item() + # print("Dth[%d]=%g"%(i,Dth[i])) -bTh=np.sqrt(b0**2+2*A**2*(Dth-1)*(1/Dth-1/M**2)) +bTh = np.sqrt(b0**2 + 2 * A**2 * (Dth - 1) * (1 / Dth - 1 / M**2)) -errb=(bSim[:iend]-bTh[:iend])/np.amax(bTh[:iend]) -errD=(DSim[:iend]-Dth[:iend])/np.amax(Dth[:iend]) +errb = (bSim[:iend] - bTh[:iend]) / np.amax(bTh[:iend]) +errD = (DSim[:iend] - Dth[:iend]) / np.amax(Dth[:iend]) -if(not args.noplot): - plt.close('all') +if not args.noplot: + plt.close("all") plt.figure() plt.subplot(211) - plt.plot(x[:iend]/L,bSim[:iend],'--',label='Sim') - plt.plot(x[:iend]/L,bTh[:iend],label='Theoretical') - plt.xlabel('x/L') - plt.ylabel('b') + plt.plot(x[:iend] / L, bSim[:iend], "--", label="Sim") + plt.plot(x[:iend] / L, bTh[:iend], label="Theoretical") + plt.xlabel("x/L") + plt.ylabel("b") plt.subplot(212) - plt.plot(x[:iend]/L,errb,'--',label='Error') - plt.xlabel('x/L') - plt.ylabel('b') + plt.plot(x[:iend] / L, errb, "--", label="Error") + plt.xlabel("x/L") + plt.ylabel("b") plt.legend() plt.figure() plt.subplot(211) - plt.plot(x[:iend]/L,DSim[:iend],label='Sim') - plt.plot(x[:iend]/L,Dth[:iend],'--',label='Theoretical') - plt.xlabel('x/L') - plt.ylabel('D') + plt.plot(x[:iend] / L, DSim[:iend], label="Sim") + plt.plot(x[:iend] / L, Dth[:iend], "--", label="Theoretical") + plt.xlabel("x/L") + plt.ylabel("D") plt.subplot(212) - plt.plot(x[:iend]/L,errD,'--',label='Error') - plt.xlabel('x/L') - plt.ylabel('D') + plt.plot(x[:iend] / L, errD, "--", label="Error") + plt.xlabel("x/L") + plt.ylabel("D") plt.legend() plt.ioff() plt.show() -err=np.mean(0.5*np.sqrt(errb**2+errD**2)) -print("Error total=%e"%err) -if(err<5e-3): +err = np.mean(0.5 * np.sqrt(errb**2 + errD**2)) +print("Error total=%e" % err) +if err < 5e-3: print("Success!") sys.exit(0) else: diff --git a/test/MHD/AmbipolarCshock/setup.cpp b/test/MHD/AmbipolarCshock/setup.cpp index 65f42ffdb..b3a11d876 100644 --- a/test/MHD/AmbipolarCshock/setup.cpp +++ b/test/MHD/AmbipolarCshock/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/AmbipolarCshock/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/AmbipolarCshock/testme.json b/test/MHD/AmbipolarCshock/testme.json index 2eb2ac51f..4ce0ace6d 100644 --- a/test/MHD/AmbipolarCshock/testme.json +++ b/test/MHD/AmbipolarCshock/testme.json @@ -1,14 +1,16 @@ { - "namings": "ini", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-rkl.ini"], - "noplot": true, - "single": false, - "reconstruction": 2, - "mpi": false, - "tolerance": 0 - } - ] + "namings": "ini", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "single": false, + "reconstruction": 2, + "mpi": false, + "tolerance": 0 + }, + "variants": [ + { + "ini": ["idefix.ini","idefix-rkl.ini"] + } + ] } diff --git a/test/MHD/AmbipolarCshock/testme.py b/test/MHD/AmbipolarCshock/testme.py index 0e2f0815e..e89e27f24 100755 --- a/test/MHD/AmbipolarCshock/testme.py +++ b/test/MHD/AmbipolarCshock/testme.py @@ -1,38 +1,56 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/AmbipolarCshock/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -tolerance=0 + +tolerance = 0 + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-rkl.ini"] - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") - test.standardTest() - test.nonRegressionTest(filename="dump.0001.dmp",tolerance=tolerance) + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-rkl.ini"] + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") + test.standardTest() + test.nonRegressionTest(filename="dump.0001.dmp", tolerance=tolerance) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp",tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp", tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) + test.noplot = True + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) diff --git a/test/MHD/AmbipolarCshock3D/CMakeLists.txt b/test/MHD/AmbipolarCshock3D/CMakeLists.txt index 629aed2d1..bbc860a76 100644 --- a/test/MHD/AmbipolarCshock3D/CMakeLists.txt +++ b/test/MHD/AmbipolarCshock3D/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/AmbipolarCshock3D/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/AmbipolarCshock3D/definitions.hpp b/test/MHD/AmbipolarCshock3D/definitions.hpp index f023918fa..1c517331f 100644 --- a/test/MHD/AmbipolarCshock3D/definitions.hpp +++ b/test/MHD/AmbipolarCshock3D/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/AmbipolarCshock3D/definitions.hpp +// +// Last modified : 05/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 #define ISOTHERMAL diff --git a/test/MHD/AmbipolarCshock3D/python/testidefix.py b/test/MHD/AmbipolarCshock3D/python/testidefix.py index a7354fbaa..08361ab6a 100755 --- a/test/MHD/AmbipolarCshock3D/python/testidefix.py +++ b/test/MHD/AmbipolarCshock3D/python/testidefix.py @@ -1,120 +1,139 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/AmbipolarCshock3D/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Tue Sep 8 09:10:06 2020 @author: lesurg """ -import numpy as np -from scipy.integrate import ode -import matplotlib.pyplot as plt + import os import sys + +import matplotlib.pyplot as plt +import numpy as np +from scipy.integrate import ode + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK import argparse +from pytools.vtk_io import readVTK + parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() # Parameters from Maclow+ 1995 -theta=np.pi/4 -M=50 -b0=np.sin(theta) -A=10 -L=1 +theta = np.pi / 4 +M = 50 +b0 = np.sin(theta) +A = 10 +L = 1 + +xcut = 40.0 + -xcut=40.0 +def f(x, D): + b = np.sqrt(b0**2 + 2 * A**2 * (D - 1) * (1 / D - 1 / M**2)) + diff = (b - b0) / A**2 * np.cos(theta) ** 2 + np.sin(theta) + diff = (b - D * diff) / (b**2 + np.cos(theta) ** 2) + diff = (b / A) * diff / (L * (1 / D**2 - 1 / M**2)) -def f(x,D): - b=np.sqrt(b0**2+2*A**2*(D-1)*(1/D-1/M**2)) - diff=(b-b0)/A**2*np.cos(theta)**2+np.sin(theta) - diff=(b-D*diff)/(b**2+np.cos(theta)**2) - diff=(b/A)*diff/(L*(1/D**2-1/M**2)) + return diff - return(diff) # load solution -V=readVTK('../data.0001.vtk', geometry='cartesian') - - -if(V.y.size>V.x.size): - x=V.y - DSim=V.data['RHO'][0,:,0] - bxSim=V.data['BX2'][0,:,0] - bySim=V.data['BX3'][0,:,0] -elif(V.z.size>V.x.size): - x=V.z - DSim=V.data['RHO'][0,0,:] - bxSim=V.data['BX3'][0,0,:] - bySim=V.data['BX1'][0,0,:] +V = readVTK("../data.0001.vtk", geometry="cartesian") + + +if V.y.size > V.x.size: + x = V.y + DSim = V.data["RHO"][0, :, 0] + bxSim = V.data["BX2"][0, :, 0] + bySim = V.data["BX3"][0, :, 0] +elif V.z.size > V.x.size: + x = V.z + DSim = V.data["RHO"][0, 0, :] + bxSim = V.data["BX3"][0, 0, :] + bySim = V.data["BX1"][0, 0, :] else: - x=V.x - DSim=V.data['RHO'][:,0,0] - bxSim=V.data['BX1'][:,0,0] - bySim=V.data['BX2'][:,0,0] + x = V.x + DSim = V.data["RHO"][:, 0, 0] + bxSim = V.data["BX1"][:, 0, 0] + bySim = V.data["BX2"][:, 0, 0] -bSim=bySim/np.sqrt(bySim[0]**2+bxSim[0]**2) +bSim = bySim / np.sqrt(bySim[0] ** 2 + bxSim[0] ** 2) # Index where the two solutions are assumed to match -iref=np.argwhere(DSim>5.0)[0][0] +iref = np.argwhere(DSim > 5.0)[0][0] -#spatial index where we cut the solution -iend=np.argwhere(x>xcut)[0][0] +# spatial index where we cut the solution +iend = np.argwhere(x > xcut)[0][0] # compute analytical solution -r=ode(f).set_integrator('vode',rtol=1e-6) -r.set_initial_value(DSim[iref],x[iref]) +r = ode(f).set_integrator("vode", rtol=1e-6) +r.set_initial_value(DSim[iref], x[iref]) -Dth=np.zeros(x.shape) +Dth = np.zeros(x.shape) for i in range(x.size): - r.set_initial_value(DSim[iref],x[iref]) - Dth[i]=r.integrate(x[i]).item() - #print("Dth[%d]=%g"%(i,Dth[i])) + r.set_initial_value(DSim[iref], x[iref]) + Dth[i] = r.integrate(x[i]).item() + # print("Dth[%d]=%g"%(i,Dth[i])) -bTh=np.sqrt(b0**2+2*A**2*(Dth-1)*(1/Dth-1/M**2)) +bTh = np.sqrt(b0**2 + 2 * A**2 * (Dth - 1) * (1 / Dth - 1 / M**2)) -errb=(bSim[:iend]-bTh[:iend])/np.amax(bTh[:iend]) -errD=(DSim[:iend]-Dth[:iend])/np.amax(Dth[:iend]) +errb = (bSim[:iend] - bTh[:iend]) / np.amax(bTh[:iend]) +errD = (DSim[:iend] - Dth[:iend]) / np.amax(Dth[:iend]) -if(not args.noplot): - plt.close('all') +if not args.noplot: + plt.close("all") plt.figure() plt.subplot(211) - plt.plot(x[:iend]/L,bSim[:iend],'--',label='Sim') - plt.plot(x[:iend]/L,bTh[:iend],label='Theoretical') - plt.xlabel('x/L') - plt.ylabel('b') + plt.plot(x[:iend] / L, bSim[:iend], "--", label="Sim") + plt.plot(x[:iend] / L, bTh[:iend], label="Theoretical") + plt.xlabel("x/L") + plt.ylabel("b") plt.subplot(212) - plt.plot(x[:iend]/L,errb,'--',label='Error') - plt.xlabel('x/L') - plt.ylabel('b') + plt.plot(x[:iend] / L, errb, "--", label="Error") + plt.xlabel("x/L") + plt.ylabel("b") plt.legend() plt.figure() plt.subplot(211) - plt.plot(x[:iend]/L,DSim[:iend],label='Sim') - plt.plot(x[:iend]/L,Dth[:iend],'--',label='Theoretical') - plt.xlabel('x/L') - plt.ylabel('D') + plt.plot(x[:iend] / L, DSim[:iend], label="Sim") + plt.plot(x[:iend] / L, Dth[:iend], "--", label="Theoretical") + plt.xlabel("x/L") + plt.ylabel("D") plt.subplot(212) - plt.plot(x[:iend]/L,errD,'--',label='Error') - plt.xlabel('x/L') - plt.ylabel('D') + plt.plot(x[:iend] / L, errD, "--", label="Error") + plt.xlabel("x/L") + plt.ylabel("D") plt.legend() plt.ioff() plt.show() -err=np.mean(0.5*np.sqrt(errb**2+errD**2)) -print("Error total=%e"%err) -if(err<5.9e-3): +err = np.mean(0.5 * np.sqrt(errb**2 + errD**2)) +print("Error total=%e" % err) +if err < 5.9e-3: print("Success!") sys.exit(0) else: diff --git a/test/MHD/AmbipolarCshock3D/setup.cpp b/test/MHD/AmbipolarCshock3D/setup.cpp index abf8a0f24..5defddcf2 100644 --- a/test/MHD/AmbipolarCshock3D/setup.cpp +++ b/test/MHD/AmbipolarCshock3D/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/AmbipolarCshock3D/setup.cpp +// +// Last modified : 12/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2025) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/AmbipolarCshock3D/testme.json b/test/MHD/AmbipolarCshock3D/testme.json index fdcb11a76..22f9df910 100644 --- a/test/MHD/AmbipolarCshock3D/testme.json +++ b/test/MHD/AmbipolarCshock3D/testme.json @@ -1,35 +1,33 @@ { - "namings": "ini,mpi,vectPot", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-rkl.ini"], - "noplot": true, - "single": false, - "reconstruction": 2, - "mpi": [false], - "vectPot": [false, true], - "dec": ["2","1","1"], - "tolerance": 3e-14 - },{ - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-rkl.ini"], - "noplot": true, - "single": false, - "reconstruction": 2, - "mpi": [true], - "vectPot": [false], - "dec": ["2","1","1"], - "tolerance": 3e-14 - } - ], - "when": { - "conditions": { - "ini": "idefix-rkl.ini", - "mpi": true - }, - "apply": { - "tolerance": 2e-10 - } + "namings": "ini,mpi,vectPot", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "single": false, + "reconstruction": 2, + "tolerance": 3e-14 + }, + "variants": [ + { + "ini": ["idefix.ini","idefix-rkl.ini"], + "mpi": [false], + "vectPot": [false, true], + "dec": [2,1,1] + },{ + "ini": ["idefix.ini","idefix-rkl.ini"], + "mpi": [true], + "vectPot": [false], + "dec": [2,1,1], + "tolerance": 3e-14 } + ], + "when": { + "conditions": { + "ini": "idefix-rkl.ini", + "mpi": true + }, + "apply": { + "tolerance": 2e-10 + } + } } diff --git a/test/MHD/AmbipolarCshock3D/testme.py b/test/MHD/AmbipolarCshock3D/testme.py index 94a8b0f4c..42a3eb46e 100755 --- a/test/MHD/AmbipolarCshock3D/testme.py +++ b/test/MHD/AmbipolarCshock3D/testme.py @@ -1,51 +1,70 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/AmbipolarCshock3D/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -tolerance=3e-14 + +tolerance = 3e-14 + + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-rkl.ini"] - for ini in inifiles: - mytol=tolerance - - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") - test.standardTest() - # When using RKL, except larger error due to B reconstruction and RKL # of substeps - if test.mpi and ini=="idefix-rkl.ini": - mytol=2e-10 - test.nonRegressionTest(filename="dump.0001.dmp",tolerance=mytol) - - -test=tst.idfxTest(__file__) + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-rkl.ini"] + for ini in inifiles: + mytol = tolerance + + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") + test.standardTest() + # When using RKL, except larger error due to B reconstruction and RKL # of substeps + if test.mpi and ini == "idefix-rkl.ini": + mytol = 2e-10 + test.nonRegressionTest(filename="dump.0001.dmp", tolerance=mytol) + + +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','1','1'] + test.dec = ["2", "1", "1"] if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp",tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp", tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - - test.vectPot=True - testMe(test) - - test.vectPot=False - test.mpi=True - testMe(test) + test.noplot = True + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + + test.vectPot = True + testMe(test) + + test.vectPot = False + test.mpi = True + testMe(test) diff --git a/test/MHD/AmbipolarShearingBox/CMakeLists.txt b/test/MHD/AmbipolarShearingBox/CMakeLists.txt index 629aed2d1..59e586822 100644 --- a/test/MHD/AmbipolarShearingBox/CMakeLists.txt +++ b/test/MHD/AmbipolarShearingBox/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/AmbipolarShearingBox/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/AmbipolarShearingBox/definitions.hpp b/test/MHD/AmbipolarShearingBox/definitions.hpp index 3b581bd62..e1127b289 100644 --- a/test/MHD/AmbipolarShearingBox/definitions.hpp +++ b/test/MHD/AmbipolarShearingBox/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/AmbipolarShearingBox/definitions.hpp +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/AmbipolarShearingBox/python/testidefix.py b/test/MHD/AmbipolarShearingBox/python/testidefix.py index 1d1ccb281..c00531950 100755 --- a/test/MHD/AmbipolarShearingBox/python/testidefix.py +++ b/test/MHD/AmbipolarShearingBox/python/testidefix.py @@ -1,38 +1,56 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/AmbipolarShearingBox/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +# - Clément Robert (IPAG/UGA/CNRS - 2021 - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # -*- coding: utf-8 -*- """ Created on Wed Sep 9 15:31:57 2020 @author: lesurg """ -import numpy as np -import matplotlib.pyplot as plt + import os import sys + +import matplotlib.pyplot as plt +import numpy as np + sys.path.append(os.getenv("IDEFIX_DIR")) from pytools.vtk_io import readVTK -rep='../' -nend=1000 +rep = "../" +nend = 1000 -n=0 -dt=0.1 +n = 0 +dt = 0.1 -Bx=np.zeros(nend) +Bx = np.zeros(nend) -t=dt*np.arange(0,nend) +t = dt * np.arange(0, nend) for n in range(nend): - V=readVTK(rep+'/data.'+'%0*d'%(4,n)+'.vtk', geometry='cartesian') - Bx[n]=np.sqrt(np.mean(np.mean(V.data['BX1']**2,axis=2),axis=0)) + V = readVTK(rep + "/data." + "%0*d" % (4, n) + ".vtk", geometry="cartesian") + Bx[n] = np.sqrt(np.mean(np.mean(V.data["BX1"] ** 2, axis=2), axis=0)) plt.figure() -plt.semilogy(t,Bx) -plt.semilogy(t,Bx[-1]*np.exp(0.171*(t-t[-1]))) +plt.semilogy(t, Bx) +plt.semilogy(t, Bx[-1] * np.exp(0.171 * (t - t[-1]))) -gr=np.log(Bx[-1]/Bx[-700])/(t[-1]-t[-700]) -print('growth rate=%g'%gr) -if np.abs(gr-0.171)/0.171<0.05: +gr = np.log(Bx[-1] / Bx[-700]) / (t[-1] - t[-700]) +print("growth rate=%g" % gr) +if np.abs(gr - 0.171) / 0.171 < 0.05: print("SUCCESS!") else: print("FAILED!") diff --git a/test/MHD/AmbipolarShearingBox/setup.cpp b/test/MHD/AmbipolarShearingBox/setup.cpp index 8c9092fd5..e5bf314b1 100644 --- a/test/MHD/AmbipolarShearingBox/setup.cpp +++ b/test/MHD/AmbipolarShearingBox/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/AmbipolarShearingBox/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/AmbipolarWind/CMakeLists.txt b/test/MHD/AmbipolarWind/CMakeLists.txt index 629aed2d1..ff27f6c18 100644 --- a/test/MHD/AmbipolarWind/CMakeLists.txt +++ b/test/MHD/AmbipolarWind/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/AmbipolarWind/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/AmbipolarWind/definitions.hpp b/test/MHD/AmbipolarWind/definitions.hpp index fbf0a7c45..71c25745f 100644 --- a/test/MHD/AmbipolarWind/definitions.hpp +++ b/test/MHD/AmbipolarWind/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/AmbipolarWind/definitions.hpp +// +// Last modified : 12/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 2 diff --git a/test/MHD/AmbipolarWind/setup.cpp b/test/MHD/AmbipolarWind/setup.cpp index 78620f6e2..6bc801347 100644 --- a/test/MHD/AmbipolarWind/setup.cpp +++ b/test/MHD/AmbipolarWind/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/AmbipolarWind/setup.cpp +// +// Last modified : 06/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" @@ -335,7 +349,7 @@ void EmfBoundary(DataBlock& data, const real t) { } void FluxBoundary(DataBlock & data, int dir, BoundarySide side, const real t) { - IdefixArray4D Flux = data.hydro->FluxRiemann; + IdefixArray4D Flux = data.hydro->FluxRiemann[dir]; if( dir==IDIR && side == left) { int iref = data.beg[IDIR]; @@ -373,7 +387,7 @@ void ComputeUserVars(DataBlock & data, UserDefVariablesContainer &variables) { IdefixHostArray1D x1=d.x[IDIR]; IdefixHostArray1D x2=d.x[JDIR]; IdefixHostArray4D Vc=d.Vc; - IdefixArray3D::HostMirror scrhHost = Kokkos::create_mirror_view(scrh); + IdefixArray3D::host_mirror_type scrhHost = Kokkos::create_mirror_view(scrh); Kokkos::deep_copy(scrhHost,scrh); for(int k = d.beg[KDIR]; k < d.end[KDIR] ; k++) { diff --git a/test/MHD/AxisFluxTube/CMakeLists.txt b/test/MHD/AxisFluxTube/CMakeLists.txt index 629aed2d1..e3c70540e 100644 --- a/test/MHD/AxisFluxTube/CMakeLists.txt +++ b/test/MHD/AxisFluxTube/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/AxisFluxTube/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/AxisFluxTube/definitions.hpp b/test/MHD/AxisFluxTube/definitions.hpp index 53b4f38e3..696a44229 100644 --- a/test/MHD/AxisFluxTube/definitions.hpp +++ b/test/MHD/AxisFluxTube/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/AxisFluxTube/definitions.hpp +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/AxisFluxTube/python/checkAxisBounds.py b/test/MHD/AxisFluxTube/python/checkAxisBounds.py index 44eec58e2..a63f26e49 100755 --- a/test/MHD/AxisFluxTube/python/checkAxisBounds.py +++ b/test/MHD/AxisFluxTube/python/checkAxisBounds.py @@ -1,69 +1,86 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/AxisFluxTube/python/checkAxisBounds.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022 - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Tue Jan 26 15:52:44 2021 @author: lesurg """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.idfx_io import readIdfxFile import matplotlib.pyplot as plt -rep="../" +from pytools.idfx_io import readIdfxFile + +rep = "../" -idfx=readIdfxFile(rep+"analysis.99.0.idfx") -d=idfx.data -Bx1s=d['Vs'][0,:-1,:-1,:] -Bx2s=d['Vs'][1,:-1,:,:-1] -Bx3s=d['Vs'][2,:,:-1,:-1] +idfx = readIdfxFile(rep + "analysis.99.0.idfx") +d = idfx.data +Bx1s = d["Vs"][0, :-1, :-1, :] +Bx2s = d["Vs"][1, :-1, :, :-1] +Bx3s = d["Vs"][2, :, :-1, :-1] -nxhalf=10 -Bx1slice=Bx1s[:,:,nxhalf] -Bx2slice=Bx2s[:,:,nxhalf] -Bx3slice=Bx3s[:,:,nxhalf] +nxhalf = 10 +Bx1slice = Bx1s[:, :, nxhalf] +Bx2slice = Bx2s[:, :, nxhalf] +Bx3slice = Bx3s[:, :, nxhalf] -plt.matshow(Bx1slice,cmap='RdBu_r') +plt.matshow(Bx1slice, cmap="RdBu_r") plt.colorbar() plt.title("Bx1") -plt.matshow(Bx2slice,cmap='RdBu_r') +plt.matshow(Bx2slice, cmap="RdBu_r") plt.colorbar() plt.title("Bx2") -plt.matshow(Bx3slice,cmap='RdBu_r') +plt.matshow(Bx3slice, cmap="RdBu_r") plt.colorbar() plt.title("Bx3") # inner boundary -Bx1slice=Bx1s[:,:5,nxhalf] -Bx2slice=Bx2s[:,:5,nxhalf] -Bx3slice=Bx3s[:,:5,nxhalf] +Bx1slice = Bx1s[:, :5, nxhalf] +Bx2slice = Bx2s[:, :5, nxhalf] +Bx3slice = Bx3s[:, :5, nxhalf] -Vx1slice=d['Vc'][1,:,:5,nxhalf] -Vx2slice=d['Vc'][2,:,:5,nxhalf] -Vx3slice=d['Vc'][3,:,:5,nxhalf] +Vx1slice = d["Vc"][1, :, :5, nxhalf] +Vx2slice = d["Vc"][2, :, :5, nxhalf] +Vx3slice = d["Vc"][3, :, :5, nxhalf] -plt.matshow(Bx1slice,cmap='RdBu_r') +plt.matshow(Bx1slice, cmap="RdBu_r") plt.colorbar() plt.title("Bx1") -plt.matshow(Bx2slice,cmap='RdBu_r') +plt.matshow(Bx2slice, cmap="RdBu_r") plt.colorbar() plt.title("Bx2") -plt.matshow(Bx3slice,cmap='RdBu_r') +plt.matshow(Bx3slice, cmap="RdBu_r") plt.colorbar() plt.title("Bx3") -plt.matshow(Vx1slice,cmap='RdBu_r') +plt.matshow(Vx1slice, cmap="RdBu_r") plt.colorbar() plt.title("Vx1") -plt.matshow(Vx2slice,cmap='RdBu_r') +plt.matshow(Vx2slice, cmap="RdBu_r") plt.colorbar() plt.title("Vx2") -plt.matshow(Vx3slice,cmap='RdBu_r') +plt.matshow(Vx3slice, cmap="RdBu_r") plt.colorbar() plt.title("Vx3") diff --git a/test/MHD/AxisFluxTube/setup.cpp b/test/MHD/AxisFluxTube/setup.cpp index 4c30506d3..7819bc4e1 100644 --- a/test/MHD/AxisFluxTube/setup.cpp +++ b/test/MHD/AxisFluxTube/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/AxisFluxTube/setup.cpp +// +// Last modified : 03/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2025) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/AxisFluxTube/testme.json b/test/MHD/AxisFluxTube/testme.json index 781d4f7b3..2ff1e570f 100644 --- a/test/MHD/AxisFluxTube/testme.json +++ b/test/MHD/AxisFluxTube/testme.json @@ -1,16 +1,32 @@ { - "namings": "ini,mpi", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-coarsening.ini"], - "noplot": true, - "single": false, - "reconstruction": 2, - "mpi": [false, true], - "vectPot": false, - "standardTest": false, - "tolerance": 1e-14 - } - ] + "namings": "ini,mpi,mpiGpuForceCopy,mpiMode", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "single": false, + "reconstruction": 2, + "vectPot": false, + "standardTest": false, + "tolerance": 1e-14 + }, + "variants": [ + { + "ini": ["idefix.ini","idefix-coarsening.ini"], + "mpi": [false, true], + "mpiGpuForceCopy": false, + "mpiMode": "Default" + }, + { + "ini": ["idefix.ini"], + "mpi": true, + "mpiGpuForceCopy": [true], + "mpiMode": ["Persistent"] + }, + { + "ini": ["idefix.ini"], + "mpi": true, + "mpiGpuForceCopy": [false, true], + "mpiMode": ["NonBlocking", "Blocking"] + } + ] } diff --git a/test/MHD/AxisFluxTube/testme.py b/test/MHD/AxisFluxTube/testme.py index 5abb46568..f3bc4c1c8 100755 --- a/test/MHD/AxisFluxTube/testme.py +++ b/test/MHD/AxisFluxTube/testme.py @@ -1,48 +1,65 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/AxisFluxTube/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + +tolerance = 1e-14 -tolerance=1e-14 def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-coarsening.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-coarsening.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename=name) - test.nonRegressionTest(filename=name,tolerance=tolerance) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename=name) + test.nonRegressionTest(filename=name, tolerance=tolerance) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename=name,tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name, tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True + test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) - # test with MPI - test.mpi=True - testMe(test) + # test with MPI + test.mpi = True + testMe(test) diff --git a/test/MHD/Coarsening/CMakeLists.txt b/test/MHD/Coarsening/CMakeLists.txt index 629aed2d1..129d1914a 100644 --- a/test/MHD/Coarsening/CMakeLists.txt +++ b/test/MHD/Coarsening/CMakeLists.txt @@ -1 +1,16 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/Coarsening/CMakeLists.txt +# +# Last modified : 03/2024 +# +# Copyright(C) by : +# - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2024) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/Coarsening/definitions.hpp b/test/MHD/Coarsening/definitions.hpp index 10b5f5f10..bac087ffb 100644 --- a/test/MHD/Coarsening/definitions.hpp +++ b/test/MHD/Coarsening/definitions.hpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/Coarsening/definitions.hpp +// +// Last modified : 03/2024 +// +// Copyright(C) by : +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2024) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/Coarsening/python/testidefix.py b/test/MHD/Coarsening/python/testidefix.py index e3ea0cd0a..12158561c 100755 --- a/test/MHD/Coarsening/python/testidefix.py +++ b/test/MHD/Coarsening/python/testidefix.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/Coarsening/python/testidefix.py +# +# Last modified : 08/2026 +# +# Copyright(C) by : +# - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2024) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # -*- coding: utf-8 -*- """ Created on Thu Mar 5 11:29:41 2020 @@ -8,39 +24,41 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK import argparse -import numpy as np -import matplotlib.pyplot as plt + import inifix +import matplotlib.pyplot as plt +import numpy as np + +from pytools.vtk_io import readVTK parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() # find which ini file was used -with open('../idefix.0.log','r') as fp: - lines = fp.readlines() - for line in lines: - if line.find(".ini") != -1: - s=line.split() - inputFile=s[5][:-1] - -input = inifix.load('../'+inputFile) +with open("../idefix.0.log", "r") as fp: + lines = fp.readlines() + for line in lines: + if line.find(".ini") != -1: + s = line.split() + inputFile = s[5][:-1] + +input = inifix.load(f"../{inputFile}", sections="require") componentDir = input["Setup"]["direction"][0] spatialDir = input["Setup"]["direction"][1] # Convert componentDir -componentName=["BX1","BX2","BX3"] +componentName = ["BX1", "BX2", "BX3"] -V=readVTK('../data.0001.vtk', geometry='cartesian') +V = readVTK("../data.0001.vtk", geometry="cartesian") # left_state and right_state set p, rho and u # geometry sets left boundary on 0., right boundary on 1 and initial @@ -49,48 +67,46 @@ # gamma denotes specific heat # note that gamma and npts are default parameters (1.4 and 500) in solve function -x=V.x -if spatialDir==0: - qside=V.data[componentName[componentDir]][:,4,0] - qcenter=V.data[componentName[componentDir]][:,32,0] - x=V.x -if spatialDir==1: - qside=V.data[componentName[componentDir]][4,:,0] - qcenter=V.data[componentName[componentDir]][32,:,0] - x=V.y -if spatialDir==2: - qside=V.data[componentName[componentDir]][4,0,:] - qcenter=V.data[componentName[componentDir]][32,0,:] - x=V.z - -#initial condition in the code -q0=0.*x+0.1*(np.abs(x)<0.1) +x = V.x +if spatialDir == 0: + qside = V.data[componentName[componentDir]][:, 4, 0] + qcenter = V.data[componentName[componentDir]][:, 32, 0] + x = V.x +if spatialDir == 1: + qside = V.data[componentName[componentDir]][4, :, 0] + qcenter = V.data[componentName[componentDir]][32, :, 0] + x = V.y +if spatialDir == 2: + qside = V.data[componentName[componentDir]][4, 0, :] + qcenter = V.data[componentName[componentDir]][32, 0, :] + x = V.z + +# initial condition in the code +q0 = 0.0 * x + 0.1 * (np.abs(x) < 0.1) # compute solution to diffusion equation using Fourier transforms -qf0=np.fft.fft(q0) -k2=(2.0*np.pi*q0.size*np.fft.fftfreq(q0.size))**2 -qf=qf0*np.exp(-k2*V.t*0.05) -qtheory=np.real(np.fft.ifft(qf)) +qf0 = np.fft.fft(q0) +k2 = (2.0 * np.pi * q0.size * np.fft.fftfreq(q0.size)) ** 2 +qf = qf0 * np.exp(-k2 * V.t * 0.05) +qtheory = np.real(np.fft.ifft(qf)) -if(not args.noplot): +if not args.noplot: plt.figure(1) - plt.plot(x,qside,'+',markersize=6,label='side') - plt.plot(x,qcenter,'+',markersize=6,label='center') + plt.plot(x, qside, "+", markersize=6, label="side") + plt.plot(x, qcenter, "+", markersize=6, label="center") - #plt.plot(x,q0) - plt.plot(x,qtheory,label='theory') + # plt.plot(x,q0) + plt.plot(x, qtheory, label="theory") plt.legend() plt.title(componentName[componentDir]) - - plt.ioff() plt.show() -errorCenter=np.mean((qcenter-qtheory)**2) -errorSide=np.mean((qside-qtheory)**2) -print("Error Side=%e, Error Center=%e"%(errorSide,errorCenter)) -assert(errorCenter<2e-5) -assert(errorSide<2e-8) +errorCenter = np.mean((qcenter - qtheory) ** 2) +errorSide = np.mean((qside - qtheory) ** 2) +print("Error Side=%e, Error Center=%e" % (errorSide, errorCenter)) +assert errorCenter < 2e-5 +assert errorSide < 2e-8 print("SUCCESS!") diff --git a/test/MHD/Coarsening/setup.cpp b/test/MHD/Coarsening/setup.cpp index a7683eee6..8e10b7fb7 100644 --- a/test/MHD/Coarsening/setup.cpp +++ b/test/MHD/Coarsening/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/Coarsening/setup.cpp +// +// Last modified : 03/2024 +// +// Copyright(C) by : +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2024) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/Coarsening/testme.json b/test/MHD/Coarsening/testme.json index 5b38ffebb..b631c5ec7 100644 --- a/test/MHD/Coarsening/testme.json +++ b/test/MHD/Coarsening/testme.json @@ -1,12 +1,14 @@ { - "namings": "ini,mpi", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-rkl.ini","idefix-x2.ini","idefix-x3.ini"], - "noplot": true, - "mpi": [false,true], - "tolerance": 0 - } - ] + "namings": "ini,mpi", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "tolerance": 0 + }, + "variants": [ + { + "ini": ["idefix.ini","idefix-rkl.ini","idefix-x2.ini","idefix-x3.ini"], + "mpi": [false,true] + } + ] } diff --git a/test/MHD/Coarsening/testme.py b/test/MHD/Coarsening/testme.py index 50d13c926..993f53127 100755 --- a/test/MHD/Coarsening/testme.py +++ b/test/MHD/Coarsening/testme.py @@ -1,42 +1,60 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/Coarsening/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2024) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-rkl.ini","idefix-x2.ini","idefix-x3.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-rkl.ini", "idefix-x2.ini", "idefix-x3.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename=name) - test.standardTest() - test.nonRegressionTest(filename=name) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename=name) + test.standardTest() + test.nonRegressionTest(filename=name) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename=name) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name) + else: + testMe(test) else: - test.noplot = True - test.mpi=False - testMe(test) + test.noplot = True + test.mpi = False + testMe(test) - test.mpi=True - testMe(test) + test.mpi = True + testMe(test) diff --git a/test/MHD/FargoMHDSpherical/CMakeLists.txt b/test/MHD/FargoMHDSpherical/CMakeLists.txt index 629aed2d1..f2b64435d 100644 --- a/test/MHD/FargoMHDSpherical/CMakeLists.txt +++ b/test/MHD/FargoMHDSpherical/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/FargoMHDSpherical/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/FargoMHDSpherical/definitions.hpp b/test/MHD/FargoMHDSpherical/definitions.hpp index b2aa4ab59..8e01162a5 100644 --- a/test/MHD/FargoMHDSpherical/definitions.hpp +++ b/test/MHD/FargoMHDSpherical/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/FargoMHDSpherical/definitions.hpp +// +// Last modified : 04/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 #define ISOTHERMAL diff --git a/test/MHD/FargoMHDSpherical/setup.cpp b/test/MHD/FargoMHDSpherical/setup.cpp index 0ff536997..45cce8f51 100644 --- a/test/MHD/FargoMHDSpherical/setup.cpp +++ b/test/MHD/FargoMHDSpherical/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/FargoMHDSpherical/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/FargoMHDSpherical/testme.json b/test/MHD/FargoMHDSpherical/testme.json index 72d93f493..70748b449 100644 --- a/test/MHD/FargoMHDSpherical/testme.json +++ b/test/MHD/FargoMHDSpherical/testme.json @@ -1,17 +1,19 @@ { - "namings": "ini,mpi,vectPot", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "noplot": true, - "single": false, - "reconstruction": 2, - "vectPot": [false, true], - "mpi": [false, true], - "dec": ["2","2","2"], - "standardTest": false, - "tolerance": 1e-14 - } - ] + "namings": "ini,mpi,vectPot", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "single": false, + "reconstruction": 2, + "dec": [2,2,2], + "standardTest": false, + "tolerance": 1e-14 + }, + "variants": [ + { + "ini": ["idefix.ini"], + "vectPot": [false, true], + "mpi": [false, true] + } + ] } diff --git a/test/MHD/FargoMHDSpherical/testme.py b/test/MHD/FargoMHDSpherical/testme.py index 1a3b28adb..c8a286aa3 100755 --- a/test/MHD/FargoMHDSpherical/testme.py +++ b/test/MHD/FargoMHDSpherical/testme.py @@ -1,59 +1,76 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/FargoMHDSpherical/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + +tolerance = 1e-14 -tolerance=1e-14 def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename=name) - test.nonRegressionTest(filename=name,tolerance=tolerance) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename=name) + test.nonRegressionTest(filename=name, tolerance=tolerance) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2','2'] + test.dec = ["2", "2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename=name,tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name, tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - - #test vector potential formulation - test.vectPot=True - testMe(test) - - # test with MPI - test.vectPot=False - test.mpi=True - testMe(test) - - test.vectPot=True - test.mpi=True - testMe(test) + test.noplot = True + + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + + # test vector potential formulation + test.vectPot = True + testMe(test) + + # test with MPI + test.vectPot = False + test.mpi = True + testMe(test) + + test.vectPot = True + test.mpi = True + testMe(test) diff --git a/test/MHD/FieldLoop/CMakeLists.txt b/test/MHD/FieldLoop/CMakeLists.txt index 629aed2d1..08ba5edb3 100644 --- a/test/MHD/FieldLoop/CMakeLists.txt +++ b/test/MHD/FieldLoop/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/FieldLoop/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/FieldLoop/definitions.hpp b/test/MHD/FieldLoop/definitions.hpp index 3b581bd62..e05bf33d5 100644 --- a/test/MHD/FieldLoop/definitions.hpp +++ b/test/MHD/FieldLoop/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/FieldLoop/definitions.hpp +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/FieldLoop/setup.cpp b/test/MHD/FieldLoop/setup.cpp index d1ea953ec..537506e31 100644 --- a/test/MHD/FieldLoop/setup.cpp +++ b/test/MHD/FieldLoop/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/FieldLoop/setup.cpp +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/HallDisk/CMakeLists.txt b/test/MHD/HallDisk/CMakeLists.txt index 629aed2d1..ed644dd4b 100644 --- a/test/MHD/HallDisk/CMakeLists.txt +++ b/test/MHD/HallDisk/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/HallDisk/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/HallDisk/definitions.hpp b/test/MHD/HallDisk/definitions.hpp index 993757b1d..4ba9f6cee 100644 --- a/test/MHD/HallDisk/definitions.hpp +++ b/test/MHD/HallDisk/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/HallDisk/definitions.hpp +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/HallDisk/setup.cpp b/test/MHD/HallDisk/setup.cpp index 641126aba..4c6c1ba01 100644 --- a/test/MHD/HallDisk/setup.cpp +++ b/test/MHD/HallDisk/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/HallDisk/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/HallWhistler/CMakeLists.txt b/test/MHD/HallWhistler/CMakeLists.txt index 629aed2d1..51ba83ef4 100644 --- a/test/MHD/HallWhistler/CMakeLists.txt +++ b/test/MHD/HallWhistler/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/HallWhistler/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/HallWhistler/definitions.hpp b/test/MHD/HallWhistler/definitions.hpp index 3b581bd62..a5ab09e2b 100644 --- a/test/MHD/HallWhistler/definitions.hpp +++ b/test/MHD/HallWhistler/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/HallWhistler/definitions.hpp +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/HallWhistler/python/testidefix.py b/test/MHD/HallWhistler/python/testidefix.py index 3d3eab2d3..6ed8e1f29 100755 --- a/test/MHD/HallWhistler/python/testidefix.py +++ b/test/MHD/HallWhistler/python/testidefix.py @@ -1,10 +1,25 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/HallWhistler/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2021) +# - Clément Robert (IPAG/UGA/CNRS - 2021 - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Thu Sep 10 15:33:28 2020 @author: lesurg """ + #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ @@ -12,76 +27,75 @@ @author: lesurg """ -import sys -import numpy as np import argparse +import sys + import matplotlib.pyplot as plt +import numpy as np from scipy.signal import argrelextrema parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() # values for the field strength to compute theoretical eigenfrequency values -lH=1.0 -B=1.0 -Va=1.0 -k=2.0*np.pi +lH = 1.0 +B = 1.0 +Va = 1.0 +k = 2.0 * np.pi # load the dat file produced by the setup -raw=np.loadtxt('../timevol.dat',skiprows=1) -t=raw[:,0] -by=raw[:,1] +raw = np.loadtxt("../timevol.dat", skiprows=1) +t = raw[:, 0] +by = raw[:, 1] # Theoretical speedes -f_w=Va/(2*np.pi)*k*(np.sqrt(1+(k*lH/2)**2)+k*lH/2) -f_i=Va/(2*np.pi)*k*(np.sqrt(1+(k*lH/2)**2)-k*lH/2) -f_A=k*Va/(2*np.pi) - +f_w = Va / (2 * np.pi) * k * (np.sqrt(1 + (k * lH / 2) ** 2) + k * lH / 2) +f_i = Va / (2 * np.pi) * k * (np.sqrt(1 + (k * lH / 2) ** 2) - k * lH / 2) +f_A = k * Va / (2 * np.pi) # Compute temporal spectrum and get frequency -#by=By[:,0] -sp=np.abs(np.fft.rfft(by)) -f=np.arange(sp.size)/(t[-1]-t[0]) - -r=10**np.arange(np.floor(np.log10(np.amin(sp))),np.ceil(np.log10(np.amax(sp))),0.1) - - - +# by=By[:,0] +sp = np.abs(np.fft.rfft(by)) +f = np.arange(sp.size) / (t[-1] - t[0]) -if(not args.noplot): +r = 10 ** np.arange( + np.floor(np.log10(np.amin(sp))), np.ceil(np.log10(np.amax(sp))), 0.1 +) - plt.close('all') +if not args.noplot: + plt.close("all") plt.figure() - plt.loglog(f,sp,label='signal') - plt.loglog(f_w+0*r,r,'--',label='whistler') - plt.loglog(f_i+0*r,r,'-.',label='ion cyclotron') - plt.loglog(f_A+0*r,r,':',label='Alfven') - plt.xlabel('frequency') - plt.ylabel('By amplitude') + plt.loglog(f, sp, label="signal") + plt.loglog(f_w + 0 * r, r, "--", label="whistler") + plt.loglog(f_i + 0 * r, r, "-.", label="ion cyclotron") + plt.loglog(f_A + 0 * r, r, ":", label="Alfven") + plt.xlabel("frequency") + plt.ylabel("By amplitude") plt.legend() plt.ioff() plt.show() -imax=argrelextrema(sp,np.greater,order=2)[0][0] -f_wnum=f[imax] -error=np.fabs(f_w-f_wnum)/f_w -print("Theoretical whistler frequency=%g, numerical=%g, error=%g"%(f_w,f_wnum,error)) +imax = argrelextrema(sp, np.greater, order=2)[0][0] +f_wnum = f[imax] +error = np.fabs(f_w - f_wnum) / f_w +print( + "Theoretical whistler frequency=%g, numerical=%g, error=%g" % (f_w, f_wnum, error) +) -if(error<0.06): +if error < 0.06: print("SUCCESS") sys.exit(0) else: diff --git a/test/MHD/HallWhistler/setup.cpp b/test/MHD/HallWhistler/setup.cpp index df281f8d4..a83b32186 100644 --- a/test/MHD/HallWhistler/setup.cpp +++ b/test/MHD/HallWhistler/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/HallWhistler/setup.cpp +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include diff --git a/test/MHD/HallWhistler/testme.json b/test/MHD/HallWhistler/testme.json index cc71c4bf7..b08340cbe 100644 --- a/test/MHD/HallWhistler/testme.json +++ b/test/MHD/HallWhistler/testme.json @@ -1,15 +1,12 @@ { - "namings": "ini", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "noplot": true, - "vectPot": false, - "single": false, - "reconstruction": 2, - "mpi": false, - "tolerance": 1e-15 - } - ] + "default": { + "dumpname": "dump.0001.dmp", + "ini": "idefix.ini", + "noplot": true, + "vectPot": false, + "single": false, + "reconstruction": 2, + "mpi": false, + "tolerance": 1e-15 + } } diff --git a/test/MHD/HallWhistler/testme.py b/test/MHD/HallWhistler/testme.py index f8ba0a258..94d1fbd1f 100755 --- a/test/MHD/HallWhistler/testme.py +++ b/test/MHD/HallWhistler/testme.py @@ -1,43 +1,61 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/HallWhistler/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" -tolerance=1e-15 +name = "dump.0001.dmp" +tolerance = 1e-15 + + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - test.standardTest(); - if test.init: - test.makeReference(filename=name) - test.nonRegressionTest(filename=name,tolerance=tolerance) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + test.standardTest() + if test.init: + test.makeReference(filename=name) + test.nonRegressionTest(filename=name, tolerance=tolerance) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename=name,tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name, tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True + test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) diff --git a/test/MHD/LinearWaveTest/CMakeLists.txt b/test/MHD/LinearWaveTest/CMakeLists.txt index 629aed2d1..9de2eff6b 100644 --- a/test/MHD/LinearWaveTest/CMakeLists.txt +++ b/test/MHD/LinearWaveTest/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/LinearWaveTest/CMakeLists.txt +# +# Last modified : 07/2022 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/LinearWaveTest/definitions.hpp b/test/MHD/LinearWaveTest/definitions.hpp index 10b5f5f10..05f2b16dc 100644 --- a/test/MHD/LinearWaveTest/definitions.hpp +++ b/test/MHD/LinearWaveTest/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/LinearWaveTest/definitions.hpp +// +// Last modified : 07/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/LinearWaveTest/python/testidefix.py b/test/MHD/LinearWaveTest/python/testidefix.py index be82269a6..b609da3c1 100755 --- a/test/MHD/LinearWaveTest/python/testidefix.py +++ b/test/MHD/LinearWaveTest/python/testidefix.py @@ -1,64 +1,90 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/LinearWaveTest/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- -import numpy as np +import math import os import sys -import math + +import numpy as np + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.dump_io import readDump -import matplotlib.pyplot as plt import argparse +import matplotlib.pyplot as plt + +from pytools.dump_io import readDump + parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() def getError(rep): try: - V=readDump(rep+'/dump.0000.dmp') - U=readDump(rep+'/dump.0001.dmp') + V = readDump(rep + "/dump.0000.dmp") + U = readDump(rep + "/dump.0001.dmp") except: return math.nan - keylist=[] - keylist=['Vc-RHO','Vc-VX1','Vc-VX2','Vc-VX3','Vs-BX1s','Vs-BX2s','Vs-BX3s','Vc-PRS'] + keylist = [] + keylist = [ + "Vc-RHO", + "Vc-VX1", + "Vc-VX2", + "Vc-VX3", + "Vs-BX1s", + "Vs-BX2s", + "Vs-BX3s", + "Vc-PRS", + ] err = 0.0 for key in keylist: - Q1=V.data[key] - Q2=U.data[key] - - Q1=Q1-np.mean(Q1) - Q2=Q2-np.mean(Q2) - print(key+" error=%e"%((np.mean(np.abs(Q1-Q2)))*1e6)) - err=err + (np.mean(np.abs(Q1-Q2)))**2 - if(not args.noplot): - plt.figure() - plt.contourf(V.data[key][:,:,16]-U.data[key][:,:,16]) - plt.title(key) + Q1 = V.data[key] + Q2 = U.data[key] + Q1 = Q1 - np.mean(Q1) + Q2 = Q2 - np.mean(Q2) + print(key + " error=%e" % ((np.mean(np.abs(Q1 - Q2))) * 1e6)) + err = err + (np.mean(np.abs(Q1 - Q2))) ** 2 + if not args.noplot: + plt.figure() + plt.contourf(V.data[key][:, :, 16] - U.data[key][:, :, 16]) + plt.title(key) - err = err/len(keylist) + err = err / len(keylist) err = np.sqrt(err) return err + error = getError("..") -print("Error=%e"%(error*1e6)) +print("Error=%e" % (error * 1e6)) -if(not args.noplot): - plt.show() +if not args.noplot: + plt.show() -if error*1e6<3e-2: - print("SUCCESS") - sys.exit(0) +if error * 1e6 < 3e-2: + print("SUCCESS") + sys.exit(0) else: - print("Failed") - sys.exit(1) + print("Failed") + sys.exit(1) diff --git a/test/MHD/LinearWaveTest/setup.cpp b/test/MHD/LinearWaveTest/setup.cpp index 06f8a7002..5fe1e42dd 100644 --- a/test/MHD/LinearWaveTest/setup.cpp +++ b/test/MHD/LinearWaveTest/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/LinearWaveTest/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/LinearWaveTest/testme.json b/test/MHD/LinearWaveTest/testme.json index a3f997e34..b552fb8f7 100644 --- a/test/MHD/LinearWaveTest/testme.json +++ b/test/MHD/LinearWaveTest/testme.json @@ -1,24 +1,22 @@ { - "namings": "ini,reconstruction,mpi", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix-fast.ini","idefix-slow.ini","idefix-alfven.ini","idefix-entropy.ini"], - "noplot": true, - "single": false, - "reconstruction": [2], - "mpi": [false,true], - "dec": ["2","2","2"], - "tolerance": 2e-13 - },{ - "dumpname": "dump.0001.dmp", - "ini": ["idefix-fast.ini","idefix-slow.ini","idefix-alfven.ini","idefix-entropy.ini"], - "noplot": true, - "single": false, - "reconstruction": [3, 4], - "mpi": [false], - "dec": ["2","2","2"], - "tolerance": 2e-13 - } - ] + "namings": "ini,reconstruction,mpi", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "dec": [2,2,2], + "tolerance": 2e-13 + }, + "variants": [ + { + "ini": ["idefix-fast.ini","idefix-slow.ini","idefix-alfven.ini","idefix-entropy.ini"], + "single": false, + "reconstruction": [2], + "mpi": [false,true] + },{ + "ini": ["idefix-fast.ini","idefix-slow.ini","idefix-alfven.ini","idefix-entropy.ini"], + "single": false, + "reconstruction": [3, 4], + "mpi": [false] + } + ] } diff --git a/test/MHD/LinearWaveTest/testme.py b/test/MHD/LinearWaveTest/testme.py index eeaaab0fe..a3e2256c7 100755 --- a/test/MHD/LinearWaveTest/testme.py +++ b/test/MHD/LinearWaveTest/testme.py @@ -1,51 +1,75 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/LinearWaveTest/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -tolerance=2e-13 + +tolerance = 2e-13 + + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix-fast.ini","idefix-slow.ini","idefix-alfven.ini","idefix-entropy.ini"] - for ini in inifiles: - mytol=tolerance + test.configure() + test.compile() + inifiles = [ + "idefix-fast.ini", + "idefix-slow.ini", + "idefix-alfven.ini", + "idefix-entropy.ini", + ] + for ini in inifiles: + mytol = tolerance - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") - test.standardTest() - test.nonRegressionTest(filename="dump.0001.dmp",tolerance=mytol) + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") + test.standardTest() + test.nonRegressionTest(filename="dump.0001.dmp", tolerance=mytol) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2','2'] + test.dec = ["2", "2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp",tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp", tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) + test.noplot = True + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) - test.mpi=True - testMe(test) + test.mpi = True + testMe(test) - test.mpi=False - test.reconstruction=3 - testMe(test) + test.mpi = False + test.reconstruction = 3 + testMe(test) - test.reconstruction=4 - testMe(test) + test.reconstruction = 4 + testMe(test) diff --git a/test/MHD/MTI/CMakeLists.txt b/test/MHD/MTI/CMakeLists.txt index 7fcdaa863..62d9a282c 100644 --- a/test/MHD/MTI/CMakeLists.txt +++ b/test/MHD/MTI/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/MTI/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + set_idefix_property(Idefix_RECONSTRUCTION LimO3) enable_idefix_property(Idefix_MHD) add_idefix_source(analysis.hpp) diff --git a/test/MHD/MTI/analysis.cpp b/test/MHD/MTI/analysis.cpp index d0065cf9f..e7cd714fe 100644 --- a/test/MHD/MTI/analysis.cpp +++ b/test/MHD/MTI/analysis.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/MTI/analysis.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include diff --git a/test/MHD/MTI/analysis.hpp b/test/MHD/MTI/analysis.hpp index 9f8b9707a..3887e711d 100644 --- a/test/MHD/MTI/analysis.hpp +++ b/test/MHD/MTI/analysis.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/MTI/analysis.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #ifndef ANALYSIS_HPP_ #define ANALYSIS_HPP_ diff --git a/test/MHD/MTI/definitions.hpp b/test/MHD/MTI/definitions.hpp index 69f0c49e9..c6cce9495 100644 --- a/test/MHD/MTI/definitions.hpp +++ b/test/MHD/MTI/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/MTI/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 2 diff --git a/test/MHD/MTI/python/testidefix.py b/test/MHD/MTI/python/testidefix.py index 4b60cc8bd..770c5681e 100644 --- a/test/MHD/MTI/python/testidefix.py +++ b/test/MHD/MTI/python/testidefix.py @@ -1,3 +1,18 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/MTI/python/testidefix.py +# +# Last modified : 08/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + """ Created in July 2021 @@ -9,64 +24,76 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -import numpy as np import inifix +import numpy as np -n = 1 # fondamental mode +n = 1 # fondamental mode -conf = inifix.load("../idefix.ini") -Pr=conf["Setup"]["pr"] -ksi=conf["Setup"]["ksi"] +conf = inifix.load("../idefix.ini", sections="require") +Pr = conf["Setup"]["pr"] +ksi = conf["Setup"]["ksi"] L = 0.1 -H = 3. -wbuoy = 1/np.sqrt(3) -gamma = 5/3 +H = 3.0 +wbuoy = 1 / np.sqrt(3) +gamma = 5 / 3 -kn = 2*np.pi*n*np.sqrt(2)/L +kn = 2 * np.pi * n * np.sqrt(2) / L -fid=open('../average.dat',"r") +fid = open("../average.dat", "r") # read the first line to get data names -varnames=fid.readline().split() +varnames = fid.readline().split() fid.close() # load the bulk of the file -data=np.loadtxt('../average.dat',skiprows=1) +data = np.loadtxt("../average.dat", skiprows=1) # store this in our data structure -V={} -i=0 +V = {} +i = 0 for name in varnames: - V[name]=data[:,i] - i=i+1 + V[name] = data[:, i] + i = i + 1 + +sigma_vx = ( + 0.5 * (np.log(V["kinx"][20]) - np.log(V["kinx"][15])) / (V["t"][20] - V["t"][15]) +) +sigma_vy = ( + 0.5 * (np.log(V["kiny"][20]) - np.log(V["kiny"][15])) / (V["t"][20] - V["t"][15]) +) +sigma_by = ( + 0.5 * (np.log(V["by_2"][20]) - np.log(V["by_2"][15])) / (V["t"][20] - V["t"][15]) +) +sigma_num = (sigma_vx + sigma_vy + sigma_by) / 3.0 -sigma_vx = 0.5*(np.log(V['kinx'][20]) - np.log(V['kinx'][15]))/(V['t'][20] - V['t'][15]) -sigma_vy = 0.5*(np.log(V['kiny'][20]) - np.log(V['kiny'][15]))/(V['t'][20] - V['t'][15]) -sigma_by = 0.5*(np.log(V['by_2'][20]) - np.log(V['by_2'][15]))/(V['t'][20] - V['t'][15]) -sigma_num = (sigma_vx + sigma_vy + sigma_by)/3. def dispMTI(wcond, k, Pr): - cosk_2 = 0.5 # here cosk_2 = sqrt(bhat) dot khat i.e. xhat dot khat + cosk_2 = 0.5 # here cosk_2 = sqrt(bhat) dot khat i.e. xhat dot khat k_2 = k**2 - ksi = 2.5/k_2/cosk_2*wcond - kx_2 = k_2*cosk_2 - K = kx_2/k_2 + ksi = 2.5 / k_2 / cosk_2 * wcond + kx_2 = k_2 * cosk_2 + K = kx_2 / k_2 - bk_2 = k_2*cosk_2 + bk_2 = k_2 * cosk_2 bkhat_2 = cosk_2 - nu = Pr*ksi - wvisc = 3*nu*bk_2 - v = wvisc*(1 - bkhat_2) - N_2 = wbuoy**2/gamma*((H-1)*gamma-H) - return np.array([1, wcond+v, wcond*v+N_2*kx_2/k_2, K*wcond*-wbuoy**2]) + nu = Pr * ksi + wvisc = 3 * nu * bk_2 + v = wvisc * (1 - bkhat_2) + N_2 = wbuoy**2 / gamma * ((H - 1) * gamma - H) + return np.array( + [1, wcond + v, wcond * v + N_2 * kx_2 / k_2, K * wcond * -(wbuoy**2)] + ) + def sigmaMTI(wcond, k, Pr): - roots = np.roots(dispMTI(wcond,k,Pr)) + roots = np.roots(dispMTI(wcond, k, Pr)) return np.real(roots[np.real(roots) > 0])[0] -wcd = 0.4*ksi*kn**2/2 + +wcd = 0.4 * ksi * kn**2 / 2 sigma_analytic = sigmaMTI(wcd, kn, Pr) -if np.abs(np.log(sigma_analytic/sigma_num)/np.log(sigma_num)) >= 0.1: +if np.abs(np.log(sigma_analytic / sigma_num) / np.log(sigma_num)) >= 0.1: print("Failed") sys.exit(1) else: diff --git a/test/MHD/MTI/setup.cpp b/test/MHD/MTI/setup.cpp index 552f76465..0149d996b 100644 --- a/test/MHD/MTI/setup.cpp +++ b/test/MHD/MTI/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/MTI/setup.cpp +// +// Last modified : 02/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// - Victor Réville (IRAP - 2025) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" #include "analysis.hpp" diff --git a/test/MHD/MTI/testme.json b/test/MHD/MTI/testme.json index 3bd669cca..1adf7c6f7 100644 --- a/test/MHD/MTI/testme.json +++ b/test/MHD/MTI/testme.json @@ -1,15 +1,17 @@ { - "namings": "ini", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-rkl.ini","idefix-sl.ini"], - "noplot": true, - "vectPot": false, - "single": false, - "reconstruction": 2, - "mpi": false, - "tolerance": 0 - } - ] + "namings": "ini", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "vectPot": false, + "single": false, + "reconstruction": 2, + "mpi": false, + "tolerance": 0 + }, + "variants": [ + { + "ini": ["idefix.ini","idefix-rkl.ini","idefix-sl.ini"] + } + ] } diff --git a/test/MHD/MTI/testme.py b/test/MHD/MTI/testme.py index 0e2c9e317..afc50362a 100755 --- a/test/MHD/MTI/testme.py +++ b/test/MHD/MTI/testme.py @@ -1,43 +1,59 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/MTI/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-rkl.ini","idefix-sl.ini"] -# inifiles=["idefix-rkl.ini","idefix-sl.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-rkl.ini", "idefix-sl.ini"] + # inifiles=["idefix-rkl.ini","idefix-sl.ini"] - # loop on all the ini files for this test - name="dump.0001.dmp" - for ini in inifiles: - test.run(inputFile=ini) - test.standardTest() - if test.init: - test.makeReference(filename=name) - test.nonRegressionTest(filename=name) + # loop on all the ini files for this test + name = "dump.0001.dmp" + for ini in inifiles: + test.run(inputFile=ini) + test.standardTest() + if test.init: + test.makeReference(filename=name) + test.nonRegressionTest(filename=name) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp") - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp") + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) diff --git a/test/MHD/OrszagTang/CMakeLists.txt b/test/MHD/OrszagTang/CMakeLists.txt index 629aed2d1..74e1a3df5 100644 --- a/test/MHD/OrszagTang/CMakeLists.txt +++ b/test/MHD/OrszagTang/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/OrszagTang/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/OrszagTang/definitions.hpp b/test/MHD/OrszagTang/definitions.hpp index 69f0c49e9..581c79b3e 100644 --- a/test/MHD/OrszagTang/definitions.hpp +++ b/test/MHD/OrszagTang/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/OrszagTang/definitions.hpp +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 2 diff --git a/test/MHD/OrszagTang/idefix-hll.ini b/test/MHD/OrszagTang/idefix-hll.ini index 4f13fd972..707f35605 100644 --- a/test/MHD/OrszagTang/idefix-hll.ini +++ b/test/MHD/OrszagTang/idefix-hll.ini @@ -18,6 +18,7 @@ X2-beg periodic X2-end periodic [Output] -vtk 0.5 -dmp 0.5 -log 100 +analysis 0.1 +vtk 0.5 +dmp 0.5 +log 100 diff --git a/test/MHD/OrszagTang/idefix-hlld-arithmetic.ini b/test/MHD/OrszagTang/idefix-hlld-arithmetic.ini index 8a656d7b3..0c62cfcc5 100644 --- a/test/MHD/OrszagTang/idefix-hlld-arithmetic.ini +++ b/test/MHD/OrszagTang/idefix-hlld-arithmetic.ini @@ -19,6 +19,7 @@ X2-beg periodic X2-end periodic [Output] -vtk 0.5 -dmp 0.5 -log 100 +analysis 0.1 +vtk 0.5 +dmp 0.5 +log 100 diff --git a/test/MHD/OrszagTang/idefix-hlld-hll.ini b/test/MHD/OrszagTang/idefix-hlld-hll.ini index b396e9917..26ae64973 100644 --- a/test/MHD/OrszagTang/idefix-hlld-hll.ini +++ b/test/MHD/OrszagTang/idefix-hlld-hll.ini @@ -19,6 +19,7 @@ X2-beg periodic X2-end periodic [Output] -vtk 0.5 -dmp 0.5 -log 100 +analysis 0.1 +vtk 0.5 +dmp 0.5 +log 100 diff --git a/test/MHD/OrszagTang/idefix-hlld-hlld.ini b/test/MHD/OrszagTang/idefix-hlld-hlld.ini index 5e158b939..8f82d6f8e 100644 --- a/test/MHD/OrszagTang/idefix-hlld-hlld.ini +++ b/test/MHD/OrszagTang/idefix-hlld-hlld.ini @@ -19,6 +19,7 @@ X2-beg periodic X2-end periodic [Output] -vtk 0.5 -dmp 0.5 -log 100 +analysis 0.1 +vtk 0.5 +dmp 0.5 +log 100 diff --git a/test/MHD/OrszagTang/idefix-hlld-uct0.ini b/test/MHD/OrszagTang/idefix-hlld-uct0.ini index 23646b96f..b0d637d74 100644 --- a/test/MHD/OrszagTang/idefix-hlld-uct0.ini +++ b/test/MHD/OrszagTang/idefix-hlld-uct0.ini @@ -19,6 +19,7 @@ X2-beg periodic X2-end periodic [Output] -vtk 0.5 -dmp 0.5 -log 100 +analysis 0.1 +vtk 0.5 +dmp 0.5 +log 100 diff --git a/test/MHD/OrszagTang/idefix-hlld.ini b/test/MHD/OrszagTang/idefix-hlld.ini index cf6d5cbfd..449d941f4 100644 --- a/test/MHD/OrszagTang/idefix-hlld.ini +++ b/test/MHD/OrszagTang/idefix-hlld.ini @@ -18,6 +18,7 @@ X2-beg periodic X2-end periodic [Output] -vtk 0.5 -dmp 0.5 -log 100 +analysis 0.1 +vtk 0.5 +dmp 0.5 +log 100 diff --git a/test/MHD/OrszagTang/idefix-tvdlf.ini b/test/MHD/OrszagTang/idefix-tvdlf.ini index ec9ffe85e..62cf6d280 100644 --- a/test/MHD/OrszagTang/idefix-tvdlf.ini +++ b/test/MHD/OrszagTang/idefix-tvdlf.ini @@ -18,6 +18,7 @@ X2-beg periodic X2-end periodic [Output] -vtk 0.5 -dmp 0.5 -log 100 +analysis 0.1 +vtk 0.5 +dmp 0.5 +log 100 diff --git a/test/MHD/OrszagTang/idefix.ini b/test/MHD/OrszagTang/idefix.ini index 0e7421843..2ecc050ec 100644 --- a/test/MHD/OrszagTang/idefix.ini +++ b/test/MHD/OrszagTang/idefix.ini @@ -18,6 +18,7 @@ X2-beg periodic X2-end periodic [Output] -vtk 0.5 -dmp 0.5 -log 100 +analysis 0.1 +vtk 0.5 +dmp 0.5 +log 100 diff --git a/test/MHD/OrszagTang/setup.cpp b/test/MHD/OrszagTang/setup.cpp index 50c981c18..21114ce88 100644 --- a/test/MHD/OrszagTang/setup.cpp +++ b/test/MHD/OrszagTang/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/OrszagTang/setup.cpp +// +// Last modified : 09/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" @@ -9,13 +23,53 @@ generators on different architectures. **/ /*********************************************/ - +void CheckConservation(DataBlock &data) { + static real firstCall{true}; + static std::array consArray; + data.hydro->ConvertPrimToCons(); + auto Uc = data.hydro->Uc; + auto dV = data.dV; + //idfx::cout << "Analysis: checking conserved quantities..." << std::endl; + #ifdef SINGLE_PRECISION + const real threshold = 1e-4; + #else + const real threshold = 1e-13; + #endif + for(int nv = 0 ; nv < DefaultPhysics::nvar ; nv++) { + real cons = 0; + idefix_reduce("Conserved quantity reduction", + data.beg[KDIR], data.end[KDIR], + data.beg[JDIR], data.end[JDIR], + data.beg[IDIR], data.end[IDIR], + KOKKOS_LAMBDA (int k, int j, int i, real &c) { + c += dV(k,j,i)*Uc(nv,k,j,i); + }, + Kokkos::Sum(cons)); + #ifdef WITH_MPI + MPI_Allreduce(MPI_IN_PLACE, &cons, 1, realMPI, MPI_SUM, MPI_COMM_WORLD); + #endif + if(firstCall) { + consArray[nv] = cons; + } else { + real err = std::fabs((consArray[nv]-cons)); + if(err>threshold) { + std::stringstream str; + str << "Quantity " << data.hydro->VcName[nv] << " is not conserved" << std::endl; + std::cout << "Error on " << data.hydro->VcName[nv] << " is " << err << std::endl; + std::cout << "Original=" << consArray[nv] << " New=" << cons << std::endl; + IDEFIX_ERROR(str); + } + } + } + firstCall=false; + //idfx::cout << "Analysis: done." << std::endl; +} // Default constructor // Initialisation routine. Can be used to allocate // Arrays or variables which are used later on Setup::Setup(Input &input, Grid &grid, DataBlock &data, Output &output) { - + output.EnrollAnalysis(&CheckConservation); } // This routine initialize the flow diff --git a/test/MHD/OrszagTang/testme.json b/test/MHD/OrszagTang/testme.json index 3128b3239..a2a5b478a 100644 --- a/test/MHD/OrszagTang/testme.json +++ b/test/MHD/OrszagTang/testme.json @@ -1,74 +1,66 @@ { - "namings": "ini,reconstruction,mpi,single,vectPot", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": [ - "idefix.ini", - "idefix-hll.ini", - "idefix-hlld-arithmetic.ini", - "idefix-hlld-hll.ini", - "idefix-hlld-hlld.ini", - "idefix-hlld-uct0.ini", - "idefix-hlld.ini", - "idefix-tvdlf.ini" - ], - "noplot": true, - "vectPot": [false], - "single": false, - "reconstruction": [2,3,4], - "mpi": [false, true], - "dec": ["2","2"], - "tolerance": 1e-12, - "standardTest": false - },{ - "dumpname": "dump.0001.dmp", - "ini": [ - "idefix.ini", - "idefix-hll.ini", - "idefix-hlld-arithmetic.ini", - "idefix-hlld-hll.ini", - "idefix-hlld-hlld.ini", - "idefix-hlld-uct0.ini", - "idefix-hlld.ini", - "idefix-tvdlf.ini" - ], - "noplot": true, - "vectPot": [false], - "single": true, - "reconstruction": [2], - "mpi": [false], - "dec": ["2","2"], - "tolerance": 1e-12, - "standardTest": false - },{ - "dumpname": "dump.0001.dmp", - "ini": [ - "idefix.ini", - "idefix-hll.ini", - "idefix-hlld-arithmetic.ini", - "idefix-hlld-hll.ini", - "idefix-hlld-hlld.ini", - "idefix-hlld-uct0.ini", - "idefix-hlld.ini", - "idefix-tvdlf.ini" - ], - "noplot": true, - "vectPot": [true], - "single": false, - "reconstruction": [2], - "mpi": [false], - "dec": ["2","2"], - "tolerance": 1e-12, - "standardTest": false - } - ], - "when": { - "conditions": { - "single": true - }, - "apply" : { - "tolerance": 1e-5 - } + "namings": "ini,reconstruction,mpi,single,vectPot", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "dec": [2,2], + "tolerance": 1e-12, + "standardTest": false + }, + "variants": [ + { + "ini": [ + "idefix.ini", + "idefix-hll.ini", + "idefix-hlld-arithmetic.ini", + "idefix-hlld-hll.ini", + "idefix-hlld-hlld.ini", + "idefix-hlld-uct0.ini", + "idefix-hlld.ini", + "idefix-tvdlf.ini" + ], + "vectPot": [false], + "single": false, + "reconstruction": [2,3,4], + "mpi": [false, true] + },{ + "ini": [ + "idefix.ini", + "idefix-hll.ini", + "idefix-hlld-arithmetic.ini", + "idefix-hlld-hll.ini", + "idefix-hlld-hlld.ini", + "idefix-hlld-uct0.ini", + "idefix-hlld.ini", + "idefix-tvdlf.ini" + ], + "vectPot": [false], + "single": true, + "reconstruction": [2], + "mpi": [false] + },{ + "ini": [ + "idefix.ini", + "idefix-hll.ini", + "idefix-hlld-arithmetic.ini", + "idefix-hlld-hll.ini", + "idefix-hlld-hlld.ini", + "idefix-hlld-uct0.ini", + "idefix-hlld.ini", + "idefix-tvdlf.ini" + ], + "vectPot": [true], + "single": false, + "reconstruction": [2], + "mpi": [false] } + ], + "when": { + "conditions": { + "single": true + }, + "apply" : { + "tolerance": 1e-5 + } + } } diff --git a/test/MHD/OrszagTang/testme.py b/test/MHD/OrszagTang/testme.py index 41f33aba6..e7d8c005e 100755 --- a/test/MHD/OrszagTang/testme.py +++ b/test/MHD/OrszagTang/testme.py @@ -1,66 +1,89 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/OrszagTang/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -tolerance=1e-12 + +tolerance = 1e-12 + + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini", - "idefix-hll.ini","idefix-hlld-arithmetic.ini", - "idefix-hlld-hll.ini", - "idefix-hlld-hlld.ini", - "idefix-hlld-uct0.ini", - "idefix-hlld.ini","idefix-tvdlf.ini"] + test.configure() + test.compile() + inifiles = [ + "idefix.ini", + "idefix-hll.ini", + "idefix-hlld-arithmetic.ini", + "idefix-hlld-hll.ini", + "idefix-hlld-hlld.ini", + "idefix-hlld-uct0.ini", + "idefix-hlld.ini", + "idefix-tvdlf.ini", + ] - for ini in inifiles: - mytol=tolerance + for ini in inifiles: + mytol = tolerance - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") - if(test.single): - mytol=1e-5 + if test.single: + mytol = 1e-5 - test.nonRegressionTest(filename="dump.0001.dmp",tolerance=mytol) + test.nonRegressionTest(filename="dump.0001.dmp", tolerance=mytol) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2'] + test.dec = ["2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp",tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp", tolerance=tolerance) + else: + testMe(test) else: - for rec in [2,3,4]: - test.noplot = True - test.vectPot = False - test.single=False - test.reconstruction=rec - test.mpi=False - testMe(test) - test.mpi=True + for rec in [2, 3, 4]: + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = rec + test.mpi = False + testMe(test) + test.mpi = True + testMe(test) + + # single precision validation + test.reconstruction = 2 + test.mpi = False + test.single = True testMe(test) - # single precision validation - test.reconstruction=2 - test.mpi=False - test.single=True - testMe(test) - - # Vector potential validation - test.single=False - test.mpi=False - test.vectPot=True - testMe(test) + # Vector potential validation + test.single = False + test.mpi = False + test.vectPot = True + testMe(test) diff --git a/test/MHD/OrszagTang3D/CMakeLists.txt b/test/MHD/OrszagTang3D/CMakeLists.txt index 629aed2d1..4a457930c 100644 --- a/test/MHD/OrszagTang3D/CMakeLists.txt +++ b/test/MHD/OrszagTang3D/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/OrszagTang3D/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/OrszagTang3D/definitions.hpp b/test/MHD/OrszagTang3D/definitions.hpp index a854ad9e3..92e7ff34a 100644 --- a/test/MHD/OrszagTang3D/definitions.hpp +++ b/test/MHD/OrszagTang3D/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/OrszagTang3D/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 //#define DEBUG diff --git a/test/MHD/OrszagTang3D/idefix.ini b/test/MHD/OrszagTang3D/idefix.ini index 1021bd335..5551b23f8 100644 --- a/test/MHD/OrszagTang3D/idefix.ini +++ b/test/MHD/OrszagTang3D/idefix.ini @@ -22,6 +22,7 @@ X3-beg periodic X3-end periodic [Output] -vtk 0.2 -dmp 0.2 -log 10 +vtk 0.2 +dmp 0.2 +log 10 +analysis 0.1 diff --git a/test/MHD/OrszagTang3D/setup.cpp b/test/MHD/OrszagTang3D/setup.cpp index a6927a132..2f20958a1 100644 --- a/test/MHD/OrszagTang3D/setup.cpp +++ b/test/MHD/OrszagTang3D/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/OrszagTang3D/setup.cpp +// +// Last modified : 09/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" @@ -11,11 +25,53 @@ generators on different architectures. Output* myOutput; int outnum; -// Analysis function + +void CheckConservation(DataBlock &data) { + static real firstCall{true}; + static std::array consArray; + data.hydro->ConvertPrimToCons(); + auto Uc = data.hydro->Uc; + auto dV = data.dV; + //idfx::cout << "Analysis: checking conserved quantities..." << std::endl; + #ifdef SINGLE_PRECISION + const real threshold = 2e-4; + #else + const real threshold = 1e-13; + #endif + for(int nv = 0 ; nv < DefaultPhysics::nvar ; nv++) { + real cons = 0; + idefix_reduce("Conserved quantity reduction", + data.beg[KDIR], data.end[KDIR], + data.beg[JDIR], data.end[JDIR], + data.beg[IDIR], data.end[IDIR], + KOKKOS_LAMBDA (int k, int j, int i, real &c) { + c += dV(k,j,i)*Uc(nv,k,j,i); + }, + Kokkos::Sum(cons)); + #ifdef WITH_MPI + MPI_Allreduce(MPI_IN_PLACE, &cons, 1, realMPI, MPI_SUM, MPI_COMM_WORLD); + #endif + if(firstCall) { + consArray[nv] = cons; + } else { + real err = std::fabs((consArray[nv]-cons)); + if(err>threshold) { + std::stringstream str; + str << "Quantity " << data.hydro->VcName[nv] << " is not conserved" << std::endl; + std::cout << "Error on " << data.hydro->VcName[nv] << " is " << err << std::endl; + std::cout << "Original=" << consArray[nv] << " New=" << cons << std::endl; + IDEFIX_ERROR(str); + } + } + } + firstCall=false; + //idfx::cout << "Analysis: done." << std::endl; +} // Initialisation routine. Can be used to allocate // Arrays or variables which are used later on Setup::Setup(Input &input, Grid &grid, DataBlock &data, Output &output) { + output.EnrollAnalysis(&CheckConservation); } // This routine initialize the flow diff --git a/test/MHD/OrszagTang3D/testme.json b/test/MHD/OrszagTang3D/testme.json index a37b54164..fac783064 100644 --- a/test/MHD/OrszagTang3D/testme.json +++ b/test/MHD/OrszagTang3D/testme.json @@ -1,34 +1,31 @@ { - "namings": "ini,single,vectPot,mpi", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "vectPot": [false, true], - "reconstruction": 2, - "single": [false], - "mpi": [false, true], - "dec": ["2","2","2"], - "standardTest": false, - "tolerance": 1e-13 - },{ - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "vectPot": [false], - "reconstruction": 2, - "mpi": [false, true], - "single": [true], - "dec": ["2","2","2"], - "standardTest": false, - "tolerance": 1e-13 - } - ], - "when": { - "conditions": { - "single": true - }, - "apply" : { - "tolerance": 1e-6 - } + "namings": "ini,single,vectPot,mpi", + "default": { + "dumpname": "dump.0001.dmp", + "reconstruction": 2, + "dec": [2,2,2], + "standardTest": false, + "tolerance": 1e-13 + }, + "variants": [ + { + "ini": ["idefix.ini"], + "vectPot": [false, true], + "single": [false], + "mpi": [false, true] + },{ + "ini": ["idefix.ini"], + "vectPot": [false], + "mpi": [false, true], + "single": [true] } + ], + "when": { + "conditions": { + "single": true + }, + "apply" : { + "tolerance": 1e-6 + } + } } diff --git a/test/MHD/OrszagTang3D/testme.py b/test/MHD/OrszagTang3D/testme.py index 7a66150c5..20caf4501 100755 --- a/test/MHD/OrszagTang3D/testme.py +++ b/test/MHD/OrszagTang3D/testme.py @@ -1,69 +1,85 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/OrszagTang3D/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst # Whether we should reset our reference run (only do that on purpose!) -tolerance=1e-13 +tolerance = 1e-13 + def testMe(test): - test.configure() - test.compile() - tol=tolerance - if test.single: - tol=1e-6 + test.configure() + test.compile() + tol = tolerance + if test.single: + tol = 1e-6 - # default with idefix.ini - test.run() - if test.init: - if not test.mpi: - test.makeReference(filename="dump.0001.dmp") - test.nonRegressionTest(filename="dump.0001.dmp",tolerance=tol) + # default with idefix.ini + test.run() + if test.init: + if not test.mpi: + test.makeReference(filename="dump.0001.dmp") + test.nonRegressionTest(filename="dump.0001.dmp", tolerance=tol) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) # if no decomposition is specified, use that one if not test.dec: - test.dec=["2","2","2"] + test.dec = ["2", "2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp",tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp", tolerance=tolerance) + else: + testMe(test) else: - test.vectPot=False - test.reconstruction=2 - test.mpi=False - testMe(test) - # test in MPI mode - test.mpi=True - testMe(test) - - - # test with vector potential - test.mpi=False - test.vectPot=True - test.reconstruction=2 - testMe(test) - - test.mpi=True - testMe(test) - - # test with other precision - test.single=True - test.vectPot=False - test.reconstruction=2 - test.mpi=False - testMe(test) - # test in MPI mode - test.mpi=True - testMe(test) + test.vectPot = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + # test in MPI mode + test.mpi = True + testMe(test) + + # test with vector potential + test.mpi = False + test.vectPot = True + test.reconstruction = 2 + testMe(test) + + test.mpi = True + testMe(test) + + # test with other precision + test.single = True + test.vectPot = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + # test in MPI mode + test.mpi = True + testMe(test) diff --git a/test/MHD/ResistiveAlfvenWave/CMakeLists.txt b/test/MHD/ResistiveAlfvenWave/CMakeLists.txt index 629aed2d1..cfb97d069 100644 --- a/test/MHD/ResistiveAlfvenWave/CMakeLists.txt +++ b/test/MHD/ResistiveAlfvenWave/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/ResistiveAlfvenWave/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/ResistiveAlfvenWave/definitions.hpp b/test/MHD/ResistiveAlfvenWave/definitions.hpp index 536d96048..664f3d0aa 100644 --- a/test/MHD/ResistiveAlfvenWave/definitions.hpp +++ b/test/MHD/ResistiveAlfvenWave/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/ResistiveAlfvenWave/definitions.hpp +// +// Last modified : 09/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 1 diff --git a/test/MHD/ResistiveAlfvenWave/python/testidefix.py b/test/MHD/ResistiveAlfvenWave/python/testidefix.py index 89b0f136c..9e70fba53 100644 --- a/test/MHD/ResistiveAlfvenWave/python/testidefix.py +++ b/test/MHD/ResistiveAlfvenWave/python/testidefix.py @@ -1,44 +1,58 @@ -import sys -import numpy as np +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/ResistiveAlfvenWave/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + import argparse +import sys + import matplotlib.pyplot as plt +import numpy as np parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() # values for the field strength to compute theoretical decay rate -eta=0.05 -k=2.0*np.pi -B0=1.0 +eta = 0.05 +k = 2.0 * np.pi +B0 = 1.0 # decay rate of the energy, assuming k^2eta^2 < 2B0^2 -gamma=-k**2*eta/2 - -raw=np.loadtxt('../timevol.dat',skiprows=1) -t=raw[:,0] -e=raw[:,1] +gamma = -(k**2) * eta / 2 -eth=e[0]*np.exp(2*gamma*t) -error=np.mean(e/eth-1.0) +raw = np.loadtxt("../timevol.dat", skiprows=1) +t = raw[:, 0] +e = raw[:, 1] -if(not args.noplot): +eth = e[0] * np.exp(2 * gamma * t) +error = np.mean(e / eth - 1.0) - plt.close('all') +if not args.noplot: + plt.close("all") plt.figure() - plt.semilogy(t,e) - plt.semilogy(t,eth) + plt.semilogy(t, e) + plt.semilogy(t, eth) plt.ioff() plt.show() -if(error<0.03): +if error < 0.03: print("SUCCESS") sys.exit(0) else: diff --git a/test/MHD/ResistiveAlfvenWave/setup.cpp b/test/MHD/ResistiveAlfvenWave/setup.cpp index d03f583eb..9bfa7f48a 100644 --- a/test/MHD/ResistiveAlfvenWave/setup.cpp +++ b/test/MHD/ResistiveAlfvenWave/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/ResistiveAlfvenWave/setup.cpp +// +// Last modified : 11/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/ResistiveAlfvenWave/testme.json b/test/MHD/ResistiveAlfvenWave/testme.json index 56ae122ec..fc5d9bc71 100644 --- a/test/MHD/ResistiveAlfvenWave/testme.json +++ b/test/MHD/ResistiveAlfvenWave/testme.json @@ -1,14 +1,16 @@ { "namings": "ini,mpi", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "single": false, + "reconstruction": 2, + "tolerance": 1e-14 + }, "variants": [ { - "dumpname": "dump.0001.dmp", "ini": ["idefix.ini","idefix-rkl.ini"], - "noplot": true, - "single": false, - "reconstruction": 2, - "mpi": [false, true], - "tolerance": 1e-14 + "mpi": [false, true] } ], "when": { diff --git a/test/MHD/ResistiveAlfvenWave/testme.py b/test/MHD/ResistiveAlfvenWave/testme.py index ebc29ab57..c9579d6f5 100755 --- a/test/MHD/ResistiveAlfvenWave/testme.py +++ b/test/MHD/ResistiveAlfvenWave/testme.py @@ -1,43 +1,61 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/ResistiveAlfvenWave/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -tolerance=1e-14 + +tolerance = 1e-14 + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-rkl.ini"] - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") - test.standardTest() - mytol=tolerance - if ini=="idefix-rkl.ini": - mytol=1e-10 - test.nonRegressionTest(filename="dump.0001.dmp",tolerance=mytol) - - -test=tst.idfxTest(__file__) + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-rkl.ini"] + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") + test.standardTest() + mytol = tolerance + if ini == "idefix-rkl.ini": + mytol = 1e-10 + test.nonRegressionTest(filename="dump.0001.dmp", tolerance=mytol) + + +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp",tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp", tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - test.mpi=True - testMe(test) + test.noplot = True + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + test.mpi = True + testMe(test) diff --git a/test/MHD/RotorCartesian/CMakeLists.txt b/test/MHD/RotorCartesian/CMakeLists.txt index 629aed2d1..c52e9b969 100644 --- a/test/MHD/RotorCartesian/CMakeLists.txt +++ b/test/MHD/RotorCartesian/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/RotorCartesian/CMakeLists.txt +# +# Last modified : 08/2022 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/RotorCartesian/definitions.hpp b/test/MHD/RotorCartesian/definitions.hpp index 69f0c49e9..b2f7f3895 100644 --- a/test/MHD/RotorCartesian/definitions.hpp +++ b/test/MHD/RotorCartesian/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/RotorCartesian/definitions.hpp +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 2 diff --git a/test/MHD/RotorCartesian/setup.cpp b/test/MHD/RotorCartesian/setup.cpp index c2e668b9a..4f85c6d22 100644 --- a/test/MHD/RotorCartesian/setup.cpp +++ b/test/MHD/RotorCartesian/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/RotorCartesian/setup.cpp +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/RotorPolar/CMakeLists.txt b/test/MHD/RotorPolar/CMakeLists.txt index 629aed2d1..da8966d2c 100644 --- a/test/MHD/RotorPolar/CMakeLists.txt +++ b/test/MHD/RotorPolar/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/RotorPolar/CMakeLists.txt +# +# Last modified : 08/2022 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/RotorPolar/definitions.hpp b/test/MHD/RotorPolar/definitions.hpp index fe0999f1c..c86114d84 100644 --- a/test/MHD/RotorPolar/definitions.hpp +++ b/test/MHD/RotorPolar/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/RotorPolar/definitions.hpp +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 2 diff --git a/test/MHD/RotorPolar/setup.cpp b/test/MHD/RotorPolar/setup.cpp index 7e0d910a8..981e0783d 100644 --- a/test/MHD/RotorPolar/setup.cpp +++ b/test/MHD/RotorPolar/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/RotorPolar/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/ShearingBox/CMakeLists.txt b/test/MHD/ShearingBox/CMakeLists.txt index 2ea4f2e12..51322c308 100644 --- a/test/MHD/ShearingBox/CMakeLists.txt +++ b/test/MHD/ShearingBox/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/ShearingBox/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # add specific source file to idefix build tree add_idefix_source(analysis.cpp) add_idefix_source(analysis.hpp) diff --git a/test/MHD/ShearingBox/analysis.cpp b/test/MHD/ShearingBox/analysis.cpp index 95102b993..cf9a3e704 100644 --- a/test/MHD/ShearingBox/analysis.cpp +++ b/test/MHD/ShearingBox/analysis.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/ShearingBox/analysis.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "analysis.hpp" #include "idefix.hpp" #include "fluid.hpp" @@ -58,7 +72,8 @@ double Analysis::ShwaveAmplitude(const int field, const int nx, const int ny, const int nz, - const real t) + const real t, + const real phaseShift = 0.0) /* * compute the weighted average: int dphi dz rho *infield/int dphi dz rho * @@ -74,7 +89,7 @@ double Analysis::ShwaveAmplitude(const int field, real z = d->x[KDIR](k); real wave = sin(2.0*M_PI*( (nx-ny*shear*t)*x + ny*y - + nz*z)); + + nz*z ) + 2*phaseShift*M_PI); q += wave*d->Vc(field,k,j,i); } } @@ -159,9 +174,9 @@ void Analysis::PerformAnalysis(DataBlock &data) { WriteField(ShwaveAmplitude(VX1, 0, 1, 2, data.t) ); WriteField(ShwaveAmplitude(VX2, 0, 1, 2, data.t) ); WriteField(ShwaveAmplitude(VX3, 0, 1, 2, data.t) ); - WriteField(ShwaveAmplitude(BX1, 0, 1, 2, data.t) ); - WriteField(ShwaveAmplitude(BX2, 0, 1, 2, data.t) ); - WriteField(ShwaveAmplitude(BX3, 0, 1, 2, data.t) ); + WriteField(ShwaveAmplitude(BX1, 0, 1, 2, data.t, -0.25)); + WriteField(ShwaveAmplitude(BX2, 0, 1, 2, data.t, -0.25)); + WriteField(ShwaveAmplitude(BX3, 0, 1, 2, data.t, -0.25)); if(idfx::prank==0) { diff --git a/test/MHD/ShearingBox/analysis.hpp b/test/MHD/ShearingBox/analysis.hpp index 8b65c4317..602a4610f 100644 --- a/test/MHD/ShearingBox/analysis.hpp +++ b/test/MHD/ShearingBox/analysis.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/ShearingBox/analysis.hpp +// +// Last modified : 08/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #ifndef ANALYSIS_HPP_ #define ANALYSIS_HPP_ @@ -25,7 +39,8 @@ class Analysis { const int, const int, const int, - const real); + const real, + const real); DataBlockHost *d; Grid *grid; diff --git a/test/MHD/ShearingBox/definitions.hpp b/test/MHD/ShearingBox/definitions.hpp index 3b581bd62..314c63853 100644 --- a/test/MHD/ShearingBox/definitions.hpp +++ b/test/MHD/ShearingBox/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/ShearingBox/definitions.hpp +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/ShearingBox/python/testidefix.py b/test/MHD/ShearingBox/python/testidefix.py index e1a882229..f9056c99f 100755 --- a/test/MHD/ShearingBox/python/testidefix.py +++ b/test/MHD/ShearingBox/python/testidefix.py @@ -1,23 +1,40 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/ShearingBox/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Mon Jun 21 15:42:19 2021 @author: lesurg """ + +import argparse import sys -import numpy as np + import matplotlib.pyplot as plt +import numpy as np from scipy.integrate import solve_ivp -import argparse -#compute theoretical solution (from Balbus & Hawley 2006, using notations from Lesur 2021) + +# compute theoretical solution (from Balbus & Hawley 2006, using notations from Lesur 2021) def rhs(t, y, Omega, q, B0y, B0z, k0x, k0y, k0z): - kx = k0x + q*Omega * t * k0y + kx = k0x + q * Omega * t * k0y ky = k0y kz = k0z - k2 = kx*kx+ky*ky+kz*kz + k2 = kx * kx + ky * ky + kz * kz vx = y[0] vy = y[1] vz = y[2] @@ -25,100 +42,127 @@ def rhs(t, y, Omega, q, B0y, B0z, k0x, k0y, k0z): by = y[4] bz = y[5] - gxx = kx*kx/k2 - gxy = kx*ky/k2 - gyy = ky*ky/k2 - gyz = ky*kz/k2 - gxz = kx*kz/k2 - #gzz = kz*kz/k2 + gxx = kx * kx / k2 + gxy = kx * ky / k2 + gyy = ky * ky / k2 + gyz = ky * kz / k2 + gxz = kx * kz / k2 + # gzz = kz*kz/k2 + + kdotB = ky * B0y + kz * B0z - kdotB = ky*B0y+kz*B0z + # we assume b=1j*db hence db=-1j*b - #we assume b=1j*db hence db=-1j*b + dvx = kdotB * bx + 2 * Omega * vy * (1 - gxx) + 2 * (1 - q) * Omega * gxy * vx + dvy = ( + kdotB * by + - q * Omega * vx * gyy + - (2 - q) * Omega * (1 - gyy) * vx + - 2 * Omega * vy * gxy + ) + dvz = kdotB * bz + 2 * (1 - q) * Omega * vx * gyz - 2 * Omega * vy * gxz - dvx = kdotB*bx + 2*Omega*vy*(1-gxx) + 2*(1-q)*Omega*gxy*vx - dvy = kdotB*by - q*Omega*vx*gyy - (2-q)*Omega*(1-gyy)*vx - 2*Omega*vy*gxy - dvz= kdotB*bz +2*(1-q)*Omega*vx*gyz-2*Omega*vy*gxz + dbx = -kdotB * vx + dby = -kdotB * vy - q * Omega * bx + dbz = -kdotB * vz - dbx = - kdotB*vx - dby = - kdotB*vy - q*Omega*bx - dbz = - kdotB*vz + return np.asarray([dvx, dvy, dvz, dbx, dby, dbz]) - return np.asarray([dvx,dvy,dvz,dbx,dby,dbz]) parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() -#initial condition: vr=1, rest is 0, mode initial is nx=0, ny=1, nz=5) -y=solve_ivp(rhs, [0,30], [1, 0, 0, 0, 0, 0], args=(1, 1.5, 0.02, 0.05, 0, 2.0*np.pi, 4*np.pi), dense_output=True) +# initial condition: vr=1, rest is 0, mode initial is nx=0, ny=1, nz=2) +y = solve_ivp( + rhs, + [0, 30], + [1, 0, 0, 0, 0, 0], + args=(1, 1.5, 0.02, 0.05, 0, 2.0 * np.pi, 4 * np.pi), + dense_output=True, +) # read timevol file rep = "../" filename = "timevol.dat" -fid=open(rep+filename,"r") +fid = open(rep + filename, "r") -gamma=5/3 +gamma = 5 / 3 # read the first line to get data names -varnames=fid.readline().split() +varnames = fid.readline().split() fid.close() # load the bulk of the file -data=np.loadtxt(rep+filename,skiprows=1) +data = np.loadtxt(rep + filename, skiprows=1) # store this in our data structure -V={} +V = {} -i=0 +i = 0 for name in varnames: - V[name]=data[:,i] - i=i+1 + V[name] = data[:, i] + i = i + 1 # velocity normalisation -v0=V['vx'][0] +v0 = V["vx"][0] # compute L2 error norm -error=np.sqrt((V['vx']/v0-y.sol(V["t"])[0,:])**2 + (V['vy']/v0-y.sol(V["t"])[1,:])**2+ + (V['vz']/v0-y.sol(V["t"])[2,:])**2) - - - -if(not args.noplot): - # Comparison with exact solution - plt.rc('text', usetex=True) - plt.rc('font', family='serif') - plt.rc('font', size=16) - plt.close('all') - plt.figure(1) - plt.plot(V["t"],V['vx']/v0,'r-',label=r'$u_{R}$') - plt.plot(V["t"],y.sol(V["t"])[0,:],'r--') - plt.plot(V["t"],V['vy']/v0,'b-',label=r'$u_{\varphi}$') - plt.plot(V["t"],y.sol(V["t"])[1,:],'b--') - plt.plot(V["t"],V['vz']/v0,'g-',label=r'$u_{z}$') - plt.plot(V["t"],y.sol(V["t"])[2,:],'g--') - plt.legend() - plt.xlabel('t') - - # plot error - plt.figure() - plt.semilogy(V["t"],error) - plt.xlim([0,10]) - plt.ylim([1e-3,1]) - - plt.ioff() - plt.show() - -err=np.mean(error) -print("Error=",err) - -if(err<0.03): - print("SUCCESS") - sys.exit(0) +error = np.sqrt( + (V["vx"] / v0 - y.sol(V["t"])[0, :]) ** 2 + + (V["vy"] / v0 - y.sol(V["t"])[1, :]) ** 2 + + (V["vz"] / v0 - y.sol(V["t"])[2, :]) ** 2 + + (V["bx"] / v0 - y.sol(V["t"])[3, :]) ** 2 + + (V["by"] / v0 - y.sol(V["t"])[4, :]) ** 2 + + (V["bz"] / v0 - y.sol(V["t"])[5, :]) ** 2 +) + + +if not args.noplot: + # Comparison with exact solution + plt.rc("text", usetex=True) + plt.rc("font", family="serif") + plt.rc("font", size=16) + plt.close("all") + plt.figure(1) + plt.plot(V["t"], V["vx"] / v0, "r-", label=r"$u_{R}$") + plt.plot(V["t"], y.sol(V["t"])[0, :], "r--") + plt.plot(V["t"], V["vy"] / v0, "b-", label=r"$u_{\varphi}$") + plt.plot(V["t"], y.sol(V["t"])[1, :], "b--") + plt.plot(V["t"], V["vz"] / v0, "g-", label=r"$u_{z}$") + plt.plot(V["t"], y.sol(V["t"])[2, :], "g--") + plt.legend() + plt.xlabel("t") + + plt.figure(2) + plt.plot(V["t"], V["bx"] / v0, "r-", label=r"$b_{R}$") + plt.plot(V["t"], y.sol(V["t"])[3, :], "r--") + plt.plot(V["t"], V["by"] / v0, "b-", label=r"$b_{\varphi}$") + plt.plot(V["t"], y.sol(V["t"])[4, :], "b--") + plt.plot(V["t"], V["bz"] / v0, "g-", label=r"$b_{z}$") + plt.plot(V["t"], y.sol(V["t"])[5, :], "g--") + plt.legend() + plt.xlabel("t") + + # plot error + plt.figure() + plt.semilogy(V["t"], error) + plt.xlim([0, 10]) + plt.ylim([1e-3, 1]) + + plt.ioff() + plt.show() + +err = np.mean(error) +print("Error=", err) + +if err < 0.04: + print("SUCCESS") + sys.exit(0) else: - print("FAILED") + print("FAILED") diff --git a/test/MHD/ShearingBox/setup.cpp b/test/MHD/ShearingBox/setup.cpp index fb25092a6..c1219f6e1 100644 --- a/test/MHD/ShearingBox/setup.cpp +++ b/test/MHD/ShearingBox/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/ShearingBox/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" #include "analysis.hpp" diff --git a/test/MHD/ShearingBox/testme.json b/test/MHD/ShearingBox/testme.json index 71ae0ab0d..e347fa894 100644 --- a/test/MHD/ShearingBox/testme.json +++ b/test/MHD/ShearingBox/testme.json @@ -1,15 +1,17 @@ { "namings": "ini,mpi", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "single": false, + "reconstruction": 2, + "dec": [2,1,2], + "tolerance": 1e-14 + }, "variants": [ { - "dumpname": "dump.0001.dmp", "ini": ["idefix.ini","idefix-fargo.ini"], - "noplot": true, - "single": false, - "reconstruction": 2, - "mpi": [false, true], - "dec": ["2","1","2"], - "tolerance": 1e-14 + "mpi": [false, true] } ] } diff --git a/test/MHD/ShearingBox/testme.py b/test/MHD/ShearingBox/testme.py index ccee1a69c..be3a43703 100755 --- a/test/MHD/ShearingBox/testme.py +++ b/test/MHD/ShearingBox/testme.py @@ -1,46 +1,64 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/ShearingBox/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -tolerance=1e-14 + +tolerance = 1e-14 + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-fargo.ini"] - for ini in inifiles: - mytol=tolerance + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-fargo.ini"] + for ini in inifiles: + mytol = tolerance - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename="dump.0001.dmp") - test.standardTest() - # When using RKL, except larger error due to B reconstruction and RKL # of substeps - test.nonRegressionTest(filename="dump.0001.dmp",tolerance=mytol) + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename="dump.0001.dmp") + test.standardTest() + # When using RKL, except larger error due to B reconstruction and RKL # of substeps + test.nonRegressionTest(filename="dump.0001.dmp", tolerance=mytol) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','1','2'] + test.dec = ["2", "1", "2"] if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp",tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp", tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - - test.mpi=True - testMe(test) + test.noplot = True + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + + test.mpi = True + testMe(test) diff --git a/test/MHD/advectionOBlique/CMakeLists.txt b/test/MHD/advectionOBlique/CMakeLists.txt index 629aed2d1..e5aa0071f 100644 --- a/test/MHD/advectionOBlique/CMakeLists.txt +++ b/test/MHD/advectionOBlique/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/advectionOBlique/CMakeLists.txt +# +# Last modified : 08/2022 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/advectionOBlique/definitions.hpp b/test/MHD/advectionOBlique/definitions.hpp index 3b581bd62..67014485d 100644 --- a/test/MHD/advectionOBlique/definitions.hpp +++ b/test/MHD/advectionOBlique/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/advectionOBlique/definitions.hpp +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/advectionOBlique/setup.cpp b/test/MHD/advectionOBlique/setup.cpp index 594a38e39..ddc1dd208 100644 --- a/test/MHD/advectionOBlique/setup.cpp +++ b/test/MHD/advectionOBlique/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/advectionOBlique/setup.cpp +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/clessTDiffusion/CMakeLists.txt b/test/MHD/clessTDiffusion/CMakeLists.txt index 629aed2d1..98215b8d3 100644 --- a/test/MHD/clessTDiffusion/CMakeLists.txt +++ b/test/MHD/clessTDiffusion/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/clessTDiffusion/CMakeLists.txt +# +# Last modified : 01/2025 +# +# Copyright(C) by : +# - Victor Réville (IRAP - 2025) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/clessTDiffusion/definitions.hpp b/test/MHD/clessTDiffusion/definitions.hpp index 21b1f8733..ee11160cf 100644 --- a/test/MHD/clessTDiffusion/definitions.hpp +++ b/test/MHD/clessTDiffusion/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/clessTDiffusion/definitions.hpp +// +// Last modified : 01/2025 +// +// Copyright(C) by : +// - Victor Réville (IRAP - 2025) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 1 #define GEOMETRY SPHERICAL diff --git a/test/MHD/clessTDiffusion/python/testidefix.py b/test/MHD/clessTDiffusion/python/testidefix.py index 9427aca82..091745f13 100644 --- a/test/MHD/clessTDiffusion/python/testidefix.py +++ b/test/MHD/clessTDiffusion/python/testidefix.py @@ -1,34 +1,53 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/clessTDiffusion/python/testidefix.py +# +# Last modified : 08/2026 +# +# Copyright(C) by : +# - Victor Réville (IRAP - 2025) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK -import numpy as np import inifix +import numpy as np -conf = inifix.load("../idefix.ini") +from pytools.vtk_io import readVTK + +conf = inifix.load("../idefix.ini", sections="require") gamma = conf["Hydro"]["gamma"] kappa = conf["Hydro"]["bragTDiffusion"][-1] -current_VTK = readVTK('../data.0003.vtk', geometry='spherical') +current_VTK = readVTK("../data.0003.vtk", geometry="spherical") -rho = current_VTK.data['RHO'].squeeze() -prs = current_VTK.data['PRS'].squeeze() -r = current_VTK.r +rho = current_VTK.data["RHO"].squeeze() +prs = current_VTK.data["PRS"].squeeze() +r = current_VTK.r + +idx1 = np.where(r > 20)[0][0] +idx2 = np.where(r > 30)[0][0] -idx1=np.where(r > 20)[0][0] -idx2=np.where(r > 30)[0][0] def gamma_prime(gamma, beta): - return (gamma+beta*(gamma-1))/(1+beta*(gamma-1)) + return (gamma + beta * (gamma - 1)) / (1 + beta * (gamma - 1)) + success = True eps = 3e-4 -gamma_eff = np.gradient(prs, r)/np.gradient(rho, r)*rho/prs +gamma_eff = np.gradient(prs, r) / np.gradient(rho, r) * rho / prs -Error=np.abs(gamma_eff[idx1:idx2]-gamma_prime(gamma, 1.5)).mean() +Error = np.abs(gamma_eff[idx1:idx2] - gamma_prime(gamma, 1.5)).mean() if Error > eps: - success=False + success = False if success: print("SUCCESS") diff --git a/test/MHD/clessTDiffusion/setup.cpp b/test/MHD/clessTDiffusion/setup.cpp index c540c0def..4c16d3b0e 100644 --- a/test/MHD/clessTDiffusion/setup.cpp +++ b/test/MHD/clessTDiffusion/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/clessTDiffusion/setup.cpp +// +// Last modified : 02/2025 +// +// Copyright(C) by : +// - Victor Réville (IRAP - 2025) +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/clessTDiffusion/testme.json b/test/MHD/clessTDiffusion/testme.json index d615696f5..a6ca18745 100644 --- a/test/MHD/clessTDiffusion/testme.json +++ b/test/MHD/clessTDiffusion/testme.json @@ -1,15 +1,12 @@ { - "namings": "ini", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "noplot": true, - "single": false, - "reconstruction": 2, - "mpi": false, - "vectPot": false, - "tolerance": 2e-15 - } - ] + "default": { + "ini": "idefix.ini", + "dumpname": "dump.0001.dmp", + "noplot": true, + "single": false, + "reconstruction": 2, + "mpi": false, + "vectPot": false, + "tolerance": 2e-15 + } } diff --git a/test/MHD/clessTDiffusion/testme.py b/test/MHD/clessTDiffusion/testme.py index 41193e141..e7efc14f0 100755 --- a/test/MHD/clessTDiffusion/testme.py +++ b/test/MHD/clessTDiffusion/testme.py @@ -1,42 +1,58 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/clessTDiffusion/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Victor Réville (IRAP - 2025) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini"] - # loop on all the ini files for this test - name = "dump.0001.dmp" - for ini in inifiles: - test.run(inputFile=ini) - test.standardTest() - if test.init: - test.makeReference(filename=name) - test.nonRegressionTest(filename=name, tolerance=2e-15) + # loop on all the ini files for this test + name = "dump.0001.dmp" + for ini in inifiles: + test.run(inputFile=ini) + test.standardTest() + if test.init: + test.makeReference(filename=name) + test.nonRegressionTest(filename=name, tolerance=2e-15) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp") - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp") + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) diff --git a/test/MHD/disk/CMakeLists.txt b/test/MHD/disk/CMakeLists.txt index 629aed2d1..74f85b679 100644 --- a/test/MHD/disk/CMakeLists.txt +++ b/test/MHD/disk/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/disk/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/disk/definitions.hpp b/test/MHD/disk/definitions.hpp index 993757b1d..11b3864e0 100644 --- a/test/MHD/disk/definitions.hpp +++ b/test/MHD/disk/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/disk/definitions.hpp +// +// Last modified : 08/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/disk/setup.cpp b/test/MHD/disk/setup.cpp index c59332077..4175fab42 100644 --- a/test/MHD/disk/setup.cpp +++ b/test/MHD/disk/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/disk/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/diskSpherical/CMakeLists.txt b/test/MHD/diskSpherical/CMakeLists.txt index 629aed2d1..a0ea4404e 100644 --- a/test/MHD/diskSpherical/CMakeLists.txt +++ b/test/MHD/diskSpherical/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/diskSpherical/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/diskSpherical/definitions.hpp b/test/MHD/diskSpherical/definitions.hpp index 0f44bb5b6..1c6a03830 100644 --- a/test/MHD/diskSpherical/definitions.hpp +++ b/test/MHD/diskSpherical/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/diskSpherical/definitions.hpp +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/diskSpherical/setup.cpp b/test/MHD/diskSpherical/setup.cpp index d18b6b7e9..8a811f505 100644 --- a/test/MHD/diskSpherical/setup.cpp +++ b/test/MHD/diskSpherical/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/diskSpherical/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2023) +// - Clément Robert (IPAG/UGA/CNRS - 2021 - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/sod-iso/CMakeLists.txt b/test/MHD/sod-iso/CMakeLists.txt index 629aed2d1..f0c9a00bf 100644 --- a/test/MHD/sod-iso/CMakeLists.txt +++ b/test/MHD/sod-iso/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/sod-iso/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/sod-iso/definitions.hpp b/test/MHD/sod-iso/definitions.hpp index 3048637d7..1283eff1f 100644 --- a/test/MHD/sod-iso/definitions.hpp +++ b/test/MHD/sod-iso/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/sod-iso/definitions.hpp +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 1 #define ISOTHERMAL diff --git a/test/MHD/sod-iso/setup.cpp b/test/MHD/sod-iso/setup.cpp index d47c764e1..3473d9f32 100644 --- a/test/MHD/sod-iso/setup.cpp +++ b/test/MHD/sod-iso/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/sod-iso/setup.cpp +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2021) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/sod-iso/testme.json b/test/MHD/sod-iso/testme.json index 9f5534fbc..459744862 100644 --- a/test/MHD/sod-iso/testme.json +++ b/test/MHD/sod-iso/testme.json @@ -1,33 +1,25 @@ { "namings": "ini,reconstruction,single", + "default": { + "dumpname": "dump.0001.dmp", + "vectPot": false, + "mpi": false, + "standardTest": false, + "tolerance": 0 + }, "variants": [ { - "dumpname": "dump.0001.dmp", "ini": ["idefix.ini","idefix-hll.ini","idefix-hlld.ini","idefix-tvdlf.ini"], - "vectPot": false, "single": false, - "reconstruction": [2,3], - "mpi": false, - "standardTest": false, - "tolerance": 0 + "reconstruction": [2,3] },{ - "dumpname": "dump.0001.dmp", "ini": ["idefix-rk3.ini","idefix-hlld-rk3.ini"], - "vectPot": false, "single": false, - "reconstruction": [4], - "mpi": false, - "standardTest": false, - "tolerance": 0 + "reconstruction": [4] },{ - "dumpname": "dump.0001.dmp", "ini": ["idefix.ini","idefix-hll.ini","idefix-hlld.ini","idefix-tvdlf.ini"], - "vectPot": false, "reconstruction": [2], - "mpi": false, - "single": true, - "standardTest": false, - "tolerance": 0 + "single": true } ], "when": [ diff --git a/test/MHD/sod-iso/testme.py b/test/MHD/sod-iso/testme.py index c85cc4ce7..a9cde01b9 100755 --- a/test/MHD/sod-iso/testme.py +++ b/test/MHD/sod-iso/testme.py @@ -1,49 +1,66 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/sod-iso/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-hll.ini","idefix-hlld.ini","idefix-tvdlf.ini"] - if test.reconstruction==4: - inifiles=["idefix-rk3.ini","idefix-hlld-rk3.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-hll.ini", "idefix-hlld.ini", "idefix-tvdlf.ini"] + if test.reconstruction == 4: + inifiles = ["idefix-rk3.ini", "idefix-hlld-rk3.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init: - test.makeReference(filename=name) - test.nonRegressionTest(filename=name) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init: + test.makeReference(filename=name) + test.nonRegressionTest(filename=name) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename=name) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name) + else: + testMe(test) else: - test.noplot = True - for rec in range(2,5): - test.vectPot=False - test.single=False - test.reconstruction=rec - test.mpi=False - testMe(test) + test.noplot = True + for rec in range(2, 5): + test.vectPot = False + test.single = False + test.reconstruction = rec + test.mpi = False + testMe(test) - # test in single precision - test.reconstruction=2 - test.single=True - testMe(test) + # test in single precision + test.reconstruction = 2 + test.single = True + testMe(test) diff --git a/test/MHD/sod/CMakeLists.txt b/test/MHD/sod/CMakeLists.txt index 629aed2d1..1daac5ddb 100644 --- a/test/MHD/sod/CMakeLists.txt +++ b/test/MHD/sod/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/sod/CMakeLists.txt +# +# Last modified : 12/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/sod/definitions.hpp b/test/MHD/sod/definitions.hpp index b19c2df81..51cfd1c46 100644 --- a/test/MHD/sod/definitions.hpp +++ b/test/MHD/sod/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/sod/definitions.hpp +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 1 diff --git a/test/MHD/sod/setup.cpp b/test/MHD/sod/setup.cpp index 6a6d68ae8..062b06940 100644 --- a/test/MHD/sod/setup.cpp +++ b/test/MHD/sod/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/sod/setup.cpp +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020 - 2021) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/sod/testme.json b/test/MHD/sod/testme.json index 1501e3049..b0f6f927b 100644 --- a/test/MHD/sod/testme.json +++ b/test/MHD/sod/testme.json @@ -1,33 +1,28 @@ { "namings": "ini,reconstruction,single", + "default": { + "dumpname": "dump.0001.dmp", + "vectPot": false, + "mpi": false, + "standardTest": false, + "tolerance": 0 + }, "variants": [ { - "dumpname": "dump.0001.dmp", "ini": ["idefix.ini","idefix-hll.ini","idefix-hlld.ini","idefix-tvdlf.ini"], - "vectPot": false, "single": false, "reconstruction": [2,3], - "mpi": false, - "standardTest": false, - "tolerance": 0 + "standardTest": false },{ - "dumpname": "dump.0001.dmp", "ini": ["idefix-rk3.ini","idefix-hlld-rk3.ini"], - "vectPot": false, "single": false, "reconstruction": 4, - "mpi": false, "standardTest": false, "tolerance": 0 },{ - "dumpname": "dump.0001.dmp", "ini": ["idefix.ini","idefix-hll.ini","idefix-hlld.ini","idefix-tvdlf.ini"], - "vectPot": false, "reconstruction": 2, - "mpi": false, - "single": true, - "standardTest": false, - "tolerance": 0 + "single": true } ] } diff --git a/test/MHD/sod/testme.py b/test/MHD/sod/testme.py index c85cc4ce7..167853581 100755 --- a/test/MHD/sod/testme.py +++ b/test/MHD/sod/testme.py @@ -1,49 +1,66 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/sod/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-hll.ini","idefix-hlld.ini","idefix-tvdlf.ini"] - if test.reconstruction==4: - inifiles=["idefix-rk3.ini","idefix-hlld-rk3.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-hll.ini", "idefix-hlld.ini", "idefix-tvdlf.ini"] + if test.reconstruction == 4: + inifiles = ["idefix-rk3.ini", "idefix-hlld-rk3.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init: - test.makeReference(filename=name) - test.nonRegressionTest(filename=name) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init: + test.makeReference(filename=name) + test.nonRegressionTest(filename=name) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename=name) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name) + else: + testMe(test) else: - test.noplot = True - for rec in range(2,5): - test.vectPot=False - test.single=False - test.reconstruction=rec - test.mpi=False - testMe(test) + test.noplot = True + for rec in range(2, 5): + test.vectPot = False + test.single = False + test.reconstruction = rec + test.mpi = False + testMe(test) - # test in single precision - test.reconstruction=2 - test.single=True - testMe(test) + # test in single precision + test.reconstruction = 2 + test.single = True + testMe(test) diff --git a/test/MHD/sphBragTDiffusion/CMakeLists.txt b/test/MHD/sphBragTDiffusion/CMakeLists.txt index 629aed2d1..05093e1e3 100644 --- a/test/MHD/sphBragTDiffusion/CMakeLists.txt +++ b/test/MHD/sphBragTDiffusion/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/sphBragTDiffusion/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/MHD/sphBragTDiffusion/definitions.hpp b/test/MHD/sphBragTDiffusion/definitions.hpp index 53b4f38e3..57c73aee5 100644 --- a/test/MHD/sphBragTDiffusion/definitions.hpp +++ b/test/MHD/sphBragTDiffusion/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/sphBragTDiffusion/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/sphBragTDiffusion/python/testidefix.py b/test/MHD/sphBragTDiffusion/python/testidefix.py index 8bf639cb4..481d2f2c8 100644 --- a/test/MHD/sphBragTDiffusion/python/testidefix.py +++ b/test/MHD/sphBragTDiffusion/python/testidefix.py @@ -1,25 +1,41 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/sphBragTDiffusion/python/testidefix.py +# +# Last modified : 08/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK -import numpy as np import inifix +import numpy as np -conf = inifix.load("../idefix.ini") +from pytools.vtk_io import readVTK + +conf = inifix.load("../idefix.ini", sections="require") amplitude = conf["Setup"]["amplitude"] gamma = conf["Hydro"]["gamma"] kappa = conf["Hydro"]["bragTDiffusion"][-1] time_step = conf["Output"]["vtk"] nfile = 6 -list_time = [round(i*time_step, 3) for i in range(nfile)] +list_time = [round(i * time_step, 3) for i in range(nfile)] list_VTK = list() for k in range(nfile): if k >= 10: current_number = str(k) else: - current_number = '0' + str(k) - current_VTK = readVTK('../data.00' + current_number + '.vtk', geometry='spherical') + current_number = "0" + str(k) + current_VTK = readVTK("../data.00" + current_number + ".vtk", geometry="spherical") list_VTK.append(current_VTK) list_VX = list() @@ -28,55 +44,65 @@ list_K = list() list_T = list() for VTK in list_VTK: - list_VX.append(VTK.data['VX1']) - list_RHO.append(VTK.data['RHO']) - list_PRS.append(VTK.data['PRS']) - list_K.append(VTK.data['PRS']/(VTK.data['RHO']**gamma)) - list_T.append(VTK.data['PRS']/VTK.data['RHO']) + list_VX.append(VTK.data["VX1"]) + list_RHO.append(VTK.data["RHO"]) + list_PRS.append(VTK.data["PRS"]) + list_K.append(VTK.data["PRS"] / (VTK.data["RHO"] ** gamma)) + list_T.append(VTK.data["PRS"] / VTK.data["RHO"]) VTK = list_VTK[-1] R = VTK.r TH = VTK.theta PHI = VTK.phi -ir = len(R)//5 -ith = len(TH)//14 -iphi = len(PHI)*5//7 +ir = len(R) // 5 +ith = len(TH) // 14 +iphi = len(PHI) * 5 // 7 + +rho0 = 1.0 +c = 1.0 / (gamma - 1.0) +D = kappa / (rho0 * c) -rho0 = 1. -c = 1./(gamma - 1.) -D = kappa/(rho0*c) def analytic_sol(r, th, phi, t): - lambd2 = 1./r**2/np.sin(th)**2 - return amplitude*((3/r**2 - 1)*np.sin(r)/r - 3*np.cos(r)/r**2)*(-3*np.cos(th)*np.sin(th))*(np.sin(phi))*np.exp(-t*D*lambd2) + 1 + lambd2 = 1.0 / r**2 / np.sin(th) ** 2 + return ( + amplitude + * ((3 / r**2 - 1) * np.sin(r) / r - 3 * np.cos(r) / r**2) + * (-3 * np.cos(th) * np.sin(th)) + * (np.sin(phi)) + * np.exp(-t * D * lambd2) + + 1 + ) + def analytic_rad_sol(r, t): th = TH[ith] phi = PHI[iphi] - return analytic_sol(r,th,phi,t) + return analytic_sol(r, th, phi, t) + def analytic_th_sol(th, t): r = R[ir] phi = PHI[iphi] - return analytic_sol(r,th,phi,t) + return analytic_sol(r, th, phi, t) def analytic_phi_sol(phi, t): r = R[ir] th = TH[ith] - return analytic_sol(r,th,phi,t) + return analytic_sol(r, th, phi, t) success = True eps = 6.4e-8 -for it,t in enumerate(list_time): +for it, t in enumerate(list_time): analytic_T = np.zeros((R.shape[0], TH.shape[0], PHI.shape[0])) - for ir,r in enumerate(R): - for ith,th in enumerate(TH): - for iphi,phi in enumerate(PHI): - analytic_T[ir,ith,iphi] = analytic_sol(r,th,phi,t) + for ir, r in enumerate(R): + for ith, th in enumerate(TH): + for iphi, phi in enumerate(PHI): + analytic_T[ir, ith, iphi] = analytic_sol(r, th, phi, t) TEMP = list_T[it] if np.mean(np.fabs(TEMP - analytic_T)) > eps: - success = False + success = False if success: print("SUCCESS") diff --git a/test/MHD/sphBragTDiffusion/setup.cpp b/test/MHD/sphBragTDiffusion/setup.cpp index 41a45f010..2f1767d8b 100644 --- a/test/MHD/sphBragTDiffusion/setup.cpp +++ b/test/MHD/sphBragTDiffusion/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/sphBragTDiffusion/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/sphBragTDiffusion/testme.json b/test/MHD/sphBragTDiffusion/testme.json index c4cb9a334..79d2ac668 100644 --- a/test/MHD/sphBragTDiffusion/testme.json +++ b/test/MHD/sphBragTDiffusion/testme.json @@ -1,15 +1,12 @@ { - "namings": "ini", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "noplot": true, - "vectPot": false, - "single": false, - "reconstruction": 2, - "mpi": false, - "tolerance": 2e-15 - } - ] + "default": { + "dumpname": "dump.0001.dmp", + "ini": "idefix.ini", + "noplot": true, + "vectPot": false, + "single": false, + "reconstruction": 2, + "mpi": false, + "tolerance": 2e-15 + } } diff --git a/test/MHD/sphBragTDiffusion/testme.py b/test/MHD/sphBragTDiffusion/testme.py index 41193e141..6fc21e43e 100755 --- a/test/MHD/sphBragTDiffusion/testme.py +++ b/test/MHD/sphBragTDiffusion/testme.py @@ -1,42 +1,58 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/sphBragTDiffusion/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini"] - # loop on all the ini files for this test - name = "dump.0001.dmp" - for ini in inifiles: - test.run(inputFile=ini) - test.standardTest() - if test.init: - test.makeReference(filename=name) - test.nonRegressionTest(filename=name, tolerance=2e-15) + # loop on all the ini files for this test + name = "dump.0001.dmp" + for ini in inifiles: + test.run(inputFile=ini) + test.standardTest() + if test.init: + test.makeReference(filename=name) + test.nonRegressionTest(filename=name, tolerance=2e-15) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp") - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp") + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) diff --git a/test/MHD/sphBragViscosity/CMakeLists.txt b/test/MHD/sphBragViscosity/CMakeLists.txt index ba8dc8b1c..9659bd1f5 100644 --- a/test/MHD/sphBragViscosity/CMakeLists.txt +++ b/test/MHD/sphBragViscosity/CMakeLists.txt @@ -1,3 +1,17 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/sphBragViscosity/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) ## The current test is not physics, but merely a non-regression check ## The physical test needs to have the divergence of the velocity field artifiacially set to zero diff --git a/test/MHD/sphBragViscosity/definitions.hpp b/test/MHD/sphBragViscosity/definitions.hpp index efd699f11..bc825a20c 100644 --- a/test/MHD/sphBragViscosity/definitions.hpp +++ b/test/MHD/sphBragViscosity/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/sphBragViscosity/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/MHD/sphBragViscosity/noDivBragViscosity.cpp b/test/MHD/sphBragViscosity/noDivBragViscosity.cpp index befb93d0c..b1af5886a 100644 --- a/test/MHD/sphBragViscosity/noDivBragViscosity.cpp +++ b/test/MHD/sphBragViscosity/noDivBragViscosity.cpp @@ -1,7 +1,14 @@ // *********************************************************************************** // Idefix MHD astrophysical code -// Copyright(C) Geoffroy R. J. Lesur +// +// Source file test/MHD/sphBragViscosity/noDivBragViscosity.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) // and other code contributors +// // Licensed under CeCILL 2.1 License, see COPYING for more information // *********************************************************************************** diff --git a/test/MHD/sphBragViscosity/python/testidefix.py b/test/MHD/sphBragViscosity/python/testidefix.py index c016242d6..c73cdfb9d 100644 --- a/test/MHD/sphBragViscosity/python/testidefix.py +++ b/test/MHD/sphBragViscosity/python/testidefix.py @@ -1,20 +1,37 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/sphBragViscosity/python/testidefix.py +# +# Last modified : 08/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK -import numpy as np import inifix +import numpy as np from scipy.special import jn -conf = inifix.load("../idefix.ini") +from pytools.vtk_io import readVTK + +conf = inifix.load("../idefix.ini", sections="require") amplitude = conf["Setup"]["amplitude"] time_step = conf["Output"]["vtk"] nfile = 10 -list_time = [round(i*time_step, 7) for i in range(nfile)] +list_time = [round(i * time_step, 7) for i in range(nfile)] list_VTK = list() for k in range(nfile): - current_VTK = readVTK('../data.00{0:02d}.vtk'.format(k), 'spherical') + current_VTK = readVTK("../data.00{0:02d}.vtk".format(k), "spherical") list_VTK.append(current_VTK) list_VX = list() @@ -25,32 +42,33 @@ list_BY = list() list_BZ = list() for VTK in list_VTK: - list_VX.append(VTK.data['VX1']) - list_VY.append(VTK.data['VX2']) - list_VZ.append(VTK.data['VX3']) - list_BX.append(VTK.data['BX1']) - list_BY.append(VTK.data['BX2']) - list_BZ.append(VTK.data['BX3']) - list_RHO.append(VTK.data['RHO']) + list_VX.append(VTK.data["VX1"]) + list_VY.append(VTK.data["VX2"]) + list_VZ.append(VTK.data["VX3"]) + list_BX.append(VTK.data["BX1"]) + list_BY.append(VTK.data["BX2"]) + list_BZ.append(VTK.data["BX3"]) + list_RHO.append(VTK.data["RHO"]) X = VTK.r Y = VTK.theta Z = VTK.phi mu = conf["Hydro"]["bragViscosity"][-1] + def analytic_sol(r, th, phi, t): - lambd2 = 2. - return amplitude*jn(1,r)/r*np.exp(-t*lambd2*mu) + lambd2 = 2.0 + return amplitude * jn(1, r) / r * np.exp(-t * lambd2 * mu) eps = 7e-7 for k, Vx in enumerate(list_VX): t = list_time[k] - current_sol = np.zeros((len(X),len(Y),len(Z))) - for ix,x in enumerate(X): - for iy,y in enumerate(Y): - for iz,z in enumerate(Z): - current_sol[ix,iy,iz] = analytic_sol(x,y,z,t) + current_sol = np.zeros((len(X), len(Y), len(Z))) + for ix, x in enumerate(X): + for iy, y in enumerate(Y): + for iz, z in enumerate(Z): + current_sol[ix, iy, iz] = analytic_sol(x, y, z, t) if np.mean(abs(current_sol - Vx)) > eps: print("Failed") sys.exit(1) diff --git a/test/MHD/sphBragViscosity/setup.cpp b/test/MHD/sphBragViscosity/setup.cpp index fa20e1684..f2f7df03e 100644 --- a/test/MHD/sphBragViscosity/setup.cpp +++ b/test/MHD/sphBragViscosity/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/MHD/sphBragViscosity/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" diff --git a/test/MHD/sphBragViscosity/testme.json b/test/MHD/sphBragViscosity/testme.json index 900a34a77..017a9b625 100644 --- a/test/MHD/sphBragViscosity/testme.json +++ b/test/MHD/sphBragViscosity/testme.json @@ -1,16 +1,13 @@ { - "namings": "ini", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "noplot": true, - "vectPot": false, - "single": false, - "reconstruction": 2, - "mpi": false, - "standardTest": false, - "tolerance": 1e-15 - } - ] + "default": { + "dumpname": "dump.0001.dmp", + "ini": "idefix.ini", + "noplot": true, + "vectPot": false, + "single": false, + "reconstruction": 2, + "mpi": false, + "standardTest": false, + "tolerance": 1e-15 + } } diff --git a/test/MHD/sphBragViscosity/testme.py b/test/MHD/sphBragViscosity/testme.py index b6c3467ea..c63bdbd67 100755 --- a/test/MHD/sphBragViscosity/testme.py +++ b/test/MHD/sphBragViscosity/testme.py @@ -1,45 +1,61 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/MHD/sphBragViscosity/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini"] - # loop on all the ini files for this test - name = "dump.0001.dmp" - for ini in inifiles: - test.run(inputFile=ini) -## The current test is not physics, but merely a non-regression check -## The physical test needs to have the divergence of the velocity field artifiacially set to zero -# test.standardTest() - if test.init: - test.makeReference(filename=name) + # loop on all the ini files for this test + name = "dump.0001.dmp" + for ini in inifiles: + test.run(inputFile=ini) + ## The current test is not physics, but merely a non-regression check + ## The physical test needs to have the divergence of the velocity field artifiacially set to zero + # test.standardTest() + if test.init: + test.makeReference(filename=name) - test.nonRegressionTest(filename=name, tolerance=1e-15) + test.nonRegressionTest(filename=name, tolerance=1e-15) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename="dump.0001.dmp") - else: - testMe(test) + if test.check: + test.checkOnly(filename="dump.0001.dmp") + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) diff --git a/test/Planet/Planet3Body/definitions.hpp b/test/Planet/Planet3Body/definitions.hpp index e2c9ceee3..e0b023a38 100644 --- a/test/Planet/Planet3Body/definitions.hpp +++ b/test/Planet/Planet3Body/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Planet/Planet3Body/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 2 #define DIMENSIONS 2 diff --git a/test/Planet/Planet3Body/python/testidefix.py b/test/Planet/Planet3Body/python/testidefix.py index a3b7f64d5..203b81962 100755 --- a/test/Planet/Planet3Body/python/testidefix.py +++ b/test/Planet/Planet3Body/python/testidefix.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Planet/Planet3Body/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Tue Dec 21 12:04:41 2021 @@ -8,75 +22,99 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import numpy as np + def separation(resonance): a = int(resonance[-1]) b = int(resonance[0]) - return pow(a/b,2/3) + return pow(a / b, 2 / 3) + def datafile(filename): return np.loadtxt(filename, dtype="float64").T + planet0 = datafile("../planet0.dat") planet1 = datafile("../planet1.dat") resonance = "3:2" plot_orbit = False -theta1 = np.arctan2(planet1[2],planet1[1]) +theta1 = np.arctan2(planet1[2], planet1[1]) apl1 = 1.0 ecc1 = 0.0 -rpl1 = (apl1*(1-ecc1**2)/(1-ecc1*np.cos(theta1))) -xpl1 = rpl1*np.cos(theta1) -ypl1 = rpl1*np.sin(theta1) +rpl1 = apl1 * (1 - ecc1**2) / (1 - ecc1 * np.cos(theta1)) +xpl1 = rpl1 * np.cos(theta1) +ypl1 = rpl1 * np.sin(theta1) -theta0 = np.arctan2(planet0[2],planet0[1]) +theta0 = np.arctan2(planet0[2], planet0[1]) apl0 = separation(resonance) ecc0 = 0.2 -rpl0 = (apl0*(1-ecc0**2)/(1+ecc0*np.cos(theta0))) -xpl0 = rpl0*np.cos(theta0) -ypl0 = rpl0*np.sin(theta0) +rpl0 = apl0 * (1 - ecc0**2) / (1 + ecc0 * np.cos(theta0)) +xpl0 = rpl0 * np.cos(theta0) +ypl0 = rpl0 * np.sin(theta0) if plot_orbit: import matplotlib.pyplot as plt + plt.close("all") - fig, ax = plt.subplots(figsize=(6,6)) + fig, ax = plt.subplots(figsize=(6, 6)) ax.scatter(planet0[1], planet0[2], ls="-", c="k") ax.scatter(planet1[1], planet1[2], ls="--", c="r") - ax.scatter(0,0,marker="+") + ax.scatter(0, 0, marker="+") ax.plot(xpl0, ypl0, c="b") ax.plot(xpl1, ypl1, c="g") - ax.set(xlabel="x", ylabel="y", aspect="equal", xlim=(-1.2,1.2), ylim=(-1.2,1.2)) + ax.set(xlabel="x", ylabel="y", aspect="equal", xlim=(-1.2, 1.2), ylim=(-1.2, 1.2)) # ax.set(xlabel="x", ylabel="y", aspect="equal", xlim=(-2.5,2.5), ylim=(-2.5,2.5)) - ax.set_title(r"m$_{\rm sat}=0$, e=%.1f, n/n$_s$=%s (a0=%.3f)"%(ecc0,resonance,separation(resonance=resonance)), pad=20) + ax.set_title( + r"m$_{\rm sat}=0$, e=%.1f, n/n$_s$=%s (a0=%.3f)" + % (ecc0, resonance, separation(resonance=resonance)), + pad=20, + ) # plt.savefig(f"resonance{resonance}_e{ecc}.png", dpi=200) fig.tight_layout() - fig2, ax2 = plt.subplots(figsize=(6,6)) - ax2.scatter(theta0, (rpl0-np.sqrt(planet0[1]**2 + planet0[2]**2))/(rpl0), c="b", s=200) - ax2.scatter(theta1, (rpl1-np.sqrt(planet1[1]**2 + planet1[2]**2))/(rpl1), c="g", s=200) + fig2, ax2 = plt.subplots(figsize=(6, 6)) + ax2.scatter( + theta0, + (rpl0 - np.sqrt(planet0[1] ** 2 + planet0[2] ** 2)) / (rpl0), + c="b", + s=200, + ) + ax2.scatter( + theta1, + (rpl1 - np.sqrt(planet1[1] ** 2 + planet1[2] ** 2)) / (rpl1), + c="g", + s=200, + ) plt.show() -rpl0_sim = np.sqrt(planet0[1]**2 + planet0[2]**2) -rpl1_sim = np.sqrt(planet1[1]**2 + planet1[2]**2) +rpl0_sim = np.sqrt(planet0[1] ** 2 + planet0[2] ** 2) +rpl1_sim = np.sqrt(planet1[1] ** 2 + planet1[2] ** 2) -mean0 = np.mean(100*(rpl0-rpl0_sim)/rpl0) -mean1 = np.mean(100*(rpl1-rpl1_sim)/rpl1) -std0 = np.std(100*(rpl0-rpl0_sim)/rpl0) -std1 = np.std(100*(rpl1-rpl1_sim)/rpl1) +mean0 = np.mean(100 * (rpl0 - rpl0_sim) / rpl0) +mean1 = np.mean(100 * (rpl1 - rpl1_sim) / rpl1) +std0 = np.std(100 * (rpl0 - rpl0_sim) / rpl0) +std1 = np.std(100 * (rpl1 - rpl1_sim) / rpl1) error_mean0 = mean0 error_mean1 = mean1 -error_dispersion0 = np.max([abs(mean0+std0),abs(mean0-std0)]) -error_dispersion1 = np.max([abs(mean1+std1),abs(mean1-std1)]) - -print("Mean Error (planet0)=%s"%error_mean0) -print("Mean Error (planet1)=%s"%error_mean1) -print("max(mean +/- std) (planet0)=%s"%error_dispersion0) -print("max(mean +/- std) (planet1)=%s"%error_dispersion1) -if error_mean0<1.0e-10 and error_dispersion0<1.0e-9 and error_mean1<1.0e-10 and error_dispersion1<1.0e-9: +error_dispersion0 = np.max([abs(mean0 + std0), abs(mean0 - std0)]) +error_dispersion1 = np.max([abs(mean1 + std1), abs(mean1 - std1)]) + +print("Mean Error (planet0)=%s" % error_mean0) +print("Mean Error (planet1)=%s" % error_mean1) +print("max(mean +/- std) (planet0)=%s" % error_dispersion0) +print("max(mean +/- std) (planet1)=%s" % error_dispersion1) +if ( + error_mean0 < 1.0e-10 + and error_dispersion0 < 1.0e-9 + and error_mean1 < 1.0e-10 + and error_dispersion1 < 1.0e-9 +): print("SUCCESS!") sys.exit(0) else: diff --git a/test/Planet/Planet3Body/setup.cpp b/test/Planet/Planet3Body/setup.cpp index 01bae094e..68d349aa4 100644 --- a/test/Planet/Planet3Body/setup.cpp +++ b/test/Planet/Planet3Body/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Planet/Planet3Body/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include #include "idefix.hpp" diff --git a/test/Planet/Planet3Body/testme.py b/test/Planet/Planet3Body/testme.py index 6edac53ee..c9c6056cf 100755 --- a/test/Planet/Planet3Body/testme.py +++ b/test/Planet/Planet3Body/testme.py @@ -1,47 +1,64 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Planet/Planet3Body/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + +tolerance = 2e-11 -tolerance=2e-11 def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename=name) - test.standardTest() - test.nonRegressionTest(filename=name,tolerance=tolerance) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename=name) + test.standardTest() + test.nonRegressionTest(filename=name, tolerance=tolerance) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.checkOnly(filename=name,tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name, tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - - test.mpi=True - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + + test.mpi = True + testMe(test) diff --git a/test/Planet/PlanetMigration2D/definitions.hpp b/test/Planet/PlanetMigration2D/definitions.hpp index 9ea3b16e5..36708e428 100644 --- a/test/Planet/PlanetMigration2D/definitions.hpp +++ b/test/Planet/PlanetMigration2D/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Planet/PlanetMigration2D/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 2 diff --git a/test/Planet/PlanetMigration2D/python/testidefix.py b/test/Planet/PlanetMigration2D/python/testidefix.py index 897d7b53f..3c954fe6c 100755 --- a/test/Planet/PlanetMigration2D/python/testidefix.py +++ b/test/Planet/PlanetMigration2D/python/testidefix.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Planet/PlanetMigration2D/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Tue Dec 21 12:04:41 2021 @@ -8,42 +22,46 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import numpy as np + def datafile(filename): return np.loadtxt(filename, dtype="float64").T + plot = False planet_ref = datafile("planet0.ref.dat") planet = datafile("../planet0.dat") -migration_ref = np.sqrt(planet_ref[1]**2+planet_ref[2]**2+planet_ref[3]**2) -migration = np.sqrt(planet[1]**2+planet[2]**2+planet[3]**2) +migration_ref = np.sqrt(planet_ref[1] ** 2 + planet_ref[2] ** 2 + planet_ref[3] ** 2) +migration = np.sqrt(planet[1] ** 2 + planet[2] ** 2 + planet[3] ** 2) # Compute the error on the planet distance -error_d=np.max(np.abs((migration-migration_ref)/migration_ref)) +error_d = np.max(np.abs((migration - migration_ref) / migration_ref)) torque_ref = datafile("tqwk0.ref.dat") torque = datafile("../tqwk0.dat") -tq_tot_ref = torque_ref[1]+torque_ref[2] -tq_tot = torque[1]+torque[2] +tq_tot_ref = torque_ref[1] + torque_ref[2] +tq_tot = torque[1] + torque[2] # Compute the error on the planet torque -error_t=np.max(np.abs((tq_tot-tq_tot_ref)/tq_tot_ref)) +error_t = np.max(np.abs((tq_tot - tq_tot_ref) / tq_tot_ref)) if plot: import matplotlib.pyplot as plt + plt.close("all") - fig, ax = plt.subplots(figsize=(6,6)) + fig, ax = plt.subplots(figsize=(6, 6)) ax.plot(planet_ref[-1], migration_ref, ls="-", c="k", label="dist ref") ax.plot(planet[-1], migration, ls="--", c="r", label="dist new") ax.set(xlabel="time") fig.tight_layout() ax.legend(frameon=False) - fig2, ax2 = plt.subplots(figsize=(6,6)) + fig2, ax2 = plt.subplots(figsize=(6, 6)) ax2.plot(torque_ref[-1], tq_tot_ref, ls="-", c="k", label="torque ref") ax2.plot(torque[-1], tq_tot, ls="--", c="r", label="torque new") ax2.set(xlabel="time") @@ -51,12 +69,12 @@ def datafile(filename): ax2.legend(frameon=False) plt.show() -diff_torque = np.max(np.abs(tq_tot-tq_tot_ref)) -print("diff_torque=%e"%diff_torque) -print("Error_dist=%e"%error_d) +diff_torque = np.max(np.abs(tq_tot - tq_tot_ref)) +print("diff_torque=%e" % diff_torque) +print("Error_dist=%e" % error_d) # print("Error_torque=%e"%error_t) # if error_d<5.0e-2 and error_t<5.0e-2 and error_rho<5.0e-2: -if error_d<5.0e-2 and diff_torque<1.0e-15: +if error_d < 5.0e-2 and diff_torque < 1.0e-15: print("SUCCESS!") sys.exit(0) else: diff --git a/test/Planet/PlanetMigration2D/setup.cpp b/test/Planet/PlanetMigration2D/setup.cpp index c6ec4cb64..1c8b03ab6 100644 --- a/test/Planet/PlanetMigration2D/setup.cpp +++ b/test/Planet/PlanetMigration2D/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Planet/PlanetMigration2D/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include #include "idefix.hpp" diff --git a/test/Planet/PlanetMigration2D/testme.json b/test/Planet/PlanetMigration2D/testme.json index 6e1e08537..af4f84b43 100644 --- a/test/Planet/PlanetMigration2D/testme.json +++ b/test/Planet/PlanetMigration2D/testme.json @@ -1,16 +1,18 @@ { - "namings": "ini,mpi", + "namings": "mpi", + "default": { + "dumpname": "dump.0001.dmp", + "ini": "idefix.ini", + "noplot": true, + "vectPot": false, + "single": false, + "reconstruction": 2, + "dec": [2,2], + "tolerance": 1e-13 + }, "variants": [ { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "noplot": true, - "vectPot": false, - "single": false, - "reconstruction": 2, - "mpi": [false, true], - "dec": ["2","2"], - "tolerance": 1e-13 + "mpi": [false, true] } ] } diff --git a/test/Planet/PlanetMigration2D/testme.py b/test/Planet/PlanetMigration2D/testme.py index 6c435cbd3..90797e808 100755 --- a/test/Planet/PlanetMigration2D/testme.py +++ b/test/Planet/PlanetMigration2D/testme.py @@ -1,49 +1,66 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Planet/PlanetMigration2D/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + +tolerance = 1e-13 -tolerance=1e-13 def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename=name) - test.standardTest() - test.nonRegressionTest(filename=name,tolerance=tolerance) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename=name) + test.standardTest() + test.nonRegressionTest(filename=name, tolerance=tolerance) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2'] + test.dec = ["2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename=name,tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name, tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - - test.mpi=True - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + + test.mpi = True + testMe(test) diff --git a/test/Planet/PlanetPlanetRK42D/definitions.hpp b/test/Planet/PlanetPlanetRK42D/definitions.hpp index bdda00a5d..4d1f27120 100644 --- a/test/Planet/PlanetPlanetRK42D/definitions.hpp +++ b/test/Planet/PlanetPlanetRK42D/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Planet/PlanetPlanetRK42D/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 2 diff --git a/test/Planet/PlanetPlanetRK42D/python/testidefix.py b/test/Planet/PlanetPlanetRK42D/python/testidefix.py index c3d4aa9b6..49e618734 100755 --- a/test/Planet/PlanetPlanetRK42D/python/testidefix.py +++ b/test/Planet/PlanetPlanetRK42D/python/testidefix.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Planet/PlanetPlanetRK42D/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Tue Dec 21 12:04:41 2021 @@ -7,22 +21,25 @@ """ import os -import sys import re +import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import numpy as np + def filter_index(t): # get read of data previously generated (when the code was restarted) - tref=t[-1] - idx=np.array([2]) - idx[0]=t.size-1 - for i in range(t.size-2,0,-1): - if(t[i] (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include #include "idefix.hpp" diff --git a/test/Planet/PlanetPlanetRK42D/testme.json b/test/Planet/PlanetPlanetRK42D/testme.json index 0181b072f..ece6aa2d6 100644 --- a/test/Planet/PlanetPlanetRK42D/testme.json +++ b/test/Planet/PlanetPlanetRK42D/testme.json @@ -1,16 +1,18 @@ { - "namings": "ini,mpi", + "namings": "mpi", + "default": { + "ini": "idefix.ini", + "dumpname": "dump.0002.dmp", + "noplot": true, + "vectPot": false, + "single": false, + "reconstruction": 2, + "dec": [2,2], + "tolerance": 1e-13 + }, "variants": [ { - "dumpname": "dump.0002.dmp", - "ini": ["idefix.ini"], - "noplot": true, - "vectPot": false, - "single": false, - "reconstruction": 2, "mpi": [false, true], - "dec": ["2","2"], - "tolerance": 1e-13, "multirun": [ { "nonRegressionTest": true, diff --git a/test/Planet/PlanetPlanetRK42D/testme.py b/test/Planet/PlanetPlanetRK42D/testme.py index 9521aabac..aea485b9f 100755 --- a/test/Planet/PlanetPlanetRK42D/testme.py +++ b/test/Planet/PlanetPlanetRK42D/testme.py @@ -1,59 +1,81 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Planet/PlanetPlanetRK42D/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0002.dmp" +name = "dump.0002.dmp" + +tolerance = 1e-13 -tolerance=1e-13 def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini"] - - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename=name) - test.standardTest() - test.nonRegressionTest(filename=name,tolerance=tolerance) - - # Test the restart option - dump_mtime = os.path.getmtime("dump.0001.dmp") - vtk_mtime = os.path.getmtime("data.0005.vtk") - - test.run(inputFile=ini, restart=1) - test.standardTest() - test.nonRegressionTest(filename=name,tolerance=tolerance) - - assert dump_mtime == os.path.getmtime("dump.0001.dmp"), "Dump was overwritten on restart" - assert vtk_mtime == os.path.getmtime("data.0005.vtk"), "VTK file was overwritten on restart" - -test=tst.idfxTest(__file__) + test.configure() + test.compile() + inifiles = ["idefix.ini"] + + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename=name) + test.standardTest() + test.nonRegressionTest(filename=name, tolerance=tolerance) + + # Test the restart option + dump_mtime = os.path.getmtime("dump.0001.dmp") + vtk_mtime = os.path.getmtime("data.0005.vtk") + + test.run(inputFile=ini, restart=1) + test.standardTest() + test.nonRegressionTest(filename=name, tolerance=tolerance) + + assert dump_mtime == os.path.getmtime("dump.0001.dmp"), ( + "Dump was overwritten on restart" + ) + assert vtk_mtime == os.path.getmtime("data.0005.vtk"), ( + "VTK file was overwritten on restart" + ) + + +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2'] + test.dec = ["2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename=name,tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name, tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - - test.mpi=True - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + + test.mpi = True + testMe(test) diff --git a/test/Planet/PlanetSpiral2D/definitions.hpp b/test/Planet/PlanetSpiral2D/definitions.hpp index 9ea3b16e5..f8a35e36e 100644 --- a/test/Planet/PlanetSpiral2D/definitions.hpp +++ b/test/Planet/PlanetSpiral2D/definitions.hpp @@ -1,3 +1,16 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Planet/PlanetSpiral2D/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** #define COMPONENTS 3 #define DIMENSIONS 2 diff --git a/test/Planet/PlanetSpiral2D/python/testidefix.py b/test/Planet/PlanetSpiral2D/python/testidefix.py index ee9f5acc2..facbca2ee 100755 --- a/test/Planet/PlanetSpiral2D/python/testidefix.py +++ b/test/Planet/PlanetSpiral2D/python/testidefix.py @@ -1,19 +1,34 @@ #!/usr/bin/env python +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Planet/PlanetSpiral2D/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # coding: utf-8 -import sys import os -sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK +import sys -import numpy as np +sys.path.append(os.getenv("IDEFIX_DIR")) import matplotlib.pyplot as plt +import numpy as np + +from pytools.vtk_io import readVTK on = 3 ds = readVTK(f"../data.{on:04d}.vtk", geometry="polar") Rmed = ds.x -phimed = (ds.y/(np.pi))%2*np.pi-np.pi +phimed = (ds.y / (np.pi)) % 2 * np.pi - np.pi dR = np.ediff1d(ds.x)[0] h0 = 0.05 @@ -21,22 +36,24 @@ # Planet in a fixed circular orbit Rp = 1.0 -hp = h0*pow(Rp,flaring) +hp = h0 * pow(Rp, flaring) # See Bae+Zhu (2018, I) # Dominant azimuthal wavenumber when # perturbation driven by point mass perturber -mdom = int((1/2)*pow(hp,-1)) +mdom = int((1 / 2) * pow(hp, -1)) # Lindblad resonance radii -Rmp = pow(1+1/mdom,2/3)*Rp -Rmm = pow(1-1/mdom,2/3)*Rp +Rmp = pow(1 + 1 / mdom, 2 / 3) * Rp +Rmm = pow(1 - 1 / mdom, 2 / 3) * Rp + def find_nearest(array, value): array = np.asarray(array) idx = (np.abs(array - value)).argmin() return idx + def omega( R, *, @@ -46,7 +63,8 @@ def omega( if info: print(f"keplerian = {keplerian}") if keplerian: - return(pow(R,-3/2)) + return pow(R, -3 / 2) + def soundSpeed( R, @@ -61,7 +79,8 @@ def soundSpeed( print(f"h0 = {h0:.2f}") print(f"flaring = {flaring:.2f}") if isotherm: - return(h0*pow(R,flaring-1/2)) + return h0 * pow(R, flaring - 1 / 2) + def _integral( RR, @@ -76,16 +95,16 @@ def _integral( if info: print(f"planet in Rp = {Rp:.2f}") print(f"dominant phi-wavenumber m = {m}") - Rm = pow(1+np.sign(resonance)*1/m,2/3)*Rp - data = (omega(Rmed, info=info)/soundSpeed(Rmed, h0=h0, flaring=flaring, info=info))*pow(abs(pow(1-pow(Rmed/Rp,3/2),2)-1/m/m),1/2) + Rm = pow(1 + np.sign(resonance) * 1 / m, 2 / 3) * Rp + data = ( + omega(Rmed, info=info) / soundSpeed(Rmed, h0=h0, flaring=flaring, info=info) + ) * pow(abs(pow(1 - pow(Rmed / Rp, 3 / 2), 2) - 1 / m / m), 1 / 2) k = find_nearest(Rmed, Rm) kk = find_nearest(Rmed, RR) if np.sign(resonance) > 0: - integ = ( - np.nansum( - (data * dR)[k : kk + 1], - dtype="float64", - ) + integ = np.nansum( + (data * dR)[k : kk + 1], + dtype="float64", ) else: integ = -( @@ -96,8 +115,9 @@ def _integral( ) return integ + # Phase equation for m,n -#(phi-wavenumber,order of the spiral) +# (phi-wavenumber,order of the spiral) def phaseEquation( RR, *, @@ -107,17 +127,22 @@ def phaseEquation( Rp=Rp, info=False, ): - phieq = -np.sign(RR-Rp)*np.pi/4/m + 2*np.pi*n/m -_integral( - RR, - resonance=resonance, - m=mdom, - Rp=Rp, - h0=h0, - flaring=flaring, - info=info, - ) + phieq = ( + -np.sign(RR - Rp) * np.pi / 4 / m + + 2 * np.pi * n / m + - _integral( + RR, + resonance=resonance, + m=mdom, + Rp=Rp, + h0=h0, + flaring=flaring, + info=info, + ) + ) return phieq + plot = False RwkzMin = find_nearest(Rmed, 0.7) @@ -126,45 +151,45 @@ def phaseEquation( spiralR = [] spiralP = [] spiralP_theo = [] -for ir in range(RwkzMin, RwkzMax+1): - if (Rmed[ir] < Rmm): - rho = ds.data["RHO"][ir,:,0] +for ir in range(RwkzMin, RwkzMax + 1): + if Rmed[ir] < Rmm: + rho = ds.data["RHO"][ir, :, 0] spiralR.append(Rmed[ir]) - spiralP.append(phimed[find_nearest(rho,rho.max())]) - spiralP_theo.append(phaseEquation(Rmed[ir],resonance=-1)) - if (Rmed[ir] > Rmp): - rho = ds.data["RHO"][ir,:,0] + spiralP.append(phimed[find_nearest(rho, rho.max())]) + spiralP_theo.append(phaseEquation(Rmed[ir], resonance=-1)) + if Rmed[ir] > Rmp: + rho = ds.data["RHO"][ir, :, 0] spiralR.append(Rmed[ir]) - spiralP.append(phimed[find_nearest(rho,rho.max())]) - spiralP_theo.append(phaseEquation(Rmed[ir],resonance=+1)) + spiralP.append(phimed[find_nearest(rho, rho.max())]) + spiralP_theo.append(phaseEquation(Rmed[ir], resonance=+1)) spiralR_theo = spiralR spiralP = np.array(spiralP) -spiralP_theo = (np.array(spiralP_theo)/(np.pi))%2*np.pi-np.pi +spiralP_theo = (np.array(spiralP_theo) / (np.pi)) % 2 * np.pi - np.pi if plot: - fig, ax = plt.subplots(figsize=(5,4)) + fig, ax = plt.subplots(figsize=(5, 4)) ax.axvline(x=1.0, ls="--", c="k") - ax.scatter(spiralR_theo,spiralP_theo, c="r",marker="+", label="theoretical") - ax.scatter(spiralR,spiralP,c="k",marker="x", label=r"max $\rho$ simulation") + ax.scatter(spiralR_theo, spiralP_theo, c="r", marker="+", label="theoretical") + ax.scatter(spiralR, spiralP, c="k", marker="x", label=r"max $\rho$ simulation") fig.tight_layout() ax.legend(frameon=False) fig2, ax2 = plt.subplots() - ax2.scatter(spiralR, 100*(spiralP-spiralP_theo)/spiralP_theo) + ax2.scatter(spiralR, 100 * (spiralP - spiralP_theo) / spiralP_theo) fig2.tight_layout() plt.show() -mean = np.mean(100*(spiralP-spiralP_theo)/spiralP_theo) -std = np.std(100*(spiralP-spiralP_theo)/spiralP_theo) +mean = np.mean(100 * (spiralP - spiralP_theo) / spiralP_theo) +std = np.std(100 * (spiralP - spiralP_theo) / spiralP_theo) error_mean = mean -error_dispersion = np.max([abs(mean+std),abs(mean-std)]) +error_dispersion = np.max([abs(mean + std), abs(mean - std)]) -print("Mean Error=%.2f"%error_mean) -print("max(mean +/- std)=%.2f"%error_dispersion) -if error_mean<1.0 and error_dispersion<5.0: +print("Mean Error=%.2f" % error_mean) +print("max(mean +/- std)=%.2f" % error_dispersion) +if error_mean < 1.0 and error_dispersion < 5.0: print("SUCCESS!") sys.exit(0) else: diff --git a/test/Planet/PlanetSpiral2D/setup.cpp b/test/Planet/PlanetSpiral2D/setup.cpp index 064d6c75b..94d4b7544 100644 --- a/test/Planet/PlanetSpiral2D/setup.cpp +++ b/test/Planet/PlanetSpiral2D/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Planet/PlanetSpiral2D/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include #include "idefix.hpp" diff --git a/test/Planet/PlanetSpiral2D/testme.json b/test/Planet/PlanetSpiral2D/testme.json index 6e1e08537..af4f84b43 100644 --- a/test/Planet/PlanetSpiral2D/testme.json +++ b/test/Planet/PlanetSpiral2D/testme.json @@ -1,16 +1,18 @@ { - "namings": "ini,mpi", + "namings": "mpi", + "default": { + "dumpname": "dump.0001.dmp", + "ini": "idefix.ini", + "noplot": true, + "vectPot": false, + "single": false, + "reconstruction": 2, + "dec": [2,2], + "tolerance": 1e-13 + }, "variants": [ { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "noplot": true, - "vectPot": false, - "single": false, - "reconstruction": 2, - "mpi": [false, true], - "dec": ["2","2"], - "tolerance": 1e-13 + "mpi": [false, true] } ] } diff --git a/test/Planet/PlanetSpiral2D/testme.py b/test/Planet/PlanetSpiral2D/testme.py index 6c435cbd3..35c7b0cef 100755 --- a/test/Planet/PlanetSpiral2D/testme.py +++ b/test/Planet/PlanetSpiral2D/testme.py @@ -1,49 +1,66 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Planet/PlanetSpiral2D/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + +tolerance = 1e-13 -tolerance=1e-13 def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename=name) - test.standardTest() - test.nonRegressionTest(filename=name,tolerance=tolerance) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename=name) + test.standardTest() + test.nonRegressionTest(filename=name, tolerance=tolerance) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2'] + test.dec = ["2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename=name,tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name, tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - - test.mpi=True - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + + test.mpi = True + testMe(test) diff --git a/test/Planet/PlanetTorque3D/definitions.hpp b/test/Planet/PlanetTorque3D/definitions.hpp index a81d32864..a96f5f62e 100644 --- a/test/Planet/PlanetTorque3D/definitions.hpp +++ b/test/Planet/PlanetTorque3D/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Planet/PlanetTorque3D/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/Planet/PlanetTorque3D/python/testidefix.py b/test/Planet/PlanetTorque3D/python/testidefix.py index 47477f64b..a940d711a 100755 --- a/test/Planet/PlanetTorque3D/python/testidefix.py +++ b/test/Planet/PlanetTorque3D/python/testidefix.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Planet/PlanetTorque3D/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Tue Dec 21 12:04:41 2021 @@ -8,12 +22,15 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import numpy as np + def datafile(filename): return np.loadtxt(filename, dtype="float64").T + plot = False torque_ref = datafile("tqwk0.ref.dat") @@ -21,18 +38,19 @@ def datafile(filename): # Factor 2 here because the reference has been computed for half the disk # (hence the torque was half) -tq_tot_ref = 2*(torque_ref[1]+torque_ref[2]) -tq_tot = torque[1]+torque[2] -tqh_tot_ref = 2*(torque_ref[3]+torque_ref[4]) -tqh_tot = torque[3]+torque[4] +tq_tot_ref = 2 * (torque_ref[1] + torque_ref[2]) +tq_tot = torque[1] + torque[2] +tqh_tot_ref = 2 * (torque_ref[3] + torque_ref[4]) +tqh_tot = torque[3] + torque[4] # Compute the error on the planet torque -error_t=np.max(np.abs((tq_tot-tq_tot_ref)/tq_tot_ref)) -error_th=np.max(np.abs((tqh_tot-tqh_tot_ref)/tqh_tot_ref)) +error_t = np.max(np.abs((tq_tot - tq_tot_ref) / tq_tot_ref)) +error_th = np.max(np.abs((tqh_tot - tqh_tot_ref) / tqh_tot_ref)) if plot: import matplotlib.pyplot as plt - fig, ax = plt.subplots(figsize=(6,6)) + + fig, ax = plt.subplots(figsize=(6, 6)) ax.plot(torque_ref[-1], tq_tot_ref, ls="-", c="k", label="torque ref") ax.plot(torque[-1], tq_tot, ls="--", c="r", label="torque new") ax.plot(torque_ref[-1], tqh_tot_ref, ls="-", c="b", label="torque nohill ref") @@ -43,14 +61,14 @@ def datafile(filename): plt.show() -diff_torque = np.max(np.abs(tq_tot-tq_tot_ref)) -diff_torqueh = np.max(np.abs(tqh_tot-tqh_tot_ref)) -print("diff_torque=%e"%diff_torque) -print("diff_torque_nohill=%e"%diff_torqueh) +diff_torque = np.max(np.abs(tq_tot - tq_tot_ref)) +diff_torqueh = np.max(np.abs(tqh_tot - tqh_tot_ref)) +print("diff_torque=%e" % diff_torque) +print("diff_torque_nohill=%e" % diff_torqueh) # print("Error_torque=%e"%error_t) # print("Error_torque_nohill=%e"%error_th) # if error_t<5.0e-2 and error_th<5.0e-2 and error_rho<5.0e-2: -if diff_torque<1.0e-12 and diff_torqueh<1.0e-13: +if diff_torque < 1.0e-12 and diff_torqueh < 1.0e-13: print("SUCCESS!") sys.exit(0) else: diff --git a/test/Planet/PlanetTorque3D/setup.cpp b/test/Planet/PlanetTorque3D/setup.cpp index 367f49c8b..0b07e0a80 100644 --- a/test/Planet/PlanetTorque3D/setup.cpp +++ b/test/Planet/PlanetTorque3D/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Planet/PlanetTorque3D/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include #include "idefix.hpp" diff --git a/test/Planet/PlanetTorque3D/testme.json b/test/Planet/PlanetTorque3D/testme.json index 085fb6c0f..8cb617f9c 100644 --- a/test/Planet/PlanetTorque3D/testme.json +++ b/test/Planet/PlanetTorque3D/testme.json @@ -1,16 +1,18 @@ { "namings": "ini,mpi", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "vectPot": false, + "single": false, + "reconstruction": 2, + "dec": [2,2,2], + "tolerance": 1e-13 + }, "variants": [ { - "dumpname": "dump.0001.dmp", "ini": ["idefix.ini"], - "noplot": true, - "vectPot": false, - "single": false, - "reconstruction": 2, - "mpi": [false, true], - "dec": ["2","2","2"], - "tolerance": 1e-13 + "mpi": [false, true] } ] } diff --git a/test/Planet/PlanetTorque3D/testme.py b/test/Planet/PlanetTorque3D/testme.py index 4393636ea..634cf4745 100755 --- a/test/Planet/PlanetTorque3D/testme.py +++ b/test/Planet/PlanetTorque3D/testme.py @@ -1,49 +1,66 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Planet/PlanetTorque3D/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + +tolerance = 1e-13 -tolerance=1e-13 def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - if test.init and not test.mpi: - test.makeReference(filename=name) - test.standardTest() - test.nonRegressionTest(filename=name,tolerance=tolerance) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + if test.init and not test.mpi: + test.makeReference(filename=name) + test.standardTest() + test.nonRegressionTest(filename=name, tolerance=tolerance) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2','2'] + test.dec = ["2", "2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename=name,tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name, tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - - test.mpi=True - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + + test.mpi = True + testMe(test) diff --git a/test/Planet/PlanetsIsActiveRK52D/definitions.hpp b/test/Planet/PlanetsIsActiveRK52D/definitions.hpp index bdda00a5d..0ab1b2d4c 100644 --- a/test/Planet/PlanetsIsActiveRK52D/definitions.hpp +++ b/test/Planet/PlanetsIsActiveRK52D/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Planet/PlanetsIsActiveRK52D/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 2 diff --git a/test/Planet/PlanetsIsActiveRK52D/python/testidefix.py b/test/Planet/PlanetsIsActiveRK52D/python/testidefix.py index 0a5f91499..0b6f254ec 100755 --- a/test/Planet/PlanetsIsActiveRK52D/python/testidefix.py +++ b/test/Planet/PlanetsIsActiveRK52D/python/testidefix.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Planet/PlanetsIsActiveRK52D/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Tue Dec 21 12:04:41 2021 @@ -8,20 +22,25 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import numpy as np + def find_nearest(array, value): array = np.asarray(array) idx = (np.abs(array - value)).argmin() return idx + def datafile(filename): return np.loadtxt(filename, dtype="float64").T + def time_dist(filename): columns = datafile(filename) - return(columns[-1], np.sqrt(columns[1]**2+columns[2]**2+columns[3]**2)) + return (columns[-1], np.sqrt(columns[1] ** 2 + columns[2] ** 2 + columns[3] ** 2)) + plot = False @@ -39,14 +58,15 @@ def time_dist(filename): time1, dist1 = time_dist("../planet1.dat") # Compute the error on the planet distance -error_d0=np.max(np.abs((dist0-dist0_rk5)/dist0_rk5)) -error_d1=np.max(np.abs((dist1-dist1_rk5)/dist1_rk5)) +error_d0 = np.max(np.abs((dist0 - dist0_rk5) / dist0_rk5)) +error_d1 = np.max(np.abs((dist1 - dist1_rk5) / dist1_rk5)) if plot: import matplotlib.pyplot as plt + plt.close("all") - fig, ax = plt.subplots(figsize=(6,6)) + fig, ax = plt.subplots(figsize=(6, 6)) ax.plot(time0_rk5, dist0_rk5, ls="-", c="k", label="dist 0 rk5") ax.plot(time0, dist0, ls="--", c="r", label="dist 0 new") ax.plot(time1_rk5, dist1_rk5, ls="-", c="b", label="dist 1 rk5") @@ -54,7 +74,7 @@ def time_dist(filename): ax.set(xlabel="time") fig.tight_layout() ax.legend(frameon=False) - fig1, ax1 = plt.subplots(figsize=(6,6)) + fig1, ax1 = plt.subplots(figsize=(6, 6)) ax1.plot(time0_active, active0, ls="-", c="k", label="isActive 0") ax1.plot(time1_active, active1, ls="--", c="r", label="isActive 1") ax1.axvline(x=time0_active[i0_active], c="k", ls=":") @@ -64,11 +84,19 @@ def time_dist(filename): ax1.legend(frameon=False) plt.show() -print("Error_dist0=%e"%error_d0) -print("Error_dist1=%e"%error_d1) -print("active0[ip0]=%e"%active0[i0_active]) -print("active1[ip1]=%e, active1[ip1-1]=%e"%(active1[i1_active],active1[i1_active-1])) -if error_d0<5.0e-10 and error_d1<5.0e-10 and active0[i0_active]==1.0 and active1[i1_active]==1.0 and active1[i1_active-1]==0.0: +print("Error_dist0=%e" % error_d0) +print("Error_dist1=%e" % error_d1) +print("active0[ip0]=%e" % active0[i0_active]) +print( + "active1[ip1]=%e, active1[ip1-1]=%e" % (active1[i1_active], active1[i1_active - 1]) +) +if ( + error_d0 < 5.0e-10 + and error_d1 < 5.0e-10 + and active0[i0_active] == 1.0 + and active1[i1_active] == 1.0 + and active1[i1_active - 1] == 0.0 +): print("SUCCESS!") sys.exit(0) else: diff --git a/test/Planet/PlanetsIsActiveRK52D/setup.cpp b/test/Planet/PlanetsIsActiveRK52D/setup.cpp index a1d16c590..810e41134 100644 --- a/test/Planet/PlanetsIsActiveRK52D/setup.cpp +++ b/test/Planet/PlanetsIsActiveRK52D/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Planet/PlanetsIsActiveRK52D/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include #include "idefix.hpp" diff --git a/test/Planet/PlanetsIsActiveRK52D/testme.json b/test/Planet/PlanetsIsActiveRK52D/testme.json index 30848aecd..3f219b916 100644 --- a/test/Planet/PlanetsIsActiveRK52D/testme.json +++ b/test/Planet/PlanetsIsActiveRK52D/testme.json @@ -1,17 +1,19 @@ { "namings": "ini,mpi", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "vectPot": false, + "single": false, + "reconstruction": 2, + "dec": [2,2], + "nonRegressionTest": false, + "tolerance": 1e-13 + }, "variants": [ { - "dumpname": "dump.0001.dmp", "ini": ["idefix-rk4.ini", "idefix-rk5.ini"], - "noplot": true, - "vectPot": false, - "single": false, - "reconstruction": 2, - "mpi": [false, true], - "dec": ["2","2"], - "nonRegressionTest": false, - "tolerance": 1e-13 + "mpi": [false, true] } ] } diff --git a/test/Planet/PlanetsIsActiveRK52D/testme.py b/test/Planet/PlanetsIsActiveRK52D/testme.py index aca39ae53..a491b6960 100755 --- a/test/Planet/PlanetsIsActiveRK52D/testme.py +++ b/test/Planet/PlanetsIsActiveRK52D/testme.py @@ -1,47 +1,64 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Planet/PlanetsIsActiveRK52D/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + +tolerance = 1e-13 -tolerance=1e-13 def testMe(test): - test.configure() - test.compile() - inifiles=["idefix-rk4.ini", "idefix-rk5.ini"] + test.configure() + test.compile() + inifiles = ["idefix-rk4.ini", "idefix-rk5.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - test.standardTest() - # test.nonRegressionTest(filename=name,tolerance=tolerance) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + test.standardTest() + # test.nonRegressionTest(filename=name,tolerance=tolerance) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2'] + test.dec = ["2", "2"] if not test.all: - if(test.check): - test.checkOnly(filename=name,tolerance=tolerance) - else: - testMe(test) + if test.check: + test.checkOnly(filename=name, tolerance=tolerance) + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - - test.mpi=True - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + + test.mpi = True + testMe(test) diff --git a/test/Pluto/HD/FargoPlanet/definitions.h b/test/Pluto/HD/FargoPlanet/definitions.h index 255f8c034..2ad5d3ed0 100644 --- a/test/Pluto/HD/FargoPlanet/definitions.h +++ b/test/Pluto/HD/FargoPlanet/definitions.h @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/FargoPlanet/definitions.h +// +// Last modified : 03/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define PHYSICS HD #define DIMENSIONS 2 #define COMPONENTS 2 diff --git a/test/Pluto/HD/FargoPlanet/eos.c b/test/Pluto/HD/FargoPlanet/eos.c index 61845c172..dfa3d46cc 100644 --- a/test/Pluto/HD/FargoPlanet/eos.c +++ b/test/Pluto/HD/FargoPlanet/eos.c @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/FargoPlanet/eos.c +// +// Last modified : 03/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "pluto.h" /* **************************************************************** */ diff --git a/test/Pluto/HD/FargoPlanet/init.c b/test/Pluto/HD/FargoPlanet/init.c index 5504b18d9..84617d9ba 100644 --- a/test/Pluto/HD/FargoPlanet/init.c +++ b/test/Pluto/HD/FargoPlanet/init.c @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/FargoPlanet/init.c +// +// Last modified : 03/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + /* ///////////////////////////////////////////////////////////////////// */ /*! \file diff --git a/test/Pluto/HD/MachReflection/definitions.h b/test/Pluto/HD/MachReflection/definitions.h index f35626906..b6b70e77f 100644 --- a/test/Pluto/HD/MachReflection/definitions.h +++ b/test/Pluto/HD/MachReflection/definitions.h @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/MachReflection/definitions.h +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define PHYSICS HD #define DIMENSIONS 2 #define COMPONENTS 2 diff --git a/test/Pluto/HD/MachReflection/init.c b/test/Pluto/HD/MachReflection/init.c index c556f91a7..827244ba0 100644 --- a/test/Pluto/HD/MachReflection/init.c +++ b/test/Pluto/HD/MachReflection/init.c @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/MachReflection/init.c +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + /* ///////////////////////////////////////////////////////////////////// */ /*! \file diff --git a/test/Pluto/HD/PlanetDisk/definitions.h b/test/Pluto/HD/PlanetDisk/definitions.h index 255f8c034..1b3fdb259 100644 --- a/test/Pluto/HD/PlanetDisk/definitions.h +++ b/test/Pluto/HD/PlanetDisk/definitions.h @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/PlanetDisk/definitions.h +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define PHYSICS HD #define DIMENSIONS 2 #define COMPONENTS 2 diff --git a/test/Pluto/HD/PlanetDisk/eos.c b/test/Pluto/HD/PlanetDisk/eos.c index 61845c172..99638be92 100644 --- a/test/Pluto/HD/PlanetDisk/eos.c +++ b/test/Pluto/HD/PlanetDisk/eos.c @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/PlanetDisk/eos.c +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "pluto.h" /* **************************************************************** */ diff --git a/test/Pluto/HD/PlanetDisk/init.c b/test/Pluto/HD/PlanetDisk/init.c index bd35a262f..bfd688d1e 100644 --- a/test/Pluto/HD/PlanetDisk/init.c +++ b/test/Pluto/HD/PlanetDisk/init.c @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/PlanetDisk/init.c +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + /* ///////////////////////////////////////////////////////////////////// */ /*! \file diff --git a/test/Pluto/HD/PlanetDisk3D/definitions.h b/test/Pluto/HD/PlanetDisk3D/definitions.h index 5ad7a3154..158d745d8 100644 --- a/test/Pluto/HD/PlanetDisk3D/definitions.h +++ b/test/Pluto/HD/PlanetDisk3D/definitions.h @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/PlanetDisk3D/definitions.h +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define PHYSICS HD #define DIMENSIONS 3 #define COMPONENTS 3 diff --git a/test/Pluto/HD/PlanetDisk3D/eos.c b/test/Pluto/HD/PlanetDisk3D/eos.c index 61845c172..4dd7543ee 100644 --- a/test/Pluto/HD/PlanetDisk3D/eos.c +++ b/test/Pluto/HD/PlanetDisk3D/eos.c @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/PlanetDisk3D/eos.c +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "pluto.h" /* **************************************************************** */ diff --git a/test/Pluto/HD/PlanetDisk3D/init.c b/test/Pluto/HD/PlanetDisk3D/init.c index 39577c773..4f58ac906 100644 --- a/test/Pluto/HD/PlanetDisk3D/init.c +++ b/test/Pluto/HD/PlanetDisk3D/init.c @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/PlanetDisk3D/init.c +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + /* ///////////////////////////////////////////////////////////////////// */ /*! \file diff --git a/test/Pluto/HD/ViscousFlowPastCylinder/definitions.h b/test/Pluto/HD/ViscousFlowPastCylinder/definitions.h index bf502011c..87318e709 100644 --- a/test/Pluto/HD/ViscousFlowPastCylinder/definitions.h +++ b/test/Pluto/HD/ViscousFlowPastCylinder/definitions.h @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/ViscousFlowPastCylinder/definitions.h +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define PHYSICS HD #define DIMENSIONS 2 #define COMPONENTS 2 diff --git a/test/Pluto/HD/ViscousFlowPastCylinder/init.c b/test/Pluto/HD/ViscousFlowPastCylinder/init.c index 508503db9..e6b8636db 100644 --- a/test/Pluto/HD/ViscousFlowPastCylinder/init.c +++ b/test/Pluto/HD/ViscousFlowPastCylinder/init.c @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/ViscousFlowPastCylinder/init.c +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + /* ///////////////////////////////////////////////////////////////////// */ /*! \file diff --git a/test/Pluto/HD/ViscousFlowPastCylinder/userdef_output.c b/test/Pluto/HD/ViscousFlowPastCylinder/userdef_output.c index b93b41710..abff72fe0 100644 --- a/test/Pluto/HD/ViscousFlowPastCylinder/userdef_output.c +++ b/test/Pluto/HD/ViscousFlowPastCylinder/userdef_output.c @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/ViscousFlowPastCylinder/userdef_output.c +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "pluto.h" /* *************************************************************** */ diff --git a/test/Pluto/HD/ViscousFlowPastCylinder/visc_nu.c b/test/Pluto/HD/ViscousFlowPastCylinder/visc_nu.c index 19579a520..7f21a9478 100644 --- a/test/Pluto/HD/ViscousFlowPastCylinder/visc_nu.c +++ b/test/Pluto/HD/ViscousFlowPastCylinder/visc_nu.c @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/ViscousFlowPastCylinder/visc_nu.c +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + /* /////////////////////////////////////////////////////////////////// */ /*! \file * \brief Specification of explicit first and second viscosity coefficients*/ diff --git a/test/Pluto/HD/sod/definitions.h b/test/Pluto/HD/sod/definitions.h index 5c7fb3253..5e7810097 100644 --- a/test/Pluto/HD/sod/definitions.h +++ b/test/Pluto/HD/sod/definitions.h @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/sod/definitions.h +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define PHYSICS HD #define DIMENSIONS 1 #define COMPONENTS 1 diff --git a/test/Pluto/HD/sod/init.c b/test/Pluto/HD/sod/init.c index 39971778e..b94887a48 100644 --- a/test/Pluto/HD/sod/init.c +++ b/test/Pluto/HD/sod/init.c @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/HD/sod/init.c +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + /* ///////////////////////////////////////////////////////////////////// */ /*! \file diff --git a/test/Pluto/HD/sod/python/idefixTools.py b/test/Pluto/HD/sod/python/idefixTools.py index a8d2dc86f..90d9ac685 100644 --- a/test/Pluto/HD/sod/python/idefixTools.py +++ b/test/Pluto/HD/sod/python/idefixTools.py @@ -1,3 +1,18 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Pluto/HD/sod/python/idefixTools.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # -*- coding: utf-8 -*- """ Created on Mon Nov 3 15:23:00 2014 @@ -5,371 +20,385 @@ @author: glesur """ - import numpy as np + + class DataStructure: pass + # Read a vtk file def readVTKCart(filename): try: - fid=open(filename,"rb") + fid = open(filename, "rb") except: print("Can't open file") return 0 # define our datastructure - V=DataStructure() + V = DataStructure() # raw data which will be read from the file - V.data={} + V.data = {} - #print("Hello") + # print("Hello") # datatype we read - dt=np.dtype(">f") # Big endian single precision floats + dt = np.dtype(">f") # Big endian single precision floats - s=fid.readline() # VTK DataFile Version x.x - s=fid.readline() # Comments + s = fid.readline() # VTK DataFile Version x.x + s = fid.readline() # Comments - s=fid.readline() # BINARY - s=fid.readline() # DATASET RECTILINEAR_GRID - slist=s.split() - grid_type=str(slist[1],'utf-8') - if(grid_type != "RECTILINEAR_GRID"): + s = fid.readline() # BINARY + s = fid.readline() # DATASET RECTILINEAR_GRID + slist = s.split() + grid_type = str(slist[1], "utf-8") + if grid_type != "RECTILINEAR_GRID": print("ERROR: Wrong VTK file type.") print("This routine can only open Cartesian or Cylindrical VTK files.") fid.close() return 0 - s=fid.readline() # DIMENSIONS NX NY NZ - slist=s.split() - #s=fid.readline() # Extre line feed - V.nx=int(slist[1]) - V.ny=int(slist[2]) - V.nz=int(slist[3]) + s = fid.readline() # DIMENSIONS NX NY NZ + slist = s.split() + # s=fid.readline() # Extre line feed + V.nx = int(slist[1]) + V.ny = int(slist[2]) + V.nz = int(slist[3]) - s=fid.readline() # X_COORDINATES NX float + s = fid.readline() # X_COORDINATES NX float - x=np.fromfile(fid,dt,V.nx) - s=fid.readline() # Extra line feed added by pluto + x = np.fromfile(fid, dt, V.nx) + s = fid.readline() # Extra line feed added by pluto + s = fid.readline() # X_COORDINATES NX float - s=fid.readline() # X_COORDINATES NX float + y = np.fromfile(fid, dt, V.ny) + s = fid.readline() # Extra line feed added by pluto - y=np.fromfile(fid,dt,V.ny) - s=fid.readline() # Extra line feed added by pluto + s = fid.readline() # X_COORDINATES NX float - s=fid.readline() # X_COORDINATES NX float + z = np.fromfile(fid, dt, V.nz) + s = fid.readline() # Extra line feed added by pluto - z=np.fromfile(fid,dt,V.nz) - s=fid.readline() # Extra line feed added by pluto + s = fid.readline() # POINT_DATA NXNYNZ + slist = s.split() + point_type = str(slist[0], "utf-8") + npoints = int(slist[1]) + s = fid.readline() # EXTRA LINE FEED - - s=fid.readline() # POINT_DATA NXNYNZ - - slist=s.split() - point_type=str(slist[0],'utf-8') - npoints=int(slist[1]) - s=fid.readline() # EXTRA LINE FEED - - if(point_type == "CELL_DATA"): + if point_type == "CELL_DATA": # The file contains face coordinates, so we extrapolate to get the cell center coordinates. - if V.nx>1: - V.nx=V.nx-1 - V.x=0.5*(x[1:]+x[:-1]) + if V.nx > 1: + V.nx = V.nx - 1 + V.x = 0.5 * (x[1:] + x[:-1]) else: - V.x=x - if V.ny>1: - V.ny=V.ny-1 - V.y=0.5*(y[1:]+y[:-1]) + V.x = x + if V.ny > 1: + V.ny = V.ny - 1 + V.y = 0.5 * (y[1:] + y[:-1]) else: - V.y=y - if V.nz>1: - V.nz=V.nz-1 - V.z=0.5*(z[1:]+z[:-1]) + V.y = y + if V.nz > 1: + V.nz = V.nz - 1 + V.z = 0.5 * (z[1:] + z[:-1]) else: - V.z=z - elif(point_type == "POINT_DATA"): - V.x=x - V.y=y - V.z=z + V.z = z + elif point_type == "POINT_DATA": + V.x = x + V.y = y + V.z = z - if V.nx*V.ny*V.nz != npoints: + if V.nx * V.ny * V.nz != npoints: print("ERROR: Grid size incompatible with number of points in the data set") while 1: - s=fid.readline() # SCALARS/VECTORS name data_type (ex: SCALARS imagedata unsigned_char) - #print repr(s) - if len(s)<2: # leave if end of file + s = ( + fid.readline() + ) # SCALARS/VECTORS name data_type (ex: SCALARS imagedata unsigned_char) + # print repr(s) + if len(s) < 2: # leave if end of file break - slist=s.split() - datatype=str(slist[0],'utf-8') - varname=str(slist[1],'utf-8') + slist = s.split() + datatype = str(slist[0], "utf-8") + varname = str(slist[1], "utf-8") if datatype == "SCALARS": fid.readline() # LOOKUP TABLE - V.data[varname] = np.transpose(np.fromfile(fid,dt,V.nx*V.ny*V.nz).reshape(V.nz,V.ny,V.nx)) + V.data[varname] = np.transpose( + np.fromfile(fid, dt, V.nx * V.ny * V.nz).reshape(V.nz, V.ny, V.nx) + ) elif datatype == "VECTORS": - Q=np.fromfile(fid,dt,3*V.nx*V.ny*V.nz) + Q = np.fromfile(fid, dt, 3 * V.nx * V.ny * V.nz) - V.data[varname+'_X']=np.transpose(Q[::3].reshape(V.nz,V.ny,V.nx)) - V.data[varname+'_Y']=np.transpose(Q[1::3].reshape(V.nz,V.ny,V.nx)) - V.data[varname+'_Z']=np.transpose(Q[2::3].reshape(V.nz,V.ny,V.nx)) + V.data[varname + "_X"] = np.transpose(Q[::3].reshape(V.nz, V.ny, V.nx)) + V.data[varname + "_Y"] = np.transpose(Q[1::3].reshape(V.nz, V.ny, V.nx)) + V.data[varname + "_Z"] = np.transpose(Q[2::3].reshape(V.nz, V.ny, V.nx)) else: print("ERROR: Unknown datatype %s" % datatype) - break; + break - fid.readline() #extra line feed + fid.readline() # extra line feed fid.close() return V + # Read a vtk file def readVTKPolar(filename): try: - fid=open(filename,"rb") + fid = open(filename, "rb") except: print("Can't open file") return 0 # define our datastructure - V=DataStructure() + V = DataStructure() # raw data which will be read from the file - V.data={} + V.data = {} - #print("Hello") + # print("Hello") # datatype we read - dt=np.dtype(">f") # Big endian single precision floats + dt = np.dtype(">f") # Big endian single precision floats - s=fid.readline() # VTK DataFile Version x.x - s=fid.readline() # Comments + s = fid.readline() # VTK DataFile Version x.x + s = fid.readline() # Comments - s=fid.readline() # BINARY - s=fid.readline() # DATASET RECTILINEAR_GRID + s = fid.readline() # BINARY + s = fid.readline() # DATASET RECTILINEAR_GRID print(s) - slist=s.split() - grid_type=str(slist[1],'utf-8') - if(grid_type != "STRUCTURED_GRID"): + slist = s.split() + grid_type = str(slist[1], "utf-8") + if grid_type != "STRUCTURED_GRID": print("ERROR: Wrong VTK file type.") - print("Current type is: %s"%(grid_type)) + print("Current type is: %s" % (grid_type)) print("This routine can only open Polar VTK files.") fid.close() return 0 - s=fid.readline() # DIMENSIONS NX NY NZ - slist=s.split() - V.nx=int(slist[1]) - V.ny=int(slist[2]) - V.nz=int(slist[3]) + s = fid.readline() # DIMENSIONS NX NY NZ + slist = s.split() + V.nx = int(slist[1]) + V.ny = int(slist[2]) + V.nz = int(slist[3]) - print("nx=%d, ny=%d, nz=%d"%(V.nx,V.ny,V.nz)) + print("nx=%d, ny=%d, nz=%d" % (V.nx, V.ny, V.nz)) - s=fid.readline() # POINTS NXNYNZ float - slist=s.split() - npoints=int(slist[1]) - points=np.fromfile(fid,dt,3*npoints) - s=fid.readline() # EXTRA LINE FEED + s = fid.readline() # POINTS NXNYNZ float + slist = s.split() + npoints = int(slist[1]) + points = np.fromfile(fid, dt, 3 * npoints) + s = fid.readline() # EXTRA LINE FEED - V.points=points + V.points = points - if V.nx*V.ny*V.nz != npoints: + if V.nx * V.ny * V.nz != npoints: print("ERROR: Grid size incompatible with number of points in the data set") return 0 # Reconstruct the polar coordinate system - x1d=points[::3] - y1d=points[1::3] - z1d=points[2::3] - - xcart=np.transpose(x1d.reshape(V.nz,V.ny,V.nx)) - ycart=np.transpose(y1d.reshape(V.nz,V.ny,V.nx)) - zcart=np.transpose(z1d.reshape(V.nz,V.ny,V.nx)) - - r=np.sqrt(xcart[:,0,0]**2+ycart[:,0,0]**2) - theta=np.unwrap(np.arctan2(ycart[0,:,0],xcart[0,:,0])) - z=zcart[0,0,:] - - s=fid.readline() # CELL_DATA (NX-1)(NY-1)(NZ-1) - slist=s.split() - data_type=str(slist[0],'utf-8') - if(data_type != "CELL_DATA"): + x1d = points[::3] + y1d = points[1::3] + z1d = points[2::3] + + xcart = np.transpose(x1d.reshape(V.nz, V.ny, V.nx)) + ycart = np.transpose(y1d.reshape(V.nz, V.ny, V.nx)) + zcart = np.transpose(z1d.reshape(V.nz, V.ny, V.nx)) + + r = np.sqrt(xcart[:, 0, 0] ** 2 + ycart[:, 0, 0] ** 2) + theta = np.unwrap(np.arctan2(ycart[0, :, 0], xcart[0, :, 0])) + z = zcart[0, 0, :] + + s = fid.readline() # CELL_DATA (NX-1)(NY-1)(NZ-1) + slist = s.split() + data_type = str(slist[0], "utf-8") + if data_type != "CELL_DATA": print("ERROR: this routine expect CELL DATA as produced by PLUTO.") fid.close() return 0 - s=fid.readline() # Line feed + s = fid.readline() # Line feed # Perform averaging on coordinate system to get cell centers # The file contains face coordinates, so we extrapolate to get the cell center coordinates. - if V.nx>1: - V.nx=V.nx-1 - V.x=0.5*(r[1:]+r[:-1]) + if V.nx > 1: + V.nx = V.nx - 1 + V.x = 0.5 * (r[1:] + r[:-1]) else: - V.x=r - if V.ny>1: - V.ny=V.ny-1 - V.y=(0.5*(theta[1:]+theta[:-1])+np.pi)%(2.0*np.pi)-np.pi + V.x = r + if V.ny > 1: + V.ny = V.ny - 1 + V.y = (0.5 * (theta[1:] + theta[:-1]) + np.pi) % (2.0 * np.pi) - np.pi else: - V.y=theta - if V.nz>1: - V.nz=V.nz-1 - V.z=0.5*(z[1:]+z[:-1]) + V.y = theta + if V.nz > 1: + V.nz = V.nz - 1 + V.z = 0.5 * (z[1:] + z[:-1]) else: - V.z=z - + V.z = z while 1: - s=fid.readline() # SCALARS/VECTORS name data_type (ex: SCALARS imagedata unsigned_char) - #print repr(s) - if len(s)<2: # leave if end of file + s = ( + fid.readline() + ) # SCALARS/VECTORS name data_type (ex: SCALARS imagedata unsigned_char) + # print repr(s) + if len(s) < 2: # leave if end of file break - slist=s.split() - datatype=str(slist[0],'utf-8') - varname=str(slist[1],'utf-8') + slist = s.split() + datatype = str(slist[0], "utf-8") + varname = str(slist[1], "utf-8") if datatype == "SCALARS": fid.readline() # LOOKUP TABLE - V.data[varname] = np.transpose(np.fromfile(fid,dt,V.nx*V.ny*V.nz).reshape(V.nz,V.ny,V.nx)) + V.data[varname] = np.transpose( + np.fromfile(fid, dt, V.nx * V.ny * V.nz).reshape(V.nz, V.ny, V.nx) + ) elif datatype == "VECTORS": - Q=np.fromfile(fid,dt,3*V.nx*V.ny*V.nz) + Q = np.fromfile(fid, dt, 3 * V.nx * V.ny * V.nz) - V.data[varname+'_X']=np.transpose(Q[::3].reshape(V.nz,V.ny,V.nx)) - V.data[varname+'_Y']=np.transpose(Q[1::3].reshape(V.nz,V.ny,V.nx)) - V.data[varname+'_Z']=np.transpose(Q[2::3].reshape(V.nz,V.ny,V.nx)) + V.data[varname + "_X"] = np.transpose(Q[::3].reshape(V.nz, V.ny, V.nx)) + V.data[varname + "_Y"] = np.transpose(Q[1::3].reshape(V.nz, V.ny, V.nx)) + V.data[varname + "_Z"] = np.transpose(Q[2::3].reshape(V.nz, V.ny, V.nx)) else: print("ERROR: Unknown datatype %s" % datatype) - break; + break - fid.readline() #extra line feed + fid.readline() # extra line feed fid.close() return V + # Read a vtk file def readVTKSpherical(filename): try: - fid=open(filename,"rb") + fid = open(filename, "rb") except: print("Can't open file") return 0 # define our datastructure - V=DataStructure() + V = DataStructure() # raw data which will be read from the file - V.data={} + V.data = {} - #print("Hello") + # print("Hello") # datatype we read - dt=np.dtype(">f") # Big endian single precision floats + dt = np.dtype(">f") # Big endian single precision floats - s=fid.readline() # VTK DataFile Version x.x - s=fid.readline() # Comments + s = fid.readline() # VTK DataFile Version x.x + s = fid.readline() # Comments - s=fid.readline() # BINARY - s=fid.readline() # DATASET RECTILINEAR_GRID - slist=s.split() - grid_type=str(slist[1],'utf-8') - if(grid_type != "STRUCTURED_GRID"): + s = fid.readline() # BINARY + s = fid.readline() # DATASET RECTILINEAR_GRID + slist = s.split() + grid_type = str(slist[1], "utf-8") + if grid_type != "STRUCTURED_GRID": print("ERROR: Wrong VTK file type.") print("This routine can only open Spherical VTK files.") fid.close() return 0 - s=fid.readline() # DIMENSIONS NX NY NZ - slist=s.split() - V.nx=int(slist[1]) - V.ny=int(slist[2]) - V.nz=int(slist[3]) + s = fid.readline() # DIMENSIONS NX NY NZ + slist = s.split() + V.nx = int(slist[1]) + V.ny = int(slist[2]) + V.nz = int(slist[3]) - if(V.nz==1): - is2d=1 + if V.nz == 1: + is2d = 1 else: - is2d=0 + is2d = 0 - s=fid.readline() # POINTS NXNYNZ float - slist=s.split() - npoints=int(slist[1]) - points=np.fromfile(fid,dt,3*npoints) - s=fid.readline() # EXTRA LINE FEED + s = fid.readline() # POINTS NXNYNZ float + slist = s.split() + npoints = int(slist[1]) + points = np.fromfile(fid, dt, 3 * npoints) + s = fid.readline() # EXTRA LINE FEED - V.points=points + V.points = points - if V.nx*V.ny*V.nz != npoints: + if V.nx * V.ny * V.nz != npoints: print("ERROR: Grid size incompatible with number of points in the data set") return 0 # Reconstruct the spherical coordinate system + x1d = points[::3] + y1d = points[1::3] + z1d = points[2::3] - x1d=points[::3] - y1d=points[1::3] - z1d=points[2::3] - - xcart=np.transpose(x1d.reshape(V.nz,V.ny,V.nx)) - ycart=np.transpose(y1d.reshape(V.nz,V.ny,V.nx)) - zcart=np.transpose(z1d.reshape(V.nz,V.ny,V.nx)) + xcart = np.transpose(x1d.reshape(V.nz, V.ny, V.nx)) + ycart = np.transpose(y1d.reshape(V.nz, V.ny, V.nx)) + zcart = np.transpose(z1d.reshape(V.nz, V.ny, V.nx)) - if(is2d): - r=np.sqrt(xcart[:,0,0]**2+ycart[:,0,0]**2) - phi=np.unwrap(np.arctan2(zcart[0,0,:],xcart[0,0,:])) - theta=np.arccos(ycart[0,:,0]/np.sqrt(xcart[0,:,0]**2+ycart[0,:,0]**2)) + if is2d: + r = np.sqrt(xcart[:, 0, 0] ** 2 + ycart[:, 0, 0] ** 2) + phi = np.unwrap(np.arctan2(zcart[0, 0, :], xcart[0, 0, :])) + theta = np.arccos( + ycart[0, :, 0] / np.sqrt(xcart[0, :, 0] ** 2 + ycart[0, :, 0] ** 2) + ) else: - r=np.sqrt(xcart[:,0,0]**2+ycart[:,0,0]**2+zcart[:,0,0]**2) - phi=np.unwrap(np.arctan2(ycart[0,0,:],xcart[0,0,:])) - theta=np.arccos(zcart[0,:,0]/np.sqrt(xcart[0,:,0]**2+ycart[0,:,0]**2+zcart[0,:,0]**2)) - - - s=fid.readline() # CELL_DATA (NX-1)(NY-1)(NZ-1) - slist=s.split() - data_type=str(slist[0],'utf-8') - if(data_type != "CELL_DATA"): + r = np.sqrt(xcart[:, 0, 0] ** 2 + ycart[:, 0, 0] ** 2 + zcart[:, 0, 0] ** 2) + phi = np.unwrap(np.arctan2(ycart[0, 0, :], xcart[0, 0, :])) + theta = np.arccos( + zcart[0, :, 0] + / np.sqrt(xcart[0, :, 0] ** 2 + ycart[0, :, 0] ** 2 + zcart[0, :, 0] ** 2) + ) + + s = fid.readline() # CELL_DATA (NX-1)(NY-1)(NZ-1) + slist = s.split() + data_type = str(slist[0], "utf-8") + if data_type != "CELL_DATA": print("ERROR: this routine expect CELL DATA as produced by PLUTO.") fid.close() return 0 - s=fid.readline() # Line feed + s = fid.readline() # Line feed # Perform averaging on coordinate system to get cell centers # The file contains face coordinates, so we extrapolate to get the cell center coordinates. - if V.nx>1: - V.nx=V.nx-1 - V.r=0.5*(r[1:]+r[:-1]) + if V.nx > 1: + V.nx = V.nx - 1 + V.r = 0.5 * (r[1:] + r[:-1]) else: - V.x=r - if V.ny>1: - V.ny=V.ny-1 - V.theta=0.5*(theta[1:]+theta[:-1]) + V.x = r + if V.ny > 1: + V.ny = V.ny - 1 + V.theta = 0.5 * (theta[1:] + theta[:-1]) else: - V.y=theta - if V.nz>1: - V.nz=V.nz-1 - V.phi=(0.5*(phi[1:]+phi[:-1])+np.pi)%(2.0*np.pi)-np.pi + V.y = theta + if V.nz > 1: + V.nz = V.nz - 1 + V.phi = (0.5 * (phi[1:] + phi[:-1]) + np.pi) % (2.0 * np.pi) - np.pi else: - V.phi=phi - + V.phi = phi while 1: - s=fid.readline() # SCALARS/VECTORS name data_type (ex: SCALARS imagedata unsigned_char) - #print repr(s) - if len(s)<2: # leave if end of file + s = ( + fid.readline() + ) # SCALARS/VECTORS name data_type (ex: SCALARS imagedata unsigned_char) + # print repr(s) + if len(s) < 2: # leave if end of file break - slist=s.split() - datatype=str(slist[0],'utf-8') - varname=str(slist[1],'utf-8') + slist = s.split() + datatype = str(slist[0], "utf-8") + varname = str(slist[1], "utf-8") if datatype == "SCALARS": fid.readline() # LOOKUP TABLE - V.data[varname] = np.transpose(np.fromfile(fid,dt,V.nx*V.ny*V.nz).reshape(V.nz,V.ny,V.nx)) + V.data[varname] = np.transpose( + np.fromfile(fid, dt, V.nx * V.ny * V.nz).reshape(V.nz, V.ny, V.nx) + ) elif datatype == "VECTORS": - Q=np.fromfile(fid,dt,3*V.nx*V.ny*V.nz) + Q = np.fromfile(fid, dt, 3 * V.nx * V.ny * V.nz) - V.data[varname+'_X']=np.transpose(Q[::3].reshape(V.nz,V.ny,V.nx)) - V.data[varname+'_Y']=np.transpose(Q[1::3].reshape(V.nz,V.ny,V.nx)) - V.data[varname+'_Z']=np.transpose(Q[2::3].reshape(V.nz,V.ny,V.nx)) + V.data[varname + "_X"] = np.transpose(Q[::3].reshape(V.nz, V.ny, V.nx)) + V.data[varname + "_Y"] = np.transpose(Q[1::3].reshape(V.nz, V.ny, V.nx)) + V.data[varname + "_Z"] = np.transpose(Q[2::3].reshape(V.nz, V.ny, V.nx)) else: print("ERROR: Unknown datatype %s" % datatype) - break; + break - fid.readline() #extra line feed + fid.readline() # extra line feed fid.close() return V diff --git a/test/Pluto/HD/sod/python/sod.py b/test/Pluto/HD/sod/python/sod.py index 717c27ca6..14236465b 100755 --- a/test/Pluto/HD/sod/python/sod.py +++ b/test/Pluto/HD/sod/python/sod.py @@ -1,4 +1,19 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Pluto/HD/sod/python/sod.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # -*- coding: utf-8 -*- """ Created on Thu Mar 5 11:27:16 2020 @@ -13,7 +28,7 @@ import scipy.optimize -def sound_speed(gamma, pressure, density, dustFrac=0.): +def sound_speed(gamma, pressure, density, dustFrac=0.0): """ Calculate sound speed, scaled by the dust fraction according to: @@ -23,27 +38,28 @@ def sound_speed(gamma, pressure, density, dustFrac=0.): Where :math:`\epsilon` is the dustFrac """ scale = np.sqrt(1 - dustFrac) - return np.sqrt(gamma * pressure/ density) * scale + return np.sqrt(gamma * pressure / density) * scale + -def shock_tube_function(p4, p1, p5, rho1, rho5, gamma, dustFrac=0.): +def shock_tube_function(p4, p1, p5, rho1, rho5, gamma, dustFrac=0.0): """ Shock tube equation """ - z = (p4 / p5 - 1.) + z = p4 / p5 - 1.0 c1 = sound_speed(gamma, p1, rho1, dustFrac) c5 = sound_speed(gamma, p5, rho5, dustFrac) - gm1 = gamma - 1. - gp1 = gamma + 1. - g2 = 2. * gamma + gm1 = gamma - 1.0 + gp1 = gamma + 1.0 + g2 = 2.0 * gamma - fact = gm1 / g2 * (c5 / c1) * z / np.sqrt(1. + gp1 / g2 * z) - fact = (1. - fact) ** (g2 / gm1) + fact = gm1 / g2 * (c5 / c1) * z / np.sqrt(1.0 + gp1 / g2 * z) + fact = (1.0 - fact) ** (g2 / gm1) return p1 * fact - p4 -def calculate_regions(pl, ul, rhol, pr, ur, rhor, gamma=1.4, dustFrac=0.): +def calculate_regions(pl, ul, rhol, pr, ur, rhor, gamma=1.4, dustFrac=0.0): """ Compute regions :rtype : tuple @@ -70,18 +86,18 @@ def calculate_regions(pl, ul, rhol, pr, ur, rhor, gamma=1.4, dustFrac=0.): p4 = scipy.optimize.fsolve(shock_tube_function, p1, (p1, p5, rho1, rho5, gamma))[0] # compute post-shock density and velocity - z = (p4 / p5 - 1.) + z = p4 / p5 - 1.0 c5 = sound_speed(gamma, p5, rho5, dustFrac) - gm1 = gamma - 1. - gp1 = gamma + 1. + gm1 = gamma - 1.0 + gp1 = gamma + 1.0 gmfac1 = 0.5 * gm1 / gamma gmfac2 = 0.5 * gp1 / gamma - fact = np.sqrt(1. + gmfac2 * z) + fact = np.sqrt(1.0 + gmfac2 * z) u4 = c5 * z / (gamma * fact) - rho4 = rho5 * (1. + gmfac2 * z) / (1. + gmfac1 * z) + rho4 = rho5 * (1.0 + gmfac2 * z) / (1.0 + gmfac1 * z) # shock speed w = c5 * fact @@ -89,11 +105,11 @@ def calculate_regions(pl, ul, rhol, pr, ur, rhor, gamma=1.4, dustFrac=0.): # compute values at foot of rarefaction p3 = p4 u3 = u4 - rho3 = rho1 * (p3 / p1)**(1. / gamma) + rho3 = rho1 * (p3 / p1) ** (1.0 / gamma) return (p1, rho1, u1), (p3, rho3, u3), (p4, rho4, u4), (p5, rho5, u5), w -def calc_positions(pl, pr, region1, region3, w, xi, t, gamma, dustFrac=0.): +def calc_positions(pl, pr, region1, region3, w, xi, t, gamma, dustFrac=0.0): """ :return: tuple of positions in the following order -> Head of Rarefaction: xhd, Foot of Rarefaction: xft, @@ -125,21 +141,39 @@ def region_states(pl, pr, region1, region3, region4, region5): where the value is a string, obviously """ if pl > pr: - return {'Region 1': region1, - 'Region 2': 'RAREFACTION', - 'Region 3': region3, - 'Region 4': region4, - 'Region 5': region5} + return { + "Region 1": region1, + "Region 2": "RAREFACTION", + "Region 3": region3, + "Region 4": region4, + "Region 5": region5, + } else: - return {'Region 1': region5, - 'Region 2': region4, - 'Region 3': region3, - 'Region 4': 'RAREFACTION', - 'Region 5': region1} - - -def create_arrays(pl, pr, xl, xr, positions, state1, state3, state4, state5, - npts, gamma, t, xi, dustFrac=0.): + return { + "Region 1": region5, + "Region 2": region4, + "Region 3": region3, + "Region 4": "RAREFACTION", + "Region 5": region1, + } + + +def create_arrays( + pl, + pr, + xl, + xr, + positions, + state1, + state3, + state4, + state5, + npts, + gamma, + t, + xi, + dustFrac=0.0, +): """ :return: tuple of x, p, rho and u values across the domain of interest """ @@ -148,8 +182,8 @@ def create_arrays(pl, pr, xl, xr, positions, state1, state3, state4, state5, p3, rho3, u3 = state3 p4, rho4, u4 = state4 p5, rho5, u5 = state5 - gm1 = gamma - 1. - gp1 = gamma + 1. + gm1 = gamma - 1.0 + gp1 = gamma + 1.0 x_arr = np.linspace(xl, xr, npts) rho = np.zeros(npts, dtype=float) @@ -163,10 +197,10 @@ def create_arrays(pl, pr, xl, xr, positions, state1, state3, state4, state5, p[i] = p1 u[i] = u1 elif x < xft: - u[i] = 2. / gp1 * (c1 + (x - xi) / t) - fact = 1. - 0.5 * gm1 * u[i] / c1 - rho[i] = rho1 * fact ** (2. / gm1) - p[i] = p1 * fact ** (2. * gamma / gm1) + u[i] = 2.0 / gp1 * (c1 + (x - xi) / t) + fact = 1.0 - 0.5 * gm1 * u[i] / c1 + rho[i] = rho1 * fact ** (2.0 / gm1) + p[i] = p1 * fact ** (2.0 * gamma / gm1) elif x < xcd: rho[i] = rho3 p[i] = p3 @@ -194,10 +228,10 @@ def create_arrays(pl, pr, xl, xr, positions, state1, state3, state4, state5, p[i] = p3 u[i] = -u3 elif x < xhd: - u[i] = -2. / gp1 * (c1 + (xi - x) / t) - fact = 1. + 0.5 * gm1 * u[i] / c1 - rho[i] = rho1 * fact ** (2. / gm1) - p[i] = p1 * fact ** (2. * gamma / gm1) + u[i] = -2.0 / gp1 * (c1 + (xi - x) / t) + fact = 1.0 + 0.5 * gm1 * u[i] / c1 + rho[i] = rho1 * fact ** (2.0 / gm1) + p[i] = p1 * fact ** (2.0 * gamma / gm1) else: rho[i] = rho1 p[i] = p1 @@ -206,8 +240,7 @@ def create_arrays(pl, pr, xl, xr, positions, state1, state3, state4, state5, return x_arr, p, rho, u -def solve(left_state, right_state, geometry, t, gamma=1.4, npts=500, - dustFrac=0.): +def solve(left_state, right_state, geometry, t, gamma=1.4, npts=500, dustFrac=0.0): """ Solves the Sod shock tube problem (i.e. riemann problem) of discontinuity across an interface. @@ -248,34 +281,57 @@ def solve(left_state, right_state, geometry, t, gamma=1.4, npts=500, # basic checking if xl >= xr: - print('xl has to be less than xr!') + print("xl has to be less than xr!") exit() if xi >= xr or xi <= xl: - print('xi has in between xl and xr!') + print("xi has in between xl and xr!") exit() # calculate regions - region1, region3, region4, region5, w = \ - calculate_regions(pl, ul, rhol, pr, ur, rhor, gamma, dustFrac) + region1, region3, region4, region5, w = calculate_regions( + pl, ul, rhol, pr, ur, rhor, gamma, dustFrac + ) regions = region_states(pl, pr, region1, region3, region4, region5) # calculate positions - x_positions = calc_positions(pl, pr, region1, region3, w, xi, t, gamma, - dustFrac) + x_positions = calc_positions(pl, pr, region1, region3, w, xi, t, gamma, dustFrac) - pos_description = ('Head of Rarefaction', 'Foot of Rarefaction', - 'Contact Discontinuity', 'Shock') - positions = dict(zip(pos_description, x_positions)) + pos_description = ( + "Head of Rarefaction", + "Foot of Rarefaction", + "Contact Discontinuity", + "Shock", + ) + positions = dict(zip(pos_description, x_positions, strict=True)) # create arrays - x, p, rho, u = create_arrays(pl, pr, xl, xr, x_positions, - region1, region3, region4, region5, - npts, gamma, t, xi, dustFrac) - - energy = p/(rho * (gamma - 1.0)) - rho_total = rho/(1.0 - dustFrac) - val_dict = {'x':x, 'p':p, 'rho':rho, 'u':u, 'energy':energy, - 'rho_total':rho_total} + x, p, rho, u = create_arrays( + pl, + pr, + xl, + xr, + x_positions, + region1, + region3, + region4, + region5, + npts, + gamma, + t, + xi, + dustFrac, + ) + + energy = p / (rho * (gamma - 1.0)) + rho_total = rho / (1.0 - dustFrac) + val_dict = { + "x": x, + "p": p, + "rho": rho, + "u": u, + "energy": energy, + "rho_total": rho_total, + } return positions, regions, val_dict diff --git a/test/Pluto/HD/sod/python/testidefix.py b/test/Pluto/HD/sod/python/testidefix.py index d01db7bca..525d865bb 100755 --- a/test/Pluto/HD/sod/python/testidefix.py +++ b/test/Pluto/HD/sod/python/testidefix.py @@ -1,4 +1,19 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/Pluto/HD/sod/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # -*- coding: utf-8 -*- """ Created on Thu Mar 5 11:29:41 2020 @@ -6,24 +21,24 @@ @author: glesur """ -import idefixTools as idfx -import sod -import sys import argparse -import numpy as np +import sys + +import idefixTools as idfx import matplotlib.pyplot as plt +import numpy as np +import sod from scipy.interpolate import interp1d parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args, unknown=parser.parse_known_args() +args, unknown = parser.parse_known_args() -V=idfx.readVTKCart('../data.0002.vtk') +V = idfx.readVTKCart("../data.0002.vtk") gamma = 1.4 npts = 5000 @@ -33,42 +48,48 @@ # t is the time evolution for which positions and states in tube should be calculated # gamma denotes specific heat # note that gamma and npts are default parameters (1.4 and 500) in solve function -positions, regions, values = sod.solve(left_state=(1, 1, 0), right_state=(0.1, 0.125, 0.), - geometry=(0., 1., 0.5), t=0.2, gamma=gamma, npts=npts) +positions, regions, values = sod.solve( + left_state=(1, 1, 0), + right_state=(0.1, 0.125, 0.0), + geometry=(0.0, 1.0, 0.5), + t=0.2, + gamma=gamma, + npts=npts, +) # Finally, let's plot solutions -p = values['p'] -rho = values['rho'] -u = values['u'] -x= values['x'] +p = values["p"] +rho = values["rho"] +u = values["u"] +x = values["x"] -solinterp=interp1d(x,p) +solinterp = interp1d(x, p) -if(not args.noplot): +if not args.noplot: plt.figure(1) - plt.plot(x,rho) - plt.plot(V.x,V.data['rho'][:,0,0],'+',markersize=2) - plt.title('Density') + plt.plot(x, rho) + plt.plot(V.x, V.data["rho"][:, 0, 0], "+", markersize=2) + plt.title("Density") plt.figure(2) - plt.plot(x,u) - plt.plot(V.x,V.data['vx1'][:,0,0],'+',markersize=2) - plt.title('Velocity') + plt.plot(x, u) + plt.plot(V.x, V.data["vx1"][:, 0, 0], "+", markersize=2) + plt.title("Velocity") plt.figure(3) - plt.plot(x,p) - plt.plot(V.x,V.data['prs'][:,0,0],'+',markersize=2) - plt.title('Pressure') + plt.plot(x, p) + plt.plot(V.x, V.data["prs"][:, 0, 0], "+", markersize=2) + plt.title("Pressure") plt.ioff() plt.show() -error=np.mean(np.fabs(V.data['prs'][:,0,0]-solinterp(V.x))) -print("Error=%e"%error) -if error<1e-2: +error = np.mean(np.fabs(V.data["prs"][:, 0, 0] - solinterp(V.x))) +print("Error=%e" % error) +if error < 1e-2: print("SUCCESS!") sys.exit(0) else: diff --git a/test/Pluto/MHD/OrszagTang/definitions.h b/test/Pluto/MHD/OrszagTang/definitions.h index a9d6a3aef..6b8d7ce67 100644 --- a/test/Pluto/MHD/OrszagTang/definitions.h +++ b/test/Pluto/MHD/OrszagTang/definitions.h @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/MHD/OrszagTang/definitions.h +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define PHYSICS MHD #define DIMENSIONS 2 #define COMPONENTS 2 diff --git a/test/Pluto/MHD/OrszagTang/init.c b/test/Pluto/MHD/OrszagTang/init.c index c96ab1c14..f21df9469 100644 --- a/test/Pluto/MHD/OrszagTang/init.c +++ b/test/Pluto/MHD/OrszagTang/init.c @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/MHD/OrszagTang/init.c +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + /* ///////////////////////////////////////////////////////////////////// */ /*! \file diff --git a/test/Pluto/MHD/sod-iso/definitions.h b/test/Pluto/MHD/sod-iso/definitions.h index 3204bb5f7..b30eeac1f 100644 --- a/test/Pluto/MHD/sod-iso/definitions.h +++ b/test/Pluto/MHD/sod-iso/definitions.h @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/MHD/sod-iso/definitions.h +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define PHYSICS MHD #define DIMENSIONS 1 #define COMPONENTS 3 diff --git a/test/Pluto/MHD/sod-iso/init.c b/test/Pluto/MHD/sod-iso/init.c index f03c3114b..94def23fd 100644 --- a/test/Pluto/MHD/sod-iso/init.c +++ b/test/Pluto/MHD/sod-iso/init.c @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/MHD/sod-iso/init.c +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "pluto.h" #define LEFTGOING YES diff --git a/test/Pluto/MHD/sod/definitions.h b/test/Pluto/MHD/sod/definitions.h index 5517b826e..c8e729867 100644 --- a/test/Pluto/MHD/sod/definitions.h +++ b/test/Pluto/MHD/sod/definitions.h @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/MHD/sod/definitions.h +// +// Last modified : 11/2020 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define PHYSICS MHD #define DIMENSIONS 1 #define COMPONENTS 3 diff --git a/test/Pluto/MHD/sod/init.c b/test/Pluto/MHD/sod/init.c index 7d1248f12..476fd8859 100644 --- a/test/Pluto/MHD/sod/init.c +++ b/test/Pluto/MHD/sod/init.c @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/Pluto/MHD/sod/init.c +// +// Last modified : 01/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2020) +// - Clément Robert (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "pluto.h" #define LEFTGOING YES diff --git a/test/SelfGravity/DustyCollapse/definitions.hpp b/test/SelfGravity/DustyCollapse/definitions.hpp index 77affc7ef..7ffedc491 100644 --- a/test/SelfGravity/DustyCollapse/definitions.hpp +++ b/test/SelfGravity/DustyCollapse/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/SelfGravity/DustyCollapse/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 1 #define DIMENSIONS 1 #define ISOTHERMAL diff --git a/test/SelfGravity/DustyCollapse/python/testidefix.py b/test/SelfGravity/DustyCollapse/python/testidefix.py index 370d89e77..a10a87f8b 100644 --- a/test/SelfGravity/DustyCollapse/python/testidefix.py +++ b/test/SelfGravity/DustyCollapse/python/testidefix.py @@ -1,22 +1,39 @@ -import numpy as np +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/SelfGravity/DustyCollapse/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + import os import sys +import numpy as np + sys.path.append(os.getenv("IDEFIX_DIR")) from pytools.vtk_io import readVTK -G=6.6743e-11 -M=1e16 #mass of spheric clump -r0=1e4 #radius of spheric clump -rmax = 3e4 #right edge of simulation box -d=M/(4*np.pi*r0**3/3) #density of spheric clump -phi0 = -22.247666667 #gravitationnal potential at rmax +G = 6.6743e-11 +M = 1e16 # mass of spheric clump +r0 = 1e4 # radius of spheric clump +rmax = 3e4 # right edge of simulation box +d = M / (4 * np.pi * r0**3 / 3) # density of spheric clump +phi0 = -22.247666667 # gravitationnal potential at rmax + def potential(r): retv = np.empty_like(r) - interior = (r (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" #include "npy.hpp" diff --git a/test/SelfGravity/DustyCollapse/testme.json b/test/SelfGravity/DustyCollapse/testme.json index 8afbcdb6d..208d8a307 100644 --- a/test/SelfGravity/DustyCollapse/testme.json +++ b/test/SelfGravity/DustyCollapse/testme.json @@ -1,16 +1,18 @@ { - "namings": "ini,mpi", + "namings": "mpi", + "default": { + "dumpname": "dump.0001.dmp", + "ini": "idefix.ini", + "noplot": true, + "vectPot": false, + "single": false, + "reconstruction": 2, + "nonRegressionTest": false, + "tolerance": 1e-13 + }, "variants": [ { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "noplot": true, - "vectPot": false, - "single": false, - "reconstruction": 2, - "mpi": [false, true], - "nonRegressionTest": false, - "tolerance": 1e-13 + "mpi": [false, true] } ] } diff --git a/test/SelfGravity/DustyCollapse/testme.py b/test/SelfGravity/DustyCollapse/testme.py index 2df3893ab..7d3da1fac 100755 --- a/test/SelfGravity/DustyCollapse/testme.py +++ b/test/SelfGravity/DustyCollapse/testme.py @@ -1,43 +1,60 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/SelfGravity/DustyCollapse/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + +tolerance = 1e-13 -tolerance=1e-13 def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - test.standardTest() + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + test.standardTest() -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.standardTest() - else: - testMe(test) + if test.check: + test.standardTest() + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - test.mpi=True - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + test.mpi = True + testMe(test) diff --git a/test/SelfGravity/JeansInstability/definitions.hpp b/test/SelfGravity/JeansInstability/definitions.hpp index f64d67e95..518c5bb1a 100644 --- a/test/SelfGravity/JeansInstability/definitions.hpp +++ b/test/SelfGravity/JeansInstability/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/SelfGravity/JeansInstability/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 1 #define DIMENSIONS 1 diff --git a/test/SelfGravity/JeansInstability/python/testidefix.py b/test/SelfGravity/JeansInstability/python/testidefix.py index 80d6ee620..43f248d37 100755 --- a/test/SelfGravity/JeansInstability/python/testidefix.py +++ b/test/SelfGravity/JeansInstability/python/testidefix.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/SelfGravity/JeansInstability/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Thu Mar 5 11:29:41 2020 @@ -8,46 +22,48 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK import numpy as np from scipy.fftpack import fft, fftfreq +from pytools.vtk_io import readVTK + # Arguments -gravCst = np.pi # grav cst G=pi -gamma = 5/3 -rho_bg = 3.0 # background density +gravCst = np.pi # grav cst G=pi +gamma = 5 / 3 +rho_bg = 3.0 # background density # Parameters (calculated from the arguments) -prs_bg = 1.0/gamma -cs02 = gamma*prs_bg/rho_bg # squared bg speed velocity -lbdJ = np.sqrt(cs02*np.pi/(gravCst*rho_bg)) # Jean's wavelength -kJ = 2*np.pi/lbdJ # Jean's wavevector +prs_bg = 1.0 / gamma +cs02 = gamma * prs_bg / rho_bg # squared bg speed velocity +lbdJ = np.sqrt(cs02 * np.pi / (gravCst * rho_bg)) # Jean's wavelength +kJ = 2 * np.pi / lbdJ # Jean's wavevector # Collect vtk files (we ignore those before vtkRef) -Vmax=readVTK('../data.0004.vtk') # Best time vtk (for gr fitting) -Vref=readVTK('../data.0003.vtk') # Ref vtk (after unwanted modes are quenched) +Vmax = readVTK("../data.0004.vtk") # Best time vtk (for gr fitting) +Vref = readVTK("../data.0003.vtk") # Ref vtk (after unwanted modes are quenched) # Collect data x1 = np.squeeze(Vref.x) tref, tmax = Vref.t[0], Vmax.t[0] -uref, umax = np.squeeze(Vref.data['VX1']), np.squeeze(Vmax.data['VX1']) +uref, umax = np.squeeze(Vref.data["VX1"]), np.squeeze(Vmax.data["VX1"]) # Compute fft N1 = x1.size -dx1 = x1[1]-x1[0] -k1 = 2*np.pi*fftfreq(N1, dx1) +dx1 = x1[1] - x1[0] +k1 = 2 * np.pi * fftfreq(N1, dx1) furef, fumax = np.abs(fft(uref)), np.abs(fft(umax)) # Compute the numerical/theoretical growth rate of the second non-zero unstable mode mode = 2 -gr_num = np.log(fumax/furef)[mode]/(tmax-tref) -gr_th = np.sqrt(np.abs(k1[mode]**2*cs02-4.*np.pi*gravCst*rho_bg)) -error = np.abs((gr_num-gr_th)/gr_th) +gr_num = np.log(fumax / furef)[mode] / (tmax - tref) +gr_th = np.sqrt(np.abs(k1[mode] ** 2 * cs02 - 4.0 * np.pi * gravCst * rho_bg)) +error = np.abs((gr_num - gr_th) / gr_th) # Print the result of the test -print("Error=%e"%error) -if error<2.3e-3: +print("Error=%e" % error) +if error < 2.3e-3: print("SUCCESS!") sys.exit(0) else: diff --git a/test/SelfGravity/JeansInstability/setup.cpp b/test/SelfGravity/JeansInstability/setup.cpp index 78ee7a154..794b03575 100644 --- a/test/SelfGravity/JeansInstability/setup.cpp +++ b/test/SelfGravity/JeansInstability/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/SelfGravity/JeansInstability/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include "idefix.hpp" diff --git a/test/SelfGravity/JeansInstability/testme.json b/test/SelfGravity/JeansInstability/testme.json index bf4819389..ba620fb6b 100644 --- a/test/SelfGravity/JeansInstability/testme.json +++ b/test/SelfGravity/JeansInstability/testme.json @@ -1,17 +1,19 @@ { "namings": "ini,mpi", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "vectPot": false, + "single": false, + "reconstruction": 2, + "dec": [2], + "nonRegressionTest": false, + "tolerance": 1e-13 + }, "variants": [ { - "dumpname": "dump.0001.dmp", "ini": ["idefix.ini","idefix-cg.ini"], - "noplot": true, - "vectPot": false, - "single": false, - "reconstruction": 2, - "mpi": [false, true], - "dec": ["2"], - "nonRegressionTest": false, - "tolerance": 1e-13 + "mpi": [false, true] } ] } diff --git a/test/SelfGravity/JeansInstability/testme.py b/test/SelfGravity/JeansInstability/testme.py index 833feb262..bed603c9b 100755 --- a/test/SelfGravity/JeansInstability/testme.py +++ b/test/SelfGravity/JeansInstability/testme.py @@ -1,48 +1,65 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/SelfGravity/JeansInstability/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + +tolerance = 1e-12 -tolerance=1e-12 def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-cg.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-cg.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - test.standardTest() + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + test.standardTest() -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) # if no decomposition is specified, use that one if not test.dec: - test.dec=['2'] + test.dec = ["2"] if not test.all: - if(test.check): - test.standardTest() - else: - testMe(test) + if test.check: + test.standardTest() + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) - test.mpi=True - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) + test.mpi = True + testMe(test) diff --git a/test/SelfGravity/RandomSphere/definitions.hpp b/test/SelfGravity/RandomSphere/definitions.hpp index 1abadf739..612bfcf02 100644 --- a/test/SelfGravity/RandomSphere/definitions.hpp +++ b/test/SelfGravity/RandomSphere/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/SelfGravity/RandomSphere/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/SelfGravity/RandomSphere/python/testidefix.py b/test/SelfGravity/RandomSphere/python/testidefix.py index 444c3034d..cff04f926 100755 --- a/test/SelfGravity/RandomSphere/python/testidefix.py +++ b/test/SelfGravity/RandomSphere/python/testidefix.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/SelfGravity/RandomSphere/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Thu Mar 5 11:29:41 2020 @@ -6,11 +20,12 @@ @author: glesur """ +import argparse import os import sys -import numpy as np + import matplotlib.pyplot as plt -import argparse +import numpy as np sys.path.append(os.getenv("IDEFIX_DIR")) @@ -18,15 +33,14 @@ # Add noplot argument to parser parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args=parser.parse_args() +args = parser.parse_args() # Read vtk -V=readVTK('../data.0000.vtk') +V = readVTK("../data.0000.vtk") # Spherical coordinates nr, nth, nphi = np.squeeze(V.nx), np.squeeze(V.ny), np.squeeze(V.nz) @@ -36,55 +50,55 @@ rg, thg, phig = np.meshgrid(r, th, phi, indexing="ij") # Cartesian coordinates -x = rg*np.sin(thg)*np.cos(phig) -y = rg*np.sin(thg)*np.sin(phig) -z = rg*np.cos(thg) +x = rg * np.sin(thg) * np.cos(phig) +y = rg * np.sin(thg) * np.sin(phig) +z = rg * np.cos(thg) # Density (for norm) -rho = np.squeeze(V.data['RHO']) +rho = np.squeeze(V.data["RHO"]) # Constrained potential -phi_f = np.squeeze(V.data['phiP']) +phi_f = np.squeeze(V.data["phiP"]) # Theoretical parameters -r0 = 3. -delta = 1. -rho0 = 3./(4.*np.pi) -G = 1. -M = 4.*np.pi/3.*delta**3*rho0 +r0 = 3.0 +delta = 1.0 +rho0 = 3.0 / (4.0 * np.pi) +G = 1.0 +M = 4.0 * np.pi / 3.0 * delta**3 * rho0 # Theoretical potential -dr = np.sqrt((x-r0)**2 + y**2 + z**2) -sph = np.where(dr <= delta) # Sphere delimitation -phi_th = -G*M/dr # Out of the sphere -phi_th[sph] = - (G*M)/(2*delta**3)*(3*delta**2 - dr[sph]**2) # In the sphere +dr = np.sqrt((x - r0) ** 2 + y**2 + z**2) +sph = np.where(dr <= delta) # Sphere delimitation +phi_th = -G * M / dr # Out of the sphere +phi_th[sph] = -(G * M) / (2 * delta**3) * (3 * delta**2 - dr[sph] ** 2) # In the sphere # Recovering gradients to get rid of the integration constant gth, gf = np.zeros(phi_f.shape), np.zeros(phi_f.shape) for i in range(nphi): for j in range(nth): - gth[:,j,i] = -np.gradient(phi_th[:,j,i], r, axis=0) - gf[:,j,i] = -np.gradient(phi_f[:,j,i], r, axis=0) + gth[:, j, i] = -np.gradient(phi_th[:, j, i], r, axis=0) + gf[:, j, i] = -np.gradient(phi_f[:, j, i], r, axis=0) # Recovering the norm (density ponderated like the solver) -num = np.linalg.norm(gf-gth) +num = np.linalg.norm(gf - gth) denom = np.linalg.norm(rho) -norm = num/denom +norm = num / denom print(norm) # Display a check plot if necessary -if(not args.noplot): - plt.plot(r, gf[:,nth//2-1,0], 'c-', label='cpt') - plt.plot(r, gth[:,nth//2-1,0], 'k--', label='th') - plt.title('Gravitational gradient along the sphere solid angle') - plt.xlabel('r') - plt.ylabel('g') +if not args.noplot: + plt.plot(r, gf[:, nth // 2 - 1, 0], "c-", label="cpt") + plt.plot(r, gth[:, nth // 2 - 1, 0], "k--", label="th") + plt.title("Gravitational gradient along the sphere solid angle") + plt.xlabel("r") + plt.ylabel("g") plt.legend() plt.show() # Print the result of the test -print("Error=%e"%norm) -if norm<1.5e-1: +print("Error=%e" % norm) +if norm < 1.5e-1: print("SUCCESS!") sys.exit(0) else: diff --git a/test/SelfGravity/RandomSphere/setup.cpp b/test/SelfGravity/RandomSphere/setup.cpp index ce545b0a5..098ed02aa 100644 --- a/test/SelfGravity/RandomSphere/setup.cpp +++ b/test/SelfGravity/RandomSphere/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/SelfGravity/RandomSphere/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include "idefix.hpp" diff --git a/test/SelfGravity/RandomSphere/testme.json b/test/SelfGravity/RandomSphere/testme.json index d5cda3135..20128b31e 100644 --- a/test/SelfGravity/RandomSphere/testme.json +++ b/test/SelfGravity/RandomSphere/testme.json @@ -1,14 +1,16 @@ { "namings": "ini,mpi", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "dec": [2,2,1], + "nonRegressionTest": false, + "tolerance": 0 + }, "variants": [ { - "dumpname": "dump.0001.dmp", "ini": ["idefix.ini","idefix-cg.ini","idefix-minres.ini"], - "noplot": true, - "mpi": [false, true], - "dec": ["2","2","1"], - "nonRegressionTest": false, - "tolerance": 0 + "mpi": [false, true] } ] } diff --git a/test/SelfGravity/RandomSphere/testme.py b/test/SelfGravity/RandomSphere/testme.py index 65123498b..ea242d153 100755 --- a/test/SelfGravity/RandomSphere/testme.py +++ b/test/SelfGravity/RandomSphere/testme.py @@ -1,41 +1,58 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/SelfGravity/RandomSphere/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-cg.ini","idefix-minres.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-cg.ini", "idefix-minres.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - #if test.init: - # test.makeReference(filename=name) - test.standardTest() - # since the gravitationnal potential is not included in .dmp files, we can't perform - # the full non-regression test - #test.nonRegressionTest(filename=name) + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + # if test.init: + # test.makeReference(filename=name) + test.standardTest() + # since the gravitationnal potential is not included in .dmp files, we can't perform + # the full non-regression test + # test.nonRegressionTest(filename=name) -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.dec: - test.dec=['2','2','1'] + test.dec = ["2", "2", "1"] if not test.all: - testMe(test) + testMe(test) else: - test.mpi=False - test.noplot=True - testMe(test) - test.mpi=True - testMe(test) + test.mpi = False + test.noplot = True + testMe(test) + test.mpi = True + testMe(test) diff --git a/test/SelfGravity/RandomSphereCartesian/definitions.hpp b/test/SelfGravity/RandomSphereCartesian/definitions.hpp index 0eebd2c1f..7cba4803d 100644 --- a/test/SelfGravity/RandomSphereCartesian/definitions.hpp +++ b/test/SelfGravity/RandomSphereCartesian/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/SelfGravity/RandomSphereCartesian/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/SelfGravity/RandomSphereCartesian/python/testidefix.py b/test/SelfGravity/RandomSphereCartesian/python/testidefix.py index 7367b3d9a..37f5d0cd1 100755 --- a/test/SelfGravity/RandomSphereCartesian/python/testidefix.py +++ b/test/SelfGravity/RandomSphereCartesian/python/testidefix.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/SelfGravity/RandomSphereCartesian/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Thu Mar 5 11:29:41 2020 @@ -6,12 +20,13 @@ @author: glesur """ +import argparse import os import sys -import numpy as np + import matplotlib.pyplot as plt +import numpy as np import numpy.fft as fft -import argparse sys.path.append(os.getenv("IDEFIX_DIR")) @@ -19,37 +34,37 @@ # Compute theoretical psi from spectral solution to Laplace equation -def getPsiTheoretical(x,y,z,rho): - n=x.shape[0] +def getPsiTheoretical(x, y, z, rho): - # Compute fourier transform and k vector - k1D=2.0*np.pi*fft.fftfreq(n,1/n) - [kx,ky,kz]=np.meshgrid(k1D,k1D,k1D,indexing='ij') - k2=(kx**2+ky**2+kz**2) - # avoid divide by 0 - k2[0,0,0]=1.0 - ik2=1.0/k2 - # kill zero frequency - ik2[0,0,0]=0 + n = x.shape[0] + + # Compute fourier transform and k vector + k1D = 2.0 * np.pi * fft.fftfreq(n, 1 / n) + [kx, ky, kz] = np.meshgrid(k1D, k1D, k1D, indexing="ij") + k2 = kx**2 + ky**2 + kz**2 + # avoid divide by 0 + k2[0, 0, 0] = 1.0 + ik2 = 1.0 / k2 + # kill zero frequency + ik2[0, 0, 0] = 0 + + rhof = fft.fft2(rho, axes=(0, 1, 2)) + psif = -rhof * ik2 + psi = 4.0 * np.pi * np.real(fft.ifft2(psif, axes=(0, 1, 2))) + return psi - rhof=fft.fft2(rho,axes=(0,1,2)) - psif=-rhof*ik2 - psi=4.0*np.pi*np.real(fft.ifft2(psif,axes=(0,1,2))) - return(psi) # Add noplot argument to parser parser = argparse.ArgumentParser() -parser.add_argument("-noplot", - default=False, - help="disable plotting", - action="store_true") +parser.add_argument( + "-noplot", default=False, help="disable plotting", action="store_true" +) -args=parser.parse_args() +args = parser.parse_args() # Read vtk -V=readVTK('../data.0000.vtk') - +V = readVTK("../data.0000.vtk") # Cartesian coordinates @@ -58,39 +73,41 @@ def getPsiTheoretical(x,y,z,rho): z = V.z # Density (for norm) -rho = V.data['RHO'] +rho = V.data["RHO"] # Constrained potential -phi_f = V.data['phiP'] - -phi_th=getPsiTheoretical(x,y,z,rho) +phi_f = V.data["phiP"] +phi_th = getPsiTheoretical(x, y, z, rho) # Recovering gradients to get rid of the integration constant gx, gy, gz = np.zeros(phi_f.shape), np.zeros(phi_f.shape), np.zeros(phi_f.shape) -gx_f=-np.gradient(phi_f,axis=0) -gx_th=-np.gradient(phi_th,axis=0) -gy_f=-np.gradient(phi_f,axis=1) -gy_th=-np.gradient(phi_th,axis=1) -gz_f=-np.gradient(phi_f,axis=2) -gz_th=-np.gradient(phi_th,axis=2) - -norm=np.sqrt(np.mean((gx_f-gx_th)**2+(gy_f-gy_th)**2+(gz_f-gz_th)**2)/np.mean(gx_th**2+gy_th**2+gz_th**2)) +gx_f = -np.gradient(phi_f, axis=0) +gx_th = -np.gradient(phi_th, axis=0) +gy_f = -np.gradient(phi_f, axis=1) +gy_th = -np.gradient(phi_th, axis=1) +gz_f = -np.gradient(phi_f, axis=2) +gz_th = -np.gradient(phi_th, axis=2) + +norm = np.sqrt( + np.mean((gx_f - gx_th) ** 2 + (gy_f - gy_th) ** 2 + (gz_f - gz_th) ** 2) + / np.mean(gx_th**2 + gy_th**2 + gz_th**2) +) # Display a check plot if necessary -if(not args.noplot): - n=x.size//2 - plt.plot(x,gx_f[:,n,n], 'c-', label='cpt') - plt.plot(x, gx_th[:,n,n], 'k--', label='th') - plt.xlabel('r') - plt.ylabel('g') +if not args.noplot: + n = x.size // 2 + plt.plot(x, gx_f[:, n, n], "c-", label="cpt") + plt.plot(x, gx_th[:, n, n], "k--", label="th") + plt.xlabel("r") + plt.ylabel("g") plt.legend() plt.show() # Print the result of the test -print("Error=%e"%norm) -if norm<1e-2: +print("Error=%e" % norm) +if norm < 1e-2: print("SUCCESS!") sys.exit(0) else: diff --git a/test/SelfGravity/RandomSphereCartesian/setup.cpp b/test/SelfGravity/RandomSphereCartesian/setup.cpp index 7eaf4411f..e13430863 100644 --- a/test/SelfGravity/RandomSphereCartesian/setup.cpp +++ b/test/SelfGravity/RandomSphereCartesian/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/SelfGravity/RandomSphereCartesian/setup.cpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include "idefix.hpp" diff --git a/test/SelfGravity/RandomSphereCartesian/testme.json b/test/SelfGravity/RandomSphereCartesian/testme.json index 85f0f3889..0cf3294a9 100644 --- a/test/SelfGravity/RandomSphereCartesian/testme.json +++ b/test/SelfGravity/RandomSphereCartesian/testme.json @@ -1,12 +1,14 @@ { "namings": "ini", + "default": { + "dumpname": "dump.0001.dmp", + "noplot": true, + "nonRegressionTest": false, + "tolerance": 0 + }, "variants": [ { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini","idefix-cg.ini","idefix-minres.ini","idefix-jacobi.ini"], - "noplot": true, - "nonRegressionTest": false, - "tolerance": 0 + "ini": ["idefix.ini","idefix-cg.ini","idefix-minres.ini","idefix-jacobi.ini"] } ] } diff --git a/test/SelfGravity/RandomSphereCartesian/testme.py b/test/SelfGravity/RandomSphereCartesian/testme.py index 598aa3f21..4e19f9447 100755 --- a/test/SelfGravity/RandomSphereCartesian/testme.py +++ b/test/SelfGravity/RandomSphereCartesian/testme.py @@ -1,34 +1,51 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/SelfGravity/RandomSphereCartesian/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst + def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini","idefix-cg.ini","idefix-minres.ini","idefix-jacobi.ini"] - - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - #if test.init: - # test.makeReference(filename=name) - test.standardTest() - # since the gravitationnal potential is not included in .dmp files, we can't perform - # the full non-regression test - #test.nonRegressionTest(filename=name) - - -test=tst.idfxTest(__file__) + test.configure() + test.compile() + inifiles = ["idefix.ini", "idefix-cg.ini", "idefix-minres.ini", "idefix-jacobi.ini"] + + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + # if test.init: + # test.makeReference(filename=name) + test.standardTest() + # since the gravitationnal potential is not included in .dmp files, we can't perform + # the full non-regression test + # test.nonRegressionTest(filename=name) + + +test = tst.idfxTest(__file__) if not test.all: - testMe(test) + testMe(test) else: - test.noplot=True - testMe(test) + test.noplot = True + testMe(test) diff --git a/test/SelfGravity/UniformCollapse/CMakeLists.txt b/test/SelfGravity/UniformCollapse/CMakeLists.txt index fe9547125..63e8260af 100644 --- a/test/SelfGravity/UniformCollapse/CMakeLists.txt +++ b/test/SelfGravity/UniformCollapse/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/SelfGravity/UniformCollapse/CMakeLists.txt +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + #replace_idefix_source(main.cpp main.cpp) diff --git a/test/SelfGravity/UniformCollapse/definitions.hpp b/test/SelfGravity/UniformCollapse/definitions.hpp index 923795c2a..95a4c2dd9 100644 --- a/test/SelfGravity/UniformCollapse/definitions.hpp +++ b/test/SelfGravity/UniformCollapse/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/SelfGravity/UniformCollapse/definitions.hpp +// +// Last modified : 10/2023 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 1 #define DIMENSIONS 1 #define ISOTHERMAL diff --git a/test/SelfGravity/UniformCollapse/python/testidefix.py b/test/SelfGravity/UniformCollapse/python/testidefix.py index e89a296a0..0832e6492 100755 --- a/test/SelfGravity/UniformCollapse/python/testidefix.py +++ b/test/SelfGravity/UniformCollapse/python/testidefix.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/SelfGravity/UniformCollapse/python/testidefix.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # -*- coding: utf-8 -*- """ Created on Thu Mar 5 11:29:41 2020 @@ -8,44 +22,50 @@ import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) -from pytools.vtk_io import readVTK import numpy as np +from pytools.vtk_io import readVTK + # Arguments -gravCst = 1./(4.*np.pi) # grav cst 4piG -rho0 = 1e-3 # initial density +gravCst = 1.0 / (4.0 * np.pi) # grav cst 4piG +rho0 = 1e-3 # initial density # Parameters (calculated from the arguments) -tff = np.sqrt(3.*np.pi/(32.*rho0*gravCst)) # Theoretical free-fall time to achieve collapse +tff = np.sqrt( + 3.0 * np.pi / (32.0 * rho0 * gravCst) +) # Theoretical free-fall time to achieve collapse # Collecting data -V=readVTK('../data.0005.vtk') +V = readVTK("../data.0005.vtk") time = V.t[0] -rho = np.squeeze(V.data['RHO']) +rho = np.squeeze(V.data["RHO"]) + # A function to detect density plateau, its size and position def get_plateau(rho): plateau = [rho[0]] for dsty in rho[1:]: - if np.abs(dsty-plateau[-1])>0.01*plateau[-1]: + if np.abs(dsty - plateau[-1]) > 0.01 * plateau[-1]: return np.mean(plateau) else: plateau.append(dsty) return "Error : the whole density distribution is approximately constant !" + # Isolating density plateau -plateau=get_plateau(rho) +plateau = get_plateau(rho) # Calculating absolute error -r_th=time/tff # Theoretical ratio -eta = np.arccos((plateau/rho0)**(-1./6.)) -r_num = 2./np.pi*(eta + 1./2.*np.sin(2.*eta)) # Numerical ratio -error = np.abs(r_num-r_th) # Absolute error +r_th = time / tff # Theoretical ratio +eta = np.arccos((plateau / rho0) ** (-1.0 / 6.0)) +r_num = 2.0 / np.pi * (eta + 1.0 / 2.0 * np.sin(2.0 * eta)) # Numerical ratio +error = np.abs(r_num - r_th) # Absolute error # Print the result of the test -print("Error=%e"%error) -if error<2.0e-3: +print("Error=%e" % error) +if error < 2.0e-3: print("SUCCESS!") sys.exit(0) else: diff --git a/test/SelfGravity/UniformCollapse/setup.cpp b/test/SelfGravity/UniformCollapse/setup.cpp index 6f773a153..ba213f8f6 100644 --- a/test/SelfGravity/UniformCollapse/setup.cpp +++ b/test/SelfGravity/UniformCollapse/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/SelfGravity/UniformCollapse/setup.cpp +// +// Last modified : 03/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include "idefix.hpp" @@ -65,7 +80,7 @@ void FluxBoundary(Fluid *hydro, int dir, BoundarySide side, cons if((dir==IDIR) && (side == left)) { // Loading needed data DataBlock &data = *hydro->data; - IdefixArray4D Flux = hydro->FluxRiemann; + IdefixArray4D Flux = hydro->FluxRiemann[dir]; real halfDt = data.dt/2.; // RK2, dt is actually half at each flux calculation int iref = data.nghost[IDIR]; real rin = data.xbeg[IDIR]; diff --git a/test/SelfGravity/UniformCollapse/testme.json b/test/SelfGravity/UniformCollapse/testme.json index 3de00c4df..50e6e9e3d 100644 --- a/test/SelfGravity/UniformCollapse/testme.json +++ b/test/SelfGravity/UniformCollapse/testme.json @@ -1,16 +1,13 @@ { - "namings": "ini", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "noplot": true, - "single": false, - "reconstruction": 2, - "mpi": false, - "standardTest": false, - "tolerance": 0, - "nonRegressionTest": false - } - ] + "default": { + "dumpname": "dump.0001.dmp", + "ini": "idefix.ini", + "noplot": true, + "single": false, + "reconstruction": 2, + "mpi": false, + "standardTest": false, + "tolerance": 0, + "nonRegressionTest": false + } } diff --git a/test/SelfGravity/UniformCollapse/testme.py b/test/SelfGravity/UniformCollapse/testme.py index 69918896b..a1f4b85f1 100755 --- a/test/SelfGravity/UniformCollapse/testme.py +++ b/test/SelfGravity/UniformCollapse/testme.py @@ -1,41 +1,58 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/SelfGravity/UniformCollapse/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -name="dump.0001.dmp" +name = "dump.0001.dmp" + +tolerance = 1e-13 -tolerance=1e-13 def testMe(test): - test.configure() - test.compile() - inifiles=["idefix.ini"] + test.configure() + test.compile() + inifiles = ["idefix.ini"] - # loop on all the ini files for this test - for ini in inifiles: - test.run(inputFile=ini) - test.standardTest() + # loop on all the ini files for this test + for ini in inifiles: + test.run(inputFile=ini) + test.standardTest() -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) if not test.all: - if(test.check): - test.standardTest() - else: - testMe(test) + if test.check: + test.standardTest() + else: + testMe(test) else: - test.noplot = True - test.vectPot=False - test.single=False - test.reconstruction=2 - test.mpi=False - testMe(test) + test.noplot = True + test.vectPot = False + test.single = False + test.reconstruction = 2 + test.mpi = False + testMe(test) diff --git a/test/checks_examples.sh b/test/checks_examples.sh index 4cca16217..8d32f9e8e 100755 --- a/test/checks_examples.sh +++ b/test/checks_examples.sh @@ -1,4 +1,17 @@ #!/bin/bash +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/checks_examples.sh +# +# Last modified : 10/2023 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2023) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### # check that the provided examples (which do not have a reference case) compile and run for a few loops diff --git a/test/python_requirements.txt b/test/python_requirements.txt index 9cf2383a2..9ff69aedb 100644 --- a/test/python_requirements.txt +++ b/test/python_requirements.txt @@ -1,14 +1,14 @@ -# note: version requirements are indicative and tests # should be able to run with +# note: version requirements are indicative and tests should be able to run with # older versions of our dependencies, though it is not guaranteed. -# minimally require last versions available for Python 2.7 -numpy>=1.16.6 -matplotlib>=2.2.5 -scipy>=1.2.3 - -# note that no version of inifix supports Python older than 3.6 -inifix>=0.11.2 +# minimally require earliest versions available for Python 3.10 +numpy>=1.21.1 +matplotlib>=3.5.0 +scipy>=1.7.2 +inifix>=5.1.0 +pybind11 >= 3.0.4 # To run the test suite, we can use pytest, mostly any version # 6.0 is the one available on system available on debian-11 pytest >= 6.0 +jsonschema >= 4.26.0 diff --git a/test/skeleton/CMakeLists.txt b/test/skeleton/CMakeLists.txt index 55ea7b2ca..602e996ae 100644 --- a/test/skeleton/CMakeLists.txt +++ b/test/skeleton/CMakeLists.txt @@ -1,2 +1,16 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/skeleton/CMakeLists.txt +# +# Last modified : 10/2021 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # replace the normal idefix main by our skeleton replace_idefix_source(main.cpp main.cpp) diff --git a/test/skeleton/definitions.hpp b/test/skeleton/definitions.hpp index 498be97af..59d595250 100644 --- a/test/skeleton/definitions.hpp +++ b/test/skeleton/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/skeleton/definitions.hpp +// +// Last modified : 10/2021 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 1 #define DIMENSIONS 1 diff --git a/test/skeleton/main.cpp b/test/skeleton/main.cpp index 4930ecb15..76b4d4f25 100644 --- a/test/skeleton/main.cpp +++ b/test/skeleton/main.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/skeleton/main.cpp +// +// Last modified : 06/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2021 - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include #include @@ -37,7 +51,7 @@ void testReduction() { // Init an array on device, and image on host IdefixArray3D rho = IdefixArray3D("rho",nx3,nx2,nx1); - IdefixArray3D::HostMirror rhoHost = Kokkos::create_mirror_view(rho); + IdefixArray3D::host_mirror_type rhoHost = Kokkos::create_mirror_view(rho); // Fill the host array, and compute the theoretical results real theoreticalResult = 0; diff --git a/test/utils/columnDensity/definitions.hpp b/test/utils/columnDensity/definitions.hpp index 3b581bd62..34e5c59b7 100644 --- a/test/utils/columnDensity/definitions.hpp +++ b/test/utils/columnDensity/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/utils/columnDensity/definitions.hpp +// +// Last modified : 01/2025 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/utils/columnDensity/setup.cpp b/test/utils/columnDensity/setup.cpp index fe7c57e69..1158e0cde 100644 --- a/test/utils/columnDensity/setup.cpp +++ b/test/utils/columnDensity/setup.cpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/utils/columnDensity/setup.cpp +// +// Last modified : 06/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2025 - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" #include "column.hpp" @@ -33,7 +47,7 @@ void Analysis(DataBlock & data) { columnX3Right->ComputeColumn(rho); IdefixArray3D columnDensityLeft, columnDensityRight; - IdefixArray3D::HostMirror columnDensityLeftHost, columnDensityRightHost; + IdefixArray3D::host_mirror_type columnDensityLeftHost, columnDensityRightHost; // IDIR columnDensityLeft = columnX1Left->GetColumn(); columnDensityRight = columnX1Right->GetColumn(); diff --git a/test/utils/columnDensity/testme.json b/test/utils/columnDensity/testme.json index 718413c4d..4163c0327 100644 --- a/test/utils/columnDensity/testme.json +++ b/test/utils/columnDensity/testme.json @@ -1,13 +1,15 @@ { - "namings": "ini,mpi", + "namings": "mpi", + "default": { + "ini": "idefix.ini", + "dumpname": "dump.0001.dmp", + "nonRegressionTest": false, + "standardTest": false, + "tolerance": 0 + }, "variants": [ { - "dumpname": "dump.0001.dmp", - "ini": ["idefix.ini"], - "mpi": [false,true], - "nonRegressionTest": false, - "standardTest": false, - "tolerance": 0 + "mpi": [false,true] } ] } diff --git a/test/utils/columnDensity/testme.py b/test/utils/columnDensity/testme.py index cd94eb4ef..75a326310 100755 --- a/test/utils/columnDensity/testme.py +++ b/test/utils/columnDensity/testme.py @@ -1,15 +1,31 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/utils/columnDensity/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2025) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) test.configure() test.compile() diff --git a/test/utils/dumpImage/CMakeLists.txt b/test/utils/dumpImage/CMakeLists.txt index 629aed2d1..4fa3e1fbc 100644 --- a/test/utils/dumpImage/CMakeLists.txt +++ b/test/utils/dumpImage/CMakeLists.txt @@ -1 +1,15 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/utils/dumpImage/CMakeLists.txt +# +# Last modified : 08/2022 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + enable_idefix_property(Idefix_MHD) diff --git a/test/utils/dumpImage/definitions.hpp b/test/utils/dumpImage/definitions.hpp index 3b581bd62..b2c20e75f 100644 --- a/test/utils/dumpImage/definitions.hpp +++ b/test/utils/dumpImage/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/utils/dumpImage/definitions.hpp +// +// Last modified : 08/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 3 #define DIMENSIONS 3 diff --git a/test/utils/dumpImage/setup.cpp b/test/utils/dumpImage/setup.cpp index 5e080e1b0..d44afacf4 100644 --- a/test/utils/dumpImage/setup.cpp +++ b/test/utils/dumpImage/setup.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/utils/dumpImage/setup.cpp +// +// Last modified : 05/2024 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022 - 2024) +// - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include "idefix.hpp" #include "setup.hpp" #include "dumpImage.hpp" diff --git a/test/utils/dumpImage/testme.py b/test/utils/dumpImage/testme.py index cd94eb4ef..3a50dfb8b 100755 --- a/test/utils/dumpImage/testme.py +++ b/test/utils/dumpImage/testme.py @@ -1,15 +1,32 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/utils/dumpImage/testme.py +# +# Last modified : 07/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023 - 2024) +# - Gaylor Wafflard (IPAG/UGA/CNRS - 2024) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys + sys.path.append(os.getenv("IDEFIX_DIR")) import pytools.idfx_test as tst -test=tst.idfxTest(__file__) +test = tst.idfxTest(__file__) test.configure() test.compile() diff --git a/test/utils/lookupTable/CMakeLists.txt b/test/utils/lookupTable/CMakeLists.txt index 55ea7b2ca..6bf9e8b0d 100644 --- a/test/utils/lookupTable/CMakeLists.txt +++ b/test/utils/lookupTable/CMakeLists.txt @@ -1,2 +1,16 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/utils/lookupTable/CMakeLists.txt +# +# Last modified : 06/2022 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + # replace the normal idefix main by our skeleton replace_idefix_source(main.cpp main.cpp) diff --git a/test/utils/lookupTable/definitions.hpp b/test/utils/lookupTable/definitions.hpp index 498be97af..b33de1670 100644 --- a/test/utils/lookupTable/definitions.hpp +++ b/test/utils/lookupTable/definitions.hpp @@ -1,3 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/utils/lookupTable/definitions.hpp +// +// Last modified : 06/2022 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #define COMPONENTS 1 #define DIMENSIONS 1 diff --git a/test/utils/lookupTable/main.cpp b/test/utils/lookupTable/main.cpp index 619cae6d2..263178a0b 100644 --- a/test/utils/lookupTable/main.cpp +++ b/test/utils/lookupTable/main.cpp @@ -1,3 +1,18 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// +// Source file test/utils/lookupTable/main.cpp +// +// Last modified : 08/2026 +// +// Copyright(C) by : +// - Geoffroy Lesur (IPAG/UGA/CNRS - 2022 - 2026) +// - Alankar Dutta (MPA Garching - 2026) +// and other code contributors +// +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + #include #include #include @@ -10,6 +25,87 @@ // minimal skeleton to use idfx basic functions void testReduction(); +// Custom transformation (and its inverse) to check that the functions used for the interpolation +// in function space can be changed when the lookup table is created +struct MyLog10 { + KOKKOS_INLINE_FUNCTION real operator() (const real x) const { + return(log10(x)); + } +}; + +struct MyPow10 { + KOKKOS_INLINE_FUNCTION real operator() (const real x) const { + return(pow(10.0,x)); + } +}; + +// --------------------------------------------------------------------------------------------- +// Small test helpers, so that each check below states what it verifies and why it failed, instead +// of every failure printing an undifferentiated "ERROR!!" that has to be traced back to the last +// banner that was printed. +// --------------------------------------------------------------------------------------------- +namespace { + +void Banner(const std::string &what) { + idfx::cout << "--------------------------------------" << std::endl; + idfx::cout << what << std::endl; +} + +void Success() { + idfx::cout << "Success" << std::endl; +} + +// Exact equality: used for values that should reproduce bit-for-bit (e.g. requesting a table node +// directly, or comparing an int index), matching what the original tests checked with a plain !=. +template +void CheckEqual(T got, T expected, const std::string &what) { + if(got != expected) { + idfx::cerr << "ERROR!! " << what << ": got " << got << ", expected " << expected << std::endl; + exit(1); + } +} + +// Element-wise exact equality over a small fixed-size array (neighbour coordinates/data/indices). +template +void CheckArrayEqual(const T *got, const T *expected, int n, const std::string &what) { + for(int i = 0 ; i < n ; i++) { + if(got[i] != expected[i]) { + idfx::cerr << "ERROR!! " << what << " (element " << i << "): got " << got[i] + << ", expected " << expected[i] << std::endl; + exit(1); + } + } +} + +// Tolerance-based equality, for values obtained through interpolation. +void CheckClose(real got, real expected, real tol, const std::string &what) { + if(std::fabs(got - expected) > tol) { + idfx::cerr << std::scientific; + idfx::cerr << "ERROR!! " << what << ": got " << got << ", expected " << expected + << " (|diff|=" << std::fabs(got - expected) << ", tol=" << tol << ")" << std::endl; + exit(1); + } +} + +void CheckTrue(bool cond, const std::string &what) { + if(!cond) { + idfx::cerr << "ERROR!! " << what << std::endl; + exit(1); + } +} + +// Expected bracketing neighbours of the 2D CSV table (toto.csv) around (x=2.1, y=3.5): x brackets +// [2,3], y brackets [3,4], and the data on the four surrounding vertices is 5,6,6,7. This is +// checked from several angles across the file below (Get vs GetNeighbours vs GetNeighboursIndx, +// host vs device, cached vs uncached search), so it is defined once here instead of being +// retyped as magic numbers in every block. +const real kXN2D[4] = {2.0, 3.0, 3.0, 4.0}; +const real kDataN2D[4] = {5.0, 6.0, 6.0, 7.0}; +const int kIdx2D[2] = {0, 1}; +const int kDataIdx2D[4] = {1, 4, 2, 5}; +const real kValue2D = 5.6; // csv.Get({2.1, 3.5}) + +} // namespace // main function int main( int argc, char* argv[] ) @@ -35,10 +131,10 @@ int main( int argc, char* argv[] ) { idfx::initialize(); - idfx::cout << "--------------------------------------" << std::endl; - idfx::cout << "Testing 2D CSV file on device." << std::endl; + + Banner("Testing 2D CSV file on device."); IdefixArray1D arr = IdefixArray1D("Test",1); - IdefixArray1D::HostMirror arrHost = Kokkos::create_mirror_view(arr); + IdefixArray1D::host_mirror_type arrHost = Kokkos::create_mirror_view(arr); LookupTable<2> csv("toto.csv",','); @@ -50,33 +146,20 @@ int main( int argc, char* argv[] ) }); Kokkos::deep_copy(arrHost , arr); - idfx::cout << "result="<1e-13) { - idfx::cerr << std::scientific; - idfx::cerr << "ERROR!!" << std::endl; - idfx::cerr << arrHost(0)-5.6; - exit(1); - } - idfx::cout << "Success" << std::endl; + CheckClose(arrHost(0), kValue2D, 1e-13, "2D CSV, device"); + Success(); - idfx::cout << "--------------------------------------" << std::endl; - idfx::cout << "Testing 2D CSV file on Host." << std::endl; + Banner("Testing 2D CSV file on Host."); real x[2]; x[0] = 2.1; x[1] = 3.5; real result = csv.GetHost(x); idfx::cout << "result="<1e-13) { - idfx::cerr << std::scientific; - idfx::cerr << "ERROR!!" << std::endl; - idfx::cerr << result-5.6; - exit(1); - } - idfx::cout << "Success" << std::endl; + CheckClose(result, kValue2D, 1e-13, "2D CSV, host"); + Success(); - idfx::cout << "--------------------------------------" << std::endl; - idfx::cout << "Testing 1D CSV file on device." << std::endl; + Banner("Testing 1D CSV file on device."); // Read 1D CSV File LookupTable<1> csv1D("toto1D.csv",','); @@ -87,30 +170,403 @@ int main( int argc, char* argv[] ) }); Kokkos::deep_copy(arrHost , arr); - idfx::cout << "result="< csv1Dcolumn("toto1Dcolumn.csv",',', true, true); + + idefix_for("loop",0, 1, KOKKOS_LAMBDA (int i) { + real x[1]; + x[0] = 2.1; + arr(i) = csv1Dcolumn.Get(x); + }); + + Kokkos::deep_copy(arrHost , arr); + idfx::cout << "result="< csv1Dlin("toto1Dlog.csv",',', true, true); + LookupTable<1> csv1Dlog("toto1Dlog.csv",',', true, true, true); + // the transformation and its inverse can also be chosen when the table is created + LookupTable<1, MyLog10, MyPow10> csv1Dlog10("toto1Dlog.csv",',', true, true, true); + + idefix_for("loop",0, 1, KOKKOS_LAMBDA (int i) { + real x[1]; + x[0] = 3.0; + arr(i) = csv1Dlog.Get(x); + }); + Kokkos::deep_copy(arrHost , arr); + idfx::cout << "result="< xNdev = IdefixArray1D("xN",4); + IdefixArray1D dataNdev = IdefixArray1D("dataN",4); + IdefixArray1D idxDev = IdefixArray1D("idx",2); + IdefixArray1D dataIdxDev = IdefixArray1D("dataIdx",4); + + idefix_for("neighbours",0, 1, KOKKOS_LAMBDA (int i) { + real xq[2]; + xq[0] = 2.1; + xq[1] = 3.5; + real xN[4]; + real dataN[4]; + int idx[2]; + int dataIdx[4]; + csv.GetNeighbours(xq, xN, dataN); + csv.GetNeighboursIndx(xq, idx, dataIdx); + for(int n = 0 ; n < 4 ; n++) { + xNdev(n) = xN[n]; + dataNdev(n) = dataN[n]; + dataIdxDev(n) = dataIdx[n]; + } + idxDev(0) = idx[0]; + idxDev(1) = idx[1]; + }); + + auto xNHost = Kokkos::create_mirror_view(xNdev); + auto dataNHost = Kokkos::create_mirror_view(dataNdev); + auto idxHost = Kokkos::create_mirror_view(idxDev); + auto dataIdxHost = Kokkos::create_mirror_view(dataIdxDev); + Kokkos::deep_copy(xNHost, xNdev); + Kokkos::deep_copy(dataNHost, dataNdev); + Kokkos::deep_copy(idxHost, idxDev); + Kokkos::deep_copy(dataIdxHost, dataIdxDev); + + idfx::cout << "2D: x=" << xNHost(0) << "," << xNHost(1) << " y=" << xNHost(2) << "," + << xNHost(3) << " data=" << dataNHost(0) << "," << dataNHost(1) << "," + << dataNHost(2) << "," << dataNHost(3) << " idx=" << idxHost(0) << "," + << idxHost(1) << std::endl; + real xN[4], dataN[4]; + int idx[2], dataIdx[4]; + for(int n = 0 ; n < 4 ; n++) { xN[n] = xNHost(n); dataN[n] = dataNHost(n); } + idx[0] = idxHost(0); idx[1] = idxHost(1); + for(int n = 0 ; n < 4 ; n++) dataIdx[n] = dataIdxHost(n); + CheckArrayEqual(xN, kXN2D, 4, "2D neighbours (device), coordinates"); + CheckArrayEqual(dataN, kDataN2D, 4, "2D neighbours (device), data"); + CheckArrayEqual(idx, kIdx2D, 2, "2D neighbours (device), idx"); + CheckArrayEqual(dataIdx, kDataIdx2D, 4, "2D neighbours (device), dataIdx"); + Success(); + } + + Banner("Testing the 1D neighbours on the edges of the table."); + { + // toto1D.csv holds x=1,2,3 and data=2,4,6. Whatever the requested value, we expect the two + // neighbours bracketing it, i.e. the last two nodes when we sit on the upper edge + real xq[1]; + real xN[2]; + real dataN[2]; + real expected[3][2] = {{1.0,2.0}, {2.0,3.0}, {2.0,3.0}}; + real xRequest[3] = {1.0, 2.0, 3.0}; + for(int n = 0 ; n < 3 ; n++) { + xq[0] = xRequest[n]; + csv1D.GetNeighboursHost(xq, xN, dataN); + idfx::cout << "x=" << xq[0] << " -> neighbours " << xN[0] << "," << xN[1] + << " (data " << dataN[0] << "," << dataN[1] << ")" << std::endl; + CheckArrayEqual(xN, expected[n], 2, "1D edge neighbours, coordinates"); + CheckTrue(xN[0] <= xq[0] && xN[1] >= xq[0], + "1D edge neighbours do not bracket the requested value"); + } + Success(); + } + + Banner("Testing the reuse of the search between Get and GetNeighbours on Host."); + { + real xq[2]; + xq[0] = 2.1; + xq[1] = 3.5; + // The neighbours found by Get are stored in nb... + LookupTableSearchCache<2> nb; + result = csv.GetHost(xq, nb); + CheckClose(result, kValue2D, 1e-13, "Get-then-GetNeighbours (host), value"); + CheckTrue(nb.valid, "Get-then-GetNeighbours (host), search validity"); + CheckArrayEqual(nb.idx, kIdx2D, 2, "Get-then-GetNeighbours (host), cached idx"); + + // ... and are reused (not computed again) by the getters below + real xN[4]; + real dataN[4]; + int idx[2]; + int dataIdx[4]; + csv.GetNeighboursHost(xq, nb, xN, dataN); + csv.GetNeighboursIndxHost(xq, nb, idx, dataIdx); + CheckArrayEqual(xN, kXN2D, 4, "Get-then-GetNeighbours (host), coordinates"); + CheckArrayEqual(dataN, kDataN2D, 4, "Get-then-GetNeighbours (host), data"); + CheckArrayEqual(idx, kIdx2D, 2, "Get-then-GetNeighbours (host), idx"); + CheckArrayEqual(dataIdx, kDataIdx2D, 4, "Get-then-GetNeighbours (host), dataIdx"); + + // Check that the table is really not searched again for the same coordinates: we corrupt + // the stored search, and check that the corrupted result is the one which is used + nb.idx[0] = 1; + csv.GetNeighboursIndxHost(xq, nb, idx, dataIdx); + CheckEqual(idx[0], 1, "Get-then-GetNeighbours (host): the stored search was not reused"); + + // ... while different coordinates trigger a new search, as usual + real xq2[2]; + xq2[0] = 2.9; + xq2[1] = 2.5; + csv.GetNeighboursIndxHost(xq2, nb, idx, dataIdx); + CheckTrue(idx[0] == 0 && idx[1] == 0, + "Get-then-GetNeighbours (host): different coordinates did not trigger a new search"); + Success(); + } + + Banner("Testing the search performed by GetNeighbours first, and reused by Get, on Host."); + { + real xq[2]; + xq[0] = 2.1; + xq[1] = 3.5; + + // No call to Get yet: GetNeighbours searches the table as usual, and stores the result + LookupTableSearchCache<2> nb; + real xN[4]; + real dataN[4]; + csv.GetNeighboursHost(xq, nb, xN, dataN); + CheckTrue(nb.valid, "GetNeighbours-then-Get (host), search validity"); + CheckArrayEqual(nb.idx, kIdx2D, 2, "GetNeighbours-then-Get (host), cached idx"); + CheckArrayEqual(xN, kXN2D, 4, "GetNeighbours-then-Get (host), coordinates"); + CheckArrayEqual(dataN, kDataN2D, 4, "GetNeighbours-then-Get (host), data"); + + // Get now reuses that search for the same coordinates + result = csv.GetHost(xq, nb); + CheckClose(result, kValue2D, 1e-13, "GetNeighbours-then-Get (host), value"); + + // Same check as before, the other way around: we corrupt the ratio stored by + // GetNeighbours, and check that Get uses it instead of computing it again. + // With delta[0]=0.5 instead of 0.1, the interpolation gives (5+6+6+7)/4=6 + nb.delta[0] = 0.5; + result = csv.GetHost(xq, nb); + CheckClose(result, 6.0, 1e-13, + "GetNeighbours-then-Get (host): the stored search was not reused by Get"); + + // ... while different coordinates make Get search the table again + real xq2[2]; + xq2[0] = 2.9; + xq2[1] = 2.5; + result = csv.GetHost(xq2, nb); + CheckClose(result, csv.GetHost(xq2), 1e-13, + "GetNeighbours-then-Get (host): different coordinates did not trigger a new search"); + CheckEqual(nb.idx[1], 0, + "GetNeighbours-then-Get (host): different coordinates did not trigger a new search"); + + // The same holds when the search comes from GetNeighboursIndx, here on the 1D table + LookupTableSearchCache<1> nb1D; + real xq1[1]; + xq1[0] = 2.1; + int idx1[1]; + int dataIdx1[2]; + csv1D.GetNeighboursIndxHost(xq1, nb1D, idx1, dataIdx1); + CheckTrue(nb1D.valid, "GetNeighboursIndx-then-Get (host, 1D), search validity"); + CheckEqual(idx1[0], 1, "GetNeighboursIndx-then-Get (host, 1D), idx"); + nb1D.delta[0] = 0.0; // x is now on the left neighbour, so we expect its data + result = csv1D.GetHost(xq1, nb1D); + CheckClose(result, 4.0, 1e-13, + "GetNeighboursIndx-then-Get (host, 1D): the stored search was not reused by Get"); + Success(); } - idfx::cout << "Success" << std::endl; - idfx::cout << "--------------------------------------" << std::endl; - idfx::cout << "Testing 3D npy file on device." << std::endl; + Banner("Testing the reuse of the search between Get and GetNeighbours on device."); + { + IdefixArray1D xNdev = IdefixArray1D("xN",4); + IdefixArray1D dataNdev = IdefixArray1D("dataN",4); + IdefixArray1D idxDev = IdefixArray1D("idx",2); + IdefixArray1D dataIdxDev = IdefixArray1D("dataIdx",4); + + idefix_for("neighbours",0, 1, KOKKOS_LAMBDA (int i) { + real xq[2]; + xq[0] = 2.1; + xq[1] = 3.5; + // the structure is local to the loop, and is therefore private to each thread + LookupTableSearchCache<2> nb; + real xN[4]; + real dataN[4]; + int idx[2]; + int dataIdx[4]; + arr(i) = csv.Get(xq, nb); + csv.GetNeighbours(xq, nb, xN, dataN); + csv.GetNeighboursIndx(xq, nb, idx, dataIdx); + for(int n = 0 ; n < 4 ; n++) { + xNdev(n) = xN[n]; + dataNdev(n) = dataN[n]; + dataIdxDev(n) = dataIdx[n]; + } + idxDev(0) = idx[0]; + idxDev(1) = idx[1]; + }); + + Kokkos::deep_copy(arrHost , arr); + auto xNHost = Kokkos::create_mirror_view(xNdev); + auto dataNHost = Kokkos::create_mirror_view(dataNdev); + auto idxHost = Kokkos::create_mirror_view(idxDev); + auto dataIdxHost = Kokkos::create_mirror_view(dataIdxDev); + Kokkos::deep_copy(xNHost, xNdev); + Kokkos::deep_copy(dataNHost, dataNdev); + Kokkos::deep_copy(idxHost, idxDev); + Kokkos::deep_copy(dataIdxHost, dataIdxDev); + + // Same test on device, but with GetNeighbours called first and Get reusing its search. + // The ratio stored by GetNeighbours is corrupted in between, so that a value of 6 (instead + // of 5.6) proves that Get did not search the table again + IdefixArray1D valuesDev = IdefixArray1D("values",2); + idefix_for("neighboursFirst",0, 1, KOKKOS_LAMBDA (int i) { + real xq[2]; + xq[0] = 2.1; + xq[1] = 3.5; + LookupTableSearchCache<2> nb; + real xN[4]; + real dataN[4]; + // no call to Get yet: the search is performed here for the first time + csv.GetNeighbours(xq, nb, xN, dataN); + valuesDev(0) = csv.Get(xq, nb); + nb.delta[0] = 0.5; + valuesDev(1) = csv.Get(xq, nb); + }); + auto valuesHost = Kokkos::create_mirror_view(valuesDev); + Kokkos::deep_copy(valuesHost, valuesDev); + idfx::cout << "neighbours first: value=" << valuesHost(0) + << " (with a corrupted stored search)=" << valuesHost(1) << std::endl; + CheckClose(valuesHost(0), kValue2D, 1e-13, + "GetNeighbours-then-Get (device): the stored search was not reused by Get"); + CheckClose(valuesHost(1), 6.0, 1e-13, + "GetNeighbours-then-Get (device): the stored search was not reused by Get"); + + idfx::cout << "value=" << arrHost(0) << " x=" << xNHost(0) << "," << xNHost(1) + << " y=" << xNHost(2) << "," << xNHost(3) + << " data=" << dataNHost(0) << "," << dataNHost(1) << "," << dataNHost(2) + << "," << dataNHost(3) << " idx=" << idxHost(0) << "," << idxHost(1) << std::endl; + CheckClose(arrHost(0), kValue2D, 1e-13, "Get-then-GetNeighbours (device), value"); + real xN[4], dataN[4]; + int idx[2], dataIdx[4]; + for(int n = 0 ; n < 4 ; n++) { xN[n] = xNHost(n); dataN[n] = dataNHost(n); } + idx[0] = idxHost(0); idx[1] = idxHost(1); + for(int n = 0 ; n < 4 ; n++) dataIdx[n] = dataIdxHost(n); + CheckArrayEqual(xN, kXN2D, 4, "Get-then-GetNeighbours (device), coordinates"); + CheckArrayEqual(dataN, kDataN2D, 4, "Get-then-GetNeighbours (device), data"); + CheckArrayEqual(idx, kIdx2D, 2, "Get-then-GetNeighbours (device), idx"); + CheckArrayEqual(dataIdx, kDataIdx2D, 4, "Get-then-GetNeighbours (device), dataIdx"); + Success(); + } + + Banner("Testing 3D npy file on device."); // Read npy File std::vector coords({"x.npy","y.npy","z.npy"}); @@ -125,36 +581,21 @@ int main( int argc, char* argv[] ) }); Kokkos::deep_copy(arrHost , arr); - idfx::cout << "result="<1e-13) { - idfx::cerr << std::scientific; - idfx::cerr << "ERROR!!" << std::endl; - idfx::cerr << arrHost(0)-13.6; - exit(1); - } - idfx::cout << "Success" << std::endl; - - idfx::cout << "--------------------------------------" << std::endl; - idfx::cout << "Testing 3D npy file on host." << std::endl; + CheckClose(arrHost(0), 13.6, 1e-13, "3D npy, device"); + Success(); + Banner("Testing 3D npy file on host."); real y[3]; y[0] = 2.7; y[1] = 7.4; y[2] = 3.9; result = csvnpy.GetHost(y); - idfx::cout << "result="<< result << std::endl; - if(std::fabs(result - 13.6)>1e-13) { - idfx::cerr << std::scientific; - idfx::cerr << "ERROR!!" << std::endl; - idfx::cerr << result-13.6; - exit(1); - } - idfx::cout << "Success" << std::endl; - idfx::cout << "--------------------------------------" << std::endl; - idfx::cout << "Done." << std::endl; + CheckClose(result, 13.6, 1e-13, "3D npy, host"); + Success(); + Banner("Done."); } Kokkos::finalize(); #ifdef WITH_MPI diff --git a/test/utils/lookupTable/testme.json b/test/utils/lookupTable/testme.json index 8ea6f6961..d012528b4 100644 --- a/test/utils/lookupTable/testme.json +++ b/test/utils/lookupTable/testme.json @@ -1,12 +1,10 @@ { - "namings": "ini", - "variants": [ - { - "dumpname": "dump.0001.dmp", - "ini":["idefix.ini"], - "nonRegressionTest": false, - "standardTest": false, - "tolerance": 0 - } - ] + "default": { + "dumpname": "dump.0001.dmp", + "ini": "idefix.ini", + "nonRegressionTest": false, + "standardTest": false, + "tolerance": 0, + "callPyFunctionBefore": "testmelib.py:MakeNumpyFile" + } } diff --git a/test/utils/lookupTable/testme.py b/test/utils/lookupTable/testme.py index 53f6607f2..c724b6eb1 100755 --- a/test/utils/lookupTable/testme.py +++ b/test/utils/lookupTable/testme.py @@ -1,37 +1,36 @@ #!/usr/bin/env python3 +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/utils/lookupTable/testme.py +# +# Last modified : 08/2026 +# +# Copyright(C) by : +# - Geoffroy Lesur (IPAG/UGA/CNRS - 2023) +# - Clément Robert (IPAG/UGA/CNRS - 2026) +# - Sébastien Valat (IPAG/UGA/CNRS - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### """ @author: glesur """ + import os import sys -sys.path.append(os.getenv("IDEFIX_DIR")) -import numpy as np -#from scipy.interpolate import RegularGridInterpolator -import pytools.idfx_test as tst - -def MakeNumpyFile(): - x=np.arange(1,10,1.0) - y=np.arange(5,10,1.0) - z=np.arange(2,5,1.0) - - xp, yp, zp = np.meshgrid(x,y,z,indexing='ij') - - data=xp+2*yp-zp - - np.save("x.npy",x) - np.save("y.npy",y) - np.save("z.npy",z) - np.save("data.npy",data) - # show the expected result - #f=RegularGridInterpolator((x, y, z), data) - #print(f([2.7,7.4,3.9])) +sys.path.append(os.getenv("IDEFIX_DIR")) +# from scipy.interpolate import RegularGridInterpolator +import testmelib +import pytools.idfx_test as tst -test=tst.idfxTest(__file__) -MakeNumpyFile() +test = tst.idfxTest(__file__) +testmelib.MakeNumpyFile() test.configure() test.compile() diff --git a/test/utils/lookupTable/testmelib.py b/test/utils/lookupTable/testmelib.py new file mode 100644 index 000000000..52fb36434 --- /dev/null +++ b/test/utils/lookupTable/testmelib.py @@ -0,0 +1,42 @@ +###################################################################################### +# Idefix MHD astrophysical code +# +# Source file test/utils/lookupTable/testmelib.py +# +# Last modified : 08/2026 +# +# Copyright(C) by : +# - Sébastien Valat (IPAG/UGA/CNRS - 2026) +# - Alankar Dutta (MPA Garching - 2026) +# and other code contributors +# +# Licensed under CeCILL 2.1 License, see COPYING for more information +###################################################################################### + +import numpy as np +from scipy.interpolate import RegularGridInterpolator + + +def MakeNumpyFile(): + x = 2 ** np.arange(np.log2(1), np.log2(10), 0.2) + y = 2 ** np.arange(np.log2(5), np.log2(10), 0.2) + z = 2 ** np.arange(np.log2(2), np.log2(5), 0.2) + + print(x) + print(y) + print(z) + xp, yp, zp = np.meshgrid(x, y, z, indexing="ij") + + data = xp + 2 * yp - zp + + np.save("x.npy", x) + np.save("y.npy", y) + np.save("z.npy", z) + np.save("data.npy", data) + f = RegularGridInterpolator((x, y, z), data) + return f([2.7, 7.4, 3.9]) + + +if __name__ == "__main__": + f = MakeNumpyFile() + print("expected result:%f", f) diff --git a/test/utils/lookupTable/toto1Dcolumn.csv b/test/utils/lookupTable/toto1Dcolumn.csv new file mode 100644 index 000000000..291aa31cb --- /dev/null +++ b/test/utils/lookupTable/toto1Dcolumn.csv @@ -0,0 +1,5 @@ +# test csv file, same 1D table as toto1D.csv, but stored as columns + +1.0, 2.0 +2.0, 4.0 +3.0, 6.0 diff --git a/test/utils/lookupTable/toto1Dlog.csv b/test/utils/lookupTable/toto1Dlog.csv new file mode 100644 index 000000000..2cb5d5d51 --- /dev/null +++ b/test/utils/lookupTable/toto1Dlog.csv @@ -0,0 +1,6 @@ +# test csv file, power law data = x^2 stored as columns +# used to test the interpolation in function space + +1.0, 1.0 +2.0, 4.0 +4.0, 16.0