Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
geometry_util.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 * Author: Andreas Vogel
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__LIB_DISC__COMMON__GEOMETRY_UTIL__
34#define __H__UG__LIB_DISC__COMMON__GEOMETRY_UTIL__
35
36#include <vector>
37#include <cmath>
38
39#include "common/common.h"
44
45namespace ug{
46
49template <typename TRefElem, int TWorldDim>
50inline number ElementSize(const MathVector<TWorldDim>* vCornerCoords);
51
54// 1D Reference Elements
57
60
66template <>
68{
69 return VecDistance(vCornerCoords[0], vCornerCoords[1]);
70}
71
74
80template <>
82{
83 return VecDistance(vCornerCoords[0], vCornerCoords[1]);
84}
85
88
94template <>
96{
97 return VecDistance(vCornerCoords[0], vCornerCoords[1]);
98}
99
102// 2D Reference Elements
105
108
117template <>
119{
120 return(0.5*fabs((vCornerCoords[1][1]-vCornerCoords[0][1])*(vCornerCoords[2][0]-vCornerCoords[0][0])
121 -(vCornerCoords[1][0]-vCornerCoords[0][0])*(vCornerCoords[2][1]-vCornerCoords[0][1])));
122}
123
126
134template <>
136{
137 MathVector<3> x10, x20, n;
138
139 VecSubtract(x10, vCornerCoords[1], vCornerCoords[0]);
140 VecSubtract(x20, vCornerCoords[2], vCornerCoords[0]);
141 VecCross(n, x10, x20);
142
143 return(0.5 * VecTwoNorm(n) );
144}
145
148
156template <>
158{
159 return( 0.5*fabs( (vCornerCoords[3][1]-vCornerCoords[1][1])*(vCornerCoords[2][0]-vCornerCoords[0][0])
160 -(vCornerCoords[3][0]-vCornerCoords[1][0])*(vCornerCoords[2][1]-vCornerCoords[0][1]) ) );
161}
162
165
175template <>
177{
178 MathVector<3> x20, x31, n;
179
180 VecSubtract(x20, vCornerCoords[2], vCornerCoords[0]);
181 VecSubtract(x31, vCornerCoords[3], vCornerCoords[1]);
182 VecCross(n, x20, x31);
183
184 return(0.5 * VecTwoNorm(n) );
185}
186
187
190// 3D Reference Elements
193
196
208template <>
210{
211 MathVector<3> x10, x20, x30, n;
212
213 VecSubtract(x10, vCornerCoords[1], vCornerCoords[0]);
214 VecSubtract(x20, vCornerCoords[2], vCornerCoords[0]);
215 VecSubtract(x30, vCornerCoords[3], vCornerCoords[0]);
216 VecCross(n, x10, x20);
217
218 return (1./6.) * fabs ( VecDot(n, x30) );
219}
220
223
234template <>
236{
237 MathVector<3> x20, x31, x40, n;
238
239 VecSubtract(x20, vCornerCoords[2], vCornerCoords[0]);
240 VecSubtract(x31, vCornerCoords[3], vCornerCoords[1]);
241 VecSubtract(x40, vCornerCoords[4], vCornerCoords[0]);
242 VecCross(n, x20, x31);
243
244 return (1./6.) * VecDot(n, x40);
245}
246
249
259template <>
261{
262 MathVector<3> x40, x13, x10, x20, x50, m, n;
263
264 VecSubtract(x40, vCornerCoords[4], vCornerCoords[0]);
265 VecSubtract(x13, vCornerCoords[1], vCornerCoords[3]);
266 VecSubtract(x10, vCornerCoords[1], vCornerCoords[0]);
267 VecSubtract(x20, vCornerCoords[2], vCornerCoords[0]);
268
269 // height for both subelements
270 VecSubtract(x50, vCornerCoords[5], vCornerCoords[0]);
271
272 VecCross(m, x40, x13); // base of pyramid
273 VecCross(n, x10, x20); // base of tetrahedron
274
275 // n = n + m
276 VecAppend(n, m);
277
278 return (1./6.) * VecDot(n, x50);
279}
280
283
294template <>
296{
297 MathVector<3> x50, x14, x10, x20, x60, m1, n1;
298 MathVector<3> x24, x30, x70, m2, n2;
299
300 // 1. prism
301 VecSubtract(x50, vCornerCoords[5], vCornerCoords[0]);
302 VecSubtract(x14, vCornerCoords[1], vCornerCoords[4]);
303 VecSubtract(x10, vCornerCoords[1], vCornerCoords[0]);
304 VecSubtract(x20, vCornerCoords[2], vCornerCoords[0]);
305 VecSubtract(x60, vCornerCoords[6], vCornerCoords[0]);
306
307 VecCross(m1, x50, x14); // base of pyramid
308 VecCross(n1, x10, x20); // base of tetrahedron
309
310 // n1 = n1 + m1
311 VecAppend(n1, m1);
312
313 // 2. prism
314 //VecSubtract(x60, vCornerCoords[6], vCornerCoords[0]);
315 VecSubtract(x24, vCornerCoords[2], vCornerCoords[4]);
316 //VecSubtract(x20, vCornerCoords[2], vCornerCoords[0]);
317 VecSubtract(x30, vCornerCoords[3], vCornerCoords[0]);
318 VecSubtract(x70, vCornerCoords[7], vCornerCoords[0]);
319
320 VecCross(m2, x60, x24); // base of pyramid
321 VecCross(n2, x20, x30); // base of tetrahedron
322
323 // n2 = n2 + m2
324 VecAppend(n2, m2);
325
326 return (1./6.) * (VecDot(n1, x60) + VecDot(n2, x70));
327}
328
331
344template <>
346{
347 MathVector<3> x31, x42, x51, n;
348 MathVector<3> x01;
349
350 VecSubtract(x31, vCornerCoords[3], vCornerCoords[1]);
351 VecSubtract(x42, vCornerCoords[4], vCornerCoords[2]);
352 VecSubtract(x51, vCornerCoords[5], vCornerCoords[1]);
353 VecCross(n, x31, x42);
354
355 //VecSubtract(x31, vCornerCoords[3], vCornerCoords[1]);
356 //VecSubtract(x42, vCornerCoords[4], vCornerCoords[2]);
357 VecSubtract(x01, vCornerCoords[0], vCornerCoords[1]);
358 //VecCross(n, x31, x42);
359
360 number volTopPyr = (1./6.) * fabs(VecDot(n, x51));
361 number volBottomPyr = (1./6.) * fabs(VecDot(n, x01));
362
363 return volTopPyr + volBottomPyr;
364}
365
367// run-time size of element
369
370template <int dim>
371inline number ElementSize(ReferenceObjectID roid, const MathVector<dim>* vCornerCoords);
372
373template <>
374inline number ElementSize<1>(ReferenceObjectID roid, const MathVector<1>* vCornerCoords)
375{
376 switch(roid)
377 {
378 case ROID_VERTEX: return 1.0;
379 case ROID_EDGE: return ElementSize<ReferenceEdge, 1>(vCornerCoords);
380 default: UG_THROW("ReferenceObject "<<roid<<" not found in dim 1.");
381 }
382}
383
384template <>
385inline number ElementSize<2>(ReferenceObjectID roid, const MathVector<2>* vCornerCoords)
386{
387 switch(roid)
388 {
389 case ROID_VERTEX: return 1.0;
390 case ROID_EDGE: return ElementSize<ReferenceEdge, 2>(vCornerCoords);
391 case ROID_TRIANGLE: return ElementSize<ReferenceTriangle, 2>(vCornerCoords);
393 default: UG_THROW("ReferenceObject "<<roid<<" not found in dim 2.");
394 }
395}
396
397template <>
398inline number ElementSize<3>(ReferenceObjectID roid, const MathVector<3>* vCornerCoords)
399{
400 switch(roid)
401 {
402 case ROID_VERTEX: return 1.0;
403 case ROID_EDGE: return ElementSize<ReferenceEdge, 3>(vCornerCoords);
404 case ROID_TRIANGLE: return ElementSize<ReferenceTriangle, 3>(vCornerCoords);
406 case ROID_TETRAHEDRON: return ElementSize<ReferenceTetrahedron, 3>(vCornerCoords);
407 case ROID_PYRAMID: return ElementSize<ReferencePyramid, 3>(vCornerCoords);
408 case ROID_PRISM: return ElementSize<ReferencePrism, 3>(vCornerCoords);
409 case ROID_HEXAHEDRON: return ElementSize<ReferenceHexahedron, 3>(vCornerCoords);
410 case ROID_OCTAHEDRON: return ElementSize<ReferenceOctahedron, 3>(vCornerCoords);
411 default: UG_THROW("ReferenceObject "<<roid<<" not found in dim 3.");
412 }
413}
414
417// Normals on Elements
420
423template <typename TRefElem, int TWorldDim>
424inline void ElementNormal(MathVector<TWorldDim>& normalOut, const MathVector<TWorldDim>* vCornerCoords);
425
428
435template <>
436inline void ElementNormal<ReferenceVertex, 1>(MathVector<1>& normalOut, const MathVector<1>* vCornerCoords)
437{
438 normalOut[0] = 1.0;
439}
440
443
453template <>
454inline void ElementNormal<ReferenceVertex, 2>(MathVector<2>& normalOut, const MathVector<2>* vCornerCoords)
455{
456 try
457 {
458 normalOut = vCornerCoords[0];
459 normalOut -= vCornerCoords[1];
460 VecNormalize(normalOut, normalOut);
461 }
462 UG_CATCH_THROW("Element normal can not be computed. Maybe there are not enough vertices to work on.")
463}
464
467
477template <>
478inline void ElementNormal<ReferenceVertex, 3>(MathVector<3>& normalOut, const MathVector<3>* vCornerCoords)
479{
480 try
481 {
482 normalOut = vCornerCoords[0];
483 normalOut -= vCornerCoords[1];
484 VecNormalize(normalOut, normalOut);
485 }
486 UG_CATCH_THROW("Element normal can not be computed. Maybe there are not enough vertices to work on.")
487}
488
491
499template <>
500inline void ElementNormal<ReferenceEdge, 2>(MathVector<2>& normalOut, const MathVector<2>* vCornerCoords)
501{
502 MathVector<2> diff(vCornerCoords[1]);
503 diff -= vCornerCoords[0];
504
505 normalOut[0] = diff[1];
506 normalOut[1] = -diff[0];
507}
508
511
523template <>
524inline void ElementNormal<ReferenceEdge, 3>(MathVector<3>& normalOut, const MathVector<3>* vCornerCoords)
525{
526 try
527 {
528 // normal on triangle
529 MathVector<3> edge0, edge1;
530 VecSubtract(edge0, vCornerCoords[1], vCornerCoords[0]);
531 VecSubtract(edge1, vCornerCoords[2], vCornerCoords[1]);
532 VecCross(normalOut, edge0, edge1);
533 // normal an edge is edge x normal on triangle
534 VecCross(normalOut, edge0, normalOut);
535 // scale
536 VecNormalize(normalOut, normalOut);
537 VecScale(normalOut, normalOut, VecTwoNorm(edge0));
538 }
539 UG_CATCH_THROW("Element normal can not be computed. Maybe there are not enough vertices to work on.")
540}
541
544
555template <>
556inline void ElementNormal<ReferenceTriangle, 3>(MathVector<3>& normalOut, const MathVector<3>* vCornerCoords)
557{
558 MathVector<3> a, b;
559 VecSubtract(a, vCornerCoords[1], vCornerCoords[0]);
560 VecSubtract(b, vCornerCoords[2], vCornerCoords[0]);
561 VecCross(normalOut, a,b);
562 VecScale(normalOut, normalOut, 0.5);
563}
564
567
578template <>
579inline void ElementNormal<ReferenceQuadrilateral, 3>(MathVector<3>& normalOut, const MathVector<3>* vCornerCoords)
580{
581 MathVector<3> a, b;
582 VecSubtract(a, vCornerCoords[2], vCornerCoords[0]);
583 VecSubtract(b, vCornerCoords[3], vCornerCoords[1]);
584 VecCross(normalOut, a,b);
585 VecScale(normalOut, normalOut, 0.5);
586}
587
589// run-time normal of element
591
592template <int dim>
593inline void ElementNormal(ReferenceObjectID roid, MathVector<dim>& normalOut, const MathVector<dim>* vCornerCoords);
594
595template <>
596inline void ElementNormal<1>(ReferenceObjectID roid, MathVector<1>& normalOut, const MathVector<1>* vCornerCoords)
597{
598 switch(roid)
599 {
600 case ROID_VERTEX: ElementNormal<ReferenceVertex, 1>(normalOut, vCornerCoords); return;
601 default: UG_THROW("ReferenceObject "<<roid<<" not found in dim 1.");
602 }
603}
604
605template <>
606inline void ElementNormal<2>(ReferenceObjectID roid, MathVector<2>& normalOut, const MathVector<2>* vCornerCoords)
607{
608 switch(roid)
609 {
610 case ROID_VERTEX: ElementNormal<ReferenceVertex, 2>(normalOut, vCornerCoords); return;
611 case ROID_EDGE: ElementNormal<ReferenceEdge, 2>(normalOut, vCornerCoords); return;
612 default: UG_THROW("ReferenceObject "<<roid<<" not found in dim 2.");
613 }
614}
615
616template <>
617inline void ElementNormal<3>(ReferenceObjectID roid, MathVector<3>& normalOut, const MathVector<3>* vCornerCoords)
618{
619 switch(roid)
620 {
621 case ROID_VERTEX: ElementNormal<ReferenceVertex, 3>(normalOut, vCornerCoords); return;
622 case ROID_EDGE: ElementNormal<ReferenceEdge, 3>(normalOut, vCornerCoords); return;
623 case ROID_TRIANGLE: ElementNormal<ReferenceTriangle, 3>(normalOut, vCornerCoords); return;
624 case ROID_QUADRILATERAL: ElementNormal<ReferenceQuadrilateral, 3>(normalOut, vCornerCoords); return;
625 default: UG_THROW("ReferenceObject "<<roid<<" not found in dim 3.");
626 }
627}
628
631
641template <typename TRefElem, int TWorldDim>
642inline void SideNormal(MathVector<TWorldDim>& normalOut, int side, const MathVector<TWorldDim>* vCornerCoords)
643{
644 static const int dim = (int) TRefElem::dim;
645 static const int maxSideCorners = element_list_traits<typename domain_traits<dim-1>::DimElemList>::maxCorners;
646
647// Get own reference element and the side roid:
648 TRefElem & rRefElem = (TRefElem&) ReferenceElementProvider::get(TRefElem::REFERENCE_OBJECT_ID);
649 ReferenceObjectID sideRoid = rRefElem.roid(dim-1,side);
650
651// Get the coordinates of the vertices:
652 MathVector<TWorldDim> vSideCorner [(dim == TWorldDim)? maxSideCorners : maxSideCorners + 1];
653 size_t numSideCorners = rRefElem.num(dim-1, side, 0);
654 for (size_t co = 0; co < numSideCorners; ++co)
655 vSideCorner[co] = vCornerCoords[rRefElem.id(dim-1, side, 0, co)];
656 // we need another point if dim != TWorldDim:
657 // take the highest-numbered corner of the next side, since
658 // it is always different from the other points (is it not?)
659 if (dim != TWorldDim)
660 {
661 vSideCorner[numSideCorners] =
662 vCornerCoords[rRefElem.id(dim-1, (side+1)%rRefElem.num(dim-1), 0,
663 rRefElem.num(dim-1, (side+1)%rRefElem.num(dim-1), 0)-1)];
664 }
665
666// Get the normal:
667 ElementNormal<TWorldDim>(sideRoid, normalOut, vSideCorner);
668// Note: We assume that the for the standard ordering, the last line computes
669// the outer normal.
670}
671
673template <int dim>
674inline void SideNormal(ReferenceObjectID roid, MathVector<dim>& normalOut, int side, const MathVector<dim>* vCornerCoords);
675
676template <>
677inline void SideNormal<1>(ReferenceObjectID roid, MathVector<1>& normalOut, int side, const MathVector<1>* vCornerCoords)
678{
679 switch(roid)
680 {
681 case ROID_EDGE: SideNormal<ReferenceEdge,1>(normalOut, side, vCornerCoords); return;
682 default: UG_THROW("ReferenceObject "<<roid<<" not found in dim 1.");
683 }
684}
685
686template <>
687inline void SideNormal<2>(ReferenceObjectID roid, MathVector<2>& normalOut, int side, const MathVector<2>* vCornerCoords)
688{
689 switch(roid)
690 {
691 case ROID_EDGE: SideNormal<ReferenceEdge,2>(normalOut, side, vCornerCoords); return;
692 case ROID_TRIANGLE: SideNormal<ReferenceTriangle,2>(normalOut, side, vCornerCoords); return;
693 case ROID_QUADRILATERAL: SideNormal<ReferenceQuadrilateral,2>(normalOut, side, vCornerCoords); return;
694 default: UG_THROW("ReferenceObject "<<roid<<" not found in dim 2.");
695 }
696}
697
698template <>
699inline void SideNormal<3>(ReferenceObjectID roid, MathVector<3>& normalOut, int side, const MathVector<3>* vCornerCoords)
700{
701 switch(roid)
702 {
703 case ROID_EDGE: SideNormal<ReferenceEdge,3>(normalOut, side, vCornerCoords); return;
704 case ROID_TRIANGLE: SideNormal<ReferenceTriangle,3>(normalOut, side, vCornerCoords); return;
705 case ROID_QUADRILATERAL: SideNormal<ReferenceQuadrilateral,3>(normalOut, side, vCornerCoords); return;
706 case ROID_TETRAHEDRON: SideNormal<ReferenceTetrahedron,3>(normalOut, side, vCornerCoords); return;
707 case ROID_PYRAMID: SideNormal<ReferencePyramid,3>(normalOut, side, vCornerCoords); return;
708 case ROID_PRISM: SideNormal<ReferencePrism,3>(normalOut, side, vCornerCoords); return;
709 case ROID_HEXAHEDRON: SideNormal<ReferenceHexahedron,3>(normalOut, side, vCornerCoords); return;
710 case ROID_OCTAHEDRON: SideNormal<ReferenceOctahedron,3>(normalOut, side, vCornerCoords); return;
711 default: UG_THROW("ReferenceObject "<<roid<<" not found in dim 3.");
712 }
713}
714
717// ElementSideRayIntersection
720
721// wrapper class to distinguish reference dimesion
722template <typename TRefElem, int TWorldDim, int TRefDim = TRefElem::dim>
724{
725 static bool apply( size_t& sideOut,
726 MathVector<TWorldDim>& GlobalIntersectionPointOut,
727 MathVector<TRefElem::dim>& LocalIntersectionPoint,
728 const MathVector<TWorldDim>& From, const MathVector<TWorldDim>& Direction,
729 bool bPositiv, const MathVector<TWorldDim>* vCornerCoords)
730 {
731 UG_THROW("Not implemented.");
732 return false;
733 }
734};
735
736// specialization for 2d
737template <typename TRefElem>
739{
740 static bool apply( size_t& sideOut,
741 MathVector<2>& GlobalIntersectionPointOut,
742 MathVector<TRefElem::dim>& LocalIntersectionPoint,
743 const MathVector<2>& From, const MathVector<2>& Direction,
744 bool bPositiv, const MathVector<2>* vCornerCoords)
745 {
746 static const TRefElem& rRefElem = Provider<TRefElem>::get();
747
748 // reference dimension
749 const int dim = TRefElem::dim;
750
751 // parameters
752 number bc = 0., t = 0.;
753 size_t p0 = 0, p1 = 0;
754
755 // find side
756 for(sideOut = 0; sideOut < rRefElem.num(dim-1); ++sideOut)
757 {
758 // get corners
759 p0 = rRefElem.id(dim-1, sideOut, 0, 0);
760 p1 = rRefElem.id(dim-1, sideOut, 0, 1);
761
762 // if match: break
763 if(RayLineIntersection2d( GlobalIntersectionPointOut, bc, t,
764 vCornerCoords[p0], vCornerCoords[p1],
765 From, Direction))
766 {
767 if(bPositiv && t >= 0.0) break;
768 else if(!bPositiv && t <= 0.0) break;
769 }
770 }
771 // if not found
772 if(sideOut >= rRefElem.num(dim-1))
773 UG_THROW("ElementSideRayIntersection: no cut side found.");
774
775 // Compute local intersection
776 VecScaleAdd(LocalIntersectionPoint, bc, rRefElem.corner(p1), 1.-bc, rRefElem.corner(p0));
777
778 // true if found
779 return true;
780 }
781};
782
783// specialization for 3d
784template <typename TRefElem>
786{
787 static bool apply( size_t& sideOut,
788 MathVector<3>& GlobalIntersectionPointOut,
789 MathVector<TRefElem::dim>& LocalIntersectionPoint,
790 const MathVector<3>& From, const MathVector<3>& Direction,
791 bool bPositiv, const MathVector<3>* vCornerCoords)
792 {
793 static const TRefElem& rRefElem = Provider<TRefElem>::get();
794
795 // reference dimension
796 const int dim = TRefElem::dim;
797
798 // parameters
799 number bc0 = 0., bc1 = 0., t = 0.;
800 size_t p0 = 0, p1 = 0, p2 = 0;
801
802 // find side
803 for(sideOut = 0; sideOut < rRefElem.num(dim-1); ++sideOut)
804 {
805 // get corners
806 p0 = rRefElem.id(dim-1, sideOut, 0, 0);
807 p1 = rRefElem.id(dim-1, sideOut, 0, 1);
808 p2 = rRefElem.id(dim-1, sideOut, 0, 2);
809
810 // if match: break
811 if(RayTriangleIntersection( GlobalIntersectionPointOut, bc0, bc1, t,
812 vCornerCoords[p0], vCornerCoords[p1], vCornerCoords[p2],
813 From, Direction))
814 {
815 if(bPositiv && t >= 0.0) break;
816 else if(!bPositiv && t <= 0.0) break;
817 }
818
819 // second triangle (only if 4 corners)
820 if(rRefElem.num(dim-1, sideOut, 0) == 3) continue;
821
822 // get corner number 4
823 p1 = rRefElem.id(dim-1, sideOut, 0, 3);
824
825 // if match: break
826 if(RayTriangleIntersection( GlobalIntersectionPointOut, bc0, bc1, t,
827 vCornerCoords[p0], vCornerCoords[p1], vCornerCoords[p2],
828 From, Direction))
829 {
830 if(bPositiv && t >= 0.0) break;
831 else if(!bPositiv && t <= 0.0) break;
832 }
833 }
834
835 // if not found
836 if(sideOut >= rRefElem.num(dim-1))
837 UG_THROW("ElementSideRayIntersection: no cut side found.");
838
839 // Compute local intersection
840 VecScaleAdd(LocalIntersectionPoint,
841 (1.-bc0-bc1), rRefElem.corner(p0),
842 bc0, rRefElem.corner(p1),
843 bc1, rRefElem.corner(p2));
844
845 // true if found
846 return true;
847 }
848};
849
850
853
869template <typename TRefElem, int TWorldDim>
870bool ElementSideRayIntersection( size_t& sideOut,
871 MathVector<TWorldDim>& GlobalIntersectionPointOut,
872 MathVector<TRefElem::dim>& LocalIntersectionPoint,
873 const MathVector<TWorldDim>& From, const MathVector<TWorldDim>& Direction,
874 bool bPositiv, const MathVector<TWorldDim>* vCornerCoords)
875{
876 UG_ASSERT(VecTwoNorm(Direction) > 0, "Direction must be non-zero vector.");
878 apply(sideOut, GlobalIntersectionPointOut, LocalIntersectionPoint,
879 From, Direction, bPositiv, vCornerCoords);
880}
881
882
885// ElementSideRayIntersection
888
889// wrapper class to distinguish reference dimesion
890template <int TDim, int TWorldDim>
892{
893 static bool apply( size_t& sideOut, number& bc,
894 MathVector<TWorldDim>& GlobalIntersectionPointOut,
895 MathVector<TDim>& LocalIntersectionPoint,
896 const MathVector<TWorldDim>& From, const MathVector<TWorldDim>& Direction,
897 bool bPositiv, const MathVector<TWorldDim>* vCornerCoords)
898 {
899 UG_THROW("Not implemented.");
900 return false;
901 }
902};
903
904// specialization for 2d
905template <>
907{
908 static bool apply( size_t& sideOut, number& bc,
909 MathVector<2>& GlobalIntersectionPointOut,
910 MathVector<2>& LocalIntersectionPoint,
911 const MathVector<2>& From, const MathVector<2>& Direction,
912 bool bPositiv, const MathVector<2>* vCornerCoords)
913 {
915
916 // reference dimension
917 static const int dim = 2;
918
919 // parameters
920 bc = 0.;
921 number t = 0.;
922 size_t p0 = 0, p1 = 0;
923
924 // find side
925 for(sideOut = 0; sideOut < rRefElem.num(0); ++sideOut)
926 {
927 // get corners
928 p0 = rRefElem.id(dim-1, sideOut, 0, 0);
929 p1 = rRefElem.id(dim-1, sideOut, 0, 1);
930
931 // if match: break
932 if(RayLineIntersection2d( GlobalIntersectionPointOut, bc, t,
933 vCornerCoords[p0], vCornerCoords[p1],
934 From, Direction))
935 {
936 // skip if one root-point scvf
937 if(fabs(t) <= std::numeric_limits<number>::epsilon() * 10)
938 continue;
939
940 // upwind / downwind switch
941 if(bPositiv && t >= 0.0) break;
942 else if(!bPositiv && t <= 0.0) break;
943 }
944 }
945
946 // if not found
947 if(sideOut >= rRefElem.num(0))
948 UG_THROW("Side not found.");
949
950 // Compute local intersection
951 VecScaleAdd(LocalIntersectionPoint, bc, rRefElem.corner(p1), 1.-bc, rRefElem.corner(p0));
952
953 // parameter of intersection should loop always from center to edgeMidpoint
954 // thus, for side 2 this is correct, but for side 1 we have to invert direction
955 if(sideOut == 1) bc = 1. - bc;
956
957 // true if found on scvf
958 if(sideOut == 1 || sideOut == 2) return true;
959 // false if found on element corner
960 else return false;
961 }
962};
963
965// SCVFofSCVRayIntersection
986template <int TDim, int TWorldDim>
987bool SCVFofSCVRayIntersection( size_t& sideOut, number& bc,
988 MathVector<TWorldDim>& GlobalIntersectionPointOut,
989 MathVector<TDim>& LocalIntersectionPoint,
990 const MathVector<TWorldDim>& Root, const MathVector<TWorldDim>& Direction,
991 bool bPositiv, const MathVector<TWorldDim>* vCornerCoords)
992{
993 UG_ASSERT(VecTwoNorm(Direction) > 0, "Direction must be non-zero vector.");
995 apply(sideOut, bc, GlobalIntersectionPointOut, LocalIntersectionPoint,
996 Root, Direction, bPositiv, vCornerCoords);
997}
998
999
1000
1004
1005
1006template <typename TVector>
1007inline void ComputeElementExtensionsSqForEdges(const TVector* vCornerCoords, TVector &ext)
1008{
1009 VecElemProd(ext, vCornerCoords[0], vCornerCoords[1]);
1010}
1011
1012
1013template <int TWorldDim, int ncorners>
1015{
1016 // compute center
1017 MathVector<TWorldDim> mid = 0.0;
1018 for (int i=ncorners-1; i>=0; --i){
1019 VecAppend(mid, vCornerCoords[i]);
1020 }
1021 VecScale(mid, mid, 1.0/ncorners);
1022
1023 // compute
1024 ext = 0.0;
1026 for (int i=ncorners-1; i>=0; --i){
1027 VecSubtract(aux, mid, vCornerCoords[i]);
1028 VecElemProd(aux, aux, aux);
1029 VecAppend(ext, aux);
1030 }
1031 VecScale(ext, ext, 1.0/ncorners);
1032}
1033
1035// extensions of an element
1037
1038
1039template <int dim>
1040inline void ElementExtensionsSq(ReferenceObjectID roid, MathVector<dim>& ext, const MathVector<dim>* vCornerCoords);
1041
1042template <>
1043inline void ElementExtensionsSq<1>(ReferenceObjectID roid, MathVector<1>& ext, const MathVector<1>* vCornerCoords)
1044{
1045 switch(roid)
1046 {
1047 case ROID_VERTEX: ext = 0; return;
1048 case ROID_EDGE: ComputeElementExtensionsSqForEdges(vCornerCoords,ext); return;
1049 default: UG_THROW("ReferenceObject "<<roid<<" not found in dim 1.");
1050 }
1051}
1052
1053template <>
1054inline void ElementExtensionsSq<2>(ReferenceObjectID roid, MathVector<2>& ext, const MathVector<2>* vCornerCoords)
1055{
1056 switch(roid)
1057 {
1058 case ROID_VERTEX: ext = 0; return;
1059 case ROID_EDGE: ComputeElementExtensionsSqForEdges(vCornerCoords,ext); return;
1060 case ROID_TRIANGLE: ComputeElementExtensionsSq<2,3>(vCornerCoords,ext); return;
1061 case ROID_QUADRILATERAL: ComputeElementExtensionsSq<2,4>(vCornerCoords,ext); return;
1062 default: UG_THROW("ReferenceObject "<<roid<<" not found in dim 2.");
1063 }
1064}
1065
1066template <>
1067inline void ElementExtensionsSq<3>(ReferenceObjectID roid, MathVector<3>& ext, const MathVector<3>* vCornerCoords)
1068{
1069 switch(roid)
1070 {
1071 case ROID_VERTEX: ext = 0; return;
1072 case ROID_EDGE: ComputeElementExtensionsSqForEdges(vCornerCoords,ext); return;
1073 case ROID_TRIANGLE: ComputeElementExtensionsSq<3,3>(vCornerCoords,ext); return;
1074 case ROID_QUADRILATERAL: ComputeElementExtensionsSq<3,4>(vCornerCoords,ext); return;
1075 case ROID_TETRAHEDRON: ComputeElementExtensionsSq<3,4>(vCornerCoords,ext); return;
1076 case ROID_PYRAMID: ComputeElementExtensionsSq<3,5>(vCornerCoords,ext); return;
1077 case ROID_PRISM: ComputeElementExtensionsSq<3,6>(vCornerCoords,ext); return;
1078 case ROID_HEXAHEDRON: ComputeElementExtensionsSq<3,8>(vCornerCoords,ext); return;
1079 case ROID_OCTAHEDRON: ComputeElementExtensionsSq<3,6>(vCornerCoords,ext); return;
1080 default: UG_THROW("ReferenceObject "<<roid<<" not found in dim 3.");
1081 }
1082}
1083
1084
1085} // end namespace ug
1086
1087#endif /* __H__UG__LIB_DISC__COMMON__GEOMETRY_UTIL__ */
const MathVector< dim > & corner(size_t i) const
coordinates of reference corner (i = 0 ... num(0))
Definition reference_element.h:192
a mathematical Vector with N entries.
Definition math_vector.h:97
static TClass & get()
returns a singleton based on the identifier
Definition provider.h:54
size_t num(int dim) const
returns the number of geometric objects of dim
Definition reference_element.h:95
ReferenceObjectID roid() const
returns the reference object id
Definition reference_element.h:76
int id(int dim_i, size_t i, int dim_j, size_t j) const
id of object j in dimension dim_j of obj i in dimension dim_i
Definition reference_element.h:127
static const DimReferenceElement< dim > & get(ReferenceObjectID roid)
returns a dimension dependent Reference Element
Definition reference_element.h:280
Definition reference_element.h:445
Class for computing integral properties of geometric objects types in lists.
Definition element_list_traits.h:60
#define UG_ASSERT(expr, msg)
Definition assert.h:70
#define UG_CATCH_THROW(msg)
Definition error.h:64
#define UG_THROW(msg)
Definition error.h:57
double number
Definition types.h:124
bool RayLineIntersection2d(vector_t &vOut, number &bcOut, number &tOut, const vector_t &p0, const vector_t &p1, const vector_t &vFrom, const vector_t &vDir, number sml=0)
calculates the intersection of a ray with a Line in 2d
Definition math_util_impl.hpp:428
bool RayTriangleIntersection(vector_t &vOut, number &bc1Out, number &bc2Out, number &tOut, const vector_t &p0, const vector_t &p1, const vector_t &p2, const vector_t &vFrom, const vector_t &vDir, const number small=SMALL)
calculates the intersection of a ray with a triangle
Definition math_util_impl.hpp:506
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
void VecNormalize(vector_t &vOut, const vector_t &v)
scales a vector_t to unit length
Definition math_vector_functions_common_impl.hpp:501
void VecSubtract(vector_t &vOut, const vector_t &v1, const vector_t &v2)
subtracts v2 from v1 and stores the result in a vOut
Definition math_vector_functions_common_impl.hpp:226
void VecAppend(vector_t &vOut, const vector_t &v1)
adds a MathVector<N> to a second one
Definition math_vector_functions_common_impl.hpp:72
vector_t::value_type VecDistance(const vector_t &v1, const vector_t &v2)
returns the distance of two vector_ts.
Definition math_vector_functions_common_impl.hpp:375
void VecScale(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
scales a MathVector<N>
Definition math_vector_functions_common_impl.hpp:252
vector_t::value_type VecTwoNorm(const vector_t &v)
Definition math_vector_functions_common_impl.hpp:577
void VecCross(vector_t &vOut, const vector_t &v1, const vector_t &v2)
calculates the cross product of two Vectors of dimension 3. It makes no sense to use VecCross for vec...
Definition math_vector_functions_common_impl.hpp:437
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
returns the dot-product of two vector_ts
Definition math_vector_functions_common_impl.hpp:385
the ug namespace
void SideNormal< 1 >(ReferenceObjectID roid, MathVector< 1 > &normalOut, int side, const MathVector< 1 > *vCornerCoords)
Definition geometry_util.h:677
number ElementSize< ReferenceQuadrilateral, 3 >(const MathVector< 3 > *vCornerCoords)
Volume of a Quadrilateral in 3d.
Definition geometry_util.h:176
void SideNormal(MathVector< TWorldDim > &normalOut, int side, const MathVector< TWorldDim > *vCornerCoords)
Normal to a side of an Element in a given Dimension.
Definition geometry_util.h:642
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
void ElementNormal< 1 >(ReferenceObjectID roid, MathVector< 1 > &normalOut, const MathVector< 1 > *vCornerCoords)
Definition geometry_util.h:596
number ElementSize< 1 >(ReferenceObjectID roid, const MathVector< 1 > *vCornerCoords)
Definition geometry_util.h:374
number ElementSize< 3 >(ReferenceObjectID roid, const MathVector< 3 > *vCornerCoords)
Definition geometry_util.h:398
void ElementNormal< ReferenceQuadrilateral, 3 >(MathVector< 3 > &normalOut, const MathVector< 3 > *vCornerCoords)
Normal to a Quadrilateral in 3d.
Definition geometry_util.h:579
number ElementSize< ReferencePyramid, 3 >(const MathVector< 3 > *vCornerCoords)
Volume of a Pyramid in 3d.
Definition geometry_util.h:235
number ElementSize< ReferenceEdge, 1 >(const MathVector< 1 > *vCornerCoords)
Volume of a Line in 1d.
Definition geometry_util.h:67
number ElementSize< ReferenceTetrahedron, 3 >(const MathVector< 3 > *vCornerCoords)
Volume of a Tetrahedron in 3d.
Definition geometry_util.h:209
void ElementNormal(MathVector< TWorldDim > &normalOut, const MathVector< TWorldDim > *vCornerCoords)
Normal to an Element in a given Dimension.
void ElementNormal< ReferenceTriangle, 3 >(MathVector< 3 > &normalOut, const MathVector< 3 > *vCornerCoords)
Normal to a Triangle in 3d.
Definition geometry_util.h:556
void SideNormal< 3 >(ReferenceObjectID roid, MathVector< 3 > &normalOut, int side, const MathVector< 3 > *vCornerCoords)
Definition geometry_util.h:699
number ElementSize< ReferenceEdge, 2 >(const MathVector< 2 > *vCornerCoords)
Volume of a Line in 2d.
Definition geometry_util.h:81
number ElementSize< 2 >(ReferenceObjectID roid, const MathVector< 2 > *vCornerCoords)
Definition geometry_util.h:385
void ElementNormal< 3 >(ReferenceObjectID roid, MathVector< 3 > &normalOut, const MathVector< 3 > *vCornerCoords)
Definition geometry_util.h:617
number ElementSize< ReferenceOctahedron, 3 >(const MathVector< 3 > *vCornerCoords)
Volume of an Octahedron in 3d.
Definition geometry_util.h:345
void ComputeElementExtensionsSq(const MathVector< TWorldDim > *vCornerCoords, MathVector< TWorldDim > &ext)
Definition geometry_util.h:1014
number ElementSize< ReferenceTriangle, 2 >(const MathVector< 2 > *vCornerCoords)
Volume of a Triangle in 2d.
Definition geometry_util.h:118
bool SCVFofSCVRayIntersection(size_t &sideOut, number &bc, MathVector< TWorldDim > &GlobalIntersectionPointOut, MathVector< TDim > &LocalIntersectionPoint, const MathVector< TWorldDim > &Root, const MathVector< TWorldDim > &Direction, bool bPositiv, const MathVector< TWorldDim > *vCornerCoords)
Definition geometry_util.h:987
void ElementExtensionsSq< 1 >(ReferenceObjectID roid, MathVector< 1 > &ext, const MathVector< 1 > *vCornerCoords)
Definition geometry_util.h:1043
void ElementNormal< ReferenceEdge, 2 >(MathVector< 2 > &normalOut, const MathVector< 2 > *vCornerCoords)
Normal to a Line in 2d.
Definition geometry_util.h:500
void ElementExtensionsSq(ReferenceObjectID roid, MathVector< dim > &ext, const MathVector< dim > *vCornerCoords)
number ElementSize< ReferenceHexahedron, 3 >(const MathVector< 3 > *vCornerCoords)
Volume of a Hexahedron in 3d.
Definition geometry_util.h:295
number ElementSize< ReferenceTriangle, 3 >(const MathVector< 3 > *vCornerCoords)
Volume of a Triangle in 3d.
Definition geometry_util.h:135
void ElementNormal< ReferenceEdge, 3 >(MathVector< 3 > &normalOut, const MathVector< 3 > *vCornerCoords)
Normal to a Line in 3d.
Definition geometry_util.h:524
void ElementNormal< ReferenceVertex, 2 >(MathVector< 2 > &normalOut, const MathVector< 2 > *vCornerCoords)
Normal to a Point in 2d.
Definition geometry_util.h:454
number ElementSize< ReferencePrism, 3 >(const MathVector< 3 > *vCornerCoords)
Volume of a Prism in 3d.
Definition geometry_util.h:260
void ElementNormal< ReferenceVertex, 1 >(MathVector< 1 > &normalOut, const MathVector< 1 > *vCornerCoords)
Normal to a Point in 1d.
Definition geometry_util.h:436
number ElementSize< ReferenceQuadrilateral, 2 >(const MathVector< 2 > *vCornerCoords)
Volume of a Quadrilateral in 2d.
Definition geometry_util.h:157
number ElementSize< ReferenceEdge, 3 >(const MathVector< 3 > *vCornerCoords)
Volume of a Line in 3d.
Definition geometry_util.h:95
void ElementNormal< ReferenceVertex, 3 >(MathVector< 3 > &normalOut, const MathVector< 3 > *vCornerCoords)
Normal to a Point in 3d.
Definition geometry_util.h:478
void SideNormal< 2 >(ReferenceObjectID roid, MathVector< 2 > &normalOut, int side, const MathVector< 2 > *vCornerCoords)
Definition geometry_util.h:687
void ElementExtensionsSq< 3 >(ReferenceObjectID roid, MathVector< 3 > &ext, const MathVector< 3 > *vCornerCoords)
Definition geometry_util.h:1067
void ComputeElementExtensionsSqForEdges(const TVector *vCornerCoords, TVector &ext)
Extension of an element (in a given dimension)
Definition geometry_util.h:1007
void VecElemProd(vector_t &vOut, const vector_t &v1, const vector_t &v2)
component-wise product: vOut_i = v1_i*v2_i
Definition math_vector_functions_common_impl.hpp:651
void ElementNormal< 2 >(ReferenceObjectID roid, MathVector< 2 > &normalOut, const MathVector< 2 > *vCornerCoords)
Definition geometry_util.h:606
bool ElementSideRayIntersection(size_t &sideOut, MathVector< TWorldDim > &GlobalIntersectionPointOut, MathVector< TRefElem::dim > &LocalIntersectionPoint, const MathVector< TWorldDim > &From, const MathVector< TWorldDim > &Direction, bool bPositiv, const MathVector< TWorldDim > *vCornerCoords)
ElementSideRayIntersection.
Definition geometry_util.h:870
void ElementExtensionsSq< 2 >(ReferenceObjectID roid, MathVector< 2 > &ext, const MathVector< 2 > *vCornerCoords)
Definition geometry_util.h:1054
number ElementSize(const MathVector< TWorldDim > *vCornerCoords)
Volume of an Element in a given Dimension.
static bool apply(size_t &sideOut, MathVector< 2 > &GlobalIntersectionPointOut, MathVector< TRefElem::dim > &LocalIntersectionPoint, const MathVector< 2 > &From, const MathVector< 2 > &Direction, bool bPositiv, const MathVector< 2 > *vCornerCoords)
Definition geometry_util.h:740
static bool apply(size_t &sideOut, MathVector< 3 > &GlobalIntersectionPointOut, MathVector< TRefElem::dim > &LocalIntersectionPoint, const MathVector< 3 > &From, const MathVector< 3 > &Direction, bool bPositiv, const MathVector< 3 > *vCornerCoords)
Definition geometry_util.h:787
Definition geometry_util.h:724
static bool apply(size_t &sideOut, MathVector< TWorldDim > &GlobalIntersectionPointOut, MathVector< TRefElem::dim > &LocalIntersectionPoint, const MathVector< TWorldDim > &From, const MathVector< TWorldDim > &Direction, bool bPositiv, const MathVector< TWorldDim > *vCornerCoords)
Definition geometry_util.h:725
static bool apply(size_t &sideOut, number &bc, MathVector< 2 > &GlobalIntersectionPointOut, MathVector< 2 > &LocalIntersectionPoint, const MathVector< 2 > &From, const MathVector< 2 > &Direction, bool bPositiv, const MathVector< 2 > *vCornerCoords)
Definition geometry_util.h:908
Definition geometry_util.h:892
static bool apply(size_t &sideOut, number &bc, MathVector< TWorldDim > &GlobalIntersectionPointOut, MathVector< TDim > &LocalIntersectionPoint, const MathVector< TWorldDim > &From, const MathVector< TWorldDim > &Direction, bool bPositiv, const MathVector< TWorldDim > *vCornerCoords)
Definition geometry_util.h:893
Definition domain_traits.h:53