33 #ifndef __H__UG__LIB_DISC__FUNCTION_SPACE__LEVEL_TRANSFER__
34 #define __H__UG__LIB_DISC__FUNCTION_SPACE__LEVEL_TRANSFER__
47 template <
typename TDomain,
typename TAlgebra>
52 typedef typename TGridFunction::template traits<Vertex>::const_iterator const_iterator;
63 UG_THROW(
"ProlongateP1: Top Level not supported.")
64 if(fineTopLevel < coarseTopLevel)
65 UG_THROW(
"ProlongateP1: fine level must be >= coarse level.");
68 std::vector<size_t> vFineIndex, vCoarseIndex;
71 const_iterator iterEnd = uFine.template end<Vertex>();
72 const_iterator iter = uFine.template begin<Vertex>();
73 for(; iter != iterEnd; ++iter)
77 const int vertexLevel = mg->
get_level(vrt);
83 if(vertexLevel != fineTopLevel && vertexLevel <= coarseTopLevel)
88 for(
size_t i = 0; i < vFineIndex.size(); ++i)
89 uFine[ vFineIndex[i] ] = uCoarse[ vCoarseIndex[i] ];
98 while(parentLevel > coarseTopLevel){
107 if(parentLevel == vertexLevel - 1)
110 switch(parentBaseObjectID)
118 for(
size_t i = 0; i < vFineIndex.size(); ++i)
119 uFine[ vFineIndex[i] ] = uCoarse[ vCoarseIndex[i] ];
125 for(
size_t i = 0; i < vFineIndex.size(); ++i)
126 uFine[ vFineIndex[i] ] = 0.0;
128 Edge* pParent =
static_cast<Edge*
>(parent);
134 for(
size_t i = 0; i < vFineIndex.size(); ++i)
136 1.0, uFine[ vFineIndex[i] ],
137 0.5, uCoarse[ vCoarseIndex[i] ]);
144 for(
size_t i = 0; i < vFineIndex.size(); ++i)
145 uFine[ vFineIndex[i] ] = 0.0;
147 Face* pParent =
static_cast<Face*
>(parent);
153 for(
size_t i = 0; i < vFineIndex.size(); ++i)
155 1.0, uFine[ vFineIndex[i] ],
156 0.25, uCoarse[ vCoarseIndex[i] ]);
163 for(
size_t i = 0; i < vFineIndex.size(); ++i)
164 uFine[ vFineIndex[i] ] = 0.0;
172 for(
size_t i = 0; i < vFineIndex.size(); ++i)
174 1.0, uFine[ vFineIndex[i] ],
175 0.125, uCoarse[ vCoarseIndex[i] ]);
184 default:
UG_THROW(
"Unexpected case appeared.");
191 UG_THROW(
"This case not implemented.");
197 template <
typename TDomain,
typename TAlgebra>
209 const int coarseTopLevel = uCoarse.
dof_distribution()->grid_level().level();
213 UG_THROW(
"ProlongateElemwise: Top Level not supported.")
214 if(fineTopLevel < coarseTopLevel)
215 UG_THROW(
"ProlongateElemwise: fine level must be >= coarse level.");
218 std::vector<DoFIndex> vCoarseMI, vFineMI;
222 std::vector<LFEID> vFineLFEID(fineDD->num_fct());
223 for(
size_t fct = 0; fct < fineDD->num_fct(); ++fct)
224 vFineLFEID[fct] = fineDD->local_finite_element_id(fct);
226 std::vector<LFEID> vCoarseLFEID(coarseDD->num_fct());
227 for(
size_t fct = 0; fct < coarseDD->num_fct(); ++fct)
228 vCoarseLFEID[fct] = coarseDD->local_finite_element_id(fct);
231 if(vFineLFEID.size() != vCoarseLFEID.size())
232 UG_THROW(
"ProlongateElemwise: Spaces must contain same number of functions.")
236 for(
size_t fct = 0; fct < vFineLFEID.size(); ++fct){
248 const_iterator iter, iterBegin, iterEnd;
251 for(
int si = 0; si < coarseDD->num_subsets(); ++si)
253 iterBegin = coarseDD->template begin<Element>(si);
254 iterEnd = coarseDD->template end<Element>(si);
257 for(iter = iterBegin; iter != iterEnd; ++iter)
260 Element* coarseElem = *iter;
263 std::vector<Element*> vChild;
264 std::queue<Element*> qElem;
265 qElem.push(coarseElem);
266 while(!qElem.empty()){
267 Element* elem = qElem.front(); qElem.pop();
269 vChild.push_back(elem);
271 for(
size_t c = 0; c < mg->
num_children<Element,Element>(elem); ++c){
272 qElem.push(mg->
get_child<Element,Element>(elem, c));
281 for(
size_t fct = 0; fct < coarseDD->num_fct(); fct++)
284 if(!coarseDD->is_def_in_subset(fct, si))
continue;
287 coarseDD->dof_indices(coarseElem, fct, vCoarseMI);
291 = LocalFiniteElementProvider::get<dim>(coarseROID, vCoarseLFEID[fct]);
294 std::vector<MathVector<dim> > vCornerCoarse;
298 for(
size_t c = 0; c < vChild.size(); ++c)
300 Element* child = vChild[c];
303 fineDD->dof_indices(child, fct, vFineMI);
306 std::vector<MathVector<dim> > vDoFPos, vLocPos;
309 UG_ASSERT(vDoFPos.size() == vFineMI.size(),
"numDoFPos ("
310 <<vDoFPos.size()<<
") != numDoFs ("<<vFineMI.size()<<
").");
314 = ReferenceMappingProvider::get<dim, dim>(coarseROID, vCornerCoarse);
318 vLocPos.resize(vDoFPos.size());
319 for(
size_t ip = 0; ip < vLocPos.size(); ++ip)
VecSet(vLocPos[ip], 0.0);
323 std::vector<std::vector<number> > vvShape;
326 lsfs.
shapes(vvShape, vLocPos);
328 for(
size_t ip = 0; ip < vvShape.size(); ++ip){
329 DoFRef(uFine, vFineMI[ip]) = 0.0;
330 for(
size_t sh = 0; sh < vvShape[ip].size(); ++sh){
331 DoFRef(uFine, vFineMI[ip]) +=
332 vvShape[ip][sh] *
DoFRef(uCoarse, vCoarseMI[sh]);
342 template <
typename TDomain,
typename TAlgebra>
348 UG_THROW(
"Prolongate: GridFunctions must have same Domain.");
352 UG_THROW(
"Prolongate: GridFunctions must have same Function Pattern.");
356 const int coarseTopLevel = uCoarse.
dof_distribution()->grid_level().level();
358 UG_THROW(
"Prolongate: Top Level not supported.")
359 if(fineTopLevel < coarseTopLevel)
360 UG_THROW(
"Prolongate: fine level must be >= coarse level.");
363 bool bOnlyP1Fct =
true;
364 for(
size_t fct = 0; fct < uFine.
num_fct(); ++fct)
368 bOnlyP1Fct =
false;
break;
372 (fineTopLevel == coarseTopLevel+1 || fineTopLevel == coarseTopLevel)){
380 uFine.set_storage_type(uCoarse.get_storage_mask());
389 template <
typename TDomain,
typename TAlgebra>
394 typedef typename TGridFunction::template traits<Vertex>::const_iterator const_iterator;
401 const int coarseTopLevel = uCoarse.
dof_distribution()->grid_level().level();
405 UG_THROW(
"RestrictP1: Top Level not supported.")
406 if(fineTopLevel < coarseTopLevel)
407 UG_THROW(
"RestrictP1: fine level must be >= coarse level.");
410 std::vector<size_t> vFineIndex, vCoarseIndex;
413 const_iterator iterEnd = uCoarse.template end<Vertex>();
414 const_iterator iter = uCoarse.template begin<Vertex>();
415 for(; iter != iterEnd; ++iter)
418 Vertex* coarseVrt = *iter;
421 Vertex* fineVrt = coarseVrt;
422 while(mg->
get_level(fineVrt) != fineTopLevel &&
431 for(
size_t i = 0; i < vFineIndex.size(); ++i)
432 uCoarse[ vCoarseIndex[i] ] = uFine[ vFineIndex[i] ];
438 template <
typename TDomain,
typename TAlgebra>
451 const int coarseTopLevel = uCoarse.
dof_distribution()->grid_level().level();
455 UG_THROW(
"RestrictElemwise: Top Level not supported.")
456 if(fineTopLevel < coarseTopLevel)
457 UG_THROW(
"RestrictElemwise: fine level must be >= coarse level.");
460 std::vector<DoFIndex> vCoarseMI, vFineMI;
464 std::vector<LFEID> vFineLFEID(fineDD->num_fct());
465 for(
size_t fct = 0; fct < fineDD->num_fct(); ++fct)
466 vFineLFEID[fct] = fineDD->local_finite_element_id(fct);
468 std::vector<LFEID> vCoarseLFEID(coarseDD->num_fct());
469 for(
size_t fct = 0; fct < coarseDD->num_fct(); ++fct)
470 vCoarseLFEID[fct] = coarseDD->local_finite_element_id(fct);
473 if(vFineLFEID.size() != vCoarseLFEID.size())
474 UG_THROW(
"RestrictElemwise: Spaces must contain same number of functions.")
478 for(
size_t fct = 0; fct < vFineLFEID.size(); ++fct){
490 const_iterator iter, iterBegin, iterEnd;
493 for(
int si = 0; si < coarseDD->num_subsets(); ++si)
495 iterBegin = coarseDD->template begin<Element>(si);
496 iterEnd = coarseDD->template end<Element>(si);
499 for(iter = iterBegin; iter != iterEnd; ++iter)
502 Element* coarseElem = *iter;
505 std::vector<Element*> vFineElem;
506 std::queue<Element*> qElem;
507 qElem.push(coarseElem);
508 while(!qElem.empty()){
509 Element* elem = qElem.front(); qElem.pop();
511 vFineElem.push_back(elem);
513 for(
size_t c = 0; c < mg->
num_children<Element,Element>(elem); ++c){
514 qElem.push(mg->
get_child<Element,Element>(elem, c));
520 for(
size_t fct = 0; fct < coarseDD->num_fct(); fct++)
523 if(!coarseDD->is_def_in_subset(fct, si))
continue;
526 coarseDD->inner_dof_indices(coarseElem, fct, vCoarseMI);
529 std::vector<MathVector<dim> > vDoFPos;
533 for(
size_t ip = 0; ip < vDoFPos.size(); ++ip)
536 for(
size_t c = 0; c < vFineElem.size(); ++c)
538 Element* fineElem = vFineElem[c];
540 UG_THROW(
"This part does not work.");
548 std::vector<MathVector<dim> > vCornerFine;
556 = LocalFiniteElementProvider::get<locDim>(fineROID, vFineLFEID[fct]);
560 = ReferenceMappingProvider::get<locDim, dim>(fineROID, vCornerFine);
568 fineDD->dof_indices(fineElem, fct, vFineMI);
571 std::vector<number> vShape;
574 lsfs.
shapes(vShape, vLocPos);
577 DoFRef(uCoarse, vCoarseMI[ip]) = 0.0;
578 for(
size_t sh = 0; sh < vShape.size(); ++sh)
580 DoFRef(uCoarse, vCoarseMI[ip]) +=
581 vShape[sh] *
DoFRef(uFine, vFineMI[sh]);
591 template <
typename TDomain,
typename TAlgebra>
597 UG_THROW(
"Restrict: GridFunctions must have same Domain.");
601 UG_THROW(
"Restrict: GridFunctions must have same Function Pattern.");
604 const int coarseTopLevel = uCoarse.
dof_distribution()->grid_level().level();
607 UG_THROW(
"Restrict: Top Level not supported.")
608 if(coarseTopLevel > fineTopLevel)
609 UG_THROW(
"Restrict: fine level must be >= coarse level.");
612 bool bOnlyP1Fct =
true;
613 for(
size_t fct = 0; fct < uCoarse.
num_fct(); ++fct)
617 bOnlyP1Fct =
false;
break;
621 (coarseTopLevel+1 == fineTopLevel || coarseTopLevel == fineTopLevel)){
625 UG_THROW(
"Restrict: Only P1 implemented.")
630 uCoarse.set_storage_type(uFine.get_storage_mask());
Definition: smart_pointer.h:296
virtual base class for reference mappings
Definition: reference_mapping_provider.h:53
virtual void global_to_local(MathVector< dim > &locPos, const MathVector< worldDim > &globPos, const size_t maxIter=1000, const number tol=1e-10) const =0
map global coordinate to local coordinate
const LFEID & local_finite_element_id(size_t fct) const
Definition: dof_distribution_info.h:225
ConstSmartPtr< FunctionPattern > function_pattern() const
returns the function pattern
Definition: dof_distribution_info.h:172
size_t num_fct() const
number of discrete functions on subset si
Definition: dof_distribution_info.h:176
Base-class for edges.
Definition: grid_base_objects.h:397
virtual Vertex * vertex(size_t index) const
Definition: grid_base_objects.h:366
virtual size_t num_vertices() const
Definition: grid_base_objects.h:368
Faces are 2-dimensional objects.
Definition: grid_base_objects.h:510
virtual Vertex * vertex(size_t index) const
Definition: grid_base_objects.h:486
virtual size_t num_vertices() const
Definition: grid_base_objects.h:488
represents numerical solutions on a grid using an algebraic vector
Definition: grid_function.h:121
SmartPtr< TDomain > domain()
returns domain
Definition: grid_function.h:342
SmartPtr< DoFDistribution > dof_distribution()
Definition: grid_function.h:236
size_t inner_algebra_indices(TElem *elem, std::vector< size_t > &ind, bool bClear=true) const
get algebra indices on an geometric object in canonical order
Definition: grid_function.h:337
@ TOP
Definition: grid_level.h:45
The base class for all geometric objects, such as vertices, edges, faces, volumes,...
Definition: grid_base_objects.h:157
virtual ReferenceObjectID reference_object_id() const =0
SpaceType type() const
returns the type of the local finite element
Definition: local_finite_element_id.h:132
int order() const
returns the order of the local finite element
Definition: local_finite_element_id.h:126
@ PIECEWISE_CONSTANT
Definition: local_finite_element_id.h:106
@ LAGRANGE
Definition: local_finite_element_id.h:104
virtual base class for local shape function sets
Definition: local_shape_function_set.h:70
virtual void shapes(shape_type *vShape, const MathVector< dim > &x) const =0
returns all shape functions evaluated at a point
a mathematical Vector with N entries.
Definition: math_vector.h:97
int get_level(TElem *elem) const
Definition: multi_grid.h:206
TChild * get_child(TElem *elem, size_t ind) const
returns the i-th child of the given child-type
Definition: multi_grid.h:268
GridObject * get_parent(GridObject *parent) const
Definition: multi_grid.cpp:180
bool has_children(TElem *elem) const
Definition: multi_grid.h:217
size_t num_children(TElem *elem) const
returns the number of children of the given child-type
Definition: multi_grid.h:225
Const iterator to traverse the surface of a multi-grid hierarchy.
Definition: surface_view.h:237
Base-class for all vertex-types.
Definition: grid_base_objects.h:231
Volumes are 3-dimensional objects.
Definition: grid_base_objects.h:754
virtual Vertex * vertex(size_t index) const
Definition: grid_base_objects.h:727
virtual size_t num_vertices() const
Definition: grid_base_objects.h:729
void CollectCornerCoordinates(std::vector< typename TAAPos::ValueType > &vCornerCoordsOut, const TElem &elem, const TAAPos &aaPos, bool clearContainer=true)
returns the corner coordinates of a geometric object
Definition: domain_util_impl.h:75
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
#define UG_THROW(msg)
Definition: error.h:57
void VecSet(vector_t &vInOut, typename vector_t::value_type s)
Set each vector component to scalar (componentwise)
Definition: math_vector_functions_common_impl.hpp:539
void VecScaleAdd(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1, typename vector_t::value_type s2, const vector_t &v2)
Scales two Vectors, adds them and returns the sum in a third vector.
Definition: math_vector_functions_common_impl.hpp:265
ReferenceObjectID
these ids are used to identify the shape of a geometric object.
Definition: grid_base_objects.h:74
@ ROID_TETRAHEDRON
Definition: grid_base_objects.h:80
@ ROID_QUADRILATERAL
Definition: grid_base_objects.h:79
@ ROID_PYRAMID
Definition: grid_base_objects.h:83
@ ROID_PRISM
Definition: grid_base_objects.h:82
@ ROID_EDGE
Definition: grid_base_objects.h:77
@ ROID_OCTAHEDRON
Definition: grid_base_objects.h:84
@ ROID_HEXAHEDRON
Definition: grid_base_objects.h:81
@ ROID_TRIANGLE
Definition: grid_base_objects.h:78
@ ROID_VERTEX
Definition: grid_base_objects.h:76
number & DoFRef(TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
Definition: multi_index.h:276
void ProlongateElemwise(GridFunction< TDomain, TAlgebra > &uFine, const GridFunction< TDomain, TAlgebra > &uCoarse)
Definition: level_transfer.h:198
bool DoFPosition(std::vector< MathVector< dim > > &vPos, const ReferenceObjectID roid, const std::vector< MathVector< dim > > &vCornerCoord, const LFEID &lfeID)
�
Definition: dof_position_util.cpp:202
void RestrictP1(GridFunction< TDomain, TAlgebra > &uCoarse, const GridFunction< TDomain, TAlgebra > &uFine)
Definition: level_transfer.h:390
void Restrict(GridFunction< TDomain, TAlgebra > &uCoarse, const GridFunction< TDomain, TAlgebra > &uFine)
Definition: level_transfer.h:592
void ProlongateP1(GridFunction< TDomain, TAlgebra > &uFine, const GridFunction< TDomain, TAlgebra > &uCoarse)
Definition: level_transfer.h:48
bool InnerDoFPosition(std::vector< MathVector< dim > > &vPos, const ReferenceObjectID roid, const std::vector< MathVector< dim > > &vCornerCoord, const LFEID &lfeID)
�
Definition: dof_position_util.cpp:112
void RestrictElemwise(GridFunction< TDomain, TAlgebra > &uCoarse, const GridFunction< TDomain, TAlgebra > &uFine)
Definition: level_transfer.h:439
void Prolongate(GridFunction< TDomain, TAlgebra > &uFine, const GridFunction< TDomain, TAlgebra > &uCoarse)
Definition: level_transfer.h:343
domain_traits< dim >::grid_base_object grid_base_object
Definition: dof_distribution.h:88