v0.14.0
Loading...
Searching...
No Matches
unsaturated_transport.cpp File Reference

Implementation of unsaturated flow problem. More...

#include <MoFEM.hpp>
#include <MethodForForceScaling.hpp>
#include <TimeForceScale.hpp>
#include <boost/program_options.hpp>
#include <MixTransportElement.hpp>
#include <UnsaturatedFlow.hpp>
#include <MaterialUnsaturatedFlow.hpp>

Go to the source code of this file.

Functions

int main (int argc, char *argv[])
 

Variables

static char help [] = "...\n\n"
 

Detailed Description

Implementation of unsaturated flow problem.

Definition in file unsaturated_transport.cpp.

Function Documentation

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 37 of file unsaturated_transport.cpp.

37 {
38
39 const string default_options = "-ksp_type fgmres\n"
40 "-pc_type lu \n"
41 "-pc_factor_mat_solver_type mumps \n"
42 "-mat_mumps_icntl_20 0 \n";
43
44 string param_file = "param_file.petsc";
45 if (!static_cast<bool>(ifstream(param_file))) {
46 std::ofstream file(param_file.c_str(), std::ios::ate);
47 if (file.is_open()) {
48 file << default_options;
49 file.close();
50 }
51 }
52
53 MoFEM::Core::Initialize(&argc, &argv, param_file.c_str(), help);
54
55 // Register DM Manager
56 CHKERR DMRegister_MoFEM("DMMOFEM"); // register MoFEM DM in PETSc
57 // Register materials
59
60 PetscBool test_mat = PETSC_FALSE;
61 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-test_mat", &test_mat,
62 PETSC_NULL);
63
64 if (test_mat == PETSC_TRUE) {
66 // Testing van_genuchten
67 MaterialVanGenuchten van_genuchten(data);
68 van_genuchten.printMatParameters(-1, "testing");
69 van_genuchten.printTheta(-1e-16, -1e4, -1e-12, "hTheta");
70 van_genuchten.printKappa(-1e-16, -1, -1e-12, "hK");
71 van_genuchten.printC(-1e-16, -1, -1e-12, "hC");
72 CHKERR PetscFinalize();
73 return 0;
74 }
75
76 try {
77
78 moab::Core mb_instance;
79 moab::Interface &moab = mb_instance;
80
81 // get file name form command line
82 PetscBool flg_mesh_file_name = PETSC_TRUE;
83 char mesh_file_name[255];
84 PetscBool flg_conf_file_name = PETSC_TRUE;
85 char conf_file_name[255];
86
87 int order = 1;
88
89 ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "Unsaturated flow options",
90 "none");
92 ierr = PetscOptionsString("-my_file", "mesh file name", "", "mesh.h5m",
93 mesh_file_name, 255, &flg_mesh_file_name);
95 ierr = PetscOptionsString(
96 "-configure", "material and bc configuration file name", "",
97 "unsaturated.cfg", conf_file_name, 255, &flg_conf_file_name);
99 ierr = PetscOptionsInt("-my_order", "default approximation order", "",
100 order, &order, PETSC_NULL);
101 CHKERRG(ierr);
102 ierr = PetscOptionsEnd();
103 CHKERRG(ierr);
104
105 if (flg_mesh_file_name != PETSC_TRUE) {
106 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
107 "File name not set (e.g. -my_name mesh.h5m)");
108 }
109 if (flg_conf_file_name != PETSC_TRUE) {
110 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
111 "File name not set (e.g. -config unsaturated.cfg)");
112 }
113
114 // Create MOAB communicator
115 auto pcomm = ParallelComm::get_pcomm(&moab, MYPCOMM_INDEX);
116 auto moab_comm_wrap =
117 boost::make_shared<WrapMPIComm>(PETSC_COMM_WORLD, false);
118 if (pcomm == NULL)
119 pcomm =
120 new ParallelComm(&moab, moab_comm_wrap->get_comm());
121
122 const char *option;
123 option = "PARALLEL=READ_PART;"
124 "PARALLEL_RESOLVE_SHARED_ENTS;"
125 "PARTITION=PARALLEL_PARTITION;";
126 CHKERR moab.load_file(mesh_file_name, 0, option);
127
128 // Create mofem interface
129 MoFEM::Core core(moab);
130 MoFEM::Interface &m_field = core;
131
132 // Add meshsets with material and boundary conditions
133 MeshsetsManager *meshsets_manager_ptr;
134 CHKERR m_field.getInterface(meshsets_manager_ptr);
135 CHKERR meshsets_manager_ptr->setMeshsetFromFile();
136
137 PetscPrintf(PETSC_COMM_WORLD,
138 "Read meshsets and added meshsets from bc.cfg\n");
139 for (_IT_CUBITMESHSETS_FOR_LOOP_(m_field, it)) {
140 PetscPrintf(PETSC_COMM_WORLD, "%s",
141 static_cast<std::ostringstream &>(
142 std::ostringstream().seekp(0) << *it << endl)
143 .str()
144 .c_str());
145 }
146
147 // Set entities bit level
148 CHKERR m_field.getInterface<BitRefManager>()->setBitRefLevelByDim(
149 0, 3, BitRefLevel().set(0));
150
151 UnsaturatedFlowElement uf(m_field);
152
153 ifstream ini_file(conf_file_name);
154 po::variables_map vm;
155 po::options_description config_file_options;
156 Range domain_ents, bc_boundary_ents;
157
158 map<int, CommonMaterialData> material_blocks;
159 map<int, double> head_blocks;
160 map<int, double> flux_blocks;
161 // Set material blocks
163 if (it->getName().compare(0, 4, "SOIL") != 0)
164 continue;
165 // get block id
166 const int block_id = it->getMeshsetId();
167 std::string block_name =
168 "mat_block_" + boost::lexical_cast<std::string>(block_id);
169 material_blocks[block_id].blockId = block_id;
170 material_blocks[block_id].addOptions(config_file_options, block_name);
171 }
173 if (it->getName().compare(0, 4, "HEAD") != 0)
174 continue;
175 // get block id
176 const int block_id = it->getMeshsetId();
177 std::string block_name =
178 "head_block_" + boost::lexical_cast<std::string>(block_id);
179 config_file_options.add_options()(
180 (block_name + ".head").c_str(),
181 po::value<double>(&head_blocks[block_id])->default_value(0));
182 }
184 if (it->getName().compare(0, 4, "FLUX") != 0)
185 continue;
186 // get block id
187 const int block_id = it->getMeshsetId();
188 std::string block_name =
189 "flux_block_" + boost::lexical_cast<std::string>(block_id);
190 config_file_options.add_options()(
191 (block_name + ".flux").c_str(),
192 po::value<double>(&head_blocks[block_id])->default_value(0));
193 }
194 po::parsed_options parsed =
195 parse_config_file(ini_file, config_file_options, true);
196 store(parsed, vm);
197 po::notify(vm);
199 if (it->getName().compare(0, 4, "SOIL") != 0)
200 continue;
201 const int block_id = it->getMeshsetId();
202 uf.dMatMap[block_id] = RegisterMaterials::mapOfRegistredMaterials.at(
203 material_blocks[block_id].matName)(material_blocks.at(block_id));
204 if (!uf.dMatMap.at(block_id)) {
205 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
206 "Material block not set");
207 }
208 // get block test
209 CHKERR m_field.get_moab().get_entities_by_type(
210 it->meshset, MBTET, uf.dMatMap.at(block_id)->tEts, true);
211 domain_ents.merge(uf.dMatMap.at(block_id)->tEts);
212 uf.dMatMap.at(block_id)->printMatParameters(block_id, "Read material");
213 }
214 std::vector<std::string> additional_parameters;
215 additional_parameters =
216 collect_unrecognized(parsed.options, po::include_positional);
217 for (std::vector<std::string>::iterator vit = additional_parameters.begin();
218 vit != additional_parameters.end(); vit++) {
219 CHKERR PetscPrintf(m_field.get_comm(),
220 "** WARNING Unrecognized option %s\n", vit->c_str());
221 }
222 // Set capillary pressure bc data
224 if (it->getName().compare(0, 4, "HEAD") != 0)
225 continue;
226 // get block id
227 const int block_id = it->getMeshsetId();
228 // create block data instance
229 uf.bcValueMap[block_id] =
230 boost::shared_ptr<UnsaturatedFlowElement::BcData>(
232 // get bc value
233 std::vector<double> attributes;
234 CHKERR it->getAttributes(attributes);
235 if (attributes.size() != 1)
236 SETERRQ1(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
237 "Wrong number of head parameters %d", attributes.size());
238 uf.bcValueMap[block_id]->fixValue = attributes[0];
239 std::string block_name =
240 "head_block_" + boost::lexical_cast<std::string>(block_id);
241 if (vm.count((block_name) + ".head")) {
242 uf.bcValueMap[block_id]->fixValue = head_blocks[block_id];
243 }
244 // cerr << uf.bcValueMap[block_id]->fixValue << endl;
245 // CHKERR it->printAttributes(std::cout);
246 // get faces in the block
247 CHKERR m_field.get_moab().get_entities_by_type(
248 it->meshset, MBTRI, uf.bcValueMap[block_id]->eNts, true);
249 bc_boundary_ents.merge(uf.bcValueMap[block_id]->eNts);
250 }
251
252 int max_flux_id = 0;
253 // Set water flux bc data
255 if (it->getName().compare(0, 4, "FLUX") != 0)
256 continue;
257 // get block id
258 const int block_id = it->getMeshsetId();
259 // create block data instance
260 uf.bcFluxMap[block_id] =
261 boost::shared_ptr<UnsaturatedFlowElement::BcData>(
263 // get bc value
264 std::vector<double> attributes;
265 CHKERR it->getAttributes(attributes);
266 // CHKERR it->printAttributes(std::cout);
267 uf.bcFluxMap[block_id]->fixValue = attributes[0];
268 std::string block_name =
269 "flux_block_" + boost::lexical_cast<std::string>(block_id);
270 if (vm.count((block_name) + ".flux")) {
271 uf.bcValueMap[block_id]->fixValue = head_blocks[block_id];
272 }
273 // get faces in the block
274 CHKERR m_field.get_moab().get_entities_by_type(
275 it->meshset, MBTRI, uf.bcFluxMap[block_id]->eNts, true);
276 bc_boundary_ents.merge(uf.bcFluxMap[block_id]->eNts);
277 max_flux_id = max_flux_id > block_id ? max_flux_id : block_id + 1;
278 }
279
280 // Add zero flux on the rest of the boundary
281 auto get_zero_flux_entities = [&m_field,
282 &pcomm](const auto &domain_ents,
283 const auto &bc_boundary_ents) {
284 Range zero_flux_ents;
285 Skinner skin(&m_field.get_moab());
286 Range domain_skin;
287 CHKERR skin.find_skin(0, domain_ents, false, domain_skin);
288 // filter not owned entities, those are not on boundary
289 CHKERR pcomm->filter_pstatus(domain_skin,
290 PSTATUS_SHARED | PSTATUS_MULTISHARED,
291 PSTATUS_NOT, -1, &zero_flux_ents);
292 zero_flux_ents = subtract(zero_flux_ents, bc_boundary_ents);
293 return zero_flux_ents;
294 };
295
296 CHKERR uf.addFields("VALUES", "FLUXES", order);
297 CHKERR uf.addFiniteElements("FLUXES", "VALUES");
298 CHKERR uf.buildProblem(
299 get_zero_flux_entities(domain_ents, bc_boundary_ents));
300 CHKERR uf.createMatrices();
301 CHKERR uf.setFiniteElements();
302 CHKERR uf.calculateEssentialBc();
303 CHKERR uf.calculateInitialPc();
304 CHKERR uf.solveProblem();
305 CHKERR uf.destroyMatrices();
306
307 }
309
311
312 return 0;
313}
#define CATCH_ERRORS
Catch errors.
#define MYPCOMM_INDEX
default communicator number PCOMM
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
@ BLOCKSET
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_INVALID_DATA
Definition definitions.h:36
#define CHKERR
Inline error check.
constexpr int order
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
#define _IT_CUBITMESHSETS_FOR_LOOP_(MESHSET_MANAGER, IT)
Iterator that loops over all the Cubit MeshSets in a moFEM field.
#define _IT_CUBITMESHSETS_BY_SET_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet having a particular BC meshset in a moFEM field.
char mesh_file_name[255]
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition Types.hpp:40
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
static map< std::string, CommonMaterialData::RegisterHook > mapOfRegistredMaterials
Class storing information about boundary condition.
Implementation of operators, problem and finite elements for unsaturated flow.
Managing BitRefLevels.
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =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:112
Deprecated interface functions.
Interface for managing meshsets containing materials and boundary conditions.
MoFEMErrorCode setMeshsetFromFile(const string file_name, const bool clean_file_options=true)
add blocksets reading config file
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
static char help[]

Variable Documentation

◆ help

char help[] = "...\n\n"
static

Definition at line 28 of file unsaturated_transport.cpp.