36 #ifndef LEVELSETBDQRADAPTER_H 37 #define LEVELSETBDQRADAPTER_H 1
39 #include <lifev/core/LifeV.hpp> 41 #include <lifev/eta/fem/QuadratureBoundary.hpp> 42 #include <lifev/eta/fem/ETCurrentFE.hpp> 44 #include <boost/shared_ptr.hpp> 53 template<
typename FESpaceType,
typename VectorType >
54 class LevelSetBDQRAdapter
61 typedef std::shared_ptr<FESpaceType> FESpaceType_Ptr;
69 LevelSetBDQRAdapter ( FESpaceType_Ptr fespace,
const VectorType& vect,
const QuadratureBoundary& qrbd)
70 : M_lsFESpace (fespace),
71 M_lsValue (vect, Repeated),
73 M_currentFE (fespace->refFE(), getGeometricMap (*fespace->mesh() ), qrbd.qr (0) ),
74 M_isAdaptedElement (
false),
75 M_adaptedQrBd (
new QuadratureBoundary (qrbd) )
78 LevelSetBDQRAdapter (
const LevelSetBDQRAdapter& lsbdqra)
79 : M_lsFESpace ( lsbdqra.M_lsFESpace),
80 M_lsValue ( lsbdqra.M_lsValue),
81 M_qrBd ( lsbdqra.M_qrBd),
82 M_currentFE ( lsbdqra.M_currentFE),
83 M_isAdaptedElement ( lsbdqra.M_isAdaptedElement),
84 M_adaptedQrBd (
new QuadratureBoundary (lsbdqra.M_qrBd) )
87 ~LevelSetBDQRAdapter() {}
95 void update (UInt elementID, UInt localFaceID);
109 QuadratureRule adaptedBdQR (
const UInt i)
const 111 if (
this->M_isAdaptedElement)
113 return M_adaptedQrBd->qr (i);
115 return M_qrBd.qr (i);
122 LevelSetBDQRAdapter();
125 FESpaceType_Ptr M_lsFESpace;
127 VectorType M_lsValue;
129 QuadratureBoundary M_qrBd;
131 ETCurrentFE<FESpaceType::space_dim, 1> M_currentFE;
133 bool M_isAdaptedElement;
135 std::shared_ptr<QuadratureBoundary> M_adaptedQrBd;
139 template<
typename FESpaceType,
typename VectorType>
140 LevelSetBDQRAdapter<FESpaceType, VectorType>
141 adapt (std::shared_ptr<FESpaceType> fespace,
const VectorType& vector,
const QuadratureBoundary& qrbd)
143 return LevelSetBDQRAdapter<FESpaceType, VectorType> (fespace, vector, qrbd);
147 template<
typename FESpaceType,
typename VectorType>
149 LevelSetBDQRAdapter<FESpaceType, VectorType>::
150 update (UInt elementID, UInt localFaceID)
155 std::vector<UInt> myLID (3);
157 if (localFaceID == 0)
163 else if (localFaceID == 1)
169 else if (localFaceID == 2)
183 std::vector<UInt> myGID (3);
185 for (UInt i (0); i < 3; ++i)
187 myGID[i] = M_lsFESpace->dof().localToGlobalMap (elementID, myLID[i]);
191 std::vector<UInt> localPositive;
192 std::vector<UInt> localNegative;
193 std::vector<Real> localPositiveValue;
194 std::vector<Real> localNegativeValue;
196 for (UInt i (0); i < 3; ++i)
198 if (M_lsValue[myGID[i]] >= 0)
200 localPositive.push_back (i);
201 localPositiveValue.push_back (M_lsValue[myGID[i]]);
205 localNegative.push_back (i);
206 localNegativeValue.push_back (M_lsValue[myGID[i]]);
211 if (localPositive.empty() || localNegative.empty() )
213 M_isAdaptedElement =
false;
214 *M_adaptedQrBd = M_qrBd;
219 M_isAdaptedElement =
true;
221 std::vector<std::vector<Real> >refCoor (3, std::vector<Real> (2) );
229 QuadratureRule qrRef (
"none", TRIANGLE, 3, 0, 0);
232 if (localPositive.size() == 1)
239 localPositive.swap (localNegative);
240 localPositiveValue.swap (localNegativeValue);
245 Real lambda1 = -localPositiveValue[0] / (localNegativeValue[0] - localPositiveValue[0]);
247 std::vector < Real > I1 (2);
248 I1[0] = refCoor[localPositive[0]][0] + lambda1 * (refCoor[localNegative[0]][0] - refCoor[localPositive[0]][0]);
249 I1[1] = refCoor[localPositive[0]][1] + lambda1 * (refCoor[localNegative[0]][1] - refCoor[localPositive[0]][1]);
251 Real lambda2 = -localPositiveValue[0] / (localNegativeValue[1] - localPositiveValue[0]);
253 std::vector < Real > I2 (2);
254 I2[0] = refCoor[localPositive[0]][0] + lambda2 * (refCoor[localNegative[1]][0] - refCoor[localPositive[0]][0]);
255 I2[1] = refCoor[localPositive[0]][1] + lambda2 * (refCoor[localNegative[1]][1] - refCoor[localPositive[0]][1]);
259 std::vector<Real> P0 (2);
260 P0[0] = refCoor[localPositive[0]][0];
261 P0[1] = refCoor[localPositive[0]][1];
263 std::vector<Real> v1 (2);
264 v1[0] = I1[0] - refCoor[localPositive[0]][0];
265 v1[1] = I1[1] - refCoor[localPositive[0]][1];
267 std::vector<Real> v2 (2);
268 v2[0] = I2[0] - refCoor[localPositive[0]][0];
269 v2[1] = I2[1] - refCoor[localPositive[0]][1];
271 Real wRel (std::abs (v1[0]*v2[1] - v1[1]*v2[0]) );
273 for (UInt iq (0); iq < M_qrBd.qr (0).nbQuadPt(); ++iq)
275 Real x (P0[0] + M_qrBd.qr (0).quadPointCoor (iq, 0) *v1[0] + M_qrBd.qr (0).quadPointCoor (iq, 1) *v2[0]);
276 Real y (P0[1] + M_qrBd.qr (0).quadPointCoor (iq, 0) *v1[1] + M_qrBd.qr (0).quadPointCoor (iq, 1) *v2[1]);
278 qrRef.addPoint (QuadraturePoint (x, y, M_qrBd.qr (0).weight (iq) *wRel) );
284 std::vector<Real> P0 (2);
285 P0[0] = refCoor[localNegative[0]][0];
286 P0[1] = refCoor[localNegative[0]][1];
288 std::vector<Real> v1 (2);
289 v1[0] = I1[0] - refCoor[localNegative[0]][0];
290 v1[1] = I1[1] - refCoor[localNegative[0]][1];
292 std::vector<Real> v2 (2);
293 v2[0] = I2[0] - refCoor[localNegative[0]][0];
294 v2[1] = I2[1] - refCoor[localNegative[0]][1];
296 Real wRel (std::abs (v1[0]*v2[1] - v1[1]*v2[0]) );
298 for (UInt iq (0); iq < M_qrBd.qr (0).nbQuadPt(); ++iq)
300 Real x (P0[0] + M_qrBd.qr (0).quadPointCoor (iq, 0) *v1[0] + M_qrBd.qr (0).quadPointCoor (iq, 1) *v2[0]);
301 Real y (P0[1] + M_qrBd.qr (0).quadPointCoor (iq, 0) *v1[1] + M_qrBd.qr (0).quadPointCoor (iq, 1) *v2[1]);
303 qrRef.addPoint (QuadraturePoint (x, y, M_qrBd.qr (0).weight (iq) *wRel) );
309 std::vector<Real> P0 (2);
310 P0[0] = refCoor[localNegative[0]][0];
311 P0[1] = refCoor[localNegative[0]][1];
313 std::vector<Real> v1 (2);
314 v1[0] = I2[0] - refCoor[localNegative[0]][0];
315 v1[1] = I2[1] - refCoor[localNegative[0]][1];
317 std::vector<Real> v2 (2);
318 v2[0] = refCoor[localNegative[1]][0] - refCoor[localNegative[0]][0];
319 v2[1] = refCoor[localNegative[1]][1] - refCoor[localNegative[0]][1];
321 Real wRel (std::abs (v1[0]*v2[1] - v1[1]*v2[0]) );
323 for (UInt iq (0); iq < M_qrBd.qr (0).nbQuadPt(); ++iq)
325 Real x (P0[0] + M_qrBd.qr (0).quadPointCoor (iq, 0) *v1[0] + M_qrBd.qr (0).quadPointCoor (iq, 1) *v2[0]);
326 Real y (P0[1] + M_qrBd.qr (0).quadPointCoor (iq, 0) *v1[1] + M_qrBd.qr (0).quadPointCoor (iq, 1) *v2[1]);
328 qrRef.addPoint (QuadraturePoint (x, y, M_qrBd.qr (0).weight (iq) *wRel) );
333 M_adaptedQrBd.reset (
new QuadratureBoundary (buildTetraBDQR (qrRef) ) );