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 302 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 304 of file main.cpp.

304 {}, size_t interval = 0)
305 : d_outDir(std::move(out_dir)), d_interval(interval) {
306 if (!d_outDir.empty() && util::parallel::mpiRank() == 0) {
307 std::filesystem::create_directories(d_outDir / "nodal");
308 d_metricOs.open(d_outDir / "mpi_metric_ts.csv");
309 d_metricOs << "step,t,max_u,com0x,com0y\n";
310 }
311 }
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 313 of file main.cpp.

313 {
316 if (data.d_particlesListTypeAll.size() < 3)
317 return;
318 double Rc = 0.;
319 try {
320 Rc = data.d_particleDeck_p->d_contactDeck.getContact(0, 0).d_contactR;
321 } catch (...) {
322 return;
323 }
324 if (Rc <= 0.)
325 return;
326 d_Rc = Rc;
327 double min_gap = 1.0e9;
328 int n_in = 0;
329 const auto &all = data.d_particlesListTypeAll;
330 for (size_t i = 0; i < all.size(); ++i) {
331 if (all[i]->getGroupId("contact_id") != 0)
332 continue;
333 for (size_t j = i + 1; j < all.size(); ++j) {
334 if (all[j]->getGroupId("contact_id") != 0)
335 continue;
336 const double gap = all[i]->getXCenter().dist(all[j]->getXCenter()) -
337 all[i]->d_geom_p->boundingRadius() -
338 all[j]->d_geom_p->boundingRadius();
339 min_gap = std::min(min_gap, gap);
340 if (gap < Rc)
341 ++n_in;
342 }
343 }
344 if (d_gap0 == 0. && min_gap < 1.0e8)
345 d_gap0 = min_gap;
346 if (min_gap < d_minGap) {
347 d_minGap = min_gap;
348 d_tMin = data.d_time;
349 }
350 if (n_in > d_maxPairs) {
351 d_maxPairs = n_in;
352 util::io::print(std::format(
353 "grain contact: {} pair(s) in Rc at t={:.6e}, min_gap={:.6e}, Rc={:.6e}\n",
354 n_in, data.d_time, min_gap, Rc));
355 }
356 }
void sampleMetric(data::ModelData &data)
Definition main.cpp:384
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:128

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 359 of file main.cpp.

359{ 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 362 of file main.cpp.

362{ return d_maxPairs; }

◆ minGap()

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

Definition at line 358 of file main.cpp.

358{ return d_minGap; }

◆ ownsNode()

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

Definition at line 365 of file main.cpp.

365 {
366 const int rank = util::parallel::mpiRank();
367 if (data.d_pdDofMpi) {
368 if (i >= data.d_pdNodePartition.size())
369 return false;
370 return static_cast<int>(data.d_pdNodePartition[i]) == rank;
371 }
372 for (const auto *p : data.d_particlesListTypeAll) {
373 const size_t i0 = p->d_globStart;
374 const size_t i1 = i0 + p->getNumNodes();
375 if (i < i0 || i >= i1)
376 continue;
377 if (p->isWall())
378 return rank == 0;
379 return particle::isLocallyOwned(*p);
380 }
381 return rank == 0;
382 }
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 360 of file main.cpp.

360{ return d_Rc; }

◆ sampleMetric()

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

Definition at line 384 of file main.cpp.

384 {
385 if (d_outDir.empty() || d_interval == 0)
386 return;
387 const size_t nstep = data.currentStep();
388 if (nstep % d_interval != 0 && nstep < data.numTimeSteps())
389 return;
390 double max_u = 0.;
391 for (const auto &u : data.d_u)
392 max_u = std::max(max_u, u.length());
393 if (util::parallel::mpiSize() > 1)
394 MPI_Allreduce(MPI_IN_PLACE, &max_u, 1, MPI_DOUBLE, MPI_MAX,
396 double com0x = 0., com0y = 0.;
397 if (!data.d_particlesListTypeParticle.empty()) {
398 const auto c = data.d_particlesListTypeParticle[0]->getXCenter();
399 com0x = c.d_x;
400 com0y = c.d_y;
401 }
402 if (util::parallel::mpiRank() == 0) {
403 d_metricOs << std::format("{},{:.12e},{:.12e},{:.12e},{:.12e}\n", nstep,
404 data.d_time, max_u, com0x, com0y);
405 d_metricOs.flush();
406 }
407 const size_t n = data.d_u.size();
408 std::vector<double> buf(6 * n, 0.);
409 for (size_t i = 0; i < n; ++i) {
410 if (!ownsNode(data, i))
411 continue;
412 buf[6 * i + 0] = data.d_u[i].d_x;
413 buf[6 * i + 1] = data.d_u[i].d_y;
414 buf[6 * i + 2] = data.d_u[i].d_z;
415 buf[6 * i + 3] = data.d_v[i].d_x;
416 buf[6 * i + 4] = data.d_v[i].d_y;
417 buf[6 * i + 5] = data.d_v[i].d_z;
418 }
419 if (util::parallel::mpiSize() > 1)
420 MPI_Allreduce(MPI_IN_PLACE, buf.data(), static_cast<int>(buf.size()),
421 MPI_DOUBLE, MPI_SUM, util::parallel::mpiComm());
422 if (util::parallel::mpiRank() != 0)
423 return;
424 if (!d_wroteXref) {
425 std::ofstream xr(d_outDir / "nodal" / "x_ref.bin", std::ios::binary);
426 const uint32_t nn = static_cast<uint32_t>(n);
427 xr.write(reinterpret_cast<const char *>(&nn), sizeof(nn));
428 for (size_t i = 0; i < n; ++i) {
429 const double p[3] = {data.d_xRef[i].d_x, data.d_xRef[i].d_y,
430 data.d_xRef[i].d_z};
431 xr.write(reinterpret_cast<const char *>(p), sizeof(p));
432 }
433 d_wroteXref = true;
434 }
435 std::ofstream os(d_outDir / "nodal" / std::format("uv_{:06d}.bin", nstep),
436 std::ios::binary);
437 const char magic[4] = {'P', 'D', 'U', 'V'};
438 const uint32_t step32 = static_cast<uint32_t>(nstep);
439 const uint32_t nn = static_cast<uint32_t>(n);
440 os.write(magic, 4);
441 os.write(reinterpret_cast<const char *>(&step32), sizeof(step32));
442 os.write(reinterpret_cast<const char *>(&nn), sizeof(nn));
443 os.write(reinterpret_cast<const char *>(buf.data()),
444 static_cast<std::streamsize>(buf.size() * sizeof(double)));
445 }
static bool ownsNode(const data::ModelData &data, size_t i)
Definition main.cpp:365
T max(const std::vector< T > &data)
Returns the maximum from list of data.
Definition vecMethods.h:74
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 361 of file main.cpp.

361{ return d_tMin; }

Field Documentation

◆ d_gap0

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

Definition at line 448 of file main.cpp.

◆ d_interval

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

Definition at line 453 of file main.cpp.

◆ d_maxPairs

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

Definition at line 451 of file main.cpp.

◆ d_metricOs

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

Definition at line 454 of file main.cpp.

◆ d_minGap

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

Definition at line 447 of file main.cpp.

◆ d_outDir

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

Definition at line 452 of file main.cpp.

◆ d_Rc

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

Definition at line 449 of file main.cpp.

◆ d_tMin

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

Definition at line 450 of file main.cpp.

◆ d_wroteXref

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

Definition at line 455 of file main.cpp.


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