10 using namespace boost::numeric;
11 using namespace MoFEM;
13 static char help[] =
"-order approximation order\n"
40 const double coefficient = yOung / ((1 + pOisson) * (1 - 2 * pOisson));
49 tD(0, 0, 0, 0) = 1 - pOisson;
50 tD(1, 1, 1, 1) = 1 - pOisson;
51 tD(2, 2, 2, 2) = 1 - pOisson;
53 tD(0, 1, 0, 1) = 0.5 * (1 - 2 * pOisson);
54 tD(0, 2, 0, 2) = 0.5 * (1 - 2 * pOisson);
55 tD(1, 2, 1, 2) = 0.5 * (1 - 2 * pOisson);
57 tD(0, 0, 1, 1) = pOisson;
58 tD(1, 1, 0, 0) = pOisson;
59 tD(0, 0, 2, 2) = pOisson;
60 tD(2, 2, 0, 0) = pOisson;
61 tD(1, 1, 2, 2) = pOisson;
62 tD(2, 2, 1, 1) = pOisson;
64 tD(
i,
j,
k,
l) *= coefficient;
100 K.resize(nbRows, nbCols,
false);
104 nbIntegrationPts = getGaussPts().size2();
106 if (row_side == col_side && row_type == col_type) {
113 CHKERR iNtegrate(row_data, col_data);
116 CHKERR aSsemble(row_data, col_data);
141 &
m(
r + 0,
c + 0), &
m(
r + 0,
c + 1), &
m(
r + 0,
c + 2),
142 &
m(
r + 1,
c + 0), &
m(
r + 1,
c + 1), &
m(
r + 1,
c + 2),
143 &
m(
r + 2,
c + 0), &
m(
r + 2,
c + 1), &
m(
r + 2,
c + 2));
152 double vol = getVolume();
155 auto t_w = getFTensor0IntegrationWeight();
160 for (
int gg = 0; gg != nbIntegrationPts; ++gg) {
163 const double a = t_w * vol;
166 for (
int rr = 0; rr != nbRows / 3; ++rr) {
169 auto t_m = get_tensor2(
K, 3 * rr, 0);
175 for (
int cc = 0; cc != nbCols / 3; ++cc) {
179 a * (tD(
i,
j,
k,
l) * (t_row_diff_base(
j) * t_col_diff_base(
l)));
209 const int *row_indices = &*row_data.
getIndices().data().begin();
211 const int *col_indices = &*col_data.
getIndices().data().begin();
212 Mat B = getFEMethod()->ksp_B != PETSC_NULL ? getFEMethod()->ksp_B
213 : getFEMethod()->snes_B;
216 &*
K.data().begin(), ADD_VALUES);
218 if (!isDiag && sYmm) {
223 &*
K.data().begin(), ADD_VALUES);
235 pressureVal(pressure_val) {}
254 nF.resize(nb_dofs,
false);
258 const int nb_gauss_pts = data.
getN().size1();
262 auto t_normal = getFTensor1Normal();
265 auto t_w = getFTensor0IntegrationWeight();
271 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
273 double w = 0.5 * t_w;
279 for (
int bb = 0; bb != nb_dofs / 3; ++bb) {
282 t_nf(
i) += (
w * pressureVal * t_base) * t_normal(
i);
306 const Range &fix_second_node)
307 :
MoFEM::
FEMethod(), fixFaces(fix_faces), fixNodes(fix_nodes),
308 fixSecondNode(fix_second_node) {
315 std::set<int> set_fix_dofs;
318 if (dit->get()->getDofCoeffIdx() == 2) {
319 if (fixFaces.find(dit->get()->getEnt()) != fixFaces.end()) {
320 set_fix_dofs.insert(dit->get()->getPetscGlobalDofIdx());
324 if (fixSecondNode.find(dit->get()->getEnt()) != fixSecondNode.end()) {
325 if (dit->get()->getDofCoeffIdx() == 1) {
326 set_fix_dofs.insert(dit->get()->getPetscGlobalDofIdx());
330 if (fixNodes.find(dit->get()->getEnt()) != fixNodes.end()) {
331 set_fix_dofs.insert(dit->get()->getPetscGlobalDofIdx());
335 std::vector<int> fix_dofs(set_fix_dofs.size());
337 std::copy(set_fix_dofs.begin(), set_fix_dofs.end(), fix_dofs.begin());
339 CHKERR MatAssemblyBegin(ksp_B, MAT_FINAL_ASSEMBLY);
340 CHKERR MatAssemblyEnd(ksp_B, MAT_FINAL_ASSEMBLY);
341 CHKERR VecAssemblyBegin(ksp_f);
342 CHKERR VecAssemblyEnd(ksp_f);
346 CHKERR VecDuplicate(ksp_f, &x);
348 CHKERR MatZeroRowsColumns(ksp_B, fix_dofs.size(), &fix_dofs[0], 1, x,
369 int operator()(
int,
int,
int p)
const {
return 2 * (p - 1); }
390 int main(
int argc,
char *argv[]) {
392 const string default_options =
"-ksp_type fgmres \n"
394 "-pc_factor_mat_solver_type mumps \n"
395 "-mat_mumps_icntl_20 0 \n"
398 string param_file =
"param_file.petsc";
399 if (!
static_cast<bool>(ifstream(param_file))) {
400 std::ofstream file(param_file.c_str(), std::ios::ate);
401 if (file.is_open()) {
402 file << default_options;
422 PetscBool flg_test = PETSC_FALSE;
423 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"SimpleElasticProblem",
431 CHKERR PetscOptionsBool(
"-test",
"if true is ctest",
"", flg_test,
432 &flg_test, PETSC_NULL);
434 ierr = PetscOptionsEnd();
442 Range fix_faces, pressure_faces, fix_nodes, fix_second_node;
447 BRICK_PRESSURE_FACES = 3,
453 int id =
bit->getMeshsetId();
455 if (
id == FIX_BRICK_FACES) {
461 CHKERR m_field.
get_moab().get_adjacencies(fix_faces, 0,
false, adj_ents,
462 moab::Interface::UNION);
464 CHKERR m_field.
get_moab().get_adjacencies(fix_faces, 1,
false, adj_ents,
465 moab::Interface::UNION);
466 fix_faces.merge(adj_ents);
467 }
else if (
id == FIX_NODES) {
472 }
else if (
id == BRICK_PRESSURE_FACES) {
474 meshset, 2, pressure_faces,
true);
479 meshset, 0, fix_second_node,
true);
516 boost::shared_ptr<VolumeElementForcesAndSourcesCore> elastic_fe(
518 boost::shared_ptr<FaceElementForcesAndSourcesCore> pressure_fe(
522 elastic_fe->getRuleHook =
VolRule();
523 pressure_fe->getRuleHook =
FaceRule();
527 elastic_fe->getOpPtrVector().push_back(
new OpK());
529 pressure_fe->getOpPtrVector().push_back(
new OpPressure());
531 boost::shared_ptr<FEMethod> fix_dofs_fe(
534 boost::shared_ptr<FEMethod> null_fe;
538 dm, simple_interface->
getDomainFEName(), elastic_fe, null_fe, null_fe);
553 CHKERR DMCreateGlobalVector(dm, &x);
561 elastic_fe->ksp_B =
A;
562 fix_dofs_fe->ksp_B =
A;
566 fix_dofs_fe->ksp_f =
f;
567 pressure_fe->ksp_f =
f;
583 CHKERR KSPCreate(PETSC_COMM_WORLD, &solver);
587 CHKERR KSPSetFromOptions(solver);
590 CHKERR KSPSetOperators(solver,
A,
A);
599 CHKERR KSPDestroy(&solver);
603 VecView(x, PETSC_VIEWER_STDOUT_WORLD);
610 auto get_post_proc_ele = [&]() {
611 auto jac_ptr = boost::make_shared<MatrixDouble>();
612 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
613 auto det_ptr = boost::make_shared<VectorDouble>();
615 auto post_proc_ele = boost::make_shared<
619 post_proc_ele->getOpPtrVector().push_back(
621 post_proc_ele->getOpPtrVector().push_back(
623 post_proc_ele->getOpPtrVector().push_back(
626 auto u_ptr = boost::make_shared<MatrixDouble>();
627 auto grad_ptr = boost::make_shared<MatrixDouble>();
628 post_proc_ele->getOpPtrVector().push_back(
630 post_proc_ele->getOpPtrVector().push_back(
635 post_proc_ele->getOpPtrVector().push_back(
639 post_proc_ele->getPostProcMesh(), post_proc_ele->getMapGaussPts(),
644 {{
"GRAD", grad_ptr}},
650 return post_proc_ele;
653 if (
auto post_proc = get_post_proc_ele()) {
657 CHKERR post_proc->writeFile(
"out.h5m");
661 if (flg_test == PETSC_TRUE) {
662 const double x_vec_norm_const = 0.4;
667 CHKERR VecNorm(x, NORM_INFINITY, &norm_check);
668 if (std::abs(norm_check - x_vec_norm_const) / x_vec_norm_const >
671 "test failed (nrm 2 %6.4e)", norm_check);