42 #ifndef LEVELSETQRADAPTER_H 43 #define LEVELSETQRADAPTER_H 1
45 #include <lifev/core/LifeV.hpp> 49 #include <lifev/eta/fem/ETCurrentFE.hpp> 50 #include <lifev/core/fem/GeometricMap.hpp> 51 #include <lifev/core/fem/QuadratureRule.hpp> 53 #include <lifev/eta/fem/QRAdapterBase.hpp> 55 #include <boost/shared_ptr.hpp> 70 template<
typename FESpaceType,
typename VectorType >
71 class LevelSetQRAdapter :
public QRAdapterBase< LevelSetQRAdapter<FESpaceType, VectorType> >
78 typedef std::shared_ptr<FESpaceType> FESpaceType_Ptr;
80 typedef QRAdapterBase< LevelSetQRAdapter<FESpaceType, VectorType> > base_Type;
89 LevelSetQRAdapter (FESpaceType_Ptr fespace,
const VectorType& vect,
const QuadratureRule& qr);
92 LevelSetQRAdapter (
const LevelSetQRAdapter<FESpaceType, VectorType>& lsqra);
95 ~LevelSetQRAdapter() {}
114 void update (UInt elementID);
130 bool isAdaptedElement()
const 132 return M_isAdaptedElement;
136 const QuadratureRule& standardQR()
const 142 const QuadratureRule& adaptedQR()
const 163 FESpaceType_Ptr M_lsFESpace;
166 VectorType M_lsValue;
173 ETCurrentFE<FESpaceType::space_dim, 1> M_currentFE;
176 bool M_isAdaptedElement;
179 std::shared_ptr<QuadratureRule> M_adaptedQR;
183 template<
typename FESpaceType,
typename VectorType>
184 LevelSetQRAdapter<FESpaceType, VectorType>
185 adapt (std::shared_ptr<FESpaceType> fespace,
const VectorType& vector,
const QuadratureRule& qr)
187 return LevelSetQRAdapter<FESpaceType, VectorType> (fespace, vector, qr);
191 template<
typename FESpaceType,
typename VectorType >
192 LevelSetQRAdapter<FESpaceType, VectorType>::
193 LevelSetQRAdapter (FESpaceType_Ptr fespace,
const VectorType& vect,
const QuadratureRule& qr)
196 M_lsFESpace (fespace),
197 M_lsValue (vect, Repeated),
199 M_currentFE (fespace->refFE(), getGeometricMap (*fespace->mesh() ), qr),
200 M_isAdaptedElement (
false),
201 M_adaptedQR (
new QuadratureRule (qr) )
204 ASSERT ( FESpaceType::field_dim == 1,
"Quadrature adaptation only for scalar fields!");
205 ASSERT ( FESpaceType::space_dim == 3,
"Quadrature adaptation only 3D cases for the moment!");
208 template<
typename FESpaceType,
typename VectorType >
209 LevelSetQRAdapter<FESpaceType, VectorType>::
210 LevelSetQRAdapter (
const LevelSetQRAdapter<FESpaceType, VectorType>& lsqra)
213 M_lsFESpace ( lsqra.M_lsFESpace ),
214 M_lsValue ( lsqra.M_lsValue ),
216 M_currentFE ( lsqra.M_currentFE ),
217 M_isAdaptedElement ( lsqra.M_isAdaptedElement ),
218 M_adaptedQR (
new QuadratureRule (*lsqra.M_adaptedQR) )
222 template<
typename FESpaceType,
typename VectorType >
224 LevelSetQRAdapter<FESpaceType, VectorType>::
225 update (UInt elementID)
228 ASSERT ( M_lsValue.mapType() == Repeated,
"Internal error: level values are Unique!");
229 ASSERT ( M_lsFESpace != 0,
"Internal error: empty pointer to the Space");
233 std::vector<UInt> localPositive;
234 std::vector<UInt> localNegative;
235 std::vector<Real> localLSValue (4, 0.0);
237 for (UInt iDof (0); iDof < 4; ++iDof)
239 UInt myGlobalID ( M_lsFESpace->dof().localToGlobalMap (elementID, iDof) );
240 localLSValue[iDof] = M_lsValue[myGlobalID];
242 if (localLSValue[iDof] >= 0)
244 localPositive.push_back (iDof);
248 localNegative.push_back (iDof);
253 if ( localPositive.empty() || localNegative.empty() )
256 M_isAdaptedElement =
false;
262 M_isAdaptedElement =
true;
265 std::vector< VectorSmall<3> > refPts (4);
273 ETCurrentFE<3, 1> QRMapper (feTetraP1, getGeometricMap (*M_lsFESpace->mesh() ), M_qr);
276 M_adaptedQR.reset (
new QuadratureRule);
277 M_adaptedQR->setDimensionShape (3, TETRA);
280 UInt QuadratureSize (M_qr.nbQuadPt() );
285 if (localPositive.size() == 1)
288 std::vector< VectorSmall<3> > intersections (3);
290 for (UInt i (0); i < 3; ++i)
292 UInt pos (localPositive[0]);
293 UInt neg (localNegative[i]);
294 Real mu ( localLSValue[pos] / (localLSValue[pos] - localLSValue[neg]) );
295 VectorSmall<3> I ( refPts[pos] + mu * ( refPts[neg] - refPts[pos] ) );
296 intersections[i] = I;
301 std::vector< VectorSmall<3> > tetra1 (4);
302 tetra1[0] = refPts[localPositive[0]];
303 tetra1[1] = intersections[0];
304 tetra1[2] = intersections[1];
305 tetra1[3] = intersections[2];
308 QRMapper.update ( tetra1, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
310 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
312 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
313 QRMapper.quadNode (iQuadPt, 1),
314 QRMapper.quadNode (iQuadPt, 2),
315 std::abs (QRMapper.wDet (iQuadPt) ) ) );
319 std::vector< VectorSmall<3> > tetra2 (4);
320 tetra2[0] = intersections[0];
321 tetra2[1] = intersections[1];
322 tetra2[2] = intersections[2];
323 tetra2[3] = refPts[localNegative[0]];
326 QRMapper.update ( tetra2, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
328 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
330 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
331 QRMapper.quadNode (iQuadPt, 1),
332 QRMapper.quadNode (iQuadPt, 2),
333 std::abs (QRMapper.wDet (iQuadPt) ) ) );
337 std::vector< VectorSmall<3> > tetra3 (4);
338 tetra3[0] = refPts[localNegative[0]];
339 tetra3[1] = refPts[localNegative[1]];
340 tetra3[2] = refPts[localNegative[2]];
341 tetra3[3] = intersections[2];
344 QRMapper.update ( tetra3, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
346 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
348 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
349 QRMapper.quadNode (iQuadPt, 1),
350 QRMapper.quadNode (iQuadPt, 2),
351 std::abs (QRMapper.wDet (iQuadPt) ) ) );
356 std::vector< VectorSmall<3> > tetra4 (4);
357 tetra4[0] = refPts[localNegative[0]];
358 tetra4[1] = refPts[localNegative[1]];
359 tetra4[2] = intersections[1];
360 tetra4[3] = intersections[2];
363 QRMapper.update ( tetra4, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
365 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
367 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
368 QRMapper.quadNode (iQuadPt, 1),
369 QRMapper.quadNode (iQuadPt, 2),
370 std::abs (QRMapper.wDet (iQuadPt) ) ) );
374 else if ( localPositive.size() == 2)
378 std::vector< VectorSmall<3> > intersections (4);
380 for (UInt i (0); i < 2; ++i)
382 for (UInt j (0); j < 2; ++j)
384 UInt pos (localPositive[i]);
385 UInt neg (localNegative[j]);
386 Real mu ( localLSValue[pos] / (localLSValue[pos] - localLSValue[neg]) );
387 VectorSmall<3> I ( refPts[pos] + mu * ( refPts[neg] - refPts[pos] ) );
388 intersections[i + 2 * j] = I;
394 std::vector< VectorSmall<3> > tetra1 (4);
395 tetra1[0] = refPts[localPositive[0]];
396 tetra1[1] = intersections[0];
397 tetra1[2] = intersections[1];
398 tetra1[3] = intersections[2];
401 QRMapper.update ( tetra1, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
403 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
405 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
406 QRMapper.quadNode (iQuadPt, 1),
407 QRMapper.quadNode (iQuadPt, 2),
408 std::abs (QRMapper.wDet (iQuadPt) ) ) );
412 std::vector< VectorSmall<3> > tetra2 (4);
413 tetra2[0] = intersections[1];
414 tetra2[1] = intersections[2];
415 tetra2[2] = intersections[3];
416 tetra2[3] = refPts[localPositive[0]];
419 QRMapper.update ( tetra2, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
421 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
423 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
424 QRMapper.quadNode (iQuadPt, 1),
425 QRMapper.quadNode (iQuadPt, 2),
426 std::abs (QRMapper.wDet (iQuadPt) ) ) );
430 std::vector< VectorSmall<3> > tetra3 (4);
431 tetra3[0] = refPts[localPositive[0]];
432 tetra3[1] = refPts[localPositive[1]];
433 tetra3[2] = intersections[1];
434 tetra3[3] = intersections[3];
437 QRMapper.update ( tetra3, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
439 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
441 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
442 QRMapper.quadNode (iQuadPt, 1),
443 QRMapper.quadNode (iQuadPt, 2),
444 std::abs (QRMapper.wDet (iQuadPt) ) ) );
448 std::vector< VectorSmall<3> > tetra4 (4);
449 tetra4[0] = refPts[localNegative[0]];
450 tetra4[1] = intersections[0];
451 tetra4[2] = intersections[1];
452 tetra4[3] = intersections[2];
455 QRMapper.update ( tetra4, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
457 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
459 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
460 QRMapper.quadNode (iQuadPt, 1),
461 QRMapper.quadNode (iQuadPt, 2),
462 std::abs (QRMapper.wDet (iQuadPt) ) ) );
466 std::vector< VectorSmall<3> > tetra5 (4);
467 tetra5[0] = refPts[localNegative[0]];
468 tetra5[1] = intersections[1];
469 tetra5[2] = intersections[2];
470 tetra5[3] = intersections[3];
473 QRMapper.update ( tetra5, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
475 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
477 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
478 QRMapper.quadNode (iQuadPt, 1),
479 QRMapper.quadNode (iQuadPt, 2),
480 std::abs (QRMapper.wDet (iQuadPt) ) ) );
484 std::vector< VectorSmall<3> > tetra6 (4);
485 tetra6[0] = refPts[localNegative[0]];
486 tetra6[1] = refPts[localNegative[1]];
487 tetra6[2] = intersections[2];
488 tetra6[3] = intersections[3];
491 QRMapper.update ( tetra6, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
493 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
495 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
496 QRMapper.quadNode (iQuadPt, 1),
497 QRMapper.quadNode (iQuadPt, 2),
498 std::abs (QRMapper.wDet (iQuadPt) ) ) );
506 ASSERT ( localPositive.size() == 3,
"Internal inconsistency");
509 std::vector< VectorSmall<3> > intersections (3);
511 for (UInt i (0); i < 3; ++i)
513 UInt pos (localPositive[i]);
514 UInt neg (localNegative[0]);
515 Real mu ( localLSValue[pos] / (localLSValue[pos] - localLSValue[neg]) );
516 VectorSmall<3> I ( refPts[pos] + mu * ( refPts[neg] - refPts[pos] ) );
517 intersections[i] = I;
522 std::vector< VectorSmall<3> > tetra1 (4);
523 tetra1[0] = refPts[localNegative[0]];
524 tetra1[1] = intersections[0];
525 tetra1[2] = intersections[1];
526 tetra1[3] = intersections[2];
529 QRMapper.update ( tetra1, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
531 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
533 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
534 QRMapper.quadNode (iQuadPt, 1),
535 QRMapper.quadNode (iQuadPt, 2),
536 std::abs (QRMapper.wDet (iQuadPt) ) ) );
541 std::vector< VectorSmall<3> > tetra2 (4);
542 tetra2[0] = intersections[0];
543 tetra2[1] = intersections[1];
544 tetra2[2] = intersections[2];
545 tetra2[3] = refPts[localPositive[0]];
548 QRMapper.update ( tetra2, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
550 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
552 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
553 QRMapper.quadNode (iQuadPt, 1),
554 QRMapper.quadNode (iQuadPt, 2),
555 std::abs (QRMapper.wDet (iQuadPt) ) ) );
559 std::vector< VectorSmall<3> > tetra3 (4);
560 tetra3[0] = refPts[localPositive[0]];
561 tetra3[1] = refPts[localPositive[1]];
562 tetra3[2] = refPts[localPositive[2]];
563 tetra3[3] = intersections[2];
566 QRMapper.update ( tetra3, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
568 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
570 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
571 QRMapper.quadNode (iQuadPt, 1),
572 QRMapper.quadNode (iQuadPt, 2),
573 std::abs (QRMapper.wDet (iQuadPt) ) ) );
577 std::vector< VectorSmall<3> > tetra4 (4);
578 tetra4[0] = refPts[localPositive[0]];
579 tetra4[1] = refPts[localPositive[1]];
580 tetra4[2] = intersections[1];
581 tetra4[3] = intersections[2];
584 QRMapper.update ( tetra4, ET_UPDATE_QUAD_NODE | ET_UPDATE_WDET);
586 for (UInt iQuadPt (0); iQuadPt < QuadratureSize; ++iQuadPt)
588 M_adaptedQR->addPoint (QuadraturePoint ( QRMapper.quadNode (iQuadPt, 0),
589 QRMapper.quadNode (iQuadPt, 1),
590 QRMapper.quadNode (iQuadPt, 2),
591 std::abs (QRMapper.wDet (iQuadPt) ) ) );