5 namespace bio = boost::iostreams;
11 static char help[] =
"...\n\n";
13 static const double face_coords[4][9] = {{0, 0, 0, 1, 0, 0, 0, 0, 1},
14 {1, 0, 0, 0, 1, 0, 0, 0, 1},
15 {0, 0, 0, 0, 1, 0, 0, 0, 1},
16 {0, 0, 0, 1, 0, 0, 0, 1, 0}};
19 {0, 0, 0, 1, 0, 0}, {1, 0, 0, 0, 1, 0}, {0, 1, 0, 0, 0, 0},
20 {0, 0, 0, 0, 0, 1}, {1, 0, 0, 0, 0, 1}, {0, 1, 0, 0, 0, 1}};
22 int main(
int argc,
char *argv[]) {
31 MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
33 PetscBool flg = PETSC_TRUE;
35 #if PETSC_VERSION_GE(3, 6, 4)
44 if (flg != PETSC_TRUE) {
45 SETERRQ(PETSC_COMM_SELF, 1,
"*** ERROR -my_file (MESH FILE NEEDED)");
52 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOP };
54 const char *list_bases[] = {
"ainsworth",
"demkowicz"};
56 PetscInt choice_base_value = AINSWORTH;
58 LASBASETOP, &choice_base_value, &flg);
60 if (flg != PETSC_TRUE) {
65 if (choice_base_value == AINSWORTH) {
67 }
else if (choice_base_value == DEMKOWICZ) {
79 CHKERR moab.create_meshset(MESHSET_SET, meshset_level0);
101 "MESH_NODE_POSITIONS");
107 "MESH_NODE_POSITIONS");
113 "MESH_NODE_POSITIONS");
119 "MESH_NODE_POSITIONS");
148 CHKERR skin.find_skin(0, tets,
false, skin_faces);
157 faces = subtract(faces, skin_faces);
161 CHKERR moab.get_adjacencies(faces, 1,
false, edges, moab::Interface::UNION);
166 CHKERR moab.get_adjacencies(skin_faces, 1,
false, skin_edges,
167 moab::Interface::UNION);
215 CHKERR VecSetRandom(
v, PETSC_NULL);
218 "TEST_PROBLEM",
ROW,
v, INSERT_VALUES, SCATTER_REVERSE);
222 typedef tee_device<std::ostream, std::ofstream>
TeeDevice;
224 std::ofstream ofs(
"forces_and_sources_hdiv_continuity_check.txt");
237 mField(m_field), tH(
th) {}
248 boost::shared_ptr<const NumeredEntFiniteElement> mofem_fe =
249 getNumeredEntFiniteElementPtr();
252 .find(boost::make_tuple(
type, side))
255 int sense = side_table.get<1>()
256 .find(boost::make_tuple(
type, side))
263 int nb_dofs = data.
getN().size2() / 3;
264 for (
int dd = 0;
dd < nb_dofs;
dd++) {
265 for (
int ddd = 0; ddd < 3; ddd++) {
273 (
const void **)&t_ptr);
275 for (
int dd = 0;
dd < 3;
dd++) {
276 t_ptr[
dd] += sense *
t[
dd];
280 if (
type == MBEDGE) {
282 boost::shared_ptr<const NumeredEntFiniteElement> mofem_fe =
283 getNumeredEntFiniteElementPtr();
286 .find(boost::make_tuple(
type, side))
290 CHKERR mField.
get_moab().get_adjacencies(&edge, 1, 3,
false, adj_tets,
291 moab::Interface::UNION);
292 const int nb_adj_tets = adj_tets.size();
295 int nb_dofs = data.
getN().size2() / 3;
296 for (
int dd = 0;
dd < nb_dofs;
dd++) {
297 for (
int ddd = 0; ddd < 3; ddd++) {
305 (
const void **)&t_ptr);
307 for (
int dd = 0;
dd < 3;
dd++) {
308 t_ptr[
dd] +=
t[
dd] / nb_adj_tets;
320 int getRule(
int order) {
return -1; };
332 gaussPts.resize(4, 4 + 6);
334 for (; ff < 4; ff++) {
336 for (;
dd < 3;
dd++) {
344 for (; ee < 6; ee++) {
346 for (;
dd < 3;
dd++) {
347 gaussPts(
dd, 4 + ee) =
350 gaussPts(3, 4 + ee) = 1;
355 }
catch (std::exception &ex) {
356 std::ostringstream ss;
357 ss <<
"throw in method: " << ex.what() <<
" at line " << __LINE__
358 <<
" in file " << __FILE__;
366 struct OpFacesSkinFluxes
377 mField(m_field), tH1(th1), tH2(th2), mySplit(my_split) {}
386 EntityHandle face = getNumeredEntFiniteElementPtr()->getEnt();
390 (
const void **)&t_ptr);
394 (
const void **)&tn_ptr);
396 *tn_ptr = getTangent1AtGaussPts()(0, 0) * t_ptr[0] +
397 getTangent1AtGaussPts()(0, 1) * t_ptr[1] +
398 getTangent1AtGaussPts()(0, 2) * t_ptr[2] +
399 getTangent2AtGaussPts()(0, 0) * t_ptr[0] +
400 getTangent2AtGaussPts()(0, 1) * t_ptr[1] +
401 getTangent2AtGaussPts()(0, 2) * t_ptr[2];
403 int nb_dofs = data.
getN().size2() / 3;
405 for (;
dd < nb_dofs;
dd++) {
408 -getTangent1AtGaussPts()(0, 0) * data.
getN()(0, 3 *
dd + 0) *
410 getTangent1AtGaussPts()(0, 1) * data.
getN()(0, 3 *
dd + 1) * val -
411 getTangent1AtGaussPts()(0, 2) * data.
getN()(0, 3 *
dd + 2) * val -
412 getTangent2AtGaussPts()(0, 0) * data.
getN()(0, 3 *
dd + 0) * val -
413 getTangent2AtGaussPts()(0, 1) * data.
getN()(0, 3 *
dd + 1) * val -
414 getTangent2AtGaussPts()(0, 2) * data.
getN()(0, 3 *
dd + 2) * val;
417 const double eps = 1e-8;
418 if (fabs(*tn_ptr) >
eps) {
420 "HCurl continuity failed %6.4e", *tn_ptr);
423 mySplit.precision(5);
424 mySplit << face <<
" " << fabs(*tn_ptr) << std::endl;
441 mField(m_field), tH1(_th1), tH2(_th2), mySplit(my_split) {}
450 EntityHandle face = getNumeredEntFiniteElementPtr()->getEnt();
454 (
const void **)&t_ptr);
458 (
const void **)&tn_ptr);
460 *tn_ptr = getTangent1AtGaussPts()(0, 0) * t_ptr[0] +
461 getTangent1AtGaussPts()(0, 1) * t_ptr[1] +
462 getTangent1AtGaussPts()(0, 2) * t_ptr[2] +
463 getTangent2AtGaussPts()(0, 0) * t_ptr[0] +
464 getTangent2AtGaussPts()(0, 1) * t_ptr[1] +
465 getTangent2AtGaussPts()(0, 2) * t_ptr[2];
467 const double eps = 1e-8;
468 if (fabs(*tn_ptr) >
eps) {
470 "HCurl continuity failed %6.4e", *tn_ptr);
473 mySplit.precision(5);
475 mySplit << face <<
" " << fabs(*tn_ptr) << std::endl;
485 int getRule(
int order) {
return -1; };
490 gaussPts.resize(3, 1);
510 mField(m_field), tH1(_th1), tH2(_th2), mySplit(my_split) {}
519 EntityHandle edge = getNumeredEntFiniteElementPtr()->getEnt();
523 (
const void **)&t_ptr);
527 (
const void **)&tn_ptr);
529 *tn_ptr = getTangentAtGaussPts()(0, 0) * t_ptr[0] +
530 getTangentAtGaussPts()(0, 1) * t_ptr[1] +
531 getTangentAtGaussPts()(0, 2) * t_ptr[2];
534 unsigned int nb_dofs = data.
getN().size2() / 3;
537 "Number of dofs on edge and number of base functions not "
542 for (
unsigned int dd = 0;
dd != nb_dofs; ++
dd) {
544 tn += getTangentAtGaussPts()(0, 0) * data.
getN()(0, 3 *
dd + 0) *
546 getTangentAtGaussPts()(0, 1) * data.
getN()(0, 3 *
dd + 1) *
548 getTangentAtGaussPts()(0, 2) * data.
getN()(0, 3 *
dd + 2) *
559 const double eps = 1e-8;
560 if (fabs(*tn_ptr) >
eps) {
562 "HCurl continuity failed %6.4e", *tn_ptr);
565 mySplit.precision(5);
567 mySplit << edge <<
" " << fabs(*tn_ptr) << std::endl;
577 int getRule(
int order) {
return -1; };
582 gaussPts.resize(2, 1);
583 gaussPts(0, 0) = 0.5;
590 MyTetFE tet_fe(m_field);
591 MyTriFE tri_fe(m_field);
592 MyTriFE skin_fe(m_field);
593 MyEdgeFE edge_fe(m_field);
596 double def_val[] = {0, 0, 0};
597 CHKERR moab.tag_get_handle(
"T", 3, MB_TYPE_DOUBLE, th1,
598 MB_TAG_CREAT | MB_TAG_SPARSE, &def_val);
600 auto material_grad_mat = boost::make_shared<MatrixDouble>();
601 auto material_det_vec = boost::make_shared<VectorDouble>();
602 auto material_inv_grad_mat = boost::make_shared<MatrixDouble>();
605 "MESH_NODE_POSITIONS", material_grad_mat));
607 material_grad_mat, material_det_vec, material_inv_grad_mat));
608 tet_fe.getOpPtrVector().push_back(
new OpSetHOWeights(material_det_vec));
609 tet_fe.getOpPtrVector().push_back(
611 tet_fe.getOpPtrVector().push_back(
613 tet_fe.getOpPtrVector().push_back(
new OpTetFluxes(m_field, th1));
616 CHKERR moab.tag_get_handle(
"TN", 1, MB_TYPE_DOUBLE, th2,
617 MB_TAG_CREAT | MB_TAG_SPARSE, &def_val);
619 tri_fe.getOpPtrVector().push_back(
621 tri_fe.getOpPtrVector().push_back(
624 tri_fe.getOpPtrVector().push_back(
626 tri_fe.getOpPtrVector().push_back(
629 skin_fe.getOpPtrVector().push_back(
631 skin_fe.getOpPtrVector().push_back(
633 skin_fe.getOpPtrVector().push_back(
634 new OpFacesSkinFluxes(m_field, th1, th2, my_split));
636 edge_fe.getOpPtrVector().push_back(
638 edge_fe.getOpPtrVector().push_back(
640 edge_fe.getOpPtrVector().push_back(
641 new OpEdgesFluxes(m_field, th1, th2, my_split));
643 for (Range::iterator fit = faces.begin(); fit != faces.end(); fit++) {
644 CHKERR moab.tag_set_data(th1, &*fit, 1, &def_val);
645 CHKERR moab.tag_set_data(th2, &*fit, 1, &def_val);
649 my_split <<
"internal\n";
651 my_split <<
"skin\n";
653 my_split <<
"edges\n";
657 CHKERR moab.create_meshset(MESHSET_SET, meshset);
660 CHKERR moab.write_file(
"out.vtk",
"VTK",
"", &meshset, 1);