-
Robert Kloefkorn authoredRobert Kloefkorn authored
problemcreator.hh 6.27 KiB
#undef ENABLE_MPI
#ifndef FEMHOWTO_POISSONSTEPPER_HH
#define FEMHOWTO_POISSONSTEPPER_HH
#include <config.h>
//#define WANT_ISTL 1
#ifndef NDEBUG
// enable fvector and fmatrix checking
#define DUNE_ISTL_WITH_CHECKING
#endif
#define PROBLEMTRAITS_HAVE_STEPPERTYPE
#include <dune/fem-dg/main/codegen.hh>
#include "passtraits.hh"
// dune-grid includes
#include <dune/grid/io/file/dgfparser/dgfparser.hh>
// dune-fem includes
#include <dune/fem/io/parameter.hh>
// dune-fem-dg includes
#include <dune/fem-dg/operator/fluxes/diffusionflux.hh>
#include <dune/fem-dg/operator/dg/dgoperatorchoice.hh>
#include <dune/fem-dg/operator/fluxes/noflux.hh>
#include <dune/fem-dg/assemble/primalmatrix.hh>
#include <dune/fem-dg/solver/linearsolvers.hh>
#include <dune/fem-dg/stepper/ellipt.hh>
// local includes
#include "poissonproblem.hh"
#include "models.hh"
template <class GridType>
struct ProblemGenerator
{
typedef Dune :: ProblemInterface<
Dune::Fem::FunctionSpace< double, double, GridType::dimension, DIMRANGE> > ProblemType;
template <class GridPart>
struct Traits
{
typedef ProblemType InitialDataType;
typedef PoissonModel< GridPart, InitialDataType > ModelType;
typedef Dune::NoFlux< ModelType > FluxType;
// choice of diffusion flux (see diffusionflux.hh for methods)
static const Dune :: DGDiffusionFluxIdentifier PrimalDiffusionFluxId
= Dune :: method_general ;
};
// type of stepper to be used
template < class Traits >
struct Stepper
{
typedef EllipticAlgorithm< GridType, Traits, POLORDER > Type;
};
static inline std::string diffusionFluxName()
{
#if (defined PRIMALDG)
return Dune::Fem::Parameter::getValue< std::string >("dgdiffusionflux.method");
#else
return "LDG";
#endif
}
static inline Dune::GridPtr<GridType> initializeGrid()
{
// use default implementation
std::string filename = Dune::Fem::Parameter::getValue< std::string >(Dune::Fem::IOInterface::defaultGridKey(GridType :: dimension, false));
std::string description ("poisson-"+diffusionFluxName());
// initialize grid
Dune::GridPtr< GridType > gridptr = initialize< GridType >( description );
std::string::size_type position = std::string::npos;
if( GridType::dimension == 2)
position = filename.find("mesh3");
if( GridType::dimension == 3 )
position = filename.find("_locraf.msh" );
std::string::size_type locraf = filename.find("locrafgrid_");
std::string::size_type checkerboard = filename.find("heckerboard" );;
GridType& grid = *gridptr ;
const int refineelement = 1 ;
bool nonConformOrigin = Dune::Fem::Parameter::getValue< bool > ( "poisson.nonConformOrigin",false );
if ( nonConformOrigin )
{
std::cout << "Create local refined grid" << std::endl;
if( grid.comm().rank() == 0)
{
typedef typename GridType:: template Codim<0>::LeafIterator IteratorType;
IteratorType endit = grid.template leafend<0>();
for(IteratorType it = grid.template leafbegin<0>(); it != endit ; ++it)
{
const typename IteratorType :: Entity & entity = *it ;
const typename IteratorType :: Entity :: Geometry& geo = entity.geometry();
if (geo.center().two_norm() < 0.5)
grid.mark(refineelement, entity );
}
}
}
else if ( position != std::string::npos ||
locraf != std::string::npos )
{
std::cout << "Create local refined grid" << std::endl;
if( grid.comm().rank() == 0)
{
typedef typename GridType:: template Codim<0>::LeafIterator IteratorType;
Dune::FieldVector<double,GridType::dimension> point(1.0);
if( locraf != std::string::npos ) point[ 0 ] = 3.0;
const int loops = ( GridType::dimension == 2 ) ? 2 : 1;
for (int i=0; i < loops; ++i)
{
point /= 2.0 ;
IteratorType endit = grid.template leafend<0>();
for(IteratorType it = grid.template leafbegin<0>(); it != endit ; ++it)
{
const typename IteratorType :: Entity & entity = *it ;
const typename IteratorType :: Entity :: Geometry& geo = entity.geometry();
bool inside = true ;
const int corners = geo.corners();
for( int c = 0; c<corners; ++ c)
{
for( int i = 0; i<GridType::dimension; ++i )
{
if( geo.corner( c )[ i ] - point[ i ] > 1e-8 )
{
inside = false ;
break ;
}
}
}
if( inside ) grid.mark(refineelement, entity );
}
}
}
}
else if ( checkerboard != std::string::npos )
{
std::cout << "Create Checkerboard mesh" << std::endl;
int moduloNum = 32 ;
for( int i = 2; i<32; i *= 2 )
{
std::stringstream key;
key << i << "x" << i << "x" << i;
std::string::size_type counter = filename.find( key.str() );
if( counter != std::string::npos )
{
moduloNum = i;
break ;
}
}
std::cout << "Found checkerboard cell number " << moduloNum << std::endl;
if( grid.comm().rank() == 0)
{
typedef typename GridType:: template Codim<0>::LeafIterator IteratorType;
IteratorType endit = grid.template leafend<0>();
int count = 1;
int modul = 1; // start with 1, such that the fine cube is at (0,0,0)
for(IteratorType it = grid.template leafbegin<0>(); it != endit ; ++it, ++ count )
{
const typename IteratorType :: Entity & entity = *it ;
if( count % 2 == modul )
grid.mark(refineelement, entity );
if( count % moduloNum == 0 )
modul = 1 - modul ;
if( count % (moduloNum * moduloNum) == 0 )
modul = 1 - modul ;
}
}
}
// adapt the grid
grid.preAdapt();
grid.adapt();
grid.postAdapt();
//Dune :: GrapeGridDisplay< GridType > grape( grid );
//grape.display ();
return gridptr ;
}
static ProblemType* problem( )
{
// choice of benchmark problem
int probNr = Dune::Fem::Parameter::getValue< int > ( "femhowto.problem" );
return new Dune :: PoissonProblem< GridType > ( probNr );
}
};
#endif // FEMHOWTO_POISSONSTEPPER_HH