v0.14.0
NavierStokesElement.hpp

Implementation of operators for fluid flowImplementation of operators for computations of the fluid flow, governed by for Stokes and Navier-Stokes equations, and computation of the drag force

/**
* \file NavierStokesElement.hpp
* \example NavierStokesElement.hpp
*
* \brief Implementation of operators for fluid flow
*
* Implementation of operators for computations of the fluid flow, governed by
* for Stokes and Navier-Stokes equations, and computation of the drag force
*/
#ifndef __NAVIERSTOKESELEMENT_HPP__
#define __NAVIERSTOKESELEMENT_HPP__
#ifndef __BASICFINITEELEMENTS_HPP__
#endif // __BASICFINITEELEMENTS_HPP__
using namespace boost::numeric;
/**
* @brief Element for simulating viscous fluid flow
*/
using PostProcVol =
PostProcBrokenMeshInMoab<VolumeElementForcesAndSourcesCore>;
using PostProcFace =
PostProcBrokenMeshInMoab<FaceElementForcesAndSourcesCore>;
struct BlockData {
int iD;
double fluidViscosity;
double fluidDensity;
double inertiaCoef;
double viscousCoef;
Range eNts;
: iD(-1), fluidViscosity(-1), fluidDensity(-1), inertiaCoef(-1),
viscousCoef(-1) {}
};
struct CommonData {
boost::shared_ptr<MatrixDouble> gradVelPtr;
boost::shared_ptr<MatrixDouble> velPtr;
boost::shared_ptr<VectorDouble> pressPtr;
boost::shared_ptr<MatrixDouble> pressureDragTract;
boost::shared_ptr<MatrixDouble> shearDragTract;
boost::shared_ptr<MatrixDouble> totalDragTract;
SmartPetscObj<Vec> pressureDragForceVec;
SmartPetscObj<Vec> shearDragForceVec;
SmartPetscObj<Vec> totalDragForceVec;
SmartPetscObj<Vec> volumeFluxVec;
std::map<int, BlockData> setOfBlocksData;
std::map<int, BlockData> setOfFacesData;
gradVelPtr = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
velPtr = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
pressPtr = boost::shared_ptr<VectorDouble>(new VectorDouble());
pressureDragTract = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
shearDragTract = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
totalDragTract = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
int vec_size;
if (m_field.get_comm_rank() == 0)
vec_size = 3;
else
vec_size = 0;
pressureDragForceVec = createVectorMPI(m_field.get_comm(), vec_size, 3);
shearDragForceVec = createVectorMPI(m_field.get_comm(), vec_size, 3);
totalDragForceVec = createVectorMPI(m_field.get_comm(), vec_size, 3);
volumeFluxVec = createVectorMPI(m_field.get_comm(), vec_size, 3);
}
MoFEMErrorCode getParameters() {
CHKERR PetscOptionsBegin(PETSC_COMM_WORLD, "", "Problem", "none");
ierr = PetscOptionsEnd();
CHKERRQ(ierr);
}
};
struct LoadScale : public MethodForForceScaling {
static double lambda;
MoFEMErrorCode scaleNf(const FEMethod *fe, VectorDouble &nf) {
nf *= lambda;
}
};
/**
* @brief Setting up elements
*
* This functions adds element to the database, adds provided fields to rows
* and columns of the element, provides access of the element to the fields
* data and adds entities of particular dimension (or a given range of
* entities to the element)
*
* @param m_field MoFEM interface
* @param element_name Name of the element
* @param velocity_field_name Name of the velocity field
* @param pressure_field_name Name of the pressure field
* @param mesh_field_name Name for mesh node positions field
* @param ents Range of entities to be added to element
* @return Error code
*/
static MoFEMErrorCode addElement(MoFEM::Interface &m_field,
const string element_name,
const string velocity_field_name,
const string pressure_field_name,
const string mesh_field_name,
const int dim = 3,
Range *ents = nullptr) {
CHKERR m_field.add_finite_element(element_name);
velocity_field_name);
velocity_field_name);
velocity_field_name);
pressure_field_name);
pressure_field_name);
pressure_field_name);
mesh_field_name);
if (ents != nullptr) {
element_name);
} else {
CHKERR m_field.add_ents_to_finite_element_by_dim(0, dim, element_name);
}
}
/**
* @brief Setting up operators for solving Navier-Stokes equations
*
* Pushes operators for solving Navier-Stokes equations to pipelines of RHS
* and LHS element instances
*
* @param feRhs pointer to RHS element instance
* @param feLhs pointer to LHS element instance
* @param velocity_field name of the velocity field
* @param pressure_field name of the pressure field
* @param common_data pointer to common data object
* @param type type of entities in the domain
* @return Error code
*/
static MoFEMErrorCode setNavierStokesOperators(
boost::shared_ptr<VolumeElementForcesAndSourcesCore> feRhs,
boost::shared_ptr<VolumeElementForcesAndSourcesCore> feLhs,
const std::string velocity_field, const std::string pressure_field,
boost::shared_ptr<CommonData> common_data, const EntityType type = MBTET);
/**
* @brief Setting up operators for solving Stokes equations
*
* Pushes operators for solving Stokes equations to pipelines of RHS
* and LHS element instances
*
* @param feRhs pointer to RHS element instance
* @param feLhs pointer to LHS element instance
* @param velocity_field name of the velocity field
* @param pressure_field name of the pressure field
* @param common_data pointer to common data object
* @param type type of entities in the domain
* @return Error code
*/
static MoFEMErrorCode setStokesOperators(
boost::shared_ptr<VolumeElementForcesAndSourcesCore> feRhs,
boost::shared_ptr<VolumeElementForcesAndSourcesCore> feLhs,
const std::string velocity_field, const std::string pressure_field,
boost::shared_ptr<CommonData> common_data, const EntityType type = MBTET);
/**
* @brief Setting up operators for calculating drag force on the solid surface
*
* Pushes operators for caluclating drag force components on the fluid-solid
* interface
*
* @param dragFe pointer to face element instance
* @param sideDragFe pointer to volume on side element instance
* @param velocity_field name of the velocity field
* @param pressure_field name of the pressure field
* @param common_data pointer to common data object
* @return Error code
*/
static MoFEMErrorCode setCalcDragOperators(
boost::shared_ptr<FaceElementForcesAndSourcesCore> dragFe,
boost::shared_ptr<VolumeElementForcesAndSourcesCoreOnSide> sideDragFe,
std::string side_fe_name, const std::string velocity_field,
const std::string pressure_field,
boost::shared_ptr<CommonData> common_data);
/**
* @brief Setting up operators for post processing output of drag traction
*
* Pushes operators for post processing ouput of drag traction components on
* the fluid-solid interface
*
* @param dragFe pointer to face element instance
* @param sideDragFe pointer to volume on side element instance
* @param velocity_field name of the velocity field
* @param pressure_field name of the pressure field
* @param common_data pointer to common data object
* @return Error code
*/
static MoFEMErrorCode setPostProcDragOperators(
boost::shared_ptr<PostProcFace> postProcDragPtr,
boost::shared_ptr<VolumeElementForcesAndSourcesCoreOnSide> sideDragFe,
std::string side_fe_name, const std::string velocity_field,
const std::string pressure_field,
boost::shared_ptr<CommonData> common_data);
/**
* @brief Setting up operators for calculation of volume flux
*/
static MoFEMErrorCode setCalcVolumeFluxOperators(
boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_flux_ptr,
const std::string velocity_field,
boost::shared_ptr<CommonData> common_data, const EntityType type = MBTET);
/**
* \brief Set integration rule to volume elements
*
* Integration rule is order of polynomial which is calculated exactly.
* Finite element selects integration method based on return of this
* function.
*
*/
struct VolRule {
int operator()(int order_row, int order_col, int order_data) const {
return 2 * order_data;
}
};
struct FaceRule {
int operator()(int order_row, int order_col, int order_data) const {
return order_data + 2;
}
};
/**
* \brief Base class for operators assembling LHS
*/
struct OpAssembleLhs : public UserDataOperator {
boost::shared_ptr<CommonData> commonData;
MatrixDouble locMat;
BlockData &blockData;
bool diagonalBlock;
int row_nb_dofs;
int col_nb_dofs;
int row_nb_gauss_pts;
bool isOnDiagonal;
OpAssembleLhs(const string field_name_row, const string field_name_col,
boost::shared_ptr<CommonData> common_data,
BlockData &block_data)
: UserDataOperator(field_name_row, field_name_col,
commonData(common_data), blockData(block_data) {
sYmm = false;
diagonalBlock = false;
};
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
EntityType col_type, EntData &row_data,
EntData &col_data);
virtual MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data) {
};
MoFEMErrorCode aSsemble(EntData &row_data, EntData &col_data);
};
/**
* @brief Assemble off-diagonal block of the LHS
* Operator for assembling off-diagonal block of the LHS
*/
struct OpAssembleLhsOffDiag : public OpAssembleLhs {
OpAssembleLhsOffDiag(const string field_name_row,
const string field_name_col,
boost::shared_ptr<CommonData> common_data,
BlockData &block_data)
: OpAssembleLhs(field_name_row, field_name_col, common_data,
block_data) {
sYmm = false;
diagonalBlock = false;
};
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data);
};
/**
* @brief Assemble linear (symmetric) part of the diagonal block of the LHS
* Operator for assembling linear (symmetric) part of the diagonal block of
* the LHS
*/
struct OpAssembleLhsDiagLin : public OpAssembleLhs {
OpAssembleLhsDiagLin(const string field_name_row,
const string field_name_col,
boost::shared_ptr<CommonData> common_data,
BlockData &block_data)
: OpAssembleLhs(field_name_row, field_name_col, common_data,
block_data) {
sYmm = true;
diagonalBlock = true;
};
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data);
};
/**
* @brief Assemble non-linear (non-symmetric) part of the diagonal block of
* the LHS Operator for assembling non-linear (non-symmetric) part of the
* diagonal block of the LHS
*/
struct OpAssembleLhsDiagNonLin : public OpAssembleLhs {
OpAssembleLhsDiagNonLin(const string field_name_row,
const string field_name_col,
boost::shared_ptr<CommonData> common_data,
BlockData &block_data)
: OpAssembleLhs(field_name_row, field_name_col, common_data,
block_data) {
sYmm = false;
diagonalBlock = true;
};
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data);
};
/**
* \brief Base class for operators assembling RHS
*/
struct OpAssembleRhs : public UserDataOperator {
boost::shared_ptr<CommonData> commonData;
BlockData &blockData;
int nbRows; ///< number of dofs on row
int nbIntegrationPts;
VectorDouble locVec;
OpAssembleRhs(const string field_name,
boost::shared_ptr<CommonData> common_data,
BlockData &block_data)
commonData(common_data), blockData(block_data){};
MoFEMErrorCode doWork(int row_side, EntityType row_type, EntData &row_data);
virtual MoFEMErrorCode iNtegrate(EntData &data) {
};
MoFEMErrorCode aSsemble(EntData &data);
};
/**
* @brief Assemble linear part of the velocity component of the RHS vector
*
* Operator for assembling linear part of the velocity component of the RHS
* vector:
* \f[ \mathbf{R}^{\textrm{S}}_{\mathbf{u}} =
* C_\text{V}\int\limits_{\Omega}\nabla\mathbf{u}\mathbin{:}\nabla\mathbf{v}\,
* d\Omega
* \f]
* where \f$C_\text{V}\f$ is the viscosity
* coefficient: \f$C_\text{V}=\mu\f$ in the dimensional case and
* \f$C_\text{V}=1\f$ in the non-dimensional case.
*/
struct OpAssembleRhsVelocityLin : public OpAssembleRhs {
OpAssembleRhsVelocityLin(const string field_name,
boost::shared_ptr<CommonData> common_data,
BlockData &block_data)
: OpAssembleRhs(field_name, common_data, block_data){};
/**
* \brief Integrate local entity vector
* @param data entity data on element row
* @return error code
*/
MoFEMErrorCode iNtegrate(EntData &data);
};
/**
* @brief Assemble non-linear part of the velocity component of the RHS vector
*
* Operator for assembling non-linear part of the velocity component of the
* RHS vector:
* \f[
* \mathbf{R}^{\textrm{NS}}_{\mathbf{u}} =
* C_\text{I}\int\limits_\Omega \left(\mathbf{u}\cdot\nabla\right)\mathbf{u}
* \cdot\mathbf{v} \,d\Omega,
* \f]
* where \f$C_\text{I}\f$ is the inertia
* coefficient: \f$C_\text{V}=\rho\f$ in the dimensional case and
* \f$C_\text{V}=\mathcal{R}\f$ in the non-dimensional case.
*/
struct OpAssembleRhsVelocityNonLin : public OpAssembleRhs {
OpAssembleRhsVelocityNonLin(const string field_name,
boost::shared_ptr<CommonData> common_data,
BlockData &block_data)
: OpAssembleRhs(field_name, common_data, block_data){};
MoFEMErrorCode iNtegrate(EntData &data);
};
/**
* @brief Assemble the pressure component of the RHS vector
*
* Operator for assembling pressure component of the RHS vector:
* \f[
* \mathbf{R}^{\textrm{S}}_{p} = -\int\limits_{\Omega}p\,
* \nabla\cdot\mathbf{v} \, d\Omega
* \f]
*/
struct OpAssembleRhsPressure : public OpAssembleRhs {
OpAssembleRhsPressure(const string field_name,
boost::shared_ptr<CommonData> common_data,
BlockData &block_data)
: OpAssembleRhs(field_name, common_data, block_data){};
/**
* \brief Integrate local constrains vector
*/
MoFEMErrorCode iNtegrate(EntData &data);
};
/**
* @brief Calculate drag force on the fluid-solid interface
*
* Operator fo calculating drag force components on the fluid-solid interface.
* Integrates components of the drag traction:
* \f[
* \mathbf{F}_{\textrm{D}} =
* -\int\limits_{\Gamma_{\textrm{S}}}\left(-p\mathbf{I} +
* \mu\left(\nabla\mathbf{u}+\mathbf{u}^{\intercal}\right)\right) \, d\Gamma
* \f]
*/
struct OpCalcDragForce : public FaceUserDataOperator {
boost::shared_ptr<CommonData> commonData;
BlockData &blockData;
OpCalcDragForce(const string field_name,
boost::shared_ptr<CommonData> &common_data,
BlockData &block_data)
commonData(common_data), blockData(block_data) {
doVertices = true;
doEdges = false;
doQuads = false;
doTris = false;
doTets = false;
doPrisms = false;
};
MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
};
/**
* @brief Calculate drag traction on the fluid-solid interface
*
* Operator fo calculating drag traction on the fluid-solid interface
* \f[
* \mathbf{t} = -p\mathbf{I} +
* \mu\left(\nabla\mathbf{u}+\mathbf{u}^{\intercal}\right)
* \f]
*/
struct OpCalcDragTraction : public FaceUserDataOperator {
boost::shared_ptr<CommonData> commonData;
BlockData &blockData;
boost::shared_ptr<VolumeElementForcesAndSourcesCoreOnSide> sideFe;
std::string sideFeName;
OpCalcDragTraction(
const string field_name,
boost::shared_ptr<VolumeElementForcesAndSourcesCoreOnSide> &side_fe,
std::string side_fe_name, boost::shared_ptr<CommonData> &common_data,
BlockData &block_data)
sideFe(side_fe), sideFeName(side_fe_name), commonData(common_data),
blockData(block_data) {
doVertices = true;
doEdges = false;
doQuads = false;
doTris = false;
doTets = false;
doPrisms = false;
};
MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
};
/**
* @brief Post processing output of drag traction on the fluid-solid interface
*
*/
struct OpPostProcDrag : public FaceUserDataOperator {
boost::shared_ptr<CommonData> commonData;
moab::Interface &postProcMesh;
std::vector<EntityHandle> &mapGaussPts;
BlockData &blockData;
OpPostProcDrag(const string field_name, moab::Interface &post_proc_mesh,
std::vector<EntityHandle> &map_gauss_pts,
boost::shared_ptr<CommonData> &common_data,
BlockData &block_data)
commonData(common_data), postProcMesh(post_proc_mesh),
mapGaussPts(map_gauss_pts), blockData(block_data) {
doVertices = true;
doEdges = false;
doQuads = false;
doTris = false;
doTets = false;
doPrisms = false;
};
MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
};
/**
* @brief Post processing output of the vorticity criterion levels
*
*/
struct OpPostProcVorticity : public UserDataOperator {
boost::shared_ptr<CommonData> commonData;
moab::Interface &postProcMesh;
std::vector<EntityHandle> &mapGaussPts;
BlockData &blockData;
OpPostProcVorticity(moab::Interface &post_proc_mesh,
std::vector<EntityHandle> &map_gauss_pts,
boost::shared_ptr<CommonData> &common_data,
BlockData &block_data)
commonData(common_data), postProcMesh(post_proc_mesh),
mapGaussPts(map_gauss_pts), blockData(block_data) {
doVertices = true;
doEdges = false;
doQuads = false;
doTris = false;
doTets = false;
doPrisms = false;
};
MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
};
/**
* @brief calculating volumetric flux
*
*/
struct OpCalcVolumeFlux : public UserDataOperator {
boost::shared_ptr<CommonData> commonData;
BlockData &blockData;
int nbRows; ///< number of dofs on row
int nbIntegrationPts;
OpCalcVolumeFlux(const string field_name,
boost::shared_ptr<CommonData> common_data,
BlockData &block_data)
commonData(common_data), blockData(block_data){};
MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
};
};
#endif //__NAVIERSTOKESELEMENT_HPP__
MoFEM::EntitiesFieldData::EntData
Data on single entity (This is passed as argument to DataOperator::doWork)
Definition: EntitiesFieldData.hpp:127
PostProcVol
PostProcBrokenMeshInMoab< VolumeElementForcesAndSourcesCore > PostProcVol
Definition: navier_stokes.cpp:10
MoFEM::CoreInterface::get_comm
virtual MPI_Comm & get_comm() const =0
MoFEM::CoreInterface::modify_finite_element_add_field_row
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
MoFEM::Types::MatrixDouble
UBlasMatrix< double > MatrixDouble
Definition: Types.hpp:77
MoFEM::CoreInterface::get_comm_rank
virtual int get_comm_rank() const =0
VolRule
Set integration rule.
Definition: simple_interface.cpp:88
BasicFiniteElements.hpp
PostProcFace
PostProcBrokenMeshInMoab< FaceElementForcesAndSourcesCore > PostProcFace
Definition: navier_stokes.cpp:11
MoFEM::ForcesAndSourcesCore::UserDataOperator::OPROWCOL
@ OPROWCOL
operator doWork is executed on FE rows &columns
Definition: ForcesAndSourcesCore.hpp:569
FTensor::Tensor2< double, 3, 3 >
MoFEM::DeprecatedCoreInterface
Deprecated interface functions.
Definition: DeprecatedCoreInterface.hpp:16
MoFEM::Interface
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1975
FEMethod
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:535
MoFEM::FaceElementForcesAndSourcesCore::UserDataOperator
friend class UserDataOperator
Definition: FaceElementForcesAndSourcesCore.hpp:86
MoFEM::CoreInterface::add_finite_element
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
MoFEM::CoreInterface::modify_finite_element_add_field_col
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
BlockData
Definition: gel_analysis.cpp:74
MoFEM::ForcesAndSourcesCore::UserDataOperator
Definition: ForcesAndSourcesCore.hpp:549
convert.type
type
Definition: convert.py:64
MoFEM::VolumeElementForcesAndSourcesCore::UserDataOperator
friend class UserDataOperator
Definition: VolumeElementForcesAndSourcesCore.hpp:105
MethodForForceScaling
Class used to scale loads, f.e. in arc-length control.
Definition: MethodForForceScaling.hpp:11
FaceRule
Set integration rule to boundary elements.
Definition: simple_interface.cpp:91
MoFEM::CoreInterface::add_ents_to_finite_element_by_dim
virtual MoFEMErrorCode add_ents_to_finite_element_by_dim(const EntityHandle entities, const int dim, const std::string &name, const bool recursive=true)=0
add entities to finite element
EshelbianPlasticity::FaceUserDataOperator
FaceElementForcesAndSourcesCore::UserDataOperator FaceUserDataOperator
Definition: EshelbianPlasticity.hpp:29
EntData
EntitiesFieldData::EntData EntData
Definition: child_and_parent.cpp:37
field_name
constexpr auto field_name
Definition: poisson_2d_homogeneous.cpp:13
Range
UserDataOperator
ForcesAndSourcesCore::UserDataOperator UserDataOperator
Definition: HookeElement.hpp:75
CommonData
Definition: continuity_check_on_skeleton_with_simple_2d_for_h1.cpp:22
MoFEM::Exceptions::ierr
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
Definition: Exceptions.hpp:76
lambda
static double lambda
Definition: incompressible_elasticity.cpp:199
NavierStokesElement
Element for simulating viscous fluid flow.
Definition: NavierStokesElement.hpp:25
MoFEM::createVectorMPI
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
Definition: PetscSmartObj.hpp:198
MoFEM::CoreInterface::modify_finite_element_add_field_data
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_filed)=0
set finite element field data
MoFEM::Types::VectorDouble
UBlasVector< double > VectorDouble
Definition: Types.hpp:68
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
MoFEMFunctionBegin
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:346
BlockData
NonlinearElasticElement::BlockData BlockData
Definition: elasticity.cpp:74
MoFEM::ForcesAndSourcesCore::UserDataOperator::OPROW
@ OPROW
operator doWork function is executed on FE rows
Definition: ForcesAndSourcesCore.hpp:567