Line data Source code
1 : /*
2 : * Copyright (c) 2014: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H__UG_DISC__GRADIENT_EVALUATORS__
34 : #define __H__UG_DISC__GRADIENT_EVALUATORS__
35 :
36 : #include "grid_function.h"
37 : #include "common/util/provider.h"
38 : #include "lib_disc/common/geometry_util.h"
39 : #include "lib_disc/reference_element/reference_element_util.h"
40 : #include "lib_disc/reference_element/reference_mapping_provider.h"
41 : #include "lib_disc/local_finite_element/local_finite_element_provider.h"
42 :
43 : namespace ug{
44 :
45 : /** Provides a function to evaluate the gradient of a given grid function efficiently
46 : * in each element.*/
47 : template <class TFunction>
48 : class GradientEvaluator_LagrangeP1{
49 : public:
50 : static const int dim = TFunction::dim;
51 : typedef MathVector<dim> vector_t;
52 : typedef typename TFunction::element_type elem_t;
53 :
54 0 : GradientEvaluator_LagrangeP1(TFunction* u, size_t fct) :
55 0 : m_pu(u),
56 0 : m_aaPos(u->domain()->position_accessor()),
57 0 : m_fct(fct)
58 0 : {}
59 :
60 0 : vector_t evaluate(elem_t* elem)
61 : {
62 0 : TFunction& u = *m_pu;
63 :
64 : // reference object type
65 0 : ReferenceObjectID roid = elem->reference_object_id();
66 :
67 : // get trial space
68 : const LocalShapeFunctionSet<dim>& lsfs =
69 0 : LocalFiniteElementProvider::get<dim>(roid, LFEID(LFEID::LAGRANGE, dim, 1));
70 :
71 : // create a reference mapping
72 : DimReferenceMapping<dim, dim>& map
73 0 : = ReferenceMappingProvider::get<dim, dim>(roid);
74 :
75 : // get local Mid Point
76 0 : vector_t localIP = ReferenceElementCenter<dim>(roid);
77 :
78 : // number of shape functions
79 0 : const size_t numSH = lsfs.num_sh();
80 0 : vLocalGrad.resize(numSH);
81 0 : vGlobalGrad.resize(numSH);
82 :
83 : // evaluate reference gradient at local midpoint
84 0 : lsfs.grads(&vLocalGrad[0], localIP);
85 :
86 : // get corners of element
87 0 : CollectCornerCoordinates(vCorner, *elem, m_aaPos);
88 :
89 : // update mapping
90 0 : map.update(&vCorner[0]);
91 :
92 : // compute jacobian
93 0 : map.jacobian_transposed_inverse(JTInv, localIP);
94 :
95 : // compute gradient at mid point by summing contributions of all shape fct
96 : vector_t elemGrad;
97 : VecSet(elemGrad, 0.0);
98 0 : for(size_t sh = 0 ; sh < numSH; ++sh)
99 : {
100 : // get global Gradient
101 : MatVecMult(vGlobalGrad[sh], JTInv, vLocalGrad[sh]);
102 :
103 : // get vertex
104 0 : Vertex* vert = elem->vertex(sh);
105 :
106 : // get of of vertex
107 : std::vector<DoFIndex> ind;
108 0 : u.inner_dof_indices(vert, m_fct, ind);
109 :
110 : // scale global gradient
111 : vGlobalGrad[sh] *= DoFRef(u, ind[0]);
112 :
113 : // sum up
114 : elemGrad += vGlobalGrad[sh];
115 : }
116 0 : return elemGrad;
117 : }
118 : private:
119 : TFunction* m_pu;
120 : typename TFunction::domain_type::position_accessor_type m_aaPos;
121 : size_t m_fct;
122 : // the following members are declared here so that they can be efficiently reused
123 : MathMatrix<dim, dim> JTInv;
124 : std::vector<vector_t > vLocalGrad;
125 : std::vector<vector_t > vGlobalGrad;
126 : std::vector<vector_t > vCorner;
127 : };
128 :
129 : }// end of namespace
130 : #endif
|