-
Martin Nolte authoredMartin Nolte authored
problems.hh 27.46 KiB
#ifndef EULERPROBLEMS_HH
#define EULERPROBLEMS_HH
#include <cmath>
// dune-fem includes
#include <dune/fem/io/parameter.hh>
#include <dune/fem/misc/femeoc.hh>
#include <dune/fem/misc/l1norm.hh>
#include <dune/fem/misc/l2norm.hh>
#include <dune/fem/space/common/functionspace.hh>
#include <dune/fem/storage/vector.hh>
#include <dune/fem-dg/operator/fluxes/eulerfluxes.hh>
#include <dune/fem/io/parameter.hh>
// local includes
#include <dune/fem-dg/models/defaultprobleminterfaces.hh>
#include "chorjo.hh"
namespace Dune {
//typedef float FIELDTYPE;
typedef double FIELDTYPE;
template <class GridType>
class ProblemBase :
public EvolutionProblemInterface<
Dune::Fem::FunctionSpace< double, double, GridType::dimensionworld, GridType::dimensionworld+2>,
false >
{
typedef EvolutionProblemInterface<
Dune::Fem::FunctionSpace< double, double, GridType::dimensionworld, GridType::dimensionworld+2>,
false > BaseType ;
public:
using BaseType :: evaluate ;
using BaseType::fixedTimeFunction;
typedef Dune::Fem::Parameter ParameterType;
enum { Inflow = 1, Outflow = 2, Reflection = 3 , Slip = 4 };
enum { MaxBnd = Slip };
typedef Dune::Fem::FunctionSpace< double, double, GridType::dimension, GridType::dimension+2 > FunctionSpaceType ;
enum { dimDomain = GridType::dimensionworld };
typedef typename FunctionSpaceType :: RangeType RangeType ;
typedef typename FunctionSpaceType :: DomainType DomainType ;
typedef typename FunctionSpaceType :: RangeFieldType RangeFieldType ;
typedef RangeFieldType FieldType ;
const FieldType gamma_;
const FieldType V_;
const int eocId_ ;
ProblemBase() : gamma_( 1.4 ), V_( 1.0 ), eocId_( addToFemEoc() ) {}
ProblemBase( const FieldType gamma, const FieldType V )
: gamma_( gamma ), V_( V ), eocId_( addToFemEoc() ) {}
int addToFemEoc() const
{
return Dune::Fem::FemEoc::addEntry(std::string("$L^1$-error"));
}
FieldType gamma() const { return gamma_ ; }
FieldType V () const { return V_; }
virtual double endTime () const { return 0.1 ; }
virtual std::string dataPrefix() const { return "euler" ; }
void bg ( const DomainType&, RangeType& ) const {}
/* \brief calculate EOC between exact and numerical solution
*
* \param[in] tp time provider
* \param[in] u numerical solution
* \param[in] eocId for FemEoc
*
* \return true if no EOC was calculated
*/
template< class TimeProviderType, class DiscreteFunctionType >
bool calculateEOC( TimeProviderType& tp, DiscreteFunctionType& u,
const unsigned int eocId ) const
{
typedef typename DiscreteFunctionType :: GridPartType GridPartType;
Dune::Fem::L1Norm< GridPartType > l1norm( u.space().gridPart() );
Dune::Fem::FemEoc::setErrors(eocId_, l1norm.distance( fixedTimeFunction( tp.time() ), u ) );
return true;
}
/* \brief finalize the simulation using the calculated numerical
* solution u for this problem
*
* \param[in] variablesToOutput Numerical solution in the suitably chosen var
* \param[in] eocloop Specific EOC loop
*/
template< class DiscreteFunctionType >
void finalizeSimulation( DiscreteFunctionType& variablesToOutput,
const int eocloop) const
{}
//! methods for gradient based indicator
bool twoIndicators() const { return false ; }
//! methods for gradient based indicator
double indicator1( const DomainType& xgl, const RangeType& u ) const
{
// use density as indicator
return u[ 0 ];
}
virtual int boundaryId ( const int id ) const
{
return 2;
}
};
/*****************************************************************/
// Initial Data
template <class GridType>
class U0Smooth1D : public ProblemBase < GridType >
{
public:
typedef ProblemBase < GridType > BaseType ;
typedef typename BaseType :: RangeType RangeType ;
typedef typename BaseType :: DomainType DomainType ;
using BaseType :: gamma ;
using BaseType :: evaluate ;
DomainType u_;
std::string myName;
public:
U0Smooth1D() : BaseType( 1.4, 1.0 ),
u_(0), myName("Advection")
{
init();
}
void init()
{
enum { dim = DomainType :: dimension };
u_[ 0 ] = std::cos(M_PI/5.0);
for(int i=1; i<dim; ++i)
{
u_[ i ] = std::sin(M_PI/5.0);
}
}
double endtime() {
return 0.2;
}
void evaluate(const DomainType& x, const double time, RangeType& res) const
{
enum { dimR = RangeType :: dimension };
enum { dim = DomainType :: dimension };
res = 0;
DomainType y(0.5);
const double p = 0.3;
double tmp_c[dim], tmp=0.0, u_sq=0.0;
for(int i=0; i<dim; ++i)
{
tmp_c[i] = x[i] - y[i] - time * u_[i];
tmp += tmp_c[i]*tmp_c[i];
u_sq += u_[i] * u_[i];
}
tmp *= 16.0;
const double cos_tmp = cos(tmp * M_PI) + 1.0;
const double rho = (tmp > 1.0)? 0.5: 0.25 * cos_tmp*cos_tmp + 0.5;
res[0] = rho;
for(int i=0; i<dim; i++) res[1+i] = u_[i] * rho;
res[dim+1] = p/(gamma() - 1.0) + 0.5*rho*u_sq;
}
std::string dataPrefix() const { return "smooth1d"; }
};
/*****************************************************************/
// Initial Data
template <class GridType>
class U0FFS : public ProblemBase< GridType > {
public:
typedef ProblemBase< GridType > BaseType ;
typedef typename BaseType :: RangeType RangeType ;
typedef typename BaseType :: DomainType DomainType ;
using BaseType :: gamma ;
using BaseType :: V ;
U0FFS() : BaseType( 1.4, 3.0 ),
myName("Forward Facing Step") {}
const std::string myName;
double endtime()
{
return 5.0;
}
void evaluate(const DomainType& arg, double t, RangeType& res) const
{
evaluate(t,arg,res);
}
template <class DomainType, class RangeType>
void evaluate(double t,const DomainType& arg, RangeType& res) const
{
enum { dimR = RangeType :: dimension };
// reset all values
res = 0;
// initial values
res[0] = gamma(); // density
res[1] = V() * res[0]; // velocity-x
res[dimR-1] = 8.8;
//std::cout << "Initial value : "<< res << "\n";
//RangeType prim;
//cons2prim( res, prim );
//std::cout << "Initial value : "<< prim << "\n";
}
void cons2prim(const RangeType& u,RangeType& v) const {
v[0] = u[0];
enum { dimDomain = BaseType :: dimDomain };
for (int i=1;i<=dimDomain;i++)
{
v[i] = u[i]/u[0];
}
v[dimDomain+1] = EulerAnalyticalFlux<dimDomain>().pressure(gamma,u);
}
int boundaryId( const int id ) const
{
return (id > BaseType::MaxBnd) ? BaseType::MaxBnd : id;
}
int determineBndId(const DomainType& x) const
{
if( x[0] <= 1e-8 ) return 1; // Inflow
if( x[0] >= 3.0-1e-8 ) return 2; // Outflow
// reflection elsewhere
return 3;
}
std::string dataPrefix() const { return "ffs"; }
};
template <class GridType>
class U0Sod : public ProblemBase< GridType > {
double T,startTime;
Dune::Fem::FieldVectorAdapter<FieldVector<double,6> > Ulr;
enum { dim = GridType :: dimension };
public:
typedef ProblemBase< GridType > BaseType ;
typedef typename BaseType :: RangeType RangeType ;
typedef typename BaseType :: DomainType DomainType ;
typedef typename BaseType :: ParameterType ParameterType;
using BaseType :: gamma ;
using BaseType :: V ;
enum { dimDomain = GridType::dimensionworld,
dimRange = dimDomain+2,
energ = dimRange-1};
U0Sod() : T(0.4), startTime(0), flag(0) {
myName = "RP-Sod";
// default is sod's rp
Ulr[0] = 1.0;
Ulr[3] = 0.125;
Ulr[1] = 0.;
Ulr[4] = 0.;
Ulr[2] = 1.0;
Ulr[5] = 0.1;
//ParameterType::get("euler.riemanndata", Ulr, Ulr );
T = ParameterType::getValue("femhowto.endTime", T);
ParameterType::get("femhowto.startTime", startTime, startTime );
flag = ParameterType::getValue("euler.problemflag", flag);
}
int boundaryId( const int id ) const
{
return ( id > 2 ) ? BaseType::Reflection : id;
//return BaseType::Inflow;
//return ( id == 1 ) ? BaseType::Inflow : BaseType::Outflow ;
//return BaseType::OutFlow;
//return (id > BaseType::Inflow) ? BaseType::OutFlow : id;
}
double endtime() {
return T;
}
double saveinterval() {
return 0.01;
}
bool useReflectBndLR() const {
return false;
}
bool useReflectBndTB() const {
return flag==0;
}
void evaluate(const DomainType& arg, const double t, RangeType& res) const
{
if (flag==0) {
res[2] = 0.;
if (t>1e-8) {
chorin(t,arg[0]-0.5,res[0],res[1],res[3]);
}
else {
if (arg[0]<0.5) {
res[0]=Ulr[0];
res[1]=Ulr[1];
res[3]=Ulr[2];
} else {
res[0]=Ulr[3];
res[1]=Ulr[4];
res[3]=Ulr[5];
}
}
}
else {
DomainType c(0.075);
DomainType velo(0.5);
c[0] = 0.1;
velo[0] = 4.5;
DomainType x(arg);
DomainType v(velo);
x -= c;
v *= t;
x -= v;
double r2=0.004;
double z=x*x/r2;
res[0] = 0.1;
if (flag<=3) {
if (z < 1.) {
if (flag==1) {
double f = 0.5*(cos(z*M_PI)+1.);
double pf = pow(f,4.);
res[0] += pf;
}
else if (flag==2)
res[0] += (1.-z);
else
res[0] += 1.0;
}
} else if (flag>=4) {
double s = 1.;
for (int i=0;i<dimDomain;++i)
s *= sin(M_PI*x[i]);
if (flag==4)
res[0] = 0.6+0.5*s;
else if (flag==5 || flag==6 || flag==7 || flag==8) {
while (x[0]<0) x[0]+=1.;
while (x[0]>1) x[0]-=1.;
while (x[1]<0) x[1]+=0.25;
while (x[1]>0.25) x[1]-=0.25;
res[0] = 0.6+0.5*std::abs(sin(M_PI*x[0]))*std::abs(sin(2.*M_PI*x[1]));
if (flag==6)
if (x[0]-M_PI*x[1]>0)
res[0]+=1.;
if (flag==7)
if (x[0]<0.5)
res[0]+=1.0;
if (flag==8)
if (x[1]<0.1)
res[0]+=1.0;
}
}
for (int i=0;i<dimDomain;++i)
res[i+1] = velo[i];
res[energ] = 0.4;
}
double kinEnerg = 0;
for (int i=0;i<dimDomain;++i) {
kinEnerg += res[i+1]*res[i+1];
res[i+1] *= res[0];
}
kinEnerg *= 0.5*res[0];
res[energ] = res[energ]/(gamma()-1.0)+kinEnerg;
}
void chorin(double t,double x,
double& q_erg,double& u_erg,double& p_erg) const
{
EULERCHORIN::
lsg(x,t,&q_erg,&u_erg,&p_erg,
Ulr[0],Ulr[3],Ulr[1],Ulr[4],Ulr[2],Ulr[5],
gamma());
}
void printmyInfo(std::string filename)
{
std::ostringstream filestream;
filestream << filename;
std::ofstream ofs(filestream.str().c_str(), std::ios::app);
ofs << "Problem: " << myName << "\n\n"
<< "gamma = " << gamma() << "\n\n";
ofs << "\n\n";
ofs.close();
}
std::string dataPrefix() const { return myName; }
std::string myName;
int flag;
};
template< class Grid >
class U0P123
: public ProblemBase< Grid >
{
typedef ProblemBase< Grid > BaseType;
static const int dimension = Grid::dimension;
double T, startTime;
Dune::Fem::FieldVectorAdapter< FieldVector< double, 6 > > Ulr;
public:
typedef typename BaseType::RangeType RangeType;
typedef typename BaseType::DomainType DomainType;
typedef typename BaseType :: ParameterType ParameterType;
using BaseType::gamma;
using BaseType::V;
static const int dimDomain = Grid::dimensionworld;
static const int dimRange = dimDomain + 2;
static const int energ = dimRange - 1;
U0P123 ()
: T( 0.4 ),
startTime( 0 )
{
myName = "RP-123";
Ulr[0] = 1.0;
Ulr[3] = 1.0;
Ulr[1] = -2.0;
Ulr[4] = 2.0;
Ulr[2] = 0.4;
Ulr[5] = 0.4;
T = ParameterType::getValue( "femhowto.endTime", T );
ParameterType::get( "femhowto.startTime", startTime, startTime );
}
int boundaryId ( const int id ) const
{
return ( id > 2 ) ? BaseType::Reflection : id;
//return BaseType::Inflow;
//return ( id == 1 ) ? BaseType::Inflow : BaseType::Outflow ;
//return BaseType::OutFlow;
//return (id > BaseType::Inflow) ? BaseType::OutFlow : id;
}
double endtime () { return T; }
double saveinterval () { return 0.01; }
bool useReflectBndLR() const { return false; }
bool useReflectBndTB() const { return true; }
void evaluate ( const DomainType &arg, double t, RangeType &res ) const
{
res[2] = 0.;
if( t > 1e-8 )
chorin( t, arg[ 0 ] - 0.5, res[ 0 ], res[ 1 ], res[ 3 ] );
else
{
if( arg[ 0 ] < 0.5 )
{
res[0]= Ulr[ 0 ];
res[1]= Ulr[ 1 ];
res[3]= Ulr[ 2 ];
}
else
{
res[ 0 ] = Ulr[ 3 ];
res[ 1 ] = Ulr[ 4 ];
res[ 3 ] = Ulr[ 5 ];
}
}
double kinEnerg = 0;
for( int i = 0; i < dimDomain; ++i )
{
kinEnerg += res[ i+1 ]*res[ i+1 ];
res[ i+1 ] *= res[ 0 ];
}
kinEnerg *= 0.5*res[ 0 ];
res[energ] = res[ energ ] / (gamma()-1.0) + kinEnerg;
}
void chorin ( double t, double x, double &q_erg, double &u_erg, double &p_erg ) const
{
EULERCHORIN::lsg( x, t, &q_erg, &u_erg, &p_erg, Ulr[ 0 ], Ulr[ 3 ], Ulr[ 1 ], Ulr[ 4 ], Ulr[ 2 ], Ulr[ 5 ], gamma() );
}
void printmyInfo( const std::string &filename )
{
std::ostringstream filestream;
filestream << filename;
std::ofstream ofs(filestream.str().c_str(), std::ios::app);
ofs << "Problem: " << myName << "\n\n"
<< "gamma = " << gamma() << "\n\n";
ofs << "\n\n";
ofs.close();
}
std::string dataPrefix () const { return myName; }
std::string myName;
};
#if 0
/*****************************************************************/
// Diffraction
template <class GridType>
class U0Diffraction : public ProblemBase< GridType > {
public:
enum { dimDomain = GridType::dimensionworld };
typedef FunctionSpace<double,double,dimDomain,dimDomain+2> FunctionSpaceType;
U0Diffraction() :
gamma(1.4),myName("Shock Diffraction Problem")
, pAB_( pAlphaBeta( V() ) )
, rhoAB_( rhoAlphaBeta( pAB_ ) )
// c = std::sqrt( 1.4 * 1 / 1.4 ) = 1
, us_ ( u_s(1., pAB_ ))
{}
U0Diffraction(std::string,double,bool diff_timestep=true) :
gamma(1.4),myName("Shock Diffraction Problem")
, pAB_( pAlphaBeta( V() ) )
, rhoAB_( rhoAlphaBeta( pAB_ ) )
, us_ ( u_s(1., pAB_ ))
{}
// public member, Andreas .....
const double gamma;
const std::string myName;
const double pAB_;
const double rhoAB_;
const double us_;
void printmyInfo(std::string filename) {}
double endtime()
{
return 2.3;
}
double V() const { return 5.09; }
double pAlphaBeta(const double machNumber ) const
{
return ( 1. + ( (2*gamma)/(gamma+1) * ( (machNumber*machNumber) - 1.) ) );
}
double rhoAlphaBeta(const double pAB ) const
{
const double gammaPlusMinus = ((gamma+1.)/(gamma-1.));
return (1. + gammaPlusMinus * pAB ) /( gammaPlusMinus + pAB );
}
double u_s (const double c, double pAB ) const
{
return c/gamma * (pAB - 1.) * std::sqrt(((2*gamma)/(gamma+1))/(pAB + ((gamma-1.)/(gamma+1.)) ));
}
template <class DomainType, class RangeType>
void evaluate(const DomainType& arg, RangeType& res) const {
evaluate(0,arg,res);
}
template <class DomainType, class RangeType>
void evaluate(const DomainType& arg,double t, RangeType& res) const
{
evaluate(t,arg,res);
}
template <class DomainType, class RangeType>
void evaluate(double t,const DomainType& arg, RangeType& res) const
{
enum { dimR = RangeType :: dimension };
enum { e = dimR - 1 };
// reset all values
res = 0;
// density
res[0] = gamma;
// pressure
res[e] = 1;
// check area
double x = arg[0];
if( x <= 0.5 )
{
res[0] *= rhoAB_;
res[1] = us_;
res[e] *= pAB_;
}
const double sqrVelo = res[1] * res[1];
// get impuls
res[1] *= res[0];
// calculate energy
res[e] = res[e]/(gamma-1.) + 0.5 * sqrVelo * res[0];
//std::cout << "Initial value : "<< res << "\n";
//RangeType prim;
//cons2prim( res, prim );
//std::cout << "Initial value : "<< prim << "\n";
}
template <class RangeType>
void cons2prim(const RangeType& u,RangeType& v) const {
v[0] = u[0];
for (int i=1;i<=dimDomain;i++)
{
v[i] = u[i]/u[0];
}
v[dimDomain+1] = EulerFlux<dimDomain>().pressure(gamma,u);
}
template <class DomainType>
int determineBndId(const DomainType& x) const
{
if( x[0] <= 0.) return 1;
if( x[1] >= 11.0 ) return 4;
if( x[0] >= 13.0 ) return 2;
return 3;
}
};
/*****************************************************************/
/*****************************************************************/
// Diffraction
template <class GridType>
class U0DoubleMachReflect : public ProblemBase {
public:
enum { dimDomain = GridType::dimensionworld };
typedef FunctionSpace<double,double,dimDomain,dimDomain+2> FunctionSpaceType;
U0DoubleMachReflect() :
gamma(1.4),myName("Double Mach Reflection")
, pAB_( pAlphaBeta( V() ) )
, rhoAB_( rhoAlphaBeta( pAB_ ) )
// c = sqrt( 1.4 * 1 / 1.4 ) = 1
, us_ ( u_s(1., pAB_ ))
{}
U0DoubleMachReflect(std::string,double,bool diff_timestep=true) :
gamma(1.4),myName("Double Mach Reflection")
, pAB_( pAlphaBeta( V() ) )
, rhoAB_( rhoAlphaBeta( pAB_ ) )
, us_ ( u_s(1., pAB_ ))
{}
// public member, Andreas .....
const double gamma;
const std::string myName;
const double pAB_;
const double rhoAB_;
const double us_;
void printmyInfo(std::string filename) {}
double endtime()
{
return 1.0;
}
double V() const { return 10.; }
double pAlphaBeta(const double machNumber ) const
{
return ( 1. + ( (2*gamma)/(gamma+1) * ( (machNumber*machNumber) - 1.) ) );
}
double rhoAlphaBeta(const double pAB ) const
{
const double gammaPlusMinus = ((gamma+1.)/(gamma-1.));
return (1. + gammaPlusMinus * pAB ) /( gammaPlusMinus + pAB );
}
double u_s (const double c, double pAB ) const
{
return c/gamma * (pAB - 1.) * std::sqrt(((2*gamma)/(gamma+1))/(pAB + ((gamma+1.)/(gamma-1.))));
}
template <class DomainType, class RangeType>
void evaluate(const DomainType& arg, RangeType& res) const {
evaluate(time(),arg,res);
}
template <class DomainType, class RangeType>
void evaluate(const DomainType& arg,double t, RangeType& res) const
{
evaluate(t,arg,res);
}
template <class DomainType, class RangeType>
void evaluate(double t,const DomainType& arg, RangeType& res) const
{
enum { dimR = RangeType :: dimension };
enum { e = dimR - 1 };
// reset all values
res = 0;
// density
res[0] = gamma;
// pressure
res[e] = 1;
// check area
double x = arg[0];
if( x <= 0. )
{
res[0] *= rhoAB_;
res[1] = us_;
res[e] *= pAB_;
}
const double sqrVelo = res[1] * res[1];
// get impuls
res[1] *= res[0];
// calculate energy
res[e] = res[e]/(gamma-1.) + 0.5 * sqrVelo * res[0];
//std::cout << "Conservative value : "<< res << "\n";
//RangeType prim;
//cons2prim( res, prim );
//std::cout << "Primitve value : "<< prim << "\n";
}
template <class RangeType>
void cons2prim(const RangeType& u,RangeType& v) const {
v[0] = u[0];
for (int i=1;i<=dimDomain;i++)
{
v[i] = u[i]/u[0];
}
v[dimDomain+1] = EulerFlux<dimDomain>().pressure(gamma,u);
}
};
/*****************************************************************/
// ShockBubble
template <class GridType>
class U0ShockBubble : public ProblemBase {
public:
enum { dimDomain = GridType::dimensionworld };
typedef FunctionSpace<double,double,dimDomain,dimDomain+2> FunctionSpaceType;
typedef typename FunctionSpaceType :: DomainType DomainType;
// public member, Andreas .....
const double gamma;
const std::string myName;
DomainType center_;
const double radius2_;
U0ShockBubble() :
gamma(1.4),myName("Shock Bubble Problem")
, center_(0.5) , radius2_( 0.2 * 0.2 )
{
center_[dimDomain-1] = 0;
}
U0ShockBubble(std::string,double,bool diff_timestep=true) :
gamma(1.4),myName("Shock Bubble Problem")
, center_(0) , radius2_( 0.2 * 0.2 )
{
center_[0] = 0.5;
}
void printmyInfo(std::string filename) {}
double endtime()
{
return 0.3;
}
double V() const { return 2.95; }
template <class DomainType, class RangeType>
void evaluate(const DomainType& arg, RangeType& res) const {
evaluate(time(),arg,res);
}
template <class DomainType, class RangeType>
void evaluate(const DomainType& arg,double t, RangeType& res) const
{
evaluate(t,arg,res);
}
template <class DomainType, class RangeType>
void evaluate(double t, const DomainType& arg, RangeType& res) const
{
enum { dimR = RangeType :: dimension };
// reset all values
res = 0;
// behind shock
if ( arg[0] <= 0.2 )
{
/*
const double gamma1 = gamma-1.;
// pressure left of shock
const double pinf = 10.0;
const double rinf = ( gamma1 + (gamma+1)*pinf )/( (gamma+1) + gamma1*pinf );
const double vinf = V();
//(1.0/std::sqrt(gamma)) * (pinf - 1.)/
// std::sqrt( 0.5*((gamma+1)/gamma) * pinf + 0.5*gamma1/gamma);
res[0] = rinf;
res[dimR-1] = 0.5*rinf*vinf*vinf + pinf/gamma1;
//res[1] = vinf * rinf;
res[1] = V() * rinf;
*/
const double gamma1 = gamma-1.;
// pressure left of shock
const double pinf = 5;
const double rinf = ( gamma1 + (gamma+1)*pinf )/( (gamma+1) + gamma1*pinf );
const double vinf = (1.0/std::sqrt(gamma)) * (pinf - 1.)/
std::sqrt( 0.5*((gamma+1)/gamma) * pinf + 0.5*gamma1/gamma);
res[0] = rinf;
res[dimR-1] = 0.5*rinf*vinf*vinf + pinf/gamma1;
res[1] = vinf * rinf;
//RangeType prim;
//cons2prim( res, prim );
//std::cout << "Primitve behind: "<< prim << "\n";
}
else if( (arg - center_).two_norm2() <= radius2_ )
{
res[0] = 0.1;
// pressure in bubble
res[dimR-1] = 2.5;
//RangeType prim;
//cons2prim( res, prim );
//std::cout << "Primitve inside : "<< prim << "\n";
}
// elsewhere
else
{
res[0] = 1;
res[dimR-1] = 2.5;
//RangeType prim;
//cons2prim( res, prim );
//std::cout << "Primitve outside : "<< prim << "\n";
}
}
template <class RangeType>
void cons2prim(const RangeType& u,RangeType& v) const {
v[0] = u[0];
for (int i=1;i<=dimDomain;i++)
{
v[i] = u[i]/u[0];
}
v[dimDomain+1] = EulerFlux<dimDomain>().pressure(gamma,u);
}
};
template <class GridType>
class U0Sin : public ProblemBase {
public:
enum { dimDomain = GridType::dimensionworld };
typedef FunctionSpace<double,double,dimDomain,dimDomain+2> FunctionSpaceType;
U0Sin() :
gamma(), startTime(0) {
ParameterType::get("StartTime",startTime,startTime);
}
U0Sin(std::string,double,bool diff_timestep=true) :
gamma(1.4), startTime(0) {
ParameterType::get("StartTime",startTime,startTime);
}
double endtime() {
return 2.;
}
double saveinterval() {
return 0.1;
}
bool useReflectBndLR() const {
return false;
}
bool useReflectBndTB() const {
return true;
}
template <class DomainType, class RangeType>
void evaluate(const DomainType& arg, RangeType& res) const {
evaluate(time(),arg,res);
}
template <class DomainType, class RangeType>
void evaluate(const DomainType& arg,double t, RangeType& res) const
{
evaluate(t,arg,res);
}
template <class DomainType, class RangeType>
void evaluate(double t,const DomainType& arg, RangeType& res) const {
int e = DomainType::size + 1;
double x = (arg[0]-10.);
res=0.;
if (x<0) {
res[0]=3.857143;
res[1]=-0.920279; // 2.629369;
res[e]=10.33333;
} else if (x<10) {
res[0]= 1. + 0.2 * sin(5.*x);
res[1]=-3.549648; // 0.0
res[e]=1.0;
} else {
res[0]= 1.;
res[1]=-3.549648; // 0.0
res[e]=1.0;
}
res[1] *= res[0];
res[e] = res[e]/(gamma-1.0)+
0.5*(res[1]*res[1])/res[0];
}
void printmyInfo(std::string filename)
{
std::ostringstream filestream;
filestream << filename;
std::ofstream ofs(filestream.str().c_str(), std::ios::app);
ofs << "Problem: " << myName << "\n\n"
<< "gamma = " << gamma << "\n\n";
ofs << "\n\n";
ofs.close();
}
double gamma,startTime;
std::string myName;
};
template <class GridType>
class U0RotatingCone : public ProblemBase {
public:
enum { dimDomain = GridType::dimensionworld };
typedef FunctionSpace<double,double,dimDomain,dimDomain+2> FunctionSpaceType;
U0RotatingCone() :
gamma(), startTime(0) {
ParameterType::get("StartTime",startTime,startTime);
}
U0RotatingCone(std::string,double,bool diff_timestep=true) :
gamma(1.4), startTime(0) {
ParameterType::get("StartTime",startTime,startTime);
}
double endtime() {
return 0.5;
}
double saveinterval() {
return 0.01;
}
template <class DomainType, class RangeType>
void evaluate(const DomainType& arg, RangeType& res) const {
evaluate(startTime,arg,res);
}
template <class DomainType, class RangeType>
void evaluate(const DomainType& arg,double t, RangeType& res) const
{
evaluate(t,arg,res);
}
template <class DomainType, class RangeType>
void evaluate(double t,const DomainType& arg, RangeType& res) const {
res=0.;
DomainType c(0.5);
DomainType x=arg;
x-=c;
double r2=0.04;
if (x*x < r2) {
res[0] =cos(x*x/r2*M_PI)+2;
}
else {
res[0] = 1.0;
}
x=arg;
x-=DomainType(1.0);
if (DomainType::size>1) {
res[1] = x[1]*res[0];
res[2] = -x[0]*res[0];
} else {
res[1] = -1.*res[0];
}
res[DomainType::size+1] = 2.;
if (arg.size>1) {
res[DomainType::size+1] +=
0.5*(res[1]*res[1]+res[2]*res[2])/res[0];
} else {
res[DomainType::size+1] +=
0.5*(res[1]*res[1])/res[0];
}
}
void printmyInfo(std::string filename)
{
std::ostringstream filestream;
filestream << filename;
std::ofstream ofs(filestream.str().c_str(), std::ios::app);
ofs << "Problem: " << myName << "\n\n"
<< "gamma = " << gamma << "\n\n";
ofs << "\n\n";
ofs.close();
}
double gamma,startTime;
std::string myName;
};
#endif
} // end namespace Dune
#endif
/* CLAWPACK example
*
* Uin value in bubble
* Uout values outside bubble rigth of shock
* Uinf values left of shock
*
* 0.0 t0 = initial time
* 0.0 xlower = left edge of computational domain
* 1.2 xupper = right edge of computational domain
* 0.0 ylower = bottom edge of computational domain
* 0.5 yupper = top edge of computational domain
* 0.0 zlower = front edge of computational domain
* 0.5 zupper = back edge of computational domain
*
* 1.4 gamma
* 0.5 0.5 0.2 x0, y0, r0: center and radius of bubble
* 0.1 rhoin: density in bubble
* 5.0 pinf: pressure behind shock
*
* # density outside bubble and pressure ahead of shock are fixed:
* rhoout = 1.d0
* pout = 1.d0
* pin = 1.d0
*
* # Compute density and velocity behind shock from Hugoniot relations:
* # gamma1 = gamma-1
* rinf = ( gamma1 + (gamma+1)*pinf )/( (gamma+1) + gamma1*pinf )
* vinf = (1.0d0/sqrt(gamma)) * (pinf - 1.d0)/
* sqrt( 0.5*((gamma+1)/gamma) * pinf + 0.5*gamma1/gamma )
* einf = 0.5*rinf*vinf*vinf + pinf/gamma1
*/