PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
anonymous_namespace{main.cpp}::GrainContactProbe Class Reference
Inheritance diagram for anonymous_namespace{main.cpp}::GrainContactProbe:
Collaboration diagram for anonymous_namespace{main.cpp}::GrainContactProbe:

Public Member Functions

 GrainContactProbe (std::filesystem::path out_dir={}, size_t interval=0)
 
void checkStop (data::ModelData &data) override
 
double minGap () const
 
double gap0 () const
 
double Rc () const
 
double tMin () const
 
int maxPairs () const
 
- Public Member Functions inherited from postprocess::Postprocess
virtual ~Postprocess ()=default
 
virtual void close (data::ModelData &data)
 
virtual std::string twoParticle (data::ModelData &data)
 
virtual std::string compressive (data::ModelData &data)
 

Private Member Functions

void sampleMetric (data::ModelData &data)
 

Static Private Member Functions

static bool ownsNode (const data::ModelData &data, size_t i)
 

Private Attributes

double d_minGap = 1.0e9
 
double d_gap0 = 0.
 
double d_Rc = 0.
 
double d_tMin = 0.
 
int d_maxPairs = 0
 
std::filesystem::path d_outDir
 
size_t d_interval = 0
 
std::ofstream d_metricOs
 
bool d_wroteXref = false
 

Detailed Description

Definition at line 351 of file main.cpp.

Constructor & Destructor Documentation

◆ GrainContactProbe()

anonymous_namespace{main.cpp}::GrainContactProbe::GrainContactProbe ( std::filesystem::path  out_dir = {},
size_t  interval = 0 
)
inline

Definition at line 353 of file main.cpp.

353 {}, size_t interval = 0)
354 : d_outDir(std::move(out_dir)), d_interval(interval) {
355 if (!d_outDir.empty() && util::parallel::mpiRank() == 0) {
356 std::filesystem::create_directories(d_outDir / "nodal");
357 d_metricOs.open(d_outDir / "mpi_metric_ts.csv");
358 d_metricOs << "step,t,max_u,com0x,com0y\n";
359 }
360 }
int mpiRank()
get rank (id) of this processor

Member Function Documentation

◆ checkStop()

void anonymous_namespace{main.cpp}::GrainContactProbe::checkStop ( data::ModelData &  data)
inlineoverridevirtual

Reimplemented from postprocess::Postprocess.

Definition at line 362 of file main.cpp.

362 {
365 if (data.d_particlesListTypeAll.size() < 3)
366 return;
367 double Rc = 0.;
368 try {
369 Rc = data.d_particleDeck_p->d_contactDeck.getContact(0, 0).d_contactR;
370 } catch (...) {
371 return;
372 }
373 if (Rc <= 0.)
374 return;
375 d_Rc = Rc;
376 double min_gap = 1.0e9;
377 int n_in = 0;
378 const auto &all = data.d_particlesListTypeAll;
379 for (size_t i = 0; i < all.size(); ++i) {
380 if (all[i]->getGroupId("contact_id") != 0)
381 continue;
382 for (size_t j = i + 1; j < all.size(); ++j) {
383 if (all[j]->getGroupId("contact_id") != 0)
384 continue;
385 const double gap = all[i]->getXCenter().dist(all[j]->getXCenter()) -
386 all[i]->d_geom_p->boundingRadius() -
387 all[j]->d_geom_p->boundingRadius();
388 min_gap = std::min(min_gap, gap);
389 if (gap < Rc)
390 ++n_in;
391 }
392 }
393 if (d_gap0 == 0. && min_gap < 1.0e8)
394 d_gap0 = min_gap;
395 if (min_gap < d_minGap) {
396 d_minGap = min_gap;
397 d_tMin = data.d_time;
398 }
399 if (n_in > d_maxPairs) {
400 d_maxPairs = n_in;
401 util::io::print(std::format(
402 "grain contact: {} pair(s) in Rc at t={:.6e}, min_gap={:.6e}, Rc={:.6e}\n",
403 n_in, data.d_time, min_gap, Rc));
404 }
405 }
void sampleMetric(data::ModelData &data)
Definition main.cpp:433
virtual void checkStop(data::ModelData &data)
Definition contact.h:20
void print(const T &msg, int nt=print_default_tab, int printMpiRank=print_default_mpi_rank)
Prints formatted information.
Definition io.h:171

References postprocess::Postprocess::checkStop(), and util::io::print().

Here is the call graph for this function:

◆ gap0()

double anonymous_namespace{main.cpp}::GrainContactProbe::gap0 ( ) const
inline

Definition at line 408 of file main.cpp.

408{ return d_gap0; }

Referenced by main().

Here is the caller graph for this function:

◆ maxPairs()

int anonymous_namespace{main.cpp}::GrainContactProbe::maxPairs ( ) const
inline

Definition at line 411 of file main.cpp.

411{ return d_maxPairs; }

◆ minGap()

double anonymous_namespace{main.cpp}::GrainContactProbe::minGap ( ) const
inline

Definition at line 407 of file main.cpp.

407{ return d_minGap; }

◆ ownsNode()

static bool anonymous_namespace{main.cpp}::GrainContactProbe::ownsNode ( const data::ModelData &  data,
size_t  i 
)
inlinestaticprivate

Definition at line 414 of file main.cpp.

414 {
415 const int rank = util::parallel::mpiRank();
416 if (data.d_pdDofMpi) {
417 if (i >= data.d_pdNodePartition.size())
418 return false;
419 return static_cast<int>(data.d_pdNodePartition[i]) == rank;
420 }
421 for (const auto *p : data.d_particlesListTypeAll) {
422 const size_t i0 = p->d_globStart;
423 const size_t i1 = i0 + p->getNumNodes();
424 if (i < i0 || i >= i1)
425 continue;
426 if (p->isWall())
427 return rank == 0;
428 return particle::isLocallyOwned(*p);
429 }
430 return rank == 0;
431 }
bool isLocallyOwned(const BaseParticle &p)
True if this rank updates / assembles forces for the particle. Walls are replicated on every rank....

References particle::isLocallyOwned(), and util::parallel::mpiRank().

Here is the call graph for this function:

◆ Rc()

double anonymous_namespace{main.cpp}::GrainContactProbe::Rc ( ) const
inline

Definition at line 409 of file main.cpp.

409{ return d_Rc; }

◆ sampleMetric()

void anonymous_namespace{main.cpp}::GrainContactProbe::sampleMetric ( data::ModelData &  data)
inlineprivate

Definition at line 433 of file main.cpp.

433 {
434 if (d_outDir.empty() || d_interval == 0)
435 return;
436 const size_t nstep = data.currentStep();
437 if (nstep % d_interval != 0 && nstep < data.numTimeSteps())
438 return;
439 double max_u = 0.;
440 for (const auto &u : data.d_u)
441 max_u = std::max(max_u, u.length());
442 if (util::parallel::mpiSize() > 1)
443 MPI_Allreduce(MPI_IN_PLACE, &max_u, 1, MPI_DOUBLE, MPI_MAX,
445 double com0x = 0., com0y = 0.;
446 if (!data.d_particlesListTypeParticle.empty()) {
447 const auto c = data.d_particlesListTypeParticle[0]->getXCenter();
448 com0x = c.d_x;
449 com0y = c.d_y;
450 }
451 if (util::parallel::mpiRank() == 0) {
452 d_metricOs << std::format("{},{:.12e},{:.12e},{:.12e},{:.12e}\n", nstep,
453 data.d_time, max_u, com0x, com0y);
454 d_metricOs.flush();
455 }
456 const size_t n = data.d_u.size();
457 std::vector<double> buf(6 * n, 0.);
458 for (size_t i = 0; i < n; ++i) {
459 if (!ownsNode(data, i))
460 continue;
461 buf[6 * i + 0] = data.d_u[i].d_x;
462 buf[6 * i + 1] = data.d_u[i].d_y;
463 buf[6 * i + 2] = data.d_u[i].d_z;
464 buf[6 * i + 3] = data.d_v[i].d_x;
465 buf[6 * i + 4] = data.d_v[i].d_y;
466 buf[6 * i + 5] = data.d_v[i].d_z;
467 }
468 if (util::parallel::mpiSize() > 1)
469 MPI_Allreduce(MPI_IN_PLACE, buf.data(), static_cast<int>(buf.size()),
470 MPI_DOUBLE, MPI_SUM, util::parallel::mpiComm());
471 if (util::parallel::mpiRank() != 0)
472 return;
473 if (!d_wroteXref) {
474 std::ofstream xr(d_outDir / "nodal" / "x_ref.bin", std::ios::binary);
475 const uint32_t nn = static_cast<uint32_t>(n);
476 xr.write(reinterpret_cast<const char *>(&nn), sizeof(nn));
477 for (size_t i = 0; i < n; ++i) {
478 const double p[3] = {data.d_xRef[i].d_x, data.d_xRef[i].d_y,
479 data.d_xRef[i].d_z};
480 xr.write(reinterpret_cast<const char *>(p), sizeof(p));
481 }
482 d_wroteXref = true;
483 }
484 std::ofstream os(d_outDir / "nodal" / std::format("uv_{:06d}.bin", nstep),
485 std::ios::binary);
486 const char magic[4] = {'P', 'D', 'U', 'V'};
487 const uint32_t step32 = static_cast<uint32_t>(nstep);
488 const uint32_t nn = static_cast<uint32_t>(n);
489 os.write(magic, 4);
490 os.write(reinterpret_cast<const char *>(&step32), sizeof(step32));
491 os.write(reinterpret_cast<const char *>(&nn), sizeof(nn));
492 os.write(reinterpret_cast<const char *>(buf.data()),
493 static_cast<std::streamsize>(buf.size() * sizeof(double)));
494 }
static bool ownsNode(const data::ModelData &data, size_t i)
Definition main.cpp:414
T max(const std::vector< T > &data)
Returns the maximum from list of data.
Definition vecMethods.h:76
int mpiSize()
Get size (number) of processors.
MPI_Comm mpiComm()
Get MPI comm.

References util::parallel::mpiComm(), util::parallel::mpiRank(), util::parallel::mpiSize(), and anonymous_namespace{main.cpp}::ownsNode().

Here is the call graph for this function:

◆ tMin()

double anonymous_namespace{main.cpp}::GrainContactProbe::tMin ( ) const
inline

Definition at line 410 of file main.cpp.

410{ return d_tMin; }

Field Documentation

◆ d_gap0

double anonymous_namespace{main.cpp}::GrainContactProbe::d_gap0 = 0.
private

Definition at line 497 of file main.cpp.

◆ d_interval

size_t anonymous_namespace{main.cpp}::GrainContactProbe::d_interval = 0
private

Definition at line 502 of file main.cpp.

◆ d_maxPairs

int anonymous_namespace{main.cpp}::GrainContactProbe::d_maxPairs = 0
private

Definition at line 500 of file main.cpp.

◆ d_metricOs

std::ofstream anonymous_namespace{main.cpp}::GrainContactProbe::d_metricOs
private

Definition at line 503 of file main.cpp.

◆ d_minGap

double anonymous_namespace{main.cpp}::GrainContactProbe::d_minGap = 1.0e9
private

Definition at line 496 of file main.cpp.

◆ d_outDir

std::filesystem::path anonymous_namespace{main.cpp}::GrainContactProbe::d_outDir
private

Definition at line 501 of file main.cpp.

◆ d_Rc

double anonymous_namespace{main.cpp}::GrainContactProbe::d_Rc = 0.
private

Definition at line 498 of file main.cpp.

◆ d_tMin

double anonymous_namespace{main.cpp}::GrainContactProbe::d_tMin = 0.
private

Definition at line 499 of file main.cpp.

◆ d_wroteXref

bool anonymous_namespace{main.cpp}::GrainContactProbe::d_wroteXref = false
private

Definition at line 504 of file main.cpp.


The documentation for this class was generated from the following file: