diff --git a/.gitignore b/.gitignore index 6c8b68e0..7b3266dc 100644 --- a/.gitignore +++ b/.gitignore @@ -6,14 +6,9 @@ build # Files generated by CMake. src/base/mast_config.h -# Files generated by Python example/documentation preprocessor. -doc/example_1.dox -doc/example_2.dox -doc/example_3.dox - # CLion IDE files. .idea/ -cmake-build-debug/ +cmake-build*/ build2 # Visual Studio Code settings. diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..b85de9d5 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "doc/assets"] + path = doc/assets + url = https://github.com/MASTmultiphysics/mast-assets.git diff --git a/.travis.yml b/.travis.yml index 39b6d1da..c6036d57 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,49 +1,57 @@ language: cpp -dist: xenial + +matrix: + include: + # macOS/Linux builds - libMesh version 1.5.1 + - os: osx + osx_image: xcode10.2 + env: LIBMESH_VERSION=1.5.1 + - os: linux + dist: bionic + env: LIBMESH_VERSION=1.5.1 + + # Doxygen documentation build + # - this job also progresses to deployment when on master branch + - os: linux + dist: bionic + env: CI_BUILD_DOCS=true CI_DEPLOY_DOCS=true LIBMESH_VERSION=1.5.1 + + # macOS/Linux builds - libMesh version 1.4.1 + - os: osx + osx_image: xcode10.2 + env: LIBMESH_VERSION=1.4.1 + - os: linux + dist: bionic + env: LIBMESH_VERSION=1.4.1 + + # macOS/Linux builds - libMesh version 1.3.1 + - os: osx + osx_image: xcode10.2 + env: LIBMESH_VERSION=1.3.1 + - os: linux + dist: xenial + env: LIBMESH_VERSION=1.3.1 before_install: -- sudo apt-get -qq install -y gfortran wget m4 -- sudo apt-get -qq install -y openmpi-bin libopenmpi-dev -- sudo apt-get -qq install -y libpetsc3.6 libpetsc3.6.2-dev -- sudo apt-get -qq install -y libslepc3.6 libslepc3.6.1-dev libparpack2-dev -- sudo apt-get -qq install -y libboost-all-dev -- sudo apt-get -qq install -y libeigen3-dev -- sudo apt-get -qq install -y doxygen graphviz rsync -- sudo apt-get -qq install -y texlive-latex-base dvi2ps ghostscript + - ci/build_dependencies.sh install: -- cd ${HOME} -- wget -nv https://github.com/MASTmultiphysics/mast-ci-packages/releases/download/libmesh-1.3.1-1.deb/libmesh-1.3.1-1.deb -- sudo apt install ./libmesh-1.3.1-1.deb - -before_script: -- export MAST_INSTALL_DIR=${HOME}/mast -- cd ${TRAVIS_BUILD_DIR} -- mkdir build -- cd build -- cmake .. - -DCMAKE_INSTALL_PREFIX=${MAST_INSTALL_DIR} - -DCMAKE_C_COMPILER=mpicc - -DCMAKE_CXX_COMPILER=mpic++ - -DCMAKE_Fortran_COMPILER=mpifort - -DlibMesh_DIR=/usr/local - -DPETSc_DIR=/usr/lib/petscdir/3.6.2/x86_64-linux-gnu-real - -DSLEPc_DIR=/usr/lib/slepcdir/3.6.1/x86_64-linux-gnu-real - -DEIGEN3_ROOT=/usr/include/eigen3 - -DBOOST_ROOT=/usr - -DBUILD_DOC=ON - -DENABLE_DOT=OFF - -DENABLE_GCMMA=OFF - -DENABLE_SNOPT=OFF + - ci/get_libmesh.sh script: -- make -j 2 -- make -j 2 doc_doxygen -- cd ${TRAVIS_BUILD_DIR} + - ci/build_mast.sh + +before_deploy: +- openssl aes-256-cbc -K $encrypted_db2095f63ba3_key -iv $encrypted_db2095f63ba3_iv -in doc/deploy_rsa.enc -out /tmp/deploy_rsa -d +- eval "$(ssh-agent -s)" +- chmod 600 /tmp/deploy_rsa +- ssh-add /tmp/deploy_rsa deploy: - provider: script - script: bash doc/deploy_docs.sh - skip_cleanup: true - on: - branch: master + provider: script + script: bash ci/deploy_docs.sh + skip_cleanup: true + on: + all_branches: true + repo: MASTmultiphysics/mast-multiphysics + condition: ${CI_DEPLOY_DOCS} = true diff --git a/CMakeLists.txt b/CMakeLists.txt index d21b5eeb..23f8b7d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ # PREAMBLE -cmake_minimum_required(VERSION 3.2) +cmake_minimum_required(VERSION 3.13) project(MAST - VERSION 0.3 - LANGUAGES C CXX) + VERSION 2.0.1 + LANGUAGES C CXX) # PROJECT WIDE SETUP # Get CMake modules and set language standards. @@ -14,14 +14,15 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) include(GNUInstallDirs) # Build options with defaults. -option(ENABLE_GCMMA "Build with GCMMA interface" OFF) -option(ENABLE_DOT "Build with DOT interface" OFF) -option(ENABLE_SNOPT "Build with SNOPT interface" OFF) -option(ENABLE_NLOPT "Build with NLOPT interface" OFF) -option(ENABLE_CYTHON "Build with CYTHON interface" OFF) -option(BUILD_DOC "Build documentation" OFF) - -# Required dependency paths. +option(ENABLE_GCMMA "Build with GCMMA interface" OFF) +option(ENABLE_DOT "Build with DOT interface" OFF) +option(ENABLE_SNOPT "Build with SNOPT interface" OFF) +option(ENABLE_NLOPT "Build with NLOPT interface" OFF) +option(ENABLE_NASTRANIO "Build with support for reading Nastran meshes" OFF) +option(ENABLE_CYTHON "Build with support for Cython development" OFF) +option(BUILD_DOC "Build documentation" OFF) + +# Dependency paths (optional) - these paths help CMake find dependencies. set(MAST_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) set(libMesh_DIR "libMesh_DIR" CACHE PATH "Directory containing libMesh include/ and lib/") set(PETSc_DIR "PETSc_DIR" CACHE PATH "Directory containing PETSc include/ and lib/") @@ -29,9 +30,9 @@ set(PETSc_ARCH "PETSc_ARCH" CACHE STRING "Configuration/build of PETSc that sh set(SLEPc_DIR "SLEPc_DIR" CACHE PATH "Directory containing SLEPc include/ and lib/") set(SLEPc_ARCH "SLEPc_ARCH" CACHE STRING "Configuration/build of SLEPc that should be used.") set(EIGEN3_ROOT "Eigen_DIR" CACHE PATH "Directory containing eigen header files") -set(DOT_DIR "DOT_DIR" CACHE PATH "Directory containing DOT lib/") -set(SNOPT_DIR "SNOpt_DIR" CACHE PATH "Directory containing SNOPT lib/") -set(NLOPT_DIR "NLOpt_DIR" CACHE PATH "Directory containing NLOpt include/ and lib/") +set(DOT_DIR "DOT_DIR" CACHE PATH "Directory containing DOT lib/") +set(SNOPT_DIR "SNOpt_DIR" CACHE PATH "Directory containing SNOPT lib/") +set(NLOPT_DIR "NLOpt_DIR" CACHE PATH "Directory containing NLOpt include/ and lib/") # EXTERNALLY PROVIDED CONTENT # None. Use this if we pull something in during the build in the future. @@ -39,8 +40,8 @@ set(NLOPT_DIR "NLOpt_DIR" CACHE PATH "Directory containing NLOpt include/ and # FIND DEPENDENCIES find_package(MPI REQUIRED) find_package(LAPACK REQUIRED) -message("-- Found BLAS libs: ${BLAS_LIBRARIES}") -message("-- Found LAPACK libs: ${LAPACK_LIBRARIES}") +message(STATUS "Found BLAS libs: ${BLAS_LIBRARIES}") +message(STATUS "Found LAPACK libs: ${LAPACK_LIBRARIES}") find_package(PETSc REQUIRED) find_package(SLEPc REQUIRED) find_package(HDF5 REQUIRED) @@ -52,8 +53,8 @@ find_package(Eigen3 REQUIRED) # Boost CMake configuration in the FindBoost module for now. set(Boost_NO_BOOST_CMAKE ON) find_package(Boost COMPONENTS iostreams system filesystem unit_test_framework REQUIRED) -message("-- Found Boost include: ${Boost_INCLUDE_DIRS}") # To ensure the found Boost is what user expected -message("-- Found Boost libs: ${Boost_LIBRARY_DIRS}") # To ensure the found Boost is what user expected +message(STATUS "Found Boost include: ${Boost_INCLUDE_DIRS}") # To ensure the found Boost is what user expected +message(STATUS "Found Boost libs: ${Boost_LIBRARY_DIRS}") # To ensure the found Boost is what user expected # Find optional packages. if (ENABLE_GCMMA) @@ -83,12 +84,37 @@ else() set (MAST_ENABLE_NLOPT 0) endif() +if (ENABLE_NASTRANIO) + find_package(Python3 REQUIRED) + + # Make sure Python has pyNastran. + execute_process(COMMAND ${Python3_EXECUTABLE} -c "import pyNastran" + RESULT_VARIABLE PYNASTRAN_ERROR) + if(PYNASTRAN_ERROR) + message(FATAL_ERROR "Error finding pyNastran package for Python3_EXECUTABLE!") + else() + message(STATUS " pyNastran package found") + endif() + + # Make sure Python has NumPy. + execute_process(COMMAND ${Python3_EXECUTABLE} -c "import numpy" + RESULT_VARIABLE NUMPY_ERROR) + if(NUMPY_ERROR) + message(FATAL_ERROR "Error finding pyNastran package for Python3_EXECUTABLE!") + else() + message(STATUS " Numpy package found") + endif() + +endif() + +# THIRD PARTY/CONTRIB +# - This directory contains files developed by third parties and are included in the +# MAST source for convenience. +add_subdirectory(contrib) + # MAIN TARGETS add_subdirectory(src) -# EXAMPLES -add_subdirectory(examples) - # DOCUMENTATION if(BUILD_DOC) add_subdirectory(doc) @@ -98,3 +124,5 @@ endif() enable_testing() add_subdirectory(tests) +# EXAMPLES +add_subdirectory(examples) diff --git a/INSTALL.md b/INSTALL.md deleted file mode 100644 index 02f25fea..00000000 --- a/INSTALL.md +++ /dev/null @@ -1,166 +0,0 @@ -MAST INSTALLATION -=============================== - -Please see [https://mastmultiphysics.github.io](https://mastmultiphysics.github.io) for additional documentation. - -DEPENDENCY LIST -------------------------------- -MAST depends on the following libraries: - -- PETSc (http://www.mcs.anl.gov/petsc/) - MAST has been tested with PETSc version 3.6.3 and 3.7.7. - -- SLEPc (http://slepc.upv.es) - This builds on top of PETSc and provides the eigensolvers. The - version numbers are in sync with that of PETSc, so a 3.6.x/3.7.x - version of this library should be used. - -- libMesh (http://libmesh.github.io) - `git clone git://github.com/libMesh/libmesh.git` - -- MPI - -- LAPACK - -- BLAS - -- BOOST (http://www.boost.org) - -- BOOST unit test framework - -- EIGEN (http://eigen.tuxfamily.org/index.php?title=Main_Page) - - -- PARMETIS/METIS (http://glaros.dtc.umn.edu/gkhome/metis/parmetis/overview) - Both PETSc and libMesh use these libraries. PETSc can be requested - to download and install a version of this library during compile - time. libMesh includes these libraries in the contrib - subdirectory, which it can compile and link to. - -- HDF5 (https://www.hdfgroup.org/HDF5/) - This is used for the ExodusII output formats, which are efficiently - read into Paraview. PETSc can be requested to download/build HDF5. - libMesh also provides interfaces to Tecplot, and can be configured to - build with Tecplot, in which case ExodusII becomes optional. - -- GCMMA - Presently, this is the default optimization library. Please obtain it - from the author of GCMMA at: krille@math.kth.se - -- libgfortran - GCMMA is written in fortran. Hence, linking to GCMMA requires that - MAST be linked to libgfortran. - -CMAKE BUILD INSTRUCTIONS -------------------------------- - -1. Download, build and install METIS and PARMETIS (PETSC can be request to - install this during its configuration, which case skip this step.) -2. Download, build and install PETSc with MPI support. Please make - sure to build the shared verion of this library. -3. Download, build and install SLEPc using the PETSc installation. -4. Download libMesh. Configure libMesh. Following configuration options - are used locally. Please change the options to suit your local - system. Note that shared library is being build. - -``` -PETSC_DIR=/Users/manav/Documents/codes/numerical_lib/petsc/\ -SLEPC_DIR=/Users/manav/Documents/codes/numerical_lib/slepc/\ -FC=mpif90-openmpi-mp F77=mpif90-openmpi-mp CC=mpicc-openmpi-mp\ -CXX=mpicxx-openmpi-mp ./configure\ ---prefix=${PWD}/../ --enable-mpi --disable-unique-id\ ---enable-dependency-tracking --enable-fortran --enable-shared\ ---enable-exceptions --disable-openmp --disable-default-comm-world\ ---enable-tracefiles --enable-amr --enable-vsmoother\ ---enable-periodic --enable-dirichlet --enable-parmesh\ ---enable-nodeconstraint --enable-ghosted --enable-pfem\ ---enable-ifem --enable-second --enable-xdr --enable-reference-counting\ ---enable-perflog --enable-examples --enable-boost --disable-trilinos\ ---disable-tbb --enable-sfc --disable-tecplot --disable-tecio\ ---enable-metis --enable-parmetis --enable-tetgen --enable-triangle\ ---disable-vtk --enable-hdf5 --enable-libHilbert --enable-nanoflann\ ---enable-exodus --enable-netcdf --enable-petsc --enable-slepc\ ---with-mpi=/opt/local --with-metis=internal --with-hdf5=/opt/local/\ ---with-methods="opt dbg"\ -``` - -5. Build and install libMesh -6. Create a subdirectory MAST_DIR/build/opt to build MAST. In the - subdirectory, configure cmake build system using the following - command. Please modify it based on your local system - configuration. You can use `-DCMAKE_BUILD_TYPE=Debug` to build the - debug version. - -``` -cmake ../ -Dlibmesh_dir=~/Documents/codes/libmesh \ --Dpetsc_dir=~/Documents/codes/numerical_lib/petsc \ --Dslepc_dir=~/Documents/codes/numerical_lib/slepc \ --Dboost_include_dir=/opt/local/include \ --Dmpi_include_dir=/opt/local/include/openmpi-mp \ --Dmpi_lib_dir=/opt/local/lib/openmpi-mp -Dlapack_lib_dir=/usr/lib \ --Dblas_lib_dir=/usr/lib -Dboost_lib_dir=/opt/local/lib \ --Dgcmma_lib_file=gcmma \ --Dgcmma_lib_dir=~/Documents/codes/numerical_lib/gcmma/build \ --Ddot_lib_file=dot \ --Ddot_lib_dir=~/Documents/codes/numerical_lib/optimization_codes/dot/build \ --Dnpsol_lib_file=npsol \ --Dnpsol_lib_dir=~/Documents/codes/numerical_lib/optimization_codes/npsol/build \ --Dfortran_lib_file=libgfortran.3.dylib \ --Dfortran_lib_dir=/opt/local/lib/libgcc \ --Dboost_test_lib=boost_unit_test_framework-mt \ --DCMAKE_Fortran_COMPILER=mpif90 -DCMAKE_BUILD_TYPE=Release \ --DCMAKE_CXX_FLAGS=-std=c++11 \ --DENABLE_GCMMA=ON \ --DENABLE_DOT=ON \ --DENABLE_NPSOL=ON -``` - -Note: `CMAKE_BUILD_TYPE=Release` builds an optimized version, while -`CMAKE_BUILD_TYPE=Debug` builds the debug version of the code. - -Note: GCMMA, DOT, NPSOL can be disabled by providing OFF as the compilation option -above. - -7. Build the library using - `make mast` - -8. Build one of the examples using. - ` make example_driver` - -9. Get instructions to run example by call it - `./example_driver` - - -CLion IDE -------------------------------- -CLion is a C/C++ IDE produced by JetBrains (https://www.jetbrains.com/clion/) -that leverages the CMake build process for project organization. - -To develop/build MAST using CLion, CMake options that are typically -supplied to the `cmake` terminal are provided in the preferences under -`Preferences > Build, Execution, Deployment > CMake` in the -`CMake Options:` box. - -An example set of options is: - -``` --DCMAKE_C_COMPILER=/usr/local/bin/mpicc --DCMAKE_CXX_COMPILER=/usr/local/bin/mpicxx --DCMAKE_FORTRAN_COMPILER=/usr/local/bin/mpifort --Dlibmesh_dir=~/Code/libmesh-github-install --Deigen_include_dir=/usr/local/include --Dboost_include_dir=/usr/local/include --Dboost_lib_dir=/usr/local/lib --Dboost_test_lib=boost_unit_test_framework --Dmpi_include_dir=/usr/local/include --Dmpi_lib_dir=/usr/local/lib --Dblas_lib_dir=/usr/lib --Dlapack_lib_dir=/usr/lib --Dpetsc_dir=~/Code/mast-multiphysics-deps2 --Dslepc_dir=~/Code/mast-multiphysics-deps2 --Dfortran_lib_dir=/usr/local/lib/gcc/7 --Dfortran_lib_file=libgfortran.dylib -``` - -You will want to use options corresponding to your own environment as -described in the *CMAKE BUILD INSTRUCTIONS* section. diff --git a/README.md b/README.md index 51095565..7e069679 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,64 @@ -MAST: Multidisciplinary-design Adaptation and Sensitivity Toolkit -Copyright (C) 2013-2019 Manav Bhatia +# MAST: Multidisciplinary-design Adaptation and Sensitivity Toolkit [![Build Status](https://travis-ci.com/MASTmultiphysics/mast-multiphysics.svg?branch=master)](https://travis-ci.com/MASTmultiphysics/mast-multiphysics) -This code was developed under funding from the Air Force Research Laboratory. -MAST was cleared for public release on 08 Nov 2016 with case number 88ABW-2016-5689. +The Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST) is a sensitivity-enabled, multiphysics FEA tool developed to support computational design and engineering analysis. -Documentation for the code is available at [https://mastmultiphysics.github.io](https://mastmultiphysics.github.io). +In addition to analysis of complex, nonlinear physics on large built-up models, MAST supports efficient analytical gradient/sensitivity calculation using direct and adjoint methods. As a result, it is well suited for gradient-based multidisciplinary design optimization processes. + +MAST is developed at the [Computational Dynamics and Design Laboratory](http://bhatia.ae.msstate.edu) at Mississippi State University in collaboration with the [Air Force Research Laboratory (AFRL)](https://www.afresearchlab.com) Multidisciplinary Science and Technology Center (MSTC). + +The MAST website is [https://mastmultiphysics.github.io](https://www.mast-multiphysics.com) and includes examples/tutorials, API documentation, and a growing theory/users guide. + +## Capabilities +An abbreviated list of capabilities is given below. +- 1D, 2D, and 3D analysis in multiple disciplines +- Heat Transfer + - 1D/2D/3D nonlinear heat conduction + - Radiation and convection boundary conditions + - Temperature-dependent material properties +- Structures (Elasticity) + - Beam/plate structural and 2D/3D continuum elements + - Loading: concentrated force, surface pressure, & thermoelastic + - Single-point boundary conditions and tie/connector constraints + - Nonlinear static and transient analysis + - Modal vibration analysis (including about a nonlinear equilibrium) + - Bifurcation buckling + - Advanced continuation and load-stepping in nonlinear analysis + - Nastran Bulk Data mesh input using [pyNastran](http://pynastran-git.readthedocs.io/en/latest/) + - other mesh formats also available including Exodus-II and manual definition +- Fluids + - SU/PG discretization of compressible Euler equations + - Small-disturbance linearized time-domain and frequency-domain solvers for Euler equations + - SU/PG discretization of compressible Navier-Stokes equations (experimental) +- Fluid-structure Interaction (FSI) + - Small-disturbance flutter solution through coupling of structural and fluid discretizations + - Time-accurate fluid-structure interaction (experimental) +- Aeroelasticity + - U-g flutter solver with mode tracking + - Time-domain flutter solver for piston-theory aerodynamics +- Analytical sensitivity analysis for nearly all analysis capabilities +- Interfaces to multiple optimizers (GCMMA, DOT, NPSOL) +- Topology Optimization (TO) + - Level-set based approaches + - Density-based approaches + +## Installation +Detailed installation/build instructions for MAST and its dependencies are [located on the website](https://www.mast-multiphysics.com/_install.html) or can be located in the source repository in `doc\install\*.dox`. + +### Submodules +To keep the size of the main MAST repository smaller, a git submodule is used +to store large media/assets such as images and animations used for the documentation +in a separate repo (doc/assets). To build the documentation locally, you must update +the submodule. To do this, simply run the following commands from inside the root +level of this main repository: +``` +git submodule init +git submodule update +``` + +## Copyright +Copyright (C) 2013-2020 Manav Bhatia and MAST authors + +## Clearances +Contributions to MAST by AFRL have been cleared for public release by case numbers: 88ABW-2016-5689, 88ABW-2017-5258, 88ABW-2020-0297. \ No newline at end of file diff --git a/ci/README.md b/ci/README.md new file mode 100644 index 00000000..ae03d5da --- /dev/null +++ b/ci/README.md @@ -0,0 +1,48 @@ +# Travis CI Testing/Deployment + +On the GitHub repository of MAST, Travis CI (https://travis-ci.com) is utilized for build testing on multiple OS's and +deployment of updated documentation online. In the future we will integrate the execution of both unit tests as well as +example problems for integration testing. + +This directory contains scripts utilized by the Travis CI process. + +## Travis CI Processes +When a commit is pushed to the MASTmultiphysics/mast-multiphysics GitHub repository, GitHub initiates the continuous +integration processes on Travis CI. What these processes do is controlled by the `.travis.yml` file in the root of the +repository. The different phases of a Travis CI are described at https://docs.travis-ci.com/user/job-lifecycle/. This +repository utilizes a relatively basic subset of the phases and overall capability of Travis CI. + +The files in this directory are utilized in the main phases of the Travis CI lifecycle: + +1. `before_install` - `build_dependencies.sh` - This script ensures that the Travis CI runner executing the current job +has the required dependencies for libMesh and building MAST. +2. `install` - `get_libmesh.sh` - This script fetches pre-built binaries of libMesh on Linux or the entire dependency +package on macOS. Travis CI jobs have a limited time for execution that is not long enough to build libMesh +(which is not available in job runners standard Linux/macOS package managers.) +3. `script` - `build_mast.sh` - Depending on the job, this script either builds the MAST library/examples or builds the +doxygen documentation. +4. `deploy` - `deploy_docs.sh` - For the job satisfying the appropriate conditions, this script pushes the documentation +website produced by doxygen to the hosting location. + +## Multiple OS's/Jobs/Environments +The `matrix` section of the `.travis.yml` file allows for the definition of multiple jobs to be run that can be done +in different environments or on different workers. Each item under `matrix/include` causes the execution of different +Travis CI worker with the specified environment. In the current setup, we utilize both Linux and macOS to test builds +against different compilers as well as different versions of the libMesh dependency, which is periodically updated by +that projects maintainers. In this setup, Travis CI allows for the specification of system environment variables that +are utilized by the scripts in the `ci` folder for distinguishing work that is specific to each environment. + +### Linux +The current Linux build environment utilizes Ubuntu 16.04. Dependencies available in the Ubuntu apt package repositories +are leveraged; however, in the future these may be updated as versions of PETSc/SLEPc are quite old. The current +compiler on Linux is GNU GCC-5.4.0. The libMesh dependencies are provided as external binaries that were built in an +identical environment and archived. + +### macOS +The macOS build on Travis CI current utilizes macOS version 10.14.4 with the default clang C/C++ compiler (Apple LLVM +version 10.0.1). Travis CI suggests utilizing Homebrew to install dependencies, which currently does not contain many of +the packages required for libMesh/MAST. To overcome this, a complete set dependencies (including multiple versions of +libMesh) is built/archived using Spack on the same environment setup (macOS version/compiler) the Travis CI utilizes. +These dependencies are fetched by the Travis CI runner and MAST is built against them. Since macOS does not provide a +Fortran compiler, GCC-9.1.0 is first built via Spack. The compiler toolchain is then macOS-provided C/C++ and +gfortran-9. \ No newline at end of file diff --git a/ci/build_dependencies.sh b/ci/build_dependencies.sh new file mode 100755 index 00000000..a6c116a1 --- /dev/null +++ b/ci/build_dependencies.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +if [ "${TRAVIS_OS_NAME}" = linux ]; then # Ubuntu Linux + + cd ${HOME} || exit + + # Python 3.7 apt repository (since its not neatly included in Ubuntu 16.04/18.04) + sudo add-apt-repository -y ppa:deadsnakes/ppa + + if [ "${TRAVIS_DIST}" = xenial ]; then # Ubuntu 16.04 Xenial Xerus + # Regular libMesh/MAST dependencies. + sudo apt-get -qq update + sudo apt-get -qq install -y gfortran wget m4 + sudo apt-get -qq install -y openmpi-bin libopenmpi-dev + sudo apt-get -qq install -y libpetsc3.6 libpetsc3.6.2-dev + sudo apt-get -qq install -y libslepc3.6 libslepc3.6.1-dev libparpack2-dev + sudo apt-get -qq install -y libnetcdf11 libnetcdf-dev + sudo apt-get -qq install -y libboost-all-dev + sudo apt-get -qq install -y libeigen3-dev + sudo apt-get -qq install -y doxygen graphviz rsync + sudo apt-get -qq install -y texlive-latex-base dvi2ps ghostscript + sudo apt-get -qq install -y python3.7 python3.7-dev libpython3.7 + + elif [ "${TRAVIS_DIST}" = bionic ]; then # Ubuntu 18.04 Bionic Beaver + # Regular libMesh/MAST dependencies. + sudo apt-get -qq update + sudo apt-get -qq install -y gfortran wget m4 + sudo apt-get -qq install -y openmpi-bin libopenmpi-dev + sudo apt-get -qq install -y petsc-dev libpetsc3.7.7-dbg + sudo apt-get -qq install -y slepc-dev libparpack2-dev + sudo apt-get -qq install -y metis libmetis-dev + sudo apt-get -qq install -y libparpack2-dev + sudo apt-get -qq install -y libnetcdf11 libnetcdf-dev + sudo apt-get -qq install -y libboost-all-dev + sudo apt-get -qq install -y libeigen3-dev + sudo apt-get -qq install -y doxygen graphviz rsync + sudo apt-get -qq install -y texlive-latex-base dvi2ps ghostscript + sudo apt-get -qq install -y python3.7 python3.7-dev libpython3.7 + + else + echo "INVALID LINUX DISTRO: ${TRAVIS_DIST}" + exit 1 + fi + + # Get pip working with external Python 3.7. + wget https://bootstrap.pypa.io/get-pip.py || exit + sudo python3.7 get-pip.py || exit + + sudo python3.7 -m pip install numpy scipy docopt colorama pandas h5py matplotlib cpylog pyNastran + sudo python3.7 -m pip install Cython --install-option="--no-cython-compile" + + # Update to later CMake release. + wget https://github.com/Kitware/CMake/releases/download/v3.15.5/cmake-3.15.5-Linux-x86_64.sh || exit + sudo mkdir /opt/cmake || exit + sudo sh cmake-3.15.5-Linux-x86_64.sh --prefix=/opt/cmake --skip-license || exit + +elif [ "${TRAVIS_OS_NAME}" = osx ]; then # macOS 10.14, XCode 10.2 + # Currently we don't do anything here since we get all dependencies for macOS + # from the binary download with "ci/get_libmesh.sh" in the next stage. + echo "Hello From OSX" + +else + echo "INVALID OS: ${TRAVIS_OS_NAME}" + exit 1 +fi \ No newline at end of file diff --git a/ci/build_mast.sh b/ci/build_mast.sh new file mode 100755 index 00000000..565c5c99 --- /dev/null +++ b/ci/build_mast.sh @@ -0,0 +1,285 @@ +#!/usr/bin/env bash + +# Steps common to all OS/toolchains. +export MAST_INSTALL_DIR=${HOME}/mast || exit +cd "${TRAVIS_BUILD_DIR}" || exit + +# Create directories to test both Release (optimized) and Debug build. +mkdir build_rel || exit +mkdir build_dbg || exit +export REL_BUILD_DIR=${TRAVIS_BUILD_DIR}/build_rel +export DBG_BUILD_DIR=${TRAVIS_BUILD_DIR}/build_dbg + +# Outer if chooses Linux/macOS based on Travis CI worker. +if [ "${TRAVIS_OS_NAME}" = linux ]; then # Ubuntu Linux + + if [ "${TRAVIS_DIST}" = xenial ]; then # Ubuntu 16.04 Xenial Xerus + + # First let us build/install a Debug version of MAST (-DCMAKE_BUILD_TYPE=Debug). + echo "TEST DEBUG BUILD..." + + if [ "${LIBMESH_VERSION}" = "1.3.1" ]; then # No Debug build for libMesh < 1.5.0 + echo "-- NO DEBUG BUILD WITH libMesh < 1.5.0" + elif [ "${LIBMESH_VERSION}" = "1.4.1" ]; then + echo "-- NO DEBUG BUILD WITH libMesh < 1.5.0" + else + + cd "${DBG_BUILD_DIR}" || exit + /opt/cmake/bin/cmake .. \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX="${MAST_INSTALL_DIR}" \ + -DCMAKE_C_COMPILER=mpicc \ + -DCMAKE_CXX_COMPILER=mpic++ \ + -DCMAKE_Fortran_COMPILER=mpifort \ + -DlibMesh_DIR=/usr/local \ + -DPETSc_DIR=/usr/lib/petscdir/3.6.2/x86_64-linux-gnu-real \ + -DSLEPc_DIR=/usr/lib/slepcdir/3.6.1/x86_64-linux-gnu-real \ + -DEIGEN3_ROOT=/usr/include/eigen3 \ + -DPython3_DIR=/usr \ + -DBOOST_ROOT=/usr \ + -DBUILD_DOC=ON \ + -DENABLE_DOT=OFF \ + -DENABLE_GCMMA=OFF \ + -DENABLE_SNOPT=OFF\ + -DENABLE_NASTRANIO=ON \ + -DENABLE_CYTHON=ON || exit + + if [ ${CI_BUILD_DOCS} ]; then + echo "No CI documentation for a Debug build." + else + make -j 2 || exit + echo "RUNNING UNIT TESTS" || exit + cd "${DBG_BUILD_DIR}/tests" || exit + ctest --force-new-ctest-process --output-on-failure --timeout 10 + echo "RUNNING SHORT EXAMPLES" || exit + cd "${DBG_BUILD_DIR}/examples" || exit + ctest --force-new-ctest-process --output-on-failure -L "SHORT" --timeout 60 + fi + + fi # No Debug build for libMesh < 1.5.0 + + # Now build/install a Release (optimized) version of MAST (-DCMAKE_BUILD_TYPE=Release). + echo "TEST RELEASE/OPTIMIZED BUILD..." + cd "${REL_BUILD_DIR}" || exit + /opt/cmake/bin/cmake .. \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="${MAST_INSTALL_DIR}" \ + -DCMAKE_C_COMPILER=mpicc \ + -DCMAKE_CXX_COMPILER=mpic++ \ + -DCMAKE_Fortran_COMPILER=mpifort \ + -DlibMesh_DIR=/usr/local \ + -DPETSc_DIR=/usr/lib/petscdir/3.6.2/x86_64-linux-gnu-real \ + -DSLEPc_DIR=/usr/lib/slepcdir/3.6.1/x86_64-linux-gnu-real \ + -DEIGEN3_ROOT=/usr/include/eigen3 \ + -DPython3_DIR=/usr \ + -DBOOST_ROOT=/usr \ + -DBUILD_DOC=ON \ + -DENABLE_DOT=OFF \ + -DENABLE_GCMMA=OFF \ + -DENABLE_SNOPT=OFF \ + -DENABLE_NASTRANIO=ON \ + -DENABLE_CYTHON=ON || exit + + if [ ${CI_BUILD_DOCS} ]; then + make doc_doxygen || exit + cd "${TRAVIS_BUILD_DIR}" || exit + ci/prepare_docs.sh || exit + else + make -j 2 || exit + make install || exit + echo "RUNNING UNIT TESTS" || exit + cd "${REL_BUILD_DIR}/tests" || exit + ctest --force-new-ctest-process --output-on-failure --timeout 10 + echo "RUNNING SHORT EXAMPLES" || exit + cd "${REL_BUILD_DIR}/examples" || exit + ctest --force-new-ctest-process --output-on-failure -L "SHORT" --timeout 60 + fi + + elif [ "${TRAVIS_DIST}" = bionic ]; then # Ubuntu 18.04 Bionic Beaver + + # First let us build/install a Debug version of MAST (-DCMAKE_BUILD_TYPE=Debug). + echo "TEST DEBUG BUILD..." + + if [ "${LIBMESH_VERSION}" = "1.3.1" ]; then # No Debug build for libMesh < 1.5.0 + echo "-- NO DEBUG BUILD WITH libMesh < 1.5.0" + elif [ "${LIBMESH_VERSION}" = "1.4.1" ]; then + echo "-- NO DEBUG BUILD WITH libMesh < 1.5.0" + else + + cd "${DBG_BUILD_DIR}" || exit + /opt/cmake/bin/cmake .. \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX="${MAST_INSTALL_DIR}" \ + -DCMAKE_C_COMPILER=mpicc \ + -DCMAKE_CXX_COMPILER=mpic++ \ + -DCMAKE_Fortran_COMPILER=mpifort \ + -DlibMesh_DIR=/usr/local \ + -DPETSc_DIR=/usr/lib/petsc \ + -DSLEPc_DIR=/usr/lib/slepc \ + -DEIGEN3_ROOT=/usr/include/eigen3 \ + -DPython3_DIR=/usr \ + -DBOOST_ROOT=/usr \ + -DBUILD_DOC=ON \ + -DENABLE_DOT=OFF \ + -DENABLE_GCMMA=OFF \ + -DENABLE_SNOPT=OFF\ + -DENABLE_NASTRANIO=ON \ + -DENABLE_CYTHON=ON || exit + + if [ ${CI_BUILD_DOCS} ]; then + echo "No CI documentation for a Debug build." + else + make -j 2 || exit + echo "RUNNING UNIT TESTS" || exit + cd "${DBG_BUILD_DIR}/tests" || exit + ctest --force-new-ctest-process --output-on-failure --timeout 10 + echo "RUNNING SHORT EXAMPLES" || exit + cd "${DBG_BUILD_DIR}/examples" || exit + ctest --force-new-ctest-process --output-on-failure -L "SHORT" --timeout 60 + fi + + fi # No Debug build for libMesh < 1.5.0 + + # Now build/install a Release (optimized) version of MAST (-DCMAKE_BUILD_TYPE=Release). + echo "TEST RELEASE/OPTIMIZED BUILD..." + cd "${REL_BUILD_DIR}" || exit + /opt/cmake/bin/cmake .. \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="${MAST_INSTALL_DIR}" \ + -DCMAKE_C_COMPILER=mpicc \ + -DCMAKE_CXX_COMPILER=mpic++ \ + -DCMAKE_Fortran_COMPILER=mpifort \ + -DlibMesh_DIR=/usr/local \ + -DPETSc_DIR=/usr/lib/petsc \ + -DSLEPc_DIR=/usr/lib/slepc \ + -DEIGEN3_ROOT=/usr/include/eigen3 \ + -DPython3_DIR=/usr \ + -DBOOST_ROOT=/usr \ + -DBUILD_DOC=ON \ + -DENABLE_DOT=OFF \ + -DENABLE_GCMMA=OFF \ + -DENABLE_SNOPT=OFF \ + -DENABLE_NASTRANIO=ON \ + -DENABLE_CYTHON=ON || exit + + if [ ${CI_BUILD_DOCS} ]; then + make doc_doxygen || exit + cd "${TRAVIS_BUILD_DIR}" || exit + ci/prepare_docs.sh || exit + else + make -j 2 || exit + make install || exit + echo "RUNNING UNIT TESTS" || exit + cd "${REL_BUILD_DIR}/tests" || exit + ctest --force-new-ctest-process --output-on-failure --timeout 10 + echo "RUNNING SHORT EXAMPLES" || exit + cd "${REL_BUILD_DIR}/examples" || exit + ctest --force-new-ctest-process --output-on-failure -L "SHORT" --timeout 60 + fi + + + else + echo "INVALID LINUX DISTRO: ${TRAVIS_DIST}" + exit 1 + fi + +elif [ "${TRAVIS_OS_NAME}" = osx ]; then # macOS 10.14, XCode 10.2 + + if [ "${LIBMESH_VERSION}" = "1.3.1" ]; then + PETSc_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/petsc-3.11.4-4ode2ljnkurc55362bc6k6wtlgfjpdmf + SLEPc_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/slepc-3.11.2-nts2wrpmixfsvfev7x5b5e2e4vpct6wy + libMesh_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/libmesh-1.3.1-4h7zpmhjpw6qwodrpoehwaq7fukjwfno + elif [ "${LIBMESH_VERSION}" = "1.4.1" ]; then + PETSc_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/petsc-3.11.4-4ode2ljnkurc55362bc6k6wtlgfjpdmf + SLEPc_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/slepc-3.11.2-nts2wrpmixfsvfev7x5b5e2e4vpct6wy + libMesh_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/libmesh-1.4.1-bry6shpqjekanfoepltqyic5ami5umor + elif [ "${LIBMESH_VERSION}" = "1.5.0" ]; then + PETSc_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/petsc-3.12.1-edmddchkkhtwckfumww3mtghyadytdxj + SLEPc_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/slepc-3.12.0-dbsf3rtgj4hoih6okdja6godorotij22 + libMesh_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/libmesh-1.5.0-dcgl6zldkp4xvfvfrajghwoy5b24ilrr + elif [ "${LIBMESH_VERSION}" = "1.5.1" ]; then + PETSc_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/petsc-3.12.1-edmddchkkhtwckfumww3mtghyadytdxj + SLEPc_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/slepc-3.12.0-dbsf3rtgj4hoih6okdja6godorotij22 + libMesh_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/libmesh-1.5.1-5y4kmrrnq6axqa2hv2ag36tjv6mgwknw + fi + + # First let us build/install a Debug version of MAST (-DCMAKE_BUILD_TYPE=Debug). + echo "TEST DEBUG BUILD..." + cd "${DBG_BUILD_DIR}" || exit + /Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/cmake-3.14.4-vlzpkvowre6hweutogn563ouzkb73jsq/bin/cmake .. \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX="${MAST_INSTALL_DIR}" \ + -DCMAKE_C_COMPILER=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/openmpi-3.1.4-sep4omvhokkexyojwrahdckfugactovb/bin/mpicc \ + -DCMAKE_CXX_COMPILER=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/openmpi-3.1.4-sep4omvhokkexyojwrahdckfugactovb/bin/mpic++ \ + -DCMAKE_Fortran_COMPILER=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/openmpi-3.1.4-sep4omvhokkexyojwrahdckfugactovb/bin/mpif90 \ + -DMPIEXEC_EXECUTABLE=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/openmpi-3.1.4-sep4omvhokkexyojwrahdckfugactovb/bin/mpiexec \ + -DlibMesh_DIR="${libMesh_DIR}" \ + -DPETSc_DIR="${PETSc_DIR}" \ + -DSLEPc_DIR="${SLEPc_DIR}" \ + -DBOOST_ROOT=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/boost-1.70.0-3mel532oks2cxz76mqrxvn4xrl3bg5ri \ + -DHDF5_ROOT=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/hdf5-1.10.5-kfyeqhtsenqumr7eut6b47mjev7tstom \ + -DEIGEN3_ROOT=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/eigen-3.3.7-bd2r4aqrkox7dpebj2r3gqvgpqzwuh7x \ + -DLAPACK_LIBRARIES=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/openblas-0.3.7-xqeap7iegoomce3es67cd7exlnq3neue/lib/libopenblas.dylib \ + -DBLAS_LIBRARIES=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/openblas-0.3.7-xqeap7iegoomce3es67cd7exlnq3neue/lib/libopenblas.dylib \ + -DPython3_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/python-3.7.4-hh7odiqwzpw2nnfdcfzjxvb3ggyzwvfk \ + -DENABLE_GCMMA=OFF \ + -DENABLE_DOT=OFF \ + -DENABLE_SNOPT=OFF \ + -DENABLE_NLOPT=OFF \ + -DENABLE_CYTHON=OFF \ + -DBUILD_DOC=OFF \ + -DENABLE_NASTRANIO=ON \ + -DENABLE_CYTHON=ON || exit + + make -j 2 || exit + echo "RUNNING UNIT TESTS" || exit + cd "${DBG_BUILD_DIR}/tests" || exit + ctest --force-new-ctest-process --output-on-failure --timeout 10 + echo "RUNNING SHORT EXAMPLES" || exit + cd "${DBG_BUILD_DIR}/examples" || exit + ctest --force-new-ctest-process --output-on-failure -L "SHORT" --timeout 60 + + # Now build/install a Release (optimized) version of MAST (-DCMAKE_BUILD_TYPE=Release). + echo "TEST RELEASE/OPTIMIZED BUILD..." + cd "${REL_BUILD_DIR}" || exit + /Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/cmake-3.14.4-vlzpkvowre6hweutogn563ouzkb73jsq/bin/cmake .. \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="${MAST_INSTALL_DIR}" \ + -DCMAKE_C_COMPILER=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/openmpi-3.1.4-sep4omvhokkexyojwrahdckfugactovb/bin/mpicc \ + -DCMAKE_CXX_COMPILER=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/openmpi-3.1.4-sep4omvhokkexyojwrahdckfugactovb/bin/mpic++ \ + -DCMAKE_Fortran_COMPILER=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/openmpi-3.1.4-sep4omvhokkexyojwrahdckfugactovb/bin/mpif90 \ + -DMPIEXEC_EXECUTABLE=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/openmpi-3.1.4-sep4omvhokkexyojwrahdckfugactovb/bin/mpiexec \ + -DlibMesh_DIR="${libMesh_DIR}" \ + -DPETSc_DIR="${PETSc_DIR}" \ + -DSLEPc_DIR="${SLEPc_DIR}" \ + -DBOOST_ROOT=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/boost-1.70.0-3mel532oks2cxz76mqrxvn4xrl3bg5ri \ + -DHDF5_ROOT=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/hdf5-1.10.5-kfyeqhtsenqumr7eut6b47mjev7tstom \ + -DEIGEN3_ROOT=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/eigen-3.3.7-bd2r4aqrkox7dpebj2r3gqvgpqzwuh7x \ + -DLAPACK_LIBRARIES=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/openblas-0.3.7-xqeap7iegoomce3es67cd7exlnq3neue/lib/libopenblas.dylib \ + -DBLAS_LIBRARIES=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/openblas-0.3.7-xqeap7iegoomce3es67cd7exlnq3neue/lib/libopenblas.dylib \ + -DPython3_DIR=/Users/travis/Code/spack-mstc/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/python-3.7.4-hh7odiqwzpw2nnfdcfzjxvb3ggyzwvfk \ + -DENABLE_GCMMA=OFF \ + -DENABLE_DOT=OFF \ + -DENABLE_SNOPT=OFF \ + -DENABLE_NLOPT=OFF \ + -DENABLE_CYTHON=OFF \ + -DBUILD_DOC=OFF \ + -DENABLE_NASTRANIO=ON \ + -DENABLE_CYTHON=ON || exit + + make -j 2 || exit + make install || exit + + echo "RUNNING UNIT TESTS" || exit + cd "${REL_BUILD_DIR}/tests" || exit + ctest --force-new-ctest-process --output-on-failure --timeout 10 + echo "RUNNING SHORT EXAMPLES" || exit + cd "${REL_BUILD_DIR}/examples" || exit + ctest --force-new-ctest-process --output-on-failure -L "SHORT" --timeout 60 + +else + echo "INVALID OS: ${TRAVIS_OS_NAME}" + exit 1 +fi + +cd "${TRAVIS_BUILD_DIR}" || exit \ No newline at end of file diff --git a/ci/deploy_docs.sh b/ci/deploy_docs.sh new file mode 100755 index 00000000..c0e71d8c --- /dev/null +++ b/ci/deploy_docs.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +# Deploy organized HTML documentation to the web host. +# +# This script deploys organized HTML documentation produced by `prepare_docs.sh` to the web host. +# It is meant to be called during the Travis-CI `deploy` stage and requires a couple of secret +# tokens to be set in the Travis-CI job. These are the values of WEBSITE_HOST_USER +# and WEBSITE_HOST_ADDRESS and are specified in the Travis-CI web interface as a secret variable +# so they are not public in the repo or build logs. + +cd ${TRAVIS_BUILD_DIR}/website || exit + +# Transfer to main hosting if on master branch. +if [ "${TRAVIS_BRANCH}" = "master" ]; then + echo "DEPLOY: Deploying master documentation to https://www.mast-multiphysics.com" || exit + rsync -e "ssh -o StrictHostKeyChecking=no" -r --delete-after --quiet . ${WEBSITE_HOST_USER}@${WEBSITE_HOST_ADDRESS}:mast-multiphysics.com || exit +fi + +# Transfer temporary version of docs for all builds originating within the primary +# MASTmultiphysics/mast-multiphysics repository for push builds. +# (no forks due to deploy/repo condition in .travis.yml, and no "pull request" merged builds since +# Travis-CI deploy stage does not run for pull requests to prevent archival of arbitrary artifacts) +# Storage is identified according to the Travis-CI build number and archives are stored for 24 hours before being removed automatically +# from the web server by an external process. +cd .. || exit +CURRENT_TIME="$(date +%Y_%m_%d-%H_%M_%S_%N)" +ARCHIVE_NAME="BUILD_NUM_${TRAVIS_BUILD_NUMBER}_TIMESTAMP_${CURRENT_TIME}.tar.gz" +echo "DEPLOY: Creating website archive: ${ARCHIVE_NAME}" || exit +tar -zcf "${ARCHIVE_NAME}" website || exit +echo "DEPLOY: Transferring archive to https://temp-docs.mast-multiphysics.com" || exit +scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -q -r "${ARCHIVE_NAME}" ${WEBSITE_HOST_USER}@${WEBSITE_HOST_ADDRESS}:temp-docs.mast-multiphysics.com || exit diff --git a/ci/get_libmesh.sh b/ci/get_libmesh.sh new file mode 100755 index 00000000..35f23e76 --- /dev/null +++ b/ci/get_libmesh.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +cd "${HOME}" || exit + +if [ "${TRAVIS_OS_NAME}" = linux ]; then # Ubuntu Linux + + if [ "${TRAVIS_DIST}" = xenial ]; then # Ubuntu 16.04 Xenial Xerus + wget -nv "https://github.com/MASTmultiphysics/mast-ci-packages/releases/download/libmesh-${LIBMESH_VERSION}-1.deb/libmesh-${LIBMESH_VERSION}-1.deb" || exit + sudo apt install "./libmesh-${LIBMESH_VERSION}-1.deb" || exit + + elif [ "${TRAVIS_DIST}" = bionic ]; then # Ubuntu 18.04 Bionic Beaver + wget -nv "https://github.com/MASTmultiphysics/mast-ci-packages/releases/download/libmesh_ubuntu18.04/libmesh-${LIBMESH_VERSION}-1.deb" || exit + sudo apt install "./libmesh-${LIBMESH_VERSION}-1.deb" || exit + + else + echo "INVALID LINUX DISTRO: ${TRAVIS_DIST}" + exit 1 + fi + + sudo ldconfig # Don't remove this, it is necessary to update the cache of shared libraries to those that were just + # unpacked in the previous steps. For some reason `apt install` doesn't do this. + +elif [ "${TRAVIS_OS_NAME}" = osx ]; then # macOS 10.14, XCode 10.2 + mkdir "Code" || exit + mkdir "Code/spack-mstc" || exit + mkdir "Code/spack-mstc/spack" || exit + cd "Code/spack-mstc/spack" || exit + wget -nv https://github.com/MASTmultiphysics/mast-ci-packages/releases/download/libmesh_macos_xcode12.2/libmesh_multiple_versions_macos_xcode_10.2.zip || exit + unzip -qq libmesh_multiple_versions_macos_xcode_10.2.zip || exit + + #command -v opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/gcc-9.1.0-4amtftgtal2cnomzekpogzanzv6weadk/bin/gfortran + #opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/gcc-9.1.0-4amtftgtal2cnomzekpogzanzv6weadk/bin/gfortran --version + #opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/gcc-9.1.0-4amtftgtal2cnomzekpogzanzv6weadk/bin/gfortran + +else + echo "INVALID OS: ${TRAVIS_OS_NAME}" + exit 1 +fi \ No newline at end of file diff --git a/ci/prepare_docs.sh b/ci/prepare_docs.sh new file mode 100755 index 00000000..7919f244 --- /dev/null +++ b/ci/prepare_docs.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +# Prepare/organize Doxygen generated HTML documentation. +# +# This script organizes the Doxygen generated HTML documentation and readies it for deployment to +# a web host. + +# This script should be called during the Travis-CI 'script' phase after documentation is built so that +# if an error occurs we can catch it on a non-master build (the 'deploy' stage only runs for commits on the +# `master` branch). We currently call it inside of `ci/build_mast.sh` on the worker that satisfies +# the condition ${CI_BUILD_DOCS}=true. To actually deploy the documentation (after running this script) +# call `ci/deploy_docs.sh`. +# + +# Organize website content. First make sure we delete any existing website contents (these may exist from +# a previous Travis-CI cache) and then copy generated HTML and other desired files. +rm -rf ${TRAVIS_BUILD_DIR}/website # Don't `|| exit` here. Its not a failure if this directory doesn't exist when + # we try to delete it. +mkdir ${TRAVIS_BUILD_DIR}/website || exit +cd ${TRAVIS_BUILD_DIR}/website || exit +rsync -r ${TRAVIS_BUILD_DIR}/build_rel/doc/doxygen/html/ . || exit +cp ${TRAVIS_BUILD_DIR}/doc/.htaccess . || exit diff --git a/cmake/FindCython.cmake b/cmake/FindCython.cmake new file mode 100644 index 00000000..b8871ff1 --- /dev/null +++ b/cmake/FindCython.cmake @@ -0,0 +1,58 @@ +# Find the Cython compiler. +# +# This code sets the following variables: +# +# Cython_FOUND - Cython is available on the system. +# Cython_EXECUTABLE - Path to the Cython executable. +# +# Note this file is a modified version of that provided by Kitware online. +# --- see original Kitware copyright statement at bottom of file. + +# Use the Cython executable that lives next to the Python executable if it +# exists. If not, we will use whatever we can find on the system paths. +if(Python3_FOUND) + get_filename_component(_PYTHON_PATH ${Python3_EXECUTABLE} PATH) + find_program(Cython_EXECUTABLE + NAMES + cython + cython.bat + cython3 + HINTS ${_PYTHON_PATH}) +else() + find_program(Cython_EXECUTABLE + NAMES + cython + cython.bat + cython3) +endif() + +# Set standard CMake variables and output status. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Cython + REQUIRED_VARS + Cython_EXECUTABLE) + +# Advance cache variables. +mark_as_advanced(Cython_EXECUTABLE) + + + + + +# Original Kitware copywrite statement. Modifications to code included +# formatting changes to utilize MAST-Interface version of FindPython.cmake. +#============================================================================= +# 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. +#============================================================================= \ No newline at end of file diff --git a/cmake/FindPython3.cmake b/cmake/FindPython3.cmake new file mode 100644 index 00000000..adee561c --- /dev/null +++ b/cmake/FindPython3.cmake @@ -0,0 +1,93 @@ +# This module relies on Python3_DIR being set. +# +# The reason that we include this module rather than the CMake provided +# FindPythonInterp, FindPythonLibs, or FindPython is that they seem to be unable +# consistently find matching Python interpreter and libraries when there +# are multiple Python distributions available (especially on macOS). +# We use a HINT in this module to try to hone in on a single Python distribution. +# +# Python3_FOUND - Python 3 required components are on the system. +# Python3_EXECUTABLE - Path to Python 3 interpreter. +# Python3_LIBRARIES - Paths to Python 3 libraries. +# Python3_INCLUDE_DIRS - Python 3 include directories (including site-packages). + +# Acceptable Python versions. +set(_PY_VERSIONS 3.8 3.7 3.6) + +# Here we ensure MacOS system provided Python distributions are found by CMake +# last because they typically don't have the functionality we want. +set(CMAKE_FIND_FRAMEWORK LAST) +set(CMAKE_FIND_APPBUNDLE LAST) + +# Build list of acceptable Python executables that we will look for. +set(_PY_NAMES "") +foreach(_PY_VER ${_PY_VERSIONS}) + list(APPEND _PY_NAMES "python${_PY_VER}") +endforeach() + +# Find path to Python interpreter. We call find_program() twice to make sure we +# search user provided Python3_DIR (CMake variable) before trying default +# system environment paths. +find_program(Python3_EXECUTABLE + NAMES ${_PY_NAMES} + HINTS + ${Python3_DIR} + PATH_SUFFIXES + "bin" + NO_DEFAULT_PATH) +find_program(Python3_EXECUTABLE + NAMES ${_PY_NAMES}) + +# Find root directory of Python distribution. Stored in Python_ROOT_DIR. +get_filename_component(Python3_BIN_DIR ${Python3_EXECUTABLE} DIRECTORY) +get_filename_component(Python3_ROOT_DIR ${Python3_BIN_DIR} DIRECTORY) +# Also, get name of Python interpreter that we actually found above. +# Stored in Python3_NAME. +get_filename_component(Python3_NAME ${Python3_EXECUTABLE} NAME) + +# Find the Python headers. +# -- Currently we search relative to Python_ROOT_DIR we found above. +find_path(Python3_INCLUDE_DIR Python.h + HINTS + ${Python3_ROOT_DIR}/include/${Python3_NAME}/ + ${Python3_ROOT_DIR}/include/${Python3_NAME}m/) + +# Find the Python library. Store also library directory to help +# find modules/site-packages. +# -- Currently we search relative to Python_ROOT_DIR we found above. +find_library(Python3_LIBRARY + NAMES ${Python3_NAME} ${Python3_NAME}m + HINTS ${Python3_ROOT_DIR}/lib) +get_filename_component(Python3_LIBRARY_DIR ${Python3_LIBRARY} DIRECTORY) + +# Find the mpi4py headers required for Cython wrapper. +# find_path(mpi4py_INCLUDE_DIR MPI.pxd +# HINTS +# ${Python_LIBRARY_DIR}/${Python_NAME}/site-packages/mpi4py) + +# find_path(Python_MODULEDIR mpi4py/MPI.pxd +# HINTS +# ${Python_LIBRARY_DIR}/${Python_NAME}/site-packages) + +# Output what we found. +message(STATUS " Python3_EXECUTABLE: ${Python3_EXECUTABLE}") +message(STATUS " Python3_INCLUDE_DIR: ${Python3_INCLUDE_DIR}") +message(STATUS " Python3_LIBRARY: ${Python3_LIBRARY}") +message(STATUS " Python3 Modules: ${Python3_MODULEDIR}") + +# Set standard CMake variables and output status. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Python3 + REQUIRED_VARS + Python3_EXECUTABLE + Python3_LIBRARY + Python3_INCLUDE_DIR) + # mpi4py_INCLUDE_DIR) +#message("-- mpi4py Headers: ${mpi4py_INCLUDE_DIR}") + +# Advance cache variables. +mark_as_advanced(Python3_INCLUDE_DIR Python3_LIBRARY Python3_EXECUTABLE) + +# Roll-up libraries and headers into standard CMake variables. +set(Python3_LIBRARIES ${Python3_LIBRARY}) +set(Python3_INCLUDE_DIRS ${Python3_INCLUDE_DIR})# ${mpi4py_INCLUDE_DIR}) \ No newline at end of file diff --git a/cmake/FindlibMesh.cmake b/cmake/FindlibMesh.cmake index 9ffa67b3..e3236445 100644 --- a/cmake/FindlibMesh.cmake +++ b/cmake/FindlibMesh.cmake @@ -3,30 +3,88 @@ # libMesh_FOUND - system has libMesh # libMesh_INCLUDE_DIRS - libMesh include directories. # libMesh_dbg_LIBRARIES - libMesh libraries (libmesh_dbg) +# libMesh_dev_LIBRARIES - libMesh libraries (libmesh_devel) # libMesh_opt_LIBRARIES - libMesh libraries (libmesh_opt) # Find the headers. find_path(libMesh_INCLUDE_DIR libmesh/libmesh_config.h - HINTS ${libMesh_DIR}/include) + HINTS ${libMesh_DIR}/include) # Find the optimized libraries. find_library(libMesh_opt_LIBRARY - NAMES mesh_opt - HINTS ${libMesh_DIR}/lib) + NAMES mesh_opt + HINTS ${libMesh_DIR}/lib) + +find_library(timpi_opt_LIBRARY + NAMES timpi_opt + HINTS ${libMesh_DIR}/lib) + +# Find the development libraries. +find_library(libMesh_dev_LIBRARY + NAMES mesh_devel + HINTS ${libMesh_DIR}/lib) + +find_library(timpi_dev_LIBRARY + NAMES timpi_devel + HINTS ${libMesh_DIR}/lib) # Find the debug libraries. find_library(libMesh_dbg_LIBRARY - NAMES mesh_dbg - HINTS ${libMesh_DIR}/lib) + NAMES mesh_dbg + HINTS ${libMesh_DIR}/lib) -# If debug library is not available then set it to the optimized library +find_library(timpi_dbg_LIBRARY + NAMES timpi_dbg + HINTS ${libMesh_DIR}/lib) + +# If debug library is not available, then set it to the development library if available, else set it to the optimized library. if(NOT libMesh_dbg_LIBRARY) - message("-- WARN: Did not find libmesh_dbg using libmesh_opt for debug version.") - find_library(libMesh_dbg_LIBRARY - NAMES mesh_opt - HINTS ${libMesh_DIR}/lib) + if(NOT libMesh_dev_LIBRARY) + if(libMesh_opt_LIBRARY) + message(WARNING "Did not find libmesh_dbg or libmesh_devel, using libmesh_opt for debug version.") + SET(libMesh_dbg_LIBRARY ${libMesh_opt_LIBRARY}) + else() + message(FATAL_ERROR "Could not find any libMesh libraries.") + endif() + else() + message(WARNING "Did not find libmesh_dbg using libmesh_devel for debug version.") + SET(libMesh_dbg_LIBRARY ${libMesh_dev_LIBRARY}) + endif() +endif() + +# If development library is not available, then set it to the debug library if available, else set it to the optimized library. +if(NOT libMesh_dev_LIBRARY) + if(NOT libMesh_dbg_LIBRARY) + message(WARNING "Did not find libMesh_devel libmesh_dbg, using libmesh_opt for development version.") + SET(libMesh_dev_LIBRARY ${libMesh_opt_LIBRARY}) + else() + message(WARNING "Did not find libMesh_devel, using libmesh_dbg for devel versions.") + SET(libMesh_dev_LIBRARY ${libMesh_dbg_LIBRARY}) + endif() +endif() + +# If optimized library is not available, then set it to the development library if available, else set it to the debug library. +if(NOT libMesh_opt_LIBRARY) + if(NOT libMesh_devel_LIBRARY) + message(WARNING "Did not find libmesh_opt or libmesh_devel, using libmesh_dbg for optimized version.") + SET(libMesh_opt_LIBRARY ${libMesh_dbg_LIBRARY}) + else() + message(WARNING "Did not find libmesh_opt, using libmesh_devel for optimized version.") + SET(libMesh_opt_LIBRARY ${libMesh_dev_LIBRARY}) + endif() +endif() + +if (NOT timpi_opt_LIBRARY) + SET(timpi_opt_LIBRARY ${libMesh_opt_LIBRARY}) endif() +if (NOT timpi_dev_LIBRARY) + SET(timpi_dev_LIBRARY ${libMesh_dev_LIBRARY}) +endif() + +if (NOT timpi_dbg_LIBRARY) + SET(timpi_dbg_LIBRARY ${libMesh_dbg_LIBRARY}) +endif() # Find libMesh version. if(libMesh_INCLUDE_DIR) @@ -52,15 +110,30 @@ endif() # Set variables. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(libMesh - REQUIRED_VARS libMesh_dbg_LIBRARY libMesh_opt_LIBRARY libMesh_INCLUDE_DIR + REQUIRED_VARS + libMesh_dbg_LIBRARY + libMesh_dev_LIBRARY + libMesh_opt_LIBRARY + timpi_dbg_LIBRARY + timpi_dev_LIBRARY + timpi_opt_LIBRARY + libMesh_INCLUDE_DIR VERSION_VAR libMesh_VERSION) mark_as_advanced(libMesh_INCLUDE_DIR libMesh_dbg_LIBRARY + libMesh_dev_LIBRARY libMesh_opt_LIBRARY + timpi_dbg_LIBRARY + timpi_dev_LIBRARY + timpi_opt_LIBRARY libMesh_VERSION libMesh_FOUND) set(libMesh_dbg_LIBRARIES ${libMesh_dbg_LIBRARY}) +set(libMesh_dev_LIBRARIES ${libMesh_dev_LIBRARY}) set(libMesh_opt_LIBRARIES ${libMesh_opt_LIBRARY}) +set(timpi_dbg_LIBRARIES ${timpi_dbg_LIBRARY}) +set(timpi_dev_LIBRARIES ${timpi_dev_LIBRARY}) +set(timpi_opt_LIBRARIES ${timpi_opt_LIBRARY}) set(libMesh_INCLUDE_DIRS ${libMesh_INCLUDE_DIR}) diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt new file mode 100644 index 00000000..66bad566 --- /dev/null +++ b/contrib/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(libfort) \ No newline at end of file diff --git a/contrib/README.md b/contrib/README.md new file mode 100644 index 00000000..ef0759cf --- /dev/null +++ b/contrib/README.md @@ -0,0 +1,16 @@ +# External Third Party Sources +This directory contains files developed by third parties and are included in the MAST +source for convenience. In all cases, this is permitted by both the third party project's +license and the MAST license. + +## catch (Catch2 testing framework) +- A multi-paradigm test framework for C++, distributed primarily as a single header +- Files: `catch.hpp` +- License: [Boost Software License 1.0](https://github.com/catchorg/Catch2/blob/master/LICENSE.txt) +- https://github.com/catchorg/Catch2 + +## libfort (Library to create FORmatted Tables) +- C/C++ library to create formatted ASCII tables for console applications +- Files: `fort.c`, `fort.h`, `fort.hpp` +- License: [MIT](https://github.com/seleznevae/libfort/blob/develop/LICENSE) +- https://github.com/seleznevae/libfort diff --git a/contrib/catch/catch.hpp b/contrib/catch/catch.hpp new file mode 100644 index 00000000..b4eccfc1 --- /dev/null +++ b/contrib/catch/catch.hpp @@ -0,0 +1,17597 @@ +/* + * Catch v2.11.0 + * Generated: 2019-11-15 15:01:56.628356 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +// start catch.hpp + + +#define CATCH_VERSION_MAJOR 2 +#define CATCH_VERSION_MINOR 11 +#define CATCH_VERSION_PATCH 0 + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +// start catch_suppress_warnings.h + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ + // Because REQUIREs trigger GCC's -Wparentheses, and because still + // supported version of g++ have only buggy support for _Pragmas, + // Wparentheses have to be suppressed globally. +# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details + +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic ignored "-Wpadded" +#endif +// end catch_suppress_warnings.h +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +# define CATCH_CONFIG_ALL_PARTS +#endif + +// In the impl file, we want to have access to all parts of the headers +// Can also be used to sanely support PCHs +#if defined(CATCH_CONFIG_ALL_PARTS) +# define CATCH_CONFIG_EXTERNAL_INTERFACES +# if defined(CATCH_CONFIG_DISABLE_MATCHERS) +# undef CATCH_CONFIG_DISABLE_MATCHERS +# endif +# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +# endif +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) +// start catch_platform.h + +#ifdef __APPLE__ +# include +# if TARGET_OS_OSX == 1 +# define CATCH_PLATFORM_MAC +# elif TARGET_OS_IPHONE == 1 +# define CATCH_PLATFORM_IPHONE +# endif + +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX + +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) +# define CATCH_PLATFORM_WINDOWS +#endif + +// end catch_platform.h + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +// start catch_user_interfaces.h + +namespace Catch { + unsigned int rngSeed(); +} + +// end catch_user_interfaces.h +// start catch_tag_alias_autoregistrar.h + +// start catch_common.h + +// start catch_compiler_capabilities.h + +// Detect a number of compiler features - by compiler +// The following features are defined: +// +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +#ifdef __cplusplus + +# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) +# define CATCH_CPP14_OR_GREATER +# endif + +# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +# define CATCH_CPP17_OR_GREATER +# endif + +#endif + +#if defined(CATCH_CPP17_OR_GREATER) +# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif + +// We have to avoid both ICC and Clang, because they try to mask themselves +// as gcc, and we want only GCC in this block +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) +#endif + +#if defined(__clang__) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) + +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) + +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// Assume that non-Windows platforms support posix signals by default +#if !defined(CATCH_PLATFORM_WINDOWS) + #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS +#endif + +//////////////////////////////////////////////////////////////////////////////// +// We know some environments not to support full POSIX signals +#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) + #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#endif + +#ifdef __OS400__ +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# define CATCH_CONFIG_COLOUR_NONE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Not all Windows environments support SEH properly +#if defined(__MINGW32__) +# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#endif + +//////////////////////////////////////////////////////////////////////////////// +// PS4 +#if defined(__ORBIS__) +# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE +// some versions of cygwin (most) do not support std::to_string. Use the libstd check. +// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 +# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ + && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) + +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING + +# endif +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#if defined(_MSC_VER) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) + +# if _MSC_VER >= 1900 // Visual Studio 2015 or newer +# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +# endif + +// Universal Windows platform does not support SEH +// Or console colours (or console at all...) +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define CATCH_CONFIG_COLOUR_NONE +# else +# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +# endif + +// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ +// _MSVC_TRADITIONAL == 0 means new conformant preprocessor +// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor +# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +# endif +#endif // _MSC_VER + +#if defined(_REENTRANT) || defined(_MSC_VER) +// Enable async processing, as -pthread is specified or no additional linking is required +# define CATCH_INTERNAL_CONFIG_USE_ASYNC +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// +// Check if we are compiled with -fno-exceptions or equivalent +#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) +# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED +#endif + +//////////////////////////////////////////////////////////////////////////////// +// DJGPP +#ifdef __DJGPP__ +# define CATCH_INTERNAL_CONFIG_NO_WCHAR +#endif // __DJGPP__ + +//////////////////////////////////////////////////////////////////////////////// +// Embarcadero C++Build +#if defined(__BORLANDC__) + #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// Use of __COUNTER__ is suppressed during code analysis in +// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly +// handled by it. +// Otherwise all supported compilers support COUNTER macro, +// but user still might want to turn it off +#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) + #define CATCH_INTERNAL_CONFIG_COUNTER +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// RTX is a special version of Windows that is real time. +// This means that it is detected as Windows, but does not provide +// the same set of capabilities as real Windows does. +#if defined(UNDER_RTSS) || defined(RTX64_BUILD) + #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH + #define CATCH_INTERNAL_CONFIG_NO_ASYNC + #define CATCH_CONFIG_COLOUR_NONE +#endif + +#if defined(__UCLIBC__) +#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Various stdlib support checks that require __has_include +#if defined(__has_include) + // Check if string_view is available and usable + #if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW + #endif + + // Check if optional is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if byte is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_BYTE + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if variant is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # if defined(__clang__) && (__clang_major__ < 8) + // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 + // fix should be in clang 8, workaround in libstdc++ 8.2 + # include + # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # define CATCH_CONFIG_NO_CPP17_VARIANT + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__clang__) && (__clang_major__ < 8) + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) +#endif // defined(__has_include) + +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) +# define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) +# define CATCH_CONFIG_WCHAR +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) +# define CATCH_CONFIG_CPP17_OPTIONAL +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) +# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) +# define CATCH_CONFIG_CPP17_STRING_VIEW +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) +# define CATCH_CONFIG_CPP17_VARIANT +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) +# define CATCH_CONFIG_CPP17_BYTE +#endif + +#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) +# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) +# define CATCH_CONFIG_NEW_CAPTURE +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +# define CATCH_CONFIG_DISABLE_EXCEPTIONS +#endif + +#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) +# define CATCH_CONFIG_POLYFILL_ISNAN +#endif + +#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) +# define CATCH_CONFIG_USE_ASYNC +#endif + +#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) +# define CATCH_CONFIG_ANDROID_LOGWRITE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) +# define CATCH_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Even if we do not think the compiler has that warning, we still have +// to provide a macro that can be used by the code. +#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS +#endif + +#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#elif defined(__clang__) && (__clang_major__ < 5) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +#define CATCH_TRY if ((true)) +#define CATCH_CATCH_ALL if ((false)) +#define CATCH_CATCH_ANON(type) if ((false)) +#else +#define CATCH_TRY try +#define CATCH_CATCH_ALL catch (...) +#define CATCH_CATCH_ANON(type) catch (type) +#endif + +#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) +#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#endif + +// end catch_compiler_capabilities.h +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#include +#include +#include + +// We need a dummy global operator<< so we can bring it into Catch namespace later +struct Catch_global_namespace_dummy {}; +std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); + +namespace Catch { + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; + + protected: + NonCopyable(); + virtual ~NonCopyable(); + }; + + struct SourceLineInfo { + + SourceLineInfo() = delete; + SourceLineInfo( char const* _file, std::size_t _line ) noexcept + : file( _file ), + line( _line ) + {} + + SourceLineInfo( SourceLineInfo const& other ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo( SourceLineInfo&& ) noexcept = default; + SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; + + bool empty() const noexcept { return file[0] == '\0'; } + bool operator == ( SourceLineInfo const& other ) const noexcept; + bool operator < ( SourceLineInfo const& other ) const noexcept; + + char const* file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // Bring in operator<< from global namespace into Catch namespace + // This is necessary because the overload of operator<< above makes + // lookup stop at namespace Catch + using ::operator<<; + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() const; + }; + template + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO \ + ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) + +// end catch_common.h +namespace Catch { + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + +// end catch_tag_alias_autoregistrar.h +// start catch_test_registry.h + +// start catch_interfaces_testcase.h + +#include + +namespace Catch { + + class TestSpec; + + struct ITestInvoker { + virtual void invoke () const = 0; + virtual ~ITestInvoker(); + }; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool isThrowSafe( TestCase const& testCase, IConfig const& config ); + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); + +} + +// end catch_interfaces_testcase.h +// start catch_stringref.h + +#include +#include +#include +#include + +namespace Catch { + + /// A non-owning string class (similar to the forthcoming std::string_view) + /// Note that, because a StringRef may be a substring of another string, + /// it may not be null terminated. + class StringRef { + public: + using size_type = std::size_t; + using const_iterator = const char*; + + private: + static constexpr char const* const s_empty = ""; + + char const* m_start = s_empty; + size_type m_size = 0; + + public: // construction + constexpr StringRef() noexcept = default; + + StringRef( char const* rawChars ) noexcept; + + constexpr StringRef( char const* rawChars, size_type size ) noexcept + : m_start( rawChars ), + m_size( size ) + {} + + StringRef( std::string const& stdString ) noexcept + : m_start( stdString.c_str() ), + m_size( stdString.size() ) + {} + + explicit operator std::string() const { + return std::string(m_start, m_size); + } + + public: // operators + auto operator == ( StringRef const& other ) const noexcept -> bool; + auto operator != (StringRef const& other) const noexcept -> bool { + return !(*this == other); + } + + auto operator[] ( size_type index ) const noexcept -> char { + assert(index < m_size); + return m_start[index]; + } + + public: // named queries + constexpr auto empty() const noexcept -> bool { + return m_size == 0; + } + constexpr auto size() const noexcept -> size_type { + return m_size; + } + + // Returns the current start pointer. If the StringRef is not + // null-terminated, throws std::domain_exception + auto c_str() const -> char const*; + + public: // substrings and searches + // Returns a substring of [start, start + length). + // If start + length > size(), then the substring is [start, size()). + // If start > size(), then the substring is empty. + auto substr( size_type start, size_type length ) const noexcept -> StringRef; + + // Returns the current start pointer. May not be null-terminated. + auto data() const noexcept -> char const*; + + constexpr auto isNullTerminated() const noexcept -> bool { + return m_start[m_size] == '\0'; + } + + public: // iterators + constexpr const_iterator begin() const { return m_start; } + constexpr const_iterator end() const { return m_start + m_size; } + }; + + auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; + auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; + + constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { + return StringRef( rawChars, size ); + } +} // namespace Catch + +constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { + return Catch::StringRef( rawChars, size ); +} + +// end catch_stringref.h +// start catch_preprocessor.hpp + + +#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ +#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) + +#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ +// MSVC needs more evaluations +#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) +#else +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) +#endif + +#define CATCH_REC_END(...) +#define CATCH_REC_OUT + +#define CATCH_EMPTY() +#define CATCH_DEFER(id) id CATCH_EMPTY() + +#define CATCH_REC_GET_END2() 0, CATCH_REC_END +#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 +#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 +#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT +#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) +#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) + +#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) + +#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) + +// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, +// and passes userdata as the first parameter to each invocation, +// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) +#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) +#else +// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) +#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) +#endif + +#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ +#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) + +#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) +#else +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) +#endif + +#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ + CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) + +#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) +#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) +#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) +#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) +#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) +#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) +#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) +#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) +#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) + +#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N + +#define INTERNAL_CATCH_TYPE_GEN\ + template struct TypeList {};\ + template\ + constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ + template class...> struct TemplateTypeList{};\ + template class...Cs>\ + constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ + template\ + struct append;\ + template\ + struct rewrap;\ + template class, typename...>\ + struct create;\ + template class, typename>\ + struct convert;\ + \ + template \ + struct append { using type = T; };\ + template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ + struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ + template< template class L1, typename...E1, typename...Rest>\ + struct append, TypeList, Rest...> { using type = L1; };\ + \ + template< template class Container, template class List, typename...elems>\ + struct rewrap, List> { using type = TypeList>; };\ + template< template class Container, template class List, class...Elems, typename...Elements>\ + struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ + \ + template