diff --git a/.gitignore b/.gitignore index 1f4aec30..8296d548 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,14 @@ # Whitelist ignore file: Ignore everything that isn't explicitly included * +!*/ !ctem/** !examples/** -!/src/** +!src/** +!cmake/** +!**/.gitignore !*.f90 !*.py +!*.cmake !README.md !ctem.in !craterlist.in @@ -13,5 +17,9 @@ !NPFextrap.dat !FassettCounts.txt !NonMareNonSpa-Highlands.csv - +!CMakeLists.txt +!version.txt +*.mod +**/.idea +**/__pycache__ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..2984d6cb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,78 @@ +# Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +# CMake project file for Swiftest +################################################## +# Define the project and the depencies that it has +################################################## +CMAKE_MINIMUM_REQUIRED(VERSION 3.6.0...3.27.1) + +# Get version stored in text file +FILE(READ "version.txt" VERSION) +PROJECT(${SKBUILD_PROJECT_NAME} LANGUAGES C Fortran VERSION ${VERSION}) + +IF (CMAKE_Fortran_COMPILER_ID MATCHES "^Intel") + SET(COMPILER_OPTIONS "Intel" CACHE STRING "Compiler identified as Intel") +ELSEIF (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + SET(COMPILER_OPTIONS "GNU" CACHE STRING "Compiler identified as gfortran") +ELSE () + MESSAGE(FATAL_ERROR "Compiler ${CMAKE_Fortran_COMPILER_ID} not recognized!") +ENDIF () + +# Set some options the user may choose +OPTION(USE_COARRAY "Use Coarray Fortran for parallelization of test particles" OFF) +OPTION(USE_OPENMP "Use OpenMP for parallelization" ON) +OPTION(USE_SIMD "Use SIMD vectorization" ON) +OPTION(BUILD_SHARED_LIBS "Build using shared libraries" OFF) + +# The following section is modified from Numpy f2py documentation +IF(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) + MESSAGE(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.\n") +ENDIF() + +# Ensure scikit-build modules +FIND_PACKAGE(Python COMPONENTS Interpreter Development.Module REQUIRED) + +# Add our local modules to the module path +FILE(TO_CMAKE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules" LOCAL_MODULE_PATH) +LIST(APPEND CMAKE_MODULE_PATH ${LOCAL_MODULE_PATH}) + +# Define some directories that are important to the build +SET(SRC "${CMAKE_SOURCE_DIR}/src") +SET(LIB "${CMAKE_SOURCE_DIR}/lib") +SET(BIN "${CMAKE_SOURCE_DIR}/bin") +SET(MOD "${CMAKE_SOURCE_DIR}/include") +SET(PY "${CMAKE_SOURCE_DIR}/ctem") + +# Make sure paths are correct for Unix or Windows style +FILE(TO_CMAKE_PATH ${SRC} SRC) +FILE(TO_CMAKE_PATH ${LIB} LIB) +FILE(TO_CMAKE_PATH ${BIN} BIN) +FILE(TO_CMAKE_PATH ${MOD} MOD) +FILE(TO_CMAKE_PATH ${PY} PY) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BIN}) + +# Have the .mod files placed in the lib folder +SET(CMAKE_Fortran_MODULE_DIRECTORY ${MOD}) + +# Set the name of the ctem library +SET(CTEM_LIBRARY ctem) + +# The source for the CTEM binary and have it placed in the bin folder +ADD_SUBDIRECTORY(${SRC} ${BIN}) + +ADD_SUBDIRECTORY(${PY}) + +# Add a distclean target to the Makefile +ADD_CUSTOM_TARGET(distclean + COMMAND ${CMAKE_COMMAND} -P "${CMAKE_SOURCE_DIR}/distclean.cmake" +) diff --git a/cmake/Modules/FindCoarray_Fortran.cmake b/cmake/Modules/FindCoarray_Fortran.cmake new file mode 100644 index 00000000..01324b15 --- /dev/null +++ b/cmake/Modules/FindCoarray_Fortran.cmake @@ -0,0 +1,117 @@ +# Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +# - Finds Coarray support +# This module can be used to detect Coarray support in a compiler. +# If the compiler supports Coarray, the flags required to compile with +# coarray support are set. +# +# This module was modified from the standard FindOpenMP module to find Fortran +# flags. +# +# The following variables are set: +# Coarray_Fortran_FLAGS - flags to add to the Fortran compiler for Coarray +# support. In general, you must use these at both +# compile- and link-time. +# OMP_NUM_PROCS - the max number of processors available to Coarray + +#============================================================================= + +INCLUDE (FindPackageHandleStandardArgs) + +STRING(TOUPPER "${CMAKE_BUILD_TYPE}" BT) +IF(BT STREQUAL "DEBUG") + IF (COMPILER_OPTIONS STREQUAL "Intel") + SET (Coarray_Fortran_FLAG_CANDIDATES + #Intel + "-coarray=single" + #Intel windows + "/Qcoarray:single" + #Empty, if compiler automatically accepts coarray + " " + ) + ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + SET (Coarray_Fortran_FLAG_CANDIDATES + #Gnu + "-fcoarray=single" + #Empty, if compiler automatically accepts coarray + " " + ) + ENDIF() +ELSE() + IF (COMPILER_OPTIONS STREQUAL "Intel") + SET (Coarray_Fortran_FLAG_CANDIDATES + #Intel + "-coarray=distributed" + #Intel windows + "/Qcoarray:distributed" + #Empty, if compiler automatically accepts coarray + " " + ) + ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + SET (Coarray_Fortran_FLAG_CANDIDATES + #Gnu + "-fcoarray=lib -lcaf_mpi" + #Empty, if compiler automatically accepts coarray + " " + ) +ENDIF() + + +IF (DEFINED Coarray_Fortran_FLAGS) + SET (Coarray_Fortran_FLAG_CANDIDATES) +ENDIF (DEFINED Coarray_Fortran_FLAGS) + +# check fortran compiler. also determine number of processors +FOREACH (FLAG ${Coarray_Fortran_FLAG_CANDIDATES}) + SET (SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + SET (CMAKE_REQUIRED_FLAGS "${FLAG}") + UNSET (Coarray_FLAG_DETECTED CACHE) + MESSAGE (STATUS "Try Coarray Fortran flag = [${FLAG}]") + FILE (WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCoarray.f90" +" +program TestCoarray + integer, codimension[*] :: i + write(*,'(I2)',ADVANCE='NO') num_images() +end program TestCoarray +") + SET (MACRO_CHECK_FUNCTION_DEFINITIONS + "-DCoarray_FLAG_DETECTED ${CMAKE_REQUIRED_FLAGS}") + TRY_RUN (Coarray_RUN_FAILED Coarray_FLAG_DETECTED ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCoarray.f90 + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} + COMPILE_OUTPUT_VARIABLE OUTPUT + RUN_OUTPUT_VARIABLE OMP_NUM_PROCS_INTERNAL) + IF (Coarray_FLAG_DETECTED) + FILE (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining if the Fortran compiler supports Coarray passed with " + "the following output:\n${OUTPUT}\n\n") + SET (Coarray_FLAG_DETECTED 1) + IF (Coarray_RUN_FAILED) + MESSAGE (FATAL_ERROR "Coarray found, but test code did not run") + ENDIF (Coarray_RUN_FAILED) + SET (Coarray_Fortran_FLAGS_INTERNAL "${FLAG}") + BREAK () + ELSE () + FILE (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining if the Fortran compiler supports Coarray failed with " + "the following output:\n${OUTPUT}\n\n") + SET (Coarray_FLAG_DETECTED 0) + ENDIF (Coarray_FLAG_DETECTED) +ENDFOREACH (FLAG ${Coarray_Fortran_FLAG_CANDIDATES}) + +SET (Coarray_Fortran_FLAGS "${Coarray_Fortran_FLAGS_INTERNAL}" + CACHE STRING "Fortran compiler flags for Coarray parallization") + +# handle the standard arguments for FIND_PACKAGE +FIND_PACKAGE_HANDLE_STANDARD_ARGS (Coarray_Fortran DEFAULT_MSG + Coarray_Fortran_FLAGS) + +MARK_AS_ADVANCED(Coarray_Fortran_FLAGS) diff --git a/cmake/Modules/FindCython.cmake b/cmake/Modules/FindCython.cmake new file mode 100644 index 00000000..c8de1311 --- /dev/null +++ b/cmake/Modules/FindCython.cmake @@ -0,0 +1,88 @@ +#.rst: +# +# Find ``cython`` executable. +# +# This module will set the following variables in your project: +# +# ``CYTHON_EXECUTABLE`` +# path to the ``cython`` program +# +# ``CYTHON_VERSION`` +# version of ``cython`` +# +# ``CYTHON_FOUND`` +# true if the program was found +# +# For more information on the Cython project, see https://cython.org/. +# +# *Cython is a language that makes writing C extensions for the Python language +# as easy as Python itself.* +# +#============================================================================= +# Copyright 2011 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +# Use the Cython executable that lives next to the Python executable +# if it is a local installation. +if(Python_EXECUTABLE) + get_filename_component(_python_path ${Python_EXECUTABLE} PATH) +elseif(Python3_EXECUTABLE) + get_filename_component(_python_path ${Python3_EXECUTABLE} PATH) +elseif(DEFINED PYTHON_EXECUTABLE) + get_filename_component(_python_path ${PYTHON_EXECUTABLE} PATH) +endif() + +if(DEFINED _python_path) + find_program(CYTHON_EXECUTABLE + NAMES cython cython.bat cython3 + HINTS ${_python_path} + DOC "path to the cython executable") +else() + find_program(CYTHON_EXECUTABLE + NAMES cython cython.bat cython3 + DOC "path to the cython executable") +endif() + +if(CYTHON_EXECUTABLE) + set(CYTHON_version_command ${CYTHON_EXECUTABLE} --version) + + execute_process(COMMAND ${CYTHON_version_command} + OUTPUT_VARIABLE CYTHON_version_output + ERROR_VARIABLE CYTHON_version_error + RESULT_VARIABLE CYTHON_version_result + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE) + + if(NOT ${CYTHON_version_result} EQUAL 0) + set(_error_msg "Command \"${CYTHON_version_command}\" failed with") + set(_error_msg "${_error_msg} output:\n${CYTHON_version_error}") + message(SEND_ERROR "${_error_msg}") + else() + if("${CYTHON_version_output}" MATCHES "^[Cc]ython version ([^,]+)") + set(CYTHON_VERSION "${CMAKE_MATCH_1}") + else() + if("${CYTHON_version_error}" MATCHES "^[Cc]ython version ([^,]+)") + set(CYTHON_VERSION "${CMAKE_MATCH_1}") + endif() + endif() + endif() +endif() + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cython REQUIRED_VARS CYTHON_EXECUTABLE) + +mark_as_advanced(CYTHON_EXECUTABLE) + +include(UseCython) diff --git a/cmake/Modules/FindMKL.cmake b/cmake/Modules/FindMKL.cmake new file mode 100644 index 00000000..9e48932c --- /dev/null +++ b/cmake/Modules/FindMKL.cmake @@ -0,0 +1,17 @@ +# Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +# - Finds the Intel MKL libraries +find_path(MKL_INCLUDE_DIR NAMES mkl.h HINTS ENV MKLROOT PATH_SUFFIXES include) +find_library(MKL_LIBRARY NAMES libmkl_core.a HINTS ENV MKLROOT PATH_SUFFIXES lib lib/intel64 ) + +set(MKL_FOUND TRUE) +set(MKL_INCLUDE_DIRS ${MKL_INCLUDE_DIR}) +set(MKL_LIBRARIES ${MKL_LIBRARY}) +mark_as_advanced(MKL_LIBRARY MKL_INCLUDE_DIR) \ No newline at end of file diff --git a/cmake/Modules/FindNETCDF.cmake b/cmake/Modules/FindNETCDF.cmake new file mode 100644 index 00000000..05f91e77 --- /dev/null +++ b/cmake/Modules/FindNETCDF.cmake @@ -0,0 +1,207 @@ +# Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +# - Finds the NetCDF libraries + +SET(NFPREFIX_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Location of provided NetCDF-Fortran dependencies") +SET(NFINCLUDE_DIR "${NFPREFIX_DIR}/include" CACHE PATH "Location of provided netcdf.mod") +IF(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") + FIND_PATH(NFBIN + NAMES nf-config + HINTS + NFPREFIX_DIR + ENV NETCDF_FORTRAN_HOME + ENV PATH + PATH_SUFFIXES + bin + ) + + IF (NFBIN) + SET(CMD "${NFBIN}/nf-config") + LIST(APPEND CMD "--includedir") + MESSAGE(STATUS "Searching for NetCDF-Fortran include directory using ${CMD}") + EXECUTE_PROCESS(COMMAND ${CMD} OUTPUT_VARIABLE NFINCLUDE_DIR ERROR_VARIABLE ERR RESULT_VARIABLE RES OUTPUT_STRIP_TRAILING_WHITESPACE) + IF (NFINCLUDE_DIR) + MESSAGE(STATUS "Found in ${NFINCLUDE_DIR}") + ELSE () + MESSAGE(STATUS "Cannot execute ${CMD}") + MESSAGE(STATUS "OUTPUT: ${NFINCLUDE_DIR}") + MESSAGE(STATUS "RESULT: ${RES}") + MESSAGE(STATUS "ERROR : ${ERR}") + ENDIF () + + SET(CMD "${NFBIN}/nf-config") + LIST(APPEND CMD "--prefix") + MESSAGE(STATUS "Searching for NetCDF-Fortran library directory using ${CMD}") + EXECUTE_PROCESS(COMMAND ${CMD} OUTPUT_VARIABLE NFPREFIX_DIR ERROR_VARIABLE ERR RESULT_VARIABLE RES OUTPUT_STRIP_TRAILING_WHITESPACE) + IF (NFPREFIX_DIR) + MESSAGE(STATUS "Found in ${NFPREFIX_DIR}") + ELSE () + MESSAGE(STATUS "Cannot execute ${CMD}") + MESSAGE(STATUS "OUTPUT: ${NFPREFIX_DIR}") + MESSAGE(STATUS "RESULT: ${RES}") + MESSAGE(STATUS "ERROR : ${ERR}") + ENDIF () + ENDIF() +ENDIF() + +MESSAGE(STATUS "\nNETCDF_INCLUDE: $ENV{NETCDF_INCLUDE}\nNETCDF_FORTRAN_HOME: $ENV{NETCDF_FORTRAN_HOME}\n") +FIND_PATH(NETCDF_INCLUDE_DIR + NAMES netcdf.mod + HINTS + ${NFINCLUDE_DIR} + ENV NETCDF_INCLUDE + ENV NETCDF_FORTRAN_HOME + ENV CPATH + PATH_SUFFIXES + include + modules + mod + REQUIRED +) + +MESSAGE(STATUS "NetCDF-Fortran include directory: ${NETCDF_INCLUDE_DIR}") + +IF (BUILD_SHARED_LIBS) + SET(NETCDFF "netcdff") +ELSE () + SET(NCPREFIX_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Location of provided NetCDF-C dependencies") + SET(H5PREFIX_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Location of provided HDF5 dependencies") + SET(ZPREFIX_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Location of provided zlib dependencies") + IF (CMAKE_SYSTEM_NAME STREQUAL "Windows") + SET(NETCDFF "netcdff.lib") + SET(NETCDF "netcdf.lib") + SET(HDF5 "libhdf5.lib") + SET(HDF5_HL "libhdf5_hl.lib") + SET(ZLIB "zlibstatic.lib") + ELSE () + SET(NETCDFF "libnetcdff.a") + SET(NETCDF "libnetcdf.a") + SET(HDF5 "libhdf5.a") + SET(HDF5_HL "libhdf5_hl.a") + SET(ZLIB "libz.a") + ENDIF() +ENDIF() + +FIND_LIBRARY(NETCDF_FORTRAN_LIBRARY + NAMES ${NETCDFF} + HINTS + ${NFPREFIX_DIR} + ENV NETCDF_FORTRAN_HOME + ENV NETCDF_HOME + ENV LD_LIBRARY_PATH + PATH_SUFFIXES + lib + ${CMAKE_LIBRARY_ARCHITECTURE} + REQUIRED +) + +MESSAGE(STATUS "NetCDF-Fortran Library: ${NETCDF_FORTRAN_LIBRARY}") + +IF (BUILD_SHARED_LIBS) + SET(NETCDF_LIBRARIES ${NETCDF_FORTRAN_LIBRARY} CACHE STRING "NetCDF Fortran library") +ELSE () + FIND_LIBRARY(NETCDF_LIBRARY + NAMES ${NETCDF} + HINTS + ${NCPREFIX_DIR} + ENV NETCDF_HOME + ENV LD_LIBRARY_PATH + PATH_SUFFIXES + lib + ${CMAKE_LIBRARY_ARCHITECTURE} + REQUIRED + ) + + MESSAGE(STATUS "NetCDF-C Library: ${NETCDF_LIBRARY}") + IF (CMAKE_SYSTEM_NAME STREQUAL "Windows") + FIND_LIBRARY(HDF5_LIBRARY + NAMES ${HDF5} + HINTS + ${H5PREFIX_DIR} + ENV HDF5_ROOT + ENV LD_LIBRARY_PATH + PATH_SUFFIXES + lib + ${CMAKE_LIBRARY_ARCHITECTURE} + REQUIRED + ) + + FIND_LIBRARY(HDF5_HL_LIBRARY + NAMES ${HDF5_HL} + HINTS + ${H5PREFIX_DIR} + ENV HDF5_ROOT + ENV LD_LIBRARY_PATH + PATH_SUFFIXES + lib + ${CMAKE_LIBRARY_ARCHITECTURE} + REQUIRED + ) + + FIND_LIBRARY(Z_LIBRARY + NAMES ${ZLIB} + HINTS + ${ZPREFIX_DIR} + ENV ZLIB_ROOT + ENV LD_LIBRARY_PATH + PATH_SUFFIXES + lib + ${CMAKE_LIBRARY_ARCHITECTURE} + REQUIRED + ) + + LIST(APPEND EXTRA_FLAGS ${HDF5_LIBRARY} ${HDF5_HL_LIBRARY} ${Z_LIBRARY}) + + ELSE () + FIND_PATH(NCBIN + NAMES nc-config + HINTS + ENV NETCDF_HOME + ENV PATH + PATH_SUFFIXES + bin + ) + + IF (NCBIN) # The nc-config utility is available. Parse its output for unique flags + SET(CMD "${NCBIN}/nc-config") + LIST(APPEND CMD "--libs") + LIST(APPEND CMD "--static") + MESSAGE(STATUS "NetCDF configuration command: ${CMD}") + EXECUTE_PROCESS(COMMAND ${CMD} OUTPUT_VARIABLE EXTRA_FLAGS ERROR_VARIABLE ERR RESULT_VARIABLE RES OUTPUT_STRIP_TRAILING_WHITESPACE) + IF (EXTRA_FLAGS) + SEPARATE_ARGUMENTS(EXTRA_FLAGS NATIVE_COMMAND "${EXTRA_FLAGS}") + LIST(REMOVE_DUPLICATES EXTRA_FLAGS) + LIST(FILTER EXTRA_FLAGS EXCLUDE REGEX "netcdf+") + MESSAGE(STATUS "Extra library flags: ${EXTRA_FLAGS}") + ELSE () + MESSAGE(STATUS "Cannot execute ${CMD}") + MESSAGE(STATUS "OUTPUT: ${EXTRA_FLAGS}") + MESSAGE(STATUS "RESUL : ${RES}") + MESSAGE(STATUS "ERROR : ${ERR}") + MESSAGE(FATAL_ERROR "Cannot configure NetCDF for static") + ENDIF () + ELSE () + MESSAGE(FATAL_ERROR "Cannot find nc-config") + ENDIF () + ENDIF() + + IF (DEFINED ENV{LIBS}) + STRING(STRIP "$ENV{LIBS}" LIBS) + SEPARATE_ARGUMENTS(LIBS NATIVE_COMMAND "${LIBS}") + LIST(APPEND EXTRA_FLAGS ${LIBS}) + ENDIF() + + # Note for posterity: When building static libraries, NETCDF_FORTRAN_LIBRARY must come *before* NETCDF_LIBRARY. Otherwise you get a bunch of "undefined reference to" errors + SET(NETCDF_LIBRARIES ${NETCDF_FORTRAN_LIBRARY} ${NETCDF_LIBRARY} ${EXTRA_FLAGS} CACHE STRING "NetCDF Fortran and dependant static libraries") +ENDIF () +MESSAGE(STATUS "NetCDF dependencies: ${NETCDF_LIBRARIES}") + +SET(NETCDF_FOUND TRUE) +MARK_AS_ADVANCED(NETCDF_LIBRARIES NETCDF_INCLUDE_DIR) \ No newline at end of file diff --git a/cmake/Modules/FindOpenMP_Fortran.cmake b/cmake/Modules/FindOpenMP_Fortran.cmake new file mode 100644 index 00000000..33eda8f5 --- /dev/null +++ b/cmake/Modules/FindOpenMP_Fortran.cmake @@ -0,0 +1,116 @@ +# Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +# - Finds OpenMP support +# This module can be used to detect OpenMP support in a compiler. +# If the compiler supports OpenMP, the flags required to compile with +# openmp support are set. +# +# This module was modified from the standard FindOpenMP module to find Fortran +# flags. +# +# The following variables are set: +# OpenMP_Fortran_FLAGS - flags to add to the Fortran compiler for OpenMP +# support. In general, you must use these at both +# compile- and link-time. +# OMP_NUM_PROCS - the max number of processors available to OpenMP + +#============================================================================= + +INCLUDE (FindPackageHandleStandardArgs) + +IF (COMPILER_OPTIONS STREQUAL "Intel") + MESSAGE(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}") + IF (CMAKE_SYSTEM_NAME STREQUAL "Windows") + IF (USE_SIMD) + SET (OpenMP_Fortran_FLAG_CANDIDATES + "/Qopenmp" # Intel Windows + ) + ELSE () + SET (OpenMP_Fortran_FLAG_CANDIDATES + "/Qopenmp-simd-" # Intel Windows + ) + ENDIF (USE_SIMD) + ELSE () + IF (USE_SIMD) + SET (OpenMP_Fortran_FLAG_CANDIDATES + "-qopenmp" # Intel + ) + ELSE () + SET (OpenMP_Fortran_FLAG_CANDIDATES + "-qopenmp -qno-openmp-simd" # Intel + ) + ENDIF (USE_SIMD) + ENDIF () +ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + IF (USE_SIMD) + SET (OpenMP_Fortran_FLAG_CANDIDATES + "-fopenmp" # GNU + ) + ELSE () + SET (OpenMP_Fortran_FLAG_CANDIDATES + "-fopenmp -fno-openmp-simd" # GNU + ) + ENDIF (USE_SIMD) + +ENDIF () + +IF (DEFINED OpenMP_Fortran_FLAGS) + SET (OpenMP_Fortran_FLAG_CANDIDATES) +ENDIF (DEFINED OpenMP_Fortran_FLAGS) + +# check fortran compiler. also determine number of processors +FOREACH (FLAG ${OpenMP_Fortran_FLAG_CANDIDATES}) + SET (SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + SET (CMAKE_REQUIRED_FLAGS "${FLAG}") + UNSET (OpenMP_FLAG_DETECTED CACHE) + MESSAGE (STATUS "Try OpenMP Fortran flag = [${FLAG}]") + FILE (WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranOpenMP.f90" +" +program TestOpenMP + use omp_lib + write(*,'(I2)',ADVANCE='NO') omp_get_num_procs() +end program TestOpenMP +") + SET (MACRO_CHECK_FUNCTION_DEFINITIONS + "-DOpenMP_FLAG_DETECTED ${CMAKE_REQUIRED_FLAGS}") + TRY_RUN (OpenMP_RUN_FAILED OpenMP_FLAG_DETECTED ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranOpenMP.f90 + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} + COMPILE_OUTPUT_VARIABLE OUTPUT + RUN_OUTPUT_VARIABLE OMP_NUM_PROCS_INTERNAL) + IF (OpenMP_FLAG_DETECTED) + FILE (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining if the Fortran compiler supports OpenMP passed with " + "the following output:\n${OUTPUT}\n\n") + SET (OpenMP_FLAG_DETECTED 1) + IF (OpenMP_RUN_FAILED) + MESSAGE (FATAL_ERROR "OpenMP found, but test code did not run") + ENDIF (OpenMP_RUN_FAILED) + SET (OMP_NUM_PROCS ${OMP_NUM_PROCS_INTERNAL} CACHE + STRING "Number of processors OpenMP may use" FORCE) + SET (OpenMP_Fortran_FLAGS_INTERNAL "${FLAG}") + BREAK () + ELSE () + FILE (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining if the Fortran compiler supports OpenMP failed with " + "the following output:\n${OUTPUT}\n\n") + SET (OpenMP_FLAG_DETECTED 0) + ENDIF (OpenMP_FLAG_DETECTED) +ENDFOREACH (FLAG ${OpenMP_Fortran_FLAG_CANDIDATES}) + +SET (OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_INTERNAL}" + CACHE STRING "Fortran compiler flags for OpenMP parallization") + +# handle the standard arguments for FIND_PACKAGE +FIND_PACKAGE_HANDLE_STANDARD_ARGS (OpenMP_Fortran DEFAULT_MSG + OpenMP_Fortran_FLAGS) + +MARK_AS_ADVANCED(OpenMP_Fortran_FLAGS) diff --git a/cmake/Modules/FindPythonExtensions.cmake b/cmake/Modules/FindPythonExtensions.cmake new file mode 100644 index 00000000..59b30c2a --- /dev/null +++ b/cmake/Modules/FindPythonExtensions.cmake @@ -0,0 +1,597 @@ +#.rst: +# +# This module defines CMake functions to build Python extension modules and +# stand-alone executables. +# +# The following variables are defined: +# :: +# +# PYTHON_PREFIX - absolute path to the current Python +# distribution's prefix +# PYTHON_SITE_PACKAGES_DIR - absolute path to the current Python +# distribution's site-packages directory +# PYTHON_RELATIVE_SITE_PACKAGES_DIR - path to the current Python +# distribution's site-packages directory +# relative to its prefix +# PYTHON_SEPARATOR - separator string for file path +# components. Equivalent to ``os.sep`` in +# Python. +# PYTHON_PATH_SEPARATOR - separator string for PATH-style +# environment variables. Equivalent to +# ``os.pathsep`` in Python. +# PYTHON_EXTENSION_MODULE_SUFFIX - suffix of the compiled module. For example, on +# Linux, based on environment, it could be ``.cpython-35m-x86_64-linux-gnu.so``. +# +# +# +# The following functions are defined: +# +# .. cmake:command:: python_extension_module +# +# For libraries meant to be used as Python extension modules, either dynamically +# loaded or directly linked. Amend the configuration of the library target +# (created using ``add_library``) with additional options needed to build and +# use the referenced library as a Python extension module. +# +# python_extension_module( +# [LINKED_MODULES_VAR ] +# [FORWARD_DECL_MODULES_VAR ] +# [MODULE_SUFFIX ]) +# +# Only extension modules that are configured to be built as MODULE libraries can +# be runtime-loaded through the standard Python import mechanism. All other +# modules can only be included in standalone applications that are written to +# expect their presence. In addition to being linked against the libraries for +# these modules, such applications must forward declare their entry points and +# initialize them prior to use. To generate these forward declarations and +# initializations, see ``python_modules_header``. +# +# If ```` does not refer to a target, then it is assumed to refer to an +# extension module that is not linked at all, but compiled along with other +# source files directly into an executable. Adding these modules does not cause +# any library configuration modifications, and they are not added to the list of +# linked modules. They still must be forward declared and initialized, however, +# and so are added to the forward declared modules list. +# +# If the associated target is of type ``MODULE_LIBRARY``, the LINK_FLAGS target +# property is used to set symbol visibility and export only the module init function. +# This applies to GNU and MSVC compilers. +# +# Options: +# +# ``LINKED_MODULES_VAR `` +# Name of the variable referencing a list of extension modules whose libraries +# must be linked into the executables of any stand-alone applications that use +# them. By default, the global property ``PY_LINKED_MODULES_LIST`` is used. +# +# ``FORWARD_DECL_MODULES_VAR `` +# Name of the variable referencing a list of extension modules whose entry +# points must be forward declared and called by any stand-alone applications +# that use them. By default, the global property +# ``PY_FORWARD_DECL_MODULES_LIST`` is used. +# +# ``MODULE_SUFFIX `` +# Suffix appended to the python extension module file. +# The default suffix is retrieved using ``sysconfig.get_config_var("SO")"``, +# if not available, the default is then ``.so`` on unix and ``.pyd`` on +# windows. +# Setting the variable ``PYTHON_EXTENSION_MODULE_SUFFIX`` in the caller +# scope defines the value used for all extensions not having a suffix +# explicitly specified using ``MODULE_SUFFIX`` parameter. +# +# +# .. cmake:command:: python_standalone_executable +# +# python_standalone_executable() +# +# For standalone executables that initialize their own Python runtime +# (such as when building source files that include one generated by Cython with +# the --embed option). Amend the configuration of the executable target +# (created using ``add_executable``) with additional options needed to properly +# build the referenced executable. +# +# +# .. cmake:command:: python_modules_header +# +# Generate a header file that contains the forward declarations and +# initialization routines for the given list of Python extension modules. +# ```` is the logical name for the header file (no file extensions). +# ```` is the actual destination filename for the header file +# (e.g.: decl_modules.h). +# +# python_modules_header( [HeaderFilename] +# [FORWARD_DECL_MODULES_LIST ] +# [HEADER_OUTPUT_VAR ] +# [INCLUDE_DIR_OUTPUT_VAR ]) +# +# without the extension is used as the logical name. If only ```` is +# +# If only ```` is provided, and it ends in the ".h" extension, then it +# is assumed to be the ````. The filename of the header file +# provided, and it does not end in the ".h" extension, then the +# ```` is assumed to ``.h``. +# +# The exact contents of the generated header file depend on the logical +# ````. It should be set to a value that corresponds to the target +# application, or for the case of multiple applications, some identifier that +# conveyes its purpose. It is featured in the generated multiple inclusion +# guard as well as the names of the generated initialization routines. +# +# The generated header file includes forward declarations for all listed +# modules, as well as implementations for the following class of routines: +# +# ``int _(void)`` +# Initializes the python extension module, ````. Returns an integer +# handle to the module. +# +# ``void _LoadAllPythonModules(void)`` +# Initializes all listed python extension modules. +# +# ``void CMakeLoadAllPythonModules(void);`` +# Alias for ``_LoadAllPythonModules`` whose name does not depend on +# ````. This function is excluded during preprocessing if the +# preprocessing macro ``EXCLUDE_LOAD_ALL_FUNCTION`` is defined. +# +# ``void Py_Initialize_Wrapper();`` +# Wrapper arpund ``Py_Initialize()`` that initializes all listed python +# extension modules. This function is excluded during preprocessing if the +# preprocessing macro ``EXCLUDE_PY_INIT_WRAPPER`` is defined. If this +# function is generated, then ``Py_Initialize()`` is redefined to a macro +# that calls this function. +# +# Options: +# +# ``FORWARD_DECL_MODULES_LIST `` +# List of extension modules for which to generate forward declarations of +# their entry points and their initializations. By default, the global +# property ``PY_FORWARD_DECL_MODULES_LIST`` is used. +# +# ``HEADER_OUTPUT_VAR `` +# Name of the variable to set to the path to the generated header file. By +# default, ```` is used. +# +# ``INCLUDE_DIR_OUTPUT_VAR `` +# Name of the variable to set to the path to the directory containing the +# generated header file. By default, ``_INCLUDE_DIRS`` is used. +# +# Defined variables: +# +# ```` +# The path to the generated header file +# +# ```` +# Directory containing the generated header file +# +# +# Example usage +# ^^^^^^^^^^^^^ +# +# .. code-block:: cmake +# +# find_package(PythonExtensions) +# find_package(Cython) +# find_package(Boost COMPONENTS python) +# +# # Simple Cython Module -- no executables +# add_cython_target(_module.pyx) +# add_library(_module MODULE ${_module}) +# python_extension_module(_module) +# +# # Mix of Cython-generated code and C++ code using Boost Python +# # Stand-alone executable -- no modules +# include_directories(${Boost_INCLUDE_DIRS}) +# add_cython_target(main.pyx CXX EMBED_MAIN) +# add_executable(main boost_python_module.cxx ${main}) +# target_link_libraries(main ${Boost_LIBRARIES}) +# python_standalone_executable(main) +# +# # stand-alone executable with three extension modules: +# # one statically linked, one dynamically linked, and one loaded at runtime +# # +# # Freely mixes Cython-generated code, code using Boost-Python, and +# # hand-written code using the CPython API. +# +# # module1 -- statically linked +# add_cython_target(module1.pyx) +# add_library(module1 STATIC ${module1}) +# python_extension_module(module1 +# LINKED_MODULES_VAR linked_module_list +# FORWARD_DECL_MODULES_VAR fdecl_module_list) +# +# # module2 -- dynamically linked +# include_directories(${Boost_INCLUDE_DIRS}) +# add_library(module2 SHARED boost_module2.cxx) +# target_link_libraries(module2 ${Boost_LIBRARIES}) +# python_extension_module(module2 +# LINKED_MODULES_VAR linked_module_list +# FORWARD_DECL_MODULES_VAR fdecl_module_list) +# +# # module3 -- loaded at runtime +# add_cython_target(module3a.pyx) +# add_library(module3 MODULE ${module3a} module3b.cxx) +# target_link_libraries(module3 ${Boost_LIBRARIES}) +# python_extension_module(module3 +# LINKED_MODULES_VAR linked_module_list +# FORWARD_DECL_MODULES_VAR fdecl_module_list) +# +# # application executable -- generated header file + other source files +# python_modules_header(modules +# FORWARD_DECL_MODULES_LIST ${fdecl_module_list}) +# include_directories(${modules_INCLUDE_DIRS}) +# +# add_cython_target(mainA) +# add_cython_target(mainC) +# add_executable(main ${mainA} mainB.cxx ${mainC} mainD.c) +# +# target_link_libraries(main ${linked_module_list} ${Boost_LIBRARIES}) +# python_standalone_executable(main) +# +#============================================================================= +# Copyright 2011 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_package(PythonInterp REQUIRED) +if(SKBUILD AND NOT PYTHON_LIBRARY) + set(PYTHON_LIBRARY "no-library-required") + find_package(PythonLibs) + unset(PYTHON_LIBRARY) + unset(PYTHON_LIBRARIES) +else() + find_package(PythonLibs) +endif() +include(targetLinkLibrariesWithDynamicLookup) + +set(_command " +import distutils.sysconfig +import itertools +import os +import os.path +import site +import sys + +result = None +rel_result = None +candidate_lists = [] + +try: + candidate_lists.append((distutils.sysconfig.get_python_lib(),)) +except AttributeError: pass + +try: + candidate_lists.append(site.getsitepackages()) +except AttributeError: pass + +try: + candidate_lists.append((site.getusersitepackages(),)) +except AttributeError: pass + +candidates = itertools.chain.from_iterable(candidate_lists) + +for candidate in candidates: + rel_candidate = os.path.relpath( + candidate, sys.prefix) + if not rel_candidate.startswith(\"..\"): + result = candidate + rel_result = rel_candidate + break + +sys.stdout.write(\";\".join(( + os.sep, + os.pathsep, + sys.prefix, + result, + rel_result, + distutils.sysconfig.get_config_var('EXT_SUFFIX') +))) +") + +execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "${_command}" + OUTPUT_VARIABLE _list + RESULT_VARIABLE _result) + +list(GET _list 0 _item) +set(PYTHON_SEPARATOR "${_item}") +mark_as_advanced(PYTHON_SEPARATOR) + +list(GET _list 1 _item) +set(PYTHON_PATH_SEPARATOR "${_item}") +mark_as_advanced(PYTHON_PATH_SEPARATOR) + +list(GET _list 2 _item) +set(PYTHON_PREFIX "${_item}") +mark_as_advanced(PYTHON_PREFIX) + +list(GET _list 3 _item) +set(PYTHON_SITE_PACKAGES_DIR "${_item}") +mark_as_advanced(PYTHON_SITE_PACKAGES_DIR) + +list(GET _list 4 _item) +set(PYTHON_RELATIVE_SITE_PACKAGES_DIR "${_item}") +mark_as_advanced(PYTHON_RELATIVE_SITE_PACKAGES_DIR) + +if(NOT DEFINED PYTHON_EXTENSION_MODULE_SUFFIX) + list(GET _list 5 _item) + set(PYTHON_EXTENSION_MODULE_SUFFIX "${_item}") +endif() + +function(_set_python_extension_symbol_visibility _target) + if(PYTHON_VERSION_MAJOR VERSION_GREATER 2) + set(_modinit_prefix "PyInit_") + else() + set(_modinit_prefix "init") + endif() + message("_modinit_prefix:${_modinit_prefix}") + if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") + set_target_properties(${_target} PROPERTIES LINK_FLAGS + "/EXPORT:${_modinit_prefix}${_target}" + ) + elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + # Option to not run version script. See https://github.com/scikit-build/scikit-build/issues/668 + if(NOT DEFINED SKBUILD_GNU_SKIP_LOCAL_SYMBOL_EXPORT_OVERRIDE) + set(SKBUILD_GNU_SKIP_LOCAL_SYMBOL_EXPORT_OVERRIDE FALSE) + endif() + set(_script_path + ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_target}-version-script.map + ) + # Export all symbols. See https://github.com/scikit-build/scikit-build/issues/668 + if(SKBUILD_GNU_SKIP_LOCAL_SYMBOL_EXPORT_OVERRIDE) + file(WRITE ${_script_path} + "{global: ${_modinit_prefix}${_target};};" + ) + else() + file(WRITE ${_script_path} + "{global: ${_modinit_prefix}${_target}; local: *;};" + ) + endif() + if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS + " -Wl,--version-script=\"${_script_path}\"" + ) + else() + set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS + " -Wl,-M \"${_script_path}\"" + ) + endif() + endif() +endfunction() + +function(python_extension_module _target) + set(one_ops LINKED_MODULES_VAR FORWARD_DECL_MODULES_VAR MODULE_SUFFIX) + cmake_parse_arguments(_args "" "${one_ops}" "" ${ARGN}) + + set(_lib_type "NA") + if(TARGET ${_target}) + get_property(_lib_type TARGET ${_target} PROPERTY TYPE) + endif() + + set(_is_non_lib TRUE) + + set(_is_static_lib FALSE) + if(_lib_type STREQUAL "STATIC_LIBRARY") + set(_is_static_lib TRUE) + set(_is_non_lib FALSE) + endif() + + set(_is_shared_lib FALSE) + if(_lib_type STREQUAL "SHARED_LIBRARY") + set(_is_shared_lib TRUE) + set(_is_non_lib FALSE) + endif() + + set(_is_module_lib FALSE) + if(_lib_type STREQUAL "MODULE_LIBRARY") + set(_is_module_lib TRUE) + set(_is_non_lib FALSE) + endif() + + if(_is_static_lib OR _is_shared_lib OR _is_non_lib) + + if(_is_static_lib OR _is_shared_lib) + if(_args_LINKED_MODULES_VAR) + set(${_args_LINKED_MODULES_VAR} + ${${_args_LINKED_MODULES_VAR}} ${_target} PARENT_SCOPE) + else() + set_property(GLOBAL APPEND PROPERTY PY_LINKED_MODULES_LIST ${_target}) + endif() + endif() + + if(_args_FORWARD_DECL_MODULES_VAR) + set(${_args_FORWARD_DECL_MODULES_VAR} + ${${_args_FORWARD_DECL_MODULES_VAR}} ${_target} PARENT_SCOPE) + else() + set_property(GLOBAL APPEND PROPERTY + PY_FORWARD_DECL_MODULES_LIST ${_target}) + endif() + endif() + + if(NOT _is_non_lib) + include_directories("${PYTHON_INCLUDE_DIRS}") + endif() + + if(_is_module_lib) + set_target_properties(${_target} PROPERTIES + PREFIX "${PYTHON_MODULE_PREFIX}") + endif() + + if(_is_module_lib OR _is_shared_lib) + if(_is_module_lib) + + if(NOT _args_MODULE_SUFFIX) + set(_args_MODULE_SUFFIX "${PYTHON_EXTENSION_MODULE_SUFFIX}") + endif() + + if(_args_MODULE_SUFFIX STREQUAL "" AND WIN32 AND NOT CYGWIN) + set(_args_MODULE_SUFFIX ".pyd") + endif() + + if(NOT _args_MODULE_SUFFIX STREQUAL "") + set_target_properties(${_target} + PROPERTIES SUFFIX ${_args_MODULE_SUFFIX}) + endif() + endif() + + target_link_libraries_with_dynamic_lookup(${_target} ${PYTHON_LIBRARIES}) + + if(_is_module_lib) + _set_python_extension_symbol_visibility(${_target}) + endif() + endif() +endfunction() + +function(python_standalone_executable _target) + include_directories(${PYTHON_INCLUDE_DIRS}) + target_link_libraries(${_target} ${SKBUILD_LINK_LIBRARIES_KEYWORD} ${PYTHON_LIBRARIES}) +endfunction() + +function(python_modules_header _name) + set(one_ops FORWARD_DECL_MODULES_LIST + HEADER_OUTPUT_VAR + INCLUDE_DIR_OUTPUT_VAR) + cmake_parse_arguments(_args "" "${one_ops}" "" ${ARGN}) + + list(GET _args_UNPARSED_ARGUMENTS 0 _arg0) + # if present, use arg0 as the input file path + if(_arg0) + set(_source_file ${_arg0}) + + # otherwise, must determine source file from name, or vice versa + else() + get_filename_component(_name_ext "${_name}" EXT) + + # if extension provided, _name is the source file + if(_name_ext) + set(_source_file ${_name}) + get_filename_component(_name "${_source_file}" NAME_WE) + + # otherwise, assume the source file is ${_name}.h + else() + set(_source_file ${_name}.h) + endif() + endif() + + if(_args_FORWARD_DECL_MODULES_LIST) + set(static_mod_list ${_args_FORWARD_DECL_MODULES_LIST}) + else() + get_property(static_mod_list GLOBAL PROPERTY PY_FORWARD_DECL_MODULES_LIST) + endif() + + string(REPLACE "." "_" _header_name "${_name}") + string(TOUPPER ${_header_name} _header_name_upper) + set(_header_name_upper "_${_header_name_upper}_H") + set(generated_file ${CMAKE_CURRENT_BINARY_DIR}/${_source_file}) + + set(generated_file_tmp "${generated_file}.in") + file(WRITE ${generated_file_tmp} + "/* Created by CMake. DO NOT EDIT; changes will be lost. */\n") + + set(_chunk "") + set(_chunk "${_chunk}#ifndef ${_header_name_upper}\n") + set(_chunk "${_chunk}#define ${_header_name_upper}\n") + set(_chunk "${_chunk}\n") + set(_chunk "${_chunk}#include \n") + set(_chunk "${_chunk}\n") + set(_chunk "${_chunk}#ifdef __cplusplus\n") + set(_chunk "${_chunk}extern \"C\" {\n") + set(_chunk "${_chunk}#endif /* __cplusplus */\n") + set(_chunk "${_chunk}\n") + set(_chunk "${_chunk}#if PY_MAJOR_VERSION < 3\n") + file(APPEND ${generated_file_tmp} "${_chunk}") + + foreach(_module ${static_mod_list}) + file(APPEND ${generated_file_tmp} + "PyMODINIT_FUNC init${PYTHON_MODULE_PREFIX}${_module}(void);\n") + endforeach() + + file(APPEND ${generated_file_tmp} "#else /* PY_MAJOR_VERSION >= 3*/\n") + + foreach(_module ${static_mod_list}) + file(APPEND ${generated_file_tmp} + "PyMODINIT_FUNC PyInit_${PYTHON_MODULE_PREFIX}${_module}(void);\n") + endforeach() + + set(_chunk "") + set(_chunk "${_chunk}#endif /* PY_MAJOR_VERSION >= 3*/\n\n") + set(_chunk "${_chunk}#ifdef __cplusplus\n") + set(_chunk "${_chunk}}\n") + set(_chunk "${_chunk}#endif /* __cplusplus */\n") + set(_chunk "${_chunk}\n") + file(APPEND ${generated_file_tmp} "${_chunk}") + + foreach(_module ${static_mod_list}) + set(_import_function "${_header_name}_${_module}") + set(_prefixed_module "${PYTHON_MODULE_PREFIX}${_module}") + + set(_chunk "") + set(_chunk "${_chunk}int ${_import_function}(void)\n") + set(_chunk "${_chunk}{\n") + set(_chunk "${_chunk} static char name[] = \"${_prefixed_module}\";\n") + set(_chunk "${_chunk} #if PY_MAJOR_VERSION < 3\n") + set(_chunk "${_chunk} return PyImport_AppendInittab(") + set(_chunk "${_chunk}name, init${_prefixed_module});\n") + set(_chunk "${_chunk} #else /* PY_MAJOR_VERSION >= 3 */\n") + set(_chunk "${_chunk} return PyImport_AppendInittab(") + set(_chunk "${_chunk}name, PyInit_${_prefixed_module});\n") + set(_chunk "${_chunk} #endif /* PY_MAJOR_VERSION >= 3 */\n") + set(_chunk "${_chunk}}\n\n") + file(APPEND ${generated_file_tmp} "${_chunk}") + endforeach() + + file(APPEND ${generated_file_tmp} + "void ${_header_name}_LoadAllPythonModules(void)\n{\n") + foreach(_module ${static_mod_list}) + file(APPEND ${generated_file_tmp} " ${_header_name}_${_module}();\n") + endforeach() + file(APPEND ${generated_file_tmp} "}\n\n") + + set(_chunk "") + set(_chunk "${_chunk}#ifndef EXCLUDE_LOAD_ALL_FUNCTION\n") + set(_chunk "${_chunk}void CMakeLoadAllPythonModules(void)\n") + set(_chunk "${_chunk}{\n") + set(_chunk "${_chunk} ${_header_name}_LoadAllPythonModules();\n") + set(_chunk "${_chunk}}\n") + set(_chunk "${_chunk}#endif /* !EXCLUDE_LOAD_ALL_FUNCTION */\n\n") + + set(_chunk "${_chunk}#ifndef EXCLUDE_PY_INIT_WRAPPER\n") + set(_chunk "${_chunk}static void Py_Initialize_Wrapper()\n") + set(_chunk "${_chunk}{\n") + set(_chunk "${_chunk} ${_header_name}_LoadAllPythonModules();\n") + set(_chunk "${_chunk} Py_Initialize();\n") + set(_chunk "${_chunk}}\n") + set(_chunk "${_chunk}#define Py_Initialize Py_Initialize_Wrapper\n") + set(_chunk "${_chunk}#endif /* !EXCLUDE_PY_INIT_WRAPPER */\n\n") + + set(_chunk "${_chunk}#endif /* !${_header_name_upper} */\n") + file(APPEND ${generated_file_tmp} "${_chunk}") + + # with configure_file() cmake complains that you may not use a file created + # using file(WRITE) as input file for configure_file() + execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${generated_file_tmp}" "${generated_file}" + OUTPUT_QUIET ERROR_QUIET) + + set(_header_output_var ${_name}) + if(_args_HEADER_OUTPUT_VAR) + set(_header_output_var ${_args_HEADER_OUTPUT_VAR}) + endif() + set(${_header_output_var} ${generated_file} PARENT_SCOPE) + + set(_include_dir_var ${_name}_INCLUDE_DIRS) + if(_args_INCLUDE_DIR_OUTPUT_VAR) + set(_include_dir_var ${_args_INCLUDE_DIR_OUTPUT_VAR}) + endif() + set(${_include_dirs_var} ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) +endfunction() + +include(UsePythonExtensions) diff --git a/cmake/Modules/SetCompileFlag.cmake b/cmake/Modules/SetCompileFlag.cmake new file mode 100644 index 00000000..69e3526f --- /dev/null +++ b/cmake/Modules/SetCompileFlag.cmake @@ -0,0 +1,125 @@ +# Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +############################################################################# +# Given a list of flags, this function will try each, one at a time, +# and choose the first flag that works. If no flags work, then nothing +# will be set, unless the REQUIRED key is given, in which case an error +# will be given. +# +# Call is: +# SET_COMPILE_FLAG(FLAGVAR FLAGVAL (Fortran|C|CXX) flag1 flag2...) +# +# For example, if you have the flag CMAKE_C_FLAGS and you want to add +# warnings and want to fail if this is not possible, you might call this +# function in this manner: +# SET_COMPILE_FLAGS(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" C REQUIRED +# "-Wall" # GNU +# "-warn all" # Intel +# ) +# The option "-Wall" will be checked first, and if it works, will be +# appended to the CMAKE_C_FLAGS variable. If it doesn't work, then +# "-warn all" will be tried. If this doesn't work then checking will +# terminate because REQUIRED was given. +# +# The reasoning that the variable must be given twice (first as the name then +# as the value in quotes) is because of the way CMAKE handles the passing +# of variables in functions; it is difficult to extract a variable's +# contents and assign new values to it from within a function. +############################################################################# + +INCLUDE(${CMAKE_ROOT}/Modules/CheckCCompilerFlag.cmake) +INCLUDE(${CMAKE_ROOT}/Modules/CheckCXXCompilerFlag.cmake) + +FUNCTION(SET_COMPILE_FLAG FLAGVAR FLAGVAL LANG) + + # Do some up front setup if Fortran + IF(LANG STREQUAL "Fortran") + # Create a list of error messages from compilers + SET(FAIL_REGEX + "ignoring unknown option" # Intel + "invalid argument" # Intel + "not supported" # Intel ifx + "unrecognized .*option" # GNU + "[Uu]nknown switch" # Portland Group + "ignoring unknown option" # MSVC + "warning D9002" # MSVC, any lang + "[Uu]nknown option" # HP + "[Ww]arning: [Oo]ption" # SunPro + "command option .* is not recognized" # XL + ) + ENDIF(LANG STREQUAL "Fortran") + + # Make a variable holding the flags. Filter out REQUIRED if it is there + SET(FLAG_REQUIRED FALSE) + SET(FLAG_FOUND FALSE) + UNSET(FLAGLIST) + FOREACH (var ${ARGN}) + STRING(TOUPPER "${var}" UP) + IF(UP STREQUAL "REQUIRED") + SET(FLAG_REQUIRED TRUE) + ELSE() + SET(FLAGLIST ${FLAGLIST} "${var}") + ENDIF(UP STREQUAL "REQUIRED") + ENDFOREACH (var ${ARGN}) + + # Now, loop over each flag + FOREACH(flag ${FLAGLIST}) + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E echo_append "Checking compiler option ${flag}: ") + UNSET(FLAG_WORKS) + # Check the flag for the given language + IF(LANG STREQUAL "C") + CHECK_C_COMPILER_FLAG("${flag}" FLAG_WORKS) + ELSEIF(LANG STREQUAL "CXX") + CHECK_CXX_COMPILER_FLAG("${flag}" FLAG_WORKS) + ELSEIF(LANG STREQUAL "Fortran") + # There is no nice function to do this for FORTRAN, so we must manually + # create a test program and check if it compiles with a given flag. + SET(TESTFILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}") + SET(TESTFILE "${TESTFILE}/CMakeTmp/testFortranFlags.f90") + FILE(WRITE "${TESTFILE}" +" +program dummyprog + i = 5 +end program dummyprog +") + TRY_COMPILE(FLAG_WORKS ${CMAKE_BINARY_DIR} ${TESTFILE} + COMPILE_DEFINITIONS "${flag}" OUTPUT_VARIABLE OUTPUT) + + # Check that the output message doesn't match any errors + FOREACH(rx ${FAIL_REGEX}) + IF("${OUTPUT}" MATCHES "${rx}") + SET(FLAG_WORKS FALSE) + ENDIF("${OUTPUT}" MATCHES "${rx}") + ENDFOREACH(rx ${FAIL_REGEX}) + + ELSE() + MESSAGE(FATAL_ERROR "Unknown language in SET_COMPILE_FLAGS: ${LANG}") + ENDIF(LANG STREQUAL "C") + + # If this worked, use these flags, otherwise use other flags + IF(FLAG_WORKS) + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E echo "OK") + # Append this flag to the end of the list that already exists + SET(${FLAGVAR} "${FLAGVAL} ${flag}" CACHE STRING + "Set the ${FLAGVAR} flags" FORCE) + SET(FLAG_FOUND TRUE) + BREAK() # We found something that works, so exit + ELSE(FLAG_WORKS) + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E echo "NO") + ENDIF(FLAG_WORKS) + + ENDFOREACH(flag ${FLAGLIST}) + + # Raise an error if no flag was found + IF(FLAG_REQUIRED AND NOT FLAG_FOUND) + MESSAGE(FATAL_ERROR "No compile flags were found") + ENDIF(FLAG_REQUIRED AND NOT FLAG_FOUND) + +ENDFUNCTION() diff --git a/cmake/Modules/SetFortranFlags.cmake b/cmake/Modules/SetFortranFlags.cmake new file mode 100644 index 00000000..c5514e74 --- /dev/null +++ b/cmake/Modules/SetFortranFlags.cmake @@ -0,0 +1,692 @@ +# Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +###################################################### +# Determine and set the Fortran compiler flags we want +###################################################### + +#################################################################### +# Make sure that the default build type is RELEASE if not specified. +#################################################################### +INCLUDE(SetCompileFlag) + +# Make sure the build type is uppercase +STRING(TOUPPER "${CMAKE_BUILD_TYPE}" BT) + +SET(BUILD_TYPE_MSG "Choose the type of build, options are DEBUG, RELEASE, PROFILE, or TESTING.") + +IF(BT STREQUAL "RELEASE") + SET(CMAKE_BUILD_TYPE RELEASE CACHE STRING + ${BUILD_TYPE_MSG} + FORCE) +ELSEIF(BT STREQUAL "DEBUG") + SET (CMAKE_BUILD_TYPE DEBUG CACHE STRING + ${BUILD_TYPE_MSG} + FORCE) +ELSEIF(BT STREQUAL "TESTING") + SET (CMAKE_BUILD_TYPE TESTING CACHE STRING + ${BUILD_TYPE_MSG} + FORCE) +ELSEIF(BT STREQUAL "PROFILE") + SET (CMAKE_BUILD_TYPE PROFILE CACHE STRING + ${BUILD_TYPE_MSG} + FORCE) +ELSEIF(NOT BT) + SET(CMAKE_BUILD_TYPE RELEASE CACHE STRING + ${BUILD_TYPE_MSG} + FORCE) + MESSAGE(STATUS "CMAKE_BUILD_TYPE not given, defaulting to RELEASE") +ELSE() + MESSAGE(FATAL_ERROR "CMAKE_BUILD_TYPE not valid! ${BUILD_TYPE_MSG}") +ENDIF(BT STREQUAL "RELEASE") + + +######################################################### +# If the compiler flags have already been set, return now +######################################################### + +IF(CMAKE_Fortran_FLAGS_RELEASE AND CMAKE_Fortran_FLAGS_TESTING AND CMAKE_Fortran_FLAGS_DEBUG AND CMAKE_Fortran_FLAGS_PROFILE ) + RETURN () +ENDIF(CMAKE_Fortran_FLAGS_RELEASE AND CMAKE_Fortran_FLAGS_TESTING AND CMAKE_Fortran_FLAGS_DEBUG AND CMAKE_Fortran_FLAGS_PROFILE) + +######################################################################## +# Determine the appropriate flags for this compiler for each build type. +# For each option type, a list of possible flags is given that work +# for various compilers. The first flag that works is chosen. +# If none of the flags work, nothing is added (unless the REQUIRED +# flag is given in the call). This way unknown compiles are supported. +####################################################################### + +IF (CMAKE_SYSTEM_NAME STREQUAL "Windows") + SET(WINOPT True) +ELSE () + SET(WINOPT False) +ENDIF () +##################### +### GENERAL FLAGS ### +##################### + + +# Free form +IF (COMPILER_OPTIONS STREQUAL "GNU") + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-ffree-form" # GNU + ) + + # Don't add underscores in symbols for C-compatability + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-fno-underscoring" # GNU + ) + # Compile code assuming that IEEE signaling NaNs may generate user-visible traps during floating-point operations. + # Setting this option disables optimizations that may change the number of exceptions visible with signaling NaNs. + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-fsignaling-nans " # GNU + ) + + # Allows for lines longer than 80 characters without truncation + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-ffree-line-length-512" # GNU (gfortran) + ) + + # Sets the dialect standard + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-std=f2018" + ) +ELSEIF (COMPILER_OPTIONS STREQUAL "Intel") + # Disables right margin wrapping in list-directed output + IF (WINOPT) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "/wrap-margin-" # Intel Windows + ) + # Aligns a variable to a specified boundary and offset + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "/align:all /align:array64byte" # Intel + ) + # Enables changing the variable and array memory layout + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "/Qpad" # Intel Windows + ) + ELSE () + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-no-wrap-margin" # Intel + ) + # Aligns a variable to a specified boundary and offset + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-align all -align array64byte" # Intel + ) + # Enables changing the variable and array memory layout + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-pad" # Intel Windows + ) + ENDIF () +ENDIF () + +IF (NOT BUILD_SHARED_LIBS AND NOT WINOPT) + SET_COMPILE_FLAG(CMAKE_FORTRAN_FLAGS "${CMAKE_FORTRAN_FLAGS}" + Fortran "-fPIC" + ) + + IF (COMPILER_OPTIONS STREQUAL "Intel") + # Use static Intel libraries + SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + Fortran "-static-intel" # Intel + ) + # Use static Intel MPI libraries + SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + Fortran "-static_mpi" # Intel + ) + + IF (USE_OPENMP) + SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + Fortran "-qopenmp-link=static" # Intel + ) + ENDIF (USE_OPENMP) + + ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + # # Set GNU static libraries + # SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + # Fortran "-static-libgfortran" + # ) + # SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + # Fortran "-static-libgcc" + # ) + # SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + # Fortran "-static-libstdc++" + # ) + # SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + # Fortran "-static-libquadmath" + # ) + IF (USE_OPENMP) + SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + Fortran "-lomp" + "-lgomp" + ) + ENDIF (USE_OPENMP) + ENDIF () +ENDIF () + +IF (USE_SIMD) + IF (COMPILER_OPTIONS STREQUAL "Intel") + SET(MACHINE_CODE_VALUE "Host" CACHE STRING "Tells the compiler which processor features it may target, including which instruction sets and optimizations it may generate.") + + IF (MACHINE_CODE_VALUE STREQUAL "generic") + SET(MACHINE_CODE_VALUE "SSE2" CACHE STRING "SSE2 is the safest option when compiling for non-host compatibility" FORCE) + ENDIF() + + # Enables OpenMP SIMD compilation when OpenMP parallelization is disabled. + IF (NOT USE_OPENMP) + IF (WINOPT) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "/Qopenmp- /Qopenmp-simd" # Intel + ) + ELSE () + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-qno-openmp -qopenmp-simd>" # Intel + ) + ENDIF () + ENDIF (NOT USE_OPENMP) + + # Optimize for an old enough processor that it should run on most computers + IF (WINOPT) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "/Qx${MACHINE_CODE_VALUE}" # Intel + ) + # Generate an extended set of vector functions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "/Qvecabi:cmdtarget" # Intel Windows + ) + ELSE () + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-x${MACHINE_CODE_VALUE}" # Intel + ) + # Generate an extended set of vector functions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-vecabi=cmdtarget" # Intel + ) + ENDIF () + + ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + SET(MACHINE_CODE_VALUE "native" CACHE STRING "Tells the compiler which processor features it may target, including which instruction sets and optimizations it may generate.") + + # Enables OpenMP SIMD compilation when OpenMP parallelization is disabled. + IF (NOT USE_OPENMP) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-fno-openmp -fopenmp-simd" # GNU + ) + ENDIF (NOT USE_OPENMP) + + IF (MACHINE_CODE_VALUE STREQUAL "Host") + SET(MACHINE_CODE_VALUE "native" CACHE STRING "native is the GNU equivalent of Host" FORCE) + ENDIF () + + IF (APPLE) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-mtune=${MACHINE_CODE_VALUE}" + ) + ELSE () + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-march=${MACHINE_CODE_VALUE}" + ) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-mtune=${MACHINE_CODE_VALUE}" + ) + ENDIF () + + ENDIF () + SET(MACHINE_CODE_VALUE ${MACHINE_CODE_VALUE} CACHE STRING "Tells the compiler which processor features it may target, including which instruction sets and optimizations it may generate.") +ENDIF (USE_SIMD) + + +################### +### DEBUG FLAGS ### +################### +IF (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "TESTING" ) + # Disable optimizations + IF (COMPILER_OPTIONS STREQUAL "Intel") + IF (WINOPT) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran REQUIRED "/Od" # Intel Windows + ) + + # Turn on all warnings + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/warn:all" # Intel Windows + ) + + # Tells the compiler to issue compile-time messages for nonstandard language elements (Fortran 2018). + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/stand:f18" # Intel Windows + ) + + # Traceback + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/traceback" # Intel Windows + ) + + # Check everything + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/check:all" # Intel Windows + ) + + # Initializes matrices/arrays with NaN values + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/Qinit:snan,arrays" # Intel Windows + ) + + # Does not generate an interface block for each routine in a source file + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/nogen-interfaces" # Intel Windows + ) + + # Does not set denormal results from floating-point calculations to zero + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/Qftz-" # Intel Windows + ) + + # Enables floating-point invalid, divide-by-zero, and overflow exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/fpe-all:0" # Intel Windows + ) + + # Enables floating-point invalid, divide-by-zero, and overflow exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/fpe:0" # Intel Windows + ) + + # Enables debug info + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/debug:all" # Intel Windows + ) + + # Disables additional interprocedural optimizations for a single file compilation + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/Qip-" # Intel Windows + ) + + # Disables prefetch insertion optimization + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/Qopt-prefetch-" # Intel Windows + ) + ELSE () + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran REQUIRED "-O0" # All compilers not on Windows + ) + + # Turn on all warnings + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-warn all" # Intel + ) + + # Tells the compiler to issue compile-time messages for nonstandard language elements (Fortran 2018). + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-stand f18" # Intel + ) + + # Traceback + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-traceback" # Intel Group + ) + + # Check everything + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-check all" # Intel + ) + + # Initializes matrices/arrays with NaN values + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-init=snan,arrays" # Intel + ) + + # Does not generate an interface block for each routine in a source file + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-nogen-interfaces" # Intel + ) + + # Does not generate aposition independent executable + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-no-pie" # Intel + ) + + # Does not set denormal results from floating-point calculations to zero + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-no-ftz" # Intel + ) + + # Enables floating-point invalid, divide-by-zero, and overflow exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fpe-all=0" # Intel + ) + + # Enables floating-point invalid, divide-by-zero, and overflow exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fpe0" # Intel + ) + + # Enables debug info + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-debug all" # Intel + ) + + # Disables additional interprocedural optimizations for a single file compilation + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-no-ip" # Intel + ) + + # Disables prefetch insertion optimization + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-qno-opt-prefetch" # Intel + ) + + ENDIF () + + ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran REQUIRED "-Og" # GNU (gfortran) + ) + + # Turn on all warnings + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-Wall" # GNU + ) + # This enables some extra warning flags that are not enabled by -Wall + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-Wextra" # GNU + ) + + # Disable the warning that arrays may be uninitialized, which comes up due to a known bug in gfortran + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-Wno-maybe-uninitialized" # GNU + ) + # Disable the warning about unused dummy arguments. These primarily occur due to interface rules for type-bound procedures used in extendable types. + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-Wno-unused-dummy-argument" # GNU + ) + + # Tells the compiler to issue compile-time messages for nonstandard language elements (Fortran 2018). + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fstd=f2018" # GNU + ) + + # Traceback + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fbacktrace" # GNU (gfortran) + ) + + # Sanitize + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fsanitize=address, undefined" # Gnu + ) + + # Check everything + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fcheck=all" # GNU + ) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fstack-check" # GNU + ) + + # Initializes matrices/arrays with NaN values + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-finit-real=snan" # GNU + ) + + # Generates non position-independent code + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fno-PIE" # GNU + ) + + # Enables floating-point invalid, divide-by-zero, and overflow exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-ffpe-trap=zero,overflow,underflow" # GNU + ) + + # List of floating-point exceptions, whose flag status is printed to ERROR_UNIT when invoking STOP and ERROR STOP + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-ffpe-summary=all" # GNU + ) + + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fstack-check" # GNU + ) + ENDIF () + +ENDIF () + +##################### +### TESTING FLAGS ### +##################### + +IF (CMAKE_BUILD_TYPE STREQUAL "TESTING" ) + + # Optimizations + IF (WINOPT) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_TESTING "${CMAKE_Fortran_FLAGS_DEBUG}" + REQUIRED "/O3" # Intel Windows + ) + ELSE () + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_TESTING "${CMAKE_Fortran_FLAGS_DEBUG}" + REQUIRED "-O3" # All compilers not on Windows + ) + ENDIF () +ENDIF () + +##################### +### RELEASE FLAGS ### +##################### +# NOTE: agressive optimizations (-O3) are already turned on by default + + +IF (CMAKE_BUILD_TYPE STREQUAL "RELEASE" OR CMAKE_BUILD_TYPE STREQUAL "PROFILE") + + IF (COMPILER_OPTIONS STREQUAL "Intel") + IF (WINOPT) + # Unroll loops + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/unroll" # Intel Windows + ) + + # Inline functions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/Qinline" # Intel Windows + ) + + # Calls the Matrix Multiply library + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/Qopt-matmul" # Intel Windows + ) + + # Aligns a variable to a specified boundary and offset + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/align:all" # Intel Windows + ) + + # No floating-point exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/fp:no-except" # Intel Windows + ) + + # Generate fused multiply-add instructions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/Qfma" # Intel Windows + ) + + # Tells the compiler to link to certain libraries in the Intel oneAPI Math Kernel Library (oneMKL). + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/Qmkl:cluster" # Intel Windows + "/Qmkl" # Intel Windows + ) + + # Enables additional interprocedural optimizations for a single file compilation + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/Qip" # Intel Windows + ) + ELSE () + # Unroll loops + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-unroll" # Intel + ) + + # Inline functions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-inline" # Intel + ) + + # Calls the Matrix Multiply library + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-qopt-matmul" # Intel + ) + + # Aligns a variable to a specified boundary and offset + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-align all" # Intel + ) + + # No floating-point exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-fp-model no-except" # Intel + ) + + # Generate fused multiply-add instructions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-fma" # Intel + ) + + # Tells the compiler to link to certain libraries in the Intel oneAPI Math Kernel Library (oneMKL). + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-qmkl=cluster" # Intel + "-qmkl" # Intel + ) + + # Enables additional interprocedural optimizations for a single file compilation + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-ip" # Intel + ) + ENDIF () + + ELSEIF(COMPILER_OPTIONS STREQUAL "GNU") + # Unroll loops + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-funroll-loops" # GNU + ) + + # Inline functions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-finline-functions" # GNU + ) + ENDIF () + +ENDIF () + +##################### +### MATH FLAGS ### +##################### +IF (COMPILER_OPTIONS STREQUAL "Intel") + + IF (WINOPT) + # Some subroutines require more strict floating point operation optimizations for repeatability + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "/fp:precise" # Intel Windows + ) + + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "/Qprec-div" # Intel Windows + ) + + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "/Qprec-sqrt" # Intel Windows + ) + + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "/assume:protect-parens" # Intel Windows + ) + + # Improves floating-point precision and consistency + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "/Qprec" # Intel Windows + ) + + # Most subroutines can use aggressive optimization of floating point operations without problems. + SET_COMPILE_FLAG(FASTMATH_FLAGS "${FASTMATH_FLAGS}" + Fortran "/fp:fast" # Intel Windows + ) + ELSE () + # Some subroutines require more strict floating point operation optimizations for repeatability + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "-fp-module=precise" # Intel + ) + + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "-prec-div" # Intel + ) + + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "-prec-sqrt" # Intel + ) + + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "-assume protect-parens" # Intel + ) + + # Improves floating-point precision and consistency + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "-mp1" # Intel Windows + ) + + # Most subroutines can use aggressive optimization of floating point operations without problems. + SET_COMPILE_FLAG(FASTMATH_FLAGS "${FASTMATH_FLAGS}" + Fortran "-fp-model=fast" # Intel Windows + ) + + ENDIF () + +ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + + # Some subroutines require more strict floating point operation optimizations for repeatability + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "-fno-unsafe-math-optimizations" # GNU + ) + # Disable transformations and optimizations that assume default floating-point rounding behavior. + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "-frounding-math" + ) + + # Most subroutines can use aggressive optimization of floating point operations without problems. + SET_COMPILE_FLAG(FASTMATH_FLAGS "${FASTMATH_FLAGS}" + Fortran "-ffast-math" # GNU + ) +ENDIF () + +# Debug mode always uses strict math +SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran ${STRICTMATH_FLAGS} +) + +##################### +### PROFILE FLAGS ### +##################### +IF (CMAKE_BUILD_TYPE STREQUAL "PROFILE") + + IF (COMPILER_OPTIONS STREQUAL "Intel") + # Enables the optimization reports to be generated + IF (WINOPT) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_PROFILE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/O2 /Qopt-report:5 /traceback /Z7" # Intel Windows + ) + ELSE () + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_PROFILE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-O2 -pg -qopt-report=5 -traceback -p -g3" # Intel + ) + ENDIF () + ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + # Enables the optimization reports to be generated + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_PROFILE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-O2 -pg -fbacktrace" # GNU + ) + ENDIF () +ENDIF () diff --git a/cmake/Modules/SetMKL.cmake b/cmake/Modules/SetMKL.cmake new file mode 100644 index 00000000..e58c9f51 --- /dev/null +++ b/cmake/Modules/SetMKL.cmake @@ -0,0 +1,14 @@ +# Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +# Find MKL if not already found +IF(NOT MKL_FOUND) + ENABLE_LANGUAGE(C) # Some libraries need a C compiler to find + FIND_PACKAGE(MKL REQUIRED) +ENDIF(NOT MKL_FOUND) diff --git a/cmake/Modules/SetParallelizationLibrary.cmake b/cmake/Modules/SetParallelizationLibrary.cmake new file mode 100644 index 00000000..505a77d6 --- /dev/null +++ b/cmake/Modules/SetParallelizationLibrary.cmake @@ -0,0 +1,36 @@ +# Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +IF (USE_OPENMP) + # Find OpenMP + IF (NOT OpenMP_Fortran_FLAGS) + FIND_PACKAGE (OpenMP_Fortran) + IF (NOT OpenMP_Fortran_FLAGS) + MESSAGE (FATAL_ERROR "Fortran compiler does not support OpenMP") + ENDIF (NOT OpenMP_Fortran_FLAGS) + ENDIF (NOT OpenMP_Fortran_FLAGS) +ENDIF (USE_OPENMP) + +IF (USE_COARRAY) + IF (NOT Coarray_Fortran_FLAGS) + FIND_PACKAGE (Coarray_Fortran) + IF (NOT Coarray_Fortran_FLAGS) + MESSAGE (FATAL_ERROR "Fortran compiler does not support Coarrays") + ENDIF (NOT Coarray_Fortran_FLAGS) + ENDIF (NOT Coarray_Fortran_FLAGS) +ENDIF (USE_COARRAY) + +IF (NOT USE_OPENMP AND NOT USE_COARRAY) + # Turn off both OpenMP and CAF + SET (OMP_NUM_PROCS 0 CACHE + STRING "Number of processors OpenMP may use" FORCE) + UNSET (OpenMP_Fortran_FLAGS CACHE) + UNSET (Coarray_Fortran_FLAGS CACHE) + UNSET (GOMP_Fortran_LINK_FLAGS CACHE) +ENDIF (NOT USE_OPENMP AND NOT USE_COARRAY) diff --git a/cmake/Modules/SetUpNetCDF.cmake b/cmake/Modules/SetUpNetCDF.cmake new file mode 100644 index 00000000..fad06d4f --- /dev/null +++ b/cmake/Modules/SetUpNetCDF.cmake @@ -0,0 +1,15 @@ +# Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +# Find NetCDF if not already found +IF(NOT NETCDF_FOUND) + ENABLE_LANGUAGE(C) # Some libraries need a C compiler to find + FIND_PACKAGE(NETCDF REQUIRED) +ENDIF(NOT NETCDF_FOUND) + diff --git a/cmake/Modules/UseCython.cmake b/cmake/Modules/UseCython.cmake new file mode 100644 index 00000000..4e0fa790 --- /dev/null +++ b/cmake/Modules/UseCython.cmake @@ -0,0 +1,383 @@ +#.rst: +# +# The following functions are defined: +# +# .. cmake:command:: add_cython_target +# +# Create a custom rule to generate the source code for a Python extension module +# using cython. +# +# add_cython_target( [] +# [EMBED_MAIN] +# [C | CXX] +# [PY2 | PY3] +# [OUTPUT_VAR ]) +# +# ```` is the name of the new target, and ```` +# is the path to a cython source file. Note that, despite the name, no new +# targets are created by this function. Instead, see ``OUTPUT_VAR`` for +# retrieving the path to the generated source for subsequent targets. +# +# If only ```` is provided, and it ends in the ".pyx" extension, then it +# is assumed to be the ````. The name of the input without the +# extension is used as the target name. If only ```` is provided, and it +# does not end in the ".pyx" extension, then the ```` is assumed to +# be ``.pyx``. +# +# The Cython include search path is amended with any entries found in the +# ``INCLUDE_DIRECTORIES`` property of the directory containing the +# ```` file. Use ``include_directories`` to add to the Cython +# include search path. +# +# Options: +# +# ``EMBED_MAIN`` +# Embed a main() function in the generated output (for stand-alone +# applications that initialize their own Python runtime). +# +# ``C | CXX`` +# Force the generation of either a C or C++ file. By default, a C file is +# generated, unless the C language is not enabled for the project; in this +# case, a C++ file is generated by default. +# +# ``PY2 | PY3`` +# Force compilation using either Python-2 or Python-3 syntax and code +# semantics. By default, Python-2 syntax and semantics are used if the major +# version of Python found is 2. Otherwise, Python-3 syntax and semantics are +# used. +# +# ``OUTPUT_VAR `` +# Set the variable ```` in the parent scope to the path to the +# generated source file. By default, ```` is used as the output +# variable name. +# +# Defined variables: +# +# ```` +# The path of the generated source file. +# +# Cache variables that affect the behavior include: +# +# ``CYTHON_ANNOTATE`` +# Whether to create an annotated .html file when compiling. +# +# ``CYTHON_FLAGS`` +# Additional flags to pass to the Cython compiler. +# +# Example usage +# ^^^^^^^^^^^^^ +# +# .. code-block:: cmake +# +# find_package(Cython) +# +# # Note: In this case, either one of these arguments may be omitted; their +# # value would have been inferred from that of the other. +# add_cython_target(cy_code cy_code.pyx) +# +# add_library(cy_code MODULE ${cy_code}) +# target_link_libraries(cy_code ...) +# +#============================================================================= +# Copyright 2011 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +# Configuration options. +set(CYTHON_ANNOTATE OFF + CACHE BOOL "Create an annotated .html file when compiling *.pyx.") + +set(CYTHON_FLAGS "" CACHE STRING + "Extra flags to the cython compiler.") +mark_as_advanced(CYTHON_ANNOTATE CYTHON_FLAGS) + +set(CYTHON_CXX_EXTENSION "cxx") +set(CYTHON_C_EXTENSION "c") + +get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES) + +function(add_cython_target _name) + set(options EMBED_MAIN C CXX PY2 PY3) + set(options1 OUTPUT_VAR) + cmake_parse_arguments(_args "${options}" "${options1}" "" ${ARGN}) + + list(GET _args_UNPARSED_ARGUMENTS 0 _arg0) + + # if provided, use _arg0 as the input file path + if(_arg0) + set(_source_file ${_arg0}) + + # otherwise, must determine source file from name, or vice versa + else() + get_filename_component(_name_ext "${_name}" EXT) + + # if extension provided, _name is the source file + if(_name_ext) + set(_source_file ${_name}) + get_filename_component(_name "${_source_file}" NAME_WE) + + # otherwise, assume the source file is ${_name}.pyx + else() + set(_source_file ${_name}.pyx) + endif() + endif() + + set(_embed_main FALSE) + + if("C" IN_LIST languages) + set(_output_syntax "C") + elseif("CXX" IN_LIST languages) + set(_output_syntax "CXX") + else() + message(FATAL_ERROR "Either C or CXX must be enabled to use Cython") + endif() + + if(_args_EMBED_MAIN) + set(_embed_main TRUE) + endif() + + if(_args_C) + set(_output_syntax "C") + endif() + + if(_args_CXX) + set(_output_syntax "CXX") + endif() + + # Doesn't select an input syntax - Cython + # defaults to 2 for Cython 2 and 3 for Cython 3 + set(_input_syntax "default") + + if(_args_PY2) + set(_input_syntax "PY2") + endif() + + if(_args_PY3) + set(_input_syntax "PY3") + endif() + + set(embed_arg "") + if(_embed_main) + set(embed_arg "--embed") + endif() + + set(cxx_arg "") + set(extension "c") + if(_output_syntax STREQUAL "CXX") + set(cxx_arg "--cplus") + set(extension "cxx") + endif() + + set(py_version_arg "") + if(_input_syntax STREQUAL "PY2") + set(py_version_arg "-2") + elseif(_input_syntax STREQUAL "PY3") + set(py_version_arg "-3") + endif() + + set(generated_file "${CMAKE_CURRENT_BINARY_DIR}/${_name}.${extension}") + set_source_files_properties(${generated_file} PROPERTIES GENERATED TRUE) + + set(_output_var ${_name}) + if(_args_OUTPUT_VAR) + set(_output_var ${_args_OUTPUT_VAR}) + endif() + set(${_output_var} ${generated_file} PARENT_SCOPE) + + file(RELATIVE_PATH generated_file_relative + ${CMAKE_BINARY_DIR} ${generated_file}) + + set(comment "Generating ${_output_syntax} source ${generated_file_relative}") + set(cython_include_directories "") + set(pxd_dependencies "") + set(c_header_dependencies "") + + # Get the include directories. + get_directory_property(cmake_include_directories + DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + INCLUDE_DIRECTORIES) + list(APPEND cython_include_directories ${cmake_include_directories}) + + # Determine dependencies. + # Add the pxd file with the same basename as the given pyx file. + get_source_file_property(pyx_location ${_source_file} LOCATION) + get_filename_component(pyx_path ${pyx_location} PATH) + get_filename_component(pyx_file_basename ${_source_file} NAME_WE) + unset(corresponding_pxd_file CACHE) + find_file(corresponding_pxd_file ${pyx_file_basename}.pxd + PATHS "${pyx_path}" ${cmake_include_directories} + NO_DEFAULT_PATH) + if(corresponding_pxd_file) + list(APPEND pxd_dependencies "${corresponding_pxd_file}") + endif() + + # pxd files to check for additional dependencies + set(pxds_to_check "${_source_file}" "${pxd_dependencies}") + set(pxds_checked "") + set(number_pxds_to_check 1) + while(number_pxds_to_check GREATER 0) + foreach(pxd ${pxds_to_check}) + list(APPEND pxds_checked "${pxd}") + list(REMOVE_ITEM pxds_to_check "${pxd}") + + # look for C headers + file(STRINGS "${pxd}" extern_from_statements + REGEX "cdef[ ]+extern[ ]+from.*$") + foreach(statement ${extern_from_statements}) + # Had trouble getting the quote in the regex + string(REGEX REPLACE + "cdef[ ]+extern[ ]+from[ ]+[\"]([^\"]+)[\"].*" "\\1" + header "${statement}") + unset(header_location CACHE) + find_file(header_location ${header} PATHS ${cmake_include_directories}) + if(header_location) + list(FIND c_header_dependencies "${header_location}" header_idx) + if(${header_idx} LESS 0) + list(APPEND c_header_dependencies "${header_location}") + endif() + endif() + endforeach() + + # check for pxd dependencies + # Look for cimport statements. + set(module_dependencies "") + file(STRINGS "${pxd}" cimport_statements REGEX cimport) + foreach(statement ${cimport_statements}) + if(${statement} MATCHES from) + string(REGEX REPLACE + "from[ ]+([^ ]+).*" "\\1" + module "${statement}") + else() + string(REGEX REPLACE + "cimport[ ]+([^ ]+).*" "\\1" + module "${statement}") + endif() + list(APPEND module_dependencies ${module}) + endforeach() + + # check for pxi dependencies + # Look for include statements. + set(include_dependencies "") + file(STRINGS "${pxd}" include_statements REGEX include) + foreach(statement ${include_statements}) + string(REGEX REPLACE + "include[ ]+[\"]([^\"]+)[\"].*" "\\1" + module "${statement}") + list(APPEND include_dependencies ${module}) + endforeach() + + list(REMOVE_DUPLICATES module_dependencies) + list(REMOVE_DUPLICATES include_dependencies) + + # Add modules to the files to check, if appropriate. + foreach(module ${module_dependencies}) + unset(pxd_location CACHE) + find_file(pxd_location ${module}.pxd + PATHS "${pyx_path}" ${cmake_include_directories} + NO_DEFAULT_PATH) + if(pxd_location) + list(FIND pxds_checked ${pxd_location} pxd_idx) + if(${pxd_idx} LESS 0) + list(FIND pxds_to_check ${pxd_location} pxd_idx) + if(${pxd_idx} LESS 0) + list(APPEND pxds_to_check ${pxd_location}) + list(APPEND pxd_dependencies ${pxd_location}) + endif() # if it is not already going to be checked + endif() # if it has not already been checked + endif() # if pxd file can be found + endforeach() # for each module dependency discovered + + # Add includes to the files to check, if appropriate. + foreach(_include ${include_dependencies}) + unset(pxi_location CACHE) + find_file(pxi_location ${_include} + PATHS "${pyx_path}" ${cmake_include_directories} + NO_DEFAULT_PATH) + if(pxi_location) + list(FIND pxds_checked ${pxi_location} pxd_idx) + if(${pxd_idx} LESS 0) + list(FIND pxds_to_check ${pxi_location} pxd_idx) + if(${pxd_idx} LESS 0) + list(APPEND pxds_to_check ${pxi_location}) + list(APPEND pxd_dependencies ${pxi_location}) + endif() # if it is not already going to be checked + endif() # if it has not already been checked + endif() # if include file can be found + endforeach() # for each include dependency discovered + endforeach() # for each include file to check + + list(LENGTH pxds_to_check number_pxds_to_check) + endwhile() + + # Set additional flags. + set(annotate_arg "") + if(CYTHON_ANNOTATE) + set(annotate_arg "--annotate") + endif() + + set(cython_debug_arg "") + set(line_directives_arg "") + if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR + CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + set(cython_debug_arg "--gdb") + set(line_directives_arg "--line-directives") + endif() + + # Include directory arguments. + list(REMOVE_DUPLICATES cython_include_directories) + set(include_directory_arg "") + foreach(_include_dir ${cython_include_directories}) + set(include_directory_arg + ${include_directory_arg} "--include-dir" "${_include_dir}") + endforeach() + + list(REMOVE_DUPLICATES pxd_dependencies) + list(REMOVE_DUPLICATES c_header_dependencies) + + string(REGEX REPLACE " " ";" CYTHON_FLAGS_LIST "${CYTHON_FLAGS}") + + # Add the command to run the compiler. + add_custom_command(OUTPUT ${generated_file} + COMMAND ${CYTHON_EXECUTABLE} + ARGS ${cxx_arg} ${include_directory_arg} ${py_version_arg} + ${embed_arg} ${annotate_arg} ${cython_debug_arg} + ${line_directives_arg} ${CYTHON_FLAGS_LIST} ${pyx_location} + --output-file ${generated_file} + DEPENDS ${_source_file} + ${pxd_dependencies} + IMPLICIT_DEPENDS ${_output_syntax} + ${c_header_dependencies} + COMMENT ${comment}) + + # NOTE(opadron): I thought about making a proper target, but after trying it + # out, I decided that it would be far too convenient to use the same name as + # the target for the extension module (e.g.: for single-file modules): + # + # ... + # add_cython_target(_module.pyx) + # add_library(_module ${_module}) + # ... + # + # The above example would not be possible since the "_module" target name + # would already be taken by the cython target. Since I can't think of a + # reason why someone would need the custom target instead of just using the + # generated file directly, I decided to leave this commented out. + # + # add_custom_target(${_name} DEPENDS ${generated_file}) + + # Remove their visibility to the user. + set(corresponding_pxd_file "" CACHE INTERNAL "") + set(header_location "" CACHE INTERNAL "") + set(pxd_location "" CACHE INTERNAL "") +endfunction() diff --git a/cmake/Modules/UsePythonExtensions.cmake b/cmake/Modules/UsePythonExtensions.cmake new file mode 100644 index 00000000..c411e20c --- /dev/null +++ b/cmake/Modules/UsePythonExtensions.cmake @@ -0,0 +1,320 @@ +#.rst: +# +# The following functions are defined: +# +# .. cmake:command:: add_python_library +# +# Add a library that contains a mix of C, C++, Fortran, Cython, F2PY, Template, +# and Tempita sources. The required targets are automatically generated to +# "lower" source files from their high-level representation to a file that the +# compiler can accept. +# +# +# add_python_library( +# SOURCES [source1 [source2 ...]] +# [INCLUDE_DIRECTORIES [dir1 [dir2 ...]] +# [LINK_LIBRARIES [lib1 [lib2 ...]] +# [DEPENDS [source1 [source2 ...]]]) +# +# +# Example usage +# ^^^^^^^^^^^^^ +# +# .. code-block:: cmake +# +# find_package(PythonExtensions) +# +# file(GLOB arpack_sources ARPACK/SRC/*.f ARPACK/UTIL/*.f) +# +# add_python_library(arpack_scipy +# SOURCES ${arpack_sources} +# ${g77_wrapper_sources} +# INCLUDE_DIRECTORIES ARPACK/SRC +# ) +# +# .. cmake:command:: add_python_extension +# +# Add a extension that contains a mix of C, C++, Fortran, Cython, F2PY, Template, +# and Tempita sources. The required targets are automatically generated to +# "lower" source files from their high-level representation to a file that the +# compiler can accept. +# +# +# add_python_extension( +# SOURCES [source1 [source2 ...]] +# [INCLUDE_DIRECTORIES [dir1 [dir2 ...]] +# [LINK_LIBRARIES [lib1 [lib2 ...]] +# [DEPENDS [source1 [source2 ...]]]) +# +# +# Example usage +# ^^^^^^^^^^^^^ +# +# .. code-block:: cmake +# +# find_package(PythonExtensions) +# +# file(GLOB arpack_sources ARPACK/SRC/*.f ARPACK/UTIL/*.f) +# +# add_python_extension(arpack_scipy +# SOURCES ${arpack_sources} +# ${g77_wrapper_sources} +# INCLUDE_DIRECTORIES ARPACK/SRC +# ) +# +# +#============================================================================= +# Copyright 2011 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +macro(_remove_whitespace _output) + string(REGEX REPLACE "[ \r\n\t]+" " " ${_output} "${${_output}}") + string(STRIP "${${_output}}" ${_output}) +endmacro() + +function(add_python_library _name) + set(options STATIC SHARED MODULE) + set(multiValueArgs SOURCES INCLUDE_DIRECTORIES LINK_LIBRARIES COMPILE_DEFINITIONS DEPENDS) + cmake_parse_arguments(_args "${options}" "" "${multiValueArgs}" ${ARGN} ) + + # Validate arguments to allow simpler debugging + if(NOT _args_SOURCES) + message( + FATAL_ERROR + "You have called add_python_library for library ${_name} without " + "any source files. This typically indicates a problem with " + "your CMakeLists.txt file" + ) + endif() + + # Initialize the list of sources + set(_sources ${_args_SOURCES}) + + # Generate targets for all *.src files + set(_processed ) + foreach(_source IN LISTS _sources) + if(${_source} MATCHES ".pyf.src$" OR ${_source} MATCHES "\\.f\\.src$") + if(NOT NumPy_FOUND) + message( + FATAL_ERROR + "NumPy is required to process *.src Template files" + ) + endif() + string(REGEX REPLACE "\\.[^.]*$" "" _source_we ${_source}) + add_custom_command( + OUTPUT ${_source_we} + COMMAND ${NumPy_FROM_TEMPLATE_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/${_source} + ${CMAKE_CURRENT_BINARY_DIR}/${_source_we} + DEPENDS ${_source} ${_args_DEPENDS} + COMMENT "Generating ${_source_we} from template ${_source}" + ) + list(APPEND _processed ${_source_we}) + elseif(${_source} MATCHES "\\.c\\.src$") + if(NOT NumPy_FOUND) + message( + FATAL_ERROR + "NumPy is required to process *.src Template files" + ) + endif() + string(REGEX REPLACE "\\.[^.]*$" "" _source_we ${_source}) + add_custom_command( + OUTPUT ${_source_we} + COMMAND ${NumPy_CONV_TEMPLATE_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/${_source} + ${CMAKE_CURRENT_BINARY_DIR}/${_source_we} + DEPENDS ${_source} ${_args_DEPENDS} + COMMENT "Generating ${_source_we} from template ${_source}" + ) + list(APPEND _processed ${_source_we}) + elseif(${_source} MATCHES "\\.pyx\\.in$") + if(NOT Cython_FOUND) + message( + FATAL_ERROR + "Cython is required to process *.in Tempita files" + ) + endif() + string(REGEX REPLACE "\\.[^.]*$" "" _source_we ${_source}) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/${_source} + ${CMAKE_CURRENT_BINARY_DIR}/${_source} + COPYONLY + ) + set(_tempita_command + " + import os; + import sys; + from Cython.Tempita import Template; + cwd = os.getcwd(); + open(os.path.join(cwd, '${_source_we}'), 'w+') + .write( + Template.from_filename(os.path.join(cwd, '${_source}'), + encoding=sys.getdefaultencoding()).substitute() + ) + " + ) + _remove_whitespace(_tempita_command) + add_custom_command( + OUTPUT ${_source_we} + COMMAND ${PYTHON_EXECUTABLE} -c "${_tempita_command}" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${_source}" + ${_args_DEPENDS} + ) + list(APPEND _processed ${_source_we}) + else() + list(APPEND _processed ${_source}) + endif() + endforeach() + set(_sources ${_processed}) + + # If we're building a Python extension and we're given only Fortran sources, + # We can conclude that we need to generate a Fortran interface file + list(FILTER _processed EXCLUDE REGEX "(\\.f|\\.f90)$") + if(NOT _processed AND _args_MODULE) + if(NOT NumPy_FOUND) + message( + FATAL_ERROR + "NumPy is required to process *.pyf F2PY files" + ) + endif() + set(_sources_abs ) + foreach(_source IN LISTS _sources) + if(NOT IS_ABSOLUTE ${_source}) + set(_source ${CMAKE_CURRENT_SOURCE_DIR}/${_source}) + endif() + list(APPEND _sources_abs ${_source}) + endforeach() + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name}.pyf + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${F2PY_EXECUTABLE} + ARGS -h ${_name}.pyf -m ${_name} --overwrite-signature + ${_sources_abs} + DEPENDS ${_sources} ${_args_DEPENDS} + COMMENT "Generating ${_name} Fortran interface file" + ) + list(APPEND _sources ${_name}.pyf) + endif() + + # Are there F2PY targets? + set(_has_f2py_targets OFF) + set(_has_cython_targets OFF) + + # Generate targets for all *.pyx and *.pyf files + set(_processed ) + foreach(_source IN LISTS _sources) + if(${_source} MATCHES \\.pyx$) + if(NOT Cython_FOUND) + message( + FATAL_ERROR + "Cython is required to process *.pyx Cython files" + ) + endif() + string(REGEX REPLACE "\\.[^.]*$" "" _pyx_target_name ${_source}) + set(_has_cython_targets ON) + add_cython_target(${_pyx_target_name} + ${_source} + OUTPUT_VAR _pyx_target_output + DEPENDS ${_args_DEPENDS} + ) + list(APPEND _processed ${_pyx_target_output}) + elseif(${_source} MATCHES \\.pyf$) + if(NOT NumPy_FOUND) + message( + FATAL_ERROR + "NumPy is required to process *.pyf F2PY files" + ) + endif() + string(REGEX REPLACE "\\.[^.]*$" "" _pyf_target_name ${_source}) + set(_has_f2py_targets ON) + add_f2py_target(${_pyf_target_name} + ${_source} + OUTPUT_VAR _pyf_target_output + DEPENDS ${_args_DEPENDS} + ) + list(APPEND _processed ${_pyf_target_output}) + else() + list(APPEND _processed ${_source}) + endif() + endforeach() + set(_sources ${_processed}) + + if(_args_SHARED) + add_library(${_name} SHARED ${_sources}) + elseif(_args_MODULE) + add_library(${_name} MODULE ${_sources}) + else() + # Assume static + add_library(${_name} STATIC ${_sources}) + endif() + + target_include_directories(${_name} PRIVATE ${_args_INCLUDE_DIRECTORIES}) + target_link_libraries(${_name} ${SKBUILD_LINK_LIBRARIES_KEYWORD} ${_args_LINK_LIBRARIES}) + + if(_has_f2py_targets) + target_include_directories(${_name} PRIVATE ${F2PY_INCLUDE_DIRS}) + target_link_libraries(${_name} ${SKBUILD_LINK_LIBRARIES_KEYWORD} ${F2PY_LIBRARIES}) + endif() + + if(_args_COMPILE_DEFINITIONS) + target_compile_definitions(${_name} PRIVATE ${_args_COMPILE_DEFINITIONS}) + endif() + + if(_args_DEPENDS) + add_custom_target( + "${_name}_depends" + DEPENDS ${_args_DEPENDS} + ) + add_dependencies(${_name} "${_name}_depends") + endif() +endfunction() + +function(add_python_extension _name) + # FIXME: make sure that extensions with the same name can happen + # in multiple directories + + set(multiValueArgs SOURCES INCLUDE_DIRECTORIES LINK_LIBRARIES COMPILE_DEFINITIONS DEPENDS) + cmake_parse_arguments(_args "" "" "${multiValueArgs}" ${ARGN} ) + + # Validate arguments to allow simpler debugging + if(NOT _args_SOURCES) + message( + FATAL_ERROR + "You have called add_python_extension for library ${_name} without " + "any source files. This typically indicates a problem with " + "your CMakeLists.txt file" + ) + endif() + + add_python_library(${_name} MODULE + SOURCES ${_args_SOURCES} + INCLUDE_DIRECTORIES ${_args_INCLUDE_DIRECTORIES} + LINK_LIBRARIES ${_args_LINK_LIBRARIES} + COMPILE_DEFINITIONS ${_args_COMPILE_DEFINITIONS} + DEPENDS ${_args_DEPENDS} + ) + python_extension_module(${_name}) + + file(RELATIVE_PATH _relative "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}") + if(_relative STREQUAL "") + set(_relative ".") + endif() + + install( + TARGETS ${_name} + LIBRARY DESTINATION "${_relative}" + RUNTIME DESTINATION "${_relative}" + ) +endfunction() diff --git a/cmake/Modules/targetLinkLibrariesWithDynamicLookup.cmake b/cmake/Modules/targetLinkLibrariesWithDynamicLookup.cmake new file mode 100644 index 00000000..a583f42c --- /dev/null +++ b/cmake/Modules/targetLinkLibrariesWithDynamicLookup.cmake @@ -0,0 +1,597 @@ +#.rst: +# +# Public Functions +# ^^^^^^^^^^^^^^^^ +# +# The following functions are defined: +# +# .. cmake:command:: target_link_libraries_with_dynamic_lookup +# +# :: +# +# target_link_libraries_with_dynamic_lookup( []) +# +# +# Useful to "weakly" link a loadable module. For example, it should be used +# when compiling a loadable module when the symbols should be resolve from +# the run-time environment where the module is loaded, and not a specific +# system library. +# +# Like proper linking, except that the given ```` are not necessarily +# linked. Instead, the ```` is produced in a manner that allows for +# symbols unresolved within it to be resolved at runtime, presumably by the +# given ````. If such a target can be produced, the provided +# ```` are not actually linked. +# +# It links a library to a target such that the symbols are resolved at +# run-time not link-time. +# +# The linker is checked to see if it supports undefined +# symbols when linking a shared library. If it does then the library +# is not linked when specified with this function. +# +# On platforms that do not support weak-linking, this function works just +# like ``target_link_libraries``. +# +# .. note:: +# +# For OSX it uses ``undefined dynamic_lookup``. This is similar to using +# ``-shared`` on Linux where undefined symbols are ignored. +# +# For more details, see `blog `_ +# from Tim D. Smith. +# +# +# .. cmake:command:: check_dynamic_lookup +# +# Check if the linker requires a command line flag to allow leaving symbols +# unresolved when producing a target of type ```` that is +# weakly-linked against a dependency of type ````. +# +# ```` +# can be one of "STATIC", "SHARED", "MODULE", or "EXE". +# +# ```` +# can be one of "STATIC", "SHARED", or "MODULE". +# +# Long signature: +# +# :: +# +# check_dynamic_lookup( +# +# +# []) +# +# +# Short signature: +# +# :: +# +# check_dynamic_lookup() # set to "MODULE" +# # set to "SHARED" +# +# +# The result is cached between invocations and recomputed only when the value +# of CMake's linker flag list changes; ``CMAKE_STATIC_LINKER_FLAGS`` if +# ```` is "STATIC", and ``CMAKE_SHARED_LINKER_FLAGS`` otherwise. +# +# +# Defined variables: +# +# ```` +# Whether the current C toolchain supports weak-linking for target binaries of +# type ```` that are weakly-linked against a dependency target of +# type ````. +# +# ```` +# List of flags to add to the linker command to produce a working target +# binary of type ```` that is weakly-linked against a dependency +# target of type ````. +# +# ``HAS_DYNAMIC_LOOKUP__`` +# Cached, global alias for ```` +# +# ``DYNAMIC_LOOKUP_FLAGS__`` +# Cached, global alias for ```` +# +# +# Private Functions +# ^^^^^^^^^^^^^^^^^ +# +# The following private functions are defined: +# +# .. warning:: These functions are not part of the scikit-build API. They +# exist purely as an implementation detail and may change from version +# to version without notice, or even be removed. +# +# We mean it. +# +# +# .. cmake:command:: _get_target_type +# +# :: +# +# _get_target_type( ) +# +# +# Shorthand for querying an abbreviated version of the target type +# of the given ````. +# +# ```` is set to: +# +# - "STATIC" for a STATIC_LIBRARY, +# - "SHARED" for a SHARED_LIBRARY, +# - "MODULE" for a MODULE_LIBRARY, +# - and "EXE" for an EXECUTABLE. +# +# Defined variables: +# +# ```` +# The abbreviated version of the ````'s type. +# +# +# .. cmake:command:: _test_weak_link_project +# +# :: +# +# _test_weak_link_project( +# +# +# ) +# +# +# Attempt to compile and run a test project where a target of type +# ```` is weakly-linked against a dependency of type ````: +# +# - ```` can be one of "STATIC", "SHARED", "MODULE", or "EXE". +# - ```` can be one of "STATIC", "SHARED", or "MODULE". +# +# Defined variables: +# +# ```` +# Whether the current C toolchain can produce a working target binary of type +# ```` that is weakly-linked against a dependency target of type +# ````. +# +# ```` +# List of flags to add to the linker command to produce a working target +# binary of type ```` that is weakly-linked against a dependency +# target of type ````. +# + +function(_get_target_type result_var target) + set(target_type "SHARED_LIBRARY") + if(TARGET ${target}) + get_property(target_type TARGET ${target} PROPERTY TYPE) + endif() + + set(result "STATIC") + + if(target_type STREQUAL "STATIC_LIBRARY") + set(result "STATIC") + endif() + + if(target_type STREQUAL "SHARED_LIBRARY") + set(result "SHARED") + endif() + + if(target_type STREQUAL "MODULE_LIBRARY") + set(result "MODULE") + endif() + + if(target_type STREQUAL "EXECUTABLE") + set(result "EXE") + endif() + + set(${result_var} ${result} PARENT_SCOPE) +endfunction() + + +function(_test_weak_link_project + target_type + lib_type + can_weak_link_var + project_name) + + set(gnu_ld_ignore "-Wl,--unresolved-symbols=ignore-all") + set(osx_dynamic_lookup "-undefined dynamic_lookup") + set(no_flag "") + + if(CMAKE_CROSSCOMPILING) + set(link_flag_spec "no_flag") + set(link_flag "${${link_flag_spec}}") + set(test_skipping_reason "") + set(test_pass FALSE) + + if(APPLE AND NOT CMAKE_CROSSCOMPILING_EMULATOR) + set(link_flag_spec "osx_dynamic_lookup") + set(link_flag "${${link_flag_spec}}") + set(test_skipping_reason " (Cross compiling without emulator on macOS)") + set(test_pass TRUE) + endif() + + if(test_pass) + set(test_description "Weak Link ${target_type} -> ${lib_type} (${link_flag_spec})") + message(STATUS "Performing Test ${test_description} - Assuming Success${test_skipping_reason}") + set(${can_weak_link_var} ${test_pass} PARENT_SCOPE) + set(${project_name} ${link_flag} PARENT_SCOPE) + return() + endif() + endif() + + foreach(link_flag_spec gnu_ld_ignore osx_dynamic_lookup no_flag) + set(link_flag "${${link_flag_spec}}") + + set(test_project_dir "${PROJECT_BINARY_DIR}/CMakeTmp") + set(test_project_dir "${test_project_dir}/${project_name}") + set(test_project_dir "${test_project_dir}/${link_flag_spec}") + set(test_project_dir "${test_project_dir}/${target_type}") + set(test_project_dir "${test_project_dir}/${lib_type}") + + set(test_project_src_dir "${test_project_dir}/src") + set(test_project_bin_dir "${test_project_dir}/build") + + file(MAKE_DIRECTORY ${test_project_src_dir}) + file(MAKE_DIRECTORY ${test_project_bin_dir}) + + set(mod_type "STATIC") + set(link_mod_lib TRUE) + set(link_exe_lib TRUE) + set(link_exe_mod FALSE) + + if("${target_type}" STREQUAL "EXE") + set(link_exe_lib FALSE) + set(link_exe_mod TRUE) + else() + set(mod_type "${target_type}") + endif() + + if("${mod_type}" STREQUAL "MODULE") + set(link_mod_lib FALSE) + endif() + + + file(WRITE "${test_project_src_dir}/CMakeLists.txt" " + cmake_minimum_required(VERSION ${CMAKE_VERSION}) + project(${project_name} C) + + include_directories(${test_project_src_dir}) + + add_library(number ${lib_type} number.c) + add_library(counter ${mod_type} counter.c) + ") + + if("${mod_type}" STREQUAL "MODULE") + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + set_target_properties(counter PROPERTIES PREFIX \"\") + ") + endif() + + if(link_mod_lib) + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + target_link_libraries(counter ${SKBUILD_LINK_LIBRARIES_KEYWORD} number) + ") + elseif(NOT link_flag STREQUAL "") + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + set_target_properties(counter PROPERTIES LINK_FLAGS \"${link_flag}\") + ") + endif() + + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + add_executable(main main.c) + ") + + if(link_exe_lib) + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + target_link_libraries(main ${SKBUILD_LINK_LIBRARIES_KEYWORD} number) + ") + elseif(NOT link_flag STREQUAL "") + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + target_link_libraries(main ${SKBUILD_LINK_LIBRARIES_KEYWORD} \"${link_flag}\") + ") + endif() + + if(link_exe_mod) + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + target_link_libraries(main ${SKBUILD_LINK_LIBRARIES_KEYWORD} counter) + ") + else() + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + target_link_libraries(main ${SKBUILD_LINK_LIBRARIES_KEYWORD} \"${CMAKE_DL_LIBS}\") + ") + endif() + + file(WRITE "${test_project_src_dir}/number.c" " + #include + + static int _number; + void set_number(int number) { _number = number; } + int get_number() { return _number; } + ") + + file(WRITE "${test_project_src_dir}/number.h" " + #ifndef _NUMBER_H + #define _NUMBER_H + extern void set_number(int); + extern int get_number(void); + #endif + ") + + file(WRITE "${test_project_src_dir}/counter.c" " + #include + int count() { + int result = get_number(); + set_number(result + 1); + return result; + } + ") + + file(WRITE "${test_project_src_dir}/counter.h" " + #ifndef _COUNTER_H + #define _COUNTER_H + extern int count(void); + #endif + ") + + file(WRITE "${test_project_src_dir}/main.c" " + #include + #include + #include + ") + + if(NOT link_exe_mod) + file(APPEND "${test_project_src_dir}/main.c" " + #include + ") + endif() + + file(APPEND "${test_project_src_dir}/main.c" " + int my_count() { + int result = get_number(); + set_number(result + 1); + return result; + } + + int main(int argc, char **argv) { + int result; + ") + + if(NOT link_exe_mod) + file(APPEND "${test_project_src_dir}/main.c" " + void *counter_module; + int (*count)(void); + + counter_module = dlopen(\"./counter.so\", RTLD_LAZY | RTLD_GLOBAL); + if(!counter_module) goto error; + + count = dlsym(counter_module, \"count\"); + if(!count) goto error; + ") + endif() + + file(APPEND "${test_project_src_dir}/main.c" " + result = count() != 0 ? EXIT_FAILURE : + my_count() != 1 ? EXIT_FAILURE : + my_count() != 2 ? EXIT_FAILURE : + count() != 3 ? EXIT_FAILURE : + count() != 4 ? EXIT_FAILURE : + count() != 5 ? EXIT_FAILURE : + my_count() != 6 ? EXIT_FAILURE : EXIT_SUCCESS; + ") + + if(NOT link_exe_mod) + file(APPEND "${test_project_src_dir}/main.c" " + goto done; + error: + fprintf(stderr, \"Error occurred:\\n %s\\n\", dlerror()); + result = 1; + + done: + if(counter_module) dlclose(counter_module); + ") + endif() + + file(APPEND "${test_project_src_dir}/main.c" " + return result; + } + ") + + set(_rpath_arg) + if(APPLE AND ${CMAKE_VERSION} VERSION_GREATER 2.8.11) + set(_rpath_arg "-DCMAKE_MACOSX_RPATH='${CMAKE_MACOSX_RPATH}'") + endif() + + try_compile(project_compiles + "${test_project_bin_dir}" + "${test_project_src_dir}" + "${project_name}" + CMAKE_FLAGS + "-DCMAKE_SHARED_LINKER_FLAGS='${CMAKE_SHARED_LINKER_FLAGS}'" + "-DCMAKE_ENABLE_EXPORTS=ON" + ${_rpath_arg} + OUTPUT_VARIABLE compile_output) + + set(project_works 1) + set(run_output) + + if(project_compiles) + execute_process(COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} + "${test_project_bin_dir}/main" + WORKING_DIRECTORY "${test_project_bin_dir}" + RESULT_VARIABLE project_works + OUTPUT_VARIABLE run_output + ERROR_VARIABLE run_output) + endif() + + set(test_description + "Weak Link ${target_type} -> ${lib_type} (${link_flag_spec})") + + if(project_works EQUAL 0) + set(project_works TRUE) + message(STATUS "Performing Test ${test_description} - Success") + else() + set(project_works FALSE) + message(STATUS "Performing Test ${test_description} - Failed") + file(APPEND ${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Performing Test ${test_description} failed with the " + "following output:\n" + "BUILD\n-----\n${compile_output}\nRUN\n---\n${run_output}\n") + endif() + + set(${can_weak_link_var} ${project_works} PARENT_SCOPE) + if(project_works) + set(${project_name} ${link_flag} PARENT_SCOPE) + break() + endif() + endforeach() +endfunction() + +function(check_dynamic_lookup) + # Two signatures are supported: + + if(ARGC EQUAL "1") + # + # check_dynamic_lookup() + # + set(target_type "MODULE") + set(lib_type "SHARED") + set(has_dynamic_lookup_var "${ARGV0}") + set(link_flags_var "unused") + + elseif(ARGC GREATER "2") + # + # check_dynamic_lookup( + # + # + # []) + # + set(target_type "${ARGV0}") + set(lib_type "${ARGV1}") + set(has_dynamic_lookup_var "${ARGV2}") + if(ARGC EQUAL "3") + set(link_flags_var "unused") + else() + set(link_flags_var "${ARGV3}") + endif() + else() + message(FATAL_ERROR "missing arguments") + endif() + + _check_dynamic_lookup( + ${target_type} + ${lib_type} + ${has_dynamic_lookup_var} + ${link_flags_var} + ) + set(${has_dynamic_lookup_var} ${${has_dynamic_lookup_var}} PARENT_SCOPE) + if(NOT "x${link_flags_var}x" STREQUAL "xunusedx") + set(${link_flags_var} ${${link_flags_var}} PARENT_SCOPE) + endif() +endfunction() + +function(_check_dynamic_lookup + target_type + lib_type + has_dynamic_lookup_var + link_flags_var + ) + + # hash the CMAKE_FLAGS passed and check cache to know if we need to rerun + if("${target_type}" STREQUAL "STATIC") + string(MD5 cmake_flags_hash "${CMAKE_STATIC_LINKER_FLAGS}") + else() + string(MD5 cmake_flags_hash "${CMAKE_SHARED_LINKER_FLAGS}") + endif() + + set(cache_var "HAS_DYNAMIC_LOOKUP_${target_type}_${lib_type}") + set(cache_hash_var "HAS_DYNAMIC_LOOKUP_${target_type}_${lib_type}_hash") + set(result_var "DYNAMIC_LOOKUP_FLAGS_${target_type}_${lib_type}") + + if( NOT DEFINED ${cache_hash_var} + OR NOT "${${cache_hash_var}}" STREQUAL "${cmake_flags_hash}") + unset(${cache_var} CACHE) + endif() + + if(NOT DEFINED ${cache_var}) + + if(CMAKE_CROSSCOMPILING AND NOT CMAKE_CROSSCOMPILING_EMULATOR) + set(skip_test TRUE) + endif() + + _test_weak_link_project(${target_type} + ${lib_type} + has_dynamic_lookup + link_flags) + + set(caveat " (when linking ${target_type} against ${lib_type})") + + set(${cache_var} "${has_dynamic_lookup}" + CACHE BOOL + "linker supports dynamic lookup for undefined symbols${caveat}") + mark_as_advanced(${cache_var}) + + set(${result_var} "${link_flags}" + CACHE STRING + "linker flags for dynamic lookup${caveat}") + mark_as_advanced(${result_var}) + + set(${cache_hash_var} "${cmake_flags_hash}" + CACHE INTERNAL "hashed flags for ${cache_var} check") + endif() + + set(${has_dynamic_lookup_var} "${${cache_var}}" PARENT_SCOPE) + set(${link_flags_var} "${${result_var}}" PARENT_SCOPE) +endfunction() + +function(target_link_libraries_with_dynamic_lookup target) + _get_target_type(target_type ${target}) + + set(link_props) + set(link_items) + set(link_libs) + + foreach(lib ${ARGN}) + _get_target_type(lib_type ${lib}) + check_dynamic_lookup(${target_type} + ${lib_type} + has_dynamic_lookup + dynamic_lookup_flags) + + if(has_dynamic_lookup) + if(dynamic_lookup_flags) + if("${target_type}" STREQUAL "EXE") + list(APPEND link_items "${dynamic_lookup_flags}") + else() + list(APPEND link_props "${dynamic_lookup_flags}") + endif() + endif() + elseif(${lib} MATCHES "(debug|optimized|general)") + # See gh-255 + else() + list(APPEND link_libs "${lib}") + endif() + endforeach() + + if(link_props) + list(REMOVE_DUPLICATES link_props) + endif() + + if(link_items) + list(REMOVE_DUPLICATES link_items) + endif() + + if(link_libs) + list(REMOVE_DUPLICATES link_libs) + endif() + + if(link_props) + set_target_properties(${target} + PROPERTIES LINK_FLAGS "${link_props}") + endif() + + set(links "${link_items}" "${link_libs}") + if(links) + target_link_libraries(${target} ${SKBUILD_LINK_LIBRARIES_KEYWORD} "${links}") + endif() +endfunction() diff --git a/ctem/ctem/NPF.py b/ctem/ctem/NPF.py new file mode 100644 index 00000000..cb7ee363 --- /dev/null +++ b/ctem/ctem/NPF.py @@ -0,0 +1,104 @@ +import numpy as np +# The Neukum production function +# Ivanov, Neukum, and Hartmann (2001) SSR v. 96 pp. 55-86 +def N1lunar(T): + return 5.44e-14 * (np.exp(6.93*T) - 1) + 8.38e-4 * T + + +def Nlunar(D): + # Lunar crater SFD + aL00 = -3.0876 + aL01 = -3.557528 + aL02 = 0.781027 + aL03 = 1.021521 + aL04 = -0.156012 + aL05 = -0.444058 + aL06 = 0.019977 + aL07 = 0.086850 + aL08 = -0.005874 + aL09 = -0.006809 + aL10 = 8.25e-4 + aL11 = 5.54e-5 + + return np.where((D > 0.01) & (D < 1000.0), + 10**(aL00 + + aL01 * np.log10(D) ** 1 + + aL02 * np.log10(D) ** 2 + + aL03 * np.log10(D) ** 3 + + aL04 * np.log10(D) ** 4 + + aL05 * np.log10(D) ** 5 + + aL06 * np.log10(D) ** 6 + + aL07 * np.log10(D) ** 7 + + aL08 * np.log10(D) ** 8 + + aL09 * np.log10(D) ** 9 + + aL10 * np.log10(D) ** 10 + + aL11 * np.log10(D) ** 11),float('nan')) + +def Rproj(D): + #Projectile SFD + aP00 = 0.0 + aP01 = -1.375458 + aP02 = 1.272521e-1 + aP03 = -1.282166 + aP04 = -3.074558e-1 + aP05 = 4.149280e-1 + aP06 = 1.910668e-1 + aP07 = -4.260980e-2 + aP08 = -3.976305e-2 + aP09 = -3.180179e-3 + aP10 = 2.799369e-3 + aP11 = 6.892223e-4 + aP12 = 2.614385e-6 + aP13 = -1.416178e-5 + aP14 = -1.191124e-6 + + return np.where((D > 1e-4) & (D < 300), + 10**(aP00 + + aP01 * np.log10(D)**1 + + aP02 * np.log10(D)**2 + + aP03 * np.log10(D)**3 + + aP04 * np.log10(D)**4 + + aP05 * np.log10(D)**5 + + aP06 * np.log10(D)**6 + + aP07 * np.log10(D)**7 + + aP08 * np.log10(D)**8 + + aP09 * np.log10(D)**9 + + aP10 * np.log10(D)**10 + + aP11 * np.log10(D)**11 + + aP12 * np.log10(D)**12 + + aP13 * np.log10(D)**13 + + aP14 * np.log10(D)**14),float('nan')) + +def N1mars(T): + # Mars crater SFD + # Ivanov (2001) SSR v. 96 pp. 87-104 + return 2.68e-14 * (np.exp(6.93 * T) - 1) + 4.13e-4 * T + +def Nmars(D): + aM00 = -3.384 + aM01 = -3.197 + aM02 = 1.257 + aM03 = 0.7915 + aM04 = -0.4861 + aM05 = -0.3630 + aM06 = 0.1016 + aM07 = 6.756e-2 + aM08 = -1.181e-2 + aM09 = -4.753e-3 + aM10 = 6.233e-4 + aM11 = 5.805e-5 + + return np.where((D > 0.01) & (D < 1000.), + 10**(aM00 + + aM01 * np.log10(D)**1 + + aM02 * np.log10(D)**2 + + aM03 * np.log10(D)**3 + + aM04 * np.log10(D)**4 + + aM05 * np.log10(D)**5 + + aM06 * np.log10(D)**6 + + aM07 * np.log10(D)**7 + + aM08 * np.log10(D)**8 + + aM09 * np.log10(D)**9 + + aM10 * np.log10(D)**10 + + aM11 * np.log10(D)**11), + np.full_like(D, np.nan)) diff --git a/ctem/ctem/__init__.py b/ctem/ctem/__init__.py new file mode 100644 index 00000000..2e8ce2a0 --- /dev/null +++ b/ctem/ctem/__init__.py @@ -0,0 +1 @@ +from ctem.driver import * \ No newline at end of file diff --git a/ctem/ctem/craterproduction.py b/ctem/ctem/craterproduction.py new file mode 100644 index 00000000..4d81b687 --- /dev/null +++ b/ctem/ctem/craterproduction.py @@ -0,0 +1,216 @@ +import numpy as np +from scipy import optimize + +# The Neukum production function for the Moon and Mars +#Lunar PF from: Ivanov, Neukum, and Hartmann (2001) SSR v. 96 pp. 55-86 +#Mars PF from: Ivanov (2001) SSR v. 96 pp. 87-104 +sfd_coef = { + "NPF_Moon" : [-3.0876,-3.557528,+0.781027,+1.021521,-0.156012,-0.444058,+0.019977,+0.086850,-0.005874,-0.006809,+8.25e-4, +5.54e-5], + "NPF_Mars" : [-3.384, -3.197, +1.257, +0.7915, -0.4861, -0.3630, +0.1016, +6.756e-2,-1.181e-2,-4.753e-3,+6.233e-4,+5.805e-5] + } +sfd_range = { + "NPF_Moon" : [0.01,1000], + "NPF_Mars" : [0.015,362] +} +#Exponential time constant (Ga) +tau = 6.93 +Nexp = 5.44e-14 + +time_coef = { + "NPF_Moon" : Nexp, + "NPF_Mars" : Nexp * 10**(sfd_coef.get("NPF_Mars")[0]) / 10**(sfd_coef.get("NPF_Moon")[0]) +} + +def N1(T, pfmodel): + """ + Return the N(1) value as a function of time for a particular production function model + + Parameters + ---------- + T : numpy array + Time in units of Ga + pfmodel : string + The production function model to use + Currently options are 'NPF_Moon' or 'NPF_Mars' + + Returns + ------- + N1 : numpy array + The number of craters per square kilometer greater than 1 km in diameter + """ + T_valid_range = np.where((T <= 4.5) & (T >= 0.0), T, np.nan) + return time_coef.get(pfmodel) * (np.exp(tau * T_valid_range) - 1.0) + 10 ** (sfd_coef.get(pfmodel)[0]) * T_valid_range + +def CSFD(Dkm,planet): + """ + Return the cumulative size-frequency distribution for a particular production function model + + Parameters + ---------- + Dkm : numpy array + Diameters in units of km + pfmodel : string + The production function model to use + Currently options are 'NPF_Moon' or 'NPF_Mars' + + Returns + ------- + CSFD : numpy array + The number of craters per square kilometer greater than Dkm in diameter at T=1 Ga + """ + logCSFD = sum(co * np.log10(Dkm) ** i for i, co in enumerate(sfd_coef.get(planet))) + return 10**(logCSFD) + +def DSFD(Dkm,planet): + """ + Return the differential size-frequency distribution for a particular production function model + + Parameters + ---------- + Dkm : numpy array + Diameters in units of km + pfmodel : string + The production function model to use + Currently options are 'NPF_Moon' or 'NPF_Mars' + + Returns + ------- + DSFD : numpy array + The differential number of craters (dN/dD) per square kilometer greater than Dkm in diameter at T = 1 Ga + """ + dcoef = sfd_coef.get(planet)[1:] + logDSFD = sum(co * np.log10(Dkm) ** i for i, co in enumerate(dcoef)) + return 10**(logDSFD) * CSFD(Dkm,planet) / Dkm + +def Tscale(T,planet): + """ + Return the number density of craters at time T relative to time T = 1 Ga + + Parameters + ---------- + T : numpy array + Time in units of Ga + pfmodel : string + The production function model to use + Currently options are 'NPF_Moon' or 'NPF_Mars' + + Returns + ------- + Tscale : numpy array + N1(T) / CSFD(Dkm = 1.0) + """ + return N1(T,planet) / CSFD(1.0,planet) + +def pf_csfd(T,Dkm,planet): + """ + Return the cumulative size-frequency distribution for a particular production function model as a function of Time + + Parameters + ---------- + T : numpy array + Time in units of Ga + Dkm : numpy array + Diameters in units of km + pfmodel : string + The production function model to use + Currently options are 'NPF_Moon' or 'NPF_Mars' + + Returns + ------- + pf_csfd : numpy array + The cumulative number of craters per square kilometer greater than Dkm in diameter at time T T + """ + D_valid_range = np.where((Dkm >= sfd_range.get(planet)[0]) & (Dkm <= sfd_range.get(planet)[1]),Dkm,np.nan) + return CSFD(D_valid_range,planet) * Tscale(T,planet) + +def pf_dsfd(T,Dkm,planet): + """ + Return the differential size-frequency distribution for a particular production function model as a function of Time + + Parameters + ---------- + T : numpy array + Time in units of Ga + Dkm : numpy array + Diameters in units of km + pfmodel : string + The production function model to use + Currently options are 'NPF_Moon' or 'NPF_Mars' + + Returns + ------- + pf_dsfd : numpy array + The cumulative number of craters per square kilometer greater than Dkm in diameter at time T T + """ + D_valid_range = np.where((Dkm >= sfd_range.get(planet)[0]) & (Dkm <= sfd_range.get(planet)[1]), Dkm, np.nan) + return DSFD(D_valid_range, planet) * Tscale(T, planet) + +def T_from_scale(TS,planet): + """ + Return the time in Ga for the given number density of craters relative to that at 1 Ga. + This is the inverse of Tscale + + Parameters + ---------- + TS : numpy array + number density of craters relative to that at 1 Ga + pfmodel : string + The production function model to use + Currently options are 'NPF_Moon' or 'NPF_Mars' + + Returns + ------- + T_from_scale : numpy array + The time in Ga + """ + def func(S): + return Tscale(S,planet) - TS + return optimize.fsolve(func, np.full_like(TS,4.4),xtol=1e-10) + + +if __name__ == "__main__": + import matplotlib.pyplot as plt + import matplotlib.ticker as ticker + print("Tests go here") + print(f"T = 1 Ga, N(1) = {pf_csfd(1.0,1.00,'NPF_Moon')}") + print(f"T = 4.2 Ga, N(1) = {pf_csfd(4.2,1.00,'NPF_Moon')}") + print("Tscale test: Should return all 1s") + Ttest = np.logspace(-4,np.log10(4.4),num=100) + Tres = T_from_scale(Tscale(Ttest,'NPF_Mars'),'NPF_Mars') + print(Ttest / Tres) + #for i,t in enumerate(Ttest): + # print(t,Tscale(t,'Moon'),Tres[i]) + + CSFDfig = plt.figure(1, figsize=(8, 7)) + ax = {'NPF_Moon': CSFDfig.add_subplot(121), + 'NPF_Mars': CSFDfig.add_subplot(122)} + + tvals = [0.01,1.0,4.0] + x_min = 1e-3 + x_max = 1e3 + y_min = 1e-9 + y_max = 1e3 + Dvals = np.logspace(np.log10(x_min), np.log10(x_max)) + for key in ax: + ax[key].title.set_text(key) + ax[key].set_xscale('log') + ax[key].set_yscale('log') + ax[key].set_ylabel('$\mathregular{N_{>D} (km^{-2})}$') + ax[key].set_xlabel('Diameter (km)') + ax[key].set_xlim(x_min, x_max) + ax[key].set_ylim(y_min, y_max) + ax[key].yaxis.set_major_locator(ticker.LogLocator(base=10.0, numticks=20)) + ax[key].yaxis.set_minor_locator(ticker.LogLocator(base=10.0, subs=np.arange(2,10), numticks=100)) + ax[key].xaxis.set_major_locator(ticker.LogLocator(base=10.0, numticks=20)) + ax[key].xaxis.set_minor_locator(ticker.LogLocator(base=10.0, subs=np.arange(2,10), numticks=100)) + ax[key].grid(True,which="minor",ls="-",lw=0.5,zorder=5) + ax[key].grid(True,which="major",ls="-",lw=1,zorder=10) + for t in tvals: + prod = pf_csfd(t,Dvals,key) + ax[key].plot(Dvals, prod, '-', color='black', linewidth=1.0, zorder=50) + labeli = 15 + ax[key].text(Dvals[labeli],prod[labeli],f"{t:.2f} Ga", ha="left", va="top",rotation=-72) + + plt.tick_params(axis='y', which='minor') + plt.tight_layout() + plt.show() diff --git a/ctem/ctem/driver.py b/ctem/ctem/driver.py new file mode 100644 index 00000000..0c9bd611 --- /dev/null +++ b/ctem/ctem/driver.py @@ -0,0 +1,380 @@ +import numpy as np +import os +import subprocess +import shutil +from ctem import util +import sys +import pandas +from ctem import craterproduction +from scipy.interpolate import interp1d +from ctem import __file__ as _pyfile +from pathlib import Path +import warnings + +class Simulation: + """ + This is a class that defines the basic CTEM simulation object. It initializes a dictionary of user and reads + it in from a file (default name is ctem.in). It also creates the directory structure needed to store simulation + files if necessary. + """ + def __init__(self, param_file="ctem.in", isnew=True): + currentdir = os.getcwd() + self.user = { + 'restart': None, + 'runtype': None, + 'popupconsole': None, + 'saveshaded': None, + 'saverego': None, + 'savetruelist': None, + 'seedn': 1, + 'totalimpacts': 0, + 'ncount': 0, + 'curyear': 0.0, + 'fracdone': 1.0, + 'masstot': 0.0, + 'interval': 0.0, + 'numintervals': 0, + 'pix': -1.0, + 'gridsize': -1, + 'seed': 0, + 'maxcrat': 1.0, + 'shadedminhdefault': 1, + 'shadedmaxhdefault': 1, + 'shadedminh': 0.0, + 'shadedmaxh': 0.0, + 'workingdir': currentdir, + 'ctemfile': param_file, + 'impfile': None, + 'sfdcompare': None, + 'quasimc': None, + 'sfdfile' : None, + 'realcraterlist': None, + } + + # Get the location of the CTEM executable + self.ctem_executable = Path(_pyfile).parent.parent.parent.parent / "build" / "src" / "CTEM" + if not self.ctem_executable.exists(): + print(f"CTEM driver not found at {self.ctem_executable}. Trying current directory.") + self.ctem_executable = Path(currentdir) / "CTEM" + if not self.ctem_executable.exists(): + warnings.warn(f"Cannot find the CTEM driver {str(self.ctem_executable)}", stacklevel=2) + self.ctem_executable = None + + + self.user = util.read_user_input(self.user) + + # This is containsall files generated by the main Fortran CTEM program plus the ctem.dat file that + # communicates the state of the simulation from the Python driver to the Fortran program + self.output_filenames = { + 'dat': 'ctem.dat', + 'dem': 'surface_dem.dat', + 'diam': 'surface_diam.dat', + 'ejc': 'surface_ejc.dat', + 'pos': 'surface_pos.dat', + 'time': 'surface_time.dat', + 'stack': 'surface_stacknum.dat', + 'rego': 'surface_rego.dat', + 'melt': 'surface_melt.dat', + 'comp': 'surface_comp.dat', + 'age' : 'surface_age.dat', + 'ocum': 'ocumulative.dat', + 'odist': 'odistribution.dat', + 'pdist': 'pdistribution.dat', + 'tcum' : 'tcumulative.dat', + 'tdist' : 'tdistribution.dat', + 'impmass' : 'impactmass.dat', + 'fracdone' : 'fracdone.dat', + 'regodepth' : 'regolithdepth.dat', + 'ejmax' : 'ejecta_table_max.dat', + 'ejmin' : 'ejecta_table_min.dat', + 'testprof' : 'testprofile.dat', + 'craterscale' : 'craterscale.dat', + 'craterlist' : 'craterlist.dat', + 'sfdfile' : 'production.dat', + 'distfrac' : 'surface_distfrac.dat', + 'ejm' : 'surface_ejm.dat', + 'ejmf' : 'surface_ejmf.dat', + 'meltdist' : 'surface_meltdist.dat', + 'meltfrac' : 'surface_meltfrac.dat' + } + if self.user['sfdfile'] is not None: # Override the default sfdfile name if the user supplies an alternative + self.output_filenames['sfdfile'] = self.user['sfdfile'] + + for k, v in self.output_filenames.items(): + self.output_filenames[k] = os.path.join(currentdir, v) + + self.directories = ['dist', 'misc', 'surf'] + if self.user['saveshaded'].upper() == 'T': + self.directories.append('shaded') + if self.user['saverego'].upper() == 'T': + self.directories.append('rego') + + # Set up data arrays + self.seedarr = np.zeros(100, dtype=int) + self.seedarr[0] = self.user['seed'] + self.odist = np.zeros([1, 6]) + self.pdist = np.zeros([1, 6]) + self.tdist = np.zeros([1, 6]) + self.surface_dem = np.zeros([self.user['gridsize'], self.user['gridsize']], dtype=float) + self.surface_ejc = np.zeros([self.user['gridsize'], self.user['gridsize']], dtype=float) + self.ph1 = None + + if self.user['sfdcompare'] is not None: + # Read sfdcompare file + sfdfile = os.path.join(self.user['workingdir'], self.user['sfdcompare']) + self.ph1 = util.read_formatted_ascii(sfdfile, skip_lines=0) + + + # If this is a new simulation, run and post-process results. Otherwise, don't do anything more + if isnew: + # Starting new or old run? + if (self.user['restart'].upper() == 'F'): + print('Starting a new run') + + util.create_dir_structure(self.user, self.directories) + # Delete any old output files + for k, v in self.output_filenames.items(): + if os.path.isfile(v): + os.remove(v) + + # Scale the production function to the simulation domain + self.scale_production() + + # Setup Quasi-MC run + + if (self.user['quasimc'] == 'T'): + + #Read list of real craters + print("quasi-MC mode is ON") + print("Generating the crater scaling data in CTEM") + rclist = util.read_formatted_ascii(self.user['realcraterlist'], skip_lines = 0) + tempfile = os.path.join(currentdir, 'temp.in') + + # Generate craterlist.dat + shutil.copy2(self.user['ctemfile'], tempfile ) + + #Write a temporary input file to generate the necessary quasimc files + util.write_temp_input(self.user, tempfile) + util.write_datfile(self.user, self.output_filenames['dat'], self.seedarr) + self.compute_one_interval(ctemin=tempfile) + os.remove(tempfile) + + #Interpolate craterscale.dat to get impactor sizes from crater sizes given + df = pandas.read_csv(self.output_filenames['craterscale'], sep='\s+') + df['log(Dc)'] = np.log(df['Dcrat(m)']) + df['log(Di)'] = np.log(df['#Dimp(m)']) + xnew = df['log(Dc)'].values + ynew = df['log(Di)'].values + interp = interp1d(xnew, ynew, fill_value='extrapolate') + rclist[:,0] = np.exp(interp(np.log(rclist[:,0]))) + + #Convert age in Ga to "interval time" + rclist[:,5] = (self.user['interval'] * self.user['numintervals']) - craterproduction.Tscale(rclist[:,5], 'NPF_Moon') + rclist = rclist[rclist[:,5].argsort()] + + #Export to dat file + util.write_realcraters(self.output_filenames['craterlist'], rclist) + + util.write_datfile(self.user, self.output_filenames['dat'], self.seedarr) + else: + print('Continuing a previous run') + self.read_output() + + return + + def scale_production(self): + """ + Scales the production function to the simulation domain and saves the scaled production function to a file that + will be read in by the main Fortran program. + """ + + # Read production function file + impfile = os.path.join(self.user['workingdir'], self.user['impfile']) + prodfunction = util.read_formatted_ascii(impfile, skip_lines=0) + + # Create impactor production population + area = (self.user['gridsize'] * self.user['pix']) ** 2 + self.production = np.copy(prodfunction) + self.production[:, 1] = self.production[:, 1] * area * self.user['interval'] + + # Write the scaled production function to file + util.write_production(self.output_filenames['sfdfile'], self.production) + + return + + def run(self): + """ + Runs a complete simulation over all intervals specified in the input user. This method loops over all + intervals and process outputs into images, and redirect output files to their apporpriate folders. + + This method replaces most of the functionality of the original ctem_driver.py + """ + + print('Beginning loops') + while (self.user['ncount'] <= self.user['numintervals']): + if (self.user['ncount'] > 0): + # Move ctem.dat + self.redirect_outputs(['dat'], 'misc') + + #Execute Fortran code + self.compute_one_interval(self.user['ctemfile']) + + # Read in output files + self.read_output() + + # Process the output files + self.process_output() + + # Update ncount + self.user['ncount'] = self.user['ncount'] + 1 + + if ((self.user['runtype'].upper() == 'STATISTICAL') or (self.user['ncount'] == 1)): # Reset the simulation + self.user['restart'] = 'F' + self.user['curyear'] = 0.0 + self.user['totalimpacts'] = 0 + self.user['masstot'] = 0.0 + + # Delete tdistribution file, if it exists so that we don't accumulate true craters in statistical mode + tdist_file = self.user['workingdir'] + 'tdistribution.dat' + if os.path.isfile(tdist_file): + os.remove(tdist_file) + + else: + self.user['restart'] = 'T' + + # Write ctem.dat file for next interval + util.write_datfile(self.user, self.output_filenames['dat'], self.seedarr) + + return + + def compute_one_interval(self, ctemin="ctem.in"): + """ + Executes the Fortran code to generate one interval of simulation output. + """ + # Create crater population and display CTEM progress on screen + print(self.user['ncount'], ' Calling FORTRAN routine') + try: + p = subprocess.Popen([os.path.join(self.user['workingdir'], self.ctem_executable), ctemin], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + shell=False) + for line in p.stdout: + if "%" in line: + print(line.replace('\n','\r'), end='') + else: + print(line,end='') + res = p.communicate() + if p.returncode != 0: + for line in res[1]: + print(line, end='') + raise Exception ("CTEM Failure") + except: + print("Error executing main CTEM program") + sys.exit() + + return + + def read_output(self): + """ + Reads in all of the files generated by the Fortran code after one interval and redirects them to appropriate + folders for storage after appending the interval number to the filename. + """ + # Read Fortran output + print(self.user['ncount'], ' Reading Fortran output') + + # Read surface dem(shaded relief) and ejecta data files + self.surface_dem = util.read_unformatted_binary(self.output_filenames['dem'], self.user['gridsize']) + self.surface_ejc = util.read_unformatted_binary(self.output_filenames['ejc'], self.user['gridsize']) + + # Read odistribution, tdistribution, and pdistribution files + self.odist = util.read_formatted_ascii(self.output_filenames['odist'], skip_lines=1) + self.tdist = util.read_formatted_ascii(self.output_filenames['tdist'], skip_lines=1) + self.pdist = util.read_formatted_ascii(self.output_filenames['pdist'], skip_lines=1) + + # Read impact mass from file + self.impact_mass = util.read_impact_mass(self.output_filenames['impmass']) + + # Read ctem.dat file + util.read_datfile(self.user, self.output_filenames['dat'], self.seedarr) + + + def process_output(self): + """ + Processes output to update masses, time, computes regolith depth, generates all plots, and redirects files + into intermediate storage. + """ + # Display results + print(self.user['ncount'], ' Generating surface images and plots') + + # Write surface dem, surface ejecta and shaded relief data + util.image_dem(self.user, self.surface_dem) + if (self.user['saverego'].upper() == 'T'): + util.image_regolith(self.user, self.surface_ejc) + if (self.user['saveshaded'].upper() == 'T'): + util.image_shaded_relief(self.user, self.surface_dem) + + if self.user['ncount'] > 0: # These aren't available yet from the initial conditions + + # Save copy of crater distribution files + # Update user: mass, curyear, regolith properties + self.user['masstot'] = self.user['masstot'] + self.impact_mass + + self.user['curyear'] = self.user['curyear'] + self.user['fracdone'] * self.user['interval'] + template = "%(fracdone)9.6f %(curyear)19.12E\n" + with open(self.output_filenames['fracdone'], 'w') as fp_frac: + fp_frac.write(template % self.user) + + reg_text = "%19.12E %19.12E %19.12E %19.12E\n" % (self.user['curyear'], + np.mean(self.surface_ejc), np.amax(self.surface_ejc), + np.amin(self.surface_ejc)) + with open(self.output_filenames['regodepth'], 'w') as fp_reg: + fp_reg.write(reg_text) + # Redirect output files to storage + self.redirect_outputs(['odist', 'ocum', 'pdist', 'tdist'], 'dist') + if (self.user['savetruelist'].upper() == 'T'): + self.redirect_outputs(['tcum'], 'dist') + self.redirect_outputs(['impmass'], 'misc') + if (self.user['saverego'].upper() == 'T') : + self.redirect_outputs(['stack','rego','age','melt','comp','ejm','meltdist'], 'rego') + + + + def redirect_outputs(self, filekeys, foldername): + """ + Copies a set of output files from the working directory into a subfolder. + Takes as input the dictionaries of user parameters and output file names, the dictionary keys to the file names + you wish to redirect, and the redirection destination folder name. The new name will be the key name + zero padded + interval number. + + Example: + calling redirect_outputs(['odist','tdist'], 'dist') when user['ncount'] is 1 + should do the following: + copy 'odistribution.dat' to 'dist/odist_000001.dat' + copy 'tdistribution.dat' to 'dist/tdist_000001.dat' + """ + + for k in filekeys: + forig = self.output_filenames[k] + fdest = os.path.join(self.user['workingdir'], foldername, f"{k}_{self.user['ncount']:06d}.dat") + shutil.copy2(forig, fdest) + + def cleanup(self): + """ + Deletes all files and folders generated by CTEM. + """ + # This is a list of files generated by the main Fortran program + print("Deleting all files generated by CTEM") + util.destroy_dir_structure(self.user, self.directories) + for key, filename in self.output_filenames.items(): + print(f"Deleting file {filename}") + try: + os.remove(filename) + except OSError as error: + print(error) + + return + +if __name__ == '__main__': + sim = Simulation() + sim.run() \ No newline at end of file diff --git a/ctem/ctem/util.py b/ctem/ctem/util.py new file mode 100644 index 00000000..00922421 --- /dev/null +++ b/ctem/ctem/util.py @@ -0,0 +1,443 @@ +import numpy as np +import os +import shutil +from matplotlib.colors import LightSource +import matplotlib.cm as cm +import matplotlib.pyplot as plt +import re +from tempfile import mkstemp +from scipy.io import FortranFile + +# Set pixel scaling common for image writing, at 1 pixel/ array element +dpi = 72.0 +class CTEMLightSource(LightSource): + """ + Override one function in LightSource to prevent the contrast from being rescaled. + """ + def shade_normals(self, normals, fraction=1.): + """ + Calculate the illumination intensity for the normal vectors of a + surface using the defined azimuth and elevation for the light source. + + Imagine an artificial sun placed at infinity in some azimuth and + elevation position illuminating our surface. The parts of the surface + that slope toward the sun should brighten while those sides facing away + should become darker. + + Changes by David Minton: The matplotlib version of this rescales the intensity + in a way that causes the brightness level of the images to change between + simulation outputs. This makes movies of the surface evolution appear to flicker. + + Parameters + ---------- + fraction : number, optional + Increases or decreases the contrast of the hillshade. Values + greater than one will cause intermediate values to move closer to + full illumination or shadow (and clipping any values that move + beyond 0 or 1). Note that this is not visually or mathematically + the same as vertical exaggeration. + + Returns + ------- + ndarray + A 2D array of illumination values between 0-1, where 0 is + completely in shadow and 1 is completely illuminated. + """ + + intensity = normals.dot(self.direction) + + # Apply contrast stretch + imin, imax = intensity.min(), intensity.max() + intensity *= fraction + + # Rescale to 0-1, keeping range before contrast stretch + # If constant slope, keep relative scaling (i.e. flat should be 0.5, + # fully occluded 0, etc.) + # if (imax - imin) > 1e-6: + # # Strictly speaking, this is incorrect. Negative values should be + # # clipped to 0 because they're fully occluded. However, rescaling + # # in this manner is consistent with the previous implementation and + # # visually appears better than a "hard" clip. + # intensity -= imin + # intensity /= (imax - imin) + intensity = np.clip(intensity, 0, 1) + + return intensity + + + +# These are directories that are created by CTEM in order to store intermediate results + +def create_dir_structure(user, directories): + """ + Create directories for various output files if they do not already exist + """ + + for dirname in directories: + dirpath = os.path.join(user['workingdir'], dirname) + if not os.path.isdir(dirpath): + print(f"Creating directory {dirpath}") + os.makedirs(dirpath) + + return + +def destroy_dir_structure(user, directories): + """ + Deletes directories generated by create_dir_structure + """ + for dirname in directories: + dirpath = os.path.join(user['workingdir'], dirname) + if os.path.isdir(dirpath): + print(f"Deleting directory {dirpath}") + shutil.rmtree(dirpath, ignore_errors=True) + + return + +def image_dem(user, DEM): + dpi = 300.0 # 72.0 + pix = user['pix'] + gridsize = user['gridsize'] + ve = 1.0 + azimuth = 300.0 # user['azimuth'] + solar_angle = 20.0 # user['solar_angle'] + + ls = CTEMLightSource(azdeg=azimuth, altdeg=solar_angle) + dem_img = ls.hillshade(np.flip(DEM,axis=0), vert_exag=ve, dx=pix, dy=pix, fraction=1) + + # Generate image to put into an array + height = gridsize / dpi + width = gridsize / dpi + fig = plt.figure(figsize=(width, height), dpi=dpi) + ax = plt.axes([0, 0, 1, 1]) + ax.imshow(dem_img, interpolation="nearest", cmap='gray', vmin=0.0, vmax=1.0) + plt.axis('off') + # Save image to file + filename = os.path.join(user['workingdir'],'surf',"surf%06d.png" % user['ncount']) + plt.savefig(filename, dpi=dpi, bbox_inches=0) + plt.close() + + return + + +def image_regolith(user, regolith): + # Create scaled regolith image + minref = user['pix'] * 1.0e-4 + maxreg = np.amax(regolith) + minreg = np.amin(regolith) + if (minreg < minref): minreg = minref + if (maxreg < minref): maxreg = (minref + 1.0e3) + regolith_scaled = np.copy(regolith) + np.place(regolith_scaled, regolith_scaled < minref, minref) + regolith_scaled = 254.0 * ( + (np.log(regolith_scaled) - np.log(minreg)) / (np.log(maxreg) - np.log(minreg))) + + # Save image to file + filename = os.path.join(user['workingdir'],'rego', "rego%06d.png" % user['ncount']) + height = user['gridsize'] / dpi + width = height + fig = plt.figure(figsize=(width, height), dpi=dpi) + fig.figimage(regolith_scaled, cmap=cm.nipy_spectral, origin='lower') + plt.savefig(filename) + plt.close() + + return + + +def image_shaded_relief(user, DEM): + dpi = 300.0 # 72.0 + pix = user['pix'] + gridsize = user['gridsize'] + ve = 1.0 + mode = 'overlay' + azimuth = 300.0 # user['azimuth'] + solar_angle = 20.0 # user['solar_angle'] + + ls = CTEMLightSource(azdeg=azimuth, altdeg=solar_angle) + cmap = cm.cividis + + # If min and max appear to be reversed, then fix them + if (user['shadedminh'] > user['shadedmaxh']): + temp = user['shadedminh'] + user['shadedminh'] = user['shadedmaxh'] + user['shadedmaxh'] = temp + else: + user['shadedminh'] = user['shadedminh'] + user['shadedmaxh'] = user['shadedmaxh'] + + # If no shadedmin/max user are read in from ctem.dat, determine the values from the data + if (user['shadedminhdefault'] == 1): + shadedminh = np.amin(DEM) + else: + shadedminh = user['shadedminh'] + if (user['shadedmaxhdefault'] == 1): + shadedmaxh = np.amax(DEM) + else: + shadedmaxh = user['shadedmaxh'] + + dem_img = ls.shade(np.flip(DEM,axis=0), cmap=cmap, blend_mode=mode, fraction=1.0, + vert_exag=ve, dx=pix, dy=pix, + vmin=shadedminh, vmax=shadedmaxh) + + # Generate image to put into an array + height = gridsize / dpi + width = gridsize / dpi + fig = plt.figure(figsize=(width, height), dpi=dpi) + ax = plt.axes([0, 0, 1, 1]) + ax.imshow(dem_img, interpolation="nearest", vmin=0.0, vmax=1.0) + plt.axis('off') + # Save image to file + filename = os.path.join(user['workingdir'],'shaded',"shaded%06d.png" % user['ncount']) + plt.savefig(filename, dpi=dpi, bbox_inches=0) + plt.close() + + return user + + +def read_datfile(user, datfile, seedarr): + # Read and parse ctem.dat file + + # Read ctem.dat file + print('Reading input file ' + datfile) + fp = open(datfile, 'r') + lines = fp.readlines() + fp.close() + + # Parse file lines and update parameter fields + fields = lines[0].split() + if len(fields) > 0: + user['totalimpacts'] = real2float(fields[0]) + user['ncount'] = int(fields[1]) + user['curyear'] = real2float(fields[2]) + user['restart'] = fields[3] + user['fracdone'] = real2float(fields[4]) + user['masstot'] = real2float(fields[5]) + + # Parse remainder of file to build seed array + nlines = len(lines) + index = 1 + while (index < nlines): + fields = lines[index].split() + seedarr[index - 1] = real2float(fields[0]) + index += 1 + + user['seedn'] = index - 1 + + return + + +def read_formatted_ascii(filename, skip_lines): + # Generalized ascii text reader + # For use with sfdcompare, production, odist, tdist, pdist data files + try: + data = np.genfromtxt(filename, skip_header=skip_lines) + except: + print(f"Error reading {filename}") + data = None + return data + + +def read_impact_mass(filename): + # Read impact mass file + + fp = open(filename, 'r') + line = fp.readlines() + fp.close() + + fields = line[0].split() + if (len(fields) > 0): + mass = real2float(fields[0]) + else: + mass = 0 + + return mass + + +# Write production function to file production.dat +# This file format does not exactly match that generated from IDL. Does it work? +def read_user_input(user): + # Read and parse ctem.in file + inputfile = user['ctemfile'] + + # Read ctem.in file + print('Reading input file ' + user['ctemfile']) + with open(inputfile, 'r') as fp: + lines = fp.readlines() + + # Process file text + for line in lines: + fields = line.split() + if len(fields) > 0: + if ('pix' == fields[0].lower()): user['pix'] = real2float(fields[1]) + if ('gridsize' == fields[0].lower()): user['gridsize'] = int(fields[1]) + if ('seed' == fields[0].lower()): user['seed'] = int(fields[1]) + if ('sfdfile' == fields[0].lower()): user['sfdfile'] = os.path.join(user['workingdir'],fields[1]) + if ('impfile' == fields[0].lower()): user['impfile'] = os.path.join(user['workingdir'],fields[1]) + if ('maxcrat' == fields[0].lower()): user['maxcrat'] = real2float(fields[1]) + if ('sfdcompare' == fields[0].lower()): user['sfdcompare'] = os.path.join(user['workingdir'], fields[1]) + if ('realcraterlist' == fields[0].lower()): user['realcraterlist'] = os.path.join(user['workingdir'], fields[1]) + if ('interval' == fields[0].lower()): user['interval'] = real2float(fields[1]) + if ('numintervals' == fields[0].lower()): user['numintervals'] = int(fields[1]) + if ('popupconsole' == fields[0].lower()): user['popupconsole'] = fields[1] + if ('saveshaded' == fields[0].lower()): user['saveshaded'] = fields[1] + if ('saverego' == fields[0].lower()): user['saverego'] = fields[1] + if ('savepres' == fields[0].lower()): user['savepres'] = fields[1] + if ('savetruelist' == fields[0].lower()): user['savetruelist'] = fields[1] + if ('runtype' == fields[0].lower()): user['runtype'] = fields[1] + if ('restart' == fields[0].lower()): user['restart'] = fields[1] + if ('quasimc' == fields[0].lower()): user['quasimc'] = fields[1] + if ('shadedminh' == fields[0].lower()): + user['shadedminh'] = real2float(fields[1]) + user['shadedminhdefault'] = 0 + if ('shadedmaxh' == fields[0].lower()): + user['shadedmaxh'] = real2float(fields[1]) + user['shadedmaxhdefault'] = 0 + + # Test values for further processing + if (user['interval'] <= 0.0): + print('Invalid value for or missing variable INTERVAL in ' + inputfile) + if (user['numintervals'] <= 0): + print('Invalid value for or missing variable NUMINTERVALS in ' + inputfile) + if (user['pix'] <= 0.0): + print('Invalid value for or missing variable PIX in ' + inputfile) + if (user['gridsize'] <= 0): + print('Invalid value for or missing variable GRIDSIZE in ' + inputfile) + if (user['seed'] == 0): + print('Invalid value for or missing variable SEED in ' + inputfile) + if (user['impfile'] is None): + print('Invalid value for or missing variable IMPFILE in ' + inputfile) + if (user['popupconsole'] is None): + print('Invalid value for or missing variable POPUPCONSOLE in ' + inputfile) + if (user['saveshaded'] is None): + print('Invalid value for or missing variable SAVESHADED in ' + inputfile) + if (user['saverego'] is None): + print('Invalid value for or missing variable SAVEREGO in ' + inputfile) + if (user['savepres'] is None): + print('Invalid value for or missing variable SAVEPRES in ' + inputfile) + if (user['savetruelist'] is None): + print('Invalid value for or missing variable SAVETRUELIST in ' + inputfile) + if (user['runtype'] is None): + print('Invalid value for or missing variable RUNTYPE in ' + inputfile) + if (user['restart'] is None): + print('Invalid value for or missing variable RESTART in ' + inputfile) + + return user + + +def read_unformatted_binary(filename, gridsize, kind='DP'): + # Read unformatted binary files created by Fortran + # For use with surface ejecta and surface dem data files + if kind == 'DP': + dt = np.dtype('f8') + elif kind == 'SP': + dt = np.dtype('f4') + elif kind == 'I4B': + dt = np.dtype(' count: + break + + fout.writelines(fin.readlines()) + + + fin.close() + fout.close() + + shutil.move(name, source) + + return + +def write_datfile(user, filename, seedarr): + # Write various user and random number seeds into ctem.dat file + fp = open(filename, 'w') + + template = "%(totalimpacts)17d %(ncount)12d %(curyear)19.12E %(restart)s %(fracdone)9.6f %(masstot)19.12E\n" + fp.write(template % user) + + # Write random number seeds to the file + for index in range(user['seedn']): + fp.write("%12d\n" % seedarr[index]) + + fp.close() + + return + + +def write_production(filename, production): + np.savetxt(filename, production, fmt='%1.8e', delimiter=' ') + + return + + +def write_realcraters(filename, realcraters): + """Writes file of real craters for use in quasi-MC runs""" + + np.savetxt(filename, realcraters, fmt='%1.8e', delimiter='\t') + + return + +def write_temp_input(user, filename): + """Makes changes to a temporary input file for use when generating craterlist.dat for quasimc runs""" + + sed('testflag', 'testflag T!', filename) + sed('testimp', f'testimp {user["pix"]*1e-3} !', filename) # Make a tiny test crater. We don't care about the crater itself, just that we run CTEM once to get all of the converted files + sed('quasimc', 'quasimc F!', filename) + sed('interval', 'interval 1 !', filename) + sed('numinterval 1 !s', 'numintervals 1 !', filename) + + return \ No newline at end of file diff --git a/ctem/ctem/viewer3d.py b/ctem/ctem/viewer3d.py new file mode 100644 index 00000000..8aacf84e --- /dev/null +++ b/ctem/ctem/viewer3d.py @@ -0,0 +1,124 @@ +import numpy as np +import open3d +import ctem + +class Polysurface(ctem.Simulation): + """A model of a self-gravitating small body""" + def __init__(self): + ctem.Simulation.__init__(self, isnew=False) # Initialize the data structures, but doesn't start a new run + self.read_output() + #used for Open3d module + self.mesh = open3d.geometry.TriangleMesh() + return + + def ctem2blockmesh(self): + # Build mesh grid + s = self.user['gridsize'] + pix = self.user['pix'] + ygrid, xgrid = np.mgrid[-s/2:s/2, -s/2:s/2] * pix + y0, x0 = ygrid - pix/2, xgrid - pix/2 + y1, x1 = ygrid - pix/2, xgrid + pix/2 + y2, x2 = ygrid + pix/2, xgrid + pix/2 + y3, x3 = ygrid + pix/2, xgrid - pix/2 + + xvals = np.append( + np.append( + np.append(x0.flatten(), + x1.flatten()), + x2.flatten()), + x3.flatten()) + yvals = np.append( + np.append( + np.append(y0.flatten(), + y1.flatten()), + y2.flatten()), + y3.flatten()) + zvals = np.append( + np.append( + np.append(self.surface_dem.flatten(), + self.surface_dem.flatten()), + self.surface_dem.flatten()), + self.surface_dem.flatten()) + verts = np.array((xvals, yvals, zvals)).T + nface_triangles = 10 + faces = np.full([nface_triangles*s**2, 3], -1, dtype=np.int64) + for j in range(s): + for i in range(s): + i0 = s*j + i + i1 = i0 + s**2 + i2 = i1 + s**2 + i3 = i2 + s**2 + + fidx = np.arange(nface_triangles*i0,nface_triangles*(i0+1)) + # Make the two top triangles + faces[fidx[0],:] = [i0, i1, i2] + faces[fidx[1],:] = [i0, i2, i3] + # Make the two west side triangles + if i > 0: + faces[fidx[2],:] = [i0, i3, i2-1] + faces[fidx[3],:] = [i0, i2-1, i1-1] + # Make the two south side triangles + if j > 0: + faces[fidx[4],:] = [i1, i0, i3-s ] + faces[fidx[5],:] = [i1, i3-s, i2-s] + # Make the two east side triangles + if i < (s - 1): + faces[fidx[6],:] = [i2, i1, i0+1] + faces[fidx[7],:] = [i2, i0+1, i3+1] + #Make the two north side triangles + if j < (s -1): + faces[fidx[8],:] = [i3, i2, i1+s] + faces[fidx[9],:] = [i3, i1+s, i0+s] + nz = faces[:,0] != -1 + f2 = faces[nz,:] + self.mesh.vertices = open3d.utility.Vector3dVector(verts) + self.mesh.triangles = open3d.utility.Vector3iVector(f2) + self.mesh.compute_vertex_normals() + self.mesh.compute_triangle_normals() + + return + + def ctem2trimesh(self): + # Build mesh grid + s = self.user['gridsize'] + pix = self.user['pix'] + ygrid, xgrid = np.mgrid[-s/2:s/2, -s/2:s/2] * pix + + xvals = xgrid.flatten() + yvals = ygrid.flatten() + zvals = self.surface_dem.flatten() + verts = np.array((xvals, yvals, zvals)).T + faces = np.full([2 * (s-1)**2, 3], -1, dtype=np.int64) + for j in range(s - 1): + for i in range(s - 1): + idx = (s - 1) * j + i + faces[idx, :] = [j * s + i, j * s + i + 1, (j + 1) * s + i + 1] + idx += (s - 1) ** 2 + faces[idx, :] = [(j + 1) * s + i + 1, (j + 1) * s + i, j * s + i ] + self.mesh.vertices = open3d.utility.Vector3dVector(verts) + self.mesh.triangles = open3d.utility.Vector3iVector(faces) + self.mesh.compute_vertex_normals() + self.mesh.compute_triangle_normals() + + return + + def visualize(self): + vis = open3d.visualization.Visualizer() + vis.create_window() + vis.add_geometry(self.mesh) + opt = vis.get_render_option() + opt.background_color = np.asarray([0, 0, 0]) + + self.mesh.paint_uniform_color([0.5, 0.5, 0.5]) + vis.run() + vis.destroy_window() + + +if __name__ == '__main__': + sim = Polysurface() + sim.surface_dem *= 10 + sim.ctem2trimesh() + sim.visualize() + + + diff --git a/ctem/readme.txt b/ctem/readme.txt new file mode 100644 index 00000000..4a127168 --- /dev/null +++ b/ctem/readme.txt @@ -0,0 +1,22 @@ +1) Install a distribution of Python 2.x to your machine. This source code + has been tested on Anaconda Python 4.1.1. + +2) Insure required modules are installed: + numpy + os + scipy + shutil + subprocess + +3) Place the .py files in this directory into the directory you wish + to execute from, with the required initialization files. For this, + the IDL directory may be copied, and ctem.in replaced by the one found + in this directory. + +4) Inside Anaconda Python, the program can be run through the Spyder2 GUI. + Outside of Anaconda, the progam can be begun by configuring the ctem.in + file, then typing + + python < ctem_driver.py + + at the command line. diff --git a/ctem/setup.py b/ctem/setup.py new file mode 100644 index 00000000..f7003601 --- /dev/null +++ b/ctem/setup.py @@ -0,0 +1,6 @@ +from setuptools import setup, find_packages + +setup(name='ctem', + version='0.1', + author='David A. Minton', + packages=find_packages()) diff --git a/distclean.cmake b/distclean.cmake new file mode 100644 index 00000000..e6b7f7a8 --- /dev/null +++ b/distclean.cmake @@ -0,0 +1,82 @@ +# Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +# This CMake script will delete build directories and files to bring the +# package back to it's distribution state + +# We want to start from the top of the source dir, so if we are in build +# we want to start one directory up +GET_FILENAME_COMPONENT(BASEDIR ${CMAKE_SOURCE_DIR} NAME) +IF(${BASEDIR} STREQUAL "build") + SET(TOPDIR "${CMAKE_SOURCE_DIR}/..") +ELSE() + SET(TOPDIR "${CMAKE_SOURCE_DIR}") +ENDIF() + +SET(CIBW_DIR "_skbuild" "ctem.egg-info" "_cmake_test_compile") + +MACRO(GET_PARENT_DIRECTORIES search_string return_list grandparents) + FILE(GLOB_RECURSE new_list ${search_string}) + SET(dir_list "") + FOREACH(file_path ${new_list}) + GET_FILENAME_COMPONENT(dir_path ${file_path} PATH) + # Remove an extra directory component to return grandparent + IF(${grandparents}) + # Tack on a fake extension to trick CMake into removing a second + # path component + SET(dir_path "${dir_path}.tmp") + GET_FILENAME_COMPONENT(dir_path ${dir_path} PATH) + ENDIF(${grandparents}) + SET(dir_list ${dir_list} ${dir_path}) + ENDFOREACH() + LIST(REMOVE_DUPLICATES dir_list) + SET(${return_list} ${dir_list}) +ENDMACRO() + +# Find directories and files that we will want to remove +FILE(GLOB_RECURSE CMAKECACHE "${TOPDIR}/*CMakeCache.txt") +FILE(GLOB_RECURSE CMAKEINSTALL "${TOPDIR}/*cmake_install.cmake" + "${TOPDIR}/*install_manifest.txt") +FILE(GLOB_RECURSE MAKEFILE "${TOPDIR}/*Makefile") +FILE(GLOB_RECURSE CMAKETESTFILES "${TOPDIR}/*CTestTestfile.cmake") +SET(TOPDIRECTORIES "${TOPDIR}/lib" + "${TOPDIR}/libexec" + "${TOPDIR}/bin" + "${TOPDIR}/include" + "${TOPDIR}/share" +) + +# CMake has trouble finding directories recursively, so locate these +# files and then save the parent directory of the files +GET_PARENT_DIRECTORIES(Makefile.cmake CMAKEFILES 0) +GET_PARENT_DIRECTORIES(LastTest.log CMAKETESTING 1) + +# Place these files and directories into a list +SET(DEL ${TOPDIRECTORIES} + ${CMAKECACHE} + ${CMAKEINSTALL} + ${MAKEFILE} + ${CMAKEFILES} + ${CMAKETESTING} + ${CMAKETESTFILES} + ${CIBW_DIR} +) + +# If we are not in the build dir, delete that as well +IF(NOT (${BASEDIR} STREQUAL "build")) + FILE(GLOB BUILD "${TOPDIR}/build") + SET(DEL ${DEL} ${BUILD}) +ENDIF() + +# Loop over the directories and delete each one +FOREACH(D ${DEL}) + IF(EXISTS ${D}) + FILE(REMOVE_RECURSE ${D}) + ENDIF() +ENDFOREACH() diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 00000000..8dd22f64 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,20 @@ +*.jpg +*.png +surface_* +*cumulative.dat +testprofile.dat +production.dat +*dist*.dat +ejecta_*.dat +ctem.dat +output_psd.txt +rego*.dat +impactmass.dat +fracdone.dat +craterscale.dat +avgkdiff.dat +craterlist.dat +*_0*.dat +ctem_io_readers.py +ctem_io_writers.py +*.DS_Store \ No newline at end of file diff --git a/examples/global-lunar-bombardment/.gitignore b/examples/global-lunar-bombardment/.gitignore index 4778e90c..e69de29b 100644 --- a/examples/global-lunar-bombardment/.gitignore +++ b/examples/global-lunar-bombardment/.gitignore @@ -1,5 +0,0 @@ -*.jpg -*.png -*.out -surface_* -temp.in diff --git a/examples/global-lunar-bombardment/CTEM b/examples/global-lunar-bombardment/CTEM new file mode 120000 index 00000000..604970bd --- /dev/null +++ b/examples/global-lunar-bombardment/CTEM @@ -0,0 +1 @@ +../../build/src/CTEM \ No newline at end of file diff --git a/examples/global-lunar-bombardment/ctem_driver.pro b/examples/global-lunar-bombardment/ctem_driver.pro deleted file mode 100755 index 071af0f7..00000000 --- a/examples/global-lunar-bombardment/ctem_driver.pro +++ /dev/null @@ -1,233 +0,0 @@ -pro ctem_driver - -;------------------------------------------------------------------------- -; Jim Richardson, Arecibo Observatory -; David Minton, Purdue University Dept. of Earth, Atmospheric, & Planetary Sciences -; July 2014 -; Cratered Terrain Evolution Model display module -; -; Inputs are read in from the ctem.in file -; -;------------------------------------------------------------------------- -;------------- Initial Setup ---------------- -;------------------------------------------------------------------------- -Compile_Opt DEFINT32 -!EXCEPT=2 - -; ----------- input file ----------------------- -infilename = 'ctem.in' -DATFILE='ctem.dat' - -; ---------- reading input files ---------- -seedarr = lon64arr(100) -seedn = 1 -totalimpacts = long64(0) -ncount = long64(0) -curyear = 0.d0 -restart = "F" -fracdone = 1.0d0 -masstot = 0.d0 - -ctem_io_read_input,infilename,interval,numintervals,gridsize,pix,seed,numlayers,sfdfile,impfile,maxcrat,ph1,shadedmaxhdefault,shadedminhdefault,shadedminh,shadedmaxh,restart,runtype,popupconsole,saveshaded,saverego,savepres,savetruelist - -seedarr(0) = seed -area = (gridsize * pix)^2 - -;read input data -pnum = file_lines(impfile) -production = dblarr(2,pnum) -productionfunction = dblarr(2,pnum) -openr,LUN,impfile,/GET_LUN -readf,LUN,productionfunction -free_lun,LUN - -;create impactor production population -production(0,*) = productionfunction(0,*) -production(1,*) = productionfunction(1,*)*area*interval - -;write out corrected production population -openw,1,sfdfile -printf,1,production -close,1 -free_lun,1 - -;set up cratering surface grid and display-only grid -surface_dem = dblarr(gridsize,gridsize) -regolith = dblarr(gridsize,gridsize) - -;set up temporary distribution bins -distl = 1 -pdistl = 1 -odist = dblarr(6,distl) -tdist = dblarr(6,distl) -pdist = dblarr(6,pdistl) -pdisttotal = dblarr(6,pdistl) - -datformat = "(I17,1X,I12,1X,E19.12,1X,A1,1X,F9.6,1X,E19.12)" - - -if strmatch(restart,'F',/fold_case) then begin ; Start with a clean slate - print, 'Starting a new run' - curyear = 0.0d0 - totalimpacts = 0 - masstot = 0.d0 - fracdone = 1.0d0 - - if strmatch(runtype,'statistical',/fold_case) then begin - ncount = 1 - openw,LUN,DATFILE,/GET_LUN - printf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - for n=0,seedn-1 do begin - printf,LUN,seedarr(n),format='(I12)' - endfor - free_lun,LUN - endif else begin - ncount = 0 - endelse - - surface_dem(*,*) = 0.0d0 - regolith(*,*) = 0.0d0 - - file_delete, 'tdistribution.dat',/allow_nonexistent - -endif else begin ; continue an old run - print, 'Continuing a previous run' - - ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass - - ;read in constants file - openr,LUN,DATFILE,/GET_LUN - readf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - seedn = 0 - while ~ eof(LUN) do begin - readf,LUN,iseed - seedarr(seedn) = long64(iseed) - seedn=seedn+1 - endwhile - -endelse - -openw,FRACDONEFILE,'fracdone.dat',/GET_LUN -openw,REGODEPTHFILE,'regolithdepth.dat',/GET_LUN - -;------------------------------------------------------------------------- -; ---------- begin loops ---------- -;------------------------------------------------------------------------- -print, 'Beginning loops' - -;define number of loop iterations and begin -;numintervals=ceil(endyear/interval)-ncount -while (ncount le numintervals) do begin - - - ; ---------- creating crater population ---------- - if (ncount gt 0) then begin - - fnum = string(ncount,format='(I6.6)') - if (file_test('misc',/DIRECTORY) eq 0) then begin - file_mkdir,'misc' - endif - ; save a copy of the ctem.dat file - fname = 'misc/ctem_' + fnum + '.dat' - file_copy, 'ctem.dat', fname, /OVERWRITE - - print, ncount, ' Calling FORTRAN routine' - ;call fortran program to create & count craters - spawn, './CTEM',/noshell - - ; ---------- reading FORTRAN output ---------- - print, ncount, ' Reading FORTRAN output' - ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass - - ;read in constants file - openr,LUN,DATFILE,/GET_LUN - readf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - seedn = 0 - while ~ eof(LUN) do begin - readf,LUN,iseed - seedarr(seedn) = long64(iseed) - seedn = seedn + 1 - endwhile - free_lun,LUN - - curyear = curyear + fracdone * interval - masstot = masstot + mass - printf,FRACDONEFILE,fracdone,curyear - flush,FRACDONEFILE - - printf,REGODEPTHFILE,curyear,mean(regolith),max(regolith),min(regolith) - flush,REGODEPTHFILE - - ;save a copy of the binned observed crater distribution - if (file_test('dist',/DIRECTORY) eq 0) then begin - file_mkdir,'dist' - endif - fname = 'dist/odist_' + fnum + '.dat' - file_copy, 'odistribution.dat', fname, /OVERWRITE - - ; save a copy of the cumulative observed crater distribution - fname = 'dist/ocum_' + fnum + '.dat' - file_copy, 'ocumulative.dat', fname, /OVERWRITE - - ;save a copy of the binned true distribution - fname = 'dist/tdist_' + fnum + '.dat' - file_copy, 'tdistribution.dat', fname, /OVERWRITE - - ;save a copy of the binned idealized production function - fname = 'dist/pdist_' + fnum + '.dat' - file_copy, 'pdistribution.dat', fname, /OVERWRITE - - ; save a copy of the cumulative true crater distribution if the user requests it - if strmatch(savetruelist,'T',/fold_case) then begin - fname = 'dist/tcum_' + fnum + '.dat' - file_copy, 'tcumulative.dat', fname, /OVERWRITE - endif - - ; save a copy of the impacted mass - fname = 'misc/mass_' + fnum + '.dat' - file_copy, 'impactmass.dat', fname, /OVERWRITE - - - endif - - ; Get the accumulated production function - pdisttotal = pdist - pdisttotal(3:5,*) = pdist(3:5,*) * curyear / interval - - ; ---------- displaying results ---------- - print, ncount, ' Displaying results' - - ctem_image_dem,ncount,gridsize,pix,surface_dem,surface_dem_image - if strmatch(saverego,'T',/fold_case) then ctem_image_regolith,ncount,gridsize,pix,regolith,regolith_image - if strmatch(saveshaded,'T',/fold_case) then begin - if (shadedminhdefault eq 1) then shadedminh = min(surface_dem) - if (shadedmaxhdefault eq 1) then shadedmaxh = max(surface_dem) - ctem_image_shaded_relief,ncount,gridsize,pix,surface_dem,surface_dem,shadedminh,shadedmaxh,'shaded',shaded_image - endif - if strmatch(savepres,'T',/fold_case) then ctem_image_presentation,ncount,gridsize,pix,curyear,odist,pdisttotal,tdist,ph1,surface_dem_image - ctem_window_display,ncount,totalimpacts,gridsize,pix,curyear,masstot,odist,pdisttotal,tdist,ph1,surface_dem,regolith,surface_dem_image,popupconsole - - ncount = ncount + 1 - - ;write out the current data file - if (strmatch(runtype,'statistical',/fold_case)) || (ncount eq 1) then begin - restart = 'F' - curyear = 0.0d0 - totalimpacts = 0 - masstot = 0.d0 - file_delete, 'tdistribution.dat',/allow_nonexistent - endif else begin - restart = 'T' - endelse - - openw,LUN,DATFILE,/GET_LUN - printf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - for n=0,seedn-1 do begin - printf,LUN,seedarr(n),format='(I12)' - endfor - free_lun,LUN -endwhile -free_lun,FRACDONEFILE -free_lun,REGODEPTHFILE - -end diff --git a/examples/global-lunar-bombardment/ctem_image_dem.pro b/examples/global-lunar-bombardment/ctem_image_dem.pro deleted file mode 100755 index ad6fbd7e..00000000 --- a/examples/global-lunar-bombardment/ctem_image_dem.pro +++ /dev/null @@ -1,41 +0,0 @@ -pro ctem_image_dem,ncount,gridsize,pix,surface_dem,surface_dem_image -; Generates the shaded surface DEM image and saves it as a jpeg output image in the 'surf' directory -; outputs surface_dem_arr, which may be scaled to use as a console image - -; This code is for reading in the x-y positions from the cumulative distribution and separating out into layers -; so that the tallied craters can be drawn as circles -;!PATH = Expand_Path('+/home/campus/daminton/coyote/') + ':' + !PATH - -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -TVLCT, red, green, blue, /GET - -sun = 20.d0 -radsun = sun * !dtor - -surface_dem_arr = dblarr(gridsize,gridsize) - -surface_dem_arr=surface_dem-shift(surface_dem,0,1) -surface_dem_arr = (0.5d0*!dpi) + atan(surface_dem_arr,pix) ; Get average slope -surface_dem_arr = abs(surface_dem_arr - radsun < 0.5d0*!dpi) ; incident angle -surface_dem_arr = 254.0d0 * cos(surface_dem_arr) ; shaded relief surface - -tv, surface_dem_arr, 0, 0, xsize=gridsize, ysize=gridsize, /device -print,'plotting' - -surface_dem_image = TVRD(True=1) -Set_Plot, thisDevice - -; save surface display -if (file_test('surf',/DIRECTORY) eq 0) then begin - file_mkdir,'surf' -endif -fnum = string(ncount,format='(I6.6)') -fname = 'surf/surf' + fnum + '.jpg' - -write_jpeg, fname, surface_dem_image, true=1, quality=100 - -end diff --git a/examples/global-lunar-bombardment/ctem_image_presentation.pro b/examples/global-lunar-bombardment/ctem_image_presentation.pro deleted file mode 100755 index 05a7d65a..00000000 --- a/examples/global-lunar-bombardment/ctem_image_presentation.pro +++ /dev/null @@ -1,143 +0,0 @@ -pro ctem_image_presentation,ncount,gridsize,pix,curyear,odist,pdist,tdist,ph1,map -; Generates the simplified version of the console display for use in presentations -; Plots the R-plot on the left and the image map on the right - -; presentation graphics -presresx = 1024 -presresy = 0.6*presresx -area = (gridsize * pix)^2 - -minx = (pix / 3.0d0) * 1d-3 -maxx = 3 * pix * gridsize * 1d-3 - -;strings for display -dum = string(format='(E10.4)', curyear) -parts = strsplit(dum, 'E', /extract) -fcuryear = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) -time = 'Time = ' -timeunit = ' yr' - -if (file_test('presentation',/DIRECTORY) eq 0) then begin - file_mkdir,'presentation' -endif - -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[presresx,presresy],Set_Pixel_Depth=24, Decomposed=0 -loadct, 0 -TVLCT, red, green, blue, /GET - -;geometric saturation -geom = dblarr(2,2) -geomem = dblarr(2,2) -geomep = dblarr(2,2) -geomel = dblarr(2,2) -geom(0,0) = minx -geom(0,1) = maxx -geom(1,*) = 3.12636d0 -geomem(0,0) = minx -geomem(0,1) = maxx -geomem(1,*) = 0.156318d0 -geomep(0,0) = minx -geomep(0,1) = maxx -geomep(1,*) = 0.312636d0 -geomel(0,0) = minx -geomel(0,1) = maxx -geomel(1,*) = 0.0312636d0 - -; Remove zeros -nz = where(odist(5,*) ne 0.0,count) -if (count gt 0) then begin - odistnz = dblarr(6,count) - odistnz(*,*)= odist(*,nz) -endif else begin - odistnz = odist -endelse - -nz = where(tdist(5,*) ne 0.0,count) -if (count gt 0) then begin - tdistnz = dblarr(6,count) - tdistnz(*,*)= tdist(*,nz) -endif else begin - tdistnz = tdist -endelse - -nz = where(pdist(5,*) ne 0.0,count) -if (count gt 0) then begin - pdistnz = dblarr(6,count) - pdistnz(*,*)= pdist(*,nz) -endif else begin - pdistnz = pdist -endelse - -; create r-plot array containing exactly 1 crater per bin -area = (gridsize * pix * 1d-3)^2 -plo = 1 -while (sqrt(2.0d0)^plo gt minx) do begin - plo = plo - 1 -endwhile -phi = plo + 1 -while (sqrt(2.0d0)^phi lt maxx) do begin - phi = phi + 1 -endwhile -n = phi - plo -sdist = dblarr(6,n + 1) -p = plo -for i=0,n do begin - sdist(0,i) = sqrt(2.d0)^p - sdist(1,i) = sqrt(2.d0)^(p+1) - sdist(2,i) = sqrt(sdist(0,i) * sdist(1,i)) - sdist(3,i) = 1.0d0 - sdist(5,i) = (sdist(2,i))^3 / (area * (sdist(1,i) - sdist(0,i))) - p = p + 1 -endfor -sdist(4,*) = reverse(total(sdist(3,*),/cumulative),2) - - -plot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=0, color=255, thick=2.0, $ - TITLE='Crater Distribution R-Plot', charsize=1.2, $ - XTITLE='Crater Diameter (km)', $ - XRANGE=[minx,maxx], /XLOG, XSTYLE=1, $ - YTITLE='R Value', $ - YRANGE=[5.0e-4,5.0e0], /YLOG, YSTYLE=1, $ - /device, pos = [0.12,0.12,0.495,0.495]*presresx - -Dfac = sqrt(sqrt(2.0d0)) - -;display observed crater distribution -oplot, tdistnz(2,*)*1.0d-3, tdistnz(5,*), line=0, color=255, thick=1.0 -;oplot, geom(0,*), geom(1,*), line=2, color=255, thick=1.0 -oplot, geomem(0,*), geomem(1,*), line=1, color=255, thick=1.0 -oplot, geomep(0,*), geomep(1,*), line=1, color=255, thick=1.0 -;oplot, geomel(0,*), geomel(1,*), line=1, color=255, thick=1.0 -oplot, pdistnz(2,*)*1.0d-3, pdistnz(5,*), line=3, color=255, thick=1.0 -oplot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=1, color=255, thick=1.0 -oplot, sdist(0,*), sdist(5,*), line=1, color=255, thick=1.0 -oplot, ph1(0,*)*Dfac*1.0d-3, ph1(1,*), psym=1, color=255, thick=1.0 -;oplot, ph2(0,*), ph2(1,*), psym=4, color=255, thick=1.0 -;oplot, ph3(0,*), ph3(1,*), psym=5, color=255, thick=1.0 - -;draw box around the main surface display & fill -displaysize = floor(0.45*presresx) ; size of displayed surface -surfxpos = floor(0.520*presresx) -surfypos = floor(0.12*presresy) -xbox = [surfxpos - 1,surfxpos - 1,surfxpos + displaysize,surfxpos + displaysize,surfxpos - 1] -ybox = [surfypos - 1,surfypos + displaysize,surfypos + displaysize,surfypos - 1,surfypos - 1] -plotS, xbox, ybox, /device, color=255 - -mapscaled = congrid(map,3,displaysize,displaysize,/interp) - -;mapscaled=congrid(map,displaysize,displaysize) ; scale image -tv, mapscaled, surfxpos, surfypos, xsize=displaysize, ysize=displaysize, true=1, /device - -xyouts, 0.310*presresx, 0.04*presresy, time + fcuryear + timeunit, color=255, charsize=2*presresy/720., /device - -snapshot = TVRD(True=1) -Set_Plot, thisDevice -fnum = string(ncount,format='(I6.6)') -fname = 'presentation/presentation' + fnum + '.jpg' -Write_JPEG, fname, snapshot, True=1, Quality=90 - - -end diff --git a/examples/global-lunar-bombardment/ctem_image_regolith.pro b/examples/global-lunar-bombardment/ctem_image_regolith.pro deleted file mode 100755 index 8d7f07a7..00000000 --- a/examples/global-lunar-bombardment/ctem_image_regolith.pro +++ /dev/null @@ -1,33 +0,0 @@ -pro ctem_image_regolith,ncount,gridsize,pix,regolith,regolith_image -; Generates the regolith depth map image and saves it as a jpeg output image in the 'rego' directory -; outputs dregolith, which may be scaled to use as a console image -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -loadct, 39 -TVLCT, red, green, blue, /GET - -minref = pix * 1.0d-4 -regolith_scaled = dblarr(gridsize,gridsize) -maxreg = max(regolith) -minreg = min(regolith) -if minreg lt minref then minreg = minref -if maxreg lt minref then maxreg = minref + 1.0d30 -regolith_scaled = regolith > minreg -regolith_scaled = 254.0d0 * ((alog(regolith_scaled) - alog(minreg)) / (alog(maxreg) - alog(minreg))) - -; save regolith display -tv, regolith_scaled, 0, 0, xsize=gridsize, ysize=gridsize, /device -regolith_image = TVRD(True=1) -Set_Plot, thisDevice - -if (file_test('rego',/DIRECTORY) eq 0) then begin - file_mkdir,'rego' -endif -fnum = string(ncount,format='(I6.6)') -fname = 'rego/rego' + fnum + '.jpg' -write_jpeg, fname, regolith_image, true=1, quality=100 - -end diff --git a/examples/global-lunar-bombardment/ctem_image_shaded_relief.pro b/examples/global-lunar-bombardment/ctem_image_shaded_relief.pro deleted file mode 100755 index 73986f84..00000000 --- a/examples/global-lunar-bombardment/ctem_image_shaded_relief.pro +++ /dev/null @@ -1,52 +0,0 @@ -pro ctem_image_shaded_relief,ncount,gridsize,pix,surface_dem,height_vals,minh,maxh,dirname,shaded_image -; Generates the shaded depth map image and saves it as a jpeg output image in the 'rego' directory -; outputs dshaded, which may be scaled to use as a console image -; Uses the array height_vals for the color -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -loadct, 33 -TVLCT, red, green, blue, /GET - -light=[[1,1,1],[0,0,0],[-1,-1,-1]] - -; convolution of the dem with the 3x3 matrix - -shaded=bytscl(convol(float(surface_dem),float(light))) -if max(shaded) eq 0 then shaded=255 - -; scale the dem to the height -if (minh gt maxh) then begin - tmp = minh - minh = maxh - maxh = tmp -endif - -demscaled = ((height_vals - minh) > 0.0) < (maxh-minh) -if ((maxh - minh) eq 0.0) then begin - demscaled = demscaled * 0.0 -endif else begin - demscaled = demscaled/(maxh-minh)*255.0 -endelse - -tv, demscaled, 0, 0, xsize=gridsize, ysize=gridsize, /device -shaded_image = TVRD(True=1) -shadedscl =float(shaded)/255.0 -shaded_imagearr = dblarr(3,gridsize,gridsize) -shaded_imagearr(0,*,*) = float(shaded_image(0,*,*)) * shadedscl(*,*) -shaded_imagearr(1,*,*) = float(shaded_image(1,*,*)) * shadedscl(*,*) -shaded_imagearr(2,*,*) = float(shaded_image(2,*,*)) * shadedscl(*,*) -shaded_image=round(shaded_imagearr) -Set_Plot, thisDevice - -if (file_test(dirname,/DIRECTORY) eq 0) then begin - file_mkdir,dirname -endif - -fnum = string(ncount,format='(I6.6)') -fname = dirname + '/' + dirname + fnum + '.jpg' -write_jpeg,fname,shaded_image,true=1,quality=90 - -end diff --git a/examples/global-lunar-bombardment/ctem_io_read_input.pro b/examples/global-lunar-bombardment/ctem_io_read_input.pro deleted file mode 100755 index ea135668..00000000 --- a/examples/global-lunar-bombardment/ctem_io_read_input.pro +++ /dev/null @@ -1,131 +0,0 @@ -pro ctem_io_read_input,infilename,interval,numintervals,gridsize,pix,seed,numlayers,sfdfile,impfile,maxcrat,ph1,shadedmaxhdefault,shadedminhdefault,shadedminh,shadedmaxh,restart,runtype,popupconsole,saveshaded,saverego,savepres,savetruelist -Compile_Opt DEFINT32 -print, 'Reading input file' -openr,infile,infilename, /GET_LUN -line="" -comment="!" -interval = 0.d0 -numintervals = 0 -pix=-1.0d0 -gridsize=-1 -seed = 0 -maxcrat = 1.0d0 -shadedmaxhdefault = 1 -shadedminhdefault = 1 -shadedminh = 0.d0 -shademaxnh = 0.d0 - - -; Set required strings to unset value -notset="-----NOTSET----" -sfdfile = notset -impfile = notset -sfdcompare = notset -restart = notset -runtype = notset -popupconsole = notset -saveshaded = notset -saverego = notset -savepres = notset -savetruelist = notset -while (not EOF(infile)) do begin - readf,infile,line - if (~strcmp(line,comment,1)) then begin - substrings = strsplit(line,' ',/extract) - if strmatch(substrings(0),'pix',/fold_case) then reads,substrings(1),pix - if strmatch(substrings(0),'gridsize',/fold_case) then reads,substrings(1),gridsize - if strmatch(substrings(0),'seed',/fold_case) then reads,substrings(1),seed - if strmatch(substrings(0),'sfdfile',/fold_case) then reads,substrings(1),sfdfile - if strmatch(substrings(0),'impfile',/fold_case) then reads,substrings(1),impfile - if strmatch(substrings(0),'maxcrat',/fold_case) then reads,substrings(1),maxcrat - if strmatch(substrings(0),'sfdcompare',/fold_case) then reads,substrings(1),sfdcompare - if strmatch(substrings(0),'interval',/fold_case) then reads,substrings(1),interval - if strmatch(substrings(0),'numintervals',/fold_case) then reads,substrings(1),numintervals - if strmatch(substrings(0),'popupconsole',/fold_case) then reads,substrings(1),popupconsole - if strmatch(substrings(0),'saveshaded',/fold_case) then reads,substrings(1),saveshaded - if strmatch(substrings(0),'saverego',/fold_case) then reads,substrings(1),saverego - if strmatch(substrings(0),'savepres',/fold_case) then reads,substrings(1),savepres - if strmatch(substrings(0),'savetruelist',/fold_case) then reads,substrings(1),savetruelist - if strmatch(substrings(0),'runtype',/fold_case) then reads,substrings(1),runtype - if strmatch(substrings(0),'restart',/fold_case) then reads,substrings(1),restart - if strmatch(substrings(0),'shadedminh',/fold_case) then begin - reads,substrings(1),shadedminh - shadedminhdefault = 0 - endif - if strmatch(substrings(0),'shadedmaxh',/fold_case) then begin - reads,substrings(1),shadedmaxh - shadedmaxhdefault = 0 - endif - end -end -if interval le 0.0d0 then begin - print,'Invalid value for or missing variable INTERVAL in ' + infilename - stop -end -if numintervals le 0 then begin - print,'Invalid value for or missing variable NUMINTERVALS in ' + infilename - stop -end -if pix le 0.0d0 then begin - print,'Invalid value for or missing variable PIX in ' + infilename - stop -end -if gridsize le 0 then begin - print,'Invalid value for or missing variable GRIDSIZE in ' + infilename - stop -end -if seed eq 0 then begin - print,'Invalid value for or missing variable SEED in ' + infilename - stop -end -if strmatch(sfdfile,notset) then begin - print,'Invalid value for or missing variable SFDFILE in ' + infilename - stop -end -if strmatch(impfile,notset) then begin - print,'Invalid value for or missing variable IMPFILE in ' + infilename - stop -end -if strmatch(popupconsole,notset) then begin - print,'Invalid value for or missing variable POPUPCONSOLE in ' + infilename - stop -end -if strmatch(saveshaded,notset) then begin - print,'Invalid value for or missing variable SAVESHADED in ' + infilename - stop -end -if strmatch(saverego,notset) then begin - print,'Invalid value for or missing variable SAVEREGO in ' + infilename - stop -end -if strmatch(savepres,notset) then begin - print,'Invalid value for or missing variable SAVEPRES in ' + infilename - stop -end -if strmatch(savetruelist,notset) then begin - print,'Invalid value for or missing variable SAVETRUELIST in ' + infilename - stop -end -if strmatch(runtype,notset) then begin - print,'Invalid value for or missing variable RUNTYPE in ' + infilename - stop -end -if strmatch(restart,notset) then begin - print,'Invalid value for or missing variable RESTART in ' + infilename - stop -end - -free_lun,infile - -ph1 = dblarr(3,1) -if ~strmatch(sfdcompare,notset) then begin - cnum = file_lines(sfdcompare) - ph1 = dblarr(3,cnum) - openr,COMP,sfdcompare,/GET_LUN - readf,COMP,ph1 - close,COMP - free_lun,COMP -end -free_lun,infile - -end diff --git a/examples/global-lunar-bombardment/ctem_io_read_old.pro b/examples/global-lunar-bombardment/ctem_io_read_old.pro deleted file mode 100755 index a9013687..00000000 --- a/examples/global-lunar-bombardment/ctem_io_read_old.pro +++ /dev/null @@ -1,45 +0,0 @@ -pro ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass -Compile_Opt DEFINT32 -openr,LUN,'surface_ejc.dat',/GET_LUN -readu,LUN,regolith -free_lun,LUN - -openr,LUN,'surface_dem.dat',/GET_LUN -readu,LUN,surface_dem -free_lun,LUN - -distl = file_lines('odistribution.dat') - 1 -pdistl = file_lines('pdistribution.dat') - 1 - -;read in observed cumulative distribution -odist = dblarr(6,distl) -line = "temp" -openr,LUN,'odistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,odist -close,LUN -free_lun,LUN - -;read in true cumulative distribution -tdist = dblarr(6,distl) -openr,LUN,'tdistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,tdist -close,LUN -free_lun,LUN - -;read in production function -pdist = dblarr(6,pdistl) -openr,LUN,'pdistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,pdist -close,LUN -free_lun,LUN - -;read in accumulated mass from file -openr,LUN,'impactmass.dat',/GET_LUN -readf,LUN,mass -close,LUN -free_lun,LUN - -end diff --git a/examples/global-lunar-bombardment/ctem_window_display.pro b/examples/global-lunar-bombardment/ctem_window_display.pro deleted file mode 100755 index d6edf5b9..00000000 --- a/examples/global-lunar-bombardment/ctem_window_display.pro +++ /dev/null @@ -1,249 +0,0 @@ -pro ctem_window_display,ncount,totalimpacts,gridsize,pix,curyear,masstot,odist,pdist,tdist,ph1,surface_dem,regolith,map,popupconsole -; Produces the console window display. The array 'map' is used to generate the image on the right-hand side -Compile_Opt DEFINT32 - -; console output graphics resolution -minref = pix * 1.0d-4 -conresx = 1280 -;conresy = 0.758*conresx -profsize = 0.00 -conresy = (0.60 + profsize) * conresx -sun = 20.d0 ; sun angle for display - -minx = (pix / 3.0d0) * 1d-3 -maxx = 3 * pix * gridsize * 1d-3 -charfac = 1.6 ; character size multiplier - -if strmatch(popupconsole,'T',/fold_case) then begin - device, decomposed=0, retain=2 - thisDevice = !D.NAME - SET_PLOT, 'Z' - TVLCT, red, green, blue, /GET - SET_PLOT, thisDevice - !P.MULTI = [0, 1, 2] - Window, 0, xsize=conresx, ysize=conresy -endif else begin - SET_PLOT, 'Z', /COPY - device, set_resolution=[conresx,conresy],decomposed=0, Z_Buffer=0 - TVLCT, red, green, blue, /GET - !P.MULTI = [0, 1, 2] - erase -endelse - -;set up first color scale -loadct, 0 - -;strings for display -time = 'Time = ' -timeunit = ' yr' -timp = 'Total impacts (dotdash) = ' -tcrt = 'Total craters (line) = ' -ocrt = 'Countable craters (bold) = ' -epwr = 'Mean regolith depth = ' -mtot = 'Impacted mass = ' -c1lab = 'Min. Elevation' -c2lab = 'Mean Elevation' -c3lab = 'Max. Elevation' - -maxelev = max(surface_dem) -minelev = min(surface_dem) -medelev = mean(surface_dem) -c1 = string(minelev, format = '(F9.1)') + ' m' -c2 = string(medelev, format = '(F9.1)') + ' m' -c3 = string(maxelev, format = '(F9.1)') + ' m' -tslp = mean(regolith) - -;geometric saturation -geom = dblarr(2,2) -geomem = dblarr(2,2) -geomep = dblarr(2,2) -geomel = dblarr(2,2) -geom(0,0) = minx -geom(0,1) = maxx -geom(1,*) = 3.12636d0 -geomem(0,0) = minx -geomem(0,1) = maxx -geomem(1,*) = 0.156318d0 -geomep(0,0) = minx -geomep(0,1) = maxx -geomep(1,*) = 0.312636d0 -geomel(0,0) = minx -geomel(0,1) = maxx -geomel(1,*) = 0.0312636d0 - -; Remove zeros -nz = where(odist(5,*) ne 0.0,count) -if (count gt 0) then begin - odistnz = dblarr(6,count) - odistnz(*,*)= odist(*,nz) -endif else begin - odistnz = odist -endelse - -nz = where(tdist(5,*) ne 0.0,count) -if (count gt 0) then begin - tdistnz = dblarr(6,count) - tdistnz(*,*)= tdist(*,nz) -endif else begin - tdistnz = tdist -endelse - -nz = where(pdist(5,*) ne 0.0,count) -if (count gt 0) then begin - pdistnz = dblarr(6,count) - pdistnz(*,*)= pdist(*,nz) - -endif else begin - pdistnz = pdist -endelse - -; create r-plot array containing exactly 1 crater per bin -area = (gridsize * pix * 1d-3)^2 -plo = 1 -while (sqrt(2.0d0)^plo gt minx) do begin - plo = plo - 1 -endwhile -phi = plo + 1 -while (sqrt(2.0d0)^phi lt maxx) do begin - phi = phi + 1 -endwhile -n = phi - plo -sdist = dblarr(6,n + 1) -p = plo -for i=0,n do begin - sdist(0,i) = sqrt(2.d0)^p - sdist(1,i) = sqrt(2.d0)^(p+1) - sdist(2,i) = sqrt(sdist(0,i) * sdist(1,i)) - sdist(3,i) = 1.0d0 - sdist(5,i) = (sdist(2,i))^3 / (area * (sdist(1,i) - sdist(0,i))) - p = p + 1 -endfor -sdist(4,*) = reverse(total(sdist(3,*),/cumulative),2) - -plot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=0, color=255, thick=2.0, $ - TITLE='Crater Distribution R-Plot', charsize=charfac*conresy/720, $ - XTITLE='Crater Diameter (km)', $ - XRANGE=[minx,maxx], /XLOG, XSTYLE=1, $ - YTITLE='R Value', $ - YRANGE=[5.0e-4,5.0e0], /YLOG, YSTYLE=1, $ - /device, pos = [0.085*conresx,(0.25 + profsize)*conresy,0.44*conresx,0.85*conresy] - -Dfac = sqrt(sqrt(2.0d0)) - -;display observed crater distribution -oplot, tdistnz(2,*)*1.0d-3, tdistnz(5,*), line=0, color=255, thick=1.0 -oplot, geom(0,*), geom(1,*), line=2, color=255, thick=1.0 -oplot, geomem(0,*), geomem(1,*), line=1, color=255, thick=1.0 -oplot, geomep(0,*), geomep(1,*), line=1, color=255, thick=1.0 -oplot, geomel(0,*), geomel(1,*), line=1, color=255, thick=1.0 -oplot, pdistnz(2,*)*1.0d-3, pdistnz(5,*), line=3, color=255, thick=1.0 -oplot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=1, color=255, thick=1.0 -oplot, sdist(0,*), sdist(5,*), line=1, color=255, thick=1.0 -oplot, ph1(0,*)*Dfac*1.0d-3, ph1(1,*), psym=1, color=255, thick=1.0 -;oplot, ph2(0,*), ph2(1,*), psym=4, color=255, thick=1.0 -;oplot, ph3(0,*), ph3(1,*), psym=5, color=255, thick=1.0 - -; set up profile display -surfpos = dblarr(gridsize) -surfpro = dblarr(gridsize) -surfhpro = dblarr(gridsize) -surfrpro = dblarr(gridsize) -for k = 0,gridsize-1 do begin - surfpos(k) = (-0.5d0*(gridsize-1) + double(k)) * pix -endfor -surfpro(*) = surface_dem(*,gridsize/2-1) -surfhpro(*) = regolith(*,gridsize/2-1) -surfrpro(*) = surfpro(*) - surfhpro(*) - -; set up profile -;maxelevp = max(surfpro) -;minelevp = min(surfpro) -;medelevp = mean(surfpro) -;vertrange = 1.5 * abs(maxelevp-minelevp) -;vertadd = 0.5d0 * (vertrange - abs(maxelevp-minelevp)) -;horzrange = vertrange * 5.86666666667d0 -;if (horzrange gt (pix*gridsize)) then horzrange = pix*gridsize -;plot, surfpos(*)/1.0d3, surfpro(*)/1.0d3, line=0, color=255, thick=1.0, $ -; TITLE='Matrix Cross-Section', charsize=1.0, $ -; XTITLE='Horizontal Position (km)', $ -; XRANGE=[(-1.0d0*horzrange/2.0d3),(horzrange/2.0d3)], XSTYLE=1, $ -; YTITLE='Elevation (km)', $ -; YRANGE=[((minelevp - vertadd)/1.0d3),((maxelevp + vertadd)/1.0d3)], YSTYLE=1, $ -; /device, pos = [0.063*conresx,0.049*conresy,0.99*conresx,0.26*conresy] -;oplot, surfpos(*)*1.0d-3, surfrpro(*)*1.0d-3, line=0, color=255, thick=1.0 - -;display text -dum = string(format='(E10.4)', curyear) -parts = strsplit(dum, 'E', /extract) -fcuryear = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) + ' yr' -ftimp = string(totalimpacts, format = '(I13)') -ftcnt = string(tdist(4,0), format = '(I13)') -focnt = string(odist(4,0), format = '(I13)') -ftslp = string(tslp, format = '(F13.3)') + ' m' - - -dum = string(format='(E10.4)',masstot) -parts = strsplit(dum, 'E', /extract) -fmtot = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) + ' kg' - -; Display information text below the R-plot -texttop = 0.15 + profsize -textspc = 0.035 -textleft = 0.05*conresx -textbreak = 0.25*conresx -xyouts, textleft, (texttop - 0*textspc)*conresy, time, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 1*textspc)*conresy, timp, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 2*textspc)*conresy, tcrt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 3*textspc)*conresy, ocrt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 4*textspc)*conresy, mtot, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 0*textspc)*conresy, fcuryear, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 1*textspc)*conresy, ftimp, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 2*textspc)*conresy, ftcnt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 3*textspc)*conresy, focnt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 4*textspc)*conresy, fmtot, color=255, charsize=charfac*conresy/720., /device - -; Display information text above the R-plot -xyouts, 0.0368*conresx, 0.972*conresy, c1lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.195*conresx, 0.972*conresy, c2lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.353*conresx, 0.972*conresy, c3lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.0368*conresx, 0.944*conresy, c1, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.195*conresx, 0.944*conresy, c2, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.353*conresx, 0.944*conresy, c3, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.100*conresx, 0.917*conresy, epwr, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.278*conresx, 0.917*conresy, ftslp, color=255, charsize=charfac*conresy/720., /device - -;print to screen -print, ncount, ' time = ', curyear -;print, ncount, ' tot impacts = ', tdist -;print, ncount, ' tot craters = ', totalimpacts -;print, ncount, ' obs craters = ', ocrcnt -;print, ncount, ' regolith = ', tslp -;print, ncount, ' prod R = ', mean(prval(1,*)) - -;draw box around the main surface display & fill -displaysize = floor(0.53*conresx) ; size of displayed surface -surfxpos = floor(0.462*conresx) -surfypos = floor((0.05 + profsize)*conresy) -xbox = [surfxpos - 1,surfxpos - 1,surfxpos + displaysize,surfxpos + displaysize,surfxpos - 1] -ybox = [surfypos - 1,surfypos + displaysize,surfypos + displaysize,surfypos - 1,surfypos - 1] -plotS, xbox, ybox, /device, color=255 - -; for display -mapscaled = congrid(map,3,displaysize,displaysize,/interp) - -tv, mapscaled, surfxpos, surfypos, xsize=displaysize, ysize=displaysize, true=1, /device - -; ---------- saving window ---------- - -; save console window -fnum = string(ncount,format='(I6.6)') -; print screen to JPEG file -if (file_test('console',/DIRECTORY) eq 0) then begin - file_mkdir,'console' -endif -print, ncount, ' saving window' -fname = 'console/console' + fnum + '.jpg' -dwin = tvrd(true=1) -write_jpeg, fname, dwin, true=1, quality=90 - -end diff --git a/examples/mare-with-rays-model2/.gitignore b/examples/mare-with-rays-model2/.gitignore deleted file mode 100644 index 2632688e..00000000 --- a/examples/mare-with-rays-model2/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.jpg -*.png -*.out -surface_* -*.idea diff --git a/examples/mare-with-rays-model2/ctem_driver.pro b/examples/mare-with-rays-model2/ctem_driver.pro deleted file mode 100644 index 071af0f7..00000000 --- a/examples/mare-with-rays-model2/ctem_driver.pro +++ /dev/null @@ -1,233 +0,0 @@ -pro ctem_driver - -;------------------------------------------------------------------------- -; Jim Richardson, Arecibo Observatory -; David Minton, Purdue University Dept. of Earth, Atmospheric, & Planetary Sciences -; July 2014 -; Cratered Terrain Evolution Model display module -; -; Inputs are read in from the ctem.in file -; -;------------------------------------------------------------------------- -;------------- Initial Setup ---------------- -;------------------------------------------------------------------------- -Compile_Opt DEFINT32 -!EXCEPT=2 - -; ----------- input file ----------------------- -infilename = 'ctem.in' -DATFILE='ctem.dat' - -; ---------- reading input files ---------- -seedarr = lon64arr(100) -seedn = 1 -totalimpacts = long64(0) -ncount = long64(0) -curyear = 0.d0 -restart = "F" -fracdone = 1.0d0 -masstot = 0.d0 - -ctem_io_read_input,infilename,interval,numintervals,gridsize,pix,seed,numlayers,sfdfile,impfile,maxcrat,ph1,shadedmaxhdefault,shadedminhdefault,shadedminh,shadedmaxh,restart,runtype,popupconsole,saveshaded,saverego,savepres,savetruelist - -seedarr(0) = seed -area = (gridsize * pix)^2 - -;read input data -pnum = file_lines(impfile) -production = dblarr(2,pnum) -productionfunction = dblarr(2,pnum) -openr,LUN,impfile,/GET_LUN -readf,LUN,productionfunction -free_lun,LUN - -;create impactor production population -production(0,*) = productionfunction(0,*) -production(1,*) = productionfunction(1,*)*area*interval - -;write out corrected production population -openw,1,sfdfile -printf,1,production -close,1 -free_lun,1 - -;set up cratering surface grid and display-only grid -surface_dem = dblarr(gridsize,gridsize) -regolith = dblarr(gridsize,gridsize) - -;set up temporary distribution bins -distl = 1 -pdistl = 1 -odist = dblarr(6,distl) -tdist = dblarr(6,distl) -pdist = dblarr(6,pdistl) -pdisttotal = dblarr(6,pdistl) - -datformat = "(I17,1X,I12,1X,E19.12,1X,A1,1X,F9.6,1X,E19.12)" - - -if strmatch(restart,'F',/fold_case) then begin ; Start with a clean slate - print, 'Starting a new run' - curyear = 0.0d0 - totalimpacts = 0 - masstot = 0.d0 - fracdone = 1.0d0 - - if strmatch(runtype,'statistical',/fold_case) then begin - ncount = 1 - openw,LUN,DATFILE,/GET_LUN - printf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - for n=0,seedn-1 do begin - printf,LUN,seedarr(n),format='(I12)' - endfor - free_lun,LUN - endif else begin - ncount = 0 - endelse - - surface_dem(*,*) = 0.0d0 - regolith(*,*) = 0.0d0 - - file_delete, 'tdistribution.dat',/allow_nonexistent - -endif else begin ; continue an old run - print, 'Continuing a previous run' - - ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass - - ;read in constants file - openr,LUN,DATFILE,/GET_LUN - readf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - seedn = 0 - while ~ eof(LUN) do begin - readf,LUN,iseed - seedarr(seedn) = long64(iseed) - seedn=seedn+1 - endwhile - -endelse - -openw,FRACDONEFILE,'fracdone.dat',/GET_LUN -openw,REGODEPTHFILE,'regolithdepth.dat',/GET_LUN - -;------------------------------------------------------------------------- -; ---------- begin loops ---------- -;------------------------------------------------------------------------- -print, 'Beginning loops' - -;define number of loop iterations and begin -;numintervals=ceil(endyear/interval)-ncount -while (ncount le numintervals) do begin - - - ; ---------- creating crater population ---------- - if (ncount gt 0) then begin - - fnum = string(ncount,format='(I6.6)') - if (file_test('misc',/DIRECTORY) eq 0) then begin - file_mkdir,'misc' - endif - ; save a copy of the ctem.dat file - fname = 'misc/ctem_' + fnum + '.dat' - file_copy, 'ctem.dat', fname, /OVERWRITE - - print, ncount, ' Calling FORTRAN routine' - ;call fortran program to create & count craters - spawn, './CTEM',/noshell - - ; ---------- reading FORTRAN output ---------- - print, ncount, ' Reading FORTRAN output' - ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass - - ;read in constants file - openr,LUN,DATFILE,/GET_LUN - readf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - seedn = 0 - while ~ eof(LUN) do begin - readf,LUN,iseed - seedarr(seedn) = long64(iseed) - seedn = seedn + 1 - endwhile - free_lun,LUN - - curyear = curyear + fracdone * interval - masstot = masstot + mass - printf,FRACDONEFILE,fracdone,curyear - flush,FRACDONEFILE - - printf,REGODEPTHFILE,curyear,mean(regolith),max(regolith),min(regolith) - flush,REGODEPTHFILE - - ;save a copy of the binned observed crater distribution - if (file_test('dist',/DIRECTORY) eq 0) then begin - file_mkdir,'dist' - endif - fname = 'dist/odist_' + fnum + '.dat' - file_copy, 'odistribution.dat', fname, /OVERWRITE - - ; save a copy of the cumulative observed crater distribution - fname = 'dist/ocum_' + fnum + '.dat' - file_copy, 'ocumulative.dat', fname, /OVERWRITE - - ;save a copy of the binned true distribution - fname = 'dist/tdist_' + fnum + '.dat' - file_copy, 'tdistribution.dat', fname, /OVERWRITE - - ;save a copy of the binned idealized production function - fname = 'dist/pdist_' + fnum + '.dat' - file_copy, 'pdistribution.dat', fname, /OVERWRITE - - ; save a copy of the cumulative true crater distribution if the user requests it - if strmatch(savetruelist,'T',/fold_case) then begin - fname = 'dist/tcum_' + fnum + '.dat' - file_copy, 'tcumulative.dat', fname, /OVERWRITE - endif - - ; save a copy of the impacted mass - fname = 'misc/mass_' + fnum + '.dat' - file_copy, 'impactmass.dat', fname, /OVERWRITE - - - endif - - ; Get the accumulated production function - pdisttotal = pdist - pdisttotal(3:5,*) = pdist(3:5,*) * curyear / interval - - ; ---------- displaying results ---------- - print, ncount, ' Displaying results' - - ctem_image_dem,ncount,gridsize,pix,surface_dem,surface_dem_image - if strmatch(saverego,'T',/fold_case) then ctem_image_regolith,ncount,gridsize,pix,regolith,regolith_image - if strmatch(saveshaded,'T',/fold_case) then begin - if (shadedminhdefault eq 1) then shadedminh = min(surface_dem) - if (shadedmaxhdefault eq 1) then shadedmaxh = max(surface_dem) - ctem_image_shaded_relief,ncount,gridsize,pix,surface_dem,surface_dem,shadedminh,shadedmaxh,'shaded',shaded_image - endif - if strmatch(savepres,'T',/fold_case) then ctem_image_presentation,ncount,gridsize,pix,curyear,odist,pdisttotal,tdist,ph1,surface_dem_image - ctem_window_display,ncount,totalimpacts,gridsize,pix,curyear,masstot,odist,pdisttotal,tdist,ph1,surface_dem,regolith,surface_dem_image,popupconsole - - ncount = ncount + 1 - - ;write out the current data file - if (strmatch(runtype,'statistical',/fold_case)) || (ncount eq 1) then begin - restart = 'F' - curyear = 0.0d0 - totalimpacts = 0 - masstot = 0.d0 - file_delete, 'tdistribution.dat',/allow_nonexistent - endif else begin - restart = 'T' - endelse - - openw,LUN,DATFILE,/GET_LUN - printf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - for n=0,seedn-1 do begin - printf,LUN,seedarr(n),format='(I12)' - endfor - free_lun,LUN -endwhile -free_lun,FRACDONEFILE -free_lun,REGODEPTHFILE - -end diff --git a/examples/mare-with-rays-model2/ctem_image_dem.pro b/examples/mare-with-rays-model2/ctem_image_dem.pro deleted file mode 100755 index ad6fbd7e..00000000 --- a/examples/mare-with-rays-model2/ctem_image_dem.pro +++ /dev/null @@ -1,41 +0,0 @@ -pro ctem_image_dem,ncount,gridsize,pix,surface_dem,surface_dem_image -; Generates the shaded surface DEM image and saves it as a jpeg output image in the 'surf' directory -; outputs surface_dem_arr, which may be scaled to use as a console image - -; This code is for reading in the x-y positions from the cumulative distribution and separating out into layers -; so that the tallied craters can be drawn as circles -;!PATH = Expand_Path('+/home/campus/daminton/coyote/') + ':' + !PATH - -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -TVLCT, red, green, blue, /GET - -sun = 20.d0 -radsun = sun * !dtor - -surface_dem_arr = dblarr(gridsize,gridsize) - -surface_dem_arr=surface_dem-shift(surface_dem,0,1) -surface_dem_arr = (0.5d0*!dpi) + atan(surface_dem_arr,pix) ; Get average slope -surface_dem_arr = abs(surface_dem_arr - radsun < 0.5d0*!dpi) ; incident angle -surface_dem_arr = 254.0d0 * cos(surface_dem_arr) ; shaded relief surface - -tv, surface_dem_arr, 0, 0, xsize=gridsize, ysize=gridsize, /device -print,'plotting' - -surface_dem_image = TVRD(True=1) -Set_Plot, thisDevice - -; save surface display -if (file_test('surf',/DIRECTORY) eq 0) then begin - file_mkdir,'surf' -endif -fnum = string(ncount,format='(I6.6)') -fname = 'surf/surf' + fnum + '.jpg' - -write_jpeg, fname, surface_dem_image, true=1, quality=100 - -end diff --git a/examples/mare-with-rays-model2/ctem_image_presentation.pro b/examples/mare-with-rays-model2/ctem_image_presentation.pro deleted file mode 100755 index 05a7d65a..00000000 --- a/examples/mare-with-rays-model2/ctem_image_presentation.pro +++ /dev/null @@ -1,143 +0,0 @@ -pro ctem_image_presentation,ncount,gridsize,pix,curyear,odist,pdist,tdist,ph1,map -; Generates the simplified version of the console display for use in presentations -; Plots the R-plot on the left and the image map on the right - -; presentation graphics -presresx = 1024 -presresy = 0.6*presresx -area = (gridsize * pix)^2 - -minx = (pix / 3.0d0) * 1d-3 -maxx = 3 * pix * gridsize * 1d-3 - -;strings for display -dum = string(format='(E10.4)', curyear) -parts = strsplit(dum, 'E', /extract) -fcuryear = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) -time = 'Time = ' -timeunit = ' yr' - -if (file_test('presentation',/DIRECTORY) eq 0) then begin - file_mkdir,'presentation' -endif - -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[presresx,presresy],Set_Pixel_Depth=24, Decomposed=0 -loadct, 0 -TVLCT, red, green, blue, /GET - -;geometric saturation -geom = dblarr(2,2) -geomem = dblarr(2,2) -geomep = dblarr(2,2) -geomel = dblarr(2,2) -geom(0,0) = minx -geom(0,1) = maxx -geom(1,*) = 3.12636d0 -geomem(0,0) = minx -geomem(0,1) = maxx -geomem(1,*) = 0.156318d0 -geomep(0,0) = minx -geomep(0,1) = maxx -geomep(1,*) = 0.312636d0 -geomel(0,0) = minx -geomel(0,1) = maxx -geomel(1,*) = 0.0312636d0 - -; Remove zeros -nz = where(odist(5,*) ne 0.0,count) -if (count gt 0) then begin - odistnz = dblarr(6,count) - odistnz(*,*)= odist(*,nz) -endif else begin - odistnz = odist -endelse - -nz = where(tdist(5,*) ne 0.0,count) -if (count gt 0) then begin - tdistnz = dblarr(6,count) - tdistnz(*,*)= tdist(*,nz) -endif else begin - tdistnz = tdist -endelse - -nz = where(pdist(5,*) ne 0.0,count) -if (count gt 0) then begin - pdistnz = dblarr(6,count) - pdistnz(*,*)= pdist(*,nz) -endif else begin - pdistnz = pdist -endelse - -; create r-plot array containing exactly 1 crater per bin -area = (gridsize * pix * 1d-3)^2 -plo = 1 -while (sqrt(2.0d0)^plo gt minx) do begin - plo = plo - 1 -endwhile -phi = plo + 1 -while (sqrt(2.0d0)^phi lt maxx) do begin - phi = phi + 1 -endwhile -n = phi - plo -sdist = dblarr(6,n + 1) -p = plo -for i=0,n do begin - sdist(0,i) = sqrt(2.d0)^p - sdist(1,i) = sqrt(2.d0)^(p+1) - sdist(2,i) = sqrt(sdist(0,i) * sdist(1,i)) - sdist(3,i) = 1.0d0 - sdist(5,i) = (sdist(2,i))^3 / (area * (sdist(1,i) - sdist(0,i))) - p = p + 1 -endfor -sdist(4,*) = reverse(total(sdist(3,*),/cumulative),2) - - -plot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=0, color=255, thick=2.0, $ - TITLE='Crater Distribution R-Plot', charsize=1.2, $ - XTITLE='Crater Diameter (km)', $ - XRANGE=[minx,maxx], /XLOG, XSTYLE=1, $ - YTITLE='R Value', $ - YRANGE=[5.0e-4,5.0e0], /YLOG, YSTYLE=1, $ - /device, pos = [0.12,0.12,0.495,0.495]*presresx - -Dfac = sqrt(sqrt(2.0d0)) - -;display observed crater distribution -oplot, tdistnz(2,*)*1.0d-3, tdistnz(5,*), line=0, color=255, thick=1.0 -;oplot, geom(0,*), geom(1,*), line=2, color=255, thick=1.0 -oplot, geomem(0,*), geomem(1,*), line=1, color=255, thick=1.0 -oplot, geomep(0,*), geomep(1,*), line=1, color=255, thick=1.0 -;oplot, geomel(0,*), geomel(1,*), line=1, color=255, thick=1.0 -oplot, pdistnz(2,*)*1.0d-3, pdistnz(5,*), line=3, color=255, thick=1.0 -oplot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=1, color=255, thick=1.0 -oplot, sdist(0,*), sdist(5,*), line=1, color=255, thick=1.0 -oplot, ph1(0,*)*Dfac*1.0d-3, ph1(1,*), psym=1, color=255, thick=1.0 -;oplot, ph2(0,*), ph2(1,*), psym=4, color=255, thick=1.0 -;oplot, ph3(0,*), ph3(1,*), psym=5, color=255, thick=1.0 - -;draw box around the main surface display & fill -displaysize = floor(0.45*presresx) ; size of displayed surface -surfxpos = floor(0.520*presresx) -surfypos = floor(0.12*presresy) -xbox = [surfxpos - 1,surfxpos - 1,surfxpos + displaysize,surfxpos + displaysize,surfxpos - 1] -ybox = [surfypos - 1,surfypos + displaysize,surfypos + displaysize,surfypos - 1,surfypos - 1] -plotS, xbox, ybox, /device, color=255 - -mapscaled = congrid(map,3,displaysize,displaysize,/interp) - -;mapscaled=congrid(map,displaysize,displaysize) ; scale image -tv, mapscaled, surfxpos, surfypos, xsize=displaysize, ysize=displaysize, true=1, /device - -xyouts, 0.310*presresx, 0.04*presresy, time + fcuryear + timeunit, color=255, charsize=2*presresy/720., /device - -snapshot = TVRD(True=1) -Set_Plot, thisDevice -fnum = string(ncount,format='(I6.6)') -fname = 'presentation/presentation' + fnum + '.jpg' -Write_JPEG, fname, snapshot, True=1, Quality=90 - - -end diff --git a/examples/mare-with-rays-model2/ctem_image_regolith.pro b/examples/mare-with-rays-model2/ctem_image_regolith.pro deleted file mode 100755 index 8d7f07a7..00000000 --- a/examples/mare-with-rays-model2/ctem_image_regolith.pro +++ /dev/null @@ -1,33 +0,0 @@ -pro ctem_image_regolith,ncount,gridsize,pix,regolith,regolith_image -; Generates the regolith depth map image and saves it as a jpeg output image in the 'rego' directory -; outputs dregolith, which may be scaled to use as a console image -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -loadct, 39 -TVLCT, red, green, blue, /GET - -minref = pix * 1.0d-4 -regolith_scaled = dblarr(gridsize,gridsize) -maxreg = max(regolith) -minreg = min(regolith) -if minreg lt minref then minreg = minref -if maxreg lt minref then maxreg = minref + 1.0d30 -regolith_scaled = regolith > minreg -regolith_scaled = 254.0d0 * ((alog(regolith_scaled) - alog(minreg)) / (alog(maxreg) - alog(minreg))) - -; save regolith display -tv, regolith_scaled, 0, 0, xsize=gridsize, ysize=gridsize, /device -regolith_image = TVRD(True=1) -Set_Plot, thisDevice - -if (file_test('rego',/DIRECTORY) eq 0) then begin - file_mkdir,'rego' -endif -fnum = string(ncount,format='(I6.6)') -fname = 'rego/rego' + fnum + '.jpg' -write_jpeg, fname, regolith_image, true=1, quality=100 - -end diff --git a/examples/mare-with-rays-model2/ctem_image_shaded_relief.pro b/examples/mare-with-rays-model2/ctem_image_shaded_relief.pro deleted file mode 100755 index 73986f84..00000000 --- a/examples/mare-with-rays-model2/ctem_image_shaded_relief.pro +++ /dev/null @@ -1,52 +0,0 @@ -pro ctem_image_shaded_relief,ncount,gridsize,pix,surface_dem,height_vals,minh,maxh,dirname,shaded_image -; Generates the shaded depth map image and saves it as a jpeg output image in the 'rego' directory -; outputs dshaded, which may be scaled to use as a console image -; Uses the array height_vals for the color -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -loadct, 33 -TVLCT, red, green, blue, /GET - -light=[[1,1,1],[0,0,0],[-1,-1,-1]] - -; convolution of the dem with the 3x3 matrix - -shaded=bytscl(convol(float(surface_dem),float(light))) -if max(shaded) eq 0 then shaded=255 - -; scale the dem to the height -if (minh gt maxh) then begin - tmp = minh - minh = maxh - maxh = tmp -endif - -demscaled = ((height_vals - minh) > 0.0) < (maxh-minh) -if ((maxh - minh) eq 0.0) then begin - demscaled = demscaled * 0.0 -endif else begin - demscaled = demscaled/(maxh-minh)*255.0 -endelse - -tv, demscaled, 0, 0, xsize=gridsize, ysize=gridsize, /device -shaded_image = TVRD(True=1) -shadedscl =float(shaded)/255.0 -shaded_imagearr = dblarr(3,gridsize,gridsize) -shaded_imagearr(0,*,*) = float(shaded_image(0,*,*)) * shadedscl(*,*) -shaded_imagearr(1,*,*) = float(shaded_image(1,*,*)) * shadedscl(*,*) -shaded_imagearr(2,*,*) = float(shaded_image(2,*,*)) * shadedscl(*,*) -shaded_image=round(shaded_imagearr) -Set_Plot, thisDevice - -if (file_test(dirname,/DIRECTORY) eq 0) then begin - file_mkdir,dirname -endif - -fnum = string(ncount,format='(I6.6)') -fname = dirname + '/' + dirname + fnum + '.jpg' -write_jpeg,fname,shaded_image,true=1,quality=90 - -end diff --git a/examples/mare-with-rays-model2/ctem_io_read_input.pro b/examples/mare-with-rays-model2/ctem_io_read_input.pro deleted file mode 100644 index ea135668..00000000 --- a/examples/mare-with-rays-model2/ctem_io_read_input.pro +++ /dev/null @@ -1,131 +0,0 @@ -pro ctem_io_read_input,infilename,interval,numintervals,gridsize,pix,seed,numlayers,sfdfile,impfile,maxcrat,ph1,shadedmaxhdefault,shadedminhdefault,shadedminh,shadedmaxh,restart,runtype,popupconsole,saveshaded,saverego,savepres,savetruelist -Compile_Opt DEFINT32 -print, 'Reading input file' -openr,infile,infilename, /GET_LUN -line="" -comment="!" -interval = 0.d0 -numintervals = 0 -pix=-1.0d0 -gridsize=-1 -seed = 0 -maxcrat = 1.0d0 -shadedmaxhdefault = 1 -shadedminhdefault = 1 -shadedminh = 0.d0 -shademaxnh = 0.d0 - - -; Set required strings to unset value -notset="-----NOTSET----" -sfdfile = notset -impfile = notset -sfdcompare = notset -restart = notset -runtype = notset -popupconsole = notset -saveshaded = notset -saverego = notset -savepres = notset -savetruelist = notset -while (not EOF(infile)) do begin - readf,infile,line - if (~strcmp(line,comment,1)) then begin - substrings = strsplit(line,' ',/extract) - if strmatch(substrings(0),'pix',/fold_case) then reads,substrings(1),pix - if strmatch(substrings(0),'gridsize',/fold_case) then reads,substrings(1),gridsize - if strmatch(substrings(0),'seed',/fold_case) then reads,substrings(1),seed - if strmatch(substrings(0),'sfdfile',/fold_case) then reads,substrings(1),sfdfile - if strmatch(substrings(0),'impfile',/fold_case) then reads,substrings(1),impfile - if strmatch(substrings(0),'maxcrat',/fold_case) then reads,substrings(1),maxcrat - if strmatch(substrings(0),'sfdcompare',/fold_case) then reads,substrings(1),sfdcompare - if strmatch(substrings(0),'interval',/fold_case) then reads,substrings(1),interval - if strmatch(substrings(0),'numintervals',/fold_case) then reads,substrings(1),numintervals - if strmatch(substrings(0),'popupconsole',/fold_case) then reads,substrings(1),popupconsole - if strmatch(substrings(0),'saveshaded',/fold_case) then reads,substrings(1),saveshaded - if strmatch(substrings(0),'saverego',/fold_case) then reads,substrings(1),saverego - if strmatch(substrings(0),'savepres',/fold_case) then reads,substrings(1),savepres - if strmatch(substrings(0),'savetruelist',/fold_case) then reads,substrings(1),savetruelist - if strmatch(substrings(0),'runtype',/fold_case) then reads,substrings(1),runtype - if strmatch(substrings(0),'restart',/fold_case) then reads,substrings(1),restart - if strmatch(substrings(0),'shadedminh',/fold_case) then begin - reads,substrings(1),shadedminh - shadedminhdefault = 0 - endif - if strmatch(substrings(0),'shadedmaxh',/fold_case) then begin - reads,substrings(1),shadedmaxh - shadedmaxhdefault = 0 - endif - end -end -if interval le 0.0d0 then begin - print,'Invalid value for or missing variable INTERVAL in ' + infilename - stop -end -if numintervals le 0 then begin - print,'Invalid value for or missing variable NUMINTERVALS in ' + infilename - stop -end -if pix le 0.0d0 then begin - print,'Invalid value for or missing variable PIX in ' + infilename - stop -end -if gridsize le 0 then begin - print,'Invalid value for or missing variable GRIDSIZE in ' + infilename - stop -end -if seed eq 0 then begin - print,'Invalid value for or missing variable SEED in ' + infilename - stop -end -if strmatch(sfdfile,notset) then begin - print,'Invalid value for or missing variable SFDFILE in ' + infilename - stop -end -if strmatch(impfile,notset) then begin - print,'Invalid value for or missing variable IMPFILE in ' + infilename - stop -end -if strmatch(popupconsole,notset) then begin - print,'Invalid value for or missing variable POPUPCONSOLE in ' + infilename - stop -end -if strmatch(saveshaded,notset) then begin - print,'Invalid value for or missing variable SAVESHADED in ' + infilename - stop -end -if strmatch(saverego,notset) then begin - print,'Invalid value for or missing variable SAVEREGO in ' + infilename - stop -end -if strmatch(savepres,notset) then begin - print,'Invalid value for or missing variable SAVEPRES in ' + infilename - stop -end -if strmatch(savetruelist,notset) then begin - print,'Invalid value for or missing variable SAVETRUELIST in ' + infilename - stop -end -if strmatch(runtype,notset) then begin - print,'Invalid value for or missing variable RUNTYPE in ' + infilename - stop -end -if strmatch(restart,notset) then begin - print,'Invalid value for or missing variable RESTART in ' + infilename - stop -end - -free_lun,infile - -ph1 = dblarr(3,1) -if ~strmatch(sfdcompare,notset) then begin - cnum = file_lines(sfdcompare) - ph1 = dblarr(3,cnum) - openr,COMP,sfdcompare,/GET_LUN - readf,COMP,ph1 - close,COMP - free_lun,COMP -end -free_lun,infile - -end diff --git a/examples/mare-with-rays-model2/ctem_io_read_old.pro b/examples/mare-with-rays-model2/ctem_io_read_old.pro deleted file mode 100644 index a9013687..00000000 --- a/examples/mare-with-rays-model2/ctem_io_read_old.pro +++ /dev/null @@ -1,45 +0,0 @@ -pro ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass -Compile_Opt DEFINT32 -openr,LUN,'surface_ejc.dat',/GET_LUN -readu,LUN,regolith -free_lun,LUN - -openr,LUN,'surface_dem.dat',/GET_LUN -readu,LUN,surface_dem -free_lun,LUN - -distl = file_lines('odistribution.dat') - 1 -pdistl = file_lines('pdistribution.dat') - 1 - -;read in observed cumulative distribution -odist = dblarr(6,distl) -line = "temp" -openr,LUN,'odistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,odist -close,LUN -free_lun,LUN - -;read in true cumulative distribution -tdist = dblarr(6,distl) -openr,LUN,'tdistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,tdist -close,LUN -free_lun,LUN - -;read in production function -pdist = dblarr(6,pdistl) -openr,LUN,'pdistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,pdist -close,LUN -free_lun,LUN - -;read in accumulated mass from file -openr,LUN,'impactmass.dat',/GET_LUN -readf,LUN,mass -close,LUN -free_lun,LUN - -end diff --git a/examples/mare-with-rays-model2/ctem_window_display.pro b/examples/mare-with-rays-model2/ctem_window_display.pro deleted file mode 100644 index d6edf5b9..00000000 --- a/examples/mare-with-rays-model2/ctem_window_display.pro +++ /dev/null @@ -1,249 +0,0 @@ -pro ctem_window_display,ncount,totalimpacts,gridsize,pix,curyear,masstot,odist,pdist,tdist,ph1,surface_dem,regolith,map,popupconsole -; Produces the console window display. The array 'map' is used to generate the image on the right-hand side -Compile_Opt DEFINT32 - -; console output graphics resolution -minref = pix * 1.0d-4 -conresx = 1280 -;conresy = 0.758*conresx -profsize = 0.00 -conresy = (0.60 + profsize) * conresx -sun = 20.d0 ; sun angle for display - -minx = (pix / 3.0d0) * 1d-3 -maxx = 3 * pix * gridsize * 1d-3 -charfac = 1.6 ; character size multiplier - -if strmatch(popupconsole,'T',/fold_case) then begin - device, decomposed=0, retain=2 - thisDevice = !D.NAME - SET_PLOT, 'Z' - TVLCT, red, green, blue, /GET - SET_PLOT, thisDevice - !P.MULTI = [0, 1, 2] - Window, 0, xsize=conresx, ysize=conresy -endif else begin - SET_PLOT, 'Z', /COPY - device, set_resolution=[conresx,conresy],decomposed=0, Z_Buffer=0 - TVLCT, red, green, blue, /GET - !P.MULTI = [0, 1, 2] - erase -endelse - -;set up first color scale -loadct, 0 - -;strings for display -time = 'Time = ' -timeunit = ' yr' -timp = 'Total impacts (dotdash) = ' -tcrt = 'Total craters (line) = ' -ocrt = 'Countable craters (bold) = ' -epwr = 'Mean regolith depth = ' -mtot = 'Impacted mass = ' -c1lab = 'Min. Elevation' -c2lab = 'Mean Elevation' -c3lab = 'Max. Elevation' - -maxelev = max(surface_dem) -minelev = min(surface_dem) -medelev = mean(surface_dem) -c1 = string(minelev, format = '(F9.1)') + ' m' -c2 = string(medelev, format = '(F9.1)') + ' m' -c3 = string(maxelev, format = '(F9.1)') + ' m' -tslp = mean(regolith) - -;geometric saturation -geom = dblarr(2,2) -geomem = dblarr(2,2) -geomep = dblarr(2,2) -geomel = dblarr(2,2) -geom(0,0) = minx -geom(0,1) = maxx -geom(1,*) = 3.12636d0 -geomem(0,0) = minx -geomem(0,1) = maxx -geomem(1,*) = 0.156318d0 -geomep(0,0) = minx -geomep(0,1) = maxx -geomep(1,*) = 0.312636d0 -geomel(0,0) = minx -geomel(0,1) = maxx -geomel(1,*) = 0.0312636d0 - -; Remove zeros -nz = where(odist(5,*) ne 0.0,count) -if (count gt 0) then begin - odistnz = dblarr(6,count) - odistnz(*,*)= odist(*,nz) -endif else begin - odistnz = odist -endelse - -nz = where(tdist(5,*) ne 0.0,count) -if (count gt 0) then begin - tdistnz = dblarr(6,count) - tdistnz(*,*)= tdist(*,nz) -endif else begin - tdistnz = tdist -endelse - -nz = where(pdist(5,*) ne 0.0,count) -if (count gt 0) then begin - pdistnz = dblarr(6,count) - pdistnz(*,*)= pdist(*,nz) - -endif else begin - pdistnz = pdist -endelse - -; create r-plot array containing exactly 1 crater per bin -area = (gridsize * pix * 1d-3)^2 -plo = 1 -while (sqrt(2.0d0)^plo gt minx) do begin - plo = plo - 1 -endwhile -phi = plo + 1 -while (sqrt(2.0d0)^phi lt maxx) do begin - phi = phi + 1 -endwhile -n = phi - plo -sdist = dblarr(6,n + 1) -p = plo -for i=0,n do begin - sdist(0,i) = sqrt(2.d0)^p - sdist(1,i) = sqrt(2.d0)^(p+1) - sdist(2,i) = sqrt(sdist(0,i) * sdist(1,i)) - sdist(3,i) = 1.0d0 - sdist(5,i) = (sdist(2,i))^3 / (area * (sdist(1,i) - sdist(0,i))) - p = p + 1 -endfor -sdist(4,*) = reverse(total(sdist(3,*),/cumulative),2) - -plot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=0, color=255, thick=2.0, $ - TITLE='Crater Distribution R-Plot', charsize=charfac*conresy/720, $ - XTITLE='Crater Diameter (km)', $ - XRANGE=[minx,maxx], /XLOG, XSTYLE=1, $ - YTITLE='R Value', $ - YRANGE=[5.0e-4,5.0e0], /YLOG, YSTYLE=1, $ - /device, pos = [0.085*conresx,(0.25 + profsize)*conresy,0.44*conresx,0.85*conresy] - -Dfac = sqrt(sqrt(2.0d0)) - -;display observed crater distribution -oplot, tdistnz(2,*)*1.0d-3, tdistnz(5,*), line=0, color=255, thick=1.0 -oplot, geom(0,*), geom(1,*), line=2, color=255, thick=1.0 -oplot, geomem(0,*), geomem(1,*), line=1, color=255, thick=1.0 -oplot, geomep(0,*), geomep(1,*), line=1, color=255, thick=1.0 -oplot, geomel(0,*), geomel(1,*), line=1, color=255, thick=1.0 -oplot, pdistnz(2,*)*1.0d-3, pdistnz(5,*), line=3, color=255, thick=1.0 -oplot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=1, color=255, thick=1.0 -oplot, sdist(0,*), sdist(5,*), line=1, color=255, thick=1.0 -oplot, ph1(0,*)*Dfac*1.0d-3, ph1(1,*), psym=1, color=255, thick=1.0 -;oplot, ph2(0,*), ph2(1,*), psym=4, color=255, thick=1.0 -;oplot, ph3(0,*), ph3(1,*), psym=5, color=255, thick=1.0 - -; set up profile display -surfpos = dblarr(gridsize) -surfpro = dblarr(gridsize) -surfhpro = dblarr(gridsize) -surfrpro = dblarr(gridsize) -for k = 0,gridsize-1 do begin - surfpos(k) = (-0.5d0*(gridsize-1) + double(k)) * pix -endfor -surfpro(*) = surface_dem(*,gridsize/2-1) -surfhpro(*) = regolith(*,gridsize/2-1) -surfrpro(*) = surfpro(*) - surfhpro(*) - -; set up profile -;maxelevp = max(surfpro) -;minelevp = min(surfpro) -;medelevp = mean(surfpro) -;vertrange = 1.5 * abs(maxelevp-minelevp) -;vertadd = 0.5d0 * (vertrange - abs(maxelevp-minelevp)) -;horzrange = vertrange * 5.86666666667d0 -;if (horzrange gt (pix*gridsize)) then horzrange = pix*gridsize -;plot, surfpos(*)/1.0d3, surfpro(*)/1.0d3, line=0, color=255, thick=1.0, $ -; TITLE='Matrix Cross-Section', charsize=1.0, $ -; XTITLE='Horizontal Position (km)', $ -; XRANGE=[(-1.0d0*horzrange/2.0d3),(horzrange/2.0d3)], XSTYLE=1, $ -; YTITLE='Elevation (km)', $ -; YRANGE=[((minelevp - vertadd)/1.0d3),((maxelevp + vertadd)/1.0d3)], YSTYLE=1, $ -; /device, pos = [0.063*conresx,0.049*conresy,0.99*conresx,0.26*conresy] -;oplot, surfpos(*)*1.0d-3, surfrpro(*)*1.0d-3, line=0, color=255, thick=1.0 - -;display text -dum = string(format='(E10.4)', curyear) -parts = strsplit(dum, 'E', /extract) -fcuryear = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) + ' yr' -ftimp = string(totalimpacts, format = '(I13)') -ftcnt = string(tdist(4,0), format = '(I13)') -focnt = string(odist(4,0), format = '(I13)') -ftslp = string(tslp, format = '(F13.3)') + ' m' - - -dum = string(format='(E10.4)',masstot) -parts = strsplit(dum, 'E', /extract) -fmtot = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) + ' kg' - -; Display information text below the R-plot -texttop = 0.15 + profsize -textspc = 0.035 -textleft = 0.05*conresx -textbreak = 0.25*conresx -xyouts, textleft, (texttop - 0*textspc)*conresy, time, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 1*textspc)*conresy, timp, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 2*textspc)*conresy, tcrt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 3*textspc)*conresy, ocrt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 4*textspc)*conresy, mtot, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 0*textspc)*conresy, fcuryear, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 1*textspc)*conresy, ftimp, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 2*textspc)*conresy, ftcnt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 3*textspc)*conresy, focnt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 4*textspc)*conresy, fmtot, color=255, charsize=charfac*conresy/720., /device - -; Display information text above the R-plot -xyouts, 0.0368*conresx, 0.972*conresy, c1lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.195*conresx, 0.972*conresy, c2lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.353*conresx, 0.972*conresy, c3lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.0368*conresx, 0.944*conresy, c1, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.195*conresx, 0.944*conresy, c2, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.353*conresx, 0.944*conresy, c3, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.100*conresx, 0.917*conresy, epwr, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.278*conresx, 0.917*conresy, ftslp, color=255, charsize=charfac*conresy/720., /device - -;print to screen -print, ncount, ' time = ', curyear -;print, ncount, ' tot impacts = ', tdist -;print, ncount, ' tot craters = ', totalimpacts -;print, ncount, ' obs craters = ', ocrcnt -;print, ncount, ' regolith = ', tslp -;print, ncount, ' prod R = ', mean(prval(1,*)) - -;draw box around the main surface display & fill -displaysize = floor(0.53*conresx) ; size of displayed surface -surfxpos = floor(0.462*conresx) -surfypos = floor((0.05 + profsize)*conresy) -xbox = [surfxpos - 1,surfxpos - 1,surfxpos + displaysize,surfxpos + displaysize,surfxpos - 1] -ybox = [surfypos - 1,surfypos + displaysize,surfypos + displaysize,surfypos - 1,surfypos - 1] -plotS, xbox, ybox, /device, color=255 - -; for display -mapscaled = congrid(map,3,displaysize,displaysize,/interp) - -tv, mapscaled, surfxpos, surfypos, xsize=displaysize, ysize=displaysize, true=1, /device - -; ---------- saving window ---------- - -; save console window -fnum = string(ncount,format='(I6.6)') -; print screen to JPEG file -if (file_test('console',/DIRECTORY) eq 0) then begin - file_mkdir,'console' -endif -print, ncount, ' saving window' -fname = 'console/console' + fnum + '.jpg' -dwin = tvrd(true=1) -write_jpeg, fname, dwin, true=1, quality=90 - -end diff --git a/examples/morphology_test_cases/complex/shaded/.gitignore b/examples/morphology_test_cases/complex/shaded/.gitignore deleted file mode 100644 index 88cc1070..00000000 --- a/examples/morphology_test_cases/complex/shaded/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.jpg -*.png diff --git a/examples/morphology_test_cases/global/ctem_driver.pro b/examples/morphology_test_cases/global/ctem_driver.pro deleted file mode 100755 index 071af0f7..00000000 --- a/examples/morphology_test_cases/global/ctem_driver.pro +++ /dev/null @@ -1,233 +0,0 @@ -pro ctem_driver - -;------------------------------------------------------------------------- -; Jim Richardson, Arecibo Observatory -; David Minton, Purdue University Dept. of Earth, Atmospheric, & Planetary Sciences -; July 2014 -; Cratered Terrain Evolution Model display module -; -; Inputs are read in from the ctem.in file -; -;------------------------------------------------------------------------- -;------------- Initial Setup ---------------- -;------------------------------------------------------------------------- -Compile_Opt DEFINT32 -!EXCEPT=2 - -; ----------- input file ----------------------- -infilename = 'ctem.in' -DATFILE='ctem.dat' - -; ---------- reading input files ---------- -seedarr = lon64arr(100) -seedn = 1 -totalimpacts = long64(0) -ncount = long64(0) -curyear = 0.d0 -restart = "F" -fracdone = 1.0d0 -masstot = 0.d0 - -ctem_io_read_input,infilename,interval,numintervals,gridsize,pix,seed,numlayers,sfdfile,impfile,maxcrat,ph1,shadedmaxhdefault,shadedminhdefault,shadedminh,shadedmaxh,restart,runtype,popupconsole,saveshaded,saverego,savepres,savetruelist - -seedarr(0) = seed -area = (gridsize * pix)^2 - -;read input data -pnum = file_lines(impfile) -production = dblarr(2,pnum) -productionfunction = dblarr(2,pnum) -openr,LUN,impfile,/GET_LUN -readf,LUN,productionfunction -free_lun,LUN - -;create impactor production population -production(0,*) = productionfunction(0,*) -production(1,*) = productionfunction(1,*)*area*interval - -;write out corrected production population -openw,1,sfdfile -printf,1,production -close,1 -free_lun,1 - -;set up cratering surface grid and display-only grid -surface_dem = dblarr(gridsize,gridsize) -regolith = dblarr(gridsize,gridsize) - -;set up temporary distribution bins -distl = 1 -pdistl = 1 -odist = dblarr(6,distl) -tdist = dblarr(6,distl) -pdist = dblarr(6,pdistl) -pdisttotal = dblarr(6,pdistl) - -datformat = "(I17,1X,I12,1X,E19.12,1X,A1,1X,F9.6,1X,E19.12)" - - -if strmatch(restart,'F',/fold_case) then begin ; Start with a clean slate - print, 'Starting a new run' - curyear = 0.0d0 - totalimpacts = 0 - masstot = 0.d0 - fracdone = 1.0d0 - - if strmatch(runtype,'statistical',/fold_case) then begin - ncount = 1 - openw,LUN,DATFILE,/GET_LUN - printf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - for n=0,seedn-1 do begin - printf,LUN,seedarr(n),format='(I12)' - endfor - free_lun,LUN - endif else begin - ncount = 0 - endelse - - surface_dem(*,*) = 0.0d0 - regolith(*,*) = 0.0d0 - - file_delete, 'tdistribution.dat',/allow_nonexistent - -endif else begin ; continue an old run - print, 'Continuing a previous run' - - ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass - - ;read in constants file - openr,LUN,DATFILE,/GET_LUN - readf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - seedn = 0 - while ~ eof(LUN) do begin - readf,LUN,iseed - seedarr(seedn) = long64(iseed) - seedn=seedn+1 - endwhile - -endelse - -openw,FRACDONEFILE,'fracdone.dat',/GET_LUN -openw,REGODEPTHFILE,'regolithdepth.dat',/GET_LUN - -;------------------------------------------------------------------------- -; ---------- begin loops ---------- -;------------------------------------------------------------------------- -print, 'Beginning loops' - -;define number of loop iterations and begin -;numintervals=ceil(endyear/interval)-ncount -while (ncount le numintervals) do begin - - - ; ---------- creating crater population ---------- - if (ncount gt 0) then begin - - fnum = string(ncount,format='(I6.6)') - if (file_test('misc',/DIRECTORY) eq 0) then begin - file_mkdir,'misc' - endif - ; save a copy of the ctem.dat file - fname = 'misc/ctem_' + fnum + '.dat' - file_copy, 'ctem.dat', fname, /OVERWRITE - - print, ncount, ' Calling FORTRAN routine' - ;call fortran program to create & count craters - spawn, './CTEM',/noshell - - ; ---------- reading FORTRAN output ---------- - print, ncount, ' Reading FORTRAN output' - ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass - - ;read in constants file - openr,LUN,DATFILE,/GET_LUN - readf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - seedn = 0 - while ~ eof(LUN) do begin - readf,LUN,iseed - seedarr(seedn) = long64(iseed) - seedn = seedn + 1 - endwhile - free_lun,LUN - - curyear = curyear + fracdone * interval - masstot = masstot + mass - printf,FRACDONEFILE,fracdone,curyear - flush,FRACDONEFILE - - printf,REGODEPTHFILE,curyear,mean(regolith),max(regolith),min(regolith) - flush,REGODEPTHFILE - - ;save a copy of the binned observed crater distribution - if (file_test('dist',/DIRECTORY) eq 0) then begin - file_mkdir,'dist' - endif - fname = 'dist/odist_' + fnum + '.dat' - file_copy, 'odistribution.dat', fname, /OVERWRITE - - ; save a copy of the cumulative observed crater distribution - fname = 'dist/ocum_' + fnum + '.dat' - file_copy, 'ocumulative.dat', fname, /OVERWRITE - - ;save a copy of the binned true distribution - fname = 'dist/tdist_' + fnum + '.dat' - file_copy, 'tdistribution.dat', fname, /OVERWRITE - - ;save a copy of the binned idealized production function - fname = 'dist/pdist_' + fnum + '.dat' - file_copy, 'pdistribution.dat', fname, /OVERWRITE - - ; save a copy of the cumulative true crater distribution if the user requests it - if strmatch(savetruelist,'T',/fold_case) then begin - fname = 'dist/tcum_' + fnum + '.dat' - file_copy, 'tcumulative.dat', fname, /OVERWRITE - endif - - ; save a copy of the impacted mass - fname = 'misc/mass_' + fnum + '.dat' - file_copy, 'impactmass.dat', fname, /OVERWRITE - - - endif - - ; Get the accumulated production function - pdisttotal = pdist - pdisttotal(3:5,*) = pdist(3:5,*) * curyear / interval - - ; ---------- displaying results ---------- - print, ncount, ' Displaying results' - - ctem_image_dem,ncount,gridsize,pix,surface_dem,surface_dem_image - if strmatch(saverego,'T',/fold_case) then ctem_image_regolith,ncount,gridsize,pix,regolith,regolith_image - if strmatch(saveshaded,'T',/fold_case) then begin - if (shadedminhdefault eq 1) then shadedminh = min(surface_dem) - if (shadedmaxhdefault eq 1) then shadedmaxh = max(surface_dem) - ctem_image_shaded_relief,ncount,gridsize,pix,surface_dem,surface_dem,shadedminh,shadedmaxh,'shaded',shaded_image - endif - if strmatch(savepres,'T',/fold_case) then ctem_image_presentation,ncount,gridsize,pix,curyear,odist,pdisttotal,tdist,ph1,surface_dem_image - ctem_window_display,ncount,totalimpacts,gridsize,pix,curyear,masstot,odist,pdisttotal,tdist,ph1,surface_dem,regolith,surface_dem_image,popupconsole - - ncount = ncount + 1 - - ;write out the current data file - if (strmatch(runtype,'statistical',/fold_case)) || (ncount eq 1) then begin - restart = 'F' - curyear = 0.0d0 - totalimpacts = 0 - masstot = 0.d0 - file_delete, 'tdistribution.dat',/allow_nonexistent - endif else begin - restart = 'T' - endelse - - openw,LUN,DATFILE,/GET_LUN - printf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - for n=0,seedn-1 do begin - printf,LUN,seedarr(n),format='(I12)' - endfor - free_lun,LUN -endwhile -free_lun,FRACDONEFILE -free_lun,REGODEPTHFILE - -end diff --git a/examples/morphology_test_cases/global/ctem_image_dem.pro b/examples/morphology_test_cases/global/ctem_image_dem.pro deleted file mode 100755 index ad6fbd7e..00000000 --- a/examples/morphology_test_cases/global/ctem_image_dem.pro +++ /dev/null @@ -1,41 +0,0 @@ -pro ctem_image_dem,ncount,gridsize,pix,surface_dem,surface_dem_image -; Generates the shaded surface DEM image and saves it as a jpeg output image in the 'surf' directory -; outputs surface_dem_arr, which may be scaled to use as a console image - -; This code is for reading in the x-y positions from the cumulative distribution and separating out into layers -; so that the tallied craters can be drawn as circles -;!PATH = Expand_Path('+/home/campus/daminton/coyote/') + ':' + !PATH - -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -TVLCT, red, green, blue, /GET - -sun = 20.d0 -radsun = sun * !dtor - -surface_dem_arr = dblarr(gridsize,gridsize) - -surface_dem_arr=surface_dem-shift(surface_dem,0,1) -surface_dem_arr = (0.5d0*!dpi) + atan(surface_dem_arr,pix) ; Get average slope -surface_dem_arr = abs(surface_dem_arr - radsun < 0.5d0*!dpi) ; incident angle -surface_dem_arr = 254.0d0 * cos(surface_dem_arr) ; shaded relief surface - -tv, surface_dem_arr, 0, 0, xsize=gridsize, ysize=gridsize, /device -print,'plotting' - -surface_dem_image = TVRD(True=1) -Set_Plot, thisDevice - -; save surface display -if (file_test('surf',/DIRECTORY) eq 0) then begin - file_mkdir,'surf' -endif -fnum = string(ncount,format='(I6.6)') -fname = 'surf/surf' + fnum + '.jpg' - -write_jpeg, fname, surface_dem_image, true=1, quality=100 - -end diff --git a/examples/morphology_test_cases/global/ctem_image_presentation.pro b/examples/morphology_test_cases/global/ctem_image_presentation.pro deleted file mode 100755 index 05a7d65a..00000000 --- a/examples/morphology_test_cases/global/ctem_image_presentation.pro +++ /dev/null @@ -1,143 +0,0 @@ -pro ctem_image_presentation,ncount,gridsize,pix,curyear,odist,pdist,tdist,ph1,map -; Generates the simplified version of the console display for use in presentations -; Plots the R-plot on the left and the image map on the right - -; presentation graphics -presresx = 1024 -presresy = 0.6*presresx -area = (gridsize * pix)^2 - -minx = (pix / 3.0d0) * 1d-3 -maxx = 3 * pix * gridsize * 1d-3 - -;strings for display -dum = string(format='(E10.4)', curyear) -parts = strsplit(dum, 'E', /extract) -fcuryear = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) -time = 'Time = ' -timeunit = ' yr' - -if (file_test('presentation',/DIRECTORY) eq 0) then begin - file_mkdir,'presentation' -endif - -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[presresx,presresy],Set_Pixel_Depth=24, Decomposed=0 -loadct, 0 -TVLCT, red, green, blue, /GET - -;geometric saturation -geom = dblarr(2,2) -geomem = dblarr(2,2) -geomep = dblarr(2,2) -geomel = dblarr(2,2) -geom(0,0) = minx -geom(0,1) = maxx -geom(1,*) = 3.12636d0 -geomem(0,0) = minx -geomem(0,1) = maxx -geomem(1,*) = 0.156318d0 -geomep(0,0) = minx -geomep(0,1) = maxx -geomep(1,*) = 0.312636d0 -geomel(0,0) = minx -geomel(0,1) = maxx -geomel(1,*) = 0.0312636d0 - -; Remove zeros -nz = where(odist(5,*) ne 0.0,count) -if (count gt 0) then begin - odistnz = dblarr(6,count) - odistnz(*,*)= odist(*,nz) -endif else begin - odistnz = odist -endelse - -nz = where(tdist(5,*) ne 0.0,count) -if (count gt 0) then begin - tdistnz = dblarr(6,count) - tdistnz(*,*)= tdist(*,nz) -endif else begin - tdistnz = tdist -endelse - -nz = where(pdist(5,*) ne 0.0,count) -if (count gt 0) then begin - pdistnz = dblarr(6,count) - pdistnz(*,*)= pdist(*,nz) -endif else begin - pdistnz = pdist -endelse - -; create r-plot array containing exactly 1 crater per bin -area = (gridsize * pix * 1d-3)^2 -plo = 1 -while (sqrt(2.0d0)^plo gt minx) do begin - plo = plo - 1 -endwhile -phi = plo + 1 -while (sqrt(2.0d0)^phi lt maxx) do begin - phi = phi + 1 -endwhile -n = phi - plo -sdist = dblarr(6,n + 1) -p = plo -for i=0,n do begin - sdist(0,i) = sqrt(2.d0)^p - sdist(1,i) = sqrt(2.d0)^(p+1) - sdist(2,i) = sqrt(sdist(0,i) * sdist(1,i)) - sdist(3,i) = 1.0d0 - sdist(5,i) = (sdist(2,i))^3 / (area * (sdist(1,i) - sdist(0,i))) - p = p + 1 -endfor -sdist(4,*) = reverse(total(sdist(3,*),/cumulative),2) - - -plot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=0, color=255, thick=2.0, $ - TITLE='Crater Distribution R-Plot', charsize=1.2, $ - XTITLE='Crater Diameter (km)', $ - XRANGE=[minx,maxx], /XLOG, XSTYLE=1, $ - YTITLE='R Value', $ - YRANGE=[5.0e-4,5.0e0], /YLOG, YSTYLE=1, $ - /device, pos = [0.12,0.12,0.495,0.495]*presresx - -Dfac = sqrt(sqrt(2.0d0)) - -;display observed crater distribution -oplot, tdistnz(2,*)*1.0d-3, tdistnz(5,*), line=0, color=255, thick=1.0 -;oplot, geom(0,*), geom(1,*), line=2, color=255, thick=1.0 -oplot, geomem(0,*), geomem(1,*), line=1, color=255, thick=1.0 -oplot, geomep(0,*), geomep(1,*), line=1, color=255, thick=1.0 -;oplot, geomel(0,*), geomel(1,*), line=1, color=255, thick=1.0 -oplot, pdistnz(2,*)*1.0d-3, pdistnz(5,*), line=3, color=255, thick=1.0 -oplot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=1, color=255, thick=1.0 -oplot, sdist(0,*), sdist(5,*), line=1, color=255, thick=1.0 -oplot, ph1(0,*)*Dfac*1.0d-3, ph1(1,*), psym=1, color=255, thick=1.0 -;oplot, ph2(0,*), ph2(1,*), psym=4, color=255, thick=1.0 -;oplot, ph3(0,*), ph3(1,*), psym=5, color=255, thick=1.0 - -;draw box around the main surface display & fill -displaysize = floor(0.45*presresx) ; size of displayed surface -surfxpos = floor(0.520*presresx) -surfypos = floor(0.12*presresy) -xbox = [surfxpos - 1,surfxpos - 1,surfxpos + displaysize,surfxpos + displaysize,surfxpos - 1] -ybox = [surfypos - 1,surfypos + displaysize,surfypos + displaysize,surfypos - 1,surfypos - 1] -plotS, xbox, ybox, /device, color=255 - -mapscaled = congrid(map,3,displaysize,displaysize,/interp) - -;mapscaled=congrid(map,displaysize,displaysize) ; scale image -tv, mapscaled, surfxpos, surfypos, xsize=displaysize, ysize=displaysize, true=1, /device - -xyouts, 0.310*presresx, 0.04*presresy, time + fcuryear + timeunit, color=255, charsize=2*presresy/720., /device - -snapshot = TVRD(True=1) -Set_Plot, thisDevice -fnum = string(ncount,format='(I6.6)') -fname = 'presentation/presentation' + fnum + '.jpg' -Write_JPEG, fname, snapshot, True=1, Quality=90 - - -end diff --git a/examples/morphology_test_cases/global/ctem_image_regolith.pro b/examples/morphology_test_cases/global/ctem_image_regolith.pro deleted file mode 100755 index 8d7f07a7..00000000 --- a/examples/morphology_test_cases/global/ctem_image_regolith.pro +++ /dev/null @@ -1,33 +0,0 @@ -pro ctem_image_regolith,ncount,gridsize,pix,regolith,regolith_image -; Generates the regolith depth map image and saves it as a jpeg output image in the 'rego' directory -; outputs dregolith, which may be scaled to use as a console image -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -loadct, 39 -TVLCT, red, green, blue, /GET - -minref = pix * 1.0d-4 -regolith_scaled = dblarr(gridsize,gridsize) -maxreg = max(regolith) -minreg = min(regolith) -if minreg lt minref then minreg = minref -if maxreg lt minref then maxreg = minref + 1.0d30 -regolith_scaled = regolith > minreg -regolith_scaled = 254.0d0 * ((alog(regolith_scaled) - alog(minreg)) / (alog(maxreg) - alog(minreg))) - -; save regolith display -tv, regolith_scaled, 0, 0, xsize=gridsize, ysize=gridsize, /device -regolith_image = TVRD(True=1) -Set_Plot, thisDevice - -if (file_test('rego',/DIRECTORY) eq 0) then begin - file_mkdir,'rego' -endif -fnum = string(ncount,format='(I6.6)') -fname = 'rego/rego' + fnum + '.jpg' -write_jpeg, fname, regolith_image, true=1, quality=100 - -end diff --git a/examples/morphology_test_cases/global/ctem_image_shaded_relief.pro b/examples/morphology_test_cases/global/ctem_image_shaded_relief.pro deleted file mode 100755 index 73986f84..00000000 --- a/examples/morphology_test_cases/global/ctem_image_shaded_relief.pro +++ /dev/null @@ -1,52 +0,0 @@ -pro ctem_image_shaded_relief,ncount,gridsize,pix,surface_dem,height_vals,minh,maxh,dirname,shaded_image -; Generates the shaded depth map image and saves it as a jpeg output image in the 'rego' directory -; outputs dshaded, which may be scaled to use as a console image -; Uses the array height_vals for the color -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -loadct, 33 -TVLCT, red, green, blue, /GET - -light=[[1,1,1],[0,0,0],[-1,-1,-1]] - -; convolution of the dem with the 3x3 matrix - -shaded=bytscl(convol(float(surface_dem),float(light))) -if max(shaded) eq 0 then shaded=255 - -; scale the dem to the height -if (minh gt maxh) then begin - tmp = minh - minh = maxh - maxh = tmp -endif - -demscaled = ((height_vals - minh) > 0.0) < (maxh-minh) -if ((maxh - minh) eq 0.0) then begin - demscaled = demscaled * 0.0 -endif else begin - demscaled = demscaled/(maxh-minh)*255.0 -endelse - -tv, demscaled, 0, 0, xsize=gridsize, ysize=gridsize, /device -shaded_image = TVRD(True=1) -shadedscl =float(shaded)/255.0 -shaded_imagearr = dblarr(3,gridsize,gridsize) -shaded_imagearr(0,*,*) = float(shaded_image(0,*,*)) * shadedscl(*,*) -shaded_imagearr(1,*,*) = float(shaded_image(1,*,*)) * shadedscl(*,*) -shaded_imagearr(2,*,*) = float(shaded_image(2,*,*)) * shadedscl(*,*) -shaded_image=round(shaded_imagearr) -Set_Plot, thisDevice - -if (file_test(dirname,/DIRECTORY) eq 0) then begin - file_mkdir,dirname -endif - -fnum = string(ncount,format='(I6.6)') -fname = dirname + '/' + dirname + fnum + '.jpg' -write_jpeg,fname,shaded_image,true=1,quality=90 - -end diff --git a/examples/morphology_test_cases/global/ctem_io_read_input.pro b/examples/morphology_test_cases/global/ctem_io_read_input.pro deleted file mode 100755 index ea135668..00000000 --- a/examples/morphology_test_cases/global/ctem_io_read_input.pro +++ /dev/null @@ -1,131 +0,0 @@ -pro ctem_io_read_input,infilename,interval,numintervals,gridsize,pix,seed,numlayers,sfdfile,impfile,maxcrat,ph1,shadedmaxhdefault,shadedminhdefault,shadedminh,shadedmaxh,restart,runtype,popupconsole,saveshaded,saverego,savepres,savetruelist -Compile_Opt DEFINT32 -print, 'Reading input file' -openr,infile,infilename, /GET_LUN -line="" -comment="!" -interval = 0.d0 -numintervals = 0 -pix=-1.0d0 -gridsize=-1 -seed = 0 -maxcrat = 1.0d0 -shadedmaxhdefault = 1 -shadedminhdefault = 1 -shadedminh = 0.d0 -shademaxnh = 0.d0 - - -; Set required strings to unset value -notset="-----NOTSET----" -sfdfile = notset -impfile = notset -sfdcompare = notset -restart = notset -runtype = notset -popupconsole = notset -saveshaded = notset -saverego = notset -savepres = notset -savetruelist = notset -while (not EOF(infile)) do begin - readf,infile,line - if (~strcmp(line,comment,1)) then begin - substrings = strsplit(line,' ',/extract) - if strmatch(substrings(0),'pix',/fold_case) then reads,substrings(1),pix - if strmatch(substrings(0),'gridsize',/fold_case) then reads,substrings(1),gridsize - if strmatch(substrings(0),'seed',/fold_case) then reads,substrings(1),seed - if strmatch(substrings(0),'sfdfile',/fold_case) then reads,substrings(1),sfdfile - if strmatch(substrings(0),'impfile',/fold_case) then reads,substrings(1),impfile - if strmatch(substrings(0),'maxcrat',/fold_case) then reads,substrings(1),maxcrat - if strmatch(substrings(0),'sfdcompare',/fold_case) then reads,substrings(1),sfdcompare - if strmatch(substrings(0),'interval',/fold_case) then reads,substrings(1),interval - if strmatch(substrings(0),'numintervals',/fold_case) then reads,substrings(1),numintervals - if strmatch(substrings(0),'popupconsole',/fold_case) then reads,substrings(1),popupconsole - if strmatch(substrings(0),'saveshaded',/fold_case) then reads,substrings(1),saveshaded - if strmatch(substrings(0),'saverego',/fold_case) then reads,substrings(1),saverego - if strmatch(substrings(0),'savepres',/fold_case) then reads,substrings(1),savepres - if strmatch(substrings(0),'savetruelist',/fold_case) then reads,substrings(1),savetruelist - if strmatch(substrings(0),'runtype',/fold_case) then reads,substrings(1),runtype - if strmatch(substrings(0),'restart',/fold_case) then reads,substrings(1),restart - if strmatch(substrings(0),'shadedminh',/fold_case) then begin - reads,substrings(1),shadedminh - shadedminhdefault = 0 - endif - if strmatch(substrings(0),'shadedmaxh',/fold_case) then begin - reads,substrings(1),shadedmaxh - shadedmaxhdefault = 0 - endif - end -end -if interval le 0.0d0 then begin - print,'Invalid value for or missing variable INTERVAL in ' + infilename - stop -end -if numintervals le 0 then begin - print,'Invalid value for or missing variable NUMINTERVALS in ' + infilename - stop -end -if pix le 0.0d0 then begin - print,'Invalid value for or missing variable PIX in ' + infilename - stop -end -if gridsize le 0 then begin - print,'Invalid value for or missing variable GRIDSIZE in ' + infilename - stop -end -if seed eq 0 then begin - print,'Invalid value for or missing variable SEED in ' + infilename - stop -end -if strmatch(sfdfile,notset) then begin - print,'Invalid value for or missing variable SFDFILE in ' + infilename - stop -end -if strmatch(impfile,notset) then begin - print,'Invalid value for or missing variable IMPFILE in ' + infilename - stop -end -if strmatch(popupconsole,notset) then begin - print,'Invalid value for or missing variable POPUPCONSOLE in ' + infilename - stop -end -if strmatch(saveshaded,notset) then begin - print,'Invalid value for or missing variable SAVESHADED in ' + infilename - stop -end -if strmatch(saverego,notset) then begin - print,'Invalid value for or missing variable SAVEREGO in ' + infilename - stop -end -if strmatch(savepres,notset) then begin - print,'Invalid value for or missing variable SAVEPRES in ' + infilename - stop -end -if strmatch(savetruelist,notset) then begin - print,'Invalid value for or missing variable SAVETRUELIST in ' + infilename - stop -end -if strmatch(runtype,notset) then begin - print,'Invalid value for or missing variable RUNTYPE in ' + infilename - stop -end -if strmatch(restart,notset) then begin - print,'Invalid value for or missing variable RESTART in ' + infilename - stop -end - -free_lun,infile - -ph1 = dblarr(3,1) -if ~strmatch(sfdcompare,notset) then begin - cnum = file_lines(sfdcompare) - ph1 = dblarr(3,cnum) - openr,COMP,sfdcompare,/GET_LUN - readf,COMP,ph1 - close,COMP - free_lun,COMP -end -free_lun,infile - -end diff --git a/examples/morphology_test_cases/global/ctem_io_read_old.pro b/examples/morphology_test_cases/global/ctem_io_read_old.pro deleted file mode 100755 index a9013687..00000000 --- a/examples/morphology_test_cases/global/ctem_io_read_old.pro +++ /dev/null @@ -1,45 +0,0 @@ -pro ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass -Compile_Opt DEFINT32 -openr,LUN,'surface_ejc.dat',/GET_LUN -readu,LUN,regolith -free_lun,LUN - -openr,LUN,'surface_dem.dat',/GET_LUN -readu,LUN,surface_dem -free_lun,LUN - -distl = file_lines('odistribution.dat') - 1 -pdistl = file_lines('pdistribution.dat') - 1 - -;read in observed cumulative distribution -odist = dblarr(6,distl) -line = "temp" -openr,LUN,'odistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,odist -close,LUN -free_lun,LUN - -;read in true cumulative distribution -tdist = dblarr(6,distl) -openr,LUN,'tdistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,tdist -close,LUN -free_lun,LUN - -;read in production function -pdist = dblarr(6,pdistl) -openr,LUN,'pdistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,pdist -close,LUN -free_lun,LUN - -;read in accumulated mass from file -openr,LUN,'impactmass.dat',/GET_LUN -readf,LUN,mass -close,LUN -free_lun,LUN - -end diff --git a/examples/morphology_test_cases/global/ctem_window_display.pro b/examples/morphology_test_cases/global/ctem_window_display.pro deleted file mode 100755 index d6edf5b9..00000000 --- a/examples/morphology_test_cases/global/ctem_window_display.pro +++ /dev/null @@ -1,249 +0,0 @@ -pro ctem_window_display,ncount,totalimpacts,gridsize,pix,curyear,masstot,odist,pdist,tdist,ph1,surface_dem,regolith,map,popupconsole -; Produces the console window display. The array 'map' is used to generate the image on the right-hand side -Compile_Opt DEFINT32 - -; console output graphics resolution -minref = pix * 1.0d-4 -conresx = 1280 -;conresy = 0.758*conresx -profsize = 0.00 -conresy = (0.60 + profsize) * conresx -sun = 20.d0 ; sun angle for display - -minx = (pix / 3.0d0) * 1d-3 -maxx = 3 * pix * gridsize * 1d-3 -charfac = 1.6 ; character size multiplier - -if strmatch(popupconsole,'T',/fold_case) then begin - device, decomposed=0, retain=2 - thisDevice = !D.NAME - SET_PLOT, 'Z' - TVLCT, red, green, blue, /GET - SET_PLOT, thisDevice - !P.MULTI = [0, 1, 2] - Window, 0, xsize=conresx, ysize=conresy -endif else begin - SET_PLOT, 'Z', /COPY - device, set_resolution=[conresx,conresy],decomposed=0, Z_Buffer=0 - TVLCT, red, green, blue, /GET - !P.MULTI = [0, 1, 2] - erase -endelse - -;set up first color scale -loadct, 0 - -;strings for display -time = 'Time = ' -timeunit = ' yr' -timp = 'Total impacts (dotdash) = ' -tcrt = 'Total craters (line) = ' -ocrt = 'Countable craters (bold) = ' -epwr = 'Mean regolith depth = ' -mtot = 'Impacted mass = ' -c1lab = 'Min. Elevation' -c2lab = 'Mean Elevation' -c3lab = 'Max. Elevation' - -maxelev = max(surface_dem) -minelev = min(surface_dem) -medelev = mean(surface_dem) -c1 = string(minelev, format = '(F9.1)') + ' m' -c2 = string(medelev, format = '(F9.1)') + ' m' -c3 = string(maxelev, format = '(F9.1)') + ' m' -tslp = mean(regolith) - -;geometric saturation -geom = dblarr(2,2) -geomem = dblarr(2,2) -geomep = dblarr(2,2) -geomel = dblarr(2,2) -geom(0,0) = minx -geom(0,1) = maxx -geom(1,*) = 3.12636d0 -geomem(0,0) = minx -geomem(0,1) = maxx -geomem(1,*) = 0.156318d0 -geomep(0,0) = minx -geomep(0,1) = maxx -geomep(1,*) = 0.312636d0 -geomel(0,0) = minx -geomel(0,1) = maxx -geomel(1,*) = 0.0312636d0 - -; Remove zeros -nz = where(odist(5,*) ne 0.0,count) -if (count gt 0) then begin - odistnz = dblarr(6,count) - odistnz(*,*)= odist(*,nz) -endif else begin - odistnz = odist -endelse - -nz = where(tdist(5,*) ne 0.0,count) -if (count gt 0) then begin - tdistnz = dblarr(6,count) - tdistnz(*,*)= tdist(*,nz) -endif else begin - tdistnz = tdist -endelse - -nz = where(pdist(5,*) ne 0.0,count) -if (count gt 0) then begin - pdistnz = dblarr(6,count) - pdistnz(*,*)= pdist(*,nz) - -endif else begin - pdistnz = pdist -endelse - -; create r-plot array containing exactly 1 crater per bin -area = (gridsize * pix * 1d-3)^2 -plo = 1 -while (sqrt(2.0d0)^plo gt minx) do begin - plo = plo - 1 -endwhile -phi = plo + 1 -while (sqrt(2.0d0)^phi lt maxx) do begin - phi = phi + 1 -endwhile -n = phi - plo -sdist = dblarr(6,n + 1) -p = plo -for i=0,n do begin - sdist(0,i) = sqrt(2.d0)^p - sdist(1,i) = sqrt(2.d0)^(p+1) - sdist(2,i) = sqrt(sdist(0,i) * sdist(1,i)) - sdist(3,i) = 1.0d0 - sdist(5,i) = (sdist(2,i))^3 / (area * (sdist(1,i) - sdist(0,i))) - p = p + 1 -endfor -sdist(4,*) = reverse(total(sdist(3,*),/cumulative),2) - -plot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=0, color=255, thick=2.0, $ - TITLE='Crater Distribution R-Plot', charsize=charfac*conresy/720, $ - XTITLE='Crater Diameter (km)', $ - XRANGE=[minx,maxx], /XLOG, XSTYLE=1, $ - YTITLE='R Value', $ - YRANGE=[5.0e-4,5.0e0], /YLOG, YSTYLE=1, $ - /device, pos = [0.085*conresx,(0.25 + profsize)*conresy,0.44*conresx,0.85*conresy] - -Dfac = sqrt(sqrt(2.0d0)) - -;display observed crater distribution -oplot, tdistnz(2,*)*1.0d-3, tdistnz(5,*), line=0, color=255, thick=1.0 -oplot, geom(0,*), geom(1,*), line=2, color=255, thick=1.0 -oplot, geomem(0,*), geomem(1,*), line=1, color=255, thick=1.0 -oplot, geomep(0,*), geomep(1,*), line=1, color=255, thick=1.0 -oplot, geomel(0,*), geomel(1,*), line=1, color=255, thick=1.0 -oplot, pdistnz(2,*)*1.0d-3, pdistnz(5,*), line=3, color=255, thick=1.0 -oplot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=1, color=255, thick=1.0 -oplot, sdist(0,*), sdist(5,*), line=1, color=255, thick=1.0 -oplot, ph1(0,*)*Dfac*1.0d-3, ph1(1,*), psym=1, color=255, thick=1.0 -;oplot, ph2(0,*), ph2(1,*), psym=4, color=255, thick=1.0 -;oplot, ph3(0,*), ph3(1,*), psym=5, color=255, thick=1.0 - -; set up profile display -surfpos = dblarr(gridsize) -surfpro = dblarr(gridsize) -surfhpro = dblarr(gridsize) -surfrpro = dblarr(gridsize) -for k = 0,gridsize-1 do begin - surfpos(k) = (-0.5d0*(gridsize-1) + double(k)) * pix -endfor -surfpro(*) = surface_dem(*,gridsize/2-1) -surfhpro(*) = regolith(*,gridsize/2-1) -surfrpro(*) = surfpro(*) - surfhpro(*) - -; set up profile -;maxelevp = max(surfpro) -;minelevp = min(surfpro) -;medelevp = mean(surfpro) -;vertrange = 1.5 * abs(maxelevp-minelevp) -;vertadd = 0.5d0 * (vertrange - abs(maxelevp-minelevp)) -;horzrange = vertrange * 5.86666666667d0 -;if (horzrange gt (pix*gridsize)) then horzrange = pix*gridsize -;plot, surfpos(*)/1.0d3, surfpro(*)/1.0d3, line=0, color=255, thick=1.0, $ -; TITLE='Matrix Cross-Section', charsize=1.0, $ -; XTITLE='Horizontal Position (km)', $ -; XRANGE=[(-1.0d0*horzrange/2.0d3),(horzrange/2.0d3)], XSTYLE=1, $ -; YTITLE='Elevation (km)', $ -; YRANGE=[((minelevp - vertadd)/1.0d3),((maxelevp + vertadd)/1.0d3)], YSTYLE=1, $ -; /device, pos = [0.063*conresx,0.049*conresy,0.99*conresx,0.26*conresy] -;oplot, surfpos(*)*1.0d-3, surfrpro(*)*1.0d-3, line=0, color=255, thick=1.0 - -;display text -dum = string(format='(E10.4)', curyear) -parts = strsplit(dum, 'E', /extract) -fcuryear = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) + ' yr' -ftimp = string(totalimpacts, format = '(I13)') -ftcnt = string(tdist(4,0), format = '(I13)') -focnt = string(odist(4,0), format = '(I13)') -ftslp = string(tslp, format = '(F13.3)') + ' m' - - -dum = string(format='(E10.4)',masstot) -parts = strsplit(dum, 'E', /extract) -fmtot = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) + ' kg' - -; Display information text below the R-plot -texttop = 0.15 + profsize -textspc = 0.035 -textleft = 0.05*conresx -textbreak = 0.25*conresx -xyouts, textleft, (texttop - 0*textspc)*conresy, time, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 1*textspc)*conresy, timp, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 2*textspc)*conresy, tcrt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 3*textspc)*conresy, ocrt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 4*textspc)*conresy, mtot, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 0*textspc)*conresy, fcuryear, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 1*textspc)*conresy, ftimp, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 2*textspc)*conresy, ftcnt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 3*textspc)*conresy, focnt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 4*textspc)*conresy, fmtot, color=255, charsize=charfac*conresy/720., /device - -; Display information text above the R-plot -xyouts, 0.0368*conresx, 0.972*conresy, c1lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.195*conresx, 0.972*conresy, c2lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.353*conresx, 0.972*conresy, c3lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.0368*conresx, 0.944*conresy, c1, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.195*conresx, 0.944*conresy, c2, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.353*conresx, 0.944*conresy, c3, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.100*conresx, 0.917*conresy, epwr, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.278*conresx, 0.917*conresy, ftslp, color=255, charsize=charfac*conresy/720., /device - -;print to screen -print, ncount, ' time = ', curyear -;print, ncount, ' tot impacts = ', tdist -;print, ncount, ' tot craters = ', totalimpacts -;print, ncount, ' obs craters = ', ocrcnt -;print, ncount, ' regolith = ', tslp -;print, ncount, ' prod R = ', mean(prval(1,*)) - -;draw box around the main surface display & fill -displaysize = floor(0.53*conresx) ; size of displayed surface -surfxpos = floor(0.462*conresx) -surfypos = floor((0.05 + profsize)*conresy) -xbox = [surfxpos - 1,surfxpos - 1,surfxpos + displaysize,surfxpos + displaysize,surfxpos - 1] -ybox = [surfypos - 1,surfypos + displaysize,surfypos + displaysize,surfypos - 1,surfypos - 1] -plotS, xbox, ybox, /device, color=255 - -; for display -mapscaled = congrid(map,3,displaysize,displaysize,/interp) - -tv, mapscaled, surfxpos, surfypos, xsize=displaysize, ysize=displaysize, true=1, /device - -; ---------- saving window ---------- - -; save console window -fnum = string(ncount,format='(I6.6)') -; print screen to JPEG file -if (file_test('console',/DIRECTORY) eq 0) then begin - file_mkdir,'console' -endif -print, ncount, ' saving window' -fname = 'console/console' + fnum + '.jpg' -dwin = tvrd(true=1) -write_jpeg, fname, dwin, true=1, quality=90 - -end diff --git a/examples/morphology_test_cases/simple/ctem_driver.pro b/examples/morphology_test_cases/simple/ctem_driver.pro deleted file mode 100755 index 071af0f7..00000000 --- a/examples/morphology_test_cases/simple/ctem_driver.pro +++ /dev/null @@ -1,233 +0,0 @@ -pro ctem_driver - -;------------------------------------------------------------------------- -; Jim Richardson, Arecibo Observatory -; David Minton, Purdue University Dept. of Earth, Atmospheric, & Planetary Sciences -; July 2014 -; Cratered Terrain Evolution Model display module -; -; Inputs are read in from the ctem.in file -; -;------------------------------------------------------------------------- -;------------- Initial Setup ---------------- -;------------------------------------------------------------------------- -Compile_Opt DEFINT32 -!EXCEPT=2 - -; ----------- input file ----------------------- -infilename = 'ctem.in' -DATFILE='ctem.dat' - -; ---------- reading input files ---------- -seedarr = lon64arr(100) -seedn = 1 -totalimpacts = long64(0) -ncount = long64(0) -curyear = 0.d0 -restart = "F" -fracdone = 1.0d0 -masstot = 0.d0 - -ctem_io_read_input,infilename,interval,numintervals,gridsize,pix,seed,numlayers,sfdfile,impfile,maxcrat,ph1,shadedmaxhdefault,shadedminhdefault,shadedminh,shadedmaxh,restart,runtype,popupconsole,saveshaded,saverego,savepres,savetruelist - -seedarr(0) = seed -area = (gridsize * pix)^2 - -;read input data -pnum = file_lines(impfile) -production = dblarr(2,pnum) -productionfunction = dblarr(2,pnum) -openr,LUN,impfile,/GET_LUN -readf,LUN,productionfunction -free_lun,LUN - -;create impactor production population -production(0,*) = productionfunction(0,*) -production(1,*) = productionfunction(1,*)*area*interval - -;write out corrected production population -openw,1,sfdfile -printf,1,production -close,1 -free_lun,1 - -;set up cratering surface grid and display-only grid -surface_dem = dblarr(gridsize,gridsize) -regolith = dblarr(gridsize,gridsize) - -;set up temporary distribution bins -distl = 1 -pdistl = 1 -odist = dblarr(6,distl) -tdist = dblarr(6,distl) -pdist = dblarr(6,pdistl) -pdisttotal = dblarr(6,pdistl) - -datformat = "(I17,1X,I12,1X,E19.12,1X,A1,1X,F9.6,1X,E19.12)" - - -if strmatch(restart,'F',/fold_case) then begin ; Start with a clean slate - print, 'Starting a new run' - curyear = 0.0d0 - totalimpacts = 0 - masstot = 0.d0 - fracdone = 1.0d0 - - if strmatch(runtype,'statistical',/fold_case) then begin - ncount = 1 - openw,LUN,DATFILE,/GET_LUN - printf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - for n=0,seedn-1 do begin - printf,LUN,seedarr(n),format='(I12)' - endfor - free_lun,LUN - endif else begin - ncount = 0 - endelse - - surface_dem(*,*) = 0.0d0 - regolith(*,*) = 0.0d0 - - file_delete, 'tdistribution.dat',/allow_nonexistent - -endif else begin ; continue an old run - print, 'Continuing a previous run' - - ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass - - ;read in constants file - openr,LUN,DATFILE,/GET_LUN - readf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - seedn = 0 - while ~ eof(LUN) do begin - readf,LUN,iseed - seedarr(seedn) = long64(iseed) - seedn=seedn+1 - endwhile - -endelse - -openw,FRACDONEFILE,'fracdone.dat',/GET_LUN -openw,REGODEPTHFILE,'regolithdepth.dat',/GET_LUN - -;------------------------------------------------------------------------- -; ---------- begin loops ---------- -;------------------------------------------------------------------------- -print, 'Beginning loops' - -;define number of loop iterations and begin -;numintervals=ceil(endyear/interval)-ncount -while (ncount le numintervals) do begin - - - ; ---------- creating crater population ---------- - if (ncount gt 0) then begin - - fnum = string(ncount,format='(I6.6)') - if (file_test('misc',/DIRECTORY) eq 0) then begin - file_mkdir,'misc' - endif - ; save a copy of the ctem.dat file - fname = 'misc/ctem_' + fnum + '.dat' - file_copy, 'ctem.dat', fname, /OVERWRITE - - print, ncount, ' Calling FORTRAN routine' - ;call fortran program to create & count craters - spawn, './CTEM',/noshell - - ; ---------- reading FORTRAN output ---------- - print, ncount, ' Reading FORTRAN output' - ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass - - ;read in constants file - openr,LUN,DATFILE,/GET_LUN - readf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - seedn = 0 - while ~ eof(LUN) do begin - readf,LUN,iseed - seedarr(seedn) = long64(iseed) - seedn = seedn + 1 - endwhile - free_lun,LUN - - curyear = curyear + fracdone * interval - masstot = masstot + mass - printf,FRACDONEFILE,fracdone,curyear - flush,FRACDONEFILE - - printf,REGODEPTHFILE,curyear,mean(regolith),max(regolith),min(regolith) - flush,REGODEPTHFILE - - ;save a copy of the binned observed crater distribution - if (file_test('dist',/DIRECTORY) eq 0) then begin - file_mkdir,'dist' - endif - fname = 'dist/odist_' + fnum + '.dat' - file_copy, 'odistribution.dat', fname, /OVERWRITE - - ; save a copy of the cumulative observed crater distribution - fname = 'dist/ocum_' + fnum + '.dat' - file_copy, 'ocumulative.dat', fname, /OVERWRITE - - ;save a copy of the binned true distribution - fname = 'dist/tdist_' + fnum + '.dat' - file_copy, 'tdistribution.dat', fname, /OVERWRITE - - ;save a copy of the binned idealized production function - fname = 'dist/pdist_' + fnum + '.dat' - file_copy, 'pdistribution.dat', fname, /OVERWRITE - - ; save a copy of the cumulative true crater distribution if the user requests it - if strmatch(savetruelist,'T',/fold_case) then begin - fname = 'dist/tcum_' + fnum + '.dat' - file_copy, 'tcumulative.dat', fname, /OVERWRITE - endif - - ; save a copy of the impacted mass - fname = 'misc/mass_' + fnum + '.dat' - file_copy, 'impactmass.dat', fname, /OVERWRITE - - - endif - - ; Get the accumulated production function - pdisttotal = pdist - pdisttotal(3:5,*) = pdist(3:5,*) * curyear / interval - - ; ---------- displaying results ---------- - print, ncount, ' Displaying results' - - ctem_image_dem,ncount,gridsize,pix,surface_dem,surface_dem_image - if strmatch(saverego,'T',/fold_case) then ctem_image_regolith,ncount,gridsize,pix,regolith,regolith_image - if strmatch(saveshaded,'T',/fold_case) then begin - if (shadedminhdefault eq 1) then shadedminh = min(surface_dem) - if (shadedmaxhdefault eq 1) then shadedmaxh = max(surface_dem) - ctem_image_shaded_relief,ncount,gridsize,pix,surface_dem,surface_dem,shadedminh,shadedmaxh,'shaded',shaded_image - endif - if strmatch(savepres,'T',/fold_case) then ctem_image_presentation,ncount,gridsize,pix,curyear,odist,pdisttotal,tdist,ph1,surface_dem_image - ctem_window_display,ncount,totalimpacts,gridsize,pix,curyear,masstot,odist,pdisttotal,tdist,ph1,surface_dem,regolith,surface_dem_image,popupconsole - - ncount = ncount + 1 - - ;write out the current data file - if (strmatch(runtype,'statistical',/fold_case)) || (ncount eq 1) then begin - restart = 'F' - curyear = 0.0d0 - totalimpacts = 0 - masstot = 0.d0 - file_delete, 'tdistribution.dat',/allow_nonexistent - endif else begin - restart = 'T' - endelse - - openw,LUN,DATFILE,/GET_LUN - printf,LUN,totalimpacts,ncount,curyear,restart,fracdone,masstot,format=datformat - for n=0,seedn-1 do begin - printf,LUN,seedarr(n),format='(I12)' - endfor - free_lun,LUN -endwhile -free_lun,FRACDONEFILE -free_lun,REGODEPTHFILE - -end diff --git a/examples/morphology_test_cases/simple/ctem_image_dem.pro b/examples/morphology_test_cases/simple/ctem_image_dem.pro deleted file mode 100755 index ad6fbd7e..00000000 --- a/examples/morphology_test_cases/simple/ctem_image_dem.pro +++ /dev/null @@ -1,41 +0,0 @@ -pro ctem_image_dem,ncount,gridsize,pix,surface_dem,surface_dem_image -; Generates the shaded surface DEM image and saves it as a jpeg output image in the 'surf' directory -; outputs surface_dem_arr, which may be scaled to use as a console image - -; This code is for reading in the x-y positions from the cumulative distribution and separating out into layers -; so that the tallied craters can be drawn as circles -;!PATH = Expand_Path('+/home/campus/daminton/coyote/') + ':' + !PATH - -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -TVLCT, red, green, blue, /GET - -sun = 20.d0 -radsun = sun * !dtor - -surface_dem_arr = dblarr(gridsize,gridsize) - -surface_dem_arr=surface_dem-shift(surface_dem,0,1) -surface_dem_arr = (0.5d0*!dpi) + atan(surface_dem_arr,pix) ; Get average slope -surface_dem_arr = abs(surface_dem_arr - radsun < 0.5d0*!dpi) ; incident angle -surface_dem_arr = 254.0d0 * cos(surface_dem_arr) ; shaded relief surface - -tv, surface_dem_arr, 0, 0, xsize=gridsize, ysize=gridsize, /device -print,'plotting' - -surface_dem_image = TVRD(True=1) -Set_Plot, thisDevice - -; save surface display -if (file_test('surf',/DIRECTORY) eq 0) then begin - file_mkdir,'surf' -endif -fnum = string(ncount,format='(I6.6)') -fname = 'surf/surf' + fnum + '.jpg' - -write_jpeg, fname, surface_dem_image, true=1, quality=100 - -end diff --git a/examples/morphology_test_cases/simple/ctem_image_presentation.pro b/examples/morphology_test_cases/simple/ctem_image_presentation.pro deleted file mode 100755 index 05a7d65a..00000000 --- a/examples/morphology_test_cases/simple/ctem_image_presentation.pro +++ /dev/null @@ -1,143 +0,0 @@ -pro ctem_image_presentation,ncount,gridsize,pix,curyear,odist,pdist,tdist,ph1,map -; Generates the simplified version of the console display for use in presentations -; Plots the R-plot on the left and the image map on the right - -; presentation graphics -presresx = 1024 -presresy = 0.6*presresx -area = (gridsize * pix)^2 - -minx = (pix / 3.0d0) * 1d-3 -maxx = 3 * pix * gridsize * 1d-3 - -;strings for display -dum = string(format='(E10.4)', curyear) -parts = strsplit(dum, 'E', /extract) -fcuryear = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) -time = 'Time = ' -timeunit = ' yr' - -if (file_test('presentation',/DIRECTORY) eq 0) then begin - file_mkdir,'presentation' -endif - -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[presresx,presresy],Set_Pixel_Depth=24, Decomposed=0 -loadct, 0 -TVLCT, red, green, blue, /GET - -;geometric saturation -geom = dblarr(2,2) -geomem = dblarr(2,2) -geomep = dblarr(2,2) -geomel = dblarr(2,2) -geom(0,0) = minx -geom(0,1) = maxx -geom(1,*) = 3.12636d0 -geomem(0,0) = minx -geomem(0,1) = maxx -geomem(1,*) = 0.156318d0 -geomep(0,0) = minx -geomep(0,1) = maxx -geomep(1,*) = 0.312636d0 -geomel(0,0) = minx -geomel(0,1) = maxx -geomel(1,*) = 0.0312636d0 - -; Remove zeros -nz = where(odist(5,*) ne 0.0,count) -if (count gt 0) then begin - odistnz = dblarr(6,count) - odistnz(*,*)= odist(*,nz) -endif else begin - odistnz = odist -endelse - -nz = where(tdist(5,*) ne 0.0,count) -if (count gt 0) then begin - tdistnz = dblarr(6,count) - tdistnz(*,*)= tdist(*,nz) -endif else begin - tdistnz = tdist -endelse - -nz = where(pdist(5,*) ne 0.0,count) -if (count gt 0) then begin - pdistnz = dblarr(6,count) - pdistnz(*,*)= pdist(*,nz) -endif else begin - pdistnz = pdist -endelse - -; create r-plot array containing exactly 1 crater per bin -area = (gridsize * pix * 1d-3)^2 -plo = 1 -while (sqrt(2.0d0)^plo gt minx) do begin - plo = plo - 1 -endwhile -phi = plo + 1 -while (sqrt(2.0d0)^phi lt maxx) do begin - phi = phi + 1 -endwhile -n = phi - plo -sdist = dblarr(6,n + 1) -p = plo -for i=0,n do begin - sdist(0,i) = sqrt(2.d0)^p - sdist(1,i) = sqrt(2.d0)^(p+1) - sdist(2,i) = sqrt(sdist(0,i) * sdist(1,i)) - sdist(3,i) = 1.0d0 - sdist(5,i) = (sdist(2,i))^3 / (area * (sdist(1,i) - sdist(0,i))) - p = p + 1 -endfor -sdist(4,*) = reverse(total(sdist(3,*),/cumulative),2) - - -plot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=0, color=255, thick=2.0, $ - TITLE='Crater Distribution R-Plot', charsize=1.2, $ - XTITLE='Crater Diameter (km)', $ - XRANGE=[minx,maxx], /XLOG, XSTYLE=1, $ - YTITLE='R Value', $ - YRANGE=[5.0e-4,5.0e0], /YLOG, YSTYLE=1, $ - /device, pos = [0.12,0.12,0.495,0.495]*presresx - -Dfac = sqrt(sqrt(2.0d0)) - -;display observed crater distribution -oplot, tdistnz(2,*)*1.0d-3, tdistnz(5,*), line=0, color=255, thick=1.0 -;oplot, geom(0,*), geom(1,*), line=2, color=255, thick=1.0 -oplot, geomem(0,*), geomem(1,*), line=1, color=255, thick=1.0 -oplot, geomep(0,*), geomep(1,*), line=1, color=255, thick=1.0 -;oplot, geomel(0,*), geomel(1,*), line=1, color=255, thick=1.0 -oplot, pdistnz(2,*)*1.0d-3, pdistnz(5,*), line=3, color=255, thick=1.0 -oplot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=1, color=255, thick=1.0 -oplot, sdist(0,*), sdist(5,*), line=1, color=255, thick=1.0 -oplot, ph1(0,*)*Dfac*1.0d-3, ph1(1,*), psym=1, color=255, thick=1.0 -;oplot, ph2(0,*), ph2(1,*), psym=4, color=255, thick=1.0 -;oplot, ph3(0,*), ph3(1,*), psym=5, color=255, thick=1.0 - -;draw box around the main surface display & fill -displaysize = floor(0.45*presresx) ; size of displayed surface -surfxpos = floor(0.520*presresx) -surfypos = floor(0.12*presresy) -xbox = [surfxpos - 1,surfxpos - 1,surfxpos + displaysize,surfxpos + displaysize,surfxpos - 1] -ybox = [surfypos - 1,surfypos + displaysize,surfypos + displaysize,surfypos - 1,surfypos - 1] -plotS, xbox, ybox, /device, color=255 - -mapscaled = congrid(map,3,displaysize,displaysize,/interp) - -;mapscaled=congrid(map,displaysize,displaysize) ; scale image -tv, mapscaled, surfxpos, surfypos, xsize=displaysize, ysize=displaysize, true=1, /device - -xyouts, 0.310*presresx, 0.04*presresy, time + fcuryear + timeunit, color=255, charsize=2*presresy/720., /device - -snapshot = TVRD(True=1) -Set_Plot, thisDevice -fnum = string(ncount,format='(I6.6)') -fname = 'presentation/presentation' + fnum + '.jpg' -Write_JPEG, fname, snapshot, True=1, Quality=90 - - -end diff --git a/examples/morphology_test_cases/simple/ctem_image_regolith.pro b/examples/morphology_test_cases/simple/ctem_image_regolith.pro deleted file mode 100755 index 8d7f07a7..00000000 --- a/examples/morphology_test_cases/simple/ctem_image_regolith.pro +++ /dev/null @@ -1,33 +0,0 @@ -pro ctem_image_regolith,ncount,gridsize,pix,regolith,regolith_image -; Generates the regolith depth map image and saves it as a jpeg output image in the 'rego' directory -; outputs dregolith, which may be scaled to use as a console image -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -loadct, 39 -TVLCT, red, green, blue, /GET - -minref = pix * 1.0d-4 -regolith_scaled = dblarr(gridsize,gridsize) -maxreg = max(regolith) -minreg = min(regolith) -if minreg lt minref then minreg = minref -if maxreg lt minref then maxreg = minref + 1.0d30 -regolith_scaled = regolith > minreg -regolith_scaled = 254.0d0 * ((alog(regolith_scaled) - alog(minreg)) / (alog(maxreg) - alog(minreg))) - -; save regolith display -tv, regolith_scaled, 0, 0, xsize=gridsize, ysize=gridsize, /device -regolith_image = TVRD(True=1) -Set_Plot, thisDevice - -if (file_test('rego',/DIRECTORY) eq 0) then begin - file_mkdir,'rego' -endif -fnum = string(ncount,format='(I6.6)') -fname = 'rego/rego' + fnum + '.jpg' -write_jpeg, fname, regolith_image, true=1, quality=100 - -end diff --git a/examples/morphology_test_cases/simple/ctem_image_shaded_relief.pro b/examples/morphology_test_cases/simple/ctem_image_shaded_relief.pro deleted file mode 100755 index 73986f84..00000000 --- a/examples/morphology_test_cases/simple/ctem_image_shaded_relief.pro +++ /dev/null @@ -1,52 +0,0 @@ -pro ctem_image_shaded_relief,ncount,gridsize,pix,surface_dem,height_vals,minh,maxh,dirname,shaded_image -; Generates the shaded depth map image and saves it as a jpeg output image in the 'rego' directory -; outputs dshaded, which may be scaled to use as a console image -; Uses the array height_vals for the color -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -loadct, 33 -TVLCT, red, green, blue, /GET - -light=[[1,1,1],[0,0,0],[-1,-1,-1]] - -; convolution of the dem with the 3x3 matrix - -shaded=bytscl(convol(float(surface_dem),float(light))) -if max(shaded) eq 0 then shaded=255 - -; scale the dem to the height -if (minh gt maxh) then begin - tmp = minh - minh = maxh - maxh = tmp -endif - -demscaled = ((height_vals - minh) > 0.0) < (maxh-minh) -if ((maxh - minh) eq 0.0) then begin - demscaled = demscaled * 0.0 -endif else begin - demscaled = demscaled/(maxh-minh)*255.0 -endelse - -tv, demscaled, 0, 0, xsize=gridsize, ysize=gridsize, /device -shaded_image = TVRD(True=1) -shadedscl =float(shaded)/255.0 -shaded_imagearr = dblarr(3,gridsize,gridsize) -shaded_imagearr(0,*,*) = float(shaded_image(0,*,*)) * shadedscl(*,*) -shaded_imagearr(1,*,*) = float(shaded_image(1,*,*)) * shadedscl(*,*) -shaded_imagearr(2,*,*) = float(shaded_image(2,*,*)) * shadedscl(*,*) -shaded_image=round(shaded_imagearr) -Set_Plot, thisDevice - -if (file_test(dirname,/DIRECTORY) eq 0) then begin - file_mkdir,dirname -endif - -fnum = string(ncount,format='(I6.6)') -fname = dirname + '/' + dirname + fnum + '.jpg' -write_jpeg,fname,shaded_image,true=1,quality=90 - -end diff --git a/examples/morphology_test_cases/simple/ctem_io_read_input.pro b/examples/morphology_test_cases/simple/ctem_io_read_input.pro deleted file mode 100755 index ea135668..00000000 --- a/examples/morphology_test_cases/simple/ctem_io_read_input.pro +++ /dev/null @@ -1,131 +0,0 @@ -pro ctem_io_read_input,infilename,interval,numintervals,gridsize,pix,seed,numlayers,sfdfile,impfile,maxcrat,ph1,shadedmaxhdefault,shadedminhdefault,shadedminh,shadedmaxh,restart,runtype,popupconsole,saveshaded,saverego,savepres,savetruelist -Compile_Opt DEFINT32 -print, 'Reading input file' -openr,infile,infilename, /GET_LUN -line="" -comment="!" -interval = 0.d0 -numintervals = 0 -pix=-1.0d0 -gridsize=-1 -seed = 0 -maxcrat = 1.0d0 -shadedmaxhdefault = 1 -shadedminhdefault = 1 -shadedminh = 0.d0 -shademaxnh = 0.d0 - - -; Set required strings to unset value -notset="-----NOTSET----" -sfdfile = notset -impfile = notset -sfdcompare = notset -restart = notset -runtype = notset -popupconsole = notset -saveshaded = notset -saverego = notset -savepres = notset -savetruelist = notset -while (not EOF(infile)) do begin - readf,infile,line - if (~strcmp(line,comment,1)) then begin - substrings = strsplit(line,' ',/extract) - if strmatch(substrings(0),'pix',/fold_case) then reads,substrings(1),pix - if strmatch(substrings(0),'gridsize',/fold_case) then reads,substrings(1),gridsize - if strmatch(substrings(0),'seed',/fold_case) then reads,substrings(1),seed - if strmatch(substrings(0),'sfdfile',/fold_case) then reads,substrings(1),sfdfile - if strmatch(substrings(0),'impfile',/fold_case) then reads,substrings(1),impfile - if strmatch(substrings(0),'maxcrat',/fold_case) then reads,substrings(1),maxcrat - if strmatch(substrings(0),'sfdcompare',/fold_case) then reads,substrings(1),sfdcompare - if strmatch(substrings(0),'interval',/fold_case) then reads,substrings(1),interval - if strmatch(substrings(0),'numintervals',/fold_case) then reads,substrings(1),numintervals - if strmatch(substrings(0),'popupconsole',/fold_case) then reads,substrings(1),popupconsole - if strmatch(substrings(0),'saveshaded',/fold_case) then reads,substrings(1),saveshaded - if strmatch(substrings(0),'saverego',/fold_case) then reads,substrings(1),saverego - if strmatch(substrings(0),'savepres',/fold_case) then reads,substrings(1),savepres - if strmatch(substrings(0),'savetruelist',/fold_case) then reads,substrings(1),savetruelist - if strmatch(substrings(0),'runtype',/fold_case) then reads,substrings(1),runtype - if strmatch(substrings(0),'restart',/fold_case) then reads,substrings(1),restart - if strmatch(substrings(0),'shadedminh',/fold_case) then begin - reads,substrings(1),shadedminh - shadedminhdefault = 0 - endif - if strmatch(substrings(0),'shadedmaxh',/fold_case) then begin - reads,substrings(1),shadedmaxh - shadedmaxhdefault = 0 - endif - end -end -if interval le 0.0d0 then begin - print,'Invalid value for or missing variable INTERVAL in ' + infilename - stop -end -if numintervals le 0 then begin - print,'Invalid value for or missing variable NUMINTERVALS in ' + infilename - stop -end -if pix le 0.0d0 then begin - print,'Invalid value for or missing variable PIX in ' + infilename - stop -end -if gridsize le 0 then begin - print,'Invalid value for or missing variable GRIDSIZE in ' + infilename - stop -end -if seed eq 0 then begin - print,'Invalid value for or missing variable SEED in ' + infilename - stop -end -if strmatch(sfdfile,notset) then begin - print,'Invalid value for or missing variable SFDFILE in ' + infilename - stop -end -if strmatch(impfile,notset) then begin - print,'Invalid value for or missing variable IMPFILE in ' + infilename - stop -end -if strmatch(popupconsole,notset) then begin - print,'Invalid value for or missing variable POPUPCONSOLE in ' + infilename - stop -end -if strmatch(saveshaded,notset) then begin - print,'Invalid value for or missing variable SAVESHADED in ' + infilename - stop -end -if strmatch(saverego,notset) then begin - print,'Invalid value for or missing variable SAVEREGO in ' + infilename - stop -end -if strmatch(savepres,notset) then begin - print,'Invalid value for or missing variable SAVEPRES in ' + infilename - stop -end -if strmatch(savetruelist,notset) then begin - print,'Invalid value for or missing variable SAVETRUELIST in ' + infilename - stop -end -if strmatch(runtype,notset) then begin - print,'Invalid value for or missing variable RUNTYPE in ' + infilename - stop -end -if strmatch(restart,notset) then begin - print,'Invalid value for or missing variable RESTART in ' + infilename - stop -end - -free_lun,infile - -ph1 = dblarr(3,1) -if ~strmatch(sfdcompare,notset) then begin - cnum = file_lines(sfdcompare) - ph1 = dblarr(3,cnum) - openr,COMP,sfdcompare,/GET_LUN - readf,COMP,ph1 - close,COMP - free_lun,COMP -end -free_lun,infile - -end diff --git a/examples/morphology_test_cases/simple/ctem_io_read_old.pro b/examples/morphology_test_cases/simple/ctem_io_read_old.pro deleted file mode 100755 index a9013687..00000000 --- a/examples/morphology_test_cases/simple/ctem_io_read_old.pro +++ /dev/null @@ -1,45 +0,0 @@ -pro ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass -Compile_Opt DEFINT32 -openr,LUN,'surface_ejc.dat',/GET_LUN -readu,LUN,regolith -free_lun,LUN - -openr,LUN,'surface_dem.dat',/GET_LUN -readu,LUN,surface_dem -free_lun,LUN - -distl = file_lines('odistribution.dat') - 1 -pdistl = file_lines('pdistribution.dat') - 1 - -;read in observed cumulative distribution -odist = dblarr(6,distl) -line = "temp" -openr,LUN,'odistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,odist -close,LUN -free_lun,LUN - -;read in true cumulative distribution -tdist = dblarr(6,distl) -openr,LUN,'tdistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,tdist -close,LUN -free_lun,LUN - -;read in production function -pdist = dblarr(6,pdistl) -openr,LUN,'pdistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,pdist -close,LUN -free_lun,LUN - -;read in accumulated mass from file -openr,LUN,'impactmass.dat',/GET_LUN -readf,LUN,mass -close,LUN -free_lun,LUN - -end diff --git a/examples/morphology_test_cases/simple/ctem_window_display.pro b/examples/morphology_test_cases/simple/ctem_window_display.pro deleted file mode 100755 index d6edf5b9..00000000 --- a/examples/morphology_test_cases/simple/ctem_window_display.pro +++ /dev/null @@ -1,249 +0,0 @@ -pro ctem_window_display,ncount,totalimpacts,gridsize,pix,curyear,masstot,odist,pdist,tdist,ph1,surface_dem,regolith,map,popupconsole -; Produces the console window display. The array 'map' is used to generate the image on the right-hand side -Compile_Opt DEFINT32 - -; console output graphics resolution -minref = pix * 1.0d-4 -conresx = 1280 -;conresy = 0.758*conresx -profsize = 0.00 -conresy = (0.60 + profsize) * conresx -sun = 20.d0 ; sun angle for display - -minx = (pix / 3.0d0) * 1d-3 -maxx = 3 * pix * gridsize * 1d-3 -charfac = 1.6 ; character size multiplier - -if strmatch(popupconsole,'T',/fold_case) then begin - device, decomposed=0, retain=2 - thisDevice = !D.NAME - SET_PLOT, 'Z' - TVLCT, red, green, blue, /GET - SET_PLOT, thisDevice - !P.MULTI = [0, 1, 2] - Window, 0, xsize=conresx, ysize=conresy -endif else begin - SET_PLOT, 'Z', /COPY - device, set_resolution=[conresx,conresy],decomposed=0, Z_Buffer=0 - TVLCT, red, green, blue, /GET - !P.MULTI = [0, 1, 2] - erase -endelse - -;set up first color scale -loadct, 0 - -;strings for display -time = 'Time = ' -timeunit = ' yr' -timp = 'Total impacts (dotdash) = ' -tcrt = 'Total craters (line) = ' -ocrt = 'Countable craters (bold) = ' -epwr = 'Mean regolith depth = ' -mtot = 'Impacted mass = ' -c1lab = 'Min. Elevation' -c2lab = 'Mean Elevation' -c3lab = 'Max. Elevation' - -maxelev = max(surface_dem) -minelev = min(surface_dem) -medelev = mean(surface_dem) -c1 = string(minelev, format = '(F9.1)') + ' m' -c2 = string(medelev, format = '(F9.1)') + ' m' -c3 = string(maxelev, format = '(F9.1)') + ' m' -tslp = mean(regolith) - -;geometric saturation -geom = dblarr(2,2) -geomem = dblarr(2,2) -geomep = dblarr(2,2) -geomel = dblarr(2,2) -geom(0,0) = minx -geom(0,1) = maxx -geom(1,*) = 3.12636d0 -geomem(0,0) = minx -geomem(0,1) = maxx -geomem(1,*) = 0.156318d0 -geomep(0,0) = minx -geomep(0,1) = maxx -geomep(1,*) = 0.312636d0 -geomel(0,0) = minx -geomel(0,1) = maxx -geomel(1,*) = 0.0312636d0 - -; Remove zeros -nz = where(odist(5,*) ne 0.0,count) -if (count gt 0) then begin - odistnz = dblarr(6,count) - odistnz(*,*)= odist(*,nz) -endif else begin - odistnz = odist -endelse - -nz = where(tdist(5,*) ne 0.0,count) -if (count gt 0) then begin - tdistnz = dblarr(6,count) - tdistnz(*,*)= tdist(*,nz) -endif else begin - tdistnz = tdist -endelse - -nz = where(pdist(5,*) ne 0.0,count) -if (count gt 0) then begin - pdistnz = dblarr(6,count) - pdistnz(*,*)= pdist(*,nz) - -endif else begin - pdistnz = pdist -endelse - -; create r-plot array containing exactly 1 crater per bin -area = (gridsize * pix * 1d-3)^2 -plo = 1 -while (sqrt(2.0d0)^plo gt minx) do begin - plo = plo - 1 -endwhile -phi = plo + 1 -while (sqrt(2.0d0)^phi lt maxx) do begin - phi = phi + 1 -endwhile -n = phi - plo -sdist = dblarr(6,n + 1) -p = plo -for i=0,n do begin - sdist(0,i) = sqrt(2.d0)^p - sdist(1,i) = sqrt(2.d0)^(p+1) - sdist(2,i) = sqrt(sdist(0,i) * sdist(1,i)) - sdist(3,i) = 1.0d0 - sdist(5,i) = (sdist(2,i))^3 / (area * (sdist(1,i) - sdist(0,i))) - p = p + 1 -endfor -sdist(4,*) = reverse(total(sdist(3,*),/cumulative),2) - -plot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=0, color=255, thick=2.0, $ - TITLE='Crater Distribution R-Plot', charsize=charfac*conresy/720, $ - XTITLE='Crater Diameter (km)', $ - XRANGE=[minx,maxx], /XLOG, XSTYLE=1, $ - YTITLE='R Value', $ - YRANGE=[5.0e-4,5.0e0], /YLOG, YSTYLE=1, $ - /device, pos = [0.085*conresx,(0.25 + profsize)*conresy,0.44*conresx,0.85*conresy] - -Dfac = sqrt(sqrt(2.0d0)) - -;display observed crater distribution -oplot, tdistnz(2,*)*1.0d-3, tdistnz(5,*), line=0, color=255, thick=1.0 -oplot, geom(0,*), geom(1,*), line=2, color=255, thick=1.0 -oplot, geomem(0,*), geomem(1,*), line=1, color=255, thick=1.0 -oplot, geomep(0,*), geomep(1,*), line=1, color=255, thick=1.0 -oplot, geomel(0,*), geomel(1,*), line=1, color=255, thick=1.0 -oplot, pdistnz(2,*)*1.0d-3, pdistnz(5,*), line=3, color=255, thick=1.0 -oplot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=1, color=255, thick=1.0 -oplot, sdist(0,*), sdist(5,*), line=1, color=255, thick=1.0 -oplot, ph1(0,*)*Dfac*1.0d-3, ph1(1,*), psym=1, color=255, thick=1.0 -;oplot, ph2(0,*), ph2(1,*), psym=4, color=255, thick=1.0 -;oplot, ph3(0,*), ph3(1,*), psym=5, color=255, thick=1.0 - -; set up profile display -surfpos = dblarr(gridsize) -surfpro = dblarr(gridsize) -surfhpro = dblarr(gridsize) -surfrpro = dblarr(gridsize) -for k = 0,gridsize-1 do begin - surfpos(k) = (-0.5d0*(gridsize-1) + double(k)) * pix -endfor -surfpro(*) = surface_dem(*,gridsize/2-1) -surfhpro(*) = regolith(*,gridsize/2-1) -surfrpro(*) = surfpro(*) - surfhpro(*) - -; set up profile -;maxelevp = max(surfpro) -;minelevp = min(surfpro) -;medelevp = mean(surfpro) -;vertrange = 1.5 * abs(maxelevp-minelevp) -;vertadd = 0.5d0 * (vertrange - abs(maxelevp-minelevp)) -;horzrange = vertrange * 5.86666666667d0 -;if (horzrange gt (pix*gridsize)) then horzrange = pix*gridsize -;plot, surfpos(*)/1.0d3, surfpro(*)/1.0d3, line=0, color=255, thick=1.0, $ -; TITLE='Matrix Cross-Section', charsize=1.0, $ -; XTITLE='Horizontal Position (km)', $ -; XRANGE=[(-1.0d0*horzrange/2.0d3),(horzrange/2.0d3)], XSTYLE=1, $ -; YTITLE='Elevation (km)', $ -; YRANGE=[((minelevp - vertadd)/1.0d3),((maxelevp + vertadd)/1.0d3)], YSTYLE=1, $ -; /device, pos = [0.063*conresx,0.049*conresy,0.99*conresx,0.26*conresy] -;oplot, surfpos(*)*1.0d-3, surfrpro(*)*1.0d-3, line=0, color=255, thick=1.0 - -;display text -dum = string(format='(E10.4)', curyear) -parts = strsplit(dum, 'E', /extract) -fcuryear = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) + ' yr' -ftimp = string(totalimpacts, format = '(I13)') -ftcnt = string(tdist(4,0), format = '(I13)') -focnt = string(odist(4,0), format = '(I13)') -ftslp = string(tslp, format = '(F13.3)') + ' m' - - -dum = string(format='(E10.4)',masstot) -parts = strsplit(dum, 'E', /extract) -fmtot = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) + ' kg' - -; Display information text below the R-plot -texttop = 0.15 + profsize -textspc = 0.035 -textleft = 0.05*conresx -textbreak = 0.25*conresx -xyouts, textleft, (texttop - 0*textspc)*conresy, time, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 1*textspc)*conresy, timp, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 2*textspc)*conresy, tcrt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 3*textspc)*conresy, ocrt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 4*textspc)*conresy, mtot, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 0*textspc)*conresy, fcuryear, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 1*textspc)*conresy, ftimp, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 2*textspc)*conresy, ftcnt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 3*textspc)*conresy, focnt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 4*textspc)*conresy, fmtot, color=255, charsize=charfac*conresy/720., /device - -; Display information text above the R-plot -xyouts, 0.0368*conresx, 0.972*conresy, c1lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.195*conresx, 0.972*conresy, c2lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.353*conresx, 0.972*conresy, c3lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.0368*conresx, 0.944*conresy, c1, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.195*conresx, 0.944*conresy, c2, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.353*conresx, 0.944*conresy, c3, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.100*conresx, 0.917*conresy, epwr, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.278*conresx, 0.917*conresy, ftslp, color=255, charsize=charfac*conresy/720., /device - -;print to screen -print, ncount, ' time = ', curyear -;print, ncount, ' tot impacts = ', tdist -;print, ncount, ' tot craters = ', totalimpacts -;print, ncount, ' obs craters = ', ocrcnt -;print, ncount, ' regolith = ', tslp -;print, ncount, ' prod R = ', mean(prval(1,*)) - -;draw box around the main surface display & fill -displaysize = floor(0.53*conresx) ; size of displayed surface -surfxpos = floor(0.462*conresx) -surfypos = floor((0.05 + profsize)*conresy) -xbox = [surfxpos - 1,surfxpos - 1,surfxpos + displaysize,surfxpos + displaysize,surfxpos - 1] -ybox = [surfypos - 1,surfypos + displaysize,surfypos + displaysize,surfypos - 1,surfypos - 1] -plotS, xbox, ybox, /device, color=255 - -; for display -mapscaled = congrid(map,3,displaysize,displaysize,/interp) - -tv, mapscaled, surfxpos, surfypos, xsize=displaysize, ysize=displaysize, true=1, /device - -; ---------- saving window ---------- - -; save console window -fnum = string(ncount,format='(I6.6)') -; print screen to JPEG file -if (file_test('console',/DIRECTORY) eq 0) then begin - file_mkdir,'console' -endif -print, ncount, ' saving window' -fname = 'console/console' + fnum + '.jpg' -dwin = tvrd(true=1) -write_jpeg, fname, dwin, true=1, quality=90 - -end diff --git a/examples/ray-generation-test-environment/bar.pro b/examples/ray-generation-test-environment/bar.pro deleted file mode 100644 index 11ec7af0..00000000 --- a/examples/ray-generation-test-environment/bar.pro +++ /dev/null @@ -1,15 +0,0 @@ -pro bar -device, decomposed=1, retain=2 -set_plot, 'PS' -DEVICE,/ENCAPSULATED,filename='bar.eps',/INCHES,xsize=2.0,ysize=3.0,font_size=18 -thisDevice = !D.NAME -loadct, 33 -TVLCT, 255, 255, 255, 254 ; White color - !P.Color = '000000'xL - !P.Background = 'FFFFFF'xL - - ;Window, 0, xsize=150, ysize=1000 -cgColorbar,/Vertical, COLOR='black',MAXRANGE=100,MINRANGE=-400, font=0 ,position=[0.60,0.1,0.95,0.95] -;dwin = tvrd(true=1) -;write_jpeg, 'bar.jpg', dwin, true=1, quality=90 -end diff --git a/examples/ray-generation-test-environment/ctem_driver.pro b/examples/ray-generation-test-environment/ctem_driver.pro deleted file mode 100644 index bba1994b..00000000 --- a/examples/ray-generation-test-environment/ctem_driver.pro +++ /dev/null @@ -1,233 +0,0 @@ -pro ctem_driver - -;------------------------------------------------------------------------- -; Jim Richardson, Arecibo Observatory -; David Minton, Purdue University Dept. of Earth, Atmospheric, & Planetary Sciences -; July 2014 -; Cratered Terrain Evolution Model display module -; -; Inputs are read in from the ctem.in file -; -;------------------------------------------------------------------------- -;------------- Initial Setup ---------------- -;------------------------------------------------------------------------- -Compile_Opt DEFINT32 -!EXCEPT=2 - -; ----------- input file ----------------------- -infilename = 'ctem.in' -DATFILE='ctem.dat' - -; ---------- reading input files ---------- -seedarr = lon64arr(100) -seedn = 1 -totalimpacts = long64(0) -ncount = long64(0) -curyear = 0.d0 -restart = "F" -fracdone = 1.0d0 -masstot = 0.d0 - -ctem_io_read_input,infilename,interval,numintervals,gridsize,pix,seed,numlayers,sfdfile,impfile,maxcrat,ph1,shadedmaxhdefault,shadedminhdefault,shadedminh,shadedmaxh,restart,runtype,popupconsole,saveshaded,saverego,savepres,savetruelist,tallycadence - -seedarr(0) = seed -area = (gridsize * pix)^2 - -;read input data -pnum = file_lines(impfile) -production = dblarr(2,pnum) -productionfunction = dblarr(2,pnum) -openr,LUN,impfile,/GET_LUN -readf,LUN,productionfunction -free_lun,LUN - -;create impactor production population -production(0,*) = productionfunction(0,*) -production(1,*) = productionfunction(1,*)*area*interval - -;write out corrected production population -openw,1,sfdfile -printf,1,production -close,1 -free_lun,1 - -;set up cratering surface grid and display-only grid -surface_dem = dblarr(gridsize,gridsize) -regolith = dblarr(gridsize,gridsize) - -;set up temporary distribution bins -distl = 1 -pdistl = 1 -odist = dblarr(6,distl) -tdist = dblarr(6,distl) -pdist = dblarr(6,pdistl) -pdisttotal = dblarr(6,pdistl) - -datformat = "(I17,1X,I12,1X,E19.12,1X,A1,1X,I12,1X,F9.6,1X,E19.12)" - - -if strmatch(restart,'F',/fold_case) then begin ; Start with a clean slate - print, 'Starting a new run' - curyear = 0.0d0 - totalimpacts = 0 - masstot = 0.d0 - fracdone = 1.0d0 - - if strmatch(runtype,'statistical',/fold_case) then begin - ncount = 1 - openw,LUN,DATFILE,/GET_LUN - printf,LUN,totalimpacts,ncount,curyear,restart,tallycadence,fracdone,masstot,format=datformat - for n=0,seedn-1 do begin - printf,LUN,seedarr(n),format='(I12)' - endfor - free_lun,LUN - endif else begin - ncount = 0 - endelse - - surface_dem(*,*) = 0.0d0 - regolith(*,*) = 0.0d0 - - file_delete, 'tdistribution.dat',/allow_nonexistent - -endif else begin ; continue an old run - print, 'Continuing a previous run' - - ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass - - ;read in constants file - openr,LUN,DATFILE,/GET_LUN - readf,LUN,totalimpacts,ncount,curyear,restart,tallycadence,fracdone,masstot,format=datformat - seedn = 0 - while ~ eof(LUN) do begin - readf,LUN,iseed - seedarr(seedn) = long64(iseed) - seedn=seedn+1 - endwhile - -endelse - -openw,FRACDONEFILE,'fracdone.dat',/GET_LUN -openw,REGODEPTHFILE,'regolithdepth.dat',/GET_LUN - -;------------------------------------------------------------------------- -; ---------- begin loops ---------- -;------------------------------------------------------------------------- -print, 'Beginning loops' - -;define number of loop iterations and begin -;numintervals=ceil(endyear/interval)-ncount -while (ncount le numintervals) do begin - - - ; ---------- creating crater population ---------- - if (ncount gt 0) then begin - - fnum = string(ncount,format='(I6.6)') - if (file_test('misc',/DIRECTORY) eq 0) then begin - file_mkdir,'misc' - endif - ; save a copy of the ctem.dat file - fname = 'misc/ctem_' + fnum + '.dat' - file_copy, 'ctem.dat', fname, /OVERWRITE - - print, ncount, ' Calling FORTRAN routine' - ;call fortran program to create & count craters - spawn, './CTEM',/noshell - - ; ---------- reading FORTRAN output ---------- - print, ncount, ' Reading FORTRAN output' - ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass - - ;read in constants file - openr,LUN,DATFILE,/GET_LUN - readf,LUN,totalimpacts,ncount,curyear,restart,tallycadence,fracdone,masstot,format=datformat - seedn = 0 - while ~ eof(LUN) do begin - readf,LUN,iseed - seedarr(seedn) = long64(iseed) - seedn = seedn + 1 - endwhile - free_lun,LUN - - curyear = curyear + fracdone * interval - masstot = masstot + mass - printf,FRACDONEFILE,fracdone,curyear - flush,FRACDONEFILE - - printf,REGODEPTHFILE,curyear,mean(regolith),max(regolith),min(regolith) - flush,REGODEPTHFILE - - ;save a copy of the binned observed crater distribution - if (file_test('dist',/DIRECTORY) eq 0) then begin - file_mkdir,'dist' - endif - fname = 'dist/odist_' + fnum + '.dat' - file_copy, 'odistribution.dat', fname, /OVERWRITE - - ; save a copy of the cumulative observed crater distribution - fname = 'dist/ocum_' + fnum + '.dat' - file_copy, 'ocumulative.dat', fname, /OVERWRITE - - ;save a copy of the binned true distribution - fname = 'dist/tdist_' + fnum + '.dat' - file_copy, 'tdistribution.dat', fname, /OVERWRITE - - ;save a copy of the binned idealized production function - fname = 'dist/pdist_' + fnum + '.dat' - file_copy, 'pdistribution.dat', fname, /OVERWRITE - - ; save a copy of the cumulative true crater distribution if the user requests it - if strmatch(savetruelist,'T',/fold_case) then begin - fname = 'dist/tcum_' + fnum + '.dat' - file_copy, 'tcumulative.dat', fname, /OVERWRITE - endif - - ; save a copy of the impacted mass - fname = 'misc/mass_' + fnum + '.dat' - file_copy, 'impactmass.dat', fname, /OVERWRITE - - - endif - - ; Get the accumulated production function - pdisttotal = pdist - pdisttotal(3:5,*) = pdist(3:5,*) * curyear / interval - - ; ---------- displaying results ---------- - print, ncount, ' Displaying results' - - ctem_image_dem,ncount,gridsize,pix,surface_dem,surface_dem_image - if strmatch(saverego,'T',/fold_case) then ctem_image_regolith,ncount,gridsize,pix,regolith,regolith_image - if strmatch(saveshaded,'T',/fold_case) then begin - if (shadedminhdefault eq 1) then shadedminh = min(surface_dem) - if (shadedmaxhdefault eq 1) then shadedmaxh = max(surface_dem) - ctem_image_shaded_relief,ncount,gridsize,pix,surface_dem,surface_dem,shadedminh,shadedmaxh,'shaded',shaded_image - endif - if strmatch(savepres,'T',/fold_case) then ctem_image_presentation,ncount,gridsize,pix,curyear,odist,pdisttotal,tdist,ph1,surface_dem_image - ctem_window_display,ncount,totalimpacts,gridsize,pix,curyear,masstot,odist,pdisttotal,tdist,ph1,surface_dem,regolith,surface_dem_image,popupconsole - - ncount = ncount + 1 - - ;write out the current data file - if (strmatch(runtype,'statistical',/fold_case)) || (ncount eq 1) then begin - restart = 'F' - curyear = 0.0d0 - totalimpacts = 0 - masstot = 0.d0 - file_delete, 'tdistribution.dat',/allow_nonexistent - endif else begin - restart = 'T' - endelse - - openw,LUN,DATFILE,/GET_LUN - printf,LUN,totalimpacts,ncount,curyear,restart,tallycadence,fracdone,masstot,format=datformat - for n=0,seedn-1 do begin - printf,LUN,seedarr(n),format='(I12)' - endfor - free_lun,LUN -endwhile -free_lun,FRACDONEFILE -free_lun,REGODEPTHFILE - -end diff --git a/examples/ray-generation-test-environment/ctem_image_dem.pro b/examples/ray-generation-test-environment/ctem_image_dem.pro deleted file mode 100755 index ad6fbd7e..00000000 --- a/examples/ray-generation-test-environment/ctem_image_dem.pro +++ /dev/null @@ -1,41 +0,0 @@ -pro ctem_image_dem,ncount,gridsize,pix,surface_dem,surface_dem_image -; Generates the shaded surface DEM image and saves it as a jpeg output image in the 'surf' directory -; outputs surface_dem_arr, which may be scaled to use as a console image - -; This code is for reading in the x-y positions from the cumulative distribution and separating out into layers -; so that the tallied craters can be drawn as circles -;!PATH = Expand_Path('+/home/campus/daminton/coyote/') + ':' + !PATH - -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -TVLCT, red, green, blue, /GET - -sun = 20.d0 -radsun = sun * !dtor - -surface_dem_arr = dblarr(gridsize,gridsize) - -surface_dem_arr=surface_dem-shift(surface_dem,0,1) -surface_dem_arr = (0.5d0*!dpi) + atan(surface_dem_arr,pix) ; Get average slope -surface_dem_arr = abs(surface_dem_arr - radsun < 0.5d0*!dpi) ; incident angle -surface_dem_arr = 254.0d0 * cos(surface_dem_arr) ; shaded relief surface - -tv, surface_dem_arr, 0, 0, xsize=gridsize, ysize=gridsize, /device -print,'plotting' - -surface_dem_image = TVRD(True=1) -Set_Plot, thisDevice - -; save surface display -if (file_test('surf',/DIRECTORY) eq 0) then begin - file_mkdir,'surf' -endif -fnum = string(ncount,format='(I6.6)') -fname = 'surf/surf' + fnum + '.jpg' - -write_jpeg, fname, surface_dem_image, true=1, quality=100 - -end diff --git a/examples/ray-generation-test-environment/ctem_image_presentation.pro b/examples/ray-generation-test-environment/ctem_image_presentation.pro deleted file mode 100755 index 05a7d65a..00000000 --- a/examples/ray-generation-test-environment/ctem_image_presentation.pro +++ /dev/null @@ -1,143 +0,0 @@ -pro ctem_image_presentation,ncount,gridsize,pix,curyear,odist,pdist,tdist,ph1,map -; Generates the simplified version of the console display for use in presentations -; Plots the R-plot on the left and the image map on the right - -; presentation graphics -presresx = 1024 -presresy = 0.6*presresx -area = (gridsize * pix)^2 - -minx = (pix / 3.0d0) * 1d-3 -maxx = 3 * pix * gridsize * 1d-3 - -;strings for display -dum = string(format='(E10.4)', curyear) -parts = strsplit(dum, 'E', /extract) -fcuryear = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) -time = 'Time = ' -timeunit = ' yr' - -if (file_test('presentation',/DIRECTORY) eq 0) then begin - file_mkdir,'presentation' -endif - -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[presresx,presresy],Set_Pixel_Depth=24, Decomposed=0 -loadct, 0 -TVLCT, red, green, blue, /GET - -;geometric saturation -geom = dblarr(2,2) -geomem = dblarr(2,2) -geomep = dblarr(2,2) -geomel = dblarr(2,2) -geom(0,0) = minx -geom(0,1) = maxx -geom(1,*) = 3.12636d0 -geomem(0,0) = minx -geomem(0,1) = maxx -geomem(1,*) = 0.156318d0 -geomep(0,0) = minx -geomep(0,1) = maxx -geomep(1,*) = 0.312636d0 -geomel(0,0) = minx -geomel(0,1) = maxx -geomel(1,*) = 0.0312636d0 - -; Remove zeros -nz = where(odist(5,*) ne 0.0,count) -if (count gt 0) then begin - odistnz = dblarr(6,count) - odistnz(*,*)= odist(*,nz) -endif else begin - odistnz = odist -endelse - -nz = where(tdist(5,*) ne 0.0,count) -if (count gt 0) then begin - tdistnz = dblarr(6,count) - tdistnz(*,*)= tdist(*,nz) -endif else begin - tdistnz = tdist -endelse - -nz = where(pdist(5,*) ne 0.0,count) -if (count gt 0) then begin - pdistnz = dblarr(6,count) - pdistnz(*,*)= pdist(*,nz) -endif else begin - pdistnz = pdist -endelse - -; create r-plot array containing exactly 1 crater per bin -area = (gridsize * pix * 1d-3)^2 -plo = 1 -while (sqrt(2.0d0)^plo gt minx) do begin - plo = plo - 1 -endwhile -phi = plo + 1 -while (sqrt(2.0d0)^phi lt maxx) do begin - phi = phi + 1 -endwhile -n = phi - plo -sdist = dblarr(6,n + 1) -p = plo -for i=0,n do begin - sdist(0,i) = sqrt(2.d0)^p - sdist(1,i) = sqrt(2.d0)^(p+1) - sdist(2,i) = sqrt(sdist(0,i) * sdist(1,i)) - sdist(3,i) = 1.0d0 - sdist(5,i) = (sdist(2,i))^3 / (area * (sdist(1,i) - sdist(0,i))) - p = p + 1 -endfor -sdist(4,*) = reverse(total(sdist(3,*),/cumulative),2) - - -plot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=0, color=255, thick=2.0, $ - TITLE='Crater Distribution R-Plot', charsize=1.2, $ - XTITLE='Crater Diameter (km)', $ - XRANGE=[minx,maxx], /XLOG, XSTYLE=1, $ - YTITLE='R Value', $ - YRANGE=[5.0e-4,5.0e0], /YLOG, YSTYLE=1, $ - /device, pos = [0.12,0.12,0.495,0.495]*presresx - -Dfac = sqrt(sqrt(2.0d0)) - -;display observed crater distribution -oplot, tdistnz(2,*)*1.0d-3, tdistnz(5,*), line=0, color=255, thick=1.0 -;oplot, geom(0,*), geom(1,*), line=2, color=255, thick=1.0 -oplot, geomem(0,*), geomem(1,*), line=1, color=255, thick=1.0 -oplot, geomep(0,*), geomep(1,*), line=1, color=255, thick=1.0 -;oplot, geomel(0,*), geomel(1,*), line=1, color=255, thick=1.0 -oplot, pdistnz(2,*)*1.0d-3, pdistnz(5,*), line=3, color=255, thick=1.0 -oplot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=1, color=255, thick=1.0 -oplot, sdist(0,*), sdist(5,*), line=1, color=255, thick=1.0 -oplot, ph1(0,*)*Dfac*1.0d-3, ph1(1,*), psym=1, color=255, thick=1.0 -;oplot, ph2(0,*), ph2(1,*), psym=4, color=255, thick=1.0 -;oplot, ph3(0,*), ph3(1,*), psym=5, color=255, thick=1.0 - -;draw box around the main surface display & fill -displaysize = floor(0.45*presresx) ; size of displayed surface -surfxpos = floor(0.520*presresx) -surfypos = floor(0.12*presresy) -xbox = [surfxpos - 1,surfxpos - 1,surfxpos + displaysize,surfxpos + displaysize,surfxpos - 1] -ybox = [surfypos - 1,surfypos + displaysize,surfypos + displaysize,surfypos - 1,surfypos - 1] -plotS, xbox, ybox, /device, color=255 - -mapscaled = congrid(map,3,displaysize,displaysize,/interp) - -;mapscaled=congrid(map,displaysize,displaysize) ; scale image -tv, mapscaled, surfxpos, surfypos, xsize=displaysize, ysize=displaysize, true=1, /device - -xyouts, 0.310*presresx, 0.04*presresy, time + fcuryear + timeunit, color=255, charsize=2*presresy/720., /device - -snapshot = TVRD(True=1) -Set_Plot, thisDevice -fnum = string(ncount,format='(I6.6)') -fname = 'presentation/presentation' + fnum + '.jpg' -Write_JPEG, fname, snapshot, True=1, Quality=90 - - -end diff --git a/examples/ray-generation-test-environment/ctem_image_regolith.pro b/examples/ray-generation-test-environment/ctem_image_regolith.pro deleted file mode 100755 index 8019b0c7..00000000 --- a/examples/ray-generation-test-environment/ctem_image_regolith.pro +++ /dev/null @@ -1,33 +0,0 @@ -pro ctem_image_regolith,ncount,gridsize,pix,regolith,regolith_image -; Generates the regolith depth map image and saves it as a jpeg output image in the 'rego' directory -; outputs dregolith, which may be scaled to use as a console image -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -loadct, 39 -TVLCT, red, green, blue, /GET - -minref = pix * 1.0d-8 -regolith_scaled = dblarr(gridsize,gridsize) -maxreg = max(regolith) -minreg = min(regolith) -if minreg lt minref then minreg = minref -if maxreg lt minref then maxreg = minref + 1.0d30 -regolith_scaled = regolith > minreg -regolith_scaled = 254.0d0 * ((alog(regolith_scaled) - alog(minreg)) / (alog(maxreg) - alog(minreg))) - -; save regolith display -tv, regolith_scaled, 0, 0, xsize=gridsize, ysize=gridsize, /device -regolith_image = TVRD(True=1) -Set_Plot, thisDevice - -if (file_test('rego',/DIRECTORY) eq 0) then begin - file_mkdir,'rego' -endif -fnum = string(ncount,format='(I6.6)') -fname = 'rego/rego' + fnum + '.jpg' -write_jpeg, fname, regolith_image, true=1, quality=100 - -end diff --git a/examples/ray-generation-test-environment/ctem_image_shaded_relief.pro b/examples/ray-generation-test-environment/ctem_image_shaded_relief.pro deleted file mode 100755 index 73986f84..00000000 --- a/examples/ray-generation-test-environment/ctem_image_shaded_relief.pro +++ /dev/null @@ -1,52 +0,0 @@ -pro ctem_image_shaded_relief,ncount,gridsize,pix,surface_dem,height_vals,minh,maxh,dirname,shaded_image -; Generates the shaded depth map image and saves it as a jpeg output image in the 'rego' directory -; outputs dshaded, which may be scaled to use as a console image -; Uses the array height_vals for the color -Compile_Opt DEFINT32 -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[gridsize,gridsize],Set_Pixel_Depth=24, Decomposed=0 -loadct, 33 -TVLCT, red, green, blue, /GET - -light=[[1,1,1],[0,0,0],[-1,-1,-1]] - -; convolution of the dem with the 3x3 matrix - -shaded=bytscl(convol(float(surface_dem),float(light))) -if max(shaded) eq 0 then shaded=255 - -; scale the dem to the height -if (minh gt maxh) then begin - tmp = minh - minh = maxh - maxh = tmp -endif - -demscaled = ((height_vals - minh) > 0.0) < (maxh-minh) -if ((maxh - minh) eq 0.0) then begin - demscaled = demscaled * 0.0 -endif else begin - demscaled = demscaled/(maxh-minh)*255.0 -endelse - -tv, demscaled, 0, 0, xsize=gridsize, ysize=gridsize, /device -shaded_image = TVRD(True=1) -shadedscl =float(shaded)/255.0 -shaded_imagearr = dblarr(3,gridsize,gridsize) -shaded_imagearr(0,*,*) = float(shaded_image(0,*,*)) * shadedscl(*,*) -shaded_imagearr(1,*,*) = float(shaded_image(1,*,*)) * shadedscl(*,*) -shaded_imagearr(2,*,*) = float(shaded_image(2,*,*)) * shadedscl(*,*) -shaded_image=round(shaded_imagearr) -Set_Plot, thisDevice - -if (file_test(dirname,/DIRECTORY) eq 0) then begin - file_mkdir,dirname -endif - -fnum = string(ncount,format='(I6.6)') -fname = dirname + '/' + dirname + fnum + '.jpg' -write_jpeg,fname,shaded_image,true=1,quality=90 - -end diff --git a/examples/ray-generation-test-environment/ctem_io_read_input.pro b/examples/ray-generation-test-environment/ctem_io_read_input.pro deleted file mode 100644 index 080b5b01..00000000 --- a/examples/ray-generation-test-environment/ctem_io_read_input.pro +++ /dev/null @@ -1,133 +0,0 @@ -pro ctem_io_read_input,infilename,interval,numintervals,gridsize,pix,seed,numlayers,sfdfile,impfile,maxcrat,ph1,shadedmaxhdefault,shadedminhdefault,shadedminh,shadedmaxh,restart,runtype,popupconsole,saveshaded,saverego,savepres,savetruelist,tallycadence -Compile_Opt DEFINT32 -print, 'Reading input file' -openr,infile,infilename, /GET_LUN -line="" -comment="!" -interval = 0.d0 -numintervals = 0 -pix=-1.0d0 -gridsize=-1 -seed = 0 -maxcrat = 1.0d0 -shadedmaxhdefault = 1 -shadedminhdefault = 1 -shadedminh = 0.d0 -shademaxnh = 0.d0 -tallycadence = long64(5000) - - -; Set required strings to unset value -notset="-----NOTSET----" -sfdfile = notset -impfile = notset -sfdcompare = notset -restart = notset -runtype = notset -popupconsole = notset -saveshaded = notset -saverego = notset -savepres = notset -savetruelist = notset -while (not EOF(infile)) do begin - readf,infile,line - if (~strcmp(line,comment,1)) then begin - substrings = strsplit(line,' ',/extract) - if strmatch(substrings(0),'pix',/fold_case) then reads,substrings(1),pix - if strmatch(substrings(0),'gridsize',/fold_case) then reads,substrings(1),gridsize - if strmatch(substrings(0),'seed',/fold_case) then reads,substrings(1),seed - if strmatch(substrings(0),'sfdfile',/fold_case) then reads,substrings(1),sfdfile - if strmatch(substrings(0),'impfile',/fold_case) then reads,substrings(1),impfile - if strmatch(substrings(0),'maxcrat',/fold_case) then reads,substrings(1),maxcrat - if strmatch(substrings(0),'sfdcompare',/fold_case) then reads,substrings(1),sfdcompare - if strmatch(substrings(0),'interval',/fold_case) then reads,substrings(1),interval - if strmatch(substrings(0),'numintervals',/fold_case) then reads,substrings(1),numintervals - if strmatch(substrings(0),'popupconsole',/fold_case) then reads,substrings(1),popupconsole - if strmatch(substrings(0),'saveshaded',/fold_case) then reads,substrings(1),saveshaded - if strmatch(substrings(0),'saverego',/fold_case) then reads,substrings(1),saverego - if strmatch(substrings(0),'savepres',/fold_case) then reads,substrings(1),savepres - if strmatch(substrings(0),'savetruelist',/fold_case) then reads,substrings(1),savetruelist - if strmatch(substrings(0),'runtype',/fold_case) then reads,substrings(1),runtype - if strmatch(substrings(0),'restart',/fold_case) then reads,substrings(1),restart - if strmatch(substrings(0),'tallystart',/fold_case) then reads,substrings(1),tallycadence - if strmatch(substrings(0),'shadedminh',/fold_case) then begin - reads,substrings(1),shadedminh - shadedminhdefault = 0 - endif - if strmatch(substrings(0),'shadedmaxh',/fold_case) then begin - reads,substrings(1),shadedmaxh - shadedmaxhdefault = 0 - endif - end -end -if interval le 0.0d0 then begin - print,'Invalid value for or missing variable INTERVAL in ' + infilename - stop -end -if numintervals le 0 then begin - print,'Invalid value for or missing variable NUMINTERVALS in ' + infilename - stop -end -if pix le 0.0d0 then begin - print,'Invalid value for or missing variable PIX in ' + infilename - stop -end -if gridsize le 0 then begin - print,'Invalid value for or missing variable GRIDSIZE in ' + infilename - stop -end -if seed eq 0 then begin - print,'Invalid value for or missing variable SEED in ' + infilename - stop -end -if strmatch(sfdfile,notset) then begin - print,'Invalid value for or missing variable SFDFILE in ' + infilename - stop -end -if strmatch(impfile,notset) then begin - print,'Invalid value for or missing variable IMPFILE in ' + infilename - stop -end -if strmatch(popupconsole,notset) then begin - print,'Invalid value for or missing variable POPUPCONSOLE in ' + infilename - stop -end -if strmatch(saveshaded,notset) then begin - print,'Invalid value for or missing variable SAVESHADED in ' + infilename - stop -end -if strmatch(saverego,notset) then begin - print,'Invalid value for or missing variable SAVEREGO in ' + infilename - stop -end -if strmatch(savepres,notset) then begin - print,'Invalid value for or missing variable SAVEPRES in ' + infilename - stop -end -if strmatch(savetruelist,notset) then begin - print,'Invalid value for or missing variable SAVETRUELIST in ' + infilename - stop -end -if strmatch(runtype,notset) then begin - print,'Invalid value for or missing variable RUNTYPE in ' + infilename - stop -end -if strmatch(restart,notset) then begin - print,'Invalid value for or missing variable RESTART in ' + infilename - stop -end - -free_lun,infile - -ph1 = dblarr(3,1) -if ~strmatch(sfdcompare,notset) then begin - cnum = file_lines(sfdcompare) - ph1 = dblarr(3,cnum) - openr,COMP,sfdcompare,/GET_LUN - readf,COMP,ph1 - close,COMP - free_lun,COMP -end -free_lun,infile - -end diff --git a/examples/ray-generation-test-environment/ctem_io_read_old.pro b/examples/ray-generation-test-environment/ctem_io_read_old.pro deleted file mode 100644 index a9013687..00000000 --- a/examples/ray-generation-test-environment/ctem_io_read_old.pro +++ /dev/null @@ -1,45 +0,0 @@ -pro ctem_io_read_old,gridsize,surface_dem,regolith,odist,tdist,pdist,mass -Compile_Opt DEFINT32 -openr,LUN,'surface_ejc.dat',/GET_LUN -readu,LUN,regolith -free_lun,LUN - -openr,LUN,'surface_dem.dat',/GET_LUN -readu,LUN,surface_dem -free_lun,LUN - -distl = file_lines('odistribution.dat') - 1 -pdistl = file_lines('pdistribution.dat') - 1 - -;read in observed cumulative distribution -odist = dblarr(6,distl) -line = "temp" -openr,LUN,'odistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,odist -close,LUN -free_lun,LUN - -;read in true cumulative distribution -tdist = dblarr(6,distl) -openr,LUN,'tdistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,tdist -close,LUN -free_lun,LUN - -;read in production function -pdist = dblarr(6,pdistl) -openr,LUN,'pdistribution.dat',/GET_LUN -readf,LUN,line -readf,LUN,pdist -close,LUN -free_lun,LUN - -;read in accumulated mass from file -openr,LUN,'impactmass.dat',/GET_LUN -readf,LUN,mass -close,LUN -free_lun,LUN - -end diff --git a/examples/ray-generation-test-environment/ctem_window_display.pro b/examples/ray-generation-test-environment/ctem_window_display.pro deleted file mode 100644 index d6edf5b9..00000000 --- a/examples/ray-generation-test-environment/ctem_window_display.pro +++ /dev/null @@ -1,249 +0,0 @@ -pro ctem_window_display,ncount,totalimpacts,gridsize,pix,curyear,masstot,odist,pdist,tdist,ph1,surface_dem,regolith,map,popupconsole -; Produces the console window display. The array 'map' is used to generate the image on the right-hand side -Compile_Opt DEFINT32 - -; console output graphics resolution -minref = pix * 1.0d-4 -conresx = 1280 -;conresy = 0.758*conresx -profsize = 0.00 -conresy = (0.60 + profsize) * conresx -sun = 20.d0 ; sun angle for display - -minx = (pix / 3.0d0) * 1d-3 -maxx = 3 * pix * gridsize * 1d-3 -charfac = 1.6 ; character size multiplier - -if strmatch(popupconsole,'T',/fold_case) then begin - device, decomposed=0, retain=2 - thisDevice = !D.NAME - SET_PLOT, 'Z' - TVLCT, red, green, blue, /GET - SET_PLOT, thisDevice - !P.MULTI = [0, 1, 2] - Window, 0, xsize=conresx, ysize=conresy -endif else begin - SET_PLOT, 'Z', /COPY - device, set_resolution=[conresx,conresy],decomposed=0, Z_Buffer=0 - TVLCT, red, green, blue, /GET - !P.MULTI = [0, 1, 2] - erase -endelse - -;set up first color scale -loadct, 0 - -;strings for display -time = 'Time = ' -timeunit = ' yr' -timp = 'Total impacts (dotdash) = ' -tcrt = 'Total craters (line) = ' -ocrt = 'Countable craters (bold) = ' -epwr = 'Mean regolith depth = ' -mtot = 'Impacted mass = ' -c1lab = 'Min. Elevation' -c2lab = 'Mean Elevation' -c3lab = 'Max. Elevation' - -maxelev = max(surface_dem) -minelev = min(surface_dem) -medelev = mean(surface_dem) -c1 = string(minelev, format = '(F9.1)') + ' m' -c2 = string(medelev, format = '(F9.1)') + ' m' -c3 = string(maxelev, format = '(F9.1)') + ' m' -tslp = mean(regolith) - -;geometric saturation -geom = dblarr(2,2) -geomem = dblarr(2,2) -geomep = dblarr(2,2) -geomel = dblarr(2,2) -geom(0,0) = minx -geom(0,1) = maxx -geom(1,*) = 3.12636d0 -geomem(0,0) = minx -geomem(0,1) = maxx -geomem(1,*) = 0.156318d0 -geomep(0,0) = minx -geomep(0,1) = maxx -geomep(1,*) = 0.312636d0 -geomel(0,0) = minx -geomel(0,1) = maxx -geomel(1,*) = 0.0312636d0 - -; Remove zeros -nz = where(odist(5,*) ne 0.0,count) -if (count gt 0) then begin - odistnz = dblarr(6,count) - odistnz(*,*)= odist(*,nz) -endif else begin - odistnz = odist -endelse - -nz = where(tdist(5,*) ne 0.0,count) -if (count gt 0) then begin - tdistnz = dblarr(6,count) - tdistnz(*,*)= tdist(*,nz) -endif else begin - tdistnz = tdist -endelse - -nz = where(pdist(5,*) ne 0.0,count) -if (count gt 0) then begin - pdistnz = dblarr(6,count) - pdistnz(*,*)= pdist(*,nz) - -endif else begin - pdistnz = pdist -endelse - -; create r-plot array containing exactly 1 crater per bin -area = (gridsize * pix * 1d-3)^2 -plo = 1 -while (sqrt(2.0d0)^plo gt minx) do begin - plo = plo - 1 -endwhile -phi = plo + 1 -while (sqrt(2.0d0)^phi lt maxx) do begin - phi = phi + 1 -endwhile -n = phi - plo -sdist = dblarr(6,n + 1) -p = plo -for i=0,n do begin - sdist(0,i) = sqrt(2.d0)^p - sdist(1,i) = sqrt(2.d0)^(p+1) - sdist(2,i) = sqrt(sdist(0,i) * sdist(1,i)) - sdist(3,i) = 1.0d0 - sdist(5,i) = (sdist(2,i))^3 / (area * (sdist(1,i) - sdist(0,i))) - p = p + 1 -endfor -sdist(4,*) = reverse(total(sdist(3,*),/cumulative),2) - -plot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=0, color=255, thick=2.0, $ - TITLE='Crater Distribution R-Plot', charsize=charfac*conresy/720, $ - XTITLE='Crater Diameter (km)', $ - XRANGE=[minx,maxx], /XLOG, XSTYLE=1, $ - YTITLE='R Value', $ - YRANGE=[5.0e-4,5.0e0], /YLOG, YSTYLE=1, $ - /device, pos = [0.085*conresx,(0.25 + profsize)*conresy,0.44*conresx,0.85*conresy] - -Dfac = sqrt(sqrt(2.0d0)) - -;display observed crater distribution -oplot, tdistnz(2,*)*1.0d-3, tdistnz(5,*), line=0, color=255, thick=1.0 -oplot, geom(0,*), geom(1,*), line=2, color=255, thick=1.0 -oplot, geomem(0,*), geomem(1,*), line=1, color=255, thick=1.0 -oplot, geomep(0,*), geomep(1,*), line=1, color=255, thick=1.0 -oplot, geomel(0,*), geomel(1,*), line=1, color=255, thick=1.0 -oplot, pdistnz(2,*)*1.0d-3, pdistnz(5,*), line=3, color=255, thick=1.0 -oplot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=1, color=255, thick=1.0 -oplot, sdist(0,*), sdist(5,*), line=1, color=255, thick=1.0 -oplot, ph1(0,*)*Dfac*1.0d-3, ph1(1,*), psym=1, color=255, thick=1.0 -;oplot, ph2(0,*), ph2(1,*), psym=4, color=255, thick=1.0 -;oplot, ph3(0,*), ph3(1,*), psym=5, color=255, thick=1.0 - -; set up profile display -surfpos = dblarr(gridsize) -surfpro = dblarr(gridsize) -surfhpro = dblarr(gridsize) -surfrpro = dblarr(gridsize) -for k = 0,gridsize-1 do begin - surfpos(k) = (-0.5d0*(gridsize-1) + double(k)) * pix -endfor -surfpro(*) = surface_dem(*,gridsize/2-1) -surfhpro(*) = regolith(*,gridsize/2-1) -surfrpro(*) = surfpro(*) - surfhpro(*) - -; set up profile -;maxelevp = max(surfpro) -;minelevp = min(surfpro) -;medelevp = mean(surfpro) -;vertrange = 1.5 * abs(maxelevp-minelevp) -;vertadd = 0.5d0 * (vertrange - abs(maxelevp-minelevp)) -;horzrange = vertrange * 5.86666666667d0 -;if (horzrange gt (pix*gridsize)) then horzrange = pix*gridsize -;plot, surfpos(*)/1.0d3, surfpro(*)/1.0d3, line=0, color=255, thick=1.0, $ -; TITLE='Matrix Cross-Section', charsize=1.0, $ -; XTITLE='Horizontal Position (km)', $ -; XRANGE=[(-1.0d0*horzrange/2.0d3),(horzrange/2.0d3)], XSTYLE=1, $ -; YTITLE='Elevation (km)', $ -; YRANGE=[((minelevp - vertadd)/1.0d3),((maxelevp + vertadd)/1.0d3)], YSTYLE=1, $ -; /device, pos = [0.063*conresx,0.049*conresy,0.99*conresx,0.26*conresy] -;oplot, surfpos(*)*1.0d-3, surfrpro(*)*1.0d-3, line=0, color=255, thick=1.0 - -;display text -dum = string(format='(E10.4)', curyear) -parts = strsplit(dum, 'E', /extract) -fcuryear = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) + ' yr' -ftimp = string(totalimpacts, format = '(I13)') -ftcnt = string(tdist(4,0), format = '(I13)') -focnt = string(odist(4,0), format = '(I13)') -ftslp = string(tslp, format = '(F13.3)') + ' m' - - -dum = string(format='(E10.4)',masstot) -parts = strsplit(dum, 'E', /extract) -fmtot = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) + ' kg' - -; Display information text below the R-plot -texttop = 0.15 + profsize -textspc = 0.035 -textleft = 0.05*conresx -textbreak = 0.25*conresx -xyouts, textleft, (texttop - 0*textspc)*conresy, time, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 1*textspc)*conresy, timp, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 2*textspc)*conresy, tcrt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 3*textspc)*conresy, ocrt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft, (texttop - 4*textspc)*conresy, mtot, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 0*textspc)*conresy, fcuryear, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 1*textspc)*conresy, ftimp, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 2*textspc)*conresy, ftcnt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 3*textspc)*conresy, focnt, color=255, charsize=charfac*conresy/720., /device -xyouts, textleft + textbreak, (texttop - 4*textspc)*conresy, fmtot, color=255, charsize=charfac*conresy/720., /device - -; Display information text above the R-plot -xyouts, 0.0368*conresx, 0.972*conresy, c1lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.195*conresx, 0.972*conresy, c2lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.353*conresx, 0.972*conresy, c3lab, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.0368*conresx, 0.944*conresy, c1, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.195*conresx, 0.944*conresy, c2, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.353*conresx, 0.944*conresy, c3, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.100*conresx, 0.917*conresy, epwr, color=255, charsize=charfac*conresy/720., /device -xyouts, 0.278*conresx, 0.917*conresy, ftslp, color=255, charsize=charfac*conresy/720., /device - -;print to screen -print, ncount, ' time = ', curyear -;print, ncount, ' tot impacts = ', tdist -;print, ncount, ' tot craters = ', totalimpacts -;print, ncount, ' obs craters = ', ocrcnt -;print, ncount, ' regolith = ', tslp -;print, ncount, ' prod R = ', mean(prval(1,*)) - -;draw box around the main surface display & fill -displaysize = floor(0.53*conresx) ; size of displayed surface -surfxpos = floor(0.462*conresx) -surfypos = floor((0.05 + profsize)*conresy) -xbox = [surfxpos - 1,surfxpos - 1,surfxpos + displaysize,surfxpos + displaysize,surfxpos - 1] -ybox = [surfypos - 1,surfypos + displaysize,surfypos + displaysize,surfypos - 1,surfypos - 1] -plotS, xbox, ybox, /device, color=255 - -; for display -mapscaled = congrid(map,3,displaysize,displaysize,/interp) - -tv, mapscaled, surfxpos, surfypos, xsize=displaysize, ysize=displaysize, true=1, /device - -; ---------- saving window ---------- - -; save console window -fnum = string(ncount,format='(I6.6)') -; print screen to JPEG file -if (file_test('console',/DIRECTORY) eq 0) then begin - file_mkdir,'console' -endif -print, ncount, ' saving window' -fname = 'console/console' + fnum + '.jpg' -dwin = tvrd(true=1) -write_jpeg, fname, dwin, true=1, quality=90 - -end diff --git a/examples/regolith-transport-run-example/bar.pro b/examples/regolith-transport-run-example/bar.pro deleted file mode 100644 index 11ec7af0..00000000 --- a/examples/regolith-transport-run-example/bar.pro +++ /dev/null @@ -1,15 +0,0 @@ -pro bar -device, decomposed=1, retain=2 -set_plot, 'PS' -DEVICE,/ENCAPSULATED,filename='bar.eps',/INCHES,xsize=2.0,ysize=3.0,font_size=18 -thisDevice = !D.NAME -loadct, 33 -TVLCT, 255, 255, 255, 254 ; White color - !P.Color = '000000'xL - !P.Background = 'FFFFFF'xL - - ;Window, 0, xsize=150, ysize=1000 -cgColorbar,/Vertical, COLOR='black',MAXRANGE=100,MINRANGE=-400, font=0 ,position=[0.60,0.1,0.95,0.95] -;dwin = tvrd(true=1) -;write_jpeg, 'bar.jpg', dwin, true=1, quality=90 -end diff --git a/examples/regolith-transport-run-example/ctem_image_presentation.pro b/examples/regolith-transport-run-example/ctem_image_presentation.pro deleted file mode 100755 index 05a7d65a..00000000 --- a/examples/regolith-transport-run-example/ctem_image_presentation.pro +++ /dev/null @@ -1,143 +0,0 @@ -pro ctem_image_presentation,ncount,gridsize,pix,curyear,odist,pdist,tdist,ph1,map -; Generates the simplified version of the console display for use in presentations -; Plots the R-plot on the left and the image map on the right - -; presentation graphics -presresx = 1024 -presresy = 0.6*presresx -area = (gridsize * pix)^2 - -minx = (pix / 3.0d0) * 1d-3 -maxx = 3 * pix * gridsize * 1d-3 - -;strings for display -dum = string(format='(E10.4)', curyear) -parts = strsplit(dum, 'E', /extract) -fcuryear = strcompress(string(format='(F6.4,"x10!U",i,"!N")', parts[0], parts[1])) -time = 'Time = ' -timeunit = ' yr' - -if (file_test('presentation',/DIRECTORY) eq 0) then begin - file_mkdir,'presentation' -endif - -thisDevice = !D.Name -Set_Plot, 'Z' -Erase -Device, Set_Resolution=[presresx,presresy],Set_Pixel_Depth=24, Decomposed=0 -loadct, 0 -TVLCT, red, green, blue, /GET - -;geometric saturation -geom = dblarr(2,2) -geomem = dblarr(2,2) -geomep = dblarr(2,2) -geomel = dblarr(2,2) -geom(0,0) = minx -geom(0,1) = maxx -geom(1,*) = 3.12636d0 -geomem(0,0) = minx -geomem(0,1) = maxx -geomem(1,*) = 0.156318d0 -geomep(0,0) = minx -geomep(0,1) = maxx -geomep(1,*) = 0.312636d0 -geomel(0,0) = minx -geomel(0,1) = maxx -geomel(1,*) = 0.0312636d0 - -; Remove zeros -nz = where(odist(5,*) ne 0.0,count) -if (count gt 0) then begin - odistnz = dblarr(6,count) - odistnz(*,*)= odist(*,nz) -endif else begin - odistnz = odist -endelse - -nz = where(tdist(5,*) ne 0.0,count) -if (count gt 0) then begin - tdistnz = dblarr(6,count) - tdistnz(*,*)= tdist(*,nz) -endif else begin - tdistnz = tdist -endelse - -nz = where(pdist(5,*) ne 0.0,count) -if (count gt 0) then begin - pdistnz = dblarr(6,count) - pdistnz(*,*)= pdist(*,nz) -endif else begin - pdistnz = pdist -endelse - -; create r-plot array containing exactly 1 crater per bin -area = (gridsize * pix * 1d-3)^2 -plo = 1 -while (sqrt(2.0d0)^plo gt minx) do begin - plo = plo - 1 -endwhile -phi = plo + 1 -while (sqrt(2.0d0)^phi lt maxx) do begin - phi = phi + 1 -endwhile -n = phi - plo -sdist = dblarr(6,n + 1) -p = plo -for i=0,n do begin - sdist(0,i) = sqrt(2.d0)^p - sdist(1,i) = sqrt(2.d0)^(p+1) - sdist(2,i) = sqrt(sdist(0,i) * sdist(1,i)) - sdist(3,i) = 1.0d0 - sdist(5,i) = (sdist(2,i))^3 / (area * (sdist(1,i) - sdist(0,i))) - p = p + 1 -endfor -sdist(4,*) = reverse(total(sdist(3,*),/cumulative),2) - - -plot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=0, color=255, thick=2.0, $ - TITLE='Crater Distribution R-Plot', charsize=1.2, $ - XTITLE='Crater Diameter (km)', $ - XRANGE=[minx,maxx], /XLOG, XSTYLE=1, $ - YTITLE='R Value', $ - YRANGE=[5.0e-4,5.0e0], /YLOG, YSTYLE=1, $ - /device, pos = [0.12,0.12,0.495,0.495]*presresx - -Dfac = sqrt(sqrt(2.0d0)) - -;display observed crater distribution -oplot, tdistnz(2,*)*1.0d-3, tdistnz(5,*), line=0, color=255, thick=1.0 -;oplot, geom(0,*), geom(1,*), line=2, color=255, thick=1.0 -oplot, geomem(0,*), geomem(1,*), line=1, color=255, thick=1.0 -oplot, geomep(0,*), geomep(1,*), line=1, color=255, thick=1.0 -;oplot, geomel(0,*), geomel(1,*), line=1, color=255, thick=1.0 -oplot, pdistnz(2,*)*1.0d-3, pdistnz(5,*), line=3, color=255, thick=1.0 -oplot, odistnz(2,*)*1.0d-3, odistnz(5,*), line=1, color=255, thick=1.0 -oplot, sdist(0,*), sdist(5,*), line=1, color=255, thick=1.0 -oplot, ph1(0,*)*Dfac*1.0d-3, ph1(1,*), psym=1, color=255, thick=1.0 -;oplot, ph2(0,*), ph2(1,*), psym=4, color=255, thick=1.0 -;oplot, ph3(0,*), ph3(1,*), psym=5, color=255, thick=1.0 - -;draw box around the main surface display & fill -displaysize = floor(0.45*presresx) ; size of displayed surface -surfxpos = floor(0.520*presresx) -surfypos = floor(0.12*presresy) -xbox = [surfxpos - 1,surfxpos - 1,surfxpos + displaysize,surfxpos + displaysize,surfxpos - 1] -ybox = [surfypos - 1,surfypos + displaysize,surfypos + displaysize,surfypos - 1,surfypos - 1] -plotS, xbox, ybox, /device, color=255 - -mapscaled = congrid(map,3,displaysize,displaysize,/interp) - -;mapscaled=congrid(map,displaysize,displaysize) ; scale image -tv, mapscaled, surfxpos, surfypos, xsize=displaysize, ysize=displaysize, true=1, /device - -xyouts, 0.310*presresx, 0.04*presresy, time + fcuryear + timeunit, color=255, charsize=2*presresy/720., /device - -snapshot = TVRD(True=1) -Set_Plot, thisDevice -fnum = string(ncount,format='(I6.6)') -fname = 'presentation/presentation' + fnum + '.jpg' -Write_JPEG, fname, snapshot, True=1, Quality=90 - - -end diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..8e25a629 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,146 @@ +# Copyright 2023 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +# Communicate version number and other CMake build variables to the source code +#set(GLOBAL_MODULE_IN ${SRC}/globals/globals_module.f90.in) +#set(GLOBAL_MODULE_OUT ${SRC}/globals/globals_module.f90) +#CONFIGURE_FILE(${GLOBAL_MODULE_IN} ${GLOBAL_MODULE_OUT}) + +IF(NOT CMAKE_Fortran_COMPILER_SUPPORTS_F90) + MESSAGE(FATAL_ERROR "Fortran compiler does not support F90") +ENDIF(NOT CMAKE_Fortran_COMPILER_SUPPORTS_F90) + +INCLUDE(SetParallelizationLibrary) +INCLUDE(SetUpNetCDF) +IF (COMPILER_OPTIONS STREQUAL "Intel" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") + INCLUDE(SetMKL) +ENDIF () + +# This INCLUDE statement executes code that sets the compile flags for DEBUG, +# RELEASE, PROFILING, and TESTING. +INCLUDE(SetFortranFlags) + +# Add the source files +SET(SOURCE_FILES + +) + + +SET(DRIVER_src ${SRC}/main/CTEM.f90) + +# Combine all source files +set(CTEM_src ${SOURCE_FILES}) + +# Turn preprocessor on for all files +SET_SOURCE_FILES_PROPERTIES(${CTEM_src} ${DRIVER_src} PROPERTIES Fortran_PREPROCESS ON) + +#Set strict vs fast math flags +STRING(TOUPPER "${CMAKE_BUILD_TYPE}" BT) +IF(BT STREQUAL "RELEASE" OR BT STREQUAL "PROFILE") + SET_PROPERTY(SOURCE ${STRICT_MATH_FILES} APPEND_STRING PROPERTY COMPILE_FLAGS "${STRICTMATH_FLAGS}") + SET_PROPERTY(SOURCE ${FAST_MATH_FILES} APPEND_STRING PROPERTY COMPILE_FLAGS "${FASTMATH_FLAGS}") +ENDIF() + +IF(BT STREQUAL "DEBUG") + ADD_DEFINITIONS(-DDEBUG) +ELSEIF(BT STREQUAL "PROFILE") + ADD_DEFINITIONS(-DPROFILE) +ENDIF() + +# Define the executable name +SET(CTEM_DRIVER ctem_driver) +ADD_EXECUTABLE(${CTEM_DRIVER} ${DRIVER_src}) + +##################################################### +# Add the needed libraries +##################################################### +# Create a library from the source files, except the driver +ADD_LIBRARY(${CTEM_LIBRARY} ${CTEM_src}) +IF (NOT BUILD_SHARED_LIBS) + SET_PROPERTY(TARGET ${CTEM_LIBRARY} PROPERTY POSITION_INDEPENDENT_CODE) +ENDIF () + +TARGET_INCLUDE_DIRECTORIES(${CTEM_LIBRARY} PUBLIC ${NETCDF_INCLUDE_DIR}) +TARGET_INCLUDE_DIRECTORIES(${CTEM_DRIVER} PUBLIC ${NETCDF_INCLUDE_DIR}) +TARGET_LINK_LIBRARIES(${CTEM_LIBRARY} PUBLIC ${NETCDF_LIBRARIES}) +TARGET_LINK_LIBRARIES(${CTEM_DRIVER} PUBLIC ${CTEM_LIBRARY} ${NETCDF_LIBRARIES}) + +IF(USE_OPENMP OR USE_SIMD) + SET_PROPERTY(TARGET ${CTEM_LIBRARY} ${CTEM_DRIVER} APPEND_STRING PROPERTY COMPILE_FLAGS "${OpenMP_Fortran_FLAGS} ") + SET_PROPERTY(TARGET ${CTEM_LIBRARY} ${CTEM_DRIVER} APPEND_STRING PROPERTY LINK_FLAGS "${OpenMP_Fortran_FLAGS} ") +ENDIF() + +IF (CMAKE_SYSTEM_NAME STREQUAL "Windows") + SET_PROPERTY(TARGET ${CTEM_LIBRARY} ${CTEM_DRIVER} APPEND_STRING PROPERTY LINK_FLAGS "/NODEFAULTLIB") +ENDIF() + + +IF(USE_COARRAY) + TARGET_COMPILE_DEFINITIONS(${CTEM_LIBRARY} PUBLIC -DCOARRAY) + TARGET_COMPILE_DEFINITIONS(${CTEM_DRIVER} PUBLIC -DCOARRAY) + SET_PROPERTY(TARGET ${CTEM_LIBRARY} ${CTEM_DRIVER} APPEND_STRING PROPERTY COMPILE_FLAGS "${Coarray_Fortran_FLAGS} ") + SET_PROPERTY(TARGET ${CTEM_LIBRARY} ${CTEM_DRIVER} APPEND_STRING PROPERTY LINK_FLAGS "${Coarray_Fortran_FLAGS} ") +ENDIF(USE_COARRAY) + +# Check to see if the compiler allows for local-spec in do concurrent statements. Set a preprocessor variable if it does +SET(TESTFILE "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}") +SET(TESTFILE "${TESTFILE}/CMakeTmp/testFortranDoConcurrentLoc.f90") +FILE(WRITE "${TESTFILE}" +" +program TestDoConcurrentLoc +integer :: i +real,dimension(10) :: a +do concurrent(i = 1:10) shared(a) + a(i) = i +end do +end program TestDoConcurrentLoc +") +TRY_COMPILE(DOCONLOC_WORKS ${CMAKE_BINARY_DIR} ${TESTFILE} COMPILE_DEFINITIONS "${CMAKE_Fortran_FLAGS}" OUTPUT_VARIABLE OUTPUT) +IF (DOCONLOC_WORKS) + MESSAGE(STATUS "DO CONCURRENT supports locality-spec") + TARGET_COMPILE_DEFINITIONS(${CTEM_DRIVER} PRIVATE -DDOCONLOC) +ELSE () + MESSAGE(STATUS "DO CONCURRENT does not support locality-spec") +ENDIF (DOCONLOC_WORKS) + +# Check to see if quad precision is supported +SET(TESTFILE "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}") +SET(TESTFILE "${TESTFILE}/CMakeTmp/testFortranQuadPrecisionReal.f90") +FILE(WRITE "${TESTFILE}" +" +program TestQuadPrecisionReal +integer, parameter :: QP = selected_Real_kind(30) +real(QP) :: x +end program TestQuadPrecisionReal +") +TRY_COMPILE(QUADPREC ${CMAKE_BINARY_DIR} ${TESTFILE} COMPILE_DEFINITIONS "${CMAKE_Fortran_FLAGS}" OUTPUT_VARIABLE OUTPUT) +IF (QUADPREC) + MESSAGE(STATUS "Quad precision real is supported") + TARGET_COMPILE_DEFINITIONS(${CTEM_DRIVER} PRIVATE -DQUADPREC) +ELSE () + MESSAGE(STATUS "Quad precision real is not supported") +ENDIF () + + +##################################### +# Tell how to install this executable +##################################### +IF(WIN32) + SET(CMAKE_INSTALL_PREFIX "C:\\Program Files") + FILE(TO_CMAKE_PATH ${CMAKE_INSTALL_PREFIX} CMAKE_INSTALL_PREFIX) +ELSE() + SET(CMAKE_INSTALL_PREFIX /usr/local) +ENDIF(WIN32) +INSTALL(TARGETS ${CTEM_DRIVER} ${CTEM_LIBRARY} + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + INCLUDES DESTINATION include +) + diff --git a/version.txt b/version.txt new file mode 100644 index 00000000..882e3029 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +2023.9.0 \ No newline at end of file