diff --git a/.gitignore b/.gitignore index 8c77683d..f4cbe1ea 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ build external .*.swp test_include/test_data_filepath.hpp +**/output diff --git a/CMake/CLI11.cmake b/CMake/CLI11.cmake index 6255482b..eb84deb7 100644 --- a/CMake/CLI11.cmake +++ b/CMake/CLI11.cmake @@ -35,3 +35,5 @@ if( TARGET cli11_download ) endif() target_include_directories( cli11 INTERFACE ${cli_include_dir} ) + +list( APPEND dependencies cli11 ) diff --git a/CMake/catch.cmake b/CMake/catch.cmake new file mode 100644 index 00000000..c2a281d4 --- /dev/null +++ b/CMake/catch.cmake @@ -0,0 +1,42 @@ +# catch2 + +set( catch2_library_file_0 + "${prefix}/catch2-install/lib/libCatch2Main.a" + CACHE FILEPATH "" + FORCE ) + +set( catch2_library_file_1 + "${prefix}/catch2-install/lib/libCatch2.a" + CACHE FILEPATH "" + FORCE ) + +set( catch2_url "https://github.com/catchorg/Catch2.git" ) + +set( download_command git clone ${catch2_url} ${prefix}/catch2 ) + +set( configure_command + ${CMAKE_COMMAND} + -S ${prefix}/catch2 + -B ${prefix}/catch2-build + -DCMAKE_INSTALL_PREFIX=${prefix}/catch2-install ) + +ExternalProject_Add( catch2_download + PREFIX ${prefix} + DOWNLOAD_COMMAND ${download_command} + CONFIGURE_COMMAND ${configure_command} + BUILD_BYPRODUCTS ${catch2_library_file_0} ${catch2_library_file_1} + BUILD_COMMAND ${CMAKE_COMMAND} + --build ${prefix}/catch2-build --target install -- -j + INSTALL_COMMAND ${CMAKE_COMMAND} --install ${prefix}/catch2-build ) + +add_library( catch2 INTERFACE ) + +add_dependencies( catch2 catch2_download ) + +target_include_directories( catch2 INTERFACE ${prefix}/catch2-install/include ) + +target_link_libraries( catch2 INTERFACE + ${catch2_library_file_0} + ${catch2_library_file_1} ) + +list( APPEND dependencies catch2 ) diff --git a/CMake/configure_test_data.cmake b/CMake/configure_test_data.cmake index 7c14a137..9f692262 100644 --- a/CMake/configure_test_data.cmake +++ b/CMake/configure_test_data.cmake @@ -1,9 +1,11 @@ # copies over the file and sets destination_path macro( generate_testing_file test_file_name ) -set( source_path "${CMAKE_SOURCE_DIR}/${test_file_name}" ) -set( destination_path "${CMAKE_BINARY_DIR}/${test_file_name}" ) -configure_file( ${source_path} ${destination_path} COPYONLY ) + set( source_path "${CMAKE_SOURCE_DIR}/${test_file_name}" ) + + set( destination_path "${CMAKE_BINARY_DIR}/${test_file_name}" ) + + configure_file( ${source_path} ${destination_path} COPYONLY ) endmacro() @@ -69,3 +71,8 @@ set( test_file_name "test_data/netcdf_file_py.nc" ) set( source_path "${CMAKE_SOURCE_DIR}/${test_file_name}" ) set( destination_path "${CMAKE_BINARY_DIR}/${test_file_name}" ) configure_file( ${source_path} ${destination_path} COPYONLY ) + +# copy examples folder to the binary directory +set( source_path "${CMAKE_SOURCE_DIR}/examples/" ) +set( destination_path "${CMAKE_BINARY_DIR}/examples" ) +file( COPY ${source_path} DESTINATION ${destination_path} ) diff --git a/CMake/crosslink_components.cmake b/CMake/crosslink_components.cmake index 29c37e7f..6ad335ce 100644 --- a/CMake/crosslink_components.cmake +++ b/CMake/crosslink_components.cmake @@ -67,30 +67,29 @@ if( GITR_USE_MPI ) endif() # link test targets -target_link_libraries( config_interface_tests test_utils libconfig config_interface ) +target_link_libraries( config_interface_tests libconfig config_interface catch2 ) target_link_libraries( coulomb_tests - test_utils libconfig thrust interp2d utils flags netcdf boris fields ) + libconfig thrust interp2d utils flags netcdf boris fields + catch2 ) -target_link_libraries( atomic_tests test_utils ionize interp2d utils flags ) +target_link_libraries( atomic_tests ionize interp2d utils flags catch2 ) target_link_libraries( field_tests - test_utils interp2d libconfig utils netcdf fields boris ) + interp2d libconfig utils netcdf fields boris catch2 ) target_link_libraries( file_io_tests - test_utils libconfig utils flags boris geometry_check ) + libconfig utils flags boris geometry_check catch2 ) target_link_libraries( cross_field_diffusion_tests - test_utils utils flags libconfig boris spectroscopy thrust - geometry_check ) + utils flags libconfig boris spectroscopy thrust + geometry_check config_interface catch2 ) -target_link_libraries( surface_model_tests - surface_model spectroscopy test_utils flags - libconfig utils boris geometry_check ) +target_link_libraries( boris_tests flags libconfig utils boris slow_math catch2 ) -target_link_libraries( boris_tests test_utils flags libconfig utils boris slow_math ) +target_link_libraries( slow_math_tests slow_math catch2 ) -target_link_libraries( slow_math_tests test_utils slow_math ) +target_link_libraries( interpolator_tests catch2 ) if( OpenMP_CXX_FOUND ) diff --git a/CMake/cuda.cmake b/CMake/cuda.cmake index 411c5b4f..303deed3 100644 --- a/CMake/cuda.cmake +++ b/CMake/cuda.cmake @@ -1,37 +1,32 @@ # Configure system for GPU support if specified -if( GITR_USE_CUDA ) +set( CUDA_SEPARABLE_COMPILATION ON ) - add_compile_definitions( THRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA ) +set(CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER}) - set( CUDA_SEPARABLE_COMPILATION ON ) +enable_language( CUDA ) - set(CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER}) +# Captain: enforce minimum requirement +include( FindCUDAToolkit ) - # Note: CMAKE_CUDA_COMPILER must be set so that the enable_language() call succeeds - enable_language( CUDA ) +if( NOT CUDAToolkit_FOUND ) - # Later: enforce minimum requirement + message( FATAL_ERROR + "CUDA toolkit not found: to enable, set -DCUDAToolkit_ROOT=/path/to/cuda_root." + "The CUDA root path can be inferred from your nvcc executable: run 'which nvcc' + to indicate where nvcc is located, take the directory portion of the path as + the root." + " Alternatively, to disable GPU support, set -DGITR_USE_CUDA=0 when configuring + with CMake" ) - include( FindCUDAToolkit ) - - if( NOT CUDAToolkit_FOUND ) - - message( FATAL_ERROR - "CUDA toolkit not found: to enable, set -DCUDAToolkit_ROOT=/path/to/cuda_root." - "The CUDA root path can be inferred from your nvcc executable: run 'which nvcc' - to indicate where nvcc is located, take the directory portion of the path as - the root." - " Alternatively, to disable GPU support, set -DGITR_USE_CUDA=0 when configuring - with CMake" ) - endif() +endif() - include_directories( ${CUDAToolkit_INCLUDE_DIRS} ) +if( "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" ) - set( CMAKE_CUDA_ARCHITECTURES 70 ) + set( CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -g -G" ) -else() +endif() - add_compile_definitions( THRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_OMP ) +include_directories( ${CUDAToolkit_INCLUDE_DIRS} ) -endif() +set( CMAKE_CUDA_ARCHITECTURES 70 ) diff --git a/CMake/define_source_components.cmake b/CMake/define_source_components.cmake index 5653f952..51c96fe8 100644 --- a/CMake/define_source_components.cmake +++ b/CMake/define_source_components.cmake @@ -20,13 +20,14 @@ endif() target_include_directories( GITR PUBLIC include ) # CPU-only targets -set( cpu_targets +set( non_gpu_targets efield_interp particle utils flags config_interface slow_math + interpolator setup) # conditionally compile as GPU targets @@ -39,16 +40,15 @@ set( gpu_targets hashGeom fields spectroscopy - geometry_check - curandInitialize) + geometry_check ) if( NOT GITR_USE_CUDA ) - set( cpu_targets ${cpu_targets} ${gpu_targets} ) + set( non_gpu_targets ${non_gpu_targets} ${gpu_targets} ) endif() -foreach( component IN LISTS cpu_targets ) +foreach( component IN LISTS non_gpu_targets ) add_library( ${component} src/${component}.cpp ) diff --git a/CMake/define_test_components.cmake b/CMake/define_test_components.cmake index 81c0674b..691c75e1 100644 --- a/CMake/define_test_components.cmake +++ b/CMake/define_test_components.cmake @@ -3,21 +3,9 @@ include( CTest ) enable_testing() -# create a component to encapsulate the external testing framework -# Since catch2 is a header-only library, it's target can be created as an interface target -add_library( catch2 INTERFACE ) - -target_include_directories( catch2 INTERFACE - test_include ) - -add_library( test_utils test_src/test_utils.cpp test_include/test_utils.hpp ) - -target_include_directories( test_utils PUBLIC ${CMAKE_SOURCE_DIR} ) - -target_link_libraries( test_utils PUBLIC catch2 ) - -set( cpu_test_targets +set( non_gpu_test_targets slow_math_tests + interpolator_tests config_interface_tests ) # atomic tests does not compile and is disabled @@ -27,16 +15,15 @@ set( gpu_test_targets field_tests atomic_tests boris_tests - surface_model_tests cross_field_diffusion_tests ) if( NOT GITR_USE_CUDA ) - set( cpu_test_targets ${cpu_test_targets} ${gpu_test_targets} ) + set( non_gpu_test_targets ${non_gpu_test_targets} ${gpu_test_targets} ) endif() -foreach( component IN LISTS cpu_test_targets ) +foreach( component IN LISTS non_gpu_test_targets ) add_executable( ${component} test_src/${component}.cpp ) @@ -67,3 +54,15 @@ if( GITR_USE_CUDA ) endforeach() endif() + +# Captain! Add a "ninja clean that will delete all the +# add simple system tests +add_test( NAME system_particle_straightline + COMMAND GITR -c input/gitrInput.cfg + WORKING_DIRECTORY + "${CMAKE_BINARY_DIR}/examples/particle_trajectories/straightLine/2Dgeom" ) + +add_test( NAME system_particle_gyro + COMMAND GITR -c input/gitrInput.cfg + WORKING_DIRECTORY + "${CMAKE_BINARY_DIR}/examples/particle_trajectories/gyroMotion" ) diff --git a/CMake/dependencies.cmake b/CMake/dependencies.cmake index 37d47d5f..9ecfd931 100644 --- a/CMake/dependencies.cmake +++ b/CMake/dependencies.cmake @@ -1,8 +1,13 @@ +# Only OpenMP or Cuda can be specified +if( GITR_USE_CUDA AND GITR_USE_OPENMP ) + + message( FATAL_ERROR "Both GITR_USE_CUDA and GITR_USE_OPENMP are set. Please select one" ) + +endif() + # Handle external dependencies include( ExternalProject ) -set( dependencies "" ) - set( prefix "${CMAKE_BINARY_DIR}/external" ) if( APPLE ) @@ -17,46 +22,51 @@ endif() set( CMAKE_BUILD_WITH_INSTALL_RPATH True ) +# ensure shared dependency libs are discoverable at load-time set( CMAKE_INSTALL_RPATH "${CMAKE_BINARY_DIR}" "${prefix}/libconfig_install/lib" "${prefix}/netcdf-c-install/lib" "${prefix}/netcdf-cxx4-install/lib" ) -# OpenMP -include( FindOpenMP ) +# Captain! Rename to "common dependency set" or something more descriptive +set( dependencies "" ) -include_directories( ${OpenMP_C_INCLUDE_DIRS} ${OpenMP_CXX_INCLUDE_DIRS} ) +# The following lines populate the "dependencies" variable # CLI11 include( CMake/CLI11.cmake ) # ---> creates target cli11 -list( APPEND dependencies cli11 ) - -# hdf5 -#include( FindHDF5 ) +# HDF5 find_package( HDF5 COMPONENTS C HL ) -message( "HDF5_INCLUDE_DIRS: ${HDF5_INCLUDE_DIRS}" ) -message( "HDF5_INCLUDE_DIRS: ${HDF5_LIBRARIES}" ) - # CUDA -include( CMake/cuda.cmake ) # ---> creates target CUDA::cudart +if( GITR_USE_CUDA ) -# MPI -include( CMake/mpi.cmake ) # ---> creates target mpi + include( CMake/cuda.cmake ) # ---> creates target CUDA::cudart + +# OpenMP +elseif( GITR_USE_OPENMP ) + + include( CMake/openmp.cmake ) # ---> creates target OpenMP + +endif() # Thrust include( CMake/thrust.cmake ) # ---> creates target thrust -list( APPEND dependencies thrust ) +# MPI +if( GITR_USE_MPI ) + + include( CMake/mpi.cmake ) # ---> creates target mpi + +endif() # Libconfig include( CMake/libconfig.cmake ) # ---> creates target libconfig -list( APPEND dependencies libconfig ) - # NETCDF include( CMake/netcdf.cmake ) # ---> creates target netcdf -list( APPEND dependencies netcdf ) +# Catch2 +include( CMake/catch.cmake ) diff --git a/CMake/enforce_build_order.cmake b/CMake/enforce_build_order.cmake index f4b8eb7c..5e265f68 100644 --- a/CMake/enforce_build_order.cmake +++ b/CMake/enforce_build_order.cmake @@ -4,7 +4,7 @@ # before linking if( dependencies ) - foreach( component IN LISTS cpu_targets gpu_targets ) + foreach( component IN LISTS non_gpu_targets gpu_targets ) add_dependencies( ${component} ${dependencies} ) @@ -12,15 +12,14 @@ if( dependencies ) endif() -# ensure that test targets are built after source targets foreach( target IN LISTS cpu_test_targets gpu_test_targets ) - add_dependencies( ${target} ${cpu_targets} ${gpu_targets} test_utils ) + add_dependencies( ${target} ${cpu_targets} ${gpu_targets} ${dependencies} ) endforeach() # ensure that all source targets are built before GITR -add_dependencies( GITR ${cpu_targets} ${gpu_targets} ) +add_dependencies( GITR ${non_gpu_targets} ${gpu_targets} ) # ensure that hdf5 is build before netcdf add_dependencies( netcdf hdf5 ) diff --git a/CMake/json.cmake b/CMake/json.cmake new file mode 100644 index 00000000..a2c7452b --- /dev/null +++ b/CMake/json.cmake @@ -0,0 +1,48 @@ +# Captain! Add Ninja as the default cmake generator for any of these projects +set( JSON_BuildTests OFF CACHE INTERNAL "" ) + +set( json_url "https://github.com/nlohmann/json.git" ) + +set( json_file ${prefix}/json/json_install/include/nlohmann/json.hpp ) + +set( download_command + git clone --depth 1 --branch v3.10.5 + ${json_url} + ${prefix}/json ) + +set( configure_command + ${CMAKE_COMMAND} + -S ${prefix}/json + -B ${prefix}/json_build + -DENABLE_DAP=OFF + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_INSTALL_PREFIX=${prefix}/json_install ) + +# Download only +ExternalProject_Add( json_download + PREFIX ${prefix} + DOWNLOAD_COMMAND ${download_command} + CONFIGURE_COMMAND ${configure_command} + BUILD_BYPRODUCTS ${json_file} + BUILD_COMMAND ${CMAKE_COMMAND} --build ${prefix}/json_build -- -j + INSTALL_COMMAND ${CMAKE_COMMAND} --install ${prefix}/json_build ) + + + +add_library( json_lib INTERFACE ) + +if( TARGET json_download ) + + add_dependencies( json_lib json_download ) + +endif() + +target_include_directories( json_lib INTERFACE ${prefix}/json_install/include ) + +# Captain! +add_executable( json src/json.cpp ) + +add_dependencies( json json_lib ) + +target_link_libraries( json json_lib ) diff --git a/CMake/libconfig.cmake b/CMake/libconfig.cmake index 830b8711..1dc1b1b6 100644 --- a/CMake/libconfig.cmake +++ b/CMake/libconfig.cmake @@ -76,3 +76,5 @@ target_include_directories( libconfig INTERFACE target_link_libraries( libconfig INTERFACE ${LIBCONFIG_LIBRARY} ${LIBCONFIGPP_LIBRARY} ) + +list( APPEND dependencies libconfig ) diff --git a/CMake/mpi.cmake b/CMake/mpi.cmake index c25cf55e..a5d56405 100644 --- a/CMake/mpi.cmake +++ b/CMake/mpi.cmake @@ -1,25 +1,21 @@ # configure system for MPI support if specified -if( GITR_USE_MPI ) +include( FindMPI ) - include( FindMPI ) +if(MPI_FOUND) - if(MPI_FOUND) + add_library( mpi INTERFACE ) + target_include_directories( mpi INTERFACE ${MPI_CXX_INCLUDE_DIRS} ${MPI_C_INCLUDE_DIRS}) + target_link_libraries( mpi INTERFACE ${MPI_CXX_LIBRARIES} ${MPI_C_LIBRARIES} ) - add_library( mpi INTERFACE ) - target_include_directories( mpi INTERFACE ${MPI_CXX_INCLUDE_DIRS} ${MPI_C_INCLUDE_DIRS}) - target_link_libraries( mpi INTERFACE ${MPI_CXX_LIBRARIES} ${MPI_C_LIBRARIES} ) + set( MPI_CXX_INCLUDE_DIRS ${MPI_CXX_INCLUDE_DIRS} CACHE PATH "" FORCE ) + set( MPI_C_INCLUDE_DIRS ${MPI_C_INCLUDE_DIRS} CACHE PATH "" FORCE ) + set( MPI_CXX_LIBRARIES ${MPI_CXX_LIBRARIES} CACHE FILEPATH "" FORCE ) + set( MPI_C_LIBRARIES ${MPI_C_LIBRARIES} CACHE FILEPATH "" FORCE ) - set( MPI_CXX_INCLUDE_DIRS ${MPI_CXX_INCLUDE_DIRS} CACHE PATH "" FORCE ) - set( MPI_C_INCLUDE_DIRS ${MPI_C_INCLUDE_DIRS} CACHE PATH "" FORCE ) - set( MPI_CXX_LIBRARIES ${MPI_CXX_LIBRARIES} CACHE FILEPATH "" FORCE ) - set( MPI_C_LIBRARIES ${MPI_C_LIBRARIES} CACHE FILEPATH "" FORCE ) +else() - else() - - message( FATAL_ERROR "MPI was not found - please specify MPI library location with" - " -DMPI_HOME=/path/to/mpi or disable MPI support with -DGITR_USE_MPI=0" ) - - endif() + message( FATAL_ERROR "MPI was not found - please specify MPI library location with" + " -DMPI_HOME=/path/to/mpi or disable MPI support with -DGITR_USE_MPI=0" ) endif() diff --git a/CMake/netcdf.cmake b/CMake/netcdf.cmake index 2aa11495..526ada22 100644 --- a/CMake/netcdf.cmake +++ b/CMake/netcdf.cmake @@ -116,3 +116,5 @@ target_link_libraries( netcdf INTERFACE ${NETCDF_LIBRARY} ${NETCDF_CXX_LIBRARY} ${HDF5_LIBRARIES} ) + +list( APPEND dependencies netcdf ) diff --git a/CMake/openmp.cmake b/CMake/openmp.cmake new file mode 100644 index 00000000..7d0de0a9 --- /dev/null +++ b/CMake/openmp.cmake @@ -0,0 +1,9 @@ +include( FindOpenMP ) + +if( NOT OpenMP_CXX_FOUND ) + + message( FATAL_ERROR "OpenMP not found" ) + +endif() + +include_directories( ${OpenMP_C_INCLUDE_DIRS} ${OpenMP_CXX_INCLUDE_DIRS} ) diff --git a/CMake/thrust.cmake b/CMake/thrust.cmake index 28969abf..afd394d2 100644 --- a/CMake/thrust.cmake +++ b/CMake/thrust.cmake @@ -1,6 +1,28 @@ # Add thrust -if( NOT GITR_USE_CUDA ) +# set the thrust backend accelerator +if( GITR_USE_CUDA ) + + add_compile_definitions( THRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA ) + +elseif( GITR_USE_OPENMP ) + + # Captain! Once OpenMP does not appear in GITR source code, check for OpenMP here. + add_compile_definitions( THRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_OMP ) + +else() + + add_compile_definitions( THRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CPP ) + +endif() + +# If CUDA is specified, use the thrust that ships with the CUDA package +if( GITR_USE_CUDA ) + + set( THRUST_INCLUDE_DIR "${CUDAToolkit_INCLUDE_DIRS}" CACHE PATH "" FORCE ) + +# Otherwise, it must be downloaded +else() set( THRUST_INCLUDE_DIR "${prefix}/thrust" CACHE PATH "" FORCE ) @@ -24,12 +46,9 @@ if( NOT GITR_USE_CUDA ) endif() -else() - - set( THRUST_INCLUDE_DIR "${CUDAToolkit_INCLUDE_DIRS}" CACHE PATH "" FORCE ) - endif() +# Captain! Why is this here? Who actually needs this? Remove it after tests pass set(THRUST_INCLUDE_DIRS ${THRUST_INCLUDE_DIR} CACHE PATH "" FORCE ) add_library( thrust INTERFACE ) @@ -43,3 +62,5 @@ endif() include_directories( ${THRUST_INCLUDE_DIR} ) target_include_directories( thrust INTERFACE ${THRUST_INCLUDE_DIR} ) + +list( APPEND dependencies thrust ) diff --git a/CMake/user_options.cmake b/CMake/user_options.cmake index ee60c9ae..7867e89f 100644 --- a/CMake/user_options.cmake +++ b/CMake/user_options.cmake @@ -1,96 +1,17 @@ -# Anti-pattern: build-time options - these will be converted to runtime options in the future - # String description for each option set( description "(no description added - see define_options.cmake)" ) -set( GITR_USE_CUDA 1 CACHE STRING "${description}" ) -set( GITR_USE_MPI 0 CACHE STRING "${description}" ) -set( GITR_USE_DOUBLE 1 CACHE STRING "${description}" ) -set( GITR_USE_IONIZATION 1 CACHE STRING "${description}" ) # if ionization is on, recombination on -set( GITR_USE_RECOMBINATION 1 CACHE STRING "${description}" ) -set( GITR_USE_PERP_DIFFUSION 1 CACHE STRING "${description}" ) -set( GITR_USE_COULOMB_COLLISIONS 1 CACHE STRING "${description}" ) # if collisions are on, friction, scattering, heating -set( GITR_USE_FRICTION 1 CACHE STRING "${description}" ) -set( GITR_USE_ANGLE_SCATTERING 1 CACHE STRING "${description}" ) -set( GITR_USE_HEATING 1 CACHE STRING "${description}" ) -set( GITR_USE_THERMAL_FORCE 0 CACHE STRING "${description}" ) -set( GITR_USE_SURFACE_MODEL 1 CACHE STRING "${description}" ) -set( GITR_USE_SHEATH_EFIELD 1 CACHE STRING "${description}" ) -set( GITR_BIASED_SURFACE 0 CACHE STRING "${description}" ) -set( GITR_USE_SURFACE_POTENTIAL 0 CACHE STRING "${description}" ) -set( GITR_USE_PRE_SHEATH_EFIELD 0 CACHE STRING "${description}" ) -set( GITR_BFIELD_INTERP 0 CACHE STRING "${description}" ) -set( GITR_LC_INTERP 0 CACHE STRING "${description}" ) -set( GITR_GENERATE_LC 0 CACHE STRING "${description}" ) -set( GITR_EFIELD_INTERP 0 CACHE STRING "${description}" ) -set( GITR_PRE_SHEATH_INTERP 0 CACHE STRING "${description}" ) -set( GITR_DENSITY_INTERP 2 CACHE STRING "${description}" ) -set( GITR_TEMP_INTERP 2 CACHE STRING "${description}" ) -set( GITR_FLOWV_INTERP 0 CACHE STRING "${description}" ) -set( GITR_GRADT_INTERP 0 CACHE STRING "${description}" ) -set( GITR_ODE_INT 0 CACHE STRING "${description}" ) -set( GITR_FIXED_SEEDS 1 CACHE STRING "${description}" ) -set( GITR_PARTICLE_SEEDS 1 CACHE STRING "${description}" ) -set( GITR_GEOM_TRACE 0 CACHE STRING "${description}" ) -set( GITR_GEOM_HASH 0 CACHE STRING "${description}" ) -set( GITR_GEOM_HASH_SHEATH 0 CACHE STRING "${description}" ) -set( GITR_PARTICLE_TRACKS 0 CACHE STRING "${description}" ) -set( GITR_PARTICLE_SOURCE 0 CACHE STRING "${description}" ) -set( GITR_PARTICLE_SOURCE_SPACE 0 CACHE STRING "${description}" ) -set( GITR_PARTICLE_SOURCE_ENERGY 0 CACHE STRING "${description}" ) -set( GITR_PARTICLE_SOURCE_ANGLE 0 CACHE STRING "${description}" ) -set( GITR_PARTICLE_SOURCE_FILE 0 CACHE STRING "${description}" ) -set( GITR_SPECTROSCOPY 2 CACHE STRING "${description}" ) -set( GITR_USE_3DTET_GEOM 0 CACHE STRING "${description}" ) -set( GITR_USE_CYLSYMM 0 CACHE STRING "${description}" ) -set( GITR_USE_FIELD_ALIGNED_VALUES 0 CACHE STRING "${description}" ) -set( GITR_FLUX_EA 1 CACHE STRING "${description}" ) -set( GITR_FORCE_EVAL 0 CACHE STRING "${description}" ) -set( GITR_USE_SORT 0 CACHE STRING "${description}" ) -set( GITR_CHECK_COMPATIBILITY 1 CACHE STRING "${description}" ) +set( GITR_USE_CUDA 1 CACHE STRING "${description}" FORCE ) +set( GITR_USE_OPENMP 0 CACHE STRING "${description}" FORCE ) +set( GITR_USE_MPI 0 CACHE STRING "${description}" FORCE ) +set( GITR_USE_DOUBLE 1 CACHE STRING "${description}" FORCE ) add_compile_definitions( USE_CUDA=${GITR_USE_CUDA} USE_MPI=${GITR_USE_MPI} - USE_DOUBLE=${GITR_USE_DOUBLE} - USEIONIZATION=${GITR_USE_IONIZATION} - USERECOMBINATION=${GITR_USE_RECOMBINATION} - USEPERPDIFFUSION=${GITR_USE_PERP_DIFFUSION} - USECOULOMBCOLLISIONS=${GITR_USE_COULOMB_COLLISIONS} - USEFRICTION=${GITR_USE_FRICTION} - USEANGLESCATTERING=${GITR_USE_ANGLE_SCATTERING} - USEHEATING=${GITR_USE_HEATING} - USETHERMALFORCE=${GITR_USE_THERMAL_FORCE} - USESURFACEMODEL=${GITR_USE_SURFACE_MODEL} - USESHEATHEFIELD=${GITR_USE_SHEATH_EFIELD} - BIASED_SURFACE=${GITR_BIASED_SURFACE} - USE_SURFACE_POTENTIAL=${GITR_USE_SURFACE_POTENTIAL} - USEPRESHEATHEFIELD=${GITR_USE_PRE_SHEATH_EFIELD} - BFIELD_INTERP=${GITR_BFIELD_INTERP} - LC_INTERP=${GITR_LC_INTERP} - GENERATE_LC=${GITR_GENERATE_LC} - EFIELD_INTERP=${GITR_EFIELD_INTERP} - PRESHEATH_INTERP=${GITR_PRE_SHEATH_INTERP} - DENSITY_INTERP=${GITR_DENSITY_INTERP} - TEMP_INTERP=${GITR_TEMP_INTERP} - FLOWV_INTERP=${GITR_FLOWV_INTERP} - GRADT_INTERP=${GITR_GRADT_INTERP} - ODEINT=${GITR_ODE_INT} - FIXEDSEEDS=${GITR_FIXED_SEEDS} - PARTICLESEEDS=${GITR_PARTICLE_SEEDS} - GEOM_TRACE=${GITR_GEOM_TRACE} - GEOM_HASH=${GITR_GEOM_HASH} - GEOM_HASH_SHEATH=${GITR_GEOM_HASH_SHEATH} - PARTICLE_TRACKS=${GITR_PARTICLE_TRACKS} - PARTICLE_SOURCE=${GITR_PARTICLE_SOURCE} - PARTICLE_SOURCE_SPACE=${GITR_PARTICLE_SOURCE_SPACE} - PARTICLE_SOURCE_ENERGY=${GITR_PARTICLE_SOURCE_ENERGY} - PARTICLE_SOURCE_ANGLE=${GITR_PARTICLE_SOURCE_ANGLE} - PARTICLE_SOURCE_FILE=${GITR_PARTICLE_SOURCE_FILE} - SPECTROSCOPY=${GITR_SPECTROSCOPY} - USE3DTETGEOM=${GITR_USE_3DTET_GEOM} - USECYLSYMM=${GITR_USE_CYLSYMM} - USEFIELDALIGNEDVALUES=${GITR_USE_FIELD_ALIGNED_VALUES} - FLUX_EA=${GITR_FLUX_EA} - FORCE_EVAL=${GITR_FORCE_EVAL} - USE_SORT=${GITR_USE_SORT} - CHECK_COMPATIBILITY=${GITR_CHECK_COMPATIBILITY}) + USE_OPENMP=${GITR_USE_OPENMP} + USE_DOUBLE=${GITR_USE_DOUBLE} + FIELD_ALIGNED_VALUES=0 + LC_INTERP=0 + GENERATE_LC=0 + BIASED_SURFACE=0 + ODEINT=0 ) diff --git a/CMakeLists.txt b/CMakeLists.txt index 025314ca..260b8c0a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project( gitr CXX C ) set( CMAKE_CXX_STANDARD 17 ) -set( CMAKE_BUILD_TYPE Debug ) +set( CMAKE_BUILD_TYPE "Release" ) # point cmake to the find_package modules set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/CMake/ ) diff --git a/README.md b/README.md index 9fb11f94..3f7a7691 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ This final command should print out all the loaded environments. ## Installation -### Configure: +### Hardware Configuration: Configure build system with CMake. Physics operators can be activated via **-D**-style build-time options provided to CMake. @@ -177,14 +177,89 @@ If using Ninja: ### Run GITR expects to be run in a directory containing subdirectories **input** and **output**. -The **input** directory must contain a file called *gitrInput.cfg*. Reference -docs/runtime_config.md for details about this file. These following options in the file must -be mirrored with their CMake **-D**-style counterpart build-time option. +The **input** directory must contain a file called *gitrInput.cfg*. Navigate to this directory and run: > /path/to/build/GITR +### Configuration options + +There are 32 options GITR expects to consume at runtime, in a block of the gitrInput.cfg +file called: + +> flags + +A list of the required options and a brief description of each is provided: + + - USESURFACEMODEL + - Binary option - turn on or off for surface modeling + - FLUX_EA + - Binary option - turn on to collect energy/angle flux + - SPECTROSCOPY + - Ternary option for density histogram collection: + - 0: do not collect density histograms + - 2: create 2d histograms + - 3: create 3d histograms + - BIASED_SURFACE + - Binary option, 0 or 1. Enabled by USESHEATHEFIELD + - USE3DTETGEOM + - binary variable + - 0: 3d off, 2d + - 1: 3d on, 3d + - USECYLSYMM + - description + - BFIELD_INTERP + - description + - GRADT_INTERP + - description + - FORCE_EVAL + - description + - SORT_PARTICLES + - description + - USE_ADAPTIVE_DT + - description + - GEOM_HASH + - description + - PARTICLE_SOURCE_FILE + - description + - PARTICLE_SOURCE_SPACE + - description + - PARTICLE_SOURCE_ENERGY + - description + - PARTICLE_SOURCE_ANGLE + - description + - PARTICLE_TRACKS + - description + - PRESHEATH_INTERP + - description + - EFIELD_INTERP + - description + - USE_SURFACE_POTENTIAL + - description + - FLOWV_INTERP + - description + - DENSITY_INTERP + - description + - TEMP_INTERP + - description + - GEOM_HASH_SHEATH + - description + - USETHERMALFORCE + - description + - USESHEATHEFIELD + - description + - USEPRESHEATHEFIELD + - description + - USE_IONIZATION + - description + - USECOULOMBCOLLISIONS + - description + - USEPERPDIFFUSION + - description + - USEFIELDALIGNEDVALUES + - description + ## Canonical Example The default configuration options in GITR are compatible with the input deck in: diff --git a/branch.txt b/branch.txt deleted file mode 100644 index 2f4684c9..00000000 --- a/branch.txt +++ /dev/null @@ -1 +0,0 @@ -The point of this branch is to add a maximum dt that is not dependent on B-field magnitude diff --git a/examples/particle_trajectories/gyroMotion/LcS.nc b/examples/particle_trajectories/gyroMotion/LcS.nc new file mode 100644 index 00000000..8c1332fd Binary files /dev/null and b/examples/particle_trajectories/gyroMotion/LcS.nc differ diff --git a/examples/particle_trajectories/gyroMotion/cleanGITRrun.sh b/examples/particle_trajectories/gyroMotion/cleanGITRrun.sh new file mode 100755 index 00000000..48cad659 --- /dev/null +++ b/examples/particle_trajectories/gyroMotion/cleanGITRrun.sh @@ -0,0 +1,9 @@ +#!/bin/bash +rm -r geometry +rm -r profiles +rm -r output +rm history.nc +rm positions.nc +rm positions.m +rm surface.nc +rm spec.nc diff --git a/examples/particle_trajectories/gyroMotion/gold/history.nc b/examples/particle_trajectories/gyroMotion/gold/history.nc new file mode 100644 index 00000000..d26b627c Binary files /dev/null and b/examples/particle_trajectories/gyroMotion/gold/history.nc differ diff --git a/examples/particle_trajectories/gyroMotion/gold/particleSource.nc b/examples/particle_trajectories/gyroMotion/gold/particleSource.nc new file mode 100644 index 00000000..f58e7cde Binary files /dev/null and b/examples/particle_trajectories/gyroMotion/gold/particleSource.nc differ diff --git a/examples/particle_trajectories/gyroMotion/gold/positions.m b/examples/particle_trajectories/gyroMotion/gold/positions.m new file mode 100644 index 00000000..07a774dd --- /dev/null +++ b/examples/particle_trajectories/gyroMotion/gold/positions.m @@ -0,0 +1 @@ +Pos( 1,:) = [ -1.49557 0.0130978 3.96638e-17 ]; diff --git a/examples/particle_trajectories/gyroMotion/gold/positions.nc b/examples/particle_trajectories/gyroMotion/gold/positions.nc new file mode 100644 index 00000000..4bbce8b5 Binary files /dev/null and b/examples/particle_trajectories/gyroMotion/gold/positions.nc differ diff --git a/examples/particle_trajectories/gyroMotion/input/gitrGeometry.cfg b/examples/particle_trajectories/gyroMotion/input/gitrGeometry.cfg new file mode 100644 index 00000000..8786791f --- /dev/null +++ b/examples/particle_trajectories/gyroMotion/input/gitrGeometry.cfg @@ -0,0 +1,22 @@ +geom = +{ + x1 = [1.0,2.0,2.0,1.0]; + z1 = [0.0,0.0,1.0,1.0]; + x2 = [2.0,2.0,1.0,1.0]; + z2 = [0.0,1.0,1.0,0.0]; + slope = [0.0,1000000000000.0,0.0,-1000000000000.0]; + intercept = [0.0,1000000000000.0,1.0,1000000000000.0]; + length = [1.0,1.0,1.0,1.0]; + Z = [74.0,74.0,74.0,74.0,0.0]; + surface = [1, 1, 1, 1, 1]; + potential= [0, 0, 0, 0]; + inDir = [-1, 1, 1, 1, 1]; + y1 = -1.0; + y2 = 1.0; + periodic = 0; + theta0 = 0.0; + theta1 = 0.0; + periodic_bc_x0 = -10000.0; + periodic_bc_x1 = 100000.0; + periodic_bc_x = 0; +} diff --git a/examples/particle_trajectories/gyroMotion/input/gitrInput.cfg b/examples/particle_trajectories/gyroMotion/input/gitrInput.cfg new file mode 100755 index 00000000..fd4d26a0 --- /dev/null +++ b/examples/particle_trajectories/gyroMotion/input/gitrInput.cfg @@ -0,0 +1,443 @@ +geometry = +{ + fileString = "gitrGeometry.cfg"; +} +backgroundPlasmaProfiles = +{ + Z = 1.0; + amu = 2.0; + biasPotential = 0.0; + + Bfield = + { + r = 0.0; + z = 0.8; + y = 0.0; + fileString = "ar2Input.nc"; + gridNrString = "nR"; + gridNyString = "nY"; + gridNzString = "nZ"; + gridRString = "r"; + gridYString = "y"; + gridZString = "z"; + radialComponentString = "br"; + axialComponentString = "bz"; + toroidalComponentString = "bt"; + } + Efield = + { + Er = 0.0; + Ez = 0.0; + Et = 0.0; + fileString = "LcS.nc"; + gridNrString = "nR"; + gridNyString = "nY"; + gridNzString = "nZ"; + gridRString = "gridR"; + gridYString = "gridY"; + gridZString = "gridZ"; + radialComponentString = "PSEr"; + axialComponentString = "PSEz"; + toroidalComponentString = "PSEt"; + } + dtsEfield = + { + dtsEr = 0.0; + dtsEz = 0.0; + dtsEt = 0.0; + fileString = "profiles.nc"; + gridNrString = "n_r_sheathDTS"; + gridNzString = "n_z_sheathDTS"; + gridRString = "gridRsheathDTS"; + gridZString = "gridZsheathDTS"; + sheathDTS = "sheathDTS"; + } + Temperature = + { + ti = 4.0; + te = 4.0; + fileString = "profiles.nc"; + gridNrString = "nX_t"; + gridNzString = "nZ_t"; + gridRString = "gridx_t"; + gridZString = "gridz_t"; + IonTempString = "ti"; + ElectronTempString = "te"; + } + Density = + { + ni = 7.0E+17; + ne = 7.0E+17; + fileString = "profiles.nc"; + gridNrString = "nX_n"; + gridNzString = "nZ_n"; + gridRString = "gridx_n"; + gridZString = "gridz_n"; + IonDensityString = "ni"; + ElectronDensityString = "ne"; + } + Diffusion = + { + Dperp = 0.1; + fileString = "profiles.nc"; + gridNrString = "n_x"; + gridNzString = "n_z"; + gridRString = "gridx"; + gridZString = "gridz"; + variableString = "ni"; + } + FlowVelocity = + { + interpolatorNumber = 0; + flowVr = 0.0; + flowVy = 0.0; + flowVz = -200000.0; + fileString = "LcS.nc"; + gridNrString = "nR"; + gridNyString = "nY"; + gridNzString = "nZ"; + gridRString = "gridR"; + gridYString = "gridY"; + gridZString = "gridZ"; + flowVrString = "flowVr"; + flowVzString = "flowVz"; + flowVtString = "flowVt"; + } + ConnectionLength = + { + interpolatorNumber = 2; + Lc = 10.0; + s = 1.0; + fileString = "LcS.nc"; + gridNrString = "nR"; + gridNyString = "nY"; + gridNzString = "nZ"; + gridRString = "gridR"; + gridYString = "gridY"; + gridZString = "gridZ"; + LcString = "Lc"; + SString = "s"; + } + gradT = + { + gradTeR = 0.0; + gradTeY = 0.0; + gradTeZ = 0.0; + gradTiR = 0.0; + gradTiY = 0.0; + gradTiZ = 0.0; + fileString = "profiles.nc"; + gridNrString = "nX_gradTi"; + gridNzString = "nZ_gradTi"; + gridRString = "gridx_gradTi"; + gridZString = "gridz_gradTi"; + gradTiRString = "gradTiR"; + gradTiZString = "gradTiZ"; + gradTeRString = "gradTeR"; + gradTeZString = "gradTeZ"; + } + Lc = + { + value = 1.0; + fileString = "profiles.nc"; + gridNrString = "nX_Lc"; + gridNzString = "nY_Lc"; + gridRString = "gridx_Lc"; + gridZString = "gridy_Lc"; + variableString = "Lc"; + } + s = + { + value = 1.0; + fileString = "profiles.nc"; + gridNrString = "nX_s"; + gridNzString = "nY_s"; + gridRString = "gridx_s"; + gridZString = "gridy_s"; + variableString = "s"; + } +} +connectionLength = +{ + nTraceSteps = 5000; + dr = 0.0001; + netx0 = -0.076; + netx1 = 0.076; + nX = 80; + nety0 = -0.076; + nety1 = 0.076; + nY = 70; + netz0 = -0.05; + netz1 = 0.2; + nZ = 100; + fileString = "LcS.nc"; + gridNrString = "nR"; + gridNyString = "nY"; + gridNzString = "nZ"; + gridRString = "gridR"; + gridYString = "gridY"; + gridZString = "gridZ"; + LcString = "Lc"; + SString = "s"; + noIntersectionString = "noIntersection"; +} +impurityParticleSource = +{ + nP = 1; + sourceStrength = 1E+19; + Z = 74.0; + source_material_Z = 74; + source_material_SurfaceBindingEnergy = 11.75; + + initialConditions = + { + x_start = -1.5; + y_start = 0.0; + z_start = 0.0; + energy_eV_x_start = 6.0; + energy_eV_y_start = 0.0; + energy_eV_z_start = 6.0; + impurity_amu = 184.0; + impurity_Z = 74.0; + charge = 1.0; + energy_eV=10.0; + phi = 90.0; + theta = 135.0; + } + ionization = + { + fileString = "ADAS_Rates_W.nc"; + TempGridString = "n_Temperatures_Ionize"; + DensGridString = "n_Densities_Ionize"; + nChargeStateString = "n_ChargeStates_Ionize"; + TempGridVarName = "gridTemperature_Ionization"; + DensGridVarName = "gridDensity_Ionization"; + CoeffVarName = "IonizationRateCoeff"; + } + + recombination = + { + fileString = "ADAS_Rates_W.nc"; + TempGridString = "n_Temperatures_Recombine"; + DensGridString = "n_Densities_Recombine"; + nChargeStateString = "n_ChargeStates_Recombine"; + TempGridVarName = "gridTemperature_Recombination"; + DensGridVarName = "gridDensity_Recombination"; + CoeffVarName = "RecombinationRateCoeff"; + } +} + +timeStep = +{ + dt = 1E-8; + nPtsPerGyroOrbit = 10000.0; + ionization_nDtPerApply = 1; + collision_nDtPerApply = 5; + nT = 20000; +} +geometry_hash = +{ + fileString = "profiles.nc"; + gridNrString = "nX_hash"; + gridNyString = "nY_hash"; + gridNzString = "nZ_hash"; + nearestNelementsString = "nN_hash"; + gridRString = "gridx_hash"; + gridYString = "gridy_hash"; + gridZString = "gridz_hash"; + closeGeomString = "geomHash3d"; +} + +geometry_sheath = +{ + fileString = "profiles.nc"; + gridNrString = "nX_hash_sheath"; + gridNyString = "nY_hash_sheath"; + gridNzString = "nZ_hash_sheath"; + nearestNelementsString = "nN_hash_sheath"; + gridRString = "gridx_hash_sheath"; + gridYString = "gridy_hash_sheath"; + gridZString = "gridz_hash_sheath"; + closeGeomString = "geomHash3d_sheath"; +} +surfaces = +{ + useMaterialSurfaces=1; + flux = + { + nE=200; + E0 = 0.0; + E = 1000.0; + nA = 30; + A0 = 0.0; + A = 90.0; + } +} +volumeDefinition = +{ + xMinV = -0.02; + xMaxV = +0.02; + + grid = + { + nXv = 100; + nYv = 150; + nZv = 150; + } +} + +surfaceDefinition = +{ + yMin = -0.03; + yMax = 0.03; + zMin = -0.03; + zMax = 0.03; + + grid = + { + nY = 150; + nZ = 150; + } + + planeParameterization = + { + surface_dz_dx = 1.73205; + surface_zIntercept = 0.0; + } +} + +bField = +{ + interpolatorNumber = 0; + Bx_in = 0.00; + By_in = 0.00; + Bz_in = -2.0; + connectionLength = 50.0; +} + +eField = +{ + interpolatorNumber = 2; +} + +perpDiffusion = +{ + interpolatorNumber = 0; + perDiffusionCoeff_in = 0.0; +} + +backgroundPlasma = +{ + Z = [-1, 1]; + amu = [5.446e-4, 2.0]; + + temp = + { + interpolatorNumber = 0; + max = [20.0, 20.0]; + tempSOLDecayLength = (1E+04,1E+04); + } + + density = + { + interpolatorNumber = 0; + max = [1e19, 1e19]; + densitySOLDecayLength = (1E+04, 1E+04); + } + + flow = + { + interpolatorNumber = 0; + fractionOfThermalVelocity = [ 0.0, 0.0]; + } +} + +diagnostics = +{ + trackSubSampleFactor=1; + leakZ=0.0; + netx0 = -0.08; + netx1 = 0.08; + nX = 100; + nety0 = -0.1; + nety1 = 0.1; + nY = 120; + netz0 = -0.05; + netz1 = 0.2; + nZ = 150; + densityChargeBins = 5; +} + +operators = +{ + boris = + { seed = 1.25E+5; + } + ionization = + { seed = 2.05E+5; + } + recombination = + { seed = 3.15E+5; + } + perpDiffusion = + { seed = 4.35E+5; + } + coulombCollisions = + { seed1 = 5.45E+5; + seed2 = 7.84E+5; + seed3 = 8.90E+5; + } + surfaceModel = + { seed = 6.55E+5; + } +} +flags = +{ + USE_CUDA=1; + USEMPI=0; + USE_MPI=0; + USE_OPENMP=0; + USE_BOOST=1; + USEIONIZATION=0; + USE_IONIZATION=0; + USERECOMBINATION=0; + USEPERPDIFFUSION=0; + USECOULOMBCOLLISIONS=0; + USETHERMALFORCE=0; + USESURFACEMODEL=0; + USESHEATHEFIELD=0; + BIASED_SURFACE=0; + USEPRESHEATHEFIELD=0; + BFIELD_INTERP=0; + LC_INTERP=0; + GENERATE_LC=0; + EFIELD_INTERP=0; + PRESHEATH_INTERP=0; + DENSITY_INTERP=0; + TEMP_INTERP=0; + FLOWV_INTERP=0; + GRADT_INTERP=0; + ODEINT=0; + FIXEDSEEDS=1; + FIXED_SEEDS=1; + PARTICLESEEDS=1; + GEOM_TRACE=0; + GEOM_HASH=0; + GEOM_HASH_SHEATH=0; + PARTICLE_TRACKS=1; + PARTICLE_SOURCE_SPACE=0; + PARTICLE_SOURCE_ENERGY=0; + PARTICLE_SOURCE_ANGLE=0; + PARTICLE_SOURCE_FILE=0; + SPECTROSCOPY=0; + USE3DTETGEOM=0; + USECYLSYMM=0; + USEFIELDALIGNEDVALUES=0; + FLUX_EA=0; + FORCE_EVAL=0; + CHECK_COMPATIBILITY=1; + USE_ADAPTIVE_DT=0; + USE_SORT = 0; + USE_SURFACE_POTENTIAL=0; +} + diff --git a/examples/particle_trajectories/gyroMotion/track.png b/examples/particle_trajectories/gyroMotion/track.png new file mode 100644 index 00000000..35e9a277 Binary files /dev/null and b/examples/particle_trajectories/gyroMotion/track.png differ diff --git a/examples/particle_trajectories/plot_tracks.m b/examples/particle_trajectories/plot_tracks.m new file mode 100644 index 00000000..b64fd9b0 --- /dev/null +++ b/examples/particle_trajectories/plot_tracks.m @@ -0,0 +1,32 @@ +close all +clear all + +file = strcat(pwd,'/history.nc'); +x = ncread(file,'x'); +y = ncread(file,'y'); +z = ncread(file,'z'); +vx = ncread(file,'vx'); +vy = ncread(file,'vy'); +vz = ncread(file,'vz'); +charge = ncread(file,'charge'); +weight = ncread(file,'weight'); +sizeArray = size(x); +nP = sizeArray(2); +hit = find(weight(end,:) < 1); + +r = sqrt(x.^2 + y.^2); + figure(1) + hold on + +for i=1:1 + +plot3(x(:,i),y(:,i),z(:,i),'k') +end +hold on +scatter3(x(1,1),y(1,1),z(1,1)) +scatter3(x(end,1),y(end,1),z(end,1)) +xlabel('x [m]') +ylabel('y [m]') +zlabel('z [m]') +legend('Track','Begin','End') +axis equal diff --git a/examples/particle_trajectories/straightLine/2Dgeom/LcS.nc b/examples/particle_trajectories/straightLine/2Dgeom/LcS.nc new file mode 100644 index 00000000..8c1332fd Binary files /dev/null and b/examples/particle_trajectories/straightLine/2Dgeom/LcS.nc differ diff --git a/examples/particle_trajectories/straightLine/2Dgeom/cleanGITRrun.sh b/examples/particle_trajectories/straightLine/2Dgeom/cleanGITRrun.sh new file mode 100755 index 00000000..48cad659 --- /dev/null +++ b/examples/particle_trajectories/straightLine/2Dgeom/cleanGITRrun.sh @@ -0,0 +1,9 @@ +#!/bin/bash +rm -r geometry +rm -r profiles +rm -r output +rm history.nc +rm positions.nc +rm positions.m +rm surface.nc +rm spec.nc diff --git a/examples/particle_trajectories/straightLine/2Dgeom/gold/history.nc b/examples/particle_trajectories/straightLine/2Dgeom/gold/history.nc new file mode 100644 index 00000000..de689728 Binary files /dev/null and b/examples/particle_trajectories/straightLine/2Dgeom/gold/history.nc differ diff --git a/examples/particle_trajectories/straightLine/2Dgeom/gold/particleSource.nc b/examples/particle_trajectories/straightLine/2Dgeom/gold/particleSource.nc new file mode 100644 index 00000000..489c669e Binary files /dev/null and b/examples/particle_trajectories/straightLine/2Dgeom/gold/particleSource.nc differ diff --git a/examples/particle_trajectories/straightLine/2Dgeom/gold/positions.m b/examples/particle_trajectories/straightLine/2Dgeom/gold/positions.m new file mode 100644 index 00000000..7b92253b --- /dev/null +++ b/examples/particle_trajectories/straightLine/2Dgeom/gold/positions.m @@ -0,0 +1 @@ +Pos( 1,:) = [ -3.29356 1.79356 1.55315e-16 ]; diff --git a/examples/particle_trajectories/straightLine/2Dgeom/gold/positions.nc b/examples/particle_trajectories/straightLine/2Dgeom/gold/positions.nc new file mode 100644 index 00000000..1abbcd9a Binary files /dev/null and b/examples/particle_trajectories/straightLine/2Dgeom/gold/positions.nc differ diff --git a/examples/particle_trajectories/straightLine/2Dgeom/input/ADAS_Rates_W.nc b/examples/particle_trajectories/straightLine/2Dgeom/input/ADAS_Rates_W.nc new file mode 100644 index 00000000..1abc88c3 Binary files /dev/null and b/examples/particle_trajectories/straightLine/2Dgeom/input/ADAS_Rates_W.nc differ diff --git a/examples/particle_trajectories/straightLine/2Dgeom/input/answer.cfg b/examples/particle_trajectories/straightLine/2Dgeom/input/answer.cfg new file mode 100644 index 00000000..656a03ab --- /dev/null +++ b/examples/particle_trajectories/straightLine/2Dgeom/input/answer.cfg @@ -0,0 +1,8 @@ +answer = +{ + x=1.5; + y=0.0; + z=1.0; + r=1.5; + charge=0; +} diff --git a/examples/particle_trajectories/straightLine/2Dgeom/input/gitrGeometry.cfg b/examples/particle_trajectories/straightLine/2Dgeom/input/gitrGeometry.cfg new file mode 100644 index 00000000..8786791f --- /dev/null +++ b/examples/particle_trajectories/straightLine/2Dgeom/input/gitrGeometry.cfg @@ -0,0 +1,22 @@ +geom = +{ + x1 = [1.0,2.0,2.0,1.0]; + z1 = [0.0,0.0,1.0,1.0]; + x2 = [2.0,2.0,1.0,1.0]; + z2 = [0.0,1.0,1.0,0.0]; + slope = [0.0,1000000000000.0,0.0,-1000000000000.0]; + intercept = [0.0,1000000000000.0,1.0,1000000000000.0]; + length = [1.0,1.0,1.0,1.0]; + Z = [74.0,74.0,74.0,74.0,0.0]; + surface = [1, 1, 1, 1, 1]; + potential= [0, 0, 0, 0]; + inDir = [-1, 1, 1, 1, 1]; + y1 = -1.0; + y2 = 1.0; + periodic = 0; + theta0 = 0.0; + theta1 = 0.0; + periodic_bc_x0 = -10000.0; + periodic_bc_x1 = 100000.0; + periodic_bc_x = 0; +} diff --git a/examples/particle_trajectories/straightLine/2Dgeom/input/gitrInput.cfg b/examples/particle_trajectories/straightLine/2Dgeom/input/gitrInput.cfg new file mode 100755 index 00000000..691302f3 --- /dev/null +++ b/examples/particle_trajectories/straightLine/2Dgeom/input/gitrInput.cfg @@ -0,0 +1,443 @@ +geometry = +{ + fileString = "gitrGeometry.cfg"; +} +backgroundPlasmaProfiles = +{ + Z = 1.0; + amu = 2.0; + biasPotential = 0.0; + + Bfield = + { + r = 0.0; + z = -0.08; + y = 0.0; + fileString = "ar2Input.nc"; + gridNrString = "nR"; + gridNyString = "nY"; + gridNzString = "nZ"; + gridRString = "r"; + gridYString = "y"; + gridZString = "z"; + radialComponentString = "br"; + axialComponentString = "bz"; + toroidalComponentString = "bt"; + } + Efield = + { + Er = 0.0; + Ez = -10000.0; + Et = 0.0; + fileString = "LcS.nc"; + gridNrString = "nR"; + gridNyString = "nY"; + gridNzString = "nZ"; + gridRString = "gridR"; + gridYString = "gridY"; + gridZString = "gridZ"; + radialComponentString = "PSEr"; + axialComponentString = "PSEz"; + toroidalComponentString = "PSEt"; + } + dtsEfield = + { + dtsEr = 0.0; + dtsEz = 0.0; + dtsEt = 0.0; + fileString = "profiles.nc"; + gridNrString = "n_r_sheathDTS"; + gridNzString = "n_z_sheathDTS"; + gridRString = "gridRsheathDTS"; + gridZString = "gridZsheathDTS"; + sheathDTS = "sheathDTS"; + } + Temperature = + { + ti = 4.0; + te = 4.0; + fileString = "profiles.nc"; + gridNrString = "nX_t"; + gridNzString = "nZ_t"; + gridRString = "gridx_t"; + gridZString = "gridz_t"; + IonTempString = "ti"; + ElectronTempString = "te"; + } + Density = + { + ni = 7.0E+17; + ne = 7.0E+17; + fileString = "profiles.nc"; + gridNrString = "nX_n"; + gridNzString = "nZ_n"; + gridRString = "gridx_n"; + gridZString = "gridz_n"; + IonDensityString = "ni"; + ElectronDensityString = "ne"; + } + Diffusion = + { + Dperp = 0.1; + fileString = "profiles.nc"; + gridNrString = "n_x"; + gridNzString = "n_z"; + gridRString = "gridx"; + gridZString = "gridz"; + variableString = "ni"; + } + FlowVelocity = + { + interpolatorNumber = 0; + flowVr = 0.0; + flowVy = 0.0; + flowVz = -200000.0; + fileString = "LcS.nc"; + gridNrString = "nR"; + gridNyString = "nY"; + gridNzString = "nZ"; + gridRString = "gridR"; + gridYString = "gridY"; + gridZString = "gridZ"; + flowVrString = "flowVr"; + flowVzString = "flowVz"; + flowVtString = "flowVt"; + } + ConnectionLength = + { + interpolatorNumber = 2; + Lc = 10.0; + s = 1.0; + fileString = "LcS.nc"; + gridNrString = "nR"; + gridNyString = "nY"; + gridNzString = "nZ"; + gridRString = "gridR"; + gridYString = "gridY"; + gridZString = "gridZ"; + LcString = "Lc"; + SString = "s"; + } + gradT = + { + gradTeR = 0.0; + gradTeY = 0.0; + gradTeZ = 0.0; + gradTiR = 0.0; + gradTiY = 0.0; + gradTiZ = 0.0; + fileString = "profiles.nc"; + gridNrString = "nX_gradTi"; + gridNzString = "nZ_gradTi"; + gridRString = "gridx_gradTi"; + gridZString = "gridz_gradTi"; + gradTiRString = "gradTiR"; + gradTiZString = "gradTiZ"; + gradTeRString = "gradTeR"; + gradTeZString = "gradTeZ"; + } + Lc = + { + value = 1.0; + fileString = "profiles.nc"; + gridNrString = "nX_Lc"; + gridNzString = "nY_Lc"; + gridRString = "gridx_Lc"; + gridZString = "gridy_Lc"; + variableString = "Lc"; + } + s = + { + value = 1.0; + fileString = "profiles.nc"; + gridNrString = "nX_s"; + gridNzString = "nY_s"; + gridRString = "gridx_s"; + gridZString = "gridy_s"; + variableString = "s"; + } +} +connectionLength = +{ + nTraceSteps = 5000; + dr = 0.0001; + netx0 = -0.076; + netx1 = 0.076; + nX = 80; + nety0 = -0.076; + nety1 = 0.076; + nY = 70; + netz0 = -0.05; + netz1 = 0.2; + nZ = 100; + fileString = "LcS.nc"; + gridNrString = "nR"; + gridNyString = "nY"; + gridNzString = "nZ"; + gridRString = "gridR"; + gridYString = "gridY"; + gridZString = "gridZ"; + LcString = "Lc"; + SString = "s"; + noIntersectionString = "noIntersection"; +} +impurityParticleSource = +{ + nP = 1; + sourceStrength = 1E+19; + Z = 74.0; + source_material_Z = 74; + source_material_SurfaceBindingEnergy = 11.75; + + initialConditions = + { + x_start = -1.5; + y_start = 0.0; + z_start = 0.0; + energy_eV_x_start = 6.0; + energy_eV_y_start = 0.0; + energy_eV_z_start = 6.0; + impurity_amu = 12.0; + impurity_Z = 6.0; + charge = 0.0; + energy_eV=10.0; + phi = 90.0; + theta = 135.0; + } + ionization = + { + fileString = "ADAS_Rates_W.nc"; + TempGridString = "n_Temperatures_Ionize"; + DensGridString = "n_Densities_Ionize"; + nChargeStateString = "n_ChargeStates_Ionize"; + TempGridVarName = "gridTemperature_Ionization"; + DensGridVarName = "gridDensity_Ionization"; + CoeffVarName = "IonizationRateCoeff"; + } + + recombination = + { + fileString = "ADAS_Rates_W.nc"; + TempGridString = "n_Temperatures_Recombine"; + DensGridString = "n_Densities_Recombine"; + nChargeStateString = "n_ChargeStates_Recombine"; + TempGridVarName = "gridTemperature_Recombination"; + DensGridVarName = "gridDensity_Recombination"; + CoeffVarName = "RecombinationRateCoeff"; + } +} + +timeStep = +{ + dt = 1E-5; + nPtsPerGyroOrbit = 10000.0; + ionization_nDtPerApply = 1; + collision_nDtPerApply = 5; + nT = 20; +} +geometry_hash = +{ + fileString = "profiles.nc"; + gridNrString = "nX_hash"; + gridNyString = "nY_hash"; + gridNzString = "nZ_hash"; + nearestNelementsString = "nN_hash"; + gridRString = "gridx_hash"; + gridYString = "gridy_hash"; + gridZString = "gridz_hash"; + closeGeomString = "geomHash3d"; +} + +geometry_sheath = +{ + fileString = "profiles.nc"; + gridNrString = "nX_hash_sheath"; + gridNyString = "nY_hash_sheath"; + gridNzString = "nZ_hash_sheath"; + nearestNelementsString = "nN_hash_sheath"; + gridRString = "gridx_hash_sheath"; + gridYString = "gridy_hash_sheath"; + gridZString = "gridz_hash_sheath"; + closeGeomString = "geomHash3d_sheath"; +} +surfaces = +{ + useMaterialSurfaces=1; + flux = + { + nE=200; + E0 = 0.0; + E = 1000.0; + nA = 30; + A0 = 0.0; + A = 90.0; + } +} +volumeDefinition = +{ + xMinV = -0.02; + xMaxV = +0.02; + + grid = + { + nXv = 100; + nYv = 150; + nZv = 150; + } +} + +surfaceDefinition = +{ + yMin = -0.03; + yMax = 0.03; + zMin = -0.03; + zMax = 0.03; + + grid = + { + nY = 150; + nZ = 150; + } + + planeParameterization = + { + surface_dz_dx = 1.73205; + surface_zIntercept = 0.0; + } +} + +bField = +{ + interpolatorNumber = 0; + Bx_in = 0.00; + By_in = 0.00; + Bz_in = -2.0; + connectionLength = 50.0; +} + +eField = +{ + interpolatorNumber = 2; +} + +perpDiffusion = +{ + interpolatorNumber = 0; + perDiffusionCoeff_in = 0.0; +} + +backgroundPlasma = +{ + Z = [-1, 1]; + amu = [5.446e-4, 2.0]; + + temp = + { + interpolatorNumber = 0; + max = [20.0, 20.0]; + tempSOLDecayLength = (1E+04,1E+04); + } + + density = + { + interpolatorNumber = 0; + max = [1e19, 1e19]; + densitySOLDecayLength = (1E+04, 1E+04); + } + + flow = + { + interpolatorNumber = 0; + fractionOfThermalVelocity = [ 0.0, 0.0]; + } +} + +diagnostics = +{ + trackSubSampleFactor=1; + leakZ = 0.0; + netx0 = -0.08; + netx1 = 0.08; + nX = 100; + nety0 = -0.1; + nety1 = 0.1; + nY = 120; + netz0 = -0.05; + netz1 = 0.2; + nZ = 150; + densityChargeBins = 5; +} + +operators = +{ + boris = + { seed = 1.25E+5; + } + ionization = + { seed = 2.05E+5; + } + recombination = + { seed = 3.15E+5; + } + perpDiffusion = + { seed = 4.35E+5; + } + coulombCollisions = + { seed1 = 5.45E+5; + seed2 = 7.84E+5; + seed3 = 8.90E+5; + } + surfaceModel = + { seed = 6.55E+5; + } +} +flags = +{ + USE_CUDA=1; + USEMPI=0; + USE_MPI=0; + USE_OPENMP=0; + USE_BOOST=1; + USEIONIZATION=0; + USE_IONIZATION=0; + USERECOMBINATION=0; + USEPERPDIFFUSION=0; + USECOULOMBCOLLISIONS=0; + USETHERMALFORCE=0; + USESURFACEMODEL=0; + USESHEATHEFIELD=0; + BIASED_SURFACE=0; + USEPRESHEATHEFIELD=0; + BFIELD_INTERP=0; + LC_INTERP=0; + GENERATE_LC=0; + EFIELD_INTERP=0; + PRESHEATH_INTERP=0; + DENSITY_INTERP=0; + TEMP_INTERP=0; + FLOWV_INTERP=0; + GRADT_INTERP=0; + ODEINT=0; + FIXEDSEEDS=1; + FIXED_SEEDS=1; + PARTICLESEEDS=1; + GEOM_TRACE=0; + GEOM_HASH=0; + GEOM_HASH_SHEATH=0; + PARTICLE_TRACKS=1; + PARTICLE_SOURCE_SPACE=0; + PARTICLE_SOURCE_ENERGY=0; + PARTICLE_SOURCE_ANGLE=0; + PARTICLE_SOURCE_FILE=0; + SPECTROSCOPY=0; + USE3DTETGEOM=0; + USECYLSYMM=0; + USEFIELDALIGNEDVALUES=0; + FLUX_EA=0; + FORCE_EVAL=0; + CHECK_COMPATIBILITY=1; + USE_ADAPTIVE_DT=0; + USE_SORT=0; + USE_SURFACE_POTENTIAL=0; +} + diff --git a/examples/particle_trajectories/straightLine/2Dgeom/input/particleSource.cfg b/examples/particle_trajectories/straightLine/2Dgeom/input/particleSource.cfg new file mode 100644 index 00000000..8a714852 --- /dev/null +++ b/examples/particle_trajectories/straightLine/2Dgeom/input/particleSource.cfg @@ -0,0 +1,14 @@ +particleSource = +{ + nSources = 1; + nSegments = 64; + nSegmentsAngle = 100; + cylSymm = 1; + r0 = [0.000000,0.025000 ] + z0 = [1.00E-06,1.00E-06 ] + r = [0.000000,0.000768,0.001535,0.002303,0.003071,0.003838,0.004606,0.005374,0.006141,0.006909,0.007677,0.008444,0.009212,0.009980,0.010747,0.011515,0.012283,0.013051,0.013818,0.014586,0.015354,0.016121,0.016889,0.017657,0.018424,0.019192,0.019960,0.020727,0.021495,0.022263,0.023030,0.023798,0.024566,0.025333,0.026101,0.026869,0.027636,0.028404,0.029172,0.029939,0.030707,0.031475,0.032242,0.033010,0.033778,0.034545,0.035313,0.036081,0.036848,0.037616,0.038384,0.039152,0.039919,0.040687,0.041455,0.042222,0.042990,0.043758,0.044525,0.045293,0.046061,0.046828,0.047596,0.048364 ] + z = [0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,0.000001 ] + angles = [0.000000,0.015867,0.031733,0.047600,0.063467,0.079333,0.095200,0.111066,0.126933,0.142800,0.158666,0.174533,0.190400,0.206266,0.222133,0.237999,0.253866,0.269733,0.285599,0.301466,0.317333,0.333199,0.349066,0.364932,0.380799,0.396666,0.412532,0.428399,0.444266,0.460132,0.475999,0.491866,0.507732,0.523599,0.539465,0.555332,0.571199,0.587065,0.602932,0.618799,0.634665,0.650532,0.666398,0.682265,0.698132,0.713998,0.729865,0.745732,0.761598,0.777465,0.793331,0.809198,0.825065,0.840931,0.856798,0.872665,0.888531,0.904398,0.920265,0.936131,0.951998,0.967864,0.983731,0.999598,1.015464,1.031331,1.047198,1.063064,1.078931,1.094797,1.110664,1.126531,1.142397,1.158264,1.174131,1.189997,1.205864,1.221730,1.237597,1.253464,1.269330,1.285197,1.301064,1.316930,1.332797,1.348664,1.364530,1.380397,1.396263,1.412130,1.427997,1.443863,1.459730,1.475597,1.491463,1.507330,1.523196,1.539063,1.554930,1.570796 ] + spaceCDF = [0.000000,0.064903,0.127199,0.186922,0.244110,0.298800,0.351027,0.400832,0.448251,0.493325,0.536093,0.576596,0.614874,0.650970,0.684927,0.716789,0.746600,0.774405,0.800253,0.824189,0.846264,0.866528,0.885033,0.901832,0.916980,0.930533,0.942552,0.953098,0.962234,0.970027,0.976548,0.981871,0.986076,0.989246,0.991475,0.992865,0.993528,0.993855,0.994175,0.994487,0.994792,0.995090,0.995382,0.995667,0.995945,0.996217,0.996483,0.996743,0.996997,0.997245,0.997487,0.997724,0.997956,0.998182,0.998403,0.998619,0.998830,0.999037,0.999238,0.999435,0.999628,0.999816,1.000000,1.000180 ] + angleCDF = [0.000000,0.031482,0.047216,0.062941,0.078651,0.094343,0.110014,0.125659,0.141275,0.156857,0.172401,0.187904,0.203361,0.218770,0.234125,0.249423,0.264661,0.279834,0.294938,0.309970,0.324927,0.339803,0.354595,0.369301,0.383915,0.398435,0.412857,0.427176,0.441390,0.455495,0.469487,0.483363,0.497119,0.510752,0.524258,0.537635,0.550878,0.563984,0.576951,0.589774,0.602450,0.614977,0.627352,0.639570,0.651629,0.663526,0.675258,0.686822,0.698215,0.709434,0.720477,0.731340,0.742021,0.752518,0.762827,0.772945,0.782872,0.792603,0.802136,0.811470,0.820601,0.829528,0.838248,0.846758,0.855058,0.863144,0.871015,0.878669,0.886104,0.893317,0.900308,0.907074,0.913613,0.919925,0.926006,0.931857,0.937475,0.942859,0.948008,0.952920,0.957594,0.962029,0.966224,0.970178,0.973889,0.977357,0.980581,0.983561,0.986294,0.988781,0.991022,0.993015,0.994759,0.996256,0.997503,0.998502,0.999251,0.999750,1.000000,1.000000 ] + } \ No newline at end of file diff --git a/examples/particle_trajectories/straightLine/2Dgeom/untitled.png b/examples/particle_trajectories/straightLine/2Dgeom/untitled.png new file mode 100644 index 00000000..6e33a1c8 Binary files /dev/null and b/examples/particle_trajectories/straightLine/2Dgeom/untitled.png differ diff --git a/examples/particle_trajectories/straightLine/README.md b/examples/particle_trajectories/straightLine/README.md new file mode 100644 index 00000000..b41a7fc0 --- /dev/null +++ b/examples/particle_trajectories/straightLine/README.md @@ -0,0 +1,138 @@ +# Straight Line Particle Track Tests/Examples +The straight line (neutral particle streaming) tests are formulated in order +to test geometry operations during development to make sure things don't break. +This makes up a handful of tests to see when/where particles intersec the surface +for different geometry types. These geometry types include: +1. 2Dgeom - 2D cube geometry bounded in the 3rd dimension +2. 2D cube geometry periodic in the 3rd dimension +3. 2DgeomCyl - square geometry cylindrical +4. 3Dgeom - 3D cube geometry +5. 3D geometry intersection with a vertex +6. 2D DIII-D geometry cylindrical +7. 2D DIII-D geometry cylindrical using hash +8. 3D DIII-D geometry using hash + +## Input File and Particle Initial Conditions +with the flags for ionization off, most of the operators will not be applied, keep them off +the particle source energy angle file =0 so it is a point source +So our most relevant section of the input file is the initial conditions section: +``` +#input/gitrInput.cfg +. +. +. +impurityParticleSource = +{ + nP = 1; + sourceStrength = 1E+19; + Z = 74.0; + source_material_Z = 74; + source_material_SurfaceBindingEnergy = 11.75; + + initialConditions = + { + x_start = 1.5; + y_start = 0.0; + z_start = 0.0000000001; + energy_eV_x_start = 6.0; + energy_eV_y_start = 0.0; + energy_eV_z_start = 6.0; + impurity_amu = 12.0; + impurity_Z = 6.0; + charge = 0.0; + energy_eV=10.0; + phi = 0.0; + theta = 0.0; + } + + +. +. +. +timeStep = +{ + dt = 1E-5; + nPtsPerGyroOrbit = 10000.0; + ionization_nDtPerApply = 1; + collision_nDtPerApply = 5; + nT = 1; +} +``` + +## 2D Geometry Setup and File Structure +The GITR 2D geometries are made up of a collection of lines in the x-z plane which are then +applied in 3D space with one of the following: +1. Bounded in the y direction (2 planes in the x-z plane) +2. Periodic in the y direction +3. Periodic in the theta direction (where the lines are in the r-z plane) + +An example geometry cfg file used for the 2D geometry is shown below: +``` +#2Dgeom/input/gitrGeometry.cfg +geom = +{ + x1 = [1.0,2.0,2.0,1.0] + z1 = [0.0,0.0,1.0,1.0] + x2 = [2.0,2.0,1.0,1.0] + z2 = [0.0,1.0,1.0,0.0] + slope = [0.0,1000000000000.0,0.0,-1000000000000.0] + intercept = [0.0,1000000000000.0,1.0,1000000000000.0] + length = [1.0,1.0,1.0,1.0] + Z = [74.0,74.0,74.0,74.0,0.0] + y1 = -1.0; + y2 = 1.0; + periodic = 0; +} + +``` +The end points of the lines are shown to make up 4 lines: +(1,0) to (2,0) - slope and intercept of 0 length of 1 +(2,0) to (2,1) - large slope and intercept (vertical line approximation) +(2,1) to (1,1) - zero slope and intercept of 1 +(1,1) to (1,0) - large negative slope and intercept (vertical line approximation) + +The material Z has one more element than lines to describe the material of bounding plane in the y direction. +y1 and y2 can describe the bounds in either y or theta depending on whether the geometry is being used in the cylindrical application or not. + +periodic=1 is on and periodic=0 is off. + +## 3D Geometry Setup and File Structure +The GITR 3D geometries are made up of a collection of triangles in 3D space. For the 3D geometries, several coefficients are pre-computed and stored in the geometry file. + +An example geometry cfg file used for the 3D geometry is shown below: +``` +#3Dgeom/input/gitrGeometry.cfg +geom = +{ + x1 = [1.0,1.0,1.0,1.0,2.0,2.0,1.0,1.0,1.0,1.0,1.0,1.0 ] + y1 = [-1.0e-1,-1.0e-1,1.0e-1,1.0e-1,-1.0e-1,-1.0e-1,-1.0e-1,-1.0e-1,-1.0e-1,-1.0e-1,-1.0e-1,-1.0e-1 ] + z1 = [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,0.0,0.0 ] + x2 = [2.0,1.0,2.0,1.0,2.0,2.0,1.0,1.0,2.0,1.0,2.0,1.0 ] + y2 = [-1.0e-1,-1.0e-1,1.0e-1,1.0e-1,1.0e-1,-1.0e-1,1.0e-1,-1.0e-1,-1.0e-1,1.0e-1,-1.0e-1,1.0e-1 ] + z2 = [0.0,1.0,0.0,1.0,0.0,1.0,0.0,0.0,1.0,1.0,0.0,0.0 ] + x3 = [2.0,2.0,2.0,2.0,2.0,2.0,1.0,1.0,2.0,2.0,2.0,2.0 ] + y3 = [-1.0e-1,-1.0e-1,1.0e-1,1.0e-1,1.0e-1,1.0e-1,1.0e-1,1.0e-1,1.0e-1,1.0e-1,1.0e-1,1.0e-1 ] + z3 = [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0 ] + a = [0.0,0.0,0.0,0.0,2.0e-1,-2.0e-1,2.0e-1,0.0,0.0,0.0,0.0,0.0 ] + b = [-1.0,1.0,-1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 ] + c = [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0e-1,-2.0e-1,2.0e-1,-2.0e-1 ] + d = [-1.0e-1,1.0e-1,1.0e-1,-1.0e-1,-4.0e-1,4.0e-1,-2.0e-1,-0.0,-2.0e-1,2.0e-1,-0.0,-0.0 ] + plane_norm = [1.0,1.0,1.0,1.0,2.0e-1,2.0e-1,2.0e-1,0.0,2.0e-1,2.0e-1,2.0e-1,2.0e-1 ] + BCxBA = [1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,1.0,1.0,1.0,1.0 ] + CAxCB = [1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,1.0,1.0,1.0,1.0 ] + area = [5.0e-1,5.0e-1,5.0e-1,5.0e-1,1.0e-1,1.0e-1,1.0e-1,0.0,1.0e-1,1.0e-1,1.0e-1,1.0e-1 ] + Z = [23.0,23.0,23.0,23.0,23.0,23.0,23.0,23.0,23.0,23.0,23.0,23.0 ] + theta0=0.0; + theta1=0.0; + periodic=0; +} +} +``` +The three vertices of each triangle are made up by (x1,y1,z1), (x2,y2,z2), (x3,y3,z3) corresponding to the vectors A,B,C. This makes up the geometry shown below. +3dgeom.png + +The coefficients a,b,c, and d correspond to the plane equation for each triangle ax+by+cz+d=0 and plane_norm = sqrt(a^2 + b^2 + c^2) + +BCxBA and CAxCB are the sign of the cross product of these vectors. This helps give the code a relative direction of the triangle normal and parallel directions. + +periodic=1 is on and periodic=0 is off. diff --git a/examples/particle_trajectories/user_options.cmake b/examples/particle_trajectories/user_options.cmake new file mode 100644 index 00000000..dadd8d66 --- /dev/null +++ b/examples/particle_trajectories/user_options.cmake @@ -0,0 +1,96 @@ +# Anti-pattern: build-time options - these will be converted to runtime options in the future + +# String description for each option +set( description "(no description added - see define_options.cmake)" ) +set( GITR_USE_CUDA 1 CACHE STRING "${description}" ) +set( GITR_USE_MPI 0 CACHE STRING "${description}" ) +set( GITR_USE_DOUBLE 1 CACHE STRING "${description}" ) +set( GITR_USE_IONIZATION 0 CACHE STRING "${description}" ) # if ionization is on, recombination on +set( GITR_USE_RECOMBINATION 0 CACHE STRING "${description}" ) +set( GITR_USE_PERP_DIFFUSION 0 CACHE STRING "${description}" ) +set( GITR_USE_COULOMB_COLLISIONS 0 CACHE STRING "${description}" ) # if collisions are on, friction, scattering, heating +set( GITR_USE_FRICTION 0 CACHE STRING "${description}" ) +set( GITR_USE_ANGLE_SCATTERING 0 CACHE STRING "${description}" ) +set( GITR_USE_HEATING 0 CACHE STRING "${description}" ) +set( GITR_USE_THERMAL_FORCE 0 CACHE STRING "${description}" ) +set( GITR_USE_SURFACE_MODEL 0 CACHE STRING "${description}" ) +set( GITR_USE_SHEATH_EFIELD 0 CACHE STRING "${description}" ) +set( GITR_BIASED_SURFACE 0 CACHE STRING "${description}" ) +set( GITR_USE_SURFACE_POTENTIAL 0 CACHE STRING "${description}" ) +set( GITR_USE_PRE_SHEATH_EFIELD 0 CACHE STRING "${description}" ) +set( GITR_BFIELD_INTERP 0 CACHE STRING "${description}" ) +set( GITR_LC_INTERP 0 CACHE STRING "${description}" ) +set( GITR_GENERATE_LC 0 CACHE STRING "${description}" ) +set( GITR_EFIELD_INTERP 0 CACHE STRING "${description}" ) +set( GITR_PRE_SHEATH_INTERP 0 CACHE STRING "${description}" ) +set( GITR_DENSITY_INTERP 0 CACHE STRING "${description}" ) +set( GITR_TEMP_INTERP 0 CACHE STRING "${description}" ) +set( GITR_FLOWV_INTERP 0 CACHE STRING "${description}" ) +set( GITR_GRADT_INTERP 0 CACHE STRING "${description}" ) +set( GITR_ODE_INT 0 CACHE STRING "${description}" ) +set( GITR_FIXED_SEEDS 1 CACHE STRING "${description}" ) +set( GITR_PARTICLE_SEEDS 1 CACHE STRING "${description}" ) +set( GITR_GEOM_TRACE 0 CACHE STRING "${description}" ) +set( GITR_GEOM_HASH 0 CACHE STRING "${description}" ) +set( GITR_GEOM_HASH_SHEATH 0 CACHE STRING "${description}" ) +set( GITR_PARTICLE_TRACKS 1 CACHE STRING "${description}" ) +set( GITR_PARTICLE_SOURCE 0 CACHE STRING "${description}" ) +set( GITR_PARTICLE_SOURCE_SPACE 0 CACHE STRING "${description}" ) +set( GITR_PARTICLE_SOURCE_ENERGY 0 CACHE STRING "${description}" ) +set( GITR_PARTICLE_SOURCE_ANGLE 0 CACHE STRING "${description}" ) +set( GITR_PARTICLE_SOURCE_FILE 0 CACHE STRING "${description}" ) +set( GITR_SPECTROSCOPY 0 CACHE STRING "${description}" ) +set( GITR_USE_3DTET_GEOM 0 CACHE STRING "${description}" ) +set( GITR_USE_CYLSYMM 0 CACHE STRING "${description}" ) +set( GITR_USE_FIELD_ALIGNED_VALUES 0 CACHE STRING "${description}" ) +set( GITR_FLUX_EA 0 CACHE STRING "${description}" ) +set( GITR_FORCE_EVAL 0 CACHE STRING "${description}" ) +set( GITR_USE_SORT 0 CACHE STRING "${description}" ) +set( GITR_CHECK_COMPATIBILITY 1 CACHE STRING "${description}" ) + +add_compile_definitions( + USE_CUDA=${GITR_USE_CUDA} + USE_MPI=${GITR_USE_MPI} + USE_DOUBLE=${GITR_USE_DOUBLE} + USEIONIZATION=${GITR_USE_IONIZATION} + USERECOMBINATION=${GITR_USE_RECOMBINATION} + USEPERPDIFFUSION=${GITR_USE_PERP_DIFFUSION} + USECOULOMBCOLLISIONS=${GITR_USE_COULOMB_COLLISIONS} + USEFRICTION=${GITR_USE_FRICTION} + USEANGLESCATTERING=${GITR_USE_ANGLE_SCATTERING} + USEHEATING=${GITR_USE_HEATING} + USETHERMALFORCE=${GITR_USE_THERMAL_FORCE} + USESURFACEMODEL=${GITR_USE_SURFACE_MODEL} + USESHEATHEFIELD=${GITR_USE_SHEATH_EFIELD} + BIASED_SURFACE=${GITR_BIASED_SURFACE} + USE_SURFACE_POTENTIAL=${GITR_USE_SURFACE_POTENTIAL} + USEPRESHEATHEFIELD=${GITR_USE_PRE_SHEATH_EFIELD} + BFIELD_INTERP=${GITR_BFIELD_INTERP} + LC_INTERP=${GITR_LC_INTERP} + GENERATE_LC=${GITR_GENERATE_LC} + EFIELD_INTERP=${GITR_EFIELD_INTERP} + PRESHEATH_INTERP=${GITR_PRE_SHEATH_INTERP} + DENSITY_INTERP=${GITR_DENSITY_INTERP} + TEMP_INTERP=${GITR_TEMP_INTERP} + FLOWV_INTERP=${GITR_FLOWV_INTERP} + GRADT_INTERP=${GITR_GRADT_INTERP} + ODEINT=${GITR_ODE_INT} + FIXEDSEEDS=${GITR_FIXED_SEEDS} + PARTICLESEEDS=${GITR_PARTICLE_SEEDS} + GEOM_TRACE=${GITR_GEOM_TRACE} + GEOM_HASH=${GITR_GEOM_HASH} + GEOM_HASH_SHEATH=${GITR_GEOM_HASH_SHEATH} + PARTICLE_TRACKS=${GITR_PARTICLE_TRACKS} + PARTICLE_SOURCE=${GITR_PARTICLE_SOURCE} + PARTICLE_SOURCE_SPACE=${GITR_PARTICLE_SOURCE_SPACE} + PARTICLE_SOURCE_ENERGY=${GITR_PARTICLE_SOURCE_ENERGY} + PARTICLE_SOURCE_ANGLE=${GITR_PARTICLE_SOURCE_ANGLE} + PARTICLE_SOURCE_FILE=${GITR_PARTICLE_SOURCE_FILE} + SPECTROSCOPY=${GITR_SPECTROSCOPY} + USE3DTETGEOM=${GITR_USE_3DTET_GEOM} + USECYLSYMM=${GITR_USE_CYLSYMM} + USEFIELDALIGNEDVALUES=${GITR_USE_FIELD_ALIGNED_VALUES} + FLUX_EA=${GITR_FLUX_EA} + FORCE_EVAL=${GITR_FORCE_EVAL} + USE_SORT=${GITR_USE_SORT} + CHECK_COMPATIBILITY=${GITR_CHECK_COMPATIBILITY}) diff --git a/images/GITR_integration.png b/images/GITR_integration.png deleted file mode 100644 index 3a653c56..00000000 Binary files a/images/GITR_integration.png and /dev/null differ diff --git a/images/TraceImp.png b/images/TraceImp.png deleted file mode 100644 index fe9258e8..00000000 Binary files a/images/TraceImp.png and /dev/null differ diff --git a/include/Boundary.h b/include/Boundary.h index 75c211d2..b565e388 100644 --- a/include/Boundary.h +++ b/include/Boundary.h @@ -60,15 +60,12 @@ class Boundary gitr_precision c; gitr_precision d; gitr_precision plane_norm; //16 - #if USE3DTETGEOM > 0 gitr_precision x3; gitr_precision y3; gitr_precision z3; gitr_precision area; - #else gitr_precision slope_dzdx; gitr_precision intercept_z; - #endif gitr_precision periodic_bc_x0; gitr_precision periodic_bc_x1; gitr_precision Z; @@ -101,38 +98,49 @@ class Boundary gitr_precision unit_vec2; CUDA_CALLABLE_MEMBER - void getSurfaceParallel(gitr_precision A[],gitr_precision y,gitr_precision x) + void getSurfaceParallel(gitr_precision A[],gitr_precision y,gitr_precision x, + int use_3d_geom, int cylsymm ) + { + gitr_precision norm; + if( use_3d_geom > 0 ) { -#if USE3DTETGEOM > 0 - gitr_precision norm = std::sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1)); + norm = std::sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1)); A[1] = (y2 - y1) / norm; -#else - gitr_precision norm = std::sqrt((x2 - x1) * (x2 - x1) + (z2 - z1) * (z2 - z1)); + } + else + { + norm = std::sqrt((x2 - x1) * (x2 - x1) + (z2 - z1) * (z2 - z1)); A[1] = 0.0; -#endif + } //std::cout << "surf par calc " << x2 << " " << x1 << " " << norm << std::endl; A[0] = (x2-x1)/norm; A[2] = (z2-z1)/norm; -#if USE3DTETGEOM > 0 -#else -#if USECYLSYMM > 0 + + if( use_3d_geom <= 0 ) + { + if( cylsymm > 0 ) + { gitr_precision theta = std::atan2(y, x); gitr_precision B[3] = {0.0}; B[0] = std::cos(theta) * A[0] - std::sin(theta) * A[1]; B[1] = std::sin(theta) * A[0] + std::cos(theta) * A[1]; A[0] = B[0]; A[1] = B[1]; -#endif -#endif + } + } } CUDA_CALLABLE_MEMBER - void getSurfaceNormal(gitr_precision B[], gitr_precision y, gitr_precision x) { -#if USE3DTETGEOM > 0 + void getSurfaceNormal(gitr_precision B[], gitr_precision y, gitr_precision x, int use_3d_geom, + int cylsymm ) { + if( use_3d_geom > 0 ) + { B[0] = a / plane_norm; B[1] = b / plane_norm; B[2] = c / plane_norm; -#else + } + else + { gitr_precision perpSlope = 0.0; if (slope_dzdx == 0.0) { perpSlope = 1.0e12; @@ -142,29 +150,33 @@ class Boundary gitr_precision Br = 1.0 / std::sqrt(perpSlope * perpSlope + 1.0); gitr_precision Bt = 0.0; B[2] = std::copysign(1.0,perpSlope) * std::sqrt(1 - Br * Br); -#if USECYLSYMM > 0 + if( cylsymm > 0 ) + { gitr_precision theta = std::atan2(y, x); B[0] = std::cos(theta) * Br - std::sin(theta) * Bt; B[1] = std::sin(theta) * Br + std::cos(theta) * Bt; -#else + } + else + { B[0] = Br; B[1] = Bt; -#endif + } //B[0] = -a/plane_norm; //B[1] = -b/plane_norm; //B[2] = -c/plane_norm; //std::cout << "perp x and z comp " << B[0] << " " << B[2] << std::endl; -#endif + } } CUDA_CALLABLE_MEMBER - void transformToSurface(gitr_precision C[],gitr_precision y, gitr_precision x) + void transformToSurface(gitr_precision C[],gitr_precision y, gitr_precision x, + int use_3d_geom, int cylsymm ) { gitr_precision X[3] = {0.0}; gitr_precision Y[3] = {0.0}; gitr_precision Z[3] = {0.0}; gitr_precision tmp[3] = {0.0}; - getSurfaceParallel(X,y,x); - getSurfaceNormal(Z,y,x); + getSurfaceParallel(X,y,x, use_3d_geom, cylsymm ); + getSurfaceNormal(Z,y,x, use_3d_geom, cylsymm ); Y[0] = Z[1]*X[2] - Z[2]*X[1]; Y[1] = Z[2]*X[0] - Z[0]*X[2]; Y[2] = Z[0]*X[1] - Z[1]*X[0]; @@ -186,7 +198,6 @@ class Boundary // this->x2 = x2; // this->y2 = y2; // this->z2 = z2; -//#if USE3DTETGEOM > 0 //#else // this->slope_dzdx = slope; // this->intercept_z = intercept; diff --git a/include/Particle.h b/include/Particle.h index 27acf7ad..dc5629bf 100644 --- a/include/Particle.h +++ b/include/Particle.h @@ -40,13 +40,11 @@ class Particle { float Z; float amu; float charge; -#if PARTICLESEEDS > 0 #ifdef __CUDACC__ curandState streams[7]; #else std::mt19937 streams[7]; #endif -#endif float hitWall; float transitTime; int wallIndex; diff --git a/include/array.h b/include/array.h index f0545ff9..d791f815 100755 --- a/include/array.h +++ b/include/array.h @@ -56,6 +56,7 @@ namespace sim { if(err != cudaSuccess){ throw std::runtime_error("error allocating managed memory"); } + /* Captain! What are the contents of the "bin" variables in the CUDA vs OpenMP case?? */ return data; #else return new T[capacity_]; @@ -110,9 +111,12 @@ namespace sim { free_data(); } + /* Captain! Is this needed? Delete the copy assignment and copy constructor */ /*! Copy constructor */ - Array(const Array &source) { + Array(const Array &source) = delete; + /* + { capacity_ = source.capacity_; size_ = source.size_; data_ = alloc_data(); @@ -123,8 +127,10 @@ namespace sim { } } } + */ - Array &operator=(const Array &source)// = delete; + Array &operator=(const Array &source) = delete; + /* { for(int i=0;i &source)// = delete; { @@ -236,22 +243,26 @@ namespace sim { /*! Remove element from end of the array * Remove element from end of array by reducing size by 1, element is not destructed */ + /* void pop_back() { if (size_ == 0) throw std::runtime_error("Array popped_back with 0 size"); else size_--; } + */ /*! Remove multiple elements from end of the array * Remove element from end of array by reducing size by 1, element is not destructed */ + /* void pop_back(std::size_t pop_count) { if (size_ == 0 && pop_count != 0) throw std::runtime_error("Array popped_back with 0 size"); else size_ -= pop_count; } + */ /*! Getter for pointer to underlying data */ @@ -331,19 +342,23 @@ void print(std::string const label) /*! begin iterator for range based for loops */ + /* template DEVICE_CALLABLE const T *begin(const Array &array) { return array.data(); } + */ /*! end iterator for range based for loops */ + /* template DEVICE_CALLABLE const T *end(const Array &array) { return array.data() + array.size(); } + */ diff --git a/include/boris.h b/include/boris.h index d636bf67..1e260649 100644 --- a/include/boris.h +++ b/include/boris.h @@ -51,7 +51,9 @@ CUDA_CALLABLE_MEMBER gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, gitr_precision E[], Boundary *boundaryVector, int nLines, int nR_closeGeom, int nY_closeGeom,int nZ_closeGeom, int n_closeGeomElements, gitr_precision *closeGeomGridr,gitr_precision *closeGeomGridy, gitr_precision *closeGeomGridz, int *closeGeom, - int& closestBoundaryIndex); + int& closestBoundaryIndex, int biased_surface, int use_3d_geom, + int geom_hash_sheath, + int cylsymm ); struct move_boris { @@ -89,6 +91,12 @@ struct move_boris { const int nLines; gitr_precision magneticForce[3]; gitr_precision electricForce[3]; + int sheath_efield; + int presheath_efield; + int biased_surface; + int geom_hash_sheath; + int use_3d_geom; + int cylsymm; move_boris(Particles *_particlesPointer, gitr_precision _span, Boundary *_boundaryVector,int _nLines, int _nR_Bfield, int _nZ_Bfield, @@ -104,7 +112,12 @@ struct move_boris { gitr_precision * _EfieldRDevicePointer, gitr_precision * _EfieldZDevicePointer, gitr_precision * _EfieldTDevicePointer, - int _nR_closeGeom, int _nY_closeGeom,int _nZ_closeGeom, int _n_closeGeomElements, gitr_precision *_closeGeomGridr,gitr_precision *_closeGeomGridy, gitr_precision *_closeGeomGridz, int *_closeGeom, Flags* _gitr_flags, gitr_precision _max_dt = 1.0e5); + int _nR_closeGeom, int _nY_closeGeom,int _nZ_closeGeom, int _n_closeGeomElements, gitr_precision *_closeGeomGridr,gitr_precision *_closeGeomGridy, gitr_precision *_closeGeomGridz, int *_closeGeom, Flags* _gitr_flags, int sheath_efield_, int presheath_efield_, + int biased_surface_, + int geom_hash_sheath_, + int use_3d_geom_, + int cylsymm_, + gitr_precision _max_dt = 1.0e5); CUDA_CALLABLE_MEMBER void operator()(std::size_t indx); diff --git a/include/boundaryInit.h b/include/boundaryInit.h index c039ec35..431c3520 100644 --- a/include/boundaryInit.h +++ b/include/boundaryInit.h @@ -44,12 +44,17 @@ struct boundary_init { gitr_precision* bfieldZ; gitr_precision* bfieldT; gitr_precision potential; + int biased_surface; + int surface_potential; + int use_3d_geom; + int cylsymm; boundary_init(gitr_precision _background_Z, gitr_precision _background_amu,int _nx, int _nz, gitr_precision* _densityGridx, gitr_precision* _densityGridz,gitr_precision* _density,gitr_precision* _ne,int _nxB, int _nzB, gitr_precision* _bfieldGridr, gitr_precision* _bfieldGridz,gitr_precision* _bfieldR, gitr_precision* _bfieldZ,gitr_precision* _bfieldT,int _nR_Temp, int _nZ_Temp, - gitr_precision* _TempGridr, gitr_precision* _TempGridz, gitr_precision* _ti, gitr_precision* _te, gitr_precision _potential) + gitr_precision* _TempGridr, gitr_precision* _TempGridz, gitr_precision* _ti, gitr_precision* _te, gitr_precision _potential, int biased_surface_, int surface_potential_, + int use_3d_geom_, int cylsymm_ ) : background_Z(_background_Z), background_amu(_background_amu), @@ -72,31 +77,44 @@ struct boundary_init { bfieldR(_bfieldR), bfieldZ(_bfieldZ), bfieldT(_bfieldT), - potential(_potential) {} + potential(_potential), + biased_surface( biased_surface_ ), + surface_potential( surface_potential_ ), + use_3d_geom( use_3d_geom_ ), + cylsymm( cylsymm_ ) + {} void operator()(Boundary &b) const { -#if USE3DTETGEOM - gitr_precision midpointx = b.x1 + 0.666666667*(b.x2 + 0.5*(b.x3-b.x2)-b.x1); - gitr_precision midpointy = b.y1 + 0.666666667*(b.y2 + 0.5*(b.y3-b.y2)-b.y1); - gitr_precision midpointz = b.z1 + 0.666666667*(b.z2 + 0.5*(b.z3-b.z2)-b.z1); -#else + gitr_precision midpointx; + gitr_precision midpointy; + gitr_precision midpointz; + if( use_3d_geom ) + { + midpointx = b.x1 + 0.666666667*(b.x2 + 0.5*(b.x3-b.x2)-b.x1); + midpointy = b.y1 + 0.666666667*(b.y2 + 0.5*(b.y3-b.y2)-b.y1); + midpointz = b.z1 + 0.666666667*(b.z2 + 0.5*(b.z3-b.z2)-b.z1); + } + else + { - gitr_precision midpointx = 0.5*(b.x2 - b.x1)+ b.x1; - gitr_precision midpointy = 0.0; - gitr_precision midpointz = 0.5*(b.z2 - b.z1) + b.z1; -#endif - b.density = interp2dCombined(midpointx,midpointy,midpointz,nx,nz,densityGridx,densityGridz,density); - b.ne = interp2dCombined(midpointx,midpointy,midpointz,nx,nz,densityGridx,densityGridz,ne); - b.ti = interp2dCombined(midpointx,midpointy,midpointz,nR_Temp,nZ_Temp,TempGridr,TempGridz,ti); - b.te = interp2dCombined(midpointx,midpointy,midpointz,nR_Temp,nZ_Temp,TempGridr,TempGridz,te); + midpointx = 0.5*(b.x2 - b.x1)+ b.x1; + midpointy = 0.0; + midpointz = 0.5*(b.z2 - b.z1) + b.z1; + } + b.density = interp2dCombined(midpointx,midpointy,midpointz,nx,nz,densityGridx,densityGridz,density, cylsymm ); + b.ne = interp2dCombined(midpointx,midpointy,midpointz,nx,nz,densityGridx,densityGridz,ne, cylsymm ); + b.ti = interp2dCombined(midpointx,midpointy,midpointz,nR_Temp,nZ_Temp,TempGridr,TempGridz,ti, cylsymm ); + b.te = interp2dCombined(midpointx,midpointy,midpointz,nR_Temp,nZ_Temp,TempGridr,TempGridz,te, cylsymm ); gitr_precision B[3] = {0.0,0.0,0.0}; interp2dVector(&B[0],midpointx,midpointy,midpointz,nxB,nzB,bfieldGridr, - bfieldGridz,bfieldR,bfieldZ,bfieldT); + bfieldGridz,bfieldR,bfieldZ,bfieldT, cylsymm ); gitr_precision norm_B = vectorNorm(B); -#if USE3DTETGEOM + gitr_precision theta; + if( use_3d_geom ) + { gitr_precision surfNorm[3] = {0.0,0.0,0.0}; - b.getSurfaceNormal(surfNorm,0.0,0.0); - gitr_precision theta = std::acos(vectorDotProduct(B,surfNorm)/(vectorNorm(B)*vectorNorm(surfNorm))); + b.getSurfaceNormal(surfNorm,0.0,0.0, use_3d_geom, cylsymm ); + theta = std::acos(vectorDotProduct(B,surfNorm)/(vectorNorm(B)*vectorNorm(surfNorm))); if (theta > 3.14159265359*0.5) { theta = std::abs(theta - (3.14159265359)); @@ -104,17 +122,19 @@ interp2dVector(&B[0],midpointx,midpointy,midpointz,nxB,nzB,bfieldGridr, b.unit_vec0 = b.inDir*b.a/b.plane_norm; // b.unit_vec1 = b.inDir*b.b/b.plane_norm; // b.unit_vec2 = b.inDir*b.c/b.plane_norm; -#else + } + else + { gitr_precision br = B[0]; gitr_precision bt = B[1]; gitr_precision bz = B[2]; - gitr_precision theta = std::acos((-br*b.slope_dzdx + bz)/(std::sqrt(br*br+bz*bz+bt*bt)*std::sqrt(b.slope_dzdx*b.slope_dzdx + 1.0))); + theta = std::acos((-br*b.slope_dzdx + bz)/(std::sqrt(br*br+bz*bz+bt*bt)*std::sqrt(b.slope_dzdx*b.slope_dzdx + 1.0))); if (theta > 3.14159265359*0.5) { theta = std::acos((br*b.slope_dzdx - bz)/(std::sqrt(br*br+bz*bz+bt*bt)*std::sqrt(b.slope_dzdx*b.slope_dzdx + 1.0))); } -#endif + } b.angle = theta*180.0/3.14159265359; b.debyeLength = std::sqrt(8.854187e-12*b.te/(b.ne*std::pow(background_Z,2)*1.60217662e-19)); //std::cout << "debyeLength " << b.debyeLength << std::endl; @@ -131,7 +151,8 @@ interp2dVector(&B[0],midpointx,midpointy,midpointz,nxB,nzB,bfieldGridr, b.larmorRadius = 1.44e-4*std::sqrt(background_amu*b.ti/2)/(background_Z*norm_B); b.flux = 0.25*b.density*std::sqrt(8.0*b.ti*1.602e-19/(3.1415*background_amu)); b.impacts = 0.0; -#if BIASED_SURFACE + if( biased_surface ) + { b.potential = potential; //gitr_precision cs = std::sqrt(2*b.ti*1.602e-19/(1.66e-27*background_amu)); //gitr_precision jsat_ion = 1.602e-19*b.density*cs; @@ -144,11 +165,13 @@ interp2dVector(&B[0],midpointx,midpointy,midpointz,nxB,nzB,bfieldGridr, else { b.ChildLangmuirDist = 1e12; } -#elif USE_SURFACE_POTENTIAL >0 -#else + } + else if( surface_potential <= 0 ) + { b.potential = sheath_fac*b.te; - std::cout << "Surface number " << b.surfaceNumber << " has te and potential " << b.te << " " << b.potential << std::endl; -#endif + std::cout << "Surface number " << b.surfaceNumber << " has te and potential " + << b.te << " " << b.potential << std::endl; + } //if(b.Z > 0.0) //{ //std::cout << "Boundary ti density potensial and CLdist " < #include #include +#include +#include +#include +#include "config_interface_exceptions.h" #include "libconfig.h++" /* This class wraps the libconfig object and inserts @@ -20,21 +24,80 @@ class libconfig_string_query libconfig_string_query( std::string libconfig_file = "" ); template< typename T > - void operator()( std::string const query_key, T &query_value ) const + void operator()( std::string const query_key, T &query_value ) const; + + template< typename T > + void operator()( std::string const query_key, std::vector< T > &query_values ) const; + + private: + + libconfig::Config cfg; +}; + +template< typename T > +void libconfig_string_query::operator()( std::string const query_key, + std::vector< T > &query_values ) const +{ + assert( query_values.size() == 0 ); + + if( cfg.exists( query_key.c_str() ) == false ) { - bool success = cfg.lookupValue( query_key, query_value ); + throw invalid_key( query_key ); + } - if( success == false ) + auto const &setting = cfg.getRoot().lookup( query_key ); + + /* this should be the local name of the setting */ + std::string setting_name( setting.getName() ); + + /* check for array status */ + if( setting.isArray() ) + { + int len = setting.getLength(); + + for( int i = 0; i < len; i++ ) { - std::cout << "invalid query key: " << query_key << std::endl; - exit(0); + T value = setting[ i ]; + + query_values.push_back( value ); } } - private: + else + { + /* Captain! */ + throw 0; + //throw not_an_array( query_key ); + } +} - libconfig::Config cfg; -}; +template< typename T > +void libconfig_string_query::operator()( std::string const query_key, T &query_value ) const +{ + if( cfg.exists( query_key.c_str() ) == false ) + { + throw invalid_key( query_key ); + } + + auto const &setting = cfg.getRoot().lookup( query_key ); + + if( setting.isArray() ) + { + /* Captain! */ + //throw not_a_scalar( query_key ); + throw 0; + } + + else + { + bool success = cfg.lookupValue( query_key, query_value ); + + if( success == false ) + { + throw lookup_failed( query_key ); + } + } +} class config_module_base { @@ -43,14 +106,14 @@ class config_module_base config_module_base( class libconfig_string_query const &query, std::string module_path = ""); - /* get config sub-module */ - /* default behavior is to return the submodule itself */ template< typename T = std::shared_ptr< class config_module_base > > T get( int key ); template< typename T > void generate_sub_module( int key ); + std::string lookup_key( int key ) { return lookup[ key ]; }; + protected: std::string const &get_module_path() { return module_path; } @@ -69,6 +132,31 @@ class config_module_base class libconfig_string_query const &query; }; +class geometry final : public config_module_base +{ + public: + + enum : int + { + slope, + intercept, + length, + z, + surface, + in_dir, + periodic, + x1, + x2, + y1, + y2, + z1, + z2 + }; + + geometry( class libconfig_string_query const &query, + std::string module_path = "geom" ); +}; + class ionization_process final : public config_module_base { public: @@ -112,22 +200,19 @@ class use final : public config_module_base cuda, use_openmp, mpi, - useionization, - use_ionization, - userecombination, - useperpdiffusion, - usecoulombcollisions, - usefriction, - useanglescattering, - useheating, - usethermalforce, - usesurfacemodel, - usesheathefield, + ionization, + perp_diffusion, + coulomb_collisions, + friction, + angle_scattering, + heating, + thermal_force, + surface_model, + sheath_efield, biased_surface, - usepresheathefield, + presheath_efield, bfield_interp, - lc_interp, - generate_lc, + adaptive_dt, efield_interp, presheath_interp, density_interp, @@ -135,10 +220,8 @@ class use final : public config_module_base flowv_interp, gradt_interp, odeint, - fixedseeds, fixed_seeds, - particleseeds , - geom_trace , + geom_trace, geom_hash, geom_hash_sheath, particle_tracks, @@ -147,14 +230,14 @@ class use final : public config_module_base particle_source_angle, particle_source_file, spectroscopy, - use3dtetgeom, + use_3d_geom, flux_ea, - usecylsymm, - usefieldalignedvalues, + field_aligned_values, force_eval, compatibility_check, - use_sort, - use_adaptive_dt + surface_potential, + cylsymm, + sort }; use( class libconfig_string_query const &query, diff --git a/include/config_interface_exceptions.h b/include/config_interface_exceptions.h new file mode 100644 index 00000000..c38c3941 --- /dev/null +++ b/include/config_interface_exceptions.h @@ -0,0 +1,129 @@ +#include + +class unregistered_config_mapping: public std::exception +{ + public: + + unregistered_config_mapping( int const query_key = -1 ) + : + query_key( query_key ) + { } + + std::string get_key() const { return std::to_string( query_key ); } + + std::string static get_message() { return message; } + + const char* what() const throw() + { + return message.c_str(); + } + + private: + + int const query_key; + + std::string static const inline + message{ "configuration interface error - no mapping exists for key: " }; +}; + +class lookup_failed: public std::exception +{ + public: + + lookup_failed( std::string const query_key ) + : + query_key( query_key ) + { } + + std::string get_key() const { return query_key; } + + std::string static get_message() { return message; } + + const char* what() const throw() + { + return message.c_str(); + } + + private: + + std::string const query_key; + + std::string static const inline + message{ "configuration interface error - lookup failed for registered key: " }; +}; + +class config_exception_base : public std::exception +{ + public: + + config_exception_base() + : + query_key( query_key ) + { } + + std::string get_key() const { return query_key; } + + std::string get_message() const { return message; } + + const char* what() const throw() + { + return message.c_str(); + } + + private: + + std::string const query_key; + + std::string static const inline + message{ "configuration interface error - key not found: " }; +}; + +/* Captain! Use config_base above to make a different message for each type of exception? */ +class invalid_key: public std::exception +{ + public: + + invalid_key( std::string const &query_key ) + : + query_key( query_key ) + { } + + /* Captain! All of these are identical. Template on int vs string for the unregistered + lookups exception and then replace all this repeated code */ + std::string get_key() const { return query_key; } + + std::string static get_message() { return message; } + + const char* what() const throw() + { + return message.c_str(); + } + + private: + + std::string const query_key; + + std::string static const inline + message{ "configuration interface error - key not found: " }; +}; + +/* +class not_an_array : public std::exception +{ + public: + + not_a_scalar( std::string const &query_key ) + : + query_key( query_key ) + { } + + private: +}; + +class not_a_scalar : public std::exception +{ + public: + + private: +}; +*/ diff --git a/include/coulombCollisions.h b/include/coulombCollisions.h index 7eb1b634..d79676db 100644 --- a/include/coulombCollisions.h +++ b/include/coulombCollisions.h @@ -51,7 +51,8 @@ void getSlowDownFrequencies ( gitr_precision& nu_friction, gitr_precision& nu_de int nR_Bfield, int nZ_Bfield, gitr_precision* BfieldGridR ,gitr_precision* BfieldGridZ , gitr_precision* BfieldR ,gitr_precision* BfieldZ , - gitr_precision* BfieldT,gitr_precision &T_background ) + gitr_precision* BfieldT,gitr_precision &T_background, + int flowv_interp, int cylsymm, int field_aligned_values ) { //int feenableexcept(FE_INVALID | FE_OVERFLOW); //enables trapping of the floating-point exceptions gitr_precision Q = 1.60217662e-19; @@ -60,11 +61,14 @@ void getSlowDownFrequencies ( gitr_precision& nu_friction, gitr_precision& nu_de gitr_precision MI = 1.6737236e-27; gitr_precision ME = 9.10938356e-31; - gitr_precision te_eV = interp2dCombined(x,y,z,nR_Temp,nZ_Temp,TempGridr,TempGridz,te); - gitr_precision ti_eV = interp2dCombined(x,y,z,nR_Temp,nZ_Temp,TempGridr,TempGridz,ti); + gitr_precision te_eV = interp2dCombined(x,y,z,nR_Temp,nZ_Temp,TempGridr,TempGridz,te, + cylsymm ); + gitr_precision ti_eV = interp2dCombined(x,y,z,nR_Temp,nZ_Temp,TempGridr,TempGridz,ti, + cylsymm ); T_background = ti_eV; - gitr_precision density = interp2dCombined(x,y,z,nR_Dens,nZ_Dens,DensGridr,DensGridz,ni); + gitr_precision density = interp2dCombined( x,y,z,nR_Dens,nZ_Dens,DensGridr,DensGridz,ni, + cylsymm ); gitr_precision flowVelocity[3]= {0.0}; gitr_precision relativeVelocity[3] = {0.0, 0.0, 0.0}; @@ -96,23 +100,32 @@ void getSlowDownFrequencies ( gitr_precision& nu_friction, gitr_precision& nu_de gitr_precision nu_parallel_e; gitr_precision nu_energy_e; -#if FLOWV_INTERP == 3 + if( flowv_interp == 3 ) + { + exit( 0 ); + /* interp3dVector (&flowVelocity[0], x,y,z,nR_flowV,nY_flowV,nZ_flowV, flowVGridr,flowVGridy,flowVGridz,flowVr,flowVz,flowVt); -#elif FLOWV_INTERP < 3 -#if USEFIELDALIGNEDVALUES > 0 + */ + } + else if( flowv_interp < 3 ) + { + if( field_aligned_values > 0 ) + { interpFieldAlignedVector(&flowVelocity[0],x,y,z, nR_flowV,nZ_flowV, flowVGridr,flowVGridz,flowVr, flowVz,flowVt,nR_Bfield,nZ_Bfield, BfieldGridR,BfieldGridZ,BfieldR, - BfieldZ,BfieldT); -#else + BfieldZ,BfieldT, cylsymm ); + } + else + { interp2dVector(&flowVelocity[0],x,y,z, nR_flowV,nZ_flowV, - flowVGridr,flowVGridz,flowVr,flowVz,flowVt); -#endif -#endif + flowVGridr,flowVGridz,flowVr,flowVz,flowVt, cylsymm ); + } + } relativeVelocity[0] = vx - flowVelocity[0]; relativeVelocity[1] = vy - flowVelocity[1]; relativeVelocity[2] = vz - flowVelocity[2]; @@ -277,6 +290,12 @@ struct coulombCollisions { std::mt19937 *state; #endif + int flowv_interp; + + int cylsymm; + + int field_aligned_values; + coulombCollisions(Particles *_particlesPointer,gitr_precision _dt, #if __CUDACC__ curandState *_state, @@ -293,7 +312,8 @@ struct coulombCollisions { int _nR_Bfield, int _nZ_Bfield, gitr_precision * _BfieldGridR ,gitr_precision * _BfieldGridZ , gitr_precision * _BfieldR ,gitr_precision * _BfieldZ , - gitr_precision * _BfieldT, Flags* _gitr_flags ) + gitr_precision * _BfieldT, Flags* _gitr_flags, int flowv_interp_, + int cylsymm_, int field_aligned_values_ ) : particlesPointer(_particlesPointer), dt(_dt), nR_flowV(_nR_flowV), @@ -327,8 +347,13 @@ struct coulombCollisions { BfieldT(_BfieldT), gitr_flags(_gitr_flags), dv{0.0, 0.0, 0.0}, - state(_state) { - } + state(_state), + flowv_interp( flowv_interp_ ), + cylsymm( cylsymm_ ), + field_aligned_values( field_aligned_values_ ) + + { } + CUDA_CALLABLE_MEMBER_DEVICE void operator()(std::size_t indx) { @@ -361,31 +386,36 @@ void operator()(std::size_t indx) { gitr_precision vy = particlesPointer->vy[indx]; gitr_precision vz = particlesPointer->vz[indx]; -#if FLOWV_INTERP == 3 + if( flowv_interp == 3 ) + { interp3dVector (&flowVelocity[0], particlesPointer->xprevious[indx],particlesPointer->yprevious[indx],particlesPointer->zprevious[indx],nR_flowV,nY_flowV,nZ_flowV, flowVGridr,flowVGridy,flowVGridz,flowVr,flowVz,flowVt); -#elif FLOWV_INTERP < 3 -#if USEFIELDALIGNEDVALUES > 0 + } + else if( flowv_interp < 3 ) + { + if( field_aligned_values > 0 ) + { interpFieldAlignedVector(&flowVelocity[0], particlesPointer->xprevious[indx],particlesPointer->yprevious[indx],particlesPointer->zprevious[indx], nR_flowV,nZ_flowV, flowVGridr,flowVGridz,flowVr, flowVz,flowVt,nR_Bfield,nZ_Bfield, BfieldGridR,BfieldGridZ,BfieldR, - BfieldZ,BfieldT); -#else + BfieldZ,BfieldT, cylsymm ); + } + else + { interp2dVector(flowVelocity,particlesPointer->xprevious[indx],particlesPointer->yprevious[indx],particlesPointer->zprevious[indx], nR_flowV,nZ_flowV, - flowVGridr,flowVGridz,flowVr,flowVz,flowVt); -#endif -#endif + flowVGridr,flowVGridz,flowVr,flowVz,flowVt, cylsymm ); + } + } relativeVelocity[0] = vx - flowVelocity[0]; relativeVelocity[1] = vy - flowVelocity[1]; relativeVelocity[2] = vz - flowVelocity[2]; velocityRelativeNorm = vectorNorm(relativeVelocity); -#if PARTICLESEEDS > 0 #ifdef __CUDACC__ gitr_precision n1 = curand_normal(&state[indx]); gitr_precision n2 = curand_normal(&state[indx]); @@ -403,19 +433,7 @@ void operator()(std::size_t indx) { gitr_precision r3 = dist(state[indx]); gitr_precision xsi = dist(state[indx]); #endif -#else -#if __CUDACC__ - gitr_precision n1 = curand_normal(&state[indx]); - gitr_precision n2 = curand_normal(&state[indx]); - gitr_precision xsi = curand_uniform(&state[indx]); -#else - std::normal_distribution distribution(0.0,1.0); - std::uniform_real_distribution dist(0.0, 1.0); - gitr_precision n1 = distribution(state[indx]); - gitr_precision n2 = distribution(state[indx]); - gitr_precision xsi = dist(state[indx]); -#endif -#endif + getSlowDownFrequencies(nu_friction, nu_deflection, nu_parallel, nu_energy, x, y, z, vx, vy, vz, @@ -432,13 +450,17 @@ void operator()(std::size_t indx) { BfieldGridZ, BfieldR, BfieldZ, - BfieldT, T_background); + BfieldT, T_background, flowv_interp, cylsymm, + field_aligned_values ); getSlowDownDirections2(parallel_direction, perp_direction1, perp_direction2, relativeVelocity[0] , relativeVelocity[1] , relativeVelocity[2] ); - gitr_precision ti_eV = interp2dCombined(x, y, z, nR_Temp, nZ_Temp, TempGridr, TempGridz, ti); - gitr_precision density = interp2dCombined(x, y, z, nR_Dens, nZ_Dens, DensGridr, DensGridz, ni); + gitr_precision ti_eV = interp2dCombined( x, y, z, nR_Temp, nZ_Temp, TempGridr, TempGridz, ti, + cylsymm ); + + gitr_precision density = interp2dCombined( x, y, z, nR_Dens, nZ_Dens, DensGridr, + DensGridz, ni, cylsymm ); if(nu_parallel <=0.0) nu_parallel = 0.0; gitr_precision coeff_par = n1 * std::sqrt(2.0*nu_parallel * dt); diff --git a/include/crossFieldDiffusion.h b/include/crossFieldDiffusion.h index 78e16f47..f74d55c6 100644 --- a/include/crossFieldDiffusion.h +++ b/include/crossFieldDiffusion.h @@ -17,6 +17,80 @@ typedef double gitr_precision; typedef float gitr_precision; #endif +CUDA_CALLABLE_MEMBER_DEVICE +void legacy_code_block_0( Particles *particlesPointer, + int indx, + gitr_precision *B_unit, + gitr_precision step, + gitr_precision r3 ) +{ + gitr_precision perpVector[3]= {0, 0, 0}; + + gitr_precision phi_random = 2*3.14159265*r3; + perpVector[0] = std::cos(phi_random); + perpVector[1] = std::sin(phi_random); + perpVector[2] = 0.0; + + gitr_precision ez1 = B_unit[0]; + gitr_precision ez2 = B_unit[1]; + gitr_precision ez3 = B_unit[2]; + + // Get perpendicular velocity unit vectors + // this comes from a cross product of + // (ez1,ez2,ez3)x(0,0,1) + gitr_precision ex1 = ez2; + gitr_precision ex2 = -ez1; + gitr_precision ex3 = 0.0; + + // The above cross product will be zero for particles + // with a pure z-directed (ez3) velocity + // here we find those particles and get the perpendicular + // unit vectors by taking the cross product + // (ez1,ez2,ez3)x(0,1,0) instead + gitr_precision exnorm = std::sqrt(ex1*ex1 + ex2*ex2); + if(std::abs(exnorm) < 1.0e-12) + { + ex1 = -ez3; + ex2 = 0.0; + ex3 = ez1; + } + + // Ensure all the perpendicular direction vectors + // ex are unit + exnorm = std::sqrt(ex1*ex1+ex2*ex2 + ex3*ex3); + ex1 = ex1/exnorm; + ex2 = ex2/exnorm; + ex3 = ex3/exnorm; + + // Find the second perpendicular direction + // by taking the cross product + // (ez1,ez2,ez3)x(ex1,ex2,ex3) + gitr_precision ey1 = ez2*ex3 - ez3*ex2; + gitr_precision ey2 = ez3*ex1 - ez1*ex3; + gitr_precision ey3 = ez1*ex2 - ez2*ex1; + + gitr_precision tmp[3] = {0.0}; + tmp[0] = ex1*perpVector[0] + ey1*perpVector[1] + ez1*perpVector[2]; + tmp[1] = ex2*perpVector[0] + ey2*perpVector[1] + ez2*perpVector[2]; + tmp[2] = ex3*perpVector[0] + ey3*perpVector[1] + ez3*perpVector[2]; + + perpVector[0] = tmp[0]; + perpVector[1] = tmp[1]; + perpVector[2] = tmp[2]; + + gitr_precision norm = + std::sqrt( perpVector[0]*perpVector[0] + + perpVector[1]*perpVector[1] + + perpVector[2]*perpVector[2] ); + + perpVector[0] = perpVector[0]/norm; + perpVector[1] = perpVector[1]/norm; + perpVector[2] = perpVector[2]/norm; + particlesPointer->x[indx] = particlesPointer->xprevious[indx] + step*perpVector[0]; + particlesPointer->y[indx] = particlesPointer->yprevious[indx] + step*perpVector[1]; + particlesPointer->z[indx] = particlesPointer->zprevious[indx] + step*perpVector[2]; +} + /* How do particles move perpendicular to the B field */ struct crossFieldDiffusion { /* control flow */ @@ -44,6 +118,10 @@ struct crossFieldDiffusion { #else std::mt19937 *state; #endif + int perp_diffusion; + + int cylsymm; + crossFieldDiffusion(Flags* _flags, Particles *_particlesPointer, gitr_precision _dt, #if __CUDACC__ curandState *_state, @@ -54,7 +132,7 @@ struct crossFieldDiffusion { int _nR_Bfield, int _nZ_Bfield, gitr_precision * _BfieldGridRDevicePointer,gitr_precision * _BfieldGridZDevicePointer, gitr_precision * _BfieldRDevicePointer,gitr_precision * _BfieldZDevicePointer, - gitr_precision * _BfieldTDevicePointer) + gitr_precision * _BfieldTDevicePointer, int perp_diffusion_, int cylsymm_ ) : flags(_flags), particlesPointer(_particlesPointer), dt(_dt), diffusionCoefficient(_diffusionCoefficient), @@ -65,8 +143,10 @@ struct crossFieldDiffusion { BfieldRDevicePointer(_BfieldRDevicePointer), BfieldZDevicePointer(_BfieldZDevicePointer), BfieldTDevicePointer(_BfieldTDevicePointer), - state(_state) { - } + state(_state), + perp_diffusion( perp_diffusion_ ), + cylsymm( cylsymm_ ) + { } /* Monte Carlo solution to diffusion equation - we need this tested */ /* semi-non-deterministic test - tolerance type test */ @@ -84,12 +164,11 @@ void operator()(std::size_t indx) const { gitr_precision B[3] = {0.0,0.0,0.0}; gitr_precision Bmag = 0.0; gitr_precision B_unit[3] = {0.0, 0.0, 0.0}; - gitr_precision phi_random; gitr_precision norm; gitr_precision step; gitr_precision dt_step = dt; - if (flags->USE_ADAPTIVE_DT) + if ( flags->USE_ADAPTIVE_DT ) { if(particlesPointer->advance[indx]) { @@ -110,7 +189,8 @@ void operator()(std::size_t indx) const { particlesPointer->zprevious[indx], nR_Bfield,nZ_Bfield, BfieldGridRDevicePointer,BfieldGridZDevicePointer, - BfieldRDevicePointer,BfieldZDevicePointer,BfieldTDevicePointer); + BfieldRDevicePointer,BfieldZDevicePointer,BfieldTDevicePointer, + cylsymm ); Bmag = std::sqrt(B[0]*B[0] + B[1]*B[1] + B[2]*B[2]); if(Bmag < 1.0e-12) @@ -124,7 +204,6 @@ void operator()(std::size_t indx) const { B_unit[1] = B[1]/Bmag; B_unit[2] = B[2]/Bmag; -#if PARTICLESEEDS > 0 #ifdef __CUDACC__ gitr_precision r3 = curand_uniform(&state[indx]); #else @@ -132,21 +211,18 @@ void operator()(std::size_t indx) const { gitr_precision r3=dist(state[indx]); gitr_precision r4=dist(state[indx]); #endif -#else -#if __CUDACC__ - gitr_precision r3 = curand_uniform(&state[2]); -#else - std::uniform_real_distribution dist(0.0, 1.0); - gitr_precision r3=dist(state[2]); -#endif -#endif + /* magnitude of spacial step for 1 particle? */ /* m^2 / sec units for diffusionCoefficient */ step = std::sqrt(4*diffusionCoefficient*dt_step); - //printf("B_unit %f %f %f" ,B_unit[0], B_unit[1], B_unit[2]); - //printf("step %f" ,step); - // printf("ex nan %f %f %f v %f", ez1, ez2, ez3,v); -#if USEPERPDIFFUSION > 1 + /* Captain! Is an "else" even needed here? It doesn't appear to be so */ + if( perp_diffusion <= 1 ) + { + legacy_code_block_0( particlesPointer, indx, B_unit, step, r3 ); + } + + else + { /* Notice of code change: previously, this wass floor(r4 + 0.5)*2 - 1 */ /* r3 was replaced with variable r4 since r4 is not declared if CUDA is activated */ gitr_precision plus_minus1 = floor(r3 + 0.5)*2 - 1; @@ -158,7 +234,10 @@ void operator()(std::size_t indx) const { gitr_precision B_plus[3] = {0.0}; interp2dVector(&B_plus[0],x_plus,y_plus,z_plus,nR_Bfield,nZ_Bfield, - BfieldGridRDevicePointer,BfieldGridZDevicePointer,BfieldRDevicePointer,BfieldZDevicePointer,BfieldTDevicePointer); + BfieldGridRDevicePointer,BfieldGridZDevicePointer, + BfieldRDevicePointer,BfieldZDevicePointer,BfieldTDevicePointer, + cylsymm ); + gitr_precision Bmag_plus = std::sqrt(B_plus[0]*B_plus[0] + B_plus[1]*B_plus[1] + B_plus[2]*B_plus[2]); gitr_precision B_deriv1[3] = {0.0}; @@ -226,113 +305,29 @@ void operator()(std::size_t indx) const { vectorCrossProduct(B, B_deriv1, y_dir); gitr_precision x_comp = s*std::cos(theta0); gitr_precision y_comp = s*std::sin(theta0); + gitr_precision x_transform = x_comp*perpVector[0] + y_comp*y_dir[0]; gitr_precision y_transform = x_comp*perpVector[1] + y_comp*y_dir[1]; gitr_precision z_transform = x_comp*perpVector[2] + y_comp*y_dir[2]; if(std::abs(denom) < 1.0e-8) { -#endif - perpVector[0] = 0.0; - perpVector[1] = 0.0; - perpVector[2] = 0.0; - phi_random = 2*3.14159265*r3; - perpVector[0] = std::cos(phi_random); - perpVector[1] = std::sin(phi_random); - perpVector[2] = 0.0;//(-perpVector[0]*B_unit[0] - perpVector[1]*B_unit[1])/B_unit[2]; - //printf("perp_vec 1 %f %f %f \n" ,perpVector[0], perpVector[1], perpVector[2]); - - gitr_precision ez1 = B_unit[0]; - gitr_precision ez2 = B_unit[1]; - gitr_precision ez3 = B_unit[2]; - //printf("ez %f %f %f \n" ,ez1, ez2, ez3); - // Get perpendicular velocity unit vectors - // this comes from a cross product of - // (ez1,ez2,ez3)x(0,0,1) - gitr_precision ex1 = ez2; - gitr_precision ex2 = -ez1; - gitr_precision ex3 = 0.0; - //printf("ex 1 %f %f %f \n" ,ex1, ex2, ex3); - - // The above cross product will be zero for particles - // with a pure z-directed (ez3) velocity - // here we find those particles and get the perpendicular - // unit vectors by taking the cross product - // (ez1,ez2,ez3)x(0,1,0) instead - gitr_precision exnorm = std::sqrt(ex1*ex1 + ex2*ex2); - if(std::abs(exnorm) < 1.0e-12){ - ex1 = -ez3; - ex2 = 0.0; - ex3 = ez1; - } - //printf("ex 2 %f %f %f \n" ,ex1, ex2, ex3); - // Ensure all the perpendicular direction vectors - // ex are unit - exnorm = std::sqrt(ex1*ex1+ex2*ex2 + ex3*ex3); - ex1 = ex1/exnorm; - ex2 = ex2/exnorm; - ex3 = ex3/exnorm; - //printf("ex unit %f %f %f \n" ,ex1, ex2, ex3); - - //if(isnan(ex1) || isnan(ex2) || isnan(ex3)){ - // //printf("ex nan %f %f %f v %f", ez1, ez2, ez3,v); - //} - // Find the second perpendicular direction - // by taking the cross product - // (ez1,ez2,ez3)x(ex1,ex2,ex3) - gitr_precision ey1 = ez2*ex3 - ez3*ex2; - gitr_precision ey2 = ez3*ex1 - ez1*ex3; - gitr_precision ey3 = ez1*ex2 - ez2*ex1; - //printf("ey %f %f %f \n" ,ey1, ey2, ey3); - - gitr_precision tmp[3] = {0.0}; - tmp[0] = ex1*perpVector[0] + ey1*perpVector[1] + ez1*perpVector[2]; - tmp[1] = ex2*perpVector[0] + ey2*perpVector[1] + ez2*perpVector[2]; - tmp[2] = ex3*perpVector[0] + ey3*perpVector[1] + ez3*perpVector[2]; - - perpVector[0] = tmp[0]; - perpVector[1] = tmp[1]; - perpVector[2] = tmp[2]; - //printf("perp_vec %f %f %f \n" ,perpVector[0], perpVector[1], perpVector[2]); - //printf("step %f \n" ,step); -// if (B_unit[2] == 0) -// { -// perpVector[2] = perpVector[1]; -// perpVector[1] = (-perpVector[0]*B_unit[0] - perpVector[2]*B_unit[2])/B_unit[1]; -// } -// -// if ((B_unit[0] == 1.0 && B_unit[1] ==0.0 && B_unit[2] ==0.0) || (B_unit[0] == -1.0 && B_unit[1] ==0.0 && B_unit[2] ==0.0)) -// { -// perpVector[2] = perpVector[0]; -// perpVector[0] = 0; -// perpVector[1] = sin(phi_random); -// } -// else if ((B_unit[0] == 0.0 && B_unit[1] ==1.0 && B_unit[2] ==0.0) || (B_unit[0] == 0.0 && B_unit[1] ==-1.0 && B_unit[2] ==0.0)) -// { -// perpVector[1] = 0.0; -// } -// else if ((B_unit[0] == 0.0 && B_unit[1] ==0.0 && B_unit[2] ==1.0) || (B_unit[0] == 0.0 && B_unit[1] ==0.0 && B_unit[2] ==-1.0)) -// { -// perpVector[2] = 0; -// } +//#endif + /* Captain! Turn this into a function. Move stuff from the block into the comment then + move it all and butcher the control flow. Define and call the lambda function here */ + //f( perpVector, particlesPointer, indx, B_unit, step ) + legacy_code_block_0( particlesPointer, indx, B_unit, step, r3 ); - norm = std::sqrt(perpVector[0]*perpVector[0] + perpVector[1]*perpVector[1] + perpVector[2]*perpVector[2]); - - perpVector[0] = perpVector[0]/norm; - perpVector[1] = perpVector[1]/norm; - perpVector[2] = perpVector[2]/norm; - particlesPointer->x[indx] = particlesPointer->xprevious[indx] + step*perpVector[0]; - particlesPointer->y[indx] = particlesPointer->yprevious[indx] + step*perpVector[1]; - particlesPointer->z[indx] = particlesPointer->zprevious[indx] + step*perpVector[2]; -#if USEPERPDIFFUSION > 1 -} + /* Captain! */ + } else { particlesPointer->x[indx] = x0 + x_transform; particlesPointer->y[indx] = y0 + y_transform; particlesPointer->z[indx] = z0 + z_transform; } -#endif + } +//#endif } } } }; diff --git a/include/curandInitialize.h b/include/curandInitialize.h index 3e5f9814..7179fe57 100644 --- a/include/curandInitialize.h +++ b/include/curandInitialize.h @@ -7,6 +7,7 @@ #define CUDA_CALLABLE_MEMBER_DEVICE #endif #include +#include #include #include "Particles.h" #include "libconfig.h++" @@ -18,7 +19,7 @@ struct curandInitialize{ #else T *s; #endif - //int seed; + long seed; bool fixed; curandInitialize( @@ -27,25 +28,48 @@ struct curandInitialize{ #else T *_s, #endif - bool _fixed) : s(_s), fixed(_fixed) {} + bool _fixed) : s(_s), fixed(_fixed) + { + if( fixed ) + { + seed = 0; + } + + else seed = std::time( nullptr ); + } CUDA_CALLABLE_MEMBER_DEVICE void operator()(std::size_t indx) { + #if USE_CUDA > 0 - curand_init(indx, 0, 0, &s[indx]); + + if( fixed ) + { + curand_init(indx, 0, 0, &s[indx]); + } + else + { + curand_init( seed + indx, 0, 0, &s[indx] ); + } + #else + + /* fixed seeds ON with OPENMP does not work... */ if (fixed) { + //T s0(1234^indx); T s0(1234^indx); s[indx] = s0; } + else { std::random_device randDevice; std::mt19937 s0(randDevice()); s[indx] = s0; } + #endif } }; diff --git a/include/fieldLineTrace.h b/include/fieldLineTrace.h index c0e62423..47b66c58 100644 --- a/include/fieldLineTrace.h +++ b/include/fieldLineTrace.h @@ -35,6 +35,7 @@ struct field_line_trace { gitr_precision * BfieldR; gitr_precision * BfieldZ; gitr_precision * BfieldT; + int cylsymm; field_line_trace(gitr_precision _BfieldFactor,Particles* _particles,gitr_precision _dr,Boundary* _boundaries,int _nLines, int _nR_Lc, int _nZ_Lc, gitr_precision* _gridRLc, gitr_precision* _gridZLc, gitr_precision* _Lc, @@ -43,13 +44,14 @@ struct field_line_trace { gitr_precision * _BfieldGridZ, gitr_precision * _BfieldR, gitr_precision * _BfieldZ, - gitr_precision * _BfieldT) + gitr_precision * _BfieldT, + int cylsymm_ ) : BfieldFactor(_BfieldFactor),particles(_particles),dr(_dr),boundaries(_boundaries),nLines(_nLines), nR_Lc(_nR_Lc),nZ_Lc(_nZ_Lc), gridRLc(_gridRLc), gridZLc(_gridZLc),Lc(_Lc), nR_Bfield(_nR_Bfield), nZ_Bfield(_nZ_Bfield), BfieldGridR(_BfieldGridR), BfieldGridZ(_BfieldGridZ), - BfieldR(_BfieldR), BfieldZ(_BfieldZ), BfieldT(_BfieldT) {} + BfieldR(_BfieldR), BfieldZ(_BfieldZ), BfieldT(_BfieldT), cylsymm( cylsymm_ ) {} CUDA_CALLABLE_MEMBER void operator()(std::size_t indx) const { @@ -78,7 +80,7 @@ if(particles->hitWall[indx] == 0.0) interp2dVector(&B[0],x0, y0,z0, nR_Bfield,nZ_Bfield,BfieldGridR,BfieldGridZ, - BfieldR,BfieldZ,BfieldT); + BfieldR,BfieldZ,BfieldT, cylsymm ); //std::cout << "Bfield interp " << B[0] << " " << B[1] << " " << B[2] << std::endl; vectorNormalize(B,B); //Bmag = std::sqrt(B[0]*B[0] + B[1]*B[1] + B[2]*B[2]); @@ -90,20 +92,20 @@ if(particles->hitWall[indx] == 0.0) interp2dVector(&B[0],x0+0.5*k1[0],y0+0.5*k1[1],z0+0.5*k1[2], nR_Bfield,nZ_Bfield,BfieldGridR,BfieldGridZ, - BfieldR,BfieldZ,BfieldT); + BfieldR,BfieldZ,BfieldT, cylsymm ); vectorNormalize(B,B); vectorScalarMult(dr_fac,B,k2); interp2dVector(&B[0],x0+0.5*k2[0],y0+0.5*k2[1],z0+0.5*k2[2], nR_Bfield,nZ_Bfield,BfieldGridR,BfieldGridZ, - BfieldR,BfieldZ,BfieldT); + BfieldR,BfieldZ,BfieldT, cylsymm ); vectorNormalize(B,B); vectorScalarMult(dr_fac,B,k3); interp2dVector(&B[0],x0+k3[0],y0+k3[1],z0+k3[2], nR_Bfield,nZ_Bfield,BfieldGridR,BfieldGridZ, - BfieldR,BfieldZ,BfieldT); + BfieldR,BfieldZ,BfieldT, cylsymm ); vectorNormalize(B,B); vectorScalarMult(dr_fac,B,k4); diff --git a/include/geometryCheck.h b/include/geometryCheck.h index d58b02dc..8188ebac 100644 --- a/include/geometryCheck.h +++ b/include/geometryCheck.h @@ -12,7 +12,11 @@ #include "Surfaces.h" #include "surfaceModel.h" #include "boris.h" + +#if USE_OPENMP == 1 #include "omp.h" +#endif + #include #if USE_DOUBLE @@ -52,6 +56,11 @@ struct geometry_check { int nAdist; gitr_precision A0dist; gitr_precision Adist; + int flux_ea; + int surface_model; + int geom_hash; + int use_3d_geom; + int cylsymm; geometry_check(Particles *_particlesPointer, int _nLines, Boundary *_boundaryVector, Surfaces *_surfaces, gitr_precision _dt, @@ -60,7 +69,12 @@ struct geometry_check { gitr_precision *_closeGeomGridr, gitr_precision *_closeGeomGridy, gitr_precision *_closeGeomGridz, int *_closeGeom, int _nEdist, gitr_precision _E0dist, gitr_precision _Edist, int _nAdist, gitr_precision _A0dist, - gitr_precision _Adist); + gitr_precision _Adist, + int flux_ea_, + int surface_model_, + int geom_hash_, + int use_3d_geom_, + int cylsymm_ ); //CUDA_CALLABLE_MEMBER_DEVICE __host__ __device__ diff --git a/include/hashGeom.h b/include/hashGeom.h index b396952e..35abe640 100644 --- a/include/hashGeom.h +++ b/include/hashGeom.h @@ -45,6 +45,7 @@ struct hashGeom { int* nR; int* nY; int* nZ; + int use_3d_geom; hashGeom( int _nLines,int _nHashes, @@ -54,7 +55,7 @@ struct hashGeom { gitr_precision* _z, int* _n_closeGeomElements,//gitr_precision *_minDist, int *_closeGeom, - int* _nR, int* _nY, int* _nZ); + int* _nR, int* _nY, int* _nZ, int use_3d_geom_ ); CUDA_CALLABLE_MEMBER_DEVICE void operator()(std::size_t indx); diff --git a/include/hashGeomSheath.h b/include/hashGeomSheath.h index 54e099aa..76381adb 100644 --- a/include/hashGeomSheath.h +++ b/include/hashGeomSheath.h @@ -43,6 +43,7 @@ struct hashGeom_sheath { int nR; int nY; int nZ; + int use_3d_geom; hashGeom_sheath(int _nLines, @@ -52,34 +53,42 @@ struct hashGeom_sheath { gitr_precision* _z, int _n_closeGeomElements, //gitr_precision *_minDist, int *_closeGeom, - int _nR, int _nY, int _nZ) + int _nR, int _nY, int _nZ, int use_3d_geom_ ) : nLines(_nLines),boundary(_boundary), x(_x), y(_y), z(_z), n_closeGeomElements(_n_closeGeomElements), //minDist(_minDist), - closeGeom(_closeGeom), nR(_nR), nY(_nY), nZ(_nZ) {} + closeGeom(_closeGeom), nR(_nR), nY(_nY), nZ(_nZ), + use_3d_geom( use_3d_geom_ ) {} CUDA_CALLABLE_MEMBER_DEVICE void operator()(std::size_t indx) const { - #if USE3DTETGEOM > 0 - gitr_precision kk = indx/(nR*nY); + + gitr_precision x0; + gitr_precision y0; + gitr_precision z0; + gitr_precision kk; + + if( use_3d_geom > 0 ) + { + kk = indx/(nR*nY); int k = std::floor(kk); int jjj = indx - k*nR*nY; gitr_precision jj = 1.0*jjj/nR; int j = std::floor(jj); int i = indx - j*nR - k*(nR*nY); - int xyzIndx = indx; - gitr_precision x0 = x[i]; - gitr_precision y0 = y[j]; - gitr_precision z0 = z[k]; - #else - gitr_precision kk = indx/(nR); + x0 = x[i]; + y0 = y[j]; + z0 = z[k]; + } + else + { + kk = indx/(nR); int k = std::floor(kk); int i = indx - k*(nR); - gitr_precision x0 = x[i]; - gitr_precision y0 = 0.0; - gitr_precision z0 = z[k]; - int xyzIndx = indx; - #endif + x0 = x[i]; + y0 = 0.0; + z0 = z[k]; + } gitr_precision A[3] = {0.0,0.0,0.0}; gitr_precision B[3] = {0.0,0.0,0.0}; gitr_precision C[3] = {0.0,0.0,0.0}; @@ -115,24 +124,28 @@ struct hashGeom_sheath { gitr_precision b = boundary[l].b; gitr_precision c = boundary[l].c; gitr_precision d = boundary[l].d; - #if USE3DTETGEOM > 0 + gitr_precision perpDist; + if( use_3d_geom > 0 ) + { gitr_precision plane_norm = boundary[l].plane_norm; gitr_precision t = -(a*x0 + b*y0 + c*z0 + d)/(a*a + b*b + c*c); p[0] = a*t + x0; p[1] = b*t + y0; p[2] = c*t + z0; - gitr_precision perpDist = std::sqrt((x0-p[0])*(x0-p[0]) + (y0-p[1])*(y0-p[1]) + (z0-p[2])*(z0-p[2])); - #endif + perpDist = std::sqrt((x0-p[0])*(x0-p[0]) + (y0-p[1])*(y0-p[1]) + (z0-p[2])*(z0-p[2])); + } vectorAssign(boundary[l].x1, boundary[l].y1, boundary[l].z1, A); vectorAssign(boundary[l].x2, boundary[l].y2, boundary[l].z2, B); - #if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { vectorAssign(boundary[l].x3, boundary[l].y3, boundary[l].z3, C); - #endif + } vectorSubtract(B,A,AB); - #if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { vectorSubtract(C,A,AC); vectorSubtract(C,B,BC); vectorSubtract(A,C,CA); @@ -153,7 +166,7 @@ struct hashGeom_sheath { if (totalSigns == 3.0) { } else perpDist = 1.0e6; -#endif + } p[0] = x0; p[1] = y0; p[2] = z0; @@ -168,7 +181,9 @@ struct hashGeom_sheath { vectorSubtract(pA, cEdge1, dEdge1); distE1 = std::sqrt(vectorDotProduct(dEdge1, dEdge1)); } -#if USE3DTETGEOM > 0 + gitr_precision minEdge; + if( use_3d_geom > 0 ) + { gitr_precision pB[3] = {0.0}; gitr_precision cEdge2[3] = {0.0}; gitr_precision dEdge2[3] = {0.0}; @@ -191,30 +206,35 @@ struct hashGeom_sheath { vectorSubtract(pC, cEdge3, dEdge3); distE3 = std::sqrt(vectorDotProduct(dEdge3, dEdge3)); } - gitr_precision minEdge = std::min(distE1, distE2); + minEdge = std::min(distE1, distE2); minEdge = std::min(distE3, minEdge); -#else - // - gitr_precision minEdge = distE1; -#endif + } + else + { + minEdge = distE1; + } gitr_precision d1 =std::sqrt((x0 - boundary[l].x1)*(x0 - boundary[l].x1) + (y0 - boundary[l].y1)*(y0 - boundary[l].y1) + (z0 - boundary[l].z1)*(z0 - boundary[l].z1)); gitr_precision d2 =std::sqrt((x0 - boundary[l].x2)*(x0 - boundary[l].x2) + (y0 - boundary[l].y2)*(y0 - boundary[l].y2) + (z0 - boundary[l].z2)*(z0 - boundary[l].z2)); - #if USE3DTETGEOM > 0 - gitr_precision d3 =std::sqrt((x0 - boundary[l].x3)*(x0 - boundary[l].x3) + gitr_precision d3; + if( use_3d_geom > 0 ) + { + /* Ahoy, Captain! */ + d3 =std::sqrt((x0 - boundary[l].x3)*(x0 - boundary[l].x3) + (y0 - boundary[l].y3)*(y0 - boundary[l].y3) + (z0 - boundary[l].z3)*(z0 - boundary[l].z3)); - #endif + } gitr_precision minOf3 = std::min(d1,d2); minOf3 = std::min(minOf3,minEdge); //std::cout << "min of two " << minOf3 << std::endl; - #if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { minOf3 = std::min(minOf3,perpDist); minOf3 = std::min(minOf3,d3); - #endif + } int minIndClose = n_closeGeomElements; for(int m=0; m< n_closeGeomElements; m++) { diff --git a/include/interp2d.hpp b/include/interp2d.hpp index e64f2053..1ee53384 100644 --- a/include/interp2d.hpp +++ b/include/interp2d.hpp @@ -27,7 +27,7 @@ gitr_precision interp2d ( gitr_precision x, gitr_precision z,int nx, int nz, CUDA_CALLABLE_MEMBER gitr_precision interp2dCombined ( gitr_precision x, gitr_precision y, gitr_precision z,int nx, int nz, - gitr_precision* gridx,gitr_precision* gridz,gitr_precision* data ); + gitr_precision* gridx,gitr_precision* gridz,gitr_precision* data, int cylsymm ); CUDA_CALLABLE_MEMBER gitr_precision interp3d ( gitr_precision x, gitr_precision y, gitr_precision z,int nx,int ny, int nz, @@ -41,11 +41,11 @@ void interp3dVector (gitr_precision* field, gitr_precision x, gitr_precision y, gitr_precision* gridx,gitr_precision* gridy,gitr_precision* gridz,gitr_precision* datar, gitr_precision* dataz, gitr_precision* datat ); CUDA_CALLABLE_MEMBER void interp2dVector (gitr_precision* field, gitr_precision x, gitr_precision y, gitr_precision z,int nx, int nz, -gitr_precision* gridx,gitr_precision* gridz,gitr_precision* datar, gitr_precision* dataz, gitr_precision* datat ); +gitr_precision* gridx,gitr_precision* gridz,gitr_precision* datar, gitr_precision* dataz, gitr_precision* datat, int cylsymm ); CUDA_CALLABLE_MEMBER -void interpFieldAlignedVector (gitr_precision* field, gitr_precision x, gitr_precision y, gitr_precision z,int nx, int nz, +void interpFieldAlignedVector ( gitr_precision* field, gitr_precision x, gitr_precision y, gitr_precision z,int nx, int nz, gitr_precision* gridx,gitr_precision* gridz,gitr_precision* datar, gitr_precision* dataz, gitr_precision* datat, - int nxB, int nzB, gitr_precision* gridxB,gitr_precision* gridzB,gitr_precision* datarB,gitr_precision* datazB, gitr_precision* datatB); + int nxB, int nzB, gitr_precision* gridxB,gitr_precision* gridzB,gitr_precision* datarB,gitr_precision* datazB, gitr_precision* datatB, int cylsymm ); CUDA_CALLABLE_MEMBER gitr_precision interp1dUnstructured(gitr_precision samplePoint,int nx, gitr_precision max_x, gitr_precision* data,int &lowInd); CUDA_CALLABLE_MEMBER diff --git a/include/interpRateCoeff.hpp b/include/interpRateCoeff.hpp index a26fffe3..c24efe35 100644 --- a/include/interpRateCoeff.hpp +++ b/include/interpRateCoeff.hpp @@ -26,4 +26,5 @@ CUDA_CALLABLE_MEMBER gitr_precision interpRateCoeff2d ( int charge, gitr_precision x, gitr_precision y, gitr_precision z,int nx, int nz, gitr_precision* tempGridxp, gitr_precision* tempGridzp, gitr_precision* Tempp, gitr_precision* densGridxp,gitr_precision* densGridzp,gitr_precision* Densp,int nT_Rates, int nD_Rates, - gitr_precision* rateGrid_Temp,gitr_precision* rateGrid_Dens,gitr_precision* Rates ); + gitr_precision* rateGrid_Temp,gitr_precision* rateGrid_Dens,gitr_precision* Rates, + int cylsymm ); diff --git a/include/interpolator.h b/include/interpolator.h new file mode 100644 index 00000000..0f23fe76 --- /dev/null +++ b/include/interpolator.h @@ -0,0 +1,411 @@ +/* + +Mathematical Context: + + Terminology: + + A discrete function is a pair of finite sets. + The first set: + + x = { x0, x1, x2, ... , x_n } + + i < j ---> x[ i ] < x[ j ] + + x[ i ] - x[ i - 1 ] = constant + + contains domain values "x" and the other set is the co-domain values f: + + f = { f(x0), f(x1), f(x2), ... , f(x_n) } + + A continuous function is the same idea but the first set "x" contains all possible domain + values and the second set "f" contains the co-domain values for every value in "x". + + A linear interpolation is a method to infer a continuous function from a discrete one: + + Given finite "x" and "f" above, linear interpolation attempts to estimate the value of + f( p ) given: + + p itself is not contained in set "x", but it is in between two elements: + + there exists x_lower and x_upper in set "x" such that + + x_lower <= p <= x_upper + + Assumption: + + For all valid "i" in "x": The Cartesian points + + ( x[ i ], f( x[ i ] ) ) + + and + + ( x[ i + 1 ], f( x[ i + 1 ] ) ) + + are samples of a continuous function and that function is a straight line on the domain + interval [ x[ i ], x[ i + 1 ] ] + + Thus, the value f( p ) of interest must lie along that line: + + f( p ) = a * p + b + + Since this line is within a defined domain interval, "b" can be safely set to 0: + + f( p ) = a * p + + Recall that there exists "x_lower" and "x_upper" in set "x" such that + + x_lower <= p <= x_upper + + where + + ( f( x_upper ) - f( x_lower ) ) + a = --------------------------------- + ( x_upper - x_lower ) + + but + + ( x_lower * ( x_upper - p ) + x_upper * ( p - x_lower ) ) + p = ----------------------------------------------------------- + ( x_upper - x_lower ) + + so + + + ( x_lower * ( x_upper - p ) x_upper * ( p - x_lower ) ) + f( p ) = a * ------------------------------ + a * ------------------------------- + ( x_upper - x_lower ) x_upper - x_lower + + and from linearity of f: + + x_upper - p p - x_lower + f( p ) = a * f( x_lower ) * ------------------ + a * f( x_upper ) * ------------------- + x_upper - x_lower x_upper - x_lower + + + Due to equal spacing of the elements in "x", we have: + + there exists an "i" index in "x" such that + + x_lower = x[ i ] + x_upper = x[ i + 1 ] + + and the matching co-domain values: + + f( x_lower ) = f[ i ] + f( x_upper ) = f[ i + 1 ] + + due to the spacing of the x[ i ] defined above, x_lower and x_upper can be calculated given "p" + as follows: + + spacing = x[ j + 1 ] - x[ j ] for any valid index j into "x" + + x_lower = x[ i ] + + i = std::floor( p / spacing ) + + x[ i ] = i * spacing + + thus + + one-dimensional function f( p, y_const ) for a constant "y_const" is a weighted sum of + f( x_lower ) and f( x_upper ) where the + term applied to f( x_lower ) is called the "lower_fraction" + and the term applied to + f( x_upper ) will be referred to as the "upper_fraction" + + f( p, y ) = lower_fraction * f( x_lower, y ) * upper_fraction * f( x_upper, y ) + + This can be applied inductively for multidimensional interpolation for calculating for + input coordinate vector "v": + + v = ( x, y, z, ... ) + + f( v ) = f( x = v0, y = v1, z = v2, ... ) + + where + + x_lower <= x <= x_upper + y_lower <= y <= y_upper + z_lower <= z <= z_upper + . + . + . + + A hypercube in n-dimensions is a set of points defined by all combinations: + + f( x from { x_lower, x_upper }, + y from { y_lower, y_upper }, + z from { z_lower, z_upper }, + ... , + n from { n_lower, n_upper } ) + + This set contains 2^n elements, + + hypercube = { f(v0), f(v1), ... , f( vn ) } + + each "f(v_)" indexed by a number "i" represented by "n" bits stored + in "n_bits", where + a '0' at n_bits[ j ] indicates that dimension "j" in the "v_" value was the "lower" boundary + while a '1' bit indicates dimension "j" of the vector "v_" has the "upper" boundary value + + In general, any point "v" in an n-dimensional vector space will have a basis cell containing + 2^n elements that are vertices of an n-dimensional cube containing the point "v". + + An interpolation of f( v ) requires two steps: + + 1. Fetching the enclosing hypercube containing "v" + 2. Interpolating the value of f( v ) + + f( v ) = sum( w_i * f( b_i ) ) + + where + + w_i is a scalar weight term and + b_i is the i-th ordered hypercube element + + and "i" can be used to get the value b_i while the "n" bits used to represent "i" can + simultaneously be used to encode the "n" values that must be multiplied to get "w_i". + +*/ +/* + +Programmatic Representation: + + "f" are the values of a continuous n-dimensional function sampled at points in the domain. + This set of points is referred to as the "discrete domain set" and is a proper subset of + the function's domain, an infinite set. + + The domain set can be spatially represented as the vertices of a finite, n-dimensional lattice. + + For any n-dimensional "coordinate" in the continuous domain, the nearest 2^n lattice points + form an + n-dimensional hypercube. This enclosing hypercube is used to interpolate the function's value + at "coordinate". The 2^n vertices of this cube can be indexed identically to the 2^n vertices + of an n-dimensional unit hypercube. + + The n-dimensional unit hypercube has 2^n vertices. + + Each element "i" in the index set: + + { 0, 1, 2, ..., ( 2^n ) - 1 } + + indexes one of the 2^n vertices. + + The binary representation of "i" is a bit string of + n-bits where the final bit b_1 is the least significant and + the first bit b_n is the most significant. + (Big Endian bit order): + + { bit_n, bit_n-1, ..., bit_z, bit_y, bit_x, ... , bit_2, bit_1 } + + which incidentally can be interpreted as a spacial n-tuple and thus vertex of the hypercube: + + { dim_n, dim_n-1, ..., dim_z, dim_y, dim_x, ... , dim_2, dim_1 } + + A binary n-tuple of this form is associated with each vertex "i" and will be referred to as + "n-tuple_i". + +*/ +/* + +Final Calculation: + + 1. To interpolate a point "p", obtain the function values at each of the 2^n vertices + of the enclosing hypercube. + + 2. Order the values according to the n-tuple_i value for each value's associated vertex + in a list called "v" with elements "v_i" + + In the multidimensional case, the interpolation is represented as a sum: + + f( coordinate ) = sum over i: ( w_i * v_i ) + + and w_i = + product over each bit "b" in n-tuple_i: + ( lower_fraction if b is '0' or upper_fraction if b is '1' ) + +*/ +#include +#include +#include +#include + +/* + +hypercube: n-dimensional hypercube in a flattened array of 2^n vertices + +coordinates: domain coordinates for which it is desired to interpolate a function value + +d_len: + + for all "i" in d_len, d_len[ i ] specifies the number of equally spaced samples + spanning domain dimension "i" + +max_range: + + for all "i" in max_range, max_range[ i ] specifies the linear extent divided equally + by d_len[ i ] bins + +*/ +double interpolate_hypercube( std::vector< double > const &hypercube, + std::vector< double > const &coordinates, + std::vector< int > const &d_len, + std::vector< double > const &max_range ) +{ + assert( coordinates.size() == d_len.size() ); + + assert( coordinates.size() == max_range.size() ); + + std::vector< double > spacing( max_range.size() ); + + for( int i = 0; i < spacing.size(); i++ ) + { + spacing[ i ] = max_range[ i ] / double(d_len[ i ]); + } + + /* the "upper" and "lower" fractions for each dimension */ + std::vector< double > normalized_fractions( coordinates.size() * 2 ); + + for( int i = 0; i < coordinates.size(); i++ ) + { + /* high fraction, matches with a 1 bit */ + normalized_fractions[ i * 2 + 1 ] = + ( coordinates[ i ] - ( std::floor( coordinates[ i ] / spacing[ i ] ) * spacing[ i ] ) ) / + spacing[ i ]; + + /* low fraction, matches with a 0 bit */ + normalized_fractions[ i * 2 ] = 1 - normalized_fractions[ i * 2 + 1 ]; + } + + /* sum the value of each vertex weighted properly... */ + double sum = 0; + + for( int i = 0; i < hypercube.size(); i++ ) + { + double weight = 1; + + /* iterate the bits in "i" */ + for( int j = 0; j < coordinates.size(); j++ ) + { + weight *= normalized_fractions[ j * 2 + ( ( i >> j ) & 0x1 ) ]; + } + + sum += weight * hypercube[ i ]; + } + + return sum; +} + + +/* + +data: finite lattice in Euclidean n-space of samples of continuous n-dimensional function f + +coordinates: + + domain coordinates for which it is desired to interpolate a function value + coordinates are expected in order of dimension with the smallest stride (1) to dimension + with the largest stride + +d_len: + + for all "i" in d_len, d_len[ i ] specifies the number of equally spaced histogram bins + spanning dimension "i" + +max_range: + + for all "i" in max_range, max_range[ i ] specifies the linear extent divided equally + by d_len[ i ] bins + +returns: n-dimensional hypercube in a flattened array of 2^n vertices + +*/ +std::vector< double > fetch_hypercube( std::vector< double > const &data, + std::vector< double > const &coordinates, + std::vector< int > const &d_len, + std::vector< double > const &max_range ) +{ + assert( coordinates.size() == d_len.size() ); + + assert( coordinates.size() == max_range.size() ); + + /* d_multipliers[ i ] indicates the stride of dimension "i" */ + std::vector< int > d_multipliers( d_len.size(), 1 ); + + for( int i = 0; i < d_multipliers.size() - 1; i++ ) + { + d_multipliers[ i + 1 ] = d_multipliers[ i ] * d_len[ i ]; + } + + assert( data.size() == d_multipliers.back() * d_len.back() ); + + std::vector< double > spacing( max_range.size() ); + + for( int i = 0; i < spacing.size(); i++ ) + { + spacing[ i ] = max_range[ i ] / double(d_len[ i ]); + } + + /* find the index of the first vertex in the hypercube */ + int corner_vertex_index = 0; + + for( int i = 0; i < coordinates.size(); i++ ) + { + corner_vertex_index += + ( std::floor( coordinates[ i ] / spacing[ i ] ) * d_multipliers[ i ] ); + } + + std::vector< double > hypercube( 1 << d_len.size() ); + + /* find the indices of the other vertices in the hypercube by offsetting from the + first vertex */ + for( int i = 0; i < hypercube.size(); i++ ) + { + int flat_index = corner_vertex_index; + + for( int j = 0; j < coordinates.size(); j++ ) + { + flat_index += ( ( ( i >> j ) & 0x1 ) * d_multipliers[ j ] ); + } + + hypercube[ i ] = data[ flat_index ]; + } + + return hypercube; +} + +/* class to encapsulate interpolation functionality */ +class interpolated_field +{ + public: + + interpolated_field( std::vector< double > const field, + std::vector< int > const d_len, + std::vector< double > const max_range ) + : + field( field ), + d_len( d_len ), + max_range( max_range ) + { } + + + double operator()( std::vector< double > const coordinates ); + + private: + + std::vector< double > const field; + + std::vector< int > const d_len; + + std::vector< double > const max_range; +}; + +/* Captain! These do not make sense to be passed by value */ +double interpolated_field::operator()( std::vector< double > const coordinates ) +{ + std::vector< double > hypercube = fetch_hypercube( field, coordinates, d_len, max_range ); + + double interpolated_value = interpolate_hypercube( hypercube, coordinates, d_len, max_range ); + + return interpolated_value; +} diff --git a/include/ionize.h b/include/ionize.h index 14ac8d23..61a72fc4 100644 --- a/include/ionize.h +++ b/include/ionize.h @@ -74,6 +74,7 @@ struct ionize { int xx1; T *state; gitr_precision * random_uniform_number; + int cylsymm; ionize(Flags *_flags, Particles *_particlesPointer, gitr_precision _dt,T *_state, int _nR_Dens, int _nZ_Dens, gitr_precision *_DensGridr, gitr_precision *_DensGridz, @@ -81,7 +82,7 @@ struct ionize { gitr_precision *_TempGridz, gitr_precision *_te, int _nTemperaturesIonize, int _nDensitiesIonize, gitr_precision *_gridTemperature_Ionization, gitr_precision *_gridDensity_Ionization, gitr_precision *_rateCoeff_Ionization, - gitr_precision * _random_uniform_number); + gitr_precision * _random_uniform_number, int cylsymm ); CUDA_CALLABLE_MEMBER_DEVICE void operator()(std::size_t indx); diff --git a/include/recombine.h b/include/recombine.h index 550cabea..5cf4e747 100644 --- a/include/recombine.h +++ b/include/recombine.h @@ -51,6 +51,7 @@ struct recombine { gitr_precision dt; gitr_precision tion; T *state; + int cylsymm; recombine(Particles *_particlesPointer, gitr_precision _dt, T *_state, @@ -58,7 +59,7 @@ struct recombine { gitr_precision* _DensGridz,gitr_precision* _ne,int _nR_Temp, int _nZ_Temp, gitr_precision* _TempGridr, gitr_precision* _TempGridz,gitr_precision* _te,int _nTemperaturesRecomb, int _nDensitiesRecomb,gitr_precision* _gridTemperature_Recombination,gitr_precision* _gridDensity_Recombination, - gitr_precision* _rateCoeff_Recombination, Flags* _gitr_flags) : + gitr_precision* _rateCoeff_Recombination, Flags* _gitr_flags, int cylsymm_ ) : particlesPointer(_particlesPointer), nR_Dens(_nR_Dens), @@ -78,7 +79,8 @@ struct recombine { rateCoeff_Recombination(_rateCoeff_Recombination), gitr_flags(_gitr_flags), dt(_dt), - state(_state) {} + state(_state), + cylsymm( cylsymm_ ) {} CUDA_CALLABLE_MEMBER_DEVICE @@ -94,7 +96,7 @@ struct recombine { if(particlesPointer->charge[indx] > 0) { - tion = interpRateCoeff2d ( particlesPointer->charge[indx]-1, particlesPointer->x[indx], particlesPointer->y[indx], particlesPointer->z[indx],nR_Temp,nZ_Temp, TempGridr,TempGridz,te,DensGridr,DensGridz, ne,nTemperaturesRecomb,nDensitiesRecomb,gridTemperature_Recombination,gridDensity_Recombination,rateCoeff_Recombination); + tion = interpRateCoeff2d ( particlesPointer->charge[indx]-1, particlesPointer->x[indx], particlesPointer->y[indx], particlesPointer->z[indx],nR_Temp,nZ_Temp, TempGridr,TempGridz,te,DensGridr,DensGridz, ne,nTemperaturesRecomb,nDensitiesRecomb,gridTemperature_Recombination,gridDensity_Recombination,rateCoeff_Recombination, cylsymm ); gitr_precision P = exp(-dt/tion); P1 = 1.0-P; r1 = get_rand_double(state,indx); diff --git a/include/spectroscopy.h b/include/spectroscopy.h index c611a19a..ce2bc035 100644 --- a/include/spectroscopy.h +++ b/include/spectroscopy.h @@ -11,14 +11,18 @@ #include "Boundary.h" #include #include + +#if USE_OPENMP == 1 #include "omp.h" +#endif + #if USE_DOUBLE typedef double gitr_precision; #else typedef float gitr_precision; #endif #if USE_CUDA >0 -__device__ double atomicAdd1(double* address, double val); +__device__ double atomicAdd1(gitr_precision* address, gitr_precision val); #endif struct spec_bin { @@ -31,11 +35,13 @@ struct spec_bin { gitr_precision *gridX; gitr_precision *gridY; gitr_precision *gridZ; - double *bins; + gitr_precision *bins; gitr_precision dt; + int cylsymm; + int spectroscopy; spec_bin(Flags* _flags, Particles *_particlesPointer, int _nBins,int _nX,int _nY, int _nZ, gitr_precision *_gridX,gitr_precision *_gridY,gitr_precision *_gridZ, - double * _bins, gitr_precision _dt); + gitr_precision* _bins, gitr_precision _dt, int cylsymm_, int spectroscopy_ ); CUDA_CALLABLE_MEMBER_DEVICE void operator()(std::size_t indx) const; diff --git a/include/surfaceModel.h b/include/surfaceModel.h index b410eb7d..cfafe0ac 100644 --- a/include/surfaceModel.h +++ b/include/surfaceModel.h @@ -15,7 +15,11 @@ #include #include "boris.h" #include "spectroscopy.h" + +#if USE_OPENMP == 1 #include "omp.h" +#endif + #ifdef __CUDACC__ #include #else @@ -68,6 +72,10 @@ struct reflection { #else std::mt19937 *state; #endif + int flux_ea; + int use_3d_geom; + int cylsymm; + reflection(Particles* _particles, double _dt, #if __CUDACC__ curandState *_state, @@ -104,7 +112,10 @@ struct reflection { gitr_precision _Edist, int _nAdist, gitr_precision _A0dist, - gitr_precision _Adist); + gitr_precision _Adist, + int flux_ea_, + int use_3d_geom_, + int cylsymm_ ); CUDA_CALLABLE_MEMBER_DEVICE void operator()(std::size_t indx) const; diff --git a/include/thermalForce.h b/include/thermalForce.h index b4efd605..871aa17f 100644 --- a/include/thermalForce.h +++ b/include/thermalForce.h @@ -44,6 +44,7 @@ struct thermalForce { gitr_precision dv_ETGx=0.0; gitr_precision dv_ETGy=0.0; gitr_precision dv_ETGz=0.0; + int cylsymm; thermalForce(Flags* _flags,Particles *_p,gitr_precision _dt, gitr_precision _background_amu,int _nR_gradT, int _nZ_gradT, gitr_precision* _gradTGridr, gitr_precision* _gradTGridz, gitr_precision* _gradTiR, gitr_precision* _gradTiZ, gitr_precision* _gradTiT, gitr_precision* _gradTeR, gitr_precision* _gradTeZ,gitr_precision* _gradTeT, @@ -52,13 +53,14 @@ struct thermalForce { gitr_precision * _BfieldGridZDevicePointer, gitr_precision * _BfieldRDevicePointer, gitr_precision * _BfieldZDevicePointer, - gitr_precision * _BfieldTDevicePointer) + gitr_precision * _BfieldTDevicePointer, + int cylsymm_ ) : flags(_flags),p(_p), dt(_dt), background_amu(_background_amu),nR_gradT(_nR_gradT),nZ_gradT(_nZ_gradT), gradTGridr(_gradTGridr), gradTGridz(_gradTGridz), gradTiR(_gradTiR), gradTiZ(_gradTiZ),gradTiT(_gradTiT), gradTeR(_gradTeR), gradTeZ(_gradTeZ),gradTeT(_gradTeT), nR_Bfield(_nR_Bfield), nZ_Bfield(_nZ_Bfield), BfieldGridRDevicePointer(_BfieldGridRDevicePointer), BfieldGridZDevicePointer(_BfieldGridZDevicePointer), - BfieldRDevicePointer(_BfieldRDevicePointer), BfieldZDevicePointer(_BfieldZDevicePointer), BfieldTDevicePointer(_BfieldTDevicePointer) {} + BfieldRDevicePointer(_BfieldRDevicePointer), BfieldZDevicePointer(_BfieldZDevicePointer), BfieldTDevicePointer(_BfieldTDevicePointer), cylsymm( cylsymm_ ) {} CUDA_CALLABLE_MEMBER void operator()(std::size_t indx) { @@ -90,29 +92,35 @@ void operator()(std::size_t indx) { } // std:cout << " grad Ti interp " << std::endl; interp2dVector(&gradTi[0], p->xprevious[indx], p->yprevious[indx], p->zprevious[indx], nR_gradT, nZ_gradT, - gradTGridr, gradTGridz, gradTiR, gradTiZ, gradTiT); + gradTGridr, gradTGridz, gradTiR, gradTiZ, gradTiT, cylsymm ); //std::cout << "Position r z" << sqrt(p->xprevious*p->xprevious + p->yprevious*p->yprevious) << " " << p->zprevious << std::endl; //std::cout << "grad Ti " << std::copysign(1.0,gradTi[0])*sqrt(gradTi[0]*gradTi[0] + gradTi[1]*gradTi[1]) << " " << gradTi[2] << std::endl; interp2dVector(&gradTe[0], p->xprevious[indx], p->yprevious[indx], p->zprevious[indx], nR_gradT, nZ_gradT, - gradTGridr, gradTGridz, gradTeR, gradTeZ, gradTeT); + gradTGridr, gradTGridz, gradTeR, gradTeZ, gradTeT, cylsymm ); mu = p->amu[indx] / (background_amu + p->amu[indx]); alpha = p->charge[indx] * p->charge[indx] * 0.71; beta = 3 * (mu + 5 * std::sqrt(2.0) * p->charge[indx] * p->charge[indx] * (1.1 * std::pow(mu, (5 / 2)) - 0.35 * std::pow(mu, (3 / 2))) - 1) / (2.6 - 2 * mu + 5.4 * std::pow(mu, 2)); interp2dVector(&B[0],p->xprevious[indx],p->yprevious[indx],p->zprevious[indx],nR_Bfield,nZ_Bfield, - BfieldGridRDevicePointer,BfieldGridZDevicePointer,BfieldRDevicePointer,BfieldZDevicePointer,BfieldTDevicePointer); + BfieldGridRDevicePointer,BfieldGridZDevicePointer,BfieldRDevicePointer,BfieldZDevicePointer,BfieldTDevicePointer, cylsymm ); Bmag = std::sqrt(B[0]*B[0] + B[1]*B[1]+ B[2]*B[2]); + /* Captain! These are not checked for zero! Check them for zero! */ B_unit[0] = B[0]/Bmag; B_unit[1] = B[1]/Bmag; B_unit[2] = B[2]/Bmag; - dv_ETG[0] = 1.602e-19*dt_step/(p->amu[indx]*MI)*(alpha*(gradTe[0])); - dv_ETG[1] = 1.602e-19*dt_step/(p->amu[indx]*MI)*(alpha*(gradTe[1])); - dv_ETG[2] = 1.602e-19*dt_step/(p->amu[indx]*MI)*(alpha*(gradTe[2])); + dv_ETG[0] = 1.602e-19*dt_step/(p->amu[indx]*MI)*(alpha*(gradTe[0]))*B_unit[0]; + dv_ETG[1] = 1.602e-19*dt_step/(p->amu[indx]*MI)*(alpha*(gradTe[1]))*B_unit[1]; + dv_ETG[2] = 1.602e-19*dt_step/(p->amu[indx]*MI)*(alpha*(gradTe[2]))*B_unit[2]; + + dv_ETGx = dv_ETG[0]; + dv_ETGy = dv_ETG[1]; + dv_ETGz = dv_ETG[2]; dv_ITG[0] = 1.602e-19*dt_step/(p->amu[indx]*MI)*(beta*(gradTi[0]))*B_unit[0]; dv_ITG[1] = 1.602e-19*dt_step/(p->amu[indx]*MI)*(beta*(gradTi[1]))*B_unit[1]; dv_ITG[2] = 1.602e-19*dt_step/(p->amu[indx]*MI)*(beta*(gradTi[2]))*B_unit[2]; + dv_ITGx = dv_ITG[0]; dv_ITGy = dv_ITG[1]; dv_ITGz = dv_ITG[2]; diff --git a/include/utils.h b/include/utils.h index dff58d2d..e9bbb841 100644 --- a/include/utils.h +++ b/include/utils.h @@ -140,7 +140,10 @@ int regrid2dCDF(int nX, int nY, int nZ,gitr_precision* xGrid,int nNew,gitr_preci int importLibConfig(libconfig::Config &cfg,std::string filepath); int importVectorFieldNs(libconfig::Config &cfg,std::string input_path,int interpDim,std::string fieldCfgString,int &nR, int &nY,int &nZ,std::string &fileToRead); int importVectorField(libconfig::Config &cfg,std::string input_path,int interpDim,std::string fieldCfgString,int nR, int nY,int nZ,gitr_precision &gridR,gitr_precision &gridY,gitr_precision &gridZ,gitr_precision &r, gitr_precision &y,gitr_precision &z,std::string &fileToRead); -int importGeometry(libconfig::Config &cfg,sim::Array &boundaries); + +int importGeometry(libconfig::Config &cfg,sim::Array &boundaries, int use_3d_geom, + int cylsymm, int surface_potential ); + int read_ar2Input( std::string fileName, gitr_precision *Bfield[]); int read_profileNs( std::string fileName,std::string nzName,std::string nxName,int &n_x,int &n_z ); @@ -165,5 +168,5 @@ int readFileDim(const std::string& fileName,const std::string& varName); int ncdfIO(int rwCode,const std::string& fileName,std::vector< std::string> dimNames,std::vector dims, std::vector< std::string> gridNames,std::vector gridMapToDims,std::vector pointers, std::vector< std::string> intVarNames,std::vector> intVarDimMap, std::vector intVarPointers); -int importHashNs(libconfig::Config &cfg,std::string input_path,int nHashes,std::string fieldCfgString,int *nR, int *nY,int *nZ,int *n,int &nRTotal,int &nYTotal,int &nZTotal,int *nHashPoints, int &nHashPointsTotal,int &nGeomHash); +int importHashNs(libconfig::Config &cfg,std::string input_path,int nHashes,std::string fieldCfgString,int *nR, int *nY,int *nZ,int *n,int &nRTotal,int &nYTotal,int &nZTotal,int *nHashPoints, int &nHashPointsTotal,int &nGeomHash, int use_3d_geom ); #endif diff --git a/libconfig_instances.txt b/libconfig_instances.txt new file mode 100644 index 00000000..4aac42cf --- /dev/null +++ b/libconfig_instances.txt @@ -0,0 +1,129 @@ +./tasks.txt:14: safe replacement for libconfig. +./tasks.txt:16: - make a list of every libconfig invocation and how it can be replaced with json +./tasks.txt:18: - make a list of all the places that libconfig is used +Binary file ./src/.gitr.cpp.swp matches +./src/utils.cpp:2:#include "libconfig.h++" +./src/utils.cpp:13:#include "libconfig.h++" +./src/utils.cpp:37:using namespace libconfig; +./src/utils.cpp:72:void checkFlags(libconfig::Config &cfg) +./src/utils.cpp:177:T getVariable (libconfig::Config &cfg,const std::string& s, T &a) +./src/utils.cpp:192:template int getVariable(libconfig::Config &cfg,const std::string& s, int &a); +./src/utils.cpp:193:template float getVariable(libconfig::Config &cfg,const std::string& s, float &a); +./src/utils.cpp:194:template double getVariable(libconfig::Config &cfg,const std::string& s, double &a); +./src/utils.cpp:195:template std::string getVariable(libconfig::Config &cfg,const std::string& s, std::string &a); +./src/utils.cpp:198:T get_variable(libconfig::Config &cfg, const std::string s) { +./src/utils.cpp:209:template int get_variable(libconfig::Config &cfg, const std::string s); +./src/utils.cpp:210:template float get_variable(libconfig::Config &cfg, const std::string s); +./src/utils.cpp:211:template double get_variable(libconfig::Config &cfg, const std::string s); +./src/utils.cpp:212:template const char* get_variable(libconfig::Config &cfg, const std::string s); +./src/utils.cpp:215:T getVariable_cfg (libconfig::Config &cfg,const std::string& s) +./src/utils.cpp:230:template int getVariable_cfg(libconfig::Config &cfg,const std::string& s); +./src/utils.cpp:231:template unsigned int getVariable_cfg(libconfig::Config &cfg,const std::string& s); +./src/utils.cpp:232:template float getVariable_cfg(libconfig::Config &cfg,const std::string& s); +./src/utils.cpp:233:template double getVariable_cfg(libconfig::Config &cfg,const std::string& s); +./src/utils.cpp:234:template std::string getVariable_cfg(libconfig::Config &cfg,const std::string& s); +./src/utils.cpp:236:int getDimFromFile (libconfig::Config &cfg,const std::string& file,const std::string& section, +./src/utils.cpp:443:int importLibConfig(libconfig::Config &cfg, std::string filepath) +./src/utils.cpp:460: std::cout << "Finished libconfig import "<< filepath.c_str() << std::endl; +./src/utils.cpp:464:int importVectorFieldNs(libconfig::Config &cfg,std::string input_path,int interpDim,std::string fieldCfgString,int &nR, int &nY,int &nZ,std::string &fileToRead) +./src/utils.cpp:482:int importVectorField(libconfig::Config &cfg,std::string input_path,int interpDim,std::string fieldCfgString,int nR, int nY,int nZ,gitr_precision &gridR,gitr_precision &gridY,gitr_precision &gridZ,gitr_precision &r, gitr_precision &y,gitr_precision &z,std::string &fileToRead) +./src/utils.cpp:507:int importGeometry(libconfig::Config &cfg_geom, sim::Array &boundaries) +./src/utils.cpp:620:int importHashNs(libconfig::Config &cfg,std::string input_path,int nHashes,std::string fieldCfgString,int *nR, int *nY,int *nZ,int *n,int &nRTotal,int &nYTotal,int &nZTotal,int *nHashPoints, int &nHashPointsTotal,int &nGeomHash) +./src/fields.cpp:18:Field::Field(libconfig::Config &cfg, std::string field_name) { +./src/curandInitialize.cpp:12:#include "libconfig.h++" +./src/flags.cpp:11:bool Flags::initialize_flags(libconfig::Config &cfg,std::string s) +./src/config_interface.cpp:3:libconfig_string_query::libconfig_string_query( std::string libconfig_file ) +./src/config_interface.cpp:8: cfg.readFile( libconfig_file.c_str() ); +./src/config_interface.cpp:11: catch(const libconfig::FileIOException &fioex) +./src/config_interface.cpp:16: catch(const libconfig::ParseException &pex) +./src/config_interface.cpp:42:impurity_particle_source( class libconfig_string_query const &query, +./src/config_interface.cpp:75: ionization_process( class libconfig_string_query const &query, +./src/config_interface.cpp:89:use::use( class libconfig_string_query const &query, +./src/config_interface.cpp:142:config_module_base::config_module_base( class libconfig_string_query const &query, +./src/setup.cpp:6:#include +./src/setup.cpp:11:void INIT(int nP, Particle p[], libconfig::Config &cfg) +./src/gitr.cpp:35:#include +./src/gitr.cpp:97: class libconfig_string_query query( "input/gitrInput.cfg" ); +./src/gitr.cpp:143: libconfig::Config cfg, cfg_geom; +./src/gitr.cpp:267: libconfig::Setting &geom = cfg_geom.lookup("geom"); +./src/gitr.cpp:273: } catch (const libconfig::SettingNotFoundException &nfex) { +./src/gitr.cpp:468: libconfig::Setting& geomHash = cfg.lookup("geometry_hash"); +./src/gitr.cpp:554: libconfig::Setting &geomHash = cfg.lookup("geometry_hash"); +./src/gitr.cpp:616: libconfig::Setting &geomHash = cfg.lookup("geometry_hash"); +./src/gitr.cpp:3340: libconfig::Config cfg_particles; +./include/flags.hpp:10:#include "libconfig.h++" +./include/flags.hpp:21: Flags(libconfig::Config &cfg) : +./include/flags.hpp:25: bool initialize_flags(libconfig::Config &cfg, std::string s); +./include/curandInitialize2.h:12:#include "libconfig.h++" +./include/h1.cuh:13:#include "libconfig.h++" +./include/h1.cuh:26:void INIT(int nP, Particle p[], libconfig::Config &cfg); +./include/Fields.h:18:#include +./include/Fields.h:48: CUDA_CALLABLE_MEMBER Field(libconfig::Config &cfg, std::string field_name); +./include/Particles.h:13:#include +./include/Particles.h:251: Particles(std::size_t nP,std::size_t nStreams,libconfig::Config &cfg, Flags *gitr_flags) : +./include/config_interface.h:7:#include "libconfig.h++" +./include/config_interface.h:9:/* This class wraps the libconfig object and inserts +./include/config_interface.h:16:class libconfig_string_query +./include/config_interface.h:20: libconfig_string_query( std::string libconfig_file = "" ); +./include/config_interface.h:36: libconfig::Config cfg; +./include/config_interface.h:43: config_module_base( class libconfig_string_query const &query, +./include/config_interface.h:69: class libconfig_string_query const &query; +./include/config_interface.h:87: ionization_process( class libconfig_string_query const &query, +./include/config_interface.h:102: impurity_particle_source( class libconfig_string_query const &query, +./include/config_interface.h:160: use( class libconfig_string_query const &query, +./include/utils.h:19:#include "libconfig.h++" +./include/utils.h:20:#include +./include/utils.h:29:void checkFlags(libconfig::Config &cfg); +./include/utils.h:40:T getVariable (libconfig::Config &cfg,const std::string& s, T &a); +./include/utils.h:42:T getVariable_cfg (libconfig::Config &cfg,const std::string& s); +./include/utils.h:44:extern template int getVariable(libconfig::Config &cfg,const std::string& s, int &a); +./include/utils.h:45:extern template float getVariable(libconfig::Config &cfg,const std::string& s, float &a); +./include/utils.h:46:extern template double getVariable(libconfig::Config &cfg,const std::string& s, double &a); +./include/utils.h:47:extern template std::string getVariable(libconfig::Config &cfg,const std::string& s, std::string &a); +./include/utils.h:50:P get_variable(libconfig::Config &cfg, const std::string s); +./include/utils.h:52:extern template int get_variable(libconfig::Config &cfg, const std::string s); +./include/utils.h:53:extern template float get_variable(libconfig::Config &cfg, const std::string s); +./include/utils.h:54:extern template double get_variable(libconfig::Config &cfg, const std::string s); +./include/utils.h:55:extern template const char* get_variable(libconfig::Config &cfg, const std::string s); +./include/utils.h:129:int getVarFromFile (libconfig::Config &cfg,const std::string& file,const std::string& section, +./include/utils.h:137:int getDimFromFile(libconfig::Config &cfg,const std::string& file,const std::string& section,const std::string& s); +./include/utils.h:140:int importLibConfig(libconfig::Config &cfg,std::string filepath); +./include/utils.h:141:int importVectorFieldNs(libconfig::Config &cfg,std::string input_path,int interpDim,std::string fieldCfgString,int &nR, int &nY,int &nZ,std::string &fileToRead); +./include/utils.h:142:int importVectorField(libconfig::Config &cfg,std::string input_path,int interpDim,std::string fieldCfgString,int nR, int nY,int nZ,gitr_precision &gridR,gitr_precision &gridY,gitr_precision &gridZ,gitr_precision &r, gitr_precision &y,gitr_precision &z,std::string &fileToRead); +./include/utils.h:143:int importGeometry(libconfig::Config &cfg,sim::Array &boundaries); +./include/utils.h:168:int importHashNs(libconfig::Config &cfg,std::string input_path,int nHashes,std::string fieldCfgString,int *nR, int *nY,int *nZ,int *n,int &nRTotal,int &nYTotal,int &nZTotal,int *nHashPoints, int &nHashPointsTotal,int &nGeomHash); +./include/curandInitialize.h:12:#include "libconfig.h++" +./test_src/atomic_tests.cpp:46: libconfig::Config cfg; +./test_src/atomic_tests.cpp:229: libconfig::Config cfg; +./test_src/atomic_tests.cpp:408: libconfig::Config cfg; +./test_src/field_tests.cpp:25: libconfig::Config cfg; +./test_src/field_tests.cpp:43: libconfig::Config cfg; +./test_src/file_io_tests.cpp:3:#include +./test_src/file_io_tests.cpp:20: libconfig::Config cfg; +./test_src/file_io_tests.cpp:35: libconfig::Config cfg; +./test_src/file_io_tests.cpp:52: libconfig::Config cfg; +./test_src/file_io_tests.cpp:69: libconfig::Config cfg; +./test_src/file_io_tests.cpp:82: libconfig::Config cfg,cfg_geom; +./test_src/file_io_tests.cpp:90: libconfig::Setting &geom = cfg_geom.lookup("geom"); +./test_src/file_io_tests.cpp:96: } catch (const libconfig::SettingNotFoundException &nfex) { +./test_src/file_io_tests.cpp:137: libconfig::Config cfg, cfg_geom; +./test_src/file_io_tests.cpp:145: libconfig::Setting &geom = cfg_geom.lookup("geom"); +./test_src/file_io_tests.cpp:151: } catch (const libconfig::SettingNotFoundException &nfex) { +./test_src/file_io_tests.cpp:223: libconfig::Config cfg,cfg_geom; +./test_src/file_io_tests.cpp:231: libconfig::Setting &geom = cfg_geom.lookup("geom"); +./test_src/file_io_tests.cpp:237: } catch (const libconfig::SettingNotFoundException &nfex) { +./test_src/boris_tests.cpp:256: libconfig::Config cfg_geom; +./test_src/boris_tests.cpp:497: libconfig::Config cfg_geom; +./test_src/boris_tests.cpp:679: libconfig::Config cfg_geom; +./test_src/cross_field_diffusion_tests.cpp:55: libconfig::Config cfg_geom; +./test_src/cross_field_diffusion_tests.cpp:65: libconfig::Setting &geom = cfg_geom.lookup( "geom" ); +./test_src/cross_field_diffusion_tests.cpp:72: libconfig::Setting &impurity = cfg_geom.lookup( "impurityParticleSource" ); +./test_src/cross_field_diffusion_tests.cpp:277: libconfig::Config cfg_geom; +./test_src/cross_field_diffusion_tests.cpp:287: libconfig::Setting &geom = cfg_geom.lookup( "geom" ); +./test_src/cross_field_diffusion_tests.cpp:294: libconfig::Setting &impurity = cfg_geom.lookup( "impurityParticleSource" ); +./test_src/surface_model_tests.cpp:50: libconfig::Config cfg; +./test_src/surface_model_tests.cpp:58: libconfig::Setting &impurity = cfg.lookup( "impurityParticleSource" ); +./test_src/coulomb_tests.cpp:224: libconfig::Config cfg; +./test_src/coulomb_tests.cpp:351: libconfig::Config cfg; +./test_src/config_interface_tests.cpp:12: class libconfig_string_query query( CONFIG_INTERFACE_UNIT_TEST_FILE ); +./test_src/config_interface_tests.cpp:14: SECTION( "read raw libconfig data" ) diff --git a/options.txt b/options.txt new file mode 100644 index 00000000..d096cbef --- /dev/null +++ b/options.txt @@ -0,0 +1,303 @@ +important info for repeating Alyssa's results: + +solps-iter-data +pygitr + +both help with preprocessing stuff + +GITR_processing has the actual input/output + +customer service: + +cancel sirius xm radio service: + +866 635 2349 + +account number: 489 721 1916 98 + +Captain!!! Could we make GITR into a conda environment? Then simply wrap it in a script and +then... read it into Galaxy? Could that be possible? Have to get rid of netcdf first... + +You'd need to figure out how to make a conda package for HPC code? + +Today: + +1. Line up test cases from Tim. Hook into CTest. +2. Convert to build-time variables with runtime control flow ---> runtime vars runtime cflow +3. Migrate the options.txt file to the README +4. Add a link in the README to the GITR_processing repo +5. Tag a new release of GITR, submit for testing on the gitr channel + +Later: + +6. Start an issue-thon? +7. Ask about removing netcdf and multi-species/time-dependence tests? Similar to the Tim ones? +8. Meet with JonChan and Kurte Kudeep and Marthi if possible to talk about AGILE? +9. Work on the C++ file? Do it on Gitlab? +10. Do Galaxy stuff + + + +SECTION FOR MULTI-DIM: + +output histograms for GITR: + +spec.nc + +surface.nc + +new convention: +netX0 to netX1 is endpoints and net_nX + + +SECTION FOR OPTIONS: + +set( description "(no description added - see define_options.cmake)" ) + +system: + +set( GITR_USE_CUDA 1 CACHE STRING "${description}" ) +set( GITR_USE_MPI 0 CACHE STRING "${description}" ) +set( GITR_USE_DOUBLE 1 CACHE STRING "${description}" ) + + +on/off only - they can only be 1 or 0 and have to be the same + +set( GITR_USE_IONIZATION 1 CACHE STRING "${description}" ) # if ionization is on, recombination on +set( GITR_USE_RECOMBINATION 1 CACHE STRING "${description}" ) + + +0 - off +1 - straight field lines diffusion +(greater than 1) - curved field line diffusion +effectively 0 if ionization recombination are 0 + +set( GITR_USE_PERP_DIFFUSION 1 CACHE STRING "${description}" ) + + +any permutation of these is sensible/allowed +these use input profiles +these are also binary options - only 0 or 1 + +set( GITR_USE_COULOMB_COLLISIONS 1 CACHE STRING "${description}" ) # if collisions are on, friction, scattering, heating. Thus just delete those 3 +set( GITR_USE_FRICTION 1 CACHE STRING "${description}" ) +set( GITR_USE_ANGLE_SCATTERING 1 CACHE STRING "${description}" ) +set( GITR_USE_HEATING 1 CACHE STRING "${description}" ) + +can be 0 or 1 - another binary option +gradt_interp - uses 0 or 2 for constant or 2-dimensional +1: turn on, activates gradt_interp which can be 0 or 2 +0: off, gradt_interp is ignored + +set( GITR_USE_THERMAL_FORCE 0 CACHE STRING "${description}" ) + + + +binary option: +0: on +1: off +set( GITR_USE_SURFACE_MODEL 1 CACHE STRING "${description}" ) + + +0: on +1: off + +set( GITR_USE_SHEATH_EFIELD 1 CACHE STRING "${description}" ) + + +0: on +1: off + +this option is enabled by use_sheath_efield + +set( GITR_BIASED_SURFACE 0 CACHE STRING "${description}" ) + + +same as above, enabled by use_sheath_efield +0: on +1: off +should be mutually exclusive with biased surface. Only 1 should be on. +set( GITR_USE_SURFACE_POTENTIAL 0 CACHE STRING "${description}" ) + +enables particular input, additional electric field. Enables another option, +Efield_interp. If on, efield_interp specifies constant from input file +or 2 which comes from an interpolatable data field +0: off +1: on - efield_interp which can be 0 or 2 + +needs to be changed to just "use_efield" +0: off +1: on +set( GITR_USE_PRE_SHEATH_EFIELD 0 CACHE STRING "${description}" ) + +note: USE_* is 0 or 1, binary option. +interp: specifies some dimensionality, 0 or 2, constant vs data field interpolation + + +always should be on: there's no parent option here +set( GITR_BFIELD_INTERP 0 CACHE STRING "${description}" ) + + +the next 3 are used by coulomb collisions + +you need a temperature and density for ionization/recombination + +temperature, density, and flowvelocity for coulombcollisions + +set( GITR_TEMP_INTERP 2 CACHE STRING "${description}" ) +set( GITR_DENSITY_INTERP 2 CACHE STRING "${description}" ) +set( GITR_FLOWV_INTERP 0 CACHE STRING "${description}" ) + +set( GITR_GRADT_INTERP 0 CACHE STRING "${description}" ) + +deprecated +set( GITR_LC_INTERP 0 CACHE STRING "${description}" ) + +combine into 1 option +0: +>1: +set( GITR_EFIELD_INTERP 0 CACHE STRING "${description}" ) +set( GITR_PRE_SHEATH_INTERP 0 CACHE STRING "${description}" ) + +hidden option +set( GITR_GENERATE_LC 0 CACHE STRING "${description}" ) + +hidden option +set( GITR_ODE_INT 0 CACHE STRING "${description}" ) + +obvious option +set( GITR_FIXED_SEEDS 1 CACHE STRING "${description}" ) + +always on +set( GITR_PARTICLE_SEEDS 1 CACHE STRING "${description}" ) + +hiding? or deprecating. Not great for comparision +set( GITR_GEOM_TRACE 0 CACHE STRING "${description}" ) + + +0: don't use at all +1: create a new hash depending on use_3d_tet_geom is? +2: read in previously created 2d hash +3: read in previously created 3d hash + +set( GITR_GEOM_HASH 0 CACHE STRING "${description}" ) +set( GITR_GEOM_HASH_SHEATH 0 CACHE STRING "${description}" ) + + +recording things. Possibly not compatible with use_sort. +Might create a black hole + +set( GITR_PARTICLE_TRACKS 0 CACHE STRING "${description}" ) + + +creates checkable output file: + +0: don't create + +2: create 2d version + +3: create 3d version? + +histogram of density +affected somewhat by use_cylsymm, using r and z. So negative r doesn't make sense. +set( GITR_SPECTROSCOPY 2 CACHE STRING "${description}" ) + +binary variable +0: 3d off, 2d +1: 3d on, 3d +set( GITR_USE_3DTET_GEOM 0 CACHE STRING "${description}" ) + +variables: + +r t z + +0: x y z + +1: r t z + +cylindrical symm will project 2d geometries and profiles in theta direction ( toroidally ) +if 3d_tet is on: does this for profiles, but not geometry. Because 3d geom is already in +3d no projection for curvature is needed. + +profiles.nc is the only thing that is ever projected to cylindrical. 2d geometry is also +projected if cylsymm is on. + +set( GITR_USE_CYLSYMM 0 CACHE STRING "${description}" ) + +deprecated +set( GITR_USE_FIELD_ALIGNED_VALUES 0 CACHE STRING "${description}" ) + +data collection file +set( GITR_FLUX_EA 1 CACHE STRING "${description}" ) + +not super important +set( GITR_FORCE_EVAL 0 CACHE STRING "${description}" ) + +on or off: keeps the same number of particles in the simulation +all stuff + +1: every 10k steps, stop, examine deposited particles, stop tracking them. +0: don't exclude particles based on weight thresholds + +set( GITR_USE_SORT 0 CACHE STRING "${description}" ) + +set( GITR_CHECK_COMPATIBILITY 1 CACHE STRING "${description}" ) + +all should be combined into 1 option, is it a file or not? +directly from input file (point) +or is it coming from a file. Initial positions and velocities. +checkpointing +set( GITR_PARTICLE_SOURCE 0 CACHE STRING "${description}" ) +set( GITR_PARTICLE_SOURCE_SPACE 0 CACHE STRING "${description}" ) +set( GITR_PARTICLE_SOURCE_ENERGY 0 CACHE STRING "${description}" ) +set( GITR_PARTICLE_SOURCE_ANGLE 0 CACHE STRING "${description}" ) +set( GITR_PARTICLE_SOURCE_FILE 0 CACHE STRING "${description}" ) + +Everything below is just uneccesary information + +add_compile_definitions( + USE_CUDA=${GITR_USE_CUDA} + USE_MPI=${GITR_USE_MPI} + USE_DOUBLE=${GITR_USE_DOUBLE} + USEIONIZATION=${GITR_USE_IONIZATION} + USERECOMBINATION=${GITR_USE_RECOMBINATION} + USEPERPDIFFUSION=${GITR_USE_PERP_DIFFUSION} + USECOULOMBCOLLISIONS=${GITR_USE_COULOMB_COLLISIONS} + USEFRICTION=${GITR_USE_FRICTION} + USEANGLESCATTERING=${GITR_USE_ANGLE_SCATTERING} + USEHEATING=${GITR_USE_HEATING} + USETHERMALFORCE=${GITR_USE_THERMAL_FORCE} + USESURFACEMODEL=${GITR_USE_SURFACE_MODEL} + USESHEATHEFIELD=${GITR_USE_SHEATH_EFIELD} + BIASED_SURFACE=${GITR_BIASED_SURFACE} + USE_SURFACE_POTENTIAL=${GITR_USE_SURFACE_POTENTIAL} + USEPRESHEATHEFIELD=${GITR_USE_PRE_SHEATH_EFIELD} + BFIELD_INTERP=${GITR_BFIELD_INTERP} + LC_INTERP=${GITR_LC_INTERP} + GENERATE_LC=${GITR_GENERATE_LC} + EFIELD_INTERP=${GITR_EFIELD_INTERP} + PRESHEATH_INTERP=${GITR_PRE_SHEATH_INTERP} + DENSITY_INTERP=${GITR_DENSITY_INTERP} + TEMP_INTERP=${GITR_TEMP_INTERP} + FLOWV_INTERP=${GITR_FLOWV_INTERP} + GRADT_INTERP=${GITR_GRADT_INTERP} + ODEINT=${GITR_ODE_INT} + FIXEDSEEDS=${GITR_FIXED_SEEDS} + PARTICLESEEDS=${GITR_PARTICLE_SEEDS} + GEOM_TRACE=${GITR_GEOM_TRACE} + GEOM_HASH=${GITR_GEOM_HASH} + GEOM_HASH_SHEATH=${GITR_GEOM_HASH_SHEATH} + PARTICLE_TRACKS=${GITR_PARTICLE_TRACKS} + PARTICLE_SOURCE=${GITR_PARTICLE_SOURCE} + PARTICLE_SOURCE_SPACE=${GITR_PARTICLE_SOURCE_SPACE} + PARTICLE_SOURCE_ENERGY=${GITR_PARTICLE_SOURCE_ENERGY} + PARTICLE_SOURCE_ANGLE=${GITR_PARTICLE_SOURCE_ANGLE} + PARTICLE_SOURCE_FILE=${GITR_PARTICLE_SOURCE_FILE} + SPECTROSCOPY=${GITR_SPECTROSCOPY} + USE3DTETGEOM=${GITR_USE_3DTET_GEOM} + USECYLSYMM=${GITR_USE_CYLSYMM} + USEFIELDALIGNEDVALUES=${GITR_USE_FIELD_ALIGNED_VALUES} + FLUX_EA=${GITR_FLUX_EA} + FORCE_EVAL=${GITR_FORCE_EVAL} + USE_SORT=${GITR_USE_SORT} + CHECK_COMPATIBILITY=${GITR_CHECK_COMPATIBILITY}) diff --git a/src/boris.cpp b/src/boris.cpp index 32a43edd..086d9af1 100644 --- a/src/boris.cpp +++ b/src/boris.cpp @@ -86,15 +86,23 @@ CUDA_CALLABLE_MEMBER gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, gitr_precision E[], Boundary *boundaryVector, int nLines, int nR_closeGeom, int nY_closeGeom,int nZ_closeGeom, int n_closeGeomElements, gitr_precision *closeGeomGridr,gitr_precision *closeGeomGridy, gitr_precision *closeGeomGridz, int *closeGeom, - int& closestBoundaryIndex) { -#if USE3DTETGEOM > 0 + int& closestBoundaryIndex, int biased_surface, int use_3d_geom, + int geom_hash_sheath, int cylsymm ) + { + + gitr_precision pot = 0.0; + int minIndex = 0; + gitr_precision minDistance = 1.0e12; gitr_precision Emag = 0.0; + gitr_precision angle = 0.0; + gitr_precision fd = 0.0; + gitr_precision directionUnitVector[ 3 ] = { 0.0, 0.0, 0.0 }; gitr_precision Er = 0.0; gitr_precision Et = 0.0; + + if( use_3d_geom > 0 ) + { gitr_precision p0[3] = {x0,y,z}; - gitr_precision angle = 0.0; - gitr_precision fd = 0.0; - gitr_precision pot = 0.0; gitr_precision a = 0.0; gitr_precision b = 0.0; gitr_precision c = 0.0; @@ -129,7 +137,6 @@ gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, git gitr_precision crossABAp[3] = {0.0,0.0,0.0}; gitr_precision crossBCBp[3] = {0.0,0.0,0.0}; gitr_precision crossCACp[3] = {0.0,0.0,0.0}; - gitr_precision directionUnitVector[3] = {0.0,0.0,0.0}; gitr_precision dot0 = 0.0; gitr_precision dot1 = 0.0; gitr_precision dot2 = 0.0; @@ -154,58 +161,66 @@ gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, git gitr_precision signDot1 = 0.0; gitr_precision signDot2 = 0.0; gitr_precision totalSigns = 0.0; - gitr_precision minDistance = 1.0e12; + minDistance = 1.0e12; int nBoundariesCrossed = 0; int boundariesCrossed[6] = {0,0,0,0,0,0}; - int minIndex=0; gitr_precision distances[7] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0}; gitr_precision normals[21] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0}; -#if GEOM_HASH_SHEATH > 0 - gitr_precision dr = closeGeomGridr[1] - closeGeomGridr[0]; - gitr_precision dy = closeGeomGridy[1] - closeGeomGridy[0]; - gitr_precision dz = closeGeomGridz[1] - closeGeomGridz[0]; - int rInd = std::floor((x0 - closeGeomGridr[0])/dr + 0.5); - int yInd = std::floor((y - closeGeomGridy[0])/dy + 0.5); - int zInd = std::floor((z - closeGeomGridz[0])/dz + 0.5); - int i; - if(rInd < 0 || rInd >= nR_closeGeom) - rInd =0; - if(yInd < 0 || yInd >= nY_closeGeom) - yInd =0; - if(zInd < 0 || zInd >= nZ_closeGeom) - zInd =0; - - for (int k=0; k< n_closeGeomElements; k++) //n_closeGeomElements + int top_limit = -1; + + gitr_precision dr; + gitr_precision dy; + gitr_precision dz; + + int rInd; + int yInd; + int zInd; + + if( geom_hash_sheath > 0 ) + { + dr = closeGeomGridr[1] - closeGeomGridr[0]; + dy = closeGeomGridy[1] - closeGeomGridy[0]; + dz = closeGeomGridz[1] - closeGeomGridz[0]; + rInd = std::floor((x0 - closeGeomGridr[0])/dr + 0.5); + yInd = std::floor((y - closeGeomGridy[0])/dy + 0.5); + zInd = std::floor((z - closeGeomGridz[0])/dz + 0.5); + + if(rInd < 0 || rInd >= nR_closeGeom) rInd =0; + + if(yInd < 0 || yInd >= nY_closeGeom) yInd =0; + + if(zInd < 0 || zInd >= nZ_closeGeom) zInd =0; + + top_limit = n_closeGeomElements; + } + + else top_limit = nLines; + + for (int k=0; k < top_limit; k++) //n_closeGeomElements + { + int i = -1; + + if( geom_hash_sheath > 0 ) { i = closeGeom[zInd*nY_closeGeom*nR_closeGeom*n_closeGeomElements + yInd*nR_closeGeom*n_closeGeomElements + rInd*n_closeGeomElements + k]; - //closestBoundaryIndex = i; - //std::cout << "closest boundaries to check " << i << std::endl; -#else - for (int i=0; i 0.0) && (tAB < normAB)) { vectorScalarMult(tAB,ABhat,projP0AB); @@ -363,16 +342,8 @@ gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, git //if (fabs(pointToPlaneDistance0) < minDistance) //{ perpDist = std::abs(pointToPlaneDistance0); - //minDistance = fabs(pointToPlaneDistance0); - //std::cout << "p " << p[0] << " " << p[1] << " " << p[2] << std::endl; - //std::cout << "p0 " << p0[0] << " " << p0[1] << " " << p0[2] << std::endl; vectorSubtract(p,p0 ,normalVector); - //std::cout << "unit vec " << directionUnitVector[0] << " " << directionUnitVector[1] << - // " " << directionUnitVector[2] << std::endl; vectorNormalize(normalVector,normalVector); - //std::cout << "unit vec " << directionUnitVector[0] << " " << directionUnitVector[1] << - // " " << directionUnitVector[2] << std::endl; - //std::cout << "perp distance " << std::endl; distances[0] = perpDist; normals[0] = boundaryVector[i].unit_vec0; //normalVector[0]; normals[1] = boundaryVector[i].unit_vec1; //normalVector[1]; @@ -383,59 +354,6 @@ gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, git { perpDist = 1.0e12; distances[0] = perpDist; - /* - if (p0Anorm < p0Bnorm) - { - if (p0Anorm < p0Cnorm) - { - if (p0Anorm < minDistance) - { - minDistance = p0Anorm; - vectorAssign(p0A[0]/p0Anorm,p0A[1]/p0Anorm,p0A[2]/p0Anorm, - directionUnitVector); - minIndex = i; - std::cout << "p0A " << std::endl; - } - } - else - { - if (p0Cnorm < minDistance) - { - minDistance = p0Cnorm; - vectorAssign(p0C[0]/p0Cnorm,p0C[1]/p0Cnorm,p0C[2]/p0Cnorm, - directionUnitVector); - minIndex = i; - std::cout << "p0C " << p0Cnorm << std::endl; - } - } - } - else - { - if (p0Bnorm < p0Cnorm) - { - if (p0Bnorm < minDistance) - { - minDistance = p0Bnorm; - vectorAssign(p0B[0]/p0Bnorm,p0B[1]/p0Bnorm,p0B[2]/p0Bnorm, - directionUnitVector); - minIndex = i; - std::cout << "p0B " << std::endl; - } - } - else - { - if (p0Cnorm < minDistance) - { - minDistance = p0Cnorm; - vectorAssign(p0C[0]/p0Cnorm,p0C[1]/p0Cnorm,p0C[2]/p0Cnorm, - directionUnitVector); - minIndex = i; - std::cout << "p0C two " << std::endl; - } - } - - } - */ } int index = 0; for(int j = 0; j < 7; j++) @@ -455,10 +373,8 @@ gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, git closestBoundaryIndex = i; minIndex = i; } - //std::cout << "perp dist " << perpDist << std::endl; - //std::cout << "point to AB BC CA " << p0ABdist << " " << p0BCdist << " " << p0CAdist << std::endl; - //} - } + } + if(isnan(directionUnitVector[0]) || isnan(directionUnitVector[1]) || isnan(directionUnitVector[2])){ //printf("minDist %f \n", minDistance); //printf("directionV %f %f %f \n", directionUnitVector[0],directionUnitVector[1],directionUnitVector[2]); @@ -468,57 +384,70 @@ gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, git } //vectorScalarMult(-1.0,directionUnitVector,directionUnitVector); //std::cout << "min dist " << minDistance << std::endl; -#else //2dGeom + } + else + { - gitr_precision Emag = 0.0; - gitr_precision fd = 0.0; - gitr_precision pot = 0.0; - int minIndex = 0; - gitr_precision minDistance = 1e12; int direction_type; gitr_precision tol = 1e12; gitr_precision point1_dist; gitr_precision point2_dist; gitr_precision perp_dist; - gitr_precision directionUnitVector[3] = {0.0,0.0,0.0}; gitr_precision vectorMagnitude; gitr_precision max = 0.0; gitr_precision min = 0.0; - gitr_precision angle = 0.0; - gitr_precision Er = 0.0; - gitr_precision Et = 0.0; gitr_precision Bfabsfperp = 0.0; gitr_precision distanceToParticle = 0.0; int pointLine=0; -//#if EFIELD_INTERP ==1 -#if USECYLSYMM > 0 - gitr_precision x = std::sqrt(x0*x0 + y*y); -#else - gitr_precision x = x0; -#endif - -#if GEOM_HASH_SHEATH > 0 - gitr_precision dr = closeGeomGridr[1] - closeGeomGridr[0]; - gitr_precision dz = closeGeomGridz[1] - closeGeomGridz[0]; - int rInd = std::floor((x - closeGeomGridr[0])/dr + 0.5); - int zInd = std::floor((z - closeGeomGridz[0])/dz + 0.5); + gitr_precision x; + if( cylsymm > 0 ) + { + x = std::sqrt(x0*x0 + y*y); + } + else + { + x = x0; + } + + int top_limit = -1; + gitr_precision dr; + gitr_precision dz; + + int rInd; + int zInd; + + if( geom_hash_sheath > 0 ) + { + dr = closeGeomGridr[1] - closeGeomGridr[0]; + + dz = closeGeomGridz[1] - closeGeomGridz[0]; + + rInd = std::floor((x - closeGeomGridr[0])/dr + 0.5); + + zInd = std::floor((z - closeGeomGridz[0])/dz + 0.5); + if(rInd >= nR_closeGeom) rInd = nR_closeGeom -1; + if(zInd >= nZ_closeGeom) zInd = nZ_closeGeom -1; + if(rInd < 0) rInd = 0; + if(zInd < 0) zInd = 0; - int j; - for (int k=0; k< n_closeGeomElements; k++) //n_closeGeomElements + + top_limit = n_closeGeomElements; + } + + else top_limit = nLines; + + for( int k = 0; k < top_limit; k++) //n_closeGeomElements { + int j = -1; + + if( geom_hash_sheath > 0 ) j = closeGeom[zInd*nR_closeGeom*n_closeGeomElements + rInd*n_closeGeomElements + k]; -#else - for (int j=0; j< nLines; j++) - { //std::cout << " surface check " << j << std::endl; -#endif - //if(j > nLines) - //{ - // j = 0; - //} + else j = k; + gitr_precision boundZhere = boundaryVector[j].Z; if (boundZhere != 0.0) @@ -535,10 +464,6 @@ gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, git { perp_dist = x0 - boundaryVector[j].x1; } - //std::cout << " x0 z " << x0 << " " << z << " slope " << boundaryVector[j].slope_dzdx << " intercept " << boundaryVector[j].intercept_z << std::endl; - - //std::cout << " surface check " << j << " point1dist " << point1_dist << " point2_dist " << point2_dist << - // " perp_dist " << perp_dist << std::endl; if (point1_dist > point2_dist) { max = point1_dist; @@ -549,18 +474,14 @@ gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, git max = point2_dist; min = point1_dist; } - // std::cout << "p1dist p2dist perpDist " << point1_dist << " " << point2_dist << " " << perp_dist << std::endl; if (boundaryVector[j].length*boundaryVector[j].length + perp_dist*perp_dist >= max*max) { - //boundaryVector[j].distanceToParticle =fabsf( perp_dist); distanceToParticle = std::abs(perp_dist); - //boundaryVector[j].pointLine = 1; pointLine = 1; } else { - //boundaryVector[j].distanceToParticle = min; distanceToParticle = min; if (boundaryVector[j].distanceToParticle == point1_dist) { @@ -584,49 +505,6 @@ gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, git { distanceToParticle = tol; } - //int thisTmp=0; - //int Bperiodic = boundaryVector[minIndex].periodic; - //int BpointLine = boundaryVector[minIndex].pointLine; - //int BsurfaceNumber = boundaryVector[minIndex].surfaceNumber; - //int Bsurface = boundaryVector[minIndex].surface; - //gitr_precision Bx1 = boundaryVector[minIndex].x1; - //gitr_precision By1 = boundaryVector[minIndex].y1; - //gitr_precision Bz1 = boundaryVector[minIndex].z1; - //gitr_precision Bx2 = boundaryVector[minIndex].x2; - //gitr_precision By2 = boundaryVector[minIndex].y2; - //gitr_precision Bz2 = boundaryVector[minIndex].z2; - //gitr_precision Ba = boundaryVector[minIndex].a; - //gitr_precision Bb = boundaryVector[minIndex].b; - //gitr_precision Bc = boundaryVector[minIndex].c; - //gitr_precision Bd = boundaryVector[minIndex].d; - //gitr_precision Bplane_norm = boundaryVector[minIndex].plane_norm; - //#if USE3DTETGEOM > 0 - // gitr_precision Bx3 = boundaryVector[minIndex].x3; - // gitr_precision By3 = boundaryVector[minIndex].y3; - // gitr_precision Bz3 = boundaryVector[minIndex].z3; - // gitr_precision Barea = boundaryVector[minIndex].area; - //#else - // gitr_precision Bslope_dzdx = boundaryVector[minIndex].slope_dzdx; - // gitr_precision Bintercept_z = boundaryVector[minIndex].intercept_z; - //#endif - //gitr_precision BZ = boundaryVector[minIndex].Z; - //gitr_precision Bamu = boundaryVector[minIndex].amu; - //gitr_precision Bpotential = boundaryVector[minIndex].potential; - // - //gitr_precision BhitWall = boundaryVector[minIndex].hitWall; - //gitr_precision Blength = boundaryVector[minIndex].length; - //gitr_precision BdistanceToParticle = boundaryVector[minIndex].distanceToParticle; - //gitr_precision Bangle = boundaryVector[minIndex].angle; - //gitr_precision Bfd = boundaryVector[minIndex].fd; - //gitr_precision Bdensity = boundaryVector[minIndex].density; - //gitr_precision Bti = boundaryVector[minIndex].ti; - //gitr_precision Bne = boundaryVector[minIndex].ne; - //gitr_precision Bte = boundaryVector[minIndex].te; - //gitr_precision BdebyeLength = boundaryVector[minIndex].debyeLength; - //gitr_precision BlarmorRadius = boundaryVector[minIndex].larmorRadius; - // if(x0==0.0 && z > 1.0e-3 && minDistance<1.0e-9) - // thisTmp=1; - //std::cout << "min distance " << j << " " << minDistance << std::endl; } if (direction_type == 1) { @@ -648,23 +526,19 @@ gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, git directionUnitVector[0] = 1.0 * std::copysign(1.0,(z - boundaryVector[minIndex].intercept_z)/(boundaryVector[minIndex].slope_dzdx) - x0); directionUnitVector[1] = 0.0; directionUnitVector[2] = 1.0 * std::copysign(1.0,perp_dist)/(boundaryVector[minIndex].slope_dzdx); - //std::cout << "sign boundarVec.slope sign perp_dist " << sgn(boundaryVector[minIndex].slope_dzdx) << " " << sgn(perp_dist) << std::endl; } - //std::cout << "direction_type 1 " << directionUnitVector[0] << " " << directionUnitVector[1] << " " << directionUnitVector[2] << std::endl; } else if (direction_type == 2) { directionUnitVector[0] = (boundaryVector[minIndex].x1 - x); directionUnitVector[1] = 0.0; directionUnitVector[2] = (boundaryVector[minIndex].z1 - z); - //std::cout << "direction_type 2 " << directionUnitVector[0] << " " << directionUnitVector[1] << " " << directionUnitVector[2] << std::endl; } else { directionUnitVector[0] = (boundaryVector[minIndex].x2 - x); directionUnitVector[1] = 0.0; directionUnitVector[2] = (boundaryVector[minIndex].z2 - z); - //std::cout << "direction_type 3 " << directionUnitVector[0] << " " << directionUnitVector[1] << " " << directionUnitVector[2] << std::endl; } vectorMagnitude = std::sqrt(directionUnitVector[0]*directionUnitVector[0] + directionUnitVector[1]*directionUnitVector[1] @@ -672,40 +546,24 @@ gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, git directionUnitVector[0] = directionUnitVector[0]/vectorMagnitude; directionUnitVector[1] = directionUnitVector[1]/vectorMagnitude; directionUnitVector[2] = directionUnitVector[2]/vectorMagnitude; - //gitr_precision surfaceNormalVector[3] = {0.0}; - //boundaryVector[minIndex].getSurfaceNormal(surfaceNormalVector,y,x); - //directionUnitVector[0]= boundaryVector[minIndex].inDir*surfaceNormalVector[0]; - //directionUnitVector[1]= boundaryVector[minIndex].inDir*surfaceNormalVector[1]; - //directionUnitVector[2]= boundaryVector[minIndex].inDir*surfaceNormalVector[2]; - //vectorMagnitude = std::sqrt(directionUnitVector[0]*directionUnitVector[0] + directionUnitVector[1]*directionUnitVector[1] - // + directionUnitVector[2]*directionUnitVector[2]); - //directionUnitVector[0] = directionUnitVector[0]/vectorMagnitude; - //directionUnitVector[1] = directionUnitVector[1]/vectorMagnitude; - //directionUnitVector[2] = directionUnitVector[2]/vectorMagnitude; -#endif -#if BIASED_SURFACE > 0 + } + if( biased_surface > 0 ) + { pot = boundaryVector[minIndex].potential; Emag = pot/(2.0*boundaryVector[minIndex].ChildLangmuirDist)*exp(-minDistance/(2.0*boundaryVector[minIndex].ChildLangmuirDist)); -#else + } + else + { angle = boundaryVector[minIndex].angle; fd = boundaryVector[minIndex].fd; pot = boundaryVector[minIndex].potential; - //std::cout << "potential and debye length " << pot << " " << boundaryVector[minIndex].debyeLength << " " << pot/boundaryVector[minIndex].debyeLength << std::endl; - //std::cout << " larmorRad " << boundaryVector[minIndex].larmorRadius << std::endl; gitr_precision debyeLength = boundaryVector[minIndex].debyeLength; gitr_precision larmorRadius = boundaryVector[minIndex].larmorRadius; Emag = pot*(fd/(2.0 * boundaryVector[minIndex].debyeLength)*exp(-minDistance/(2.0 * boundaryVector[minIndex].debyeLength))+ (1.0 - fd)/(boundaryVector[minIndex].larmorRadius)*exp(-minDistance/boundaryVector[minIndex].larmorRadius) ); gitr_precision part1 = pot*(fd/(2.0 * boundaryVector[minIndex].debyeLength)*exp(-minDistance/(2.0 * boundaryVector[minIndex].debyeLength))); gitr_precision part2 = pot*(1.0 - fd)/(boundaryVector[minIndex].larmorRadius)*exp(-minDistance/boundaryVector[minIndex].larmorRadius); - //if(isnan(Emag)){ - //printf("Emag %f ", Emag); - //} - //if(isnan(directionUnitVector[0]) ||isnan(directionUnitVector[1]) || isnan(directionUnitVector[2]) ){ - //printf("direction %f %f %f \n", directionUnitVector[0],directionUnitVector[1],directionUnitVector[2]); - //} - //std::cout << "fd " << fd << std::endl; - //std::cout << "minDistance " << minDistance << std::endl; -#endif + } + /* Captain! This appears to be skipped? */ if(minDistance == 0.0 || boundaryVector[minIndex].larmorRadius == 0.0) { Emag = 0.0; @@ -725,21 +583,27 @@ gitr_precision getE ( gitr_precision x0, gitr_precision y, gitr_precision z, git //std::cout << "direction unit vector " << directionUnitVector[0] << " " << directionUnitVector[1] << " " << directionUnitVector[2] << std::endl; //std::cout << "pos " << x << " " << y << " "<< z << " min Dist" << minDistance << "Efield " << Emag << std::endl; -#if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { E[0] = Er; E[1] = Et; -#else -#if USECYLSYMM > 0 + } + else + { + if( cylsymm > 0 ) + { //if cylindrical geometry gitr_precision theta = std::atan2(y,x0); E[0] = std::cos(theta)*Er - std::sin(theta)*Et; E[1] = std::sin(theta)*Er + std::cos(theta)*Et; -#else + } + else + { E[0] = Er; E[1] = Et; -#endif -#endif + } + } //std::cout << "Ex and Ey and Ez " << E[0] << " " << E[1] << " " << E[2] << std::endl; return minDistance; @@ -776,6 +640,12 @@ move_boris::move_boris( gitr_precision *_closeGeomGridz, int *_closeGeom, Flags* _gitr_flags, + int sheath_efield_, + int presheath_efield_, + int biased_surface_, + int geom_hash_sheath_, + int use_3d_geom_, + int cylsymm_, gitr_precision _max_dt) : @@ -810,7 +680,14 @@ move_boris::move_boris( span(_span), nLines(_nLines), magneticForce{0.0, 0.0, 0.0}, - electricForce{0.0, 0.0, 0.0} {} + electricForce{0.0, 0.0, 0.0}, + sheath_efield( sheath_efield_ ), + presheath_efield( presheath_efield_ ), + biased_surface( biased_surface_ ), + geom_hash_sheath( geom_hash_sheath_ ), + use_3d_geom( use_3d_geom_ ), + cylsymm( cylsymm_ ) + {} CUDA_CALLABLE_MEMBER void move_boris::operator()(std::size_t indx) @@ -825,18 +702,14 @@ void move_boris::operator()(std::size_t indx) gitr_precision v_half_dt[3]= {0.0, 0.0, 0.0}; gitr_precision v[3]= {0.0, 0.0, 0.0}; gitr_precision E[3] = {0.0, 0.0, 0.0}; -#if USEPRESHEATHEFIELD > 0 gitr_precision PSE[3] = {0.0, 0.0, 0.0}; -#endif gitr_precision B[3] = {0.0,0.0,0.0}; gitr_precision Bmag = 0.0; gitr_precision gyrofrequency = 0.0; gitr_precision q_prime = 0.0; gitr_precision coeff = 0.0; -#if USESHEATHEFIELD > 0 gitr_precision minDist = 0.0; int closestBoundaryIndex; -#endif #if ODEINT == 0 gitr_precision qpE[3] = {0.0,0.0,0.0}; @@ -854,16 +727,19 @@ void move_boris::operator()(std::size_t indx) gitr_precision half_dt = 0.5*dt; gitr_precision new_dt = 0.0; gitr_precision new_advance = false; -#if USESHEATHEFIELD > 0 + if( sheath_efield > 0 ) + { minDist = getE(position[0], position[1], position[2], E,boundaryVector,nLines,nR_closeGeom_sheath, nY_closeGeom_sheath,nZ_closeGeom_sheath, n_closeGeomElements_sheath,closeGeomGridr_sheath, closeGeomGridy_sheath, - closeGeomGridz_sheath,closeGeom_sheath, closestBoundaryIndex); -#endif + closeGeomGridz_sheath,closeGeom_sheath, closestBoundaryIndex, + biased_surface, use_3d_geom, geom_hash_sheath, cylsymm ); + } -#if USEPRESHEATHEFIELD > 0 + if( presheath_efield > 0 ) + { /* #if LC_INTERP==3 @@ -883,15 +759,14 @@ void move_boris::operator()(std::size_t indx) */ interp2dVector(&PSE[0],position[0], position[1], position[2],nR_Efield,nZ_Efield, EfieldGridRDevicePointer,EfieldGridZDevicePointer,EfieldRDevicePointer, - EfieldZDevicePointer,EfieldTDevicePointer); + EfieldZDevicePointer,EfieldTDevicePointer, cylsymm ); vectorAdd(E,PSE,E); //std::cout << "Efield in boris " <charge[indx]*1.60217662e-19*Bmag/(particlesPointer->amu[indx]*1.6737236e-27); @@ -980,25 +855,28 @@ void move_boris::operator()(std::size_t indx) position[2] = position[2] + v[2] * half_dt; // second step of half_dt -#if USESHEATHEFIELD > 0 + if( sheath_efield > 0 ) + { minDist = getE(position[0], position[1], position[2], E,boundaryVector,nLines,nR_closeGeom_sheath, nY_closeGeom_sheath,nZ_closeGeom_sheath, n_closeGeomElements_sheath,closeGeomGridr_sheath, closeGeomGridy_sheath, - closeGeomGridz_sheath,closeGeom_sheath, closestBoundaryIndex); -#endif + closeGeomGridz_sheath,closeGeom_sheath, closestBoundaryIndex, + biased_surface, use_3d_geom, geom_hash_sheath, cylsymm ); + } -#if USEPRESHEATHEFIELD > 0 + if( presheath_efield > 0 ) + { interp2dVector(&PSE[0],position[0], position[1], position[2],nR_Efield,nZ_Efield, EfieldGridRDevicePointer,EfieldGridZDevicePointer,EfieldRDevicePointer, - EfieldZDevicePointer,EfieldTDevicePointer); + EfieldZDevicePointer,EfieldTDevicePointer, cylsymm ); vectorAdd(E,PSE,E); -#endif + } interp2dVector(&B[0],position[0], position[1], position[2],nR_Bfield,nZ_Bfield, BfieldGridRDevicePointer,BfieldGridZDevicePointer,BfieldRDevicePointer, - BfieldZDevicePointer,BfieldTDevicePointer); + BfieldZDevicePointer,BfieldTDevicePointer, cylsymm ); Bmag = vectorNorm(B); q_prime = particlesPointer->charge[indx]*1.60217662e-19/(particlesPointer->amu[indx]*1.6737236e-27)*half_dt*0.5; coeff = 2.0*q_prime/(1.0+(q_prime*Bmag)*(q_prime*Bmag)); @@ -1137,16 +1015,19 @@ for ( int s=0; s 0 + if( sheath_efield > 0 ) + { minDist = getE(r[0],r[1],r[2],E,boundaryVector,nLines); -#endif -#if USEPRESHEATHEFIELD > 0 + } + + if( presheath_efield > 0 ) + { interparticlesPointer->dVector(&particlesPointer->E[0],particlesPointer->xparticlesPointer->evious,particlesPointer->yparticlesPointer->evious,particlesPointer->zparticlesPointer->evious,nR_Efield,nZ_Efield, EfieldGridRDeviceparticlesPointer->inter,EfieldGridZDeviceparticlesPointer->inter,EfieldRDeviceparticlesPointer->inter, EfieldZDeviceparticlesPointer->inter,EfieldTDeviceparticlesPointer->inter); vectorAdd(E,particlesPointer->E,E); -#endif + } #ifdef __CUDACC__ #else #endif @@ -1193,15 +1074,17 @@ for ( int s=0; s 0 +if( sheath_efield > 0 ) +{ minDist = getE(r2[0],r2[1],r2[2],E,boundaryVector,nLines); -#endif -#if USEPRESHEATHEFIELD > 0 +} +if( presheath_efield > 0 ) +{ interparticlesPointer->dVector(&particlesPointer->E[0],particlesPointer->xparticlesPointer->evious,particlesPointer->yparticlesPointer->evious,particlesPointer->zparticlesPointer->evious,nR_Efield,nZ_Efield, EfieldGridRDeviceparticlesPointer->inter,EfieldGridZDeviceparticlesPointer->inter,EfieldRDeviceparticlesPointer->inter, EfieldZDeviceparticlesPointer->inter,EfieldTDeviceparticlesPointer->inter); vectorAdd(E,particlesPointer->E,E); -#endif +} #ifdef __CUDACC__ #else #endif @@ -1249,15 +1132,18 @@ for ( int s=0; s 0 +if( sheath_efield > 0 ) +{ minDist = getE(r3[0],r3[1],r3[2],E,boundaryVector,nLines); -#endif -#if USEPRESHEATHEFIELD > 0 +} + +if( presheath_efield > 0 ) +{ interparticlesPointer->dVector(&particlesPointer->E[0],particlesPointer->xparticlesPointer->evious,particlesPointer->yparticlesPointer->evious,particlesPointer->zparticlesPointer->evious,nR_Efield,nZ_Efield, EfieldGridRDeviceparticlesPointer->inter,EfieldGridZDeviceparticlesPointer->inter,EfieldRDeviceparticlesPointer->inter, EfieldZDeviceparticlesPointer->inter,EfieldTDeviceparticlesPointer->inter); vectorAdd(E,particlesPointer->E,E); -#endif +} #ifdef __CUDACC__ #else @@ -1303,15 +1189,17 @@ for ( int s=0; s 0 + if( sheath_efield > 0 ) + { minDist = getE(r4[0],r4[1],r4[2],E,boundaryVector,nLines); -#endif -#if USEPRESHEATHEFIELD > 0 + } + if( presheath_efield > 0 ) + { interp2dVector(&particlesPointer->E[0],particlesPointer->xparticlesPointer->evious,particlesPointer->yparticlesPointer->evious,particlesPointer->zparticlesPointer->evious,nR_Efield,nZ_Efield, EfieldGridRDeviceparticlesPointer->inter,EfieldGridZDeviceparticlesPointer->inter,EfieldRDeviceparticlesPointer->inter, EfieldZDeviceparticlesPointer->inter,EfieldTDeviceparticlesPointer->inter); vectorAdd(E,particlesPointer->E,E); -#endif + } #ifdef __CUDACC__ #else #endif diff --git a/src/config_interface.cpp b/src/config_interface.cpp index 00778f0b..7852eb54 100644 --- a/src/config_interface.cpp +++ b/src/config_interface.cpp @@ -8,34 +8,41 @@ libconfig_string_query::libconfig_string_query( std::string libconfig_file ) cfg.readFile( libconfig_file.c_str() ); } + /* bad file */ catch(const libconfig::FileIOException &fioex) { std::cerr << "I/O error while reading file." << std::endl; + exit( 0 ); } + /* bad format */ catch(const libconfig::ParseException &pex) { std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine() << " - " << pex.getError() << std::endl; + exit( 0 ); } } -/* geta config value */ -template< typename T > -T config_module_base::get( int key ) +geometry:: +geometry( class libconfig_string_query const &query, + std::string module_path ) + : + config_module_base( query, module_path ) { - auto access = lookup.find( key ); - if( access == lookup.end() ) - { - std::cout << "error: value key not found" << std::endl; - exit(0); - } - - T val; - - query( get_module_path() + "." + access->second, val ); - - return val; + lookup[ geometry::slope ] = "slope"; + lookup[ geometry::intercept ] = "intercept"; + lookup[ geometry::length ] = "length"; + lookup[ geometry::z ] = "Z"; + lookup[ geometry::surface ] = "surface"; + lookup[ geometry::in_dir ] = "in_dir"; + lookup[ geometry::periodic ] = "periodic"; + lookup[ geometry::x1 ] = "x1"; + lookup[ geometry::x2 ] = "x2"; + lookup[ geometry::y1 ] = "y1"; + lookup[ geometry::y2 ] = "y2"; + lookup[ geometry::z1 ] = "z1"; + lookup[ geometry::z2 ] = "z2"; } impurity_particle_source:: @@ -94,22 +101,19 @@ use::use( class libconfig_string_query const &query, lookup[ use::cuda ] = "USE_CUDA"; lookup[ use::use_openmp ] = "USE_OPENMP"; lookup[ use::mpi ] = "USE_MPI"; - lookup[ use::useionization ] = "USEIONIZATION"; - lookup[ use::use_ionization ] = "USE_IONIZATION"; - lookup[ use::userecombination ] = "USERECOMBINATION"; - lookup[ use::useperpdiffusion ] = "USEPERPDIFFUSION"; - lookup[ use::usecoulombcollisions ] = "USECOULOMBCOLLISIONS"; - lookup[ use::usefriction ] = "USEFRICTION"; - lookup[ use::useanglescattering ] = "USEANGLESCATTERING"; - lookup[ use::useheating ] = "USEHEATING"; - lookup[ use::usethermalforce ] = "USETHERMALFORCE"; - lookup[ use::usesurfacemodel ] = "USESURFACEMODEL"; - lookup[ use::usesheathefield ] = "USESHEATHEFIELD"; - lookup[ use::biased_surface ] = "BIASED_SURFACE"; - lookup[ use::usepresheathefield ] = "USEPRESHEATHEFIELD"; + lookup[ use::ionization ] = "USE_IONIZATION"; + lookup[ use::perp_diffusion ] = "USEPERPDIFFUSION"; + lookup[ use::coulomb_collisions ] = "USECOULOMBCOLLISIONS"; + //lookup[ use::friction ] = "USEFRICTION"; + //lookup[ use::angle_scattering ] = "USEANGLESCATTERING"; + //lookup[ use::heating ] = "USEHEATING"; + lookup[ use::thermal_force ] = "USETHERMALFORCE"; + lookup[ use::surface_model ] = "USESURFACEMODEL"; + lookup[ use::sheath_efield ] = "USESHEATHEFIELD"; + // hardcoded to 0 for now + //lookup[ use::biased_surface ] = "BIASED_SURFACE"; + //lookup[ use::presheath_efield ] = "USEPRESHEATHEFIELD"; lookup[ use::bfield_interp ] = "BFIELD_INTERP"; - lookup[ use::lc_interp ] = "LC_INTERP"; - lookup[ use::generate_lc ] = "GENERATE_LC"; lookup[ use::efield_interp ] = "EFIELD_INTERP"; lookup[ use::presheath_interp ] = "PRESHEATH_INTERP"; lookup[ use::density_interp ] = "DENSITY_INTERP"; @@ -117,9 +121,7 @@ use::use( class libconfig_string_query const &query, lookup[ use::flowv_interp ] = "FLOWV_INTERP"; lookup[ use::gradt_interp ] = "GRADT_INTERP"; lookup[ use::odeint ] = "ODEINT"; - lookup[ use::fixedseeds ] = "FIXEDSEEDS"; lookup[ use::fixed_seeds ] = "FIXED_SEEDS"; - lookup[ use::particleseeds ] = "PARTICLESEEDS "; lookup[ use::geom_trace ] = "GEOM_TRACE "; lookup[ use::geom_hash ] = "GEOM_HASH"; lookup[ use::geom_hash_sheath ] = "GEOM_HASH_SHEATH"; @@ -129,14 +131,15 @@ use::use( class libconfig_string_query const &query, lookup[ use::particle_source_angle ] = "PARTICLE_SOURCE_ANGLE"; lookup[ use::particle_source_file ] = "PARTICLE_SOURCE_FILE"; lookup[ use::spectroscopy ] = "SPECTROSCOPY"; - lookup[ use::use3dtetgeom ] = "USE3DTETGEOM"; + lookup[ use::use_3d_geom ] = "USE3DTETGEOM"; lookup[ use::flux_ea ] = "FLUX_EA"; - lookup[ use::usecylsymm ] = "USECYLSYMM"; - lookup[ use::usefieldalignedvalues ] = "USEFIELDALIGNEDVALUES"; + lookup[ use::cylsymm ] = "USECYLSYMM"; + lookup[ use::field_aligned_values ] = "USEFIELDALIGNEDVALUES"; lookup[ use::force_eval ] = "FORCE_EVAL"; - lookup[ use::compatibility_check ] = "CHECK_COMPATIBILITY"; - lookup[ use::use_sort ] = "USE_SORT"; - lookup[ use::use_adaptive_dt ] = "USE_ADAPTIVE_DT"; + //lookup[ use::compatibility_check ] = "CHECK_COMPATIBILITY"; + lookup[ use::sort ] = "USE_SORT"; + lookup[ use::adaptive_dt ] = "USE_ADAPTIVE_DT"; + lookup[ use::surface_potential ] = "USE_SURFACE_POTENTIAL"; } config_module_base::config_module_base( class libconfig_string_query const &query, @@ -146,14 +149,67 @@ config_module_base::config_module_base( class libconfig_string_query const &quer query( query ) { } -/* explicit instantiations of that template */ +/* general "get" for values */ +template< typename T > +T config_module_base::get( int key ) +{ + auto access = lookup.find( key ); + + if( access == lookup.end() ) + { + throw unregistered_config_mapping( key ); + } + + T val; + + try + { + query( get_module_path() + "." + access->second, val ); + } + + catch( class invalid_key const &exception ) + { + std::string const error_message{ exception.what() }; + + std::string const error_key{ exception.get_key() }; + + std::cout << error_message << error_key << std::endl; + + throw invalid_key( error_key ); + } + + catch( class lookup_failed const &exception ) + { + std::string const error_message{ exception.what() }; + + std::string const error_key{ exception.get_key() }; + + std::cout << error_message << error_key << std::endl; + + throw lookup_failed( error_key ); + } + + return val; +} + +/* instantiations for singleton config setting values */ template int config_module_base::get( int key ); template float config_module_base::get( int key ); template double config_module_base::get( int key ); template bool config_module_base::get( int key ); template std::string config_module_base::get( int key ); -/* get a config submodule */ +/* instantiations for vector/array config setting values */ +template std::vector< int > config_module_base::get< std::vector< int > >( int key ); +template std::vector< float > +config_module_base::get< std::vector< float > >( int key ); +template std::vector< double > +config_module_base::get< std::vector< double > >( int key ); +template std::vector< bool > config_module_base::get< std::vector< bool > >( int key ); +template std::vector< std::string > +config_module_base::get< std::vector< std::string > >( int key ); + +/* template specialization for non-specified type: specialization for default T from header */ template<> std::shared_ptr< config_module_base > config_module_base::get( int key ) @@ -162,8 +218,7 @@ config_module_base::get( int key ) if( access == sub_modules.end() ) { - std::cout << "error: config_module key not found" << std::endl; - exit( 0 ); + throw( unregistered_config_mapping( key ) ); } return access->second; diff --git a/src/curandInitialize.cpp b/src/curandInitialize.cpp deleted file mode 100644 index 3e5f9814..00000000 --- a/src/curandInitialize.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef _CURANDINITIAL_ -#define _CURANDINITIAL_ - -#ifdef __CUDACC__ -#define CUDA_CALLABLE_MEMBER_DEVICE __device__ -#else -#define CUDA_CALLABLE_MEMBER_DEVICE -#endif -#include -#include -#include "Particles.h" -#include "libconfig.h++" - -template -struct curandInitialize{ -#if USE_CUDA > 0 - curandState *s; -#else - T *s; -#endif - //int seed; - bool fixed; - - curandInitialize( -#if USE_CUDA > 0 - curandState *_s, -#else - T *_s, -#endif - bool _fixed) : s(_s), fixed(_fixed) {} - - CUDA_CALLABLE_MEMBER_DEVICE - void operator()(std::size_t indx) - { -#if USE_CUDA > 0 - curand_init(indx, 0, 0, &s[indx]); -#else - if (fixed) - { - T s0(1234^indx); - s[indx] = s0; - } - else - { - std::random_device randDevice; - std::mt19937 s0(randDevice()); - s[indx] = s0; - } -#endif - } -}; -#endif diff --git a/src/geometry_check.cpp b/src/geometry_check.cpp index 1b028a5e..85b961a5 100644 --- a/src/geometry_check.cpp +++ b/src/geometry_check.cpp @@ -62,7 +62,12 @@ geometry_check::geometry_check( gitr_precision _Edist, int _nAdist, gitr_precision _A0dist, - gitr_precision _Adist ) + gitr_precision _Adist, + int flux_ea_, + int surface_model_, + int geom_hash_, + int use_3d_geom_, + int cylsymm_ ) : particlesPointer(_particlesPointer), nLines(_nLines), @@ -73,7 +78,9 @@ geometry_check::geometry_check( closeGeomGridr(_closeGeomGridr), closeGeomGridy(_closeGeomGridy), closeGeomGridz(_closeGeomGridz), closeGeom(_closeGeom), nEdist(_nEdist), E0dist(_E0dist), Edist(_Edist), nAdist(_nAdist), A0dist(_A0dist), - Adist(_Adist) {} + Adist(_Adist), flux_ea( flux_ea_ ), surface_model( surface_model_ ), + geom_hash( geom_hash_ ), use_3d_geom( use_3d_geom_ ), cylsymm( cylsymm_ ) + {} __host__ __device__ void geometry_check::operator()(std::size_t indx) const { @@ -97,15 +104,14 @@ void geometry_check::operator()(std::size_t indx) const { gitr_precision dpath = std::sqrt((x - xprev) * (x - xprev) + (y - yprev) * (y - yprev) + (z - zprev) * (z - zprev)); -#if FLUX_EA > 0 gitr_precision dEdist = (Edist - E0dist) / static_cast(nEdist); gitr_precision dAdist = (Adist - A0dist) / static_cast(nAdist); int AdistInd = 0; int EdistInd = 0; -#endif gitr_precision vxy[3] = {0.0}; gitr_precision vtheta[3] = {0.0}; -#if USECYLSYMM > 0 + if( cylsymm ) + { if (boundaryVector[nLines].periodic) // if periodic { gitr_precision pi = 3.14159265; @@ -169,7 +175,9 @@ void geometry_check::operator()(std::size_t indx) const { particlesPointer->vy[indx] = vy0; } } -#else + } + else + { /* Ahoy! So what happens if x[ index ] is to far away from the boundary condition to get mapped? Shouldn't this be if( x < -x_size * 0.5 ) x = x + x_size ? */ /* will this result in incorrect behavior from the PBC equation from wikipedia */ @@ -209,8 +217,9 @@ void geometry_check::operator()(std::size_t indx) const { (particlesPointer->y[indx] - boundaryVector[nLines].y2); } } -#endif -#if USE3DTETGEOM > 0 + } + if( use_3d_geom > 0 ) + { gitr_precision a = 0.0; gitr_precision b = 0.0; @@ -264,9 +273,17 @@ void geometry_check::operator()(std::size_t indx) const { particlesPointer->zprevious[indx]}; gitr_precision p1[3] = {particlesPointer->x[indx], particlesPointer->y[indx], particlesPointer->z[indx]}; -#if GEOM_HASH > 0 - // find which hash + + int top_limit = -1; + + int buffIndx; + int rInd; + int zInd; + int yInd; int nHash = 0; + + if( geom_hash > 0 ) + { int rHashInd = 0; int yHashInd = 0; int zHashInd = 0; @@ -319,12 +336,12 @@ void geometry_check::operator()(std::size_t indx) const { gitr_precision dr = closeGeomGridr[rHashInd + 1] - closeGeomGridr[rHashInd]; gitr_precision dz = closeGeomGridz[zHashInd + 1] - closeGeomGridz[zHashInd]; gitr_precision dy = closeGeomGridy[yHashInd + 1] - closeGeomGridy[yHashInd]; - int rInd = std::floor((r_position - closeGeomGridr[rHashInd]) / dr + 0.5); - int zInd = std::floor( + rInd = std::floor((r_position - closeGeomGridr[rHashInd]) / dr + 0.5); + zInd = std::floor( (particlesPointer->zprevious[indx] - closeGeomGridz[zHashInd]) / dz + 0.5); int i = 0; - int yInd = std::floor( + yInd = std::floor( (particlesPointer->yprevious[indx] - closeGeomGridy[yHashInd]) / dy + 0.5); // std::cout << "rHashInd " << rHashInd << " " << yHashInd << " " << @@ -347,21 +364,33 @@ void geometry_check::operator()(std::size_t indx) const { yInd = 0; zInd = 0; } - int buffIndx = 0; + buffIndx = 0; if (nHash > 0) buffIndx = nR_closeGeom[nHash - 1] * nY_closeGeom[nHash - 1] * nZ_closeGeom[nHash - 1] * n_closeGeomElements[nHash - 1]; - // std::cout << "buff Index " << buffIndx << std::endl; - for (int j = 0; j < n_closeGeomElements[nHash]; j++) { + + top_limit = n_closeGeomElements[ nHash ]; + } + + else top_limit = nLines; + + /* Captain! */ + for( int k = 0; k < top_limit; k++ ) + { + int i = -1; + + if( geom_hash > 0 ) + { + i = closeGeom[buffIndx + zInd * nY_closeGeom[nHash] * nR_closeGeom[nHash] * n_closeGeomElements[nHash] + yInd * nR_closeGeom[nHash] * n_closeGeomElements[nHash] + - rInd * n_closeGeomElements[nHash] + j]; - // std::cout << "i's " << i << std::endl; -#else - for (int i = 0; i < nLines; i++) { -#endif + rInd * n_closeGeomElements[nHash] + k]; + } + + else i = k; + a = boundaryVector[i].a; b = boundaryVector[i].b; c = boundaryVector[i].c; @@ -523,26 +552,40 @@ else{ particlesPointer->z[indx] = temp_position_xyz[2]; particlesPointer->surfaceHit[indx] = nearest_boundary_index; } -#else // 2D geometry -#if USECYLSYMM > 0 - gitr_precision pdim1 = std::sqrt(particlesPointer->x[indx] * particlesPointer->x[indx] + + } + // 2D geometry + else + { + gitr_precision pdim1; + gitr_precision pdim1previous; + gitr_precision theta0; + gitr_precision theta1; + gitr_precision thetaNew = 0; + gitr_precision rNew = 0; + gitr_precision xNew = 0; + gitr_precision yNew = 0; + if( cylsymm > 0 ) + { + pdim1 = std::sqrt(particlesPointer->x[indx] * particlesPointer->x[indx] + particlesPointer->y[indx] * particlesPointer->y[indx]); - gitr_precision pdim1previous = std::sqrt(particlesPointer->xprevious[indx] * + pdim1previous = std::sqrt(particlesPointer->xprevious[indx] * particlesPointer->xprevious[indx] + particlesPointer->yprevious[indx] * particlesPointer->yprevious[indx]); - gitr_precision theta0 = std::atan2(particlesPointer->yprevious[indx], + theta0 = std::atan2(particlesPointer->yprevious[indx], particlesPointer->xprevious[indx]); - gitr_precision theta1 = + theta1 = std::atan2(particlesPointer->y[indx], particlesPointer->x[indx]); - gitr_precision thetaNew = 0; - gitr_precision rNew = 0; - gitr_precision xNew = 0; - gitr_precision yNew = 0; -#else - gitr_precision pdim1 = particlesPointer->x[indx]; - gitr_precision pdim1previous = particlesPointer->xprevious[indx]; -#endif + thetaNew = 0; + rNew = 0; + xNew = 0; + yNew = 0; + } + else + { + pdim1 = particlesPointer->x[indx]; + pdim1previous = particlesPointer->xprevious[indx]; + } gitr_precision particle_slope = (particlesPointer->z[indx] - particlesPointer->zprevious[indx]) / (pdim1 - pdim1previous); @@ -570,56 +613,61 @@ else{ //std::cout << "r0 " << particlesPointer->x[indx] << " " << //particlesPointer->y[indx] << " " << //particlesPointer->z[indx]<< std::endl; -#if GEOM_HASH > 0 -#if USECYLSYMM > 0 - gitr_precision r_position = std::sqrt(particlesPointer->xprevious[indx] * + +int top_limit = -1; +int closeIndx = 0; + +int rInd; +int zInd; + +if( geom_hash > 0 ) +{ + gitr_precision r_position; + + if( cylsymm > 0 ) + { + r_position = std::sqrt(particlesPointer->xprevious[indx] * particlesPointer->xprevious[indx] + particlesPointer->yprevious[indx] * particlesPointer->yprevious[indx]); -#else - gitr_precision r_position = particlesPointer->xprevious[indx]; -#endif + } + else + { + r_position = particlesPointer->xprevious[indx]; + } + gitr_precision dr = closeGeomGridr[1] - closeGeomGridr[0]; gitr_precision dz = closeGeomGridz[1] - closeGeomGridz[0]; - int rInd = std::floor((r_position - closeGeomGridr[0]) / dr + 0.5); - int zInd = std::floor( + + rInd = std::floor((r_position - closeGeomGridr[0]) / dr + 0.5); + zInd = std::floor( (particlesPointer->zprevious[indx] - closeGeomGridz[0]) / dz + 0.5); - if (rInd < 0 || rInd >= nR_closeGeom[0]) - rInd = 0; - if (zInd < 0 || zInd >= nZ_closeGeom[0]) - zInd = 0; - int i = 0; - int closeIndx = 0; - for (int j = 0; j < n_closeGeomElements[0]; j++) { + + if (rInd < 0 || rInd >= nR_closeGeom[0]) rInd = 0; + + if (zInd < 0 || zInd >= nZ_closeGeom[0]) zInd = 0; + + top_limit = n_closeGeomElements[ 0 ]; +} + +else top_limit = nLines; + + for ( int k = 0; k < top_limit; k++ ) + { + + int i = -1; + + if( geom_hash > 0 ) + { + closeIndx = zInd * nR_closeGeom[0] * n_closeGeomElements[0] + - rInd * n_closeGeomElements[0] + j; - // if(zInd*nR_closeGeom[0]*n_closeGeomElements[0] + - // rInd*n_closeGeomElements[0] + j < 0) - //{ - // zInd=0; - // rInd=0; - // j=0; - // //std::cout << "index " << - // zInd*nR_closeGeom[0]*n_closeGeomElements[0] + - // rInd*n_closeGeomElements[0] + j << std::endl; - //} - // if(zInd*nR_closeGeom[0]*n_closeGeomElements[0] + - // rInd*n_closeGeomElements[0] + j > 1309440) - // { - // zInd=0; - // rInd=0; - // j=0; - // //std::cout << "index " << - // zInd*nR_closeGeom[0]*n_closeGeomElements[0] + - // rInd*n_closeGeomElements[0] + j << std::endl; - // } + rInd * n_closeGeomElements[0] + k; + i = closeGeom[closeIndx]; + } + + else i = k; -#else - for (int i = 0; i < nLines; i++) { -#endif - // std::cout << "vert geom " << i << " " << - // fabs(boundaryVector[i].slope_dzdx) << " " << tol << std::endl; if (std::abs(boundaryVector[i].slope_dzdx) >= tol * 0.75) { signPoint = std::copysign(1.0, pdim1 - boundaryVector[i].x1); @@ -770,7 +818,8 @@ else{ // particlesPointer->test0[indx] = -100.0; if (particle_slope >= tol * 0.75) { -#if USECYLSYMM > 0 + if( cylsymm > 0 ) + { gitr_precision x0 = particlesPointer->xprevious[indx]; gitr_precision x1 = particlesPointer->x[indx]; gitr_precision y0 = particlesPointer->yprevious[indx]; @@ -786,7 +835,9 @@ else{ (theta1 - theta0); particlesPointer->y[indx] = yNew; particlesPointer->yprevious[indx] = yNew; -#else + } + else + { // std::cout << "Particle index " << indx << " hit wall and is // calculating y point " << particlesPointer->y[indx] << std::endl; particlesPointer->y[indx] = @@ -802,11 +853,12 @@ else{ // particlesPointer->z[indx] << " " << particlesPointer->y[indx] << // std::endl; -#endif + } } else { -#if USECYLSYMM > 0 + if( cylsymm > 0 ) + { gitr_precision x0 = particlesPointer->xprevious[indx]; gitr_precision x1 = particlesPointer->x[indx]; gitr_precision y0 = particlesPointer->yprevious[indx]; @@ -836,7 +888,9 @@ else{ // yNew " << xNew << " " << yNew << std::endl; std::cout << // "intersectionx " << intersectionx[0] << std::endl; //} -#else + } + else + { // std::cout << "Particle index " << indx << " hit wall and is // calculating y point " << particlesPointer->y[indx] << std::endl; particlesPointer->y[indx] = @@ -851,15 +905,18 @@ else{ // "<< particlesPointer->zprevious[indx] << " " << // particlesPointer->z[indx] << " " << particlesPointer->y[indx] << // std::endl; -#endif + } } -#if USECYLSYMM > 0 + if( cylsymm > 0 ) + { particlesPointer->xprevious[indx] = xNew; particlesPointer->x[indx] = particlesPointer->xprevious[indx]; -#else + } + else + { particlesPointer->x[indx] = intersectionx[0]; particlesPointer->xprevious[indx] = intersectionx[0]; -#endif + } particlesPointer->zprevious[indx] = intersectiony[0]; particlesPointer->z[indx] = intersectiony[0]; // std::cout << "nInt = 1 position " << intersectionx[0] << " " << @@ -884,7 +941,8 @@ else{ particlesPointer->wallIndex[indx] = intersectionIndices[minDistInd]; particlesPointer->surfaceHit[indx] = intersectionIndices[minDistInd]; particlesPointer->hitWall[indx] = 1.0; -#if USECYLSYMM > 0 + if( cylsymm ) + { thetaNew = theta0 + (intersectionx[minDistInd] - pdim1previous) / (pdim1 - pdim1previous) * (theta1 - theta0); particlesPointer->yprevious[indx] = @@ -894,7 +952,9 @@ else{ // intersectionx[minDistInd]*cosf(thetaNew); particlesPointer->x[indx] = intersectionx[minDistInd] * std::cos(thetaNew); -#else + } + else + { // std::cout << "Particle index " << indx << " hit wall and is // calculating y point " << particlesPointer->yprevious[indx] << " " << // particlesPointer->y[indx] << std::endl; @@ -917,7 +977,7 @@ else{ // particlesPointer->z[indx] << " " << particlesPointer->y[indx] << // std::endl; particlesPointer->x[indx] = intersectionx[minDistInd]; -#endif + } particlesPointer->z[indx] = intersectiony[minDistInd]; } ////} @@ -932,10 +992,11 @@ else{ // particlesPointer->hitWall[indx] = 1.0; // } //} -#endif + } if (particlesPointer->hitWall[indx] == 1.0) { -#if (FLUX_EA > 0 && USESURFACEMODEL == 0) + if( flux_ea > 0 && surface_model == 0 ) + { gitr_precision E0 = 0.0; gitr_precision thetaImpact = 0.0; gitr_precision particleTrackVector[3] = {0.0}; @@ -953,7 +1014,7 @@ else{ int wallHitP = particlesPointer->surfaceHit[indx]; boundaryVector[particlesPointer->surfaceHit[indx]].getSurfaceNormal( surfaceNormalVector, particlesPointer->y[indx], - particlesPointer->x[indx]); + particlesPointer->x[indx], use_3d_geom, cylsymm ); particleTrackVector[0] = particleTrackVector[0] / norm_part; particleTrackVector[1] = particleTrackVector[1] / norm_part; particleTrackVector[2] = particleTrackVector[2] / norm_part; @@ -1000,26 +1061,35 @@ else{ #else #pragma omp atomic + /* surfaces->energyDistribution[surfaceHit * nEdist * nAdist + EdistInd * nAdist + AdistInd] = surfaces->energyDistribution[surfaceHit * nEdist * nAdist + EdistInd * nAdist + AdistInd] + weight; + */ + surfaces->energyDistribution[surfaceHit * nEdist * nAdist + + EdistInd * nAdist + AdistInd] += weight; #pragma omp atomic - surfaces->sumWeightStrike[surfaceHit] = - surfaces->sumWeightStrike[surfaceHit] + weight; + //surfaces->sumWeightStrike[surfaceHit] = + // surfaces->sumWeightStrike[surfaceHit] + weight; + surfaces->sumWeightStrike[surfaceHit] += weight; #pragma omp atomic - surfaces->sumParticlesStrike[surfaceHit] = - surfaces->sumParticlesStrike[surfaceHit] + 1; + //surfaces->sumParticlesStrike[surfaceHit] = + // surfaces->sumParticlesStrike[surfaceHit] + 1; + surfaces->sumParticlesStrike[surfaceHit]++; #pragma omp atomic - surfaces->grossDeposition[surfaceHit] = - surfaces->grossDeposition[surfaceHit] + weight; + //surfaces->grossDeposition[surfaceHit] = + // surfaces->grossDeposition[surfaceHit] + weight; + surfaces->grossDeposition[surfaceHit] += weight; #endif } } -#elif (FLUX_EA == 0 && USESURFACEMODEL == 0) + } + else if( surface_model == 0 && surface_model == 0 ) + { particlesPointer->weight[indx] = 0.0; -#endif + } // particlesPointer->transitTime[indx] = tt*dt; } } diff --git a/src/gitr.cpp b/src/gitr.cpp index 5ffcf8c8..0ebb31b6 100644 --- a/src/gitr.cpp +++ b/src/gitr.cpp @@ -19,7 +19,6 @@ #include "ionize.h" #include //#include "ncFile.h" -#include "ompPrint.h" #include "recombine.h" #include "spectroscopy.h" #include "surfaceModel.h" @@ -77,31 +76,72 @@ netCDF::NcType netcdf_precision = netCDF::ncFloat; int main(int argc, char **argv, char **envp) { -/* Placeholder code for runtime CLI */ -/* - -CLI::App app{ "!" }; + /* Placeholder code for runtime CLI */ -std::string file_name = ""; + CLI::App app{ "!" }; -app.add_option( "-c", file_name, "config filepath" ); + std::string file_name = "input/gitrInput.cfg"; -CLI11_PARSE( app, argc, argv ); + //app.add_option( "-c", file_name, "config filepath" )->required(); + app.add_option( "-c", file_name, "config filepath" ); -std::cout << "file_name read from stdin: " << file_name << std::endl; + CLI11_PARSE( app, argc, argv ); -*/ + std::cout << "file_name read from stdin: " << file_name << std::endl; typedef std::chrono::high_resolution_clock gitr_time; auto gitr_start_clock = gitr_time::now(); - class libconfig_string_query query( "input/gitrInput.cfg" ); + class libconfig_string_query query( file_name ); class use use( query ); + int surface_model = use.get< int >( use::surface_model ); + int flux_ea = use.get(use::flux_ea); + int spectroscopy = use.get< int >( use::spectroscopy ); + // hardcoded to 0 for now, taken out of config_interface + //int biased_surface = use.get< int >( use::biased_surface ); + int biased_surface = BIASED_SURFACE; + int use_3d_geom = use.get< int >( use::use_3d_geom ); + int cylsymm = use.get< int >( use::cylsymm ); + int bfield_interp = use.get< int >( use::bfield_interp ); + int gradt_interp = use.get< int >( use::gradt_interp ); + int force_eval = use.get< int >( use::force_eval ); + int sort_particles = use.get< int >( use::sort ); + int use_adaptive_dt = use.get< int >( use::adaptive_dt ); + int geom_hash = use.get( use::geom_hash); + int particle_source_file = use.get< int >( use::particle_source_file ); + int particle_source_space = use.get< int >( use::particle_source_space ); + int particle_source_energy = use.get< int >( use::particle_source_energy ); + int particle_source_angle = use.get< int >( use::particle_source_angle ); + + //int particle_source_space = use.get< int >( use::particle_source_space ); + //int particle_source_energy = use.get< int >( use::particle_source_energy ); + //int particle_source_angle = use.get< int >( use::particle_source_angle ); + int particle_tracks = use.get< int >( use::particle_tracks ); + int presheath_interp = use.get< int >( use::presheath_interp ); + int efield_interp = use.get< int >( use::efield_interp ); + int surface_potential = use.get< int >( use::surface_potential ); + int flowv_interp = use.get( use::flowv_interp ); + int density_interp = use.get( use::density_interp ); + int temp_interp = use.get(use::temp_interp); + int geom_hash_sheath = use.get( use::geom_hash_sheath ); + int thermal_force = use.get< int >( use::thermal_force ); + int sheath_efield = use.get< int >( use::sheath_efield ); + // hardcoded to 1 for now + //int presheath_efield = use.get< int >( use::presheath_efield ); + int presheath_efield = 1; + int ionization = use.get< int >( use::ionization ); + int coulomb_collisions = use.get< int >( use::coulomb_collisions ); + int perp_diffusion = use.get< int >( use::perp_diffusion ); + // hardcoded to 1 for now + //int field_aligned_values = use.get< int >( use::field_aligned_values ); + int field_aligned_values = FIELD_ALIGNED_VALUES; + bool fixed_seeds = bool( use.get< int >( use::fixed_seeds ) ); + // Set default processes per node to 1 int ppn = 1; // Set default input file string - std::string inputFile = "gitrInput.cfg"; + std::string inputFile = file_name; #if USE_MPI > 0 // Initialize the MPI environment @@ -150,8 +190,8 @@ std::cout << "file_name read from stdin: " << file_name << std::endl; // Parse and read input file std::cout << "Open configuration file " << input_path << inputFile << std::endl; - importLibConfig(cfg, input_path + inputFile); - checkFlags( cfg ); + importLibConfig(cfg, inputFile); + //checkFlags( cfg ); // Parse and read geometry file std::string geomFile; @@ -220,8 +260,10 @@ std::cout << "file_name read from stdin: " << file_name << std::endl; std::string bfieldCfg = "backgroundPlasmaProfiles.Bfield."; std::string bfieldFile; if (world_rank == 0) { - importVectorFieldNs(cfg, input_path, BFIELD_INTERP, bfieldCfg, nR_Bfield, + //std::cout << "Ahoy, Captain!" << std::endl; + importVectorFieldNs(cfg, input_path, bfield_interp, bfieldCfg, nR_Bfield, nY_Bfield, nZ_Bfield, bfieldFile); + //std::cout << "Ahoy, Captain!" << std::endl; } #if USE_MPI > 0 MPI_Bcast(&nR_Bfield, 1, MPI_INT, 0, MPI_COMM_WORLD); @@ -236,7 +278,7 @@ std::cout << "file_name read from stdin: " << file_name << std::endl; sim::Array br(n_Bfield), by(n_Bfield), bz(n_Bfield); if (world_rank == 0) { - importVectorField(cfg, input_path, BFIELD_INTERP, bfieldCfg, nR_Bfield, + importVectorField(cfg, input_path, bfield_interp, bfieldCfg, nR_Bfield, nY_Bfield, nZ_Bfield, bfieldGridr.front(), bfieldGridy.front(), bfieldGridz.front(), br.front(), by.front(), bz.front(), bfieldFile); @@ -253,7 +295,7 @@ std::cout << "file_name read from stdin: " << file_name << std::endl; gitr_precision Btest[3] = {0.0}; interp2dVector(&Btest[0], 5.5, 0.0, -4.0, nR_Bfield, nZ_Bfield, bfieldGridr.data(), bfieldGridz.data(), br.data(), bz.data(), - by.data()); + by.data(), cylsymm ); //std::cout << "node " << world_rank << "Bfield at 5.5 -4 " << Btest[0] << " " // << Btest[1] << " " << Btest[2] << std::endl; std::string profiles_folder = "output/profiles"; @@ -280,19 +322,16 @@ std::cout << "file_name read from stdin: " << file_name << std::endl; MPI_Barrier(MPI_COMM_WORLD); #endif - /* Ahoy! Is the +1 the index that indicates the type? the // if periodic <--- comment in - geometryCheck.h */ sim::Array boundaries(nLines + 1, Boundary()); if (world_rank == 0) { - nSurfaces = importGeometry(cfg_geom, boundaries); + nSurfaces = importGeometry(cfg_geom, boundaries, use_3d_geom, cylsymm, surface_potential ); std::cout << "Starting Boundary Init... nSurfaces " << nSurfaces << std::endl; } - int use3dtetgeom = use.get( use::use3dtetgeom ); #if USE_MPI > 0 MPI_Bcast(&nSurfaces, 1, MPI_INT, 0, MPI_COMM_WORLD); int nBoundaryMembers; - if(use3dtetgeom) + if(use_3d_geom) { nBoundaryMembers = 41; } @@ -321,7 +360,6 @@ std::cout << "file_name read from stdin: " << file_name << std::endl; #endif gitr_precision biasPotential = 0.0; - int biased_surface = use.get(use::biased_surface); if(biased_surface) { if (world_rank == 0) { @@ -340,7 +378,6 @@ std::cout << "file_name read from stdin: " << file_name << std::endl; int nAdist = 1; gitr_precision A0dist = 0.0; gitr_precision Adist = 0.0; - int flux_ea = use.get(use::flux_ea); if(flux_ea) { if (world_rank == 0) { @@ -433,9 +470,8 @@ std::cout << "file_name read from stdin: " << file_name << std::endl; int nHashPointsTotal = 1; int nGeomHash = 1; std::string geomHashCfg = "geometry_hash."; - int geom_hash = use.get( use::geom_hash); - //int use3dtetgeom = 1; - if(geom_hash) + + if( geom_hash == 1 ) { //nR_closeGeomTotal = 0; //nY_closeGeomTotal = 0; @@ -456,14 +492,14 @@ std::cout << "file_name read from stdin: " << file_name << std::endl; sim::Array nHashPoints(nHashes, 0); sim::Array n_closeGeomElements(nHashes, 0); - if(geom_hash) + if( geom_hash == 1 ) { if (world_rank == 0) { importHashNs(cfg, input_path, nHashes, "geometry_hash", nR_closeGeom.data(), nY_closeGeom.data(), nZ_closeGeom.data(), n_closeGeomElements.data(), nR_closeGeomTotal, nY_closeGeomTotal, nZ_closeGeomTotal, nHashPoints.data(), - nHashPointsTotal, nGeomHash); + nHashPointsTotal, nGeomHash, use_3d_geom ); std::cout << "made it here" << std::endl; libconfig::Setting& geomHash = cfg.lookup("geometry_hash"); if(nHashes > 1) @@ -492,7 +528,7 @@ std::cout << "file_name read from stdin: " << file_name << std::endl; nR_closeGeomTotal = nR_closeGeomTotal + nR_closeGeom[j]; nZ_closeGeomTotal = nZ_closeGeomTotal + nZ_closeGeom[j]; } - if(use3dtetgeom) + if( use_3d_geom > 0 ) { if(nHashes > 1) { @@ -568,7 +604,7 @@ if( geom_hash > 1 ) nGeomHash = nGeomHash + nR_closeGeom[i] * nZ_closeGeom[i] * n_closeGeomElements[i]; - if( use3dtetgeom > 0 ) + if( use_3d_geom > 0 ) { nY_closeGeom[i] = getDimFromFile(cfg, input_path + hashFile[i], geomHashCfg, "gridNyString"); @@ -620,7 +656,7 @@ if( geom_hash == 1 ) hashX1[i] = geomHash["hashX1"][i]; hashZ0[i] = geomHash["hashZ0"][i]; hashZ1[i] = geomHash["hashZ1"][i]; - if( use3dtetgeom > 0 ) + if( use_3d_geom > 0 ) { hashY0[i] = geomHash["hashY0"][i]; hashY1[i] = geomHash["hashY1"][i]; @@ -631,7 +667,7 @@ if( geom_hash == 1 ) getVariable(cfg, geomHashCfg + "hashX1", hashX1[0]); getVariable(cfg, geomHashCfg + "hashZ0", hashZ0[0]); getVariable(cfg, geomHashCfg + "hashZ1", hashZ1[0]); - if( use3dtetgeom > 0 ) + if( use_3d_geom > 0 ) { getVariable(cfg, geomHashCfg + "hashY0", hashY0[0]); getVariable(cfg, geomHashCfg + "hashY1", hashY1[0]); @@ -742,7 +778,7 @@ if( geom_hash == 1 ) hashGeom geo1(nLines, nHashes, boundaries.data(), closeGeomGridr.data(), closeGeomGridy.data(), closeGeomGridz.data(), n_closeGeomElements.data(), closeGeom.data(), - nR_closeGeom.data(), nY_closeGeom.data(), nZ_closeGeom.data()); + nR_closeGeom.data(), nY_closeGeom.data(), nZ_closeGeom.data(), use_3d_geom ); std::cout << "nHashPoints start stop " << world_rank * nHashMeshPointsPerProcess << " " << world_rank * nHashMeshPointsPerProcess + hashMeshIncrements[world_rank] - 1<< std::endl; thrust::for_each(thrust::device, @@ -791,7 +827,7 @@ if( geom_hash == 1 ) } }; - if(use3dtetgeom) + if(use_3d_geom) { for (int j = 0; j < nY_closeGeom[ii]; j++) { @@ -845,15 +881,29 @@ if( geom_hash == 1 ) netCDF::NcFile::replace); std::cout << "opened file" << std::endl; netCDF::NcDim hashNR = ncFile_hash.addDim("nR", nR_closeGeom[i]); + netCDF::NcDim hashNY; + if( use_3d_geom > 0 ) + { + hashNY = ncFile_hash.addDim("nY", nY_closeGeom[i]); + } netCDF::NcDim hashNZ = ncFile_hash.addDim("nZ", nZ_closeGeom[i]); netCDF::NcDim hashN = ncFile_hash.addDim("n", n_closeGeomElements[i]); vector geomHashDim; geomHashDim.push_back(hashNR); std::cout << "created dims" << std::endl; + if( use_3d_geom > 0 ) + { + geomHashDim.push_back(hashNY); + } geomHashDim.push_back(hashNZ); geomHashDim.push_back(hashN); netCDF::NcVar hash_gridR = ncFile_hash.addVar("gridR", netcdf_precision, hashNR); std::cout << "created dims2" << std::endl; + netCDF::NcVar hash_gridY; + if( use_3d_geom > 0 ) + { + hash_gridY = ncFile_hash.addVar("gridY", netcdf_precision, hashNY); + } netCDF::NcVar hash_gridZ = ncFile_hash.addVar("gridZ", netcdf_precision, hashNZ); netCDF::NcVar hash = ncFile_hash.addVar("hash", netCDF::ncInt, geomHashDim); std::cout << "created vars" << std::endl; @@ -861,11 +911,8 @@ if( geom_hash == 1 ) if (i > 0) ncIndex = nR_closeGeom[i - 1]; hash_gridR.putVar(&closeGeomGridr[ncIndex]); - if( use3dtetgeom > 0 ) + if( use_3d_geom > 0 ) { - netCDF::NcDim hashNY = ncFile_hash.addDim("nY", nY_closeGeom[i]); - geomHashDim.push_back(hashNY); - netCDF::NcVar hash_gridY = ncFile_hash.addVar("gridY", netcdf_precision, hashNY); if (i > 0) ncIndex = nY_closeGeom[i - 1]; hash_gridY.putVar(&closeGeomGridy[ncIndex]); @@ -883,6 +930,7 @@ if( geom_hash == 1 ) } std::cout << "created vars2" << std::endl; } + else if( geom_hash > 1 ) { if (world_rank == 0) { @@ -897,7 +945,7 @@ else if( geom_hash > 1 ) getVarFromFile(cfg, input_path + hashFile[i], geomHashCfg, "gridZString", closeGeomGridz[dataIndex]); std::cout << "created vars3" << std::endl; - if( use3dtetgeom > 0 ) + if( use_3d_geom > 0 ) { if (i > 0) dataIndex = nY_closeGeom[0]; @@ -930,7 +978,6 @@ else if( geom_hash > 1 ) int n_closeGeomElements_sheath = 1; int nGeomHash_sheath = 1; std::string geomHashSheathCfg = "geometry_sheath."; -int geom_hash_sheath = use.get( use::geom_hash_sheath ); if( geom_hash_sheath == 1 ) { if (world_rank == 0) { @@ -940,7 +987,7 @@ if( geom_hash_sheath == 1 ) n_closeGeomElements_sheath); nGeomHash_sheath = nR_closeGeom_sheath * nZ_closeGeom_sheath * n_closeGeomElements_sheath; - if( use3dtetgeom > 0 ) + if( use_3d_geom > 0 ) { getVariable(cfg, geomHashSheathCfg + "nY_closeGeom", nY_closeGeom_sheath); nGeomHash_sheath = nY_closeGeom_sheath * nGeomHash_sheath; @@ -970,7 +1017,7 @@ if( geom_hash_sheath > 1 ) "nearestNelementsString"); nGeomHash_sheath = nR_closeGeom_sheath * nZ_closeGeom_sheath * n_closeGeomElements_sheath; - if( use3dtetgeom > 0 ) + if( use_3d_geom > 0 ) { nY_closeGeom_sheath = getDimFromFile(cfg, input_path + hashFile_sheath, geomHashSheathCfg, "gridNyString"); @@ -1000,10 +1047,12 @@ if( geom_hash_sheath > 1 ) getVariable(cfg, geomHashSheathCfg + "hashX1", hashX1_s); getVariable(cfg, geomHashSheathCfg + "hashZ0", hashZ0_s); getVariable(cfg, geomHashSheathCfg + "hashZ1", hashZ1_s); -#if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { getVariable(cfg, geomHashSheathCfg + "hashY0", hashY0_s); getVariable(cfg, geomHashSheathCfg + "hashY1", hashY1_s); -#endif +//#endif + } } #if USE_MPI > 0 MPI_Bcast(&hashX0_s, nHashes, MPI_FLOAT, 0, MPI_COMM_WORLD); @@ -1049,7 +1098,7 @@ if( geom_hash_sheath > 1 ) nLines, boundaries.data(), closeGeomGridr_sheath.data(), closeGeomGridy_sheath.data(), closeGeomGridz_sheath.data(), n_closeGeomElements_sheath, closeGeom_sheath.data(), nR_closeGeom_sheath, - nY_closeGeom_sheath, nZ_closeGeom_sheath); + nY_closeGeom_sheath, nZ_closeGeom_sheath, use_3d_geom ); thrust::for_each(thrust::device, lines0_s + world_rank * nHashMeshPointsPerProcess_s, lines0_s + world_rank * nHashMeshPointsPerProcess_s + @@ -1126,10 +1175,12 @@ else if( geom_hash_sheath > 1 ) "gridRString", closeGeomGridr_sheath[0]); getVarFromFile(cfg, input_path + hashFile_sheath, geomHashSheathCfg, "gridZString", closeGeomGridz_sheath[0]); -#if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { getVarFromFile(cfg, input_path + hashFile_sheath, geomHashSheathCfg, "gridYString", closeGeomGridy_sheath[0]); -#endif +//#endif + } getVarFromFile(cfg, input_path + hashFile_sheath, geomHashSheathCfg, "closeGeomString", closeGeom_sheath[0]); #if USE_MPI > 0 @@ -1154,10 +1205,11 @@ else if( geom_hash_sheath > 1 ) int nTraceSteps; std::string connLengthCfg = "connectionLength."; std::string lcFile; -int generate_lc = use.get( use::generate_lc ); -int lc_interp = use.get( use::lc_interp ); + NcFile ncFileLC("output/LcS.nc", NcFile::replace); + NcDim nc_nTracers = ncFileLC.addDim("nTracers", nTracers); + if (world_rank == 0) { -if( generate_lc > 0 ) +if( GENERATE_LC > 0 ) { getVariable(cfg, connLengthCfg + "fileString", lcFile); getVariable(cfg, connLengthCfg + "nX", nR_Lc); @@ -1174,7 +1226,7 @@ if( generate_lc > 0 ) } else { - if( lc_interp > 1 ) + if( LC_INTERP > 1 ) { nR_Lc = getDimFromFile(cfg, input_path + lcFile, connLengthCfg, "gridNrString"); @@ -1200,7 +1252,7 @@ else MPI_Barrier(MPI_COMM_WORLD); #endif -if( use3dtetgeom > 0 ) +if( use_3d_geom > 0 ) { nTracers = nR_Lc * nY_Lc * nZ_Lc; } @@ -1213,18 +1265,20 @@ else sim::Array gridRLc(nR_Lc), gridYLc(nY_Lc), gridZLc(nZ_Lc); sim::Array noIntersectionNodes(nTracers); -if( generate_lc > 0 ) +if( GENERATE_LC > 0 ) { gitr_precision lcBuffer = 0.0; // if( !boost::filesystem::exists( lcFile ) ) // { // std::cout << "No pre-existing connection length file found" << std::endl; -#if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { gitr_precision dy_Lc = (y1_Lc - y0_Lc) / (nY_Lc - 1); for (int j = 0; j < nY_Lc; j++) { gridYLc[j] = y0_Lc + j * dy_Lc; } -#endif +//#endif + } gitr_precision dr_Lc = (r1_Lc - r0_Lc) / (nR_Lc - 1); for (int i = 0; i < nR_Lc; i++) { gridRLc[i] = r0_Lc + i * dr_Lc; @@ -1257,11 +1311,16 @@ if( generate_lc > 0 ) for (int i = 0; i < nR_Lc; i++) { for (int j = 0; j < nY_Lc; j++) { for (int k = 0; k < nZ_Lc; k++) { -#if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { addIndex = i + j * nR_Lc + k * nR_Lc * nY_Lc; -#else + } + else + { +//#else addIndex = i + k * nR_Lc; -#endif +//#endif + } forwardTracerParticles->setParticle(addIndex, gridRLc[i], gridYLc[j], gridZLc[k], 0.0, 0.0, 0.0, 0, 0.0, 0.0); @@ -1291,7 +1350,7 @@ if( generate_lc > 0 ) gridRLc.data(), gridZLc.data(), Lc.data(), nR_Bfield, nZ_Bfield, bfieldGridr.data(), &bfieldGridz.front(), &br.front(), - &bz.front(), &by.front())); + &bz.front(), &by.front(), cylsymm )); thrust::for_each(thrust::device, lcBegin, lcEnd, field_line_trace(-1.0, backwardTracerParticles, dr, @@ -1299,7 +1358,7 @@ if( generate_lc > 0 ) gridRLc.data(), gridZLc.data(), Lc.data(), nR_Bfield, nZ_Bfield, bfieldGridr.data(), &bfieldGridz.front(), &br.front(), - &bz.front(), &by.front())); + &bz.front(), &by.front(), cylsymm )); thrust::for_each( thrust::device, lcBegin, lcEnd, @@ -1308,7 +1367,10 @@ if( generate_lc > 0 ) nY_closeGeom.data(), nZ_closeGeom.data(), n_closeGeomElements.data(), &closeGeomGridr.front(), &closeGeomGridy.front(), &closeGeomGridz.front(), - &closeGeom.front(), 0, 0.0, 0.0, 0, 0.0, 0.0)); + &closeGeom.front(), 0, 0.0, 0.0, 0, 0.0, 0.0, flux_ea, surface_model, + geom_hash, + use_3d_geom, + cylsymm ) ); thrust::for_each( thrust::device, lcBegin, lcEnd, @@ -1317,7 +1379,10 @@ if( generate_lc > 0 ) nY_closeGeom.data(), nZ_closeGeom.data(), n_closeGeomElements.data(), &closeGeomGridr.front(), &closeGeomGridy.front(), &closeGeomGridz.front(), - &closeGeom.front(), 0, 0.0, 0.0, 0, 0.0, 0.0)); + &closeGeom.front(), 0, 0.0, 0.0, 0, 0.0, 0.0, flux_ea, surface_model, + geom_hash, + use_3d_geom, + cylsymm ) ); } auto finish_clock_trace = Time_trace::now(); fsec_trace fstrace = finish_clock_trace - start_clock_trace; @@ -1389,11 +1454,16 @@ if( generate_lc > 0 ) for (int k = 0; k < nZ_Lc; k++) { // std::cout << "hitwall of tracers " << // forwardTracerParticles->hitWall[addIndex] << std::endl; -#if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { addIndex = i + j * nR_Lc + k * nR_Lc * nY_Lc; -#else + } + else + { +//#else addIndex = i + k * nR_Lc; -#endif +//#endif + } if (forwardTracerParticles->hitWall[addIndex] > 0) { forwardDist = forwardTracerParticles->distanceTraveled[addIndex]; } else { @@ -1447,16 +1517,16 @@ if( generate_lc > 0 ) } } - NcFile ncFileLC("LcS.nc", NcFile::replace); vector dims_lc; - NcDim nc_nTracers = ncFileLC.addDim("nTracers", nTracers); NcDim nc_nRLc = ncFileLC.addDim("nR", nR_Lc); dims_lc.push_back(nc_nRLc); -#if USE3DTETGEOM - NcDim nc_nYLc = ncFileLC.addDim("nY", nY_Lc); + NcDim nc_nYLc; + if( use_3d_geom ) + { + nc_nYLc = ncFileLC.addDim("nY", nY_Lc); dims_lc.push_back(nc_nYLc); -#endif + } NcDim nc_nZLc = ncFileLC.addDim("nZ", nZ_Lc); dims_lc.push_back(nc_nZLc); @@ -1471,9 +1541,11 @@ if( generate_lc > 0 ) NcVar nc_btz = ncFileLC.addVar("bz", netcdf_precision, dims_lc); NcVar nc_nI = ncFileLC.addVar("noIntersection", netcdf_precision, dims_lc); NcVar nc_gridRLc = ncFileLC.addVar("gridR", netcdf_precision, nc_nRLc); -#if USE3DTETGEOM - NcVar nc_gridYLc = ncFileLC.addVar("gridY", netcdf_precision, nc_nYLc); -#endif + NcVar nc_gridYLc; + if( use_3d_geom ) + { + nc_gridYLc = ncFileLC.addVar("gridY", netcdf_precision, nc_nYLc); + } NcVar nc_gridZLc = ncFileLC.addVar("gridZ", netcdf_precision, nc_nZLc); //FIXME - commented these because of disrupted workflow compile errors //nc_Lc.putVar(&Lc[0]); @@ -1486,9 +1558,11 @@ if( generate_lc > 0 ) //nc_btz.putVar(&backwardTracerZ[0]); //nc_nI.putVar(&noIntersectionNodes[0]); //nc_gridRLc.putVar(&gridRLc[0]); -#if USE3DTETGEOM + if( use_3d_geom ) + { nc_gridYLc.putVar(&gridYLc[0]); -#endif +//#endif + } nc_gridZLc.putVar(&gridZLc[0]); ncFileLC.close(); #if USE_MPI > 0 @@ -1503,7 +1577,7 @@ if( generate_lc > 0 ) //} } -if( lc_interp > 1 ) +if( LC_INTERP > 1 ) { std::cout << "Importing pre-existing connection length file" << std::endl; getVariable(cfg, connLengthCfg + "fileString", lcFile); @@ -1523,7 +1597,6 @@ if( lc_interp > 1 ) int nZ_Temp = 1; int n_Temp = 1; std::string tempCfg = "backgroundPlasmaProfiles.Temperature."; -int temp_interp = use.get(use::temp_interp); std::string tempFile; if(temp_interp > 0 ) { @@ -1595,7 +1668,7 @@ if(temp_interp > 0 ) gitr_precision testVec = 0.0; testVec = interp2dCombined(0.0, 0.1, 0.0, nR_Temp, nZ_Temp, TempGridr.data(), - TempGridz.data(), ti.data()); + TempGridz.data(), ti.data(), cylsymm ); std::cout << "Finished Temperature import " << testVec << std::endl; // Background Plasma Density Initialization @@ -1604,7 +1677,6 @@ if(temp_interp > 0 ) int nZ_Dens = 1; int n_Dens = 1; std::string densCfg = "backgroundPlasmaProfiles.Density."; - int density_interp = use.get( use::density_interp ); std::string densFile; if( density_interp > 0 ) { @@ -1665,11 +1737,11 @@ if( density_interp == 0 ) std::cout << "Finished density import " << interp2dCombined(5.5, 0.0, -4.4, nR_Dens, nZ_Dens, &DensGridr.front(), &DensGridz.front(), - &ne.front()) + &ne.front(), cylsymm ) << " " << interp2dCombined(0.0, 0.1, 0.0, nR_Dens, nZ_Dens, &DensGridr.front(), &DensGridz.front(), - &ne.front()) + &ne.front(), cylsymm ) << std::endl; // for(int i=0;i<100;i++) //{ @@ -1702,7 +1774,6 @@ if( density_interp == 0 ) int nZ_flowV = 1; int n_flowV = 1; std::string flowVCfg = "backgroundPlasmaProfiles.FlowVelocity."; - int flowv_interp = use.get( use::flowv_interp ); if( flowv_interp == 1 ) { nR_flowV = nR_Lc; @@ -1778,6 +1849,13 @@ if( density_interp == 0 ) MPI_Bcast(flowVz.data(), n_flowV, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); #endif + + gitr_precision surroundingMinimumR = 0.0; + gitr_precision surroundingMinimumY = 0.0; + gitr_precision surroundingMinimumZ = 0.0; + int iterIndex = 0; + int nFlowVs; + if( flowv_interp == 1 ) { for (int i = 0; i < nR_flowV; i++) { @@ -1791,8 +1869,8 @@ if( flowv_interp == 1 ) flowVGridz[i] = gridZLc[i]; } std::cout << " !!! flowvgridr0 " << flowVGridr[0] << std::endl; - int nFlowVs = nR_Lc * nZ_Lc; - if( lc_interp == 3 ) + nFlowVs = nR_Lc * nZ_Lc; + if( LC_INTERP == 3 ) { for (int i = 0; i < nY_flowV; i++) flowVGridy[i] = gridYLc[i]; @@ -1821,15 +1899,15 @@ if( flowv_interp == 1 ) // << flowVGridz[j] << " " << nR_Temp << " "< flowVrSub(nFlowVs), flowVzSub(nFlowVs), flowVySub(nFlowVs); sim::Array noIntersectionNearestMax(nFlowVs); - gitr_precision surroundingMinimumR = 0.0; - gitr_precision surroundingMinimumY = 0.0; - gitr_precision surroundingMinimumZ = 0.0; - int iterIndex = 0; for (int i = 0; i < nR_Lc; i++) { std::cout << "i of " << i << " " << nR_Lc << std::endl; for (int j = 0; j < nY_Lc; j++) { @@ -1950,19 +2024,24 @@ if( flowv_interp == 1 ) std::string gradTCfg = "backgroundPlasmaProfiles.gradT."; std::string gradTFile; if (world_rank == 0) { -#if GRADT_INTERP > 0 + if( gradt_interp > 0 ) + { getVariable(cfg, gradTCfg + "fileString", gradTFile); nR_gradT = getDimFromFile(cfg, input_path + gradTFile, gradTCfg, "gridNrString"); -#endif -#if GRADT_INTERP > 1 + } + + if( gradt_interp > 1 ) + { nZ_gradT = getDimFromFile(cfg, input_path + gradTFile, gradTCfg, "gridNzString"); -#endif -#if GRADT_INTERP > 2 + } + + if( gradt_interp > 2 ) + { nY_gradT = getDimFromFile(cfg, input_path + gradTFile, gradTCfg, "gridNyString"); -#endif + } } #if USE_MPI > 0 MPI_Bcast(&nR_gradT, 1, MPI_INT, 0, MPI_COMM_WORLD); @@ -1977,28 +2056,35 @@ if( flowv_interp == 1 ) gradTiR(n_gradT), gradTiZ(n_gradT), gradTiY(n_gradT); if (world_rank == 0) { -#if GRADT_INTERP == 0 + + if( gradt_interp == 0 ) + { getVariable(cfg, gradTCfg + "gradTeR", gradTeR[0]); getVariable(cfg, gradTCfg + "gradTeY", gradTeY[0]); getVariable(cfg, gradTCfg + "gradTeZ", gradTeZ[0]); getVariable(cfg, gradTCfg + "gradTiR", gradTiR[0]); getVariable(cfg, gradTCfg + "gradTiY", gradTiY[0]); getVariable(cfg, gradTCfg + "gradTiZ", gradTiZ[0]); -#else + } + else + { getVarFromFile(cfg, input_path + gradTFile, gradTCfg, "gridRString", gradTGridr[0]); -#if GRADT_INTERP > 1 + if( gradt_interp > 1 ) + { getVarFromFile(cfg, input_path + gradTFile, gradTCfg, "gridZString", gradTGridz[0]); -#endif -#if GRADT_INTERP > 2 + } + + if( gradt_interp > 2 ) + { getVarFromFile(cfg, input_path + gradTFile, gradTCfg, "gridYString", gradTGridy[0]); getVarFromFile(cfg, input_path + gradTFile, gradTCfg, "gradTeYString", gradTeY[0]); getVarFromFile(cfg, input_path + gradTFile, gradTCfg, "gradTiYString", gradTiY[0]); -#endif + } getVarFromFile(cfg, input_path + gradTFile, gradTCfg, "gradTiRString", gradTiR[0]); @@ -2012,7 +2098,7 @@ if( flowv_interp == 1 ) gradTeY[0]); getVarFromFile(cfg, input_path + gradTFile, gradTCfg, "gradTiYString", gradTiY[0]); -#endif + } } #if USE_MPI > 0 MPI_Bcast(&gradTGridr[0], nR_gradT, MPI_FLOAT, 0, MPI_COMM_WORLD); @@ -2029,7 +2115,7 @@ if( flowv_interp == 1 ) gitr_precision gradTi[3] = {0.0}; interp2dVector(&gradTi[0], 1.45, 0.0, -1.2, nR_gradT, nZ_gradT, gradTGridr.data(), gradTGridz.data(), gradTiR.data(), - gradTiZ.data(), gradTiY.data()); + gradTiZ.data(), gradTiY.data(), cylsymm ); std::cout << "thermal gradient interpolation gradTi " << gradTi[0] << " " << gradTi[1] << " " << gradTi[2] << " " << std::endl; @@ -2042,8 +2128,20 @@ if( flowv_interp == 1 ) int nTemperaturesIonize = 1, nDensitiesIonize = 1; int i0, i1, i2, i3, i4; int nTemperaturesRecombine = 1, nDensitiesRecombine = 1; -#if USEIONIZATION > 0 + + sim::Array rateCoeff_Ionization(nCS_Ionize * nTemperaturesIonize * + nDensitiesIonize); + sim::Array gridTemperature_Ionization(nTemperaturesIonize), + gridDensity_Ionization(nDensitiesIonize); + sim::Array rateCoeff_Recombination( + nCS_Recombine * nTemperaturesRecombine * nDensitiesRecombine); + sim::Array gridTemperature_Recombination(nTemperaturesRecombine), + gridDensity_Recombination(nDensitiesRecombine); + + if( ionization > 0 ) + { if (world_rank == 0) { + if (cfg.lookupValue("impurityParticleSource.ionization.fileString", ionizeFile) && cfg.lookupValue("impurityParticleSource.ionization.nChargeStateString", @@ -2057,16 +2155,19 @@ if( flowv_interp == 1 ) cfg.lookupValue("impurityParticleSource.ionization.DensGridVarName", ionizeDensGrid) && cfg.lookupValue("impurityParticleSource.ionization.CoeffVarName", - ionizeRCvarChar)) { + ionizeRCvarChar)) + { std::cout << "Ionization rate coefficient file: " << ionizeFile << std::endl; - } else { + } + + else + { std::cout << "ERROR: Could not get ionization string info from input file " << std::endl; } -#endif -#if USERECOMBINATION > 0 + if (cfg.lookupValue("impurityParticleSource.recombination.fileString", recombFile) && cfg.lookupValue( @@ -2089,8 +2190,7 @@ if( flowv_interp == 1 ) << "ERROR: Could not get ionization string info from input file " << std::endl; } -#endif -#if USEIONIZATION > 0 + i0 = read_profileNs(input_path + ionizeFile, ionizeNcs, recombNcs, nCS_Ionize, nCS_Recombine); @@ -2109,29 +2209,34 @@ if( flowv_interp == 1 ) MPI_Bcast(&nDensitiesRecombine, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); #endif -#endif - sim::Array rateCoeff_Ionization(nCS_Ionize * nTemperaturesIonize * - nDensitiesIonize); - sim::Array gridTemperature_Ionization(nTemperaturesIonize), - gridDensity_Ionization(nDensitiesIonize); - sim::Array rateCoeff_Recombination( - nCS_Recombine * nTemperaturesRecombine * nDensitiesRecombine); - sim::Array gridTemperature_Recombination(nTemperaturesRecombine), - gridDensity_Recombination(nDensitiesRecombine); + + rateCoeff_Ionization.resize( nCS_Ionize * nTemperaturesIonize * nDensitiesIonize ); + + gridTemperature_Ionization.resize( nTemperaturesIonize ); + + gridDensity_Ionization.resize( nDensitiesIonize ); + + rateCoeff_Recombination.resize( nCS_Recombine * + nTemperaturesRecombine * nDensitiesRecombine ); + + gridTemperature_Recombination.resize( nTemperaturesRecombine ); + + gridDensity_Recombination.resize( nDensitiesRecombine ); + if (world_rank == 0) { -#if USEIONIZATION > 0 + i2 = read_profiles( input_path + ionizeFile, nTemperaturesIonize, nDensitiesIonize, ionizeTempGrid, gridTemperature_Ionization, ionizeDensGrid, gridDensity_Ionization, ionizeRCvarChar, rateCoeff_Ionization); -#endif -#if USERECOMBINATION > 0 + i4 = read_profiles( input_path + recombFile, nTemperaturesRecombine, nDensitiesRecombine, recombTempGrid, gridTemperature_Recombination, recombDensGrid, gridDensity_Recombination, recombRCvarChar, rateCoeff_Recombination); -#endif } + } + #if USE_MPI > 0 MPI_Bcast(&rateCoeff_Ionization[0], nCS_Ionize * nTemperaturesIonize * nDensitiesIonize, MPI_FLOAT, 0, @@ -2158,7 +2263,8 @@ if( flowv_interp == 1 ) bfieldGridr.data(), bfieldGridz.data(), br.data(), bz.data(), by.data(), nR_Temp, nZ_Temp, TempGridr.data(), TempGridz.data(), ti.data(), - te.data(), biasPotential)); + te.data(), biasPotential, biased_surface, surface_potential, + use_3d_geom, cylsymm )); std::cout << "Completed Boundary Init " << std::endl; std::cout << "periodicy "< preSheathEGridy(1); -#if USEPRESHEATHEFIELD > 0 + + sim::Array< gitr_precision > PSEr( nPSEs ); + sim::Array< gitr_precision > PSEz( nPSEs ); + sim::Array< gitr_precision > PSEt( nPSEs ); + + sim::Array< gitr_precision > preSheathEGridr( nR_PreSheathEfield ); + sim::Array< gitr_precision > preSheathEGridy( nY_PreSheathEfield ); + sim::Array< gitr_precision > preSheathEGridz( nZ_PreSheathEfield ); + + if( presheath_efield > 0 ) + { std::cout << "Using presheath Efield " << std::endl; -#if PRESHEATH_INTERP == 1 + if( presheath_interp == 1 ) + { nR_PreSheathEfield = nR_Lc; nY_PreSheathEfield = nY_Lc; nZ_PreSheathEfield = nZ_Lc; -#endif -#if PRESHEATH_INTERP > 1 + } + std::string efieldFile; + + if( presheath_interp > 1 ) + { #if USE_MPI > 0 if (world_rank == 0) { #endif @@ -2210,10 +2330,13 @@ if( flowv_interp == 1 ) getDimFromFile(cfg, input_path + efieldFile, PSECfg, "gridNrString"); nZ_PreSheathEfield = getDimFromFile(cfg, input_path + efieldFile, PSECfg, "gridNzString"); -#if PRESHEATH_INTERP > 2 + + if( presheath_interp > 2 ) + { nY_PreSheathEfield = getDimFromFile(cfg, input_path + efieldFile, PSECfg, "gridNyString"); -#endif + } + #if USE_MPI > 0 } MPI_Bcast(&nR_PreSheathEfield, 1, MPI_INT, 0, MPI_COMM_WORLD); @@ -2221,27 +2344,38 @@ if( flowv_interp == 1 ) MPI_Bcast(&nZ_PreSheathEfield, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); #endif -#endif + } + + preSheathEGridr.resize( nR_PreSheathEfield ); + preSheathEGridy.resize( nY_PreSheathEfield ); + preSheathEGridz.resize( nZ_PreSheathEfield ); + nPSEs = nR_PreSheathEfield * nY_PreSheathEfield * nZ_PreSheathEfield; - sim::Array preSheathEGridr(nR_PreSheathEfield), - preSheathEGridy(nY_PreSheathEfield), preSheathEGridz(nZ_PreSheathEfield); - sim::Array PSEr(nPSEs), PSEz(nPSEs), PSEt(nPSEs); + + PSEr.resize( nPSEs ); + PSEz.resize( nPSEs ); + PSEt.resize( nPSEs ); + #if USE_MPI > 0 if (world_rank == 0) { #endif -#if PRESHEATH_INTERP == 0 + if( presheath_interp == 0 ) + { getVariable(cfg, PSECfg + "Er", PSEr[0]); getVariable(cfg, PSECfg + "Et", PSEt[0]); getVariable(cfg, PSECfg + "Ez", PSEz[0]); -#elif PRESHEATH_INTERP > 1 + } + else if( presheath_interp > 1 ) + { getVarFromFile(cfg, input_path + efieldFile, PSECfg, "gridRString", preSheathEGridr[0]); getVarFromFile(cfg, input_path + efieldFile, PSECfg, "gridZString", preSheathEGridz[0]); -#if PRESHEATH_INTERP > 2 + if( presheath_interp > 2 ) + { getVarFromFile(cfg, input_path + efieldFile, PSECfg, "gridYString", preSheathEGridy[0]); -#endif + } getVarFromFile(cfg, input_path + efieldFile, PSECfg, "radialComponentString", PSEr[0]); @@ -2249,7 +2383,8 @@ if( flowv_interp == 1 ) "toroidalComponentString", PSEt[0]); getVarFromFile(cfg, input_path + efieldFile, PSECfg, "axialComponentString", PSEz[0]); -#endif + } + #if USE_MPI > 0 } MPI_Bcast(preSheathEGridr.data(), nR_PreSheathEfield, MPI_FLOAT, 0, @@ -2264,7 +2399,8 @@ if( flowv_interp == 1 ) MPI_Barrier(MPI_COMM_WORLD); #endif -#if PRESHEATH_INTERP == 1 +if( presheath_interp == 1 ) +{ for (int i = 0; i < nR_PreSheathEfield; i++) { preSheathEGridr[i] = gridRLc[i]; @@ -2292,10 +2428,10 @@ if( flowv_interp == 1 ) for (int j = 0; j < nZ_PreSheathEfield; j++) { teLocal1 = interp2dCombined(preSheathEGridr[i], 0.0, preSheathEGridz[j], nR_Temp, nZ_Temp, &TempGridr.front(), - &TempGridz.front(), &te.front()); + &TempGridz.front(), &te.front(), cylsymm ); interp2dVector(&BLocal1[0], gridRLc[i], 0.0, gridZLc[j], nR_Bfield, nZ_Bfield, bfieldGridr.data(), bfieldGridz.data(), - br.data(), bz.data(), by.data()); + br.data(), bz.data(), by.data(), cylsymm ); Bmag1 = std::sqrt(BLocal1[0] * BLocal1[0] + BLocal1[1] * BLocal1[1] + BLocal1[2] * BLocal1[2]); Bnorm1[0] = BLocal1[0] / Bmag1; @@ -2329,7 +2465,7 @@ if( flowv_interp == 1 ) for (int i = 0; i < nR_Lc; i++) { for (int j = 0; j < nY_Lc; j++) { for (int k = 0; k < nZ_Lc; k++) { - index = i + j * nR_Lc + k * nR_Lc * nY_Lc; + int index = i + j * nR_Lc + k * nR_Lc * nY_Lc; if (noIntersectionNodes[index] == 1) { surroundingMinimumR = 0.0; surroundingMinimumY = 0.0; @@ -2378,14 +2514,17 @@ if( flowv_interp == 1 ) nc_PSEr.putVar(&PSEr[0]); nc_PSEt.putVar(&PSEt[0]); nc_PSEz.putVar(&PSEz[0]); -#endif -#else +} + } + else + { nPSEs = nR_PreSheathEfield * nY_PreSheathEfield * nZ_PreSheathEfield; sim::Array preSheathEGridr(nR_PreSheathEfield), preSheathEGridy(nY_PreSheathEfield), preSheathEGridz(nZ_PreSheathEfield); sim::Array PSEr(nPSEs), PSEz(nPSEs), PSEt(nPSEs); -#endif + } + std::string outnamePSEfieldR = "PSEfieldR.m"; std::string outnamePSEfieldZ = "PSEfieldZ.m"; std::string outnamePSEGridR = "PSEgridR.m"; @@ -2403,7 +2542,9 @@ if( flowv_interp == 1 ) Efieldz(nR_Bfield * nZ_Bfield), Efieldt(nR_Bfield * nZ_Bfield), minDist(nR_Bfield * nZ_Bfield); -#if USESHEATHEFIELD > 0 + /* Captain! Likely dead block below */ + if( sheath_efield > 0 ) + { gitr_precision thisE0[3] = {0.0, 0.0, 0.0}; gitr_precision minDist0 = 0.0; int minInd_bnd = 0; @@ -2414,9 +2555,13 @@ if( flowv_interp == 1 ) nR_closeGeom_sheath, nY_closeGeom_sheath, nZ_closeGeom_sheath, n_closeGeomElements_sheath, &closeGeomGridr_sheath.front(), &closeGeomGridy_sheath.front(), &closeGeomGridz_sheath.front(), - &closeGeom_sheath.front(), minInd_bnd); + &closeGeom_sheath.front(), minInd_bnd, biased_surface, + use_3d_geom, geom_hash_sheath, cylsymm ); //std::cout << "Efield rzt " << thisE0[0] << " " << thisE0[1] << " " << thisE0[2] << std::endl; } + /* Captain! Decayed block, leave for reference */ + /* + #if EFIELD_INTERP == 1 gitr_precision thisE[3] = {0.0, 0.0, 0.0}; @@ -2459,7 +2604,9 @@ if( flowv_interp == 1 ) int d4 = read_profile2d( cfg.lookup("backgroundPlasmaProfiles.dtsEfield.fileString"), cfg.lookup("backgroundPlasmaProfiles.dtsEfield.sheathDTS"), dtsE); -#elif EFIELD_INTERP == 2 + */ + if( efield_interp == 2 ) + { int nR_dtsEfield, nZ_dtsEfield; int d1 = read_profileNs( @@ -2484,13 +2631,15 @@ if( flowv_interp == 1 ) int d4 = read_profile2d( cfg.lookup("backgroundPlasmaProfiles.dtsEfield.fileString"), cfg.lookup("backgroundPlasmaProfiles.dtsEfield.sheathDTS"), dtsE); -#endif -#else + } + } + else + { int nR_dtsEfield = 1; int nZ_dtsEfield = 1; sim::Array dtsEfieldGridr(nR_dtsEfield), dtsEfieldGridz(nZ_dtsEfield); sim::Array dtsE(nR_dtsEfield * nZ_dtsEfield); -#endif + } std::string outnameEfieldR = "EfieldR.m"; std::string outnameEfieldZ = "EfieldZ.m"; @@ -2503,12 +2652,29 @@ if( flowv_interp == 1 ) // OUTPUT2d(profiles_folder,outnameMinDist, nR_Bfield, nZ_Bfield, // &minDist.front()); -#if SPECTROSCOPY > 0 - gitr_precision netX0 = 0.0, netX1 = 0.0, netY0 = 0.0, netY1 = 0.0, netZ0 = 0.0, - netZ1 = 0.0; - int net_nX = 0, net_nY = 0, net_nZ = 0; + gitr_precision netX0 = 0.0; + gitr_precision netX1 = 0.0; + gitr_precision netY0 = 0.0; + gitr_precision netY1 = 0.0; + gitr_precision netZ0 = 0.0; + gitr_precision netZ1 = 0.0; + + int net_nX = 0; + int net_nY = 0; + int net_nZ = 0; + int nBins = 0; int nSpec = 0; + + size_t net_Bins_size = 0; + size_t net_BinsTotal_size = 0; + + sim::Array< gitr_precision > gridX_bins(net_nX); + sim::Array< gitr_precision > gridY_bins(net_nY); + sim::Array< gitr_precision > gridZ_bins(net_nZ); + + if( spectroscopy > 0 ) + { if (world_rank == 0) { if (cfg.lookupValue("diagnostics.netx0", netX0) && cfg.lookupValue("diagnostics.netx1", netX1) && @@ -2527,11 +2693,16 @@ if( flowv_interp == 1 ) << std::endl; } } -#if SPECTROSCOPY < 3 - nSpec = (nBins + 1) * net_nX * net_nZ; -#else - nSpec = (nBins + 1) * net_nX * net_nY * net_nZ; -#endif + + if( spectroscopy < 3 ) + { + nSpec = (nBins + 1) * net_nX * net_nZ; + } + else + { + nSpec = (nBins + 1) * net_nX * net_nY * net_nZ; + } + #if USE_MPI > 0 MPI_Bcast(&netX0, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Bcast(&netX1, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); @@ -2549,26 +2720,20 @@ if( flowv_interp == 1 ) std::cout << "spec bin Ns " << nBins << " " << net_nX << " " << net_nY << " " << net_nZ << std::endl; -#if SPECTROSCOPY < 3 - sim::Array net_Bins((nBins + 1) * net_nX * net_nZ, 0.0); - sim::Array net_BinsTotal((nBins + 1) * net_nX * net_nZ, 0.0); -#else - std::cout << "initializing 3d spec arrays " << std::endl; - sim::Array net_Bins((nBins + 1) * net_nX * net_nY * net_nZ, 0.0); - sim::Array net_BinsTotal((nBins + 1) * net_nX * net_nY * net_nZ, 0.0); - std::cout << "initialized 3d spec arrays " << std::endl; -#endif - - /* - for (int i=0; i gridX_bins(net_nX), gridY_bins(net_nY), gridZ_bins(net_nZ); + gridX_bins.resize(net_nX); + gridY_bins.resize(net_nY); + gridZ_bins.resize(net_nZ); for (int i = 0; i < net_nX; i++) { gridX_bins[i] = netX0 + 1.0 / (net_nX - 1) * i * (netX1 - netX0); @@ -2580,7 +2745,11 @@ if( flowv_interp == 1 ) for (int i = 0; i < net_nZ; i++) { gridZ_bins[i] = netZ0 + i * 1.0 / (net_nZ - 1) * (netZ1 - netZ0); } -#endif +} + + sim::Array net_Bins( net_Bins_size, 0.0 ); + + sim::Array net_BinsTotal( net_BinsTotal_size, 0.0 ); // Perp DiffusionCoeff initialization - only used when Diffusion interpolator // is = 0 @@ -2604,9 +2773,10 @@ if( flowv_interp == 1 ) int nE_sputtRefDistOut = 1, nA_sputtRefDistOut = 1; int nE_sputtRefDistOutRef = 1, nDistE_surfaceModelRef = 1; int nDistE_surfaceModel = 1, nDistA_surfaceModel = 1; -#if USESURFACEMODEL > 0 std::string surfaceModelCfg = "surfaceModel."; std::string surfaceModelFile; + if( surface_model > 0 ) + { #if USE_MPI > 0 if (world_rank == 0) { #endif @@ -2651,7 +2821,7 @@ if( flowv_interp == 1 ) MPI_Bcast(&nDistA_surfaceModel, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); #endif -#endif + } sim::Array E_sputtRefCoeff(nE_sputtRefCoeff), A_sputtRefCoeff(nA_sputtRefCoeff), Elog_sputtRefCoeff(nE_sputtRefCoeff), energyDistGrid01(nE_sputtRefDistOut), @@ -2679,7 +2849,9 @@ if( flowv_interp == 1 ) AphiDist_CDF_R_regrid(nDistA_surfaceModel), AthetaDist_CDF_R_regrid(nDistA_surfaceModel), EDist_CDF_R_regrid(nDistE_surfaceModelRef); -#if USESURFACEMODEL > 0 + + if( surface_model > 0 ) + { #if USE_MPI > 0 if (world_rank == 0) { #endif @@ -2939,7 +3111,7 @@ if( flowv_interp == 1 ) MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); #endif -#endif + } // Particle time stepping control // int ionization_nDtPerApply = // cfg.lookup("timeStep.ionization_nDtPerApply"); int collision_nDtPerApply = @@ -3058,7 +3230,9 @@ if( flowv_interp == 1 ) #endif int nSourceSurfaces = 0; -#if PARTICLE_SOURCE_SPACE == 0 // Point Source + int currentSegment = 0; + if( particle_source_space == 0 ) + { if (world_rank == 0) { if (cfg.lookupValue("impurityParticleSource.initialConditions.x_start", x) && @@ -3080,8 +3254,11 @@ if( flowv_interp == 1 ) MPI_Bcast(&z, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); #endif -#elif PARTICLE_SOURCE_SPACE > 0 // Material Surfaces - flux weighted source - Config cfg_particles; + } +// Material Surfaces - flux weighted source + else if( particle_source_space > 0 ) + { + libconfig::Config cfg_particles; std::string particleSourceFile; getVariable(cfg, "particleSource.fileString", particleSourceFile); std::cout << "Open particle source file " << input_path + particleSourceFile @@ -3090,7 +3267,7 @@ if( flowv_interp == 1 ) std::cout << "Successfully staged input and particle source file " << std::endl; - Setting &particleSourceSetting = cfg_particles.lookup("particleSource"); + libconfig::Setting &particleSourceSetting = cfg_particles.lookup("particleSource"); std::cout << "Successfully set particleSource setting " << std::endl; int nSourceBoundaries = 0, nSourceElements = 0; gitr_precision sourceMaterialZ = 0.0, accumulatedLengthArea = 0.0, @@ -3104,11 +3281,14 @@ if( flowv_interp == 1 ) for (int i = 0; i < nLines; i++) { if (boundaries[i].Z == sourceMaterialZ) { nSourceBoundaries++; -#if USE3DTETGEOM + if( use_3d_geom ) + { accumulatedLengthArea = accumulatedLengthArea + boundaries[i].area; -#else + } + else + { accumulatedLengthArea = accumulatedLengthArea + boundaries[i].length; -#endif + } } } } else { @@ -3121,15 +3301,18 @@ if( flowv_interp == 1 ) << std::endl; } for (int i = 0; i < nSourceBoundaries; i++) { -#if USE3DTETGEOM + if( use_3d_geom ) + { accumulatedLengthArea = accumulatedLengthArea + boundaries[int(particleSourceSetting["surfaceIndices"][i])].area; -#else + } + else + { accumulatedLengthArea = accumulatedLengthArea + boundaries[int(particleSourceSetting["surfaceIndices"][i])].length; -#endif + } } } if (cfg_particles.lookupValue("particleSource.sourceSampleResolution", @@ -3151,7 +3334,11 @@ if( flowv_interp == 1 ) particleSourceSpaceGrid(nSourceElements, 0.0); sim::Array particleSourceIndices(nSourceElements, 0), particleSourceBoundaryIndices(nSourceBoundaries, 0); -#if PARTICLE_SOURCE_SPACE == 1 + + /* Captain! Decayed code block, leave for reference */ + /* + if( PARTICLE_SOURCE_SPACE == 1 ) + { for (int i = 0; i < nSourceBoundaries; i++) { particleSourceBoundaryIndices[i] = particleSourceSetting["surfaceIndices"][i]; @@ -3240,10 +3427,12 @@ if( flowv_interp == 1 ) gitr_precision rand0 = 0.0; int lowInd = 0; int currentSegment = 0; -#else -#endif -#endif -#if PARTICLE_SOURCE_ENERGY == 0 + } + */ + } + + if( particle_source_energy == 0 ) + { if (world_rank == 0) { if (cfg.lookupValue("impurityParticleSource.initialConditions.energy_eV", E)) { @@ -3259,8 +3448,11 @@ if( flowv_interp == 1 ) MPI_Bcast(&E, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); #endif -#elif PARTICLE_SOURCE_ENERGY > 0 -#if PARTICLE_SOURCE_ENERGY == 1 + } + else if( particle_source_energy > 0 ) + { + if( particle_source_energy == 1 ) + { // Create Thompson Distribution gitr_precision surfaceBindingEnergy = cfg.lookup("impurityParticleSource.source_material_SurfaceBindingEnergy"); @@ -3296,14 +3488,14 @@ if( flowv_interp == 1 ) // std::cout << "energy and CDF" << i*max_Energy/nThompDistPoints << " " << // CumulativeDFThompson[i] << std::endl; } -#elif PARTICLE_SOURCE_ENERGY == 2 -#endif + } //boost::random::mt19937 sE; //boost::random::uniform_01<> dist01E; gitr_precision randE = 0.0; int lowIndE = 0; -#endif -#if PARTICLE_SOURCE_ANGLE == 0 + } + if( particle_source_angle == 0 ) + { if (world_rank == 0) { if (cfg.lookupValue("impurityParticleSource.initialConditions.phi", phi) && cfg.lookupValue("impurityParticleSource.initialConditions.theta", @@ -3333,12 +3525,12 @@ if( flowv_interp == 1 ) vy = 0.0; vz = vtotal; } -#elif PARTICLE_SOURCE_ANGLE > 0 + } + else if( particle_source_angle > 0 ) + { std::cout << "Read particle source " << std::endl; -#if PARTICLE_SOURCE_ENERGY < 2 - Config cfg_particles; -#endif + // cfg_particles.readFile((input_path+"particleSource.cfg").c_str()); // Setting& particleSource = cfg_particles.lookup("particleSource"); // int nSegmentsAngle = particleSource["nSegmentsAngle"]; @@ -3355,12 +3547,13 @@ if( flowv_interp == 1 ) std::uniform_real_distribution dist01A(0.0, 1.0); gitr_precision randA = 0.0; int lowIndA = 0; -#endif + } std::cout << "Starting psourcefile import " << std::endl; -#if PARTICLE_SOURCE_FILE > 0 // File source - libconfig::Config cfg_particles; vector xpfile(nP), ypfile(nP), zpfile(nP), vxpfile(nP), vypfile(nP), vzpfile(nP); + if( particle_source_file > 0 ) + { + libconfig::Config cfg_particles; std::string ncParticleSourceFile; int nPfile = 0; if (world_rank == 0) { @@ -3430,19 +3623,19 @@ if( flowv_interp == 1 ) // << zpfile[i] << std::endl; std::cout << " Exyz from file " << Expfile[i] // << " " << Eypfile[i] << " " << Ezpfile[i] << std::endl; //} -#endif + } std::cout << "particle file import done" << std::endl; -#if USE3DTETGEOM > 0 - // MPI_Bcast(&boundaries[0].area, nLines,MPI_FLOAT,0,MPI_COMM_WORLD); -#endif sim::Array pSurfNormX(nP), pSurfNormY(nP), pSurfNormZ(nP), px(nP), py(nP), pz(nP), pvx(nP), pvy(nP), pvz(nP); int surfIndexMod = 0; gitr_precision eVec[3] = {0.0}; for (int i = 0; i < nP; i++) { //std::cout<< "setting particle " << i << std::endl; -#if PARTICLE_SOURCE_SPACE > 0 // File source -#if USE3DTETGEOM > 0 + /* Captain! Decayed block below */ + /* + if( PARTICLE_SOURCE_SPACE > 0 ) + { + { surfIndexMod = i % nSourceSurfaces; gitr_precision xCentroid = (boundaries[sourceElements[surfIndexMod]].x1 + boundaries[sourceElements[surfIndexMod]].x2 + @@ -3469,7 +3662,10 @@ if( flowv_interp == 1 ) bufferLaunch * boundaries[sourceElements[surfIndexMod]].c / boundaries[sourceElements[surfIndexMod]] .plane_norm; // boundaries[sourceElements[surfIndexMod]].z1; -#else +//#else + } + else + { // x = sampled rand0 = dist01(s0); gitr_precision distAlongSegs = @@ -3497,8 +3693,12 @@ if( flowv_interp == 1 ) z = z - buffer * boundaries[currentSegment].c / boundaries[currentSegment] .plane_norm; // boundaries[sourceElements[surfIndexMod]].z1; -#endif -#endif +//#endif + } + } + */ + /* Captain! Another decayed block */ + /* #if PARTICLE_SOURCE_ENERGY > 0 randE = dist01E(sE); #if PARTICLE_SOURCE_ENERGY == 1 @@ -3526,15 +3726,19 @@ if( flowv_interp == 1 ) << " puts the particle energy to " << E << std::endl; #endif #endif -#if PARTICLE_SOURCE_ANGLE == 1 // Analytic normal incidence + */ + if( particle_source_angle == 1 ) + { Ex = -E * boundaries[currentSegment].a / boundaries[currentSegment].plane_norm; Ey = -E * boundaries[currentSegment].b / boundaries[currentSegment].plane_norm; Ez = -E * boundaries[currentSegment].c / boundaries[currentSegment].plane_norm; + } -#elif PARTICLE_SOURCE_ANGLE > 1 + /* Captain! Decayed code block below */ + /* randA = dist01A(sA); gitr_precision sputtA = interp3d(randA, localAngle, std::log10(3.0 * localT), @@ -3599,25 +3803,28 @@ if( flowv_interp == 1 ) std::cout << "Transformed E " << Ex << " " << Ey << " " << Ez << " " << std::endl; // particleArray->setParticle(i,x, y, z, Ex, Ey,Ez, Z, amu, charge); -#endif + */ -#if PARTICLE_SOURCE_FILE > 0 // File source + if( particle_source_file > 0 ) + { x = xpfile[i]; y = ypfile[i]; z = zpfile[i]; vx = vxpfile[i]; vy = vypfile[i]; vz = vzpfile[i]; -#endif + } particleArray->setParticleV(i, x, y, z, vx, vy, vz, Z, amu, charge,dt); -#if PARTICLE_SOURCE_SPACE > 0 + + if( particle_source_space > 0 ) + { pSurfNormX[i] = -boundaries[currentSegment].a / boundaries[currentSegment].plane_norm; pSurfNormY[i] = -boundaries[currentSegment].b / boundaries[currentSegment].plane_norm; pSurfNormZ[i] = -boundaries[currentSegment].c / boundaries[currentSegment].plane_norm; -#endif + } px[i] = x; py[i] = y; pz[i] = z; @@ -3655,7 +3862,9 @@ if( flowv_interp == 1 ) } #endif -#if GEOM_TRACE > 0 + /* + if( GEOM_TRACE > 0 ) + { std::uniform_real_distribution dist2(0, 1); // std::random_device rd2; // std::default_random_engine generator2(rd2()); @@ -3671,9 +3880,9 @@ if( flowv_interp == 1 ) particleArray->vy[i] = mag_trace * std::sin(theta_trace) * std::sin(phi_trace); particleArray->vz[i] = mag_trace * std::cos(phi_trace); } -#endif + } + */ -#if PARTICLE_TRACKS > 0 int subSampleFac = 1; if (world_rank == 0) { if (cfg.lookupValue("diagnostics.trackSubSampleFactor", subSampleFac)) { @@ -3691,14 +3900,6 @@ if( flowv_interp == 1 ) #endif int nHistoriesPerParticle = (nT / subSampleFac) + 1; int nHistories = nHistoriesPerParticle * nP; - for (int i = 0; i < world_size; i++) { - pDisplacement[i] = pStartIndx[i] * nHistoriesPerParticle; - pHistPerNode[i] = nPPerRank[i] * nHistoriesPerParticle; - } - const int *displ = &pDisplacement[0]; - const int *phpn = &pHistPerNode[0]; - std::cout << "History array length " << nHistories << std::endl; -#if USE_CUDA > 0 sim::Array positionHistoryX(nHistories); sim::Array positionHistoryXgather(nHistories, 0.0); sim::Array positionHistoryY(nHistories); @@ -3717,27 +3918,19 @@ if( flowv_interp == 1 ) sim::Array chargeHistoryGather(nHistories); sim::Array weightHistory(nHistories); sim::Array weightHistoryGather(nHistories); -#else - std::vector positionHistoryX(nHistories); - std::vector positionHistoryXgather(nHistories, 0.0); - std::vector positionHistoryY(nHistories); - std::vector positionHistoryYgather(nHistories); - std::vector positionHistoryZ(nHistories); - std::vector positionHistoryZgather(nHistories); - std::vector velocityHistory(nHistories); - std::vector velocityHistoryX(nHistories); - std::vector velocityHistoryY(nHistories); - std::vector velocityHistoryZ(nHistories); - std::vector velocityHistorygather(nHistories); - std::vector velocityHistoryXgather(nHistories); - std::vector velocityHistoryYgather(nHistories); - std::vector velocityHistoryZgather(nHistories); - std::vector chargeHistory(nHistories); - std::vector chargeHistoryGather(nHistories); - std::vector weightHistory(nHistories); - std::vector weightHistoryGather(nHistories); -#endif -#endif + + if( particle_tracks > 0 ) + { + + for (int i = 0; i < world_size; i++) { + pDisplacement[i] = pStartIndx[i] * nHistoriesPerParticle; + pHistPerNode[i] = nPPerRank[i] * nHistoriesPerParticle; + } + + const int *displ = &pDisplacement[0]; + const int *phpn = &pHistPerNode[0]; + std::cout << "History array length " << nHistories << std::endl; + } gitr_precision *finalPosX = new gitr_precision[nP]; gitr_precision *finalPosY = new gitr_precision[nP]; gitr_precision *finalPosZ = new gitr_precision[nP]; @@ -3769,7 +3962,6 @@ if( flowv_interp == 1 ) thrust::counting_iterator particleZero(0); auto randInitStart_clock = gitr_time::now(); -#if PARTICLESEEDS > 0 #ifdef __CUDACC__ typedef curandState rand_type; #else @@ -3780,11 +3972,13 @@ if( flowv_interp == 1 ) #else sim::Array state1(nParticles); #endif -#if USEIONIZATION > 0 || USERECOMBINATION > 0 || USEPERPDIFFUSION > 0 || \ - USECOULOMBCOLLISIONS > 0 || USESURFACEMODEL > 0 + if( ionization > 0 || + perp_diffusion > 0 || + coulomb_collisions > 0 || + surface_model > 0 ) + { #if USE_CUDA - // if(world_rank == 0) - //{ + int *dev_i; cudaMallocManaged(&dev_i, sizeof(int)); dev_i[0] = 0; @@ -3794,29 +3988,28 @@ if( flowv_interp == 1 ) // world_rank*nP/world_size,particleBegin + // (world_rank+1)*nP/world_size-10, // curandInitialize(&state1[0],randDeviceInit,0)); - curandInitialize<>(&state1.front(), 0)); + curandInitialize<>( &state1.front(), fixed_seeds )); std::cout << " finished curandInit" << std::endl; - // curandInitialize cuIn(0); - // cuIn(0); - //} - //} #else std::random_device randDeviceInit; // thrust::for_each(thrust::device,particleBegin+ // world_rank*nP/world_size,particleBegin + (world_rank+1)*nP/world_size, // curandInitialize(&state1[0],randDeviceInit,0)); // std::mt19937 s0(randDeviceInit); + thrust::for_each( thrust::device, particleBegin, particleEnd, + curandInitialize<>( &state1.front(), fixed_seeds ) ); + /* for (int i = world_rank * nP / world_size; i < (world_rank + 1) * nP / world_size; i++) { std::mt19937 s0(randDeviceInit()); state1[i] = s0; } + */ #endif #if USE_CUDA cudaDeviceSynchronize(); #endif -#endif -#endif +} auto randInitEnd_clock = gitr_time::now(); std::chrono::duration fsRandInit = randInitEnd_clock - randInitStart_clock; printf( @@ -3843,7 +4036,12 @@ if( flowv_interp == 1 ) nR_closeGeom_sheath, nY_closeGeom_sheath, nZ_closeGeom_sheath, n_closeGeomElements_sheath, &closeGeomGridr_sheath.front(), &closeGeomGridy_sheath.front(), &closeGeomGridz_sheath.front(), - &closeGeom_sheath.front(),gitr_flags,max_dt); + &closeGeom_sheath.front(),gitr_flags, sheath_efield, presheath_efield, biased_surface, + geom_hash_sheath, + use_3d_geom, + cylsymm, + max_dt); + //void (*bor)(std::size_t) = &move_boris::operator2; //auto bor1 = *bor; geometry_check geometry_check0( @@ -3851,55 +4049,48 @@ if( flowv_interp == 1 ) nR_closeGeom.data(), nY_closeGeom.data(), nZ_closeGeom.data(), n_closeGeomElements.data(), &closeGeomGridr.front(), &closeGeomGridy.front(), &closeGeomGridz.front(), &closeGeom.front(), - nEdist, E0dist, Edist, nAdist, A0dist, Adist); -#if USE_SORT > 0 + nEdist, E0dist, Edist, nAdist, A0dist, Adist, flux_ea, surface_model, + geom_hash, + use_3d_geom, + cylsymm ); + sortParticles sort0(particleArray, nP,dev_tt, 10000, nActiveParticlesOnRank.data()); -#endif -#if SPECTROSCOPY > 0 spec_bin spec_bin0(gitr_flags,particleArray, nBins, net_nX, net_nY, net_nZ, &gridX_bins.front(), &gridY_bins.front(), - &gridZ_bins.front(), &net_Bins.front(), dt); -#endif -#if USEIONIZATION > 0 -#if USE_CUDA > 0 + &gridZ_bins.front(), &net_Bins.front(), dt, cylsymm, spectroscopy ); + gitr_precision *uni; + + if( ionization > 0 ) + { +#if USE_CUDA > 0 cudaMallocManaged(&uni, sizeof(gitr_precision)); #else - gitr_precision *uni = new gitr_precision[1]; + uni = new gitr_precision[1]; *uni = 0; #endif + } ionize ionize0( gitr_flags,particleArray, dt, &state1.front(), nR_Dens, nZ_Dens, &DensGridr.front(), &DensGridz.front(), &ne.front(), nR_Temp, nZ_Temp, &TempGridr.front(), &TempGridz.front(), &te.front(), nTemperaturesIonize, nDensitiesIonize, &gridTemperature_Ionization.front(), &gridDensity_Ionization.front(), - &rateCoeff_Ionization.front(),uni); - //if(gitr_flags.USE_IONIZATION > 0) ionize0.func = &ionize::operator(); - //else ionize0.func = &ionize::operator1; - //void (ionize::*func)(std::size_t) = &ionize::operator(); - //ionize * ionize_ptr = &ionize0; - //void (*func11)(std::size_t) = &ionize0.operator(); - //if(gitr_flags.USE_IONIZATION > 0) &func = &ionize::operator1; - //else func = NULL; - //auto func1 = *func; -#endif -#if USERECOMBINATION > 0 + &rateCoeff_Ionization.front(),uni, cylsymm ); + recombine recombine0( particleArray, dt, &state1.front(), nR_Dens, nZ_Dens, &DensGridr.front(), &DensGridz.front(), &ne.front(), nR_Temp, nZ_Temp, &TempGridr.front(), &TempGridz.front(), &te.front(), nTemperaturesRecombine, nDensitiesRecombine, gridTemperature_Recombination.data(), - gridDensity_Recombination.data(), rateCoeff_Recombination.data(),gitr_flags); -#endif -#if USEPERPDIFFUSION > 0 - crossFieldDiffusion crossFieldDiffusion0(gitr_flags, + gridDensity_Recombination.data(), rateCoeff_Recombination.data(),gitr_flags, cylsymm ); + + crossFieldDiffusion crossFieldDiffusion0( gitr_flags, particleArray, dt, &state1.front(), perpDiffusionCoeff, nR_Bfield, nZ_Bfield, bfieldGridr.data(), &bfieldGridz.front(), &br.front(), - &bz.front(), &by.front()); -#endif -#if USECOULOMBCOLLISIONS > 0 + &bz.front(), &by.front(), perp_diffusion, cylsymm ); + coulombCollisions coulombCollisions0( particleArray, dt, &state1.front(), nR_flowV, nY_flowV, nZ_flowV, &flowVGridr.front(), &flowVGridy.front(), &flowVGridz.front(), @@ -3907,19 +4098,16 @@ if( flowv_interp == 1 ) &DensGridr.front(), &DensGridz.front(), &ne.front(), nR_Temp, nZ_Temp, &TempGridr.front(), &TempGridz.front(), ti.data(), &te.front(), background_Z, background_amu, nR_Bfield, nZ_Bfield, bfieldGridr.data(), - &bfieldGridz.front(), &br.front(), &bz.front(), &by.front(),gitr_flags); + &bfieldGridz.front(), &br.front(), &bz.front(), &by.front(),gitr_flags, flowv_interp, + cylsymm, field_aligned_values ); -#endif -#if USETHERMALFORCE > 0 thermalForce thermalForce0(gitr_flags, particleArray, dt, background_amu, nR_gradT, nZ_gradT, gradTGridr.data(), gradTGridz.data(), gradTiR.data(), gradTiZ.data(), gradTiY.data(), gradTeR.data(), gradTeZ.data(), gradTeY.data(), nR_Bfield, nZ_Bfield, bfieldGridr.data(), &bfieldGridz.front(), &br.front(), &bz.front(), - &by.front()); -#endif + &by.front(), cylsymm ); -#if USESURFACEMODEL > 0 reflection reflection0( particleArray, dt, &state1.front(), nLines, &boundaries[0], surfaces, nE_sputtRefCoeff, nA_sputtRefCoeff, A_sputtRefCoeff.data(), @@ -3932,18 +4120,17 @@ if( flowv_interp == 1 ) energyDistGrid01Ref.data(), angleDistGrid01.data(), EDist_CDF_Y_regrid.data(), AphiDist_CDF_Y_regrid.data(), EDist_CDF_R_regrid.data(), AphiDist_CDF_R_regrid.data(), nEdist, E0dist, - Edist, nAdist, A0dist, Adist); -#endif + Edist, nAdist, A0dist, Adist, flux_ea, use_3d_geom, cylsymm ); -#if PARTICLE_TRACKS > 0 history history0(particleArray, dev_tt, nT, subSampleFac, nP, &positionHistoryX.front(), &positionHistoryY.front(), &positionHistoryZ.front(), &velocityHistory.front(), &velocityHistoryX.front(), &velocityHistoryY.front(), &velocityHistoryZ.front(), &chargeHistory.front(), &weightHistory.front()); -#endif -#if FORCE_EVAL > 0 + + if( force_eval > 0 ) + { if (world_rank == 0) { int nR_force, nZ_force; gitr_precision forceX0, forceX1, forceZ0, forceZ1, testEnergy; @@ -3980,55 +4167,62 @@ if( flowv_interp == 1 ) for (int j = 0; j < nZ_force; j++) { interp2dVector(&Btest[0], forceR[i], 0.0, forceZ[j], nR_Bfield, nZ_Bfield, bfieldGridr.data(), bfieldGridz.data(), - br.data(), bz.data(), by.data()); + br.data(), bz.data(), by.data(), cylsymm ); Btotal = vectorNorm(Btest); // std::cout << "node " << world_rank << "Bfield at "<< forceR[i] << " // " << forceZ[j]<< " " << Btest[0] << " " << Btest[1] << gitr_precision testTi = interp2dCombined(0.0, 0.1, 0.0, nR_Temp, nZ_Temp, TempGridr.data(), - TempGridz.data(), ti.data()); + TempGridz.data(), ti.data(), cylsymm ); //std::cout << "Finished Temperature import " << testVec << std::endl; //" " << Btest[2] << " " << Btotal << std::endl; particleArray->setParticle(0, forceR[i], 0.0, forceZ[j], testTi, 0.0, 0.0, Z, amu, charge + 1.0); move_boris0(0); -#if USEIONIZATION > 0 - thrust::for_each(thrust::device,particleBegin,particleBegin,ionize0); -#endif -#if USERECOMBINATION > 0 - thrust::for_each(thrust::device,particleBegin,particleBegin,recombine0); -#endif -#if USECOULOMBCOLLISIONS > 0 + + if( ionization > 0 ) + { + thrust::for_each(thrust::device,particleBegin,particleBegin,ionize0); + thrust::for_each(thrust::device,particleBegin,particleBegin,recombine0); + } + + if( coulomb_collisions > 0 ) + { thrust::for_each(thrust::device,particleBegin,particleBegin,coulombCollisions0); -#endif -#if USETHERMALFORCE > 0 + } + + if( thermal_force > 0 ) + { thrust::for_each(thrust::device,particleBegin,particleBegin,thermalForce0); -#endif + } dvEr[j * nR_force + i] = move_boris0.electricForce[0]; dvEz[j * nR_force + i] = move_boris0.electricForce[2]; dvEt[j * nR_force + i] = move_boris0.electricForce[1]; dvBr[j * nR_force + i] = move_boris0.magneticForce[0]; dvBz[j * nR_force + i] = move_boris0.magneticForce[2]; dvBt[j * nR_force + i] = move_boris0.magneticForce[1]; -#if USEIONIZATION > 0 - tIon[j * nR_force + i] = ionize0.tion; -#endif -#if USERECOMBINATION > 0 - tRecomb[j * nR_force + i] = recombine0.tion; -#endif -#if USECOULOMBCOLLISIONS > 0 + + if( ionization > 0 ) + { + tIon[j * nR_force + i] = ionize0.tion; + tRecomb[j * nR_force + i] = recombine0.tion; + } + + if( coulomb_collisions > 0 ) + { dvCollr[j * nR_force + i] = coulombCollisions0.dv[0]; dvCollz[j * nR_force + i] = coulombCollisions0.dv[2]; dvCollt[j * nR_force + i] = coulombCollisions0.dv[1]; -#endif -#if USETHERMALFORCE > 0 + } + if( thermal_force > 0 ) + { dvITGr[j * nR_force + i] = thermalForce0.dv_ITGx; dvITGz[j * nR_force + i] = thermalForce0.dv_ITGz; dvITGt[j * nR_force + i] = thermalForce0.dv_ITGy; dvETGr[j * nR_force + i] = thermalForce0.dv_ETGx; dvETGz[j * nR_force + i] = thermalForce0.dv_ETGz; dvETGt[j * nR_force + i] = thermalForce0.dv_ETGy; -#endif + } } } std::cout << " about to write ncFile_forces " << std::endl; @@ -4080,24 +4274,27 @@ if( flowv_interp == 1 ) particleArray->setParticleV(0, px[0], py[0], pz[0], pvx[0], pvy[0], pvz[0], Z, amu, charge, dt); } -#endif +} auto start_clock = gitr_time::now(); std::chrono::duration fs1 = start_clock - gitr_start_clock; printf("Initialize time for node %i is %6.3f (secs) \n", world_rank, fs1.count()); gitr_precision testFlowVec[3] = {0.0}; -#if USEFIELDALIGNEDVALUES > 0 + if( field_aligned_values > 0 ) + { interpFieldAlignedVector(&testFlowVec[0], 1.4981, 0.0, 1.0, nR_flowV, nZ_flowV, flowVGridr.data(), flowVGridz.data(), flowVr.data(), flowVz.data(), flowVt.data(), nR_Bfield, nZ_Bfield, bfieldGridr.data(), - bfieldGridz.data(), br.data(), bz.data(), by.data()); -#else + bfieldGridz.data(), br.data(), bz.data(), by.data(), cylsymm ); + } + else + { interp2dVector(&testFlowVec[0], 1.4981, 0.0, 1.0, nR_flowV, nZ_flowV, flowVGridr.data(), flowVGridz.data(), flowVr.data(), - flowVz.data(), flowVt.data()); -#endif + flowVz.data(), flowVt.data(), cylsymm ); + } gitr_precision leakZ = 0.0; if (world_rank == 0) { @@ -4153,11 +4350,12 @@ if( flowv_interp == 1 ) #ifdef __CUDACC__ cudaDeviceSynchronize(); #endif - /* Ahoy! this is a 3 level 4-loop to calculate density n = (x, y, q). To show the spacial + /* this is a 3 level 4-loop to calculate density n = (x, y, q). To show the spacial density and the result. Loop over timesteps, each operator loops over a section of the particles... find 0 */ for (tt; tt < nT; tt++) { -#if USE_SORT > 0 + if( sort_particles > 0 ) + { dev_tt[0] = tt; //std::cout << " tt " << tt << std::endl; thrust::for_each(thrust::host, particleBegin, particleOne, sort0); @@ -4165,14 +4363,12 @@ if( flowv_interp == 1 ) #ifdef __CUDACC__ cudaDeviceSynchronize(); #endif -#endif + } -#if PARTICLE_TRACKS > 0 + if( particle_tracks > 0 ) + { thrust::for_each(thrust::device, particleBegin, particleEnd, history0); -#ifdef __CUDACC__ - // cudaThreadSynchronize(); -#endif -#endif + } // std::cout << " world rank pstart nactive " << world_rank << " " << // pStartIndx[world_rank] << " " << nActiveParticlesOnRank[world_rank] << // std::endl; thrust::for_each(thrust::device,particleBegin,particleOne, @@ -4188,70 +4384,50 @@ if( flowv_interp == 1 ) // cudaThreadSynchronize(); #endif -#if SPECTROSCOPY > 0 + if( spectroscopy > 0 ) + { thrust::for_each(thrust::device, particleBegin, particleEnd, spec_bin0); -#ifdef __CUDACC__ - // cudaThreadSynchronize(); -#endif -#endif - -#if USEIONIZATION > 0 - thrust::for_each(thrust::device, particleBegin, particleEnd,ionize0); -#ifdef __CUDACC__ - // cudaThreadSynchronize(); -#endif -#endif + } -#if USERECOMBINATION > 0 - thrust::for_each(thrust::device, particleBegin, particleEnd, recombine0); -#ifdef __CUDACC__ - // cudaThreadSynchronize(); -#endif -#endif + if( ionization > 0 ) + { + thrust::for_each(thrust::device, particleBegin, particleEnd,ionize0); + thrust::for_each(thrust::device, particleBegin, particleEnd, recombine0); + } -#if USEPERPDIFFUSION > 0 + if( perp_diffusion > 0 ) + { thrust::for_each(thrust::device, particleBegin, particleEnd, crossFieldDiffusion0); thrust::for_each(thrust::device, particleBegin, particleEnd, geometry_check0); -#ifdef __CUDACC__ - // cudaThreadSynchronize(); -#endif - -#ifdef __CUDACC__ - // cudaThreadSynchronize(); -#endif -#endif + } -#if USECOULOMBCOLLISIONS > 0 + if( coulomb_collisions > 0 ) + { thrust::for_each(thrust::device, particleBegin, particleEnd, coulombCollisions0); -#ifdef __CUDACC__ - // cudaThreadSynchronize(); -#endif -#endif + } -#if USETHERMALFORCE > 0 + if( thermal_force > 0 ) + { thrust::for_each(thrust::device, particleBegin, particleEnd, thermalForce0); -#ifdef __CUDACC__ - // cudaThreadSynchronize(); -#endif -#endif + } -#if USESURFACEMODEL > 0 + if( surface_model > 0 ) + { + //std::cout << "Ahoy, Captain!" << std::endl; thrust::for_each(thrust::device, particleBegin, particleEnd, reflection0); -#ifdef __CUDACC__ - // cudaThreadSynchronize(); -#endif -#endif + } } -#if PARTICLE_TRACKS > 0 + if( particle_tracks > 0 ) + { tt = nT; // dev_tt[0] = tt; // std::cout << " tt for final history " << tt << std::endl; thrust::for_each(thrust::device, particleBegin, particleEnd, history0); -#endif + } // Ensure that all time step loop GPU kernels are complete before proceeding #ifdef __CUDACC__ @@ -4396,7 +4572,9 @@ for(int i=0; i 0 + + if( particle_tracks > 0 ) + { std::vector exampleArray(4, 0.0); std::vector exampleArrayGather(4, 0.0); @@ -4468,21 +4646,18 @@ for(int i=0; i 0 + if( spectroscopy > 0 ) + { MPI_Barrier(MPI_COMM_WORLD); MPI_Reduce(&net_Bins[0], &net_BinsTotal[0], nSpec, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); -#endif -#if (USESURFACEMODEL > 0 || FLUX_EA > 0) + } + + if( surface_model > 0 || flux_ea > 0 ) + { // MPI_Barrier(MPI_COMM_WORLD); std::cout << "Starting surface reduce " << std::endl; // for(int i=0;ihitWall[i] > 0.0) totalHitWall++; } -#if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { gitr_precision meanTransitTime0 = 0.0; /* for (int i=0; i 0.0) { surfIndex = boundaries[closestBoundaryIndex].surfaceNumber; @@ -4767,7 +4948,8 @@ std::cout << "bound 255 " << boundaries[255].impacts << std::endl; // std::cout << "weights " << " " << weights1[i] << " " << // weightThreshold[0] << std::endl; //} -#if (USESURFACEMODEL > 0 || FLUX_EA > 0) + if( surface_model > 0 || flux_ea > 0 ) + { #if USE_MPI > 0 std::vector surfaceNumbers(nSurfaces, 0); int srf = 0; @@ -4889,9 +5071,10 @@ std::cout << "bound 255 " << boundaries[255].impacts << std::endl; // NcVar nc_surfADistGrid = ncFile1.addVar("gridA",ncDouble,nc_nAngles); // nc_surfADistGrid.putVar(&surfaces->gridA[0]); ncFile1.close(); + } #endif -#endif -#if PARTICLE_TRACKS > 0 + if( particle_tracks > 0 ) + { // Write netCDF output for histories netCDF::NcFile ncFile_hist("output/history.nc", netCDF::NcFile::replace); @@ -4945,22 +5128,29 @@ std::cout << "bound 255 " << boundaries[255].impacts << std::endl; nc_charge.putVar(&chargeHistory[0]); #endif ncFile_hist.close(); -#endif -#if SPECTROSCOPY > 0 + } + if( spectroscopy > 0 ) + { // Write netCDF output for density data netCDF::NcFile ncFile("output/spec.nc", netCDF::NcFile::replace); netCDF::NcDim nc_nBins = ncFile.addDim("nBins", nBins + 1); netCDF::NcDim nc_nR = ncFile.addDim("nR", net_nX); -#if SPECTROSCOPY > 2 - netCDF::NcDim nc_nY = ncFile.addDim("nY", net_nY); -#endif + netCDF::NcDim nc_nY; + if( spectroscopy > 2 ) + { + nc_nY = ncFile.addDim("nY", net_nY); + } + netCDF::NcDim nc_nZ = ncFile.addDim("nZ", net_nZ); vector dims; dims.push_back(nc_nBins); dims.push_back(nc_nZ); -#if SPECTROSCOPY > 2 + + if( spectroscopy > 2 ) + { dims.push_back(nc_nY); -#endif + } + dims.push_back(nc_nR); netCDF::NcVar nc_n = ncFile.addVar("n", netcdf_precision, dims); @@ -4968,17 +5158,19 @@ std::cout << "bound 255 " << boundaries[255].impacts << std::endl; netCDF::NcVar nc_gridZ = ncFile.addVar("gridZ", netcdf_precision, nc_nZ); nc_gridR.putVar(&gridX_bins[0]); nc_gridZ.putVar(&gridZ_bins[0]); -#if SPECTROSCOPY > 2 + if( spectroscopy > 2 ) + { netCDF::NcVar nc_gridY = ncFile.addVar("gridY", netcdf_precision, nc_nY); nc_gridY.putVar(&gridY_bins[0]); -#endif + } + #if USE_MPI > 0 nc_n.putVar(&net_BinsTotal[0]); #else nc_n.putVar(&net_Bins[0]); #endif ncFile.close(); -#endif + } #ifdef __CUDACC__ cudaDeviceSynchronize(); #endif diff --git a/src/hashGeom.cpp b/src/hashGeom.cpp index f9372d18..ea6aa3f6 100644 --- a/src/hashGeom.cpp +++ b/src/hashGeom.cpp @@ -7,11 +7,10 @@ hashGeom::hashGeom( int _nLines,int _nHashes, gitr_precision* _z, int* _n_closeGeomElements,//gitr_precision *_minDist, int *_closeGeom, - int* _nR, int* _nY, int* _nZ) + int* _nR, int* _nY, int* _nZ, int use_3d_geom_ ) : nLines(_nLines),nHashes(_nHashes),boundary(_boundary), x(_x), y(_y), z(_z), n_closeGeomElements(_n_closeGeomElements), - //minDist(_minDist), - closeGeom(_closeGeom), nR(_nR), nY(_nY), nZ(_nZ) + closeGeom(_closeGeom), nR(_nR), nY(_nY), nZ(_nZ), use_3d_geom( use_3d_geom_ ) { } CUDA_CALLABLE_MEMBER_DEVICE @@ -24,6 +23,7 @@ void hashGeom::operator()(std::size_t indx) { int nYhashSum=0; int nZhashSum=0; int nHashPoints=0; + /* Captain! Iterate over the number of hash files */ for(int i=0;i 0 + gitr_precision x0; + + gitr_precision y0; + + gitr_precision z0; + + int xyzIndx; + + int buffIndx; + + if( use_3d_geom > 0 ) + { gitr_precision kk = (indx-nHashPoints)/(nR[nHash]*nY[nHash]); //std::cout << "kk " << kk << std::endl; @@ -78,14 +89,16 @@ void hashGeom::operator()(std::size_t indx) { //if( j > nY || j < 0){ std::cout << "j out of range " << j << std::endl; exit(0);} //if( k > nZ || k < 0){ std::cout << "k out of range " << k << "indx " << indx<< std::endl; exit(0);} //std::cout << "ijk " << i << " " << j << " "<< k << std::endl; - int xyzIndx = indx; - int buffIndx = hashSum+(k*(nR[nHash]*nY[nHash])+j*nR[nHash]+i)*n_closeGeomElements[nHash] ; - gitr_precision x0 = x[nRhashSum+i]; - gitr_precision y0 = y[nYhashSum+j]; - gitr_precision z0 = z[nZhashSum+k]; + xyzIndx = indx; + buffIndx = hashSum+(k*(nR[nHash]*nY[nHash])+j*nR[nHash]+i)*n_closeGeomElements[nHash] ; + x0 = x[nRhashSum+i]; + y0 = y[nYhashSum+j]; + z0 = z[nZhashSum+k]; //std::cout << "point " << nHash << " " << x0 << " " << y0 << " " // << z0 << std::endl; -#else + } + else + { nHash=0; hashSum=0; nRhashSum=0; @@ -95,15 +108,15 @@ void hashGeom::operator()(std::size_t indx) { gitr_precision kk = indx/(nR[0]); int k = std::floor(kk); int i = indx - k*(nR[0]); - gitr_precision x0 = x[i]; - gitr_precision y0 = 0.0; - gitr_precision z0 = z[k]; - int xyzIndx = indx; - int buffIndx=(k*(nR[0])+ i)*n_closeGeomElements[0]; + x0 = x[i]; + y0 = 0.0; + z0 = z[k]; + xyzIndx = indx; + buffIndx=(k*(nR[0])+ i)*n_closeGeomElements[0]; //std::cout << "point " < 0 + gitr_precision perpDist; + if( use_3d_geom > 0 ) + { gitr_precision plane_norm = boundary[l].plane_norm; gitr_precision t = -(a*x0 + b*y0 + c*z0 + d)/(a*a + b*b + c*c); p[0] = a*t + x0; p[1] = b*t + y0; p[2] = c*t + z0; - gitr_precision perpDist = std::sqrt((x0-p[0])*(x0-p[0]) + (y0-p[1])*(y0-p[1]) + (z0-p[2])*(z0-p[2])); -#endif + perpDist = std::sqrt((x0-p[0])*(x0-p[0]) + (y0-p[1])*(y0-p[1]) + (z0-p[2])*(z0-p[2])); + } vectorAssign(boundary[l].x1, boundary[l].y1, boundary[l].z1, A); vectorAssign(boundary[l].x2, boundary[l].y2, boundary[l].z2, B); -#if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { vectorAssign(boundary[l].x3, boundary[l].y3, boundary[l].z3, C); -#endif + } vectorSubtract(B,A,AB); -#if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { vectorSubtract(C,A,AC); vectorSubtract(C,B,BC); vectorSubtract(A,C,CA); @@ -193,7 +210,7 @@ void hashGeom::operator()(std::size_t indx) { { } else perpDist = 1.0e6; -#endif + } //std::cout << "perpDist " << perpDist << std::endl; //Edge checking p[0] = x0; @@ -214,7 +231,9 @@ void hashGeom::operator()(std::size_t indx) { //std::cout << "edge1 comp " << pA[0] << " " << pA[1] << " " << pA[2] << // " " << cEdge1mag << " " << cEdge1[0] << " " << cEdge1[1] << " " << cEdge1[2] << " " // << dEdge1[0] << " " < 0 + gitr_precision minEdge; + if( use_3d_geom > 0 ) + { gitr_precision pB[3] = {0.0}; gitr_precision cEdge2[3] = {0.0}; gitr_precision dEdge2[3] = {0.0}; @@ -239,12 +258,14 @@ void hashGeom::operator()(std::size_t indx) { vectorSubtract(pC,cEdge3,dEdge3); distE3 = std::sqrt(vectorDotProduct(dEdge3,dEdge3)); } - gitr_precision minEdge = std::min(distE1,distE2); + minEdge = std::min(distE1,distE2); minEdge = std::min(distE3,minEdge); -#else + } + else + { // - gitr_precision minEdge = distE1; -#endif + minEdge = distE1; + } //std::cout << "edgeDistances " << distE1 << " " << distE2 << " " << distE3 << std::endl; gitr_precision d1 =std::sqrt((x0 - boundary[l].x1)*(x0 - boundary[l].x1) + (y0 - boundary[l].y1)*(y0 - boundary[l].y1) @@ -252,19 +273,22 @@ void hashGeom::operator()(std::size_t indx) { gitr_precision d2 =std::sqrt((x0 - boundary[l].x2)*(x0 - boundary[l].x2) + (y0 - boundary[l].y2)*(y0 - boundary[l].y2) + (z0 - boundary[l].z2)*(z0 - boundary[l].z2)); -#if USE3DTETGEOM > 0 - gitr_precision d3 =std::sqrt((x0 - boundary[l].x3)*(x0 - boundary[l].x3) + gitr_precision d3; + if( use_3d_geom > 0 ) + { + d3 = std::sqrt((x0 - boundary[l].x3)*(x0 - boundary[l].x3) + (y0 - boundary[l].y3)*(y0 - boundary[l].y3) + (z0 - boundary[l].z3)*(z0 - boundary[l].z3)); -#endif + } //std::cout << " point Distances " << d3 << " " << d2 << " " << d1 << std::endl; gitr_precision minOf3 = std::min(d1,d2); minOf3 = std::min(minOf3,minEdge); //std::cout << "min of two " << minOf3 << std::endl; -#if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { minOf3 = std::min(minOf3,perpDist); minOf3 = std::min(minOf3,d3); -#endif + } //std::cout << "mindist " << minOf3 << " " << std::endl; // if(indx ==1) // {std::cout << "minof3" << perpDist << " " << minEdge << " " << minOf3<< std::endl;} diff --git a/src/interp2d.cpp b/src/interp2d.cpp index 97f839d7..a3f2786c 100644 --- a/src/interp2d.cpp +++ b/src/interp2d.cpp @@ -69,7 +69,7 @@ gitr_precision interp2d ( gitr_precision x, gitr_precision z,int nx, int nz, return fxz; } gitr_precision interp2dCombined ( gitr_precision x, gitr_precision y, gitr_precision z,int nx, int nz, - gitr_precision* gridx,gitr_precision* gridz,gitr_precision* data ) { + gitr_precision* gridx,gitr_precision* gridz,gitr_precision* data, int cylsymm ) { gitr_precision fxz = 0.0; gitr_precision fx_z1 = 0.0; @@ -79,11 +79,15 @@ gitr_precision interp2dCombined ( gitr_precision x, gitr_precision y, gitr_preci fxz = data[0]; } else{ -#if USECYLSYMM > 0 - gitr_precision dim1 = std::sqrt(x*x + y*y); -#else - gitr_precision dim1 = x; -#endif + gitr_precision dim1; + if( cylsymm ) + { + dim1 = std::sqrt(x*x + y*y); + } + else + { + dim1 = x; + } gitr_precision d_dim1 = gridx[1] - gridx[0]; gitr_precision dz = gridz[1] - gridz[0]; int i = std::floor((dim1 - gridx[0])/d_dim1);//addition of 0.5 finds nearest gridpoint @@ -207,33 +211,42 @@ void interp3dVector (gitr_precision* field, gitr_precision x, gitr_precision y, field[2] = interp3d (x,y,z,nx,ny,nz,gridx, gridy,gridz,dataz ); } CUDA_CALLABLE_MEMBER -void interp2dVector (gitr_precision* field, gitr_precision x, gitr_precision y, gitr_precision z,int nx, int nz, -gitr_precision* gridx,gitr_precision* gridz,gitr_precision* datar, gitr_precision* dataz, gitr_precision* datat ) { +void interp2dVector (gitr_precision* field, gitr_precision x, gitr_precision y, gitr_precision z, +int nx, int nz, +gitr_precision* gridx,gitr_precision* gridz,gitr_precision* datar, gitr_precision* dataz, +gitr_precision* datat, int cylsymm ) { - gitr_precision Ar = interp2dCombined(x,y,z,nx,nz,gridx,gridz, datar); - gitr_precision At = interp2dCombined(x,y,z,nx,nz,gridx,gridz, datat); - field[2] = interp2dCombined(x,y,z,nx,nz,gridx,gridz, dataz); -#if USECYLSYMM > 0 + gitr_precision Ar = interp2dCombined(x,y,z,nx,nz,gridx,gridz, datar, cylsymm ); + gitr_precision At = interp2dCombined(x,y,z,nx,nz,gridx,gridz, datat, cylsymm ); + field[2] = interp2dCombined(x,y,z,nx,nz,gridx,gridz, dataz, cylsymm ); + if( cylsymm ) + { gitr_precision theta = std::atan2(y,x); field[0] = std::cos(theta)*Ar - std::sin(theta)*At; field[1] = std::sin(theta)*Ar + std::cos(theta)*At; -#else + } + else + { field[0] = Ar; field[1] = At; -#endif + } } CUDA_CALLABLE_MEMBER -void interpFieldAlignedVector (gitr_precision* field, gitr_precision x, gitr_precision y, gitr_precision z,int nx, int nz, -gitr_precision* gridx,gitr_precision* gridz,gitr_precision* datar, gitr_precision* dataz, gitr_precision* datat, -int nxB, int nzB, gitr_precision* gridxB,gitr_precision* gridzB,gitr_precision* datarB,gitr_precision* datazB, gitr_precision* datatB) { +void interpFieldAlignedVector (gitr_precision* field, gitr_precision x, gitr_precision y, +gitr_precision z,int nx, int nz, +gitr_precision* gridx,gitr_precision* gridz,gitr_precision* datar, gitr_precision* dataz, +gitr_precision* datat, +int nxB, int nzB, gitr_precision* gridxB,gitr_precision* gridzB,gitr_precision* datarB, +gitr_precision* datazB, gitr_precision* datatB, int cylsymm ) +{ - gitr_precision Ar = interp2dCombined(x,y,z,nx,nz,gridx,gridz, datar); + gitr_precision Ar = interp2dCombined(x,y,z,nx,nz,gridx,gridz, datar, cylsymm ); gitr_precision B[3] = {0.0}; gitr_precision B_unit[3] = {0.0}; gitr_precision Bmag = 0.0; interp2dVector (&B[0],x,y,z,nxB,nzB, - gridxB,gridzB,datarB,datazB,datatB); + gridxB,gridzB,datarB,datazB,datatB, cylsymm ); Bmag = std::sqrt(B[0]*B[0] + B[1]*B[1] + B[2]*B[2]); B_unit[0] = B[0]/Bmag; B_unit[1] = B[1]/Bmag; diff --git a/src/interpRateCoeff.cpp b/src/interpRateCoeff.cpp index a8bcaee4..50bf55ee 100644 --- a/src/interpRateCoeff.cpp +++ b/src/interpRateCoeff.cpp @@ -49,11 +49,12 @@ gitr_precision rateCoeffInterp(int charge, gitr_precision te, gitr_precision ne, gitr_precision interpRateCoeff2d ( int charge, gitr_precision x, gitr_precision y, gitr_precision z,int nx, int nz, gitr_precision* tempGridxp, gitr_precision* tempGridzp, gitr_precision* Tempp, gitr_precision* densGridxp,gitr_precision* densGridzp,gitr_precision* Densp,int nT_Rates, int nD_Rates, - gitr_precision* rateGrid_Temp,gitr_precision* rateGrid_Dens,gitr_precision* Rates ) + gitr_precision* rateGrid_Temp,gitr_precision* rateGrid_Dens,gitr_precision* Rates, + int cylsymm ) { - gitr_precision tlocal = interp2dCombined(x,y,z,nx,nz,tempGridxp,tempGridzp,Tempp); - gitr_precision nlocal = interp2dCombined(x,y,z,nx,nz,densGridxp,densGridzp,Densp); + gitr_precision tlocal = interp2dCombined( x,y,z,nx,nz,tempGridxp,tempGridzp,Tempp, cylsymm ); + gitr_precision nlocal = interp2dCombined(x,y,z,nx,nz,densGridxp,densGridzp,Densp, cylsymm ); gitr_precision RClocal = rateCoeffInterp(charge,tlocal,nlocal,nT_Rates,nD_Rates,rateGrid_Temp, rateGrid_Dens, Rates); gitr_precision tion = 1.0/(RClocal*nlocal); if(tlocal == 0.0 || nlocal == 0.0) tion=1.0e12; diff --git a/src/interpolator.cpp b/src/interpolator.cpp new file mode 100644 index 00000000..5323c27f --- /dev/null +++ b/src/interpolator.cpp @@ -0,0 +1 @@ +#include "interpolator.h" diff --git a/src/ionize.cpp b/src/ionize.cpp index c378027a..b68d22b3 100644 --- a/src/ionize.cpp +++ b/src/ionize.cpp @@ -67,7 +67,8 @@ ionize< T >::ionize(Flags *_flags, gitr_precision *_gridTemperature_Ionization, gitr_precision *_gridDensity_Ionization, gitr_precision *_rateCoeff_Ionization, - gitr_precision *_random_uniform_number) + gitr_precision *_random_uniform_number, + int cylsymm_ ) : flags(_flags), particlesPointer(_particlesPointer), nR_Dens(_nR_Dens), @@ -80,7 +81,8 @@ ionize< T >::ionize(Flags *_flags, gridTemperature_Ionization(_gridTemperature_Ionization), rateCoeff_Ionization(_rateCoeff_Ionization), dt(_dt), - state(_state),random_uniform_number{_random_uniform_number} + state(_state),random_uniform_number{_random_uniform_number}, + cylsymm( cylsymm_ ) { } template< typename T > @@ -99,7 +101,7 @@ void ionize< T >::operator()(std::size_t indx) particlesPointer->y[indx], particlesPointer->z[indx], nR_Temp, nZ_Temp, TempGridr, TempGridz, te, DensGridr, DensGridz, ne, nTemperaturesIonize, nDensitiesIonize, gridTemperature_Ionization, - gridDensity_Ionization, rateCoeff_Ionization); + gridDensity_Ionization, rateCoeff_Ionization, cylsymm ); gitr_precision P = exp(-dt / tion); gitr_precision P1 = 1.0 - P; diff --git a/src/json.cpp b/src/json.cpp new file mode 100644 index 00000000..ead0c651 --- /dev/null +++ b/src/json.cpp @@ -0,0 +1,57 @@ +/* + +Why aren't we usting an IOT solution? Seems fundamentally like an IOT problem. + +just looking at getting a mantid conda setup, got files copied over, good that the SNS system +is mounted so I actually need +that mount to be able to run the workflow. I'm working on adding stories/tasks. And the current +tasks I'm working on getting mantid conda setup locally, to make sure it's repeatable etc, then +next week hopefully will be begin encapsulating it into a galaxy tool. That's when the tasks for +having a nexus file reader will come into play. + +add up these +intersect is instrument focused + +message based instead of API to include the custom OS's on the instruments into the +communication interface + +limiting flexibility? + +*/ +#include +#include + +#include "nlohmann/json.hpp" + +using json = nlohmann::json; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } + } + )"; + + // fill a stream with JSON text + std::stringstream ss; + ss << text; + + // parse and serialize JSON + json j_complete = json::parse(ss); + + return 0; +} + diff --git a/src/spectroscopy.cpp b/src/spectroscopy.cpp index a02f06d4..3c26ee6d 100644 --- a/src/spectroscopy.cpp +++ b/src/spectroscopy.cpp @@ -1,7 +1,7 @@ #include "spectroscopy.h" #if USE_CUDA >0 -__device__ double atomicAdd1(double* address, double val) +__device__ double atomicAdd1(gitr_precision* address, gitr_precision val) { unsigned long long int* address_as_ull = (unsigned long long int*)address; @@ -19,9 +19,9 @@ __device__ double atomicAdd1(double* address, double val) #endif spec_bin::spec_bin(Flags* _flags, Particles *_particlesPointer, int _nBins,int _nX,int _nY, int _nZ, gitr_precision *_gridX,gitr_precision *_gridY,gitr_precision *_gridZ, - double * _bins, gitr_precision _dt) : + gitr_precision* _bins, gitr_precision _dt, int cylsymm_, int spectroscopy_ ) : flags(_flags), particlesPointer(_particlesPointer), nBins(_nBins),nX(_nX),nY(_nY), nZ(_nZ), gridX(_gridX),gridY(_gridY),gridZ(_gridZ), bins(_bins), - dt(_dt) {} + dt(_dt), cylsymm( cylsymm_ ), spectroscopy( spectroscopy_ ) {} CUDA_CALLABLE_MEMBER_DEVICE void spec_bin::operator()(std::size_t indx) const { @@ -33,15 +33,22 @@ void spec_bin::operator()(std::size_t indx) const { gitr_precision z = particlesPointer->zprevious[indx]; gitr_precision dt_particle = 0.0; -#if SPECTROSCOPY > 2 - gitr_precision dim1 = particlesPointer->xprevious[indx]; -#else -#if USECYLSYMM > 0 - gitr_precision dim1 = std::sqrt(x*x + y*y); - #else - gitr_precision dim1 = x; - #endif -#endif + gitr_precision dim1; + if( spectroscopy > 2 ) + { + dim1 = particlesPointer->xprevious[indx]; + } + else + { + if( cylsymm > 0 ) + { + dim1 = std::sqrt(x*x + y*y); + } + else + { + dim1 = x; + } + } if ((z > gridZ[0]) && (z < gridZ[nZ-1])) { @@ -49,80 +56,128 @@ void spec_bin::operator()(std::size_t indx) const { { dx = gridX[1] - gridX[0]; dz = gridZ[1] - gridZ[0]; -#if SPECTROSCOPY < 3 - int indx_X = std::floor((dim1-gridX[0])/dx); - int indx_Z = std::floor((z-gridZ[0])/dz); - int indx_Y = 0; + + int indx_X; + int indx_Z; + int indx_Y; int nnYY=1; - //printf ("indX %i \n", indx_X); - //printf ("indZ %i \n", indx_Z); -#else - if((y > gridY[0]) && (y < gridY[nY-1])) - { - int indx_X = std::floor((dim1-gridX[0])/dx); - int indx_Z = std::floor((z-gridZ[0])/dz); - dy = gridY[1] - gridY[0]; - int indx_Y = std::floor((y-gridY[0])/dy); - if (indx_Y < 0 || indx_Y >= nY) indx_Y = 0; - int nnYY = nY; -#endif + + if( spectroscopy < 3 ) + { + indx_X = std::floor((dim1-gridX[0])/dx); + indx_Z = std::floor((z-gridZ[0])/dz); + indx_Y = 0; + nnYY=1; if (indx_X < 0 || indx_X >= nX) indx_X = 0; + if (indx_Z < 0 || indx_Z >= nZ) indx_Z = 0; - //std::cout << "gridx0 " << gridX[0] << std::endl; - //std::cout << "gridz0 " << gridZ[0] << std::endl; - - //std::cout << "dx " << dx << std::endl; - //std::cout << "dz " << dz << std::endl; - //std::cout << "ind x " << indx_X << "ind z " << indx_Z << std::endl; + int charge = std::floor(particlesPointer->charge[indx]); + gitr_precision specWeight = 0.0; + if(particlesPointer->hitWall[indx]== 0.0) { - if (flags->USE_ADAPTIVE_DT) { - if(particlesPointer->advance[indx]) - { - dt_particle = particlesPointer->dt[indx]; - specWeight = particlesPointer->weight[indx]*dt_particle/dt; - } + if (flags->USE_ADAPTIVE_DT) + { + if(particlesPointer->advance[indx]) + { + dt_particle = particlesPointer->dt[indx]; + specWeight = particlesPointer->weight[indx]*dt_particle/dt; + } } - else - { + + else + { specWeight = particlesPointer->weight[indx]; - //printf ("Characters: %f \n", specWeight); - } + } #if USE_CUDA >0 - //for 2d - /* - atomicAdd(&bins[nBins*nX*nZ + indx_Z*nX + indx_X], 1.0);//0*nX*nZ + indx_Z*nZ + indx_X - if(charge < nBins) - { - atomicAdd(&bins[charge*nX*nZ + indx_Z*nX + indx_X], 1.0);//0*nX*nZ + indx_Z*nZ + indx_X - } - */ - //for 3d - int index = nBins*nX*nnYY*nZ + indx_Z*nX*nnYY +indx_Y*nX+ indx_X; - //printf ("Index %i \n", index); - atomicAdd1(&bins[index], specWeight);//0*nX*nZ + indx_Z*nZ + indx_X + + int index = nBins*nX*nnYY*nZ + indx_Z*nX*nnYY +indx_Y*nX+ indx_X; + + atomicAdd1(&bins[index], specWeight);//0*nX*nZ + indx_Z*nZ + indx_X + if(charge < nBins) { - atomicAdd1(&bins[charge*nX*nnYY*nZ + indx_Z*nX*nnYY + indx_Y*nX+ indx_X], 1.0*specWeight);//0*nX*nZ + indx_Z*nZ + indx_X + atomicAdd1( &bins[charge*nX*nnYY*nZ + indx_Z*nX*nnYY + indx_Y*nX+ indx_X], + 1.0*specWeight); } #else + #pragma omp atomic - bins[nBins*nX*nnYY*nZ + indx_Z*nX*nnYY +indx_Y*nX +indx_X] = - bins[nBins*nX*nnYY*nZ + indx_Z*nX*nnYY+ indx_Y*nX + indx_X] + specWeight; + bins[nBins*nX*nnYY*nZ + indx_Z*nX*nnYY +indx_Y*nX +indx_X] += specWeight; + if(charge < nBins) { #pragma omp atomic - bins[charge*nX*nnYY*nZ + indx_Z*nX*nnYY +indx_Y*nX + indx_X] = - bins[charge*nX*nnYY*nZ + indx_Z*nX*nnYY+indx_Y*nX + indx_X] + specWeight; + bins[charge*nX*nnYY*nZ + indx_Z*nX*nnYY +indx_Y*nX + indx_X] += specWeight; } #endif + } } -#if SPECTROSCOPY >2 + + else if((y > gridY[0]) && (y < gridY[nY-1])) + { + indx_X = std::floor((dim1-gridX[0])/dx); + indx_Z = std::floor((z-gridZ[0])/dz); + + dy = gridY[1] - gridY[0]; + + indx_Y = std::floor((y-gridY[0])/dy); + + if (indx_Y < 0 || indx_Y >= nY) indx_Y = 0; + + nnYY = nY; + + if (indx_X < 0 || indx_X >= nX) indx_X = 0; + + if (indx_Z < 0 || indx_Z >= nZ) indx_Z = 0; + + int charge = std::floor(particlesPointer->charge[indx]); + + gitr_precision specWeight = 0.0; + + if(particlesPointer->hitWall[indx]== 0.0) + { + if (flags->USE_ADAPTIVE_DT) + { + if(particlesPointer->advance[indx]) + { + dt_particle = particlesPointer->dt[indx]; + specWeight = particlesPointer->weight[indx]*dt_particle/dt; + } + } + + else + { + specWeight = particlesPointer->weight[indx]; + } +#if USE_CUDA >0 + + int index = nBins*nX*nnYY*nZ + indx_Z*nX*nnYY +indx_Y*nX+ indx_X; + + atomicAdd1(&bins[index], specWeight);//0*nX*nZ + indx_Z*nZ + indx_X + + if(charge < nBins) + { + atomicAdd1( &bins[charge*nX*nnYY*nZ + indx_Z*nX*nnYY + indx_Y*nX+ indx_X], + 1.0*specWeight); } -#endif + +#else + + #pragma omp atomic + bins[nBins*nX*nnYY*nZ + indx_Z*nX*nnYY +indx_Y*nX +indx_X] += specWeight; + + if(charge < nBins) + { + #pragma omp atomic + bins[charge*nX*nnYY*nZ + indx_Z*nX*nnYY +indx_Y*nX + indx_X] += specWeight; } - } +#endif + } + } + }// end + } } diff --git a/src/surface_model.cpp b/src/surface_model.cpp index 8e7da641..bb3419c0 100644 --- a/src/surface_model.cpp +++ b/src/surface_model.cpp @@ -37,8 +37,11 @@ gitr_precision _Edist, int _nAdist, gitr_precision _A0dist, - gitr_precision _Adist) : -particles(_particles), + gitr_precision _Adist, + int flux_ea_, + int use_3d_geom_, + int cylsymm_ ) : + particles(_particles), dt(_dt), nLines(_nLines), boundaryVector(_boundaryVector), @@ -72,7 +75,11 @@ particles(_particles), nAdist(_nAdist), A0dist(_A0dist), Adist(_Adist), - state(_state) { } + state(_state), + flux_ea( flux_ea_ ), + use_3d_geom( use_3d_geom_ ), + cylsymm( cylsymm_ ) + { } CUDA_CALLABLE_MEMBER_DEVICE void reflection::operator()(std::size_t indx) const { @@ -107,12 +114,17 @@ void reflection::operator()(std::size_t indx) const { gitr_precision vx = particles->vx[indx]; gitr_precision vy = particles->vy[indx]; gitr_precision vz = particles->vz[indx]; -#if FLUX_EA > 0 - gitr_precision dEdist = (Edist - E0dist) / static_cast(nEdist); - gitr_precision dAdist = (Adist - A0dist) / static_cast(nAdist); int AdistInd = 0; int EdistInd = 0; -#endif + gitr_precision dEdist; + gitr_precision dAdist; + + if( flux_ea > 0 ) + { + dEdist = (Edist - E0dist) / static_cast(nEdist); + dAdist = (Adist - A0dist) / static_cast(nAdist); + } + particles->firstCollision[indx] = 1; particleTrackVector[0] = vx; particleTrackVector[1] = vy; @@ -128,7 +140,7 @@ void reflection::operator()(std::size_t indx) const { E0_for_flux_binning = Edist; wallIndex = particles->wallIndex[indx]; - boundaryVector[wallHit].getSurfaceNormal(surfaceNormalVector, particles->y[indx], particles->x[indx]); + boundaryVector[wallHit].getSurfaceNormal(surfaceNormalVector, particles->y[indx], particles->x[indx], use_3d_geom, cylsymm ); particleTrackVector[0] = particleTrackVector[0] / norm_part; particleTrackVector[1] = particleTrackVector[1] / norm_part; particleTrackVector[2] = particleTrackVector[2] / norm_part; @@ -162,7 +174,6 @@ void reflection::operator()(std::size_t indx) const { totalYR = Y0 + R0; -#if PARTICLESEEDS > 0 #ifdef __CUDACC__ gitr_precision r7 = curand_uniform(&state[indx]); gitr_precision r8 = curand_uniform(&state[indx]); @@ -176,18 +187,6 @@ void reflection::operator()(std::size_t indx) const { gitr_precision r10 = dist(state[indx]); #endif -#else - #if __CUDACC__ - gitr_precision r7 = curand_uniform(&state[6]); - gitr_precision r8 = curand_uniform(&state[7]); - gitr_precision r9 = curand_uniform(&state[8]); - #else - std::uniform_real_distribution dist(0.0, 1.0); - gitr_precision r7=dist(state[6]); - gitr_precision r8=dist(state[7]); - gitr_precision r9=dist(state[8]); - #endif -#endif //particle either reflects or deposits gitr_precision sputtProb = Y0/totalYR; int didReflect = 0; @@ -207,7 +206,9 @@ void reflection::operator()(std::size_t indx) const { E_sputtRefDistIn,EDist_CDF_R_regrid ); newWeight = weight*(totalYR); -#if FLUX_EA > 0 + + if( flux_ea > 0 ) + { EdistInd = std::floor((eInterpVal-E0dist)/dEdist); AdistInd = std::floor((aInterpVal-A0dist)/dAdist); if((EdistInd >= 0) && (EdistInd < nEdist) && @@ -220,7 +221,7 @@ void reflection::operator()(std::size_t indx) const { surfaces->reflDistribution[surfaceHit*nEdist*nAdist + EdistInd*nAdist + AdistInd] + newWeight; #endif } -#endif + } if(surface > 0) { @@ -229,9 +230,11 @@ void reflection::operator()(std::size_t indx) const { atomicAdd1(&surfaces->grossErosion[surfaceHit],weight*Y0); #else #pragma omp atomic - surfaces->grossDeposition[surfaceHit] = surfaces->grossDeposition[surfaceHit]+weight*(1.0-R0); + //surfaces->grossDeposition[surfaceHit] = surfaces->grossDeposition[surfaceHit]+weight*(1.0-R0); + surfaces->grossDeposition[surfaceHit] += ( weight*(1.0-R0) ); #pragma omp atomic - surfaces->grossErosion[surfaceHit] = surfaces->grossErosion[surfaceHit]+weight*Y0; + //surfaces->grossErosion[surfaceHit] = surfaces->grossErosion[surfaceHit]+weight*Y0; + surfaces->grossErosion[surfaceHit] += ( weight * Y0 ); #endif } } @@ -246,7 +249,8 @@ void reflection::operator()(std::size_t indx) const { energyDistGrid01,A_sputtRefDistIn,E_sputtRefDistIn,EDist_CDF_Y_regrid); newWeight=weight*totalYR; - #if FLUX_EA > 0 + if( flux_ea > 0 ) + { EdistInd = std::floor((eInterpVal-E0dist)/dEdist); AdistInd = std::floor((aInterpVal-A0dist)/dAdist); if((EdistInd >= 0) && (EdistInd < nEdist) && @@ -259,7 +263,7 @@ void reflection::operator()(std::size_t indx) const { surfaces->sputtDistribution[surfaceHit*nEdist*nAdist + EdistInd*nAdist + AdistInd] + newWeight; #endif } - #endif + } if(sputtProb == 0.0) newWeight = 0.0; if(surface > 0) { @@ -322,7 +326,8 @@ void reflection::operator()(std::size_t indx) const { surfaces->sumParticlesStrike[surfaceHit] = surfaces->sumParticlesStrike[surfaceHit]+1; //boundaryVector[wallHit].impacts = boundaryVector[wallHit].impacts + particles->weight[indx]; #endif - #if FLUX_EA > 0 + if( flux_ea > 0 ) + { EdistInd = std::floor((E0_for_flux_binning-E0dist)/dEdist); AdistInd = std::floor((thetaImpact-A0dist)/dAdist); @@ -338,7 +343,7 @@ void reflection::operator()(std::size_t indx) const { surfaces->energyDistribution[surfaceHit*nEdist*nAdist + EdistInd*nAdist + AdistInd] + weight; #endif } -#endif + } } //reflect with weight and new initial conditions @@ -352,7 +357,9 @@ void reflection::operator()(std::size_t indx) const { vSampled[0] = V0 * std::sin(aInterpVal * 3.1415 / 180) * std::cos(2.0 * 3.1415 * r10); vSampled[1] = V0 * std::sin(aInterpVal * 3.1415 / 180) * std::sin(2.0 * 3.1415 * r10); vSampled[2] = V0 * std::cos(aInterpVal * 3.1415 / 180); - boundaryVector[wallHit].transformToSurface(vSampled, particles->y[indx], particles->x[indx]); + boundaryVector[wallHit].transformToSurface(vSampled, particles->y[indx], + particles->x[indx], use_3d_geom, + cylsymm ); particles->vx[indx] = -static_cast(boundaryVector[wallHit].inDir) * vSampled[0]; particles->vy[indx] = -static_cast(boundaryVector[wallHit].inDir) * vSampled[1]; particles->vz[indx] = -static_cast(boundaryVector[wallHit].inDir) * vSampled[2]; diff --git a/src/utils.cpp b/src/utils.cpp index d13f4df5..f10f7f39 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -75,7 +75,7 @@ void checkFlags(libconfig::Config &cfg) << std::endl; const char *flags0[] = {//"flags.USE_CUDA", //"flags.USE_MPI", - "flags.USEIONIZATION", + "flags.USE_IONIZATION", "flags.USERECOMBINATION","flags.USEPERPDIFFUSION", "flags.USECOULOMBCOLLISIONS", "flags.USETHERMALFORCE","flags.USESURFACEMODEL", @@ -94,6 +94,7 @@ void checkFlags(libconfig::Config &cfg) "flags.PARTICLE_SOURCE_FILE", "flags.SPECTROSCOPY","flags.USE3DTETGEOM","flags.USECYLSYMM", "flags.FLUX_EA","flags.FORCE_EVAL"}; + /* int flagValues[] = {//USE_CUDA, USE_MPI, USEIONIZATION, USERECOMBINATION,USEPERPDIFFUSION,USECOULOMBCOLLISIONS, @@ -107,6 +108,8 @@ void checkFlags(libconfig::Config &cfg) PARTICLE_SOURCE_ENERGY,PARTICLE_SOURCE_ANGLE, PARTICLE_SOURCE_FILE, SPECTROSCOPY,USE3DTETGEOM,USECYLSYMM,FLUX_EA,FORCE_EVAL}; + */ + /* int check1; for (int i=0; i &boundaries) +int importGeometry(libconfig::Config &cfg_geom, sim::Array &boundaries, + int use_3d_geom, int cylsymm, int surface_potential ) { Setting& geom = cfg_geom.lookup("geom"); std::cout << "Boundary import routine " << int(boundaries.size()) << std::endl; @@ -517,7 +522,8 @@ int importGeometry(libconfig::Config &cfg_geom, sim::Array &boundaries std::string full_path = geom_folder + "/" + geom_outname; outfile.open (full_path ); - #if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { std::cout << "Reading 3D geometry file " << std::endl; for(int i=0 ; i &boundaries boundaries[i].area = geom["area"][i]; boundaries[i].surface = geom["surface"][i]; boundaries[i].inDir = geom["inDir"][i]; - #if USE_SURFACE_POTENTIAL > 0 - boundaries[i].potential = geom["potential"][i]; - #endif + if( surface_potential > 0 ) + { + boundaries[i].potential = geom["potential"][i]; + } //std::cout << "inDir " << i << " " << boundaries[i].inDir << std::endl; if(boundaries[i].surface > 0) { @@ -558,14 +565,17 @@ int importGeometry(libconfig::Config &cfg_geom, sim::Array &boundaries boundaries[nLines].y1 = geom["theta0"]; boundaries[nLines].y2 = geom["theta1"]; boundaries[nLines].periodic = geom["periodic"]; - #if USECYLSYMM + if( cylsymm ) + { std::cout << "Reading cylindrically symmetric boundary characteristics " << std::endl; boundaries[nLines].y1 = geom["theta0"]; boundaries[nLines].y2 = geom["theta1"]; boundaries[nLines].periodic = geom["periodic"]; - #endif + } outfile.close(); - #else + } + else + { //int nMaterials = geom["nMaterials"]; //std::cout << "nmat " << nMaterials << std::endl; @@ -584,9 +594,10 @@ int importGeometry(libconfig::Config &cfg_geom, sim::Array &boundaries boundaries[i].intercept_z = geom["intercept"][i]; boundaries[i].length = geom["length"][i]; //std::cout << "got Z slope length " << std::endl; - #if USE_SURFACE_POTENTIAL > 0 + if( surface_potential > 0 ) + { boundaries[i].potential = geom["potential"][i]; - #endif + } boundaries[i].a = boundaries[i].z2 - boundaries[i].z1; boundaries[i].b = 0.0; @@ -614,10 +625,10 @@ int importGeometry(libconfig::Config &cfg_geom, sim::Array &boundaries boundaries[nLines].y1 = geom["y1"]; boundaries[nLines].y2 = geom["y2"]; boundaries[nLines].periodic = geom["periodic"]; - #endif + } return nZSurfs; } -int importHashNs(libconfig::Config &cfg,std::string input_path,int nHashes,std::string fieldCfgString,int *nR, int *nY,int *nZ,int *n,int &nRTotal,int &nYTotal,int &nZTotal,int *nHashPoints, int &nHashPointsTotal,int &nGeomHash) +int importHashNs(libconfig::Config &cfg,std::string input_path,int nHashes,std::string fieldCfgString,int *nR, int *nY,int *nZ,int *n,int &nRTotal,int &nYTotal,int &nZTotal,int *nHashPoints, int &nHashPointsTotal,int &nGeomHash, int use_3d_geom ) { Setting& geomHash = cfg.lookup(fieldCfgString); if(nHashes > 1) @@ -641,7 +652,8 @@ int importHashNs(libconfig::Config &cfg,std::string input_path,int nHashes,std:: nRTotal = nRTotal + nR[j]; nZTotal = nZTotal + nZ[j]; } - #if USE3DTETGEOM > 0 + if( use_3d_geom > 0 ) + { if(nHashes > 1) { for(int i=0; i 0 + if( use_3d_geom > 0 ) + { // if(nHashes > 1) //{ nHashPoints[j] =nR[j]*nY[j]*nZ[j]; //} - #else //else + } + else + { //{ nHashPoints[j] =nR[j]*nZ[j]; //} - #endif + } nHashPointsTotal = nHashPointsTotal + nHashPoints[j]; nGeomHash = nGeomHash + nHashPoints[j]*n[j]; nRTotal = nRTotal + nR[j]; diff --git a/test_data/test_config.cfg b/test_data/test_config.cfg index b50e3389..802ff033 100755 --- a/test_data/test_config.cfg +++ b/test_data/test_config.cfg @@ -1,3 +1,37 @@ +testing_dummy = +{ + setting_doubles = [ 1.5, 2.5, 3.5, 4.5, 5.5 ]; + + setting_string = "Ahoy, Captain!"; +} + +geom = +{ + x1 = [ -0.2, 0.2]; + z1 = [-10000, -10000]; + + x2 = [ -0.2, 0.2]; + z2 = [10000, 10000]; + + y1 = 0; + y2 = 0; + + + slope = [ 1.0E+12, 1E+12 ]; + + intercept = [ -1.0E+12, -1.0E+12 ]; + + length = [ 20000, 20000 ]; + + Z = [ 0.0, 0.0, 0.0 ]; + + surface = [ 1, 1, 0 ]; + + inDir = [ -1, -1, 1 ]; + + periodic = 0; +} + geometry = { fileString = "gitrGeometryPointPlane3d.cfg"; diff --git a/test_include/catch.hpp b/test_include/catch.hpp deleted file mode 100644 index 0384171a..00000000 --- a/test_include/catch.hpp +++ /dev/null @@ -1,17881 +0,0 @@ -/* - * Catch v2.13.4 - * Generated: 2020-12-29 14:48:00.116107 - * ---------------------------------------------------------- - * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved. - * - * Distributed under the Boost Software License, Version 1.0. (See accompanying - * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -// start catch.hpp - - -#define CATCH_VERSION_MAJOR 2 -#define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 4 - -#ifdef __clang__ -# pragma clang system_header -#elif defined __GNUC__ -# pragma GCC system_header -#endif - -// start catch_suppress_warnings.h - -#ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(push) -# pragma warning(disable: 161 1682) -# else // __ICC -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wpadded" -# pragma clang diagnostic ignored "-Wswitch-enum" -# pragma clang diagnostic ignored "-Wcovered-switch-default" -# endif -#elif defined __GNUC__ - // Because REQUIREs trigger GCC's -Wparentheses, and because still - // supported version of g++ have only buggy support for _Pragmas, - // Wparentheses have to be suppressed globally. -# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details - -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wunused-variable" -# pragma GCC diagnostic ignored "-Wpadded" -#endif -// end catch_suppress_warnings.h -#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) -# define CATCH_IMPL -# define CATCH_CONFIG_ALL_PARTS -#endif - -// In the impl file, we want to have access to all parts of the headers -// Can also be used to sanely support PCHs -#if defined(CATCH_CONFIG_ALL_PARTS) -# define CATCH_CONFIG_EXTERNAL_INTERFACES -# if defined(CATCH_CONFIG_DISABLE_MATCHERS) -# undef CATCH_CONFIG_DISABLE_MATCHERS -# endif -# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) -# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER -# endif -#endif - -#if !defined(CATCH_CONFIG_IMPL_ONLY) -// start catch_platform.h - -#ifdef __APPLE__ -# include -# if TARGET_OS_OSX == 1 -# define CATCH_PLATFORM_MAC -# elif TARGET_OS_IPHONE == 1 -# define CATCH_PLATFORM_IPHONE -# endif - -#elif defined(linux) || defined(__linux) || defined(__linux__) -# define CATCH_PLATFORM_LINUX - -#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) -# define CATCH_PLATFORM_WINDOWS -#endif - -// end catch_platform.h - -#ifdef CATCH_IMPL -# ifndef CLARA_CONFIG_MAIN -# define CLARA_CONFIG_MAIN_NOT_DEFINED -# define CLARA_CONFIG_MAIN -# endif -#endif - -// start catch_user_interfaces.h - -namespace Catch { - unsigned int rngSeed(); -} - -// end catch_user_interfaces.h -// start catch_tag_alias_autoregistrar.h - -// start catch_common.h - -// start catch_compiler_capabilities.h - -// Detect a number of compiler features - by compiler -// The following features are defined: -// -// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? -// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? -// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? -// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? -// **************** -// Note to maintainers: if new toggles are added please document them -// in configuration.md, too -// **************** - -// In general each macro has a _NO_ form -// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. -// Many features, at point of detection, define an _INTERNAL_ macro, so they -// can be combined, en-mass, with the _NO_ forms later. - -#ifdef __cplusplus - -# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) -# define CATCH_CPP14_OR_GREATER -# endif - -# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -# define CATCH_CPP17_OR_GREATER -# endif - -#endif - -// We have to avoid both ICC and Clang, because they try to mask themselves -// as gcc, and we want only GCC in this block -#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) - -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) - -#endif - -#if defined(__clang__) - -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) - -// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug -// which results in calls to destructors being emitted for each temporary, -// without a matching initialization. In practice, this can result in something -// like `std::string::~string` being called on an uninitialized value. -// -// For example, this code will likely segfault under IBM XL: -// ``` -// REQUIRE(std::string("12") + "34" == "1234") -// ``` -// -// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. -# if !defined(__ibmxl__) && !defined(__CUDACC__) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ -# endif - -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ - _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") - -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) - -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) - -#endif // __clang__ - -//////////////////////////////////////////////////////////////////////////////// -// Assume that non-Windows platforms support posix signals by default -#if !defined(CATCH_PLATFORM_WINDOWS) - #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS -#endif - -//////////////////////////////////////////////////////////////////////////////// -// We know some environments not to support full POSIX signals -#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) - #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -#endif - -#ifdef __OS400__ -# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -# define CATCH_CONFIG_COLOUR_NONE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Android somehow still does not support std::to_string -#if defined(__ANDROID__) -# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING -# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Not all Windows environments support SEH properly -#if defined(__MINGW32__) -# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH -#endif - -//////////////////////////////////////////////////////////////////////////////// -// PS4 -#if defined(__ORBIS__) -# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Cygwin -#ifdef __CYGWIN__ - -// Required for some versions of Cygwin to declare gettimeofday -// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin -# define _BSD_SOURCE -// some versions of cygwin (most) do not support std::to_string. Use the libstd check. -// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 -# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ - && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) - -# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING - -# endif -#endif // __CYGWIN__ - -//////////////////////////////////////////////////////////////////////////////// -// Visual C++ -#if defined(_MSC_VER) - -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) - -// Universal Windows platform does not support SEH -// Or console colours (or console at all...) -# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) -# define CATCH_CONFIG_COLOUR_NONE -# else -# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH -# endif - -// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ -// _MSVC_TRADITIONAL == 0 means new conformant preprocessor -// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor -# if !defined(__clang__) // Handle Clang masquerading for msvc -# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) -# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -# endif // MSVC_TRADITIONAL -# endif // __clang__ - -#endif // _MSC_VER - -#if defined(_REENTRANT) || defined(_MSC_VER) -// Enable async processing, as -pthread is specified or no additional linking is required -# define CATCH_INTERNAL_CONFIG_USE_ASYNC -#endif // _MSC_VER - -//////////////////////////////////////////////////////////////////////////////// -// Check if we are compiled with -fno-exceptions or equivalent -#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) -# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED -#endif - -//////////////////////////////////////////////////////////////////////////////// -// DJGPP -#ifdef __DJGPP__ -# define CATCH_INTERNAL_CONFIG_NO_WCHAR -#endif // __DJGPP__ - -//////////////////////////////////////////////////////////////////////////////// -// Embarcadero C++Build -#if defined(__BORLANDC__) - #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// Use of __COUNTER__ is suppressed during code analysis in -// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly -// handled by it. -// Otherwise all supported compilers support COUNTER macro, -// but user still might want to turn it off -#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) - #define CATCH_INTERNAL_CONFIG_COUNTER -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// RTX is a special version of Windows that is real time. -// This means that it is detected as Windows, but does not provide -// the same set of capabilities as real Windows does. -#if defined(UNDER_RTSS) || defined(RTX64_BUILD) - #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH - #define CATCH_INTERNAL_CONFIG_NO_ASYNC - #define CATCH_CONFIG_COLOUR_NONE -#endif - -#if !defined(_GLIBCXX_USE_C99_MATH_TR1) -#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER -#endif - -// Various stdlib support checks that require __has_include -#if defined(__has_include) - // Check if string_view is available and usable - #if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW - #endif - - // Check if optional is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) - - // Check if byte is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # include - # if __cpp_lib_byte > 0 - # define CATCH_INTERNAL_CONFIG_CPP17_BYTE - # endif - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) - - // Check if variant is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # if defined(__clang__) && (__clang_major__ < 8) - // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 - // fix should be in clang 8, workaround in libstdc++ 8.2 - # include - # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) - # define CATCH_CONFIG_NO_CPP17_VARIANT - # else - # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT - # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) - # else - # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT - # endif // defined(__clang__) && (__clang_major__ < 8) - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) -#endif // defined(__has_include) - -#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) -# define CATCH_CONFIG_COUNTER -#endif -#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) -# define CATCH_CONFIG_WINDOWS_SEH -#endif -// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. -#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) -# define CATCH_CONFIG_POSIX_SIGNALS -#endif -// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. -#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) -# define CATCH_CONFIG_WCHAR -#endif - -#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) -# define CATCH_CONFIG_CPP11_TO_STRING -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) -# define CATCH_CONFIG_CPP17_OPTIONAL -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) -# define CATCH_CONFIG_CPP17_STRING_VIEW -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) -# define CATCH_CONFIG_CPP17_VARIANT -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) -# define CATCH_CONFIG_CPP17_BYTE -#endif - -#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) -# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE -#endif - -#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) -# define CATCH_CONFIG_NEW_CAPTURE -#endif - -#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -# define CATCH_CONFIG_DISABLE_EXCEPTIONS -#endif - -#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) -# define CATCH_CONFIG_POLYFILL_ISNAN -#endif - -#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) -# define CATCH_CONFIG_USE_ASYNC -#endif - -#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) -# define CATCH_CONFIG_ANDROID_LOGWRITE -#endif - -#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) -# define CATCH_CONFIG_GLOBAL_NEXTAFTER -#endif - -// Even if we do not think the compiler has that warning, we still have -// to provide a macro that can be used by the code. -#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION -#endif -#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS -#endif - -// The goal of this macro is to avoid evaluation of the arguments, but -// still have the compiler warn on problems inside... -#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) -#endif - -#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) -# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#elif defined(__clang__) && (__clang_major__ < 5) -# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#endif - -#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#endif - -#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -#define CATCH_TRY if ((true)) -#define CATCH_CATCH_ALL if ((false)) -#define CATCH_CATCH_ANON(type) if ((false)) -#else -#define CATCH_TRY try -#define CATCH_CATCH_ALL catch (...) -#define CATCH_CATCH_ANON(type) catch (type) -#endif - -#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) -#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#endif - -// end catch_compiler_capabilities.h -#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line -#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) -#ifdef CATCH_CONFIG_COUNTER -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) -#else -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) -#endif - -#include -#include -#include - -// We need a dummy global operator<< so we can bring it into Catch namespace later -struct Catch_global_namespace_dummy {}; -std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); - -namespace Catch { - - struct CaseSensitive { enum Choice { - Yes, - No - }; }; - - class NonCopyable { - NonCopyable( NonCopyable const& ) = delete; - NonCopyable( NonCopyable && ) = delete; - NonCopyable& operator = ( NonCopyable const& ) = delete; - NonCopyable& operator = ( NonCopyable && ) = delete; - - protected: - NonCopyable(); - virtual ~NonCopyable(); - }; - - struct SourceLineInfo { - - SourceLineInfo() = delete; - SourceLineInfo( char const* _file, std::size_t _line ) noexcept - : file( _file ), - line( _line ) - {} - - SourceLineInfo( SourceLineInfo const& other ) = default; - SourceLineInfo& operator = ( SourceLineInfo const& ) = default; - SourceLineInfo( SourceLineInfo&& ) noexcept = default; - SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; - - bool empty() const noexcept { return file[0] == '\0'; } - bool operator == ( SourceLineInfo const& other ) const noexcept; - bool operator < ( SourceLineInfo const& other ) const noexcept; - - char const* file; - std::size_t line; - }; - - std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); - - // Bring in operator<< from global namespace into Catch namespace - // This is necessary because the overload of operator<< above makes - // lookup stop at namespace Catch - using ::operator<<; - - // Use this in variadic streaming macros to allow - // >> +StreamEndStop - // as well as - // >> stuff +StreamEndStop - struct StreamEndStop { - std::string operator+() const; - }; - template - T const& operator + ( T const& value, StreamEndStop ) { - return value; - } -} - -#define CATCH_INTERNAL_LINEINFO \ - ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) - -// end catch_common.h -namespace Catch { - - struct RegistrarForTagAliases { - RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); - }; - -} // end namespace Catch - -#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ - CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ - CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ - CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION - -// end catch_tag_alias_autoregistrar.h -// start catch_test_registry.h - -// start catch_interfaces_testcase.h - -#include - -namespace Catch { - - class TestSpec; - - struct ITestInvoker { - virtual void invoke () const = 0; - virtual ~ITestInvoker(); - }; - - class TestCase; - struct IConfig; - - struct ITestCaseRegistry { - virtual ~ITestCaseRegistry(); - virtual std::vector const& getAllTests() const = 0; - virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; - }; - - bool isThrowSafe( TestCase const& testCase, IConfig const& config ); - bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); - std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); - std::vector const& getAllTestCasesSorted( IConfig const& config ); - -} - -// end catch_interfaces_testcase.h -// start catch_stringref.h - -#include -#include -#include -#include - -namespace Catch { - - /// A non-owning string class (similar to the forthcoming std::string_view) - /// Note that, because a StringRef may be a substring of another string, - /// it may not be null terminated. - class StringRef { - public: - using size_type = std::size_t; - using const_iterator = const char*; - - private: - static constexpr char const* const s_empty = ""; - - char const* m_start = s_empty; - size_type m_size = 0; - - public: // construction - constexpr StringRef() noexcept = default; - - StringRef( char const* rawChars ) noexcept; - - constexpr StringRef( char const* rawChars, size_type size ) noexcept - : m_start( rawChars ), - m_size( size ) - {} - - StringRef( std::string const& stdString ) noexcept - : m_start( stdString.c_str() ), - m_size( stdString.size() ) - {} - - explicit operator std::string() const { - return std::string(m_start, m_size); - } - - public: // operators - auto operator == ( StringRef const& other ) const noexcept -> bool; - auto operator != (StringRef const& other) const noexcept -> bool { - return !(*this == other); - } - - auto operator[] ( size_type index ) const noexcept -> char { - assert(index < m_size); - return m_start[index]; - } - - public: // named queries - constexpr auto empty() const noexcept -> bool { - return m_size == 0; - } - constexpr auto size() const noexcept -> size_type { - return m_size; - } - - // Returns the current start pointer. If the StringRef is not - // null-terminated, throws std::domain_exception - auto c_str() const -> char const*; - - public: // substrings and searches - // Returns a substring of [start, start + length). - // If start + length > size(), then the substring is [start, size()). - // If start > size(), then the substring is empty. - auto substr( size_type start, size_type length ) const noexcept -> StringRef; - - // Returns the current start pointer. May not be null-terminated. - auto data() const noexcept -> char const*; - - constexpr auto isNullTerminated() const noexcept -> bool { - return m_start[m_size] == '\0'; - } - - public: // iterators - constexpr const_iterator begin() const { return m_start; } - constexpr const_iterator end() const { return m_start + m_size; } - }; - - auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; - auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; - - constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { - return StringRef( rawChars, size ); - } -} // namespace Catch - -constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { - return Catch::StringRef( rawChars, size ); -} - -// end catch_stringref.h -// start catch_preprocessor.hpp - - -#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ -#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) - -#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ -// MSVC needs more evaluations -#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) -#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) -#else -#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) -#endif - -#define CATCH_REC_END(...) -#define CATCH_REC_OUT - -#define CATCH_EMPTY() -#define CATCH_DEFER(id) id CATCH_EMPTY() - -#define CATCH_REC_GET_END2() 0, CATCH_REC_END -#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 -#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 -#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT -#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) -#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) - -#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) - -#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) - -// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, -// and passes userdata as the first parameter to each invocation, -// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) -#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) -#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ -#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ -#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF -#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ -#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) -#else -// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF -#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) -#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ -#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) -#endif - -#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ -#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) - -#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) - -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) -#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) -#else -#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) -#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) -#endif - -#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ - CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) - -#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) -#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) -#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) -#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) -#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) -#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) -#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) -#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) -#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) -#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) -#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) - -#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N - -#define INTERNAL_CATCH_TYPE_GEN\ - template struct TypeList {};\ - template\ - constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ - template class...> struct TemplateTypeList{};\ - template class...Cs>\ - constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ - template\ - struct append;\ - template\ - struct rewrap;\ - template class, typename...>\ - struct create;\ - template class, typename>\ - struct convert;\ - \ - template \ - struct append { using type = T; };\ - template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ - struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ - template< template class L1, typename...E1, typename...Rest>\ - struct append, TypeList, Rest...> { using type = L1; };\ - \ - template< template class Container, template class List, typename...elems>\ - struct rewrap, List> { using type = TypeList>; };\ - template< template class Container, template class List, class...Elems, typename...Elements>\ - struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ - \ - template