46 namespace Electromagnetism{
54 template <
typename TDomain,
typename TElem>
63 "Not a simplex (" << ref_elem_type::REFERENCE_OBJECT_ID
64 <<
") as a template param. of NedelecT1_LDisc_forSimplex: Only triangles and tetrahedra accepted.");
71 ref_mapping.
update (corners);
80 W0_shapes.
grads (local_grad, local_pos);
82 for (
size_t co = 0; co < numCorners; co++)
95 template <
typename TDomain,
typename TElem>
98 const TDomain * domain,
100 size_t edge_corner [numEdges] [2]
109 for (
size_t e = 0; e < numEdges; e++)
111 int co_0 = rRefElem.id (1, e, 0, 0);
112 int co_1 = rRefElem.id (1, e, 0, 1);
113 UG_ASSERT ((co_0 >= 0 && co_1 >= 0),
"NedelecT1_LDisc_forSimplex::get_edge_corners: Internal error.");
117 if (elem->vertex (co_0) == edge->
vertex (0))
119 UG_ASSERT ((elem->vertex (co_0) == edge->
vertex (0)),
"NedelecT1_LDisc_forSimplex::get_edge_corners: Internal error.")
120 edge_corner[e][0] = co_0;
121 edge_corner[e][1] = co_1;
126 "NedelecT1_LDisc_forSimplex::get_edge_corners: Internal error.")
127 edge_corner[e][0] = co_1;
128 edge_corner[e][1] = co_0;
143 template <
typename TDomain,
typename TElem>
146 const TDomain * domain,
149 number S [maxNumEdges][maxNumEdges],
150 number M [maxNumEdges][maxNumEdges]
154 memset (S, 0, maxNumEdges * maxNumEdges *
sizeof (
number));
155 memset (M, 0, maxNumEdges * maxNumEdges *
sizeof (
number));
158 number V = ElementSize<ref_elem_type, WDim> (corners);
164 compute_W0_grads (corners, grad_w0);
167 size_t edge_corner [numEdges] [2];
168 get_edge_corners (domain, elem, edge_corner);
173 for (
size_t e = 0; e < numEdges; e++)
174 GenVecCross (half_rot_w1[e], grad_w0[edge_corner[e][0]], grad_w0[edge_corner[e][1]]);
177 for (
size_t e_1 = 0; e_1 < numEdges; e_1++)
178 for (
size_t e_2 = 0; e_2 <= e_1; e_2++)
179 S[e_1][e_2] =
VecDot (half_rot_w1[e_1], half_rot_w1[e_2]) * 4 * V;
180 for (
size_t e_1 = 0; e_1 < numEdges-1; e_1++)
181 for (
size_t e_2 = e_1 + 1; e_2 < numEdges; e_2++) S[e_1][e_2] = S[e_2][e_1];
191 static const number lambda = ((
number) (WDim + 1)) / (WDim + 2);
195 for (
size_t e = 0; e < numEdges; e++)
200 VecSubtract (w1_at_center[e], grad_w0[edge_corner[e][0]], grad_w0[edge_corner[e][1]]);
201 w1_at_center[e] /= numCorners;
205 for (
size_t e = 0; e < numEdges; e++)
209 for (
size_t co = 0; co < numCorners; co++) w1_at_co[e][co] = 0;
210 w1_at_co[e][edge_corner[e][0]] = grad_w0[edge_corner[e][1]];
211 w1_at_co[e][edge_corner[e][1]] -= grad_w0[edge_corner[e][0]];
214 for (
size_t e_1 = 0; e_1 < numEdges; e_1++)
215 for (
size_t e_2 = 0; e_2 <= e_1; e_2++)
218 for (
size_t co = 0; co < numCorners; co++)
219 t +=
VecDot (w1_at_co[e_1][co], w1_at_co[e_2][co]);
222 M[e_1][e_2] = (lambda *
VecDot (w1_at_center[e_1], w1_at_center[e_2])
223 + (1 - lambda) * t) * V;
225 for (
size_t e_1 = 0; e_1 < numEdges-1; e_1++)
226 for (
size_t e_2 = e_1 + 1; e_2 < numEdges; e_2++) M[e_1][e_2] = M[e_2][e_1];
236 template <
typename TDomain,
typename TElem>
239 const TDomain * domain,
242 number M [maxNumEdges][maxNumEdges]
246 memset (M, 0, maxNumEdges * maxNumEdges *
sizeof (
number));
249 number V = ElementSize<ref_elem_type, WDim> (corners);
255 compute_W0_grads (corners, grad_w0);
258 size_t edge_corner [numEdges] [2];
259 get_edge_corners (domain, elem, edge_corner);
267 static const number lambda = ((
number) (WDim + 1)) / (WDim + 2);
271 for (
size_t e = 0; e < numEdges; e++)
276 VecSubtract (w1_at_center[e], grad_w0[edge_corner[e][0]], grad_w0[edge_corner[e][1]]);
277 w1_at_center[e] /= numCorners;
281 for (
size_t e = 0; e < numEdges; e++)
285 for (
size_t co = 0; co < numCorners; co++) w1_at_co[e][co] = 0;
286 w1_at_co[e][edge_corner[e][0]] = grad_w0[edge_corner[e][1]];
287 w1_at_co[e][edge_corner[e][1]] -= grad_w0[edge_corner[e][0]];
290 for (
size_t e_1 = 0; e_1 < numEdges; e_1++)
291 for (
size_t e_2 = 0; e_2 <= e_1; e_2++)
294 for (
size_t co = 0; co < numCorners; co++)
295 t +=
VecDot (w1_at_co[e_1][co], w1_at_co[e_2][co]);
298 M[e_1][e_2] = (lambda *
VecDot (w1_at_center[e_1], w1_at_center[e_2])
299 + (1 - lambda) * t) * V;
301 for (
size_t e_1 = 0; e_1 < numEdges-1; e_1++)
302 for (
size_t e_2 = e_1 + 1; e_2 < numEdges; e_2++) M[e_1][e_2] = M[e_2][e_1];
319 template <
typename TDomain,
typename TElem>
322 const TDomain * domain,
329 memset (B, 0, numCorners * numEdges *
sizeof (
number));
333 compute_W0_grads (corners, grad_w0);
336 size_t edge_corner [numEdges] [2];
337 get_edge_corners (domain, elem, edge_corner);
340 number V = - ElementSize<ref_elem_type, WDim> (corners) / numCorners;
342 for (
size_t e = 0; e < numEdges; e++)
344 VecSubtract (T_w1_at_center[e], grad_w0[edge_corner[e][0]], grad_w0[edge_corner[e][1]]);
345 T_w1_at_center[e] *= V;
349 for (
size_t v = 0; v < numCorners; v++)
350 for (
size_t e = 0; e < numEdges; e++)
351 B[v][e] =
VecDot (T_w1_at_center[e], grad_w0[v]);
360 template <
typename TDomain,
typename TElem>
363 const TDomain * domain,
372 compute_W0_grads (corners, grad_w0);
375 size_t edge_corner [numEdges] [2];
376 get_edge_corners (domain, elem, edge_corner);
384 for (
size_t e = 0; e < numEdges; e++)
386 size_t m = edge_corner[e][0], n = edge_corner[e][1];
387 VecScaleAdd (shapes[e], w0[m], grad_w0[n], - w0[n], grad_w0[m]);
396 template <
typename TDomain,
typename TElem>
399 const TDomain * domain,
410 compute_W0_grads (corners, grad_w0);
413 size_t edge_corner [numEdges] [2];
414 get_edge_corners (domain, elem, edge_corner);
420 for (
size_t pnt = 0; pnt < n_pnt; pnt++)
429 for (
size_t e = 0; e < numEdges; e++)
432 size_t m = edge_corner[e][0], n = edge_corner[e][1];
433 VecScaleAdd (shape, w0[m], grad_w0[n], - w0[n], grad_w0[m]);
447 template <
typename TDomain,
typename TElem>
450 const TDomain * domain,
459 compute_W0_grads (corners, grad_w0);
462 size_t edge_corner [numEdges] [2];
463 get_edge_corners (domain, elem, edge_corner);
468 for (
size_t e = 0; e < numEdges; e++)
469 GenVecCross (half_rot_w1[e], grad_w0[edge_corner[e][0]], grad_w0[edge_corner[e][1]]);
473 for (
size_t e = 0; e < numEdges; e++)
486 template <
typename TDomain>
489 const TDomain * domain,
500 UG_THROW (
"NedelecInterpolation::curl_flux:"
501 " No implementation of the Nedelec elements for"
503 " of reference dim. 3 in a 3d domain. (This must be a tetrahedron.)");
516 area =
TriangleArea (sect_corners[0], sect_corners[1], sect_corners[2]);
519 area =
TriangleArea (sect_corners[0], sect_corners[1], sect_corners[2])
520 +
TriangleArea (sect_corners[0], sect_corners[2], sect_corners[3]);
524 UG_THROW (
"NedelecInterpolation::curl_flux:"
525 " Illegal number of intersections of a plane with a tetrahedron.");
531 corners, dofs, curl_vec);
void shapes(shape_type *vShape, const MathVector< dim > &x) const
void grads(grad_type *vGrad, const MathVector< dim > &x) const
virtual Vertex * vertex(size_t index) const
TDomain::position_type position_type
type of the geometric positions (WDim-vectors)
Definition: nedelec_local_ass.h:565
static number curl_flux(const TDomain *domain, GridObject *elem, const position_type corners[], const number dofs[], const MathVector< WDim > &normal, const position_type pnt, number &flux)
computes flux of the curl through a given plane in an element
Definition: nedelec_local_ass.h:457
static void local_mass(const TDomain *domain, TElem *elem, const position_type *corners, number M[maxNumEdges][maxNumEdges])
assembles the local mass matrix of the Nedelec elements
Definition: nedelec_local_ass_impl.h:238
static void interpolate(const TDomain *domain, TElem *elem, const position_type *corners, const number dofs[], const MathVector< dim > local[], const size_t n_pnt, MathVector< WDim > values[])
computes of the values of the grid functions
Definition: nedelec_local_ass_impl.h:398
TDomain::position_type position_type
type of the geometric positions (WDim-vectors)
Definition: nedelec_local_ass.h:266
static void local_div_matrix(const TDomain *domain, TElem *elem, const position_type *corners, number B[][numEdges])
assembles the discrete weak div operator
Definition: nedelec_local_ass_impl.h:321
static void compute_W0_grads(const position_type *corners, MathVector< WDim > grad[numCorners])
computes the gradients of the Whitney-0 (Lagrange P1) shape functions
Definition: nedelec_local_ass_impl.h:56
static void get_shapes(const TDomain *domain, TElem *elem, const position_type *corners, const MathVector< dim > local, MathVector< WDim > shapes[])
computes the Nedelec shapes at a given point
Definition: nedelec_local_ass_impl.h:362
static void curl(const TDomain *domain, TElem *elem, const position_type *corners, const number dofs[], MathVector< WDim > &curl_vec)
computes the curl of the grid functions (in 2d represented as instead of )
Definition: nedelec_local_ass_impl.h:449
static void local_stiffness_and_mass(const TDomain *domain, TElem *elem, const position_type *corners, number S[maxNumEdges][maxNumEdges], number M[maxNumEdges][maxNumEdges])
assembles the local stiffness and mass matrices of the rot-rot operator
Definition: nedelec_local_ass_impl.h:145
static void get_edge_corners(const TDomain *domain, TElem *elem, size_t edge_corner[numEdges][2])
gets the correspondence between the edge dof indices and the corners of the element
Definition: nedelec_local_ass_impl.h:97
reference_element_traits< TElem >::reference_element_type ref_elem_type
type of reference element
Definition: nedelec_local_ass.h:269
TDomain::grid_type grid_type
type of the grid
Definition: nedelec_local_ass.h:263
static void curl(const TDomain *domain, TElem *elem, const position_type *corners, const number dofs[], MathVector< WDim > &curl_vec)
computes the curl of the grid functions (in 2d represented as instead of )
Definition: nedelec_local_ass.h:184
virtual ReferenceObjectID reference_object_id() const=0
number jacobian_transposed_inverse(MathMatrix< worldDim, dim > &JTInv, const MathVector< dim > &locPos) const
void update(const MathVector< worldDim > *vCornerCoord)
size_t IntersectPlaneWithTetrahedron(vector3 intsOut[4], const vector3 &planePoint, const vector3 &planeNormal, const vector3 t[4])
#define UG_ASSERT(expr, msg)
void MatVecMult(vector_t_out &vOut, const matrix_t &m, const vector_t_in &v)
number TriangleArea(const vector_t &p1, const vector_t &p2, const vector_t &p3)
void VecScaleAppend(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1)
void GenVecCross(MathVector< dim > &result, const MathVector< dim > &v_1, const MathVector< dim > &v_2)
void VecSubtract(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
int local(bglp_vertex_descriptor p)
void VecScaleAdd(double &dest, double alpha1, const double &v1, double alpha2, const double &v2)