CMAKE_DEPENDENT_OPTION(NEKTAR_SOLVER_ADR
    "Build the ADR Solver." ON
    "NEKTAR_BUILD_SOLVERS" OFF)

IF (NOT NEKTAR_BUILD_SOLVERS)
    SET(NEKTAR_SOLVER_ADR OFF CACHE INTERNAL "")
ENDIF()

IF( NEKTAR_SOLVER_ADR )
    ADD_SOLVER_EXECUTABLE(ADRSolver SOURCES
        ./ADRSolver.cpp
        ./EquationSystems/Helmholtz.cpp
        ./EquationSystems/Laplace.cpp
        ./EquationSystems/LaplacePhi.cpp
        ./EquationSystems/Poisson.cpp
        ./EquationSystems/Projection.cpp
        ./EquationSystems/SteadyAdvectionDiffusion.cpp
        ./EquationSystems/SteadyAdvectionDiffusionReaction.cpp
        ./EquationSystems/UnsteadyAdvection.cpp
        ./EquationSystems/MMFAdvection.cpp
        ./EquationSystems/UnsteadyDiffusion.cpp
        ./EquationSystems/UnsteadyAdvectionDiffusion.cpp
        ./EquationSystems/UnsteadyInviscidBurgers.cpp
        ./EquationSystems/UnsteadyReactionDiffusion.cpp
        ./EquationSystems/UnsteadyViscousBurgers.cpp
        ./EquationSystems/EigenValuesAdvection.cpp)

    IF(NEKTAR_BUILD_SOLVER_LIBS)
        MESSAGE(WARNING, "Solver library build not set up for ADRSolver - skipping.")
    ENDIF()

    # Parareal solver
    ADD_NEKTAR_PERFORMANCE_TEST(Perf_CubeAllElements)

    # Parallel-in-time solver
    IF (NEKTAR_USE_MPI)
        # The deactivate tests can be usefull for debugging purpose.
        ADD_NEKTAR_TEST(PFASSTDriverUnsteadyAdvection1D)
        ADD_NEKTAR_TEST(PFASSTDriverUnsteadyAdvection2D)
        ADD_NEKTAR_TEST(PararealDriverUnsteadyAdvection2D)
        # ADD_NEKTAR_TEST(PararealDriverImDiffusion_m6_iter0)
        # ADD_NEKTAR_TEST(PararealDriverImDiffusion_m6_iter2)
        # ADD_NEKTAR_TEST(PararealDriverImDiffusion_m6_iter4)
        # ADD_NEKTAR_TEST(PararealDriverImDiffusion_m12_iter0)
        # ADD_NEKTAR_TEST(PararealDriverImDiffusion_m12_iter2)
        ADD_NEKTAR_TEST(PararealDriverImDiffusion_m12_iter4)
        # ADD_NEKTAR_TEST(PararealDriverImDiffusion_m12_partition_iter0)
        # ADD_NEKTAR_TEST(PararealDriverImDiffusion_m12_partition_iter2)
        ADD_NEKTAR_TEST(PararealDriverImDiffusion_m12_partition_iter4)
    ENDIF()

    # SDC time-integration
    ADD_NEKTAR_TEST(UnsteadyAdvection2D_ExplicitSDCGaussLobattoLegendre)
    ADD_NEKTAR_TEST(UnsteadyAdvection2D_ExplicitSDCGaussRadauLegendre)
    ADD_NEKTAR_TEST(UnsteadyAdvection2D_ExplicitSDCGaussGaussLegendre)
    ADD_NEKTAR_TEST(UnsteadyDiffusion2D_ImplicitSDCGaussRadauLegendre)
    ADD_NEKTAR_TEST(UnsteadyDiffusion2D_ImplicitSDCGaussGaussLegendre)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion2D_IMEXSDCGaussRadauLegendre)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion2D_IMEXSDCGaussGaussLegendre)

    # IMEXdirk time-integration
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion2D_IMEXdirk_1_1_1)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion2D_IMEXdirk_1_2_1)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion2D_IMEXdirk_1_2_2)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion2D_IMEXdirk_2_2_2)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion2D_IMEXdirk_2_3_2)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion2D_IMEXdirk_2_3_3)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion2D_IMEXdirk_3_4_3)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion2D_IMEXdirk_4_4_3)

    #MMF advection
    ADD_NEKTAR_TEST        (TestMMFAdvPlane)
    ADD_NEKTAR_TEST        (TestMMFAdvCube)
    ADD_NEKTAR_TEST        (TestMMFAdvSphere)

    # 1D discontinuous advection
    ADD_NEKTAR_TEST(Advection1D_WeakDG_GLL_LAGRANGE_SEM)
    ADD_NEKTAR_TEST(Advection1D_WeakDG_GLL_LAGRANGE)
    ADD_NEKTAR_TEST(Advection1D_WeakDG_GAUSS_LAGRANGE)
    ADD_NEKTAR_TEST(Advection1D_WeakDG_MODIFIED)

    # 2D discontinuous advection (weak DG/flux reconstruction)
    ADD_NEKTAR_TEST(Advection2D_dirichlet_deformed_GLL_LAGRANGE_10x10)
    ADD_NEKTAR_TEST(Advection2D_dirichlet_deformed_GAUSS_LAGRANGE_10x10)
    ADD_NEKTAR_TEST(Advection2D_dirichlet_deformed_GLL_LAGRANGE_SEM_10x10 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_dirichlet_deformed_MODIFIED_10x10)
    ADD_NEKTAR_TEST(Advection2D_dirichlet_deformed_MODIFIED_10x10_varP)
    ADD_NEKTAR_TEST(Advection2D_dirichlet_regular_GLL_LAGRANGE_10x10)
    ADD_NEKTAR_TEST(Advection2D_dirichlet_regular_GAUSS_LAGRANGE_10x10)
    ADD_NEKTAR_TEST(Advection2D_dirichlet_regular_GAUSS_LAGRANGE_10x10_MF)
    ADD_NEKTAR_TEST(Advection2D_dirichlet_regular_GLL_LAGRANGE_SEM_10x10 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_dirichlet_regular_MODIFIED_10x10)
    ADD_NEKTAR_TEST(Advection2D_dirichlet_regular_MODIFIED_triangle_98)
    ADD_NEKTAR_TEST(Advection2D_dirichlet_regular_MODIFIED_triangle_98_MF)
    ADD_NEKTAR_TEST(Advection2D_ISO_deformed_GLL_LAGRANGE_3x3 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_ISO_deformed_GAUSS_LAGRANGE_3x3 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_ISO_deformed_GLL_LAGRANGE_SEM_3x3 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_ISO_deformed_MODIFIED_3x3 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_ISO_regular_GLL_LAGRANGE_3x3 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_ISO_regular_GAUSS_LAGRANGE_3x3 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_ISO_regular_GLL_LAGRANGE_SEM_3x3 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_ISO_regular_MODIFIED_3x3 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_ISO_reg_def_MODIFIED_3x3)
    ADD_NEKTAR_TEST(Advection2D_periodic_deformed_GLL_LAGRANGE_2x2)
    ADD_NEKTAR_TEST(Advection2D_periodic_deformed_GAUSS_LAGRANGE_2x2)
    ADD_NEKTAR_TEST(Advection2D_periodic_deformed_GLL_LAGRANGE_SEM_2x2 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_periodic_deformed_MODIFIED_2x2)
    ADD_NEKTAR_TEST(Advection2D_periodic_regular_GLL_LAGRANGE_2x2)
    ADD_NEKTAR_TEST(Advection2D_periodic_regular_GAUSS_LAGRANGE_2x2)
    ADD_NEKTAR_TEST(Advection2D_periodic_regular_GLL_LAGRANGE_SEM_2x2 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_periodic_regular_MODIFIED_2x2)
    ADD_NEKTAR_TEST(Advection2D_periodic_deformed_GLL_LAGRANGE_10x10 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_periodic_deformed_GLL_LAGRANGE_SEM_10x10 LENGTHY)
    ADD_NEKTAR_TEST(Advection2D_periodic_deformed_MODIFIED_10x10 LENGTHY)
    ADD_NEKTAR_TEST(Advection_m12_DG_periodic)
    ADD_NEKTAR_TEST(Advection2D_m12_DG_quad_VarP)
    ADD_NEKTAR_TEST(Advection2D_m12_DG_tri_VarP)
    ADD_NEKTAR_TEST(Advection2D_ISO_regular_SSPRK2)
    ADD_NEKTAR_TEST(Advection2D_ISO_regular_SSPRK3)

    # GJP tests
    ADD_NEKTAR_TEST(Advection2D_Quad_GJP)
    ADD_NEKTAR_TEST(Advection2D_Tri_GJP)
    ADD_NEKTAR_TEST(AdvDiff_QuadTri_GJP)
    ADD_NEKTAR_TEST(AdvDiff3D_AllElmt_GJP)

    # 1D continuous advection (non-conservative)
    ADD_NEKTAR_TEST(Advection1D_implicit)

    # 2D continuous advection (non-conservative)
    ADD_NEKTAR_TEST(Advection_m12_Order1)
    ADD_NEKTAR_TEST(Advection_m12_Order2)
    ADD_NEKTAR_TEST(Advection_m14_Order4)
    ADD_NEKTAR_TEST(CylindricalHelmholtz)

    # 2D advection diffusion (Imex DG)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion_2D_ImexDG)

    # 2D advection diffusion (Weak DG)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion_2D_WeakDG)

    # 3D discontinous advection
    ADD_NEKTAR_TEST(Advection3D_AllElmt_GJP)
    ADD_NEKTAR_TEST(Advection3D_m10_DG_hex_periodic_nodal LENGTHY)
    ADD_NEKTAR_TEST(Advection3D_m8_DG_hex_nodal)
    ADD_NEKTAR_TEST(Advection3D_m12_DG_hex_periodic)
    ADD_NEKTAR_TEST(Advection3D_m8_DG_hex)
    ADD_NEKTAR_TEST(Advection3D_m8_DG_hex_MF)
    ADD_NEKTAR_TEST(Advection3D_m10_DG_hex_VarP)
    ADD_NEKTAR_TEST(Advection3D_m12_DG_prism)
    ADD_NEKTAR_TEST(Advection3D_m10_DG_prism_VarP)
    ADD_NEKTAR_TEST(Advection3D_m12_DG_tet)
    ADD_NEKTAR_TEST(Advection3D_m12_DG_tet_VarP)
    # face rotation test
    ADD_NEKTAR_TEST(Advection3D_DG_hex_faceRotation1122)
    ADD_NEKTAR_TEST(Advection3D_DG_hex_faceRotation1221)
    ADD_NEKTAR_TEST(Advection3D_DG_hex_varP_faceRotation1122)
    ADD_NEKTAR_TEST(Advection3D_DG_hex_varP_faceRotation1221)
    ADD_NEKTAR_TEST(Advection3D_DG_prism)
    ADD_NEKTAR_TEST(Advection3D_DG_prism_varP)
    ADD_NEKTAR_TEST(Advection3D_DG_pyr)
    ADD_NEKTAR_TEST(Advection3D_DG_pyr_varP)

    # 1D inviscid Burgers (DG)
    ADD_NEKTAR_TEST(InviscidBurgers1D_WeakDG_GLL_LAGRANGE_SEM)
    ADD_NEKTAR_TEST(InviscidBurgers1D_WeakDG_GLL_LAGRANGE)
    ADD_NEKTAR_TEST(InviscidBurgers1D_WeakDG_GAUSS_LAGRANGE)
    ADD_NEKTAR_TEST(InviscidBurgers1D_WeakDG_MODIFIED)
    ADD_NEKTAR_TEST(InviscidBurgers1D_WeakDG)
    ADD_NEKTAR_TEST(ViscousBurgers1D_WeakDG)
    ADD_NEKTAR_TEST(ViscousBurgers1D_WeakDG_IMEX)

    # 1D explicit diffusion (LDG)
    ADD_NEKTAR_TEST(ExDiffusion_1D_LDG)
    ADD_NEKTAR_TEST(ExDiffusion_1D_LDG_GAUSS)

    # 2D explicit diffusion (LDG)
    ADD_NEKTAR_TEST(ExDiffusion_2D_LDG_hybrid_m3)
    ADD_NEKTAR_TEST(ExDiffusion_2D_LDG_hybrid_m3_periodic)
    ADD_NEKTAR_TEST(ExDiffusion_2D_LDG_hybrid_m8 LENGTHY)
    ADD_NEKTAR_TEST(ExDiffusion_2D_LDG_regular_Neumann)
    ADD_NEKTAR_TEST(ExDiffusion_2D_LDG_regular_Neumann_GAUSS)
    ADD_NEKTAR_TEST(ExDiffusion_2D_LDG_deformed)
    ADD_NEKTAR_TEST(ExDiffusion_2D_LDG_deformed_GAUSS)
    ADD_NEKTAR_TEST(ExDiffusion_VarCoeff)

    # C^0 projection
    ADD_NEKTAR_TEST(Projection2D)

    # Reaction-diffusion
    ADD_NEKTAR_TEST(ReactionDiffusion2D)
    ADD_NEKTAR_TEST(ExReactionDiffusion2D)

    ADD_NEKTAR_TEST(Helmholtz1D_8modes_DG)
    ADD_NEKTAR_TEST(Helmholtz1D_8modes)
    ADD_NEKTAR_TEST(Helmholtz1D_800modes LENGTHY)
    ADD_NEKTAR_TEST(Helmholtz1D_8nodes)

    ADD_NEKTAR_TEST(SteadyAdvDiffReact2D_modal)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion_3DHomo1D_MVM)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion_3DHomo2D_MVM)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion_Order1_0001)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion_Order1_001)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion_Order2_0001)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion_Order2_001)
    ADD_NEKTAR_TEST(UnsteadyAdvection_WDG_3DHomo1D_MVM)
    ADD_NEKTAR_TEST(UnsteadyDiffusion_LDG_3DHomo1D_MVM)
    ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion_WeakDG_LDG_3DHomo1D_MVM)

    ADD_NEKTAR_TEST(Helmholtz2D_modal_DG)
    ADD_NEKTAR_TEST(Helmholtz2D_modal)
    ADD_NEKTAR_TEST(Helmholtz2D_nodal)
    ADD_NEKTAR_TEST(Helmholtz2D_DirectFull)
    ADD_NEKTAR_TEST(Helmholtz2D_DirectFull_pRef)
    ADD_NEKTAR_TEST(Helmholtz3D_nodal_HexDeformed)
    ADD_NEKTAR_TEST(Helmholtz_3DHomo1D_MVM)
    ADD_NEKTAR_TEST(Helmholtz_3DHomo2D_MVM)
    ADD_NEKTAR_TEST(Helmholtz3D_modal)
    ADD_NEKTAR_TEST(Helmholtz3D_nodal LENGTHY)
    ADD_NEKTAR_TEST(Helmholtz3D_CubePeriodic)
    ADD_NEKTAR_TEST(Helmholtz3D_Cube_BndFile)
    ADD_NEKTAR_TEST(Helmholtz3D_Cube_BndFile_Lagrange)
    ADD_NEKTAR_TEST(Helmholtz3D_CubePeriodic_RotateFace)
    ADD_NEKTAR_TEST(Helmholtz3D_Cube_pRef)
    ADD_NEKTAR_TEST(Helmholtz3D_Cube_pRef_MixedType)
    ADD_NEKTAR_TEST(CubeAllElements)
    ADD_NEKTAR_TEST(ImDiffusion_m12)
    ADD_NEKTAR_TEST(ImDiffusion_m6)
    ADD_NEKTAR_TEST(ImDiffusion_m12_DIRKOrder3_ES5)
    ADD_NEKTAR_TEST(ImDiffusion_m12_DIRKOrder4_ES6)
    ADD_NEKTAR_TEST(ImDiffusion_VarCoeff)
    ADD_NEKTAR_TEST(ImDiffusion_VarCoeff_DirectFull)
    ADD_NEKTAR_TEST(ImDiffusion_Quad_Periodic_m7)
    ADD_NEKTAR_TEST(ImDiffusion_Hex_Periodic_m5)
    ADD_NEKTAR_TEST(SVV_Quad)
    ADD_NEKTAR_TEST(SVV_Tri)
    ADD_NEKTAR_TEST(SVV_Prism)
    ADD_NEKTAR_TEST(SVV_Tet)
    ADD_NEKTAR_TEST(LaplacePhi)

    # Movement tests
    ADD_NEKTAR_TEST(Movement_fixed_interfaces232_dirichlet)
    ADD_NEKTAR_TEST(Movement_fixed_interfaces232_periodic)
    ADD_NEKTAR_TEST(Movement_fixed_3D_Hex41)
    ADD_NEKTAR_TEST(Movement_fixed_2D_curved_quads)
    ADD_NEKTAR_TEST(Movement_fixed_2D_varied)
    ADD_NEKTAR_TEST(Movement_fixed_3D_stacked_cylinders_curved)
    ADD_NEKTAR_TEST(Movement_translate_interfaces232_dirichlet)

    IF (NEKTAR_USE_FFTW)
        ADD_NEKTAR_TEST(Helmholtz_3DHomo1D_FFT)
        ADD_NEKTAR_TEST(Helmholtz_3DHomo2D_FFT)
        ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion_3DHomo1D_FFT)
        ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion_3DHomo2D_FFT)
	ADD_NEKTAR_TEST(UnsteadyAdvection_WDG_3DHomo1D_FFT)
	ADD_NEKTAR_TEST(UnsteadyDiffusion_LDG_3DHomo1D_FFT)
        ADD_NEKTAR_TEST(UnsteadyAdvectionDiffusion_WeakDG_LDG_3DHomo1D_FFT)
    ENDIF (NEKTAR_USE_FFTW)

    ADD_NEKTAR_TEST(RotPerBcs3D LENGTHY)

    IF (NEKTAR_USE_MPI)
        ADD_NEKTAR_TEST(Advection3D_m8_DG_hex_par LENGTHY)
        ADD_NEKTAR_TEST(Advection3D_m12_DG_prism_par LENGTHY)
        ADD_NEKTAR_TEST(Advection3D_m12_DG_tet_par LENGTHY)
	    ADD_NEKTAR_TEST(Advection3D_m10_DG_hex_VarP_par LENGTHY)
	    ADD_NEKTAR_TEST(Advection3D_m12_DG_tet_VarP_par LENGTHY)
	    ADD_NEKTAR_TEST(Advection3D_m10_DG_prism_VarP_par LENGTHY)
        ADD_NEKTAR_TEST(Advection3D_m12_DG_hex_periodic_par)
        ADD_NEKTAR_TEST(ImDiffusion_Quad_Periodic_m7_par LENGTHY)
        ADD_NEKTAR_TEST(ImDiffusion_Hex_Periodic_m5_par)
        ADD_NEKTAR_TEST(Helmholtz3D_CubePeriodic_par)
        ADD_NEKTAR_TEST(Helmholtz3D_CubeDirichlet_par)
        ADD_NEKTAR_TEST(Helmholtz3D_CubePeriodic_RotateFace_par)
        ADD_NEKTAR_TEST(Advection2D_m12_DG_quad_VarP_par)
        ADD_NEKTAR_TEST(Advection2D_m12_DG_tri_VarP_par)
        ADD_NEKTAR_TEST(Advection2D_dirichlet_regular_GAUSS_LAGRANGE_10x10_MF_par)
        ADD_NEKTAR_TEST(Movement_fixed_interfaces232_periodic_par)
        ADD_NEKTAR_TEST(Movement_fixed_3D_Hex41_par)
        ADD_NEKTAR_TEST(Movement_fixed_3D_Hex_3zones_Periodic_par)
        ADD_NEKTAR_TEST(Movement_fixed_2D_varied_par)
        ADD_NEKTAR_TEST(Movement_fixed_3D_stacked_cylinders_curved_par)
        ADD_NEKTAR_TEST(Movement_rotate_3D_stacked_cylinders_curved_par)
        ADD_NEKTAR_TEST(Movement_translate_interfaces232_dirichlet_par)
        IF (NEKTAR_USE_HDF5)
            ADD_NEKTAR_TEST(Advection3D_m10_DG_prism_VarP_hdf)
            ADD_NEKTAR_TEST(Movement_fixed_3D_stacked_cylinders_curved_hdf5)
            #ADD_NEKTAR_TEST(Movement_fixed_3D_stacked_cylinders_curved_hdf5_par)
            ADD_NEKTAR_TEST(PararealDriver_Movement_fixed_3D_stacked_cylinders_curved_hdf5)
            IF (NOT APPLE OR NOT CMAKE_SYSTEM_PROCESSOR MATCHES "arm64")
                #ADD_NEKTAR_TEST(Movement_fixed_3D_stacked_cylinders_curved_hdf5_par)
                ADD_NEKTAR_TEST(PararealDriver_Movement_fixed_3D_stacked_cylinders_curved_hdf5_par)
            ENDIF()
        ENDIF()
        ADD_NEKTAR_TEST(RotPerBcs3D_Annulus LENGTHY)
            ADD_NEKTAR_TEST(UnsteadyAdvection_WDG_3DHomo1D_MVM_NPZ)
    ENDIF (NEKTAR_USE_MPI)

    IF (NEKTAR_BUILD_PYTHON AND NEKTAR_USE_VTK)
        ADD_NEKTAR_TEST(FilterPython)
    ENDIF()
ENDIF( NEKTAR_SOLVER_ADR )
