42 #ifndef _NSIPTERMS_HPP 43 #define _NSIPTERMS_HPP 45 #include <lifev/core/util/LifeChrono.hpp> 46 #include <lifev/core/array/MatrixElemental.hpp> 47 #include <lifev/core/array/VectorElemental.hpp> 48 #include <lifev/core/fem/AssemblyElemental.hpp> 49 #include <boost/shared_ptr.hpp> 51 #define USE_OLD_PARAMETERS 0
52 #define WITH_DIVERGENCE 1
90 template<
typename MeshType,
typename DofType>
97 typedef std::shared_ptr<MeshType> mesh_type;
98 typedef MeshType mesh_Type;
99 typedef DofType dof_Type;
100 typedef std::shared_ptr<mesh_Type> meshPtr_Type;
101 typedef std::shared_ptr<dof_Type> dofPtr_Type;
110 virtual ~StabilizationIP() {};
140 template<
typename MatrixType,
typename VectorType>
141 void apply ( MatrixType& matrix,
const VectorType& state,
bool verbose =
true );
148 void showMe (std::ostream& output = std::cout)
const;
154 void setGammaBeta (
const Real& gammaBeta)
156 M_gammaBeta = gammaBeta;
159 void setGammaDiv (
const Real& gammaDiv)
161 M_gammaDiv = gammaDiv;
164 void setGammaPress (
const Real& gammaPress)
166 M_gammaPress = gammaPress;
169 void setViscosity (
const Real& viscosity)
171 M_viscosity = viscosity;
174 void setMesh (
const meshPtr_Type mesh)
181 template<
typename MapType>
182 void setFeSpaceVelocity (FESpace<mesh_Type, MapType>& feSpaceVelocity);
189 typedef ID ( *FTOP ) (
ID const& localFacet,
ID const& point );
195 StabilizationIP (
const StabilizationIP<mesh_Type, dof_Type>& original);
205 std::shared_ptr<CurrentFE> M_feOnSide1;
207 std::shared_ptr<CurrentFE> M_feOnSide2;
228 template<
typename MeshType,
typename DofType>
229 StabilizationIP<MeshType, DofType>::StabilizationIP() :
232 M_gammaPress ( 0.0 ),
240 template<
typename MeshType,
typename DofType>
241 template<
typename MatrixType,
typename VectorType>
242 void StabilizationIP<MeshType, DofType>::apply ( MatrixType& matrix,
const VectorType& state,
const bool verbose )
244 if ( M_gammaBeta == 0. && M_gammaDiv == 0. && M_gammaPress == 0. )
263 ID geoDimensions = MeshType::S_geoDimensions;
264 MatrixElemental elMatU ( M_feOnSide1->nbFEDof(), geoDimensions , geoDimensions );
265 MatrixElemental elMatP ( M_feOnSide1->nbFEDof(), geoDimensions + 1, geoDimensions + 1 );
268 const UInt nDof = M_dof->numTotalDof();
271 state.normInf (&normInf);
280 for ( UInt iFacet ( M_mesh->numBoundaryFacets() ); iFacet < M_mesh->numFacets();
283 const UInt iElAd1 ( M_mesh->facet ( iFacet ).firstAdjacentElementIdentity() );
284 const UInt iElAd2 ( M_mesh->facet ( iFacet ).secondAdjacentElementIdentity() );
286 if ( Flag::testOneSet ( M_mesh->facet ( iFacet ).flag(),
287 EntityFlags::SUBDOMAIN_INTERFACE | EntityFlags::PHYSICAL_BOUNDARY ) )
294 chronoUpdate.start();
297 M_feBd->update ( M_mesh->facet ( iFacet ), UPDATE_W_ROOT_DET_METRIC );
299 M_feBd->updateMeasNormal ( M_mesh->facet ( iFacet ) );
300 KNM<Real>& normal = M_feBd->normal;
302 const Real hK2 = M_feBd->measure();
305 M_feOnSide1->updateFirstDeriv ( M_mesh->element ( iElAd1 ) );
306 M_feOnSide2->updateFirstDeriv ( M_mesh->element ( iElAd2 ) );
317 UInt iFaEl ( M_mesh->facet ( iFacet ).firstAdjacentElementPosition() );
318 for ( UInt iNode ( 0 ); iNode < M_feBd->nbFEDof(); ++iNode )
320 UInt iloc ( M_facetToPoint ( iFaEl, iNode ) );
321 for ( UInt iCoor ( 0 ); iCoor < M_feOnSide1->nbLocalCoor(); ++iCoor )
323 UInt ig ( M_dof->localToGlobalMap ( iElAd1, iloc ) + iCoor * nDof );
325 if (state.blockMap().LID (
static_cast<EpetraInt_Type> (ig) ) >= 0)
327 beta.vec() [ iCoor * M_feBd->nbFEDof() + iNode ] = state ( ig);
333 for ( UInt l ( 0 ); l <
static_cast<UInt> ( M_feOnSide1->nbLocalCoor() *M_feBd->nbFEDof() ); ++l )
335 if ( bmax < std::fabs ( beta.vec() [ l ] ) )
337 bmax = std::fabs ( beta.vec() [ l ] );
346 if ( M_gammaPress != 0.0 )
349 Real coeffPress ( M_gammaPress * hK2 );
352 Real coeffPress = M_gammaPress * hK2 /
353 std::max<Real> ( bmax, M_viscosity / std::sqrt ( hK2 ) );
357 chronoElemComp.start();
359 AssemblyElemental::ipstab_grad ( coeffPress, elMatP, *M_feOnSide1, *M_feOnSide1, *M_feBd,
360 geoDimensions, geoDimensions);
361 chronoElemComp.stop();
362 chronoAssembly1.start();
364 assembleMatrix (matrix, elMatP, *M_feOnSide1, *M_dof,
365 geoDimensions, geoDimensions, geoDimensions * nDof, geoDimensions * nDof);
366 chronoAssembly1.stop();
369 chronoElemComp.start();
371 AssemblyElemental::ipstab_grad ( coeffPress, elMatP, *M_feOnSide2, *M_feOnSide2, *M_feBd,
372 geoDimensions, geoDimensions);
373 chronoElemComp.stop();
374 chronoAssembly2.start();
376 assembleMatrix (matrix, elMatP, *M_feOnSide2, *M_dof,
377 geoDimensions, geoDimensions, geoDimensions * nDof, geoDimensions * nDof);
378 chronoAssembly2.stop();
381 chronoElemComp.start();
383 AssemblyElemental::ipstab_grad (- coeffPress, elMatP, *M_feOnSide1, *M_feOnSide2, *M_feBd,
384 geoDimensions, geoDimensions);
385 chronoElemComp.stop();
386 chronoAssembly3.start();
388 assembleMatrix (matrix, elMatP, *M_feOnSide1, *M_feOnSide2, *M_dof, *M_dof,
389 geoDimensions, geoDimensions, geoDimensions * nDof, geoDimensions * nDof);
390 chronoAssembly3.stop();
393 chronoElemComp.start();
395 AssemblyElemental::ipstab_grad (- coeffPress, elMatP, *M_feOnSide2, *M_feOnSide1, *M_feBd,
396 geoDimensions, geoDimensions);
397 chronoElemComp.stop();
398 chronoAssembly4.start();
400 assembleMatrix (matrix, elMatP, *M_feOnSide2, *M_feOnSide1, *M_dof, *M_dof,
401 geoDimensions, geoDimensions, geoDimensions * nDof, geoDimensions * nDof);
402 chronoAssembly4.stop();
406 if ( ( M_gammaDiv != 0 || M_gammaBeta != 0 ) && bmax > 0 )
410 Real coeffBeta ( M_gammaBeta * hK2 / std::max<Real> (bmax, hK2) );
412 Real coeffBeta ( M_gammaBeta * hK2 / bmax );
415 Real coeffDiv ( M_gammaDiv * hK2 * bmax );
424 for ( UInt iNode (0); iNode < M_feBd->nbNode; ++iNode )
427 for ( UInt iCoor (0); iCoor < M_feOnSide1->nbLocalCoor(); ++iCoor )
429 bn += normal (iNode, iCoor) *
430 beta.vec() [ iCoor * M_feBd->nbNode + iNode ];
431 bcmax = std::max<Real>
432 (bcmax, normal (iNode, (iCoor) % 3) *
433 beta.vec() [ (iCoor + 1) % 3 * M_feBd->nbNode + iNode ] -
434 normal (iNode, (iCoor + 1) % 3) *
435 beta.vec() [ (iCoor) % 3 * M_feBd->nbNode + iNode ]);
437 bnmax = std::max<Real> (bnmax, bn);
441 Real coeffGrad = hK2 * (M_gammaBeta * bnmax + M_gammaDiv * bcmax);
444 chronoElemComp.start();
447 AssemblyElemental::ipstab_bgrad ( coeffBeta, elMatU, *M_feOnSide1, *M_feOnSide1, beta,
448 *M_feBd, 0, 0, geoDimensions );
450 AssemblyElemental::ipstab_div ( coeffDiv, elMatU, *M_feOnSide1, *M_feOnSide1, *M_feBd );
453 AssemblyElemental::ipstab_grad ( coeffGrad, elMatU, *M_feOnSide1, *M_feOnSide1, *M_feBd, 0, 0,
456 chronoElemComp.stop();
457 chronoAssembly5.start();
458 for ( UInt iComp ( 0 ); iComp < geoDimensions; ++iComp )
459 for ( UInt jComp ( 0 ); jComp < geoDimensions; ++jComp )
461 assembleMatrix ( matrix, elMatU, *M_feOnSide1, *M_dof,
462 iComp, jComp, iComp * nDof, jComp * nDof );
464 chronoAssembly5.stop();
467 chronoElemComp.start();
470 AssemblyElemental::ipstab_bgrad ( coeffBeta, elMatU, *M_feOnSide2, *M_feOnSide2, beta,
471 *M_feBd, 0, 0, geoDimensions );
473 AssemblyElemental::ipstab_div ( coeffDiv, elMatU, *M_feOnSide2, *M_feOnSide2, *M_feBd );
476 AssemblyElemental::ipstab_grad ( coeffGrad, elMatU, *M_feOnSide2, *M_feOnSide2, *M_feBd, 0, 0,
479 chronoElemComp.stop();
480 chronoAssembly6.start();
481 for ( UInt iComp ( 0 ); iComp < geoDimensions; ++iComp )
482 for ( UInt jComp ( 0 ); jComp < geoDimensions; ++jComp )
484 assembleMatrix ( matrix, elMatU, *M_feOnSide2, *M_dof,
485 iComp, jComp, iComp * nDof, jComp * nDof );
487 chronoAssembly6.stop();
490 chronoElemComp.start();
493 AssemblyElemental::ipstab_bgrad ( -coeffBeta, elMatU, *M_feOnSide1, *M_feOnSide2, beta,
494 *M_feBd, 0, 0, geoDimensions );
496 AssemblyElemental::ipstab_div ( -coeffDiv, elMatU, *M_feOnSide1, *M_feOnSide2, *M_feBd );
499 AssemblyElemental::ipstab_grad ( -coeffGrad, elMatU, *M_feOnSide1, *M_feOnSide2, *M_feBd, 0, 0,
502 chronoElemComp.stop();
503 chronoAssembly7.start();
504 for ( UInt iComp = 0; iComp < geoDimensions; ++iComp )
505 for ( UInt jComp = 0; jComp < geoDimensions; ++jComp )
507 assembleMatrix ( matrix, elMatU, *M_feOnSide1, *M_feOnSide2, *M_dof, *M_dof,
508 iComp, jComp, iComp * nDof, jComp * nDof );
510 chronoAssembly7.stop();
513 chronoElemComp.start();
516 AssemblyElemental::ipstab_bgrad ( -coeffBeta, elMatU, *M_feOnSide2, *M_feOnSide1, beta,
517 *M_feBd, 0, 0, geoDimensions );
519 AssemblyElemental::ipstab_div ( -coeffDiv, elMatU, *M_feOnSide2, *M_feOnSide1, *M_feBd );
522 AssemblyElemental::ipstab_grad ( -coeffGrad, elMatU, *M_feOnSide2, *M_feOnSide1, *M_feBd, 0, 0,
525 chronoElemComp.stop();
526 chronoAssembly8.start();
527 for ( UInt iComp ( 0 ); iComp < geoDimensions; ++iComp )
528 for ( UInt jComp ( 0 ); jComp < geoDimensions; ++jComp )
530 assembleMatrix ( matrix, elMatU, *M_feOnSide2, *M_feOnSide1, *M_dof, *M_dof,
531 iComp, jComp, iComp * nDof, jComp * nDof );
533 chronoAssembly8.stop();
542 <<
" . Updating of element done in " 566 <<
" myFacets = " << myFacets <<
"\n";
571 template<
typename MeshType,
typename DofType>
572 void StabilizationIP<MeshType, DofType>::showMe (std::ostream& output)
const 574 output <<
"StabilizationIP::showMe() " << std::endl;
575 output <<
"Fluid Viscosity: " << M_viscosity << std::endl;
576 output <<
"Stabilization coefficient velocity SD jumps: " << M_gammaBeta << std::endl;
577 output <<
"Stabilization coefficient velocity divergence jumps: " << M_gammaDiv << std::endl;
578 output <<
"Stabilization coefficient pressure gradient jumps: " << M_gammaPress << std::endl;
579 M_mesh->showMe (output);
580 M_dof->showMe (output);
586 template<
typename MeshType,
typename DofType>
590 M_feOnSide1.reset (
new CurrentFE (refFE, getGeometricMap (*M_mesh), quadRule) );
591 M_feOnSide2.reset (
new CurrentFE (refFE, getGeometricMap (*M_mesh), quadRule) );
594 M_facetToPoint = MeshType::elementShape_Type::facetToPoint;
597 template<
typename MeshType,
typename DofType>
598 template<
typename MapType>
599 void StabilizationIP<MeshType, DofType>::setFeSpaceVelocity (FESpace<mesh_Type, MapType>& feSpaceVelocity)
601 setMesh (feSpaceVelocity.mesh() );
602 setDiscretization (feSpaceVelocity.dofPtr(), feSpaceVelocity.refFE(),
603 feSpaceVelocity.feBd(), feSpaceVelocity.qr() );
void start()
Start the timer.
Real diffCumul()
Return a cumulative time difference.
A class for a finite element on a manifold.
void updateInverseJacobian(const UInt &iQuadPt)
#define USE_OLD_PARAMETERS
double Real
Generic real data.
The class for a reference Lagrangian finite element.
NdebugStream noDebugStream(int=0, NdebugStream::stprintf=&printf)
void stop()
Stop the timer.
QuadratureRule - The basis class for storing and accessing quadrature rules.
uint32_type UInt
generic unsigned integer (used mainly for addressing)