37#include <fmt/format.h>
42#include <taskflow/taskflow/taskflow.hpp>
43#include <taskflow/taskflow/algorithm/for_each.hpp>
69 std::string filename =
71 d_ppFile = std::ofstream(filename, std::ios_base::out);
72 d_ppFile <<
"t, delta, cont_area_r, s_loc, s_val, max_dist, "
73 "cont_area_r_ideal, s_loc_ideal, s_val_ideal" << std::flush;
83 log(
d_name +
": Running TwoParticle_Demo app \n");
90 size_t totalQuadPoints = 0;
92 const auto &particle_mesh_p = p->d_rp_p->getMeshP();
105 std::cerr << fmt::format(
"Error: Can not compute strain/stress as the element "
106 "type = {} is not yet supported in this routine.\n", particle_mesh_p->getElementType());
110 totalQuadPoints += particle_mesh_p->getNumElements() *
115 or
d_strain.size() != totalQuadPoints
116 or
d_stress.size() != totalQuadPoints) {
117 std::cerr <<
"Error: DEMModel::init() did not initialize quadrature data.\n";
149 log(fmt::format(
"{}: Time step: {}, time: {:8.6f}, steps completed = {}%\n",
158 auto t1 = steady_clock::now();
160 double integrate_time =
163 log(fmt::format(
" Integration time (ms) = {}\n", integrate_time),
166 if (
d_pDeck_p->d_testName ==
"two_particle") {
195 bool continue_dt =
false;
197 if ((
d_n % check_dt == 0) && (
d_n >= check_dt))
225 const auto &xc0 = p0->getXCenter();
226 const auto &xc1 = p1->getXCenter();
227 const double &r = p0->d_geom_p->boundingRadius();
229 const auto &contact =
d_cDeck_p->getContact(p0->d_zoneId, p1->d_zoneId);
230 double r_e = r + contact.d_contactR;
235 std::sqrt(std::pow(r_e, 2.) - std::pow(r_e +
d_penDist, 2.));
242 d_maxDist = xc1.d_y + p1->d_geom_p->boundingRadius();
245 double max_y_loc = p1->getXLocal(0).d_y;
246 for (
size_t i = 0; i < p1->getNumNodes(); i++)
248 max_y_loc = p1->getXLocal(i).d_y;
256 static int contact_pp_ideal = -1;
257 if (contact_pp_ideal == -1) {
258 double mass = p1->getDensity() * M_PI * std::pow(r, 2.);
260 const auto &mat_data =
261 p1->getMaterial()->computeMaterialProperties(
d_modelDeck_p->d_dim);
264 2. * r * (1. - std::pow(mat_data.d_nu, 2.)) /
271 0.93 * mass * std::abs(
d_pDeck_p->d_gravity[1]) /
274 contact_pp_ideal = 0;
284 double max_stress_t = 0.;
292 p->getMeshP()->getDimension()));
299 const auto particle_mesh_p = p->getMeshP();
306 auto p_z_id = p->d_zoneId;
307 auto isPlaneStrain =
d_pDeck_p->d_particleZones[p_z_id].d_matDeck.d_isPlaneStrain;
319 double p_max_stress = 0.;
324 p_max_stress_loc_ref,
325 p_max_stress_loc_cur,
326 p->d_globStart, p->d_globQuadStart,
d_modelDeck_p->d_quadOrder);
329 max_stress_t = p_max_stress;
330 auto p_center_node_id = p->d_globStart + p->d_rp_p->getCenterNodeId();
331 max_stress_loc_ref_t = p_max_stress_loc_ref -
d_xRef[p_center_node_id];
332 max_stress_loc_cur_t = p_max_stress_loc_cur -
d_x[p_center_node_id];
375int main(
int argc,
char *argv[]) {
378 std::cout <<
"TwoParticle_Demo (PeriDEM)"
386 std::cout <<
"Syntax to run the app: ./TwoParticle_Demo -i <input file> -nThreads <number of threads>";
387 std::cout <<
"Example: ./TwoParticle_Demo -i input.yaml -nThreads 2";
391 unsigned int nThreads;
395 util::io::print(fmt::format(
"Running TwoParticle_Demo with number of threads = {}\n", nThreads));
401 std::string filename;
405 filename =
"./example/input_0.yaml";
406 util::io::print(fmt::format(
"Running TwoParticle_Demo with example input file = {}\n", filename));
410 auto begin = steady_clock::now();
416 if (deck->isPeriDEM()) {
418 deck->getModelDeck()->d_populateElementNodeConnectivity =
true;
426 auto end = steady_clock::now();
428 std::cout <<
"Total simulation time (s) = "
size_t const MINOR_VERSION
size_t const UPDATE_VERSION
size_t const MAJOR_VERSION
A base class which provides methods to map points to/from reference element and to compute quadrature...
size_t getNumQuadPoints()
Get number of quadrature points in the data.
A class for mapping and quadrature related operations for linear 2-node line element.
A class for mapping and quadrature related operations for bi-linear quadrangle element.
A class for mapping and quadrature related operations for linear tetrahedron element.
A class for mapping and quadrature related operations for linear triangle element.
A class for discrete element particle simulation with peridynamic model
virtual void computeExternalForces()
Computes external/boundary condition forces.
DEMModel(inp::Input *deck, std::string modelName="DEMModel")
Constructor.
virtual void output()
Output the snapshot of data at current time step.
virtual void applyInitialCondition()
Applies initial condition.
virtual void computeExternalDisplacementBC()
Applies displacement boundary conditions.
virtual void integrateStep()
Performs one time step.
virtual void close()
Closure operations.
void log(std::ostringstream &oss, int priority=0, bool check_condition=true, int override_priority=-1, bool screen_out=false)
Prints message if any of these two conditions are true.
virtual void init()
Initialize remaining data members.
virtual void checkStop()
Checks if simulation should be stopped due to abnormal state of system.
std::string d_name
Name of the model for logging purposes (useful if other classes are built on top of this class)
std::shared_ptr< inp::ContactDeck > d_cDeck_p
Contact deck.
std::vector< particle::BaseParticle * > d_particlesListTypeAll
List of particles + walls.
std::vector< util::Point > d_xRef
reference positions of the nodes
size_t d_infoN
Print log step interval.
std::vector< util::Point > d_u
Displacement of the nodes.
std::shared_ptr< inp::ModelDeck > d_modelDeck_p
Model deck.
std::vector< util::SymMatrix3 > d_stress
Stress in elements (values at quadrature points)
size_t d_n
Current time step.
std::vector< util::Point > d_x
Current positions of the nodes.
std::ofstream d_ppFile
File stream to output information.
std::vector< util::Point > d_xQuadCur
Current position of quadrature points.
std::shared_ptr< inp::OutputDeck > d_outputDeck_p
Output deck.
double d_time
Current time.
std::shared_ptr< inp::ParticleDeck > d_pDeck_p
Particle deck.
std::vector< util::SymMatrix3 > d_strain
Strain in elements (values at quadrature points)
std::vector< inp::MatData > d_particlesMatDataList
List of particle material data. Only populated if needed for calculation of stress or other quantitie...
Main model class to handle demo two-particle test implementation. Goal is to show that it is easy to ...
double d_maxStressIdeal
Ideal maximum stress.
double d_maxStressLocCur
Maximum stress location in current configuration.
void twoParticleTest()
Handles postprocessing for two-particle test.
void twoParticleTestPenetrationDist()
Computes penetration distance of top particle into bottom particle.
double d_maxStressLocRefIdeal
Ideal maximum stress location location in reference configuration.
void integrate() override
Perform time step integration.
double d_contactAreaRadiusIdeal
Ideal contact area radius from Hertz theory.
double d_maxStress
Maximum stress.
double d_maxDist
Maximum vertical distance of top particle in initial configuration.
double d_maxY
Current maximum vertical distance of top particle.
double d_contactAreaRadius
Contact area radius.
double d_penDist
Penetration distance of top particle into bottom particle.
double d_maxStressLocRef
Maximum stress location in reference configuration.
void twoParticleTestMaxShearStress()
Computes maximum shear stress and its location in particle.
void run(inp::Input *deck) override
Runs simulation by executing steps such as init(), integrate(), and close().
Model(inp::Input *deck)
Constructor.
static const int vtk_type_triangle
Integer flag for triangle element.
static const int vtk_type_quad
Integer flag for quad element.
static const int vtk_type_tetra
Integer flag for tetrahedron element.
static const int vtk_type_line
Integer flag for line element.
void getMaxShearStressAndLoc(const fe::Mesh *mesh_p, const std::vector< util::Point > &xRef, const std::vector< util::Point > &u, const std::vector< util::SymMatrix3 > &stress, double &maxShearStress, util::Point &maxShearStressLocRef, util::Point &maxShearStressLocCur, size_t iNodeStart=0, size_t iStrainStart=0, size_t quadOrder=1)
Get location where maximum of specified component of stress occurs in this particle.
void getStrainStress(const fe::Mesh *mesh_p, const std::vector< util::Point > &xRef, const std::vector< util::Point > &u, bool isPlaneStrain, std::vector< util::SymMatrix3 > &strain, std::vector< util::SymMatrix3 > &stress, size_t iNodeStart=0, size_t iStrainStart=0, double nu=0., double lambda=0., double mu=0., bool computeStress=false, size_t quadOrder=1)
Strain and stress at quadrature points in the mesh.
void getCurrentQuadPoints(const fe::Mesh *mesh_p, const std::vector< util::Point > &xRef, const std::vector< util::Point > &u, std::vector< util::Point > &xQuadCur, size_t iNodeStart=0, size_t iQuadStart=0, size_t quadOrder=1)
Get current location of quadrature points of elements in the mesh. This function expects mesh has ele...
Namespace to define demo app for two-particle tests.
void print(const T &msg, int nt=print_default_tab, int printMpiRank=print_default_mpi_rank)
Prints formatted information.
void log(std::ostringstream &oss, bool screen_out=false, int printMpiRank=print_default_mpi_rank)
Global method to log the message.
float timeDiff(std::chrono::steady_clock::time_point begin, std::chrono::steady_clock::time_point end, std::string unit="microseconds")
Returns difference between two times.
unsigned int getNThreads()
Get number of threads to be used by taskflow.
void initNThreads(unsigned int nThreads=std::thread::hardware_concurrency())
Initializes MpiStatus struct.
bool isGreater(const double &a, const double &b)
Returns true if a > b.
bool isLess(const double &a, const double &b)
Returns true if a < b.
A structure to represent 3d vectors.