PeriDEM 0.2.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
input.cpp
Go to the documentation of this file.
1/*
2 * -------------------------------------------
3 * Copyright (c) 2021 - 2024 Prashant K. Jha
4 * -------------------------------------------
5 * PeriDEM https://github.com/prashjha/PeriDEM
6 *
7 * Distributed under the Boost Software License, Version 1.0. (See accompanying
8 * file LICENSE)
9 */
10
11#include "input.h"
12#include "decks/materialDeck.h"
13#include "decks/modelDeck.h"
14#include "decks/outputDeck.h"
15#include "decks/restartDeck.h"
16#include "decks/meshDeck.h"
17#include "pdecks/contactDeck.h"
18#include "pdecks/particleDeck.h"
19#include "pdecks/contactDeck.h"
20#include "util/methods.h"
22#include <yaml-cpp/yaml.h>
23#include <iostream>
24#include <cmath>
25
26namespace {
27
28inline bool definitelyGreaterThan(const double &a, const double &b) {
29 return (a - b) >
30 ((std::abs(a) < std::abs(b) ? std::abs(b) : std::abs(a)) * 1.0E-5);
31}
32
34 std::cout << "Warning: We now require rectangle to be specified "
35 "by 3 dimensional coordinates of corner points. In "
36 "future, this will be strongly preferred.\n";
37}
38
39std::string stringVecSerial(const std::vector<std::string> &svec) {
40 if (svec.empty())
41 return "";
42
43 std::string s = "";
44 for (size_t i=0; i<svec.size(); i++) {
45 s = s + svec[i];
46 if (i < svec.size() - 1)
47 s = s + "; ";
48 }
49
50 return s;
51}
52
53void readGeometry(YAML::Node data,
54 std::string data_block_name,
55 std::string &name,
56 std::vector<double> &params,
57 std::pair<std::vector<std::string>, std::vector<std::string>> &complexInfo) {
58
59 if (!data["Type"]) {
60 std::cerr << "Error; Can not read geometry type in yaml data in block = "
61 << data_block_name << ".\n";
62 exit(EXIT_FAILURE);
63 }
64 name = data["Type"].as<std::string>();
65
66 if (name == "complex") {
67 // read vector of types and flags
68 if (data["Vec_Type"]) {
69 for (auto f: data["Vec_Type"])
70 complexInfo.first.push_back(f.as<std::string>());
71 } else {
72 std::cerr << "Error: To define complex geometry, we require vector of "
73 "types in yaml data block = "
74 << data_block_name << "\n";
75 exit(EXIT_FAILURE);
76 }
77
78 if (data["Vec_Flag"]) {
79 for (auto f: data["Vec_Flag"])
80 complexInfo.second.push_back(f.as<std::string>());
81 } else {
82 std::cerr << "Error: To define complex geometry, we require vector of "
83 "flags in yaml data block = "
84 << data_block_name << "\n";
85 exit(EXIT_FAILURE);
86 }
87 }
88
89 params.clear();
90 if (data["Parameters"]) {
91 for (auto f : data["Parameters"])
92 params.push_back(f.as<double>());
93 } else {
94 std::cerr << "Error: Parameters defining geometry is not present in data block = "
95 << data_block_name << ".\n";
96 exit(EXIT_FAILURE);
97 }
98}
99
100void readGeometry(YAML::Node data,
101 std::string data_block_name,
102 util::geometry::GeomData &geomData) {
103 readGeometry(data,
104 data_block_name,
105 geomData.d_geomName,
106 geomData.d_geomParams,
107 geomData.d_geomComplexInfo);
108}
109
110} // namespace
111
112inp::Input::Input(std::string filename, bool createDefault)
113 : d_inputFilename(filename),
114 d_createDefault(createDefault),
115 d_meshDeck_p(nullptr),
116 d_materialDeck_p(nullptr),
117 d_outputDeck_p(nullptr),
118 d_modelDeck_p(nullptr) {
119
120 if (d_inputFilename.empty()) {
121 if (d_createDefault) {
122 std::cout
123 << "Input: YAML input filename is empty and createDefault is true. "
124 "Default input decks will be created.\n";
125 } else {
126 std::cerr << "Error: YAML input filename is empty and createDefault is false. Exiting.\n";
127 exit(EXIT_FAILURE);
128 }
129 }
130
131 // follow the order of reading
132 setModelDeck();
134
135 // read particle data
136 {
139 }
141
142 // setMeshDeck();
143
144 // setMaterialDeck();
145}
146
150
151//
152// accessor methods
153//
155 return d_modelDeck_p->d_particleSimType == "Multi_Particle";
156}
157
159 if (d_modelDeck_p->d_particleSimType == "Multi_Particle" or
160 d_modelDeck_p->d_particleSimType == "Single_Particle")
161 return true;
162
163 return false;
164}
165
166std::shared_ptr<inp::MaterialDeck> inp::Input::getMaterialDeck() { return
167 d_materialDeck_p; }
168
169std::shared_ptr<inp::MeshDeck> inp::Input::getMeshDeck() { return
170 d_meshDeck_p; }
171
172std::shared_ptr<inp::ModelDeck> inp::Input::getModelDeck() { return
173 d_modelDeck_p; }
174
175std::shared_ptr<inp::OutputDeck> inp::Input::getOutputDeck() { return
176 d_outputDeck_p; }
177
178std::shared_ptr<inp::RestartDeck> inp::Input::getRestartDeck() { return
179 d_restartDeck_p; }
180
181std::shared_ptr<inp::ParticleDeck> inp::Input::getParticleDeck() { return
182 d_particleDeck_p; }
183std::shared_ptr<inp::ContactDeck> inp::Input::getContactDeck() { return
184 d_contactDeck_p; }
185
186//
187// setter methods
188//
190 d_modelDeck_p = std::make_shared<inp::ModelDeck>();
191
192 if (d_inputFilename.empty() and d_createDefault)
193 return;
194
195 YAML::Node config = YAML::LoadFile(d_inputFilename);
196
197 // read dimension
198 if (config["Model"]["Dimension"])
199 d_modelDeck_p->d_dim = config["Model"]["Dimension"].as<size_t>();
200 else {
201 std::cerr << "Error: Please specify the dimension.\n";
202 exit(1);
203 }
204
205 // read discretization info
206 if (config["Model"]["Discretization_Type"]["Time"])
207 d_modelDeck_p->d_timeDiscretization =
208 config["Model"]["Discretization_Type"]["Time"].as<std::string>();
209
210 if (config["Model"]["Discretization_Type"]["Spatial"])
211 d_modelDeck_p->d_spatialDiscretization =
212 config["Model"]["Discretization_Type"]["Spatial"].as<std::string>();
213
214
215 if (d_modelDeck_p->d_timeDiscretization == "central_difference" or
216 d_modelDeck_p->d_timeDiscretization == "velocity_verlet")
217 d_modelDeck_p->d_simType = "explicit";
218
219 if (config["Model"]["Populate_ElementNodeConnectivity"])
220 d_modelDeck_p->d_populateElementNodeConnectivity = true;
221
222 if (config["Model"]["Quad_Approximation_Order"])
223 d_modelDeck_p->d_quadOrder = config["Model"]["Quad_Approximation_Order"].as<size_t>();
224
225 // check if this is single or multi-particle simulation
226 {
227 if (config["Model"]["Particle_Sim_Type"])
228 d_modelDeck_p->d_particleSimType = config["Model"]["Particle_Sim_Type"].as<std::string>();
229 else {
230 // determine based on other data in input file
231 if (config["Particle"])
232 d_modelDeck_p->d_particleSimType = "Multi_Particle";
233 }
234
235 if (d_modelDeck_p->d_particleSimType != "Multi_Particle"
236 and d_modelDeck_p->d_particleSimType != "Single_Particle") {
237 std::cerr << "Error: Model->Particle_Sim_Type should be either Multi_Particle or Single_Particle.\n";
238 exit(EXIT_FAILURE);
239 }
240
241 // check
242 if (d_modelDeck_p->d_particleSimType != "Multi_Particle" && d_modelDeck_p->d_particleSimType != "Single_Particle") {
243 std::cerr << "Error: d_particleSimType = " << d_modelDeck_p->d_particleSimType
244 << " in Model Deck is invalid.\n";
245 exit(EXIT_FAILURE);
246 }
247 }
248
249 // read horizon and horizon to mesh ratio (if available)
250 if (config["Model"]["Mesh_Size"])
251 d_modelDeck_p->d_h = config["Model"]["Mesh_Size"].as<double>();
252 if (config["Mesh"]["Mesh_Size"])
253 d_modelDeck_p->d_h = config["Mesh"]["Mesh_Size"].as<double>();
254
255 if (config["Model"]["Horizon"])
256 d_modelDeck_p->d_horizon = config["Model"]["Horizon"].as<double>();
257
258 if (config["Model"]["Horizon_h_Ratio"]) {
259 d_modelDeck_p->d_rh = config["Model"]["Horizon_h_Ratio"].as<int>();
260 if (config["Model"]["Mesh_Size"] or config["Mesh"]["Mesh_Size"]) {
261 d_modelDeck_p->d_horizon = d_modelDeck_p->d_h * double(d_modelDeck_p->d_rh);
262 }
263 else {
264 if (config["Model"]["Horizon"])
265 d_modelDeck_p->d_h =
266 d_modelDeck_p->d_horizon / double(d_modelDeck_p->d_rh);
267 }
268 }
269
270 // read final time and time step
271 if (config["Model"]["Final_Time"])
272 d_modelDeck_p->d_tFinal = config["Model"]["Final_Time"].as<double>();
273 if (config["Model"]["Time_Steps"])
274 d_modelDeck_p->d_Nt = config["Model"]["Time_Steps"].as<int>();
275
276 if (std::abs(d_modelDeck_p->d_tFinal) < 1.0E-10 or d_modelDeck_p->d_Nt <= 0) {
277 std::cerr << "Error: Check Final_Time and Time_Steps data.\n";
278 exit(1);
279 }
280
281 d_modelDeck_p->d_dt = d_modelDeck_p->d_tFinal / d_modelDeck_p->d_Nt;
282
283 // check if this is restart problem
284 if (config["Restart"])
285 d_modelDeck_p->d_isRestartActive = true;
286
287 // seed for random number generators
288 if (config["Model"]["Seed"])
289 d_modelDeck_p->d_seed = config["Model"]["Seed"].as<int>();
290} // setModelDeck
291
293 d_particleDeck_p = std::make_shared<inp::ParticleDeck>();
294
295 if (d_inputFilename.empty() and d_createDefault)
296 return;
297
298 YAML::Node config = YAML::LoadFile(d_inputFilename);
299
300 // <<<< >>>>
301 // <<<< STEP 1 - Read container geometry details >>>>
302 // <<<< >>>>
303 // read particle container geometry and size
304 if (config["Container"]["Geometry"]) {
305 auto ce = config["Container"]["Geometry"];
306
307 readGeometry(ce,
308 "Container->Geometry",
309 d_particleDeck_p->d_contGeomData);
310
311 util::geometry::createGeomObject(d_particleDeck_p->d_contGeomData,
312 d_modelDeck_p->d_dim);
313 }
314 else {
315 // create NullGeomObject if container geometry information is not provided
316 d_particleDeck_p->d_contGeomData.createNullGeomObject();
317 d_particleDeck_p->d_contGeomData.d_geom_p->d_tags.push_back("default");
318 }
319
320 // <<<< >>>>
321 // <<<< STEP 2 - Read Zone data >>>>
322 // <<<< >>>>
323 // read input file
324 size_t n = 1;
325 if (!config["Zone"]) {
326 if (isMultiParticle()) {
327 std::cerr
328 << "Error: Zone information is not provided for Multi_Particle simulation type.\n";
329 exit(EXIT_FAILURE);
330 }
331 }
332 else {
333 n = config["Zone"]["Zones"].as<size_t>();
334 if (n == 0) {
335 std::cerr << "Error: Require at least one zone to define particles.\n";
336 exit(EXIT_FAILURE);
337 }
338 }
339
340 d_particleDeck_p->d_zoneVec.resize(n);
341 d_particleDeck_p->d_particleZones.resize(n);
342 d_particleDeck_p->d_zoneToParticleORWallDeck.resize(n);
343
344 // read zone and particle information
345 for (size_t z = 1; z <= n; z++) {
346
347 std::string read_zone = "Zone_";
348 read_zone.append(std::to_string(z));
349
350 // <<<< >>>>
351 // <<<< STEP 2.1 - Read this zone information >>>>
352 // <<<< >>>>
353 auto zone_data = inp::Zone();
354 zone_data.d_zoneId = z - 1;
355 setZoneData({"Zone", read_zone}, &zone_data);
356
357 // store zone data
358 d_particleDeck_p->d_zoneVec[z - 1] = zone_data;
359
360 // <<<< >>>>
361 // <<<< STEP 2.2 - Read particle information in this zone >>>>
362 // <<<< >>>>
363 auto particle_zone = inp::ParticleZone();
364 particle_zone.d_zone = zone_data;
365 particle_zone.d_isWall = false;
366 if (config["Zone"][read_zone]["Is_Wall"])
367 particle_zone.d_isWall = config["Zone"][read_zone]["Is_Wall"].as<bool>();
368
369 setParticleData(read_zone, &particle_zone);
370
371 // <<<< >>>>
372 // <<<< STEP 2.3 - Read mesh and reference particle information >>>>
373 // <<<< >>>>
374 setZoneMeshDeck({"Mesh", read_zone}, &(particle_zone.d_meshDeck));
375
376 // For particle geometry and reference particle geometry, if the information
377 // is not given, we created a geometry from container. However,
378 // it is possible that particle geometry information is provided in
379 // Zone Mesh block
380 if (util::methods::isTagInList("copy_from_container",
381 particle_zone.d_particleGeomData.d_geom_p->d_tags)) {
382 // particle geometry is a copy of container in which case we see if
383 // Mesh block has geometry info that we can use to
384 // have more appropriate particle geometry
385 if (particle_zone.d_meshDeck.d_createMesh) {
386 if (particle_zone.d_meshDeck.d_createMeshGeomData.d_geom_p == nullptr) {
387 std::cerr << "Error: While reading mesh data for the case of creating mesh using in-built functions, "
388 "the code expected to either get geometry details in the Mesh block or the "
389 "geometry details in the Particle block.But since particle geometry "
390 "itself is a copy of container geometry, we can not proceed with the code.\n";
391 exit(EXIT_FAILURE);
392 }
393 else {
394 // use geometry in the Mesh block to define particle geometry
395 particle_zone.d_meshDeck.d_createMeshGeomData.copyGeometry(particle_zone.d_particleGeomData,
396 d_modelDeck_p->d_dim);
397 particle_zone.d_particleGeomData.d_geom_p->d_tags.push_back("copy");
398 particle_zone.d_particleGeomData.d_geom_p->d_tags.push_back("copy_from_zone_mesh");
399 }
400 }
401 }
402
403 // Check if mesh has info about geometry if we are creating mesh in the code
404 if (particle_zone.d_meshDeck.d_createMesh) {
405 if (particle_zone.d_meshDeck.d_createMeshGeomData.d_geom_p == nullptr) {
406 // since the geometry is not provided in Mesh block, assign geometry from particle
407 particle_zone.d_particleGeomData.copyGeometry(particle_zone.d_meshDeck.d_createMeshGeomData,
408 d_modelDeck_p->d_dim);
409 }
410 }
411
412 // <<<< >>>>
413 // <<<< STEP 2.4 - Read material properties of this zone >>>>
414 // <<<< >>>>
415 setZoneMaterialDeck({"Material", read_zone}, &(particle_zone.d_matDeck),
416 z);
417
418 // add to the list
419 d_particleDeck_p->d_particleZones[z - 1] = particle_zone;
420
421 // update zone to particle/wall deck map
422 d_particleDeck_p->d_zoneToParticleORWallDeck[z - 1] =
423 std::make_pair(particle_zone.d_isWall ? "wall" : "particle",
424 z - 1);
425 } // read zone and particle information
426
427 // <<<< >>>>
428 // <<<< STEP 3 - Read neighbor search data >>>>
429 // <<<< >>>>
430 if (config["Neighbor"]) {
431 auto ne = config["Neighbor"];
432 if (ne["Update_Criteria"])
433 d_particleDeck_p->d_pNeighDeck.d_updateCriteria =
434 ne["Update_Criteria"].as<std::string>();
435 else
436 d_particleDeck_p->d_pNeighDeck.d_updateCriteria = "simple_all";
437
438 if (ne["Search_Factor"])
439 d_particleDeck_p->d_pNeighDeck.d_sFactor =
440 ne["Search_Factor"].as<double>();
441 else
442 d_particleDeck_p->d_pNeighDeck.d_sFactor = 1.;
443
444 if (ne["Search_Interval"])
445 d_particleDeck_p->d_pNeighDeck.d_neighUpdateInterval =
446 ne["Search_Interval"].as<size_t>();
447 else
448 d_particleDeck_p->d_pNeighDeck.d_neighUpdateInterval = 1;
449 } else {
450 if (isMultiParticle()) {
451 std::cout << "Warning: Neighbor block is missing in input yaml file.\n";
452 exit(1);
453 }
454 }
455
456 // <<<< >>>>
457 // <<<< STEP 4 - Read gravity force information if any >>>>
458 // <<<< >>>>
459 if (config["Force_BC"]) {
460 if (config["Force_BC"]["Gravity"]) {
461
462 d_particleDeck_p->d_gravityActive = true;
463
464 auto gf = std::vector<double>(3, 0.);
465 size_t gf_c = 0;
466 for (auto e : config["Force_BC"]["Gravity"])
467 gf[gf_c++] = e.as<double>();
468
469 d_particleDeck_p->d_gravity = util::Point(gf[0], gf[1], gf[2]);
470 }
471 }
472
473 // <<<< >>>>
474 // <<<< STEP 5 - Read force bc and displacement bc >>>>
475 // <<<< >>>>
476 std::vector<std::string> vtags = {"Displacement_BC", "Force_BC"};
477
478 for (const auto &tag : vtags) {
479
480 // get number of force bc sets
481 int nsets = 0;
482 if (config[tag]["Sets"])
483 nsets = config[tag]["Sets"].as<int>();
484
485 for (size_t s = 1; s <= nsets; s++) {
486
487 // prepare string Set_s to read file
488 std::string read_set = "Set_";
489 read_set.append(std::to_string(s));
490 auto e = config[tag][read_set];
491
492 auto bc_deck = PBCData();
493
494 // selection type
495 if (e["Selection_Type"])
496 bc_deck.d_selectionType = e["Selection_Type"].as<std::string>();
497
498 // find selection type based on data provided
499 if (e["Region"]) {
500
501 bc_deck.d_isRegionActive = true;
502
503 bc_deck.d_selectionType = "region";
504
505 if (e["Particle_List"])
506 bc_deck.d_selectionType += "_with_include_list";
507
508 if (e["Wall_List"]) {
509 std::cerr << "Error: We only accept 'Particle_List'.\n";
510 exit(EXIT_FAILURE);
511 }
512
513 if (e["Particle_Exclude_List"])
514 bc_deck.d_selectionType += "_with_exclude_list";
515 } else {
516
517 bc_deck.d_isRegionActive = false;
518
519 if (e["Particle_List"])
520 bc_deck.d_selectionType = "particle";
521
522 if (e["Wall_List"]) {
523 std::cerr << "Error: We only accept 'Particle_List'.\n";
524 exit(EXIT_FAILURE);
525 }
526 }
527
528 // check if region is provided
529 if (e["Region"]) {
530
531 // Read geometry details
532 if (e["Region"]["Geometry"]) {
533
534 auto ce = e["Region"]["Geometry"];
535
536 readGeometry(ce, tag + "->" + read_set + "->Region->Geometry",
537 bc_deck.d_regionGeomData);
538
539 util::geometry::createGeomObject(bc_deck.d_regionGeomData,
540 d_modelDeck_p->d_dim);
541 } // if geometry in config
542 else {
543 std::cerr << "Error: For region-based application of boundary condition, we require"
544 " Geometry data.\n";
545 exit(EXIT_FAILURE);
546 }
547 } // if region
548
549 // check if particle list is provided
550 if (e["Particle_List"]) {
551 for (auto f : e["Particle_List"])
552 bc_deck.d_pList.emplace_back(f.as<size_t>());
553 }
554
555 // check if wall list is provided
556 if (e["Wall_List"]) {
557 std::cerr << "Error: We only accept 'Particle_List'.\n";
558 exit(EXIT_FAILURE);
559 }
560
561 // check if particle exclude list is provided
562 if (e["Particle_Exclude_List"]) {
563 for (auto f : e["Particle_Exclude_List"])
564 bc_deck.d_pNotList.emplace_back(f.as<size_t>());
565 }
566
567 // read direction
568 for (auto j : e["Direction"])
569 bc_deck.d_direction.push_back(j.as<size_t>());
570
571 // read time function type
572 if (e["Time_Function"]) {
573 bc_deck.d_timeFnType = e["Time_Function"]["Type"].as<std::string>();
574 if (e["Time_Function"]["Parameters"])
575 for (auto j : e["Time_Function"]["Parameters"])
576 bc_deck.d_timeFnParams.push_back(j.as<double>());
577 }
578
579 if (e["Spatial_Function"]) {
580 bc_deck.d_spatialFnType =
581 e["Spatial_Function"]["Type"].as<std::string>();
582 if (e["Spatial_Function"]["Parameters"])
583 for (auto j : e["Spatial_Function"]["Parameters"])
584 bc_deck.d_spatialFnParams.push_back(j.as<double>());
585 }
586
587 // for displacement bc, check if this is simple zero displacement
588 // condition
589 if (tag == "Displacement_BC" && e["Zero_Displacement"])
590 bc_deck.d_isDisplacementZero = e["Zero_Displacement"].as<bool>();
591
592 if (bc_deck.d_regionGeomData.d_geom_p == nullptr)
593 bc_deck.d_regionGeomData.createNullGeomObject();
594
595 // add data
596 if (tag == "Displacement_BC")
597 d_particleDeck_p->d_dispDeck.push_back(bc_deck);
598 else
599 d_particleDeck_p->d_forceDeck.push_back(bc_deck);
600 } // loading sets
601 }
602
603 // <<<< >>>>
604 // <<<< STEP 6 - Read initial condition data >>>>
605 // <<<< >>>>
606 if (config["IC"]) {
607 if (config["IC"]["Constant_Velocity"]) {
608
609 d_particleDeck_p->d_icDeck.d_icActive = true;
610
611 auto icv = std::vector<double>(3, 0.);
612 size_t icv_c = 0;
613 for (auto e : config["IC"]["Constant_Velocity"]["Velocity_Vector"])
614 icv[icv_c++] = e.as<double>();
615
616 d_particleDeck_p->d_icDeck.d_icVec = util::Point(icv[0], icv[1], icv[2]);
617
618 // get particle ids
619 d_particleDeck_p->d_icDeck.d_pList.clear();
620 if (isMultiParticle()) {
621 for (auto e: config["IC"]["Constant_Velocity"]["Particle_List"])
622 d_particleDeck_p->d_icDeck.d_pList.push_back(e.as<size_t>());
623 }
624 else {
625 // the only particle in Single_Particle Simulation is particle 0
626 d_particleDeck_p->d_icDeck.d_pList.push_back(0);
627 }
628 }
629 }
630
631 // <<<< >>>>
632 // <<<< STEP 7 - Read test name (if any) >>>>
633 // <<<< >>>>
634 if (config["Particle"]["Test_Name"]) {
635 d_particleDeck_p->d_testName =
636 config["Particle"]["Test_Name"].as<std::string>();
637
638 if (d_particleDeck_p->d_testName == "compressive_test") {
639 if (!config["Particle"]["Compressive_Test"]) {
640 std::cerr << "Error: For compressive test, we require more "
641 "information such as wall id and wall force direction\n";
642 exit(0);
643 }
644
645 // check
646 if (config["Particle"]["Compressive_Test"]["Wall_Id"]) {
647 std::cerr << "Error: We only accept 'Particle_Id' in 'config[Particle][Compressive_Test]'.\n";
648 exit(EXIT_FAILURE);
649 }
650 d_particleDeck_p->d_particleIdCompressiveTest =
651 config["Particle"]["Compressive_Test"]["Particle_Id"].as<size_t>();
652
653 if (config["Particle"]["Compressive_Test"]["Wall_Force_Direction"]) {
654 std::cerr << "Error: We only accept 'Particle_Force_Direction' in 'config[Particle][Compressive_Test]'.\n";
655 exit(EXIT_FAILURE);
656 }
657 d_particleDeck_p->d_particleForceDirectionCompressiveTest =
658 config["Particle"]["Compressive_Test"]["Particle_Force_Direction"]
659 .as<size_t>();
660
661 }
662 } // test block
663} // setParticleDeck
664
666 d_contactDeck_p = std::make_shared<inp::ContactDeck>();
667
668 if (d_inputFilename.empty() and d_createDefault)
669 return;
670
671 YAML::Node config = YAML::LoadFile(d_inputFilename);
672
673 if (d_particleDeck_p == nullptr) {
674 std::cerr << "Error: Particle data must be read and populated before "
675 "reading contact data"
676 << std::endl;
677 exit(1);
678 }
679
680 // loop over zones
681 size_t n = d_particleDeck_p->d_zoneVec.size();
682
683 d_contactDeck_p->d_data.resize(n);
684 for (size_t i = 0; i < n; i++)
685 d_contactDeck_p->d_data[i].resize(n);
686
687 if (!isMultiParticle()) {
688 return;
689 }
690
691 for (size_t z = 1; z <= n; z++) {
692 for (size_t zz = z; zz <= n; zz++) {
693 std::string read_zone = "Zone_" + std::to_string(z) + std::to_string(zz);
694
695 if (d_outputDeck_p->d_debug > 3)
696 std::cout << "Processing pair (z, zz) = (" << z << ", " << zz << ").\n";
697
698 auto e = config["Contact"][read_zone];
699
700 // check if we copy the contact data from previous zone pair
701 if (e["Copy_Contact_Data"]) {
702
703 // get pair of zone id to copy
704 std::vector<size_t> zone_pair;
705 for (auto j : e["Copy_Contact_Data"])
706 zone_pair.push_back(j.as<size_t>());
707
708 if (zone_pair.size() != 2) {
709 std::cerr << "Error: Copy_Contact_Data in Contact deck for zone pair "
710 << read_zone << " is invalid.\n";
711 exit(1);
712 }
713
714 // check if zone_pair data has been read (if not then issue error)
715 //if (zone_pair[0] > z or zone_pair[1] > zz - 1) {
716 if (zone_pair[0] > z or (zone_pair[0] == z and zone_pair[1] >= zz)) {
717 std::cerr << "Error: Can not copy the contact data for zone = " <<
718 read_zone << " as the pair of data = ("
719 << zone_pair[0] << ", " << zone_pair[1]
720 << ") required to copy have not "
721 "been read.\n";
722 }
723
724 // create a copy of contact data
726 d_contactDeck_p->d_data[zone_pair[0] - 1][zone_pair[1] - 1];
727
728 if (d_outputDeck_p->d_debug > 3) {
729 std::cout << "Processing pair (z, zz) = (" << z << ", " << zz << "). "
730 << "Copying contact data from (n, m) = (" << zone_pair[0]
731 << ", " << zone_pair[1] << ").\n";
732 std::cout << cd.printStr();
733 }
734
735 // copy to the data
736 d_contactDeck_p->d_data[z - 1][zz - 1] = cd;
737 d_contactDeck_p->d_data[zz - 1][z - 1] = cd;
738 }
739 else {
740
741 auto cd = inp::ContactPairDeck();
742 //if (z == zz) {
743 if (e["Contact_Radius_Factor"]) {
744 cd.d_contactR = e["Contact_Radius_Factor"].as<double>();
745 cd.d_computeContactR = true;
746 } else if (e["Contact_Radius"]) {
747 cd.d_contactR = e["Contact_Radius"].as<double>();
748 cd.d_computeContactR = false;
749 }
750 //}
751
752 if (e["Damping_On"])
753 cd.d_dampingOn = e["Damping_On"].as<bool>();
754
755 if (e["Friction_On"])
756 cd.d_frictionOn = e["Friction_On"].as<bool>();
757
758 if (!e["Kn"]) {
759
760 bool v_max_found = false;
761 bool delta_max_found = false;
762
763 if (e["V_Max"])
764 v_max_found = true;
765 if (e["Delta_Max"])
766 delta_max_found = true;
767
768 if (v_max_found and delta_max_found) {
769 cd.d_vMax = e["V_Max"].as<double>();
770 cd.d_deltaMax = e["Delta_Max"].as<double>();
771 }
772
773 if (v_max_found and !delta_max_found) {
774 cd.d_vMax = e["V_Max"].as<double>();
775 cd.d_deltaMax = 1.;
776 }
777
778 if (!v_max_found) {
779 std::cerr << "Error: Need V_Max parameter for contact force. Either"
780 " provide V_Max (and/or Delta_Max) or provide Kn.\n"
781 << "Processing pair (z, zz) = (" << z << ", " << zz << ").\n"
782 << "Contact deck info\n"
783 << cd.printStr();
784 exit(1);
785 }
786 } else {
787
788 cd.d_Kn = e["Kn"].as<double>();
789
790 cd.d_deltaMax = 1.;
791 cd.d_vMax = std::sqrt(cd.d_Kn);
792 }
793
794 if (cd.d_dampingOn) {
795 if (e["Epsilon"])
796 cd.d_eps = e["Epsilon"].as<double>();
797 else {
798 std::cerr << "Error: Epsilon needed" << std::endl;
799 exit(1);
800 }
801 } else {
802 cd.d_eps = 1.;
803 }
804
805 if (cd.d_dampingOn && util::isLess(cd.d_betanFactor, 1.0e-8))
806 cd.d_dampingOn = false;
807
808 if (cd.d_frictionOn) {
809 if (e["Friction_Coeff"])
810 cd.d_mu = e["Friction_Coeff"].as<double>();
811 else {
812 std::cerr << "Error: Friction_Coeff needed" << std::endl;
813 exit(1);
814 }
815 } else {
816 cd.d_mu = 0.;
817 }
818
819 if (e["Kn_Factor"])
820 cd.d_KnFactor = e["Kn_Factor"].as<double>();
821 if (e["Beta_n_Factor"])
822 cd.d_betanFactor = e["Beta_n_Factor"].as<double>();
823
824 if (!cd.d_dampingOn)
825 cd.d_betanFactor = 0.;
826
827 // add contact data to list (symmetric list)
828 d_contactDeck_p->d_data[z - 1][zz - 1] = cd;
829 d_contactDeck_p->d_data[zz - 1][z - 1] = cd;
830 }
831 }
832 }
833} // setContactDeck
834
836 d_restartDeck_p = std::make_shared<inp::RestartDeck>();
837 if (d_inputFilename.empty() and d_createDefault)
838 return;
839
840 YAML::Node config = YAML::LoadFile(d_inputFilename);
841
842 // read restart file
843 if (config["Restart"]) {
844 if (config["Restart"]["File"])
845 d_restartDeck_p->d_file = config["Restart"]["File"].as<std::string>();
846 else {
847 std::cerr << "Error: Please specify the file for restart.\n";
848 exit(1);
849 }
850
851 // read time step from which to begin
852 if (config["Restart"]["Step"])
853 d_restartDeck_p->d_step = config["Restart"]["Step"].as<size_t>();
854 else {
855 std::cerr << "Error: Please specify the time step from which to restart "
856 "the simulation.\n";
857 exit(1);
858 }
859
860 if (config["Restart"]["Change_Reference_Free_Dofs"])
861 d_restartDeck_p->d_changeRefFreeDofs =
862 config["Restart"]["Change_Reference_Free_Dofs"].as<bool>();
863 }
864} // setRestartDeck
865
867 d_meshDeck_p = std::make_shared<inp::MeshDeck>();
868 if (d_inputFilename.empty() and d_createDefault)
869 return;
870
871 YAML::Node config = YAML::LoadFile(d_inputFilename);
872
873 // read dimension
874 if (config["Model"]["Dimension"])
875 d_meshDeck_p->d_dim = config["Model"]["Dimension"].as<size_t>();
876
877 // read spatial discretization type
878 if (config["Model"]["Discretization_Type"]["Spatial"])
879 d_meshDeck_p->d_spatialDiscretization =
880 config["Model"]["Discretization_Type"]["Spatial"].as<std::string>();
881
882 if (config["Model"]["Populate_ElementNodeConnectivity"])
883 d_meshDeck_p->d_populateElementNodeConnectivity = true;
884
885 if (config["Model"]["Quad_Approximation_Order"])
886 d_meshDeck_p->d_quadOrder = config["Model"]["Quad_Approximation_Order"].as<size_t>();
887
888 // read mesh filename
889 if (config["Mesh"]["File"])
890 d_meshDeck_p->d_filename = config["Mesh"]["File"].as<std::string>();
891
892 if (config["Mesh"]["CreateMesh"])
893 d_meshDeck_p->d_createMesh = config["Mesh"]["CreateMesh"].as<bool>();
894
895 if (config["Mesh"]["CreateMeshInfo"])
896 d_meshDeck_p->d_createMeshInfo = config["Mesh"]["CreateMeshInfo"].as<std::string>();
897
898 if (d_modelDeck_p->d_h < 1.0E-12)
899 d_meshDeck_p->d_computeMeshSize = true;
900 else
901 d_meshDeck_p->d_h = d_modelDeck_p->d_h;
902
903 // handle missing information
904 if (d_meshDeck_p->d_filename.empty() and !d_meshDeck_p->d_createMesh){
905 std::cerr << "Error: Either specify mesh filename or provide Mesh->CreateMesh: true in input file.\n";
906 exit(EXIT_FAILURE);
907 }
908
909 if (d_meshDeck_p->d_createMesh and d_meshDeck_p->d_h < 1.e-16) {
910 std::cerr << "Error: CreateMesh is set to true but mesh size (using Model->Mesh_Size or Mesh->Mesh_Size) is not specified.\n";
911 exit(EXIT_FAILURE);
912 }
913} // setMeshDeck
914
916 d_materialDeck_p = std::make_shared<inp::MaterialDeck>();
917 if (d_inputFilename.empty() and d_createDefault)
918 return;
919
920 YAML::Node config = YAML::LoadFile(d_inputFilename);
921
922 auto e = config["Material"];
923 if (e["Is_Plane_Strain"])
924 d_materialDeck_p->d_isPlaneStrain = e["Is_Plane_Strain"].as<bool>();
925 if (e["Type"])
926 d_materialDeck_p->d_materialType = e["Type"].as<std::string>();
927 else {
928 std::cerr << "Error: Please specify the material type.\n";
929 exit(1);
930 }
931 if (e["Compute_From_Classical"])
932 d_materialDeck_p->d_computeParamsFromElastic =
933 e["Compute_From_Classical"].as<bool>();
934 if (e["E"])
935 d_materialDeck_p->d_matData.d_E = e["E"].as<double>();
936 if (e["G"])
937 d_materialDeck_p->d_matData.d_G = e["G"].as<double>();
938 if (e["K"])
939 d_materialDeck_p->d_matData.d_K = e["K"].as<double>();
940 if (e["Lambda"])
941 d_materialDeck_p->d_matData.d_lambda = e["Lambda"].as<double>();
942 if (e["Mu"])
943 d_materialDeck_p->d_matData.d_mu = e["Mu"].as<double>();
944 if (e["Poisson_Ratio"])
945 d_materialDeck_p->d_matData.d_nu = e["Poisson_Ratio"].as<double>();
946 if (e["Gc"])
947 d_materialDeck_p->d_matData.d_Gc = e["Gc"].as<double>();
948 if (e["KIc"])
949 d_materialDeck_p->d_matData.d_KIc = e["KIc"].as<double>();
950
951 // read pairwise (bond) potential
952 if (e["Bond_Potential"]) {
953 auto f = e["Bond_Potential"];
954 if (f["Type"])
955 d_materialDeck_p->d_bondPotentialType = f["Type"].as<size_t>();
956 if (f["Check_Sc_Factor"])
957 d_materialDeck_p->d_checkScFactor = f["Check_Sc_Factor"].as<double>();
958 if (f["Irreversible_Bond_Fracture"])
959 d_materialDeck_p->d_irreversibleBondBreak =
960 f["Irreversible_Bond_Fracture"].as<bool>();
961 if (f["Parameters"])
962 for (auto j : f["Parameters"])
963 d_materialDeck_p->d_bondPotentialParams.push_back(j.as<double>());
964 }
965
966 // read hydrostatic (state) potential
967 if (e["State_Potential"]) {
968 auto f = e["State_Potential"];
969 if (f["Type"])
970 d_materialDeck_p->d_statePotentialType = f["Type"].as<size_t>();
971 if (f["Contribution_From_Broken_Bond"])
972 d_materialDeck_p->d_stateContributionFromBrokenBond =
973 f["Contribution_From_Broken_Bond"].as<bool>();
974 if (f["Parameters"])
975 for (auto j : f["Parameters"])
976 d_materialDeck_p->d_statePotentialParams.push_back(j.as<double>());
977 }
978
979 // read influence function
980 if (e["Influence_Function"]) {
981 auto f = e["Influence_Function"];
982 if (f["Type"])
983 d_materialDeck_p->d_influenceFnType = f["Type"].as<size_t>();
984 if (f["Parameters"])
985 for (auto j : f["Parameters"])
986 d_materialDeck_p->d_influenceFnParams.push_back(j.as<double>());
987 }
988
989 // read density
990 if (e["Density"])
991 d_materialDeck_p->d_density = e["Density"].as<double>();
992 else {
993 std::cerr << "Error: Please specify the density of the material.\n";
994 exit(1);
995 }
996} // setMaterialDeck
997
999 d_outputDeck_p = std::make_shared<inp::OutputDeck>();
1000 if (d_inputFilename.empty() and d_createDefault)
1001 return;
1002
1003 YAML::Node config = YAML::LoadFile(d_inputFilename);
1004
1005 if (config["Output"]) {
1006 auto e = config["Output"];
1007 if (e["File_Format"])
1008 d_outputDeck_p->d_outFormat = e["File_Format"].as<std::string>();
1009 if (e["Path"])
1010 d_outputDeck_p->d_path = e["Path"].as<std::string>();
1011 if (e["Tags"])
1012 for (auto f : e["Tags"])
1013 d_outputDeck_p->d_outTags.push_back(f.as<std::string>());
1014
1015 if (e["Output_Interval"])
1016 d_outputDeck_p->d_dtOut = e["Output_Interval"].as<size_t>();
1017 d_outputDeck_p->d_dtOutOld = d_outputDeck_p->d_dtOut;
1018 d_outputDeck_p->d_dtOutCriteria = d_outputDeck_p->d_dtOut;
1019 if (e["Debug"])
1020 d_outputDeck_p->d_debug = e["Debug"].as<size_t>();
1021 if (e["Perform_FE_Out"])
1022 d_outputDeck_p->d_performFEOut = e["Perform_FE_Out"].as<bool>();
1023 if (e["Compress_Type"])
1024 d_outputDeck_p->d_compressType = e["Compress_Type"].as<std::string>();
1025 if (e["Output_Criteria"]) {
1026 if (e["Output_Criteria"]["Type"])
1027 d_outputDeck_p->d_outCriteria =
1028 e["Output_Criteria"]["Type"].as<std::string>();
1029 if (e["Output_Criteria"]["New_Interval"])
1030 d_outputDeck_p->d_dtOutCriteria =
1031 e["Output_Criteria"]["New_Interval"].as<size_t>();
1032 if (e["Output_Criteria"]["Parameters"]) {
1033 auto ps = e["Output_Criteria"]["Parameters"];
1034 for (auto p : ps)
1035 d_outputDeck_p->d_outCriteriaParams.emplace_back(p.as<double>());
1036 }
1037 }
1038
1039 if (e["Perform_Out"])
1040 d_outputDeck_p->d_performOut = e["Perform_Out"].as<bool>();
1041 if (e["Test_Output_Interval"])
1042 d_outputDeck_p->d_dtTestOut = e["Test_Output_Interval"].as<size_t>();
1043 if (e["Tag_PP"])
1044 d_outputDeck_p->d_tagPPFile = e["Tag_PP"].as<std::string>();
1045 }
1046} // setOutputDeck
1047
1048void inp::Input::setZoneMaterialDeck(std::vector<std::string> s_config,
1049 inp::MaterialDeck *m_deck, size_t zone_id) {
1050
1051 YAML::Node config = YAML::LoadFile(d_inputFilename);
1052
1053 auto e = config[s_config[0]];
1054 if (s_config.size() > 1) {
1055 if (s_config.size() == 2)
1056 e = config[s_config[0]][s_config[1]];
1057 else if (s_config.size() == 3)
1058 e = config[s_config[0]][s_config[1]][s_config[2]];
1059 }
1060
1061 if (!e) {
1062 std::cerr << "Error: Can not read material properties for given zone.\n";
1063 exit(1);
1064 }
1065
1066 // check if we copy the material data from previous material zone deck
1067 if (e["Copy_Material_Data"]) {
1068
1069 // get the zone id from which we need to read the material data
1070 auto copy_zone_id = e["Copy_Material_Data"].as<size_t>();
1071
1072 if (copy_zone_id >= zone_id) {
1073 std::cerr << "Error: Invalid zone id for Material deck corresponding to"
1074 " zone = " << zone_id << ".\n";
1075 exit(1);
1076 }
1077
1078 s_config[1] = "Zone_" + std::to_string(copy_zone_id);
1079
1080 // make sure the copy zone does not have copy tag
1081 if (config[s_config[0]][s_config[1]]["Copy_Material_Data"]) {
1082 std::cerr << "Error: Tag " << s_config[0] << "->" << s_config[1]
1083 << " should not have tag Copy_Material_Data\n";
1084 exit(1);
1085 }
1086
1087 setZoneMaterialDeck(s_config, m_deck, copy_zone_id);
1088 return;
1089 }
1090
1091 if (e["Is_Plane_Strain"])
1092 m_deck->d_isPlaneStrain = e["Is_Plane_Strain"].as<bool>();
1093 if (e["Type"])
1094 m_deck->d_materialType = e["Type"].as<std::string>();
1095 else {
1096 std::cerr << "Error: Please specify the material type.\n";
1097 exit(1);
1098 }
1099 if (e["Compute_From_Classical"])
1100 m_deck->d_computeParamsFromElastic = e["Compute_From_Classical"].as<bool>();
1101 if (e["E"])
1102 m_deck->d_matData.d_E = e["E"].as<double>();
1103 if (e["G"])
1104 m_deck->d_matData.d_G = e["G"].as<double>();
1105 if (e["K"])
1106 m_deck->d_matData.d_K = e["K"].as<double>();
1107 if (e["Lambda"])
1108 m_deck->d_matData.d_lambda = e["Lambda"].as<double>();
1109 if (e["Mu"])
1110 m_deck->d_matData.d_mu = e["Mu"].as<double>();
1111 if (e["Poisson_Ratio"])
1112 m_deck->d_matData.d_nu = e["Poisson_Ratio"].as<double>();
1113 if (e["Gc"])
1114 m_deck->d_matData.d_Gc = e["Gc"].as<double>();
1115 if (e["KIc"])
1116 m_deck->d_matData.d_KIc = e["KIc"].as<double>();
1117
1118 // read pairwise (bond) potential
1119 if (e["Bond_Potential"]) {
1120 auto f = e["Bond_Potential"];
1121 if (f["Type"])
1122 m_deck->d_bondPotentialType = f["Type"].as<size_t>();
1123 if (f["Check_Sc_Factor"])
1124 m_deck->d_checkScFactor = f["Check_Sc_Factor"].as<double>();
1125 if (f["Irreversible_Bond_Fracture"])
1126 m_deck->d_irreversibleBondBreak =
1127 f["Irreversible_Bond_Fracture"].as<bool>();
1128 if (f["Parameters"])
1129 for (auto j : f["Parameters"])
1130 m_deck->d_bondPotentialParams.push_back(j.as<double>());
1131 }
1132
1133 // read hydrostatic (state) potential
1134 if (e["State_Potential"]) {
1135 auto f = e["State_Potential"];
1136 if (f["Type"])
1137 m_deck->d_statePotentialType = f["Type"].as<size_t>();
1138 if (f["Contribution_From_Broken_Bond"])
1140 f["Contribution_From_Broken_Bond"].as<bool>();
1141 if (f["Parameters"])
1142 for (auto j : f["Parameters"])
1143 m_deck->d_statePotentialParams.push_back(j.as<double>());
1144 }
1145
1146 // read influence function
1147 if (e["Influence_Function"]) {
1148 auto f = e["Influence_Function"];
1149 if (f["Type"])
1150 m_deck->d_influenceFnType = f["Type"].as<size_t>();
1151 if (f["Parameters"])
1152 for (auto j : f["Parameters"])
1153 m_deck->d_influenceFnParams.push_back(j.as<double>());
1154 }
1155
1156 // read density
1157 if (e["Density"])
1158 m_deck->d_density = e["Density"].as<double>();
1159 else {
1160 std::cerr << "Error: Please specify the density of the material.\n";
1161 exit(1);
1162 }
1163
1164 // read horizon
1165 if (e["Horizon"])
1166 m_deck->d_horizon = e["Horizon"].as<double>();
1167
1168 // read horizon to mesh ratio
1169 if (e["Horizon_Mesh_Ratio"])
1170 m_deck->d_horizonMeshRatio = e["Horizon_Mesh_Ratio"].as<double>();
1171
1172 // std::cout << m_deck->printStr(0, 0) << "\n";
1173} // setMaterialDeck
1174
1175void inp::Input::setZoneMeshDeck(std::vector<std::string> s_config,
1176 inp::MeshDeck *mesh_deck) {
1177
1178 YAML::Node config = YAML::LoadFile(d_inputFilename);
1179
1180 auto e = config[s_config[0]];
1181 if (s_config.size() > 1) {
1182 if (s_config.size() == 2)
1183 e = config[s_config[0]][s_config[1]];
1184 else if (s_config.size() == 3)
1185 e = config[s_config[0]][s_config[1]][s_config[2]];
1186 }
1187
1188 if (!e) {
1189 std::cerr << "Error: Can not read mesh properties for given zone.\n";
1190 exit(1);
1191 }
1192
1193 // read dimension
1194 mesh_deck->d_dim = config["Model"]["Dimension"].as<size_t>();
1195
1196 // read spatial discretization type
1197 if (config["Model"]["Discretization_Type"]["Spatial"])
1198 mesh_deck->d_spatialDiscretization =
1199 config["Model"]["Discretization_Type"]["Spatial"].as<std::string>();
1200
1201 // read mesh filename
1202 if (e["File"])
1203 mesh_deck->d_filename = e["File"].as<std::string>();
1204
1205 if (e["CreateMesh"]) {
1206 if (e["CreateMesh"]["Flag"])
1207 mesh_deck->d_createMesh = e["CreateMesh"]["Flag"].as<bool>();
1208
1209 if (e["CreateMesh"]["Info"])
1210 mesh_deck->d_createMeshInfo = e["CreateMesh"]["Info"].as<std::string>();
1211
1212 // read geometry details if provided
1213 if (e["CreateMesh"]["Geometry"]) {
1214
1215 readGeometry(e["CreateMesh"]["Geometry"],
1216 "Mesh->CreateMesh->Geometry",
1217 mesh_deck->d_createMeshGeomData);
1218
1220 d_modelDeck_p->d_dim);
1221 }
1222 }
1223
1224 if (e["Mesh_Size"]) {
1225 mesh_deck->d_h = e["Mesh_Size"].as<double>();
1226 mesh_deck->d_computeMeshSize = false;
1227 } else
1228 mesh_deck->d_computeMeshSize = true;
1229
1230 // handle missing information
1231 if (mesh_deck->d_filename.empty() and !mesh_deck->d_createMesh){
1232 std::cerr << "Error: Either specify mesh filename or provide Mesh->CreateMesh: true in input file.\n";
1233 exit(EXIT_FAILURE);
1234 }
1235
1236 if (mesh_deck->d_createMesh and mesh_deck->d_h < 1.e-16) {
1237 std::cerr << "Error: CreateMesh is set to true but mesh size (using Model->Mesh_Size or Mesh->Mesh_Size) is not specified.\n";
1238 exit(EXIT_FAILURE);
1239 }
1240
1241 //mesh_deck->print();
1242}
1243
1244void inp::Input::setZoneData(std::vector<std::string> s_config,
1245 inp::Zone *zone_data) {
1246
1247 YAML::Node config = YAML::LoadFile(d_inputFilename);
1248 auto e = config[s_config[0]];
1249 if (s_config.size() > 1)
1250 e = config[s_config[0]][s_config[1]];
1251 if (s_config.size() > 2)
1252 e = config[s_config[0]][s_config[1]][s_config[2]];
1253
1254 // Do not issue error if there is no zone data as zone data do not play critical role
1255 // and it is in our interest to not force providing this data in input file to keep
1256 // input file lite.
1257 // if (!e) {
1258 // std::cerr << "Error: Can not read zone properties for given zone.\n";
1259 // exit(1);
1260 // }
1261
1262 // read zone information
1263 if (e["Type"]) {
1264 readGeometry(e, stringVecSerial(s_config), zone_data->d_zoneGeomData);
1265
1267 d_modelDeck_p->d_dim,
1268 false);
1269 } else {
1270 // assign container geometry
1271 this->d_particleDeck_p->d_contGeomData.copyGeometry(zone_data->d_zoneGeomData,
1272 d_modelDeck_p->d_dim);
1273 zone_data->d_zoneGeomData.d_geom_p->d_tags.push_back("copy");
1274 zone_data->d_zoneGeomData.d_geom_p->d_tags.push_back("copy_from_container");
1275 }
1276}
1277
1278void inp::Input::setParticleData(std::string string_zone,
1279 inp::ParticleZone *particle_data) {
1280
1281 YAML::Node config = YAML::LoadFile(d_inputFilename);
1282
1283 auto pe = config["Particle"][string_zone];
1284
1285 if (particle_data->d_isWall) {
1286 if (!pe) {
1287 auto wall_pe = config["Particle"][string_zone];
1288 if (!wall_pe) {
1289 std::cerr << "Error: For this particle/wall in zone = " << string_zone
1290 << " , neither config['Particle'] "
1291 "nor config['Wall'] exist in input file.\n";
1292 exit(EXIT_FAILURE);
1293 } else {
1294 pe = wall_pe;
1295 std::cout << "Warning: In future, for wall, separate config['Wall'] "
1296 "will not be used.\n";
1297 }
1298 }
1299 }
1300
1301 // <<<< >>>>
1302 // <<<< STEP 1 - Read dof computation information >>>>
1303 // <<<< >>>>
1304 particle_data->d_allDofsConstrained = false;
1305 if (pe["All_Dofs_Constrained"])
1306 particle_data->d_allDofsConstrained = pe["All_Dofs_Constrained"].as<bool>();
1307
1308 particle_data->d_createParticleUsingParticleZoneGeomObject = false;
1309 if (pe["Create_Particle_Using_ParticleZone_GeomObject"])
1311 = pe["Create_Particle_Using_ParticleZone_GeomObject"].as<bool>();
1312
1313 if (!isMultiParticle() and !particle_data->d_createParticleUsingParticleZoneGeomObject) {
1314 // set the flag as true for single particle simulation
1315 particle_data->d_createParticleUsingParticleZoneGeomObject = true;
1316 }
1317
1318 // <<<< >>>>
1319 // <<<< STEP 2 - Read geometry type and create geometry >>>>
1320 // <<<< >>>>
1321 if (pe) {
1322
1323 readGeometry(pe, "Particle->" + string_zone, particle_data->d_particleGeomData);
1324
1325 // create particle
1327 d_modelDeck_p->d_dim);
1328
1329 // read test name (if any)
1330 if (pe["Near_Bd_Nodes_Tol"])
1331 particle_data->d_nearBdNodesTol =
1332 pe["Near_Bd_Nodes_Tol"].as<double>();
1333 }
1334 else {
1336 // create geometry from container as we do not really need geometry object
1337 // for this particle created through
1338 this->d_particleDeck_p->d_contGeomData.copyGeometry(particle_data->d_particleGeomData,
1339 d_modelDeck_p->d_dim);
1340 particle_data->d_particleGeomData.d_geom_p->d_tags.push_back("copy");
1341 particle_data->d_particleGeomData.d_geom_p->d_tags.push_back("copy_from_container");
1342 }
1343 else {
1344 std::cerr << "Error: Particle/wall details for zone = " << string_zone
1345 << "is not provided.\n";
1346 exit(1);
1347 }
1348 }
1349
1350 // <<<< >>>>
1351 // <<<< STEP 3 - Read reference particle geometry type and create reference geometry >>>>
1352 // <<<< >>>>
1353 auto re = config["Mesh"][string_zone]["Reference_Particle"];
1354 if (re) {
1355
1356 readGeometry(re, "Particle->" + string_zone + "->Reference_Particle",
1357 particle_data->d_refParticleGeomData);
1358
1360 d_modelDeck_p->d_dim);
1361
1362 } else {
1363 // use the general particle data for the reference particle as well
1364 particle_data->d_particleGeomData.copyGeometry(particle_data->d_refParticleGeomData,
1365 d_modelDeck_p->d_dim);
1366 particle_data->d_particleGeomData.d_geom_p->d_tags.push_back("copy");
1367 particle_data->d_particleGeomData.d_geom_p->d_tags.push_back("copy_from_particle");
1368 }
1369
1370 // <<<< >>>>
1371 // <<<< STEP 4 - Read particle generation method >>>>
1372 // <<<< >>>>
1373 if (!particle_data->d_createParticleUsingParticleZoneGeomObject) {
1374 if (config["Particle_Generation"]["From_File"]) {
1375
1376 particle_data->d_genMethod = "From_File";
1377 particle_data->d_particleFile =
1378 config["Particle_Generation"]["From_File"].as<std::string>();
1379
1380 if (config["Particle_Generation"]["File_Data_Type"]) {
1381 particle_data->d_particleFileDataType =
1382 config["Particle_Generation"]["File_Data_Type"].as<std::string>();
1383 } else {
1384 particle_data->d_particleFileDataType = "loc_rad";
1385 }
1386 } else {
1387 std::cerr << "Error: Particle_Generation->From_File block is not provided"
1388 ". Can not generate particles for dem simulation. "
1389 "Terminating the simulation.\n";
1390 exit(1);
1391 }
1392 }
1393 else {
1394 particle_data->d_genMethod = "Create_Particle_Using_ParticleZone_GeomObject";
1395 }
1396}
std::shared_ptr< inp::ParticleDeck > getParticleDeck()
Get the pointer to particle deck.
Definition input.cpp:181
Input(std::string filename="", bool createDefault=false)
Constructor.
Definition input.cpp:112
void setParticleData(std::string string_zone, inp::ParticleZone *particle_data)
Read particle data.
Definition input.cpp:1278
std::shared_ptr< inp::MaterialDeck > getMaterialDeck()
Get the pointer to material deck.
Definition input.cpp:166
std::shared_ptr< inp::ModelDeck > getModelDeck()
Get the pointer to model deck.
Definition input.cpp:172
void setOutputDeck()
Read data into output deck and store its pointer.
Definition input.cpp:998
std::shared_ptr< inp::ContactDeck > getContactDeck()
Get the pointer to contact deck.
Definition input.cpp:183
void setModelDeck()
Read data into model deck and store its pointer.
Definition input.cpp:189
void setMaterialDeck()
Read data into material deck and store its pointer.
Definition input.cpp:915
void setZoneMaterialDeck(std::vector< std::string > s_config, inp::MaterialDeck *m_deck, size_t zone_id)
Read data into material deck and store its pointer.
Definition input.cpp:1048
void setParticleDeck()
Read data into particle deck and store its pointer.
Definition input.cpp:292
std::string d_inputFilename
Name of input file.
Definition input.h:225
void setRestartDeck()
Read data into restart deck and store its pointer.
Definition input.cpp:835
void setZoneData(std::vector< std::string > s_config, inp::Zone *zone_data)
Read zone data.
Definition input.cpp:1244
bool d_createDefault
Specify if create defaul objects in Input.
Definition input.h:228
std::shared_ptr< inp::MeshDeck > getMeshDeck()
Get the pointer to mesh deck.
Definition input.cpp:169
void setContactDeck()
Read data into particle deck and store its pointer.
Definition input.cpp:665
bool isMultiParticle()
Get particle simulation type.
Definition input.cpp:154
std::shared_ptr< inp::RestartDeck > getRestartDeck()
Get the pointer to restart deck.
Definition input.cpp:178
void setZoneMeshDeck(std::vector< std::string > s_config, inp::MeshDeck *mesh_deck)
Read data into mesh deck and store its pointer.
Definition input.cpp:1175
bool isPeriDEM()
Specify if PeriDEM model should be run.
Definition input.cpp:158
std::shared_ptr< inp::OutputDeck > getOutputDeck()
Get the pointer to output deck.
Definition input.cpp:175
void setMeshDeck()
Read data into mesh deck and store its pointer.
Definition input.cpp:866
void createDefaultInputConfiguration()
Definition input.cpp:147
void readGeometry(YAML::Node data, std::string data_block_name, std::string &name, std::vector< double > &params, std::pair< std::vector< std::string >, std::vector< std::string > > &complexInfo)
Definition input.cpp:53
std::string stringVecSerial(const std::vector< std::string > &svec)
Definition input.cpp:39
bool definitelyGreaterThan(const double &a, const double &b)
Definition input.cpp:28
void createGeomObject(const std::string &geom_type, const std::vector< double > &params, const std::vector< std::string > &vec_type, const std::vector< std::string > &vec_flag, std::shared_ptr< util::geometry::GeomObject > &obj, const size_t &dim, bool perform_check=true)
bool isTagInList(const std::string &tag, const std::vector< std::string > &tags)
Returns true if tag is found in the list of tags.
Definition methods.h:279
bool isLess(const double &a, const double &b)
Returns true if a < b.
Definition function.cpp:20
Structure to read and store particle-particle contact related input data.
Definition contactDeck.h:23
std::string printStr(int nt=0, int lvl=0) const
Returns the string containing printable information about the object.
Definition contactDeck.h:82
double d_mu
Lame second parameter.
double d_KIc
Critical stress intensity factor.
double d_K
Bulk modulus.
double d_lambda
Lame first parameter.
double d_nu
Poisson's ratio.
double d_G
Shear modulus or Lame second parameter.
double d_E
Young's elastic modulus.
double d_Gc
Critical energy release rate.
Structure to read and store material related data.
bool d_isPlaneStrain
Indicates if the 2-d simulation is of plane-strain type (thick material) or plane-stress type (thin m...
double d_density
Density of material.
size_t d_bondPotentialType
Type of pairwise (bond-based) potential.
double d_horizonMeshRatio
Horizon to mesh ratio.
size_t d_influenceFnType
Type of influence function.
std::vector< double > d_bondPotentialParams
List of parameters for pairwise potential.
std::string d_materialType
Material type.
double d_horizon
Horizon for peridynamic interaction.
bool d_stateContributionFromBrokenBond
Flag for contribution to hydrostatic force from the broken bond.
bool d_computeParamsFromElastic
Compute Peridynamic material properties from elastic properties.
inp::MatData d_matData
List of elastic and fracture properties.
std::vector< double > d_influenceFnParams
List of parameters for influence function.
size_t d_statePotentialType
Type of hydrostatic (state-based) potential.
std::vector< double > d_statePotentialParams
List of parameters for hydrostatic potential.
bool d_irreversibleBondBreak
Flag for irreversible breaking of bonds.
double d_checkScFactor
Factor to check if bond is broken.
Structure to read and store mesh related input data.
Definition meshDeck.h:26
std::string d_spatialDiscretization
Tag for spatial discretization.
Definition meshDeck.h:42
bool d_computeMeshSize
Flag which indicates if mesh size is to be computed.
Definition meshDeck.h:60
double d_h
Mesh size.
Definition meshDeck.h:63
bool d_createMesh
Specify if we create mesh using in-built gmsh or in-built routine for uniform discretization of recta...
Definition meshDeck.h:69
std::string d_createMeshInfo
Information that will be used when creating a mesh using in-built routines.
Definition meshDeck.h:74
size_t d_dim
Dimension.
Definition meshDeck.h:29
std::string d_filename
Filename to read mesh data.
Definition meshDeck.h:57
util::geometry::GeomData d_createMeshGeomData
Information that will be used when creating a mesh using in-built routines.
Definition meshDeck.h:79
User-input data for particle neighbor search.
Definition pBCData.h:24
User-input data for particle zone.
Definition zoneDeck.h:78
bool d_allDofsConstrained
Specify if all dofs are constrained.
Definition zoneDeck.h:130
util::geometry::GeomData d_refParticleGeomData
Geometry of details of reference particle.
Definition zoneDeck.h:96
util::geometry::GeomData d_particleGeomData
Geometry of details of particle.
Definition zoneDeck.h:93
bool d_createParticleUsingParticleZoneGeomObject
Specify if the particle should be created using the particle geometry in the zone data and mesh file....
Definition zoneDeck.h:142
bool d_isWall
Is this particle actually a wall?
Definition zoneDeck.h:90
std::string d_particleFileDataType
Specify what data to be expected in the particle file e.g.
Definition zoneDeck.h:115
double d_nearBdNodesTol
Specify how deep we search for nodes near boundary for contact calculations.
Definition zoneDeck.h:133
std::string d_particleFile
Read particle from a file.
Definition zoneDeck.h:118
std::string d_genMethod
Particle generation method.
Definition zoneDeck.h:104
User-input data for zones.
Definition zoneDeck.h:27
util::geometry::GeomData d_zoneGeomData
Zone geometry data.
Definition zoneDeck.h:30
A structure to represent 3d vectors.
Definition point.h:30
Input data for geometrical objects.
void copyGeometry(GeomData &z, size_t dim)
Copies the geometry details.
std::shared_ptr< util::geometry::GeomObject > d_geom_p
Zone geometry.
std::pair< std::vector< std::string >, std::vector< std::string > > d_geomComplexInfo
Zone geometry info if it is a complex type.
std::string d_geomName
Zone type.
std::vector< double > d_geomParams
Zone parameters.