47 return cos(2 * x * M_PI) * cos(2 * y * M_PI);
56 -2 * M_PI * cos(2 * M_PI * y) * sin(2 * M_PI * x),
57 -2 * M_PI * cos(2 * M_PI * x) * sin(2 * M_PI * y)
64 return -(2 * x * x + 2 * y * y);
66 return 8 * M_PI * M_PI * cos(2 * x * M_PI) * cos(2 * y * M_PI);
72static char help[] =
"...\n\n";
148 auto save_shared = [&](
auto meshset, std::string prefix) {
179 auto add_base_ops = [&](
auto &pipeline) {
180 auto det_ptr = boost::make_shared<VectorDouble>();
181 auto jac_ptr = boost::make_shared<MatrixDouble>();
182 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
188 add_base_ops(pipeline_mng->getOpDomainLhsPipeline());
191 [](
const double,
const double,
const double) {
return 1; }));
192 pipeline_mng->getOpDomainRhsPipeline().push_back(
196 auto side_fe_ptr = boost::make_shared<FaceSideEle>(
mField);
197 add_base_ops(side_fe_ptr->getOpPtrVector());
198 side_fe_ptr->getOpPtrVector().push_back(
202 pipeline_mng->getOpSkeletonLhsPipeline().push_back(
206 pipeline_mng->getOpBoundaryLhsPipeline().push_back(
208 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
219 auto rule_lhs = [](int, int,
int p) ->
int {
return 2 * p; };
220 auto rule_rhs = [](int, int,
int p) ->
int {
return 2 * p; };
221 auto rule_2 = [
this](int, int, int) {
return 2 *
oRder; };
225 CHKERR pipeline_mng->setDomainRhsIntegrationRule(rule_rhs);
227 CHKERR pipeline_mng->setSkeletonLhsIntegrationRule(rule_2);
228 CHKERR pipeline_mng->setSkeletonRhsIntegrationRule(rule_2);
229 CHKERR pipeline_mng->setBoundaryLhsIntegrationRule(rule_2);
230 CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(rule_2);
242 auto ksp_solver = pipeline_mng->
createKSP();
243 CHKERR KSPSetFromOptions(ksp_solver);
244 CHKERR KSPSetUp(ksp_solver);
254 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
255 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
267 pipeline_mng->getDomainLhsFE().reset();
268 pipeline_mng->getSkeletonRhsFE().reset();
269 pipeline_mng->getSkeletonLhsFE().reset();
270 pipeline_mng->getBoundaryRhsFE().reset();
271 pipeline_mng->getBoundaryLhsFE().reset();
273 auto rule = [](int, int,
int p) ->
int {
return 2 * p; };
274 CHKERR pipeline_mng->setDomainRhsIntegrationRule(rule);
275 auto rule_2 = [
this](int, int, int) {
return 2 *
oRder; };
276 CHKERR pipeline_mng->setSkeletonRhsIntegrationRule(rule_2);
278 auto add_base_ops = [&](
auto &pipeline) {
279 auto det_ptr = boost::make_shared<VectorDouble>();
280 auto jac_ptr = boost::make_shared<MatrixDouble>();
281 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
287 auto u_vals_ptr = boost::make_shared<VectorDouble>();
288 auto u_grad_ptr = boost::make_shared<MatrixDouble>();
290 add_base_ops(pipeline_mng->getOpDomainRhsPipeline());
291 pipeline_mng->getOpDomainRhsPipeline().push_back(
293 pipeline_mng->getOpDomainRhsPipeline().push_back(
296 enum NORMS {
L2 = 0, SEMI_NORM,
H1, LAST_NORM };
297 std::array<int, LAST_NORM> error_indices;
298 for (
int i = 0;
i != LAST_NORM; ++
i)
299 error_indices[
i] =
i;
304 error_op->doWorkRhsHook = [&](
DataOperator *op_ptr,
int side, EntityType type,
311 if (
const size_t nb_dofs = data.getIndices().size()) {
313 const int nb_integration_pts = o->getGaussPts().size2();
314 auto t_w = o->getFTensor0IntegrationWeight();
317 auto t_coords = o->getFTensor1CoordsAtGaussPts();
319 std::array<double, LAST_NORM> error;
320 std::fill(error.begin(), error.end(), 0);
322 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
324 const double alpha = t_w * o->getMeasure();
326 t_val -
u_exact(t_coords(0), t_coords(1), t_coords(2));
328 auto t_exact_grad =
u_grad_exact(t_coords(0), t_coords(1), t_coords(2));
330 const double diff_grad =
331 (t_grad(
i) - t_exact_grad(
i)) * (t_grad(
i) - t_exact_grad(
i));
333 error[
L2] += alpha * pow(diff, 2);
334 error[SEMI_NORM] += alpha * diff_grad;
342 error[
H1] = error[
L2] + error[SEMI_NORM];
351 auto side_fe_ptr = boost::make_shared<FaceSideEle>(
mField);
352 add_base_ops(side_fe_ptr->getOpPtrVector());
353 side_fe_ptr->getOpPtrVector().push_back(
355 std::array<VectorDouble, 2> side_vals;
356 std::array<double, 2> area_map;
359 side_vals_op->doWorkRhsHook = [&](
DataOperator *op_ptr,
int side,
365 const auto nb_in_loop = o->getFEMethod()->nInTheLoop;
366 area_map[nb_in_loop] = o->getMeasure();
367 side_vals[nb_in_loop] = *u_vals_ptr;
370 side_vals[1].clear();
375 side_fe_ptr->getOpPtrVector().push_back(side_vals_op);
377 auto do_work_rhs_error = [&](
DataOperator *op_ptr,
int side, EntityType type,
382 CHKERR o->loopSideFaces(
"dFE", *side_fe_ptr);
383 const auto in_the_loop = side_fe_ptr->nInTheLoop;
386 const std::array<std::string, 2> ele_type_name = {
"BOUNDARY",
"SKELETON"};
388 <<
"do_work_rhs_error in_the_loop " << ele_type_name[in_the_loop];
391 const double s = o->getMeasure() / (area_map[0] + area_map[1]);
394 constexpr std::array<int, 2> sign_array{1, -1};
396 std::array<double, LAST_NORM> error;
397 std::fill(error.begin(), error.end(), 0);
399 const int nb_integration_pts = o->getGaussPts().size2();
402 side_vals[1].resize(nb_integration_pts,
false);
403 auto t_coords = o->getFTensor1CoordsAtGaussPts();
405 for (
size_t gg = 0; gg != nb_integration_pts; ++gg) {
406 t_val_m =
u_exact(t_coords(0), t_coords(1), t_coords(2));
414 auto t_w = o->getFTensor0IntegrationWeight();
416 for (
size_t gg = 0; gg != nb_integration_pts; ++gg) {
418 const double alpha = o->getMeasure() * t_w;
419 const auto diff = t_val_p - t_val_m;
420 error[SEMI_NORM] += alpha * p * diff * diff;
428 error[
H1] = error[SEMI_NORM];
436 skeleton_error_op->doWorkRhsHook = do_work_rhs_error;
438 boundary_error_op->doWorkRhsHook = do_work_rhs_error;
440 pipeline_mng->getOpDomainRhsPipeline().push_back(error_op);
441 pipeline_mng->getOpSkeletonLhsPipeline().push_back(skeleton_error_op);
442 pipeline_mng->getOpBoundaryRhsPipeline().push_back(boundary_error_op);
444 CHKERR pipeline_mng->loopFiniteElements();
446 CHKERR VecAssemblyBegin(l2_vec);
447 CHKERR VecAssemblyEnd(l2_vec);
451 CHKERR VecGetArrayRead(l2_vec, &array);
452 MOFEM_LOG_C(
"SELF", Sev::inform,
"Error Norm L2 %6.4e",
453 std::sqrt(array[
L2]));
454 MOFEM_LOG_C(
"SELF", Sev::inform,
"Error Norm Energetic %6.4e",
455 std::sqrt(array[SEMI_NORM]));
456 MOFEM_LOG_C(
"SELF", Sev::inform,
"Error Norm H1 %6.4e",
457 std::sqrt(array[
H1]));
460 constexpr double eps = 1e-12;
461 if (std::sqrt(array[
H1]) >
eps)
465 CHKERR VecRestoreArrayRead(l2_vec, &array);
483 pipeline_mng->getSkeletonRhsFE().reset();
484 pipeline_mng->getSkeletonLhsFE().reset();
485 pipeline_mng->getBoundaryRhsFE().reset();
486 pipeline_mng->getBoundaryLhsFE().reset();
488 auto post_proc_fe = boost::make_shared<PostProcEle>(
mField);
490 auto u_ptr = boost::make_shared<VectorDouble>();
491 post_proc_fe->getOpPtrVector().push_back(
496 post_proc_fe->getOpPtrVector().push_back(
500 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
512 pipeline_mng->getDomainRhsFE() = post_proc_fe;
513 CHKERR pipeline_mng->loopFiniteElements();
514 CHKERR post_proc_fe->writeFile(
"out_result.h5m");
538int main(
int argc,
char *argv[]) {
541 const char param_file[] =
"param_file.petsc";
547 DMType dm_name =
"DMMOFEM";
551 moab::Core mb_instance;
552 moab::Interface &moab = mb_instance;
#define MOFEM_LOG_C(channel, severity, format,...)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< 1, FIELD_DIM > OpDomainSource
DomainEle::UserDataOperator DomainEleOp
Finire element operator type.
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
[Define dimension]
BoundaryEle::UserDataOperator BoundaryEleOp
#define CATCH_ERRORS
Catch errors.
@ L2
field with C-1 continuity
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_ATOM_TEST_INVALID
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr auto domainField
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
PetscErrorCode DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
auto createDMVector(DM dm)
Get smart vector from DM.
SmartPetscObj< KSP > createKSP(SmartPetscObj< DM > dm=nullptr)
Create KSP (linear) solver.
#define MOFEM_LOG(channel, severity)
Log.
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradGrad< 1, 1, SPACE_DIM > OpDomainGradGrad
PipelineManager::ElementsAndOpsByDim< FE_DIM >::FaceSideEle FaceSideEle
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, 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.
OpCalculateHOJacForFaceImpl< 2 > OpCalculateHOJacForFace
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
FTensor::Tensor1< FTensor::PackPtr< T *, S >, Tensor_Dim > getFTensor1FromMat(ublas::matrix< T, L, A > &data)
Get tensor rank 1 (vector) form data matrix.
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
FTensor::Index< 'i', SPACE_DIM > i
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradGrad< BASE_DIM, FIELD_DIM, SPACE_DIM > OpDomainGradGrad
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< BASE_DIM, FIELD_DIM > OpDomainSource
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
base operator to do operations at Gauss Pt. level
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
Get field gradients at integration pts for scalar filed rank 0, i.e. vector field.
Get value at integration points for scalar field.
Post post-proc data at points from hash maps.
PipelineManager interface.
boost::shared_ptr< FEMethod > & getDomainRhsFE()
boost::shared_ptr< FEMethod > & getDomainLhsFE()
MoFEMErrorCode setDomainLhsIntegrationRule(RuleHookFun rule)
keeps basic data about problem
DofIdx getNbDofsRow() const
Simple interface for fast problem set-up.
MoFEMErrorCode addDomainField(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_ZERO, int verb=-1)
Add field on domain.
bool & getAddBoundaryFE()
Get the addSkeletonFE.
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
MoFEMErrorCode getOptions()
get options
MoFEMErrorCode getDM(DM *dm)
Get DM.
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
bool & getAddSkeletonFE()
Get the addSkeletonFE.
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
MoFEM::Interface & mField
MoFEMErrorCode boundaryCondition()
[Setup problem]
MoFEMErrorCode checkResults()
[Solve system]
MoFEMErrorCode setupProblem()
[Read mesh]
MoFEMErrorCode setIntegrationRules()
[Assemble system]
MoFEMErrorCode assembleSystem()
[Boundary condition]
Poisson2DiscontGalerkin(MoFEM::Interface &m_field)
MoFEMErrorCode solveSystem()
[Set integration rules]
MoFEMErrorCode readMesh()
[Read mesh]
MoFEMErrorCode outputResults()
[Output results]
MoFEMErrorCode runProgram()
[Output results]
Operator tp collect data from elements on the side of Edge/Face.
Operator to evaluate Dirichlet boundary conditions using DG.
Operator the left hand side matrix.