name: Grid and Mesh Solver
on: [push]

env:
  PETSC_VERSION: '3.16.2'
  HOMEBREW_NO_ANALYTICS: 'ON'     # Make Homebrew installation a little quicker
  HOMEBREW_NO_AUTO_UPDATE: 'ON'
  HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: 'ON'
  HOMEBREW_NO_GITHUB_API: 'ON'
  HOMEBREW_NO_INSTALL_CLEANUP: 'ON'

jobs:

  gcc:

    runs-on: ${{ matrix.os }}

    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
        gcc_v: [9, 10, 11]      # Version of GCC compilers

    env:
      GCC_V: ${{ matrix.gcc_v }}

    steps:

      - uses: actions/checkout@v2

      - name: GCC - Install (Linux)
        if: contains( matrix.os, 'ubuntu')
        run: |
          sudo add-apt-repository ppa:ubuntu-toolchain-r/test
          sudo apt-get update
          sudo apt-get install -y gcc-${GCC_V} gfortran-${GCC_V} g++-${GCC_V}
          sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_V} 100 \
          --slave /usr/bin/gfortran gfortran /usr/bin/gfortran-${GCC_V} \
          --slave /usr/bin/g++      g++      /usr/bin/g++-${GCC_V} \
          --slave /usr/bin/gcov     gcov     /usr/bin/gcov-${GCC_V}

      - name: GCC - Install (macOS)
        if: contains( matrix.os, 'macos')
        run: |
          brew install gcc@${GCC_V} || brew upgrade gcc@${GCC_V} || true
          brew link gcc@${GCC_V}

      - name: PETSc - Cache download
        id: petsc-download
        uses: actions/cache@v2
        with:
          path: download
          key: petsc-${{ env.PETSC_VERSION }}.tar.gz

      - name: PETSc - Download
        if: steps.petsc-download.outputs.cache-hit != 'true'
        run: |
          wget -q https://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-${PETSC_VERSION}.tar.gz -P download

      - name: PETSc - Prepare
        run: |
          tar -xf download/petsc-${PETSC_VERSION}.tar.gz -C .
          export PETSC_DIR=${PWD}/petsc-${PETSC_VERSION}
          export PETSC_ARCH=gcc${GCC_V}
          printenv >> $GITHUB_ENV

      - name: PETSc - Cache installation
        id: petsc-install
        uses: actions/cache@v2
        with:
          path: petsc-${{ env.PETSC_VERSION }}
          key: petsc-${{ env.PETSC_VERSION }}-${{ matrix.os }}-gcc${{ matrix.gcc_v }}-${{ hashFiles('**/petscversion.h') }}

      - name: PETSc - Install (Linux)
        if: contains( matrix.os, 'ubuntu')
        run: |
          cd petsc-${PETSC_VERSION}
          ./configure --with-fc=gfortran --with-cc=gcc --with-cxx=g++ \
          --download-mpich --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib \
          --with-mpi-f90module-visibility=0
          make all

      - name: PETSc - Install (macOS)
        if: contains( matrix.os, 'macos')
        run: |
          cd petsc-${PETSC_VERSION}
          ./configure --with-fc=gfortran-${GCC_V} --with-cc=gcc-${GCC_V} --with-cxx=g++-${GCC_V} \
          --download-openmpi --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib
          make all

      - name: DAMASK - Compile
        run: |
          cmake -B build/grid -DDAMASK_SOLVER=grid -DCMAKE_INSTALL_PREFIX=${PWD}
          cmake --build build/grid --parallel
          cmake --install build/grid
          cmake -B build/mesh -DDAMASK_SOLVER=mesh -DCMAKE_INSTALL_PREFIX=${PWD}
          cmake --build build/mesh --parallel
          cmake --install build/mesh

      - name: DAMASK - Run
        run: |
          ./bin/DAMASK_grid -l tensionX.yaml -g 20grains16x16x16.vti -w examples/grid

  intel:

    runs-on: [ubuntu-latest]

    strategy:
      matrix:
        intel_v: [classic, llvm]      # Variant of Intel compilers

    env:
      INTEL_V: ${{ matrix.intel_v }}

    steps:
      - uses: actions/checkout@v2

      - name: Intel - Install
        run: |
          wget -q https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
          sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
          rm GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
          echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
          sudo apt-get update
          sudo apt-get install \
          intel-basekit \
          intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic intel-oneapi-compiler-fortran \
          intel-oneapi-openmp intel-oneapi-mkl-devel
          source /opt/intel/oneapi/setvars.sh
          printenv >> $GITHUB_ENV

      - name: PETSc - Cache download
        id: petsc-download
        uses: actions/cache@v2
        with:
          path: download
          key: petsc-${{ env.PETSC_VERSION }}.tar.gz

      - name: PETSc - Download
        if: steps.petsc-download.outputs.cache-hit != 'true'
        run: |
          wget -q https://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-${PETSC_VERSION}.tar.gz -P download

      - name: PETSc - Prepare
        run: |
          tar -xf download/petsc-${PETSC_VERSION}.tar.gz -C .
          export PETSC_DIR=${PWD}/petsc-${PETSC_VERSION}
          export PETSC_ARCH=intel-${INTEL_V}
          printenv >> $GITHUB_ENV

      - name: PETSc - Cache installation
        id: petsc-install
        uses: actions/cache@v2
        with:
          path: petsc-${{ env.PETSC_VERSION }}
          key: petsc-${{ env.PETSC_VERSION }}-intel-${{ matrix.intel_v }}-${{ hashFiles('**/petscversion.h') }}

      - name: PETSc - Install (classic)
        if: contains( matrix.intel_v, 'classic')
        run: |
          cd petsc-${PETSC_VERSION}
          ./configure --with-fc=mpiifort --with-cc=mpiicc --with-cxx=mpiicpc \
          --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib
          make all

      - name: PETSc - Install (LLVM)
        if: contains( matrix.intel_v, 'llvm')
        run: |
          cd petsc-${PETSC_VERSION}
          ./configure --with-fc=mpiifort --with-cc="mpiicc -cc=icx" --with-cxx="mpiicpc -cxx=icpx" \
          --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib
          make all

      - name: DAMASK - Compile
        run: |
          cmake -B build/grid -DDAMASK_SOLVER=grid -DCMAKE_INSTALL_PREFIX=${PWD}
          cmake --build build/grid --parallel
          cmake --install build/grid
          cmake -B build/mesh -DDAMASK_SOLVER=mesh -DCMAKE_INSTALL_PREFIX=${PWD}
          cmake --build build/mesh --parallel
          cmake --install build/mesh

      - name: DAMASK - Run
        run: |
          ./bin/DAMASK_grid -l tensionX.yaml -g 20grains16x16x16.vti -w examples/grid