9 #ifndef __UNSATURATD_FLOW_HPP__
10 #define __UNSATURATD_FLOW_HPP__
14 using PostProcEle = PostProcBrokenMeshInMoab<VolumeElementForcesAndSourcesCore>;
52 const std::string &prefix)
const = 0;
57 "Not implemented how to calculate hydraulic conductivity");
64 "Not implemented how to calculate derivative of hydraulic "
72 "Not implemented how to calculate capacity");
79 "Not implemented how to calculate capacity");
86 "Not implemented how to calculate capacity");
93 "Not implemented how to calculate capacity");
112 if (
dM != PETSC_NULL) {
114 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
128 int &block_id)
const {
130 for (MaterialsDoubleMap::const_iterator mit =
dMatMap.begin();
132 if (mit->second->tEts.find(ent) != mit->second->tEts.end()) {
133 block_id = mit->first;
138 "Element not found, no material data");
148 boost::function<
double(
const double x,
const double y,
const double z)>
152 typedef map<int, boost::shared_ptr<BcData>>
BcMap;
169 const double x,
const double y,
const double z,
178 if (it->second->eNts.find(ent) != it->second->eNts.end()) {
179 block_id = it->first;
187 value =
bcValueMap.at(block_id)->hookFun(x, y, z);
211 const double y,
const double z,
double &flux) {
219 if (it->second->eNts.find(ent) != it->second->eNts.end()) {
220 block_id = it->first;
228 flux =
bcFluxMap.at(block_id)->hookFun(x, y, z);
251 boost::shared_ptr<MethodForForceScaling> &value_scale)
268 if (data.getFieldData().size() == 0)
273 nF.resize(data.getIndices().size());
276 int nb_gauss_pts = data.getN().size1();
277 for (
int gg = 0; gg < nb_gauss_pts; gg++) {
286 const double beta =
w * (value - z);
287 noalias(
nF) += beta * prod(data.getVectorN<3>(gg),
getNormal());
320 const int nb_dofs = data.getIndices().size();
323 nF.resize(nb_dofs,
false);
331 boost::shared_ptr<GenericMaterial> &block_data =
cTx.
dMatMap.at(block_id);
334 auto t_n_hdiv = data.getFTensor1N<3>();
347 auto t_base_diff_hdiv = data.getFTensor2DiffN<3, 3>();
348 divVec.resize(nb_dofs,
false);
351 int nb_gauss_pts = data.getN().size1();
352 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
355 v = t_base_diff_hdiv(
i,
i);
359 const double alpha = t_w * vol;
361 block_data->x = t_coords(0);
362 block_data->y = t_coords(1);
363 block_data->z = t_coords(2);
364 CHKERR block_data->calK();
365 const double K = block_data->K;
366 const double scaleZ = block_data->scaleZ;
367 const double z = t_coords(2);
369 noalias(
nF) -= alpha * (t_h - z * scaleZ) *
divVec;
372 for (
int rr = 0; rr != nb_dofs; rr++) {
373 t_nf += alpha * (1 /
K) * (t_n_hdiv(
i) * t_flux(
i));
384 &*data.getIndices().begin(), &*
nF.begin(),
408 const int nb_dofs = data.getIndices().size();
412 nF.resize(nb_dofs,
false);
420 boost::shared_ptr<GenericMaterial> &block_data =
cTx.
dMatMap.at(block_id);
432 const double scale = block_data->sCale;
436 int nb_gauss_pts = data.getN().size1();
437 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
438 const double alpha = t_w * vol *
scale;
440 block_data->x = t_coords(0);
441 block_data->y = t_coords(1);
442 block_data->z = t_coords(2);
443 CHKERR block_data->calC();
444 const double C = block_data->C;
446 noalias(
nF) += (alpha * (t_div_flux + C * t_h_t)) * data.getN(gg);
467 const std::string flux_name)
493 const int nb_row = row_data.getIndices().size();
494 const int nb_col = col_data.getIndices().size();
499 nN.resize(nb_row, nb_col,
false);
507 boost::shared_ptr<GenericMaterial> &block_data =
cTx.
dMatMap.at(block_id);
513 auto t_n_hdiv_row = row_data.getFTensor1N<3>();
518 int nb_gauss_pts = row_data.getN().size1();
519 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
521 block_data->x = t_coords(0);
522 block_data->y = t_coords(1);
523 block_data->z = t_coords(2);
524 CHKERR block_data->calK();
525 const double K = block_data->K;
527 const double alpha = t_w * vol;
528 const double beta = alpha * (1 /
K);
530 for (
int kk = 0; kk != nb_row; kk++) {
531 auto t_n_hdiv_col = col_data.getFTensor1N<3>(gg, 0);
532 for (
int ll = 0; ll != nb_col; ll++) {
533 t_a += beta * (t_n_hdiv_row(
j) * t_n_hdiv_col(
j));
545 &*col_data.getIndices().begin(), &*
nN.data().begin(),
548 if (row_side != col_side || row_type != col_type) {
549 transNN.resize(nb_col, nb_row);
552 &*row_data.getIndices().begin(),
553 &*
transNN.data().begin(), ADD_VALUES);
588 int nb_row = row_data.getIndices().size();
589 int nb_col = col_data.getIndices().size();
594 nN.resize(nb_row, nb_col,
false);
602 boost::shared_ptr<GenericMaterial> &block_data =
cTx.
dMatMap.at(block_id);
614 const double scale = block_data->sCale;
619 int nb_gauss_pts = row_data.getN().size1();
621 auto t_n_row = row_data.getFTensor0N();
622 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
624 double alpha = t_w * vol *
scale;
628 block_data->h_t = t_h_t;
629 block_data->x = t_coords(0);
630 block_data->y = t_coords(1);
631 block_data->z = t_coords(2);
632 CHKERR block_data->calC();
633 CHKERR block_data->calDiffC();
634 const double C = block_data->C;
635 const double diffC = block_data->diffC;
638 &*
nN.data().begin());
640 for (
int kk = 0; kk != nb_row; kk++) {
642 auto t_n_col = col_data.getFTensor0N(gg, 0);
644 for (
int ll = 0; ll != nb_col; ll++) {
646 t_a += (alpha * (C * ts_a + diffC * t_h_t)) * t_n_row * t_n_col;
660 &col_data.getIndices()[0], &*
nN.data().begin(),
675 const std::string &val_name_row,
676 const std::string &flux_name_col)
701 int nb_row = row_data.getFieldData().size();
702 int nb_col = col_data.getFieldData().size();
713 boost::shared_ptr<GenericMaterial> &block_data =
cTx.
dMatMap.at(block_id);
714 nN.resize(nb_row, nb_col,
false);
715 divVec.resize(nb_col,
false);
719 auto t_base_diff_hdiv = col_data.getFTensor2DiffN<3, 3>();
721 const double scale = block_data->sCale;
722 int nb_gauss_pts = row_data.getN().size1();
723 for (
int gg = 0; gg < nb_gauss_pts; gg++) {
726 v = t_base_diff_hdiv(
i,
i);
729 noalias(
nN) += alpha * outer_prod(row_data.getN(gg),
divVec);
732 &row_data.getIndices()[0], nb_col,
733 &col_data.getIndices()[0], &
nN(0, 0), ADD_VALUES);
747 const std::string &flux_name_col,
748 const std::string &val_name_row)
774 int nb_row = row_data.getFieldData().size();
775 int nb_col = col_data.getFieldData().size();
780 nN.resize(nb_row, nb_col,
false);
781 divVec.resize(nb_row,
false);
789 boost::shared_ptr<GenericMaterial> &block_data =
cTx.
dMatMap.at(block_id);
799 auto t_n_hdiv_row = row_data.getFTensor1N<3>();
802 auto t_base_diff_hdiv = row_data.getFTensor2DiffN<3, 3>();
805 int nb_gauss_pts = row_data.getN().size1();
806 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
808 block_data->x = t_coords(0);
809 block_data->y = t_coords(1);
810 block_data->z = t_coords(2);
811 CHKERR block_data->calK();
812 CHKERR block_data->calDiffK();
813 const double K = block_data->K;
815 const double KK =
K *
K;
816 const double diffK = block_data->diffK;
817 double alpha = t_w * vol;
819 v = t_base_diff_hdiv(
i,
i);
822 noalias(
nN) -= alpha * outer_prod(
divVec, col_data.getN(gg));
824 for (
int rr = 0; rr != nb_row; rr++) {
825 double beta = alpha * (-diffK / KK) * (t_n_hdiv_row(
i) * t_flux(
i));
826 auto t_n_col = col_data.getFTensor0N(gg, 0);
827 for (
int cc = 0; cc != nb_col; cc++) {
828 t_a += beta * t_n_col;
840 &row_data.getIndices()[0], nb_col,
841 &col_data.getIndices()[0], &
nN(0, 0), ADD_VALUES);
850 const std::string &val_name)
861 if (data.getFieldData().size() == 0)
863 auto nb_dofs = data.getFieldData().size();
864 if (nb_dofs != data.getN().size2()) {
866 "wrong number of dofs");
868 nN.resize(nb_dofs, nb_dofs,
false);
869 nF.resize(nb_dofs,
false);
881 boost::shared_ptr<GenericMaterial> &block_data =
cTx.
dMatMap.at(block_id);
885 for (
auto gg = 0; gg != nb_gauss_pts; gg++) {
892 nN += alpha * outer_prod(data.getN(gg), data.getN(gg));
893 nF += alpha * block_data->initialPcEval() * data.getN(gg);
903 &*
nF.begin(), INSERT_VALUES);
917 const std::string fluxes_name)
934 int nb_dofs = data.getFieldData().size();
938 auto t_n_hdiv = data.getFTensor1N<3>();
943 double flux_on_entity = 0;
944 int nb_gauss_pts = data.getN().size1();
945 for (
int gg = 0; gg < nb_gauss_pts; gg++) {
946 auto t_data = data.getFTensor0FieldData();
947 for (
int rr = 0; rr != nb_dofs; rr++) {
948 flux_on_entity -= (0.5 * t_data * t_w) * (t_n_hdiv(
i) * t_normal(
i));
973 std::vector<EntityHandle> &map_gauss_pts,
982 int nb_dofs = data.getFieldData().size();
992 boost::shared_ptr<GenericMaterial> &block_data =
cTx.
dMatMap.at(block_id);
996 int def_block_id = -1;
998 MB_TAG_CREAT | MB_TAG_SPARSE,
1006 MB_TAG_CREAT | MB_TAG_SPARSE, &zero);
1009 MB_TAG_CREAT | MB_TAG_SPARSE, &zero);
1018 MB_TAG_CREAT | MB_TAG_SPARSE, &zero);
1021 MB_TAG_CREAT | MB_TAG_SPARSE, &zero);
1028 int nb_gauss_pts = data.getN().size1();
1029 for (
int gg = 0; gg < nb_gauss_pts; gg++) {
1030 block_data->h = t_h;
1031 block_data->x = t_coords(0);
1032 block_data->y = t_coords(1);
1033 block_data->z = t_coords(2);
1035 CHKERR block_data->calTheta();
1036 double theta = block_data->tHeta;
1038 CHKERR block_data->calSe();
1040 double Se = block_data->Se;
1043 CHKERR block_data->calK();
1044 double K = block_data->K;
1047 CHKERR block_data->calC();
1048 double C = block_data->C;
1079 boost::shared_ptr<PostProcEle> &post_proc,
1080 boost::shared_ptr<ForcesAndSourcesCore> flux_Integrate,
1081 const int frequency)
1100 CHKERR TSGetTimeStepNumber(
ts, &step);
1104 PetscPrintf(PETSC_COMM_WORLD,
"Output results %d - %d\n", step,
1108 string(
"out_") + boost::lexical_cast<std::string>(step) +
".h5m");
1127 CHKERR PetscPrintf(PETSC_COMM_WORLD,
"Flux at time %6.4g %6.4g\n",
ts_t,
1150 if (it->getName().compare(0, 4,
"SOIL") != 0)
1157 MBTET, values +
"_t");
1173 const std::string &values_name) {
1186 values_name +
"_t");
1191 if (it->getName().compare(0, 4,
"SOIL") != 0)
1194 dMatMap[it->getMeshsetId()]->tEts, MBTET,
"MIX");
1209 if (it->getName().compare(0, 4,
"HEAD") != 0)
1212 bcValueMap[it->getMeshsetId()]->eNts, MBTRI,
"MIX_BCVALUE");
1227 if (it->getName().compare(0, 4,
"FLUX") != 0)
1230 bcFluxMap[it->getMeshsetId()]->eNts, MBTRI,
"MIX_BCFLUX");
1255 CHKERR DMCreate(PETSC_COMM_WORLD, &
dM);
1275 "MIX",
"FLUXES", zero_flux_ents);
1277 PetscSection section;
1281 CHKERR PetscSectionDestroy(§ion);
1286 boost::shared_ptr<ForcesAndSourcesCore>
1288 boost::shared_ptr<ForcesAndSourcesCore>
1290 boost::shared_ptr<ForcesAndSourcesCore>
1292 boost::shared_ptr<ForcesAndSourcesCore>
1295 boost::shared_ptr<MethodForForceScaling>
1297 boost::shared_ptr<MethodForForceScaling>
1302 boost::shared_ptr<VectorDouble>
1311 int operator()(
int,
int,
int p_data)
const {
return 3 * p_data; }
1332 boost::shared_ptr<ForcesAndSourcesCore>
fePtr;
1337 boost::shared_ptr<ForcesAndSourcesCore> &fe_ptr
1343 CHKERR fePtr->mField.getInterface<VecManager>()->setOtherLocalGhostVector(
1344 fePtr->problemPtr,
"VALUES",
string(
"VALUES") +
"_t",
ROW,
1345 fePtr->ts_u_t, INSERT_VALUES, SCATTER_REVERSE);
1346 switch (
fePtr->ts_ctx) {
1347 case TSMethod::CTX_TSSETIFUNCTION:
1348 CHKERR VecSetOption(
fePtr->ts_F, VEC_IGNORE_NEGATIVE_INDICES,
1366 const NumeredDofEntity *dof_ptr;
1367 for (std::vector<int>::iterator it =
cTx.
bcVecIds.begin();
1370 fePtr->problemPtr->getColDofsByPetscGlobalDofIdx(*it)
1372 dof_ptr->getFieldData() = *vit;
1394 boost::shared_ptr<ForcesAndSourcesCore>
fePtr;
1398 boost::shared_ptr<ForcesAndSourcesCore> &fe_ptr
1403 switch (
fePtr->ts_ctx) {
1404 case TSMethod::CTX_TSSETIJACOBIAN: {
1405 CHKERR MatAssemblyBegin(
fePtr->ts_B, MAT_FINAL_ASSEMBLY);
1406 CHKERR MatAssemblyEnd(
fePtr->ts_B, MAT_FINAL_ASSEMBLY);
1413 CHKERR MatAssemblyBegin(
fePtr->ts_B, MAT_FINAL_ASSEMBLY);
1414 CHKERR MatAssemblyEnd(
fePtr->ts_B, MAT_FINAL_ASSEMBLY);
1419 case TSMethod::CTX_TSSETIFUNCTION: {
1447 ForcesAndSourcesCore::RuleHookFun face_rule =
FaceRule()) {
1451 feFaceBc = boost::shared_ptr<ForcesAndSourcesCore>(
1453 feFaceRhs = boost::shared_ptr<ForcesAndSourcesCore>(
1456 new VolumeElementForcesAndSourcesCore(
mField));
1457 feVolLhs = boost::shared_ptr<ForcesAndSourcesCore>(
1458 new VolumeElementForcesAndSourcesCore(
mField));
1459 feVolRhs = boost::shared_ptr<ForcesAndSourcesCore>(
1460 new VolumeElementForcesAndSourcesCore(
mField));
1474 CHKERR AddHOOps<2, 3, 3>::add(
feFaceBc->getOpPtrVector(), {HDIV});
1486 feFaceBc->getOpPtrVector().push_back(
1502 CHKERR AddHOOps<3, 3, 3>::add(
feVolRhs->getOpPtrVector(), {HDIV, L2});
1503 feVolRhs->getOpPtrVector().push_back(
new OpCalculateScalarFieldValues(
1505 feVolRhs->getOpPtrVector().push_back(
1507 feVolRhs->getOpPtrVector().push_back(
1511 feVolRhs->getOpPtrVector().back().opType =
1512 ForcesAndSourcesCore::UserDataOperator::OPROW;
1514 CHKERR AddHOOps<3, 3, 3>::add(
feVolLhs->getOpPtrVector(), {HDIV, L2});
1515 feVolLhs->getOpPtrVector().push_back(
new OpCalculateScalarFieldValues(
1521 feVolLhs->getOpPtrVector().push_back(
1523 feVolLhs->getOpPtrVector().push_back(
1525 feVolLhs->getOpPtrVector().push_back(
1528 feVolLhs->getOpPtrVector().push_back(
1530 feVolLhs->getOpPtrVector().push_back(
1535 boost::shared_ptr<FEMethod>
null;
1543 auto get_post_process_ele = [&]() {
1544 auto post_process = boost::make_shared<PostProcEle>(
mField);
1546 CHKERR AddHOOps<3, 3, 3>::add(post_process->getOpPtrVector(), {HDIV, L2});
1548 auto values_ptr = boost::make_shared<VectorDouble>();
1549 auto grad_ptr = boost::make_shared<MatrixDouble>();
1550 auto flux_ptr = boost::make_shared<MatrixDouble>();
1552 post_process->getOpPtrVector().push_back(
1553 new OpCalculateScalarFieldValues(
"VALUES", values_ptr));
1554 post_process->getOpPtrVector().push_back(
1555 new OpCalculateScalarFieldGradient<3>(
"VALUES", grad_ptr));
1556 post_process->getOpPtrVector().push_back(
1557 new OpCalculateHVecVectorField<3>(
"FLUXES", flux_ptr));
1559 using OpPPMap = OpPostProcMapInMoab<3, 3>;
1561 post_process->getOpPtrVector().push_back(
1563 new OpPPMap(post_process->getPostProcMesh(),
1564 post_process->getMapGaussPts(),
1566 {{
"VALUES", values_ptr}},
1568 {{
"GRAD", grad_ptr}, {
"FLUXES", flux_ptr}},
1574 return post_process;
1577 auto post_process = get_post_process_ele();
1579 post_process->getOpPtrVector().push_back(
1580 new OpValuesAtGaussPts(*
this,
"VALUES"));
1581 post_process->getOpPtrVector().push_back(
1582 new OpPostProcMaterial(*
this, post_process->getPostProcMesh(),
1583 post_process->getMapGaussPts(),
"VALUES"));
1586 boost::shared_ptr<ForcesAndSourcesCore> flux_integrate;
1587 flux_integrate = boost::shared_ptr<ForcesAndSourcesCore>(
1589 CHKERR AddHOOps<2, 3, 3>::add(flux_integrate->getOpPtrVector(), {HDIV});
1590 flux_integrate->getOpPtrVector().push_back(
1591 new OpIntegrateFluxes(*
this,
"FLUXES"));
1593 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Monitor post proc",
"none");
1595 "-how_often_output",
1596 "frequency how often results are dumped on hard disk",
"", frequency,
1598 ierr = PetscOptionsEnd();
1601 tsMonitor = boost::shared_ptr<FEMethod>(
1618 CHKERR DMCreateMatrix(dM, &Aij);
1619 CHKERR DMCreateGlobalVector(dM, &D0);
1620 CHKERR VecDuplicate(D0, &D1);
1624 int nb_locals = mField.get_comm_rank() == 0 ? 1 : 0;
1625 int nb_ghosts = mField.get_comm_rank() > 0 ? 1 : 0;
1626 CHKERR VecCreateGhost(PETSC_COMM_WORLD, nb_locals, 1, nb_ghosts, ghosts,
1642 CHKERR VecDestroy(&ghostFlux);
1653 CHKERR VecZeroEntries(D0);
1654 CHKERR VecGhostUpdateBegin(D0, INSERT_VALUES, SCATTER_FORWARD);
1655 CHKERR VecGhostUpdateEnd(D0, INSERT_VALUES, SCATTER_FORWARD);
1660 CHKERR VecAssemblyBegin(D0);
1661 CHKERR VecAssemblyEnd(D0);
1662 CHKERR VecGhostUpdateBegin(D0, INSERT_VALUES, SCATTER_FORWARD);
1663 CHKERR VecGhostUpdateEnd(D0, INSERT_VALUES, SCATTER_FORWARD);
1665 CHKERR VecNorm(D0, NORM_2, &norm2D0);
1667 PetscPrintf(PETSC_COMM_WORLD,
"norm2D0 = %6.4e\n", norm2D0);
1678 CHKERR VecZeroEntries(D1);
1679 CHKERR VecGhostUpdateBegin(D1, INSERT_VALUES, SCATTER_FORWARD);
1680 CHKERR VecGhostUpdateEnd(D1, INSERT_VALUES, SCATTER_FORWARD);
1684 CHKERR VecAssemblyBegin(D1);
1685 CHKERR VecAssemblyEnd(D1);
1686 CHKERR VecGhostUpdateBegin(D1, INSERT_VALUES, SCATTER_FORWARD);
1687 CHKERR VecGhostUpdateEnd(D1, INSERT_VALUES, SCATTER_FORWARD);
1690 CHKERR VecNorm(D1, NORM_2, &norm2D1);
1692 PetscPrintf(PETSC_COMM_WORLD,
"norm2D1 = %6.4e\n", norm2D1);
1702 if (set_initial_pc) {
1712 CHKERR TSCreate(PETSC_COMM_WORLD, &ts);
1714 CHKERR TSSetType(ts, TSBEULER);
1717 CHKERR TSSetDuration(ts, PETSC_DEFAULT, ftime);
1719 CHKERR TSSetFromOptions(ts);
1722 #if PETSC_VERSION_GE(3, 7, 0)
1723 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER);
1735 CHKERR TSGetSNES(ts, &snes);
1737 #if PETSC_VERSION_GE(3, 7, 0)
1739 PetscViewerAndFormat *vf;
1740 CHKERR PetscViewerAndFormatCreate(PETSC_VIEWER_STDOUT_WORLD,
1741 PETSC_VIEWER_DEFAULT, &vf);
1745 void *))SNESMonitorFields,
1750 CHKERR SNESMonitorSet(snes,
1752 void *))SNESMonitorFields,
1760 CHKERR TSGetTime(ts, &ftime);
1761 PetscInt steps, snesfails, rejects, nonlinits, linits;
1762 CHKERR TSGetTimeStepNumber(ts, &steps);
1763 CHKERR TSGetSNESFailures(ts, &snesfails);
1764 CHKERR TSGetStepRejections(ts, &rejects);
1765 CHKERR TSGetSNESIterations(ts, &nonlinits);
1766 CHKERR TSGetKSPIterations(ts, &linits);
1767 PetscPrintf(PETSC_COMM_WORLD,
1768 "steps %D (%D rejected, %D SNES fails), ftime %g, nonlinits "
1770 steps, rejects, snesfails, ftime, nonlinits, linits);
1778 #endif // __UNSATURATD_FLOW_HPP__