47 const typename GridType::ctype thickness,
const typename GridType::ctype innerRadius,
48 const typename GridType::ctype fromAngle,
const typename GridType::ctype toAngle,
49 size_t nElement,
bool closeRing,
bool quadrilateral =
false,
53 static_assert(GridType::dimension==2,
"makeRingSegment2D can only be called for 2-dimensional grids");
54 typedef typename GridType::ctype ctype;
57 if ( (-eps >= fromAngle) || (fromAngle > toAngle) || (toAngle > 2*M_PI) )
60 bool fullRing = closeRing && (fromAngle==0.0) && (toAngle == 2*M_PI);
70 ArcOfCircle innerArc(center, innerRadius, fromAngle, toAngle);
72 ctype step =1.0/((ctype) nElement);
75 for (
size_t i=0; i<nElement; i++)
82 ArcOfCircle outerArc(center, innerRadius+thickness, fromAngle, toAngle);
85 for (
size_t i=0; i<nElement; i++)
97 GeometryType gt = (quadrilateral) ? GeometryTypes::quadrilateral : GeometryTypes::triangle;
104 for (
size_t i=0; i<nElement; i++) {
107 cornerIDs[2] = i+nElement+2;
108 cornerIDs[3] = i+nElement+1;
113 for (
size_t i=0; i<nElement; i++) {
117 cornerIDs[2] = i+nElement+2;
121 cornerIDs[0] = nElement +i +1;
122 cornerIDs[1] = nElement +i +2;
132 for (
size_t i=0; i<nElement-1; i++) {
135 cornerIDs[2] = i+nElement+1;
136 cornerIDs[3] = i+nElement;
140 cornerIDs[1] = nElement-1;
141 cornerIDs[2] = nElement;
142 cornerIDs[3] = 2*nElement -1;
147 for (
size_t i=0; i<nElement-1; i++) {
151 cornerIDs[2] = i+nElement+1;
155 cornerIDs[0] = nElement +i;
156 cornerIDs[1] = nElement +i +1;
162 cornerIDs[1] = nElement-1;
163 cornerIDs[2] = nElement;
167 cornerIDs[0] = 2*nElement-1;
168 cornerIDs[1] = nElement;
169 cornerIDs[2] = nElement -1;
181 ctype angleDiff = toAngle-fromAngle;
183 for (
size_t i=0; i<nElement-1; i++) {
185 vertices[0] = i; vertices[1] = i+1;
187 SegmentPointer(
new ArcOfCircle(center, innerRadius, fromAngle+i*step*angleDiff,
188 fromAngle+(i+1)*step*angleDiff)));
190 vertices[0] = nElement+i+(!fullRing); vertices[1] = nElement +i+1+(!fullRing);
192 SegmentPointer(
new ArcOfCircle(center, innerRadius+thickness, fromAngle+i*step*angleDiff,
193 fromAngle+(i+1)*step*angleDiff)));
199 vertices[0] = nElement-1; vertices[1] = (!fullRing)*nElement;
201 SegmentPointer(
new ArcOfCircle(center, innerRadius, fromAngle+(nElement-1)*step*angleDiff,
204 vertices[0] = 2*nElement-1+(!fullRing); vertices[1] =nElement + (!fullRing)*(nElement+1);
206 SegmentPointer(
new ArcOfCircle(center, innerRadius+thickness, fromAngle+(nElement-1)*step*angleDiff,
220 size_t half = innerVert.
size()/2;
222 for (
size_t i=0; i<half; i++)
231 size_t half = outerVert.
size()/2;
233 for (
size_t i=0; i<half; i++)
234 outerVert[half+i] =
true;
270 const typename GridType::ctype thickness,
271 const typename GridType::ctype length,
272 const typename GridType::ctype innerRadius,
273 const typename GridType::ctype fromAngle,
274 const typename GridType::ctype toAngle,
unsigned int nElementRing,
275 unsigned int nElementLength,
bool closeTube,
unsigned int axis = 0,
276 bool tetrahedra =
true,
bool parametrizedBoundary =
true,
280 static_assert(GridType::dimension==3,
"makeTubeSegment3D can only be called for 3-dimensional grids");
281 typedef typename GridType::ctype ctype;
283 if (fromAngle >= toAngle)
286 bool fullTube = closeTube && (fromAngle==0.0) && (toAngle == 2*M_PI);
288 using namespace Dune;
296 unsigned int nRingNodes = nElementRing+!fullTube;
300 localCenter[0] = center[(axis+1)%3];
301 localCenter[1] = center[(axis+2)%3];
303 ArcOfCircle innerArc(localCenter, innerRadius, fromAngle, toAngle);
305 ctype stepRing =1.0/((ctype) nElementRing);
306 ctype stepLength = length/((ctype) nElementLength);
309 for (
size_t j=0; j<=nElementLength; j++) {
314 vertex[axis] = center[axis] + j*stepLength;
316 for (
size_t i=0; i<nRingNodes; i++) {
319 vertex[(axis+1)%3] =
local[0]; vertex[(axis+2)%3] =
local[1];
325 ArcOfCircle outerArc(localCenter, innerRadius+thickness, fromAngle, toAngle);
328 for (
unsigned int j=0; j<=nElementLength; j++) {
333 vertex[axis] = center[axis] + j*stepLength;
335 for (
size_t i=0; i<nRingNodes; i++) {
338 vertex[(axis+1)%3] =
local[0]; vertex[(axis+2)%3] =
local[1];
345 unsigned int innerNodes = (nElementLength+1)*(nRingNodes);
357 gt = Dune::GeometryTypes::prism;
359 for (
unsigned int i=0; i<nElementLength; i++) {
361 unsigned int row = i*nRingNodes;
363 for (
unsigned int j=0; j<nRingNodes-1; j++) {
368 row+j+1+nElementRing,row+j+2+nElementRing,
369 row+j+innerNodes,row+j+1+innerNodes,
370 row+j+1+nElementRing+innerNodes,
371 row+j+2+nElementRing+innerNodes};
373 cornerIDs={hexa[0],hexa[1],hexa[3],hexa[7]};
375 cornerIDs={hexa[0],hexa[5],hexa[1],hexa[7]};
377 cornerIDs={hexa[0],hexa[4],hexa[5],hexa[7]};
379 cornerIDs={hexa[0],hexa[6],hexa[4],hexa[7]};
381 cornerIDs={hexa[0],hexa[2],hexa[6],hexa[7]};
383 cornerIDs={hexa[0],hexa[3],hexa[2],hexa[7]};
388 cornerIDs[0] = row+j;
389 cornerIDs[1] = row+j+1 ;
390 cornerIDs[2] = row+nElementRing+j+2;
391 cornerIDs[3] = cornerIDs[0]+innerNodes;
392 cornerIDs[4] = cornerIDs[1]+innerNodes;
393 cornerIDs[5] = cornerIDs[2]+innerNodes;
398 cornerIDs[0] = row+nElementRing+j+2;
399 cornerIDs[1] = row+nElementRing+j+1;
400 cornerIDs[2] = row+j;
401 cornerIDs[3] = cornerIDs[0]+innerNodes;
402 cornerIDs[4] = cornerIDs[1]+innerNodes;
403 cornerIDs[5] = cornerIDs[2]+innerNodes;
413 row+2*nElementRing-1,row+nElementRing,
414 row+nElementRing-1+innerNodes,
416 row+2*nElementRing-1+innerNodes,
417 row+nElementRing+innerNodes};
419 cornerIDs={hexa[0],hexa[1],hexa[3],hexa[7]};
421 cornerIDs={hexa[0],hexa[5],hexa[1],hexa[7]};
423 cornerIDs={hexa[0],hexa[4],hexa[5],hexa[7]};
425 cornerIDs={hexa[0],hexa[6],hexa[4],hexa[7]};
427 cornerIDs={hexa[0],hexa[2],hexa[6],hexa[7]};
429 cornerIDs={hexa[0],hexa[3],hexa[2],hexa[7]};
434 cornerIDs[0] = row+nElementRing-1;
436 cornerIDs[2] = row+nElementRing;
437 cornerIDs[3] = cornerIDs[0]+innerNodes;
438 cornerIDs[4] = cornerIDs[1]+innerNodes;
439 cornerIDs[5] = cornerIDs[2]+innerNodes;
444 cornerIDs[0] = row+nElementRing;
445 cornerIDs[1] = row+2*nElementRing-1;
446 cornerIDs[2] = row+nElementRing-1;
447 cornerIDs[3] = cornerIDs[0]+innerNodes;
448 cornerIDs[4] = cornerIDs[1]+innerNodes;
449 cornerIDs[5] = cornerIDs[2]+innerNodes;
460 if (parametrizedBoundary) {
464 ctype angleDiff = toAngle-fromAngle;
466 for (
size_t i=0; i<nElementLength; i++) {
468 unsigned int row = i*nRingNodes;
471 localCenter[0] += i*stepLength;
474 for (
size_t j=0; j<nElementRing-1; j++) {
476 vertices[0] = row+j; vertices[1] = row+j+1; vertices[2] = row+nRingNodes+j+1;
479 fromAngle+j*stepRing*angleDiff, fromAngle+(j+1)*stepRing*angleDiff)));
482 vertices[0] += innerNodes; vertices[1] += innerNodes; vertices[2] +=innerNodes;
485 fromAngle+j*stepRing*angleDiff, fromAngle+(j+1)*stepRing*angleDiff)));
489 vertices[0] = row+nElementRing-1;
490 vertices[1] = row+(!fullTube)*nElementRing;
491 vertices[2] = row+(!fullTube)*(nElementRing+1) + nElementRing;
495 fromAngle+(nElementRing-1)*stepRing*angleDiff, toAngle)));
497 vertices[0] += innerNodes;
498 vertices[1] += innerNodes;
499 vertices[2] += innerNodes;
503 fromAngle+(nElementRing-1)*stepRing*angleDiff, toAngle)));
507 localCenter[0] += stepLength;
509 for (
size_t j=0; j<nElementRing-1; j++) {
511 vertices[0] = row+nRingNodes+j; vertices[1] = row+nRingNodes+j+1; vertices[2] = row+j;
514 fromAngle+j*stepRing*angleDiff, fromAngle+(j+1)*stepRing*angleDiff)));
516 vertices[0] += innerNodes; vertices[1] += innerNodes; vertices[2] += innerNodes;
519 fromAngle+j*stepRing*angleDiff, fromAngle+(j+1)*stepRing*angleDiff)));
523 vertices[0] = row+nRingNodes+nElementRing-1;
524 vertices[1] = row+(!fullTube)*nElementRing + nRingNodes;
525 vertices[2] = row + nElementRing -1;
529 fromAngle+(nElementRing-1)*stepRing*angleDiff, toAngle)));
531 vertices[0] += innerNodes;
532 vertices[1] += innerNodes;
533 vertices[2] += innerNodes;
537 fromAngle+(nElementRing-1)*stepRing*angleDiff, toAngle)));
545 int lastRow = nElementLength*nRingNodes;
547 lastCenter[0] += length;
549 for (
size_t j=0; j<nElementRing-1; j++) {
552 vert[0] = j; vert[1] = j+1; vert[2] = j + innerNodes; vert[3] = j+innerNodes +1;
556 fromAngle+j*stepRing*angleDiff, fromAngle+(j+1)*stepRing*angleDiff)));
559 vert[0] += lastRow; vert[1] += lastRow; vert[2] += lastRow; vert[3] += lastRow;
563 fromAngle+j*stepRing*angleDiff, fromAngle+(j+1)*stepRing*angleDiff)));
571 vert[0] = nElementRing-1; vert[1] = (!fullTube)*nElementRing;
572 vert[2] = vert[0] + innerNodes; vert[3] = vert[1] + innerNodes;
576 fromAngle+(nElementRing-1)*stepRing*angleDiff, toAngle)));
579 vert[0] += lastRow; vert[1] += lastRow; vert[2] += lastRow; vert[3] += lastRow;
583 fromAngle+(nElementRing-1)*stepRing*angleDiff, toAngle)));
595 size_t half = innerVert.
size()/2;
597 for (
size_t i=0; i<half; i++)
606 size_t half = outerVert.
size()/2;
608 for (
size_t i=0; i<half; i++)
609 outerVert[half+i] =
true;
641 const typename GridType::ctype thickness,
642 const typename GridType::ctype horizontalRadius,
643 const typename GridType::ctype verticalRadius,
644 unsigned int nElementHorizontal,
unsigned int nElementVertical,
648 static_assert(GridType::dimension == 3,
649 "makeTorus can only be called for 3-dimensional grids");
650 using ctype =
typename GridType::ctype;
664 ctype stepH =1.0/nElementHorizontal;
665 ctype stepV = 1.0/nElementVertical;
668 for (
size_t j=0; j<nElementHorizontal; j++) {
671 FV ringCenter = center;
672 auto corr = hArc(j*stepH);
673 for (
int i=0; i<2; i++)
674 ringCenter.axpy(corr[i],plane[i]);
679 auto vPlane = ringCenter - center;
683 for (
size_t i=0; i<nElementVertical; i++) {
685 auto local = vInnerArc(i*stepV);
686 auto coord = ringCenter;
687 coord.axpy(
local[0],vPlane);
688 coord.axpy(
local[1],plane[2]);
694 for (
size_t i=0; i<nElementVertical; i++) {
696 auto local = vOuterArc(i*stepV);
697 auto coord = ringCenter;
698 coord.axpy(
local[0],vPlane);
699 coord.axpy(
local[1],plane[2]);
705 unsigned int innerNodes = nElementHorizontal*nElementVertical;
714 auto gt = Dune::GeometryTypes::tetrahedron;
716 for (
unsigned int i=0; i<nElementHorizontal-1; i++) {
718 unsigned int row = i*2*nElementVertical;
720 for (
unsigned int j=0; j<nElementVertical-1; j++) {
724 row+j+2*nElementVertical,row+j+1+2*nElementVertical,
725 row+j+nElementVertical,row+j+1+nElementVertical,
726 row+j+3*nElementVertical,
727 row+j+1+3*nElementVertical};
730 cornerIDs={hexa[0],hexa[1],hexa[3],hexa[7]};
732 cornerIDs={hexa[0],hexa[5],hexa[1],hexa[7]};
734 cornerIDs={hexa[0],hexa[4],hexa[5],hexa[7]};
736 cornerIDs={hexa[0],hexa[6],hexa[4],hexa[7]};
738 cornerIDs={hexa[0],hexa[2],hexa[6],hexa[7]};
740 cornerIDs={hexa[0],hexa[3],hexa[2],hexa[7]};
747 row+3*nElementVertical-1,row+2*nElementVertical,
748 row+2*nElementVertical-1,
749 row+nElementVertical,
750 row+4*nElementVertical-1,
751 row+3*nElementVertical};
753 cornerIDs={hexa[0],hexa[1],hexa[3],hexa[7]};
755 cornerIDs={hexa[0],hexa[5],hexa[1],hexa[7]};
757 cornerIDs={hexa[0],hexa[4],hexa[5],hexa[7]};
759 cornerIDs={hexa[0],hexa[6],hexa[4],hexa[7]};
761 cornerIDs={hexa[0],hexa[2],hexa[6],hexa[7]};
763 cornerIDs={hexa[0],hexa[3],hexa[2],hexa[7]};
768 unsigned int row = (nElementHorizontal-1)*2*nElementVertical;
770 for (
unsigned int j=0; j<nElementVertical-1; j++) {
774 row+j+nElementVertical,row+j+1+nElementVertical,
776 j+1+nElementVertical};
779 cornerIDs={hexa[0],hexa[1],hexa[3],hexa[7]};
781 cornerIDs={hexa[0],hexa[5],hexa[1],hexa[7]};
783 cornerIDs={hexa[0],hexa[4],hexa[5],hexa[7]};
785 cornerIDs={hexa[0],hexa[6],hexa[4],hexa[7]};
787 cornerIDs={hexa[0],hexa[2],hexa[6],hexa[7]};
789 cornerIDs={hexa[0],hexa[3],hexa[2],hexa[7]};
796 nElementVertical-1,0,
797 row+2*nElementVertical-1,
798 row+nElementVertical,
799 2*nElementVertical-1,
802 cornerIDs={hexa[0],hexa[1],hexa[3],hexa[7]};
804 cornerIDs={hexa[0],hexa[5],hexa[1],hexa[7]};
806 cornerIDs={hexa[0],hexa[4],hexa[5],hexa[7]};
808 cornerIDs={hexa[0],hexa[6],hexa[4],hexa[7]};
810 cornerIDs={hexa[0],hexa[2],hexa[6],hexa[7]};
812 cornerIDs={hexa[0],hexa[3],hexa[2],hexa[7]};
825 for (
unsigned i=0; i<nElementHorizontal; i++) {
826 auto row = i*2*nElementVertical;
827 for (
unsigned j=0; j<nElementVertical; j++)
828 innerVert[row+j] =
true;
838 for (
unsigned i=0; i<nElementHorizontal; i++) {
839 auto row = i*2*nElementVertical;
840 for (
unsigned j=nElementVertical; j<2*nElementVertical; j++)
841 outerVert[row+j] =
true;