v0.15.0
Loading...
Searching...
No Matches
mofem/tutorials/vec-6/plate.cpp

Implementation Kirchhoff-Love plate using Discointinous Galerkin (DG-Nitsche method)

/**
* \file plate.cpp
* \example mofem/tutorials/vec-6/plate.cpp
*
* Implementation Kirchhoff-Love plate using Discointinous Galerkin (DG-Nitsche
* method)
*/
#include <MoFEM.hpp>
using namespace MoFEM;
static char help[] = "...\n\n";
constexpr int BASE_DIM = 1; ///< dimension of base
constexpr int SPACE_DIM = 2; ///< dimension of space
constexpr int FIELD_DIM = 1; ///< dimension of approx. field
template <int DIM> struct ElementsAndOps {};
template <> struct ElementsAndOps<2> {
using FaceSideOp = FaceSideEle::UserDataOperator;
};
using DomainEleOp = DomainEle::UserDataOperator;
using BoundaryEleOp = BoundaryEle::UserDataOperator;
using DomainEleOp =
DomainEle::UserDataOperator; ///< Finire element operator type
using EntData = EntitiesFieldData::EntData; ///< Data on entities
GAUSS>::OpGradGradSymTensorGradGrad<1, 1, SPACE_DIM, 0>;
// Kronecker delta
// material parameters
constexpr double lambda = 1;
constexpr double mu = 1; ///< lame parameter
constexpr double t = 1; ///< plate stiffness
static double penalty = 1e6;
static double phi =
-1; // 1 - symmetric Nitsche, 0 - nonsymmetric, -1 antisymmetrica
static double nitsche = 1;
static int order = 4; // approximation order
auto source = [](const double x, const double y, const double) {
return cos(2 * x * M_PI) * sin(2 * y * M_PI);
};
/**
* @brief get fourth-order constitutive tensor
*
*/
auto plate_stiffness = []() {
constexpr auto a = (SPACE_DIM * (SPACE_DIM + 1)) / 2;
auto mat_D_ptr = boost::make_shared<MatrixDouble>(a * a, 1);
auto t_D = getFTensor4DdgFromMat<2, 2, 0>(*(mat_D_ptr));
constexpr double t3 = t * t * t;
constexpr double A = mu * t3 / 12;
constexpr double B = lambda * t3 / 12;
t_D(i, j, k, l) =
2 * B * ((t_kd(i, k) ^ t_kd(j, l)) / 4.) + A * t_kd(i, j) * t_kd(k, l);
// t_D(i, j, k, l) = (t_kd(i, k) ^ t_kd(j, l)) / 4.;
return mat_D_ptr;
};
// data for skeleton computation
std::array<std::vector<VectorInt>, 2>
indicesSideMap; ///< indices on rows for left hand-side
std::array<std::vector<MatrixDouble>, 2>
diffBaseSideMap; // first derivative of base functions
std::array<std::vector<MatrixDouble>, 2>
diff2BaseSideMap; // second derivative of base functions
std::array<double, 2> areaMap; // area/volume of elements on the side
std::array<int, 2> senseMap; // orientaton of local element edge/face in respect
// to global orientation of edge/face
/**
* @brief Operator tp collect data from elements on the side of Edge/Face
*
*/
OpCalculateSideData(std::string field_name, std::string col_field_name);
MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
};
/**
* @brief Operator the left hand side matrix
*
*/
struct OpH1LhsSkeleton : public BoundaryEleOp {
public:
/**
* @brief Construct a new OpH1LhsSkeleton
*
* @param side_fe_ptr pointer to FE to evaluate side elements
*/
OpH1LhsSkeleton(boost::shared_ptr<FaceSideEle> side_fe_ptr,
boost::shared_ptr<MatrixDouble> d_mat_ptr);
MoFEMErrorCode doWork(int side, EntityType type,
private:
boost::shared_ptr<FaceSideEle>
sideFEPtr; ///< pointer to element to get data on edge/face sides
MatrixDouble locMat; ///< local operator matrix
boost::shared_ptr<MatrixDouble> dMatPtr;
};
struct Plate {
Plate(MoFEM::Interface &m_field) : mField(m_field) {}
private:
};
//! [Read mesh]
CHKERR simple->loadFile();
}
//! [Read mesh]
//! [Set up problem]
CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &order, PETSC_NULLPTR);
CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-penalty", &penalty,
PETSC_NULLPTR);
CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-phi", &phi, PETSC_NULLPTR);
CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-nitsche", &nitsche,
PETSC_NULLPTR);
MOFEM_LOG("WORLD", Sev::inform) << "Set order: " << order;
MOFEM_LOG("WORLD", Sev::inform) << "Set penalty: " << penalty;
MOFEM_LOG("WORLD", Sev::inform) << "Set phi: " << phi;
MOFEM_LOG("WORLD", Sev::inform) << "Set nitche: " << nitsche;
CHKERR simple->addSkeletonField("U", H1, AINSWORTH_LEGENDRE_BASE, FIELD_DIM);
CHKERR simple->addBoundaryField("U", H1, AINSWORTH_LEGENDRE_BASE, FIELD_DIM);
CHKERR simple->setFieldOrder("U", order);
CHKERR simple->setUp();
}
//! [Set up problem]
//! [Boundary condition]
// get edges and vertices on body skin
auto get_skin = [&]() {
Range body_ents;
mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, body_ents));
Skinner skin(&mField.get_moab());
Range skin_ents;
MOAB_THROW(skin.find_skin(0, body_ents, false, skin_ents));
Range verts;
MOAB_THROW(mField.get_moab().get_connectivity(skin_ents, verts, true));
skin_ents.merge(verts);
return skin_ents;
};
// remove dofs on skin edges from priblem
auto remove_dofs_from_problem = [&](Range &&skin) {
auto problem_mng = mField.getInterface<ProblemsManager>();
CHKERR problem_mng->removeDofsOnEntities(simple->getProblemName(), "U",
skin, 0, 1);
};
// it make plate simply supported
CHKERR remove_dofs_from_problem(get_skin());
}
//! [Boundary condition]
//! [Push operators to pipeline]
auto pipeline_mng = mField.getInterface<PipelineManager>();
auto rule_lhs = [](int, int, int p) -> int { return 2 * p; };
auto rule_rhs = [](int, int, int p) -> int { return 2 * p; };
auto rule_2 = [this](int, int, int) { return 2 * order; };
CHKERR pipeline_mng->setDomainLhsIntegrationRule(rule_lhs);
CHKERR pipeline_mng->setDomainRhsIntegrationRule(rule_rhs);
CHKERR pipeline_mng->setSkeletonLhsIntegrationRule(rule_2);
CHKERR pipeline_mng->setSkeletonRhsIntegrationRule(rule_2);
CHKERR pipeline_mng->setBoundaryLhsIntegrationRule(rule_2);
CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(rule_2);
auto det_ptr = boost::make_shared<VectorDouble>();
auto jac_ptr = boost::make_shared<MatrixDouble>();
auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
auto base_mass_ptr = boost::make_shared<MatrixDouble>();
auto data_l2_ptr = boost::make_shared<EntitiesFieldData>(MBENTITYSET);
auto mat_D_ptr = plate_stiffness();
auto push_ho_direcatives = [&](auto &pipeline) {
pipeline.push_back(new OpBaseDerivativesMass<BASE_DIM>(
base_mass_ptr, data_l2_ptr, AINSWORTH_LEGENDRE_BASE, L2));
pipeline.push_back(new OpBaseDerivativesNext<BASE_DIM>(
BaseDerivatives::SecondDerivative, base_mass_ptr, data_l2_ptr,
};
/**
* @brief calculate jacobian
*
*/
auto push_jacobian = [&](auto &pipeline) {
pipeline.push_back(new OpSetHOWeightsOnFace());
pipeline.push_back(new OpCalculateHOJac<SPACE_DIM>(jac_ptr));
pipeline.push_back(
new OpInvertMatrix<SPACE_DIM>(jac_ptr, det_ptr, inv_jac_ptr));
// push first base derivatives tp physical element shape
pipeline.push_back(new OpSetInvJacH1ForFace<1>(inv_jac_ptr));
// push second base derivatives tp physical element shape
pipeline.push_back(new OpSetInvJacH1ForFace<2>(inv_jac_ptr));
};
push_ho_direcatives(pipeline_mng->getOpDomainLhsPipeline());
push_jacobian(pipeline_mng->getOpDomainLhsPipeline());
pipeline_mng->getOpDomainLhsPipeline().push_back(
new OpDomainPlateStiffness("U", "U", mat_D_ptr));
// pipeline_mng->getOpDomainLhsPipeline().push_back(new OpDomainGradGrad(
// "U", "U", [](const double, const double, const double) { return 1; }));
pipeline_mng->getOpDomainRhsPipeline().push_back(
// Push operators to the Pipeline for Skeleton
auto side_fe_ptr = boost::make_shared<FaceSideEle>(mField);
push_ho_direcatives(side_fe_ptr->getOpPtrVector());
push_jacobian(side_fe_ptr->getOpPtrVector());
side_fe_ptr->getOpPtrVector().push_back(new OpCalculateSideData("U", "U"));
// Push operators to the Pipeline for Skeleton
pipeline_mng->getOpSkeletonLhsPipeline().push_back(
new OpH1LhsSkeleton(side_fe_ptr, mat_D_ptr));
}
//! [Push operators to pipeline]
//! [Solve system]
auto pipeline_mng = mField.getInterface<PipelineManager>();
auto ksp_solver = pipeline_mng->createKSP();
CHKERR KSPSetFromOptions(ksp_solver);
CHKERR KSPSetUp(ksp_solver);
// Create RHS and solution vectors
auto dm = simple->getDM();
auto F = createDMVector(dm);
auto D = vectorDuplicate(F);
CHKERR KSPSolve(ksp_solver, F, D);
// Scatter result data on the mesh
CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
}
//! [Solve system]
//! [Output results]
auto pipeline_mng = mField.getInterface<PipelineManager>();
pipeline_mng->getDomainLhsFE().reset();
pipeline_mng->getSkeletonRhsFE().reset();
pipeline_mng->getSkeletonLhsFE().reset();
pipeline_mng->getBoundaryRhsFE().reset();
pipeline_mng->getBoundaryLhsFE().reset();
auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
auto u_ptr = boost::make_shared<VectorDouble>();
post_proc_fe->getOpPtrVector().push_back(
new OpCalculateScalarFieldValues("U", u_ptr));
post_proc_fe->getOpPtrVector().push_back(
new OpPPMap(post_proc_fe->getPostProcMesh(),
post_proc_fe->getMapGaussPts(),
{{"U", u_ptr}},
{}, {}, {}
)
);
pipeline_mng->getDomainRhsFE() = post_proc_fe;
CHKERR pipeline_mng->loopFiniteElements();
CHKERR post_proc_fe->writeFile("out_result.h5m");
}
//! [Output results]
//! [Run program]
// CHKERR checkResults();
}
//! [Run program]
int main(int argc, char *argv[]) {
// Initialisation of MoFEM/PETSc and MOAB data structures
const char param_file[] = "param_file.petsc";
MoFEM::Core::Initialize(&argc, &argv, param_file, help);
// Add logging channel for example
auto core_log = logging::core::get();
core_log->add_sink(LogManager::createSink(LogManager::getStrmWorld(), "PL"));
LogManager::setLog("PL");
MOFEM_LOG_TAG("PL", "plate");
try {
//! [Register MoFEM discrete manager in PETSc]
DMType dm_name = "DMMOFEM";
//! [Register MoFEM discrete manager in PETSc
//! [Create MoAB]
moab::Core mb_instance; ///< mesh database
moab::Interface &moab = mb_instance; ///< mesh database interface
//! [Create MoAB]
//! [Create MoFEM]
MoFEM::Core core(moab); ///< finite element database
MoFEM::Interface &m_field = core; ///< finite element database insterface
//! [Create MoFEM]
//! [Plate]
Plate ex(m_field);
CHKERR ex.runProblem();
//! [Plate]
}
}
OpCalculateSideData::OpCalculateSideData(std::string row_field_name,
std::string col_field_name)
: FaceSideOp(row_field_name, col_field_name, FaceSideOp::OPROW) {}
MoFEMErrorCode OpCalculateSideData::doWork(int side, EntityType type,
EntData &data) {
const auto nb_in_loop = getFEMethod()->nInTheLoop;
auto clear = [](auto nb) {
indicesSideMap[nb].clear();
diffBaseSideMap[nb].clear();
diff2BaseSideMap[nb].clear();
};
if (type == MBVERTEX) {
areaMap[nb_in_loop] = getMeasure();
senseMap[nb_in_loop] = getSkeletonSense();
if (!nb_in_loop) {
clear(0);
clear(1);
areaMap[1] = 0;
senseMap[1] = 0;
}
}
const auto nb_dofs = data.getIndices().size();
if (nb_dofs) {
indicesSideMap[nb_in_loop].push_back(data.getIndices());
diffBaseSideMap[nb_in_loop].push_back(
data.getN(BaseDerivatives::FirstDerivative));
diff2BaseSideMap[nb_in_loop].push_back(
data.getN(BaseDerivatives::SecondDerivative));
}
}
template <typename T> inline auto get_ntensor(T &base_mat) {
&*base_mat.data().begin());
};
template <typename T> inline auto get_ntensor(T &base_mat, int gg, int bb) {
double *ptr = &base_mat(gg, bb);
};
template <typename T> inline auto get_diff_ntensor(T &base_mat) {
double *ptr = &*base_mat.data().begin();
return getFTensor1FromPtr<2>(ptr);
};
template <typename T>
inline auto get_diff_ntensor(T &base_mat, int gg, int bb) {
double *ptr = &base_mat(gg, 2 * bb);
return getFTensor1FromPtr<2>(ptr);
};
template <typename T> inline auto get_diff2_ntensor(T &base_mat) {
double *ptr = &*base_mat.data().begin();
return getFTensor2SymmetricLowerFromPtr<2>(ptr);
};
template <typename T>
inline auto get_diff2_ntensor(T &base_mat, int gg, int bb) {
double *ptr = &base_mat(gg, 4 * bb);
return getFTensor2SymmetricLowerFromPtr<2>(ptr);
};
/**
* @brief Construct a new OpH1LhsSkeleton
*
* @param side_fe_ptr pointer to FE to evaluate side elements
*/
OpH1LhsSkeleton::OpH1LhsSkeleton(boost::shared_ptr<FaceSideEle> side_fe_ptr,
boost::shared_ptr<MatrixDouble> mat_d_ptr)
: BoundaryEleOp(NOSPACE, BoundaryEleOp::OPSPACE), sideFEPtr(side_fe_ptr),
dMatPtr(mat_d_ptr) {}
MoFEMErrorCode OpH1LhsSkeleton::doWork(int side, EntityType type,
// Collect data from side domian elements
CHKERR loopSideFaces("dFE", *sideFEPtr);
const auto in_the_loop =
sideFEPtr->nInTheLoop; // return number of elements on the side
// calculate penalty
const double s = getMeasure() / (areaMap[0] + areaMap[1]);
const double p = penalty * s;
// get normal of the face or edge
auto t_normal = getFTensor1Normal();
t_normal.normalize();
// Elastic stiffness tensor (4th rank tensor with minor and major
// symmetry)
auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(*dMatPtr);
// get number of integration points on face
const size_t nb_integration_pts = getGaussPts().size2();
// beta paramter is zero, when penalty method is used, also, takes value 1,
// when boundary edge/face is evaluated, and 2 when is skeleton edge/face.
const double beta = static_cast<double>(nitsche) / (in_the_loop + 1);
auto integrate = [&](auto sense_row, auto &row_ind, auto &row_diff,
auto &row_diff2, auto sense_col, auto &col_ind,
auto &col_diff, auto &col_diff2) {
// number of dofs, for homogenous approximation this value is
// constant.
const auto nb_rows = row_ind.size();
const auto nb_cols = col_ind.size();
const auto nb_row_base_functions = row_diff.size2() / SPACE_DIM;
if (nb_cols) {
// resize local element matrix
locMat.resize(nb_rows, nb_cols, false);
locMat.clear();
// get base functions, and integration weights
auto t_diff_row_base = get_diff_ntensor(row_diff);
auto t_diff2_row_base = get_diff2_ntensor(row_diff2);
auto t_w = getFTensor0IntegrationWeight();
// iterate integration points on face/edge
for (size_t gg = 0; gg != nb_integration_pts; ++gg) {
// t_w is integration weight, and measure is element area, or
// volume, depending if problem is in 2d/3d.
const double alpha = getMeasure() * t_w;
auto t_mat = locMat.data().begin();
// iterate rows
size_t rr = 0;
for (; rr != nb_rows; ++rr) {
t_mv(i, j) = t_D(i, j, k, l) * t_diff2_row_base(k, l);
// calculate tetting function
t_vn_plus(i, j) = beta * (phi * t_mv(i, j) / p);
t_vn(i, j) = (t_diff_row_base(j) * (t_normal(i) * sense_row)) -
t_vn_plus(i, j);
// get base functions on columns
auto t_diff_col_base = get_diff_ntensor(col_diff, gg, 0);
auto t_diff2_col_base = get_diff2_ntensor(col_diff2, gg, 0);
// iterate columns
for (size_t cc = 0; cc != nb_cols; ++cc) {
t_mu(i, j) = t_D(i, j, k, l) * t_diff2_col_base(k, l);
// // calculate variance of tested function
t_un(i, j) = -p * ((t_diff_col_base(j) * (t_normal(i) * sense_col) -
beta * t_mu(i, j) / p));
// assemble matrix
*t_mat -= alpha * (t_vn(i, j) * t_un(i, j));
*t_mat -= alpha * (t_vn_plus(i, j) * (beta * t_mu(i, j)));
// move to next column base and element of matrix
++t_diff_col_base;
++t_diff2_col_base;
++t_mat;
}
// move to next row base
++t_diff_row_base;
++t_diff2_row_base;
}
// this is obsolete for this particular example, we keep it for
// generality. in case of multi-physcis problems diffrent fields
// can chare hierarchical base but use diffrent approx. order,
// so is possible to have more base functions than DOFs on
// element.
for (; rr < nb_row_base_functions; ++rr) {
++t_diff_row_base;
++t_diff2_row_base;
}
++t_w;
}
// assemble system
CHKERR ::MatSetValues(getKSPB(), nb_rows, &*row_ind.begin(),
col_ind.size(), &*col_ind.begin(),
&*locMat.data().begin(), ADD_VALUES);
}
};
// iterate the sides rows
for (auto s0 : {LEFT_SIDE, RIGHT_SIDE}) {
const auto sense_row = senseMap[s0];
for (auto x0 = 0; x0 != indicesSideMap[s0].size(); ++x0) {
for (auto s1 : {LEFT_SIDE, RIGHT_SIDE}) {
const auto sense_col = senseMap[s1];
for (auto x1 = 0; x1 != indicesSideMap[s1].size(); ++x1) {
CHKERR integrate(sense_row, indicesSideMap[s0][x0],
sense_col, indicesSideMap[s1][x1],
);
}
}
}
}
}
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
static char help[]
int main()
constexpr double a
constexpr int SPACE_DIM
constexpr int FIELD_DIM
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
Kronecker Delta class symmetric.
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
#define MOAB_THROW(err)
Check error code of MoAB function and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ L2
field with C-1 continuity
Definition definitions.h:88
@ H1
continuous field
Definition definitions.h:85
@ NOSPACE
Definition definitions.h:83
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
constexpr int BASE_DIM
constexpr int order
@ F
constexpr auto t_kd
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
auto createDMVector(DM dm)
Get smart vector from DM.
Definition DMMoFEM.hpp:1234
@ GAUSS
Gaussian quadrature integration.
@ PETSC
Standard PETSc assembly.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
FTensor::Index< 'i', SPACE_DIM > i
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradGrad< 1, 1, SPACE_DIM > OpDomainGradGrad
Definition helmholtz.cpp:25
static double lambda
double D
PipelineManager::ElementsAndOpsByDim< FE_DIM >::FaceSideEle FaceSideEle
Definition level_set.cpp:41
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
constexpr AssemblyType A
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
auto get_diff_ntensor(T &base_mat)
Definition plate.cpp:478
ElementSide
Definition plate.cpp:92
@ LEFT_SIDE
Definition plate.cpp:92
@ RIGHT_SIDE
Definition plate.cpp:92
std::array< std::vector< MatrixDouble >, 2 > diff2BaseSideMap
Definition plate.cpp:100
FTensor::Index< 'j', SPACE_DIM > j
Definition plate.cpp:61
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradGradSymTensorGradGrad< 1, 1, SPACE_DIM, 0 > OpDomainPlateStiffness
Definition plate.cpp:48
std::array< std::vector< MatrixDouble >, 2 > diffBaseSideMap
Definition plate.cpp:98
FTensor::Index< 'k', SPACE_DIM > k
Definition plate.cpp:62
FTensor::Index< 'i', SPACE_DIM > i
Definition plate.cpp:60
auto get_ntensor(T &base_mat)
Definition plate.cpp:468
constexpr int SPACE_DIM
dimension of space
Definition plate.cpp:17
FTensor::Index< 'l', SPACE_DIM > l
Definition plate.cpp:63
auto source
Definition plate.cpp:71
static double nitsche
Definition plate.cpp:68
constexpr int FIELD_DIM
dimension of approx. field
Definition plate.cpp:18
auto plate_stiffness
get fourth-order constitutive tensor
Definition plate.cpp:79
std::array< double, 2 > areaMap
Definition plate.cpp:101
std::array< std::vector< VectorInt >, 2 > indicesSideMap
indices on rows for left hand-side
Definition plate.cpp:96
std::array< int, 2 > senseMap
Definition plate.cpp:102
constexpr double t
plate stiffness
Definition plate.cpp:58
static double penalty
Definition plate.cpp:65
static int order
Definition plate.cpp:69
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< BASE_DIM, FIELD_DIM > OpDomainPlateLoad
Definition plate.cpp:50
static double phi
Definition plate.cpp:66
auto get_diff2_ntensor(T &base_mat)
Definition plate.cpp:489
static double nitsche
static double penalty
static double phi
constexpr auto field_name
virtual moab::Interface & get_moab()=0
Core (interface) class.
Definition Core.hpp:82
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:72
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:118
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
Base face element used to integrate on skeleton.
Specialization for double precision scalar field values calculation.
Operator for inverting matrices at integration points.
Post post-proc data at points from hash maps.
Modify integration weights on face to take into account higher-order geometry.
PipelineManager interface.
boost::shared_ptr< FEMethod > & getDomainLhsFE()
Get domain left-hand side finite element.
MoFEMErrorCode setDomainLhsIntegrationRule(RuleHookFun rule)
Set integration rule for domain left-hand side finite element.
Problem manager is used to build and partition problems.
Simple interface for fast problem set-up.
Definition Simple.hpp:27
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Operator tp collect data from elements on the side of Edge/Face.
Definition plate.cpp:109
OpCalculateSideData(std::string field_name, std::string col_field_name)
Definition plate.cpp:429
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
Definition plate.cpp:433
Operator the left hand side matrix.
Definition plate.cpp:120
boost::shared_ptr< MatrixDouble > dMatPtr
Definition plate.cpp:137
boost::shared_ptr< FaceSideEle > sideFEPtr
pointer to element to get data on edge/face sides
Definition plate.cpp:135
MatrixDouble locMat
local operator matrix
Definition plate.cpp:136
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Definition plate.cpp:510
OpH1LhsSkeleton(boost::shared_ptr< FaceSideEle > side_fe_ptr, boost::shared_ptr< MatrixDouble > d_mat_ptr)
Construct a new OpH1LhsSkeleton.
Definition plate.cpp:505
MoFEMErrorCode setupProblem()
[Read mesh]
Definition plate.cpp:170
MoFEM::Interface & mField
Definition plate.cpp:154
MoFEMErrorCode runProblem()
[Output results]
Definition plate.cpp:375
MoFEMErrorCode boundaryCondition()
[Set up problem]
Definition plate.cpp:199
MoFEMErrorCode outputResults()
[Solve system]
Definition plate.cpp:335
MoFEMErrorCode solveSystem()
[Push operators to pipeline]
Definition plate.cpp:308
MoFEMErrorCode assembleSystem()
[Boundary condition]
Definition plate.cpp:234
MoFEMErrorCode readMesh()
[Read mesh]
Definition plate.cpp:158