DUNE-FEM (unstable)

vtxprojection.hh
1 #ifndef DUNE_FEM_VTXPROJECTION_HH
2 #define DUNE_FEM_VTXPROJECTION_HH
3 
4 #include <cstddef>
5 #include <cmath>
6 
7 #include <algorithm>
8 #include <functional>
9 #include <vector>
10 
11 #include <dune/grid/common/rangegenerators.hh>
12 
13 #include <dune/fem/common/coordinate.hh>
14 #include <dune/fem/operator/common/operator.hh>
15 #include <dune/fem/space/common/communicationmanager.hh>
16 #include <dune/fem/space/common/interpolate.hh>
17 #include <dune/fem/space/lagrange.hh>
18 
19 namespace Dune
20 {
21  namespace Fem
22  {
23 
24  template <class GridPartType>
25  struct WeightDefault {
26  typedef typename GridPartType::template Codim<0>::EntityType EntityType;
27 
28  typedef typename EntityType::Geometry::GlobalCoordinate WorldDomainType;
29  typedef typename EntityType::Geometry::LocalCoordinate DomainType;
30 
31  //typedef FieldVector<double,GridPartType::dimensionworld> WorldDomainType;
32  //typedef FieldVector<double,GridPartType::dimension> DomainType;
33  void setEntity(const EntityType& en) {
34  en_ = en;
35  volume_ = en.geometry().volume();
36  baryCenter_ = en.geometry().center();
37  }
38  double operator()(const DomainType& point) {
39  // return volume_;
40  auto tau = en_.geometry().global(point);
41  tau -= baryCenter_;
42  return tau.two_norm() / volume_;
43  }
44  double volume_;
45  WorldDomainType baryCenter_;
46  EntityType en_;
47  };
48 
49  struct VtxProjectionImpl
50  {
51  template< class DiscreteFunction, class Intersection >
52  struct OutsideLocalFunction
53  {
54  typedef typename DiscreteFunction::LocalFunctionType LocalFunctionType;
55 
56  typedef typename LocalFunctionType::EntityType EntityType;
57  typedef typename LocalFunctionType::FunctionSpaceType FunctionSpaceType;
58 
59  typedef typename FunctionSpaceType::DomainFieldType DomainFieldType;
60  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
61 
62  typedef typename FunctionSpaceType::DomainType DomainType;
63  typedef typename FunctionSpaceType::RangeType RangeType;
64 
65  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
66  typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
67 
68  typedef typename EntityType::Geometry::LocalCoordinate LocalCoordinateType;
69 
70  static const int dimDomain = FunctionSpaceType::dimDomain;
71  static const int dimRange = FunctionSpaceType::dimRange;
72 
74 
75  explicit OutsideLocalFunction ( const DiscreteFunction &df ) : order_(df.order()), localFunction_( df ) {}
76 
77  void init ( const EntityType &outside, const GeometryType &geoIn, const GeometryType &geoOut )
78  {
79  localFunction_.init( outside );
80  geoIn_ = &geoIn;
81  geoOut_ = &geoOut;
82  entity_ = outside;
83  }
84 
85  const EntityType &entity() const { return entity_; }
86 
87  int order() const { return order_; }
88 
89  template< class Point >
90  void evaluate ( const Point &x, RangeType &value ) const
91  {
92  localFunction_.evaluate( geoOut_->global( geoIn_->local( coordinate( x ) ) ), value );
93  };
94 
95  template< class Point >
96  void jacobian ( const Point &x, JacobianRangeType &jacobian ) const
97  {
98  DUNE_THROW( NotImplemented, "Vertex projection weights do not provide Jacobians." );
99  }
100 
101  template< class Point >
102  void hessian ( const Point &x, HessianRangeType &hessian ) const
103  {
104  DUNE_THROW( NotImplemented, "Vertex projection weights do not provide Hessians." );
105  }
106 
107  template< class Quadrature, class Values >
108  void evaluateQuadrature ( const Quadrature &quadrature, Values &values ) const
109  {
110  for( const auto &qp : quadrature )
111  doEvaluate( qp, values[ qp.index() ] );
112  }
113 
114  private:
115  template< class Point >
116  void doEvaluate ( const Point &x, RangeType &value ) const
117  {
118  evaluate( x, value );
119  };
120 
121  template< class Point >
122  void doEvaluate ( const Point &x, JacobianRangeType &value ) const
123  {
124  jacobian( x, value );
125  };
126 
127  template< class Point >
128  void doEvaluate ( const Point &x, HessianRangeType &value ) const
129  {
130  hessian( x, value );
131  };
132 
133  int order_;
134  LocalFunctionType localFunction_;
135  const GeometryType *geoIn_ = nullptr;
136  const GeometryType *geoOut_ = nullptr;
137  EntityType entity_;
138  };
139 
140 
141  template< class DiscreteFunction >
142  static void makeConforming ( DiscreteFunction &u )
143  {
144  typedef typename DiscreteFunction::GridPartType GridPartType;
145 
146  typedef typename GridPartType::IntersectionType IntersectionType;
147  typedef typename GridPartType::template Codim< 0 >::EntityType EntityType;
148  typedef typename DiscreteFunction::DiscreteFunctionSpaceType
149  DiscreteFunctionSpaceType;
150 
151  if( u.space().gridPart().isConforming() || !Fem::GridPartCapabilities::hasGrid< GridPartType >::v )
152  return;
153 
154  const auto &blockMapper = u.space().blockMapper();
155 
156  std::vector< typename DiscreteFunction::DofType > ldu, ldw;
157  const std::size_t localBlockSize = DiscreteFunctionSpaceType::localBlockSize;
158  const std::size_t maxNumBlocks = blockMapper.maxNumDofs();
159  ldu.reserve( maxNumBlocks * localBlockSize );
160  ldw.reserve( maxNumBlocks * localBlockSize );
161 
162  std::vector< char > onSubEntity;
163  onSubEntity.reserve( maxNumBlocks );
164 
165  OutsideLocalFunction< DiscreteFunction, IntersectionType > uOutside( u );
166 
167  LocalInterpolation< DiscreteFunctionSpaceType > interpolation( u.space() );
168 
169  for( const EntityType &inside : u.space() )
170  {
171  for( const IntersectionType &intersection : intersections( u.gridPart(), inside ) )
172  {
173  if( intersection.conforming() || !intersection.neighbor() )
174  continue;
175 
176  // skip this intersection, if inside is finer than outside
177  const EntityType outside = intersection.outside();
178  if( inside.level() <= outside.level() )
179  continue;
180 
181  // initialize "outside local function"
182  // note: intersection geometries must live until end of intersection loop!
183  const auto geoIn = intersection.geometryInInside();
184  const auto geoOut = intersection.geometryInOutside();
185  uOutside.init( outside, geoIn, geoOut );
186 
187  // resize local DoF vectors
188  const std::size_t numBlocks = blockMapper.numDofs( inside );
189  ldu.resize( numBlocks * localBlockSize );
190  ldw.resize( numBlocks * localBlockSize );
191 
192  // interpolate "outside" values
193  auto guard = bindGuard( interpolation, inside );
194  interpolation( uOutside, ldw );
195 
196  // fetch inside local DoFs
197  u.getLocalDofs( inside, ldu );
198 
199  // patch DoFs assigned to the face
200  blockMapper.onSubEntity( inside, intersection.indexInInside(), 1, onSubEntity );
201  for( std::size_t i = 0; i < numBlocks; ++i )
202  {
203  if( !onSubEntity[ i ] )
204  continue;
205  for( std::size_t j = 0; j < localBlockSize; ++j )
206  ldu[ i*localBlockSize + j ] = ldw[ i*localBlockSize + j ];
207  }
208 
209  // write back inside local DoFs
210  u.setLocalDofs( inside, ldu );
211  }
212  }
213  }
214 
215  template< class Function, class DiscreteFunction, class Weight >
216  static auto project ( const Function &f, DiscreteFunction &u, Weight &weight )
217  -> std::enable_if_t<std::is_void< decltype( interpolate(f,u,weight,u )) >::value>
218  // -> std::enable_if_t<std::is_void< decltype( interpolate(f,u,weight,std::declval<std::remove_cv<std::remove_reference<DiscreteFunction>>&>()) ) >::value>
219  {
220  DiscreteFunction w ( "weight", u.space() );
221  interpolate( f, u, weight, w );
222  makeConforming( u );
223  }
224  template< class Function, class DiscreteFunction >
225  static auto project ( const Function &f, DiscreteFunction &u )
226  -> std::enable_if_t< std::is_void< decltype( project( f,u,std::declval<WeightDefault<typename DiscreteFunction::GridPartType>&>() ) ) >::value>
227  {
228  WeightDefault<typename DiscreteFunction::GridPartType> weight;
229  project(f, u, weight);
230  }
231  };
232 
233  /*======================================================================*/
240  /*======================================================================*/
241  template < typename DType, typename RType >
242  class VtxProjection : public Operator< DType, RType >
243  {
244  public:
245  typedef DType DomainType;
246  typedef RType RangeType;
247  typedef typename DomainType :: RangeFieldType DomainFieldType;
248  typedef typename RType :: RangeFieldType RangeFieldType;
249  typedef typename Dune::FieldTraits< RangeFieldType >::real_type RealType;
250  typedef typename RType :: DiscreteFunctionSpaceType :: GridPartType GridPartType;
253 
255  template <class WeightType>
256  void operator() (const DomainType& f, RangeType& discFunc,
257  WeightType& weight) const
258  {
259  VtxProjectionImpl::project(f,discFunc,weight);
260  }
262  void operator() (const DomainType& f, RangeType& discFunc) const
263  {
264  VtxProjectionImpl::project(f,discFunc);
265  }
266 
267  private:
268  };
269 
270  } // namespace Fem
271 
272 } // name space Dune
273 
274 #endif // #ifndef DUNE_FEM_VTXPROJECTION_HH
Definition: explicitfieldvector.hh:75
FunctionSpaceTraits::DomainFieldType DomainFieldType
Intrinsic type used for values in the domain field (usually a double)
Definition: functionspaceinterface.hh:60
FunctionSpaceTraits::RangeType RangeType
Type of range vector (using type of range field) has a Dune::FieldVector type interface.
Definition: functionspaceinterface.hh:71
FunctionSpaceTraits::LinearMappingType JacobianRangeType
Intrinsic type used for the jacobian values has a Dune::FieldMatrix type interface.
Definition: functionspaceinterface.hh:75
FunctionSpaceTraits::DomainType DomainType
Type of domain vector (using type of domain field) has a Dune::FieldVector type interface.
Definition: functionspaceinterface.hh:67
FunctionSpaceTraits::RangeFieldType RangeFieldType
Intrinsic type used for values in the range field (usually a double)
Definition: functionspaceinterface.hh:63
@ dimDomain
dimension of domain vector space
Definition: functionspaceinterface.hh:46
@ dimRange
dimension of range vector space
Definition: functionspaceinterface.hh:48
A vector valued function space.
Definition: functionspace.hh:60
IntersectionIteratorType::Intersection IntersectionType
type of Intersection
Definition: gridpart.hh:116
The Projection class which average discontinuous function using the interpolation of the space (e....
Definition: vtxprojection.hh:243
VtxProjection()
Constructor.
Definition: vtxprojection.hh:252
void operator()(const DomainType &f, RangeType &discFunc, WeightType &weight) const
apply projection
Definition: vtxprojection.hh:256
GridImp::template Codim< 1 >::LocalGeometry LocalGeometry
Codim 1 geometry returned by geometryInInside() and geometryInOutside()
Definition: intersection.hh:204
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
static void interpolate(const GridFunction &u, DiscreteFunction &v)
perform native interpolation of a discrete function space
Definition: interpolate.hh:54
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
Dune namespace.
Definition: alignedallocator.hh:13
abstract operator
Definition: operator.hh:34
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)