#include <config.h>

// iostream includes
#include <iostream>

// include grid part
#include <dune/fem/gridpart/adaptiveleafgridpart.hh>
#include <dune/alugrid/dgf.hh>
// include output
#include <dune/fem/io/file/dataoutput.hh>
#include <dune/fem/space/common/adaptmanager.hh>
#include <dune/fem/space/common/restrictprolongfunction.hh>

#include "../dune/twophaseDG/models/phaseflowmodel.hh"
#include "../dune/twophaseDG/algorithms/phaseflowscheme.hh"
#include "../dune/twophaseDG/algorithms/algorithm.hh"

int main ( int argc, char **argv )
  try
    {
      // initialize MPI, if necessary
      Dune::Fem::MPIManager::initialize( argc, argv );

      // append overloaded parameters from the command line
      Dune::Fem::Parameter::append( argc, argv );

      // append possible given parameter files
      for( int i = 1; i < argc; ++i )
        Dune::Fem::Parameter::append( argv[ i ] );

      // append default parameter file
      Dune::Fem::Parameter::append( "../data/parameter" );

      // type of hierarchical grid
      typedef Dune::GridSelector::GridType  HGridType ;

      typedef Algorithm< HGridType > AlgorithmType;

      // create grid from DGF file
      const std::string gridkey = Dune::Fem::IOInterface::defaultGridKey( HGridType::dimension );
      const std::string gridfile = Dune::Fem::Parameter::getValue< std::string >( gridkey );

      // the method rank and size from MPIManager are static
      if( Dune::Fem::MPIManager::rank() == 0 )
        std::cout << "Loading macro grid: " << gridfile << std::endl;

      // construct macro using the DGF Parser
      Dune::GridPtr< HGridType > gridPtr( gridfile );
      HGridType& grid = *gridPtr ;

      AlgorithmType myalgorithm (grid);
      // do initial load balance
      grid.loadBalance();
      // Compute algorithm
      myalgorithm.compute();
      return 0;
    }
  catch( const Dune::Exception &exception )
    {
      std::cerr << "Error: " << exception << std::endl;
      return 1;
    }
