diff --git a/.github/workflows/cpuarch.yml b/.github/workflows/cpuarch.yml new file mode 100644 index 000000000..672d26395 --- /dev/null +++ b/.github/workflows/cpuarch.yml @@ -0,0 +1,107 @@ +name: CPU Compilation/Unit Tests + +on: + push: + +jobs: + check-commit: + runs-on: ubuntu-24.04 + outputs: + run_tests: ${{ steps.check_message.outputs.run_tests }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Check commit message + id: check_message + run: | + if git log -1 --pretty=%B | grep -q "CPUTEST"; then + echo "run_tests=true" >> "$GITHUB_OUTPUT" + else + echo "run_tests=false" >> "$GITHUB_OUTPUT" + fi + tests: + needs: check-commit + if: needs.check-commit.outputs.run_tests == 'true' + name: UNIT_TESTS (precision=${{ matrix.precision }}, mpi=${{ matrix.mpi }}, output=${{ matrix.output }}) + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + precision: [single, double] + mpi: [ON, OFF] + output: [ON, OFF] + exclude: + - precision: single + mpi: ON + output: ON + - precision: double + mpi: ON + output: ON + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + - name: Install GCC 14 and build tools + run: | + sudo apt-get update + sudo apt-get install -y gcc-14 g++-14 gfortran-14 build-essential wget libevent-dev libhwloc-dev + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 50 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 50 + sudo update-alternatives --install /usr/bin/gfortran gfortran /usr/bin/gfortran-14 50 + gcc --version + g++ --version + - name: Install CMake (3.x) + run: | + sudo apt-get install -y cmake + cmake --version + - name: Install OpenMPI 5 + run: | + sudo apt-get install -y libopenmpi-dev openmpi-bin + mpirun --version + - name: Configure + run: | + if [ "${{ matrix.mpi }}" = "ON" ]; then + export CC=mpicc + export CXX=mpicxx + else + export CC=gcc-14 + export CXX=g++-14 + fi + cmake -B build -D TESTS=ON -D precision=${{ matrix.precision }} -D mpi=${{ matrix.mpi }} -D output=${{ matrix.output }} + - name: Compile + run: cmake --build build -j "$(nproc)" + - name: Run tests + run: ctest --test-dir build --output-on-failure + pgens: + needs: check-commit + if: needs.check-commit.outputs.run_tests == 'true' + name: PGENS (pgen=${{ matrix.pgen }}) + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + pgen: [streaming, turbulence, reconnection, shock, magnetosphere, accretion, wald] + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + - name: Install GCC 14 and build tools + run: | + sudo apt-get update + sudo apt-get install -y gcc-14 g++-14 gfortran-14 build-essential wget libevent-dev libhwloc-dev + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 50 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 50 + sudo update-alternatives --install /usr/bin/gfortran gfortran /usr/bin/gfortran-14 50 + gcc --version + g++ --version + - name: Install CMake (3.x) + run: | + sudo apt-get install -y cmake + cmake --version + - name: Configure + run: | + cmake -B build -D pgen=${{ matrix.pgen }} -D output=OFF + - name: Compile + run: cmake --build build -j "$(nproc)" diff --git a/.github/workflows/actions.yml b/.github/workflows/multiarch.yml similarity index 94% rename from .github/workflows/actions.yml rename to .github/workflows/multiarch.yml index a5c546328..89af03747 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/multiarch.yml @@ -1,11 +1,11 @@ -name: Unit tests +name: Multi-Arch Local Tests on: push: jobs: check-commit: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 outputs: run_tests: ${{ steps.check_message.outputs.run_tests }} steps: @@ -14,7 +14,7 @@ jobs: - name: Check commit message id: check_message run: | - if git log -1 --pretty=%B | grep -q "RUNTEST"; then + if git log -1 --pretty=%B | grep -q "MARCHTEST"; then echo "run_tests=true" >> "$GITHUB_OUTPUT" else echo "run_tests=false" >> "$GITHUB_OUTPUT" diff --git a/CMakeLists.txt b/CMakeLists.txt index b0329435d..260c3e877 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ set(PROJECT_NAME entity) project( ${PROJECT_NAME} - VERSION 1.2.5 + VERSION 1.3.0 LANGUAGES CXX C) add_compile_options("-D ENTITY_VERSION=\"${PROJECT_VERSION}\"") set(hash_cmd "git diff --quiet src/ && echo $(git rev-parse HEAD) ") @@ -34,6 +34,15 @@ set(DEBUG set(precision ${default_precision} CACHE STRING "Precision") + +set(deposit + ${default_deposit} + CACHE STRING "Deposit") + +set(shape_order + ${default_shape_order} + CACHE STRING "Shape function") + set(pgen ${default_pgen} CACHE STRING "Problem generator") @@ -75,6 +84,20 @@ set(precisions "single" "double" CACHE STRING "Precisions") +set(deposits + "zigzag" "esirkepov" + CACHE STRING "Deposits") + +if(${deposit} STREQUAL "zigzag") + set(shape_order + ${default_shape_order} + CACHE STRING "Shape functions") +endif() + +set(shape_orders + "1;2;3;4;5;6;7;8;9;10;11" + CACHE STRING "Shape orders") + include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.cmake) # ------------------------- Third-Party Tests ------------------------------ # @@ -92,6 +115,7 @@ include_directories(${plog_SRC}/include) # -------------------------------- Main code ------------------------------- # set_precision(${precision}) +set_shape_order(${shape_order}) if("${Kokkos_DEVICES}" MATCHES "CUDA") add_compile_options("-D CUDA_ENABLED") set(DEVICE_ENABLED ON) diff --git a/cmake/adios2Config.cmake b/cmake/adios2Config.cmake index a4ce46179..0ff3a4e89 100644 --- a/cmake/adios2Config.cmake +++ b/cmake/adios2Config.cmake @@ -13,7 +13,7 @@ set(ADIOS2_USE_Fortran # Format/compression support set(ADIOS2_USE_HDF5 - ON + OFF CACHE BOOL "Use HDF5 for ADIOS2") set(ADIOS2_USE_MPI diff --git a/cmake/benchmark.cmake b/cmake/benchmark.cmake index 39b075716..fdd8438ea 100644 --- a/cmake/benchmark.cmake +++ b/cmake/benchmark.cmake @@ -20,7 +20,7 @@ add_executable(${exec} ${src}) set(libs ntt_global ntt_metrics ntt_kernels ntt_archetypes ntt_framework) if(${output}) - list(APPEND libs ntt_output ntt_checkpoint) + list(APPEND libs ntt_output) endif() add_dependencies(${exec} ${libs}) target_link_libraries(${exec} PRIVATE ${libs} stdc++fs) diff --git a/cmake/config.cmake b/cmake/config.cmake index 97ed658e3..e9b0de390 100644 --- a/cmake/config.cmake +++ b/cmake/config.cmake @@ -16,6 +16,16 @@ function(set_precision precision_name) endif() endfunction() +# ------------------------------- Shape function --------------------------- # +function(set_shape_order shape_order) + if(${deposit} STREQUAL "esirkepov") + if(${shape_order} GREATER 11) + message(FATAL_ERROR "Shape order must be between 1 and 11.") + endif() + add_compile_options("-DSHAPE_ORDER=${shape_order}") + endif() +endfunction() + # ---------------------------- Problem generator --------------------------- # function(set_problem_generator pgen_name) if(pgen_name STREQUAL ".") diff --git a/cmake/defaults.cmake b/cmake/defaults.cmake index 2bfa9a61c..fb8790019 100644 --- a/cmake/defaults.cmake +++ b/cmake/defaults.cmake @@ -19,6 +19,12 @@ set(default_engine set(default_precision "single" CACHE INTERNAL "Default precision") +set(default_deposit + "zigzag" + CACHE INTERNAL "Default deposit") +set(default_shape_order + 1 + CACHE INTERNAL "Default shape function order") set(default_pgen "." CACHE INTERNAL "Default problem generator") diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index 1780bf97e..1f3ed3c6a 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -58,7 +58,12 @@ function(find_or_fetch_dependency package_name header_only mode) FetchContent_Declare( ${package_name} GIT_REPOSITORY ${${package_name}_REPOSITORY} - GIT_TAG 4.6.01) + GIT_TAG 4.7.01) + elseif(${package_name} STREQUAL "adios2") + FetchContent_Declare( + ${package_name} + GIT_REPOSITORY ${${package_name}_REPOSITORY} + GIT_TAG v2.10.2) else() FetchContent_Declare(${package_name} GIT_REPOSITORY ${${package_name}_REPOSITORY}) diff --git a/cmake/report.cmake b/cmake/report.cmake index 33443d298..8f62ac17b 100644 --- a/cmake/report.cmake +++ b/cmake/report.cmake @@ -37,6 +37,24 @@ printchoices( "${Blue}" PRECISION_REPORT 46) +printchoices( + "Deposit" + "deposit" + "${deposits}" + ${deposit} + ${default_deposit} + "${Blue}" + DEPOSIT_REPORT + 46) +printchoices( + "Shape order" + "shape_order" + "${shape_orders}" + ${shape_order} + ${default_shape_order} + "${Blue}" + SHAPEFUNCTION_REPORT + 46) printchoices( "Output" "output" @@ -113,6 +131,12 @@ string( ${PRECISION_REPORT} "\n" " " + ${DEPOSIT_REPORT} + "\n" + " " + ${SHAPEFUNCTION_REPORT} + "\n" + " " ${OUTPUT_REPORT} "\n") diff --git a/cmake/styling.cmake b/cmake/styling.cmake index 5f1e4a7ad..daae19c65 100644 --- a/cmake/styling.cmake +++ b/cmake/styling.cmake @@ -140,12 +140,6 @@ function( else() padto("${rstring}" " " ${Padding} rstring) - set(new_choices ${Choices}) - foreach(ch IN LISTS new_choices) - string(REPLACE ${ch} "${Dim}${ch}${ColorReset}" new_choices - "${new_choices}") - endforeach() - set(Choices ${new_choices}) if(${Value} STREQUAL "ON") set(col ${Green}) elseif(${Value} STREQUAL "OFF") @@ -153,14 +147,23 @@ function( else() set(col ${Color}) endif() - if(NOT "${Value}" STREQUAL "") - string(REPLACE ${Value} "${col}${Value}${ColorReset}" Choices - "${Choices}") - endif() - if(NOT "${Default}" STREQUAL "") - string(REPLACE ${Default} "${Underline}${Default}${ColorReset}" Choices - "${Choices}") - endif() + set(new_choices "") + foreach(ch IN LISTS Choices) + set(elem "${ch}") + if((NOT "${Value}" STREQUAL "") AND (${ch} STREQUAL ${Value})) + set(elem "${col}${ch}${ColorReset}") + else() + set(elem "${Dim}${ch}${ColorReset}") + endif() + if((NOT "${Default}" STREQUAL "") AND (${ch} STREQUAL ${Default})) + set(elem "${Underline}${elem}${ColorReset}") + endif() + string(APPEND new_choices "${elem};") + endforeach() + string(LENGTH "${new_choices}" nlen) + math(EXPR nlen "${nlen} - 1") + string(SUBSTRING "${new_choices}" 0 ${nlen} new_choices) + set(Choices ${new_choices}) string(REPLACE ";" "/" Choices "${Choices}") string(APPEND rstring "${Choices}") endif() diff --git a/cmake/tests.cmake b/cmake/tests.cmake index 189cc2cc4..0eb043f70 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake @@ -9,9 +9,6 @@ add_subdirectory(${SRC_DIR}/kernels ${CMAKE_CURRENT_BINARY_DIR}/kernels) add_subdirectory(${SRC_DIR}/archetypes ${CMAKE_CURRENT_BINARY_DIR}/archetypes) add_subdirectory(${SRC_DIR}/framework ${CMAKE_CURRENT_BINARY_DIR}/framework) add_subdirectory(${SRC_DIR}/output ${CMAKE_CURRENT_BINARY_DIR}/output) -if(${output}) - add_subdirectory(${SRC_DIR}/checkpoint ${CMAKE_CURRENT_BINARY_DIR}/checkpoint) -endif() set(TEST_DIRECTORIES "") @@ -27,10 +24,6 @@ endif() list(APPEND TEST_DIRECTORIES output) -if(${output}) - list(APPEND TEST_DIRECTORIES checkpoint) -endif() - foreach(test_dir IN LISTS TEST_DIRECTORIES) add_subdirectory(${SRC_DIR}/${test_dir}/tests ${CMAKE_CURRENT_BINARY_DIR}/${test_dir}/tests) diff --git a/dev/nix/adios2.nix b/dev/nix/adios2.nix index 0418b71cd..a3890b788 100644 --- a/dev/nix/adios2.nix +++ b/dev/nix/adios2.nix @@ -19,7 +19,7 @@ let BUILD_TESTING = "OFF"; ADIOS2_BUILD_EXAMPLES = "OFF"; ADIOS2_USE_MPI = if mpi then "ON" else "OFF"; - ADIOS2_HAVE_HDF5_VOL = if mpi then "ON" else "OFF"; + ADIOS2_HAVE_HDF5_VOL = if (mpi && hdf5) then "ON" else "OFF"; CMAKE_BUILD_TYPE = "Release"; }; stdenv = pkgs.gcc13Stdenv; @@ -40,8 +40,27 @@ stdenv.mkDerivation { propagatedBuildInputs = [ pkgs.gcc13 - ] ++ (if hdf5 then (if mpi then [ pkgs.hdf5-mpi ] else [ pkgs.hdf5-cpp ]) else [ ]); - # ++ (if mpi then [ pkgs.openmpi ] else [ ]); + ] + ++ ( + if hdf5 then + ( + if mpi then + [ + pkgs.hdf5-mpi + ] + else + [ pkgs.hdf5-cpp ] + ) + else + ( + if mpi then + [ + pkgs.mpi + ] + else + [ ] + ) + ); configurePhase = '' cmake -B build $src ${ diff --git a/dev/nix/kokkos.nix b/dev/nix/kokkos.nix index 2f6ee6b99..7d86e665b 100644 --- a/dev/nix/kokkos.nix +++ b/dev/nix/kokkos.nix @@ -7,7 +7,7 @@ let name = "kokkos"; - pversion = "4.6.01"; + pversion = "4.7.01"; compilerPkgs = { "HIP" = with pkgs.rocmPackages; [ llvm.rocm-merged-llvm @@ -56,7 +56,7 @@ pkgs.stdenv.mkDerivation rec { src = pkgs.fetchgit { url = "https://github.com/kokkos/kokkos/"; rev = "${pversion}"; - sha256 = "sha256-+yszUbdHqhIkJZiGLZ9Ln4DYUosuJWKhO8FkbrY0/tY="; + sha256 = "sha256-MgphOsKE8umgYxVQZzex+elgvDDC09JaMCoU5YXaLco="; }; nativeBuildInputs = with pkgs; [ @@ -92,15 +92,4 @@ pkgs.stdenv.mkDerivation rec { installPhase = '' cmake --install build ''; - - # cmakeFlags = [ - # "-D CMAKE_CXX_STANDARD=17" - # "-D CMAKE_CXX_EXTENSIONS=OFF" - # "-D CMAKE_POSITION_INDEPENDENT_CODE=TRUE" - # "-D Kokkos_ARCH_${getArch { }}=ON" - # (if gpu != "none" then "-D Kokkos_ENABLE_${gpu}=ON" else "") - # "-D CMAKE_BUILD_TYPE=Release" - # ] ++ (cmakeExtraFlags.${gpu} src); - - # enableParallelBuilding = true; } diff --git a/dev/nix/shell.nix b/dev/nix/shell.nix index 33ae57095..0d4cc9119 100644 --- a/dev/nix/shell.nix +++ b/dev/nix/shell.nix @@ -5,7 +5,7 @@ }, gpu ? "NONE", arch ? "NATIVE", - hdf5 ? true, + hdf5 ? false, mpi ? false, }: @@ -62,27 +62,26 @@ pkgs.mkShell { pkgs.zlib ]); - shellHook = - '' - BLUE='\033[0;34m' - NC='\033[0m' + shellHook = '' + BLUE='\033[0;34m' + NC='\033[0m' - echo "following environment variables are set:" - '' - + pkgs.lib.concatStringsSep "" ( - pkgs.lib.mapAttrsToList ( - category: vars: - pkgs.lib.concatStringsSep "" ( - pkgs.lib.mapAttrsToList (name: value: '' - export ${name}=${value} - echo -e " ''\${BLUE}${name}''\${NC}=${value}" - '') vars.${gpuUpper} - ) - ) envVars - ) - + '' - echo "" - echo -e "${name} nix-shell activated" - ''; + echo "following environment variables are set:" + '' + + pkgs.lib.concatStringsSep "" ( + pkgs.lib.mapAttrsToList ( + category: vars: + pkgs.lib.concatStringsSep "" ( + pkgs.lib.mapAttrsToList (name: value: '' + export ${name}=${value} + echo -e " ''\${BLUE}${name}''\${NC}=${value}" + '') vars.${gpuUpper} + ) + ) envVars + ) + + '' + echo "" + echo -e "${name} nix-shell activated" + ''; } diff --git a/input.example.toml b/input.example.toml index 028102b08..9a4aedee3 100644 --- a/input.example.toml +++ b/input.example.toml @@ -201,16 +201,6 @@ # @default: 0 current_filters = "" - [algorithms.toggles] - # Toggle for the field solver - # @type: bool - # @default: true - fieldsolver = "" - # Toggle for the current deposition - # @type: bool - # @default: true - deposit = "" - [algorithms.timestep] # Courant-Friedrichs-Lewy number # @type: float [0.0 -> 1.0] @@ -229,6 +219,16 @@ # @from: `algorithms.timestep.CFL`, `scales.dx0` # @value: `CFL * dx0` + [algorithms.deposit] + # Enable the current deposition + # @type: bool + # @default: true + enable = "" + # Order of the particle shape function + # @type: int + # @default: 1 + order = "" + [algorithms.gr] # Stepsize for numerical differentiation in GR pusher # @type: float [> 0.0] @@ -257,6 +257,54 @@ # @note: [required] if one of the species has `cooling = "synchrotron"` gamma_rad = "" + # Stencil coefficients for the field solver [notation as in Blinne+ (2018)] + # @note: Standard Yee solver: `delta_i = beta_ij = 0.0` + [algorithms.fieldsolver] + # delta_x coefficient (for `F_{i +/- 3/2, j, k}`) + # @type: float + # @default: 0.0 + delta_x = "" + # delta_y coefficient (for `F_{i, j +/- 3/2, k}`) + # @type: float + # @default: 0.0 + # @note: Used only for 2D and 3D + delta_y = "" + # delta_z coefficient (for `F_{i, j, k +/- 3/2}`) + # @type: float + # @default: 0.0 + # @note: Used only for 3D + delta_z = "" + # beta_xy coefficient (for `F_{i +/- 1/2, j +/- 1, k}`) + # @type: float + # @default: 0.0 + # @note: Used only for 2D and 3D + beta_xy = "" + # beta_yx coefficient (for `F_{i +/- 1, j +/- 1/2, k}`) + # @type: float + # @default: 0.0 + # @note: Used only for 2D and 3D + beta_yx = "" + # beta_xz coefficient (for `F_{i +/- 1/2, j, k +/- 1}`) + # @type: float + # @default: 0.0 + # @note: Used only for 3D + beta_xz = "" + # beta_zx coefficient (for `F_{i +/- 1, j, k +/- 1/2}`) + # @type: float + # @default: 0.0 + # @note: Used only for 3D + beta_zx = "" + # beta_yz coefficient (for `F_{i, j +/- 1/2, k +/- 1}`) + # @type: float + # @default: 0.0 + # @note: Used only for 3D + beta_yz = "" + # beta_zy coefficient (for `F_{i, j +/- 1, k +/- 1/2}`) + # @type: float + # @default: 0.0 + # @note: Used only for 3D + beta_zy = "" + [particles] # Fiducial number of particles per cell # @required @@ -302,10 +350,19 @@ # @default: "Boris" [massive]; "Photon" [massless] # @enum: "Boris", "Vay", "Boris,GCA", "Vay,GCA", "Photon", "None" pusher = "" - # Number of additional (payload) variables for each particle of the given species + # Number of additional real-valued variables (payloads) for each particle of the given species # @type: ushort # @default: 0 - n_payloads = "" + n_payloads_real = "" + # Number of additional integer-valued variables (payloads) for each particle of the given species + # @type: ushort + # @default: 0 + # @note: If tracking is enabled, one or two extra integer payloads are reserved (depending on whether MPI is enabled) + n_payloads_int = "" + # Enable tracking of particles using indices for the given species + # @type: bool + # @default: false + tracking = "" # Radiation reaction to use for the species # @type: string # @default: "None" diff --git a/legacy/Makefile.in b/legacy/Makefile.in deleted file mode 100644 index 70d9da31a..000000000 --- a/legacy/Makefile.in +++ /dev/null @@ -1,174 +0,0 @@ -# # # # # Directories # # # # # # # # # # -# -ROOT_DIR := $(realpath ${CURDIR}/..) -# directory for the building -BUILD_DIR := ${ROOT_DIR}/@BUILD_DIR@ -# directory for the executable -BIN_DIR := ${ROOT_DIR}/@BIN_DIR@ -TEMP_DIR := .temp - -TARGET := @NTT_TARGET@ -TEST_TARGET := @TEST_TARGET@ - -PGEN_DIR := ${ROOT_DIR}/@PGEN_DIR@ - -PGEN := @PGEN@ - -SRC_DIR := ${ROOT_DIR}/@SRC_DIR@ -BUILD_SRC_DIR := @SRC_DIR@ - -# external libraries -EXT_DIR := ${ROOT_DIR}/@EXTERN_DIR@ - -# # # # # Settings # # # # # # # # # # # # -# -DEBUGMODE := @DEBUGMODE@ -VERBOSE := @VERBOSE@ - -DEFINITIONS := @DEFINITIONS@ - -ifeq ($(strip ${VERBOSE}), y) - HIDE = - PREPFLAGS = -DVERBOSE -Werror -else - HIDE = @ -endif - -# 3-rd party library configurations -KOKKOS_PATH := ${EXT_DIR}/kokkos -KOKKOS_BUILD_DIR = ${BUILD_DIR}/kokkos/ - -KOKKOS_ARCH := @KOKKOS_ARCH@ -KOKKOS_DEVICES := @KOKKOS_DEVICES@ -KOKKOS_OPTIONS := @KOKKOS_OPTIONS@ - -KOKKOS_CUDA_OPTIONS := @KOKKOS_CUDA_OPTIONS@ -KOKKOS_CXX_STANDARD := @CXXSTANDARD@ - -PREPFLAGS := ${PREPFLAGS} - -# # # # # Compiler and flags # # # # # # # -# -CXX := @COMPILER@ -HOST_CXX := @HOST_COMPILER@ -LINK := ${CXX} -CXXSTANDARD := -std=@CXXSTANDARD@ -ifeq ($(strip ${DEBUGMODE}), n) - # linker configuration flags (e.g. optimization level) - CFLAGS := @RELEASE_CFLAGS@ -else - CFLAGS := @DEBUG_CFLAGS@ -endif - -# warning flags -WARNFLAGS := @WARNING_FLAGS@ - -# custom preprocessor flags -PREPFLAGS := $(PREPFLAGS) @PRECISION@ -D@METRIC@_METRIC -D@SIMTYPE@_SIMTYPE - -CFLAGS := $(CFLAGS) $(WARNFLAGS) $(PREPFLAGS) -LIBS := -lstdc++fs - -# # # # # Targets # # # # # # # # # # # # # # -# -.PHONY: help ntt demo clean cleanlib cleanall pgenCopy - -default: help demo - -# linking the main app -ntt : pgenCopy ${BIN_DIR}/${TARGET} - @echo [M]aking $@ - -ifeq (${PGEN},) -PGEN := dummy -endif - -# Problem generator -pgenCopy: ${SRC_DIR}/${TEMP_DIR}/problem_generator.cpp ${SRC_DIR}/${TEMP_DIR}/problem_generator.hpp - -${SRC_DIR}/${TEMP_DIR}/problem_generator.cpp : ${PGEN_DIR}/${PGEN}.cpp - $(HIDE)mkdir -p ${SRC_DIR}/${TEMP_DIR} - $(HIDE)cp $< $@ - -${SRC_DIR}/${TEMP_DIR}/problem_generator.hpp : ${PGEN_DIR}/${PGEN}.hpp - $(HIDE)mkdir -p ${SRC_DIR}/${TEMP_DIR} - $(HIDE)cp $< $@ - -help: - @echo - @echo "usage: \`make [ ntt | vis | demo ]\`" - @echo - @echo "cleanup: \`make [ clean | cleanlib | cleanall ]\`" - @echo - -demo: - @echo "[C]ompile command:" - @echo ${compile_command} -c \<.cpp\> -o \<.o\> - @echo - @echo "[L]ink command:" - @echo ${link_command} \<.o\> $(LIBS) -o \ - -# # # # # File collection # # # # # # # # # # # -# -# Src files -simtype := @SIMTYPE@ -simtype := $(shell echo $(simtype) | tr A-Z a-z) -SRCS := $(wildcard ${SRC_DIR}/*.cpp ${SRC_DIR}/*.c) -SRCS := $(SRCS) ${SRC_DIR}/${TEMP_DIR}/problem_generator.cpp -SRCS := $(SRCS) $(shell @FIND@ ${SRC_DIR}/framework -name "*.cpp" -o -name "*.c") -SRCS := $(SRCS) $(shell @FIND@ ${SRC_DIR}/${simtype} -name "*.cpp" -o -name "*.c") -SRCS := $(filter-out ${SRC_DIR}/main.cpp, $(SRCS)) -OBJS := $(subst ${SRC_DIR},${BUILD_SRC_DIR},$(SRCS:%=%.o)) -DEPS := $(OBJS:.o=.d) - -# Main app -MAIN_SRCS := ${SRC_DIR}/main.cpp -MAIN_OBJS := $(subst ${SRC_DIR},${BUILD_SRC_DIR},$(MAIN_SRCS:%=%.o)) -MAIN_DEPS := $(MAIN_OBJS:.o=.d) - -INC_DIRS := $(shell @FIND@ ${SRC_DIR} -type d) ${SRC_DIR}/${TEMP_DIR} ${EXT_DIR}/plog/include ${EXT_DIR}/doctest/doctest ${EXT_DIR} ${EXT_DIR}/rapidcsv/src -INCFLAGS := $(addprefix -I,${INC_DIRS}) - -# # # # # Link/compile # # # # # # # # # # # # # # - -include ${KOKKOS_PATH}/Makefile.kokkos -OBJS := $(OBJS) $(KOKKOS_LINK_DEPENDS) -CFLAGS := $(CFLAGS) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) -LDFLAGS := $(LDFLAGS) $(KOKKOS_LDFLAGS) -LIBS := $(LIBS) $(KOKKOS_LIBS) -CFLAGS := $(filter-out ${CXXSTANDARD}, $(CFLAGS)) - -compile_command := ${CXX} ${CXXSTANDARD} $(INCFLAGS) $(DEFINITIONS) $(CFLAGS) -MMD -link_command := ${LINK} $(LDFLAGS) - -${BIN_DIR}/${TARGET} : $(MAIN_OBJS) $(OBJS) - @echo [L]inking $(notdir $@) from $< - $(HIDE)mkdir -p ${BIN_DIR} - $(HIDE)${link_command} $^ -o $@ $(LIBS) - -${BUILD_SRC_DIR}/%.o : ${SRC_DIR}/% - @echo [C]ompiling \`src\`: $(subst ${ROOT_DIR}/,,$<) - $(HIDE)mkdir -p $(dir $@) - $(HIDE)${compile_command} -c $< -o $@ - -include ${ROOT_DIR}/Tests.mk -include ${ROOT_DIR}/Docs.mk - -# to ensure recompilation when header files are changed --include $(DEPS) $(MAIN_DEPS) - -# for nttiny /> -NTTINY_DIR := @NTTINY_DIR@ -VIS_DIR := ${ROOT_DIR}/@VIS_DIR@ -include ${ROOT_DIR}/Nttiny.mk -# - struct InitFields { - InitFields(real_t bsurf, real_t rstar) : Bsurf { bsurf }, Rstar { rstar } {} - - Inline auto bx1(const coord_t& x_Ph) const -> real_t { - return Bsurf * SQR(Rstar / x_Ph[0]); - } - - private: - const real_t Bsurf, Rstar; - }; - - template - struct DriveFields : public InitFields { - DriveFields(real_t time, real_t bsurf, real_t rstar, real_t omega) - : InitFields { bsurf, rstar } - , time { time } - , Omega { omega } {} - - using InitFields::bx1; - - Inline auto bx2(const coord_t&) const -> real_t { - return ZERO; - } - - Inline auto bx3(const coord_t&) const -> real_t { - return ZERO; - } - - Inline auto ex1(const coord_t& x_Ph) const -> real_t { - return ZERO; - } - - Inline auto ex2(const coord_t& x_Ph) const -> real_t { - return -Omega * bx1(x_Ph) * x_Ph[0] * math::sin(x_Ph[1]); - } - - Inline auto ex3(const coord_t&) const -> real_t { - return ZERO; - } - - private: - const real_t time, Omega; - }; - - template - struct PGen : public arch::ProblemGenerator { - // compatibility traits for the problem generator - static constexpr auto engines { traits::compatible_with::value }; - static constexpr auto metrics { - traits::compatible_with::value - }; - static constexpr auto dimensions { traits::compatible_with::value }; - - // for easy access to variables in the child class - using arch::ProblemGenerator::D; - using arch::ProblemGenerator::C; - using arch::ProblemGenerator::params; - - const real_t Bsurf, Rstar, Omega; - InitFields init_flds; - - inline PGen(const SimulationParams& p, const Metadomain& m) - : arch::ProblemGenerator(p) - , Bsurf { p.template get("setup.Bsurf", ONE) } - , Rstar { m.mesh().extent(in::x1).first } - , Omega { static_cast(constant::TWO_PI) / - p.template get("setup.period", ONE) } - , init_flds { Bsurf, Rstar } {} - - inline PGen() {} - - auto AtmFields(real_t time) const -> DriveFields { - return DriveFields { time, Bsurf, Rstar, Omega }; - } - }; - -} // namespace user - -#endif diff --git a/legacy/benchmark.cpp b/legacy/benchmark.cpp deleted file mode 100644 index 54fc17cf9..000000000 --- a/legacy/benchmark.cpp +++ /dev/null @@ -1,273 +0,0 @@ -#include "enums.h" -#include "global.h" - -#include "utils/error.h" - -#include "metrics/metric_base.h" -#include "metrics/minkowski.h" - -#include "framework/containers/species.h" -#include "framework/domain/domain.h" -#include "framework/domain/metadomain.h" - -#include - -#include "framework/domain/communications.cpp" -#include "mpi.h" -#include "mpi-ext.h" - -#define TIMER_START(label) \ - Kokkos::fence(); \ - auto start_##label = std::chrono::high_resolution_clock::now(); - -#define TIMER_STOP(label) \ - Kokkos::fence(); \ - auto stop_##label = std::chrono::high_resolution_clock::now(); \ - auto duration_##label = std::chrono::duration_cast( \ - stop_##label - start_##label) \ - .count(); \ - std::cout << "Timer [" #label "]: " << duration_##label << " microseconds" \ - << std::endl; - -/* - Test to check the performance of the new particle allocation scheme - - Create a metadomain object main() - - Set npart + initialize tags InitializeParticleArrays() - - 'Push' the particles by randomly updating the tags PushParticles() - - Communicate particles to neighbors and time the communication - - Compute the time taken for best of N iterations for the communication - */ -using namespace ntt; - -// Set npart and set the particle tags to alive -template -void InitializeParticleArrays(Domain& domain, const int npart) { - raise::ErrorIf(npart > domain.species[0].maxnpart(), - "Npart cannot be greater than maxnpart", - HERE); - const auto nspecies = domain.species.size(); - for (int i_spec = 0; i_spec < nspecies; i_spec++) { - domain.species[i_spec].set_npart(npart); - domain.species[i_spec].SyncHostDevice(); - auto& this_tag = domain.species[i_spec].tag; - Kokkos::parallel_for( - "Initialize particles", - npart, - Lambda(const std::size_t i) { this_tag(i) = ParticleTag::alive; }); - } - return; -} - -// Randomly reassign tags to particles for a fraction of particles -template -void PushParticles(Domain& domain, - const double send_frac, - const int seed_ind, - const int seed_tag) { - raise::ErrorIf(send_frac > 1.0, "send_frac cannot be greater than 1.0", HERE); - const auto nspecies = domain.species.size(); - for (int i_spec = 0; i_spec < nspecies; i_spec++) { - domain.species[i_spec].set_unsorted(); - const auto nparticles = domain.species[i_spec].npart(); - const auto nparticles_to_send = static_cast(send_frac * nparticles); - // Generate random indices to send - // Kokkos::Random_XorShift64_Pool<> random_pool(seed_ind); - Kokkos::View indices_to_send("indices_to_send", nparticles_to_send); - Kokkos::fill_random(indices_to_send, domain.random_pool, 0, nparticles); - // Generate random tags to send - // Kokkos::Random_XorShift64_Pool<> random_pool_tag(seed_tag); - Kokkos::View tags_to_send("tags_to_send", nparticles_to_send); - Kokkos::fill_random(tags_to_send, - domain.random_pool, - 0, - domain.species[i_spec].ntags()); - auto& this_tag = domain.species[i_spec].tag; - Kokkos::parallel_for( - "Push particles", - nparticles_to_send, - Lambda(const std::size_t i) { - auto prtl_to_send = indices_to_send(i); - auto tag_to_send = tags_to_send(i); - this_tag(prtl_to_send) = tag_to_send; - }); - domain.species[i_spec].npart_per_tag(); - domain.species[i_spec].SyncHostDevice(); - } - return; -} - -auto main(int argc, char* argv[]) -> int { - GlobalInitialize(argc, argv); - { - /* - MPI checks - */ - printf("Compile time check:\n"); -#if defined(MPIX_CUDA_AWARE_SUPPORT) && MPIX_CUDA_AWARE_SUPPORT - printf("This MPI library has CUDA-aware support.\n", MPIX_CUDA_AWARE_SUPPORT); -#elif defined(MPIX_CUDA_AWARE_SUPPORT) && !MPIX_CUDA_AWARE_SUPPORT - printf("This MPI library does not have CUDA-aware support.\n"); -#else - printf("This MPI library cannot determine if there is CUDA-aware support.\n"); -#endif /* MPIX_CUDA_AWARE_SUPPORT */ -printf("Run time check:\n"); -#if defined(MPIX_CUDA_AWARE_SUPPORT) - if (1 == MPIX_Query_cuda_support()) { - printf("This MPI library has CUDA-aware support.\n"); - } else { - printf("This MPI library does not have CUDA-aware support.\n"); - } -#else /* !defined(MPIX_CUDA_AWARE_SUPPORT) */ - printf("This MPI library cannot determine if there is CUDA-aware support.\n"); -#endif /* MPIX_CUDA_AWARE_SUPPORT */ - - /* - Test to send and receive Kokkos arrays - */ - int sender_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &sender_rank); - - int neighbor_rank = 0; - if (sender_rank == 0) { - neighbor_rank = 1; - } - else if (sender_rank == 1) { - neighbor_rank = 0; - } - else { - raise::Error("This test is only for 2 ranks", HERE); - } - Kokkos::View send_array("send_array", 10); - Kokkos::View recv_array("recv_array", 10); - if (sender_rank == 0) { - Kokkos::deep_copy(send_array, 10); - } - else { - Kokkos::deep_copy(send_array, 20); - } - - auto send_array_host = Kokkos::create_mirror_view(send_array); - Kokkos::deep_copy(send_array_host, send_array); - auto host_recv_array = Kokkos::create_mirror_view(recv_array); - - MPI_Sendrecv(send_array.data(), send_array.extent(0), MPI_INT, neighbor_rank, 0, - recv_array.data(), recv_array.extent(0), MPI_INT, neighbor_rank, 0, - MPI_COMM_WORLD, MPI_STATUS_IGNORE); - - // Print the received array - Kokkos::deep_copy(host_recv_array, recv_array); - for (int i = 0; i < 10; ++i) { - printf("Rank %d: Received %d\n", sender_rank, host_recv_array(i)); - } - - - std::cout << "Constructing the domain" << std::endl; - // Create a Metadomain object - const unsigned int ndomains = 2; - const std::vector global_decomposition = { - {-1, -1, -1} - }; - const std::vector global_ncells = { 32, 32, 32 }; - const boundaries_t global_extent = { - {0.0, 3.0}, - {0.0, 3.0}, - {0.0, 3.0} - }; - const boundaries_t global_flds_bc = { - {FldsBC::PERIODIC, FldsBC::PERIODIC}, - {FldsBC::PERIODIC, FldsBC::PERIODIC}, - {FldsBC::PERIODIC, FldsBC::PERIODIC} - }; - const boundaries_t global_prtl_bc = { - {PrtlBC::PERIODIC, PrtlBC::PERIODIC}, - {PrtlBC::PERIODIC, PrtlBC::PERIODIC}, - {PrtlBC::PERIODIC, PrtlBC::PERIODIC} - }; - const std::map metric_params = {}; - const int maxnpart = argc > 1 ? std::stoi(argv[1]) : 1000; - const double npart_to_send_frac = 0.01; - const int npart = static_cast(maxnpart * (1 - 2 * npart_to_send_frac)); - auto species = ntt::ParticleSpecies(1u, - "test_e", - 1.0f, - 1.0f, - maxnpart, - ntt::PrtlPusher::BORIS, - false, - ntt::Cooling::NONE); - auto metadomain = Metadomain>( - ndomains, - global_decomposition, - global_ncells, - global_extent, - global_flds_bc, - global_prtl_bc, - metric_params, - { species }); - - const auto local_subdomain_idx = metadomain.l_subdomain_indices()[0]; - auto local_domain = metadomain.subdomain_ptr(local_subdomain_idx); - auto timers = timer::Timers { { "Communication" }, nullptr, false }; - InitializeParticleArrays(*local_domain, npart); - // Timers for both the communication routines - auto total_time_elapsed_old = 0; - auto total_time_elapsed_new = 0; - - int seed_ind = 0; - int seed_tag = 1; - Kokkos::fence(); - - for (int i = 0; i < 10; ++i) { - { - // Push - seed_ind += 2; - seed_tag += 3; - PushParticles(*local_domain, npart_to_send_frac, seed_ind, seed_tag); - // Sort new - Kokkos::fence(); - auto start_new = std::chrono::high_resolution_clock::now(); - metadomain.CommunicateParticlesBuffer(*local_domain, &timers); - auto stop_new = std::chrono::high_resolution_clock::now(); - auto duration_new = std::chrono::duration_cast( - stop_new - start_new) - .count(); - total_time_elapsed_new += duration_new; - Kokkos::fence(); - } - { - // Push - seed_ind += 2; - seed_tag += 3; - PushParticles(*local_domain, npart_to_send_frac, seed_ind, seed_tag); - // Sort old - Kokkos::fence(); - auto start_old = std::chrono::high_resolution_clock::now(); - metadomain.CommunicateParticles(*local_domain, &timers); - auto stop_old = std::chrono::high_resolution_clock::now(); - auto duration_old = std::chrono::duration_cast( - stop_old - start_old) - .count(); - total_time_elapsed_old += duration_old; - Kokkos::fence(); - } - } - printf("Total time elapsed for old: %f us : %f us/prtl\n", - total_time_elapsed_old / 10.0, - total_time_elapsed_old / 10.0 * 1000 / npart); - printf("Total time elapsed for new: %f us : %f us/prtl\n", - total_time_elapsed_new / 10.0, - total_time_elapsed_new / 10.0 * 1000 / npart); - } - GlobalFinalize(); - return 0; -} - -/* - Buggy behavior: - Consider a single domain with a single mpi rank - Particle tag arrays is set to [0, 0, 1, 1, 2, 3, ...] for a single domain - CommunicateParticles() discounts all the dead particles and reassigns the - other tags to alive - CommunicateParticlesBuffer() only keeps the ParticleTag::Alive particles - and discounts the rest -*/ diff --git a/legacy/benchmarks/CMakeLists.txt b/legacy/benchmarks/CMakeLists.txt deleted file mode 100644 index 257a0f0ea..000000000 --- a/legacy/benchmarks/CMakeLists.txt +++ /dev/null @@ -1,61 +0,0 @@ -set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../src) - -# include main source directory for all targets -include_directories(${SOURCE_DIR}) - -# --------------------------------- Wrapper -------------------------------- # -set(WRAPPER ${PROJECT_NAME}-wrapper) -add_library(${WRAPPER} STATIC ${SOURCE_DIR}/wrapper/kokkos.cpp) - -# link wrapper with all targets -link_libraries(${WRAPPER}) - -# include wrapper header for all targets -include_directories(${SOURCE_DIR}/wrapper) - -# -------------------------------- Framework ------------------------------- # -file(GLOB_RECURSE FRAMEWORK_FILES ${SOURCE_DIR}/framework/*.cpp) -file(GLOB_RECURSE PIC_FILES ${SOURCE_DIR}/pic/*.cpp) -file(GLOB_RECURSE GRPIC_FILES ${SOURCE_DIR}/grpic/*.cpp) - -# include framework headers for all targets -include_directories(${SOURCE_DIR}/framework) - -set(all_metrics ${sr_metrics} ${gr_metrics}) - -# Libraries for all metrics and engines -# compile framework for all metrics and engines + all engines with corresponding metrics -foreach(metric ${all_metrics}) - list(FIND sr_metrics ${metric} sr_metric_index) - - if(NOT ${sr_metric_index} EQUAL -1) - set(engine pic) - else() - set(engine grpic) - endif() - - string(TOUPPER ${metric} metric_upper) - string(TOUPPER ${engine} engine_upper) - - add_library(framework-${metric} STATIC ${FRAMEWORK_FILES}) - target_compile_options(framework-${metric} PUBLIC -D${metric_upper}_METRIC -D${engine_upper}_ENGINE -DSIMULATION_METRIC=\"${metric}\" -DMETRIC_HEADER=\"metrics/${metric}.h\") - - add_library(engine-${engine}-${metric} STATIC ${${engine_upper}_FILES}) - - target_compile_options(engine-${engine}-${metric} PUBLIC -D${metric_upper}_METRIC -D${engine_upper}_ENGINE -DSIMULATION_METRIC=\"${metric}\" -DMETRIC_HEADER=\"metrics/${metric}.h\") - target_compile_options(engine-${engine}-${metric} PUBLIC "-DPGEN_HEADER=\"pgen/dummy.hpp\"") - target_include_directories(engine-${engine}-${metric} PRIVATE ${SOURCE_DIR}/${engine}) -endforeach() - -# ----------------------------------- Benchmarks ----------------------------------- # -function(define_benchmark metric engine title file) - add_executable(bmark-${title}.xc ${file}) - target_link_libraries(bmark-${title}.xc PUBLIC framework-${metric} engine-${engine}-${metric}) - target_include_directories(bmark-${title}.xc PRIVATE ${SOURCE_DIR}/${engine}) -endfunction() - -define_benchmark("minkowski" "pic" "sr-mink" "sr-mink.cpp") -define_benchmark("spherical" "pic" "sr-sph" "sr-sph.cpp") -define_benchmark("qspherical" "pic" "sr-qsph" "sr-sph.cpp") -define_benchmark("kerr_schild" "grpic" "gr-ks" "gr.cpp") -define_benchmark("qkerr_schild" "grpic" "gr-qks" "gr.cpp") \ No newline at end of file diff --git a/legacy/benchmarks/gr.cpp b/legacy/benchmarks/gr.cpp deleted file mode 100644 index b00603603..000000000 --- a/legacy/benchmarks/gr.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include "wrapper.h" - -#include "field_macros.h" -#include "grpic.h" -#include "sim_params.h" - -#include "io/cargs.h" -#include "io/input.h" -#include "meshblock/meshblock.h" - -#include "utilities/archetypes.hpp" -#include "utilities/injector.hpp" - -#include - -#include -#include -#include -#include -#include - -Inline void EMfield(const ntt::coord_t& x_ph, - ntt::vec_t& d_out, - ntt::vec_t& b_out, - const real_t sx1, - const real_t sx2) { - const real_t kx1_x1 = ntt::constant::TWO_PI * x_ph[0] / sx1; - const real_t kx2_x2 = ntt::constant::TWO_PI * x_ph[1] / sx2; - d_out[0] = math::cos(kx1_x1) * math::sin(kx2_x2); - d_out[1] = -math::sin(kx1_x1) * math::cos(kx2_x2); - d_out[2] = math::cos(kx1_x1) * math::cos(kx2_x2); - b_out[0] = math::sin(kx1_x1) * math::cos(kx2_x2); - b_out[1] = -math::cos(kx1_x1) * math::sin(kx2_x2); - b_out[2] = math::sin(kx1_x1) * math::sin(kx2_x2); -} - -template -struct MaxwellianDist : public ntt::EnergyDistribution { - MaxwellianDist(const ntt::SimulationParams& params, const ntt::Meshblock& mblock) - : ntt::EnergyDistribution(params, mblock), - maxwellian { mblock }, - temperature { 0.001 } {} - Inline void operator()(const ntt::coord_t&, - ntt::vec_t& v, - const int& species) const override { - maxwellian(v, temperature); - } - -private: - const ntt::Maxwellian maxwellian; - const real_t temperature; -}; - -using namespace toml::literals::toml_literals; -const auto default_input { - R"( - [domain] - resolution = [8192, 8192] - extent = [1.0, 50.0] - boundaries = [["OPEN", "ABSORB"], ["AXIS"]] - sph_rabsorb = 45.0 - qsph_r0 = 0.0 - qsph_h = 0.0 - a = 0.95 - - [units] - ppc0 = 1.0 - larmor0 = 2.0 - skindepth0 = 1.0 - - [particles] - n_species = 2 - - [species_1] - label = "e-" - mass = 1.0 - charge = -1.0 - maxnpart = 1e8 - - [species_2] - label = "e+" - mass = 25.0 - charge = 1.0 - maxnpart = 1e8 - - [diagnostics] - blocking_timers = true - )"_toml -}; - -auto main(int argc, char* argv[]) -> int { - ntt::GlobalInitialize(argc, argv); - try { - ntt::CommandLineArguments cl_args; - cl_args.readCommandLineArguments(argc, argv); - toml::value inputdata; - - auto n_iter_str = cl_args.getArgument("-niter", "10"); - auto n_iter = std::stoi(std::string(n_iter_str)); - - if (cl_args.isSpecified("-input")) { - auto inputfilename = cl_args.getArgument("-input"); - inputdata = toml::parse(static_cast(inputfilename)); - } else { - inputdata = default_input; - } - auto sim = ntt::GRPIC(inputdata); - - auto params = *(sim.params()); - auto& mblock = sim.meshblock; - - { - const auto extent = params.extent(); - - sim.ResetSimulation(); - using namespace ntt; - const real_t sx1 = extent[1] - extent[0]; - const real_t sx2 = extent[3] - extent[2]; - Kokkos::parallel_for( - "InitFields", mblock.rangeActiveCells(), Lambda(ntt::index_t i1, ntt::index_t i2) { - set_em_fields_2d(mblock, i1, i2, EMfield, sx1, sx2); - }); - sim.Exchange(ntt::GhostCells::fields); - - ntt::InjectUniform( - params, sim.meshblock, { 1, 2 }, params.ppc0() * 0.5); - } - { - ntt::WaitAndSynchronize(); - - for (auto i { 0 }; i < n_iter; ++i) { - sim.StepForward(ntt::DiagFlags_Timers | ntt::DiagFlags_Species); - } - } - - } catch (std::exception& err) { - std::cerr << err.what() << std::endl; - ntt::GlobalFinalize(); - return -1; - } - ntt::GlobalFinalize(); - - return 0; -} \ No newline at end of file diff --git a/legacy/benchmarks/sr-mink.cpp b/legacy/benchmarks/sr-mink.cpp deleted file mode 100644 index 7089d7e98..000000000 --- a/legacy/benchmarks/sr-mink.cpp +++ /dev/null @@ -1,176 +0,0 @@ -#include "wrapper.h" - -#include "field_macros.h" -#include "pic.h" -#include "sim_params.h" - -#include "io/cargs.h" -#include "io/input.h" -#include "meshblock/meshblock.h" - -#include "utilities/archetypes.hpp" -#include "utilities/injector.hpp" - -#include - -#include -#include -#include -#include -#include - -Inline void EMfield_2d(const ntt::coord_t& x_ph, - ntt::vec_t& e_out, - ntt::vec_t& b_out, - const real_t sx1, - const real_t sx2) { - const real_t kx1_x1 = ntt::constant::TWO_PI * x_ph[0] / sx1; - const real_t kx2_x2 = ntt::constant::TWO_PI * x_ph[1] / sx2; - e_out[0] = math::cos(kx1_x1) * math::sin(kx2_x2); - e_out[1] = -math::sin(kx1_x1) * math::cos(kx2_x2); - e_out[2] = math::cos(kx1_x1) * math::cos(kx2_x2); - b_out[0] = math::sin(kx1_x1) * math::cos(kx2_x2); - b_out[1] = -math::cos(kx1_x1) * math::sin(kx2_x2); - b_out[2] = math::sin(kx1_x1) * math::sin(kx2_x2); -} - -Inline void EMfield_3d(const ntt::coord_t& x_ph, - ntt::vec_t& e_out, - ntt::vec_t& b_out, - const real_t sx1, - const real_t sx2, - const real_t) { - const real_t kx1_x1 = ntt::constant::TWO_PI * x_ph[0] / sx1; - const real_t kx2_x2 = ntt::constant::TWO_PI * x_ph[1] / sx2; - e_out[0] = math::cos(kx1_x1) * math::sin(kx2_x2); - e_out[1] = -math::sin(kx1_x1) * math::cos(kx2_x2); - e_out[2] = math::cos(kx1_x1) * math::cos(kx2_x2); - b_out[0] = math::sin(kx1_x1) * math::cos(kx2_x2); - b_out[1] = -math::cos(kx1_x1) * math::sin(kx2_x2); - b_out[2] = math::sin(kx1_x1) * math::sin(kx2_x2); -} - -using namespace toml::literals::toml_literals; -const auto default_input { - R"( - [domain] - resolution = [8192, 8192] - extent = [-5.0, 5.0, -5.0, 5.0] - boundaries = [["PERIODIC"], ["PERIODIC"]] - - [algorithm] - cfl = 0.0001 - - [units] - ppc0 = 2.0 - larmor0 = 2.0 - skindepth0 = 1.0 - - [particles] - n_species = 2 - - [species_1] - label = "e-" - mass = 1.0 - charge = -1.0 - maxnpart = 1e8 - - [species_2] - label = "e+" - mass = 25.0 - charge = 1.0 - maxnpart = 1e8 - - [diagnostics] - blocking_timers = true - )"_toml -}; - -template -struct MaxwellianDist : public ntt::EnergyDistribution { - MaxwellianDist(const ntt::SimulationParams& params, const ntt::Meshblock& mblock) - : ntt::EnergyDistribution(params, mblock), - maxwellian { mblock }, - temperature { ONE } {} - Inline void operator()(const ntt::coord_t&, - ntt::vec_t& v, - const int& species) const override { - maxwellian(v, temperature); - } - -private: - const ntt::Maxwellian maxwellian; - const real_t temperature; -}; - -template -auto Run(const toml::value input, const int n_iter) -> void { - using namespace ntt; - auto sim = PIC(input); - - auto params = *(sim.params()); - auto& mblock = sim.meshblock; - - { - auto extent = params.extent(); - sim.ResetSimulation(); - const real_t sx1 = extent[1] - extent[0]; - const real_t sx2 = extent[3] - extent[2]; - if constexpr (D == Dim2) { - Kokkos::parallel_for( - "InitFields", mblock.rangeActiveCells(), Lambda(index_t i1, index_t i2) { - set_em_fields_2d(mblock, i1, i2, EMfield_2d, sx1, sx2); - }); - } else if constexpr (D == Dim3) { - const real_t sx3 = extent[5] - extent[4]; - Kokkos::parallel_for( - "InitFields", mblock.rangeActiveCells(), Lambda(index_t i1, index_t i2, index_t i3) { - set_em_fields_3d(mblock, i1, i2, i3, EMfield_3d, sx1, sx2, sx3); - }); - } - sim.Exchange(ntt::GhostCells::fields); - - ntt::InjectUniform( - params, sim.meshblock, { 1, 2 }, params.ppc0() * 0.5); - } - { - ntt::WaitAndSynchronize(); - - for (auto i { 0 }; i < n_iter; ++i) { - sim.StepForward(ntt::DiagFlags_Timers | ntt::DiagFlags_Species); - } - } -} - -auto main(int argc, char* argv[]) -> int { - ntt::GlobalInitialize(argc, argv); - try { - ntt::CommandLineArguments cl_args; - cl_args.readCommandLineArguments(argc, argv); - toml::value inputdata; - - auto n_iter_str = cl_args.getArgument("-niter", "10"); - auto n_iter = std::stoi(std::string(n_iter_str)); - - if (cl_args.isSpecified("-input")) { - auto inputfilename = cl_args.getArgument("-input"); - inputdata = toml::parse(static_cast(inputfilename)); - } else { - inputdata = default_input; - } - auto resolution - = ntt::readFromInput>(inputdata, "domain", "resolution"); - if (resolution.size() == 2) { - Run(inputdata, n_iter); - } else { - Run(inputdata, n_iter); - } - } catch (std::exception& err) { - std::cerr << err.what() << std::endl; - ntt::GlobalFinalize(); - return -1; - } - ntt::GlobalFinalize(); - - return 0; -} \ No newline at end of file diff --git a/legacy/benchmarks/sr-sph.cpp b/legacy/benchmarks/sr-sph.cpp deleted file mode 100644 index c1de62f23..000000000 --- a/legacy/benchmarks/sr-sph.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include "wrapper.h" - -#include "field_macros.h" -#include "pic.h" -#include "sim_params.h" - -#include "io/cargs.h" -#include "io/input.h" -#include "meshblock/meshblock.h" - -#include "utilities/archetypes.hpp" -#include "utilities/injector.hpp" - -#include - -#include -#include -#include -#include -#include - -Inline void EMfield(const ntt::coord_t& x_ph, - ntt::vec_t& e_out, - ntt::vec_t& b_out, - const real_t sx1, - const real_t sx2) { - const real_t kx1_x1 = ntt::constant::TWO_PI * x_ph[0] / sx1; - const real_t kx2_x2 = ntt::constant::TWO_PI * x_ph[1] / sx2; - e_out[0] = math::cos(kx1_x1) * math::sin(kx2_x2); - e_out[1] = -math::sin(kx1_x1) * math::cos(kx2_x2); - e_out[2] = math::cos(kx1_x1) * math::cos(kx2_x2); - b_out[0] = math::sin(kx1_x1) * math::cos(kx2_x2); - b_out[1] = -math::cos(kx1_x1) * math::sin(kx2_x2); - b_out[2] = math::sin(kx1_x1) * math::sin(kx2_x2); -} - -template -struct MaxwellianDist : public ntt::EnergyDistribution { - MaxwellianDist(const ntt::SimulationParams& params, const ntt::Meshblock& mblock) - : ntt::EnergyDistribution(params, mblock), - maxwellian { mblock }, - temperature { 0.001 } {} - Inline void operator()(const ntt::coord_t&, - ntt::vec_t& v, - const int& species) const override { - maxwellian(v, temperature); - } - -private: - const ntt::Maxwellian maxwellian; - const real_t temperature; -}; - -using namespace toml::literals::toml_literals; -const auto default_input { - R"( - [domain] - resolution = [8192, 8192] - extent = [1.0, 50.0] - boundaries = [["CUSTOM", "ABSORB"], ["AXIS"]] - sph_rabsorb = 45.0 - qsph_r0 = 0.0 - qsph_h = 0.0 - - [units] - ppc0 = 1.0 - larmor0 = 2.0 - skindepth0 = 1.0 - - [particles] - n_species = 2 - - [species_1] - label = "e-" - mass = 1.0 - charge = -1.0 - maxnpart = 1e8 - - [species_2] - label = "e+" - mass = 25.0 - charge = 1.0 - maxnpart = 1e8 - - [diagnostics] - blocking_timers = true - )"_toml -}; - -auto main(int argc, char* argv[]) -> int { - ntt::GlobalInitialize(argc, argv); - try { - ntt::CommandLineArguments cl_args; - cl_args.readCommandLineArguments(argc, argv); - toml::value inputdata; - - auto n_iter_str = cl_args.getArgument("-niter", "10"); - auto n_iter = std::stoi(std::string(n_iter_str)); - - if (cl_args.isSpecified("-input")) { - auto inputfilename = cl_args.getArgument("-input"); - inputdata = toml::parse(static_cast(inputfilename)); - } else { - inputdata = default_input; - } - auto sim = ntt::PIC(inputdata); - - auto params = *(sim.params()); - auto& mblock = sim.meshblock; - - { - auto extent = params.extent(); - sim.ResetSimulation(); - using namespace ntt; - const real_t sx1 = extent[1] - extent[0]; - const real_t sx2 = extent[3] - extent[2]; - Kokkos::parallel_for( - "InitFields", mblock.rangeActiveCells(), Lambda(ntt::index_t i1, ntt::index_t i2) { - set_em_fields_2d(mblock, i1, i2, EMfield, sx1, sx2); - }); - sim.Exchange(ntt::GhostCells::fields); - - ntt::InjectUniform( - params, sim.meshblock, { 1, 2 }, params.ppc0() * 0.5); - } - { - ntt::WaitAndSynchronize(); - - for (auto i { 0 }; i < n_iter; ++i) { - sim.StepForward(ntt::DiagFlags_Timers | ntt::DiagFlags_Species); - } - } - - } catch (std::exception& err) { - std::cerr << err.what() << std::endl; - ntt::GlobalFinalize(); - return -1; - } - ntt::GlobalFinalize(); - - return 0; -} \ No newline at end of file diff --git a/legacy/cmake/config.cmake b/legacy/cmake/config.cmake deleted file mode 100644 index 304454dd5..000000000 --- a/legacy/cmake/config.cmake +++ /dev/null @@ -1,117 +0,0 @@ -# ----------------------------- Simulation engine ---------------------------- # -# function(set_engine engine_name) -# list(FIND simulation_engines ${engine_name} ENGINE_FOUND) - -# if(${ENGINE_FOUND} EQUAL -1) -# message(FATAL_ERROR "Invalid simulation engine: ${engine_name}\nValid options are: ${simulation_engines}") -# else() -# set(ENGINE_FLAG ${engine}_engine) -# string(TOUPPER ${ENGINE_FLAG} ENGINE_FLAG) -# add_compile_options("-D ${ENGINE_FLAG}") -# endif() - -# if(${engine_name} STREQUAL "sandbox") -# set(default_metric "minkowski" CACHE STRING "Default metric") -# set(metrics ${sr_metrics} ${gr_metrics} CACHE STRING "Metrics") -# elseif(${engine_name} STREQUAL "pic") -# set(default_metric "minkowski" CACHE STRING "Default metric") -# set(metrics ${sr_metrics} CACHE STRING "Metrics") -# elseif(${engine_name} STREQUAL "grpic") -# set(default_metric "qkerr_schild" CACHE STRING "Default metric") -# set(metrics ${gr_metrics} CACHE STRING "Metrics") -# endif() -# endfunction() - -# -------------------------------- Precision ------------------------------- # -function(set_precision precision_name) - list(FIND precisions ${precision_name} PRECISION_FOUND) - - if(${PRECISION_FOUND} EQUAL -1) - message(FATAL_ERROR "Invalid precision: ${precision_name}\nValid options are: ${precisions}") - endif() - - if(${precision_name} STREQUAL "single") - add_compile_options("-DSINGLE_PRECISION") - endif() -endfunction() - -# # --------------------------------- Metric --------------------------------- # -# function(set_metric metric_name) -# list(FIND metrics ${metric_name} METRIC_FOUND) - -# if(${METRIC_FOUND} EQUAL -1) -# message(FATAL_ERROR "Invalid metric: ${metric_name}\nValid options are: ${metrics}") -# else() -# set(METRIC_FLAG ${metric}_metric) -# string(TOUPPER ${METRIC_FLAG} METRIC_FLAG) -# set(SIMULATION_METRIC ${metric}) - -# add_compile_options("-D ${METRIC_FLAG}") -# add_compile_options("-D SIMULATION_METRIC=\"${SIMULATION_METRIC}\"") -# add_compile_options("-D METRIC_HEADER=\"metrics/${metric}.h\"") -# endif() -# endfunction() - -# ---------------------------- Problem generator --------------------------- # -function(set_problem_generator pgen_name engine_name) - if(NOT ${engine_name} STREQUAL "sandbox") - if (${engine_name} STREQUAL "pic") - set(ENGINE_DIRECTORY "srpic") - else() - set(ENGINE_DIRECTORY ${engine_name}) - endif() - if (${metric} STREQUAL "minkowski") - set(ENGINE_DIRECTORY ${ENGINE_DIRECTORY}-cart) - else() - set(ENGINE_DIRECTORY ${ENGINE_DIRECTORY}-axisym) - endif() - - set(PGEN_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/setups/${ENGINE_DIRECTORY}/) - file(GLOB_RECURSE PGENS ${PGEN_DIRECTORY}*.hpp) - set(problem_generators "") - set(problem_generators_full "") - - foreach(pgen_file ${PGENS}) - string(REPLACE ${PGEN_DIRECTORY} "" new_pgen ${pgen_file}) - string(REPLACE ".hpp" "" new_pgen ${new_pgen}) - list(APPEND problem_generators_full ${new_pgen}) - - string(REPLACE "/" ";" new_pgen_list ${new_pgen}) - list(GET new_pgen_list 0 pgen_left) - list(GET new_pgen_list 1 pgen_right) - if (${pgen_left} STREQUAL ${pgen_right}) - set(new_pgen ${pgen_left}) - endif() - - list(APPEND problem_generators ${new_pgen}) - endforeach() - list(APPEND problem_generators "dummy") - - if (${pgen_name} MATCHES "^.*\/.*$") - set(pgen_full ${pgen_name}) - string(REPLACE "/" ";" new_pgen_list ${pgen_name}) - list(GET new_pgen_list 0 pgen_left) - list(GET new_pgen_list 1 pgen_right) - if (${pgen_left} STREQUAL "temp") - list(APPEND problem_generators ${pgen_name}) - set(PGEN_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/) - endif() - elseif (${pgen_name} STREQUAL "dummy") - set(PGEN_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/setups/) - set(pgen_full ${pgen_name}) - else() - set(pgen_full ${pgen_name}/${pgen_name}) - endif() - - set(problem_generators ${problem_generators} CACHE STRING "Problem generators") - - list(FIND problem_generators ${pgen_name} PGEN_FOUND) - - if(${PGEN_FOUND} EQUAL -1) - message(FATAL_ERROR "Problem generator ${pgen_full}.hpp not found\nAvailable problem generators: ${problem_generators}.") - else() - add_compile_options("-D PGEN_HEADER=\"${PGEN_DIRECTORY}${pgen_full}.hpp\"") - set(PGEN_FOUND TRUE CACHE BOOL "Problem generator found") - endif() - endif() -endfunction() \ No newline at end of file diff --git a/legacy/configure.py b/legacy/configure.py deleted file mode 100644 index 54c41ef24..000000000 --- a/legacy/configure.py +++ /dev/null @@ -1,421 +0,0 @@ -# ----------------------------------------------------------------------------------------- -# Configure file for the `Entity` code to generate a temporary `Makefile`. -# -# Options: -# -h --help help message -# -# [ Compilation flags ] -# -verbose enable verbose compilation mode -# -debug compile in `debug` mode -# --compiler= compiler used (can be a valid path to the binary) -# --build= specify building directory -# --bin= specify directory for executables -# -# [ Nttiny flags ] -# -nttiny enable visualizer compilation -# --nttiny_path= specify path for `Nttiny` (relative to current dir or absolute) -# -# [ Simulation flags ] -# --pgen= specify the problem generator to be used -# --precision=[single|double] floating point precision used [default: single] -# --metric= select metric to be used [default: minkowski] -# --simtype= select simulation type [default: pic] -# -# [ Kokkos-specific flags ] -# --kokkos_devices= `Kokkos` devices -# --kokkos_arch= `Kokkos` architecture -# --kokkos_options= `Kokkos` options -# --kokkos_cuda_options= `Kokkos` Cuda options -# ---------------------------------------------------------------------------------------- - -import argparse -import glob -import re -import subprocess -import os -import sys -import textwrap -from pathlib import Path - -assert sys.version_info >= (3, 7), "Requires python 3.7 or higher" - -# Global Settings -# --------------- -# Default values: -DEF_build_dir = 'build' -DEF_bin_dir = 'bin' -DEF_compiler = 'g++' -DEF_cppstandard = 'c++17' - -# Set template and output filenames -makefile_input = 'Makefile.in' -makefile_output = 'Makefile' - -# Options: -Precision_options = ['double', 'single'] -Metric_options = ['minkowski', 'spherical', - 'qspherical', 'kerr_schild', 'qkerr_schild'] -Simtype_options = ['pic', 'grpic'] - - -def findFiles(directory, extension): - return glob.glob(directory + '/*/*.' + extension) + glob.glob(directory + '/*.' + extension) - - -Pgen_options = [f.replace('.hpp', '').replace('\\', '/').replace('pgen/', '') - for f in findFiles('pgen', 'hpp')] -Kokkos_devices = dict(host=['Serial', 'OpenMP', 'PThreads'], device=['Cuda']) -Kokkos_arch = dict(host=["AMDAVX", "EPYC", "ARMV80", "ARMV81", "ARMV8_THUNDERX", - "ARMV8_THUNDERX2", "WSM", "SNB", "HSW", "BDW", "SKX", - "KNC", "KNL", "BGQ", "POWER7", "POWER8", "POWER9"], - device=["KEPLER30", "KEPLER32", "KEPLER35", "KEPLER37", - "MAXWELL50", "MAXWELL52", "MAXWELL53", "PASCAL60", - "PASCAL61", "VOLTA70", "VOLTA72", "TURING75", - "AMPERE80", "VEGA900", "VEGA906", "INTEL_GE"]) -Kokkos_devices_options = Kokkos_devices["host"] + Kokkos_devices["device"] -Kokkos_arch_options = Kokkos_arch["host"] + Kokkos_arch["device"] -Kokkos_loop_options = ['default', '1DRange', - 'MDRange', 'TP-TVR', 'TP-TTR', 'TP-TTR-TVR', 'for'] - -# . . . auxiliary functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . --> -use_nvcc_wrapper = False - - -def findCompiler(compiler): - find_command = subprocess.run( - ['which', compiler], capture_output=True, text=True) - return find_command.stdout.strip() if (find_command.returncode == 0) else 'N/A' - - -def pathNotEmpty(path): - ls_path = subprocess.run(['ls', path], capture_output=True, text=True) - return path if (ls_path.returncode == 0) else 'N/A' - - -def defineOptions(): - parser = argparse.ArgumentParser() - # compilation - parser.add_argument('-verbose', action='store_true', - default=False, help='enable verbose compilation mode') - parser.add_argument('--build', default=DEF_build_dir, - help='specify building directory') - parser.add_argument('--bin', default=DEF_bin_dir, - help='specify directory for executables') - parser.add_argument('--compiler', default=DEF_compiler, - help='choose the compiler') - parser.add_argument('-debug', action='store_true', - default=False, help='compile in `debug` mode') - - # visualizer - parser.add_argument('-nttiny', action='store_true', - default=False, help='enable nttiny visualizer compilation') - parser.add_argument('--nttiny_path', default="extern/nttiny", - help='specify path for `Nttiny`') - - # simulation - parser.add_argument('--precision', default='single', - choices=Precision_options, help='code precision (default: `single`)') - parser.add_argument( - '--metric', default=Metric_options[0], choices=Metric_options, help='select metric to be used (default: `minkowski`)') - parser.add_argument( - '--simtype', default=Simtype_options[0], choices=Simtype_options, help='select simulation type (default: `pic`)') - parser.add_argument('--pgen', default="", choices=Pgen_options, - help='problem generator to be used (default: `ntt_dummy`)') - - # `Kokkos` specific - parser.add_argument( - '--kokkos_devices', default=Kokkos_devices['host'][0], help='`Kokkos` devices') - parser.add_argument('--kokkos_arch', default='', - help='`Kokkos` architecture') - parser.add_argument('--kokkos_options', default='', - help='`Kokkos` options') - parser.add_argument('--kokkos_cuda_options', default='', - help='`Kokkos` CUDA options') - return vars(parser.parse_args()) - - -def configureKokkos(arg, mopt): - global use_nvcc_wrapper - kokkos_configs = {} - - def parseArchDevice(carg, kokkos_list): - _ = carg.split(',') - assert len(_) <= 2, "Wrong arch/device specified" - if len(_) == 2: - _1, _2 = _ - if _2 in kokkos_list['host']: - _1 = _[1] - _2 = _[0] - return _1, _2 - elif len(_) == 1: - _1 = _[0] - _2 = None - if _1 in kokkos_list['device']: - # enabling openmp if CUDA is enabled - _2 = 'OpenMP' - elif (not (_1 in kokkos_list['host'])): - if _1 != '': - raise ValueError("Wrong arch/device specified") - else: - _1 = None - return _1, _2 - else: - return None, None - host_d, device_d = parseArchDevice(arg['kokkos_devices'], Kokkos_devices) - host_a, device_a = parseArchDevice(arg['kokkos_arch'], Kokkos_arch) - if host_d is not None: - assert (host_d in Kokkos_devices['host']), 'Wrong host' - kokkos_configs['devices'] = host_d - if device_d is not None: - assert (device_d in Kokkos_devices['device']), 'Wrong device' - kokkos_configs['devices'] += ',' + device_d - if host_a is not None: - assert (host_a in Kokkos_arch['host']), 'Wrong host architecture' - kokkos_configs['arch'] = host_a - if device_a is not None: - assert (device_a in Kokkos_arch['device']), 'Wrong device architecture' - try: - kokkos_configs['arch'] += ',' + device_a - except: - kokkos_configs['arch'] = device_a - - mopt['KOKKOS_DEVICES'] = kokkos_configs['devices'] - mopt['KOKKOS_ARCH'] = kokkos_configs.get('arch', '') - if 'Cuda' in kokkos_configs['devices']: - mopt['DEFINITIONS'] += '-DGPUENABLED ' - if 'OpenMP' in kokkos_configs['devices']: - mopt['DEFINITIONS'] += '-DOMPENABLED ' - - mopt['KOKKOS_OPTIONS'] = arg['kokkos_options'] - if mopt['KOKKOS_OPTIONS'] != '': - mopt['KOKKOS_OPTIONS'] += ',' - mopt['KOKKOS_OPTIONS'] += 'disable_deprecated_code' - - mopt['KOKKOS_CUDA_OPTIONS'] = arg['kokkos_cuda_options'] - - if 'Cuda' in mopt['KOKKOS_DEVICES']: - # using Cuda - mopt['KOKKOS_CUDA_OPTIONS'] = arg['kokkos_cuda_options'] - if mopt['KOKKOS_CUDA_OPTIONS'] != '': - mopt['KOKKOS_CUDA_OPTIONS'] += ',' - mopt['KOKKOS_CUDA_OPTIONS'] += 'enable_lambda' - - use_nvcc_wrapper = True - - # no MPI (TODO) - arg['nvcc_wrapper_cxx'] = arg['compiler'] - mopt['HOST_COMPILER'] = arg["nvcc_wrapper_cxx"] - mopt['COMPILER'] = f'NVCC_WRAPPER_DEFAULT_COMPILER={arg["nvcc_wrapper_cxx"]} '\ - + '${KOKKOS_PATH}/bin/nvcc_wrapper' - # + 'NVCC_WRAPPER_TMPDIR=${BUILD_DIR}/tmp '\ - # add with MPI here (TODO) - - settings = f''' - `Kokkos`: - {'Devices':30} {mopt['KOKKOS_DEVICES']} - {'Architecture':30} {mopt['KOKKOS_ARCH']} - {'Options':30} {mopt['KOKKOS_OPTIONS'] if mopt['KOKKOS_OPTIONS'] is not None else '-'} - {'Cuda options':30} {mopt['KOKKOS_CUDA_OPTIONS'] if mopt['KOKKOS_CUDA_OPTIONS'] is not None else '-'}''' - return settings - - -def createMakefile(m_in, m_out, mopt): - with open(m_in, 'r') as current_file: - makefile_template = current_file.read() - # print(makefile_template) - for key, val in mopt.items(): - makefile_template = makefile_template.replace(f'@{key}@', val) - if not args['nttiny']: - makefile_template = re.sub( - "# for nttiny />[\S\s]*? *', '', - re.sub(r'-[I|L|o|c].+?[ |>|$]', '', - re.sub(r'-([I|D|c|o|W|O|L]) ', r'-\1', - command[i + 1:])) - ).strip().split(' '))) - order = ['-std', '-D', '-W', '-l', '--diag', ''] - accounted_flags = [] - ordered_flags = {key: [] for key in order} - for o in order: - for flag in flags: - if (o in flag) and (not flag in accounted_flags): - accounted_flags.append(flag) - ordered_flags[o].append(re.sub('-D', '-D ', flag)) - fstring = "" - fstring += " " + cmd + "\n" - for o in order: - fstring += " " - for f in ordered_flags[o]: - fstring += f + " " - fstring += "\n" - fstring = "".join(filter(str.strip, fstring.splitlines(True)))[:-1] - return fstring - -# add some useful notes - - -def makeNotes(): - notes = '' - cxx = args['nvcc_wrapper_cxx'] if use_nvcc_wrapper else makefile_options['COMPILER'] - if use_nvcc_wrapper: - notes += f"* nvcc recognized as:\n $ {findCompiler('nvcc')}\n " - notes += f"* {'nvcc wrapper ' if use_nvcc_wrapper else ''}compiler recognized as:\n $ {findCompiler(cxx)}\n " - if 'OpenMP' in args['kokkos_devices']: - notes += f"* when using OpenMP set the following environment variables:\n $ export OMP_PROC_BIND=spread OMP_PLACES=threads\n " - if args['nttiny']: - notes += f"* `nttiny` path:\n $ {pathNotEmpty(args['nttiny_path'])}" - return notes.strip() - - -short_compiler = ( - f"nvcc_wrapper [{args['nvcc_wrapper_cxx']}]" if use_nvcc_wrapper else makefile_options['COMPILER']) - -full_command = " ".join(sys.argv[:]) - -# Finish with diagnostic output -w = 80 -full_command = ' \\\n'.join(textwrap.wrap(full_command, w - 4, - subsequent_indent=" ", - initial_indent=" ")) -report = f''' -{'':=<{w}} - __ __ - /\ \__ __/\ \__ - __ ___\ \ _\/\_\ \ _\ __ __ - / __ \/ _ \ \ \/\/\ \ \ \/ /\ \/\ \\ -/\ __//\ \/\ \ \ \_\ \ \ \ \_\ \ \_\ \ __ -\ \____\ \_\ \_\ \__\\\\ \_\ \__\\\\ \____ \/\_\\ - \/____/\/_/\/_/\/__/ \/_/\/__/ \/___/ \/_/ - /\___/ - \/__/ - -{'':=<{w}} -{'Full configure command ':.<{w}} - -{full_command} - -{'Setup configurations ':.<{w}} - - {'Simulation type':32} {args['simtype'].upper()} - {'Problem generator':32} {args['pgen'] if args['pgen'] != '' else '--'} - {'Precision':32} {args['precision']} - {'Metric':32} {args['metric']} - -{'Physics ':.<{w}} - -{'Technical details ':.<{w}} - - {'Compiler':32} {short_compiler} - {'Debug mode':32} {args['debug']} - {Kokkos_details} - -{'Notes ':.<{80}} - - {makeNotes()} - -{'Compilation command ':.<{w}} - -{beautifyCommands(compiledemo)} - -{'Linking command ':.<{w}} - -{beautifyCommands(linkdemo)} - -{'':=<{w}} -''' - -print(report) - -with open(args['build'] + "/REPORT", 'w') as reportfile: - reportfile.write(report) diff --git a/legacy/deploy/aux/argparse.sh b/legacy/deploy/aux/argparse.sh deleted file mode 100644 index a6cb18f0d..000000000 --- a/legacy/deploy/aux/argparse.sh +++ /dev/null @@ -1,45 +0,0 @@ -while [ $# -gt 0 ]; do - if [[ $1 == "--help" ]] || [[ $1 == "-h" ]]; then - usage - exit 0 - elif [[ $1 == "--"* ]]; then - v="${1/--/}" - v=$(echo $v | sed 's/-/_/g') - if [[ -z "$2" ]] || [[ "$2" == --* ]] || [[ "$2" == -* ]]; then - if [[ "$1" != "--deploy" ]] && [[ "$1" != "--verbose" ]]; then - printf "\n${RED}Invalid option: $1${NC}\n" - exit 1 - fi - declare "$v"="ON" - else - declare "$v"="$2" - shift - fi - elif [[ $1 == "-"* ]]; then - if [[ -z "$2" ]] || [[ "$2" == --* ]] || [[ "$2" == -* ]]; then - if [[ $1 == "-v" ]]; then - verbose="ON" - elif [[ $1 == "-d" ]]; then - deploy="ON" - else - printf "\n${RED}Invalid option: $1${NC}\n" - exit 1 - fi - else - printf "\n${RED}Invalid option: $1${NC}\n" - exit 1 - fi - fi - shift -done - -# manage invalid options -if [ $with_cuda = "ON" ]; then - printf "\n${RED}Please specify CUDA path or modulename${NC}\n" - exit 1 -fi - -if [ $with_mpi = "ON" ]; then - printf "\n${RED}Please specify MPI path or modulename${NC}\n" - exit 1 -fi \ No newline at end of file diff --git a/legacy/deploy/aux/aux.sh b/legacy/deploy/aux/aux.sh deleted file mode 100644 index 11a238803..000000000 --- a/legacy/deploy/aux/aux.sh +++ /dev/null @@ -1,86 +0,0 @@ -rtouch() { - mkdir -p $(sed 's/\(.*\)\/.*/\1/' <<<$1) && touch $1 -} - -function runcommand { - if [ $deploy = "OFF" ]; then - echo ": $1" - else - if [ $verbose = "ON" ]; then - eval "$1" - else - eval "$1" >>${logfile} 2>>${logfile} - fi - fi -} - -declare -x FRAME -declare -x FRAME_INTERVAL - -set_spinner() { - case $1 in - spinner1) - FRAME=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏") - FRAME_INTERVAL=0.1 - ;; - spinner2) - FRAME=("-" "\\" "|" "/") - FRAME_INTERVAL=0.25 - ;; - spinner3) - FRAME=("◐" "◓" "◑" "◒") - FRAME_INTERVAL=0.5 - ;; - spinner4) - FRAME=(":(" ":|" ":)" ":D") - FRAME_INTERVAL=0.5 - ;; - spinner5) - FRAME=("◇" "◈" "◆") - FRAME_INTERVAL=0.5 - ;; - spinner6) - FRAME=("⚬" "⚭" "⚮" "⚯") - FRAME_INTERVAL=0.25 - ;; - spinner7) - FRAME=("░" "▒" "▓" "█" "▓" "▒") - FRAME_INTERVAL=0.25 - ;; - spinner8) - FRAME=("☉" "◎" "◉" "●" "◉") - FRAME_INTERVAL=0.1 - ;; - spinner9) - FRAME=("❤" "♥" "♡") - FRAME_INTERVAL=0.15 - ;; - spinner10) - FRAME=("✧" "☆" "★" "✪" "◌" "✲") - FRAME_INTERVAL=0.1 - ;; - spinner11) - FRAME=("●" "◕" "☯" "◔" "◕") - FRAME_INTERVAL=0.25 - ;; - *) - echo "No spinner is defined for $1" - exit 1 - ;; - esac -} - -function is_gpu_arch { - local ar=$1 - if [[ $ar == "VOLTA"* ]] || [[ $ar == "TURING"* ]] || [[ $ar == "AMPERE"* ]] || [[ $ar == "MAXWELL"* ]] || [[ $ar == "PASCAL"* ]] || [[ $ar == "KEPLER"* ]] || [[ $ar == "INTEL"* ]] || [[ $ar == "VEGA"* ]] || [[ $ar == "NAVI"* ]]; then - echo "TRUE" - else - echo "FALSE" - fi -} - -GRAY='\033[0;30m' -GREEN='\033[0;32m' -RED='\033[0;31m' -BLUE='\033[0;34m' -NC='\033[0m' diff --git a/legacy/deploy/aux/config.sh b/legacy/deploy/aux/config.sh deleted file mode 100644 index a2324f286..000000000 --- a/legacy/deploy/aux/config.sh +++ /dev/null @@ -1,73 +0,0 @@ -declare -x writing_modulefile="ON" -declare -x use_modules="OFF" -declare -x enable_cuda="OFF" -declare -x install_path=${install_prefix}/${modulename_lower} - -if [ -z $has_modulefile ]; then - writing_modulefile="OFF" -else - modnm=$(eval echo "\${${modulename_lower}_module}") - if [[ $has_modulefile = "OFF" || $modnm = "OFF" ]]; then - writing_modulefile="OFF" - fi -fi - -if [ ! $with_cuda = "OFF" ]; then - enable_cuda="ON" - if [[ $with_cuda == module:* ]]; then - cuda_module=$(echo $with_cuda | cut -d':' -f2) - use_modules="ON" - else - cuda_path=$with_cuda - fi -fi - -if [[ $with_cc == module:* ]]; then - cc_module=$(echo $with_cc | cut -d':' -f2) - use_modules="ON" -fi - -if [ ! $with_mpi = "OFF" ]; then - if [[ $with_mpi == module:* ]]; then - mpi_module=$(echo $with_mpi | cut -d':' -f2) - use_modules="ON" - if [ ! $with_cuda = "OFF" ]; then - mpi_module=$mpi_module/cuda - else - mpi_module=$mpi_module/cpu - fi - else - mpi_path=$with_mpi - fi -fi - -function define_kokkos_suffix { - local arch_raw=$1 - local suffix="" - declare -xa archs - IFS=',' read -ra archs <<<"$arch_raw" - - for ar in "${archs[@]}"; do - if [ $ar = "AUTO" ]; then - break - fi - is_gpu=$(is_gpu_arch $ar) - if [ $is_gpu = "TRUE" ]; then - if [ $enable_cuda != "ON" ]; then - printf "\n${RED}GPU architecture $ar is specified but CUDA is not enabled${NC}\n" - exit 1 - fi - suffix+="/${ar,,}" - fi - done - for ar in "${archs[@]}"; do - if [ $ar = "AUTO" ]; then - break - fi - is_gpu=$(is_gpu_arch $ar) - if [ $is_gpu != "TRUE" ]; then - suffix+="/${ar,,}" - fi - done - echo $suffix -} diff --git a/legacy/deploy/aux/default.sh b/legacy/deploy/aux/default.sh deleted file mode 100644 index 186595b7d..000000000 --- a/legacy/deploy/aux/default.sh +++ /dev/null @@ -1,21 +0,0 @@ -default_with_cuda="module:cudatoolkit/12.0" -declare with_cuda="${default_with_cuda}" - -default_with_cc="module:gcc-toolset/10" -declare with_cc="${default_with_cc}" - -default_install_prefix="${HOME}/opt" -declare install_prefix="${default_install_prefix}" - -default_module_path="${HOME}/opt/.modules" -default_src_path="${HOME}/opt/src" - -declare -r modulename_lower=${modulename,,} - -declare ${modulename_lower}_module="${default_module_path}/${modulename_lower}" -declare ${modulename_lower}_src_path="${default_src_path}/${modulename_lower}" - -declare deploy="OFF" -declare verbose="OFF" - -declare -r programname=$0 \ No newline at end of file diff --git a/legacy/deploy/aux/globals.sh b/legacy/deploy/aux/globals.sh deleted file mode 100644 index b67fb917a..000000000 --- a/legacy/deploy/aux/globals.sh +++ /dev/null @@ -1,39 +0,0 @@ -declare -r logfile="$(pwd)/${modulename_lower}.log" - -function common_help { - echo "" - echo "Build and install $modulename" - echo "" - echo "usage: bash $programname --deploy -v --install_prefix ... [options]" - echo "" - echo " -h, --help print this help message" - echo "" - echo " -d, --deploy execute the script" - echo " -d OFF shows the command to be executed" - echo " (default: $deploy)" - echo "" - echo " -v, --verbose whether to print the compilation progress or not" - echo " (default: $verbose)" - echo "" - echo " --install_prefix path to $modulename installation directory" - echo " (default: $default_install_prefix)" - echo "" - printf "%-33s%s" " --${modulename_lower}_src_path " "path to ${modulename} source directory" - echo "" - echo " (default: $default_src_path/${modulename_lower})" - if [ ! -z $has_modulefile ]; then - echo "" - printf "%-33s%s" " --${modulename_lower}_module " "path to ${modulename} module" - echo "" - echo " set to OFF to disable modulefile installation" - echo " (default: $default_module_path/${modulename_lower})" - fi - echo "" - echo " --with-cc C compiler path or modulename (\`module:\`)" - echo " (default: $default_with_cc)" - echo "" - echo " --with-cuda CUDA path or modulename via (\`module:\`)" - echo " set to OFF to disable CUDA support" - echo " (default: $default_with_cuda)" - echo "" -} diff --git a/legacy/deploy/aux/run.sh b/legacy/deploy/aux/run.sh deleted file mode 100644 index 9322586fb..000000000 --- a/legacy/deploy/aux/run.sh +++ /dev/null @@ -1,172 +0,0 @@ -declare -x REPORT_VARS=() -declare -x REPORT_VALS=() - -function common_report { - # Report cuda - if [ $enable_cuda = "ON" ]; then - if [ $use_modules = "ON" ]; then - REPORT_VALS=( - "module:${cuda_module}" - "${REPORT_VALS[@]}" - ) - else - REPORT_VALS=( - "${with_cuda}" - "${REPORT_VALS[@]}" - ) - fi - REPORT_VARS=( - "CUDA" - "${REPORT_VARS[@]}" - ) - fi - - # Report C compiler - REPORT_VARS=( - "C compiler" - "${REPORT_VARS[@]}" - ) - if [ $use_modules = "ON" ]; then - REPORT_VALS=( - "module:${cc_module}" - "${REPORT_VALS[@]}" - ) - else - local cc=$(which gcc) - REPORT_VALS=( - "${cc}" - "${REPORT_VALS[@]}" - ) - fi - - # Report modulefile path - if [ $writing_modulefile != "OFF" ]; then - local module_dir=${modulename_lower}_module - REPORT_VARS=( - "modulefile path" - "${REPORT_VARS[@]}" - ) - REPORT_VALS=( - "${!module_dir}" - "${REPORT_VALS[@]}" - ) - fi - - # Report src & install directory - local src_path=${modulename_lower}_src_path - REPORT_VARS=( - "src directory" - "install directory" "${REPORT_VARS[@]}" - ) - REPORT_VALS=( - "${!src_path}" - "${install_path}" "${REPORT_VALS[@]}" - ) - - for i in "${!REPORT_VARS[@]}"; do - printf " %-25s%s\n" "${REPORT_VARS[i]}:" "${REPORT_VALS[i]}" - done - echo "" -} - -run() { - local configure="$1" - local build="$2" - local install="$3" - local cleanup="$4" - if [ $writing_modulefile != "OFF" ]; then - if [[ -z $5 ]]; then - printf "\n${RED}Missing modulefile function${NC}\n" - exit 1 - else - modulefile="$5" - fi - if [[ -z $6 ]]; then - printf "\n${RED}Missing report function${NC}\n" - exit 1 - else - report="$6" - fi - else - if [[ -z $5 ]]; then - report="" - else - report="$5" - fi - fi - - printf "Installing ${BLUE}${modulename}${NC}\n" - eval $report - common_report - - set_spinner spinner1 - declare -x STEPS=( - 'configure' - 'build' - 'install' - 'cleanup' - ) - declare -x CMDS=( - 'eval $configure' - 'eval $build' - 'eval $install' - 'eval $cleanup' - ) - if [ $writing_modulefile != "OFF" ]; then - STEPS+=( - 'modulefile' - ) - CMDS+=( - 'eval $modulefile' - ) - fi - - local step=0 - rm -f $logfile - - tput civis -- invisible - - while [ "$step" -lt "${#CMDS[@]}" ]; do - ${CMDS[$step]} & - pid=$! - - if [ $verbose = "OFF" ]; then - while ps -p $pid &>/dev/null; do - echo -ne "\\r[ ] ${STEPS[$step]}" - - for k in "${!FRAME[@]}"; do - echo -ne "\\r[ ${FRAME[k]} ]" - sleep $FRAME_INTERVAL - done - done - fi - wait $pid - local exitcode=$? - - if [ $exitcode -eq 0 ]; then - if [ $deploy = "OFF" ]; then - # draw up arrow - echo -ne "\\r[ ${BLUE}↑${NC} ] ${STEPS[$step]}\\n" - echo "" - else - echo -ne "\\r[ ${GREEN}✔${NC} ] ${STEPS[$step]}\\n" - fi - else - echo -ne "\\r[ ${RED}✘${NC} ] ${STEPS[$step]}\\n" - echo "Failed to install ${modulename} :(" - echo "see ${logfile} for more details" - exit 1 - fi - step=$((step + 1)) - done - - tput cnorm -- normal - - if [ $deploy = "ON" ]; then - echo - printf "${BLUE}${modulename}${NC} succesfully installed in ${install_prefix}/${modulename_lower}!\n" - else - echo - printf "now run \`${BLUE}bash ${programname} -d${NC}\` to execute the script\n" - fi -} diff --git a/legacy/deploy/compile_adios2.sh b/legacy/deploy/compile_adios2.sh deleted file mode 100644 index c27620820..000000000 --- a/legacy/deploy/compile_adios2.sh +++ /dev/null @@ -1,268 +0,0 @@ -#!/bin/bash - -SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) - -source ${SCRIPT_DIR}/aux/aux.sh - -declare -r modulename="ADIOS2" -declare -r has_modulefile="ON" - -default_debug="OFF" -declare debug="${default_debug}" -default_arch="AUTO" -declare arch="${default_arch}" -default_mpi_path="module:ompi" -declare with_mpi="${default_mpi_path}" -default_hdf5_path="module:hdf5" -declare hdf5="${default_hdf5_path}" -default_kokkos_path="module:kokkos" -declare kokkos="${default_kokkos_path}" - -source ${SCRIPT_DIR}/aux/default.sh -source ${SCRIPT_DIR}/aux/globals.sh - -function usage { - common_help - echo " --with-mpi MPI path or modulename (\`module:\`)" - echo " set to OFF to disable MPI support" - echo " (default: ${default_mpi_path})" - echo "" - echo " --arch Hardware architecture for Kokkos" - echo " comma-separated list of CPU and/or GPU archs" - echo " for example: \`SKX,Volta70\`" - echo " (default: ${default_arch})" - echo "" - echo " --kokkos Kokkos path or modulename (\`module:\`)" - echo " default: ${default_kokkos_path}/" - echo "" - echo " --hdf5 HDF5 path or modulename (\`module:\`)" - echo " default: ${default_hdf5_path}/" - echo "" - echo " --debug Build in debug mode" - echo " (default: $debug)" - echo "" -} - -source ${SCRIPT_DIR}/aux/argparse.sh -source ${SCRIPT_DIR}/aux/config.sh - -if [[ $hdf5 = module:* ]]; then - hdf5_module=${hdf5#module:} -fi - -if [[ $kokkos = module:* ]]; then - kokkos_module=${kokkos#module:} -fi - -if [ $arch = "AUTO" ]; then - printf "${RED}Automatic architecture detection is not supported for ADIOS2${NC}\n" - exit 1 -fi - -if [ $debug = "ON" ]; then - adios2_module+="/debug" - install_path+="/debug" - kokkos_module+="/debug" -fi - -if [ $with_mpi != "OFF" ]; then - adios2_module+="/mpi" - install_path+="/mpi" - if [ $hdf5 == $default_hdf5_path ]; then - hdf5_module+="/mpi" - if [ $enable_cuda = "ON" ]; then - hdf5_module+="/cuda" - else - hdf5_module+="/cpu" - fi - fi - kokkos_module+="/mpi" -else - if [ $hdf5 == $default_hdf5_path ]; then - hdf5_module+="/serial" - fi -fi - -if [ $enable_cuda = "ON" ]; then - adios2_module+="/cuda" - install_path+="/cuda" - kokkos_module+="/cuda" -fi - -suffix=$(define_kokkos_suffix $arch) -adios2_module+=$suffix -install_path+=$suffix -kokkos_module+=$suffix - -flags=() - -if [ $enable_cuda = "ON" ]; then - flags+=( - ADIOS2_USE_CUDA=ON - ) -fi - -if [ $with_mpi != "OFF" ]; then - flags+=( - ADIOS2_USE_MPI=ON - ) -else - flags+=( - ADIOS2_USE_MPI=OFF - ADIOS2_HAVE_HDF5_VOL=OFF - ) -fi - -compile_args=( - -D CMAKE_CXX_STANDARD=17 - -D CMAKE_CXX_EXTENSIONS=OFF - -D CMAKE_POSITION_INDEPENDENT_CODE=TRUE - -D BUILD_SHARED_LIBS=ON - - -D ADIOS2_USE_HDF5=ON - -D ADIOS2_USE_Kokkos=ON - - -D ADIOS2_USE_Python=OFF - -D ADIOS2_USE_Fortran=OFF - -D ADIOS2_USE_ZeroMQ=OFF - -D BUILD_TESTING=OFF - -D ADIOS2_BUILD_EXAMPLES=OFF - - -D CMAKE_INSTALL_PREFIX=$install_path -) - -if [ $debug = "ON" ]; then - compile_args+=( - -D CMAKE_BUILD_TYPE=Debug - ) -fi -for flag in "${flags[@]}"; do - compile_args+=( - -D $flag - ) -done - -source ${SCRIPT_DIR}/aux/run.sh - -function prebuild { - if [ $use_modules = "ON" ]; then - runcommand "module purge" - runcommand "module load $cc_module" - if [ $enable_cuda = "ON" ]; then - runcommand "module load $cuda_module" - fi - if [ ! $with_mpi = "OFF" ]; then - runcommand "module load $mpi_module" - fi - runcommand "module load $hdf5_module" - runcommand "module load $kokkos_module" - fi -} - -function configure { - prebuild - runcommand "cd $adios2_src_path" - runcommand "rm -rf build" - local args=$(printf " %s" "${compile_args[@]}") - runcommand "cmake -B build$args" -} - -function compile { - prebuild - runcommand "cd $adios2_src_path" - runcommand "cmake --build build -j" -} - -function install { - runcommand "cd $adios2_src_path" - runcommand "cmake --install build" -} - -function cleanup { - runcommand "cd $adios2_src_path" - runcommand "rm -rf build" -} - -function report { - if [ ! $with_mpi = "OFF" ]; then - REPORT_VARS+=( - "MPI" - ) - REPORT_VALS+=( - "${with_mpi}" - ) - fi - REPORT_VARS+=( - "Kokkos" - "HDF5" - ) - - REPORT_VALS+=( - "${kokkos}" - "${hdf5}" - ) - REPORT_VARS+=( - "Architecture(s)" - "Debug mode" - ) - REPORT_VALS+=( - "${arch}" - "${debug}" - ) -} - -function modulefile { - fname=$adios2_module - description="ADIOS2" - if [ $with_mpi != "OFF" ]; then - description=$description" @ MPI" - fi - if [ $enable_cuda = "ON" ]; then - description=$description" @ CUDA" - fi - for ar in "${archs[@]}"; do - if [ $ar = "AUTO" ]; then - break - fi - description=$description" @ ${ar}" - done - prereqs="" - if [ $use_modules = "ON" ]; then - prereqs+="prereq\t\t$cc_module" - if [ $enable_cuda = "ON" ]; then - prereqs+=" $cuda_module" - fi - if [ ! $with_mpi = "OFF" ]; then - prereqs+=" $mpi_module" - fi - prereqs+=" $hdf5_module $kokkos_module" - fi - local setflags="" - for flag in "${flags[@]}"; do - local setflag=$(echo $flag | sed 's/=/\t\t/') - setflags+="\nsetenv\t$setflag" - done - runcommand "mkdir -p $(dirname $fname)" - runcommand "rm -f $fname" - runcommand "echo \"Writing modulefile to $fname\"" - modulecontent='''#%Module1.0###################################################################### -## -## $description -## -proc ModulesHelp { } { - puts stderr \t\"$description\"\n -} -module-whatis \"$description\" - -conflict adios2 -$prereqs - -set basedir $install_path -append-path PATH \$basedir/bin -setenv adios2_DIR \$basedir -$setflags - ''' - runcommand "echo -e \"$modulecontent\" >>$fname" -} - -run configure compile install cleanup modulefile report diff --git a/legacy/deploy/compile_hdf5.sh b/legacy/deploy/compile_hdf5.sh deleted file mode 100644 index 3d10ff63d..000000000 --- a/legacy/deploy/compile_hdf5.sh +++ /dev/null @@ -1,166 +0,0 @@ -#!/bin/bash - -SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) - -source ${SCRIPT_DIR}/aux/aux.sh - -declare -r modulename="HDF5" -declare -r has_modulefile="ON" - -default_mpi_path="module:ompi" -declare with_mpi="${default_mpi_path}" - -source ${SCRIPT_DIR}/aux/default.sh -source ${SCRIPT_DIR}/aux/globals.sh - -function usage { - common_help - echo " --with-mpi MPI path or modulename (\`module:\`)" - echo " set to OFF to disable MPI support" - echo " (default: ${default_mpi_path})" - echo "" -} - -source ${SCRIPT_DIR}/aux/argparse.sh -source ${SCRIPT_DIR}/aux/config.sh - -if [ ! $with_mpi = "OFF" ]; then - hdf5_module+="/mpi" - install_path+="/mpi" - if [ $enable_cuda = "ON" ]; then - hdf5_module+="/cuda" - install_path+="/cuda" - else - hdf5_module+="/cpu" - install_path+="/cpu" - fi -else - hdf5_module+="/serial" - install_path+="/serial" -fi - -if [ ! $with_mpi = "OFF" ]; then - compile_args=( - -S HDF5config.cmake,HPC=sbatch,MPI=true,BUILD_GENERATOR=Unix,INSTALLDIR=$install_path - ) -else - compile_args=( - -S HDF5config.cmake,HPC=sbatch,BUILD_GENERATOR=Unix,INSTALLDIR=$install_path - ) -fi -compile_args+=( - -C Release - -V - -O hdf5.log -) - -source ${SCRIPT_DIR}/aux/run.sh - -function prebuild { - if [ $use_modules = "ON" ]; then - runcommand "module purge" - runcommand "module load $cc_module" - if [ $enable_cuda = "ON" ]; then - runcommand "module load $cuda_module" - fi - if [ ! $with_mpi = "OFF" ]; then - runcommand "module load $mpi_module" - fi - fi -} - -function configure { - : # No configuration needed -} - -function compile { - prebuild - runcommand "cd $hdf5_src_path" - runcommand "rm -rf build" - local args=$(printf " %s" "${compile_args[@]}") - runcommand "ctest$args" -} - -function install { - runcommand "module list" - runcommand "cd $hdf5_src_path/build" - runcommand "make install" - runcommand "cd HDF5_ZLIB-prefix/src/HDF5_ZLIB-build" - runcommand "make install" - runcommand "cd ../../../SZIP-prefix/src/SZIP-build" - runcommand "make install" -} - -function cleanup { - runcommand "cd $hdf5_src_path" - runcommand "rm -rf build" -} - -function report { - if [ ! $with_mpi = "OFF" ]; then - REPORT_VARS+=( - "MPI" - ) - REPORT_VALS+=( - "${with_mpi}" - ) - fi -} - -function modulefile { - fname=$hdf5_module - description="HDF5" - if [ ! $with_mpi = "OFF" ]; then - description=$description" @ MPI" - fi - if [ $enable_cuda = "ON" ]; then - description=$description" @ CUDA" - fi - prereqs="" - if [ $use_modules = "ON" ]; then - prereqs+="prereq\t\t$cc_module" - if [ $enable_cuda = "ON" ]; then - prereqs+=" $cuda_module" - fi - if [ ! $with_mpi = "OFF" ]; then - prereqs+=" $mpi_module" - fi - fi - runcommand "mkdir -p $(dirname $fname)" - runcommand "rm -f $fname" - runcommand "echo \"Writing modulefile to $fname\"" - modulecontent='''#%Module1.0###################################################################### -## -## $description -## -proc ModulesHelp { } { - puts stderr \t\"$description\"\n -} -module-whatis \"$description\" - -conflict hdf5 -$prereqs - -set basedir $install_path -prepend-path PATH \$basedir/bin -prepend-path LD_LIBRARY_PATH \$basedir/lib -prepend-path LIBRARY_PATH \$basedir/lib -prepend-path MANPATH \$basedir/man -prepend-path HDF5_ROOT \$basedir -prepend-path HDF5DIR \$basedir -append-path -d { } LDFLAGS -L\$basedir/lib -append-path -d { } INCLUDE -I\$basedir/include -append-path CPATH \$basedir/include -append-path -d { } FFLAGS -I\$basedir/include -append-path -d { } FCFLAGS -I\$basedir/include -append-path -d { } LOCAL_LDFLAGS -L\$basedir/lib -append-path -d { } LOCAL_INCLUDE -I\$basedir/include -append-path -d { } LOCAL_CFLAGS -I\$basedir/include -append-path -d { } LOCAL_FFLAGS -I\$basedir/include -append-path -d { } LOCAL_FCFLAGS -I\$basedir/include -append-path -d { } LOCAL_CXXFLAGS -I\$basedir/include - ''' - runcommand "echo -e \"$modulecontent\" >>$fname" -} - -run configure compile install cleanup modulefile report diff --git a/legacy/deploy/compile_kokkos.sh b/legacy/deploy/compile_kokkos.sh deleted file mode 100644 index 6c7b8c530..000000000 --- a/legacy/deploy/compile_kokkos.sh +++ /dev/null @@ -1,215 +0,0 @@ -#!/bin/bash - -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) - -source ${SCRIPT_DIR}/aux/aux.sh - -declare -r modulename="Kokkos" -declare -r has_modulefile="ON" - -default_debug="OFF" -declare debug="${default_debug}" -default_arch="AUTO" -declare arch="${default_arch}" -default_mpi_path="module:ompi" -declare with_mpi="${default_mpi_path}" - -source ${SCRIPT_DIR}/aux/default.sh -source ${SCRIPT_DIR}/aux/globals.sh - -function usage { - common_help - echo " --with-mpi MPI path or modulename (\`module:\`)" - echo " set to OFF to disable MPI support" - echo " (default: ${default_mpi_path})" - echo "" - echo " --arch Hardware architecture for Kokkos" - echo " comma-separated list of CPU and/or GPU archs" - echo " for example: \`SKX,Volta70\`" - echo " (default: ${default_arch})" - echo "" - echo " --debug Build in debug mode" - echo " (default: $debug)" - echo "" -} - -source ${SCRIPT_DIR}/aux/argparse.sh -source ${SCRIPT_DIR}/aux/config.sh - -declare -a archs -IFS=',' read -ra archs <<<"$arch" - -if [ $debug = "ON" ]; then - kokkos_module+="/debug" - install_path+="/debug" -fi - -if [ $with_mpi != "OFF" ]; then - kokkos_module+="/mpi" - install_path+="/mpi" -fi - -if [ $enable_cuda = "ON" ]; then - kokkos_module+="/cuda" - install_path+="/cuda" -fi - -suffix=$(define_kokkos_suffix $arch) -kokkos_module+=$suffix -install_path+=$suffix - -flags=() - -if [ $with_mpi = "OFF" ]; then - flags+=( - Kokkos_ENABLE_OPENMP=ON - ) -fi - -if [ $enable_cuda = "ON" ]; then - flags+=( - Kokkos_ENABLE_CUDA=ON - ) -fi - -for ar in "${archs[@]}"; do - if [ $ar = "AUTO" ]; then - break - fi - flags+=( - Kokkos_ARCH_${ar}=ON - ) -done - -if [ $debug = "ON" ]; then - flags+=( - Kokkos_ENABLE_DEBUG=ON - Kokkos_ENABLE_DEBUG_BOUNDS_CHECK=ON - ) -fi - -compile_args=( - -D CMAKE_CXX_STANDARD=17 - -D CMAKE_CXX_EXTENSIONS=OFF - -D CMAKE_POSITION_INDEPENDENT_CODE=TRUE - -D BUILD_SHARED_LIBS=ON - -D CMAKE_INSTALL_PREFIX=$install_path -) -for flag in "${flags[@]}"; do - compile_args+=( - -D $flag - ) -done - -source ${SCRIPT_DIR}/aux/run.sh - -function prebuild { - if [ $use_modules = "ON" ]; then - runcommand "module purge" - runcommand "module load $cc_module" - if [ $enable_cuda = "ON" ]; then - runcommand "module load $cuda_module" - fi - if [ ! $with_mpi = "OFF" ]; then - runcommand "module load $mpi_module" - fi - fi -} - -function configure { - prebuild - runcommand "cd $kokkos_src_path" - runcommand "rm -rf build" - local args=$(printf " %s" "${compile_args[@]}") - runcommand "cmake -B build$args" -} - -function compile { - prebuild - runcommand "cd $kokkos_src_path" - runcommand "cmake --build build -j" -} - -function install { - runcommand "cd $kokkos_src_path" - runcommand "cmake --install build" -} - -function cleanup { - runcommand "cd $kokkos_src_path" - runcommand "rm -rf build" -} - -function report { - if [ ! $with_mpi = "OFF" ]; then - REPORT_VARS+=( - "MPI" - ) - REPORT_VALS+=( - "${with_mpi}" - ) - fi - REPORT_VARS+=( - "Architecture(s)" - "Debug mode" - ) - REPORT_VALS+=( - "${arch}" - "${debug}" - ) -} - -function modulefile { - fname=$kokkos_module - description="Kokkos" - if [ $with_mpi != "OFF" ]; then - description=$description" @ MPI" - fi - if [ $enable_cuda = "ON" ]; then - description=$description" @ CUDA" - fi - for ar in "${archs[@]}"; do - if [ $ar = "AUTO" ]; then - break - fi - description=$description" @ ${ar}" - done - prereqs="" - if [ $use_modules = "ON" ]; then - prereqs+="prereq\t\t$cc_module" - if [ $enable_cuda = "ON" ]; then - prereqs+=" $cuda_module" - fi - if [ ! $with_mpi = "OFF" ]; then - prereqs+=" $mpi_module" - fi - fi - local setflags="" - for flag in "${flags[@]}"; do - local setflag=$(echo $flag | sed 's/=/\t\t/') - setflags+="\nsetenv\t$setflag" - done - runcommand "mkdir -p $(dirname $fname)" - runcommand "rm -f $fname" - runcommand "echo \"Writing modulefile to $fname\"" - modulecontent='''#%Module1.0###################################################################### -## -## $description -## -proc ModulesHelp { } { - puts stderr \t\"$description\"\n -} -module-whatis \"$description\" - -conflict kokkos -$prereqs - -set basedir $install_path -append-path PATH \$basedir/bin -setenv Kokkos_DIR \$basedir -$setflags - ''' - runcommand "echo -e \"$modulecontent\" >>$fname" -} - -run configure compile install cleanup modulefile report diff --git a/legacy/deploy/compile_ompi.sh b/legacy/deploy/compile_ompi.sh deleted file mode 100644 index 9a495f78f..000000000 --- a/legacy/deploy/compile_ompi.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/bin/bash - -SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) - -source ${SCRIPT_DIR}/aux/aux.sh - -declare -r modulename="OMPI" -declare -r has_modulefile="ON" - -default_ucx_path="${HOME}/opt/ucx" -declare with_ucx="${default_ucx_path}" - -source ${SCRIPT_DIR}/aux/default.sh -source ${SCRIPT_DIR}/aux/globals.sh - -function usage { - common_help - echo " --with-ucx enable UCX support (specify installation path)" - echo " set to OFF to disable UCX support" - echo " (default: ${default_ucx_path})" - echo "" -} - -source ${SCRIPT_DIR}/aux/argparse.sh -source ${SCRIPT_DIR}/aux/config.sh - -if [ $enable_cuda = "ON" ]; then - install_path="${install_path}/cuda" - ompi_module="${ompi_module}/cuda" -else - install_path="${install_path}/cpu" - ompi_module="${ompi_module}/cpu" -fi - -compile_args=( - --prefix=${install_path} - --with-devel-headers -) - -if [ $use_modules = "ON" ]; then - if [ $enable_cuda = "ON" ]; then - compile_args+=( - --with-cuda=\$CUDA_HOME - ) - fi -else - if [ $enable_cuda = "ON" ]; then - compile_args+=( - --with-cuda=$with_cuda - ) - fi -fi - -if [ ! $with_ucx = "OFF" ]; then - if [ $enable_cuda = "ON" ]; then - compile_args+=( - --with-ucx=$with_ucx/cuda - ) - else - compile_args+=( - --with-ucx=$with_ucx/cpu - ) - fi -fi - -source ${SCRIPT_DIR}/aux/run.sh - -function prebuild { - if [ $use_modules = "ON" ]; then - runcommand "module purge" - runcommand "module load $cc_module" - runcommand "export CC=\$(which gcc) CXX=\$(which g++)" - if [ $enable_cuda = "ON" ]; then - runcommand "module load $cuda_module" - fi - fi -} - -function configure { - prebuild - runcommand "cd $ompi_src_path" - runcommand "rm -rf build" - runcommand "./autogen.pl" - runcommand "mkdir build" - runcommand "cd build" - local args=$(printf " %s" "${compile_args[@]}") - runcommand "../configure$args" -} - -function compile { - prebuild - runcommand "cd $ompi_src_path/build" - runcommand "make -j" -} - -function install { - runcommand "cd $ompi_src_path/build" - runcommand "make install" -} - -function cleanup { - runcommand "cd $ompi_src_path" - runcommand "rm -rf build" -} - -function report { - REPORT_VARS+=( - "UCX" - ) - REPORT_VALS+=( - "${with_ucx}" - ) -} - -function modulefile { - fname=$ompi_module - description="Open MPI" - if [ $enable_cuda = "ON" ]; then - description=$description" @ CUDA" - fi - prereqs="" - if [ $use_modules = "ON" ]; then - prereqs+="prereq\t\t$cc_module" - fi - runcommand "mkdir -p $(dirname $fname)" - runcommand "rm -f $fname" - runcommand "echo \"Writing modulefile to $fname\"" - modulecontent='''#%Module1.0###################################################################### -## -## $description -## -proc ModulesHelp { } { - puts stderr \t\"$description\"\n -} -module-whatis \"$description\" - -conflict ompi openmpi -$prereqs - -set basedir $install_path -prepend-path PATH \$basedir/bin -prepend-path LD_LIBRARY_PATH \$basedir/lib - -append-path -d { } LOCAL_LDFLAGS -L\$basedir/lib -append-path -d { } LOCAL_INCLUDE -I\$basedir/include -append-path -d { } LOCAL_CFLAGS -I\$basedir/include -append-path -d { } LOCAL_FCFLAGS -I\$basedir/include -append-path -d { } LOCAL_CXXFLAGS -I\$basedir/include - -setenv CXX \$basedir/bin/mpicxx -setenv CC \$basedir/bin/mpicc - -setenv SLURM_MPI_TYPE pmix_v3 -setenv MPIHOME \$basedir -setenv MPI_HOME \$basedir -setenv OPENMPI_HOME \$basedir - ''' - runcommand "echo -e \"$modulecontent\" >>$fname" -} - -run configure compile install cleanup modulefile report diff --git a/legacy/deploy/compile_ucx.sh b/legacy/deploy/compile_ucx.sh deleted file mode 100644 index fcbe4a2eb..000000000 --- a/legacy/deploy/compile_ucx.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash - -SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) - -source ${SCRIPT_DIR}/aux/aux.sh - -declare -r modulename="UCX" -source ${SCRIPT_DIR}/aux/default.sh -source ${SCRIPT_DIR}/aux/globals.sh - -function usage { - common_help -} - -source ${SCRIPT_DIR}/aux/argparse.sh -source ${SCRIPT_DIR}/aux/config.sh - -if [ $enable_cuda = "ON" ]; then - install_path="${install_path}/cuda" -else - install_path="${install_path}/cpu" -fi - -compile_args=( - --prefix=$install_path -) - -if [ $use_modules = "ON" ]; then - if [ $enable_cuda = "ON" ]; then - compile_args+=( - --with-cuda=\$CUDA_HOME - ) - fi -else - if [ $enable_cuda = "ON" ]; then - compile_args+=( - --with-cuda=$cuda_path - ) - fi -fi - -source ${SCRIPT_DIR}/aux/run.sh - -function prebuild { - if [ $use_modules = "ON" ]; then - runcommand "module purge" - runcommand "module load $cc_module" - runcommand "export CC=\$(which gcc) CXX=\$(which g++)" - if [ $enable_cuda = "ON" ]; then - runcommand "module load $cuda_module" - fi - fi -} - -function configure { - prebuild - runcommand "cd $ucx_src_path" - runcommand "rm -rf build" - runcommand "./autogen.sh" - runcommand "mkdir build" - runcommand "cd build" - local args=$(printf " %s" "${compile_args[@]}") - runcommand "../configure$args" -} - -function compile { - prebuild - runcommand "cd $ucx_src_path/build" - runcommand "make -j" -} - -function install { - runcommand "cd $ucx_src_path/build" - runcommand "make install" -} - -function cleanup { - runcommand "cd $ucx_src_path" - runcommand "rm -rf build" -} - -run configure compile install cleanup diff --git a/legacy/deploy/deploy.py b/legacy/deploy/deploy.py deleted file mode 100644 index 323582f3b..000000000 --- a/legacy/deploy/deploy.py +++ /dev/null @@ -1,282 +0,0 @@ -import argparse -import pathlib -from pip._vendor import tomli -from string import Template -import os -from typing import Final - -gpu_archs = [ - "VOLTA", - "TURING", - "AMPERE", - "MAXWELL", - "PASCAL", - "KEPLER", - "INTEL", - "VEGA", - "NAVI", -] - - -class ColoredText(str): - def __new__(cls, text, color): - return super().__new__(cls, text) - - def __init__(self, text, color): - self.color = color - self.colors = { - "red": "\033[0;31m", - "green": "\033[0;32m", - "blue": "\033[0;34m", - "gray": "\033[0;30m", - "nc": "\033[0m", - } - - def __str__(self): - return self.colors[self.color] + self + self.colors["nc"] - - def __repr__(self): - return str(self) - - -# Dependency not implemented error - -dependency_error: Final[str] = ColoredText( - "Dependency deployment not implemented yet. You can run the included .sh scripts manually. Run with `bash compile_.sh` -h for more info.", - "red", -) - -arg_parser = argparse.ArgumentParser(description="Deploy Entity modulefiles") - -arg_parser.add_argument( - "-c", - "--config", - help="Path to the specific configuration file", - default="config.toml", - type=pathlib.Path, - required=True, -) -arg_parser.add_argument( - "-d", - "--deploy", - help="Execute the stript", - default=False, - action="store_true", -) -arg_parser.add_argument( - "-v", - "--verbose", - help="Print verbose output", - default=False, - action="store_true", -) -arg_parser.add_argument( - "--depends", - help="Also build, install & deploy the dependencies", - default=False, - action="store_true", -) - -modulefile_template = Template( - """ -#%Module1.0###################################################################### -## -## Entity ${configuration} -## -################################################################################ -proc ModulesHelp { } { - puts stderr "\\tEntity ${configuration}\\n" -} - -module-whatis "Entity ${configuration}" - -conflict entity - -${kokkos_setenvs} -${openmp_setenvs} - -${entity_setenvs} - -${modules} -""" -) - - -def get_suffix(debug=False, mpi=False, cuda=False, archs=[]): - return ( - ("/debug" if debug else "") - + ("/mpi" if mpi else "") - + ("/cuda" if cuda else "") - + "/" - + "/".join( - f"{arch.lower()}" - for arch in sorted( - archs, key=lambda x: not any([any(ar in x for ar in gpu_archs)]) - ) - ) - ) - - -if __name__ == "__main__": - args = arg_parser.parse_args() - configfname = args.config - dependency_build_scripts = [] - with open(configfname, "r", encoding="utf-8") as f: - config = tomli.loads(f.read()) - modulepath = pathlib.Path(os.path.expandvars(config["entity"]["modulepath"])) - instances = config["entity"]["instances"] - dependencies = config["dependencies"] - cc_module = None - if (cc_path := dependencies["cc"]).startswith("module:"): - cc_module = cc_path.split(":")[1] - for debug in instances["debug"]: - for mpi in instances["with_mpi"]: - for cuda in instances["with_cuda"]: - for architectures in instances["archs"]: - archs = architectures.split(",") - isgpu = any([any(ar in a for ar in gpu_archs) for a in archs]) - if cuda != isgpu: - continue - - entity_setenvs = [] - kokkos_setenvs = [] - openmp_setenvs = [] - modules = [cc_module] if cc_module else [] - entity_setenvs += [ - ["Entity_ENABLE_DEBUG", "ON" if debug else "OFF"] - ] - entity_setenvs += [ - ["Entity_ENABLE_MPI", "ON" if mpi else "OFF"] - ] - if cuda and (cuda_path := dependencies["cuda"]).startswith( - "module:" - ): - modules += [(cuda_module := cuda_path.split(":")[1])] - for arch in archs: - kokkos_setenvs += [[f"Kokkos_ARCH_{arch}", "ON"]] - - if mpi and (mpi_path := dependencies["mpi"]).startswith( - "module:" - ): - modules += [ - ( - mpi_module := mpi_path.split(":")[1] - + ("/cuda" if cuda else "/cpu") - ) - ] - else: - openmp_setenvs += [ - ["Kokkos_ENABLE_OPENMP", "ON"], - ["OMP_PROC_BIND", "spread"], - ["OMP_PLACES", "threads"], - ["OMP_NUM_THREADS", "[exec nproc]"], - ] - if (hdf5_path := dependencies["hdf5"]).startswith("module:"): - hdf5_path += ( - ("/mpi" if cuda else "/mpi") if mpi else "/serial" - ) - modules += [ - (hdf5_module := hdf5_path.split(":")[1]) - + ("/cuda" if cuda else "/cpu") - if mpi - else "" - ] - kokkos_setenvs += [ - ["Kokkos_ENABLE_CUDA", "ON" if cuda else "OFF"] - ] - - suffix = get_suffix(debug, mpi, cuda, archs) - if (kokkos_path := dependencies["kokkos"]).startswith( - "module:" - ): - modules += [ - ( - kokkos_module := ( - kokkos_path := kokkos_path + suffix - ).split(":")[1] - ) - ] - if (adios2_path := dependencies["adios2"]).startswith( - "module:" - ): - modules += [ - ( - adios2_module := ( - adios2_path := adios2_path + suffix - ).split(":")[1] - ) - ] - configuration = suffix.upper().replace("/", " @ ")[1:] - entity_setenvs = "\n".join( - f"{'setenv':<16}{e[0]:<27}{e[1]}" for e in entity_setenvs - ) - kokkos_setenvs = "\n".join( - f"{'setenv':<16}{e[0]:<27}{e[1]}" for e in kokkos_setenvs - ) - openmp_setenvs = "\n".join( - f"{'setenv':<16}{e[0]:<27}{e[1]}" for e in openmp_setenvs - ) - modules = "\n".join( - f"{'module load':<16}" + os.path.expandvars(m) - for m in modules - ) - modulefile = pathlib.Path.joinpath(modulepath, suffix[1:]) - modulefile_content = modulefile_template.substitute( - configuration=configuration, - entity_setenvs=entity_setenvs, - kokkos_setenvs=kokkos_setenvs, - openmp_setenvs=openmp_setenvs, - modules=modules, - ) - if args.deploy: - modulefile.parent.mkdir(parents=True, exist_ok=True) - with open(modulefile, "w") as f: - f.write(modulefile_content.strip()) - print(modulefile) - if args.verbose or not args.deploy: - print( - ColoredText(modulefile_content, "nc"), - sep="\n", - ) - - if args.depends: - dlm = " \\\n " - arch_flag = f"--arch {architectures}" - with_debug = f"--debug ON{dlm}" if debug else "" - with_cc = f"--with-cc {cc_path}{dlm}" - with_cuda = ( - f"--with-cuda {cuda_path}{dlm}" - if cuda - else f"--with-cuda OFF{dlm}" - ) - with_mpi = ( - f"--with-mpi {mpi_path}{dlm}" - if mpi - else f"--with-mpi OFF{dlm}" - ) - with_hdf5 = f"--with-hdf5 {hdf5_path}{dlm}" - with_kokkos = f"--with-kokkos {kokkos_path}{dlm}" - flags_kokkos = "{with_debug}{with_cc}{with_cuda}{with_mpi}{with_hdf5}{arch_flag}".format( - **locals() - ) - flags_adios2 = "{with_debug}{with_cc}{with_cuda}{with_mpi}{with_hdf5}{with_kokkos}{arch_flag}".format( - **locals() - ) - dependency_build_scripts += [ - f"bash compile_kokkos.sh{dlm}{flags_kokkos}" - ] - dependency_build_scripts += [ - f"bash compile_adios2.sh{dlm}{flags_adios2}" - ] - if args.depends: - print( - ColoredText("Use the following commands to build the dependencies:", "blue") - ) - print() - for group in ["kokkos", "adios2"]: - print(ColoredText(f"{group}", "green")) - print("---") - for script in dependency_build_scripts: - if f"compile_{group}" in script: - print(script) - print() diff --git a/legacy/deploy/personal.toml b/legacy/deploy/personal.toml deleted file mode 100644 index 3f5632311..000000000 --- a/legacy/deploy/personal.toml +++ /dev/null @@ -1,16 +0,0 @@ -[dependencies] -cuda = "module:cuda/12.0" -cc = "module:gcc/11.4" -mpi = "module:$HOME/opt/.modules/ompi" -hdf5 = "module:$HOME/opt/.modules/hdf5" -kokkos = "module:$HOME/opt/.modules/kokkos" -adios2 = "module:$HOME/opt/.modules/adios2" - -[entity] -modulepath = "$HOME/.modules/entity" - -[entity.instances] -debug = [true, false] -with_cuda = [true, false] -with_mpi = [true, false] -archs = ["ZEN2,AMPERE86", "ZEN2"] diff --git a/legacy/deploy/stellar.toml b/legacy/deploy/stellar.toml deleted file mode 100644 index f4c76d97b..000000000 --- a/legacy/deploy/stellar.toml +++ /dev/null @@ -1,16 +0,0 @@ -[dependencies] -cuda = "module:cudatoolkit/12.0" -cc = "module:gcc-toolset/10" -mpi = "module:$HOME/opt/.modules/ompi" -hdf5 = "module:$HOME/opt/.modules/hdf5" -kokkos = "module:$HOME/opt/.modules/kokkos" -adios2 = "module:$HOME/opt/.modules/adios2" - -[entity] -modulepath = "$HOME/.modules/entity" - -[entity.instances] -debug = [true, false] -with_cuda = [true, false] -with_mpi = [true, false] -archs = ["ZEN2,AMPERE80", "VOLTA70,SKX", "SKX"] diff --git a/legacy/deploy/zaratan.toml b/legacy/deploy/zaratan.toml deleted file mode 100644 index 4094ddf13..000000000 --- a/legacy/deploy/zaratan.toml +++ /dev/null @@ -1,16 +0,0 @@ -[dependencies] -cuda = "module:cuda/11.8.0/gcc/11.3.0/zen2" -cc = "module:gcc/11.3.0" -mpi = "" -hdf5 = "module:hdf5" -kokkos = "module:$HOME/opt/.modules/kokkos" -adios2 = "module:$HOME/opt/.modules/adios2" - -[entity] -modulepath = "$HOME/opt/.modules/entity" - -[entity.instances] -debug = [false] -with_cuda = [true] -with_mpi = [false] -archs = ["ZEN2,AMPERE80"] diff --git a/legacy/src/framework/digital_filters.hpp b/legacy/src/framework/digital_filters.hpp deleted file mode 100644 index 0d9fc776a..000000000 --- a/legacy/src/framework/digital_filters.hpp +++ /dev/null @@ -1,180 +0,0 @@ - -template -class DigitalFilter_kernel> : public DigitalFilterBase { - - using DigitalFilterBase::DigitalFilterBase; - using DigitalFilterBase::array; - using DigitalFilterBase::buffer; - using DigitalFilterBase::size; - -public: - Inline void operator()(index_t i, index_t j) const override { - if constexpr (D == Dim::_2D) { - const std::size_t j_min = N_GHOSTS, j_min_p1 = j_min + 1; - const std::size_t j_max = size[1] + N_GHOSTS, j_max_m1 = j_max - 1; - real_t cur_ij, cur_ijp1, cur_ijm1; -#if defined(BELYAEV_FILTER) // Belyaev filter - if (j == j_min) { - /* --------------------------------- r, phi --------------------------------- */ - for (auto& comp : { cur::jx1, cur::jx3 }) { - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, comp, i, j); - cur_ijp1 = FILTER_IN_I1(buffer, comp, i, j + 1); - // ... filter in theta - array(i, j, comp) = INV_2 * cur_ij + INV_4 * cur_ijp1; - } - - /* ---------------------------------- theta --------------------------------- */ - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, cur::jx2, i, j); - cur_ijp1 = FILTER_IN_I1(buffer, cur::jx2, i, j + 1); - // ... filter in theta - array(i, j, cur::jx2) = INV_4 * (cur_ij + cur_ijp1); - } else if (j == j_min_p1) { - /* --------------------------------- r, phi --------------------------------- */ - // ... filter in r - for (auto& comp : { cur::jx1, cur::jx3 }) { - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, comp, i, j); - cur_ijp1 = FILTER_IN_I1(buffer, comp, i, j + 1); - cur_ijm1 = FILTER_IN_I1(buffer, comp, i, j - 1); - // ... filter in theta - array(i, j, comp) = INV_2 * (cur_ij + cur_ijm1) + INV_4 * cur_ijp1; - } - - /* ---------------------------------- theta --------------------------------- */ - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, cur::jx2, i, j); - cur_ijp1 = FILTER_IN_I1(buffer, cur::jx2, i, j + 1); - cur_ijm1 = FILTER_IN_I1(buffer, cur::jx2, i, j - 1); - // ... filter in theta - array(i, j, cur::jx2) = INV_2 * cur_ij + INV_4 * (cur_ijm1 + cur_ijp1); - } else if (j == j_max_m1) { - /* --------------------------------- r, phi --------------------------------- */ - // ... filter in r - for (auto& comp : { cur::jx1, cur::jx3 }) { - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, comp, i, j); - cur_ijp1 = FILTER_IN_I1(buffer, comp, i, j + 1); - cur_ijm1 = FILTER_IN_I1(buffer, comp, i, j - 1); - // ... filter in theta - array(i, j, comp) = INV_2 * (cur_ij + cur_ijp1) + INV_4 * cur_ijm1; - } - - /* ---------------------------------- theta --------------------------------- */ - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, cur::jx2, i, j); - cur_ijm1 = FILTER_IN_I1(buffer, cur::jx2, i, j - 1); - // ... filter in theta - array(i, j, cur::jx2) = INV_4 * (cur_ij + cur_ijm1); - } else if (j == j_max) { - /* --------------------------------- r, phi --------------------------------- */ - for (auto& comp : { cur::jx1, cur::jx3 }) { - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, comp, i, j); - cur_ijm1 = FILTER_IN_I1(buffer, comp, i, j - 1); - // ... filter in theta - array(i, j, comp) = INV_2 * cur_ij + INV_4 * cur_ijm1; - } - // no theta component in the last cell - } else { -#else // more conventional filtering - if (j == j_min) { - /* --------------------------------- r, phi --------------------------------- */ - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, cur::jx1, i, j); - cur_ijp1 = FILTER_IN_I1(buffer, cur::jx1, i, j + 1); - // ... filter in theta - array(i, j, cur::jx1) = INV_2 * cur_ij + INV_2 * cur_ijp1; - - array(i, j, cur::jx3) = ZERO; - - /* ---------------------------------- theta --------------------------------- */ - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, cur::jx2, i, j); - cur_ijp1 = FILTER_IN_I1(buffer, cur::jx2, i, j + 1); - // ... filter in theta - array(i, j, cur::jx2) = INV_4 * (cur_ij + cur_ijp1); - } else if (j == j_min_p1) { - /* --------------------------------- r, phi --------------------------------- */ - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, cur::jx1, i, j); - cur_ijp1 = FILTER_IN_I1(buffer, cur::jx1, i, j + 1); - cur_ijm1 = FILTER_IN_I1(buffer, cur::jx1, i, j - 1); - // ... filter in theta - array(i, j, cur::jx1) = INV_2 * cur_ij + INV_4 * (cur_ijp1 + cur_ijm1); - - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, cur::jx3, i, j); - cur_ijp1 = FILTER_IN_I1(buffer, cur::jx3, i, j + 1); - // ... filter in theta - array(i, j, cur::jx3) = INV_2 * cur_ij + INV_4 * cur_ijp1; - - /* ---------------------------------- theta --------------------------------- */ - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, cur::jx2, i, j); - cur_ijp1 = FILTER_IN_I1(buffer, cur::jx2, i, j + 1); - cur_ijm1 = FILTER_IN_I1(buffer, cur::jx2, i, j - 1); - // ... filter in theta - array(i, j, cur::jx2) = INV_2 * cur_ij + INV_4 * (cur_ijm1 + cur_ijp1); - } else if (j == j_max_m1) { - /* --------------------------------- r, phi --------------------------------- */ - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, cur::jx1, i, j); - cur_ijp1 = FILTER_IN_I1(buffer, cur::jx1, i, j + 1); - cur_ijm1 = FILTER_IN_I1(buffer, cur::jx1, i, j - 1); - // ... filter in theta - array(i, j, cur::jx1) = INV_2 * cur_ij + INV_4 * (cur_ijm1 + cur_ijp1); - - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, cur::jx3, i, j); - cur_ijm1 = FILTER_IN_I1(buffer, cur::jx3, i, j - 1); - // ... filter in theta - array(i, j, cur::jx3) = INV_2 * cur_ij + INV_4 * cur_ijm1; - - /* ---------------------------------- theta --------------------------------- */ - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, cur::jx2, i, j); - cur_ijm1 = FILTER_IN_I1(buffer, cur::jx2, i, j - 1); - // ... filter in theta - array(i, j, cur::jx2) = INV_4 * (cur_ij + cur_ijm1); - } else if (j == j_max) { - /* --------------------------------- r, phi --------------------------------- */ - // ... filter in r - cur_ij = FILTER_IN_I1(buffer, cur::jx1, i, j); - cur_ijm1 = FILTER_IN_I1(buffer, cur::jx1, i, j - 1); - // ... filter in theta - array(i, j, cur::jx1) = INV_2 * cur_ij + INV_2 * cur_ijm1; - - array(i, j, cur::jx3) = ZERO; - } else { -#endif -#pragma unroll - for (auto& comp : { cur::jx1, cur::jx2, cur::jx3 }) { - array(i, j, comp) = INV_4 * buffer(i, j, comp) + - INV_8 * - (buffer(i - 1, j, comp) + buffer(i + 1, j, comp) + - buffer(i, j - 1, comp) + buffer(i, j + 1, comp)) + - INV_16 * (buffer(i - 1, j - 1, comp) + - buffer(i + 1, j + 1, comp) + - buffer(i - 1, j + 1, comp) + - buffer(i + 1, j - 1, comp)); - } - } - } else { // D != Dim::_2D - raise::KernelError( - HERE, - "DigitalFilter_kernel: 2D implementation called for D != 2"); - } - } - - Inline void operator()(index_t, index_t, index_t) const override { - if constexpr (D == Dim::_3D) { - raise::KernelNotImplementedError(HERE); - } else { - raise::KernelError( - HERE, - "DigitalFilter_kernel: 3D implementation called for D != 3"); - } - } -}; \ No newline at end of file diff --git a/legacy/src/framework/io/output_csv.cpp b/legacy/src/framework/io/output_csv.cpp deleted file mode 100644 index 54c127157..000000000 --- a/legacy/src/framework/io/output_csv.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include "wrapper.h" -#include "output_csv.h" -#include "simulation.h" -#include "meshblock/meshblock.h" -#include "particle_macros.h" - -#include - -#include -#include -#include -#include - -// namespace fs = std::filesystem; - -namespace ntt { - namespace csv { - // void ensureFileExists(const std::string& filename) { - // fs::path file(filename); - // if (!fs::exists(file)) { throw std::runtime_error("File does not exist: " + filename); - // } - // } - - // template - // void writeField(const std::string&, const Meshblock&, const em&) { - // // writeField(const std::string& filename, const Meshblock& mblock, const em& - // // field) { rapidcsv::Document doc( - // // "", rapidcsv::LabelParams(-1, -1), rapidcsv::SeparatorParams(',', false, false)); - // // if constexpr (D == Dim1) { - // // auto N = mblock.Ni1(); - // // for (int i {0}; i < N; ++i) { - // // doc.SetCell(i, 0, mblock.em(i + ntt::N_GHOSTS, field)); - // // } - // // } else if constexpr (D == Dim2) { - // // auto N1 = mblock.Ni1(); - // // auto N2 = mblock.Ni2(); - // // for (int i {0}; i < N1; ++i) { - // // for (int j {0}; j < N2; ++j) { - // // doc.SetCell(i, j, mblock.em(i + ntt::N_GHOSTS, j + ntt::N_GHOSTS, - // // field)); - // // } - // // } - // // } else { - // // (void)(field); - // // NTTHostError("Cannot write 3D field data as csv"); - // // } - // // doc.Save(filename); - // } - - // template - // void writeField(const std::string&, const Meshblock&, const cur&) { - // // writeField(const std::string& filename, const Meshblock& mblock, const cur& - // // field) { - // // rapidcsv::Document doc( - // // "", rapidcsv::LabelParams(-1, -1), rapidcsv::SeparatorParams(',', false, - // false)); - // // if constexpr (D == Dim1) { - // // auto N = mblock.Ni1(); - // // for (int i {0}; i < N; ++i) { - // // doc.SetCell(i, 0, mblock.cur(i + ntt::N_GHOSTS, field)); - // // } - // // } else if constexpr (D == Dim2) { - // // auto N1 = mblock.Ni1(); - // // auto N2 = mblock.Ni2(); - // // for (int i {0}; i < N1; ++i) { - // // for (int j {0}; j < N2; ++j) { - // // doc.SetCell(i, j, mblock.cur(i + ntt::N_GHOSTS, j + ntt::N_GHOSTS, - // // field)); - // // } - // // } - // // } else { - // // (void)(field); - // // NTTHostError("Cannot write 3D field data as csv"); - // // } - // // doc.Save(filename); - // } - - // template - // void writeParticle(std::string filename, - // const Meshblock& mblock, - // const std::size_t& species_id, - // const std::size_t& prtl_id, - // const OutputMode& mode) { - // std::ofstream outfile; - - // if (mode == OutputMode::APPEND) { - // try { - // ensureFileExists(filename); - // outfile.open(filename, std::ios_base::app); - // } - // catch (const std::exception& e) { - // PLOGI << e.what(); - // PLOGI << "Creating new file instead."; - // outfile.open(filename); - // outfile << "ux1,ux2,ux3,w,x1,x2,x3" << std::endl; - // } - // } - // if (!outfile.is_open()) { - // throw std::runtime_error("Could not open or create file: " + filename); - // } - - // outfile << mblock.particles[species_id].ux1(prtl_id) << ","; - // outfile << mblock.particles[species_id].ux2(prtl_id) << ","; - // outfile << mblock.particles[species_id].ux3(prtl_id) << ","; - // outfile << mblock.particles[species_id].weight(prtl_id); - // if constexpr (D == Dim1 || D == Dim2 || D == Dim3) { - // auto x1 = get_prtl_x1(mblock.particles[species_id], prtl_id); - // outfile << "," << x1; - // } - // if constexpr (D == Dim2 || D == Dim3) { - // auto x2 = get_prtl_x2(mblock.particles[species_id], prtl_id); - // outfile << "," << x2; - // } else if constexpr (D == Dim3) { - // auto x3 = get_prtl_x3(mblock.particles[species_id], prtl_id); - // outfile << "," << x3; - // } - // outfile << "\n"; - - // outfile.close(); - // } - } // namespace csv -} // namespace ntt - -#ifdef PIC_SIMTYPE - -// using Meshblock1D = ntt::Meshblock; -// using Meshblock2D = ntt::Meshblock; -// using Meshblock3D = ntt::Meshblock; - -// template void ntt::csv::writeField(const std::string&, -// const Meshblock1D&, -// const em&); -// template void ntt::csv::writeField(const std::string&, -// const Meshblock2D&, -// const em&); -// template void ntt::csv::writeField(const std::string&, -// const Meshblock3D&, -// const em&); - -// template void ntt::csv::writeField(const std::string&, -// const Meshblock1D&, -// const cur&); -// template void ntt::csv::writeField(const std::string&, -// const Meshblock2D&, -// const cur&); -// template void ntt::csv::writeField(const std::string&, -// const Meshblock3D&, -// const cur&); - -// template void ntt::csv::writeParticle( -// std::string, const Meshblock1D&, const std::size_t&, const std::size_t&, const -// OutputMode&); -// template void ntt::csv::writeParticle( -// std::string, const Meshblock2D&, const std::size_t&, const std::size_t&, const -// OutputMode&); -// template void ntt::csv::writeParticle( -// std::string, const Meshblock3D&, const std::size_t&, const std::size_t&, const -// OutputMode&); - -// #elif defined(GRPIC_SIMTYPE) - -// using Meshblock2D = ntt::Meshblock; -// using Meshblock3D = ntt::Meshblock; - -// template void ntt::csv::writeField(const -// std::string&, -// const -// Meshblock2D&, -// const em&); -// template void ntt::csv::writeField(const -// std::string&, -// const -// Meshblock3D&, -// const em&); - -// template void ntt::csv::writeField(const -// std::string&, -// const -// Meshblock2D&, -// const cur&); -// template void ntt::csv::writeField(const -// std::string&, -// const -// Meshblock3D&, -// const cur&); - -// template void ntt::csv::writeParticle( -// std::string, const Meshblock2D&, const std::size_t&, const std::size_t&, const -// OutputMode&); -// template void ntt::csv::writeParticle( -// std::string, const Meshblock3D&, const std::size_t&, const std::size_t&, const -// OutputMode&); - -#endif \ No newline at end of file diff --git a/legacy/src/framework/io/output_csv.h b/legacy/src/framework/io/output_csv.h deleted file mode 100644 index 7217bfdce..000000000 --- a/legacy/src/framework/io/output_csv.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef IO_OUTPUT_CSV_H -#define IO_OUTPUT_CSV_H - -#include "wrapper.h" -#include "io/output.h" -#include "meshblock/meshblock.h" - -namespace ntt { - // enum class OutputMode { UNDEFINED, WRITE, APPEND }; - - namespace csv { - // /** - // * @brief Write a field component to a csv file. - // * @param[in] fname Filename to write to. - // * @param[in] mblock Meshblock. - // * @param[in] em Field component to output. - // */ - // template - // void writeField(const std::string&, const Meshblock&, const em&); - - // /** - // * @brief Write a current component to a csv file. - // * @overload - // * @param[in] fname Filename to write to. - // * @param[in] mblock Meshblock. - // * @param[in] cur Current component to output. - // */ - // template - // void writeField(const std::string&, const Meshblock&, const cur&); - - // /** - // * @brief Write a particle data to a csv file. - // * @param[in] fname Filename to write to. - // * @param[in] mblock Meshblock. - // * @param[in] spec_id Species id. - // * @param[in] prtl_id Particle id. - // * @param[in] mode Write mode {WRITE, APPEND}. - // */ - // template - // void writeParticle(std::string, - // const Meshblock&, - // const std::size_t&, - // const std::size_t&, - // const OutputMode& mode = OutputMode::WRITE); - - // /** - // * @brief Ensure the file exists (raises an error if not). - // */ - // void ensureFileExists(const std::string&); - } // namespace csv -} // namespace ntt - -#endif \ No newline at end of file diff --git a/legacy/src/framework/ks_phys_units.h b/legacy/src/framework/ks_phys_units.h deleted file mode 100644 index f7a1b67a3..000000000 --- a/legacy/src/framework/ks_phys_units.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef FRAMEWORK_METRICS_KS_PHYS_UNITS_H -#define FRAMEWORK_METRICS_KS_PHYS_UNITS_H - -#ifdef __INTELLISENSE__ -# pragma diag_suppress 77 -# pragma diag_suppress 65 -#endif - -/** - * Compute metric component 11 in physical coordinate basis. - * - * @param x coordinate array in code units (size of the array is D). - * @returns h_11 (covariant, lower index) metric component. - */ -Inline auto h_11_phys(const coord_t& x) const -> real_t { - real_t r { x[0] * dr + this->x1_min }; - real_t theta { x[1] * dtheta }; - real_t cth { math::cos(theta) }; - return (ONE + TWO * r / (SQR(r) + a_sqr * SQR(cth))); -} - -/** - * Compute metric component 22 in physical coordinate basis. - * - * @param x coordinate array in code units (size of the array is D). - * @returns h_22 (covariant, lower index) metric component. - */ -Inline auto h_22_phys(const coord_t& x) const -> real_t { - real_t r { x[0] * dr + this->x1_min }; - real_t theta { x[1] * dtheta }; - real_t cth { math::cos(theta) }; - return (SQR(r) + a_sqr * SQR(cth)); -} - -/** - * Compute metric component 33 in physical coordinate basis. - * - * @param x coordinate array in code units (size of the array is D). - * @returns h_33 (covariant, lower index) metric component. - */ -Inline auto h_33_phys(const coord_t& x) const -> real_t { - real_t r { x[0] * dr + this->x1_min }; - real_t theta { x[1] * dtheta }; - real_t cth { math::cos(theta) }; - real_t sth { math::sin(theta) }; - - real_t delta { SQR(r) - TWO * r + a_sqr }; - real_t As { (SQR(r) + a_sqr) * (SQR(r) + a_sqr) - a_sqr * delta * SQR(sth) }; - return As * SQR(sth) / (SQR(r) + a_sqr * SQR(cth)); -} - -/** - * Compute metric component 13 in physical coordinate basis. - * - * @param x coordinate array in code units (size of the array is D). - * @returns h_13 (covariant, lower index) metric component. - */ -Inline auto h_13_phys(const coord_t& x) const -> real_t { - real_t r { x[0] * dr + this->x1_min }; - real_t theta { x[1] * dtheta }; - real_t sth { math::sin(theta) }; - return -a * SQR(sth) * (ONE + TWO * r / (SQR(r) + a_sqr * SQR(cth))); -} - -/** - * Compute inverse metric component 11 from h_ij in physical coordinate basis. - * - * @param x coordinate array in code units (size of the array is D). - * @returns h^11 (contravariant, upper index) metric component. - */ -Inline auto h11_phys(const coord_t& x) const -> real_t { - return h_33_phys(x) / (h_11_phys(x) * h_33_phys(x) - SQR(h_13_phys(x))); -} - -/** - * Compute inverse metric component 22 from h_ij in physical coordinate basis. - * - * @param x coordinate array in code units (size of the array is D). - * @returns h^22 (contravariant, upper index) metric component. - */ -Inline auto h22_phys(const coord_t& x) const -> real_t { - return ONE / h_22_phys(x); -} - -/** - * Compute inverse metric component 33 from h_ij in physical coordinate basis. - * - * @param x coordinate array in code units (size of the array is D). - * @returns h^33 (contravariant, upper index) metric component. - */ -Inline auto h33_phys(const coord_t& x) const -> real_t { - return h_11_phys(x) / (h_11_phys(x) * h_33_phys(x) - SQR(h_13_phys(x))); -} - -/** - * Compute inverse metric component 13 from h_ij in physical coordinate basis. - * - * @param x coordinate array in code units (size of the array is D). - * @returns h^13 (contravariant, upper index) metric component. - */ -Inline auto h13_phys(const coord_t& x) const -> real_t { - return -h_13_phys(x) / (h_11_phys(x) * h_33_phys(x) - SQR(h_13_phys(x))); -} - -#ifdef __INTELLISENSE__ -# pragma diag_default 65 -# pragma diag_default 77 -#endif - -#endif // FRAMEWORK_METRICS_KS_PHYS_UNITS_H \ No newline at end of file diff --git a/legacy/src/framework/metrics/kerr_schild_nomass.h b/legacy/src/framework/metrics/kerr_schild_nomass.h deleted file mode 100644 index f706befe0..000000000 --- a/legacy/src/framework/metrics/kerr_schild_nomass.h +++ /dev/null @@ -1,335 +0,0 @@ -#ifndef FRAMEWORK_METRICS_KERR_SCHILD_H -#define FRAMEWORK_METRICS_KERR_SCHILD_H - -#include "wrapper.h" - -#include "metric_base.h" - -#include -#include - -namespace ntt { - /** - * Kerr metric in Kerr-Schild coordinates - * Units: c = rg = 1 - * - * @tparam D dimension. - */ - template - class Metric : public MetricBase { - private: - const real_t dr, dtheta, dphi; - const real_t dr_inv, dtheta_inv, dphi_inv; - const real_t dr_sqr, dtheta_sqr, dphi_sqr; - // Spin parameter, in [0,1[ - // and horizon size in units of rg - // all physical extents are in units of rg - const real_t rh, a, a_sqr; - - public: - const real_t dx_min; - - Metric(std::vector resolution, - std::vector extent, - const real_t* params) - : MetricBase { "kerr_schild", resolution, extent }, - rh { params[5] }, - a { params[4] }, - a_sqr { SQR(a) }, - dr { (this->x1_max - this->x1_min) / this->nx1 }, - dtheta { (real_t)(constant::PI) / this->nx2 }, - dphi { (real_t)(constant::TWO_PI) / this->nx3 }, - dr_inv { ONE / dr }, - dtheta_inv { ONE / dtheta }, - dphi_inv { ONE / dphi }, - dr_sqr { SQR(dr) }, - dtheta_sqr { SQR(dtheta) }, - dphi_sqr { SQR(dphi) }, - dx_min { findSmallestCell() } {} - ~Metric() = default; - - [[nodiscard]] auto spin() const -> const real_t& { - return a; - } - - [[nodiscard]] auto rhorizon() const -> const real_t& { - return rh; - } - - Inline auto h_11(const coord_t& x) const -> real_t { - return dr_sqr; - } - Inline auto h_22(const coord_t& x) const -> real_t { - const real_t r { x[0] * dr + this->x1_min }; - return dtheta_sqr * SQR(r); - } - Inline auto h_33(const coord_t& x) const -> real_t { - const real_t r { x[0] * dr + this->x1_min }; - const real_t theta { x[1] * dtheta }; - if constexpr (D == Dim2) { - return SQR(r * math::sin(theta)); - } else { - return dphi_sqr * SQR(r * math::sin(theta)); - } - } - Inline auto h_13(const coord_t& x) const -> real_t { - return ZERO; - } - Inline auto h11(const coord_t& x) const -> real_t { - return SQR(dr_inv); - } - Inline auto h22(const coord_t& x) const -> real_t { - const real_t r { x[0] * dr + this->x1_min }; - return SQR(dtheta_inv / r); - } - Inline auto h33(const coord_t& x) const -> real_t { - const real_t r { x[0] * dr + this->x1_min }; - const real_t theta { x[1] * dtheta }; - if constexpr (D == Dim2) { - return ONE / (SQR(r * math::sin(theta))); - } else { - return SQR(dphi_inv / (r * math::sin(theta))); - } - } - Inline auto h13(const coord_t& x) const -> real_t { - return ZERO; - } - Inline auto alpha(const coord_t& x) const -> real_t { - return ONE; - } - Inline auto beta1(const coord_t& x) const -> real_t { - return ZERO; - } - Inline auto sqrt_det_h(const coord_t& x) const -> real_t { - const real_t r { x[0] * dr + this->x1_min }; - const real_t theta { x[1] * dtheta }; - // ?ASK is this correct? - if constexpr (D == Dim2) { - return dr * dtheta * SQR(r) * math::sin(theta); - } else { - return dr * dtheta * dphi * SQR(r) * math::sin(theta); - } - } - Inline auto sqrt_det_h_tilde(const coord_t& x) const -> real_t { - const real_t r { x[0] * dr + this->x1_min }; - const real_t theta { x[1] * dtheta }; - // ?ASK is this correct? - if constexpr (D == Dim2) { - return dr * dtheta * SQR(r); - } else { - return dr * dtheta * dphi * SQR(r); - } - } - - /** - * Compute the fiducial minimum cell volume. - * - * @returns Minimum cell volume of the grid [code units]. - */ - Inline auto min_cell_volume() const -> real_t { - return math::pow(dx_min * math::sqrt(static_cast(D)), static_cast(D)); - } - - /** - * Compute the area at the pole (used in axisymmetric solvers). - * Approximate solution for the polar area. - * - * @param x coordinate array in code units - * @returns Area at the pole. - */ - Inline auto polar_area(const coord_t& x) const -> real_t { - real_t r { x[0] * dr + this->x1_min }; - real_t del_theta { x[1] * dtheta }; - return dr * SQR(r) * (ONE - math::cos(del_theta)); - } -/** - * @note Since kokkos disallows virtual inheritance, we have to - * include vector transformations for a non-diagonal metric here - * (and not in the base class). - */ -#include "metrics_utils/ks_common.h" -#include "metrics_utils/sph_common.h" - - /** - * Compute minimum effective cell size for a given metric (in physical units). - * @returns Minimum cell size of the grid [physical units]. - */ - auto findSmallestCell() const -> real_t { - if constexpr (D == Dim2) { - real_t min_dx { -ONE }; - for (int i { 0 }; i < this->nx1; ++i) { - for (int j { 0 }; j < this->nx2; ++j) { - real_t i_ { static_cast(i) + HALF }; - real_t j_ { static_cast(j) + HALF }; - coord_t ij { i_, j_ }; - real_t dx = ONE - / (this->alpha(ij) * std::sqrt(this->h11(ij) + this->h22(ij)) - + this->beta1(ij)); - if ((min_dx > dx) || (min_dx < 0.0)) { - min_dx = dx; - } - } - } - return min_dx; - } else { - NTTHostError("min cell finding not implemented for 3D"); - return ZERO; - } - } - - /** - * Coordinate conversion from code units to Cartesian physical units. - * - * @param xi coordinate array in code units - * @param x coordinate array in Cartesian physical units - */ - Inline void x_Code2Cart(const coord_t& xi, coord_t& x) const { - if constexpr (D == Dim2) { - coord_t x_sph; - x_Code2Sph(xi, x_sph); - x[0] = x_sph[0] * math::sin(x_sph[1]); - x[1] = x_sph[0] * math::cos(x_sph[1]); - } else if constexpr (D == Dim3) { - coord_t x_sph; - x_Code2Sph(xi, x_sph); - x[0] = x_sph[0] * math::sin(x_sph[1]) * math::cos(x_sph[2]); - x[1] = x_sph[0] * math::sin(x_sph[1]) * math::sin(x_sph[2]); - x[2] = x_sph[0] * math::cos(x_sph[1]); - } - } - - /** - * Coordinate conversion from Cartesian physical units to code units. - * - * @param x coordinate array in Cartesian coordinates in physical units - * @param xi coordinate array in code units - */ - Inline void x_Cart2Code(const coord_t& x, coord_t& xi) const { - if constexpr (D == Dim2) { - coord_t x_sph; - x_sph[0] = math::sqrt(x[0] * x[0] + x[1] * x[1]); - x_sph[1] = math::atan2(x[1], x[0]); - x_Sph2Code(x_sph, xi); - } else if constexpr (D == Dim3) { - coord_t x_sph; - x_sph[0] = math::sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); - x_sph[1] = math::atan2(x[1], x[0]); - x_sph[2] = math::acos(x[2] / x_sph[0]); - x_Sph2Code(x_sph, xi); - } - } - - /** - * Coordinate conversion from code units to Spherical physical units. - * - * @param xi coordinate array in code units - * @param x coordinate array in Spherical coordinates in physical units - */ - Inline void x_Code2Sph(const coord_t& xi, coord_t& x) const { - if constexpr (D == Dim2) { - x[0] = xi[0] * dr + this->x1_min; - x[1] = xi[1] * dtheta; - } else if constexpr (D == Dim3) { - x[0] = xi[0] * dr + this->x1_min; - x[1] = xi[1] * dtheta; - x[2] = xi[2] * dphi; - } - } - - /** - * Coordinate conversion from Spherical physical units to code units. - * - * @param x coordinate array in Spherical coordinates in physical units - * @param xi coordinate array in code units - */ - Inline void x_Sph2Code(const coord_t& x, coord_t& xi) const { - if constexpr (D == Dim2) { - xi[0] = (x[0] - this->x1_min) * dr_inv; - xi[1] = x[1] * dtheta_inv; - } else if constexpr (D == Dim3) { - xi[0] = (x[0] - this->x1_min) * dr_inv; - xi[1] = x[1] * dtheta_inv; - xi[2] = x[2] * dphi_inv; - } - } - - /** - * Vector conversion from contravariant to spherical contravariant. - * - * @param xi coordinate array in code units - * @param vi_cntrv vector in contravariant basis - * @param vsph_cntrv vector in spherical contravariant basis - */ - Inline void v3_Cntrv2PhysCntrv(const coord_t&, - const vec_t& vi_cntrv, - vec_t& vsph_cntrv) const { - vsph_cntrv[0] = vi_cntrv[0] * dr; - vsph_cntrv[1] = vi_cntrv[1] * dtheta; - if constexpr (D == Dim2) { - vsph_cntrv[2] = vi_cntrv[2]; - } else { - vsph_cntrv[2] = vi_cntrv[2] * dphi; - } - } - - /** - * Vector conversion from spherical contravariant to contravariant. - * - * @param xi coordinate array in code units - * @param vsph_cntrv vector in spherical contravariant basis - * @param vi_cntrv vector in contravariant basis - */ - Inline void v3_PhysCntrv2Cntrv(const coord_t&, - const vec_t& vsph_cntrv, - vec_t& vi_cntrv) const { - vi_cntrv[0] = vsph_cntrv[0] * dr_inv; - vi_cntrv[1] = vsph_cntrv[1] * dtheta_inv; - if constexpr (D == Dim2) { - vi_cntrv[2] = vsph_cntrv[2]; - } else { - vi_cntrv[2] = vsph_cntrv[2] * dphi_inv; - } - } - - /** - * Vector conversion from covariant to spherical covariant. - * - * @param xi coordinate array in code units - * @param vi_cov vector in covariant basis - * @param vsph_cov vector in spherical covariant basis - */ - Inline void v3_Cov2PhysCov(const coord_t&, - const vec_t& vi_cov, - vec_t& vsph_cov) const { - vsph_cov[0] = vi_cov[0] * dr_inv; - vsph_cov[1] = vi_cov[1] * dtheta_inv; - if constexpr (D == Dim2) { - vsph_cov[2] = vi_cov[2]; - } else { - vsph_cov[2] = vi_cov[2] * dphi_inv; - } - } - - /** - * Vector conversion from covariant to spherical covariant. - * - * @param xi coordinate array in code units - * @param vsph_cov vector in spherical covariant basis - * @param vi_cov vector in covariant basis - */ - Inline void v3_PhysCov2Cov(const coord_t&, - const vec_t& vsph_cov, - vec_t& vi_cov) const { - vi_cov[0] = vsph_cov[0] * dr; - vi_cov[1] = vsph_cov[1] * dtheta; - if constexpr (D == Dim2) { - vi_cov[2] = vsph_cov[2]; - } else { - vi_cov[2] = vsph_cov[2] * dphi; - } - } - }; - -} // namespace ntt - -#endif diff --git a/legacy/src/framework/utils/current_filter.cpp b/legacy/src/framework/utils/current_filter.cpp deleted file mode 100644 index f9d1429c3..000000000 --- a/legacy/src/framework/utils/current_filter.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "wrapper.h" -// #include "current_filter.hpp" - -namespace ntt { - - // template <> - // void CurrentFilter::synchronizeGhostZones() const { - // auto ni {m_mesh.Ni1()}; - // auto mesh {m_mesh}; - // if (mesh.boundaries[0] == BoundaryCondition::PERIODIC) { - // Kokkos::parallel_for( - // "1d_gh_x1m", mesh.rangeCells({CellLayer::minGhostLayer}), Lambda(index_t i) { - // m_cur(i, cur::jx1) = m_cur(i + ni, cur::jx1); - // m_cur(i, cur::jx2) = m_cur(i + ni, cur::jx2); - // m_cur(i, cur::jx3) = m_cur(i + ni, cur::jx3); - // }); - // Kokkos::parallel_for( - // "1d_gh_x1p", mesh.rangeCells({CellLayer::maxGhostLayer}), Lambda(index_t i) { - // m_cur(i, cur::jx1) = m_cur(i - ni, cur::jx1); - // m_cur(i, cur::jx2) = m_cur(i - ni, cur::jx2); - // m_cur(i, cur::jx3) = m_cur(i - ni, cur::jx3); - // }); - // } - // } - - // template <> - // void CurrentFilter::synchronizeGhostZones() const { - // auto ni {m_mesh.Ni1()}; - // auto nj {m_mesh.Ni2()}; - // auto mesh {this->m_mesh}; - // if (mesh.boundaries[0] == BoundaryCondition::PERIODIC) { - // Kokkos::parallel_for( - // "2d_gh_x1m", - // mesh.rangeCells({CellLayer::minGhostLayer, CellLayer::activeLayer}), - // Lambda(index_t i, index_t j) { - // m_cur(i, j, cur::jx1) = m_cur(i + ni, j, cur::jx1); - // m_cur(i, j, cur::jx2) = m_cur(i + ni, j, cur::jx2); - // m_cur(i, j, cur::jx3) = m_cur(i + ni, j, cur::jx3); - // }); - // Kokkos::parallel_for( - // "2d_gh_x1p", - // mesh.rangeCells({CellLayer::maxGhostLayer, CellLayer::activeLayer}), - // Lambda(index_t i, index_t j) { - // m_cur(i, j, cur::jx1) = m_cur(i - ni, j, cur::jx1); - // m_cur(i, j, cur::jx2) = m_cur(i - ni, j, cur::jx2); - // m_cur(i, j, cur::jx3) = m_cur(i - ni, j, cur::jx3); - // }); - // } - // if (mesh.boundaries[1] == BoundaryCondition::PERIODIC) { - // Kokkos::parallel_for( - // "2d_gh_x2m", - // mesh.rangeCells({CellLayer::activeLayer, CellLayer::minGhostLayer}), - // Lambda(index_t i, index_t j) { - // m_cur(i, j, cur::jx1) = m_cur(i, j + nj, cur::jx1); - // m_cur(i, j, cur::jx2) = m_cur(i, j + nj, cur::jx2); - // m_cur(i, j, cur::jx3) = m_cur(i, j + nj, cur::jx3); - // }); - // Kokkos::parallel_for( - // "2d_gh_x2p", - // mesh.rangeCells({CellLayer::activeLayer, CellLayer::maxGhostLayer}), - // Lambda(index_t i, index_t j) { - // m_cur(i, j, cur::jx1) = m_cur(i, j - nj, cur::jx1); - // m_cur(i, j, cur::jx2) = m_cur(i, j - nj, cur::jx2); - // m_cur(i, j, cur::jx3) = m_cur(i, j - nj, cur::jx3); - // }); - // } - // if ((mesh.boundaries[0] == BoundaryCondition::PERIODIC) - // && (mesh.boundaries[1] == BoundaryCondition::PERIODIC)) { - // Kokkos::parallel_for( - // "2d_bc_corner1", - // mesh.rangeCells({CellLayer::minGhostLayer, CellLayer::minGhostLayer}), - // Lambda(index_t i, index_t j) { - // m_cur(i, j, cur::jx1) = m_cur(i + ni, j + nj, cur::jx1); - // m_cur(i, j, cur::jx2) = m_cur(i + ni, j + nj, cur::jx2); - // m_cur(i, j, cur::jx3) = m_cur(i + ni, j + nj, cur::jx3); - // }); - // Kokkos::parallel_for( - // "2d_bc_corner2", - // mesh.rangeCells({CellLayer::minGhostLayer, CellLayer::maxGhostLayer}), - // Lambda(index_t i, index_t j) { - // m_cur(i, j, cur::jx1) = m_cur(i + ni, j - nj, cur::jx1); - // m_cur(i, j, cur::jx2) = m_cur(i + ni, j - nj, cur::jx2); - // m_cur(i, j, cur::jx3) = m_cur(i + ni, j - nj, cur::jx3); - // }); - // Kokkos::parallel_for( - // "2d_bc_corner3", - // mesh.rangeCells({CellLayer::maxGhostLayer, CellLayer::minGhostLayer}), - // Lambda(index_t i, index_t j) { - // m_cur(i, j, cur::jx1) = m_cur(i - ni, j + nj, cur::jx1); - // m_cur(i, j, cur::jx2) = m_cur(i - ni, j + nj, cur::jx2); - // m_cur(i, j, cur::jx3) = m_cur(i - ni, j + nj, cur::jx3); - // }); - // Kokkos::parallel_for( - // "2d_bc_corner4", - // mesh.rangeCells({CellLayer::maxGhostLayer, CellLayer::maxGhostLayer}), - // Lambda(index_t i, index_t j) { - // m_cur(i, j, cur::jx1) = m_cur(i - ni, j - nj, cur::jx1); - // m_cur(i, j, cur::jx2) = m_cur(i - ni, j - nj, cur::jx2); - // m_cur(i, j, cur::jx3) = m_cur(i - ni, j - nj, cur::jx3); - // }); - // } - // } - - // template <> - // void CurrentFilter::synchronizeGhostZones() const {} - -} // namespace ntt - -// template struct ntt::CurrentFilter; -// template struct ntt::CurrentFilter; -// template struct ntt::CurrentFilter; diff --git a/legacy/src/framework/utils/current_filter.hpp b/legacy/src/framework/utils/current_filter.hpp deleted file mode 100644 index 7720f603f..000000000 --- a/legacy/src/framework/utils/current_filter.hpp +++ /dev/null @@ -1,272 +0,0 @@ -#ifndef UTILS_CURRENT_FILTER_H -#define UTILS_CURRENT_FILTER_H - -#include "wrapper.h" -#include "meshblock/meshblock.h" - -namespace ntt { -// /** -// * @brief Digital current filtering routine. -// * @tparam D Dimension. -// */ -// template -// struct CurrentFilter { -// ndfield_t m_cur; -// ndfield_t m_cur_b; -// Mesh m_mesh; -// const unsigned short m_npasses; -// tuple_t m_size; - -// /** -// * @brief Constructor. -// * @param cur Current field. -// * @param cur0 Backup current field. -// * @param npasses Number of filter passes. -// */ -// CurrentFilter(const ndfield_t& cur, -// const ndfield_t& cur_b, -// const Mesh& mesh, -// const unsigned short& npasses) -// : m_cur(cur), m_cur_b(cur_b), m_mesh(mesh), m_npasses(npasses) { -// for (short d = 0; d < (short)D; ++d) { -// m_size[d] = m_mesh.Ni(d); -// } -// } - -// void apply() { -// // for (unsigned short i = 0; i < m_npasses; ++i) { -// // synchronizeGhostZones(); -// // Kokkos::deep_copy(m_cur_b, m_cur); -// // filterPass(); -// // } -// } - -// /** -// * @brief 1D implementation of the algorithm. -// * @param i1 index. -// */ -// Inline void operator()(index_t) const; -// /** -// * @brief 2D implementation of the algorithm. -// * @param i1 index. -// * @param i2 index. -// */ -// Inline void operator()(index_t, index_t) const; -// /** -// * @brief 3D implementation of the algorithm. -// * @param i1 index. -// * @param i2 index. -// * @param i3 index. -// */ -// Inline void operator()(index_t, index_t, index_t) const; - -// void filterPass() { -// #ifdef MINKOWSKI_METRIC -// Kokkos::parallel_for("filter_pass", m_mesh.rangeActiveCells(), *this); -// #else -// if constexpr (D == Dim2) { -// Kokkos::parallel_for("filter_pass", -// CreateRangePolicy({m_mesh.i1_min(), m_mesh.i2_min()}, -// {m_mesh.i1_max(), m_mesh.i2_max() + 1}), -// *this); -// } else { -// Kokkos::parallel_for("filter_pass", m_mesh.rangeActiveCells(), *this); -// } -// #endif -// } -// void synchronizeGhostZones() const; -// }; - -// #ifdef MINKOWSKI_METRIC -// template <> -// Inline void CurrentFilter::operator()(index_t i) const { -// for (auto& comp : {cur::jx1, cur::jx2, cur::jx3}) { -// m_cur(i, comp) -// = INV_2 * m_cur_b(i, comp) + INV_4 * (m_cur_b(i - 1, comp) + m_cur_b(i + 1, comp)); -// } -// } - -// template <> -// Inline void CurrentFilter::operator()(index_t i, index_t j) const { -// for (auto& comp : {cur::jx1, cur::jx2, cur::jx3}) { -// m_cur(i, j, comp) = INV_4 * m_cur_b(i, j, comp) -// + INV_8 -// * (m_cur_b(i - 1, j, comp) + m_cur_b(i + 1, j, comp) -// + m_cur_b(i, j - 1, comp) + m_cur_b(i, j + 1, comp)) -// + INV_16 -// * (m_cur_b(i - 1, j - 1, comp) + m_cur_b(i + 1, j + 1, comp) -// + m_cur_b(i - 1, j + 1, comp) + m_cur_b(i + 1, j - 1, comp)); -// } -// } - -// template <> -// Inline void CurrentFilter::operator()(index_t i, index_t j, index_t k) const { -// for (auto& comp : {cur::jx1, cur::jx2, cur::jx3}) { -// m_cur(i, j, k, comp) -// = INV_8 * m_cur_b(i, j, k, comp) -// + INV_16 -// * (m_cur_b(i - 1, j, k, comp) + m_cur_b(i + 1, j, k, comp) -// + m_cur_b(i, j - 1, k, comp) + m_cur_b(i, j + 1, k, comp) -// + m_cur_b(i, j, k - 1, comp) + m_cur_b(i, j, k + 1, comp)) -// + INV_32 -// * (m_cur_b(i - 1, j - 1, k, comp) + m_cur_b(i + 1, j + 1, k, comp) -// + m_cur_b(i - 1, j + 1, k, comp) + m_cur_b(i + 1, j - 1, k, comp) -// + m_cur_b(i, j - 1, k - 1, comp) + m_cur_b(i, j + 1, k + 1, comp) -// + m_cur_b(i, j, k - 1, comp) + m_cur_b(i, j, k + 1, comp) -// + m_cur_b(i - 1, j, k - 1, comp) + m_cur_b(i + 1, j, k + 1, comp) -// + m_cur_b(i - 1, j, k + 1, comp) + m_cur_b(i + 1, j, k - 1, comp)) -// + INV_64 -// * (m_cur_b(i - 1, j - 1, k - 1, comp) + m_cur_b(i + 1, j + 1, k + 1, comp) -// + m_cur_b(i - 1, j + 1, k + 1, comp) + m_cur_b(i + 1, j - 1, k - 1, comp) -// + m_cur_b(i - 1, j - 1, k + 1, comp) + m_cur_b(i + 1, j + 1, k - 1, comp) -// + m_cur_b(i - 1, j + 1, k - 1, comp) + m_cur_b(i + 1, j - 1, k + 1, comp)); -// } -// } -// #else -// template <> -// Inline void CurrentFilter::operator()(index_t) const {} - -// # define FILTER_IN_I1(ARR, COMP, I, J) \ -// INV_2*(ARR)((I), (J), (COMP)) \ -// + INV_4*((ARR)((I)-1, (J), (COMP)) + (ARR)((I) + 1, (J), (COMP))) - -// template <> -// Inline void CurrentFilter::operator()(index_t i, index_t j) const { -// const std::size_t j_min = N_GHOSTS, j_min_p1 = j_min + 1; -// const std::size_t j_max = m_size[1] + N_GHOSTS - 1, j_max_m1 = j_max - 1; -// real_t cur_ij, cur_ijp1, cur_ijm1; -// # define BELYAEV_FILTER -// // # define REGULAR_FILTER - -// # ifdef BELYAEV_FILTER -// if (j == j_min) { -// /* --------------------------------- r, phi --------------------------------- */ -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx1, i, j); -// cur_ijp1 = FILTER_IN_I1(m_cur_b, cur::jx1, i, j + 1); -// // ... filter in theta -// m_cur(i, j, cur::jx1) = INV_2 * cur_ij + INV_4 * cur_ijp1; - -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx3, i, j); -// cur_ijp1 = FILTER_IN_I1(m_cur_b, cur::jx3, i, j + 1); -// // ... filter in theta -// m_cur(i, j, cur::jx3) = INV_2 * cur_ij + INV_4 * cur_ijp1; - -// /* ---------------------------------- theta --------------------------------- */ -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx2, i, j); -// cur_ijp1 = FILTER_IN_I1(m_cur_b, cur::jx2, i, j + 1); -// // ... filter in theta -// m_cur(i, j, cur::jx2) = INV_4 * cur_ij + INV_4 * cur_ijp1; -// } else if (j == j_min_p1) { -// /* --------------------------------- r, phi --------------------------------- */ -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx1, i, j); -// cur_ijp1 = FILTER_IN_I1(m_cur_b, cur::jx1, i, j + 1); -// cur_ijm1 = FILTER_IN_I1(m_cur_b, cur::jx1, i, j - 1); -// // ... filter in theta -// m_cur(i, j, cur::jx1) = INV_2 * (cur_ij + cur_ijm1) + INV_4 * cur_ijp1; - -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx3, i, j); -// cur_ijp1 = FILTER_IN_I1(m_cur_b, cur::jx3, i, j + 1); -// cur_ijm1 = FILTER_IN_I1(m_cur_b, cur::jx3, i, j - 1); -// // ... filter in theta -// m_cur(i, j, cur::jx3) = INV_2 * (cur_ij + cur_ijm1) + INV_4 * cur_ijp1; -// } else if (j == j_max_m1) { -// /* --------------------------------- r, phi --------------------------------- */ -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx1, i, j); -// cur_ijp1 = FILTER_IN_I1(m_cur_b, cur::jx1, i, j + 1); -// cur_ijm1 = FILTER_IN_I1(m_cur_b, cur::jx1, i, j - 1); -// // ... filter in theta -// m_cur(i, j, cur::jx1) = INV_2 * (cur_ij + cur_ijp1) + INV_4 * cur_ijm1; - -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx3, i, j); -// cur_ijp1 = FILTER_IN_I1(m_cur_b, cur::jx3, i, j + 1); -// cur_ijm1 = FILTER_IN_I1(m_cur_b, cur::jx3, i, j - 1); -// // ... filter in theta -// m_cur(i, j, cur::jx3) = INV_2 * (cur_ij + cur_ijp1) + INV_4 * cur_ijm1; - -// /* ---------------------------------- theta --------------------------------- */ -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx2, i, j); -// cur_ijm1 = FILTER_IN_I1(m_cur_b, cur::jx2, i, j - 1); -// // ... filter in theta -// m_cur(i, j, cur::jx2) = INV_4 * cur_ij + INV_4 * cur_ijm1; -// } else if (j == j_max) { -// /* --------------------------------- r, phi --------------------------------- */ -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx1, i, j); -// cur_ijp1 = FILTER_IN_I1(m_cur_b, cur::jx1, i, j + 1); -// cur_ijm1 = FILTER_IN_I1(m_cur_b, cur::jx1, i, j - 1); -// // ... filter in theta -// m_cur(i, j, cur::jx1) -// = INV_2 * m_cur_b(i, j, cur::jx1) + INV_4 * m_cur_b(i, j - 1, cur::jx1); - -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx3, i, j); -// cur_ijp1 = FILTER_IN_I1(m_cur_b, cur::jx3, i, j + 1); -// cur_ijm1 = FILTER_IN_I1(m_cur_b, cur::jx3, i, j - 1); -// // ... filter in theta -// m_cur(i, j, cur::jx3) -// = INV_2 * m_cur_b(i, j, cur::jx3) + INV_4 * m_cur_b(i, j - 1, cur::jx3); -// } -// # elif defined(REGULAR_FILTER) -// if (j == j_min) { -// /* --------------------------------- r, phi --------------------------------- */ -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx1, i, j); -// cur_ijp1 = FILTER_IN_I1(m_cur_b, cur::jx1, i, j + 1); -// // ... filter in theta -// m_cur(i, j, cur::jx1) = INV_2 * cur_ij + INV_2 * cur_ijp1; -// // FILTER_IN_I1(m_cur_b, cur::jx1, i, j); - -// /* ---------------------------------- theta --------------------------------- */ -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx2, i, j); -// // ... filter in theta -// m_cur(i, j, cur::jx2) = INV_2 * cur_ij; -// // FILTER_IN_I1(m_cur_b, cur::jx2, i, j); -// // INV_2 * cur_ij; -// } else if (j == j_max + 1) { -// /* --------------------------------- r, phi --------------------------------- */ -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx1, i, j); -// cur_ijm1 = FILTER_IN_I1(m_cur_b, cur::jx1, i, j - 1); -// // ... filter in theta -// m_cur(i, j, cur::jx1) -// = INV_2 * m_cur_b(i, j, cur::jx1) + INV_2 * m_cur_b(i, j - 1, cur::jx1); - -// // ... filter in r -// cur_ij = FILTER_IN_I1(m_cur_b, cur::jx2, i, j); -// // ... filter in theta -// m_cur(i, j, cur::jx2) = INV_2 * cur_ij; -// } -// # endif -// else { -// for (auto& comp : {cur::jx1, cur::jx2, cur::jx3}) { -// m_cur(i, j, comp) -// = INV_4 * m_cur_b(i, j, comp) -// + INV_8 -// * (m_cur_b(i - 1, j, comp) + m_cur_b(i + 1, j, comp) + m_cur_b(i, j - 1, comp) -// + m_cur_b(i, j + 1, comp)) -// + INV_16 -// * (m_cur_b(i - 1, j - 1, comp) + m_cur_b(i + 1, j + 1, comp) -// + m_cur_b(i - 1, j + 1, comp) + m_cur_b(i + 1, j - 1, comp)); -// } -// } -// } - -// # undef FILTER_IN_I1 - -// template <> -// Inline void CurrentFilter::operator()(index_t, index_t, index_t) const {} - -// #endif - -} // namespace ntt - -#endif \ No newline at end of file diff --git a/legacy/src/framework/utils/particle_injectors.hpp b/legacy/src/framework/utils/particle_injectors.hpp deleted file mode 100644 index c275f170a..000000000 --- a/legacy/src/framework/utils/particle_injectors.hpp +++ /dev/null @@ -1,1018 +0,0 @@ -#ifndef ARCHETYPES_PARTICLE_INJECTOR_H -#define ARCHETYPES_PARTICLE_INJECTOR_H - -#include "utilities/archetypes.hpp" - -#include - -#include "meshblock/meshblock.h" -#include "meshblock/particles.h" -#include "particle_macros.h" -#include "sim_params.h" -#include "wrapper.h" - -namespace ntt { - - /* -------------------------------------------------------------------------- */ - /* Uniform injection kernels and routines */ - /* -------------------------------------------------------------------------- */ - - /** - * @brief 1D particle-vectorized injection kernel - */ - template class EnDist> - struct UniformInjector1d_kernel { - UniformInjector1d_kernel(const SimulationParams& pr, - const Meshblock& mb, - const Particles& sp1, - const Particles& sp2, - const list_t& box, - const real_t&) - : params { pr } - , mblock { mb } - , species1 { sp1 } - , species2 { sp2 } - , species_index1 { sp1.index() } - , species_index2 { sp2.index() } - , offset1 { sp1.npart() } - , offset2 { sp2.npart() } - , region { box[0], box[1] } - , energy_dist { params, mblock } - , pool { *(mblock.random_pool_ptr) } {} - - Inline void operator()(index_t p) const { - typename random_number_pool_t::generator_type rand_gen = pool.get_state(); - - coord_t x { ZERO }; - vec_t v { ZERO }; - x[0] = rand_gen.frand(region[0], region[1]); - energy_dist(x, v, species_index1); - init_prtl_1d(mblock, species1, p + offset1, x[0], v[0], v[1], v[2], ONE); - energy_dist(x, v, species_index2); - init_prtl_1d(mblock, species2, p + offset2, x[0], v[0], v[1], v[2], ONE); - pool.free_state(rand_gen); - } - - private: - SimulationParams params; - Meshblock mblock; - Particles species1, species2; - const int species_index1, species_index2; - const std::size_t offset1, offset2; - EnDist energy_dist; - list_t region; - random_number_pool_t pool; - }; - - /** - * @brief 2D particle-vectorized injection kernel - */ - template class EnDist> - struct UniformInjector2d_kernel { - UniformInjector2d_kernel(const SimulationParams& pr, - const Meshblock& mb, - const Particles& sp1, - const Particles& sp2, - const list_t& box, - const real_t&) - : params { pr } - , mblock { mb } - , species1 { sp1 } - , species2 { sp2 } - , species_index1 { sp1.index() } - , species_index2 { sp2.index() } - , offset1 { sp1.npart() } - , offset2 { sp2.npart() } - , region { box[0], box[1], box[2], box[3] } - , energy_dist { params, mblock } - , pool { *(mblock.random_pool_ptr) } {} - - Inline void operator()(index_t p) const { - typename random_number_pool_t::generator_type rand_gen = pool.get_state(); - - coord_t x { ZERO }; - vec_t v { ZERO }; - x[0] = rand_gen.frand(region[0], region[1]); - x[1] = rand_gen.frand(region[2], region[3]); - energy_dist(x, v, species_index1); - init_prtl_2d(mblock, species1, p + offset1, x[0], x[1], v[0], v[1], v[2], ONE); - energy_dist(x, v, species_index2); - init_prtl_2d(mblock, species2, p + offset2, x[0], x[1], v[0], v[1], v[2], ONE); - pool.free_state(rand_gen); - } - - private: - SimulationParams params; - Meshblock mblock; - Particles species1, species2; - const int species_index1, species_index2; - const std::size_t offset1, offset2; - EnDist energy_dist; - list_t region; - random_number_pool_t pool; - }; - - /** - * @brief 3D particle-vectorized injection kernel - */ - template class EnDist> - struct UniformInjector3d_kernel { - UniformInjector3d_kernel(const SimulationParams& pr, - const Meshblock& mb, - const Particles& sp1, - const Particles& sp2, - const list_t& box, - const real_t&) - : params { pr } - , mblock { mb } - , species1 { sp1 } - , species2 { sp2 } - , species_index1 { sp1.index() } - , species_index2 { sp2.index() } - , offset1 { sp1.npart() } - , offset2 { sp2.npart() } - , region { box[0], box[1], box[2], box[3], box[4], box[5] } - , energy_dist { params, mblock } - , pool { *(mblock.random_pool_ptr) } {} - - Inline void operator()(index_t p) const { - typename random_number_pool_t::generator_type rand_gen = pool.get_state(); - - coord_t x { ZERO }; - vec_t v { ZERO }; - x[0] = rand_gen.frand(region[0], region[1]); - x[1] = rand_gen.frand(region[2], region[3]); - x[2] = rand_gen.frand(region[4], region[5]); - energy_dist(x, v, species_index1); - init_prtl_3d(mblock, species1, p + offset1, x[0], x[1], x[2], v[0], v[1], v[2], ONE); - energy_dist(x, v, species_index2); - init_prtl_3d(mblock, species2, p + offset2, x[0], x[1], x[2], v[0], v[1], v[2], ONE); - pool.free_state(rand_gen); - } - - private: - SimulationParams params; - Meshblock mblock; - Particles species1, species2; - const int species_index1, species_index2; - const std::size_t offset1, offset2; - EnDist energy_dist; - list_t region; - random_number_pool_t pool; - }; - - /** - * @brief Volumetrically uniform particle injector parallelized over particles. - * @tparam D dimension. - * @tparam S simulation engine. - * @tparam EnDist energy distribution [default = Cold]. - * - * @param params simulation parameters. - * @param mblock meshblock. - * @param species species to inject as a list. - * @param ppc_per_spec fiducial number of particles per cell per species. - * @param region region to inject particles as a list of coordinates [optional]. - * @param time current time [optional]. - */ - template class EnDist = Cold> - inline void InjectUniform(const SimulationParams& params, - Meshblock& mblock, - const std::vector& species, - const real_t& ppc_per_spec, - std::vector region = {}, - const real_t& time = ZERO) { - NTTHostErrorIf(species.size() != 2, - "Exactly two species can be injected at the same time"); - auto& sp1 = mblock.particles[species[0] - 1]; - auto& sp2 = mblock.particles[species[1] - 1]; - NTTHostErrorIf( - sp1.charge() != -sp2.charge(), - "Injected species must have the same but opposite charge: q1 = -q2"); - auto ncells = (std::size_t)(mblock.Ni1() * mblock.Ni2() * mblock.Ni3()); - real_t delta_V, full_V; - if (region.size() == 0) { - region = mblock.extent(); - } -#ifdef MINKOWSKI_METRIC - if constexpr (D == Dim1) { - delta_V = (region[1] - region[0]); - full_V = (mblock.extent()[1] - mblock.extent()[0]); - } else if constexpr (D == Dim2) { - delta_V = (region[1] - region[0]) * (region[3] - region[2]); - full_V = (mblock.extent()[1] - mblock.extent()[0]) * - (mblock.extent()[3] - mblock.extent()[2]); - } else if constexpr (D == Dim3) { - delta_V = (region[1] - region[0]) * (region[3] - region[2]) * - (region[5] - region[4]); - full_V = (mblock.extent()[1] - mblock.extent()[0]) * - (mblock.extent()[3] - mblock.extent()[2]) * - (mblock.extent()[5] - mblock.extent()[4]); - } -#else - if constexpr (D == Dim2) { - delta_V = (SQR(region[1]) - SQR(region[0])) * (region[3] - region[2]); - full_V = (SQR(mblock.extent()[1]) - SQR(mblock.extent()[0])) * - constant::PI * HALF; - } else if constexpr (D == Dim3) { - // !TODO: need to be a bit more careful - delta_V = (CUBE(region[1]) - CUBE(region[0])) * (region[3] - region[2]) * - (region[5] - region[4]); - full_V = (CUBE(mblock.extent()[1]) - CUBE(mblock.extent()[0])) * - (4.0 / 3.0) * constant::PI; - } -#endif - ncells = (std::size_t)((real_t)ncells * delta_V / full_V); - - auto npart_per_spec = (std::size_t)((double)(ncells * ppc_per_spec)); - list_t(D)> box { ZERO }; - for (auto i { 0 }; i < 2 * static_cast(D); ++i) { - box[i] = region[i]; - } - - if constexpr (D == Dim1) { - Kokkos::parallel_for( - "InjectUniform", - CreateRangePolicy({ 0 }, { npart_per_spec }), - UniformInjector1d_kernel(params, mblock, sp1, sp2, box, time)); - } else if constexpr (D == Dim2) { - Kokkos::parallel_for( - "InjectUniform", - CreateRangePolicy({ 0 }, { npart_per_spec }), - UniformInjector2d_kernel(params, mblock, sp1, sp2, box, time)); - } else if constexpr (D == Dim3) { - Kokkos::parallel_for( - "InjectUniform", - CreateRangePolicy({ 0 }, { npart_per_spec }), - UniformInjector3d_kernel(params, mblock, sp1, sp2, box, time)); - } - sp1.setNpart(sp1.npart() + npart_per_spec); - sp2.setNpart(sp2.npart() + npart_per_spec); - } - - /* -------------------------------------------------------------------------- */ - /* Volume injection kernels and routines */ - /* -------------------------------------------------------------------------- */ - template - class EnDist, - template - class SpDist, - template - class InjCrit> - struct VolumeInjector1d_kernel { - VolumeInjector1d_kernel(const SimulationParams& pr, - const Meshblock& mb, - const Particles& sp1, - const Particles& sp2, - const array_t& ind, - const real_t& ppc, - const real_t&) - : params { pr } - , mblock { mb } - , species1 { sp1 } - , species2 { sp2 } - , species_index1 { sp1.index() } - , species_index2 { sp2.index() } - , offset1 { sp1.npart() } - , offset2 { sp2.npart() } - , index { ind } - , nppc { ppc } - , use_weights { params.useWeights() } - , V0 { params.V0() } - , energy_dist { params, mblock } - , spatial_dist { params, mblock } - , inj_criterion { params, mblock } - , pool { *(mblock.random_pool_ptr) } {} - - Inline void operator()(index_t i1) const { - // cell node - coord_t xi { static_cast(static_cast(i1) - N_GHOSTS) }; - const auto weight { use_weights - ? (mblock.metric.sqrt_det_h({ xi[0] + HALF }) / V0) - : ONE }; - - random_generator_t rand_gen { pool.get_state() }; - real_t n_inject { nppc }; - coord_t xc { ZERO }; - coord_t xph { ZERO }; - prtldx_t dx1; - vec_t v { ZERO }, v_cart { ZERO }; - - while (n_inject > ZERO) { - dx1 = Random(rand_gen); - xc[0] = xi[0] + dx1; - mblock.metric.x_Code2Cart(xc, xph); - if ((Random(rand_gen) < n_inject) && // # of prtls - inj_criterion(xph) && // injection criterion - (Random(rand_gen) < spatial_dist(xph)) // spatial distribution - ) { - auto p { Kokkos::atomic_fetch_add(&index(), 1) }; - - energy_dist(xph, v, species_index1); - v_cart[0] = v[0]; - v_cart[1] = v[1]; - v_cart[2] = v[2]; - init_prtl_1d_i_di(species1, - offset1 + p, - static_cast(i1) - N_GHOSTS, - dx1, - v_cart[0], - v_cart[1], - v_cart[2], - weight); - - energy_dist(xph, v, species_index2); - v_cart[0] = v[0]; - v_cart[1] = v[1]; - v_cart[2] = v[2]; - init_prtl_1d_i_di(species2, - offset2 + p, - static_cast(i1) - N_GHOSTS, - dx1, - v_cart[0], - v_cart[1], - v_cart[2], - weight); - } - n_inject -= ONE; - } - pool.free_state(rand_gen); - } - - private: - SimulationParams params; - Meshblock mblock; - Particles species1, species2; - const int species_index1, species_index2; - const std::size_t offset1, offset2; - array_t index; - const real_t nppc; - const bool use_weights; - const real_t V0; - EnDist energy_dist; - SpDist spatial_dist; - InjCrit inj_criterion; - random_number_pool_t pool; - }; - - template - class EnDist, - template - class SpDist, - template - class InjCrit> - struct VolumeInjector2d_kernel { - VolumeInjector2d_kernel(const SimulationParams& pr, - const Meshblock& mb, - const Particles& sp1, - const Particles& sp2, - const array_t& ind, - const real_t& ppc, - const real_t&) - : params { pr } - , mblock { mb } - , species1 { sp1 } - , species2 { sp2 } - , species_index1 { sp1.index() } - , species_index2 { sp2.index() } - , offset1 { sp1.npart() } - , offset2 { sp2.npart() } - , index { ind } - , nppc { ppc } - , use_weights { params.useWeights() } - , V0 { params.V0() } - , energy_dist { params, mblock } - , spatial_dist { params, mblock } - , inj_criterion { params, mblock } - , pool { *(mblock.random_pool_ptr) } {} - - Inline void operator()(index_t i1, index_t i2) const { - // cell node - coord_t xi { COORD(i1), COORD(i2) }; - const auto weight { - use_weights - ? (mblock.metric.sqrt_det_h({ xi[0] + HALF, xi[1] + HALF }) / V0) - : ONE - }; - - random_generator_t rand_gen { pool.get_state() }; - real_t n_inject { nppc }; - coord_t xc { ZERO }; - coord_t xph { ZERO }; - prtldx_t dx1, dx2; - vec_t v { ZERO }, v_cart { ZERO }; - - while (n_inject > ZERO) { - dx1 = Random(rand_gen); - dx2 = Random(rand_gen); - xc[0] = xi[0] + dx1; - xc[1] = xi[1] + dx2; -#ifdef MINKOWSKI_METRIC - mblock.metric.x_Code2Cart(xc, xph); -#else - mblock.metric.x_Code2Sph(xc, xph); -#endif - if ((Random(rand_gen) < n_inject) && // # of prtls - inj_criterion(xph) && // injection criterion - (Random(rand_gen) < spatial_dist(xph)) // spatial distribution - ) { - auto p { Kokkos::atomic_fetch_add(&index(), 1) }; - - energy_dist(xph, v, species_index1); -#ifdef MINKOWSKI_METRIC - v_cart[0] = v[0]; - v_cart[1] = v[1]; - v_cart[2] = v[2]; -#else - mblock.metric.v3_Hat2Cart({ xc[0], xc[1], ZERO }, v, v_cart); -#endif - init_prtl_2d_i_di(species1, - offset1 + p, - COORD(i1), - COORD(i2), - dx1, - dx2, - v_cart[0], - v_cart[1], - v_cart[2], - weight); - - energy_dist(xph, v, species_index2); -#ifdef MINKOWSKI_METRIC - v_cart[0] = v[0]; - v_cart[1] = v[1]; - v_cart[2] = v[2]; -#else - mblock.metric.v3_Hat2Cart({ xc[0], xc[1], ZERO }, v, v_cart); -#endif - init_prtl_2d_i_di(species2, - offset2 + p, - COORD(i1), - COORD(i2), - dx1, - dx2, - v_cart[0], - v_cart[1], - v_cart[2], - weight); - } - n_inject -= ONE; - } - pool.free_state(rand_gen); - } - - private: - SimulationParams params; - Meshblock mblock; - Particles species1, species2; - const int species_index1, species_index2; - const std::size_t offset1, offset2; - array_t index; - const real_t nppc; - const bool use_weights; - const real_t V0; - EnDist energy_dist; - SpDist spatial_dist; - InjCrit inj_criterion; - random_number_pool_t pool; - }; - - template - class EnDist, - template - class SpDist, - template - class InjCrit> - struct VolumeInjector3d_kernel { - VolumeInjector3d_kernel(const SimulationParams& pr, - const Meshblock& mb, - const Particles& sp1, - const Particles& sp2, - const array_t& ind, - const real_t& ppc, - const real_t&) - : params { pr } - , mblock { mb } - , species1 { sp1 } - , species2 { sp2 } - , species_index1 { sp1.index() } - , species_index2 { sp2.index() } - , offset1 { sp1.npart() } - , offset2 { sp2.npart() } - , index { ind } - , nppc { ppc } - , use_weights { params.useWeights() } - , V0 { params.V0() } - , energy_dist { params, mblock } - , spatial_dist { params, mblock } - , inj_criterion { params, mblock } - , pool { *(mblock.random_pool_ptr) } {} - - Inline void operator()(index_t i1, index_t i2, index_t i3) const { - // cell node - coord_t xi { static_cast(static_cast(i1) - N_GHOSTS), - static_cast(static_cast(i2) - N_GHOSTS), - static_cast(static_cast(i3) - N_GHOSTS) }; - const auto weight { use_weights - ? (mblock.metric.sqrt_det_h( - { xi[0] + HALF, xi[1] + HALF, xi[2] + HALF }) / - V0) - : ONE }; - - random_generator_t rand_gen { pool.get_state() }; - real_t n_inject { nppc }; - coord_t xc { ZERO }; - coord_t xph { ZERO }; - prtldx_t dx1, dx2, dx3; - vec_t v { ZERO }, v_cart { ZERO }; - - while (n_inject > ZERO) { - dx1 = Random(rand_gen); - dx2 = Random(rand_gen); - dx3 = Random(rand_gen); - xc[0] = xi[0] + dx1; - xc[1] = xi[1] + dx2; - xc[2] = xi[2] + dx3; -#ifdef MINKOWSKI_METRIC - mblock.metric.x_Code2Cart(xc, xph); -#else - mblock.metric.x_Code2Sph(xc, xph); -#endif - if ((Random(rand_gen) < n_inject) && // # of prtls - inj_criterion(xph) && // injection criterion - (Random(rand_gen) < spatial_dist(xph)) // spatial distribution - ) { - auto p { Kokkos::atomic_fetch_add(&index(), 1) }; - - energy_dist(xph, v, species_index1); -#ifdef MINKOWSKI_METRIC - v_cart[0] = v[0]; - v_cart[1] = v[1]; - v_cart[2] = v[2]; -#else - mblock.metric.v3_Hat2Cart({ xc[0], xc[1], xc[2] }, v, v_cart); -#endif - init_prtl_3d_i_di(species1, - offset1 + p, - static_cast(i1) - N_GHOSTS, - static_cast(i2) - N_GHOSTS, - static_cast(i3) - N_GHOSTS, - dx1, - dx2, - dx3, - v_cart[0], - v_cart[1], - v_cart[2], - weight); - - energy_dist(xph, v, species_index2); -#ifdef MINKOWSKI_METRIC - v_cart[0] = v[0]; - v_cart[1] = v[1]; - v_cart[2] = v[2]; -#else - mblock.metric.v3_Hat2Cart({ xc[0], xc[1], xc[2] }, v, v_cart); -#endif - init_prtl_3d_i_di(species2, - offset2 + p, - static_cast(i1) - N_GHOSTS, - static_cast(i2) - N_GHOSTS, - static_cast(i3) - N_GHOSTS, - dx1, - dx2, - dx3, - v_cart[0], - v_cart[1], - v_cart[2], - weight); - } - n_inject -= ONE; - } - pool.free_state(rand_gen); - } - - private: - SimulationParams params; - Meshblock mblock; - Particles species1, species2; - const int species_index1, species_index2; - const std::size_t offset1, offset2; - array_t index; - const real_t nppc; - const bool use_weights; - const real_t V0; - EnDist energy_dist; - SpDist spatial_dist; - InjCrit inj_criterion; - random_number_pool_t pool; - }; - - /** - * @brief Particle injector parallelized by cells in a volume. - * @tparam D dimension. - * @tparam S simulation engine. - * @tparam EnDist energy distribution [default = Cold]. - * @tparam SpDist spatial distribution [default = Uniform]. - * @tparam InjCrit injection criterion [default = NoCriterion]. - * - * @param params simulation parameters. - * @param mblock meshblock. - * @param species species to inject as a list. - * @param ppc_per_spec fiducial number of particles per cell per species. - * @param region region to inject particles as a list of coordinates [optional]. - * @param time current time [optional]. - */ - template class EnDist = Cold, - template class SpDist = Uniform, - template class InjCrit = NoCriterion> - inline void InjectInVolume(const SimulationParams& params, - Meshblock& mblock, - const std::vector& species, - const real_t& ppc_per_spec, - std::vector region = {}, - const real_t& time = ZERO) { - range_t range_policy; - if (region.size() == 0) { - range_policy = mblock.rangeActiveCells(); - } else if (region.size() == 2 * static_cast(D)) { - tuple_t region_min; - tuple_t region_max; - coord_t xmin_ph { ZERO }, xmax_ph { ZERO }; - coord_t xmin_cu { ZERO }, xmax_cu { ZERO }; - for (short i = 0; i < static_cast(D); ++i) { - xmin_ph[i] = region[2 * i]; - xmax_ph[i] = region[2 * i + 1]; - } - mblock.metric.x_Phys2Code(xmin_ph, xmin_cu); - mblock.metric.x_Phys2Code(xmax_ph, xmax_cu); - for (short i = 0; i < static_cast(D); ++i) { - region_min[i] = static_cast(xmin_cu[i]); - region_max[i] = static_cast(xmax_cu[i]); - } - range_policy = CreateRangePolicy(region_min, region_max); - } else { - NTTHostError("region must be empty or have 2 * D elements"); - } - - NTTHostErrorIf(species.size() != 2, - "Exactly two species can be injected at the same time"); - auto& sp1 = mblock.particles[species[0] - 1]; - auto& sp2 = mblock.particles[species[1] - 1]; - NTTHostErrorIf( - sp1.charge() != -sp2.charge(), - "Injected species must have the same but opposite charge: q1 = -q2"); - array_t ind("ind_inj"); - if constexpr (D == Dim1) { - Kokkos::parallel_for( - "InjectInVolume", - range_policy, - VolumeInjector1d_kernel(params, - mblock, - sp1, - sp2, - ind, - ppc_per_spec, - time)); - } else if constexpr (D == Dim2) { - Kokkos::parallel_for( - "InjectInVolume", - range_policy, - VolumeInjector2d_kernel(params, - mblock, - sp1, - sp2, - ind, - ppc_per_spec, - time)); - } else if constexpr (D == Dim3) { - Kokkos::parallel_for( - "InjectInVolume", - range_policy, - VolumeInjector3d_kernel(params, - mblock, - sp1, - sp2, - ind, - ppc_per_spec, - time)); - } - - auto ind_h = Kokkos::create_mirror(ind); - Kokkos::deep_copy(ind_h, ind); - sp1.setNpart(sp1.npart() + ind_h()); - sp2.setNpart(sp2.npart() + ind_h()); - } - - /* -------------------------------------------------------------------------- */ - - template - class EnDist, - template - class InjCrit> - struct NonUniformInjector1d_kernel { - NonUniformInjector1d_kernel(const SimulationParams& pr, - const Meshblock& mb, - const Particles& sp1, - const Particles& sp2, - const array_t& ind, - const ndarray_t<1>& ppc, - const real_t&) - : params { pr } - , mblock { mb } - , species1 { sp1 } - , species2 { sp2 } - , species_index1 { sp1.index() } - , species_index2 { sp2.index() } - , offset1 { sp1.npart() } - , offset2 { sp2.npart() } - , index { ind } - , ppc_per_spec { ppc } - , use_weights { params.useWeights() } - , energy_dist { params, mblock } - , inj_criterion { params, mblock } - , pool { *(mblock.random_pool_ptr) } {} - - Inline void operator()(index_t i1) const { - // cell node - const auto i1_ = static_cast(i1) - N_GHOSTS; - coord_t xi = { static_cast(i1_) }; - - random_generator_t rand_gen { pool.get_state() }; - real_t n_inject { ppc_per_spec(i1_) }; - coord_t xc { ZERO }; - coord_t xph { ZERO }; - prtldx_t dx1; - vec_t v { ZERO }, v_cart { ZERO }; - - while (n_inject > ZERO) { - dx1 = Random(rand_gen); - xc[0] = xi[0] + dx1; - mblock.metric.x_Code2Phys(xc, xph); - if ((Random(rand_gen) < n_inject) && // # of prtls - inj_criterion(xph) // injection criterion - ) { - auto p { Kokkos::atomic_fetch_add(&index(), 1) }; - - energy_dist(xph, v, species_index1); - v_cart[0] = v[0]; - v_cart[1] = v[1]; - v_cart[2] = v[2]; - init_prtl_1d_i_di(species1, - offset1 + p, - i1_, - dx1, - v_cart[0], - v_cart[1], - v_cart[2], - ONE); - - energy_dist(xph, v, species_index2); - v_cart[0] = v[0]; - v_cart[1] = v[1]; - v_cart[2] = v[2]; - init_prtl_1d_i_di(species2, - offset2 + p, - i1_, - dx1, - v_cart[0], - v_cart[1], - v_cart[2], - ONE); - } - n_inject -= ONE; - } - pool.free_state(rand_gen); - } - - private: - SimulationParams params; - Meshblock mblock; - Particles species1, species2; - const int species_index1, species_index2; - const std::size_t offset1, offset2; - array_t index; - ndarray_t<1> ppc_per_spec; - const bool use_weights; - EnDist energy_dist; - InjCrit inj_criterion; - random_number_pool_t pool; - }; - - template - class EnDist, - template - class InjCrit> - struct NonUniformInjector2d_kernel { - NonUniformInjector2d_kernel(const SimulationParams& pr, - const Meshblock& mb, - const Particles& sp1, - const Particles& sp2, - const array_t& ind, - const ndarray_t<2>& ppc, - const real_t&) - : params { pr } - , mblock { mb } - , species1 { sp1 } - , species2 { sp2 } - , species_index1 { sp1.index() } - , species_index2 { sp2.index() } - , offset1 { sp1.npart() } - , offset2 { sp2.npart() } - , index { ind } - , ppc_per_spec { ppc } - , use_weights { params.useWeights() } - , V0 { params.V0() } - , energy_dist { params, mblock } - , inj_criterion { params, mblock } - , pool { *(mblock.random_pool_ptr) } {} - - Inline void operator()(index_t i1, index_t i2) const { - // cell node - const auto i1_ = i1 - static_cast(N_GHOSTS); - const auto i2_ = i2 - static_cast(N_GHOSTS); - coord_t xi = { static_cast(i1_), static_cast(i2_) }; - const auto weight { - use_weights - ? (mblock.metric.sqrt_det_h({ xi[0] + HALF, xi[1] + HALF }) / V0) - : ONE - }; - - random_generator_t rand_gen { pool.get_state() }; - real_t n_inject { ppc_per_spec(i1_, i2_) }; - coord_t xc { ZERO }; - coord_t xph { ZERO }; - prtldx_t dx1, dx2; - vec_t v { ZERO }, v_cart { ZERO }; - - while (n_inject > ZERO) { - dx1 = Random(rand_gen); - dx2 = Random(rand_gen); - xc[0] = xi[0] + dx1; - xc[1] = xi[1] + dx2; - mblock.metric.x_Code2Phys(xc, xph); - if ((Random(rand_gen) < n_inject) && // # of prtls - inj_criterion(xph) // injection criterion - ) { - auto p { Kokkos::atomic_fetch_add(&index(), 1) }; - - energy_dist(xph, v, species_index1); -#ifdef MINKOWSKI_METRIC - v_cart[0] = v[0]; - v_cart[1] = v[1]; - v_cart[2] = v[2]; -#elif defined(GRPIC_ENGINE) - mblock.metric.v3_Hat2Cov({ xc[0], xc[1] }, v, v_cart); -#else - mblock.metric.v3_Hat2Cart({ xc[0], xc[1], ZERO }, v, v_cart); -#endif - init_prtl_2d_i_di(species1, - offset1 + p, - i1_, - i2_, - dx1, - dx2, - v_cart[0], - v_cart[1], - v_cart[2], - weight); - - energy_dist(xph, v, species_index2); -#ifdef MINKOWSKI_METRIC - v_cart[0] = v[0]; - v_cart[1] = v[1]; - v_cart[2] = v[2]; -#elif defined(GRPIC_ENGINE) - mblock.metric.v3_Hat2Cov({ xc[0], xc[1] }, v, v_cart); -#else - mblock.metric.v3_Hat2Cart({ xc[0], xc[1], ZERO }, v, v_cart); -#endif - init_prtl_2d_i_di(species2, - offset2 + p, - i1_, - i2_, - dx1, - dx2, - v_cart[0], - v_cart[1], - v_cart[2], - weight); - } - n_inject -= ONE; - } - pool.free_state(rand_gen); - } - - private: - SimulationParams params; - Meshblock mblock; - Particles species1, species2; - const int species_index1, species_index2; - const std::size_t offset1, offset2; - array_t index; - ndarray_t<2> ppc_per_spec; - const bool use_weights; - const real_t V0; - EnDist energy_dist; - InjCrit inj_criterion; - random_number_pool_t pool; - }; - - /** - * @brief Particle injector parallelized by cells in a volume ... - * @brief ... up to certain number density. - * @tparam D dimension. - * @tparam S simulation engine. - * @tparam EnDist energy distribution [default = Cold]. - * @tparam InjCrit injection criterion [default = NoCriterion]. - * - * @param params simulation parameters. - * @param mblock meshblock. - * @param species species to inject as a list. - * @param ppc_per_spec target injection ppc per species. - * @param region region to inject particles as a list of coordinates [optional]. - * @param time current time [optional]. - */ - template class EnDist = Cold, - template class InjCrit = NoCriterion> - inline void InjectNonUniform(const SimulationParams& params, - Meshblock& mblock, - const std::vector& species, - const ndarray_t<(short)(D)>& ppc_per_spec, - std::vector region = {}, - const real_t& time = ZERO) { - EnDist energy_dist(params, mblock); - InjCrit inj_criterion(params, mblock); - range_t range_policy; - if (region.size() == 0) { - range_policy = mblock.rangeActiveCells(); - } else if (region.size() == 2 * static_cast(D)) { - tuple_t region_min; - tuple_t region_max; - coord_t xmin_ph { ZERO }, xmax_ph { ZERO }; - coord_t xmin_cu { ZERO }, xmax_cu { ZERO }; - for (short i = 0; i < static_cast(D); ++i) { - xmin_ph[i] = region[2 * i]; - xmax_ph[i] = region[2 * i + 1]; - } - mblock.metric.x_Phys2Code(xmin_ph, xmin_cu); - mblock.metric.x_Phys2Code(xmax_ph, xmax_cu); - for (short i = 0; i < static_cast(D); ++i) { - region_min[i] = static_cast(xmin_cu[i]); - region_max[i] = static_cast(xmax_cu[i]); - } - range_policy = CreateRangePolicy(region_min, region_max); - } else { - NTTHostError("region must be empty or have 2 * D elements"); - } - - NTTHostErrorIf(species.size() != 2, - "Exactly two species can be injected at the same time"); - auto& sp1 = mblock.particles[species[0] - 1]; - auto& sp2 = mblock.particles[species[1] - 1]; - NTTHostErrorIf( - sp1.charge() != -sp2.charge(), - "Injected species must have the same but opposite charge: q1 = -q2"); - array_t ind("ind_inj"); - if constexpr (D == Dim1) { - Kokkos::parallel_for( - "InjectNonUniform", - range_policy, - NonUniformInjector1d_kernel(params, - mblock, - sp1, - sp2, - ind, - ppc_per_spec, - time)); - } else if constexpr (D == Dim2) { - Kokkos::parallel_for( - "InjectNonUniform", - range_policy, - NonUniformInjector2d_kernel(params, - mblock, - sp1, - sp2, - ind, - ppc_per_spec, - time)); - } else if constexpr (D == Dim3) { - NTTHostError("Not implemented"); - } - - auto ind_h = Kokkos::create_mirror(ind); - Kokkos::deep_copy(ind_h, ind); - sp1.setNpart(sp1.npart() + ind_h()); - sp2.setNpart(sp2.npart() + ind_h()); - } - -} // namespace ntt - -#endif // ARCHETYPES_PARTICLE_INJECTOR_H diff --git a/legacy/src/framework/utils/timer.cpp b/legacy/src/framework/utils/timer.cpp deleted file mode 100644 index ba285cedf..000000000 --- a/legacy/src/framework/utils/timer.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "wrapper.h" -#include "timer.h" - -#include -#include -#include -#include -#include -#include - -namespace ntt { - - auto TimeUnit::getMultiplier() const -> double { return multiplier; } - auto operator<<(std::ostream& os, const TimeUnit& v) -> std::ostream& { - return os << v.unitname; - } - - Time::Time(const long double& v, const TimeUnit& u) { - value = static_cast(v); - unit = &u; - } - // auto Time::getValue() const -> long double { return value; } - // void Time::convert(const TimeUnit& to) { - // if (&to != unit) { - // value = value * unit->getMultiplier() / to.getMultiplier(); - // unit = &to; - // } - // } - auto Time::represent(const TimeUnit& to) const -> Time { - if (&to != unit) { - return Time(value * unit->getMultiplier() / to.getMultiplier(), to); - } else { - return Time(value, to); - } - } - auto operator<<(std::ostream& os, const Time& t) -> std::ostream& { - return os << t.value << " " << *(t.unit); - } - // auto Time::operator-() const -> Time { return Time(-(this->value), *(this->unit)); } - // auto operator+(const Time& t1, const Time& t2) -> Time { - // if (t1.unit == t2.unit) { - // return Time(static_cast(t1.value + t2.value), *(t1.unit)); - // } else { - // const TimeUnit* main_unit; - // if (t1.unit->getMultiplier() < t2.unit->getMultiplier()) - // main_unit = t1.unit; - // else - // main_unit = t2.unit; - // return Time(static_cast(t1.represent(*main_unit).value - // + t2.represent(*main_unit).value), - // *(main_unit)); - // } - // } - // auto operator-(const Time& t1, const Time& t2) -> Time { return (t1 + (-t2)); } - // auto operator*(double x, const Time& t) -> Time { return Time(t.value * x, *(t.unit)); } - // auto operator*(const Time& t, double x) -> Time { return Time(t.value * x, *(t.unit)); } - - namespace { // anonymous namespace - void timeNow(TimeContainer& time) { time = std::chrono::system_clock::now(); } - void timeElapsed(TimeContainer& time_start, Time& time_elapsed) { - long double dt; - dt = std::chrono::duration(std::chrono::system_clock::now() - time_start) - .count(); - time_elapsed = Time(dt, second); - } - } // namespace - - void Timer::start() { - init = true; - on = true; - timeNow(t_start); - } - void Timer::check() { - assert(init && "# Error: timer is not initialized."); - assert(on && "# Error: timer is not running."); - timeElapsed(t_start, t_elapsed); - } - void Timer::stop() { - check(); - on = false; - } - auto Timer::getElapsedIn(const TimeUnit& u) const -> long double { - if (init) { - return t_elapsed.represent(u).value; - } else { - return 0.0; - } - } - auto Timer::getName() const -> std::string { return name; } - void Timer::printElapsed(std::ostream& os, const TimeUnit& u) const { - auto repr = t_elapsed.represent(u); - os << std::setw(25) << std::left << "timer `" + name + "`" - << ": " << repr; - if (on) { os << " (and running)"; } - } - void Timer::printElapsed(const TimeUnit& u) const { printElapsed(std::cout, u); } - - // TimerCollection::TimerCollection(const std::vector& timers) { - // for (auto& t : timers) { - // m_timers.push_back(Timer(t)); - // // m_timers.emplace_back(Timer(t)); - // } - // } - - void TimerCollection::start(const int& i) { m_timers[i - 1].start(); } - - void TimerCollection::stop(const int& i) { m_timers[i - 1].stop(); } - - void TimerCollection::printAll(std::ostream& os, const TimeUnit& u) const { - os << "==============================" << std::endl; - for (auto& t : m_timers) { - t.printElapsed(os, u); - os << std::endl; - } - os << "------------------------------" << std::endl; - } - - void TimerCollection::printAll(const TimeUnit& u) const { printAll(std::cout, u); } - -} // namespace ntt diff --git a/legacy/src/framework/utils/timer.h b/legacy/src/framework/utils/timer.h deleted file mode 100644 index 5793ecede..000000000 --- a/legacy/src/framework/utils/timer.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef UTILS_TIMER_H -#define UTILS_TIMER_H - -#include -#include -#include -#include - -namespace ntt { - // Type to be used for s/ms/us/ms - class TimeUnit { - private: - double multiplier; - std::string unitname; - - public: - TimeUnit() = default; - TimeUnit(const double& mult, const std::string& unit) - : multiplier {mult}, unitname {unit} {} - ~TimeUnit() = default; - [[nodiscard]] auto getMultiplier() const -> double; - friend auto operator<<(std::ostream& os, TimeUnit const& v) -> std::ostream&; - }; - - // declaration of s/ms/us/ms - inline const TimeUnit second(1, "s"); - inline const TimeUnit millisecond(1e-3, "ms"); - inline const TimeUnit microsecond(1e-6, "us"); - inline const TimeUnit nanosecond(1e-9, "ns"); - - // Type to keep track of timestamp - class Time { - private: - long double value {0.0}; - const TimeUnit* unit; - - public: - Time() = default; - Time(const long double& v, const TimeUnit& u = second); - ~Time() = default; - // void convert(const TimeUnit& to); - // [[nodiscard]] auto getValue() const -> long double; - [[nodiscard]] auto represent(const TimeUnit& to) const -> Time; - // Time operator=(const Time & rhs); - auto operator-() const -> Time; - - // friend auto operator+(Time const&, Time const&) -> Time; - // friend auto operator-(Time const&, Time const&) -> Time; - // friend auto operator*(double x, Time const& t) -> Time; - // friend auto operator*(Time const&, double x) -> Time; - friend auto operator<<(std::ostream& os, Time const& t) -> std::ostream&; - friend class Timer; - }; - - using TimeContainer = std::chrono::time_point; - - class Timer { - private: - std::string name; - bool init {false}; - bool on {false}; - TimeContainer t_start; - Time t_elapsed; - - public: - Timer() : name("NULL"), t_elapsed {0.0} {} - Timer(const std::string& name) : name(std::move(name)), t_elapsed {0.0} {} - ~Timer() = default; - void start(); - void check(); - void stop(); - [[nodiscard]] auto getElapsedIn(const TimeUnit& u) const -> long double; - [[nodiscard]] auto getName() const -> std::string; - void printElapsed(const TimeUnit& u = second) const; - void printElapsed(std::ostream& os = std::cout, const TimeUnit& u = second) const; - }; - - class TimerCollection { - private: - // TODO: maybe map? - std::vector m_timers; - - public: - // TimerCollection(const std::vector& timers); - TimerCollection(const std::vector& timers) : m_timers(timers) {} - ~TimerCollection() = default; - void start(const int& i); - void stop(const int& i); - void printAll(std::ostream& os = std::cout, const TimeUnit& u = second) const; - void printAll(const TimeUnit& u = second) const; - }; - -} // namespace ntt - -#endif // TIMER_H diff --git a/legacy/src/framework/writer.cpp b/legacy/src/framework/writer.cpp deleted file mode 100644 index 1ef56273e..000000000 --- a/legacy/src/framework/writer.cpp +++ /dev/null @@ -1,68 +0,0 @@ - -if constexpr (D == Dim1) { - extent = fmt::format("{} {} 0 0 0 0", params.extent()[0], params.extent()[1]); -} else if constexpr (D == Dim2) { - extent = fmt::format("{} {} {} {} 0 0", - params.extent()[0], - params.extent()[1], - params.extent()[2], - params.extent()[3]); -} else if constexpr (D == Dim3) { - extent = fmt::format("{} {} {} {} {} {}", - params.extent()[0], - params.extent()[1], - params.extent()[2], - params.extent()[3], - params.extent()[4], - params.extent()[5]); -} - -const std::string vtk_xml = R"( - - - " - - - - - step - - - - - )"; - -if constexpr (D == Dim1) { - extent = fmt::format("0 {} 0 0 0 0", params.resolution()[0] + 1); -} else if constexpr (D == Dim2) { - extent - = fmt::format("0 {} 0 {} 0 0", params.resolution()[0] + 1, params.resolution()[1] + - 1); -} else if constexpr (D == Dim3) { - extent = fmt::format("0 {} 0 {} 0 {}", - params.resolution()[0] + 1, - params.resolution()[1] + 1, - params.resolution()[2] + 1); -} -const std::string vtk_xml = R"( - - - - - - - - time - - - - - )"; - -std::cout << vtk_xml << std::endl; - -m_io.DefineAttribute("vtk.xml", vtk_xml); diff --git a/legacy/src/grpic/boundaries/fields_bc.cpp b/legacy/src/grpic/boundaries/fields_bc.cpp deleted file mode 100644 index 239bf7655..000000000 --- a/legacy/src/grpic/boundaries/fields_bc.cpp +++ /dev/null @@ -1,82 +0,0 @@ - -// !LEGACY -// // theta = 0 boundary -// Kokkos::parallel_for( -// "2d_bc_theta0", -// CreateRangePolicy({0, 0}, {m_mblock.i1_max() + N_GHOSTS, m_mblock.i2_min() + 1}), -// Lambda(index_t i, index_t j) { -// // mblock.em0(i, j, em::ex3) = ZERO; -// // mblock.em(i, j, em::ex3) = ZERO; -// }); - -// // theta = pi boundary -// Kokkos::parallel_for( -// "2d_bc_thetaPi", -// CreateRangePolicy({0, m_mblock.i2_max()}, {m_mblock.i1_max() + N_GHOSTS, -// m_mblock.i2_max() + N_GHOSTS}), Lambda(index_t i, index_t j) { -// mblock.em0(i, j, em::ex3) = ZERO; - -// mblock.em(i, j, em::ex3) = ZERO; -// }); - -// auto j_min {mblock.i2_min()}; -// // Kokkos::parallel_for( -// // "2d_bc_theta0", CreateRangePolicy({mblock.i1_min() - 1}, {mblock.i1_max()}), -// Lambda(index_t i) { -// // // mblock.em0(i, j_min, em::ex3) = ZERO; -// // // mblock.em(i, j_min, em::ex3) = ZERO; -// // mblock.em0(i, j_min - 1, em::ex2) = -mblock.em0(i, j_min, em::ex2); -// // mblock.em(i, j_min - 1, em::ex2) = -mblock.em(i, j_min, em::ex2); -// // }); - -// // // theta = pi boundary -// // auto j_max {mblock.i2_max()}; -// // Kokkos::parallel_for( -// // "2d_bc_thetaPi", CreateRangePolicy({mblock.i1_min() - 1}, {m_mblock.i1_max()}), -// Lambda(index_t i) { -// // // mblock.em0(i, j_max, em::ex3) = ZERO; -// // // mblock.em(i, j_max, em::ex3) = ZERO; -// // mblock.em0(i, j_max, em::ex2) = mblock.em0(i, j_max - 1, em::ex2); -// // mblock.em(i, j_max, em::ex2) = mblock.em(i, j_max - 1, em::ex2); -// // }); - -// auto pGen {this->m_pGen}; -// auto br_func {&(this->m_pGen.userTargetField_br_cntrv)}; -// Kokkos::parallel_for( -// "2d_absorbing bc", -// CreateRangePolicy({mblock.i1_min(), mblock.i2_min()}, {mblock.i1_max() + 1, -// mblock.i2_max() + 1}), Lambda(index_t i, index_t j) { -// real_t i_ {static_cast(static_cast(i) - N_GHOSTS)}; -// real_t j_ {static_cast(static_cast(j) - N_GHOSTS)}; - -// // i -// vec_t rth_; -// mblock.metric.x_Code2Sph({i_, j_}, rth_); -// if (rth_[0] > r_absorb) { -// real_t delta_r1 {(rth_[0] - r_absorb) / (r_max - r_absorb)}; -// real_t sigma_r1 {absorb_norm * (ONE - math::exp(absorb_coeff * HEAVISIDE(delta_r1) * -// CUBE(delta_r1)))}; -// // !HACK -// // real_t br_target = pGen.userTargetField_br_cntrv(mblock, {i_, j_ + HALF}); -// real_t br_target = br_func(mblock, {i_, j_ + HALF}); -// // real_t br_target {ZERO}; -// mblock.em0(i, j, em::bx1) = (ONE - sigma_r1) * mblock.em0(i, j, em::bx1) + sigma_r1 -// * br_target; mblock.em(i, j, em::bx1) = (ONE - sigma_r1) * mblock.em(i, j, em::bx1) -// + sigma_r1 * br_target; -// } -// // i + 1/2 -// mblock.metric.x_Code2Sph({i_ + HALF, j_}, rth_); -// if (rth_[0] > r_absorb) { -// real_t delta_r2 {(rth_[0] - r_absorb) / (r_max - r_absorb)}; -// real_t sigma_r2 {absorb_norm * (ONE - math::exp(absorb_coeff * HEAVISIDE(delta_r2) * -// CUBE(delta_r2)))}; -// // !HACK -// // real_t bth_target {pGen->userTargetField_bth_cntrv(mblock, {i_ + HALF, j_})}; -// real_t bth_target {ZERO}; -// mblock.em0(i, j, em::bx2) = (ONE - sigma_r2) * mblock.em0(i, j, em::bx2) + sigma_r2 -// * bth_target; mblock.em(i, j, em::bx2) = (ONE - sigma_r2) * mblock.em(i, j, -// em::bx2) + sigma_r2 * bth_target; mblock.em0(i, j, em::bx3) = (ONE - sigma_r2) * -// mblock.em0(i, j, em::bx3); mblock.em(i, j, em::bx3) = (ONE - sigma_r2) * -// mblock.em(i, j, em::bx3); -// } -// }); diff --git a/legacy/src/nttiny.cpp b/legacy/src/nttiny.cpp deleted file mode 100644 index 6820900f0..000000000 --- a/legacy/src/nttiny.cpp +++ /dev/null @@ -1,124 +0,0 @@ - -#elif defined(GRPIC_ENGINE) - // interpolate and transform to spherical - // !TODO: mirrors for em0, aux etc - ntt::vec_t Dsph {ZERO}, Bsph {ZERO}, D0sph {ZERO}, B0sph {ZERO}; - if ((i >= 0) && (i < sx1) && (j >= 0) && (j < sx2)) { - if (m_fields_to_plot[f].at(0) == 'D') { - if (m_fields_to_plot[f].at(1) == '0') { - real_t Dx1, Dx2, Dx3; - // interpolate to cell center - Dx1 = 0.5 - * (m_sim.meshblock.em0(I, J, ntt::em::ex1) - + m_sim.meshblock.em0(I, J + 1, ntt::em::ex1)); - Dx2 = 0.5 - * (m_sim.meshblock.em0(I, J, ntt::em::ex2) - + m_sim.meshblock.em0(I + 1, J, ntt::em::ex2)); - Dx3 = 0.25 - * (m_sim.meshblock.em0(I, J, ntt::em::ex3) - + m_sim.meshblock.em0(I + 1, J, ntt::em::ex3) - + m_sim.meshblock.em0(I, J + 1, ntt::em::ex3) - + m_sim.meshblock.em0(I + 1, J + 1, ntt::em::ex3)); - m_sim.meshblock.metric.v_Cntr2SphCntrv( - {i_ + HALF, j_ + HALF}, {Dx1, Dx2, Dx3}, D0sph); - } else { - real_t Dx1, Dx2, Dx3; - // interpolate to cell center - Dx1 = 0.5 - * (m_sim.meshblock.em(I, J, ntt::em::ex1) - + m_sim.meshblock.em(I, J + 1, ntt::em::ex1)); - Dx2 = 0.5 - * (m_sim.meshblock.em(I, J, ntt::em::ex2) - + m_sim.meshblock.em(I + 1, J, ntt::em::ex2)); - Dx3 = 0.25 - * (m_sim.meshblock.em(I, J, ntt::em::ex3) - + m_sim.meshblock.em(I + 1, J, ntt::em::ex3) - + m_sim.meshblock.em(I, J + 1, ntt::em::ex3) - + m_sim.meshblock.em(I + 1, J + 1, ntt::em::ex3)); - m_sim.meshblock.metric.v_Cntr2SphCntrv( - {i_ + HALF, j_ + HALF}, {Dx1, Dx2, Dx3}, Dsph); - } - } else if (m_fields_to_plot[f].at(0) == 'B') { - if (m_fields_to_plot[f].at(1) == '0') { - real_t Bx1, Bx2, Bx3; - // interpolate to cell center - Bx1 = 0.5 - * (m_sim.meshblock.em0(I + 1, J, ntt::em::bx1) - + m_sim.meshblock.em0(I, J, ntt::em::bx1)); - Bx2 = 0.5 - * (m_sim.meshblock.em0(I, J + 1, ntt::em::bx2) - + m_sim.meshblock.em0(I, J, ntt::em::bx2)); - Bx3 = m_sim.meshblock.em0(I, J, ntt::em::bx3); - m_sim.meshblock.metric.v_Cntr2SphCntrv( - {i_ + HALF, j_ + HALF}, {Bx1, Bx2, Bx3}, B0sph); - } else { - real_t Bx1, Bx2, Bx3; - // interpolate to cell center - Bx1 = 0.5 - * (m_sim.meshblock.em(I + 1, J, ntt::em::bx1) - + m_sim.meshblock.em(I, J, ntt::em::bx1)); - Bx2 = 0.5 - * (m_sim.meshblock.em(I, J + 1, ntt::em::bx2) - + m_sim.meshblock.em(I, J, ntt::em::bx2)); - Bx3 = m_sim.meshblock.em(I, J, ntt::em::bx3); - m_sim.meshblock.metric.v_Cntr2SphCntrv( - {i_ + HALF, j_ + HALF}, {Bx1, Bx2, Bx3}, Bsph); - } - } - } else { - Dsph[0] = m_sim.meshblock.em(I, J, ntt::em::ex1); - Dsph[1] = m_sim.meshblock.em(I, J, ntt::em::ex2); - Dsph[2] = m_sim.meshblock.em(I, J, ntt::em::ex3); - Bsph[0] = m_sim.meshblock.em(I, J, ntt::em::bx1); - Bsph[1] = m_sim.meshblock.em(I, J, ntt::em::bx2); - Bsph[2] = m_sim.meshblock.em(I, J, ntt::em::bx3); - D0sph[0] = m_sim.meshblock.em0(I, J, ntt::em::ex1); - D0sph[1] = m_sim.meshblock.em0(I, J, ntt::em::ex2); - D0sph[2] = m_sim.meshblock.em0(I, J, ntt::em::ex3); - B0sph[0] = m_sim.meshblock.em0(I, J, ntt::em::bx1); - B0sph[1] = m_sim.meshblock.em0(I, J, ntt::em::bx2); - B0sph[2] = m_sim.meshblock.em0(I, J, ntt::em::bx3); - } - real_t val {ZERO}; - if (m_fields_to_plot[f] == "Dr") { - val = Dsph[0]; - } else if (m_fields_to_plot[f] == "Dtheta") { - val = Dsph[1]; - } else if (m_fields_to_plot[f] == "Dphi") { - val = Dsph[2]; - } else if (m_fields_to_plot[f] == "Br") { - val = Bsph[0]; - } else if (m_fields_to_plot[f] == "Btheta") { - val = Bsph[1]; - } else if (m_fields_to_plot[f] == "Bphi") { - val = Bsph[2]; - } else if (m_fields_to_plot[f] == "Er") { - val = m_sim.meshblock.aux(I, J, ntt::em::ex1); - } else if (m_fields_to_plot[f] == "Etheta") { - val = m_sim.meshblock.aux(I, J, ntt::em::ex2); - } else if (m_fields_to_plot[f] == "Ephi") { - val = m_sim.meshblock.aux(I, J, ntt::em::ex3); - } else if (m_fields_to_plot[f] == "Hr") { - val = m_sim.meshblock.aux(I, J, ntt::em::bx1); - } else if (m_fields_to_plot[f] == "Htheta") { - val = m_sim.meshblock.aux(I, J, ntt::em::bx2); - } else if (m_fields_to_plot[f] == "Hphi") { - val = m_sim.meshblock.aux(I, J, ntt::em::bx3); - } else if (m_fields_to_plot[f] == "D0r") { - val = D0sph[0]; - } else if (m_fields_to_plot[f] == "D0theta") { - val = D0sph[1]; - } else if (m_fields_to_plot[f] == "D0phi") { - val = D0sph[2]; - } else if (m_fields_to_plot[f] == "B0r") { - val = B0sph[0]; - } else if (m_fields_to_plot[f] == "B0theta") { - val = B0sph[1]; - } else if (m_fields_to_plot[f] == "B0phi") { - val = B0sph[2]; - } else if (m_fields_to_plot[f] == "Aphi") { - val = m_sim.meshblock.aphi(I, J, 0); - } - auto idx = Index(i, j); - (this->fields)[m_fields_to_plot[f]][idx] = val; -#endif diff --git a/legacy/src/particle_pusher_sr.hpp b/legacy/src/particle_pusher_sr.hpp deleted file mode 100644 index 637fcbc60..000000000 --- a/legacy/src/particle_pusher_sr.hpp +++ /dev/null @@ -1,966 +0,0 @@ -/** - * @file kernels/particle_pusher_sr.h - * @brief Particle pusher for the SR - * @implements - * - kernel::sr::Pusher_kernel<> - * - kernel::sr::PusherBase_kernel<> - * @depends: - * - enums.h - * - global.h - * - arch/kokkos_aliases.h - * - arch/traits.h - * - utils/error.h - * - utils/numeric.h - * @namespaces: - * - kernel::sr:: - */ - -#ifndef KERNELS_PARTICLE_PUSHER_SR_HPP -#define KERNELS_PARTICLE_PUSHER_SR_HPP - -#include "enums.h" -#include "global.h" - -#include "arch/kokkos_aliases.h" -#include "arch/traits.h" -#include "utils/error.h" -#include "utils/numeric.h" - -#include -#include - -/* -------------------------------------------------------------------------- */ -/* Local macros */ -/* -------------------------------------------------------------------------- */ -#define from_Xi_to_i(XI, I) \ - { I = static_cast((XI)); } - -#define from_Xi_to_i_di(XI, I, DI) \ - { \ - from_Xi_to_i((XI), (I)); \ - DI = static_cast((XI)) - static_cast(I); \ - } - -#define i_di_to_Xi(I, DI) static_cast((I)) + static_cast((DI)) - -/* -------------------------------------------------------------------------- */ - -namespace kernel::sr { - using namespace ntt; - - // Pushers - struct Boris_t {}; - - struct Vay_t {}; - - struct Photon_t {}; - - struct Extforce_t {}; - - struct GCA_t {}; - - // Cooling - struct NoCooling_t {}; - - struct Synchrotron_t {}; - - template - struct Union_t {}; - - template - struct is_contained; - - template - struct is_contained : is_contained {}; - - template - struct is_contained : std::true_type {}; - - template - struct is_contained : std::false_type {}; - - struct Massive_t {}; - - struct Massless_t {}; - - /** - * @tparam M Metric - * @tparam PG Problem generator - * @tparam P Particle pusher - * @tparam Cs Cooling algorithms - */ - template - struct Pusher_kernel { - static_assert(M::is_metric, "M must be a metric class"); - // static_assert(PG::is_pgen, "PG must be a problem generator class"); - static constexpr auto D = M::Dim; - // using base_t::defines_fx1; - // using base_t::defines_fx2; - // using base_t::defines_fx3; - - private: - const ndfield_t EB; - const unsigned short sp; - array_t i1, i2, i3; - array_t i1_prev, i2_prev, i3_prev; - array_t dx1, dx2, dx3; - array_t dx1_prev, dx2_prev, dx3_prev; - array_t ux1, ux2, ux3; - array_t phi; - array_t tag; - const M metric; - // const PG pgen; - - const real_t time, coeff, dt; - const int ni1, ni2, ni3; - bool is_absorb_i1min { false }, is_absorb_i1max { false }; - bool is_absorb_i2min { false }, is_absorb_i2max { false }; - bool is_absorb_i3min { false }, is_absorb_i3max { false }; - bool is_periodic_i1min { false }, is_periodic_i1max { false }; - bool is_periodic_i2min { false }, is_periodic_i2max { false }; - bool is_periodic_i3min { false }, is_periodic_i3max { false }; - bool is_axis_i2min { false }, is_axis_i2max { false }; - // gca parameters - const real_t gca_larmor, gca_EovrB_sqr; - // synchrotron cooling parameters - const real_t coeff_sync; - - public: - Pusher_kernel(const ndfield_t& EB, - unsigned short sp, - array_t& i1, - array_t& i2, - array_t& i3, - array_t& i1_prev, - array_t& i2_prev, - array_t& i3_prev, - array_t& dx1, - array_t& dx2, - array_t& dx3, - array_t& dx1_prev, - array_t& dx2_prev, - array_t& dx3_prev, - array_t& ux1, - array_t& ux2, - array_t& ux3, - array_t& phi, - array_t& tag, - const M& metric, - // const PG& pgen, - real_t time, - real_t coeff, - real_t dt, - int ni1, - int ni2, - int ni3, - const boundaries_t& boundaries, - real_t gca_larmor_max, - real_t gca_eovrb_max, - real_t coeff_sync) : - EB { EB }, - sp { sp }, - i1 { i1 }, - i2 { i2 }, - i3 { i3 }, - i1_prev { i1_prev }, - i2_prev { i2_prev }, - i3_prev { i3_prev }, - dx1 { dx1 }, - dx2 { dx2 }, - dx3 { dx3 }, - dx1_prev { dx1_prev }, - dx2_prev { dx2_prev }, - dx3_prev { dx3_prev }, - ux1 { ux1 }, - ux2 { ux2 }, - ux3 { ux3 }, - phi { phi }, - tag { tag }, - metric { metric }, - // pgen { pgen }, - time { time }, - coeff { coeff }, - dt { dt }, - ni1 { ni1 }, - ni2 { ni2 }, - ni3 { ni3 }, - gca_larmor { gca_larmor_max }, - gca_EovrB_sqr { SQR(gca_eovrb_max) }, - coeff_sync { coeff_sync } { - - raise::ErrorIf(boundaries.size() < 1, "boundaries defined incorrectly", HERE); - is_absorb_i1min = (boundaries[0].first == PrtlBC::ATMOSPHERE) || - (boundaries[0].first == PrtlBC::ABSORB); - is_absorb_i1max = (boundaries[0].second == PrtlBC::ATMOSPHERE) || - (boundaries[0].second == PrtlBC::ABSORB); - is_periodic_i1min = (boundaries[0].first == PrtlBC::PERIODIC); - is_periodic_i1max = (boundaries[0].second == PrtlBC::PERIODIC); - if constexpr ((D == Dim::_2D) || (D == Dim::_3D)) { - raise::ErrorIf(boundaries.size() < 2, "boundaries defined incorrectly", HERE); - is_absorb_i2min = (boundaries[1].first == PrtlBC::ATMOSPHERE) || - (boundaries[1].first == PrtlBC::ABSORB); - is_absorb_i2max = (boundaries[1].second == PrtlBC::ATMOSPHERE) || - (boundaries[1].second == PrtlBC::ABSORB); - is_periodic_i2min = (boundaries[1].first == PrtlBC::PERIODIC); - is_periodic_i2max = (boundaries[1].second == PrtlBC::PERIODIC); - is_axis_i2min = (boundaries[1].first == PrtlBC::AXIS); - is_axis_i2max = (boundaries[1].second == PrtlBC::AXIS); - } - if constexpr (D == Dim::_3D) { - raise::ErrorIf(boundaries.size() < 3, "boundaries defined incorrectly", HERE); - is_absorb_i3min = (boundaries[2].first == PrtlBC::ATMOSPHERE) || - (boundaries[2].first == PrtlBC::ABSORB); - is_absorb_i3max = (boundaries[2].second == PrtlBC::ATMOSPHERE) || - (boundaries[2].second == PrtlBC::ABSORB); - is_periodic_i3min = (boundaries[2].first == PrtlBC::PERIODIC); - is_periodic_i3max = (boundaries[2].second == PrtlBC::PERIODIC); - } - } - - Inline void synchrotronDrag(index_t& p, - vec_t& u_prime, - const vec_t& e0, - const vec_t& b0) const { - real_t gamma_prime_sqr = ONE / math::sqrt(ONE + NORM_SQR(u_prime[0], - u_prime[1], - u_prime[2])); - u_prime[0] *= gamma_prime_sqr; - u_prime[1] *= gamma_prime_sqr; - u_prime[2] *= gamma_prime_sqr; - gamma_prime_sqr = SQR(ONE / gamma_prime_sqr); - const real_t beta_dot_e { - DOT(u_prime[0], u_prime[1], u_prime[2], e0[0], e0[1], e0[2]) - }; - vec_t e_plus_beta_cross_b { - e0[0] + CROSS_x1(u_prime[0], u_prime[1], u_prime[2], b0[0], b0[1], b0[2]), - e0[1] + CROSS_x2(u_prime[0], u_prime[1], u_prime[2], b0[0], b0[1], b0[2]), - e0[2] + CROSS_x3(u_prime[0], u_prime[1], u_prime[2], b0[0], b0[1], b0[2]) - }; - vec_t kappaR { - CROSS_x1(e_plus_beta_cross_b[0], - e_plus_beta_cross_b[1], - e_plus_beta_cross_b[2], - b0[0], - b0[1], - b0[2]) + - beta_dot_e * e0[0], - CROSS_x2(e_plus_beta_cross_b[0], - e_plus_beta_cross_b[1], - e_plus_beta_cross_b[2], - b0[0], - b0[1], - b0[2]) + - beta_dot_e * e0[1], - CROSS_x3(e_plus_beta_cross_b[0], - e_plus_beta_cross_b[1], - e_plus_beta_cross_b[2], - b0[0], - b0[1], - b0[2]) + - beta_dot_e * e0[2], - }; - const real_t chiR_sqr { NORM_SQR(e_plus_beta_cross_b[0], - e_plus_beta_cross_b[1], - e_plus_beta_cross_b[2]) - - SQR(beta_dot_e) }; - ux1(p) += coeff_sync * (kappaR[0] - gamma_prime_sqr * u_prime[0] * chiR_sqr); - ux2(p) += coeff_sync * (kappaR[1] - gamma_prime_sqr * u_prime[1] * chiR_sqr); - ux3(p) += coeff_sync * (kappaR[2] - gamma_prime_sqr * u_prime[2] * chiR_sqr); - } - - /* photon --------------------------------------------------------------- */ - Inline void operator()(Photon_t, index_t p) const { - if (tag(p) != ParticleTag::alive) { - return; - } - coord_t xp_Cd { ZERO }; - getPrtlPos(p, xp_Cd); - posUpd(p, xp_Cd); - } - - // /* Vay/Boris, no gca, no ext force, no cooling -------------------------- */ - // template - // Inline void operator()(P, index_t p) const { - // if (tag(p) != ParticleTag::alive) { - // return; - // } - // coord_t xp_Cd { ZERO }; - // getPrtlPos(p, xp_Cd); - // vec_t ei { ZERO }, bi { ZERO }; - // vec_t ei_Cart { ZERO }, bi_Cart { ZERO }; - - // getInterpFlds(p, ei, bi); - // metric.template transform_xyz(xp_Cd, ei, ei_Cart); - // metric.template transform_xyz(xp_Cd, bi, bi_Cart); - // velUpd(P {}, p, ei_Cart, bi_Cart); - // posUpd(p, xp_Cd); - // } - - /* general case --------------------------------------------------------- */ - template - Inline void operator()(Union_t, index_t p) const { - if (tag(p) != ParticleTag::alive) { - return; - } - coord_t xp_Cd { ZERO }; - getPrtlPos(p, xp_Cd); - // update cartesian velocity - vec_t ei { ZERO }, bi { ZERO }; - vec_t ei_Cart { ZERO }, bi_Cart { ZERO }; - vec_t force_Cart { ZERO }; - vec_t u_prime { ZERO }; - vec_t ei_Cart_rad { ZERO }, bi_Cart_rad { ZERO }; - bool is_gca { false }; - - getInterpFlds(p, ei, bi); - metric.template transform_xyz(xp_Cd, ei, ei_Cart); - metric.template transform_xyz(xp_Cd, bi, bi_Cart); - if constexpr (is_contained>::value) { - // backup fields & velocities to use later in cooling - ei_Cart_rad[0] = ei_Cart[0]; - ei_Cart_rad[1] = ei_Cart[1]; - ei_Cart_rad[2] = ei_Cart[2]; - bi_Cart_rad[0] = bi_Cart[0]; - bi_Cart_rad[1] = bi_Cart[1]; - bi_Cart_rad[2] = bi_Cart[2]; - u_prime[0] = ux1(p); - u_prime[1] = ux2(p); - u_prime[2] = ux3(p); - } - if constexpr (is_contained>::value) { - // coord_t xp_Ph { ZERO }; - // xp_Ph[0] = metric.template convert<1, Crd::Cd, Crd::Ph>(xp_Cd[0]); - // if constexpr (M::PrtlDim != Dim::_1D) { - // xp_Ph[1] = metric.template convert<2, Crd::Cd, Crd::Ph>(xp_Cd[1]); - // } - // if constexpr (M::PrtlDim == Dim::_3D) { - // xp_Ph[2] = metric.template convert<3, Crd::Cd, Crd::Ph>(xp_Cd[2]); - // } - // real_t fx1 { ZERO }, fx2 { ZERO }, fx3 { ZERO }; - // metric.template transform_xyz( - // xp_Cd, - // { pgen.ext_force.fx1(sp, time, xp_Ph), - // pgen.ext_force.fx2(sp, time, xp_Ph), - // pgen.ext_force.fx3(sp, time, xp_Ph) }, - // force_Cart); - } - if constexpr (is_contained>::value) { - /* hybrid GCA/conventional mode --------------------------------- */ - const auto E2 { NORM_SQR(ei_Cart[0], ei_Cart[1], ei_Cart[2]) }; - const auto B2 { NORM_SQR(bi_Cart[0], bi_Cart[1], bi_Cart[2]) }; - const auto rL { math::sqrt(ONE + NORM_SQR(ux1(p), ux2(p), ux3(p))) * - dt / (TWO * math::abs(coeff) * math::sqrt(B2)) }; - if (B2 > ZERO && rL < gca_larmor && (E2 / B2) < gca_EovrB_sqr) { - is_gca = true; - // update with GCA - if constexpr (is_contained>::value) { - velUpd(Union_t {}, p, force_Cart, ei_Cart, bi_Cart); - } else { - velUpd(GCA_t {}, p, ei_Cart, bi_Cart); - } - } else { - // update with conventional pusher - if constexpr (is_contained>::value) { - ux1(p) += HALF * dt * force_Cart[0]; - ux2(p) += HALF * dt * force_Cart[1]; - ux3(p) += HALF * dt * force_Cart[2]; - } - velUpd(P {}, p, ei_Cart, bi_Cart); - if constexpr (is_contained>::value) { - ux1(p) += HALF * dt * force_Cart[0]; - ux2(p) += HALF * dt * force_Cart[1]; - ux3(p) += HALF * dt * force_Cart[2]; - } - } - } else { - /* conventional pusher mode ------------------------------------- */ - // update with conventional pusher - if constexpr (is_contained>::value) { - ux1(p) += HALF * dt * force_Cart[0]; - ux2(p) += HALF * dt * force_Cart[1]; - ux3(p) += HALF * dt * force_Cart[2]; - } - velUpd(P {}, p, ei_Cart, bi_Cart); - if constexpr (is_contained>::value) { - ux1(p) += HALF * dt * force_Cart[0]; - ux2(p) += HALF * dt * force_Cart[1]; - ux3(p) += HALF * dt * force_Cart[2]; - } - } - // cooling - if constexpr (is_contained>::value) { - if (!is_gca) { - u_prime[0] = HALF * (u_prime[0] + ux1(p)); - u_prime[1] = HALF * (u_prime[1] + ux2(p)); - u_prime[2] = HALF * (u_prime[2] + ux3(p)); - synchrotronDrag(p, u_prime, ei_Cart_rad, bi_Cart_rad); - } - } - // update position - posUpd(p, xp_Cd); - } - - template - Inline void posUpd(index_t& p, coord_t& xp) const { - - // get cartesian velocity - const real_t inv_energy { ONE / getEnergy(T {}, p) }; - vec_t vp_Cart { ux1(p) * inv_energy, - ux2(p) * inv_energy, - ux3(p) * inv_energy }; - // get cartesian position - coord_t xp_Cart { ZERO }; - metric.template convert_xyz(xp, xp_Cart); - // update cartesian position - for (auto d = 0u; d < M::PrtlDim; ++d) { - xp_Cart[d] += vp_Cart[d] * dt; - } - // transform back to code - metric.template convert_xyz(xp_Cart, xp); - - // update x1 - if constexpr (D == Dim::_1D || D == Dim::_2D || D == Dim::_3D) { - i1_prev(p) = i1(p); - dx1_prev(p) = dx1(p); - from_Xi_to_i_di(xp[0], i1(p), dx1(p)); - } - - // update x2 & phi - if constexpr (D == Dim::_2D || D == Dim::_3D) { - i2_prev(p) = i2(p); - dx2_prev(p) = dx2(p); - from_Xi_to_i_di(xp[1], i2(p), dx2(p)); - if constexpr (D == Dim::_2D && M::PrtlDim == Dim::_3D) { - phi(p) = xp[2]; - } - } - - // update x3 - if constexpr (D == Dim::_3D) { - i3_prev(p) = i3(p); - dx3_prev(p) = dx3(p); - from_Xi_to_i_di(xp[2], i3(p), dx3(p)); - } - boundaryConditions(p); - } - - /** - * @brief update particle velocities - * @param P pusher algorithm - * @param p, e0, b0 index & interpolated fields - */ - Inline void velUpd(Boris_t, - index_t& p, - vec_t& e0, - vec_t& b0) const { - - real_t COEFF { coeff }; - - e0[0] *= COEFF; - e0[1] *= COEFF; - e0[2] *= COEFF; - vec_t u0 { ux1(p) + e0[0], ux2(p) + e0[1], ux3(p) + e0[2] }; - - COEFF *= ONE / math::sqrt(ONE + NORM_SQR(u0[0], u0[1], u0[2])); - b0[0] *= COEFF; - b0[1] *= COEFF; - b0[2] *= COEFF; - COEFF = TWO / (ONE + NORM_SQR(b0[0], b0[1], b0[2])); - - vec_t u1 { - (u0[0] + CROSS_x1(u0[0], u0[1], u0[2], b0[0], b0[1], b0[2])) * COEFF, - (u0[1] + CROSS_x2(u0[0], u0[1], u0[2], b0[0], b0[1], b0[2])) * COEFF, - (u0[2] + CROSS_x3(u0[0], u0[1], u0[2], b0[0], b0[1], b0[2])) * COEFF - }; - - u0[0] += CROSS_x1(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]) + e0[0]; - u0[1] += CROSS_x2(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]) + e0[1]; - u0[2] += CROSS_x3(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]) + e0[2]; - - ux1(p) = u0[0]; - ux2(p) = u0[1]; - ux3(p) = u0[2]; - } - - Inline void velUpd(Vay_t, index_t& p, vec_t& e0, vec_t& b0) const { - auto COEFF { coeff }; - e0[0] *= COEFF; - e0[1] *= COEFF; - e0[2] *= COEFF; - - b0[0] *= COEFF; - b0[1] *= COEFF; - b0[2] *= COEFF; - - COEFF = ONE / math::sqrt(ONE + NORM_SQR(ux1(p), ux2(p), ux3(p))); - - vec_t u1 { - (ux1(p) + TWO * e0[0] + - CROSS_x1(ux1(p), ux2(p), ux3(p), b0[0], b0[1], b0[2]) * COEFF), - (ux2(p) + TWO * e0[1] + - CROSS_x2(ux1(p), ux2(p), ux3(p), b0[0], b0[1], b0[2]) * COEFF), - (ux3(p) + TWO * e0[2] + - CROSS_x3(ux1(p), ux2(p), ux3(p), b0[0], b0[1], b0[2]) * COEFF) - }; - COEFF = DOT(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]); - auto COEFF2 { ONE + NORM_SQR(u1[0], u1[1], u1[2]) - - NORM_SQR(b0[0], b0[1], b0[2]) }; - - COEFF = ONE / - math::sqrt( - INV_2 * (COEFF2 + math::sqrt(SQR(COEFF2) + - FOUR * (SQR(b0[0]) + SQR(b0[1]) + - SQR(b0[2]) + SQR(COEFF))))); - COEFF2 = ONE / (ONE + SQR(b0[0] * COEFF) + SQR(b0[1] * COEFF) + - SQR(b0[2] * COEFF)); - - ux1(p) = COEFF2 * (u1[0] + - COEFF * DOT(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]) * - (b0[0] * COEFF) + - u1[1] * b0[2] * COEFF - u1[2] * b0[1] * COEFF); - ux2(p) = COEFF2 * (u1[1] + - COEFF * DOT(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]) * - (b0[1] * COEFF) + - u1[2] * b0[0] * COEFF - u1[0] * b0[2] * COEFF); - ux3(p) = COEFF2 * (u1[2] + - COEFF * DOT(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]) * - (b0[2] * COEFF) + - u1[0] * b0[1] * COEFF - u1[1] * b0[0] * COEFF); - } - - Inline void velUpd(GCA_t, index_t& p, vec_t& e0, vec_t& b0) const { - const auto eb_sqr { NORM_SQR(e0[0], e0[1], e0[2]) + - NORM_SQR(b0[0], b0[1], b0[2]) }; - - const vec_t wE { - CROSS_x1(e0[0], e0[1], e0[2], b0[0], b0[1], b0[2]) / eb_sqr, - CROSS_x2(e0[0], e0[1], e0[2], b0[0], b0[1], b0[2]) / eb_sqr, - CROSS_x3(e0[0], e0[1], e0[2], b0[0], b0[1], b0[2]) / eb_sqr - }; - - { - const auto b_norm_inv { ONE / NORM(b0[0], b0[1], b0[2]) }; - b0[0] *= b_norm_inv; - b0[1] *= b_norm_inv; - b0[2] *= b_norm_inv; - } - auto upar { DOT(ux1(p), ux2(p), ux3(p), b0[0], b0[1], b0[2]) + - coeff * TWO * DOT(e0[0], e0[1], e0[2], b0[0], b0[1], b0[2]) }; - - real_t factor; - { - const auto wE_sqr { NORM_SQR(wE[0], wE[1], wE[2]) }; - if (wE_sqr < static_cast(0.01)) { - factor = ONE + wE_sqr + TWO * SQR(wE_sqr) + FIVE * SQR(wE_sqr) * wE_sqr; - } else { - factor = (ONE - math::sqrt(ONE - FOUR * wE_sqr)) / (TWO * wE_sqr); - } - } - const vec_t vE_Cart { wE[0] * factor, wE[1] * factor, wE[2] * factor }; - const auto Gamma { math::sqrt(ONE + SQR(upar)) / - math::sqrt( - ONE - NORM_SQR(vE_Cart[0], vE_Cart[1], vE_Cart[2])) }; - ux1(p) = upar * b0[0] + vE_Cart[0] * Gamma; - ux2(p) = upar * b0[1] + vE_Cart[1] * Gamma; - ux3(p) = upar * b0[2] + vE_Cart[2] * Gamma; - } - - Inline void velUpd(Union_t, - index_t& p, - vec_t& f0, - vec_t& e0, - vec_t& b0) const { - const auto eb_sqr { NORM_SQR(e0[0], e0[1], e0[2]) + - NORM_SQR(b0[0], b0[1], b0[2]) }; - - const vec_t wE { - CROSS_x1(e0[0], e0[1], e0[2], b0[0], b0[1], b0[2]) / eb_sqr, - CROSS_x2(e0[0], e0[1], e0[2], b0[0], b0[1], b0[2]) / eb_sqr, - CROSS_x3(e0[0], e0[1], e0[2], b0[0], b0[1], b0[2]) / eb_sqr - }; - - { - const auto b_norm_inv { ONE / NORM(b0[0], b0[1], b0[2]) }; - b0[0] *= b_norm_inv; - b0[1] *= b_norm_inv; - b0[2] *= b_norm_inv; - } - auto upar { DOT(ux1(p), ux2(p), ux3(p), b0[0], b0[1], b0[2]) + - coeff * TWO * DOT(e0[0], e0[1], e0[2], b0[0], b0[1], b0[2]) + - dt * DOT(f0[0], f0[1], f0[2], b0[0], b0[1], b0[2]) }; - - real_t factor; - { - const auto wE_sqr { NORM_SQR(wE[0], wE[1], wE[2]) }; - if (wE_sqr < static_cast(0.01)) { - factor = ONE + wE_sqr + TWO * SQR(wE_sqr) + FIVE * SQR(wE_sqr) * wE_sqr; - } else { - factor = (ONE - math::sqrt(ONE - FOUR * wE_sqr)) / (TWO * wE_sqr); - } - } - const vec_t vE_Cart { wE[0] * factor, wE[1] * factor, wE[2] * factor }; - const auto Gamma { math::sqrt(ONE + SQR(upar)) / - math::sqrt( - ONE - NORM_SQR(vE_Cart[0], vE_Cart[1], vE_Cart[2])) }; - ux1(p) = upar * b0[0] + vE_Cart[0] * Gamma; - ux2(p) = upar * b0[1] + vE_Cart[1] * Gamma; - ux3(p) = upar * b0[2] + vE_Cart[2] * Gamma; - } - - // Getters - Inline void getPrtlPos(index_t& p, coord_t& xp) const { - if constexpr (D == Dim::_1D || D == Dim::_2D || D == Dim::_3D) { - xp[0] = i_di_to_Xi(i1(p), dx1(p)); - } - if constexpr (D == Dim::_2D) { - xp[1] = i_di_to_Xi(i2(p), dx2(p)); - if constexpr (M::PrtlDim == Dim::_3D) { - xp[2] = phi(p); - } - } - if constexpr (D == Dim::_3D) { - xp[1] = i_di_to_Xi(i2(p), dx2(p)); - xp[2] = i_di_to_Xi(i3(p), dx3(p)); - } - } - - Inline auto getEnergy(Massive_t, index_t& p) const -> real_t { - return math::sqrt(ONE + SQR(ux1(p)) + SQR(ux2(p)) + SQR(ux3(p))); - } - - Inline auto getEnergy(Massless_t, index_t& p) const -> real_t { - return math::sqrt(SQR(ux1(p)) + SQR(ux2(p)) + SQR(ux3(p))); - } - - Inline void getInterpFlds(index_t& p, - vec_t& e0, - vec_t& b0) const { - if constexpr (D == Dim::_1D) { - const int i { i1(p) + static_cast(N_GHOSTS) }; - const auto dx1_ { static_cast(dx1(p)) }; - - // first order - real_t c0, c1; - - // Ex1 - // interpolate to nodes - c0 = HALF * (EB(i, em::ex1) + EB(i - 1, em::ex1)); - c1 = HALF * (EB(i, em::ex1) + EB(i + 1, em::ex1)); - // interpolate from nodes to the particle position - e0[0] = c0 * (ONE - dx1_) + c1 * dx1_; - // Ex2 - c0 = EB(i, em::ex2); - c1 = EB(i + 1, em::ex2); - e0[1] = c0 * (ONE - dx1_) + c1 * dx1_; - // Ex3 - c0 = EB(i, em::ex3); - c1 = EB(i + 1, em::ex3); - e0[2] = c0 * (ONE - dx1_) + c1 * dx1_; - - // Bx1 - c0 = EB(i, em::bx1); - c1 = EB(i + 1, em::bx1); - b0[0] = c0 * (ONE - dx1_) + c1 * dx1_; - // Bx2 - c0 = HALF * (EB(i - 1, em::bx2) + EB(i, em::bx2)); - c1 = HALF * (EB(i, em::bx2) + EB(i + 1, em::bx2)); - b0[1] = c0 * (ONE - dx1_) + c1 * dx1_; - // Bx3 - c0 = HALF * (EB(i - 1, em::bx3) + EB(i, em::bx3)); - c1 = HALF * (EB(i, em::bx3) + EB(i + 1, em::bx3)); - b0[2] = c0 * (ONE - dx1_) + c1 * dx1_; - } else if constexpr (D == Dim::_2D) { - const int i { i1(p) + static_cast(N_GHOSTS) }; - const int j { i2(p) + static_cast(N_GHOSTS) }; - const auto dx1_ { static_cast(dx1(p)) }; - const auto dx2_ { static_cast(dx2(p)) }; - - // first order - real_t c000, c100, c010, c110, c00, c10; - - // Ex1 - // interpolate to nodes - c000 = HALF * (EB(i, j, em::ex1) + EB(i - 1, j, em::ex1)); - c100 = HALF * (EB(i, j, em::ex1) + EB(i + 1, j, em::ex1)); - c010 = HALF * (EB(i, j + 1, em::ex1) + EB(i - 1, j + 1, em::ex1)); - c110 = HALF * (EB(i, j + 1, em::ex1) + EB(i + 1, j + 1, em::ex1)); - // interpolate from nodes to the particle position - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - e0[0] = c00 * (ONE - dx2_) + c10 * dx2_; - // Ex2 - c000 = HALF * (EB(i, j, em::ex2) + EB(i, j - 1, em::ex2)); - c100 = HALF * (EB(i + 1, j, em::ex2) + EB(i + 1, j - 1, em::ex2)); - c010 = HALF * (EB(i, j, em::ex2) + EB(i, j + 1, em::ex2)); - c110 = HALF * (EB(i + 1, j, em::ex2) + EB(i + 1, j + 1, em::ex2)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - e0[1] = c00 * (ONE - dx2_) + c10 * dx2_; - // Ex3 - c000 = EB(i, j, em::ex3); - c100 = EB(i + 1, j, em::ex3); - c010 = EB(i, j + 1, em::ex3); - c110 = EB(i + 1, j + 1, em::ex3); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - e0[2] = c00 * (ONE - dx2_) + c10 * dx2_; - - // Bx1 - c000 = HALF * (EB(i, j, em::bx1) + EB(i, j - 1, em::bx1)); - c100 = HALF * (EB(i + 1, j, em::bx1) + EB(i + 1, j - 1, em::bx1)); - c010 = HALF * (EB(i, j, em::bx1) + EB(i, j + 1, em::bx1)); - c110 = HALF * (EB(i + 1, j, em::bx1) + EB(i + 1, j + 1, em::bx1)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - b0[0] = c00 * (ONE - dx2_) + c10 * dx2_; - // Bx2 - c000 = HALF * (EB(i - 1, j, em::bx2) + EB(i, j, em::bx2)); - c100 = HALF * (EB(i, j, em::bx2) + EB(i + 1, j, em::bx2)); - c010 = HALF * (EB(i - 1, j + 1, em::bx2) + EB(i, j + 1, em::bx2)); - c110 = HALF * (EB(i, j + 1, em::bx2) + EB(i + 1, j + 1, em::bx2)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - b0[1] = c00 * (ONE - dx2_) + c10 * dx2_; - // Bx3 - c000 = INV_4 * (EB(i - 1, j - 1, em::bx3) + EB(i - 1, j, em::bx3) + - EB(i, j - 1, em::bx3) + EB(i, j, em::bx3)); - c100 = INV_4 * (EB(i, j - 1, em::bx3) + EB(i, j, em::bx3) + - EB(i + 1, j - 1, em::bx3) + EB(i + 1, j, em::bx3)); - c010 = INV_4 * (EB(i - 1, j, em::bx3) + EB(i - 1, j + 1, em::bx3) + - EB(i, j, em::bx3) + EB(i, j + 1, em::bx3)); - c110 = INV_4 * (EB(i, j, em::bx3) + EB(i, j + 1, em::bx3) + - EB(i + 1, j, em::bx3) + EB(i + 1, j + 1, em::bx3)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - b0[2] = c00 * (ONE - dx2_) + c10 * dx2_; - } else if constexpr (D == Dim::_3D) { - const int i { i1(p) + static_cast(N_GHOSTS) }; - const int j { i2(p) + static_cast(N_GHOSTS) }; - const int k { i3(p) + static_cast(N_GHOSTS) }; - const auto dx1_ { static_cast(dx1(p)) }; - const auto dx2_ { static_cast(dx2(p)) }; - const auto dx3_ { static_cast(dx3(p)) }; - - // first order - real_t c000, c100, c010, c110, c001, c101, c011, c111, c00, c10, c01, - c11, c0, c1; - - // Ex1 - // interpolate to nodes - c000 = HALF * (EB(i, j, k, em::ex1) + EB(i - 1, j, k, em::ex1)); - c100 = HALF * (EB(i, j, k, em::ex1) + EB(i + 1, j, k, em::ex1)); - c010 = HALF * (EB(i, j + 1, k, em::ex1) + EB(i - 1, j + 1, k, em::ex1)); - c110 = HALF * (EB(i, j + 1, k, em::ex1) + EB(i + 1, j + 1, k, em::ex1)); - // interpolate from nodes to the particle position - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - c0 = c00 * (ONE - dx2_) + c10 * dx2_; - // interpolate to nodes - c001 = HALF * (EB(i, j, k + 1, em::ex1) + EB(i - 1, j, k + 1, em::ex1)); - c101 = HALF * (EB(i, j, k + 1, em::ex1) + EB(i + 1, j, k + 1, em::ex1)); - c011 = HALF * - (EB(i, j + 1, k + 1, em::ex1) + EB(i - 1, j + 1, k + 1, em::ex1)); - c111 = HALF * - (EB(i, j + 1, k + 1, em::ex1) + EB(i + 1, j + 1, k + 1, em::ex1)); - // interpolate from nodes to the particle position - c01 = c001 * (ONE - dx1_) + c101 * dx1_; - c11 = c011 * (ONE - dx1_) + c111 * dx1_; - c1 = c01 * (ONE - dx2_) + c11 * dx2_; - e0[0] = c0 * (ONE - dx3_) + c1 * dx3_; - - // Ex2 - c000 = HALF * (EB(i, j, k, em::ex2) + EB(i, j - 1, k, em::ex2)); - c100 = HALF * (EB(i + 1, j, k, em::ex2) + EB(i + 1, j - 1, k, em::ex2)); - c010 = HALF * (EB(i, j, k, em::ex2) + EB(i, j + 1, k, em::ex2)); - c110 = HALF * (EB(i + 1, j, k, em::ex2) + EB(i + 1, j + 1, k, em::ex2)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - c0 = c00 * (ONE - dx2_) + c10 * dx2_; - c001 = HALF * (EB(i, j, k + 1, em::ex2) + EB(i, j - 1, k + 1, em::ex2)); - c101 = HALF * - (EB(i + 1, j, k + 1, em::ex2) + EB(i + 1, j - 1, k + 1, em::ex2)); - c011 = HALF * (EB(i, j, k + 1, em::ex2) + EB(i, j + 1, k + 1, em::ex2)); - c111 = HALF * - (EB(i + 1, j, k + 1, em::ex2) + EB(i + 1, j + 1, k + 1, em::ex2)); - c01 = c001 * (ONE - dx1_) + c101 * dx1_; - c11 = c011 * (ONE - dx1_) + c111 * dx1_; - c1 = c01 * (ONE - dx2_) + c11 * dx2_; - e0[1] = c0 * (ONE - dx3_) + c1 * dx3_; - - // Ex3 - c000 = HALF * (EB(i, j, k, em::ex3) + EB(i, j, k - 1, em::ex3)); - c100 = HALF * (EB(i + 1, j, k, em::ex3) + EB(i + 1, j, k - 1, em::ex3)); - c010 = HALF * (EB(i, j + 1, k, em::ex3) + EB(i, j + 1, k - 1, em::ex3)); - c110 = HALF * - (EB(i + 1, j + 1, k, em::ex3) + EB(i + 1, j + 1, k - 1, em::ex3)); - c001 = HALF * (EB(i, j, k, em::ex3) + EB(i, j, k + 1, em::ex3)); - c101 = HALF * (EB(i + 1, j, k, em::ex3) + EB(i + 1, j, k + 1, em::ex3)); - c011 = HALF * (EB(i, j + 1, k, em::ex3) + EB(i, j + 1, k + 1, em::ex3)); - c111 = HALF * - (EB(i + 1, j + 1, k, em::ex3) + EB(i + 1, j + 1, k + 1, em::ex3)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c01 = c001 * (ONE - dx1_) + c101 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - c11 = c011 * (ONE - dx1_) + c111 * dx1_; - c0 = c00 * (ONE - dx2_) + c10 * dx2_; - c1 = c01 * (ONE - dx2_) + c11 * dx2_; - e0[2] = c0 * (ONE - dx3_) + c1 * dx3_; - - // Bx1 - c000 = INV_4 * (EB(i, j, k, em::bx1) + EB(i, j - 1, k, em::bx1) + - EB(i, j, k - 1, em::bx1) + EB(i, j - 1, k - 1, em::bx1)); - c100 = INV_4 * - (EB(i + 1, j, k, em::bx1) + EB(i + 1, j - 1, k, em::bx1) + - EB(i + 1, j, k - 1, em::bx1) + EB(i + 1, j - 1, k - 1, em::bx1)); - c001 = INV_4 * (EB(i, j, k, em::bx1) + EB(i, j, k + 1, em::bx1) + - EB(i, j - 1, k, em::bx1) + EB(i, j - 1, k + 1, em::bx1)); - c101 = INV_4 * - (EB(i + 1, j, k, em::bx1) + EB(i + 1, j, k + 1, em::bx1) + - EB(i + 1, j - 1, k, em::bx1) + EB(i + 1, j - 1, k + 1, em::bx1)); - c010 = INV_4 * (EB(i, j, k, em::bx1) + EB(i, j + 1, k, em::bx1) + - EB(i, j, k - 1, em::bx1) + EB(i, j + 1, k - 1, em::bx1)); - c110 = INV_4 * - (EB(i + 1, j, k, em::bx1) + EB(i + 1, j, k - 1, em::bx1) + - EB(i + 1, j + 1, k - 1, em::bx1) + EB(i + 1, j + 1, k, em::bx1)); - c011 = INV_4 * (EB(i, j, k, em::bx1) + EB(i, j + 1, k, em::bx1) + - EB(i, j + 1, k + 1, em::bx1) + EB(i, j, k + 1, em::bx1)); - c111 = INV_4 * - (EB(i + 1, j, k, em::bx1) + EB(i + 1, j + 1, k, em::bx1) + - EB(i + 1, j + 1, k + 1, em::bx1) + EB(i + 1, j, k + 1, em::bx1)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c01 = c001 * (ONE - dx1_) + c101 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - c11 = c011 * (ONE - dx1_) + c111 * dx1_; - c0 = c00 * (ONE - dx2_) + c10 * dx2_; - c1 = c01 * (ONE - dx2_) + c11 * dx2_; - b0[0] = c0 * (ONE - dx3_) + c1 * dx3_; - - // Bx2 - c000 = INV_4 * (EB(i - 1, j, k - 1, em::bx2) + EB(i - 1, j, k, em::bx2) + - EB(i, j, k - 1, em::bx2) + EB(i, j, k, em::bx2)); - c100 = INV_4 * (EB(i, j, k - 1, em::bx2) + EB(i, j, k, em::bx2) + - EB(i + 1, j, k - 1, em::bx2) + EB(i + 1, j, k, em::bx2)); - c001 = INV_4 * (EB(i - 1, j, k, em::bx2) + EB(i - 1, j, k + 1, em::bx2) + - EB(i, j, k, em::bx2) + EB(i, j, k + 1, em::bx2)); - c101 = INV_4 * (EB(i, j, k, em::bx2) + EB(i, j, k + 1, em::bx2) + - EB(i + 1, j, k, em::bx2) + EB(i + 1, j, k + 1, em::bx2)); - c010 = INV_4 * - (EB(i - 1, j + 1, k - 1, em::bx2) + EB(i - 1, j + 1, k, em::bx2) + - EB(i, j + 1, k - 1, em::bx2) + EB(i, j + 1, k, em::bx2)); - c110 = INV_4 * - (EB(i, j + 1, k - 1, em::bx2) + EB(i, j + 1, k, em::bx2) + - EB(i + 1, j + 1, k - 1, em::bx2) + EB(i + 1, j + 1, k, em::bx2)); - c011 = INV_4 * - (EB(i - 1, j + 1, k, em::bx2) + EB(i - 1, j + 1, k + 1, em::bx2) + - EB(i, j + 1, k, em::bx2) + EB(i, j + 1, k + 1, em::bx2)); - c111 = INV_4 * - (EB(i, j + 1, k, em::bx2) + EB(i, j + 1, k + 1, em::bx2) + - EB(i + 1, j + 1, k, em::bx2) + EB(i + 1, j + 1, k + 1, em::bx2)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c01 = c001 * (ONE - dx1_) + c101 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - c11 = c011 * (ONE - dx1_) + c111 * dx1_; - c0 = c00 * (ONE - dx2_) + c10 * dx2_; - c1 = c01 * (ONE - dx2_) + c11 * dx2_; - b0[1] = c0 * (ONE - dx3_) + c1 * dx3_; - - // Bx3 - c000 = INV_4 * (EB(i - 1, j - 1, k, em::bx3) + EB(i - 1, j, k, em::bx3) + - EB(i, j - 1, k, em::bx3) + EB(i, j, k, em::bx3)); - c100 = INV_4 * (EB(i, j - 1, k, em::bx3) + EB(i, j, k, em::bx3) + - EB(i + 1, j - 1, k, em::bx3) + EB(i + 1, j, k, em::bx3)); - c001 = INV_4 * - (EB(i - 1, j - 1, k + 1, em::bx3) + EB(i - 1, j, k + 1, em::bx3) + - EB(i, j - 1, k + 1, em::bx3) + EB(i, j, k + 1, em::bx3)); - c101 = INV_4 * - (EB(i, j - 1, k + 1, em::bx3) + EB(i, j, k + 1, em::bx3) + - EB(i + 1, j - 1, k + 1, em::bx3) + EB(i + 1, j, k + 1, em::bx3)); - c010 = INV_4 * (EB(i - 1, j, k, em::bx3) + EB(i - 1, j + 1, k, em::bx3) + - EB(i, j, k, em::bx3) + EB(i, j + 1, k, em::bx3)); - c110 = INV_4 * (EB(i, j, k, em::bx3) + EB(i, j + 1, k, em::bx3) + - EB(i + 1, j, k, em::bx3) + EB(i + 1, j + 1, k, em::bx3)); - c011 = INV_4 * - (EB(i - 1, j, k + 1, em::bx3) + EB(i - 1, j + 1, k + 1, em::bx3) + - EB(i, j, k + 1, em::bx3) + EB(i, j + 1, k + 1, em::bx3)); - c111 = INV_4 * - (EB(i, j, k + 1, em::bx3) + EB(i, j + 1, k + 1, em::bx3) + - EB(i + 1, j, k + 1, em::bx3) + EB(i + 1, j + 1, k + 1, em::bx3)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c01 = c001 * (ONE - dx1_) + c101 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - c11 = c011 * (ONE - dx1_) + c111 * dx1_; - c0 = c00 * (ONE - dx2_) + c10 * dx2_; - c1 = c01 * (ONE - dx2_) + c11 * dx2_; - b0[2] = c0 * (ONE - dx3_) + c1 * dx3_; - } - } - - // Extra - Inline void boundaryConditions(index_t& p) const { - if constexpr (D == Dim::_1D || D == Dim::_2D || D == Dim::_3D) { - if (i1(p) < 0) { - if (is_periodic_i1min) { - i1(p) += ni1; - i1_prev(p) += ni1; - } else if (is_absorb_i1min) { - tag(p) = ParticleTag::dead; - } - } else if (i1(p) >= ni1) { - if (is_periodic_i1max) { - i1(p) -= ni1; - i1_prev(p) -= ni1; - } else if (is_absorb_i1max) { - tag(p) = ParticleTag::dead; - } - } - } - if constexpr (D == Dim::_2D || D == Dim::_3D) { - if (i2(p) < 0) { - if (is_periodic_i2min) { - i2(p) += ni2; - i2_prev(p) += ni2; - } else if (is_absorb_i2min) { - tag(p) = ParticleTag::dead; - } else if (is_axis_i2min) { - i2(p) = 0; - dx2(p) = ONE - dx2(p); - } - } else if (i2(p) >= ni2) { - if (is_periodic_i2max) { - i2(p) -= ni2; - i2_prev(p) -= ni2; - } else if (is_absorb_i2max) { - tag(p) = ParticleTag::dead; - } else if (is_axis_i2max) { - i2(p) = ni2 - 1; - dx2(p) = ONE - dx2(p); - } - } - } - if constexpr (D == Dim::_3D) { - if (i3(p) < 0) { - if (is_periodic_i3min) { - i3(p) += ni3; - i3_prev(p) += ni3; - } else if (is_absorb_i3min) { - tag(p) = ParticleTag::dead; - } - } else if (i3(p) >= ni3) { - if (is_periodic_i3max) { - i3(p) -= ni3; - i3_prev(p) -= ni3; - } else if (is_absorb_i3max) { - tag(p) = ParticleTag::dead; - } - } - } - } - }; - -} // namespace kernel::sr - -#undef from_Xi_to_i_di -#undef from_Xi_to_i -#undef i_di_to_Xi - -#endif // KERNELS_PARTICLE_PUSHER_SR_HPP diff --git a/legacy/src/pic/boundaries/currents_bc.cpp b/legacy/src/pic/boundaries/currents_bc.cpp deleted file mode 100644 index 012ad85c7..000000000 --- a/legacy/src/pic/boundaries/currents_bc.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file fields_bc.cpp - * @brief Absorbing boundary conditions for the currents at rmax (for 2D axisymmetric). - * @implements: `CurrentsBoundaryConditions` method of the `PIC` class - * @includes: `currents_bc.hpp - * @depends: `pic.h` - * - * @notes: - Periodic boundary conditions are implemented in `currents_exch.cpp` - * - */ - -#include "wrapper.h" - -#include "pic.h" - -#include "meshblock/meshblock.h" - -#ifndef MINKOWSKI_METRIC - #include "currents_bc.hpp" -#endif - -namespace ntt { - /** - * @brief Special boundary conditions on currents - */ -#ifdef MINKOWSKI_METRIC - template - void PIC::CurrentsBoundaryConditions() {} - -#else - - template <> - void PIC::CurrentsBoundaryConditions() { - // auto& mblock = this->meshblock; - // if (mblock.boundaries[0][1] == BoundaryCondition::ABSORB) { - // auto& pgen = this->problem_generator; - // auto params = *(this->params()); - // auto r_absorb = params.metricParameters()[2]; - // auto r_max = mblock.metric.x1_max; - // const auto i1_absorb = (std::size_t)(mblock.metric.x1_Sph2Code(r_absorb)); - // NTTHostErrorIf(i1_absorb >= mblock.i1_max(), - // "Absorbing layer is too small, consider " - // "increasing r_absorb"); - // /** - // * . . . . . . . . . . . . . - // * . . - // * . . - // * . ^= = = = = = = =^ . - // * . |* * * * * * * *\ . - // * . |* * * * * * * *\ . - // * . | \ . - // * . | \ . - // * . ^- - - - - - - -^ . - // * . . - // * . . - // * . . . . . . . . . . . . . - // * - // */ - // Kokkos::parallel_for( - // "CurrentsBoundaryConditions", - // CreateRangePolicy({ i1_absorb, 0 }, - // { mblock.i1_max(), mblock.i2_max() }), - // AbsorbCurrents_kernel(mblock, pgen, r_absorb, r_max)); - // } - } - - template <> - void PIC::CurrentsBoundaryConditions() { - NTTHostError("not applicable"); - } - - template <> - void PIC::CurrentsBoundaryConditions() { - NTTHostError("not implemented"); - } -#endif - -} // namespace ntt - -#ifdef MINKOWSKI_METRIC -template void ntt::PIC::CurrentsBoundaryConditions(); -template void ntt::PIC::CurrentsBoundaryConditions(); -template void ntt::PIC::CurrentsBoundaryConditions(); -#endif \ No newline at end of file diff --git a/legacy/src/pic/boundaries/currents_bc.hpp b/legacy/src/pic/boundaries/currents_bc.hpp deleted file mode 100644 index 19026bcfd..000000000 --- a/legacy/src/pic/boundaries/currents_bc.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef PIC_CURRENTS_BC_H -#define PIC_CURRENTS_BC_H - -#include "wrapper.h" - -#include "field_macros.h" -#include "pic.h" - -#include PGEN_HEADER - -namespace ntt { - // /** - // * @brief Algorithms for PIC current boundary conditions. - // * @tparam D Dimension. - // */ - // template - // class AbsorbCurrents_kernel { - // Meshblock m_mblock; - // ProblemGenerator m_pgen; - // real_t m_rabsorb; - // real_t m_rmax; - - // public: - // /** - // * @brief Constructor. - // * @param mblock Meshblock. - // * @param pgen Problem generator. - // * @param rabsorb Absorbing radius. - // * @param rmax Maximum radius. - // */ - // AbsorbCurrents_kernel(const Meshblock& mblock, - // const ProblemGenerator& pgen, - // real_t r_absorb, - // real_t r_max) : - // m_mblock { mblock }, - // m_pgen { pgen }, - // m_rabsorb { r_absorb }, - // m_rmax { r_max } {} - - // /** - // * @brief 2D implementation of the algorithm. - // * @param i1 index. - // * @param i2 index. - // */ - // Inline void operator()(index_t, index_t) const; - // }; - - // template <> - // Inline void AbsorbCurrents_kernel::operator()(index_t i, index_t j) const { - // const real_t i_ { static_cast(static_cast(i) - N_GHOSTS) }; - // const real_t j_ { static_cast(static_cast(j) - N_GHOSTS) }; - - // const real_t i1 - // // vec_t rth_; - // // m_mblock.metric.x_Code2Sph({ i_, j_, ZERO }, rth_); - // real_t delta_r1 { (rth_[0] - m_rabsorb) / (m_rmax - m_rabsorb) }; - // real_t sigma_r1 { HEAVISIDE(delta_r1) * delta_r1 * delta_r1 * delta_r1 }; - - // JX1(i, j) = (ONE - sigma_r1) * JX1(i, j); - // JX2(i, j) = (ONE - sigma_r1) * JX2(i, j); - // JX3(i, j) = (ONE - sigma_r1) * JX3(i, j); - // } -} // namespace ntt - -#endif diff --git a/legacy/src/pic/fields/ampere_curv.hpp b/legacy/src/pic/fields/ampere_curv.hpp deleted file mode 100644 index 12cf9cdf2..000000000 --- a/legacy/src/pic/fields/ampere_curv.hpp +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef PIC_AMPERE_CURVILINEAR_H -#define PIC_AMPERE_CURVILINEAR_H - -#include "wrapper.h" - -#include "field_macros.h" -#include "pic.h" - -#include "io/output.h" -#include "meshblock/meshblock.h" - -namespace ntt { - /** - * @brief Algorithm for the Ampere's law: `dE/dt = curl B` in curvilinear space. - * @tparam D Dimension. - */ - template - class Ampere_kernel { - Meshblock m_mblock; - real_t m_coeff; - - public: - /** - * @brief Constructor. - * @param mblock Meshblock. - * @param coeff Coefficient to be multiplied by dE/dt = coeff * curl B. - */ - Ampere_kernel(const Meshblock& mblock, const real_t& coeff) : - m_mblock(mblock), - m_coeff(coeff) {} - - /** - * @brief 2D version of the algorithm. - * @param i1 index. - * @param i2 index. - */ - Inline void operator()(index_t i1, index_t i2) const; - /** - * @brief 3D version of the algorithm. - * @param i1 index. - * @param i2 index. - * @param i3 index. - */ - Inline void operator()(index_t i1, index_t i2, index_t i3) const; - }; - - template <> - Inline void Ampere_kernel::operator()(index_t i, index_t j) const { - real_t i_ { static_cast(static_cast(i) - N_GHOSTS) }; - real_t j_ { static_cast(static_cast(j) - N_GHOSTS) }; - - real_t inv_sqrt_detH_ij { ONE / m_mblock.metric.sqrt_det_h({ i_, j_ }) }; - real_t inv_sqrt_detH_iPj { ONE / m_mblock.metric.sqrt_det_h({ i_ + HALF, j_ }) }; - real_t inv_sqrt_detH_ijP { ONE / m_mblock.metric.sqrt_det_h({ i_, j_ + HALF }) }; - real_t h1_ijM { m_mblock.metric.h_11({ i_, j_ - HALF }) }; - real_t h1_ijP { m_mblock.metric.h_11({ i_, j_ + HALF }) }; - real_t h2_iPj { m_mblock.metric.h_22({ i_ + HALF, j_ }) }; - real_t h2_iMj { m_mblock.metric.h_22({ i_ - HALF, j_ }) }; - real_t h3_iMjP { m_mblock.metric.h_33({ i_ - HALF, j_ + HALF }) }; - real_t h3_iPjM { m_mblock.metric.h_33({ i_ + HALF, j_ - HALF }) }; - real_t h3_iPjP { m_mblock.metric.h_33({ i_ + HALF, j_ + HALF }) }; - - EX1(i, j) += m_coeff * inv_sqrt_detH_iPj * - (h3_iPjP * BX3(i, j) - h3_iPjM * BX3(i, j - 1)); - EX2(i, j) += m_coeff * inv_sqrt_detH_ijP * - (h3_iMjP * BX3(i - 1, j) - h3_iPjP * BX3(i, j)); - EX3(i, j) += m_coeff * inv_sqrt_detH_ij * - (h1_ijM * BX1(i, j - 1) - h1_ijP * BX1(i, j) + - h2_iPj * BX2(i, j) - h2_iMj * BX2(i - 1, j)); - } - - template <> - Inline void Ampere_kernel::operator()(index_t, index_t, index_t) const { - // 3d curvilinear ampere not implemented - } - - /** - * @brief Algorithm for the Ampere's law: `dE/dt = curl B` in curvilinear - * space near the polar axes (integral form). - * @tparam D Dimension. - */ - template - class AmperePoles_kernel { - Meshblock m_mblock; - real_t m_coeff; - const std::size_t m_ni2; - - public: - /** - * @brief Constructor. - * @param mblock Meshblock. - * @param coeff Coefficient to be multiplied by dE/dt = coeff * curl B. - */ - AmperePoles_kernel(const Meshblock& mblock, const real_t& coeff) : - m_mblock(mblock), - m_coeff(coeff), - m_ni2(m_mblock.Ni2()) {} - - /** - * @brief Implementation of the algorithm. - * @param i radial index. - */ - Inline void operator()(index_t i) const; - }; - - template <> - Inline void AmperePoles_kernel::operator()(index_t i) const { - index_t j_min { N_GHOSTS }; - index_t j_max { m_ni2 + N_GHOSTS }; - - real_t i_ { static_cast(static_cast(i) - N_GHOSTS) }; - real_t j_max_ { static_cast(static_cast(j_max) - N_GHOSTS) }; - - real_t inv_polar_area_iPj { ONE / m_mblock.metric.polar_area(i_ + HALF) }; - real_t h3_min_iPjP { m_mblock.metric.h_33({ i_ + HALF, HALF }) }; - real_t h3_max_iPjM { m_mblock.metric.h_33({ i_ + HALF, j_max_ - HALF }) }; - - real_t inv_sqrt_detH_ijP { ONE / m_mblock.metric.sqrt_det_h({ i_, HALF }) }; - real_t h3_min_iMjP { m_mblock.metric.h_33({ i_ - HALF, HALF }) }; - - // theta = 0 - EX1(i, j_min) += inv_polar_area_iPj * m_coeff * (h3_min_iPjP * BX3(i, j_min)); - // theta = pi - EX1(i, j_max) -= inv_polar_area_iPj * m_coeff * (h3_max_iPjM * BX3(i, j_max)); - - // j = jmin + 1/2 - EX2(i, j_min) += inv_sqrt_detH_ijP * m_coeff * - (h3_min_iMjP * BX3(i - 1, j_min) - - h3_min_iPjP * BX3(i, j_min)); - } -} // namespace ntt - -#endif // NTT_AMPERE_KERNEL_HPP diff --git a/legacy/src/pic/fields/ampere_mink.hpp b/legacy/src/pic/fields/ampere_mink.hpp deleted file mode 100644 index 90bd5d518..000000000 --- a/legacy/src/pic/fields/ampere_mink.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef PIC_AMPERE_MINKOWSKI_H -#define PIC_AMPERE_MINKOWSKI_H - -#include "wrapper.h" - -#include "field_macros.h" -#include "pic.h" - -#include "io/output.h" -#include "meshblock/meshblock.h" - -namespace ntt { - /** - * @brief Algorithm for the Ampere's law: `dE/dt = curl B` in Minkowski space. - * @tparam D Dimension. - */ - template - class Ampere_kernel { - Meshblock m_mblock; - real_t m_coeff; - - public: - /** - * @brief Constructor. - * @param mblock Meshblock. - * @param coeff Coefficient to be multiplied by dE/dt = coeff * curl B. - */ - Ampere_kernel(const Meshblock& mblock, const real_t& coeff) : - m_mblock(mblock), - m_coeff(coeff) {} - - /** - * @brief 1D implementation of the algorithm. - * @param i1 index. - */ - Inline void operator()(index_t) const; - - /** - * @brief 2D implementation of the algorithm. - * @param i1 index. - * @param i2 index. - */ - Inline void operator()(index_t, index_t) const; - - /** - * @brief 3D implementation of the algorithm. - * @param i1 index. - * @param i2 index. - * @param i3 index. - */ - Inline void operator()(index_t, index_t, index_t) const; - }; - - template <> - Inline void Ampere_kernel::operator()(index_t i) const { - EX2(i) += m_coeff * (BX3(i - 1) - BX3(i)); - EX3(i) += m_coeff * (BX2(i) - BX2(i - 1)); - } - - template <> - Inline void Ampere_kernel::operator()(index_t i, index_t j) const { - EX1(i, j) += m_coeff * (BX3(i, j) - BX3(i, j - 1)); - EX2(i, j) += m_coeff * (BX3(i - 1, j) - BX3(i, j)); - EX3(i, j) += m_coeff * (BX1(i, j - 1) - BX1(i, j) + BX2(i, j) - BX2(i - 1, j)); - } - - template <> - Inline void Ampere_kernel::operator()(index_t i, index_t j, index_t k) const { - EX1(i, j, k) += m_coeff * (BX2(i, j, k - 1) - BX2(i, j, k) + BX3(i, j, k) - - BX3(i, j - 1, k)); - EX2(i, j, k) += m_coeff * (BX3(i - 1, j, k) - BX3(i, j, k) + BX1(i, j, k) - - BX1(i, j, k - 1)); - EX3(i, j, k) += m_coeff * (BX1(i, j - 1, k) - BX1(i, j, k) + BX2(i, j, k) - - BX2(i - 1, j, k)); - } -} // namespace ntt -#endif // PIC_AMPERE_MINKOWSKI_H \ No newline at end of file diff --git a/legacy/src/pic/fields/faraday_curv.hpp b/legacy/src/pic/fields/faraday_curv.hpp deleted file mode 100644 index 0b8880e69..000000000 --- a/legacy/src/pic/fields/faraday_curv.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef PIC_FARADAY_CURVILINEAR_H -#define PIC_FARADAY_CURVILINEAR_H - -#include "wrapper.h" - -#include "field_macros.h" -#include "pic.h" - -#include "io/output.h" -#include "meshblock/meshblock.h" - -#include - -namespace ntt { - - /** - * @brief Algorithm for the Faraday's law: `dB/dt = -curl E` in Curvilinear - * space (diagonal metric). - * @tparam D Dimension. - */ - template - class Faraday_kernel { - Meshblock m_mblock; - real_t m_coeff; - - public: - /** - * @brief Constructor. - * @param mblock Meshblock. - * @param coeff Coefficient to be multiplied by dB/dt = coeff * -curl E. - */ - Faraday_kernel(const Meshblock& mblock, const real_t& coeff) : - m_mblock(mblock), - m_coeff(coeff) {} - - /** - * @brief 2D implementation of the algorithm. - * @param i1 index. - * @param i2 index. - */ - Inline void operator()(index_t, index_t) const; - /** - * @brief 3D implementation of the algorithm. - * @param i1 index. - * @param i2 index. - * @param i3 index. - */ - Inline void operator()(index_t, index_t, index_t) const; - }; - - template <> - Inline void Faraday_kernel::operator()(index_t i, index_t j) const { - real_t i_ { static_cast(static_cast(i) - N_GHOSTS) }; - real_t j_ { static_cast(static_cast(j) - N_GHOSTS) }; - - real_t inv_sqrt_detH_iPj { ONE / m_mblock.metric.sqrt_det_h({ i_ + HALF, j_ }) }; - real_t inv_sqrt_detH_ijP { ONE / m_mblock.metric.sqrt_det_h({ i_, j_ + HALF }) }; - real_t inv_sqrt_detH_iPjP { ONE / m_mblock.metric.sqrt_det_h( - { i_ + HALF, j_ + HALF }) }; - real_t h1_iPjP1 { m_mblock.metric.h_11({ i_ + HALF, j_ + ONE }) }; - real_t h1_iPj { m_mblock.metric.h_11({ i_ + HALF, j_ }) }; - real_t h2_iP1jP { m_mblock.metric.h_22({ i_ + ONE, j_ + HALF }) }; - real_t h2_ijP { m_mblock.metric.h_22({ i_, j_ + HALF }) }; - real_t h3_ij { m_mblock.metric.h_33({ i_, j_ }) }; - real_t h3_iP1j { m_mblock.metric.h_33({ i_ + ONE, j_ }) }; - real_t h3_ijP1 { m_mblock.metric.h_33({ i_, j_ + ONE }) }; - - BX1(i, j) += m_coeff * inv_sqrt_detH_ijP * - (h3_ij * EX3(i, j) - h3_ijP1 * EX3(i, j + 1)); - if (j == N_GHOSTS) { - BX2(i, j) =m_coeff * (EX3(i + 1, j) - EX3(i, j)); - } else { - BX2(i, j) += m_coeff * inv_sqrt_detH_iPj * - (h3_iP1j * EX3(i + 1, j) - h3_ij * EX3(i, j)); - } - BX3(i, j) += m_coeff * inv_sqrt_detH_iPjP * - (h1_iPjP1 * EX1(i, j + 1) - h1_iPj * EX1(i, j) + - h2_ijP * EX2(i, j) - h2_iP1jP * EX2(i + 1, j)); - } - - template <> - Inline void Faraday_kernel::operator()(index_t, index_t, index_t) const { - // 3d curvilinear faraday not implemented - } -} // namespace ntt - -#endif diff --git a/legacy/src/pic/fields/faraday_mink.hpp b/legacy/src/pic/fields/faraday_mink.hpp deleted file mode 100644 index cebf67f15..000000000 --- a/legacy/src/pic/fields/faraday_mink.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef PIC_FARADAY_MINKOWSKI_H -#define PIC_FARADAY_MINKOWSKI_H - -#include "wrapper.h" - -#include "field_macros.h" -#include "pic.h" - -#include "io/output.h" -#include "meshblock/meshblock.h" - -namespace ntt { - - /** - * @brief Algorithm for the Faraday's law: `dB/dt = -curl E` in Minkowski space. - * @tparam D Dimension. - */ - template - class Faraday_kernel { - Meshblock m_mblock; - real_t m_coeff; - - public: - /** - * @brief Constructor. - * @param mblock Meshblock. - * @param coeff Coefficient to be multiplied by dB/dt = coeff * -curl E. - */ - Faraday_kernel(const Meshblock& mblock, const real_t& coeff) : - m_mblock(mblock), - m_coeff(coeff) {} - - /** - * @brief 1D implementation of the algorithm. - * @param i1 index. - */ - Inline void operator()(index_t) const; - /** - * @brief 2D implementation of the algorithm. - * @param i1 index. - * @param i2 index. - */ - Inline void operator()(index_t, index_t) const; - /** - * @brief 3D implementation of the algorithm. - * @param i1 index. - * @param i2 index. - * @param i3 index. - */ - Inline void operator()(index_t, index_t, index_t) const; - }; - - template <> - Inline void Faraday_kernel::operator()(index_t i) const { - BX2(i) += m_coeff * (EX3(i + 1) - EX3(i)); - BX3(i) += m_coeff * (EX2(i) - EX2(i + 1)); - } - - template <> - Inline void Faraday_kernel::operator()(index_t i, index_t j) const { - BX1(i, j) += m_coeff * (EX3(i, j) - EX3(i, j + 1)); - BX2(i, j) += m_coeff * (EX3(i + 1, j) - EX3(i, j)); - BX3(i, j) += m_coeff * (EX1(i, j + 1) - EX1(i, j) + EX2(i, j) - EX2(i + 1, j)); - } - - template <> - Inline void Faraday_kernel::operator()(index_t i, index_t j, index_t k) const { - BX1(i, j, k) += m_coeff * (EX2(i, j, k + 1) - EX2(i, j, k) + EX3(i, j, k) - - EX3(i, j + 1, k)); - BX2(i, j, k) += m_coeff * (EX3(i + 1, j, k) - EX3(i, j, k) + EX1(i, j, k) - - EX1(i, j, k + 1)); - BX3(i, j, k) += m_coeff * (EX1(i, j + 1, k) - EX1(i, j, k) + EX2(i, j, k) - - EX2(i + 1, j, k)); - } -} // namespace ntt - -#endif diff --git a/legacy/src/pic/particles/particle_pusher.hpp b/legacy/src/pic/particles/particle_pusher.hpp deleted file mode 100644 index 7991a95a4..000000000 --- a/legacy/src/pic/particles/particle_pusher.hpp +++ /dev/null @@ -1,1093 +0,0 @@ -#ifndef PIC_PARTICLE_PUSHER_H -#define PIC_PARTICLE_PUSHER_H - -#include "utils/qmath.h" - -#include "io/output.h" -#include "meshblock/meshblock.h" -#include "meshblock/particles.h" -#include "pic.h" -#include "wrapper.h" -#include METRIC_HEADER - -#include - -#ifdef EXTERNAL_FORCE - #include PGEN_HEADER -#endif - -namespace ntt { - struct Boris_t {}; - - struct Vay_t {}; - - struct Photon_t {}; - - // struct Boris_GCA_t {}; - - // struct Vay_GCA_t {}; - - struct GCA_t {}; - - struct NoGCA_t {}; - - struct Massive_t {}; - - struct Massless_t {}; - - /** - * @brief Algorithm for the Particle pusher. - * @tparam D Dimension. - */ - template - class Pusher_kernel { - ndfield_t EB; - array_t i1, i2, i3; - array_t i1_prev, i2_prev, i3_prev; - array_t dx1, dx2, dx3; - array_t dx1_prev, dx2_prev, dx3_prev; - array_t ux1, ux2, ux3; - array_t phi; - array_t tag; - const Metric metric; - - const real_t time, coeff, dt; - const int ni1, ni2, ni3; - const real_t gca_larmor { 0.05 }, gca_EovrB_sqr { 0.81 }; - bool is_ax_i2min { false }, is_ax_i2max { false }; - bool is_absorb_i1min { false }, is_absorb_i1max { false }; - bool is_absorb_i2min { false }, is_absorb_i2max { false }; - bool is_absorb_i3min { false }, is_absorb_i3max { false }; - bool is_periodic_i1min { false }, is_periodic_i1max { false }; - bool is_periodic_i2min { false }, is_periodic_i2max { false }; - bool is_periodic_i3min { false }, is_periodic_i3max { false }; - -#ifdef EXTERNAL_FORCE - ProblemGenerator pgen; -#endif - - public: - Pusher_kernel(Meshblock& mblock, - Particles& particles, - real_t time, - real_t coeff, - real_t dt, - ProblemGenerator& pgen) - : EB { mblock.em } - , i1 { particles.i1 } - , i2 { particles.i2 } - , i3 { particles.i3 } - , i1_prev { particles.i1_prev } - , i2_prev { particles.i2_prev } - , i3_prev { particles.i3_prev } - , dx1 { particles.dx1 } - , dx2 { particles.dx2 } - , dx3 { particles.dx3 } - , dx1_prev { particles.dx1_prev } - , dx2_prev { particles.dx2_prev } - , dx3_prev { particles.dx3_prev } - , ux1 { particles.ux1 } - , ux2 { particles.ux2 } - , ux3 { particles.ux3 } - , phi { particles.phi } - , tag { particles.tag } - , metric { mblock.metric } - , time { time } - , coeff { coeff } - , dt { dt } - , ni1 { (int)mblock.Ni1() } - , ni2 { (int)mblock.Ni2() } - , ni3 { (int)mblock.Ni3() } -#ifdef EXTERNAL_FORCE - , pgen { pgen } -#endif - { - (void)pgen; - NTTHostErrorIf(mblock.boundaries.size() < 1, - "boundaries defined incorrectly"); - is_absorb_i1min = (mblock.boundaries[0][0] == BoundaryCondition::OPEN) || - (mblock.boundaries[0][0] == BoundaryCondition::CUSTOM) || - (mblock.boundaries[0][0] == BoundaryCondition::ABSORB); - is_absorb_i1max = (mblock.boundaries[0][1] == BoundaryCondition::OPEN) || - (mblock.boundaries[0][1] == BoundaryCondition::CUSTOM) || - (mblock.boundaries[0][1] == BoundaryCondition::ABSORB); - is_periodic_i1min = (mblock.boundaries[0][0] == BoundaryCondition::PERIODIC); - is_periodic_i1max = (mblock.boundaries[0][1] == BoundaryCondition::PERIODIC); - if constexpr ((D == Dim2) || (D == Dim3)) { - NTTHostErrorIf(mblock.boundaries.size() < 2, - "boundaries defined incorrectly"); - is_absorb_i2min = (mblock.boundaries[1][0] == BoundaryCondition::OPEN) || - (mblock.boundaries[1][0] == BoundaryCondition::CUSTOM) || - (mblock.boundaries[1][0] == BoundaryCondition::ABSORB); - is_absorb_i2max = (mblock.boundaries[1][1] == BoundaryCondition::OPEN) || - (mblock.boundaries[1][1] == BoundaryCondition::CUSTOM) || - (mblock.boundaries[1][1] == BoundaryCondition::ABSORB); - is_ax_i2min = (mblock.boundaries[1][0] == BoundaryCondition::AXIS); - is_ax_i2max = (mblock.boundaries[1][1] == BoundaryCondition::AXIS); - is_periodic_i2min = (mblock.boundaries[1][0] == BoundaryCondition::PERIODIC); - is_periodic_i2max = (mblock.boundaries[1][1] == BoundaryCondition::PERIODIC); - } - if constexpr (D == Dim3) { - NTTHostErrorIf(mblock.boundaries.size() < 3, - "boundaries defined incorrectly"); - is_absorb_i3min = (mblock.boundaries[2][0] == BoundaryCondition::OPEN) || - (mblock.boundaries[2][0] == BoundaryCondition::CUSTOM) || - (mblock.boundaries[2][0] == BoundaryCondition::ABSORB); - is_absorb_i3max = (mblock.boundaries[2][1] == BoundaryCondition::OPEN) || - (mblock.boundaries[2][1] == BoundaryCondition::CUSTOM) || - (mblock.boundaries[2][1] == BoundaryCondition::ABSORB); - is_periodic_i3min = (mblock.boundaries[2][0] == BoundaryCondition::PERIODIC); - is_periodic_i3max = (mblock.boundaries[2][1] == BoundaryCondition::PERIODIC); - } - } - - template - Inline void operator()(P, G, M, index_t) const; - // Inline void operator()(Boris_t, index_t) const; - // Inline void operator()(Vay_t, index_t) const; - // Inline void operator()(Boris_GCA_t, index_t) const; - // Inline void operator()(Vay_GCA_t, index_t) const; - // Inline void operator()(Photon_t, index_t) const; - - // Updaters - - /** - * @brief update particle velocities - * @param P pusher algorithm - * @param G GCA tag - * @param M massive tag - * @param p, e0, b0 index & interpolated fields - */ - Inline void velUpd(Boris_t, index_t&, vec_t&, vec_t&) const; - Inline void velUpd(Vay_t, Massive_t, index_t&, vec_t&, vec_t&) const; - // Inline void velUpd(Boris_t, NoGCA_t, index_t&, vec_t&, vec_t&) const; - // Inline void velUpd(Vay_t, NoGCA_t, index_t&, vec_t&, vec_t&) const; - Inline void velUpd(Photon_t, index_t&, vec_t&, vec_t&) const; - - // Inline void velUpd(Vay_t, GCA_t, Massive_t, index_t&, vec_t&, vec_t&) const; - - // Inline void velUpd(Vay_t, index_t&, vec_t&, vec_t&) const; - - // Inline void velUpd(Photon_t, index_t&, vec_t&, vec_t&) const {} - - // #ifndef EXTERNAL_FORCE - // Inline void velUpd(GCA_t, index_t&, vec_t&, vec_t&) const; - // #else - // Inline void velUpd(GCA_t, index_t&, vec_t&, vec_t&, vec_t&) const; - // #endif - - /** - * @brief update particle positions with updated velocities - * @param p, v index & 3-velocity - */ - Inline void posUpd(index_t&, const vec_t&) const; - - /** - * @brief same as posUpd but per component - */ - Inline void posUpd_x1(index_t&, const real_t&) const; - Inline void posUpd_x2(index_t&, const real_t&) const; - Inline void posUpd_x3(index_t&, const real_t&) const; - - // /** - // * @brief apply boundary conditions - // */ - // Inline void boundaryConditions(index_t&) const; - // Inline void boundaryConditions_x1(index_t&) const; - // Inline void boundaryConditions_x2(index_t&) const; - // Inline void boundaryConditions_x3(index_t&) const; - - // Getters - Inline void getPrtlPos(index_t&, coord_t&) const; - - template - Inline void get3VelCntrv(T, index_t&, vec_t&, vec_t&) const; - - Inline auto getEnergy(Massive_t, index_t& p) const -> real_t; - - Inline auto getEnergy(Massless_t, index_t& p) const -> real_t; - - Inline void getInterpFlds(index_t&, vec_t&, vec_t&) const; - - // Extra - -#ifdef EXTERNAL_FORCE - #ifdef MINKOWSKI_METRIC - Inline void initForce(coord_t&, vec_t&) const; - #else - Inline void initForce(coord_t&, vec_t&) const; - #endif - Inline void forceHalfUpdate(index_t&, vec_t&) const; -#endif - }; - - template - void PushLoop(const SimulationParams& params, - Meshblock& mblock, - Particles& particles, - ProblemGenerator& pgen, - real_t time, - real_t factor) { - const auto dt = factor * mblock.timestep(); - const auto charge_ovr_mass = particles.mass() > ZERO - ? particles.charge() / particles.mass() - : ZERO; - const auto coeff = charge_ovr_mass * HALF * dt * params.B0(); - Kokkos::parallel_for( - "ParticlesPush", - Kokkos::RangePolicy(0, particles.npart()), - Pusher_kernel(mblock, particles, time, coeff, dt, pgen)); - } - - /** - * Definitions - */ - - template - template - Inline void Pusher_kernel::operator()(P, G, M, index_t p) const { - if (tag(p) == ParticleTag::alive) { - coord_t xp { ZERO }, xp_Cart; - getPrtlPos(p, xp); - metric.x_Code2Cart(xp, xp_Cart); - - vec_t ei { ZERO }, bi { ZERO }; - vec_t ei_Cart { ZERO }, bi_Cart { ZERO }; - getInterpFlds(p, ei, bi); - metric.v3_Cntrv2Cart(xp, ei, ei_Cart); - metric.v3_Cntrv2Cart(xp, bi, bi_Cart); - -#ifdef EXTERNAL_FORCE - vec_t force_Cart { ZERO }; - initForce(xp, force_Cart); - forceHalfUpdate(p, force_Cart); -#endif - velUpd(P {}, p, ei_Cart, bi_Cart); -#ifdef EXTERNAL_FORCE - forceHalfUpdate(p, force_Cart); -#endif - - // vec_t v { ZERO }; - // get3VelCntrv(Massive_t {}, p, xp, v); - // posUpd(p, v); - // boundaryConditions(p); - } - } - - // template - // Inline void Pusher_kernel::operator()(Photon_t, index_t p) const { - // if (tag(p) == ParticleTag::alive) { - // coord_t xp { ZERO }; - // vec_t v { ZERO }; - // getPrtlPos(p, xp); - // get3VelCntrv(Massless_t {}, p, xp, v); - // posUpd(p, v); - // boundaryConditions(p); - // } - // } - - // template - // Inline void Pusher_kernel::operator()(Boris_t, index_t p) const { - // if (tag(p) == ParticleTag::alive) { - // coord_t xp { ZERO }, xp_Cart; - // getPrtlPos(p, xp); - // metric.x_Code2Cart(xp, xp_Cart); - - // vec_t ei { ZERO }, bi { ZERO }; - // vec_t ei_Cart { ZERO }, bi_Cart { ZERO }; - // getInterpFlds(p, ei, bi); - // metric.v3_Cntrv2Cart(xp, ei, ei_Cart); - // metric.v3_Cntrv2Cart(xp, bi, bi_Cart); - - // #ifdef EXTERNAL_FORCE - // vec_t force_Cart { ZERO }; - // initForce(xp, force_Cart); - // forceHalfUpdate(p, force_Cart); - // #endif - // velUpd(Boris_t {}, p, ei_Cart, bi_Cart); - // #ifdef EXTERNAL_FORCE - // forceHalfUpdate(p, force_Cart); - // #endif - - // // vec_t v { ZERO }; - // // get3VelCntrv(Massive_t {}, p, xp, v); - // posUpd(p, v); - // // boundaryConditions(p); - // } - // } - - // template - // Inline void Pusher_kernel::operator()(Vay_t, index_t p) const { - // if (tag(p) == ParticleTag::alive) { - // coord_t xp { ZERO }; - // getPrtlPos(p, xp); - - // vec_t ei { ZERO }, bi { ZERO }; - // vec_t ei_Cart { ZERO }, bi_Cart { ZERO }; - // getInterpFlds(p, ei, bi); - // metric.v3_Cntrv2Cart(xp, ei, ei_Cart); - // metric.v3_Cntrv2Cart(xp, bi, bi_Cart); - - // #ifdef EXTERNAL_FORCE - // vec_t force_Cart { ZERO }; - // initForce(xp, force_Cart); - // forceHalfUpdate(p, force_Cart); - // #endif - // velUpd(Vay_t {}, p, ei_Cart, bi_Cart); - // #ifdef EXTERNAL_FORCE - // forceHalfUpdate(p, force_Cart); - // #endif - - // vec_t v { ZERO }; - // get3VelCntrv(Massive_t {}, p, xp, v); - // posUpd(p, v); - // boundaryConditions(p); - // } - // } - - // template - // Inline void Pusher_kernel::operator()(Boris_GCA_t, index_t p) const { - // if (tag(p) == ParticleTag::alive) { - // coord_t xp { ZERO }; - // getPrtlPos(p, xp); - - // vec_t ei { ZERO }, bi { ZERO }; - // vec_t ei_Cart { ZERO }, bi_Cart { ZERO }; - // getInterpFlds(p, ei, bi); - // metric.v3_Cntrv2Cart(xp, ei, ei_Cart); - // metric.v3_Cntrv2Cart(xp, bi, bi_Cart); - - // const auto E2 { NORM_SQR(ei_Cart[0], ei_Cart[1], ei_Cart[2]) }; - // const auto B2 { NORM_SQR(bi_Cart[0], bi_Cart[1], bi_Cart[2]) }; - // const auto rL { math::sqrt(ONE + NORM_SQR(ux1(p), ux2(p), ux3(p))) * dt / - // (TWO * coeff * math::sqrt(B2)) }; - // if (B2 > ZERO && rL < gca_larmor && (E2 / B2) < gca_EovrB_sqr) { - // #ifdef EXTERNAL_FORCE - // vec_t force_Cart { ZERO }; - // initForce(xp, force_Cart); - // velUpd(GCA_t {}, p, force_Cart, ei_Cart, bi_Cart); - // #else - // velUpd(GCA_t {}, p, ei_Cart, bi_Cart); - // #endif - // } else { - // #ifdef EXTERNAL_FORCE - // vec_t force_Cart { ZERO }; - // initForce(xp, force_Cart); - // forceHalfUpdate(p, force_Cart); - // #endif - // velUpd(Boris_t {}, p, ei_Cart, bi_Cart); - // #ifdef EXTERNAL_FORCE - // forceHalfUpdate(p, force_Cart); - // #endif - // } - - // vec_t v { ZERO }; - // get3VelCntrv(Massive_t {}, p, xp, v); - // posUpd(p, v); - // boundaryConditions(p); - // } - // } - - // template - // Inline void Pusher_kernel::operator()(Vay_GCA_t, index_t p) const { - // if (tag(p) == ParticleTag::alive) { - // coord_t xp { ZERO }; - // getPrtlPos(p, xp); - - // vec_t ei { ZERO }, bi { ZERO }; - // vec_t ei_Cart { ZERO }, bi_Cart { ZERO }; - // getInterpFlds(p, ei, bi); - // metric.v3_Cntrv2Cart(xp, ei, ei_Cart); - // metric.v3_Cntrv2Cart(xp, bi, bi_Cart); - - // const auto E2 { NORM_SQR(ei_Cart[0], ei_Cart[1], ei_Cart[2]) }; - // const auto B2 { NORM_SQR(bi_Cart[0], bi_Cart[1], bi_Cart[2]) }; - // const auto rL { math::sqrt(ONE + NORM_SQR(ux1(p), ux2(p), ux3(p))) * dt / - // (TWO * coeff * math::sqrt(B2)) }; - // if (rL < gca_larmor && (E2 / B2) < gca_EovrB_sqr) { - // #ifdef EXTERNAL_FORCE - // vec_t force_Cart { ZERO }; - // initForce(xp, force_Cart); - // velUpd(GCA_t {}, p, force_Cart, ei_Cart, bi_Cart); - // #else - // velUpd(GCA_t {}, p, ei_Cart, bi_Cart); - // #endif - // } else { - // #ifdef EXTERNAL_FORCE - // vec_t force_Cart { ZERO }; - // initForce(xp, force_Cart); - // forceHalfUpdate(p, force_Cart); - // #endif - // velUpd(Vay_t {}, p, ei_Cart, bi_Cart); - // #ifdef EXTERNAL_FORCE - // forceHalfUpdate(p, force_Cart); - // #endif - // } - - // vec_t v { ZERO }; - // get3VelCntrv(Massive_t {}, p, xp, v); - // posUpd(p, v); - // boundaryConditions(p); - // } - // } - - // Velocity update - - template - Inline void Pusher_kernel::velUpd(Boris_t, - index_t& p, - vec_t& e0, - vec_t& b0) const { - real_t COEFF { coeff }; - - e0[0] *= COEFF; - e0[1] *= COEFF; - e0[2] *= COEFF; - vec_t u0 { ux1(p) + e0[0], ux2(p) + e0[1], ux3(p) + e0[2] }; - - COEFF *= ONE / math::sqrt(ONE + NORM_SQR(u0[0], u0[1], u0[2])); - b0[0] *= COEFF; - b0[1] *= COEFF; - b0[2] *= COEFF; - COEFF = TWO / (ONE + NORM_SQR(b0[0], b0[1], b0[2])); - - vec_t u1 { - (u0[0] + CROSS_x1(u0[0], u0[1], u0[2], b0[0], b0[1], b0[2])) * COEFF, - (u0[1] + CROSS_x2(u0[0], u0[1], u0[2], b0[0], b0[1], b0[2])) * COEFF, - (u0[2] + CROSS_x3(u0[0], u0[1], u0[2], b0[0], b0[1], b0[2])) * COEFF - }; - - u0[0] += CROSS_x1(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]) + e0[0]; - u0[1] += CROSS_x2(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]) + e0[1]; - u0[2] += CROSS_x3(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]) + e0[2]; - - ux1(p) = u0[0]; - ux2(p) = u0[1]; - ux3(p) = u0[2]; - } - - template - Inline void Pusher_kernel::velUpd(Vay_t, - index_t& p, - vec_t& e0, - vec_t& b0) const { - auto COEFF { coeff }; - e0[0] *= COEFF; - e0[1] *= COEFF; - e0[2] *= COEFF; - - b0[0] *= COEFF; - b0[1] *= COEFF; - b0[2] *= COEFF; - - COEFF = ONE / math::sqrt(ONE + NORM_SQR(ux1(p), ux2(p), ux3(p))); - - vec_t u1 { - (ux1(p) + TWO * e0[0] + - CROSS_x1(ux1(p), ux2(p), ux3(p), b0[0], b0[1], b0[2]) * COEFF), - (ux2(p) + TWO * e0[1] + - CROSS_x2(ux1(p), ux2(p), ux3(p), b0[0], b0[1], b0[2]) * COEFF), - (ux3(p) + TWO * e0[2] + - CROSS_x3(ux1(p), ux2(p), ux3(p), b0[0], b0[1], b0[2]) * COEFF) - }; - COEFF = DOT(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]); - auto COEFF2 { ONE + NORM_SQR(u1[0], u1[1], u1[2]) - - NORM_SQR(b0[0], b0[1], b0[2]) }; - - COEFF = ONE / - math::sqrt( - INV_2 * (COEFF2 + math::sqrt(SQR(COEFF2) + - FOUR * (SQR(b0[0]) + SQR(b0[1]) + - SQR(b0[2]) + SQR(COEFF))))); - COEFF2 = ONE / - (ONE + SQR(b0[0] * COEFF) + SQR(b0[1] * COEFF) + SQR(b0[2] * COEFF)); - - ux1(p) = COEFF2 * (u1[0] + - COEFF * DOT(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]) * - (b0[0] * COEFF) + - u1[1] * b0[2] * COEFF - u1[2] * b0[1] * COEFF); - ux2(p) = COEFF2 * (u1[1] + - COEFF * DOT(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]) * - (b0[1] * COEFF) + - u1[2] * b0[0] * COEFF - u1[0] * b0[2] * COEFF); - ux3(p) = COEFF2 * (u1[2] + - COEFF * DOT(u1[0], u1[1], u1[2], b0[0], b0[1], b0[2]) * - (b0[2] * COEFF) + - u1[0] * b0[1] * COEFF - u1[1] * b0[0] * COEFF); - } - - // template - // Inline void Pusher_kernel::velUpd(GCA_t, - // index_t& p, - // #ifdef EXTERNAL_FORCE - // vec_t& f0, - // #endif - // vec_t& e0, - // vec_t& b0) const { - // const auto eb_sqr { NORM_SQR(e0[0], e0[1], e0[2]) + - // NORM_SQR(b0[0], b0[1], b0[2]) }; - - // const vec_t wE { - // CROSS_x1(e0[0], e0[1], e0[2], b0[0], b0[1], b0[2]) / eb_sqr, - // CROSS_x2(e0[0], e0[1], e0[2], b0[0], b0[1], b0[2]) / eb_sqr, - // CROSS_x3(e0[0], e0[1], e0[2], b0[0], b0[1], b0[2]) / eb_sqr - // }; - - // { - // const auto b_norm_inv { ONE / NORM(b0[0], b0[1], b0[2]) }; - // b0[0] *= b_norm_inv; - // b0[1] *= b_norm_inv; - // b0[2] *= b_norm_inv; - // } - // auto upar { DOT(ux1(p), ux2(p), ux3(p), b0[0], b0[1], b0[2]) + - // coeff * TWO * DOT(e0[0], e0[1], e0[2], b0[0], b0[1], b0[2]) }; - - // #ifdef EXTERNAL_FORCE - // upar += dt * DOT(f0[0], f0[1], f0[2], b0[0], b0[1], b0[2]); - // #endif - - // real_t factor; - // { - // const auto wE_sqr { NORM_SQR(wE[0], wE[1], wE[2]) }; - // if (wE_sqr < static_cast(0.01)) { - // factor = ONE + wE_sqr + TWO * SQR(wE_sqr) + FIVE * SQR(wE_sqr) * wE_sqr; - // } else { - // factor = (ONE - math::sqrt(ONE - FOUR * wE_sqr)) / (TWO * wE_sqr); - // } - // } - // const vec_t vE_Cart { wE[0] * factor, wE[1] * factor, wE[2] * factor }; - // const auto Gamma { math::sqrt(ONE + SQR(upar)) / - // math::sqrt( - // ONE - NORM_SQR(vE_Cart[0], vE_Cart[1], vE_Cart[2])) }; - // ux1(p) = upar * b0[0] + vE_Cart[0] * Gamma; - // ux2(p) = upar * b0[1] + vE_Cart[1] * Gamma; - // ux3(p) = upar * b0[2] + vE_Cart[2] * Gamma; - // } - - // Position update - template <> - Inline void Pusher_kernel::posUpd(index_t& p, const vec_t& v) const { - i1_prev(p) = i1(p); - dx1_prev(p) = dx1(p); - posUpd_x1(p, v[0]); - } - - template <> - Inline void Pusher_kernel::posUpd(index_t& p, const vec_t& v) const { - i1_prev(p) = i1(p); - dx1_prev(p) = dx1(p); - i2_prev(p) = i2(p); - dx2_prev(p) = dx2(p); - posUpd_x1(p, v[0]); - posUpd_x2(p, v[1]); -#ifndef MINKOWSKI_METRIC - phi(p) += dt * v[2]; -#endif - } - - template <> - Inline void Pusher_kernel::posUpd(index_t& p, const vec_t& v) const { - i1_prev(p) = i1(p); - dx1_prev(p) = dx1(p); - i2_prev(p) = i2(p); - dx2_prev(p) = dx2(p); - i3_prev(p) = i3(p); - dx3_prev(p) = dx3(p); - posUpd_x1(p, v[0]); - posUpd_x2(p, v[1]); - posUpd_x3(p, v[2]); - } - - // !TODO: check if SIGNf can be done better - template - Inline void Pusher_kernel::posUpd_x1(index_t& p, const real_t& vx1) const { - dx1(p) += static_cast(dt * vx1); - auto temp_i { static_cast(dx1(p)) }; - auto temp_r { math::fmax(SIGNf(dx1(p)) + temp_i, static_cast(temp_i)) - - static_cast(1.0) }; - temp_i = static_cast(temp_r); - i1(p) = i1(p) + temp_i; - dx1(p) = dx1(p) - temp_r; - } - - template - Inline void Pusher_kernel::posUpd_x2(index_t& p, const real_t& vx2) const { - dx2(p) += static_cast(dt * vx2); - auto temp_i { static_cast(dx2(p)) }; - auto temp_r { math::fmax(SIGNf(dx2(p)) + temp_i, static_cast(temp_i)) - - static_cast(1.0) }; - temp_i = static_cast(temp_r); - i2(p) = i2(p) + temp_i; - dx2(p) = dx2(p) - temp_r; - } - - template - Inline void Pusher_kernel::posUpd_x3(index_t& p, const real_t& vx3) const { - dx3(p) += static_cast(dt * vx3); - auto temp_i { static_cast(dx3(p)) }; - auto temp_r { math::fmax(SIGNf(dx3(p)) + temp_i, static_cast(temp_i)) - - static_cast(1.0) }; - temp_i = static_cast(temp_r); - i3(p) = i3(p) + temp_i; - dx3(p) = dx3(p) - temp_r; - } - - // Getters - template - template - Inline void Pusher_kernel::get3VelCntrv(T, - index_t& p, - vec_t& xp, - vec_t& v) const { - metric.v3_Cart2Cntrv(xp, { ux1(p), ux2(p), ux3(p) }, v); - auto inv_energy { ONE / getEnergy(T {}, p) }; - v[0] *= inv_energy; - v[1] *= inv_energy; - v[2] *= inv_energy; - } - -#ifdef MINKOWSKI_METRIC - template <> - Inline void Pusher_kernel::getPrtlPos(index_t& p, coord_t& xp) const { - xp[0] = static_cast(i1(p)) + static_cast(dx1(p)); - } - - template <> - Inline void Pusher_kernel::getPrtlPos(index_t& p, coord_t& xp) const { - xp[0] = static_cast(i1(p)) + static_cast(dx1(p)); - xp[1] = static_cast(i2(p)) + static_cast(dx2(p)); - } -#else - template <> - Inline void Pusher_kernel::getPrtlPos(index_t&, coord_t&) const { - NTTError("not applicable"); - } - - template <> - Inline void Pusher_kernel::getPrtlPos(index_t& p, - coord_t& xp) const { - xp[0] = static_cast(i1(p)) + static_cast(dx1(p)); - xp[1] = static_cast(i2(p)) + static_cast(dx2(p)); - xp[2] = phi(p); - } -#endif - - template <> - Inline void Pusher_kernel::getPrtlPos(index_t& p, coord_t& xp) const { - xp[0] = static_cast(i1(p)) + static_cast(dx1(p)); - xp[1] = static_cast(i2(p)) + static_cast(dx2(p)); - xp[2] = static_cast(i3(p)) + static_cast(dx3(p)); - } - - template - Inline auto Pusher_kernel::getEnergy(Massive_t, index_t& p) const -> real_t { - return math::sqrt(ONE + SQR(ux1(p)) + SQR(ux2(p)) + SQR(ux3(p))); - } - - template - Inline auto Pusher_kernel::getEnergy(Massless_t, index_t& p) const -> real_t { - return math::sqrt(SQR(ux1(p)) + SQR(ux2(p)) + SQR(ux3(p))); - } - - template <> - Inline void Pusher_kernel::getInterpFlds(index_t& p, - vec_t& e0, - vec_t& b0) const { - const int i { i1(p) + static_cast(N_GHOSTS) }; - const auto dx1_ { static_cast(dx1(p)) }; - - // first order - real_t c0, c1; - - // Ex1 - // interpolate to nodes - c0 = HALF * (EB(i, em::ex1) + EB(i - 1, em::ex1)); - c1 = HALF * (EB(i, em::ex1) + EB(i + 1, em::ex1)); - // interpolate from nodes to the particle position - e0[0] = c0 * (ONE - dx1_) + c1 * dx1_; - // Ex2 - c0 = EB(i, em::ex2); - c1 = EB(i + 1, em::ex2); - e0[1] = c0 * (ONE - dx1_) + c1 * dx1_; - // Ex3 - c0 = EB(i, em::ex3); - c1 = EB(i + 1, em::ex3); - e0[2] = c0 * (ONE - dx1_) + c1 * dx1_; - - // Bx1 - c0 = EB(i, em::bx1); - c1 = EB(i + 1, em::bx1); - b0[0] = c0 * (ONE - dx1_) + c1 * dx1_; - // Bx2 - c0 = HALF * (EB(i - 1, em::bx2) + EB(i, em::bx2)); - c1 = HALF * (EB(i, em::bx2) + EB(i + 1, em::bx2)); - b0[1] = c0 * (ONE - dx1_) + c1 * dx1_; - // Bx3 - c0 = HALF * (EB(i - 1, em::bx3) + EB(i, em::bx3)); - c1 = HALF * (EB(i, em::bx3) + EB(i + 1, em::bx3)); - b0[2] = c0 * (ONE - dx1_) + c1 * dx1_; - } - - template <> - Inline void Pusher_kernel::getInterpFlds(index_t& p, - vec_t& e0, - vec_t& b0) const { - const int i { i1(p) + static_cast(N_GHOSTS) }; - const int j { i2(p) + static_cast(N_GHOSTS) }; - const auto dx1_ { static_cast(dx1(p)) }; - const auto dx2_ { static_cast(dx2(p)) }; - - // first order - real_t c000, c100, c010, c110, c00, c10; - - // Ex1 - // interpolate to nodes - c000 = HALF * (EB(i, j, em::ex1) + EB(i - 1, j, em::ex1)); - c100 = HALF * (EB(i, j, em::ex1) + EB(i + 1, j, em::ex1)); - c010 = HALF * (EB(i, j + 1, em::ex1) + EB(i - 1, j + 1, em::ex1)); - c110 = HALF * (EB(i, j + 1, em::ex1) + EB(i + 1, j + 1, em::ex1)); - // interpolate from nodes to the particle position - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - e0[0] = c00 * (ONE - dx2_) + c10 * dx2_; - // Ex2 - c000 = HALF * (EB(i, j, em::ex2) + EB(i, j - 1, em::ex2)); - c100 = HALF * (EB(i + 1, j, em::ex2) + EB(i + 1, j - 1, em::ex2)); - c010 = HALF * (EB(i, j, em::ex2) + EB(i, j + 1, em::ex2)); - c110 = HALF * (EB(i + 1, j, em::ex2) + EB(i + 1, j + 1, em::ex2)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - e0[1] = c00 * (ONE - dx2_) + c10 * dx2_; - // Ex3 - c000 = EB(i, j, em::ex3); - c100 = EB(i + 1, j, em::ex3); - c010 = EB(i, j + 1, em::ex3); - c110 = EB(i + 1, j + 1, em::ex3); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - e0[2] = c00 * (ONE - dx2_) + c10 * dx2_; - - // Bx1 - c000 = HALF * (EB(i, j, em::bx1) + EB(i, j - 1, em::bx1)); - c100 = HALF * (EB(i + 1, j, em::bx1) + EB(i + 1, j - 1, em::bx1)); - c010 = HALF * (EB(i, j, em::bx1) + EB(i, j + 1, em::bx1)); - c110 = HALF * (EB(i + 1, j, em::bx1) + EB(i + 1, j + 1, em::bx1)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - b0[0] = c00 * (ONE - dx2_) + c10 * dx2_; - // Bx2 - c000 = HALF * (EB(i - 1, j, em::bx2) + EB(i, j, em::bx2)); - c100 = HALF * (EB(i, j, em::bx2) + EB(i + 1, j, em::bx2)); - c010 = HALF * (EB(i - 1, j + 1, em::bx2) + EB(i, j + 1, em::bx2)); - c110 = HALF * (EB(i, j + 1, em::bx2) + EB(i + 1, j + 1, em::bx2)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - b0[1] = c00 * (ONE - dx2_) + c10 * dx2_; - // Bx3 - c000 = INV_4 * (EB(i - 1, j - 1, em::bx3) + EB(i - 1, j, em::bx3) + - EB(i, j - 1, em::bx3) + EB(i, j, em::bx3)); - c100 = INV_4 * (EB(i, j - 1, em::bx3) + EB(i, j, em::bx3) + - EB(i + 1, j - 1, em::bx3) + EB(i + 1, j, em::bx3)); - c010 = INV_4 * (EB(i - 1, j, em::bx3) + EB(i - 1, j + 1, em::bx3) + - EB(i, j, em::bx3) + EB(i, j + 1, em::bx3)); - c110 = INV_4 * (EB(i, j, em::bx3) + EB(i, j + 1, em::bx3) + - EB(i + 1, j, em::bx3) + EB(i + 1, j + 1, em::bx3)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - b0[2] = c00 * (ONE - dx2_) + c10 * dx2_; - } - - template <> - Inline void Pusher_kernel::getInterpFlds(index_t& p, - vec_t& e0, - vec_t& b0) const { - const int i { i1(p) + static_cast(N_GHOSTS) }; - const int j { i2(p) + static_cast(N_GHOSTS) }; - const int k { i3(p) + static_cast(N_GHOSTS) }; - const auto dx1_ { static_cast(dx1(p)) }; - const auto dx2_ { static_cast(dx2(p)) }; - const auto dx3_ { static_cast(dx3(p)) }; - - // first order - real_t c000, c100, c010, c110, c001, c101, c011, c111, c00, c10, c01, c11, - c0, c1; - - // Ex1 - // interpolate to nodes - c000 = HALF * (EB(i, j, k, em::ex1) + EB(i - 1, j, k, em::ex1)); - c100 = HALF * (EB(i, j, k, em::ex1) + EB(i + 1, j, k, em::ex1)); - c010 = HALF * (EB(i, j + 1, k, em::ex1) + EB(i - 1, j + 1, k, em::ex1)); - c110 = HALF * (EB(i, j + 1, k, em::ex1) + EB(i + 1, j + 1, k, em::ex1)); - // interpolate from nodes to the particle position - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - c0 = c00 * (ONE - dx2_) + c10 * dx2_; - // interpolate to nodes - c001 = HALF * (EB(i, j, k + 1, em::ex1) + EB(i - 1, j, k + 1, em::ex1)); - c101 = HALF * (EB(i, j, k + 1, em::ex1) + EB(i + 1, j, k + 1, em::ex1)); - c011 = HALF * - (EB(i, j + 1, k + 1, em::ex1) + EB(i - 1, j + 1, k + 1, em::ex1)); - c111 = HALF * - (EB(i, j + 1, k + 1, em::ex1) + EB(i + 1, j + 1, k + 1, em::ex1)); - // interpolate from nodes to the particle position - c01 = c001 * (ONE - dx1_) + c101 * dx1_; - c11 = c011 * (ONE - dx1_) + c111 * dx1_; - c1 = c01 * (ONE - dx2_) + c11 * dx2_; - e0[0] = c0 * (ONE - dx3_) + c1 * dx3_; - - // Ex2 - c000 = HALF * (EB(i, j, k, em::ex2) + EB(i, j - 1, k, em::ex2)); - c100 = HALF * (EB(i + 1, j, k, em::ex2) + EB(i + 1, j - 1, k, em::ex2)); - c010 = HALF * (EB(i, j, k, em::ex2) + EB(i, j + 1, k, em::ex2)); - c110 = HALF * (EB(i + 1, j, k, em::ex2) + EB(i + 1, j + 1, k, em::ex2)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - c0 = c00 * (ONE - dx2_) + c10 * dx2_; - c001 = HALF * (EB(i, j, k + 1, em::ex2) + EB(i, j - 1, k + 1, em::ex2)); - c101 = HALF * - (EB(i + 1, j, k + 1, em::ex2) + EB(i + 1, j - 1, k + 1, em::ex2)); - c011 = HALF * (EB(i, j, k + 1, em::ex2) + EB(i, j + 1, k + 1, em::ex2)); - c111 = HALF * - (EB(i + 1, j, k + 1, em::ex2) + EB(i + 1, j + 1, k + 1, em::ex2)); - c01 = c001 * (ONE - dx1_) + c101 * dx1_; - c11 = c011 * (ONE - dx1_) + c111 * dx1_; - c1 = c01 * (ONE - dx2_) + c11 * dx2_; - e0[1] = c0 * (ONE - dx3_) + c1 * dx3_; - - // Ex3 - c000 = HALF * (EB(i, j, k, em::ex3) + EB(i, j, k - 1, em::ex3)); - c100 = HALF * (EB(i + 1, j, k, em::ex3) + EB(i + 1, j, k - 1, em::ex3)); - c010 = HALF * (EB(i, j + 1, k, em::ex3) + EB(i, j + 1, k - 1, em::ex3)); - c110 = HALF * - (EB(i + 1, j + 1, k, em::ex3) + EB(i + 1, j + 1, k - 1, em::ex3)); - c001 = HALF * (EB(i, j, k, em::ex3) + EB(i, j, k + 1, em::ex3)); - c101 = HALF * (EB(i + 1, j, k, em::ex3) + EB(i + 1, j, k + 1, em::ex3)); - c011 = HALF * (EB(i, j + 1, k, em::ex3) + EB(i, j + 1, k + 1, em::ex3)); - c111 = HALF * - (EB(i + 1, j + 1, k, em::ex3) + EB(i + 1, j + 1, k + 1, em::ex3)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c01 = c001 * (ONE - dx1_) + c101 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - c11 = c011 * (ONE - dx1_) + c111 * dx1_; - c0 = c00 * (ONE - dx2_) + c10 * dx2_; - c1 = c01 * (ONE - dx2_) + c11 * dx2_; - e0[2] = c0 * (ONE - dx3_) + c1 * dx3_; - - // Bx1 - c000 = INV_4 * (EB(i, j, k, em::bx1) + EB(i, j - 1, k, em::bx1) + - EB(i, j, k - 1, em::bx1) + EB(i, j - 1, k - 1, em::bx1)); - c100 = INV_4 * - (EB(i + 1, j, k, em::bx1) + EB(i + 1, j - 1, k, em::bx1) + - EB(i + 1, j, k - 1, em::bx1) + EB(i + 1, j - 1, k - 1, em::bx1)); - c001 = INV_4 * (EB(i, j, k, em::bx1) + EB(i, j, k + 1, em::bx1) + - EB(i, j - 1, k, em::bx1) + EB(i, j - 1, k + 1, em::bx1)); - c101 = INV_4 * - (EB(i + 1, j, k, em::bx1) + EB(i + 1, j, k + 1, em::bx1) + - EB(i + 1, j - 1, k, em::bx1) + EB(i + 1, j - 1, k + 1, em::bx1)); - c010 = INV_4 * (EB(i, j, k, em::bx1) + EB(i, j + 1, k, em::bx1) + - EB(i, j, k - 1, em::bx1) + EB(i, j + 1, k - 1, em::bx1)); - c110 = INV_4 * - (EB(i + 1, j, k, em::bx1) + EB(i + 1, j, k - 1, em::bx1) + - EB(i + 1, j + 1, k - 1, em::bx1) + EB(i + 1, j + 1, k, em::bx1)); - c011 = INV_4 * (EB(i, j, k, em::bx1) + EB(i, j + 1, k, em::bx1) + - EB(i, j + 1, k + 1, em::bx1) + EB(i, j, k + 1, em::bx1)); - c111 = INV_4 * - (EB(i + 1, j, k, em::bx1) + EB(i + 1, j + 1, k, em::bx1) + - EB(i + 1, j + 1, k + 1, em::bx1) + EB(i + 1, j, k + 1, em::bx1)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c01 = c001 * (ONE - dx1_) + c101 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - c11 = c011 * (ONE - dx1_) + c111 * dx1_; - c0 = c00 * (ONE - dx2_) + c10 * dx2_; - c1 = c01 * (ONE - dx2_) + c11 * dx2_; - b0[0] = c0 * (ONE - dx3_) + c1 * dx3_; - - // Bx2 - c000 = INV_4 * (EB(i - 1, j, k - 1, em::bx2) + EB(i - 1, j, k, em::bx2) + - EB(i, j, k - 1, em::bx2) + EB(i, j, k, em::bx2)); - c100 = INV_4 * (EB(i, j, k - 1, em::bx2) + EB(i, j, k, em::bx2) + - EB(i + 1, j, k - 1, em::bx2) + EB(i + 1, j, k, em::bx2)); - c001 = INV_4 * (EB(i - 1, j, k, em::bx2) + EB(i - 1, j, k + 1, em::bx2) + - EB(i, j, k, em::bx2) + EB(i, j, k + 1, em::bx2)); - c101 = INV_4 * (EB(i, j, k, em::bx2) + EB(i, j, k + 1, em::bx2) + - EB(i + 1, j, k, em::bx2) + EB(i + 1, j, k + 1, em::bx2)); - c010 = INV_4 * - (EB(i - 1, j + 1, k - 1, em::bx2) + EB(i - 1, j + 1, k, em::bx2) + - EB(i, j + 1, k - 1, em::bx2) + EB(i, j + 1, k, em::bx2)); - c110 = INV_4 * - (EB(i, j + 1, k - 1, em::bx2) + EB(i, j + 1, k, em::bx2) + - EB(i + 1, j + 1, k - 1, em::bx2) + EB(i + 1, j + 1, k, em::bx2)); - c011 = INV_4 * - (EB(i - 1, j + 1, k, em::bx2) + EB(i - 1, j + 1, k + 1, em::bx2) + - EB(i, j + 1, k, em::bx2) + EB(i, j + 1, k + 1, em::bx2)); - c111 = INV_4 * - (EB(i, j + 1, k, em::bx2) + EB(i, j + 1, k + 1, em::bx2) + - EB(i + 1, j + 1, k, em::bx2) + EB(i + 1, j + 1, k + 1, em::bx2)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c01 = c001 * (ONE - dx1_) + c101 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - c11 = c011 * (ONE - dx1_) + c111 * dx1_; - c0 = c00 * (ONE - dx2_) + c10 * dx2_; - c1 = c01 * (ONE - dx2_) + c11 * dx2_; - b0[1] = c0 * (ONE - dx3_) + c1 * dx3_; - - // Bx3 - c000 = INV_4 * (EB(i - 1, j - 1, k, em::bx3) + EB(i - 1, j, k, em::bx3) + - EB(i, j - 1, k, em::bx3) + EB(i, j, k, em::bx3)); - c100 = INV_4 * (EB(i, j - 1, k, em::bx3) + EB(i, j, k, em::bx3) + - EB(i + 1, j - 1, k, em::bx3) + EB(i + 1, j, k, em::bx3)); - c001 = INV_4 * - (EB(i - 1, j - 1, k + 1, em::bx3) + EB(i - 1, j, k + 1, em::bx3) + - EB(i, j - 1, k + 1, em::bx3) + EB(i, j, k + 1, em::bx3)); - c101 = INV_4 * - (EB(i, j - 1, k + 1, em::bx3) + EB(i, j, k + 1, em::bx3) + - EB(i + 1, j - 1, k + 1, em::bx3) + EB(i + 1, j, k + 1, em::bx3)); - c010 = INV_4 * (EB(i - 1, j, k, em::bx3) + EB(i - 1, j + 1, k, em::bx3) + - EB(i, j, k, em::bx3) + EB(i, j + 1, k, em::bx3)); - c110 = INV_4 * (EB(i, j, k, em::bx3) + EB(i, j + 1, k, em::bx3) + - EB(i + 1, j, k, em::bx3) + EB(i + 1, j + 1, k, em::bx3)); - c011 = INV_4 * - (EB(i - 1, j, k + 1, em::bx3) + EB(i - 1, j + 1, k + 1, em::bx3) + - EB(i, j, k + 1, em::bx3) + EB(i, j + 1, k + 1, em::bx3)); - c111 = INV_4 * - (EB(i, j, k + 1, em::bx3) + EB(i, j + 1, k + 1, em::bx3) + - EB(i + 1, j, k + 1, em::bx3) + EB(i + 1, j + 1, k + 1, em::bx3)); - c00 = c000 * (ONE - dx1_) + c100 * dx1_; - c01 = c001 * (ONE - dx1_) + c101 * dx1_; - c10 = c010 * (ONE - dx1_) + c110 * dx1_; - c11 = c011 * (ONE - dx1_) + c111 * dx1_; - c0 = c00 * (ONE - dx2_) + c10 * dx2_; - c1 = c01 * (ONE - dx2_) + c11 * dx2_; - b0[2] = c0 * (ONE - dx3_) + c1 * dx3_; - } - - // Boundary conditions - - // template - // Inline void Pusher_kernel::boundaryConditions_x1(index_t& p) const { - // if (i1(p) < 0) { - // if (is_periodic_i1min) { - // i1(p) += ni1; - // i1_prev(p) += ni1; - // } else if (is_absorb_i1min) { - // tag(p) = ParticleTag::dead; - // } - // } else if (i1(p) >= ni1) { - // if (is_periodic_i1max) { - // i1(p) -= ni1; - // i1_prev(p) -= ni1; - // } else if (is_absorb_i1max) { - // tag(p) = ParticleTag::dead; - // } - // } - // } - - // template - // Inline void Pusher_kernel::boundaryConditions_x2(index_t& p) const { - // if (i2(p) < 0) { - // if (is_periodic_i2min) { - // i2(p) += ni2; - // i2_prev(p) += ni2; - // } else if (is_absorb_i2min) { - // tag(p) = ParticleTag::dead; - // } else if (is_ax_i2min) { - // i2(p) = 0; - // dx2(p) = ONE - dx2(p); - // ux1(p) = -ux1(p); - // } - // } else if (i2(p) >= ni2) { - // if (is_periodic_i2max) { - // i2(p) -= ni2; - // i2_prev(p) -= ni2; - // } else if (is_absorb_i2max) { - // tag(p) = ParticleTag::dead; - // } else if (is_ax_i2max) { - // i2(p) = ni2 - 1; - // i2_prev(p) = ni2 - 1; - // dx2(p) = ONE - dx2(p); - // ux1(p) = -ux1(p); - // } - // } - // } - - // template <> - // Inline void Pusher_kernel::boundaryConditions_x3(index_t& p) const { - // if (i3(p) < 0) { - // if (is_periodic_i3min) { - // i3(p) += ni3; - // i3_prev(p) += ni3; - // } else if (is_absorb_i3min) { - // tag(p) = ParticleTag::dead; - // } - // } else if (i3(p) >= ni3) { - // if (is_periodic_i3max) { - // i3(p) -= ni3; - // i3_prev(p) -= ni3; - // } else if (is_absorb_i3max) { - // tag(p) = ParticleTag::dead; - // } - // } - // } - - // template <> - // Inline void Pusher_kernel::boundaryConditions(index_t& p) const { - // boundaryConditions_x1(p); - // } - - // template <> - // Inline void Pusher_kernel::boundaryConditions(index_t& p) const { - // boundaryConditions_x1(p); - // boundaryConditions_x2(p); - // } - - // template <> - // Inline void Pusher_kernel::boundaryConditions(index_t& p) const { - // boundaryConditions_x1(p); - // boundaryConditions_x2(p); - // boundaryConditions_x3(p); - // } - - // External force - -#ifdef EXTERNAL_FORCE - - #ifdef MINKOWSKI_METRIC - template - Inline void Pusher_kernel::initForce(coord_t& xp, - vec_t& force_Cart) const { - coord_t xp_Ph { ZERO }; - metric.x_Code2Cart(xp, xp_Ph); - const vec_t force_Hat { pgen.ext_force_x1(time, xp_Ph), - pgen.ext_force_x2(time, xp_Ph), - pgen.ext_force_x3(time, xp_Ph) }; - metric.v3_Hat2Cart(xp, force_Hat, force_Cart); - } - #else - template - Inline void Pusher_kernel::initForce(coord_t& xp, - vec_t& force_Cart) const { - coord_t xp_Ph { ZERO }; - coord_t xp_Code { ZERO }; - for (short d { 0 }; d < static_cast(PrtlCoordD); ++d) { - xp_Code[d] = xp[d]; - } - metric.x_Code2Sph(xp_Code, xp_Ph); - const vec_t force_Hat { pgen.ext_force_x1(time, xp_Ph), - pgen.ext_force_x2(time, xp_Ph), - pgen.ext_force_x3(time, xp_Ph) }; - metric.v3_Hat2Cart(xp_Code, force_Hat, force_Cart); - } - #endif - - template - Inline void Pusher_kernel::forceHalfUpdate(index_t& p, - vec_t& force_Cart) const { - ux1(p) += HALF * dt * force_Cart[0]; - ux2(p) += HALF * dt * force_Cart[1]; - ux3(p) += HALF * dt * force_Cart[2]; - } - -#endif - -} // namespace ntt -#endif diff --git a/legacy/src/pic/pgen/old/debug.cpp b/legacy/src/pic/pgen/old/debug.cpp deleted file mode 100644 index 944f5a872..000000000 --- a/legacy/src/pic/pgen/old/debug.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "wrapper.h" -#include "io/input.h" -#include "sim_params.h" -#include "meshblock/meshblock.h" -#include "particle_macros.h" - -#include "problem_generator.hpp" - -#include - -namespace ntt { - - template <> - void ProblemGenerator::UserInitFields(const SimulationParams&, - Meshblock& mblock) { - - Kokkos::parallel_for( - "UserInitFlds", mblock.rangeActiveCells(), Lambda(index_t i, index_t j) { - real_t i_ {(real_t)(static_cast(i) - N_GHOSTS)}, - j_ {(real_t)(static_cast(j) - N_GHOSTS)}; - real_t ex2_hat {0.1}, bx3_hat {1.0}; - vec_t e_cntrv, b_cntrv; - mblock.metric.v_Hat2Cntrv({i_ + HALF, j_}, {ZERO, ex2_hat, ZERO}, e_cntrv); - mblock.metric.v_Hat2Cntrv({i_ + HALF, j_ + HALF}, {ZERO, ZERO, bx3_hat}, b_cntrv); - mblock.em(i, j, em::ex1) = ZERO; - mblock.em(i, j, em::ex2) = ZERO; - mblock.em(i, j, em::ex3) = ZERO; - mblock.em(i, j, em::bx1) = ZERO; - mblock.em(i, j, em::bx2) = ZERO; - mblock.em(i, j, em::bx3) = ZERO; - }); - } - - template <> - void ProblemGenerator::UserInitParticles(const SimulationParams&, - Meshblock& mblock) { - auto& electrons = mblock.particles[0]; - auto& positrons = mblock.particles[1]; - auto random_pool = *(mblock.random_pool_ptr); - Kokkos::parallel_for( - "UserInitPrtls", CreateRangePolicy({0}, {1}), Lambda(index_t p) { - typename RandomNumberPool_t::generator_type rand_gen = random_pool.get_state(); - real_t rx = rand_gen.frand((real_t)(-2.0), (real_t)(2.0)); - real_t ry = rand_gen.frand((real_t)(-2.0), (real_t)(2.0)); - init_prtl_2d_XYZ(mblock, electrons, p, rx, ry, 1.0, 0.0, 0.0); - init_prtl_2d_XYZ(mblock, positrons, p, rx, ry, 1.0, 0.0, 0.0); - // init_prtl_2d_XYZ(&mblock, 2, p, 0.1, 0.12, 1.0, 0.0, 0.0); - // init_prtl_2d_XYZ(&mblock, 3, p, 0.1, 0.12, 1.0, 0.0, 0.0); - }); - electrons.setNpart(1); - positrons.setNpart(1); - // mblock.particles[2].setNpart(1); - // mblock.particles[3].setNpart(1); - } - // 1D - template <> - void ProblemGenerator::UserInitFields(const SimulationParams&, - Meshblock&) {} - template <> - void ProblemGenerator::UserInitParticles(const SimulationParams&, - Meshblock&) {} - - // 3D - template <> - void ProblemGenerator::UserInitFields(const SimulationParams&, - Meshblock&) {} - template <> - void ProblemGenerator::UserInitParticles(const SimulationParams&, - Meshblock&) {} - -} // namespace ntt - -template struct ntt::ProblemGenerator; -template struct ntt::ProblemGenerator; -template struct ntt::ProblemGenerator; diff --git a/legacy/src/pic/pgen/old/debug.hpp b/legacy/src/pic/pgen/old/debug.hpp deleted file mode 100644 index 06108ad2c..000000000 --- a/legacy/src/pic/pgen/old/debug.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef PROBLEM_GENERATOR_H -#define PROBLEM_GENERATOR_H - -#include "wrapper.h" -#include "sim_params.h" -#include "meshblock/meshblock.h" - -namespace ntt { - - template - struct ProblemGenerator { - ProblemGenerator(const SimulationParams&) {} - - void UserInitFields(const SimulationParams&, Meshblock&); - void UserInitParticles(const SimulationParams&, Meshblock&); - void UserBCFields(const real_t&, const SimulationParams&, Meshblock&); - Inline auto UserTargetField_br_hat(const Meshblock&, const coord_t&) const - -> real_t { - return ZERO; - } - void UserDriveParticles(const real_t&, const SimulationParams&, Meshblock&) {} - }; - -} // namespace ntt - -#endif diff --git a/legacy/src/pic/pgen/old/deposit.cpp b/legacy/src/pic/pgen/old/deposit.cpp deleted file mode 100644 index 568e68ea9..000000000 --- a/legacy/src/pic/pgen/old/deposit.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "wrapper.h" -#include "io/input.h" -#include "sim_params.h" -#include "meshblock/meshblock.h" - -#include "problem_generator.hpp" - -#include - -namespace ntt { - - template <> - void ProblemGenerator::userInitFields( - const SimulationParams&, Meshblock& mblock) { - - Kokkos::parallel_for( - "userInitFlds", mblock.rangeActiveCells(), Lambda(index_t i, index_t j) { - real_t i_ {(real_t)(static_cast(i) - N_GHOSTS)}, - j_ {(real_t)(static_cast(j) - N_GHOSTS)}; - // real_t ex2_hat {0.1}, bx3_hat {1.0}; - // vec_t e_cntrv, b_cntrv; - // mblock.metric.v_Hat2Cntrv({i_ + HALF, j_}, {ZERO, ex2_hat, ZERO}, e_cntrv); - // mblock.metric.v_Hat2Cntrv({i_ + HALF, j_ + HALF}, {ZERO, ZERO, bx3_hat}, b_cntrv); - mblock.em(i, j, em::ex1) = ZERO; - mblock.em(i, j, em::ex2) = ZERO; // e_cntrv[1]; - mblock.em(i, j, em::ex3) = ZERO; - mblock.em(i, j, em::bx1) = ZERO; - mblock.em(i, j, em::bx2) = ZERO; - mblock.em(i, j, em::bx3) = ZERO; // b_cntrv[2]; - }); - } - - template <> - void ProblemGenerator::userInitParticles( - const SimulationParams&, Meshblock& mblock) { - - Kokkos::parallel_for( - "userInitPrtls", CreateRangePolicy({0}, {1}), Lambda(index_t p) { - coord_t x {0.0, 0.0}, x_CU; - mblock.metric.x_Cart2Code(x, x_CU); - auto [i1, dx1] = mblock.metric.CU_to_Idi(x_CU[0]); - auto [i2, dx2] = mblock.metric.CU_to_Idi(x_CU[1]); - // electron - mblock.particles[0].i1(p) = i1; - mblock.particles[0].i2(p) = i2; - mblock.particles[0].dx1(p) = dx1; - mblock.particles[0].dx2(p) = dx2; - // mblock.particles[0].ux1(p) = -2.0; - // mblock.particles[0].ux2(p) = -5.0; - mblock.particles[0].ux1(p) = 12.0; - // positron - mblock.particles[1].i1(p) = i1; - mblock.particles[1].i2(p) = i2; - mblock.particles[1].dx1(p) = dx1; - mblock.particles[1].dx2(p) = dx2; - // mblock.particles[0].ux1(p) = -2.0; - // mblock.particles[0].ux2(p) = 6.0; - // mblock.particles[1].ux3(p) = 0.0; - }); - mblock.particles[0].setNpart(1); - mblock.particles[1].setNpart(1); - } - // 1D - template <> - void ProblemGenerator::userInitFields( - const SimulationParams&, Meshblock&) {} - template <> - void ProblemGenerator::userInitParticles( - const SimulationParams&, Meshblock&) {} - - // 3D - template <> - void ProblemGenerator::userInitFields( - const SimulationParams&, Meshblock&) {} - template <> - void ProblemGenerator::userInitParticles( - const SimulationParams&, Meshblock&) {} - -} // namespace ntt - -template struct ntt::ProblemGenerator; -template struct ntt::ProblemGenerator; -template struct ntt::ProblemGenerator; \ No newline at end of file diff --git a/legacy/src/pic/pgen/old/deposit.hpp b/legacy/src/pic/pgen/old/deposit.hpp deleted file mode 100644 index 323f05297..000000000 --- a/legacy/src/pic/pgen/old/deposit.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef PROBLEM_GENERATOR_H -#define PROBLEM_GENERATOR_H - -#include "wrapper.h" -#include "sim_params.h" -#include "meshblock/meshblock.h" - -namespace ntt { - - template - struct ProblemGenerator { - ProblemGenerator(const SimulationParams&) {} - - void userInitFields(const SimulationParams&, Meshblock&); - void userInitParticles(const SimulationParams&, Meshblock&); - void userBCFields(const real_t&, const SimulationParams&, Meshblock&); - Inline auto userTargetField_br_hat(const Meshblock&, const coord_t&) const - -> real_t { - return ZERO; - } - }; -} // namespace ntt - -#endif diff --git a/legacy/src/pic/pgen/old/em.cpp b/legacy/src/pic/pgen/old/em.cpp deleted file mode 100644 index bb790de3c..000000000 --- a/legacy/src/pic/pgen/old/em.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "wrapper.h" -#include "io/input.h" -#include "field_macros.h" -#include "sim_params.h" -#include "meshblock/meshblock.h" - -#include "problem_generator.hpp" - -namespace ntt { - - template <> - ProblemGenerator::ProblemGenerator(const SimulationParams& params) { - m_nx1 = readFromInput(params.inputdata(), "problem", "nx1", 1); - m_nx2 = readFromInput(params.inputdata(), "problem", "nx2", 1); - m_amplitude = readFromInput(params.inputdata(), "problem", "amplitude", 1.0); - } - - Inline void emWaveField(const coord_t& x_ph, - vec_t& e_out, - vec_t& b_out, - real_t ex_ampl, - real_t ey_ampl, - real_t bz_ampl, - real_t kx, - real_t ky) { - e_out[0] = ex_ampl * math::sin(kx * x_ph[0] + ky * x_ph[1]); - e_out[1] = ey_ampl * math::sin(kx * x_ph[0] + ky * x_ph[1]); - b_out[2] = bz_ampl * math::sin(kx * x_ph[0] + ky * x_ph[1]); - } - - template <> - void ProblemGenerator::UserInitParticles(const SimulationParams&, - Meshblock&) {} - - template <> - void ProblemGenerator::UserInitFields(const SimulationParams&, - Meshblock& mblock) { - - real_t sx = mblock.metric.x1_max - mblock.metric.x1_min; - real_t sy = mblock.metric.x2_max - mblock.metric.x2_min; - real_t kx = constant::TWO_PI * m_nx1 / sx; - real_t ky = constant::TWO_PI * m_nx2 / sy; - real_t ex_ampl, ey_ampl, bz_ampl = m_amplitude; - ex_ampl = -ky; - ey_ampl = kx; - ex_ampl = m_amplitude * ex_ampl / math::sqrt(ex_ampl * ex_ampl + ey_ampl * ey_ampl); - ey_ampl = m_amplitude * ey_ampl / math::sqrt(ex_ampl * ex_ampl + ey_ampl * ey_ampl); - Kokkos::parallel_for( - "userInitFlds", mblock.rangeActiveCells(), Lambda(index_t i, index_t j) { - set_em_fields_2d(mblock, i, j, emWaveField, ex_ampl, ey_ampl, bz_ampl, kx, ky); - }); - } - - template <> - void ProblemGenerator::UserDriveParticles(const real_t&, - const SimulationParams&, - Meshblock&) {} - - template <> - void ProblemGenerator::UserBCFields(const real_t&, - const SimulationParams&, - Meshblock&) {} - template <> - Inline auto ProblemGenerator::UserTargetField_br_hat( - const Meshblock&, const coord_t&) const -> real_t { - return ZERO; - } - - // clang-format off - @PgenPlaceholder1D@ - @PgenPlaceholder3D@ - // clang-format on - -} // namespace ntt - -template struct ntt::ProblemGenerator; -template struct ntt::ProblemGenerator; -template struct ntt::ProblemGenerator; - -// real_t ex_ampl, ey_ampl, bz_ampl {m_amplitude}; -// ex_ampl = -ky; -// ey_ampl = kx; -// ex_ampl = m_amplitude * ex_ampl / math::sqrt(ex_ampl * ex_ampl + ey_ampl * ey_ampl); -// ey_ampl = m_amplitude * ey_ampl / math::sqrt(ex_ampl * ex_ampl + ey_ampl * ey_ampl); -// Kokkos::parallel_for( -// "userInitFlds", mblock.rangeActiveCells(), Lambda(index_t i, index_t j) { -// // index to code units -// real_t i_ {(real_t)(static_cast(i) - N_GHOSTS)}, -// j_ {(real_t)(static_cast(j) - N_GHOSTS)}; - -// // code units to cartesian (physical units) -// coord_t xy_, xy_half; -// mblock.metric.x_Code2Cart({i_, j_}, xy_); -// mblock.metric.x_Code2Cart({i_ + HALF, j_ + HALF}, xy_half); - -// // hatted fields -// real_t ex_hat {ex_ampl * math::sin(kx * xy_half[0] + ky * xy_[1])}; -// real_t ey_hat {ey_ampl * math::sin(kx * xy_[0] + ky * xy_half[1])}; -// real_t bz_hat {bz_ampl * math::sin(kx * xy_half[0] + ky * xy_half[1])}; - -// vec_t ex_cntr, ey_cntr, bz_cntr; -// mblock.metric.v_Hat2Cntrv({i_ + HALF, j_}, {ex_hat, ZERO, ZERO}, ex_cntr); -// mblock.metric.v_Hat2Cntrv({i_, j_ + HALF}, {ZERO, ey_hat, ZERO}, ey_cntr); -// mblock.metric.v_Hat2Cntrv({i_ + HALF, j_ + HALF}, {ZERO, ZERO, bz_hat}, bz_cntr); - -// mblock.em(i, j, em::ex1) = ex_cntr[0]; -// mblock.em(i, j, em::ex2) = ey_cntr[1]; -// mblock.em(i, j, em::bx3) = bz_cntr[2]; -// }); diff --git a/legacy/src/pic/pgen/old/em.hpp b/legacy/src/pic/pgen/old/em.hpp deleted file mode 100644 index a1db5785d..000000000 --- a/legacy/src/pic/pgen/old/em.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef PROBLEM_GENERATOR_H -#define PROBLEM_GENERATOR_H - -#include "wrapper.h" -#include "sim_params.h" -#include "meshblock/meshblock.h" - -namespace ntt { - - template - struct ProblemGenerator { - ProblemGenerator(const SimulationParams&); - - void UserInitFields(const SimulationParams&, Meshblock&); - void UserInitParticles(const SimulationParams&, Meshblock&); - void UserBCFields(const real_t&, const SimulationParams&, Meshblock&); - Inline auto UserTargetField_br_hat(const Meshblock&, const coord_t&) const - -> real_t; - void UserDriveParticles(const real_t&, const SimulationParams&, Meshblock&); - - private: - int m_nx1, m_nx2; - real_t m_amplitude; - }; - -} // namespace ntt - -#endif \ No newline at end of file diff --git a/legacy/src/pic/pgen/old/magnetosphere.hpp b/legacy/src/pic/pgen/old/magnetosphere.hpp deleted file mode 100644 index 15aedc28e..000000000 --- a/legacy/src/pic/pgen/old/magnetosphere.hpp +++ /dev/null @@ -1,220 +0,0 @@ - -#ifndef PROBLEM_GENERATOR_H -#define PROBLEM_GENERATOR_H - -#include "wrapper.h" - -#include "field_macros.h" -#include "sim_params.h" - -#include "meshblock/meshblock.h" - -#include "utils/archetypes.hpp" -#include "utils/injector.hpp" - -namespace ntt { - enum FieldMode { MonopoleField = 1, DipoleField = 2 }; - - template - struct ProblemGenerator : public PGen { - inline ProblemGenerator(const SimulationParams& params) - : r_surf { params.get("problem", "r_surf", (real_t)(1.0)) }, - b_surf { params.get("problem", "b_surf", (real_t)(1.0)) }, - spin_omega { params.get("problem", "spin_omega") }, - spinup_time { params.get("problem", "spinup_time", 0.0) }, - inj_fraction { params.get("problem", "inj_fraction", (real_t)(0.1)) }, - field_mode { params.get("problem", "field_mode", 2) == 2 ? DipoleField - : MonopoleField }, - inj_rmax { params.get("problem", "inj_rmax", (real_t)(1.5)) } {} - - inline void UserInitFields(const SimulationParams&, Meshblock&) override {} - inline void UserDriveFields(const real_t&, - const SimulationParams&, - Meshblock&) override {} - inline void UserDriveParticles(const real_t&, - const SimulationParams&, - Meshblock&) override {} - - private: - const real_t r_surf, b_surf, spin_omega, spinup_time, inj_fraction, inj_rmax; - const FieldMode field_mode; - }; - - Inline void mainBField(const coord_t& x_ph, - vec_t&, - vec_t& b_out, - real_t _rsurf, - real_t _bsurf, - int _mode) { - if (_mode == 2) { - b_out[0] = _bsurf * math::cos(x_ph[1]) / CUBE(x_ph[0] / _rsurf); - b_out[1] = _bsurf * HALF * math::sin(x_ph[1]) / CUBE(x_ph[0] / _rsurf); - b_out[2] = ZERO; - } else { - b_out[0] = _bsurf * SQR(_rsurf / x_ph[0]); - b_out[1] = ZERO; - b_out[2] = ZERO; - } - } - - Inline void surfaceRotationField(const coord_t& x_ph, - vec_t& e_out, - vec_t& b_out, - real_t _rsurf, - real_t _bsurf, - int _mode, - real_t _omega) { - mainBField(x_ph, e_out, b_out, _rsurf, _bsurf, _mode); - e_out[0] = _omega * b_out[1] * x_ph[0] * math::sin(x_ph[1]); - e_out[1] = -_omega * b_out[0] * x_ph[0] * math::sin(x_ph[1]); - e_out[2] = 0.0; - } - - template <> - inline void ProblemGenerator::UserInitFields( - const SimulationParams& params, Meshblock& mblock) { - const auto _rsurf = r_surf; - { - const auto _rmin = mblock.metric.x1_min; - coord_t x_ph { r_surf, ZERO }; - coord_t xi { ZERO }; - mblock.metric.x_Sph2Code(x_ph, xi); - NTTHostErrorIf(_rmin >= _rsurf, "rmin > r_surf"); - NTTHostErrorIf(xi[0] < params.currentFilters(), "r_surf - rmin < filters"); - } - const auto _bsurf = b_surf; - const int _mode = field_mode; - Kokkos::parallel_for( - "UserInitFields", mblock.rangeActiveCells(), Lambda(index_t i, index_t j) { - set_em_fields_2d(mblock, i, j, mainBField, _rsurf, _bsurf, _mode); - }); - } - - template <> - inline void ProblemGenerator::UserDriveFields( - const real_t& time, const SimulationParams&, Meshblock& mblock) { - { - coord_t x_ph { r_surf, ZERO }; - coord_t xi { ZERO }; - mblock.metric.x_Sph2Code(x_ph, xi); - const auto i1_surf = (unsigned int)(xi[0] + N_GHOSTS); - const auto _mode = field_mode; - const auto _rsurf = r_surf; - const auto _bsurf = b_surf; - const auto i1_min = mblock.i1_min(); - const auto _omega - = (time < spinup_time) ? (time / spinup_time) * spin_omega : spin_omega; - - Kokkos::parallel_for( - "UserDriveFields_rmin", - CreateRangePolicy({ i1_min, mblock.i2_min() }, { i1_surf, mblock.i2_max() }), - Lambda(index_t i1, index_t i2) { - set_ex2_2d(mblock, i1, i2, surfaceRotationField, _rsurf, _bsurf, _mode, _omega); - set_ex3_2d(mblock, i1, i2, surfaceRotationField, _rsurf, _bsurf, _mode, _omega); - set_bx1_2d(mblock, i1, i2, surfaceRotationField, _rsurf, _bsurf, _mode, _omega); - if (i1 < i1_surf - 1) { - set_ex1_2d(mblock, i1, i2, surfaceRotationField, _rsurf, _bsurf, _mode, _omega); - set_bx2_2d(mblock, i1, i2, surfaceRotationField, _rsurf, _bsurf, _mode, _omega); - set_bx3_2d(mblock, i1, i2, surfaceRotationField, _rsurf, _bsurf, _mode, _omega); - } - }); - } - } - - template - struct PgenTargetFields : public TargetFields { - PgenTargetFields(const SimulationParams& params, const Meshblock& mblock) - : TargetFields(params, mblock), - _rsurf { params.get("problem", "r_surf", (real_t)(1.0)) }, - _bsurf { params.get("problem", "b_surf", (real_t)(1.0)) }, - _mode { params.get("problem", "field_mode", 2) } {} - Inline real_t operator()(const em& comp, const coord_t& xi) const override { - if ((comp == em::bx1) || (comp == em::bx2)) { - vec_t e_out { ZERO }, b_out { ZERO }; - coord_t x_ph { ZERO }; - (this->m_mblock).metric.x_Code2Sph(xi, x_ph); - mainBField(x_ph, e_out, b_out, _rsurf, _bsurf, _mode); - return (comp == em::bx1) ? b_out[0] : b_out[1]; - } else { - return ZERO; - } - } - - private: - const real_t _rsurf, _bsurf; - const int _mode; - }; - - template - struct RadialKick : public EnergyDistribution { - RadialKick(const SimulationParams& params, const Meshblock& mblock) - : EnergyDistribution(params, mblock), - u_kick { params.get("problem", "u_kick", ZERO) } {} - Inline void operator()(const coord_t&, vec_t& v, const int&) const override { - v[0] = u_kick; - } - - private: - const real_t u_kick; - }; - - template - struct InjectionShell : public SpatialDistribution { - explicit InjectionShell(const SimulationParams& params, Meshblock& mblock) - : SpatialDistribution(params, mblock), - _inj_rmin { params.get("problem", "r_surf", (real_t)(1.0)) }, - _inj_rmax { params.get("problem", "inj_rmax", (real_t)(1.5)) } { - NTTHostErrorIf(_inj_rmin >= _inj_rmax, "inj_rmin >= inj_rmax"); - } - Inline real_t operator()(const coord_t& x_ph) const { - return ((x_ph[0] <= _inj_rmax) && (x_ph[0] > _inj_rmin)) ? ONE : ZERO; - } - - private: - const real_t _inj_rmin, _inj_rmax; - }; - - template - struct MaxDensCrit : public InjectionCriterion { - explicit MaxDensCrit(const SimulationParams& params, Meshblock& mblock) - : InjectionCriterion(params, mblock), - _inj_maxdens { params.get("problem", "inj_maxdens", (real_t)(5.0)) } {} - Inline bool operator()(const coord_t&) const { - return true; - } - - private: - const real_t _inj_maxdens; - }; - - template <> - Inline bool MaxDensCrit::operator()(const coord_t& xph) const { - coord_t xi { ZERO }; - (this->m_mblock).metric.x_Sph2Code(xph, xi); - auto i1 = (std::size_t)(xi[0]) + N_GHOSTS; - auto i2 = (std::size_t)(xi[1]) + N_GHOSTS; - if (i1 < (this->m_mblock).buff.extent(0) && i2 < (this->m_mblock).buff.extent(1)) { - // return true; - return (this->m_mblock).buff(i1, i2, 2) < _inj_maxdens; - } else { - return false; - } - } - - template <> - inline void ProblemGenerator::UserDriveParticles( - const real_t&, const SimulationParams& params, Meshblock& mblock) { - mblock.ComputeMoments(params, FieldID::Rho, {}, { 1, 2 }, 2, 0); - WaitAndSynchronize(); - auto nppc_per_spec = (real_t)(params.ppc0()) * inj_fraction * HALF; - InjectInVolume( - params, - mblock, - { 1, 2 }, - nppc_per_spec, - { mblock.metric.x1_min, inj_rmax, mblock.metric.x2_min, mblock.metric.x2_max }); - } - -} // namespace ntt - -#endif \ No newline at end of file diff --git a/legacy/src/pic/pgen/old/oneprtl.cpp b/legacy/src/pic/pgen/old/oneprtl.cpp deleted file mode 100644 index d4f5e8d00..000000000 --- a/legacy/src/pic/pgen/old/oneprtl.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "wrapper.h" -#include "io/input.h" -#include "sim_params.h" -#include "meshblock/meshblock.h" -#include "particle_macros.h" - -#include "problem_generator.hpp" - -#include - -namespace ntt { - - template <> - ProblemGenerator::ProblemGenerator(const SimulationParams&) {} - - template <> - void ProblemGenerator::UserInitFields(const SimulationParams&, - Meshblock& mblock) { - Kokkos::parallel_for( - "UserInitFlds", mblock.rangeActiveCells(), Lambda(index_t i, index_t j) { - real_t i_ {(real_t)(static_cast(i) - N_GHOSTS)}, - j_ {(real_t)(static_cast(j) - N_GHOSTS)}; - // real_t ex2_hat {0.1}, bx3_hat {1.0}; - vec_t e_cntrv; - mblock.metric.v_Hat2Cntrv({i_, j_}, {1e-4, ZERO, ZERO}, e_cntrv); - mblock.em(i, j, em::ex1) = e_cntrv[0]; - // mblock.em(i, j, em::ex2) = e_cntrv[1]; - // mblock.em(i, j, em::ex3) = ZERO; - // mblock.em(i, j, em::bx1) = ZERO; - // mblock.em(i, j, em::bx2) = ZERO; - // mblock.em(i, j, em::bx3) = b_cntrv[2]; - }); - } - - template <> - void ProblemGenerator::UserInitParticles(const SimulationParams&, - Meshblock& mblock) { - auto& electrons = mblock.particles[0]; - // auto& positrons = mblock.particles[1]; - electrons.setNpart(1); - // positrons.setNpart(1); - Kokkos::parallel_for( - "UserInitPrtls", CreateRangePolicy({0}, {1}), Lambda(index_t p) { - real_t rx = 0.0, ry = 0.0; - init_prtl_2d_XYZ(mblock, electrons, p, rx, ry, 0.0, 0.0, 0.0); - // init_prtl_2d_XYZ(mblock, positrons, p, rx, ry, 1.0, 0.0, 0.0); - }); - } - - template <> - void ProblemGenerator::UserDriveParticles(const real_t&, - const SimulationParams&, - Meshblock&) {} - - template <> - void ProblemGenerator::UserBCFields(const real_t&, - const SimulationParams&, - Meshblock&) {} - template <> - Inline auto ProblemGenerator::UserTargetField_br_hat( - const Meshblock&, const coord_t&) const -> real_t { - return ZERO; - } - - // clang-format off - @PgenPlaceholder1D@ - @PgenPlaceholder3D@ - // clang-format on - -} // namespace ntt - -template struct ntt::ProblemGenerator; -template struct ntt::ProblemGenerator; -template struct ntt::ProblemGenerator; diff --git a/legacy/src/pic/pgen/old/oneprtl.hpp b/legacy/src/pic/pgen/old/oneprtl.hpp deleted file mode 100644 index 15e92b2a3..000000000 --- a/legacy/src/pic/pgen/old/oneprtl.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef PROBLEM_GENERATOR_H -#define PROBLEM_GENERATOR_H - -#include "wrapper.h" -#include "sim_params.h" -#include "meshblock/meshblock.h" - -namespace ntt { - - template - struct ProblemGenerator { - ProblemGenerator(const SimulationParams&); - - void UserInitFields(const SimulationParams&, Meshblock&); - void UserInitParticles(const SimulationParams&, Meshblock&); - void UserBCFields(const real_t&, const SimulationParams&, Meshblock&); - Inline auto UserTargetField_br_hat(const Meshblock&, const coord_t&) const - -> real_t; - void UserDriveParticles(const real_t&, const SimulationParams&, Meshblock&); - }; - -} // namespace ntt - -#endif diff --git a/legacy/src/pic/pgen/old/oneprtl_sph.cpp b/legacy/src/pic/pgen/old/oneprtl_sph.cpp deleted file mode 100644 index 810145a46..000000000 --- a/legacy/src/pic/pgen/old/oneprtl_sph.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include "wrapper.h" -#include "io/input.h" -#include "sim_params.h" -#include "meshblock/meshblock.h" -#include "particle_macros.h" - -#include "problem_generator.hpp" - -#include - -namespace ntt { - - template <> - void ProblemGenerator::UserInitFields(const SimulationParams&, - Meshblock& mblock) { - - Kokkos::parallel_for( - "UserInitFlds", mblock.rangeActiveCells(), Lambda(index_t i, index_t j) { - mblock.em(i, j, em::bx1) = ZERO; - mblock.em(i, j, em::bx2) = ZERO; - }); - } - - template <> - void ProblemGenerator::UserBCFields(const real_t&, - const SimulationParams&, - Meshblock& mblock) { - Kokkos::parallel_for( - "2d_bc_rmin", - CreateRangePolicy({N_GHOSTS, 0}, {N_GHOSTS + 2, mblock.i2_max() + N_GHOSTS}), - Lambda(index_t i, index_t j) { - mblock.em(i, j, em::bx1) = ZERO; - mblock.em(i, j, em::ex2) = ZERO; - mblock.em(i, j, em::ex3) = ZERO; - }); - } - - template <> - void ProblemGenerator::UserInitParticles(const SimulationParams&, - Meshblock& mblock) { - auto& electrons = mblock.particles[0]; - auto& positrons = mblock.particles[1]; - Kokkos::parallel_for( - "UserInitPrtls", CreateRangePolicy({0}, {1}), Lambda(index_t p) { - init_prtl_2d_Sph(mblock, electrons, p, 3.0, ntt::constant::PI * 0.002, 0.0, 0.0, 0.0); - init_prtl_2d_Sph(mblock, positrons, p, 3.0, ntt::constant::PI * 0.002, 0.0, 0.0, 0.0); - }); - mblock.particles[0].setNpart(1); - mblock.particles[1].setNpart(1); - } - - template <> - void ProblemGenerator::UserDriveParticles(const real_t& t, - const SimulationParams&, - Meshblock& mblock) { - real_t dt = mblock.timestep(); - if (t < 400 * dt) { - auto electron = mblock.particles[0]; - Kokkos::parallel_for( - "UserDrivePrtls", CreateRangePolicy({0}, {1}), Lambda(index_t p) { - real_t vel = 2.0 * (math::tanh((t - 350.0 * dt) / (100.0 * dt)) + 1.0) / 2.0; - electron.ux1(p) = vel * math::sin(constant::PI * 0.25); - electron.ux3(p) = vel * math::cos(constant::PI * 0.25); - }); - } - } - - // 1D - template <> - void ProblemGenerator::UserInitFields(const SimulationParams&, - Meshblock&) {} - template <> - void ProblemGenerator::UserInitParticles(const SimulationParams&, - Meshblock&) {} - template <> - void ProblemGenerator::UserBCFields(const real_t&, - const SimulationParams&, - Meshblock&) {} - template <> - void ProblemGenerator::UserDriveParticles(const real_t&, - const SimulationParams&, - Meshblock&) {} - - // 3D - template <> - void ProblemGenerator::UserInitFields(const SimulationParams&, - Meshblock&) {} - template <> - void ProblemGenerator::UserInitParticles(const SimulationParams&, - Meshblock&) {} - template <> - void ProblemGenerator::UserBCFields(const real_t&, - const SimulationParams&, - Meshblock&) {} - template <> - void ProblemGenerator::UserDriveParticles(const real_t&, - const SimulationParams&, - Meshblock&) {} - -} // namespace ntt - -template struct ntt::ProblemGenerator; -template struct ntt::ProblemGenerator; -template struct ntt::ProblemGenerator; - -// real_t i_ {(real_t)(static_cast(i) - N_GHOSTS)}; -// real_t j_ {(real_t)(static_cast(j) - N_GHOSTS)}; -// real_t r_min {mblock.metric.x1_min}; -// coord_t rth_; -// // dipole -// real_t br, btheta; -// // Br -// mblock.metric.x_Code2Sph({i_, j_ + HALF}, rth_); -// br = TWO * math::cos(rth_[1]) / CUBE(rth_[0] / r_min); -// // Btheta -// mblock.metric.x_Code2Sph({i_ + HALF, j_}, rth_); -// btheta = math::sin(rth_[1]) / CUBE(rth_[0] / r_min); - -// vec_t b_cntrv; -// // @comment not quite true (need to separate for each component) -// mblock.metric.v_Hat2Cntrv({i_ + HALF, j_ + HALF}, {br, btheta, ZERO}, b_cntrv); -// mblock.em(i, j, em::bx1) = b_cntrv[0]; -// mblock.em(i, j, em::bx2) = b_cntrv[1]; - -// rotating monopole -// real_t br, bphi, etheta; -//// Etheta -// mblock.metric.x_Code2Sph({i_, j_ + HALF}, rth_); -// etheta = -0.05 * (r_min / rth_[0]) * math::sin(rth_[1]); - -// vec_t cntrv; -// mblock.metric.v_Hat2Cntrv({i_, j_ + HALF}, {ZERO, etheta, ZERO}, cntrv); -// mblock.em(i, j, em::ex2) = cntrv[1]; - -//// Br -// mblock.metric.x_Code2Sph({i_, j_ + HALF}, rth_); -// br = SQR(r_min / rth_[0]); - -// mblock.metric.x_Code2Sph({i_, j_ + HALF}, rth_); -// bphi = -0.05 * (r_min / rth_[0]) * math::sin(rth_[1]); - -// mblock.metric.v_Hat2Cntrv({i_, j_ + HALF}, {br, ZERO, bphi}, cntrv); -// mblock.em(i, j, em::bx1) = cntrv[0]; - -//// Bphi -// mblock.metric.x_Code2Sph({i_ + HALF, j_ + HALF}, rth_); -// br = SQR(r_min / rth_[0]); - -// mblock.metric.x_Code2Sph({i_ + HALF, j_ + HALF}, rth_); -// bphi = -0.05 * (r_min / rth_[0]) * math::sin(rth_[1]); - -// mblock.metric.v_Hat2Cntrv({i_ + HALF, j_ + HALF}, {br, ZERO, bphi}, cntrv); -// mblock.em(i, j, em::bx3) = cntrv[2]; \ No newline at end of file diff --git a/legacy/src/pic/pgen/old/oneprtl_sph.hpp b/legacy/src/pic/pgen/old/oneprtl_sph.hpp deleted file mode 100644 index 720822347..000000000 --- a/legacy/src/pic/pgen/old/oneprtl_sph.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef PROBLEM_GENERATOR_H -#define PROBLEM_GENERATOR_H - -#include "wrapper.h" -#include "sim_params.h" -#include "meshblock/meshblock.h" - -namespace ntt { - - template - struct ProblemGenerator { - ProblemGenerator(const SimulationParams&) {} - - void UserInitFields(const SimulationParams&, Meshblock&); - void UserInitParticles(const SimulationParams&, Meshblock&); - void UserBCFields(const real_t&, const SimulationParams&, Meshblock&); - Inline auto UserTargetField_br_hat(const Meshblock&, const coord_t&) const - -> real_t { - return ZERO; - } - void UserDriveParticles(const real_t&, const SimulationParams&, Meshblock&); - }; - -} // namespace ntt - -#endif diff --git a/legacy/tests/TODO_CMakeLists.txt b/legacy/tests/TODO_CMakeLists.txt deleted file mode 100644 index 3e33a5809..000000000 --- a/legacy/tests/TODO_CMakeLists.txt +++ /dev/null @@ -1,263 +0,0 @@ -# include(CTest) - -set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../src) - -add_subdirectory(${SOURCE_DIR}/global ${CMAKE_CURRENT_BINARY_DIR}/global) -add_subdirectory(${SOURCE_DIR}/kernels ${CMAKE_CURRENT_BINARY_DIR}/kernels) - -set(title "kernels-new") -set(exec test-${title}.xc) -set(src ${title}.cpp) -add_executable(${exec} ${src}) - -target_link_libraries(${exec} ntt_global ntt_kernels) - -# add_test(NAME "Metadomain: ${metric}" COMMAND "test-${title}.xc") - -# # include main source directory for all targets -# include_directories(${SOURCE_DIR}) - -# # --------------------------------- Wrapper -------------------------------- # -# set(WRAPPER ${PROJECT_NAME}-wrapper) -# add_library(${WRAPPER} STATIC ${SOURCE_DIR}/wrapper/kokkos.cpp) - -# # link wrapper with all targets -# link_libraries(${WRAPPER}) - -# # include wrapper header for all targets -# include_directories(${SOURCE_DIR}/wrapper) - -# # -------------------------- Framework & Engines --------------------------- # - -# # include framework headers for all targets -# include_directories(${SOURCE_DIR}/framework) - -# set(all_metrics ${sr_metrics} ${gr_metrics}) - -# # Libraries for all metrics and engines compile framework for all metrics and -# # engines + all engines with corresponding metrics -# function(add_framework_library metric) -# string(TOUPPER ${metric} metric_upper) -# file(GLOB_RECURSE FRAMEWORK_FILES ${SOURCE_DIR}/framework/*.cpp) -# add_library(framework-${metric} STATIC EXCLUDE_FROM_ALL ${FRAMEWORK_FILES}) -# target_compile_options( -# framework-${metric} -# PUBLIC -D${metric_upper}_METRIC -DSIMULATION_METRIC=\"${metric}\" -# -DMETRIC_HEADER=\"metrics/${metric}.h\") -# endfunction() - -# function(add_engine_library metric engine pgen) -# if(${pgen} STREQUAL "dummy") -# set(pgen_full "dummy") -# else() -# if(engine STREQUAL "pic") -# if(metric STREQUAL "minkowski") -# set(pgen_full "srpic-cart/${pgen}") -# else() -# set(pgen_full "srpic-axisym/${pgen}") -# endif() -# else() -# set(pgen_full "grpic-axisym/${pgen}") -# endif() -# endif() - -# string(TOUPPER ${metric} metric_upper) -# string(TOUPPER ${engine} engine_upper) -# set(title engine-${engine}-${metric}) -# set(pgen_name ${pgen}) - -# if(NOT ${pgen} STREQUAL "dummy") -# string(REPLACE "/" "_" pgen_name ${pgen}) -# endif() - -# set(title ${title}-${pgen_name}) -# file(GLOB_RECURSE ${engine_upper}_FILES ${SOURCE_DIR}/engines/${engine}/*.cpp) -# add_library(${title} STATIC EXCLUDE_FROM_ALL ${${engine_upper}_FILES}) -# target_compile_options( -# ${title} -# PUBLIC -D${metric_upper}_METRIC -D${engine_upper}_ENGINE -# -DSIMULATION_METRIC=\"${metric}\" -# -DMETRIC_HEADER=\"metrics/${metric}.h\") -# target_compile_options(${title} PUBLIC "-DPGEN_HEADER=\"../setups/${pgen_full}.hpp\"") -# target_include_directories(${title} PRIVATE ${SOURCE_DIR}/engines -# ${SOURCE_DIR}/engines/${engine}) -# endfunction() - -# foreach(metric ${all_metrics}) -# list(FIND sr_metrics ${metric} sr_metric_index) - -# if(NOT ${sr_metric_index} EQUAL -1) -# set(engine pic) -# else() -# set(engine grpic) -# endif() - -# string(TOUPPER ${metric} metric_upper) -# string(TOUPPER ${engine} engine_upper) - -# add_framework_library(${metric}) -# add_engine_library(${metric} ${engine} dummy) -# add_engine_library(${metric} sandbox dummy) -# endforeach() - -# # ---------------------------------- Tests --------------------------------- # -# enable_testing() - -# # --------------------------------- Utils ---------------------------------- # -# foreach(metric ${all_metrics}) -# set(title utils-metadomain-${metric}) -# add_executable(test-${title}.xc utils-metadomain.cpp) -# target_link_libraries(test-${title}.xc PUBLIC framework-${metric}) -# add_test(NAME "Metadomain: ${metric}" COMMAND "test-${title}.xc") - -# if(${output}) -# set(title utils-writer-${metric}) -# set(engine sandbox) -# add_executable(test-${title}.xc utils-writer.cpp) -# target_link_libraries(test-${title}.xc PUBLIC framework-${metric} -# engine-${engine}-${metric}) -# target_include_directories(test-${title}.xc -# PRIVATE ${SOURCE_DIR}/engines/${engine}) -# add_test(NAME "Writer: ${metric}" COMMAND "test-${title}.xc") -# endif() - -# if(${mpi}) -# set(title utils-comm-${metric}) - -# list(FIND sr_metrics ${metric} sr_metric_index) - -# if(NOT ${sr_metric_index} EQUAL -1) -# set(engine pic) -# else() -# set(engine grpic) -# endif() - -# add_executable(test-${title}.xc utils-comm.cpp) -# target_link_libraries(test-${title}.xc PUBLIC framework-${metric} -# engine-${engine}-${metric}) -# target_include_directories(test-${title}.xc -# PRIVATE ${SOURCE_DIR}/engines/${engine}) -# add_test(NAME "Comm: ${metric}" COMMAND "test-${title}.xc") -# endif() -# endforeach() - -# # --------------------------------- Metrics -------------------------------- # -# foreach(metric ${all_metrics}) -# list(FIND sr_metrics ${metric} sr_metric_index) - -# if(NOT ${sr_metric_index} EQUAL -1) -# if(${metric} STREQUAL "minkowski") -# set(filename_comp metric-comp-sr-mink.cpp) -# else() -# set(filename_comp metric-comp-sr-sph.cpp) -# endif() - -# else() -# set(filename_comp metric-comp-gr.cpp) -# endif() - -# set(title metric-trans-${metric}) -# add_executable(test-${title}.xc metric-trans.cpp) -# target_link_libraries(test-${title}.xc PUBLIC framework-${metric}) - -# add_test(NAME "Vector/Coordinate Transformations: ${metric}" -# COMMAND "test-${title}.xc") - -# set(title metric-comp-${metric}) -# add_executable(test-${title}.xc ${filename_comp}) -# target_link_libraries(test-${title}.xc PUBLIC framework-${metric}) - -# add_test(NAME "Metric Components: ${metric}" COMMAND "test-${title}.xc") -# endforeach() - -# if(${mpi} STREQUAL "OFF") -# # --------------------------------- Pusher --------------------------------- # -# set(metric minkowski) -# set(engine pic) -# set(pgen dummy) -# set(title pusher-sr-minkowski) -# add_executable(test-${title}.xc pusher-sr-mink.cpp) -# target_link_libraries(test-${title}.xc PUBLIC framework-${metric} -# engine-${engine}-${metric}-${pgen}) -# target_include_directories(test-${title}.xc -# PRIVATE ${SOURCE_DIR}/engines/${engine}) -# add_test(NAME "Pusher: ${engine} ${metric}" COMMAND "test-${title}.xc") - -# # --------------------------------- Deposit -------------------------------- # -# foreach(metric ${all_metrics}) -# set(metric ${metric}) - -# list(FIND sr_metrics ${metric} sr_metric_index) - -# if(NOT ${sr_metric_index} EQUAL -1) -# set(engine pic) -# else() -# set(engine grpic) -# endif() - -# set(pgen dummy) -# set(title deposit-${metric}) -# add_executable(test-${title}.xc deposit.cpp) -# target_link_libraries( -# test-${title}.xc PUBLIC framework-${metric} -# engine-${engine}-${metric}-${pgen}) -# target_include_directories(test-${title}.xc -# PRIVATE ${SOURCE_DIR}/engines/${engine}) -# add_test(NAME "Deposit: ${engine} ${metric}" COMMAND "test-${title}.xc") -# endforeach() -# endif() - -# # --------------------------------- Kernel unit tests -------------------------------- -# foreach(metric ${all_metrics}) -# set(metric ${metric}) - -# list(FIND sr_metrics ${metric} sr_metric_index) - -# if(NOT ${sr_metric_index} EQUAL -1) -# set(engine pic) -# else() -# set(engine grpic) -# endif() - -# set(pgen dummy) -# set(title kernels-${metric}) -# add_executable(test-${title}.xc kernels.cpp) -# target_link_libraries( -# test-${title}.xc PUBLIC framework-${metric} -# engine-${engine}-${metric}-${pgen}) -# target_include_directories(test-${title}.xc -# PRIVATE ${SOURCE_DIR}/engines/${engine}) -# add_test(NAME "Kernels: ${engine} ${metric}" COMMAND "test-${title}.xc") -# endforeach() - -# foreach(metric ${sr_metrics}) -# set(metric ${metric}) - -# set(engine pic) - -# set(pgen dummy) -# set(title kernels-sr-${metric}) -# add_executable(test-${title}.xc kernels-sr.cpp) -# target_link_libraries( -# test-${title}.xc PUBLIC framework-${metric} -# engine-${engine}-${metric}-${pgen}) -# target_include_directories(test-${title}.xc -# PRIVATE ${SOURCE_DIR}/engines/${engine}) -# add_test(NAME "Kernels SR: ${engine} ${metric}" COMMAND "test-${title}.xc") -# endforeach() - -# foreach(metric ${gr_metrics}) -# set(metric ${metric}) - -# set(engine grpic) - -# set(pgen dummy) -# set(title kernels-gr-${metric}) -# add_executable(test-${title}.xc kernels-gr.cpp) -# target_link_libraries( -# test-${title}.xc PUBLIC framework-${metric} -# engine-${engine}-${metric}-${pgen}) -# target_include_directories(test-${title}.xc -# PRIVATE ${SOURCE_DIR}/engines/${engine}) -# add_test(NAME "Kernels GR: ${engine} ${metric}" COMMAND "test-${title}.xc") -# endforeach() diff --git a/legacy/tests/deposit.cpp b/legacy/tests/deposit.cpp deleted file mode 100644 index 08fcbec1c..000000000 --- a/legacy/tests/deposit.cpp +++ /dev/null @@ -1,258 +0,0 @@ -#include "wrapper.h" - -#if defined(PIC_ENGINE) - #include "pic.h" -template -using SimEngine = ntt::PIC; -#else // GRPIC_ENGINE - #include "grpic.h" -template -using SimEngine = ntt::GRPIC; -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -auto main(int argc, char* argv[]) -> int { - ntt::GlobalInitialize(argc, argv); - try { - const auto simname = "Deposit-" + std::string(SIMULATION_METRIC); - - const real_t x1_c = 128.5; - const real_t x2_c = 128.5; - const real_t r = 0.4; - real_t omega = 10.0; - - const auto inputdata = toml::table { - { "simulation", - { - { "title", simname }, - { "runtime", 2.0 * ntt::constant::TWO_PI / omega }, - } }, - { "domain", - { - { "resolution", { 256, 256 } }, -#ifdef MINKOWSKI_METRIC - { "extent", { 1.0, 10.0, 1.0, 10.0 } }, -#else - { "extent", { 1.0, 10.0 } }, - { "qsph_r0", 0.0 }, - { "qsph_h", 0.0 }, -#endif - { - "boundaries", - { -#ifdef MINKOWSKI_METRIC - toml::array { "PERIODIC" }, - toml::array { "PERIODIC" }, -#elif defined(PIC_ENGINE) - toml::array { "CUSTOM", "ABSORB" }, - toml::array { "AXIS" }, -#else - toml::array { "OPEN", "ABSORB" }, - toml::array { "AXIS" }, -#endif - }, - }, - } }, - { "units", - { - { "ppc0", 1.0 }, - { "larmor0", 1.0 }, - { "skindepth0", 1.0 }, - } }, - { "particles", - { - { "n_species", 1 }, - } }, - { "algorithm", - { - { "CFL", 0.9 }, - { "current_filters", 0 }, - } }, - { "species_1", - { - { "mass", 1.0 }, - { "charge", -1.0 }, - { "maxnpart", 1e2 }, - } }, - }; - - SimEngine sim(inputdata); - sim.ResetSimulation(); - - { - auto& mblock = sim.meshblock; - auto& electrons = mblock.particles[0]; - - const auto x1 = x1_c + r; - const auto x2 = x2_c; - const auto ux1 = ZERO; - const auto ux2 = r * omega; - - Kokkos::parallel_for( - "InitParticle", - 1, - Lambda(ntt::index_t p) { - electrons.i1(p) = (int)x1; - electrons.i2(p) = (int)x2; - electrons.dx1(p) = x1 - math::floor(x1); - electrons.dx2(p) = x2 - math::floor(x2); - - ntt::vec_t u { ZERO }; -#if defined(MINKOWSKI_METRIC) - mblock.metric.v3_Hat2Cart({ x1, x2 }, { ux1, ux2, ZERO }, u); -#elif defined(GRPIC_ENGINE) - mblock.metric.v3_Hat2Cov({ x1, x2 }, { ux1, ux2, ZERO }, u); -#else - mblock.metric.v3_Hat2Cart({ x1, x2, ZERO }, { ux1, ux2, ZERO }, u); -#endif - electrons.ux1(p) = u[0]; - electrons.ux2(p) = u[1]; - electrons.ux3(p) = u[2]; - electrons.tag(p) = ntt::ParticleTag::alive; - }); - electrons.setNpart(1); - } - - sim.PrintDetails(); - sim.Verify(); - sim.InitialStep(); - - auto& mblock = sim.meshblock; - auto& electrons = mblock.particles[0]; - - // charges in 6 nodes of two neighboring cells - std::vector q_A, q_B, q_C, q_D, q_E, q_F; - - while (sim.time() < sim.params()->totalRuntime()) { - sim.StepForward(ntt::DiagFlags_None); - - const auto t = sim.time(); - real_t ux1, ux2; - if (t > sim.params()->totalRuntime() * HALF) { - ux1 = r * omega * math::sin(omega * t); - ux2 = r * omega * math::cos(omega * t); - } else { - ux1 = -r * omega * math::sin(omega * t); - ux2 = r * omega * math::cos(omega * t); - } - - Kokkos::parallel_for( - "UpdParticle", - 1, - Lambda(ntt::index_t p) { - const auto x1_p = static_cast(electrons.i1(p)) + - static_cast(electrons.dx1(p)); - const auto x2_p = static_cast(electrons.i2(p)) + - static_cast(electrons.dx2(p)); - ntt::vec_t u { ZERO }; -#if defined(MINKOWSKI_METRIC) - mblock.metric.v3_Hat2Cart({ x1_p, x2_p }, { ux1, ux2, ZERO }, u); -#elif defined(GRPIC_ENGINE) - mblock.metric.v3_Hat2Cov({ x1_p, x2_p }, { ux1, ux2, ZERO }, u); -#else - mblock.metric.v3_Hat2Cart({ x1_p, x2_p, ZERO }, { ux1, ux2, ZERO }, u); -#endif - electrons.ux1(p) = u[0]; - electrons.ux2(p) = u[1]; - electrons.ux3(p) = u[2]; - }); - - electrons.SyncHostDevice(); - auto em_h = Kokkos::create_mirror_view(mblock.em); - Kokkos::deep_copy(em_h, mblock.em); - - const auto i0 = 128 + N_GHOSTS, j0 = 128 + N_GHOSTS; - const real_t x0 = 128.0; - const real_t y0 = 128.0; - q_A.push_back( - em_h(i0, j0, ntt::em::ex1) * mblock.metric.sqrt_det_h({ x0 + HALF, y0 }) - - em_h(i0 - 1, j0, ntt::em::ex1) * - mblock.metric.sqrt_det_h({ x0 - HALF, y0 }) + - em_h(i0, j0, ntt::em::ex2) * mblock.metric.sqrt_det_h({ x0, y0 + HALF }) - - em_h(i0, j0 - 1, ntt::em::ex2) * - mblock.metric.sqrt_det_h({ x0, y0 - HALF })); - q_B.push_back(em_h(i0 + 1, j0, ntt::em::ex1) * - mblock.metric.sqrt_det_h({ x0 + 3.0 * HALF, y0 }) - - em_h(i0, j0, ntt::em::ex1) * - mblock.metric.sqrt_det_h({ x0 + HALF, y0 }) + - em_h(i0 + 1, j0, ntt::em::ex2) * - mblock.metric.sqrt_det_h({ x0 + ONE, y0 + HALF }) - - em_h(i0 + 1, j0 - 1, ntt::em::ex2) * - mblock.metric.sqrt_det_h({ x0 + ONE, y0 - HALF })); - q_C.push_back(em_h(i0 + 2, j0, ntt::em::ex1) * - mblock.metric.sqrt_det_h({ x0 + 5.0 * HALF, y0 }) - - em_h(i0 + 1, j0, ntt::em::ex1) * - mblock.metric.sqrt_det_h({ x0 + 3.0 * HALF, y0 }) + - em_h(i0 + 2, j0, ntt::em::ex2) * - mblock.metric.sqrt_det_h({ x0 + TWO, y0 + HALF }) - - em_h(i0 + 2, j0 - 1, ntt::em::ex2) * - mblock.metric.sqrt_det_h({ x0 + TWO, y0 - HALF })); - q_D.push_back(em_h(i0, j0 + 1, ntt::em::ex1) * - mblock.metric.sqrt_det_h({ x0 + HALF, y0 + ONE }) - - em_h(i0 - 1, j0 + 1, ntt::em::ex1) * - mblock.metric.sqrt_det_h({ x0 - HALF, y0 + ONE }) + - em_h(i0, j0 + 1, ntt::em::ex2) * - mblock.metric.sqrt_det_h({ x0, y0 + 3.0 * HALF }) - - em_h(i0, j0, ntt::em::ex2) * - mblock.metric.sqrt_det_h({ x0, y0 + HALF })); - q_E.push_back(em_h(i0 + 1, j0 + 1, ntt::em::ex1) * - mblock.metric.sqrt_det_h({ x0 + 3.0 * HALF, y0 + ONE }) - - em_h(i0, j0 + 1, ntt::em::ex1) * - mblock.metric.sqrt_det_h({ x0 + HALF, y0 + ONE }) + - em_h(i0 + 1, j0 + 1, ntt::em::ex2) * - mblock.metric.sqrt_det_h({ x0 + ONE, y0 + 3.0 * HALF }) - - em_h(i0 + 1, j0, ntt::em::ex2) * - mblock.metric.sqrt_det_h({ x0 + ONE, y0 + HALF })); - q_F.push_back(em_h(i0 + 2, j0 + 1, ntt::em::ex1) * - mblock.metric.sqrt_det_h({ x0 + 5.0 * HALF, y0 + ONE }) - - em_h(i0 + 1, j0 + 1, ntt::em::ex1) * - mblock.metric.sqrt_det_h({ x0 + 3.0 * HALF, y0 + ONE }) + - em_h(i0 + 2, j0 + 1, ntt::em::ex2) * - mblock.metric.sqrt_det_h({ x0 + TWO, y0 + 3.0 * HALF }) - - em_h(i0 + 2, j0, ntt::em::ex2) * - mblock.metric.sqrt_det_h({ x0 + TWO, y0 + HALF })); - } - std::vector q_error; - auto q_max = std::numeric_limits::min(); - auto q_max_A = std::max_element(q_A.begin(), q_A.end()); - auto q_max_B = std::max_element(q_B.begin(), q_B.end()); - auto q_max_C = std::max_element(q_C.begin(), q_C.end()); - auto q_max_D = std::max_element(q_D.begin(), q_D.end()); - auto q_max_E = std::max_element(q_E.begin(), q_E.end()); - auto q_max_F = std::max_element(q_F.begin(), q_F.end()); - q_max = std::max(*q_max_A, *q_max_B); - q_max = std::max(q_max, *q_max_C); - q_max = std::max(q_max, *q_max_D); - q_max = std::max(q_max, *q_max_E); - q_max = std::max(q_max, *q_max_F); - for (std::size_t t { 0 }; t < q_A.size(); ++t) { - q_error.push_back( - math::abs(q_A[t] + q_B[t] + q_C[t] + q_D[t] + q_E[t] + q_F[t]) / q_max); - } - auto q_err_max = *std::max_element(q_error.begin(), q_error.end()); - if (q_err_max > 10.0 * std::numeric_limits::epsilon()) { - throw std::runtime_error("max(q_error) = " + std::to_string(q_err_max)); - } - } - - catch (std::exception& err) { - std::cerr << err.what() << std::endl; - ntt::GlobalFinalize(); - return -1; - } - - ntt::GlobalFinalize(); - - return 0; -} \ No newline at end of file diff --git a/legacy/tests/kernels-gr.cpp b/legacy/tests/kernels-gr.cpp deleted file mode 100644 index 6962f7c9f..000000000 --- a/legacy/tests/kernels-gr.cpp +++ /dev/null @@ -1,211 +0,0 @@ -#include - -#include -#include - -#include "wrapper.h" - -#include METRIC_HEADER - -#include "kernels/particle_pusher_gr.hpp" - -#include "particle_macros.h" - -template -void put_value(ntt::array_t& arr, T value, int i) { - auto arr_h = Kokkos::create_mirror_view(arr); - arr_h(i) = value; - Kokkos::deep_copy(arr, arr_h); -} - -template -auto get_value(const ntt::array_t& arr, int i) -> T { - auto arr_h = Kokkos::create_mirror_view(arr); - Kokkos::deep_copy(arr_h, arr); - return arr_h(i); -} - -template -auto get_physical_coord(const int p, - const ntt::array_t& i1, - const ntt::array_t& i2, - const ntt::array_t& dx1, - const ntt::array_t& dx2, - const M& metric) -> std::pair { - std::pair rth; - ntt::coord_t xC { ZERO }; - ntt::coord_t rtheta { ZERO }; - xC[0] = i_di_to_Xi(get_value(i1, p), get_value(dx1, p)); - xC[1] = i_di_to_Xi(get_value(i2, p), get_value(dx2, p)); - metric.x_Code2Phys(xC, rtheta); - rth.first = rtheta[0]; - rth.second = rtheta[1]; - return rth; -} - -auto dummy_metric(const unsigned int nx1, const unsigned int nx2) - -> ntt::Metric { - const auto resolution = std::vector({ nx1, nx2 }); - const auto extent = std::vector({ 1.0, 100.0, ZERO, ntt::constant::PI }); - const auto qsph_r0 = (real_t)(0.0); - const auto qsph_h = (real_t)(0.25); - - const auto spin = (real_t)(0.5); - const auto rh = ONE + std::sqrt(ONE - SQR(spin)); - - auto params = new real_t[6]; - params[0] = qsph_r0; - params[1] = qsph_h; - params[4] = spin; - params[5] = rh; - ntt::Metric metric(resolution, extent, params); - delete[] params; - return metric; -} - -auto main(int argc, char* argv[]) -> int { - ntt::GlobalInitialize(argc, argv); - try { - constexpr auto nx1 = 100, nx2 = 100; - auto metric = dummy_metric(nx1, nx2); - { - /* -------------------------------------------------------------------------- */ - /* pusher */ - /* -------------------------------------------------------------------------- */ - ntt::ndfield_t DB { "DB", nx1 + 2 * N_GHOSTS, nx2 + 2 * N_GHOSTS }; - ntt::ndfield_t DB0 { "DB", - nx1 + 2 * N_GHOSTS, - nx2 + 2 * N_GHOSTS }; - ntt::array_t i1 { "i1", 10 }; - ntt::array_t i2 { "i2", 10 }; - ntt::array_t i3 { "i3", 10 }; - ntt::array_t i1_prev { "i1_prev", 10 }; - ntt::array_t i2_prev { "i2_prev", 10 }; - ntt::array_t i3_prev { "i3_prev", 10 }; - ntt::array_t dx1 { "dx1", 10 }; - ntt::array_t dx2 { "dx2", 10 }; - ntt::array_t dx3 { "dx3", 10 }; - ntt::array_t dx1_prev { "dx1_prev", 10 }; - ntt::array_t dx2_prev { "dx2_prev", 10 }; - ntt::array_t dx3_prev { "dx3_prev", 10 }; - ntt::array_t ux1 { "ux1", 10 }; - ntt::array_t ux2 { "ux2", 10 }; - ntt::array_t ux3 { "ux3", 10 }; - ntt::array_t phi { "phi", 10 }; - ntt::array_t weight { "weight", 10 }; - ntt::array_t tag { "tag", 10 }; - - int i1_0, i2_0; - real_t dx1_0, dx2_0; - - const real_t r0 = 50.5, th0 = 1.5; - ntt::coord_t xC_0 { ZERO }; - - const real_t ux1_0 = 1.5, ux2_0 = 0.5, ux3_0 = -1.2; - ntt::vec_t uC_0 { ZERO }; - - metric.x_Phys2Code({ r0, th0 }, xC_0); - from_Xi_to_i_di(xC_0[0], i1_0, dx1_0); - from_Xi_to_i_di(xC_0[1], i2_0, dx2_0); - - metric.v3_Hat2Cov(xC_0, { ux1_0, ux2_0, ux3_0 }, uC_0); - - put_value(i1, i1_0, 0); - put_value(i2, i2_0, 0); - put_value(dx1, dx1_0, 0); - put_value(dx2, dx2_0, 0); - put_value(ux1, uC_0[0], 0); - put_value(ux2, uC_0[1], 0); - put_value(ux3, uC_0[2], 0); - put_value(tag, ntt::ParticleTag::alive, 0); - - std::vector> boundaries; - boundaries.push_back( - std::vector(2, ntt::BoundaryCondition::PERIODIC)); - boundaries.push_back( - std::vector(2, ntt::BoundaryCondition::PERIODIC)); - - auto kernel = ntt::Pusher_kernel>( - DB, - DB0, - i1, - i2, - i3, - i1_prev, - i2_prev, - i3_prev, - dx1, - dx2, - dx3, - dx1_prev, - dx2_prev, - dx3_prev, - ux1, - ux2, - ux3, - phi, - tag, - metric, - ONE, - ONE, - nx1, - nx2, - 1, - static_cast(1.0e-5), - 10, - boundaries); - Kokkos::parallel_for( - "ParticlesPush", - Kokkos::RangePolicy(0, 1), - kernel); - auto [ra, tha] = get_physical_coord(0, i1, i2, dx1, dx2, metric); - const real_t pha = get_value(phi, 0); - - if (metric.rg() != ZERO) { - // for KS with M != 0 - if (!ntt::AlmostEqual(ra, - static_cast(51.115658), - static_cast(1e-4))) { - throw std::runtime_error("r coordinate is not correct"); - } - if (!ntt::AlmostEqual(tha, - static_cast(1.504318), - static_cast(1e-4))) { - throw std::runtime_error("th coordinate is not correct"); - } - if (!ntt::AlmostEqual(pha, - static_cast(6.272962), - static_cast(1e-4))) { - throw std::runtime_error("phi coordinate is not correct"); - } - } else { - // for KS with M == 0 - if (!ntt::AlmostEqual(ra, - static_cast(51.180923), - static_cast(1e-4))) { - throw std::runtime_error("r coordinate is not correct"); - } - if (!ntt::AlmostEqual(tha, - static_cast(1.504381), - static_cast(1e-4))) { - throw std::runtime_error("th coordinate is not correct"); - } - if (!ntt::AlmostEqual(pha, - static_cast(6.272648), - static_cast(1e-4))) { - throw std::runtime_error("phi coordinate is not correct"); - } - } - } - } - - catch (std::exception& err) { - std::cerr << err.what() << std::endl; - ntt::GlobalFinalize(); - return -1; - } - - ntt::GlobalFinalize(); - - return 0; -} diff --git a/legacy/tests/kernels-sr.cpp b/legacy/tests/kernels-sr.cpp deleted file mode 100644 index 3f64122cd..000000000 --- a/legacy/tests/kernels-sr.cpp +++ /dev/null @@ -1,225 +0,0 @@ -#include - -#include -#include - -#include "wrapper.h" - -#include METRIC_HEADER -#include PGEN_HEADER - -#include "kernels/particle_pusher_sr.hpp" - -#include "particle_macros.h" - -template -void put_value(ntt::array_t& arr, T value, int i) { - auto arr_h = Kokkos::create_mirror_view(arr); - arr_h(i) = value; - Kokkos::deep_copy(arr, arr_h); -} - -template -auto get_value(const ntt::array_t& arr, int i) -> T { - auto arr_h = Kokkos::create_mirror_view(arr); - Kokkos::deep_copy(arr_h, arr); - return arr_h(i); -} - -template -auto get_cartesian_coord(const int p, - const ntt::array_t& i1, - const ntt::array_t& i2, - const ntt::array_t& dx1, - const ntt::array_t& dx2, - const ntt::array_t& phi, - const M& metric) -> std::pair { - std::pair xy; -#ifdef MINKOWSKI_METRIC - ntt::coord_t xC { ZERO }; - ntt::coord_t xyz { ZERO }; - xC[0] = i_di_to_Xi(get_value(i1, p), get_value(dx1, p)); - xC[1] = i_di_to_Xi(get_value(i2, p), get_value(dx2, p)); - (void)phi; - metric.x_Code2Cart(xC, xyz); - xy.first = xyz[0]; - xy.second = xyz[1]; -#else - ntt::coord_t xC { ZERO }; - ntt::coord_t xyz { ZERO }; - xC[0] = i_di_to_Xi(get_value(i1, p), get_value(dx1, p)); - xC[1] = i_di_to_Xi(get_value(i2, p), get_value(dx2, p)); - xC[2] = get_value(phi, p); - metric.x_Code2Cart(xC, xyz); - xy.first = xyz[0]; - xy.second = xyz[2]; -#endif - return xy; -} - -auto dummy_metric(const unsigned int nx1, const unsigned int nx2) - -> ntt::Metric { - const auto resolution = std::vector({ nx1, nx2 }); -#ifdef MINKOWSKI_METRIC - const auto extent = std::vector({ 1.0, 100.0, -49.5, 49.5 }); -#else - const auto extent = std::vector({ 1.0, 100.0, ZERO, ntt::constant::PI }); -#endif - // optional for Qspherical - const auto qsph_r0 = (real_t)(0.0); - const auto qsph_h = (real_t)(0.25); - - auto params = new real_t[6]; - params[0] = qsph_r0; - params[1] = qsph_h; - ntt::Metric metric(resolution, extent, params); - delete[] params; - return metric; -} - -auto dummy_pgen() -> ntt::ProblemGenerator { - return ntt::ProblemGenerator(); -} - -auto main(int argc, char* argv[]) -> int { - ntt::GlobalInitialize(argc, argv); - try { - constexpr auto nx1 = 10, nx2 = 10; - auto metric = dummy_metric(nx1, nx2); - auto pgen = dummy_pgen(); - { - /* -------------------------------------------------------------------------- */ - /* pusher */ - /* -------------------------------------------------------------------------- */ - ntt::ndfield_t EB { "EB", nx1 + 2 * N_GHOSTS, nx2 + 2 * N_GHOSTS }; - ntt::array_t i1 { "i1", 10 }; - ntt::array_t i2 { "i2", 10 }; - ntt::array_t i3 { "i3", 10 }; - ntt::array_t i1_prev { "i1_prev", 10 }; - ntt::array_t i2_prev { "i2_prev", 10 }; - ntt::array_t i3_prev { "i3_prev", 10 }; - ntt::array_t dx1 { "dx1", 10 }; - ntt::array_t dx2 { "dx2", 10 }; - ntt::array_t dx3 { "dx3", 10 }; - ntt::array_t dx1_prev { "dx1_prev", 10 }; - ntt::array_t dx2_prev { "dx2_prev", 10 }; - ntt::array_t dx3_prev { "dx3_prev", 10 }; - ntt::array_t ux1 { "ux1", 10 }; - ntt::array_t ux2 { "ux2", 10 }; - ntt::array_t ux3 { "ux3", 10 }; - ntt::array_t phi { "phi", 10 }; - ntt::array_t weight { "weight", 10 }; - ntt::array_t tag { "tag", 10 }; - - int i1_0, i2_0; - real_t dx1_0, dx2_0; - const real_t ux1_0 = 1.5; - - const real_t x0 = 50.5, y0 = 1.0; - -#ifdef MINKOWSKI_METRIC - const real_t ux2_0 = -1.2, ux3_0 = 0.5; - ntt::coord_t xyz0 { x0, y0 }; - ntt::coord_t xC_0 { ZERO }; -#else - const real_t ux3_0 = -1.2, ux2_0 = 0.5; - ntt::coord_t xyz0 { x0, ZERO, y0 }; - ntt::coord_t xC_0 { ZERO }; -#endif - - const real_t gamma = math::sqrt(ONE + SQR(ux1_0) + SQR(ux2_0) + SQR(ux3_0)); - metric.x_Cart2Code(xyz0, xC_0); - from_Xi_to_i_di(xC_0[0], i1_0, dx1_0); - from_Xi_to_i_di(xC_0[1], i2_0, dx2_0); - - put_value(i1, i1_0, 0); - put_value(i2, i2_0, 0); - put_value(dx1, dx1_0, 0); - put_value(dx2, dx2_0, 0); - put_value(ux1, ux1_0, 0); - put_value(ux2, ux2_0, 0); - put_value(ux3, ux3_0, 0); - put_value(tag, ntt::ParticleTag::alive, 0); - - std::vector> boundaries; - boundaries.push_back( - std::vector(2, ntt::BoundaryCondition::PERIODIC)); - boundaries.push_back( - std::vector(2, ntt::BoundaryCondition::PERIODIC)); - - auto kernel = ntt::Pusher_kernel, - ntt::ProblemGenerator, - ntt::Boris_t, - false>(EB, - i1, - i2, - i3, - i1_prev, - i2_prev, - i3_prev, - dx1, - dx2, - dx3, - dx1_prev, - dx2_prev, - dx3_prev, - ux1, - ux2, - ux3, - phi, - tag, - metric, - pgen, - ZERO, - ONE, - ONE, - nx1, - nx2, - 1, - boundaries, - ZERO, - ZERO, - ZERO); - Kokkos::parallel_for( - "ParticlesPush", - Kokkos::RangePolicy(0, 1), - kernel); - auto [xa, ya] = get_cartesian_coord(0, i1, i2, dx1, dx2, phi, metric); - - if (!ntt::AlmostEqual(xa, - static_cast(x0 + ux1_0 / gamma), - static_cast(1e-4))) { - throw std::runtime_error("x coordinate is not correct"); - } - - if (!ntt::AlmostEqual(ya, - static_cast(y0 - 1.2 / gamma), - static_cast(1e-4))) { - throw std::runtime_error("y/z coordinate is not correct"); - } - - if (!ntt::AlmostEqual(get_value(ux1, 0), ux1_0)) { - throw std::runtime_error("ux1 is not correct"); - } - - if (!ntt::AlmostEqual(get_value(ux2, 0), ux2_0)) { - throw std::runtime_error("ux2 is not correct"); - } - - if (!ntt::AlmostEqual(get_value(ux3, 0), ux3_0)) { - throw std::runtime_error("ux3 is not correct"); - } - } - } - - catch (std::exception& err) { - std::cerr << err.what() << std::endl; - ntt::GlobalFinalize(); - return -1; - } - - ntt::GlobalFinalize(); - - return 0; -} diff --git a/legacy/tests/pusher-sr-mink.cpp b/legacy/tests/pusher-sr-mink.cpp deleted file mode 100644 index 97f37b63c..000000000 --- a/legacy/tests/pusher-sr-mink.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include "wrapper.h" - -#include "particle_macros.h" -#include "pic.h" -#include "sim_params.h" - -#include "io/input.h" -#include "meshblock/meshblock.h" -#include "utilities/qmath.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -auto main(int argc, char* argv[]) -> int { - ntt::GlobalInitialize(argc, argv); - try { - using namespace toml::literals::toml_literals; - const auto inputdata = R"( - [domain] - resolution = [256, 128, 128] - extent = [-16.0, 16.0, -8.0, 8.0, -8.0, 8.0] - boundaries = [["PERIODIC"], ["PERIODIC"], ["PERIODIC"]] - - [units] - ppc0 = 1.0 - larmor0 = 2.0 - skindepth0 = 1.0 - - [particles] - n_species = 1 - - [species_1] - label = "e+" - mass = 1.0 - charge = 1.0 - maxnpart = 10.0 - - [output] - format = "disabled" - )"_toml; - - auto sim = ntt::PIC(inputdata); - - real_t bx1 = 0.256, bx2 = 0.953, bx3 = -0.234; - const real_t bmag = 2.0; - const real_t u_part = 2.0; - const auto nperiods = 5; - - const auto bb = math::sqrt(SQR(bx1) + SQR(bx2) + SQR(bx3)); - bx1 /= bb; - bx2 /= bb; - bx3 /= bb; - const real_t beta_part = u_part / math::sqrt(ONE + SQR(u_part)); - const real_t ax1 = bx2, ax2 = -bx3, ax3 = bx1; - real_t perp_x1 = ax2 * bx3 - ax3 * bx2; - real_t perp_x2 = ax3 * bx1 - ax1 * bx3; - real_t perp_x3 = ax1 * bx2 - ax2 * bx1; - const real_t perp = math::sqrt(SQR(perp_x1) + SQR(perp_x2) + SQR(perp_x3)); - perp_x1 /= perp; - perp_x2 /= perp; - perp_x3 /= perp; - const auto ux1 = u_part * perp_x1; - const auto ux2 = u_part * perp_x2; - const auto ux3 = u_part * perp_x3; - - auto& mblock = sim.meshblock; - { - Kokkos::parallel_for( - "InitFields", - mblock.rangeActiveCells(), - Lambda(ntt::index_t i1, ntt::index_t i2, ntt::index_t i3) { - ntt::coord_t xi { ZERO }; - ntt::vec_t b_cntrv { ZERO }; - mblock.metric.v3_PhysCntrv2Cntrv(xi, - { bmag * bx1, bmag * bx2, bmag * bx3 }, - b_cntrv); - mblock.em(i1, i2, i3, ntt::em::bx1) = b_cntrv[0]; - mblock.em(i1, i2, i3, ntt::em::bx2) = b_cntrv[1]; - mblock.em(i1, i2, i3, ntt::em::bx3) = b_cntrv[2]; - }); - sim.Communicate(ntt::Comm_B); - } - - { - using namespace ntt; - mblock.particles[0].setNpart(1); - auto positrons = mblock.particles[0]; - Kokkos::parallel_for( - "InitParticles", - positrons.rangeActiveParticles(), - Lambda(ntt::index_t p) { - init_prtl_3d(mblock, positrons, p, 0.0, 0.0, 0.0, ux1, ux2, ux3, 1.0); - }); - } - - { - const auto dt = mblock.timestep(); - const auto larmor = sim.params()->larmor0() * u_part / bmag; - const auto period = ntt::constant::TWO_PI * larmor / beta_part; - auto positrons = mblock.particles[0]; - auto maxdist = ZERO, maxupar = ZERO; - const auto nmax = static_cast(nperiods * period / dt); - for (auto n { 0 }; n < nmax + 1; ++n) { - if (n < nmax) { - sim.ParticlesPush(); - } else { - const auto fraction = (nperiods * period / dt - nmax); - sim.ParticlesPush(fraction); - } - positrons.SyncHostDevice(); - - { - ntt::coord_t xprtl { ZERO }; - ntt::coord_t xi { static_cast(positrons.i1_h(0)) + - static_cast(positrons.dx1_h(0)), - static_cast(positrons.i2_h(0)) + - static_cast(positrons.dx2_h(0)), - static_cast(positrons.i3_h(0)) + - static_cast(positrons.dx3_h(0)) }; - mblock.metric.x_Code2Cart(xi, xprtl); - const auto dist = math::sqrt( - SQR(xprtl[0]) + SQR(xprtl[1]) + SQR(xprtl[2])); - if (dist > maxdist) { - maxdist = dist; - } - if (n == nmax) { - !(ntt::AlmostZero(SQR(dist), (real_t)1e-4)) - ? throw std::logic_error(fmt::format( - "particle not in init position: %.6e != 0.0, L2 = %.6e", - dist, - SQR(dist))) - : (void)0; - !(ntt::AlmostEqual(maxdist, TWO * larmor, (real_t)1e-3)) - ? throw std::logic_error( - fmt::format("maxdist is incorrect: %.6f != %.6f", - maxdist, - TWO * larmor)) - : (void)0; - !(ntt::AlmostZero(maxupar)) - ? throw std::logic_error( - fmt::format("maxupar is nonzero: %f", maxupar)) - : (void)0; - const auto L2_u = SQR(positrons.ux1_h(0) - ux1) + - SQR(positrons.ux2_h(0) - ux2) + - SQR(positrons.ux3_h(0) - ux3); - !(ntt::AlmostZero(L2_u, (real_t)1e-4)) - ? throw std::logic_error( - fmt::format("u_init != u_final: L2 = %.2e", L2_u)) - : (void)0; - } - } - - { - const auto u_mag = math::sqrt(SQR(positrons.ux1_h(0)) + - SQR(positrons.ux2_h(0)) + - SQR(positrons.ux3_h(0))); - !(ntt::AlmostEqual(u_mag, u_part)) - ? throw std::logic_error( - fmt::format("u_mag is incorrect after %d pushes: %.6f != %.6f", - n, - u_mag, - u_part)) - : (void)0; - const auto upar = (positrons.ux1_h(0) * bx1 + positrons.ux2_h(0) * bx2 + - positrons.ux3_h(0) * bx3) / - (u_part * bmag); - if (math::abs(upar) > maxupar) { - maxupar = math::abs(upar); - } - !(ntt::AlmostZero(upar)) - ? throw std::logic_error( - fmt::format("u_|| is nonzero after %d pushes: %.2e", n, upar)) - : (void)0; - } - } - } - } catch (std::exception& err) { - std::cerr << err.what() << std::endl; - ntt::GlobalFinalize(); - return -1; - } - ntt::GlobalFinalize(); - - return 0; -} \ No newline at end of file diff --git a/legacy/tests/utils-comm.cpp b/legacy/tests/utils-comm.cpp deleted file mode 100644 index 047c71b3a..000000000 --- a/legacy/tests/utils-comm.cpp +++ /dev/null @@ -1,212 +0,0 @@ -#ifdef MPI_ENABLED - #include "wrapper.h" - - #if defined(SANDBOX_ENGINE) - - #include "sandbox.h" -template -using SimEngine = ntt::SANDBOX; - - #elif defined(PIC_ENGINE) - - #include "pic.h" -template -using SimEngine = ntt::PIC; - - #elif defined(GRPIC_ENGINE) - - #include "grpic.h" -template -using SimEngine = ntt::GRPIC; - - #endif - - #include "sim_params.h" - - #include "communications/decomposition.h" - #include "communications/metadomain.h" - #include "meshblock/meshblock.h" - #include "utilities/qmath.h" - - #include "utilities/injector.hpp" - - #include - #include - #include - #include - - #include - #include - #include - #include - #include - -auto main(int argc, char* argv[]) -> int { - ntt::GlobalInitialize(argc, argv); - try { - toml::table simulation, domain, units, output, algorithm; - toml::table particles, species_1, species_2; - const auto simname = "Writer-" + std::string(SIMULATION_METRIC); - simulation["title"] = simname; - domain["resolution"] = toml::array { 64, 64 }; - - particles["n_species"] = 2; - species_1["mass"] = 0.0; - species_1["charge"] = 0.0; - species_1["maxnpart"] = 1e2; - species_2["mass"] = 0.0; - species_2["charge"] = 0.0; - species_2["maxnpart"] = 1e2; - - #ifdef MINKOWSKI_METRIC - domain["extent"] = toml::array { -1.0, 1.0, -1.0, 1.0 }; - domain["boundaries"] = toml::array { toml::array { "PERIODIC" }, - toml::array { "PERIODIC" } }; - #else - domain["extent"] = toml::array { 0.8, 20.0 }; - domain["boundaries"] = toml::array { - toml::array { "OPEN", "ABSORB" }, - toml::array { "AXIS" } - }; - domain["qsph_r0"] = 0.0; - domain["qsph_h"] = 0.4; - domain["spin"] = 0.5; - #endif - - units["ppc0"] = 1.0; - units["larmor0"] = 0.1; - units["skindepth0"] = 1.0; - - // output["fields"] = toml::array { "E", "B" }; - output["particles"] = toml::array { "X", "U" }; - output["prtl_stride"] = 1; - output["format"] = "HDF5"; - output["as_is"] = true; - output["ghosts"] = true; - - auto inputdata = toml::table { - {"simulation", simulation}, - { "domain", domain}, - { "units", units}, - { "output", output}, - { "particles", particles}, - { "species_1", species_1}, - { "species_2", species_2} - }; - - // write - { - SimEngine sim(inputdata); - auto& mblock { sim.meshblock }; - // allocate fields - mblock.em = ntt::ndfield_t { "em", - mblock.Ni1() + 2 * N_GHOSTS, - mblock.Ni2() + 2 * N_GHOSTS }; - mblock.bckp = ntt::ndfield_t { "bckp", - mblock.Ni1() + 2 * N_GHOSTS, - mblock.Ni2() + 2 * N_GHOSTS }; - - // allocate particles - for (auto& specie : mblock.particles) { - specie.i1 = ntt::array_t { specie.label() + "_i1", - specie.maxnpart() }; - specie.i2 = ntt::array_t { specie.label() + "_i2", - specie.maxnpart() }; - specie.dx1 = ntt::array_t { specie.label() + "_dx1", - specie.maxnpart() }; - specie.dx2 = ntt::array_t { specie.label() + "_dx2", - specie.maxnpart() }; - specie.ux1 = ntt::array_t { specie.label() + "_ux1", - specie.maxnpart() }; - specie.ux2 = ntt::array_t { specie.label() + "_ux2", - specie.maxnpart() }; - specie.ux3 = ntt::array_t { specie.label() + "_ux3", - specie.maxnpart() }; - specie.weight = ntt::array_t { specie.label() + "_w", - specie.maxnpart() }; - #ifndef MINKOWSKI_METRIC - specie.phi = ntt::array_t { specie.label() + "_phi", - specie.maxnpart() }; - #endif - specie.tag = ntt::array_t { specie.label() + "_tag", - specie.maxnpart() }; - } - - { - // fill dummy fields - auto tag = (real_t)sim.metadomain()->mpiRank(); - Kokkos::deep_copy(mblock.em, (real_t)(-100.0)); - Kokkos::parallel_for( - "FillWithDummies-Flds", - mblock.rangeActiveCells(), - Lambda(ntt::index_t i1, ntt::index_t i2) { - mblock.em(i1, i2, ntt::em::ex1) = tag; - mblock.em(i1, i2, ntt::em::ex2) = tag + 0.1; - mblock.em(i1, i2, ntt::em::ex3) = tag + 0.2; - mblock.em(i1, i2, ntt::em::bx1) = tag + 0.3; - mblock.em(i1, i2, ntt::em::bx2) = tag + 0.4; - mblock.em(i1, i2, ntt::em::bx3) = tag + 0.5; - }); - } - - { - if (sim.metadomain()->mpiRank() == 0) { - auto& specie1 = mblock.particles[0]; - auto& specie2 = mblock.particles[1]; - specie1.setNpart(2); - specie2.setNpart(2); - Kokkos::parallel_for( - "FillWithDummies-Prtls", - specie1.rangeActiveParticles(), - Lambda(ntt::index_t p) { - specie1.tag(p) = ntt::ParticleTag::alive; - specie1.i1(p) = 1 + p; - specie1.i2(p) = 1 + 5 * p; - specie1.dx1(p) = 0.5; - specie1.dx2(p) = 0.5; - specie1.ux1(p) = 1.0 + (real_t)(p * 0.5); - specie1.ux2(p) = 1.0 + (real_t)(p * 4.5); - specie1.ux3(p) = 1.0 + (real_t)(p * 0.5); - - specie2.tag(p) = ntt::ParticleTag::alive; - specie2.i1(p) = 1 + 3 * p; - specie2.i2(p) = 1 + 3 * p; - specie2.dx1(p) = 0.5; - specie2.dx2(p) = 0.5; - specie2.ux1(p) = 0.5 + (real_t)(p * 0.5); - specie2.ux2(p) = 0.2 + (real_t)(p * 0.5); - specie2.ux3(p) = -0.1 + (real_t)(p * 0.5); - }); - } - } - { - // advance the fake simulation - const auto nsteps = 100; - for (auto i { 0 }; i < nsteps; ++i) { - sim.Communicate(ntt::Comm_E | ntt::Comm_B); - sim.ParticlesPush(); - sim.ParticlesBoundaryConditions(); - sim.Communicate(ntt::Comm_Prtl); - sim.writer.WriteAll(*sim.params(), - *sim.metadomain(), - mblock, - (real_t)i, - (std::size_t)i); - printf("step: %d, rank: %d, npart1: %ld, npart2: %ld\n", - i, - sim.metadomain()->mpiRank(), - mblock.particles[0].npart(), - mblock.particles[1].npart()); - } - } - } - } catch (std::exception& err) { - std::cerr << err.what() << std::endl; - ntt::GlobalFinalize(); - return -1; - } - ntt::GlobalFinalize(); - - return 0; -} -#endif \ No newline at end of file diff --git a/legacy/tests/utils-metadomain.cpp b/legacy/tests/utils-metadomain.cpp deleted file mode 100644 index b1cf80c70..000000000 --- a/legacy/tests/utils-metadomain.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include "wrapper.h" - -#include "communications/decomposition.h" -#include "communications/metadomain.h" -#include "utilities/qmath.h" - -#include -#include -#include -#include -#include - -auto main(int argc, char* argv[]) -> int { - ntt::GlobalInitialize(argc, argv); - try { - const auto resolution = std::vector({ 5000, 1800 }); -#ifdef MINKOWSKI_METRIC - const auto extent = std::vector({ 1.0, 100.0, -20.0, 15.64 }); - const auto boundaries = std::vector> { - { ntt::BoundaryCondition::PERIODIC }, - { ntt::BoundaryCondition::OPEN } - }; -#else - const auto extent = std::vector({ 1.0, 100.0, ZERO, ntt::constant::PI }); - const auto boundaries = std::vector> { - { ntt::BoundaryCondition::CUSTOM, ntt::BoundaryCondition::ABSORB }, - { ntt::BoundaryCondition::AXIS } - }; -#endif - // optional for GR - const auto spin = (real_t)(0.9); - const auto rh = ONE + std::sqrt(ONE - SQR(spin)); - // optional for Qspherical - const auto qsph_r0 = (real_t)(0.0); - const auto qsph_h = (real_t)(0.25); - - auto params = new real_t[6]; - params[0] = qsph_r0; - params[1] = qsph_h; - params[4] = spin; - params[5] = rh; - - const auto decomposition = std::vector { 7, 3 }; - - auto metadomain = ntt::Metadomain(resolution, - extent, - decomposition, - params, - boundaries, - true); - - auto first_domain = *metadomain.domainByOffset({ 0, 0 }); - auto last_domain = *metadomain.domainByOffset( - { decomposition[0] - 1, decomposition[1] - 1 }); - for (auto d { 0 }; d < 2; ++d) { - if (first_domain.offsetNdomains()[d] != 0) { - throw std::logic_error("first_domain.offsetNdomains()[d] != 0"); - } - if (first_domain.offsetNcells()[d] != 0) { - throw std::logic_error("first_domain.offsetNcells()[d] != 0"); - } - if (last_domain.offsetNdomains()[d] != decomposition[d] - 1) { - throw std::logic_error( - "last_domain.offsetNdomains()[d] != decomposition[d] - 1"); - } - if (last_domain.offsetNcells()[d] + last_domain.ncells()[d] != resolution[d]) { - throw std::logic_error("last_domain.offsetNcells()[d] + " - "last_domain.ncells()[d] != resolution[d]"); - } - } - - if (!ntt::AlmostEqual(first_domain.extent()[0], extent[0])) { - throw std::logic_error("first_domain.extent()[0] != extent[0]"); - } - if (!ntt::AlmostEqual(first_domain.extent()[2], extent[2])) { - throw std::logic_error("first_domain.extent()[2] != extent[2]"); - } - if (!ntt::AlmostEqual(last_domain.extent()[1], extent[1])) { - throw std::logic_error("last_domain.extent()[1] != extent[1]"); - } - if (!ntt::AlmostEqual(last_domain.extent()[3], extent[3])) { - throw std::logic_error("last_domain.extent()[3] != extent[3]"); - } - if (!(first_domain.boundaries()[0][0] == boundaries[0][0])) { - throw std::logic_error("wrong first_domain.boundaries()[0][0]"); - } - if (!(first_domain.boundaries()[0][1] == ntt::BoundaryCondition::COMM)) { - throw std::logic_error("wrong first_domain.boundaries()[0][1]"); - } - if (!(first_domain.boundaries()[1][0] == - (boundaries[1].size() > 1 ? boundaries[1][1] : boundaries[1][0]))) { - throw std::logic_error("wrong first_domain.boundaries()[1][0]"); - } - if (!(first_domain.boundaries()[1][1] == ntt::BoundaryCondition::COMM)) { - throw std::logic_error("wrong first_domain.boundaries()[1][1]"); - } - if (!(last_domain.boundaries()[0][0] == ntt::BoundaryCondition::COMM)) { - throw std::logic_error("wrong last_domain.boundaries()[0][0]"); - } - if (!(last_domain.boundaries()[0][1] == - (boundaries[0].size() > 1 ? boundaries[0][1] : boundaries[0][0]))) { - throw std::logic_error("wrong last_domain.boundaries()[0][1]"); - } - if (!(last_domain.boundaries()[1][0] == ntt::BoundaryCondition::COMM)) { - throw std::logic_error("wrong last_domain.boundaries()[1][0]"); - } - if (!(last_domain.boundaries()[1][1] == - (boundaries[1].size() > 1 ? boundaries[1][1] : boundaries[1][0]))) { - throw std::logic_error("wrong last_domain.boundaries()[1][1]"); - } - - auto first_domain1 = first_domain.neighbors({ 0, +1 }) - ->neighbors({ 0, +1 }) - ->neighbors({ 0, -1 }) - ->neighbors({ 0, -1 }); - - auto first_domain2 = last_domain.neighbors({ -1, -1 }) - ->neighbors({ -1, -1 }) - ->neighbors({ -1, 0 }) - ->neighbors({ -1, 0 }) - ->neighbors({ -1, 0 }) - ->neighbors({ -1, 0 }); - - if (first_domain1 != metadomain.domainByOffset({ 0, 0 })) { - throw std::logic_error("Wrong neighbor assignment"); - } - if (first_domain2 != first_domain1) { - throw std::logic_error("Wrong neighbor assignment"); - } - - if (first_domain.neighbors({ 0, -1 }) != nullptr) { - throw std::logic_error("Wrong neighbor assignment: boundaries"); - } - if (last_domain.neighbors({ 0, 1 }) != nullptr) { - throw std::logic_error("Wrong neighbor assignment: boundaries"); - } - - for (auto& domain : metadomain.domains) { - for (auto& direction : ntt::Directions::all) { - if ((domain.neighbors(direction) == nullptr) && - (domain.boundaryIn(direction) == ntt::BoundaryCondition::COMM)) { - throw std::logic_error("Neighbor == null && BC == COMM."); - } - if ((domain.neighbors(direction) != nullptr) && - (domain.boundaryIn(direction) != ntt::BoundaryCondition::COMM)) { - throw std::logic_error("Neighbor != null && BC != COMM."); - } - } - } - - } catch (std::exception& err) { - std::cerr << err.what() << std::endl; - ntt::GlobalFinalize(); - return -1; - } - ntt::GlobalFinalize(); - - return 0; -} \ No newline at end of file diff --git a/legacy/tests/utils-writer.cpp b/legacy/tests/utils-writer.cpp deleted file mode 100644 index a894e0d91..000000000 --- a/legacy/tests/utils-writer.cpp +++ /dev/null @@ -1,163 +0,0 @@ -#include "wrapper.h" - -#include "sandbox.h" -#include "sim_params.h" - -#include "communications/decomposition.h" -#include "communications/metadomain.h" -#include "meshblock/meshblock.h" -#include "utilities/qmath.h" - -#include "utilities/injector.hpp" - -#include -#include -#include - -#ifdef MPI_ENABLED - #include -#endif - -#include -#include -#include -#include -#include - -auto main(int argc, char* argv[]) -> int { - ntt::GlobalInitialize(argc, argv); - try { - toml::table simulation, domain, units, output; - toml::table particles, species_1, species_2, species_3; - const auto simname = "Writer-" + std::string(SIMULATION_METRIC); - simulation["title"] = simname; - domain["resolution"] = toml::array { 250, 400 }; - - particles["n_species"] = 3; - species_1["mass"] = 1.0; - species_1["charge"] = -1.0; - species_1["maxnpart"] = 1e6; - species_2["mass"] = 1.0; - species_2["charge"] = 1.0; - species_2["maxnpart"] = 1e6; - species_3["mass"] = 0.0; - species_3["charge"] = 0.0; - species_3["maxnpart"] = 1e6; - -#ifdef MINKOWSKI_METRIC - domain["extent"] = toml::array { -50.0, 50.0, -20.0, 140.0 }; - domain["boundaries"] = toml::array { toml::array { "PERIODIC" }, - toml::array { "PERIODIC" } }; -#else - domain["extent"] = toml::array { 1.0, 150.0 }; - domain["boundaries"] = toml::array { - toml::array { "OPEN", "ABSORB" }, - toml::array { "AXIS" } - }; - domain["qsph_r0"] = 0.0; - domain["qsph_h"] = 0.4; - domain["spin"] = 0.9; -#endif - - units["ppc0"] = 1.0; - units["larmor0"] = 1.0; - units["skindepth0"] = 1.0; - - output["fields"] = toml::array { "E", "B" }; - output["particles"] = toml::array { "X", "U" }; - output["prtl_stride"] = 1; - output["format"] = "HDF5"; - output["as_is"] = true; - output["ghosts"] = true; - - auto inputdata = toml::table { - {"simulation", simulation}, - { "domain", domain}, - { "units", units}, - { "output", output}, - { "particles", particles}, - { "species_1", species_1}, - { "species_2", species_2}, - { "species_3", species_3} - }; - - // write - { - ntt::SANDBOX sim(inputdata); - auto& mblock = sim.meshblock; - // allocate fields - mblock.em = ntt::ndfield_t { "em", - mblock.Ni1() + 2 * N_GHOSTS, - mblock.Ni2() + 2 * N_GHOSTS }; - mblock.bckp = ntt::ndfield_t { "bckp", - mblock.Ni1() + 2 * N_GHOSTS, - mblock.Ni2() + 2 * N_GHOSTS }; - - // allocate particles - for (auto& specie : mblock.particles) { - specie.i1 = ntt::array_t { specie.label() + "_i1", - specie.maxnpart() }; - specie.i2 = ntt::array_t { specie.label() + "_i2", - specie.maxnpart() }; - specie.dx1 = ntt::array_t { specie.label() + "_dx1", - specie.maxnpart() }; - specie.dx2 = ntt::array_t { specie.label() + "_dx2", - specie.maxnpart() }; - specie.ux1 = ntt::array_t { specie.label() + "_ux1", - specie.maxnpart() }; - specie.ux2 = ntt::array_t { specie.label() + "_ux2", - specie.maxnpart() }; - specie.ux3 = ntt::array_t { specie.label() + "_ux3", - specie.maxnpart() }; - specie.weight = ntt::array_t { specie.label() + "_w", - specie.maxnpart() }; -#ifndef MINKOWSKI_METRIC - specie.phi = ntt::array_t { specie.label() + "_phi", - specie.maxnpart() }; -#endif - specie.tag = ntt::array_t { specie.label() + "_tag", - specie.maxnpart() }; - } - - { - // fill dummy fields -#ifdef MPI_ENABLED - auto tag = (real_t)sim.metadomain()->mpiRank(); -#else - auto tag = ZERO; -#endif - Kokkos::deep_copy(mblock.em, (real_t)(-100.0)); - Kokkos::parallel_for( - "FillWithDummies", - mblock.rangeActiveCells(), - Lambda(ntt::index_t i1, ntt::index_t i2) { - mblock.em(i1, i2, ntt::em::ex1) = tag; - mblock.em(i1, i2, ntt::em::ex2) = tag + 0.1; - mblock.em(i1, i2, ntt::em::ex3) = tag + 0.2; - mblock.em(i1, i2, ntt::em::bx1) = tag + 0.3; - mblock.em(i1, i2, ntt::em::bx2) = tag + 0.4; - mblock.em(i1, i2, ntt::em::bx3) = tag + 0.5; - }); - } - { - ntt::InjectInVolume(*sim.params(), - mblock, - { 1, 2 }, - 2.0); - } - sim.Communicate(ntt::Comm_E | ntt::Comm_B); - sim.writer.WriteAll(*sim.params(), *sim.metadomain(), mblock, ZERO, 0); - for (auto& specie : mblock.particles) { - specie.setNpart((std::size_t)(specie.npart() / 2)); - } - sim.writer.WriteAll(*sim.params(), *sim.metadomain(), mblock, ZERO, 0); - } - } catch (std::exception& err) { - std::cerr << err.what() << std::endl; - ntt::GlobalFinalize(); - return -1; - } - ntt::GlobalFinalize(); - - return 0; -} \ No newline at end of file diff --git a/pgens/accretion/accretion.toml b/pgens/accretion/accretion.toml index 1ec641430..9215da6b2 100644 --- a/pgens/accretion/accretion.toml +++ b/pgens/accretion/accretion.toml @@ -67,7 +67,7 @@ m_eps = 1.0 [output] - format = "hdf5" + format = "BPFile" [output.fields] interval_time = 1.0 diff --git a/pgens/accretion/pgen.hpp b/pgens/accretion/pgen.hpp index 54a607352..2266f4e18 100644 --- a/pgens/accretion/pgen.hpp +++ b/pgens/accretion/pgen.hpp @@ -43,8 +43,7 @@ namespace user { TWO * metric.spin() * g_00); } - Inline auto bx1(const coord_t& x_Ph) const - -> real_t { // at ( i , j + HALF ) + Inline auto bx1(const coord_t& x_Ph) const -> real_t { // at ( i , j + HALF ) coord_t xi { ZERO }, x0m { ZERO }, x0p { ZERO }; metric.template convert(x_Ph, xi); @@ -62,8 +61,7 @@ namespace user { } } - Inline auto bx2(const coord_t& x_Ph) const - -> real_t { // at ( i + HALF , j ) + Inline auto bx2(const coord_t& x_Ph) const -> real_t { // at ( i + HALF , j ) coord_t xi { ZERO }, x0m { ZERO }, x0p { ZERO }; metric.template convert(x_Ph, xi); @@ -242,16 +240,14 @@ namespace user { params, &local_domain); - const auto injector = - arch::NonUniformInjector( - energy_dist, - spatial_dist, - { 1, 2 }); - arch::InjectNonUniform(params, - local_domain, - injector, - 1.0, - true); + arch::InjectNonUniform( + params, + local_domain, + { 1, 2 }, + { energy_dist, energy_dist }, + spatial_dist, + ONE, + true); } void CustomPostStep(std::size_t, long double time, Domain& local_domain) { @@ -264,17 +260,14 @@ namespace user { multiplicity * nGJ, params, &local_domain); - - const auto injector = - arch::NonUniformInjector( - energy_dist, - spatial_dist, - { 1, 2 }); - arch::InjectNonUniform(params, - local_domain, - injector, - 1.0, - true); + arch::InjectNonUniform( + params, + local_domain, + { 1, 2 }, + { energy_dist, energy_dist }, + spatial_dist, + ONE, + true); } }; diff --git a/pgens/magnetosphere/magnetosphere.toml b/pgens/magnetosphere/magnetosphere.toml index 0eb9a03f3..4a8eca87e 100644 --- a/pgens/magnetosphere/magnetosphere.toml +++ b/pgens/magnetosphere/magnetosphere.toml @@ -63,7 +63,7 @@ period = 60.0 [output] - format = "hdf5" + format = "BPFile" [output.fields] interval_time = 0.1 @@ -74,6 +74,3 @@ [output.spectra] enable = false - -[diagnostics] - interval = 50 diff --git a/pgens/reconnection/pgen.hpp b/pgens/reconnection/pgen.hpp index 91aa46394..b446c11f2 100644 --- a/pgens/reconnection/pgen.hpp +++ b/pgens/reconnection/pgen.hpp @@ -4,7 +4,6 @@ #include "enums.h" #include "global.h" -#include "arch/directions.h" #include "arch/kokkos_aliases.h" #include "arch/traits.h" #include "utils/numeric.h" @@ -139,15 +138,6 @@ namespace user { }; // constant particle density for particle boundaries - template - struct ConstDens { - Inline auto operator()(const coord_t& x_Ph) const -> real_t { - return ONE; - } - }; - template - using spatial_dist_t = arch::Replenish>; - template struct PGen : public arch::ProblemGenerator { // compatibility traits for the problem generator @@ -224,21 +214,18 @@ namespace user { auto edist_cs = arch::Maxwellian(local_domain.mesh.metric, local_domain.random_pool, cs_temperature, - cs_drift_u, - in::x3, - false); + { ZERO, ZERO, cs_drift_u }); const auto sdist_cs = CurrentLayer(local_domain.mesh.metric, cs_width, cs_x, cs_y); - const auto inj_cs = arch::NonUniformInjector( - edist_cs, + arch::InjectNonUniform( + params, + local_domain, + { 1, 2 }, + { edist_cs, edist_cs }, sdist_cs, - { 1, 2 }); - arch::InjectNonUniform(params, - local_domain, - inj_cs, - cs_overdensity); + cs_overdensity); } void CustomPostStep(timestep_t, simtime_t time, Domain& domain) { @@ -258,15 +245,10 @@ namespace user { const auto dx = domain.mesh.metric.template sqrt_h_<1, 1>({}); boundaries_t inj_box_up, inj_box_down; - boundaries_t probe_box_up, probe_box_down; inj_box_up.push_back(Range::All); inj_box_down.push_back(Range::All); - probe_box_up.push_back(Range::All); - probe_box_down.push_back(Range::All); inj_box_up.push_back({ ymax - inj_ypad - 10 * dx, ymax - inj_ypad }); inj_box_down.push_back({ ymin + inj_ypad, ymin + inj_ypad + 10 * dx }); - probe_box_up.push_back({ ymax - inj_ypad - 10 * dx, ymax - inj_ypad }); - probe_box_down.push_back({ ymin + inj_ypad, ymin + inj_ypad + 10 * dx }); if constexpr (M::Dim == Dim::_3D) { inj_box_up.push_back(Range::All); @@ -303,28 +285,26 @@ namespace user { Kokkos::Experimental::contribute(domain.fields.buff, scatter_buff); } - const auto injector_up = arch::KeepConstantInjector( - energy_dist, - { 1, 2 }, - 0u, - probe_box_up); - const auto injector_down = arch::KeepConstantInjector( - energy_dist, - { 1, 2 }, + const auto replenish_sdist = arch::ReplenishUniform( + domain.mesh.metric, + domain.fields.buff, 0u, - probe_box_down); - - arch::InjectUniform( + ONE); + arch::InjectNonUniform( params, domain, - injector_up, + { 1, 2 }, + { energy_dist, energy_dist }, + replenish_sdist, ONE, params.template get("particles.use_weights"), inj_box_up); - arch::InjectUniform( + arch::InjectNonUniform( params, domain, - injector_down, + { 1, 2 }, + { energy_dist, energy_dist }, + replenish_sdist, ONE, params.template get("particles.use_weights"), inj_box_down); diff --git a/pgens/shock/pgen.hpp b/pgens/shock/pgen.hpp index f93bbfd0e..fc579777d 100644 --- a/pgens/shock/pgen.hpp +++ b/pgens/shock/pgen.hpp @@ -8,9 +8,7 @@ #include "utils/error.h" #include "utils/numeric.h" -#include "archetypes/energy_dist.h" #include "archetypes/field_setter.h" -#include "archetypes/particle_injector.h" #include "archetypes/problem_generator.h" #include "archetypes/utils.h" #include "framework/domain/metadomain.h" @@ -82,6 +80,8 @@ namespace user { using arch::ProblemGenerator::C; using arch::ProblemGenerator::params; + Metadomain& global_domain; + // domain properties const real_t global_xmin, global_xmax; // gas properties @@ -93,8 +93,9 @@ namespace user { real_t Btheta, Bphi, Bmag; InitFields init_flds; - inline PGen(const SimulationParams& p, const Metadomain& global_domain) + inline PGen(const SimulationParams& p, Metadomain& global_domain) : arch::ProblemGenerator { p } + , global_domain { global_domain } , global_xmin { global_domain.mesh().extent(in::x1).first } , global_xmax { global_domain.mesh().extent(in::x1).second } , drift_ux { p.template get("setup.drift_ux") } @@ -116,8 +117,8 @@ namespace user { return init_flds; } - auto FixFieldsConst(const bc_in&, const em& comp) const - -> std::pair { + auto FixFieldsConst(const bc_in&, + const em& comp) const -> std::pair { if (comp == em::ex1) { return { init_flds.ex1({ ZERO }), true }; } else if (comp == em::ex2) { @@ -169,15 +170,15 @@ namespace user { } } - // species #1 -> e^- - // species #2 -> protons - - // energy distribution of the particles + // define temperatures of species const auto temperatures = std::make_pair(temperature, temperature_ratio * temperature); + // define drift speed of species const auto drifts = std::make_pair( std::vector { -drift_ux, ZERO, ZERO }, std::vector { -drift_ux, ZERO, ZERO }); + + // inject particles arch::InjectUniformMaxwellians(params, domain, ONE, @@ -257,6 +258,7 @@ namespace user { domain.fields.em, init_flds, domain.mesh.metric }); + global_domain.CommunicateFields(domain, Comm::E | Comm::B); /* tag particles inside the injection zone as dead diff --git a/pgens/shock/shock.toml b/pgens/shock/shock.toml index 90678488a..4148d3613 100644 --- a/pgens/shock/shock.toml +++ b/pgens/shock/shock.toml @@ -4,7 +4,7 @@ runtime = 50.0 [simulation.domain] - decomposition = [1,-1] + decomposition = [1, -1] [grid] resolution = [4096, 128] @@ -14,10 +14,10 @@ metric = "minkowski" [grid.boundaries] - fields = [["CONDUCTOR", "MATCH"], ["PERIODIC"]] + fields = [["CONDUCTOR", "MATCH"], ["PERIODIC"]] particles = [["REFLECT", "ABSORB"], ["PERIODIC"]] - + [scales] larmor0 = 0.057735 skindepth0 = 0.01 @@ -44,27 +44,27 @@ maxnpart = 8e7 [setup] - drift_ux = 0.15 # speed towards the wall [c] - temperature = 0.001683 # temperature of maxwell distribution [kB T / (m_i c^2)] - temperature_ratio = 1.0 # temperature ratio of electrons to protons - Bmag = 1.0 # magnetic field strength as fraction of magnetisation - Btheta = 63.0 # magnetic field angle in the plane - Bphi = 0.0 # magnetic field angle out of plane - filling_fraction = 0.1 # fraction of the shock piston filled with plasma - injector_velocity = 0.2 # speed of injector [c] - injection_start = 0.0 # start time of moving injector - injection_frequency = 100 # inject particles every 100 timesteps + drift_ux = 0.15 # speed towards the wall [c] + temperature = 0.001683 # temperature of maxwell distribution [kB T / (m_i c^2)] + temperature_ratio = 1.0 # temperature ratio of electrons to protons + Bmag = 1.0 # magnetic field strength as fraction of magnetisation + Btheta = 63.0 # magnetic field angle in the plane + Bphi = 0.0 # magnetic field angle out of plane + filling_fraction = 0.1 # fraction of the shock piston filled with plasma + injector_velocity = 0.2 # speed of injector [c] + injection_start = 0.0 # start time of moving injector + injection_frequency = 100 # inject particles every 100 timesteps [output] interval_time = 0.1 - format = "hdf5" - + format = "BPFile" + [output.fields] quantities = ["N_1", "N_2", "B", "E"] [output.particles] enable = true - stride = 10 + stride = 10 [output.spectra] enable = false diff --git a/pgens/streaming/bell.toml b/pgens/streaming/bell.toml new file mode 100644 index 000000000..d495e7c17 --- /dev/null +++ b/pgens/streaming/bell.toml @@ -0,0 +1,99 @@ +[simulation] + name = "bell" + engine = "srpic" + runtime = 100000.0 + +[grid] + resolution = [8192] + extent = [[0.0, 512.0]] + + [grid.metric] + metric = "minkowski" + + [grid.boundaries] + fields = [["PERIODIC"]] + particles = [["PERIODIC"]] + +[scales] + larmor0 = 1.0 + skindepth0 = 1.0 + +[algorithms] + current_filters = 8 + + [algorithms.timestep] + CFL = 0.5 + +[particles] + ppc0 = 512.0 + + [[particles.species]] + label = "ions" + mass = 50.0 + charge = 1.0 + maxnpart = 5e6 + + [[particles.species]] + label = "e-1" + mass = 1.0 + charge = -1.0 + maxnpart = 5e6 + + [[particles.species]] + label = "CR" + mass = 50.0 + charge = 1.0 + maxnpart = 1e5 + + [[particles.species]] + label = "e-2" + mass = 1.0 + charge = -1.0 + maxnpart = 1e5 + +[setup] + # Drift 4-velocities for each species in all 3 directions + # @type: array of floats (length = nspec) + # @default: [ 0.0, ... ] + drifts_in_x = [0.0, -0.00990098030746225, -99.9962499609, -0.00990098030746225] + drifts_in_y = [0.0, 0.0, 0.0, 0.0] + drifts_in_z = [0.0, 0.0, 0.0, 0.0] + # Pair-wise species densities in units of n0 + # @type: array of floats (length = nspec/2) + # @default: [ 2 / nspec, ... ] + densities = [1.0, 0.01] + # Species temperatures in units of m0 (c^2) + # @type: array of floats (length = nspec) + # @default: [ 0.0, ... ] + temperatures = [1e-4, 1e-4, 1e-4, 1e-4] + # Magnetic field + Bmag = 1.0 # magnetic field strength as fraction of magnetisation + Btheta = 0.0 # magnetic field angle in the plane [deg] + Bphi = 0.0 # magnetic field angle out of plane [deg] + +[output] + interval_time = 100.0 + format = "BPFile" + + [output.fields] + enable = true + quantities = ["E", "B"] + + [output.spectra] + enable = false + + [output.particles] + enable = false + + [output.stats] + enable = true + interval_time = 10.0 + +[diagnostics] + log_level = "WARNING" + blocking_timers = true + colored_stdout = false + +[checkpoint] + interval = 1000 + keep = 1 diff --git a/pgens/streaming/pgen.hpp b/pgens/streaming/pgen.hpp index 1b8311b34..dca6cc31d 100644 --- a/pgens/streaming/pgen.hpp +++ b/pgens/streaming/pgen.hpp @@ -16,6 +16,39 @@ namespace user { using namespace ntt; + using prmvec_t = std::vector; + + template + struct InitFields { + + /* + Sets up background magnetic field for the simulation. + + @param bmag: magnetic field scaling + @param btheta: magnetic field polar angle + @param bphi: magnetic field azimuthal angle + */ + InitFields(real_t bmag, real_t btheta, real_t bphi) + : Bmag { bmag } + , Btheta { btheta * static_cast(convert::deg2rad) } + , Bphi { bphi * static_cast(convert::deg2rad) } {} + + // magnetic field components + Inline auto bx1(const coord_t&) const -> real_t { + return Bmag * math::cos(Btheta); + } + + Inline auto bx2(const coord_t&) const -> real_t { + return Bmag * math::sin(Btheta) * math::sin(Bphi); + } + + Inline auto bx3(const coord_t&) const -> real_t { + return Bmag * math::sin(Btheta) * math::cos(Bphi); + } + + private: + const real_t Btheta, Bphi, Bmag; + }; template struct PGen : public arch::ProblemGenerator { @@ -31,16 +64,21 @@ namespace user { using arch::ProblemGenerator::C; using arch::ProblemGenerator::params; - using prmvec_t = std::vector; - prmvec_t drifts_in_x, drifts_in_y, drifts_in_z; prmvec_t densities, temperatures; + // initial magnetic field + real_t Btheta, Bphi, Bmag; + InitFields init_flds; inline PGen(const SimulationParams& p, const Metadomain& global_domain) : arch::ProblemGenerator { p } , drifts_in_x { p.template get("setup.drifts_in_x", prmvec_t {}) } , drifts_in_y { p.template get("setup.drifts_in_y", prmvec_t {}) } , drifts_in_z { p.template get("setup.drifts_in_z", prmvec_t {}) } + , Bmag { p.template get("setup.Bmag", ZERO) } + , Btheta { p.template get("setup.Btheta", ZERO) } + , Bphi { p.template get("setup.Bphi", ZERO) } + , init_flds { Bmag, Btheta, Bphi } , densities { p.template get("setup.densities", prmvec_t {}) } , temperatures { p.template get("setup.temperatures", prmvec_t {}) } { const auto nspec = p.template get("particles.nspec"); diff --git a/pgens/turbulence/pgen.hpp b/pgens/turbulence/pgen.hpp index 4c4a2c78e..e8001b090 100644 --- a/pgens/turbulence/pgen.hpp +++ b/pgens/turbulence/pgen.hpp @@ -11,6 +11,7 @@ #include "archetypes/energy_dist.h" #include "archetypes/particle_injector.h" #include "archetypes/problem_generator.h" +#include "archetypes/utils.h" #include "framework/domain/domain.h" #include "framework/domain/metadomain.h" @@ -38,22 +39,24 @@ namespace user { Inline auto bx1(const coord_t& x_Ph) const -> real_t { auto bx1_0 = ZERO; - if constexpr(D==Dim::_2D){ + if constexpr (D == Dim::_2D) { for (auto i = 0; i < n_modes; i++) { auto k_dot_r = k(0, i) * x_Ph[0] + k(1, i) * x_Ph[1]; bx1_0 -= TWO * k(1, i) * - (a_real(i) * math::sin(k_dot_r) + a_imag(i) * math::cos(k_dot_r)); + (a_real(i) * math::sin(k_dot_r) + + a_imag(i) * math::cos(k_dot_r)); bx1_0 -= TWO * k(1, i) * - (a_real_inv(i) * math::sin(k_dot_r) + - a_imag_inv(i) * math::cos(k_dot_r)); + (a_real_inv(i) * math::sin(k_dot_r) + + a_imag_inv(i) * math::cos(k_dot_r)); } return bx1_0; } - if constexpr (D==Dim::_3D){ - for (auto i = 0; i < n_modes; i++) { - auto k_dot_r = k(0, i) * x_Ph[0] + k(1, i) * x_Ph[1] + k(2, i) * x_Ph[2]; + if constexpr (D == Dim::_3D) { + for (auto i = 0; i < n_modes; i++) { + auto k_dot_r = k(0, i) * x_Ph[0] + k(1, i) * x_Ph[1] + k(2, i) * x_Ph[2]; bx1_0 -= TWO * k(1, i) * - (a_real(i) * math::sin(k_dot_r) + a_imag(i) * math::cos(k_dot_r)); + (a_real(i) * math::sin(k_dot_r) + + a_imag(i) * math::cos(k_dot_r)); } return bx1_0; } @@ -61,22 +64,24 @@ namespace user { Inline auto bx2(const coord_t& x_Ph) const -> real_t { auto bx2_0 = ZERO; - if constexpr (D==Dim::_2D){ + if constexpr (D == Dim::_2D) { for (auto i = 0; i < n_modes; i++) { auto k_dot_r = k(0, i) * x_Ph[0] + k(1, i) * x_Ph[1]; bx2_0 += TWO * k(0, i) * - (a_real(i) * math::sin(k_dot_r) + a_imag(i) * math::cos(k_dot_r)); + (a_real(i) * math::sin(k_dot_r) + + a_imag(i) * math::cos(k_dot_r)); bx2_0 += TWO * k(0, i) * (a_real_inv(i) * math::sin(k_dot_r) + a_imag_inv(i) * math::cos(k_dot_r)); } return bx2_0; } - if constexpr (D==Dim::_3D){ + if constexpr (D == Dim::_3D) { for (auto i = 0; i < n_modes; i++) { - auto k_dot_r = k(0, i) * x_Ph[0] + k(1, i) * x_Ph[1] + k(2, i) * x_Ph[2]; + auto k_dot_r = k(0, i) * x_Ph[0] + k(1, i) * x_Ph[1] + k(2, i) * x_Ph[2]; bx2_0 += TWO * k(0, i) * - (a_real(i) * math::sin(k_dot_r) + a_imag(i) * math::cos(k_dot_r)); + (a_real(i) * math::sin(k_dot_r) + + a_imag(i) * math::cos(k_dot_r)); } return bx2_0; } @@ -94,8 +99,8 @@ namespace user { std::size_t n_modes; }; - inline auto init_pool(int seed) -> unsigned int { - if (seed < 0) { + inline auto init_pool(unsigned int seed) -> unsigned int { + if (seed == 0) { unsigned int new_seed = static_cast(rand()); #if defined(MPI_ENABLED) MPI_Bcast(&new_seed, 1, MPI_UNSIGNED, MPI_ROOT_RANK, MPI_COMM_WORLD); @@ -117,14 +122,14 @@ namespace user { }; } else if constexpr (D == Dim::_3D) { return { - { 1, 0, 1 }, - { 0, 1, 1 }, - { -1, 0, 1 }, - { 0, -1, 1 }, - { 1, 0,-1 }, - { 0, 1,-1 }, - { -1, 0,-1 }, - { 0, -1,-1 } + { 1, 0, 1 }, + { 0, 1, 1 }, + { -1, 0, 1 }, + { 0, -1, 1 }, + { 1, 0, -1 }, + { 0, 1, -1 }, + { -1, 0, -1 }, + { 0, -1, -1 } }; } else { raise::Error("Invalid dimension", HERE); @@ -158,7 +163,7 @@ namespace user { , a_real_inv { "a_real_inv", n_modes } , a_imag_inv { "a_imag_inv", n_modes } , A0 { "A0", n_modes } { - // initializing random generator + // initializing random generator srand(seed); // initializing wavevectors auto k_host = Kokkos::create_mirror_view(k); @@ -191,11 +196,13 @@ namespace user { for (auto i = 0u; i < n_modes; i++) { auto k_perp = math::sqrt( k_host(0, i) * k_host(0, i) + k_host(1, i) * k_host(1, i)); - real_t phase = static_cast (rand()) / static_cast (RAND_MAX) * constant::TWO_PI; - A0_host(i) = dB / math::sqrt((real_t)n_modes) / k_perp * prefac; - a_real_host(i) = A0_host(i) * math::cos(phase); - a_imag_host(i) = A0_host(i) * math::sin(phase); - phase = static_cast (rand()) / static_cast (RAND_MAX) * constant::TWO_PI; + real_t phase = static_cast(rand()) / + static_cast(RAND_MAX) * constant::TWO_PI; + A0_host(i) = dB / math::sqrt((real_t)n_modes) / k_perp * prefac; + a_real_host(i) = A0_host(i) * math::cos(phase); + a_imag_host(i) = A0_host(i) * math::sin(phase); + phase = static_cast(rand()) / static_cast(RAND_MAX) * + constant::TWO_PI; a_imag_inv_host(i) = A0_host(i) * math::cos(phase); a_real_inv_host(i) = A0_host(i) * math::sin(phase); } @@ -270,7 +277,7 @@ namespace user { const std::vector> wavenumbers; const std::size_t n_modes; const real_t dB, Lx, Ly, Lz; - const int seed; + const unsigned int seed; public: const real_t omega_0, gamma_0; @@ -297,7 +304,7 @@ namespace user { const real_t temperature, dB, omega_0, gamma_0; const real_t Lx, Ly, Lz, escape_dist; - const int random_seed; + const unsigned int random_seed; std::vector> wavenumbers; random_number_pool_t random_pool; @@ -316,7 +323,7 @@ namespace user { , omega_0 { p.template get("setup.omega_0") } , gamma_0 { p.template get("setup.gamma_0") } , wavenumbers { init_wavenumbers() } - , random_seed { p.template get("setup.seed", -1) } + , random_seed { p.template get("setup.seed", 0) } , random_pool { init_pool(random_seed) } , Lx { global_domain.mesh().extent(in::x1).second - global_domain.mesh().extent(in::x1).first } @@ -325,32 +332,23 @@ namespace user { , Lz { global_domain.mesh().extent(in::x3).second - global_domain.mesh().extent(in::x3).first } , escape_dist { p.template get("setup.escape_dist", HALF * Lx) } - , ext_current { dB, omega_0, gamma_0, wavenumbers, init_pool(random_seed), Lx, Ly, Lz } + , ext_current { dB, omega_0, gamma_0, wavenumbers, init_pool(random_seed), + Lx, Ly, Lz } , init_flds { ext_current.k, ext_current.a_real, ext_current.a_imag, ext_current.a_real_inv, ext_current.a_imag_inv } {}; - inline void InitPrtls(Domain& local_domain) { - const auto energy_dist = arch::Maxwellian(local_domain.mesh.metric, - local_domain.random_pool, - temperature); - const auto spatial_dist = arch::UniformInjector( - energy_dist, - { 1, 2 }); - arch::InjectUniform>( - params, - local_domain, - spatial_dist, - ONE); - }; + inline void InitPrtls(Domain& domain) { + arch::InjectUniformMaxwellian(params, domain, ONE, temperature, { 1, 2 }); + } void CustomPostStep(timestep_t, simtime_t, Domain& domain) { - #if defined(MPI_ENABLED) - int rank; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - #endif +#if defined(MPI_ENABLED) + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); +#endif // update amplitudes of antenna const auto dt = params.template get("algorithms.timestep.dt"); const auto& ext_curr = ext_current; @@ -403,13 +401,13 @@ namespace user { domain.random_pool, temperature); for (const auto& sp : { 0, 1 }) { - if (domain.species[sp].npld() > 1) { - const auto& ux1 = domain.species[sp].ux1; - const auto& ux2 = domain.species[sp].ux2; - const auto& ux3 = domain.species[sp].ux3; - const auto& pld = domain.species[sp].pld; - const auto& tag = domain.species[sp].tag; - const auto L = escape_dist; + if (domain.species[sp].npld_r() > 1) { + const auto& ux1 = domain.species[sp].ux1; + const auto& ux2 = domain.species[sp].ux2; + const auto& ux3 = domain.species[sp].ux3; + const auto& pld_r = domain.species[sp].pld_r; + const auto& tag = domain.species[sp].tag; + const auto L = escape_dist; Kokkos::parallel_for( "UpdatePld", domain.species[sp].npart(), @@ -419,18 +417,18 @@ namespace user { } const auto gamma = math::sqrt( ONE + ux1(p) * ux1(p) + ux2(p) * ux2(p) + ux3(p) * ux3(p)); - pld(p, 0) += ux1(p) * dt / gamma; - pld(p, 1) += ux2(p) * dt / gamma; + pld_r(p, 0) += ux1(p) * dt / gamma; + pld_r(p, 1) += ux2(p) * dt / gamma; - if ((math::abs(pld(p, 0)) > L) or (math::abs(pld(p, 1)) > L)) { + if ((math::abs(pld_r(p, 0)) > L) or (math::abs(pld_r(p, 1)) > L)) { coord_t x_Ph { ZERO }; vec_t u_Mxw { ZERO }; energy_dist(x_Ph, u_Mxw); - ux1(p) = u_Mxw[0]; - ux2(p) = u_Mxw[1]; - ux3(p) = u_Mxw[2]; - pld(p, 0) = ZERO; - pld(p, 1) = ZERO; + ux1(p) = u_Mxw[0]; + ux2(p) = u_Mxw[1]; + ux3(p) = u_Mxw[2]; + pld_r(p, 0) = ZERO; + pld_r(p, 1) = ZERO; } }); } diff --git a/pgens/turbulence/turbulence.toml b/pgens/turbulence/turbulence.toml index 79cc641ef..a79bd07ad 100644 --- a/pgens/turbulence/turbulence.toml +++ b/pgens/turbulence/turbulence.toml @@ -42,12 +42,12 @@ [setup] temperature = 1e0 dB = 1.0 - omega_0 = 0.0156 - gamma_0 = 0.0078 - + omega_0 = 0.0156 + gamma_0 = 0.0078 + [output] - format = "hdf5" + format = "BPFile" interval_time = 12.0 [output.fields] diff --git a/pgens/wald/wald.toml b/pgens/wald/wald.toml index 2b05fbac9..7cdff5717 100644 --- a/pgens/wald/wald.toml +++ b/pgens/wald/wald.toml @@ -41,7 +41,7 @@ init_field = "wald" # or "vertical" [output] - format = "hdf5" + format = "BPFile" [output.fields] interval_time = 1.0 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5f2afc824..31114c330 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,10 +33,6 @@ add_subdirectory(${SRC_DIR}/framework ${CMAKE_CURRENT_BINARY_DIR}/framework) add_subdirectory(${SRC_DIR}/engines ${CMAKE_CURRENT_BINARY_DIR}/engines) add_subdirectory(${SRC_DIR}/output ${CMAKE_CURRENT_BINARY_DIR}/output) -if(${output}) - add_subdirectory(${SRC_DIR}/checkpoint ${CMAKE_CURRENT_BINARY_DIR}/checkpoint) -endif() - set(ENTITY ${PROJECT_NAME}.xc) set(SOURCES ${SRC_DIR}/entity.cpp) diff --git a/src/archetypes/energy_dist.h b/src/archetypes/energy_dist.h index bcb88fbc3..56a797751 100644 --- a/src/archetypes/energy_dist.h +++ b/src/archetypes/energy_dist.h @@ -48,9 +48,7 @@ namespace arch { struct Cold : public EnergyDistribution { Cold(const M& metric) : EnergyDistribution { metric } {} - Inline void operator()(const coord_t&, - vec_t& v, - spidx_t = 0) const { + Inline void operator()(const coord_t&, vec_t& v) const { v[0] = ZERO; v[1] = ZERO; @@ -73,9 +71,7 @@ namespace arch { , pl_ind { pl_ind } , pool { pool } {} - Inline void operator()(const coord_t&, - vec_t& v, - spidx_t = 0) const { + Inline void operator()(const coord_t&, vec_t& v) const { auto rand_gen = pool.get_state(); auto rand_X1 = Random(rand_gen); auto rand_gam = ONE; @@ -107,7 +103,7 @@ namespace arch { }; Inline void JuttnerSinge(vec_t& v, - const real_t& temp, + real_t temp, const random_number_pool_t& pool) { auto rand_gen = pool.get_state(); real_t randX1, randX2; @@ -165,13 +161,12 @@ namespace arch { } template - Inline void SampleFromMaxwellian( - vec_t& v, - const random_number_pool_t& pool, - const real_t& temperature, - const real_t& boost_velocity = static_cast(0), - const in& boost_direction = in::x1, - bool flip_velocity = false) { + Inline void SampleFromMaxwellian(vec_t& v, + const random_number_pool_t& pool, + real_t temperature, + real_t boost_velocity = static_cast(0), + in boost_direction = in::x1, + bool flip_velocity = false) { if (cmp::AlmostZero(temperature)) { v[0] = ZERO; v[1] = ZERO; @@ -208,228 +203,123 @@ namespace arch { struct Maxwellian : public EnergyDistribution { using EnergyDistribution::metric; - Maxwellian(const M& metric, - random_number_pool_t& pool, - real_t temperature, - real_t boost_vel = ZERO, - in boost_direction = in::x1, - bool zero_current = true) + Maxwellian(const M& metric, + random_number_pool_t& pool, + real_t temperature, + const std::vector& drift_four_vel = { ZERO, ZERO, ZERO }) : EnergyDistribution { metric } , pool { pool } - , temperature { temperature } - , boost_velocity { boost_vel } - , boost_direction { boost_direction } - , zero_current { zero_current } { + , temperature { temperature } { + raise::ErrorIf(drift_four_vel.size() != 3, + "Maxwellian: Drift velocity must be a 3D vector", + HERE); raise::ErrorIf(temperature < ZERO, "Maxwellian: Temperature must be non-negative", HERE); - raise::ErrorIf( - (not cmp::AlmostZero_host(boost_vel, ZERO)) && (M::CoordType != Coord::Cart), - "Maxwellian: Boosting is only supported in Cartesian coordinates", - HERE); - } - - Inline void operator()(const coord_t&, - vec_t& v, - spidx_t sp = 0) const { - SampleFromMaxwellian(v, - pool, - temperature, - boost_velocity, - boost_direction, - not zero_current and - sp % 2 == 0); - } - - private: - random_number_pool_t pool; - - const real_t temperature; - const real_t boost_velocity; - const in boost_direction; - const bool zero_current; - }; - - template - struct TwoTemperatureMaxwellian : public EnergyDistribution { - using EnergyDistribution::metric; - - TwoTemperatureMaxwellian(const M& metric, - random_number_pool_t& pool, - const std::pair& temperatures, - const std::pair& species, - real_t boost_vel = ZERO, - in boost_direction = in::x1, - bool zero_current = true) - : EnergyDistribution { metric } - , pool { pool } - , temperature_1 { temperatures.first } - , temperature_2 { temperatures.second } - , sp_1 { species.first } - , sp_2 { species.second } - , boost_velocity { boost_vel } - , boost_direction { boost_direction } - , zero_current { zero_current } { - raise::ErrorIf( - (temperature_1 < ZERO) or (temperature_2 < ZERO), - "TwoTemperatureMaxwellian: Temperature must be non-negative", - HERE); - raise::ErrorIf((not cmp::AlmostZero(boost_vel, ZERO)) && - (M::CoordType != Coord::Cart), - "TwoTemperatureMaxwellian: Boosting is only supported in " - "Cartesian coordinates", - HERE); - } - - Inline void operator()(const coord_t&, - vec_t& v, - spidx_t sp = 0) const { - SampleFromMaxwellian( - v, - pool, - (sp == sp_1) ? temperature_1 : temperature_2, - boost_velocity, - boost_direction, - not zero_current and sp == sp_1); - } - - private: - random_number_pool_t pool; - - const real_t temperature_1, temperature_2; - const spidx_t sp_1, sp_2; - const real_t boost_velocity; - const in boost_direction; - const bool zero_current; - }; - - namespace experimental { - - template - struct Maxwellian : public EnergyDistribution { - using EnergyDistribution::metric; - - Maxwellian(const M& metric, - random_number_pool_t& pool, - real_t temperature, - const std::vector& drift_four_vel = { ZERO, ZERO, ZERO }) - : EnergyDistribution { metric } - , pool { pool } - , temperature { temperature } { - raise::ErrorIf(drift_four_vel.size() != 3, - "Maxwellian: Drift velocity must be a 3D vector", - HERE); - raise::ErrorIf(temperature < ZERO, - "Maxwellian: Temperature must be non-negative", - HERE); - if constexpr (M::CoordType == Coord::Cart) { - drift_4vel = NORM(drift_four_vel[0], drift_four_vel[1], drift_four_vel[2]); - if (cmp::AlmostZero_host(drift_4vel)) { - drift_dir = 0; - } else { - drift_3vel = drift_4vel / math::sqrt(ONE + SQR(drift_4vel)); - drift_dir_x1 = drift_four_vel[0] / drift_4vel; - drift_dir_x2 = drift_four_vel[1] / drift_4vel; - drift_dir_x3 = drift_four_vel[2] / drift_4vel; - - // assume drift is in an arbitrary direction - drift_dir = 4; - // check whether drift is in one of principal directions - for (auto d { 0u }; d < 3u; ++d) { - const auto dprev = (d + 2) % 3; - const auto dnext = (d + 1) % 3; - if (cmp::AlmostZero_host(drift_four_vel[dprev]) and - cmp::AlmostZero_host(drift_four_vel[dnext])) { - drift_dir = SIGN(drift_four_vel[d]) * (d + 1); - break; - } + if constexpr (M::CoordType == Coord::Cart) { + drift_4vel = NORM(drift_four_vel[0], drift_four_vel[1], drift_four_vel[2]); + if (cmp::AlmostZero_host(drift_4vel)) { + drift_dir = 0; + } else { + drift_3vel = drift_4vel / math::sqrt(ONE + SQR(drift_4vel)); + drift_dir_x1 = drift_four_vel[0] / drift_4vel; + drift_dir_x2 = drift_four_vel[1] / drift_4vel; + drift_dir_x3 = drift_four_vel[2] / drift_4vel; + + // assume drift is in an arbitrary direction + drift_dir = 4; + // check whether drift is in one of principal directions + for (auto d { 0u }; d < 3u; ++d) { + const auto dprev = (d + 2) % 3; + const auto dnext = (d + 1) % 3; + if (cmp::AlmostZero_host(drift_four_vel[dprev]) and + cmp::AlmostZero_host(drift_four_vel[dnext])) { + drift_dir = SIGN(drift_four_vel[d]) * (d + 1); + break; } } - raise::ErrorIf(drift_dir > 3 and drift_dir != 4, - "Maxwellian: Incorrect drift direction", - HERE); - raise::ErrorIf( - drift_dir != 0 and (M::CoordType != Coord::Cart), - "Maxwellian: Boosting is only supported in Cartesian coordinates", - HERE); } + raise::ErrorIf(drift_dir > 3 and drift_dir != 4, + "Maxwellian: Incorrect drift direction", + HERE); + raise::ErrorIf( + drift_dir != 0 and (M::CoordType != Coord::Cart), + "Maxwellian: Boosting is only supported in Cartesian coordinates", + HERE); } + } - Inline void operator()(const coord_t& x_Code, - vec_t& v, - spidx_t = 0) const { - if (cmp::AlmostZero(temperature)) { - v[0] = ZERO; - v[1] = ZERO; - v[2] = ZERO; - } else { - JuttnerSinge(v, temperature, pool); - } - // @note: boost only when using cartesian coordinates - if constexpr (M::CoordType == Coord::Cart) { - if (drift_dir != 0) { - // Boost an isotropic Maxwellian with a drift velocity using - // flipping method https://arxiv.org/pdf/1504.03910.pdf - // 1. apply drift in X1 direction - const auto gamma { U2GAMMA(v[0], v[1], v[2]) }; - auto rand_gen = pool.get_state(); - if (-drift_3vel * v[0] > gamma * Random(rand_gen)) { - v[0] = -v[0]; - } - pool.free_state(rand_gen); - v[0] = math::sqrt(ONE + SQR(drift_4vel)) * (v[0] + drift_3vel * gamma); - // 2. rotate to desired orientation - if (drift_dir == -1) { - v[0] = -v[0]; - } else if (drift_dir == 2 || drift_dir == -2) { - const auto tmp = v[1]; - v[1] = drift_dir > 0 ? v[0] : -v[0]; - v[0] = tmp; - } else if (drift_dir == 3 || drift_dir == -3) { - const auto tmp = v[2]; - v[2] = drift_dir > 0 ? v[0] : -v[0]; - v[0] = tmp; - } else if (drift_dir == 4) { - vec_t v_old; - v_old[0] = v[0]; - v_old[1] = v[1]; - v_old[2] = v[2]; - - v[0] = v_old[0] * drift_dir_x1 - v_old[1] * drift_dir_x2 - - v_old[2] * drift_dir_x3; - v[1] = (v_old[0] * drift_dir_x2 * (drift_dir_x1 + ONE) + - v_old[1] * - (SQR(drift_dir_x1) + drift_dir_x1 + SQR(drift_dir_x3)) - - v_old[2] * drift_dir_x2 * drift_dir_x3) / - (drift_dir_x1 + ONE); - v[2] = (v_old[0] * drift_dir_x3 * (drift_dir_x1 + ONE) - - v_old[1] * drift_dir_x2 * drift_dir_x3 - - v_old[2] * (-drift_dir_x1 + SQR(drift_dir_x3) - ONE)) / - (drift_dir_x1 + ONE); - } + Inline void operator()(const coord_t& x_Code, vec_t& v) const { + if (cmp::AlmostZero(temperature)) { + v[0] = ZERO; + v[1] = ZERO; + v[2] = ZERO; + } else { + JuttnerSinge(v, temperature, pool); + } + // @note: boost only when using cartesian coordinates + if constexpr (M::CoordType == Coord::Cart) { + if (drift_dir != 0) { + // Boost an isotropic Maxwellian with a drift velocity using + // flipping method https://arxiv.org/pdf/1504.03910.pdf + // 1. apply drift in X1 direction + const auto gamma { U2GAMMA(v[0], v[1], v[2]) }; + auto rand_gen = pool.get_state(); + if (-drift_3vel * v[0] > gamma * Random(rand_gen)) { + v[0] = -v[0]; + } + pool.free_state(rand_gen); + v[0] = math::sqrt(ONE + SQR(drift_4vel)) * (v[0] + drift_3vel * gamma); + // 2. rotate to desired orientation + if (drift_dir == -1) { + v[0] = -v[0]; + } else if (drift_dir == 2 || drift_dir == -2) { + const auto tmp = v[1]; + v[1] = drift_dir > 0 ? v[0] : -v[0]; + v[0] = tmp; + } else if (drift_dir == 3 || drift_dir == -3) { + const auto tmp = v[2]; + v[2] = drift_dir > 0 ? v[0] : -v[0]; + v[0] = tmp; + } else if (drift_dir == 4) { + vec_t v_old; + v_old[0] = v[0]; + v_old[1] = v[1]; + v_old[2] = v[2]; + + v[0] = v_old[0] * drift_dir_x1 - v_old[1] * drift_dir_x2 - + v_old[2] * drift_dir_x3; + v[1] = (v_old[0] * drift_dir_x2 * (drift_dir_x1 + ONE) + + v_old[1] * + (SQR(drift_dir_x1) + drift_dir_x1 + SQR(drift_dir_x3)) - + v_old[2] * drift_dir_x2 * drift_dir_x3) / + (drift_dir_x1 + ONE); + v[2] = (v_old[0] * drift_dir_x3 * (drift_dir_x1 + ONE) - + v_old[1] * drift_dir_x2 * drift_dir_x3 - + v_old[2] * (-drift_dir_x1 + SQR(drift_dir_x3) - ONE)) / + (drift_dir_x1 + ONE); } } } + } - private: - random_number_pool_t pool; - - const real_t temperature; - - real_t drift_3vel { ZERO }, drift_4vel { ZERO }; - // components of the unit vector in the direction of the drift - real_t drift_dir_x1 { ZERO }, drift_dir_x2 { ZERO }, drift_dir_x3 { ZERO }; + private: + random_number_pool_t pool; - // values of boost_dir: - // 4 -> arbitrary direction - // 0 -> no drift - // +/- 1 -> +/- x1 - // +/- 2 -> +/- x2 - // +/- 3 -> +/- x3 - short drift_dir { 0 }; - }; + const real_t temperature; - } // namespace experimental + real_t drift_3vel { ZERO }, drift_4vel { ZERO }; + // components of the unit vector in the direction of the drift + real_t drift_dir_x1 { ZERO }, drift_dir_x2 { ZERO }, drift_dir_x3 { ZERO }; + + // values of boost_dir: + // 4 -> arbitrary direction + // 0 -> no drift + // +/- 1 -> +/- x1 + // +/- 2 -> +/- x2 + // +/- 3 -> +/- x3 + short drift_dir { 0 }; + }; } // namespace arch diff --git a/src/archetypes/particle_injector.h b/src/archetypes/particle_injector.h index 6313031d1..79743ce65 100644 --- a/src/archetypes/particle_injector.h +++ b/src/archetypes/particle_injector.h @@ -2,9 +2,9 @@ * @file archetypes/particle_injector.h * @brief Particle injector routines and classes * @implements - * - arch::UniformInjector<> - * - arch::NonUniformInjector<> - * - arch::AtmosphereInjector<> + * - arch::DeduceRegion<> -> tuple, array_t> + * - arch::ComputeNumInject<> -> tuple, array_t> + * - arch::AtmosphereDensityProfile<> * - arch::InjectUniform<> -> void * - arch::InjectGlobally<> -> void * - arch::InjectNonUniform<> -> void @@ -22,14 +22,10 @@ #include "utils/error.h" #include "utils/numeric.h" -#include "archetypes/energy_dist.h" -#include "archetypes/spatial_dist.h" #include "framework/domain/domain.h" #include "framework/domain/metadomain.h" #include "kernels/injectors.hpp" -#include "kernels/particle_moments.hpp" -#include "kernels/utils.hpp" #include @@ -45,407 +41,173 @@ namespace arch { using namespace ntt; + /** + * @brief Deduces the region of injection in computational coordinates + * @param domain Domain object + * @param box Region to inject the particles in global coords + * @tparam S Simulation engine type + * @tparam M Metric type + * @return Tuple containing: + * - bool: whether the region intersects with the local domain + * - array_t: minimum coordinates of the region in computational coords + * - array_t: maximum coordinates of the region in computational coords + */ template - struct BaseInjector { - virtual auto DeduceRegion(const Domain& domain, - const boundaries_t& box) const - -> std::tuple, array_t> { - if (not domain.mesh.Intersects(box)) { - return { false, array_t {}, array_t {} }; - } - coord_t xCorner_min_Ph { ZERO }; - coord_t xCorner_max_Ph { ZERO }; - coord_t xCorner_min_Cd { ZERO }; - coord_t xCorner_max_Cd { ZERO }; - - for (auto d { 0u }; d < M::Dim; ++d) { - const auto local_xi_min = domain.mesh.extent(static_cast(d)).first; - const auto local_xi_max = domain.mesh.extent(static_cast(d)).second; - const auto extent_min = std::min(std::max(local_xi_min, box[d].first), - local_xi_max); - const auto extent_max = std::max(std::min(local_xi_max, box[d].second), - local_xi_min); - xCorner_min_Ph[d] = extent_min; - xCorner_max_Ph[d] = extent_max; - } - domain.mesh.metric.template convert(xCorner_min_Ph, - xCorner_min_Cd); - domain.mesh.metric.template convert(xCorner_max_Ph, - xCorner_max_Cd); - - array_t xi_min { "xi_min", M::Dim }, xi_max { "xi_max", M::Dim }; - - auto xi_min_h = Kokkos::create_mirror_view(xi_min); - auto xi_max_h = Kokkos::create_mirror_view(xi_max); - for (auto d { 0u }; d < M::Dim; ++d) { - xi_min_h(d) = xCorner_min_Cd[d]; - xi_max_h(d) = xCorner_max_Cd[d]; - } - Kokkos::deep_copy(xi_min, xi_min_h); - Kokkos::deep_copy(xi_max, xi_max_h); - - return { true, xi_min, xi_max }; + auto DeduceRegion(const Domain& domain, const boundaries_t& box) + -> std::tuple, array_t> { + if (not domain.mesh.Intersects(box)) { + return { false, array_t {}, array_t {} }; } - - virtual auto ComputeNumInject(const SimulationParams& params, - const Domain& domain, - real_t number_density, - const boundaries_t& box) const - -> std::tuple, array_t> { - const auto result = DeduceRegion(domain, box); - if (not std::get<0>(result)) { - return { false, (npart_t)0, array_t {}, array_t {} }; - } - const auto xi_min = std::get<1>(result); - const auto xi_max = std::get<2>(result); - auto xi_min_h = Kokkos::create_mirror_view(xi_min); - auto xi_max_h = Kokkos::create_mirror_view(xi_max); - Kokkos::deep_copy(xi_min_h, xi_min); - Kokkos::deep_copy(xi_max_h, xi_max); - - long double num_cells { 1.0 }; - for (auto d { 0u }; d < M::Dim; ++d) { - num_cells *= static_cast(xi_max_h(d)) - - static_cast(xi_min_h(d)); - } - - const auto ppc0 = params.template get("particles.ppc0"); - const auto nparticles = static_cast( - (long double)(ppc0 * number_density * 0.5) * num_cells); - - return { true, nparticles, xi_min, xi_max }; + coord_t xCorner_min_Ph { ZERO }; + coord_t xCorner_max_Ph { ZERO }; + coord_t xCorner_min_Cd { ZERO }; + coord_t xCorner_max_Cd { ZERO }; + + for (auto d { 0u }; d < M::Dim; ++d) { + const auto local_xi_min = domain.mesh.extent(static_cast(d)).first; + const auto local_xi_max = domain.mesh.extent(static_cast(d)).second; + const auto extent_min = std::min(std::max(local_xi_min, box[d].first), + local_xi_max); + const auto extent_max = std::max(std::min(local_xi_max, box[d].second), + local_xi_min); + xCorner_min_Ph[d] = extent_min; + xCorner_max_Ph[d] = extent_max; } - }; - - template class ED> - struct UniformInjector : BaseInjector { - using energy_dist_t = ED; - static_assert(M::is_metric, "M must be a metric class"); - static_assert(energy_dist_t::is_energy_dist, - "E must be an energy distribution class"); - static constexpr bool is_uniform_injector { true }; - static constexpr Dimension D { M::Dim }; - static constexpr Coord C { M::CoordType }; - - const energy_dist_t energy_dist; - const std::pair species; - - UniformInjector(const energy_dist_t& energy_dist, - const std::pair& species) - : energy_dist { energy_dist } - , species { species } {} - - ~UniformInjector() = default; - }; - - template class ED> - struct KeepConstantInjector : UniformInjector { - using energy_dist_t = ED; - using UniformInjector::D; - using UniformInjector::C; - - const idx_t density_buff_idx; - boundaries_t probe_box; - - KeepConstantInjector(const energy_dist_t& energy_dist, - const std::pair& species, - idx_t density_buff_idx, - boundaries_t box = {}) - : UniformInjector { energy_dist, species } - , density_buff_idx { density_buff_idx } { - for (auto d { 0u }; d < M::Dim; ++d) { - if (d < box.size()) { - probe_box.push_back({ box[d].first, box[d].second }); - } else { - probe_box.push_back(Range::All); - } - } + domain.mesh.metric.template convert(xCorner_min_Ph, + xCorner_min_Cd); + domain.mesh.metric.template convert(xCorner_max_Ph, + xCorner_max_Cd); + + array_t xi_min { "xi_min", M::Dim }, xi_max { "xi_max", M::Dim }; + + auto xi_min_h = Kokkos::create_mirror_view(xi_min); + auto xi_max_h = Kokkos::create_mirror_view(xi_max); + for (auto d { 0u }; d < M::Dim; ++d) { + xi_min_h(d) = xCorner_min_Cd[d]; + xi_max_h(d) = xCorner_max_Cd[d]; } + Kokkos::deep_copy(xi_min, xi_min_h); + Kokkos::deep_copy(xi_max, xi_max_h); - ~KeepConstantInjector() = default; - - auto ComputeAvgDensity(const SimulationParams& params, - const Domain& domain) const -> real_t { - const auto result = this->DeduceRegion(domain, probe_box); - const auto should_probe = std::get<0>(result); - if (not should_probe) { - return ZERO; - } - const auto xi_min_arr = std::get<1>(result); - const auto xi_max_arr = std::get<2>(result); - - tuple_t i_min { 0 }; - tuple_t i_max { 0 }; - - auto xi_min_h = Kokkos::create_mirror_view(xi_min_arr); - auto xi_max_h = Kokkos::create_mirror_view(xi_max_arr); - Kokkos::deep_copy(xi_min_h, xi_min_arr); - Kokkos::deep_copy(xi_max_h, xi_max_arr); - - ncells_t num_cells = 1u; - for (auto d { 0u }; d < M::Dim; ++d) { - i_min[d] = std::floor(xi_min_h(d)) + N_GHOSTS; - i_max[d] = std::ceil(xi_max_h(d)) + N_GHOSTS; - num_cells *= (i_max[d] - i_min[d]); - } + return { true, xi_min, xi_max }; + } - real_t dens { ZERO }; - if (should_probe) { - Kokkos::parallel_reduce( - "AvgDensity", - CreateRangePolicy(i_min, i_max), - kernel::ComputeSum_kernel(domain.fields.buff, density_buff_idx), - dens); - } -#if defined(MPI_ENABLED) - real_t tot_dens { ZERO }; - ncells_t tot_num_cells { 0 }; - MPI_Allreduce(&dens, &tot_dens, 1, mpi::get_type(), MPI_SUM, MPI_COMM_WORLD); - MPI_Allreduce(&num_cells, - &tot_num_cells, - 1, - mpi::get_type(), - MPI_SUM, - MPI_COMM_WORLD); - dens = tot_dens; - num_cells = tot_num_cells; -#endif - if (num_cells > 0) { - return dens / (real_t)(num_cells); - } else { - return ZERO; - } + /** + * @brief Computes the number of particles to inject in a given region + * @param params Simulation parameters + * @param domain Domain object + * @param number_density Number density (in units of n0) + * @param box Region to inject the particles in global coords + * @tparam S Simulation engine type + * @tparam M Metric type + * @return Tuple containing: + * - bool: whether the region intersects with the local domain + * - npart_t: number of particles to inject + * - array_t: minimum coordinates of the region in computational coords + * - array_t: maximum coordinates of the region in computational coords + */ + template + auto ComputeNumInject(const SimulationParams& params, + const Domain& domain, + real_t number_density, + const boundaries_t& box) + -> std::tuple, array_t> { + const auto result = DeduceRegion(domain, box); + if (not std::get<0>(result)) { + return { false, (npart_t)0, array_t {}, array_t {} }; } - - auto ComputeNumInject(const SimulationParams& params, - const Domain& domain, - real_t number_density, - const boundaries_t& box) const - -> std::tuple, array_t> override { - const auto computed_avg_density = ComputeAvgDensity(params, domain); - - const auto result = this->DeduceRegion(domain, box); - if (not std::get<0>(result)) { - return { false, (npart_t)0, array_t {}, array_t {} }; - } - - const auto xi_min = std::get<1>(result); - const auto xi_max = std::get<2>(result); - auto xi_min_h = Kokkos::create_mirror_view(xi_min); - auto xi_max_h = Kokkos::create_mirror_view(xi_max); - Kokkos::deep_copy(xi_min_h, xi_min); - Kokkos::deep_copy(xi_max_h, xi_max); - - long double num_cells { 1.0 }; - for (auto d { 0u }; d < M::Dim; ++d) { - num_cells *= static_cast(xi_max_h(d)) - - static_cast(xi_min_h(d)); - } - - const auto ppc0 = params.template get("particles.ppc0"); - npart_t nparticles { 0u }; - if (number_density > computed_avg_density) { - nparticles = static_cast( - (long double)(ppc0 * (number_density - computed_avg_density) * 0.5) * - num_cells); - } - - return { nparticles != 0u, nparticles, xi_min, xi_max }; + const auto xi_min = std::get<1>(result); + const auto xi_max = std::get<2>(result); + auto xi_min_h = Kokkos::create_mirror_view(xi_min); + auto xi_max_h = Kokkos::create_mirror_view(xi_max); + Kokkos::deep_copy(xi_min_h, xi_min); + Kokkos::deep_copy(xi_max_h, xi_max); + + long double num_cells { 1.0 }; + for (auto d { 0u }; d < M::Dim; ++d) { + num_cells *= static_cast(xi_max_h(d)) - + static_cast(xi_min_h(d)); } - }; - - template - class ED, - template - class SD> - struct NonUniformInjector { - using energy_dist_t = ED; - using spatial_dist_t = SD; - static_assert(M::is_metric, "M must be a metric class"); - static_assert(energy_dist_t::is_energy_dist, - "E must be an energy distribution class"); - static_assert(spatial_dist_t::is_spatial_dist, - "SD must be a spatial distribution class"); - static constexpr bool is_nonuniform_injector { true }; - static constexpr Dimension D { M::Dim }; - static constexpr Coord C { M::CoordType }; - - const energy_dist_t energy_dist; - const spatial_dist_t spatial_dist; - const std::pair species; - - NonUniformInjector(const energy_dist_t& energy_dist, - const spatial_dist_t& spatial_dist, - const std::pair& species) - : energy_dist { energy_dist } - , spatial_dist { spatial_dist } - , species { species } {} - - ~NonUniformInjector() = default; - }; - - template - struct AtmosphereInjector { - struct TargetDensityProfile { - const real_t nmax, height, xsurf, ds; - - TargetDensityProfile(real_t nmax, real_t height, real_t xsurf, real_t ds) - : nmax { nmax } - , height { height } - , xsurf { xsurf } - , ds { ds } {} - - Inline auto operator()(const coord_t& x_Ph) const -> real_t { - if constexpr ((O == in::x1) or - (O == in::x2 and (M::Dim == Dim::_2D or M::Dim == Dim::_3D)) or - (O == in::x3 and M::Dim == Dim::_3D)) { - const auto xi = x_Ph[static_cast(O)]; - if constexpr (P) { - // + direction - if (xi < xsurf - ds or xi >= xsurf) { - return ZERO; - } else { - if constexpr (M::CoordType == Coord::Cart) { - return nmax * math::exp(-(xsurf - xi) / height); - } else { - raise::KernelError( - HERE, - "Atmosphere in +x cannot be applied for non-cartesian"); - return ZERO; - } - } - } else { - // - direction - if (xi < xsurf or xi >= xsurf + ds) { - return ZERO; - } else { - if constexpr (M::CoordType == Coord::Cart) { - return nmax * math::exp(-(xi - xsurf) / height); - } else { - return nmax * math::exp(-(xsurf / height) * (ONE - (xsurf / xi))); - } - } - } - } else { - raise::KernelError(HERE, "Wrong direction"); - return ZERO; - } - } - }; - - using energy_dist_t = Maxwellian; - using spatial_dist_t = Replenish; - static_assert(M::is_metric, "M must be a metric class"); - static constexpr bool is_nonuniform_injector { true }; - static constexpr Dimension D { M::Dim }; - static constexpr Coord C { M::CoordType }; - - const energy_dist_t energy_dist; - const TargetDensityProfile target_density; - const spatial_dist_t spatial_dist; - const std::pair species; - - AtmosphereInjector(const M& metric, - const ndfield_t& density, - real_t nmax, - real_t height, - real_t xsurf, - real_t ds, - real_t T, - random_number_pool_t& pool, - const std::pair& species) - : energy_dist { metric, pool, T } - , target_density { nmax, height, xsurf, ds } - , spatial_dist { metric, density, 0, target_density, nmax } - , species { species } {} - - ~AtmosphereInjector() = default; - }; - template - struct MovingInjector { - struct TargetDensityProfile { - const real_t nmax, xinj, xdrift; + const auto ppc0 = params.template get("particles.ppc0"); + const auto nparticles = static_cast( + (long double)(ppc0 * number_density * 0.5) * num_cells); - TargetDensityProfile(real_t xinj, real_t xdrift, real_t nmax) - : xinj { xinj } - , xdrift { xdrift } - , nmax { nmax } {} + return { true, nparticles, xi_min, xi_max }; + } - Inline auto operator()(const coord_t& x_Ph) const -> real_t { - if constexpr ((O == in::x1) or - (O == in::x2 and (M::Dim == Dim::_2D or M::Dim == Dim::_3D)) or - (O == in::x3 and M::Dim == Dim::_3D)) { - const auto xi = x_Ph[static_cast(O)]; + template + struct AtmosphereDensityProfile { + const real_t nmax, height, xsurf, ds; + + AtmosphereDensityProfile(real_t nmax, real_t height, real_t xsurf, real_t ds) + : nmax { nmax } + , height { height } + , xsurf { xsurf } + , ds { ds } {} + + Inline auto operator()(const coord_t& x_Ph) const -> real_t { + if constexpr ((O == in::x1) or + (O == in::x2 and (D == Dim::_2D or D == Dim::_3D)) or + (O == in::x3 and D == Dim::_3D)) { + const auto xi = x_Ph[static_cast(O)]; + if constexpr (P) { // + direction - if (xi < xdrift or xi >= xinj) { + if (xi < xsurf - ds or xi >= xsurf) { return ZERO; } else { - if constexpr (M::CoordType == Coord::Cart) { - return nmax; + if constexpr (C == Coord::Cart) { + return nmax * math::exp(-(xsurf - xi) / height); } else { raise::KernelError( HERE, - "Moving injector in +x cannot be applied for non-cartesian"); + "Atmosphere in +x cannot be applied for non-cartesian"); return ZERO; } } } else { - raise::KernelError(HERE, "Wrong direction"); - return ZERO; + // - direction + if (xi < xsurf or xi >= xsurf + ds) { + return ZERO; + } else { + if constexpr (C == Coord::Cart) { + return nmax * math::exp(-(xi - xsurf) / height); + } else { + return nmax * math::exp(-(xsurf / height) * (ONE - (xsurf / xi))); + } + } } + } else { + raise::KernelError(HERE, "Wrong direction"); + return ZERO; } - }; - - using energy_dist_t = Maxwellian; - using spatial_dist_t = Replenish; - static_assert(M::is_metric, "M must be a metric class"); - static constexpr bool is_nonuniform_injector { true }; - static constexpr Dimension D { M::Dim }; - static constexpr Coord C { M::CoordType }; - - const energy_dist_t energy_dist; - const TargetDensityProfile target_density; - const spatial_dist_t spatial_dist; - const std::pair species; - - MovingInjector(const M& metric, - const ndfield_t& density, - const energy_dist_t& energy_dist, - real_t xinj, - real_t xdrift, - real_t nmax, - const std::pair& species) - : energy_dist { energy_dist } - , target_density { xinj, xdrift, nmax } - , spatial_dist { metric, density, 0, target_density, nmax } - , species { species } {} - - ~MovingInjector() = default; + } }; /** * @brief Injects uniform number density of particles everywhere in the domain * @param domain Domain object - * @param injector Uniform injector object + * @param species Pair of species indices + * @param energy_dists Pair of energy distribution objects * @param number_density Total number density (in units of n0) * @param use_weights Use weights * @param box Region to inject the particles in global coords * @tparam S Simulation engine type * @tparam M Metric type - * @tparam I Injector type + * @tparam ED1 Energy distribution type for species 1 + * @tparam ED2 Energy distribution type for species 2 */ - template - inline void InjectUniform(const SimulationParams& params, - Domain& domain, - const I& injector, - real_t number_density, + template + inline void InjectUniform(const SimulationParams& params, + Domain& domain, + const std::pair& species, + const std::pair& energy_dists, + real_t number_density, bool use_weights = false, const boundaries_t& box = {}) { static_assert(M::is_metric, "M must be a metric class"); - static_assert(I::is_uniform_injector, "I must be a uniform injector class"); + static_assert(ED1::is_energy_dist, "ED1 must be an energy distribution class"); + static_assert(ED2::is_energy_dist, "ED2 must be an energy distribution class"); raise::ErrorIf((M::CoordType != Coord::Cart) && (not use_weights), "Weights must be used for non-Cartesian coordinates", HERE); @@ -456,8 +218,8 @@ namespace arch { "Weights must be enabled from the input file to use them in " "the injector", HERE); - if (domain.species[injector.species.first - 1].charge() + - domain.species[injector.species.second - 1].charge() != + if (domain.species[species.first - 1].charge() + + domain.species[species.second - 1].charge() != 0.0f) { raise::Warning("Total charge of the injected species is non-zero", HERE); } @@ -471,10 +233,7 @@ namespace arch { nonempty_box.push_back(Range::All); } } - const auto result = injector.ComputeNumInject(params, - domain, - number_density, - nonempty_box); + const auto result = ComputeNumInject(params, domain, number_density, nonempty_box); if (not std::get<0>(result)) { return; } @@ -482,147 +241,27 @@ namespace arch { const auto xi_min = std::get<2>(result); const auto xi_max = std::get<3>(result); - Kokkos::parallel_for( - "InjectUniform", - nparticles, - kernel::UniformInjector_kernel( - injector.species.first, - injector.species.second, - domain.species[injector.species.first - 1], - domain.species[injector.species.second - 1], - domain.species[injector.species.first - 1].npart(), - domain.species[injector.species.second - 1].npart(), - domain.mesh.metric, - xi_min, - xi_max, - injector.energy_dist, - ONE / params.template get("scales.V0"), - domain.random_pool)); - domain.species[injector.species.first - 1].set_npart( - domain.species[injector.species.first - 1].npart() + nparticles); - domain.species[injector.species.second - 1].set_npart( - domain.species[injector.species.second - 1].npart() + nparticles); + Kokkos::parallel_for("InjectUniform", + nparticles, + kernel::UniformInjector_kernel( + domain.species[species.first - 1], + domain.species[species.second - 1], + nparticles, + domain.index(), + domain.mesh.metric, + xi_min, + xi_max, + energy_dists.first, + energy_dists.second, + ONE / params.template get("scales.V0"), + domain.random_pool)); + domain.species[species.first - 1].set_npart( + domain.species[species.first - 1].npart() + nparticles); + domain.species[species.second - 1].set_npart( + domain.species[species.second - 1].npart() + nparticles); } } - namespace experimental { - - template - class ED1, - template - class ED2> - struct UniformInjector : BaseInjector { - using energy_dist_1_t = ED1; - using energy_dist_2_t = ED2; - static_assert(M::is_metric, "M must be a metric class"); - static_assert(energy_dist_1_t::is_energy_dist, - "ED1 must be an energy distribution class"); - static_assert(energy_dist_2_t::is_energy_dist, - "ED2 must be an energy distribution class"); - static constexpr bool is_uniform_injector { true }; - static constexpr Dimension D { M::Dim }; - static constexpr Coord C { M::CoordType }; - - const energy_dist_1_t energy_dist_1; - const energy_dist_2_t energy_dist_2; - const std::pair species; - - UniformInjector(const energy_dist_1_t& energy_dist_1, - const energy_dist_2_t& energy_dist_2, - const std::pair& species) - : energy_dist_1 { energy_dist_1 } - , energy_dist_2 { energy_dist_2 } - , species { species } {} - - ~UniformInjector() = default; - }; - - /** - * @brief Injects uniform number density of particles everywhere in the domain - * @param domain Domain object - * @param injector Uniform injector object - * @param number_density Total number density (in units of n0) - * @param use_weights Use weights - * @param box Region to inject the particles in global coords - * @tparam S Simulation engine type - * @tparam M Metric type - * @tparam I Injector type - */ - template - inline void InjectUniform(const SimulationParams& params, - Domain& domain, - const I& injector, - real_t number_density, - bool use_weights = false, - const boundaries_t& box = {}) { - static_assert(M::is_metric, "M must be a metric class"); - static_assert(I::is_uniform_injector, "I must be a uniform injector class"); - raise::ErrorIf((M::CoordType != Coord::Cart) && (not use_weights), - "Weights must be used for non-Cartesian coordinates", - HERE); - raise::ErrorIf((M::CoordType == Coord::Cart) && use_weights, - "Weights should not be used for Cartesian coordinates", - HERE); - raise::ErrorIf( - params.template get("particles.use_weights") != use_weights, - "Weights must be enabled from the input file to use them in " - "the injector", - HERE); - if (domain.species[injector.species.first - 1].charge() + - domain.species[injector.species.second - 1].charge() != - 0.0f) { - raise::Warning("Total charge of the injected species is non-zero", HERE); - } - - { - boundaries_t nonempty_box; - for (auto d { 0u }; d < M::Dim; ++d) { - if (d < box.size()) { - nonempty_box.push_back({ box[d].first, box[d].second }); - } else { - nonempty_box.push_back(Range::All); - } - } - const auto result = injector.ComputeNumInject(params, - domain, - number_density, - nonempty_box); - if (not std::get<0>(result)) { - return; - } - const auto nparticles = std::get<1>(result); - const auto xi_min = std::get<2>(result); - const auto xi_max = std::get<3>(result); - - Kokkos::parallel_for( - "InjectUniform", - nparticles, - kernel::experimental:: - UniformInjector_kernel( - injector.species.first, - injector.species.second, - domain.species[injector.species.first - 1], - domain.species[injector.species.second - 1], - domain.species[injector.species.first - 1].npart(), - domain.species[injector.species.second - 1].npart(), - domain.mesh.metric, - xi_min, - xi_max, - injector.energy_dist_1, - injector.energy_dist_2, - ONE / params.template get("scales.V0"), - domain.random_pool)); - domain.species[injector.species.first - 1].set_npart( - domain.species[injector.species.first - 1].npart() + nparticles); - domain.species[injector.species.second - 1].set_npart( - domain.species[injector.species.second - 1].npart() + nparticles); - } - } - - } // namespace experimental - /** * @brief Injects particles from a globally-defined map * @note very inefficient, should only be used for debug purposes @@ -657,21 +296,31 @@ namespace arch { * @brief Injects particles based on spatial distribution function * @param params Simulation parameters * @param domain Local domain object - * @param injector Non-uniform injector object + * @param species Pair of species indices + * @param energy_dists Pair of energy distribution objects + * @param spatial_dist Spatial distribution object * @param number_density Total number density (in units of n0) * @param use_weights Use weights * @param box Region to inject the particles in + * @tparam S Simulation engine type + * @tparam M Metric type + * @tparam ED1 Energy distribution type for species 1 + * @tparam ED2 Energy distribution type for species 2 + * @tparam SD Spatial distribution type */ - template - inline void InjectNonUniform(const SimulationParams& params, - Domain& domain, - const I& injector, + template + inline void InjectNonUniform(const SimulationParams& params, + Domain& domain, + const std::pair& species, + const std::pair& energy_dists, + const SD& spatial_dist, real_t number_density, bool use_weights = false, const boundaries_t& box = {}) { static_assert(M::is_metric, "M must be a metric class"); - static_assert(I::is_nonuniform_injector, - "I must be a nonuniform injector class"); + static_assert(ED1::is_energy_dist, "ED1 must be an energy distribution class"); + static_assert(ED2::is_energy_dist, "ED2 must be an energy distribution class"); + static_assert(SD::is_spatial_dist, "SD must be a spatial distribution class"); raise::ErrorIf((M::CoordType != Coord::Cart) && (not use_weights), "Weights must be used for non-Cartesian coordinates", HERE); @@ -686,8 +335,8 @@ namespace arch { not params.template get("particles.use_weights") and use_weights, "Weights are not enabled in the input but enabled in the injector", HERE); - if (domain.species[injector.species.first - 1].charge() + - domain.species[injector.species.second - 1].charge() != + if (domain.species[species.first - 1].charge() + + domain.species[species.second - 1].charge() != 0.0f) { raise::Warning("Total charge of the injected species is non-zero", HERE); } @@ -713,28 +362,25 @@ namespace arch { } const auto ppc = number_density * params.template get("particles.ppc0") * HALF; - auto injector_kernel = - kernel::NonUniformInjector_kernel( - ppc, - injector.species.first, - injector.species.second, - domain.species[injector.species.first - 1], - domain.species[injector.species.second - 1], - domain.species[injector.species.first - 1].npart(), - domain.species[injector.species.second - 1].npart(), - domain.mesh.metric, - injector.energy_dist, - injector.spatial_dist, - ONE / params.template get("scales.V0"), - domain.random_pool); + auto injector_kernel = kernel::NonUniformInjector_kernel( + ppc, + domain.species[species.first - 1], + domain.species[species.second - 1], + domain.index(), + domain.mesh.metric, + energy_dists.first, + energy_dists.second, + spatial_dist, + ONE / params.template get("scales.V0"), + domain.random_pool); Kokkos::parallel_for("InjectNonUniformNumberDensity", cell_range, injector_kernel); const auto n_inj = injector_kernel.number_injected(); - domain.species[injector.species.first - 1].set_npart( - domain.species[injector.species.first - 1].npart() + n_inj); - domain.species[injector.species.second - 1].set_npart( - domain.species[injector.species.second - 1].npart() + n_inj); + for (auto sp : { species.first, species.second }) { + domain.species[sp - 1].set_npart(domain.species[sp - 1].npart() + n_inj); + domain.species[sp - 1].set_counter(domain.species[sp - 1].counter() + n_inj); + } } } diff --git a/src/archetypes/spatial_dist.h b/src/archetypes/spatial_dist.h index 55c84ddf2..68477208c 100644 --- a/src/archetypes/spatial_dist.h +++ b/src/archetypes/spatial_dist.h @@ -5,6 +5,7 @@ * - arch::SpatialDistribution<> * - arch::Uniform<> : arch::SpatialDistribution<> * - arch::Replenish<> : arch::SpatialDistribution<> + * - arch::ReplenishUniform<> : arch::SpatialDistribution<> * @namespace * - arch:: * @note @@ -45,17 +46,17 @@ namespace arch { } }; - template + template struct Replenish : public SpatialDistribution { using SpatialDistribution::metric; - const ndfield_t density; + const ndfield_t density; const idx_t idx; const T target_density; const real_t target_max_density; Replenish(const M& metric, - const ndfield_t& density, + const ndfield_t& density, idx_t idx, const T& target_density, real_t target_max_density) @@ -92,6 +93,49 @@ namespace arch { } }; + template + struct ReplenishUniform : public SpatialDistribution { + using SpatialDistribution::metric; + const ndfield_t density; + const idx_t idx; + + const real_t target_density; + + ReplenishUniform(const M& metric, + const ndfield_t& density, + idx_t idx, + real_t target_density) + : SpatialDistribution { metric } + , density { density } + , idx { idx } + , target_density { target_density } {} + + Inline auto operator()(const coord_t& x_Ph) const -> real_t { + coord_t x_Cd { ZERO }; + metric.template convert(x_Ph, x_Cd); + real_t dens { ZERO }; + if constexpr (M::Dim == Dim::_1D) { + dens = density(static_cast(x_Cd[0]) + N_GHOSTS, idx); + } else if constexpr (M::Dim == Dim::_2D) { + dens = density(static_cast(x_Cd[0]) + N_GHOSTS, + static_cast(x_Cd[1]) + N_GHOSTS, + idx); + } else if constexpr (M::Dim == Dim::_3D) { + dens = density(static_cast(x_Cd[0]) + N_GHOSTS, + static_cast(x_Cd[1]) + N_GHOSTS, + static_cast(x_Cd[2]) + N_GHOSTS, + idx); + } else { + raise::KernelError(HERE, "Invalid dimension"); + } + if (0.9 * target_density > dens) { + return (target_density - dens) / target_density; + } else { + return ZERO; + } + } + }; + } // namespace arch #endif // ARCHETYPES_SPATIAL_DIST_HPP diff --git a/src/archetypes/utils.h b/src/archetypes/utils.h index d3d6ae475..3447558fb 100644 --- a/src/archetypes/utils.h +++ b/src/archetypes/utils.h @@ -17,6 +17,7 @@ #include "archetypes/energy_dist.h" #include "archetypes/particle_injector.h" #include "framework/domain/domain.h" +#include "framework/parameters.h" #include @@ -51,29 +52,23 @@ namespace arch { const auto temperature_1 = temperatures.first / mass_1; const auto temperature_2 = temperatures.second / mass_2; - const auto maxwellian_1 = arch::experimental::Maxwellian( - domain.mesh.metric, - domain.random_pool, - temperature_1, - drift_four_vels.first); - const auto maxwellian_2 = arch::experimental::Maxwellian( - domain.mesh.metric, - domain.random_pool, - temperature_2, - drift_four_vels.second); + const auto maxwellian_1 = arch::Maxwellian(domain.mesh.metric, + domain.random_pool, + temperature_1, + drift_four_vels.first); + const auto maxwellian_2 = arch::Maxwellian(domain.mesh.metric, + domain.random_pool, + temperature_2, + drift_four_vels.second); - const auto injector = arch::experimental:: - UniformInjector( - maxwellian_1, - maxwellian_2, - species); - - arch::experimental::InjectUniform(params, - domain, - injector, - tot_number_density, - use_weights, - box); + arch::InjectUniform( + params, + domain, + species, + { maxwellian_1, maxwellian_2 }, + tot_number_density, + use_weights, + box); } /** diff --git a/src/checkpoint/CMakeLists.txt b/src/checkpoint/CMakeLists.txt deleted file mode 100644 index 096aad690..000000000 --- a/src/checkpoint/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -# cmake-lint: disable=C0103 -# ------------------------------ -# @defines: ntt_checkpoint [STATIC/SHARED] -# -# @sources: -# -# * writer.cpp -# * reader.cpp -# -# @includes: -# -# * ../ -# -# @depends: -# -# * ntt_global [required] -# -# @uses: -# -# * kokkos [required] -# * ADIOS2 [required] -# * mpi [optional] -# ------------------------------ - -set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -set(SOURCES ${SRC_DIR}/writer.cpp ${SRC_DIR}/reader.cpp) -add_library(ntt_checkpoint ${SOURCES}) - -set(libs ntt_global) -add_dependencies(ntt_checkpoint ${libs}) -target_link_libraries(ntt_checkpoint PUBLIC ${libs}) -target_link_libraries(ntt_checkpoint PRIVATE stdc++fs) - -target_include_directories( - ntt_checkpoint - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../ - INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/../) diff --git a/src/checkpoint/reader.cpp b/src/checkpoint/reader.cpp deleted file mode 100644 index d973b0ddd..000000000 --- a/src/checkpoint/reader.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include "checkpoint/reader.h" - -#include "global.h" - -#include "arch/kokkos_aliases.h" -#include "utils/error.h" -#include "utils/formatting.h" -#include "utils/log.h" - -#include -#include - -#if defined(MPI_ENABLED) - #include -#endif - -#include -#include -#include - -namespace checkpoint { - - template - void ReadFields(adios2::IO& io, - adios2::Engine& reader, - const std::string& field, - const adios2::Box& range, - ndfield_t& array) { - logger::Checkpoint(fmt::format("Reading field: %s", field.c_str()), HERE); - auto field_var = io.InquireVariable(field); - if (field_var) { - field_var.SetSelection(range); - - auto array_h = Kokkos::create_mirror_view(array); - reader.Get(field_var, array_h.data(), adios2::Mode::Sync); - Kokkos::deep_copy(array, array_h); - } else { - raise::Error(fmt::format("Field variable: %s not found", field.c_str()), - HERE); - } - } - - auto ReadParticleCount(adios2::IO& io, - adios2::Engine& reader, - spidx_t s, - std::size_t local_dom, - std::size_t ndomains) -> std::pair { - logger::Checkpoint(fmt::format("Reading particle count for: %d", s + 1), HERE); - auto npart_var = io.InquireVariable(fmt::format("s%d_npart", s + 1)); - if (npart_var) { - raise::ErrorIf(npart_var.Shape()[0] != ndomains, - "npart_var.Shape()[0] != ndomains", - HERE); - raise::ErrorIf(npart_var.Shape().size() != 1, - "npart_var.Shape().size() != 1", - HERE); - npart_var.SetSelection(adios2::Box({ local_dom }, { 1 })); - npart_t npart; - reader.Get(npart_var, &npart, adios2::Mode::Sync); - const auto loc_npart = npart; -#if !defined(MPI_ENABLED) - npart_t offset_npart = 0; -#else - std::vector glob_nparts(ndomains); - MPI_Allgather(&loc_npart, - 1, - mpi::get_type(), - glob_nparts.data(), - 1, - mpi::get_type(), - MPI_COMM_WORLD); - npart_t offset_npart = 0; - for (auto d { 0u }; d < local_dom; ++d) { - offset_npart += glob_nparts[d]; - } -#endif - return { loc_npart, offset_npart }; - } else { - raise::Error("npart_var is not found", HERE); - return { 0, 0 }; - } - } - - template - void ReadParticleData(adios2::IO& io, - adios2::Engine& reader, - const std::string& quantity, - spidx_t s, - array_t& array, - npart_t count, - npart_t offset) { - logger::Checkpoint( - fmt::format("Reading quantity: s%d_%s", s + 1, quantity.c_str()), - HERE); - auto var = io.InquireVariable( - fmt::format("s%d_%s", s + 1, quantity.c_str())); - if (var) { - var.SetSelection(adios2::Box({ offset }, { count })); - const auto slice = range_tuple_t(0, count); - auto array_h = Kokkos::create_mirror_view(array); - reader.Get(var, Kokkos::subview(array_h, slice).data(), adios2::Mode::Sync); - Kokkos::deep_copy(Kokkos::subview(array, slice), - Kokkos::subview(array_h, slice)); - } else { - raise::Error( - fmt::format("Variable: s%d_%s not found", s + 1, quantity.c_str()), - HERE); - } - } - - void ReadParticlePayloads(adios2::IO& io, - adios2::Engine& reader, - spidx_t s, - array_t& array, - std::size_t nplds, - npart_t count, - npart_t offset) { - logger::Checkpoint(fmt::format("Reading quantity: s%d_plds", s + 1), HERE); - auto var = io.InquireVariable(fmt::format("s%d_plds", s + 1)); - if (var) { - var.SetSelection(adios2::Box({ offset, 0 }, { count, nplds })); - const auto slice = range_tuple_t(0, count); - auto array_h = Kokkos::create_mirror_view(array); - reader.Get(var, - Kokkos::subview(array_h, slice, range_tuple_t(0, nplds)).data(), - adios2::Mode::Sync); - Kokkos::deep_copy(array, array_h); - } else { - raise::Error(fmt::format("Variable: s%d_plds not found", s + 1), HERE); - } - } - -#define CHECKPOINT_FIELDS(D, N) \ - template void ReadFields(adios2::IO&, \ - adios2::Engine&, \ - const std::string&, \ - const adios2::Box&, \ - ndfield_t&); - CHECKPOINT_FIELDS(Dim::_1D, 3) - CHECKPOINT_FIELDS(Dim::_2D, 3) - CHECKPOINT_FIELDS(Dim::_3D, 3) - CHECKPOINT_FIELDS(Dim::_1D, 6) - CHECKPOINT_FIELDS(Dim::_2D, 6) - CHECKPOINT_FIELDS(Dim::_3D, 6) -#undef CHECKPOINT_FIELDS - -#define CHECKPOINT_PARTICLE_DATA(T) \ - template void ReadParticleData(adios2::IO&, \ - adios2::Engine&, \ - const std::string&, \ - spidx_t, \ - array_t&, \ - npart_t, \ - npart_t); - CHECKPOINT_PARTICLE_DATA(int) - CHECKPOINT_PARTICLE_DATA(float) - CHECKPOINT_PARTICLE_DATA(double) - CHECKPOINT_PARTICLE_DATA(short) -#undef CHECKPOINT_PARTICLE_DATA - -} // namespace checkpoint diff --git a/src/checkpoint/reader.h b/src/checkpoint/reader.h deleted file mode 100644 index 7939ba82b..000000000 --- a/src/checkpoint/reader.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file checkpoint/reader.h - * @brief Function for reading field & particle data from checkpoint files - * @implements - * - checkpoint::ReadFields -> void - * - checkpoint::ReadParticleData -> void - * - checkpoint::ReadParticleCount -> std::pair - * @cpp: - * - reader.cpp - * @namespaces: - * - checkpoint:: - */ - -#ifndef CHECKPOINT_READER_H -#define CHECKPOINT_READER_H - -#include "arch/kokkos_aliases.h" - -#include - -#include -#include - -namespace checkpoint { - - template - void ReadFields(adios2::IO&, - adios2::Engine&, - const std::string&, - const adios2::Box&, - ndfield_t&); - - auto ReadParticleCount(adios2::IO&, - adios2::Engine&, - spidx_t, - std::size_t, - std::size_t) -> std::pair; - - template - void ReadParticleData(adios2::IO&, - adios2::Engine&, - const std::string&, - spidx_t, - array_t&, - npart_t, - npart_t); - - void ReadParticlePayloads(adios2::IO&, - adios2::Engine&, - spidx_t, - array_t&, - std::size_t, - npart_t, - npart_t); - -} // namespace checkpoint - -#endif // CHECKPOINT_READER_H diff --git a/src/checkpoint/tests/CMakeLists.txt b/src/checkpoint/tests/CMakeLists.txt deleted file mode 100644 index cbfd63aa9..000000000 --- a/src/checkpoint/tests/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -# cmake-lint: disable=C0103,C0111 -# ------------------------------ -# @brief: Generates tests for the `ntt_checkpoint` module -# -# @uses: -# -# * kokkos [required] -# * adios2 [required] -# * mpi [optional] -# ------------------------------ - -set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../) - -function(gen_test title) - set(exec test-output-${title}.xc) - set(src ${title}.cpp) - add_executable(${exec} ${src}) - - set(libs ntt_checkpoint ntt_global) - add_dependencies(${exec} ${libs}) - target_link_libraries(${exec} PRIVATE ${libs} stdc++fs) - - add_test(NAME "CHECKPOINT::${title}" COMMAND "${exec}") -endfunction() - -if(NOT ${mpi}) - gen_test(checkpoint-nompi) -else() - gen_test(checkpoint-mpi) -endif() diff --git a/src/checkpoint/tests/checkpoint-mpi.cpp b/src/checkpoint/tests/checkpoint-mpi.cpp deleted file mode 100644 index 2372d81bc..000000000 --- a/src/checkpoint/tests/checkpoint-mpi.cpp +++ /dev/null @@ -1,273 +0,0 @@ -#include "enums.h" -#include "global.h" - -#include "utils/comparators.h" - -#include "checkpoint/reader.h" -#include "checkpoint/writer.h" - -#include -#include -#include -#include - -#include -#include -#include - -using namespace ntt; -using namespace checkpoint; - -void cleanup() { - namespace fs = std::filesystem; - fs::path temp_path { "chck" }; - fs::remove_all(temp_path); -} - -auto main(int argc, char* argv[]) -> int { - Kokkos::initialize(argc, argv); - MPI_Init(&argc, &argv); - int rank, size; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); - - try { - // assuming 4 ranks - // |------|------| - // | 2 | 3 | - // |------|------| - // | | | - // | 0 | 1 | - // |------|------| - const std::size_t g_nx1 = 20; - const std::size_t g_nx2 = 15; - const std::size_t g_nx1_gh = g_nx1 + 4 * N_GHOSTS; - const std::size_t g_nx2_gh = g_nx2 + 4 * N_GHOSTS; - - const std::size_t l_nx1 = 10; - const std::size_t l_nx2 = (rank < 2) ? 10 : 5; - - const std::size_t l_nx1_gh = l_nx1 + 2 * N_GHOSTS; - const std::size_t l_nx2_gh = l_nx2 + 2 * N_GHOSTS; - - const std::size_t l_corner_x1 = (rank % 2 == 0) ? 0 : l_nx1_gh; - const std::size_t l_corner_x2 = (rank < 2) ? 0 : l_nx2_gh; - - const std::size_t i1min = N_GHOSTS; - const std::size_t i2min = N_GHOSTS; - const std::size_t i1max = l_nx1 + N_GHOSTS; - const std::size_t i2max = l_nx2 + N_GHOSTS; - - const std::size_t npart1 = (rank % 2 + rank) * 23 + 100; - const std::size_t npart2 = (rank % 2 + rank) * 37 + 100; - - std::size_t npart1_offset = 0; - std::size_t npart2_offset = 0; - - std::size_t npart1_globtot = 0; - std::size_t npart2_globtot = 0; - - for (auto r = 0; r < rank - 1; ++r) { - npart1_offset += (r % 2 + r) * 23 + 100; - npart2_offset += (r % 2 + r) * 37 + 100; - } - - for (auto r = 0; r < size; ++r) { - npart1_globtot += (r % 2 + r) * 23 + 100; - npart2_globtot += (r % 2 + r) * 37 + 100; - } - - // init data - ndfield_t field1 { "fld1", l_nx1_gh, l_nx2_gh }; - ndfield_t field2 { "fld2", l_nx1_gh, l_nx2_gh }; - - array_t i1 { "i_1", npart1 }; - array_t u1 { "u_1", npart1 }; - array_t i2 { "i_2", npart2 }; - array_t u2 { "u_2", npart2 }; - array_t plds1 { "plds_1", npart1, 3 }; - - { - // fill data - Kokkos::parallel_for( - "fillFlds", - CreateRangePolicy({ i1min, i2min }, { i1max, i2max }), - Lambda(index_t i1, index_t i2) { - field1(i1, i2, 0) = static_cast(i1 + i2); - field1(i1, i2, 1) = static_cast(i1 * i2); - field1(i1, i2, 2) = static_cast(i1 / i2); - field1(i1, i2, 3) = static_cast(i1 - i2); - field1(i1, i2, 4) = static_cast(i2 / i1); - field1(i1, i2, 5) = static_cast(i1); - field2(i1, i2, 0) = static_cast(-(i1 + i2)); - field2(i1, i2, 1) = static_cast(-(i1 * i2)); - field2(i1, i2, 2) = static_cast(-(i1 / i2)); - field2(i1, i2, 3) = static_cast(-(i1 - i2)); - field2(i1, i2, 4) = static_cast(-(i2 / i1)); - field2(i1, i2, 5) = static_cast(-i1); - }); - Kokkos::parallel_for( - "fillPrtl1", - npart1, - Lambda(index_t p) { - u1(p) = static_cast(p); - i1(p) = static_cast(p); - plds1(p, 0) = static_cast(p); - plds1(p, 1) = static_cast(p * p); - plds1(p, 2) = static_cast(p * p * p); - }); - Kokkos::parallel_for( - "fillPrtl2", - npart2, - Lambda(index_t p) { - u2(p) = -static_cast(p); - i2(p) = -static_cast(p); - }); - } - - adios2::ADIOS adios; - const path_t checkpoint_path { "chck" }; - - { - // write checkpoint - Writer writer; - writer.init(&adios, checkpoint_path, 0, 0.0, 1); - - writer.defineFieldVariables(SimEngine::GRPIC, - { g_nx1_gh, g_nx2_gh }, - { l_corner_x1, l_corner_x2 }, - { l_nx1_gh, l_nx2_gh }); - - writer.defineParticleVariables(Coord::Sph, Dim::_2D, 2, { 3, 0 }); - - writer.beginSaving(0, 0.0); - - writer.saveField("em", field1); - writer.saveField("em0", field2); - - writer.savePerDomainVariable("s1_npart", 1, 0, npart1); - writer.savePerDomainVariable("s2_npart", 1, 0, npart2); - - writer.saveParticleQuantity("s1_i1", - npart1_globtot, - npart1_offset, - npart1, - i1); - writer.saveParticleQuantity("s1_ux1", - npart1_globtot, - npart1_offset, - npart1, - u1); - writer.saveParticleQuantity("s2_i1", - npart2_globtot, - npart2_offset, - npart2, - i2); - writer.saveParticleQuantity("s2_ux1", - npart2_globtot, - npart2_offset, - npart2, - u2); - - writer.saveParticlePayloads("s1_plds", - 3, - npart1_globtot, - npart1_offset, - npart1, - plds1); - - writer.endSaving(); - } - - { - // read checkpoint - ndfield_t field1_read { "fld1_read", l_nx1_gh, l_nx2_gh }; - ndfield_t field2_read { "fld2_read", l_nx1_gh, l_nx2_gh }; - - array_t i1_read { "i_1", npart1 }; - array_t u1_read { "u_1", npart1 }; - array_t i2_read { "i_2", npart2 }; - array_t u2_read { "u_2", npart2 }; - array_t plds1_read { "plds_1", npart1, 3 }; - - adios2::IO io = adios.DeclareIO("checkpointRead"); - adios2::Engine reader = io.Open(checkpoint_path / "step-00000000.bp", - adios2::Mode::Read); - reader.BeginStep(); - - auto fieldRange = adios2::Box({ l_corner_x1, l_corner_x2, 0 }, - { l_nx1_gh, l_nx2_gh, 6 }); - ReadFields(io, reader, "em", fieldRange, field1_read); - ReadFields(io, reader, "em0", fieldRange, field2_read); - - auto [nprtl1, noff1] = ReadParticleCount(io, reader, 0, rank, size); - auto [nprtl2, noff2] = ReadParticleCount(io, reader, 1, rank, size); - - ReadParticleData(io, reader, "ux1", 0, u1_read, nprtl1, noff1); - ReadParticleData(io, reader, "ux1", 1, u2_read, nprtl2, noff2); - ReadParticleData(io, reader, "i1", 0, i1_read, nprtl1, noff1); - ReadParticleData(io, reader, "i1", 1, i2_read, nprtl2, noff2); - ReadParticlePayloads(io, reader, 0, plds1_read, 3, nprtl1, noff1); - - reader.EndStep(); - reader.Close(); - - // check the validity - Kokkos::parallel_for( - "checkFields", - CreateRangePolicy({ 0, 0 }, { l_nx1_gh, l_nx2_gh }), - Lambda(index_t i1, index_t i2) { - for (int i = 0; i < 6; ++i) { - if (not cmp::AlmostEqual(field1(i1, i2, i), field1_read(i1, i2, i))) { - raise::KernelError(HERE, "Field1 read failed"); - } - if (not cmp::AlmostEqual(field2(i1, i2, i), field2_read(i1, i2, i))) { - raise::KernelError(HERE, "Field2 read failed"); - } - } - }); - - raise::ErrorIf(npart1 != nprtl1, "Particle count 1 mismatch", HERE); - raise::ErrorIf(npart2 != nprtl2, "Particle count 2 mismatch", HERE); - raise::ErrorIf(noff1 != npart1_offset, "Particle offset 1 mismatch", HERE); - raise::ErrorIf(noff2 != npart2_offset, "Particle offset 2 mismatch", HERE); - - Kokkos::parallel_for( - "checkPrtl1", - nprtl1, - Lambda(index_t p) { - if (not cmp::AlmostEqual(u1(p), u1_read(p))) { - raise::KernelError(HERE, "u1 read failed"); - } - if (i1(p) != i1_read(p)) { - raise::KernelError(HERE, "i1 read failed"); - } - for (auto l = 0; l < 3; ++l) { - if (not cmp::AlmostEqual(plds1(p, l), plds1_read(p, l))) { - raise::KernelError(HERE, "plds1 read failed"); - } - } - }); - Kokkos::parallel_for( - "checkPrtl2", - nprtl2, - Lambda(index_t p) { - if (not cmp::AlmostEqual(u2(p), u2_read(p))) { - raise::KernelError(HERE, "u2 read failed"); - } - if (i2(p) != i2_read(p)) { - raise::KernelError(HERE, "i2 read failed"); - } - }); - } - - } catch (std::exception& e) { - std::cerr << e.what() << std::endl; - cleanup(); - Kokkos::finalize(); - return 1; - } - cleanup(); - Kokkos::finalize(); - return 0; -} diff --git a/src/checkpoint/tests/checkpoint-nompi.cpp b/src/checkpoint/tests/checkpoint-nompi.cpp deleted file mode 100644 index 132a3679a..000000000 --- a/src/checkpoint/tests/checkpoint-nompi.cpp +++ /dev/null @@ -1,208 +0,0 @@ -#include "enums.h" -#include "global.h" - -#include "utils/comparators.h" - -#include "checkpoint/reader.h" -#include "checkpoint/writer.h" - -#include -#include -#include - -#include -#include - -using namespace ntt; -using namespace checkpoint; - -void cleanup() { - namespace fs = std::filesystem; - fs::path temp_path { "chck" }; - fs::remove_all(temp_path); -} - -auto main(int argc, char* argv[]) -> int { - Kokkos::initialize(argc, argv); - - try { - constexpr auto nx1 = 10; - constexpr auto nx1_gh = nx1 + 2 * N_GHOSTS; - constexpr auto nx2 = 13; - constexpr auto nx2_gh = nx2 + 2 * N_GHOSTS; - constexpr auto nx3 = 9; - constexpr auto nx3_gh = nx3 + 2 * N_GHOSTS; - constexpr auto i1min = N_GHOSTS; - constexpr auto i2min = N_GHOSTS; - constexpr auto i3min = N_GHOSTS; - constexpr auto i1max = nx1 + N_GHOSTS; - constexpr auto i2max = nx2 + N_GHOSTS; - constexpr auto i3max = nx3 + N_GHOSTS; - constexpr auto npart1 = 100; - constexpr auto npart2 = 100; - - // init data - ndfield_t field1 { "fld1", nx1_gh, nx2_gh, nx3_gh }; - ndfield_t field2 { "fld2", nx1_gh, nx2_gh, nx3_gh }; - - array_t i1 { "i_1", npart1 }; - array_t u1 { "u_1", npart1 }; - array_t i2 { "i_2", npart2 }; - array_t u2 { "u_2", npart2 }; - - { - // fill data - Kokkos::parallel_for( - "fillFlds", - CreateRangePolicy({ i1min, i2min, i3min }, - { i1max, i2max, i3max }), - Lambda(index_t i1, index_t i2, index_t i3) { - const auto i1_ = static_cast(i1); - const auto i2_ = static_cast(i2); - const auto i3_ = static_cast(i3); - field1(i1, i2, i3, 0) = i1_ + i2_ + i3_; - field1(i1, i2, i3, 1) = i1_ * i2_ / i3_; - field1(i1, i2, i3, 2) = i1_ / i2_ * i3_; - field1(i1, i2, i3, 3) = i1_ + i2_ - i3_; - field1(i1, i2, i3, 4) = i1_ * i2_ + i3_; - field1(i1, i2, i3, 5) = i1_ / i2_ - i3_; - field2(i1, i2, i3, 0) = -(i1_ + i2_ + i3_); - field2(i1, i2, i3, 1) = -(i1_ * i2_ / i3_); - field2(i1, i2, i3, 2) = -(i1_ / i2_ * i3_); - field2(i1, i2, i3, 3) = -(i1_ + i2_ - i3_); - field2(i1, i2, i3, 4) = -(i1_ * i2_ + i3_); - field2(i1, i2, i3, 5) = -(i1_ / i2_ - i3_); - }); - Kokkos::parallel_for( - "fillPrtl1", - npart1, - Lambda(index_t p) { - u1(p) = static_cast(p); - i1(p) = static_cast(p); - }); - Kokkos::parallel_for( - "fillPrtl2", - npart2, - Lambda(index_t p) { - u2(p) = -static_cast(p); - i2(p) = -static_cast(p); - }); - } - - adios2::ADIOS adios; - const path_t checkpoint_path { "chck" }; - - { - // write checkpoint - Writer writer {}; - writer.init(&adios, checkpoint_path, 0, 0.0, 1); - - writer.defineFieldVariables(SimEngine::GRPIC, - { nx1_gh, nx2_gh, nx3_gh }, - { 0, 0, 0 }, - { nx1_gh, nx2_gh, nx3_gh }); - writer.defineParticleVariables(Coord::Sph, Dim::_3D, 2, { 0, 2 }); - - writer.beginSaving(0, 0.0); - - writer.saveField("em", field1); - writer.saveField("em0", field2); - - writer.savePerDomainVariable("s1_npart", 1, 0, npart1); - writer.savePerDomainVariable("s2_npart", 1, 0, npart2); - - writer.saveParticleQuantity("s1_i1", npart1, 0, npart1, i1); - writer.saveParticleQuantity("s1_ux1", npart1, 0, npart1, u1); - writer.saveParticleQuantity("s2_i1", npart2, 0, npart2, i2); - writer.saveParticleQuantity("s2_ux1", npart2, 0, npart2, u2); - - writer.endSaving(); - } - - { - // read checkpoint - ndfield_t field1_read { "fld1_read", nx1_gh, nx2_gh, nx3_gh }; - ndfield_t field2_read { "fld2_read", nx1_gh, nx2_gh, nx3_gh }; - - array_t i1_read { "i_1", npart1 }; - array_t u1_read { "u_1", npart1 }; - array_t i2_read { "i_2", npart2 }; - array_t u2_read { "u_2", npart2 }; - - adios2::IO io = adios.DeclareIO("checkpointRead"); - adios2::Engine reader = io.Open(checkpoint_path / "step-00000000.bp", - adios2::Mode::Read); - reader.BeginStep(); - - auto fieldRange = adios2::Box({ 0, 0, 0, 0 }, - { nx1_gh, nx2_gh, nx3_gh, 6 }); - ReadFields(io, reader, "em", fieldRange, field1_read); - ReadFields(io, reader, "em0", fieldRange, field2_read); - - auto [nprtl1, noff1] = ReadParticleCount(io, reader, 0, 0, 1); - auto [nprtl2, noff2] = ReadParticleCount(io, reader, 1, 0, 1); - - ReadParticleData(io, reader, "ux1", 0, u1_read, nprtl1, noff1); - ReadParticleData(io, reader, "ux1", 1, u2_read, nprtl2, noff2); - ReadParticleData(io, reader, "i1", 0, i1_read, nprtl1, noff1); - ReadParticleData(io, reader, "i1", 1, i2_read, nprtl2, noff2); - - reader.EndStep(); - reader.Close(); - - // check the validity - Kokkos::parallel_for( - "checkFields", - CreateRangePolicy({ 0, 0, 0 }, { nx1_gh, nx2_gh, nx3_gh }), - Lambda(index_t i1, index_t i2, index_t i3) { - for (int i = 0; i < 6; ++i) { - if (not cmp::AlmostEqual(field1(i1, i2, i3, i), - field1_read(i1, i2, i3, i))) { - raise::KernelError(HERE, "Field1 read failed"); - } - if (not cmp::AlmostEqual(field2(i1, i2, i3, i), - field2_read(i1, i2, i3, i))) { - raise::KernelError(HERE, "Field2 read failed"); - } - } - }); - - raise::ErrorIf(npart1 != nprtl1, "Particle count 1 mismatch", HERE); - raise::ErrorIf(npart2 != nprtl2, "Particle count 2 mismatch", HERE); - raise::ErrorIf(noff1 != 0, "Particle offset 1 mismatch", HERE); - raise::ErrorIf(noff2 != 0, "Particle offset 2 mismatch", HERE); - - Kokkos::parallel_for( - "checkPrtl1", - npart1, - Lambda(index_t p) { - if (not cmp::AlmostEqual(u1(p), u1_read(p))) { - raise::KernelError(HERE, "u1 read failed"); - } - if (i1(p) != i1_read(p)) { - raise::KernelError(HERE, "i1 read failed"); - } - }); - Kokkos::parallel_for( - "checkPrtl2", - npart2, - Lambda(index_t p) { - if (not cmp::AlmostEqual(u2(p), u2_read(p))) { - raise::KernelError(HERE, "u2 read failed"); - } - if (i2(p) != i2_read(p)) { - raise::KernelError(HERE, "i2 read failed"); - } - }); - } - - } catch (std::exception& e) { - std::cerr << e.what() << std::endl; - cleanup(); - Kokkos::finalize(); - return 1; - } - cleanup(); - Kokkos::finalize(); - return 0; -} diff --git a/src/checkpoint/writer.cpp b/src/checkpoint/writer.cpp deleted file mode 100644 index b766ddfbd..000000000 --- a/src/checkpoint/writer.cpp +++ /dev/null @@ -1,302 +0,0 @@ -#include "checkpoint/writer.h" - -#include "global.h" - -#include "arch/kokkos_aliases.h" -#include "utils/error.h" -#include "utils/formatting.h" -#include "utils/log.h" - -#include "framework/parameters.h" - -#include -#include - -#include -#include -#include -#include - -namespace checkpoint { - - void Writer::init(adios2::ADIOS* ptr_adios, - const path_t& checkpoint_root, - timestep_t interval, - simtime_t interval_time, - int keep, - const std::string& walltime) { - m_keep = keep; - m_checkpoint_root = checkpoint_root; - m_enabled = keep != 0; - if (not m_enabled) { - return; - } - m_tracker.init("checkpoint", interval, interval_time, walltime); - p_adios = ptr_adios; - raise::ErrorIf(p_adios == nullptr, "ADIOS pointer is null", HERE); - - m_io = p_adios->DeclareIO("Entity::Checkpoint"); - m_io.SetEngine("BPFile"); - - m_io.DefineVariable("Step"); - m_io.DefineVariable("Time"); - m_io.DefineAttribute("NGhosts", ntt::N_GHOSTS); - - CallOnce( - [](auto&& checkpoint_root) { - if (!std::filesystem::exists(checkpoint_root)) { - std::filesystem::create_directory(checkpoint_root); - } - }, - m_checkpoint_root); - } - - void Writer::defineFieldVariables(const ntt::SimEngine& S, - const std::vector& glob_shape, - const std::vector& loc_corner, - const std::vector& loc_shape) { - auto gs6 = std::vector(glob_shape.begin(), glob_shape.end()); - auto lc6 = std::vector(loc_corner.begin(), loc_corner.end()); - auto ls6 = std::vector(loc_shape.begin(), loc_shape.end()); - gs6.push_back(6); - lc6.push_back(0); - ls6.push_back(6); - - m_io.DefineVariable("em", gs6, lc6, ls6); - if (S == ntt::SimEngine::GRPIC) { - m_io.DefineVariable("em0", gs6, lc6, ls6); - auto gs3 = std::vector(glob_shape.begin(), glob_shape.end()); - auto lc3 = std::vector(loc_corner.begin(), loc_corner.end()); - auto ls3 = std::vector(loc_shape.begin(), loc_shape.end()); - gs3.push_back(3); - lc3.push_back(0); - ls3.push_back(3); - m_io.DefineVariable("cur0", gs3, lc3, ls3); - } - } - - void Writer::defineParticleVariables(const ntt::Coord& C, - Dimension dim, - std::size_t nspec, - const std::vector& nplds) { - raise::ErrorIf(nplds.size() != nspec, - "Number of payloads does not match the number of species", - HERE); - for (auto s { 0u }; s < nspec; ++s) { - m_io.DefineVariable(fmt::format("s%d_npart", s + 1), - { adios2::UnknownDim }, - { adios2::UnknownDim }, - { adios2::UnknownDim }); - - for (auto d { 0u }; d < dim; ++d) { - m_io.DefineVariable(fmt::format("s%d_i%d", s + 1, d + 1), - { adios2::UnknownDim }, - { adios2::UnknownDim }, - { adios2::UnknownDim }); - m_io.DefineVariable(fmt::format("s%d_dx%d", s + 1, d + 1), - { adios2::UnknownDim }, - { adios2::UnknownDim }, - { adios2::UnknownDim }); - m_io.DefineVariable(fmt::format("s%d_i%d_prev", s + 1, d + 1), - { adios2::UnknownDim }, - { adios2::UnknownDim }, - { adios2::UnknownDim }); - m_io.DefineVariable(fmt::format("s%d_dx%d_prev", s + 1, d + 1), - { adios2::UnknownDim }, - { adios2::UnknownDim }, - { adios2::UnknownDim }); - } - - if (dim == Dim::_2D and C != ntt::Coord::Cart) { - m_io.DefineVariable(fmt::format("s%d_phi", s + 1), - { adios2::UnknownDim }, - { adios2::UnknownDim }, - { adios2::UnknownDim }); - } - - for (auto d { 0u }; d < 3; ++d) { - m_io.DefineVariable(fmt::format("s%d_ux%d", s + 1, d + 1), - { adios2::UnknownDim }, - { adios2::UnknownDim }, - { adios2::UnknownDim }); - } - - m_io.DefineVariable(fmt::format("s%d_tag", s + 1), - { adios2::UnknownDim }, - { adios2::UnknownDim }, - { adios2::UnknownDim }); - m_io.DefineVariable(fmt::format("s%d_weight", s + 1), - { adios2::UnknownDim }, - { adios2::UnknownDim }, - { adios2::UnknownDim }); - if (nplds[s] > 0) { - m_io.DefineVariable(fmt::format("s%d_plds", s + 1), - { adios2::UnknownDim, nplds[s] }, - { adios2::UnknownDim, 0 }, - { adios2::UnknownDim, nplds[s] }); - } - } - } - - auto Writer::shouldSave(timestep_t step, simtime_t time) -> bool { - return m_enabled and m_tracker.shouldWrite(step, time); - } - - void Writer::beginSaving(timestep_t step, simtime_t time) { - raise::ErrorIf(!m_enabled, "Checkpoint is not enabled", HERE); - raise::ErrorIf(p_adios == nullptr, "ADIOS pointer is null", HERE); - if (m_writing_mode) { - raise::Fatal("Already writing", HERE); - } - m_writing_mode = true; - try { - const auto filename = m_checkpoint_root / fmt::format("step-%08lu.bp", step); - const auto metafilename = m_checkpoint_root / - fmt::format("meta-%08lu.toml", step); - m_writer = m_io.Open(filename, adios2::Mode::Write); - m_written.push_back({ filename, metafilename }); - logger::Checkpoint(fmt::format("Writing checkpoint to %s and %s", - filename.c_str(), - metafilename.c_str()), - HERE); - } catch (std::exception& e) { - raise::Fatal(e.what(), HERE); - } - - m_writer.BeginStep(); - m_writer.Put(m_io.InquireVariable("Step"), &step); - m_writer.Put(m_io.InquireVariable("Time"), &time); - } - - void Writer::endSaving() { - raise::ErrorIf(p_adios == nullptr, "ADIOS pointer is null", HERE); - if (!m_writing_mode) { - raise::Fatal("Not writing", HERE); - } - m_writing_mode = false; - m_writer.EndStep(); - m_writer.Close(); - - // optionally remove the oldest checkpoint - CallOnce([&]() { - if (m_keep > 0 and m_written.size() > (std::size_t)m_keep) { - const auto oldest = m_written.front(); - if (std::filesystem::exists(oldest.first) and - std::filesystem::exists(oldest.second)) { - std::filesystem::remove_all(oldest.first); - std::filesystem::remove(oldest.second); - m_written.erase(m_written.begin()); - } else { - raise::Warning("Checkpoint file does not exist for some reason", HERE); - } - } - }); - } - - template - void Writer::savePerDomainVariable(const std::string& varname, - std::size_t total, - std::size_t offset, - T data) { - auto var = m_io.InquireVariable(varname); - var.SetShape({ total }); - var.SetSelection(adios2::Box({ offset }, { 1 })); - m_writer.Put(var, &data); - } - - void Writer::saveAttrs(const ntt::SimulationParams& params, simtime_t time) { - CallOnce([&]() { - std::ofstream metadata; - if (m_written.empty()) { - raise::Fatal("No checkpoint file to save metadata", HERE); - } - metadata.open(m_written.back().second.c_str()); - metadata << "[metadata]\n" - << " time = " << time << "\n\n" - << params.data() << std::endl; - metadata.close(); - }); - } - - template - void Writer::saveField(const std::string& fieldname, - const ndfield_t& field) { - auto field_h = Kokkos::create_mirror_view(field); - Kokkos::deep_copy(field_h, field); - m_writer.Put(m_io.InquireVariable(fieldname), - field_h.data(), - adios2::Mode::Sync); - } - - template - void Writer::saveParticleQuantity(const std::string& quantity, - npart_t glob_total, - npart_t loc_offset, - npart_t loc_size, - const array_t& data) { - const auto slice = range_tuple_t(0, loc_size); - auto var = m_io.InquireVariable(quantity); - - var.SetShape({ glob_total }); - var.SetSelection(adios2::Box({ loc_offset }, { loc_size })); - - auto data_h = Kokkos::create_mirror_view(data); - Kokkos::deep_copy(data_h, data); - auto data_sub = Kokkos::subview(data_h, slice); - m_writer.Put(var, data_sub.data(), adios2::Mode::Sync); - } - - void Writer::saveParticlePayloads(const std::string& quantity, - std::size_t nplds, - npart_t glob_total, - npart_t loc_offset, - npart_t loc_size, - const array_t& data) { - const auto slice = range_tuple_t(0, loc_size); - auto var = m_io.InquireVariable(quantity); - - var.SetShape({ glob_total, nplds }); - var.SetSelection( - adios2::Box({ loc_offset, 0 }, { loc_size, nplds })); - - auto data_h = Kokkos::create_mirror_view(data); - Kokkos::deep_copy(data_h, data); - auto data_sub = Kokkos::subview(data_h, slice, range_tuple_t(0, nplds)); - m_writer.Put(var, data_sub.data(), adios2::Mode::Sync); - } - -#define CHECKPOINT_PERDOMAIN_VARIABLE(T) \ - template void Writer::savePerDomainVariable(const std::string&, \ - std::size_t, \ - std::size_t, \ - T); - CHECKPOINT_PERDOMAIN_VARIABLE(int) - CHECKPOINT_PERDOMAIN_VARIABLE(float) - CHECKPOINT_PERDOMAIN_VARIABLE(double) - CHECKPOINT_PERDOMAIN_VARIABLE(npart_t) -#undef CHECKPOINT_PERDOMAIN_VARIABLE - -#define CHECKPOINT_FIELD(D, N) \ - template void Writer::saveField(const std::string&, \ - const ndfield_t&); - CHECKPOINT_FIELD(Dim::_1D, 3) - CHECKPOINT_FIELD(Dim::_1D, 6) - CHECKPOINT_FIELD(Dim::_2D, 3) - CHECKPOINT_FIELD(Dim::_2D, 6) - CHECKPOINT_FIELD(Dim::_3D, 3) - CHECKPOINT_FIELD(Dim::_3D, 6) -#undef CHECKPOINT_FIELD - -#define CHECKPOINT_PARTICLE_QUANTITY(T) \ - template void Writer::saveParticleQuantity(const std::string&, \ - npart_t, \ - npart_t, \ - npart_t, \ - const array_t&); - CHECKPOINT_PARTICLE_QUANTITY(int) - CHECKPOINT_PARTICLE_QUANTITY(float) - CHECKPOINT_PARTICLE_QUANTITY(double) - CHECKPOINT_PARTICLE_QUANTITY(short) -#undef CHECKPOINT_PARTICLE_QUANTITY - -} // namespace checkpoint diff --git a/src/checkpoint/writer.h b/src/checkpoint/writer.h deleted file mode 100644 index 6f8bc8cb5..000000000 --- a/src/checkpoint/writer.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file checkpoint/writer.h - * @brief Class that dumps checkpoints - * @implements - * - checkpoint::Writer - * @cpp: - * - writer.cpp - * @namespaces: - * - checkpoint:: - */ - -#ifndef CHECKPOINT_WRITER_H -#define CHECKPOINT_WRITER_H - -#include "enums.h" -#include "global.h" - -#include "utils/tools.h" - -#include "framework/parameters.h" - -#include - -#include -#include -#include - -namespace checkpoint { - - class Writer { - adios2::ADIOS* p_adios { nullptr }; - - adios2::IO m_io; - adios2::Engine m_writer; - - tools::Tracker m_tracker {}; - - bool m_writing_mode { false }; - - std::vector> m_written; - - int m_keep; - bool m_enabled; - path_t m_checkpoint_root; - - public: - Writer() {} - - ~Writer() = default; - - void init(adios2::ADIOS*, - const path_t&, - timestep_t, - simtime_t, - int, - const std::string& = ""); - - auto shouldSave(timestep_t, simtime_t) -> bool; - - void beginSaving(timestep_t, simtime_t); - void endSaving(); - - void saveAttrs(const ntt::SimulationParams&, simtime_t); - - template - void savePerDomainVariable(const std::string&, std::size_t, std::size_t, T); - - template - void saveField(const std::string&, const ndfield_t&); - - template - void saveParticleQuantity(const std::string&, - npart_t, - npart_t, - npart_t, - const array_t&); - - void saveParticlePayloads(const std::string&, - std::size_t, - npart_t, - npart_t, - npart_t, - const array_t&); - - void defineFieldVariables(const ntt::SimEngine&, - const std::vector&, - const std::vector&, - const std::vector&); - - void defineParticleVariables(const ntt::Coord&, - Dimension, - std::size_t, - const std::vector&); - - [[nodiscard]] - auto enabled() const -> bool { - return m_enabled; - } - }; - -} // namespace checkpoint - -#endif // CHECKPOINT_WRITER_H diff --git a/src/engines/engine_init.cpp b/src/engines/engine_init.cpp index 7a963b615..66c69ae19 100644 --- a/src/engines/engine_init.cpp +++ b/src/engines/engine_init.cpp @@ -3,16 +3,10 @@ #include "arch/traits.h" -#include "metrics/kerr_schild.h" -#include "metrics/kerr_schild_0.h" -#include "metrics/minkowski.h" -#include "metrics/qkerr_schild.h" -#include "metrics/qspherical.h" -#include "metrics/spherical.h" - #include "archetypes/field_setter.h" #include "engines/engine.hpp" +#include "framework/specialization_registry.h" #include @@ -71,13 +65,11 @@ namespace ntt { print_report(); } - template class Engine>; - template class Engine>; - template class Engine>; - template class Engine>; - template class Engine>; - template class Engine>; - template class Engine>; - template class Engine>; +#define ENGINE_INIT(S, M, D) \ + template class Engine>; + + NTT_FOREACH_SPECIALIZATION(ENGINE_INIT) + +#undef ENGINE_INIT } // namespace ntt diff --git a/src/engines/engine_printer.cpp b/src/engines/engine_printer.cpp index 20f5e81ba..4f03da773 100644 --- a/src/engines/engine_printer.cpp +++ b/src/engines/engine_printer.cpp @@ -6,14 +6,8 @@ #include "utils/colors.h" #include "utils/formatting.h" -#include "metrics/kerr_schild.h" -#include "metrics/kerr_schild_0.h" -#include "metrics/minkowski.h" -#include "metrics/qkerr_schild.h" -#include "metrics/qspherical.h" -#include "metrics/spherical.h" - #include "engines/engine.hpp" +#include "framework/specialization_registry.h" #if defined(CUDA_ENABLED) #include @@ -306,6 +300,12 @@ namespace ntt { add_param(report, 4, "Problem generator", "%s", pgen.c_str()); add_param(report, 4, "Engine", "%s", SimEngine(S).to_string()); add_param(report, 4, "Metric", "%s", Metric(M::MetricType).to_string()); +#if SHAPE_ORDER == 0 + add_param(report, 4, "Deposit", "%s", "zigzag"); +#else + add_param(report, 4, "Deposit", "%s", "esirkepov"); + add_param(report, 4, "Interpolation order", "%i", SHAPE_ORDER); +#endif add_param(report, 4, "Timestep [dt]", "%.3e", dt); add_param(report, 4, "Runtime", "%.3e [%d steps]", runtime, max_steps); report += "\n"; @@ -400,7 +400,8 @@ namespace ntt { add_param(report, 6, "GCA", "%s", species.use_gca() ? "ON" : "OFF"); } add_param(report, 6, "Cooling", "%s", species.cooling().to_string()); - add_param(report, 6, "# of payloads", "%d", species.npld()); + add_param(report, 6, "# of real-value payloads", "%d", species.npld_r()); + add_param(report, 6, "# of integer-value payloads", "%d", species.npld_i()); } report.pop_back(); }, @@ -488,13 +489,11 @@ namespace ntt { } } - template void Engine>::print_report() const; - template void Engine>::print_report() const; - template void Engine>::print_report() const; - template void Engine>::print_report() const; - template void Engine>::print_report() const; - template void Engine>::print_report() const; - template void Engine>::print_report() const; - template void Engine>::print_report() const; +#define ENGINE_PRINTER(S, M, D) \ + template void Engine>::print_report() const; + + NTT_FOREACH_SPECIALIZATION(ENGINE_PRINTER) + +#undef ENGINE_PRINTER } // namespace ntt diff --git a/src/engines/engine_run.cpp b/src/engines/engine_run.cpp index 65c87e939..17a1905d6 100644 --- a/src/engines/engine_run.cpp +++ b/src/engines/engine_run.cpp @@ -3,16 +3,10 @@ #include "arch/traits.h" #include "utils/diag.h" -#include "metrics/kerr_schild.h" -#include "metrics/kerr_schild_0.h" -#include "metrics/minkowski.h" -#include "metrics/qkerr_schild.h" -#include "metrics/qspherical.h" -#include "metrics/spherical.h" - #include "framework/domain/domain.h" #include "engines/engine.hpp" +#include "framework/specialization_registry.h" namespace ntt { @@ -143,13 +137,11 @@ namespace ntt { } } - template void Engine>::run(); - template void Engine>::run(); - template void Engine>::run(); - template void Engine>::run(); - template void Engine>::run(); - template void Engine>::run(); - template void Engine>::run(); - template void Engine>::run(); +#define ENGINE_RUN(S, M, D) \ + template void Engine>::run(); + + NTT_FOREACH_SPECIALIZATION(ENGINE_RUN) + +#undef ENGINE_RUN } // namespace ntt diff --git a/src/engines/engine_traits.h b/src/engines/engine_traits.h new file mode 100644 index 000000000..28a74bea3 --- /dev/null +++ b/src/engines/engine_traits.h @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef ENGINES_ENGINE_TRAITS_H +#define ENGINES_ENGINE_TRAITS_H + +#include "enums.h" + +#include "engines/grpic.hpp" +#include "engines/srpic.hpp" + +namespace ntt { + + template + struct EngineSelector; + + template <> + struct EngineSelector { + template + using type = SRPICEngine; + }; + + template <> + struct EngineSelector { + template + using type = GRPICEngine; + }; + +} // namespace ntt + +#endif // ENGINES_ENGINE_TRAITS_H diff --git a/src/engines/srpic.hpp b/src/engines/srpic.hpp index 6b6a52039..9a4ec31fa 100644 --- a/src/engines/srpic.hpp +++ b/src/engines/srpic.hpp @@ -23,7 +23,9 @@ #include "utils/timer.h" #include "utils/toml.h" +#include "archetypes/energy_dist.h" #include "archetypes/particle_injector.h" +#include "archetypes/spatial_dist.h" #include "framework/domain/domain.h" #include "framework/parameters.h" @@ -76,9 +78,9 @@ namespace ntt { void step_forward(timer::Timers& timers, domain_t& dom) override { const auto fieldsolver_enabled = m_params.template get( - "algorithms.toggles.fieldsolver"); + "algorithms.fieldsolver.enable"); const auto deposit_enabled = m_params.template get( - "algorithms.toggles.deposit"); + "algorithms.deposit.enable"); const auto clear_interval = m_params.template get( "particles.clear_interval"); @@ -185,7 +187,25 @@ namespace ntt { if constexpr (M::CoordType == Coord::Cart) { // minkowski case const auto dx = math::sqrt(domain.mesh.metric.template h_<1, 1>({})); - real_t coeff1, coeff2; + const auto deltax = m_params.template get( + "algorithms.fieldsolver.delta_x"); + const auto deltay = m_params.template get( + "algorithms.fieldsolver.delta_y"); + const auto betaxy = m_params.template get( + "algorithms.fieldsolver.beta_xy"); + const auto betayx = m_params.template get( + "algorithms.fieldsolver.beta_yx"); + const auto deltaz = m_params.template get( + "algorithms.fieldsolver.delta_z"); + const auto betaxz = m_params.template get( + "algorithms.fieldsolver.beta_xz"); + const auto betazx = m_params.template get( + "algorithms.fieldsolver.beta_zx"); + const auto betayz = m_params.template get( + "algorithms.fieldsolver.beta_yz"); + const auto betazy = m_params.template get( + "algorithms.fieldsolver.beta_zy"); + real_t coeff1, coeff2; if constexpr (M::Dim == Dim::_2D) { coeff1 = dT / SQR(dx); coeff2 = dT; @@ -193,10 +213,20 @@ namespace ntt { coeff1 = dT / dx; coeff2 = ZERO; } - Kokkos::parallel_for( - "Faraday", - domain.mesh.rangeActiveCells(), - kernel::mink::Faraday_kernel(domain.fields.em, coeff1, coeff2)); + Kokkos::parallel_for("Faraday", + domain.mesh.rangeActiveCells(), + kernel::mink::Faraday_kernel(domain.fields.em, + coeff1, + coeff2, + deltax, + deltay, + betaxy, + betayx, + deltaz, + betaxz, + betazx, + betayz, + betazy)); } else { Kokkos::parallel_for("Faraday", domain.mesh.rangeActiveCells(), @@ -318,6 +348,7 @@ namespace ntt { : ZERO; // cooling const auto has_synchrotron = (cooling == Cooling::SYNCHROTRON); + const auto has_compton = (cooling == Cooling::COMPTON); const auto sync_grad = has_synchrotron ? m_params.template get( "algorithms.synchrotron.gamma_rad") @@ -328,9 +359,16 @@ namespace ntt { "scales.omegaB0") / (SQR(sync_grad) * species.mass()) : ZERO; - + const auto comp_grad = has_compton ? m_params.template get( + "algorithms.compton.gamma_rad") + : ZERO; + const auto comp_coeff = has_compton ? (real_t)(0.1) * dt * + m_params.template get( + "scales.omegaB0") / + (SQR(comp_grad) * species.mass()) + : ZERO; // toggle to indicate whether pgen defines the external force - bool has_extforce = false; + bool has_extforce = false; if constexpr (traits::has_member::value) { has_extforce = true; // toggle to indicate whether the ext force applies to current species @@ -346,6 +384,9 @@ namespace ntt { if (cooling == Cooling::SYNCHROTRON) { cooling_tags = kernel::sr::Cooling::Synchrotron; } + if (cooling == Cooling::COMPTON) { + cooling_tags = kernel::sr::Cooling::Compton; + } // clang-format off if (not has_atmosphere and not has_extforce) { Kokkos::parallel_for( @@ -368,7 +409,7 @@ namespace ntt { domain.mesh.n_active(in::x2), domain.mesh.n_active(in::x3), domain.mesh.prtl_bc(), - gca_larmor_max, gca_eovrb_max, sync_coeff + gca_larmor_max, gca_eovrb_max, sync_coeff, comp_coeff )); } else if (has_atmosphere and not has_extforce) { const auto force = @@ -398,7 +439,7 @@ namespace ntt { domain.mesh.n_active(in::x2), domain.mesh.n_active(in::x3), domain.mesh.prtl_bc(), - gca_larmor_max, gca_eovrb_max, sync_coeff + gca_larmor_max, gca_eovrb_max, sync_coeff, comp_coeff )); } else if (not has_atmosphere and has_extforce) { if constexpr (traits::has_member::value) { @@ -427,7 +468,7 @@ namespace ntt { domain.mesh.n_active(in::x2), domain.mesh.n_active(in::x3), domain.mesh.prtl_bc(), - gca_larmor_max, gca_eovrb_max, sync_coeff + gca_larmor_max, gca_eovrb_max, sync_coeff, comp_coeff )); } else { raise::Error("External force not implemented", HERE); @@ -459,7 +500,7 @@ namespace ntt { domain.mesh.n_active(in::x2), domain.mesh.n_active(in::x3), domain.mesh.prtl_bc(), - gca_larmor_max, gca_eovrb_max, sync_coeff + gca_larmor_max, gca_eovrb_max, sync_coeff, comp_coeff )); } else { raise::Error("External force not implemented", HERE); @@ -477,9 +518,30 @@ namespace ntt { } } + template + void deposit_with(const Particles& species, + const M& metric, + const scatter_ndfield_t& scatter_cur, + real_t dt) { + // clang-format off + Kokkos::parallel_for("CurrentsDeposit", + species.rangeActiveParticles(), + kernel::DepositCurrents_kernel( + scatter_cur, + species.i1, species.i2, species.i3, + species.i1_prev, species.i2_prev, species.i3_prev, + species.dx1, species.dx2, species.dx3, + species.dx1_prev, species.dx2_prev, species.dx3_prev, + species.ux1, species.ux2, species.ux3, + species.phi, species.weight, species.tag, + metric, (real_t)(species.charge()), dt)); + // clang-format on + } + void CurrentsDeposit(domain_t& domain) { auto scatter_cur = Kokkos::Experimental::create_scatter_view( domain.fields.cur); + auto shape_order = m_params.template get("algorithms.deposit.order"); for (auto& species : domain.species) { if ((species.pusher() == PrtlPusher::NONE) or (species.npart() == 0) or cmp::AlmostZero_host(species.charge())) { @@ -492,20 +554,8 @@ namespace ntt { species.npart(), (double)species.charge()), HERE); - // clang-format off - Kokkos::parallel_for("CurrentsDeposit", - species.rangeActiveParticles(), - kernel::DepositCurrents_kernel( - scatter_cur, - species.i1, species.i2, species.i3, - species.i1_prev, species.i2_prev, species.i3_prev, - species.dx1, species.dx2, species.dx3, - species.dx1_prev, species.dx2_prev, species.dx3_prev, - species.ux1, species.ux2, species.ux3, - species.phi, species.weight, species.tag, - domain.mesh.metric, - (real_t)(species.charge()), dt)); - // clang-format on + + deposit_with(species, domain.mesh.metric, scatter_cur, dt); } Kokkos::Experimental::contribute(domain.fields.cur, scatter_cur); } @@ -1240,119 +1290,153 @@ namespace ntt { m_metadomain.SynchronizeFields(domain, Comm::Bckp, { 0, 1 }); } + const auto maxwellian = arch::Maxwellian { domain.mesh.metric, + domain.random_pool, + temp }; + if (dim == in::x1) { if (sign > 0) { - const auto atm_injector = - arch::AtmosphereInjector { - domain.mesh.metric, - domain.fields.bckp, + auto target_density = + arch::AtmosphereDensityProfile { nmax, height, x_surf, - ds, - temp, - domain.random_pool, - species + ds }; - arch::InjectNonUniform(m_params, - domain, - atm_injector, - nmax, - use_weights); + const auto spatial_dist = arch::Replenish { + domain.mesh.metric, + domain.fields.bckp, + 0, + target_density, + nmax + }; + arch::InjectNonUniform( + m_params, + domain, + { species.first, species.second }, + { maxwellian, maxwellian }, + spatial_dist, + nmax, + use_weights); } else { - const auto atm_injector = - arch::AtmosphereInjector { - domain.mesh.metric, - domain.fields.bckp, + auto target_density = + arch::AtmosphereDensityProfile { nmax, height, x_surf, - ds, - temp, - domain.random_pool, - species + ds }; - arch::InjectNonUniform(m_params, - domain, - atm_injector, - nmax, - use_weights); + const auto spatial_dist = arch::Replenish { + domain.mesh.metric, + domain.fields.bckp, + 0, + target_density, + nmax + }; + arch::InjectNonUniform( + m_params, + domain, + { species.first, species.second }, + { maxwellian, maxwellian }, + spatial_dist, + nmax, + use_weights); } } else if (dim == in::x2) { if (sign > 0) { - const auto atm_injector = - arch::AtmosphereInjector { - domain.mesh.metric, - domain.fields.bckp, + auto target_density = + arch::AtmosphereDensityProfile { nmax, height, x_surf, - ds, - temp, - domain.random_pool, - species + ds }; - arch::InjectNonUniform(m_params, - domain, - atm_injector, - nmax, - use_weights); + const auto spatial_dist = arch::Replenish { + domain.mesh.metric, + domain.fields.bckp, + 0, + target_density, + nmax + }; + arch::InjectNonUniform( + m_params, + domain, + { species.first, species.second }, + { maxwellian, maxwellian }, + spatial_dist, + nmax, + use_weights); } else { - const auto atm_injector = - arch::AtmosphereInjector { - domain.mesh.metric, - domain.fields.bckp, + auto target_density = + arch::AtmosphereDensityProfile { nmax, height, x_surf, - ds, - temp, - domain.random_pool, - species + ds }; - arch::InjectNonUniform(m_params, - domain, - atm_injector, - nmax, - use_weights); + const auto spatial_dist = arch::Replenish { + domain.mesh.metric, + domain.fields.bckp, + 0, + target_density, + nmax + }; + arch::InjectNonUniform( + m_params, + domain, + { species.first, species.second }, + { maxwellian, maxwellian }, + spatial_dist, + nmax, + use_weights); } } else if (dim == in::x3) { if (sign > 0) { - const auto atm_injector = - arch::AtmosphereInjector { - domain.mesh.metric, - domain.fields.bckp, + auto target_density = + arch::AtmosphereDensityProfile { nmax, height, x_surf, - ds, - temp, - domain.random_pool, - species + ds }; - arch::InjectNonUniform(m_params, - domain, - atm_injector, - nmax, - use_weights); + const auto spatial_dist = arch::Replenish { + domain.mesh.metric, + domain.fields.bckp, + 0, + target_density, + nmax + }; + arch::InjectNonUniform( + m_params, + domain, + { species.first, species.second }, + { maxwellian, maxwellian }, + spatial_dist, + nmax, + use_weights); } else { - const auto atm_injector = - arch::AtmosphereInjector { - domain.mesh.metric, - domain.fields.bckp, + auto target_density = + arch::AtmosphereDensityProfile { nmax, height, x_surf, - ds, - temp, - domain.random_pool, - species + ds }; - arch::InjectNonUniform(m_params, - domain, - atm_injector, - nmax, - use_weights); + const auto spatial_dist = arch::Replenish { + domain.mesh.metric, + domain.fields.bckp, + 0, + target_density, + nmax + }; + arch::InjectNonUniform( + m_params, + domain, + { species.first, species.second }, + { maxwellian, maxwellian }, + spatial_dist, + nmax, + use_weights); } } else { raise::Error("Invalid dimension", HERE); diff --git a/src/entity.cpp b/src/entity.cpp index 79b2f1335..33e2ac071 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -3,19 +3,15 @@ #include "arch/traits.h" #include "utils/error.h" -#include "metrics/kerr_schild.h" -#include "metrics/kerr_schild_0.h" -#include "metrics/minkowski.h" -#include "metrics/qkerr_schild.h" -#include "metrics/qspherical.h" -#include "metrics/spherical.h" - #include "framework/simulation.h" +#include "framework/specialization_registry.h" + +#include "engines/engine_traits.h" -#include "engines/grpic.hpp" -#include "engines/srpic.hpp" #include "pgen.hpp" +#include + template class M, Dimension D> static constexpr bool should_compile { traits::check_compatibility::value(user::PGen>::engines) && @@ -23,95 +19,49 @@ static constexpr bool should_compile { traits::check_compatibility::value(user::PGen>::dimensions) }; -template