PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
main.cpp File Reference
#include "fracture/prenotch.h"
#include "inp/deckIncludes.h"
#include "material/materialUtil.h"
#include "periDEMModel.h"
#include "time_int/integrator.h"
#include "util/function.h"
#include "util/io.h"
#include "util/parallelUtil.h"
#include "util/point.h"
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <filesystem>
#include <format>
#include <fstream>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
Include dependency graph for main.cpp:

Go to the source code of this file.

Data Structures

struct  anonymous_namespace{main.cpp}::CrackFit
 

Namespaces

namespace  anonymous_namespace{main.cpp}
 

Functions

size_t anonymous_namespace{main.cpp}::applyNotches (PeriDEMModel &dem, double x_left, double x_right, double y_lo, double y_hi)
 
size_t anonymous_namespace{main.cpp}::applyNotchSlots (PeriDEMModel &dem, double notch_half, double notch_w, double y_lo, double y_hi)
 
size_t anonymous_namespace{main.cpp}::applyNotchMidplanes (PeriDEMModel &dem, double notch_half, double y_tip, double y_top)
 
std::string anonymous_namespace{main.cpp}::directoryPathWithTrailingSep (const std::filesystem::path &dir)
 
double anonymous_namespace{main.cpp}::nodePhi (const PeriDEMModel &dem, size_t i)
 
double anonymous_namespace{main.cpp}::nodeDamageForFit (const PeriDEMModel &dem, size_t i, bool use_bond_count)
 
CrackFit anonymous_namespace{main.cpp}::fitCrackFromPhi (const PeriDEMModel &dem, double tip_x, double tip_y, double outward_sign, double phi_cut, double band_x, double band_y, double exclude_r, double bin_h, bool use_bond_count=false)
 
json anonymous_namespace{main.cpp}::meshSetJson (const std::filesystem::path &f, double mesh_size)
 
json anonymous_namespace{main.cpp}::uniformMeshSetJson (const std::filesystem::path &f, double mesh_size, const std::vector< std::vector< double > > &voids={})
 
std::vector< std::vector< double > > anonymous_namespace{main.cpp}::notchVoidBoxes (double H, double notch_half, double notch_w, double notch_depth, double z_lo, double z_hi)
 
geom::GeomData anonymous_namespace{main.cpp}::sillingNotchedPlateGeom (double W, double H, double notch_half, double notch_w, double notch_depth)
 
geom::GeomData anonymous_namespace{main.cpp}::bhatVNotchedPlateGeom (double W, double H, double notch_half, double notch_w, double notch_depth)
 
json anonymous_namespace{main.cpp}::fixedTopOuterBC (double W, double H, double notch_half)
 
json anonymous_namespace{main.cpp}::buildTraskInputJson (const std::string &output_path, const std::filesystem::path &mesh_plate, double W, double H, double notch_half, double notch_w, double notch_depth, double mesh_size, double horizon, double rho, double E, double K, double G, double Gc, double v_impact, double final_time, size_t num_steps)
 
json anonymous_namespace{main.cpp}::buildImpactInputJson (const std::string &output_path, const std::filesystem::path &mesh_plate, const std::filesystem::path &mesh_impactor, double W, double H, double notch_half, double notch_w, double notch_depth, double Iw, double Ih, double gap, double mesh_size, double horizon, double Rc_factor, double Kn, double rho, double E, double K, double G, double Gc, double v_impact, double final_time, size_t num_steps, double thickness=0.)
 
json anonymous_namespace{main.cpp}::buildBhatInputJson (const std::string &output_path, const std::filesystem::path &mesh_plate, const std::filesystem::path &mesh_impactor, double W, double H, double notch_half, double notch_w, double notch_depth, double Iw, double Ih, double gap, double mesh_size, double horizon, double Rc_factor, double rho, double E, double K, double G, double Gc, double v_impact, double final_time, size_t num_steps)
 
int main (int argc, char *argv[])
 

Function Documentation

◆ main()

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

Definition at line 717 of file main.cpp.

717 {
718 util::parallel::initMpi(argc, argv);
719 util::io::InputParser input(argc, argv);
720
721 unsigned n_threads = 1;
722 if (input.cmdOptionExists("-nThreads"))
723 n_threads = static_cast<unsigned>(std::stoi(input.getCmdOption("-nThreads")));
725
726 const bool quick = input.cmdOptionExists("-quick");
727 const bool trask = input.cmdOptionExists("-traskDisp");
728 const bool bhat = input.cmdOptionExists("-bhatKW");
729 // Silling's actual case is 3D: a 9 mm plate on a 200 x 100 x 9 grid.
730 const bool dim3 = input.cmdOptionExists("-dim3");
731
732 namespace fs = std::filesystem;
733 // Always write under the binary cwd (build/linux/.../notched_impact_inbuilt/) unless overridden.
734 std::string run_tag =
735 quick ? "quick" : (trask ? "trask" : (bhat ? "bhat" : (dim3 ? "silling3d" : "lit")));
736 // New campaign outputs go under runs_new/ (do not mix with archived runs/).
737 fs::path base = fs::current_path() / "runs_new" / run_tag;
738 if (input.cmdOptionExists("-outputDir"))
739 base = input.getCmdOption("-outputDir");
740 const fs::path out_dir = base / "out";
741 const fs::path inp_dir = base / "inp";
742 fs::create_directories(out_dir);
743 fs::create_directories(inp_dir);
744 std::cout << std::format("notched_impact: outputDir={}\n", base.string());
745
746 // Fig. 2 Silling 2003: 200×100 mm plate, two 1.5 mm notches depth 50 mm, tip-to-tip 50 mm.
747 double W = 0.200;
748 double H = 0.100;
749 double notch_depth = 0.050;
750 double notch_half = 0.025; // notch centerline ±25 mm
751 double notch_w = 0.0015; // Silling 1.5 mm open gap
752 double plate_thickness = 0.009; // Silling Fig. 2: 9 mm (only used with -dim3)
753 // Impactor: Silling Fig. 2/4 give a cylinder of 1.57 kg striking edge-on, as
754 // wide as the 50 mm ligament between the notches. At ρ = 8000 that mass fixes
755 // its length: 1.57/(8000·π·0.025²) = 0.100 m. Bhat Fig. 4(b) draws exactly
756 // this 50 × 100 mm section, giving the same width and length.
757 double Iw = 0.050;
758 double Ih = 0.100;
759 // Silling 2003 EMU grid 200×100×9 on the mm plate → h ≈ 1 mm; Trask KW: δ = 3h.
760 double mesh_size = 0.001;
761 double horizon = 3.0 * mesh_size; // 3 mm
762 double Rc_factor = 0.95;
763 // The impactor must start outside the contact radius, which the solver sets to
764 // Rc_factor·h_min: any closer and the first step applies a saturated repulsive
765 // force that fires the struck nodes off at kilometres per second. Nothing acts
766 // on the impactor while it closes this gap, so its only effect is to delay
767 // contact by gap/v, which the crack-speed fit measures from damage arrival.
768 double gap = 1.5 * Rc_factor * mesh_size;
769
770 // Table 2 M1 ≡ Silling maraging steel (E=191 GPa, ν≈0.3).
771 // Gc from KIc≈90 MPa√m: plane-stress KIc²/E = 42408 J/m² (Trask/Silling handbook).
772 double rho = 8000.0;
773 double E = 191.0e9;
774 double Kbulk = 159.2e9;
775 double nu = 0.5 * (1.0 - E / (3.0 * Kbulk));
776 double G = E / (2.0 * (1.0 + nu));
777 double Gc = 42408.0;
778 double v_impact = 32.0;
779 double dt = 2.5e-9; // Bhat §6.1
780 // Silling's cracks run all the way to the free edges (75 mm) at ~900 m/s, so
781 // ~85 µs of propagation on top of the free flight and the initiation delay.
782 double final_time = 1.7e-4; // 170 µs
783 if (input.cmdOptionExists("-Gc"))
784 Gc = std::stod(input.getCmdOption("-Gc"));
785 if (input.cmdOptionExists("-finalTime"))
786 final_time = std::stod(input.getCmdOption("-finalTime"));
787 if (input.cmdOptionExists("-vImpact"))
788 v_impact = std::stod(input.getCmdOption("-vImpact"));
789 if (input.cmdOptionExists("-meshSize")) {
790 mesh_size = std::stod(input.getCmdOption("-meshSize"));
791 horizon = 3.0 * mesh_size;
792 }
793 if (input.cmdOptionExists("-horizon"))
794 horizon = std::stod(input.getCmdOption("-horizon"));
795 if (input.cmdOptionExists("-horizonFactor"))
796 horizon = std::stod(input.getCmdOption("-horizonFactor")) * mesh_size;
797
798 if (quick) {
799 W = 0.040;
800 H = 0.020;
801 notch_depth = 0.5 * H;
802 notch_half = 0.125 * W;
803 mesh_size = H / 16.0;
804 notch_w = std::max(mesh_size, 0.1 * notch_half);
805 Iw = 0.008;
806 Ih = 0.004;
807 gap = 1.5 * Rc_factor * mesh_size;
808 horizon = 3.0 * mesh_size;
809 rho = 1200.0;
810 E = 1.23e9;
811 Kbulk = 2.0e9;
812 nu = 0.5 * (1.0 - E / (3.0 * Kbulk));
813 G = E / (2.0 * (1.0 + nu));
814 Gc = 424.0;
815 dt = 1.0e-8;
816 final_time = 1.0e-4;
817 }
818
819 // Contact stiffness, Bhat Eq. (4.1). The solver's contact force density is
820 // Kn·V_j·overlap, so Kn carries one power of δ per spatial dimension of the
821 // node weight: 18k/(πδ⁴) with 2D weights h²·1 m, 18k/(πδ⁵) with 3D weights h³.
822 // Using the 3D form in 2D makes contact 1/δ ≈ 333× too stiff.
823 const double Kn =
824 util::normalContactStiffness(Kbulk, Kbulk, horizon, dim3 ? 5 : 4);
825 const size_t num_steps = static_cast<size_t>(std::llround(final_time / dt));
826
827 json input_json;
828 if (trask) {
830 inp_dir / "mesh_plate.msh", W, H, notch_half, notch_w,
831 notch_depth, mesh_size, horizon, rho, E, Kbulk, G, Gc,
832 v_impact, final_time, num_steps);
833 } else if (bhat) {
834 input_json = buildBhatInputJson(
835 directoryPathWithTrailingSep(out_dir), inp_dir / "mesh_plate.msh",
836 inp_dir / "mesh_impactor.msh", W, H, notch_half, notch_w, notch_depth, Iw, Ih, gap,
837 mesh_size, horizon, Rc_factor, rho, E, Kbulk, G, Gc, v_impact, final_time, num_steps);
838 } else {
839 input_json = buildImpactInputJson(
840 directoryPathWithTrailingSep(out_dir), inp_dir / "mesh_plate.msh",
841 inp_dir / "mesh_impactor.msh", W, H, notch_half, notch_w, notch_depth, Iw, Ih, gap,
842 mesh_size, horizon, Rc_factor, Kn, rho, E, Kbulk, G, Gc, v_impact, final_time,
843 num_steps, dim3 ? plate_thickness : 0.);
844 }
845 // Optional override (e.g. Bhat paper default is reference_gap; -selfContact none
846 // isolates prenotch+void setups from restorative self-contact across the notch).
847 if (input.cmdOptionExists("-selfContact")) {
848 const auto sc = input.getCmdOption("-selfContact");
849 input_json["Model"]["Self_Contact"] = sc;
850 std::cout << std::format("notched_impact: Self_Contact override -> {}\n", sc);
851 }
852 if (input.cmdOptionExists("-bondBreak")) {
853 const auto bb = input.getCmdOption("-bondBreak");
854 input_json["Model"]["Bond_Break"] = bb;
855 std::cout << std::format("notched_impact: Bond_Break override -> {}\n", bb);
856 }
857 // The deck fixes Output_Interval at num_steps/10, which is right for a
858 // check run and far too coarse for a frame sequence. Overriding it costs
859 // nothing and leaves the physics untouched.
860 if (input.cmdOptionExists("-outInterval")) {
861 const size_t oi =
862 static_cast<size_t>(std::stoull(input.getCmdOption("-outInterval")));
863 input_json["Output"]["Output_Interval"] = std::max<size_t>(1, oi);
864 std::cout << std::format("notched_impact: Output_Interval override -> {}\n", oi);
865 }
866 if (input.cmdOptionExists("-knScale")) {
867 const double s = std::stod(input.getCmdOption("-knScale"));
868 for (auto &kv : input_json["Contact"].items()) {
869 if (!kv.value().is_object() || !kv.value().contains("Kn"))
870 continue;
871 kv.value()["Kn"] = kv.value()["Kn"].get<double>() * s;
872 }
873 std::cout << std::format("notched_impact: Contact Kn scaled by {}\n", s);
874 }
875 {
876 std::ofstream os(inp_dir / "input.json");
877 os << input_json.dump(2);
878 }
879
880 // -deckOnly stops after the deck is written. The Python comparison reads
881 // the deck and does not need this driver to run the simulation.
882 if (input.cmdOptionExists("-deckOnly")) {
883 util::io::print("deck written; -deckOnly, not running\n");
885 return 0;
886 }
887
888 auto deck = std::make_shared<inp::Input>(input_json);
889 PeriDEMModel dem(deck);
890 dem.init();
891
892 const double y_top = 0.5 * H;
893 const double y_tip = y_top - notch_depth;
894 // Prenotch bonds: Bhat §5 removes bonds whose segment leaves the nonconvex
895 // V-domain (midplane cuts through each V tip); Silling/Trask: slot spans.
896 const size_t n_pre =
897 bhat ? applyNotchMidplanes(dem, notch_half, y_tip, y_top + 0.01 * H)
898 : applyNotchSlots(dem, notch_half, notch_w, y_tip, y_top + 0.01 * H);
899 if (n_pre < 10) {
900 std::cerr << "notched_impact: expected prenotch bonds, got " << n_pre << "\n";
901 return 1;
902 }
903
904 const char *mode_str =
905 quick ? "quick"
906 : (trask ? "trask_disp"
907 : (bhat ? "bhat_kw" : (dim3 ? "silling_3d" : "silling_impact")));
908 std::cout << std::format(
909 "notched_impact: mode={} nodes={} prenotch={} h={:.4e} ε={:.4e} notch_w={:.4e} "
910 "Gc={:.0f} E={:.3e} v={:.1f} Nt={} T={:.3e}\n",
911 mode_str, dem.d_x.size(), n_pre, mesh_size, horizon, notch_w, Gc, E, v_impact, num_steps,
912 final_time);
913
914 // Drive the loop ourselves (same sequence as time_int::Integrator::integrate)
915 // so we can record when each node first becomes damaged. That arrival-time
916 // field gives the crack speed, which Silling reports as ~900 m/s.
917 std::vector<float> arrival(dem.d_x.size(), -1.f);
918 const size_t sample_every = std::max<size_t>(1, num_steps / 400);
919 auto sampleArrivals = [&]() {
920 for (size_t i = 0; i < dem.d_xRef.size(); ++i) {
921 if (arrival[i] >= 0.f || dem.d_ptId[i] != 0)
922 continue;
923 if (nodePhi(dem, i) >= 0.30)
924 arrival[i] = static_cast<float>(dem.d_time);
925 }
926 };
927
928 dem.applyInitialCondition();
929 if (dem.performOutput())
930 dem.output();
931 dem.setCurrentDt(dem.timeStep());
932 dem.applyDisplacementBC();
933 dem.computeForces();
935 while (dem.currentStep() < dem.numTimeSteps()) {
936 dem.integrateStep();
937 if (dem.shouldOutput())
938 dem.output();
939 if (dem.currentStep() % sample_every == 0)
940 sampleArrivals();
941 dem.checkStop();
942 }
943 sampleArrivals();
944
945 double vmax = 0., phi_max = 0.;
946 size_t n_phi30 = 0;
947 for (size_t i = 0; i < dem.d_v.size(); ++i) {
948 vmax = std::max(vmax, dem.d_v[i].length());
949 if (dem.d_ptId[i] != 0)
950 continue;
951 const double phi = nodePhi(dem, i);
952 phi_max = std::max(phi_max, phi);
953 if (phi >= 0.30)
954 ++n_phi30;
955 }
956 const float zmax =
957 dem.d_Z.empty() ? 0.f : *std::max_element(dem.d_Z.begin(), dem.d_Z.end());
958 std::cout << std::format(
959 "notched_impact diag: max|v|={:.3e} maxφ={:.3f} maxZ={:.3f} n(φ≥0.3)={}\n", vmax,
960 phi_max, zmax, n_phi30);
961
962 if (!(vmax < 8.0e3) || !std::isfinite(vmax)) {
963 std::cerr << "notched_impact: blow-up, max |v| = " << vmax << "\n";
964 return 1;
965 }
966
967 size_t n_extra = 0;
968 for (size_t i = 0; i < dem.d_neighPd.size(); ++i) {
969 if (dem.d_ptId[i] != 0)
970 continue;
971 for (size_t k = 0; k < dem.d_neighPd[i].size(); ++k) {
972 if (!dem.d_fracture_p->getBondState(i, k))
973 continue;
974 const size_t j = dem.d_neighPd[i][k];
975 if (dem.d_ptId[j] != 0)
976 continue;
977 const auto &xi = dem.d_xRef[i];
978 const auto &xj = dem.d_xRef[j];
979 const bool on_notch =
980 geometry::segmentCrossesVerticalLine(xi.d_x, xi.d_y, xj.d_x, xj.d_y,
981 -notch_half, y_tip,
982 y_top + 0.01 * H) ||
983 geometry::segmentCrossesVerticalLine(xi.d_x, xi.d_y, xj.d_x, xj.d_y,
984 notch_half, y_tip,
985 y_top + 0.01 * H);
986 if (!on_notch)
987 ++n_extra;
988 }
989 }
990 if (n_extra < 20) {
991 std::cerr << "notched_impact: expected new broken bonds, got " << n_extra
992 << " (prenotch=" << n_pre << ")\n";
993 return 1;
994 }
995
996 // Dump the damage field so the crack-path metric can be re-fitted offline
997 // without repeating the simulation.
998 {
999 std::ofstream csv(base / "damage.csv");
1000 csv << "x_ref,y_ref,z_ref,x_cur,y_cur,z_cur,phi,phi_bond,arrival\n";
1001 for (size_t i = 0; i < dem.d_xRef.size(); ++i) {
1002 if (dem.d_ptId[i] != 0)
1003 continue;
1004 const double phi = nodeDamageForFit(dem, i, /*use_bond_count=*/false);
1005 const double phi_b = nodeDamageForFit(dem, i, /*use_bond_count=*/true);
1006 if (std::max(phi, phi_b) < 0.05)
1007 continue;
1008 csv << std::format("{:.6e},{:.6e},{:.6e},{:.6e},{:.6e},{:.6e},{:.4f},{:.4f},{:.6e}\n",
1009 dem.d_xRef[i].d_x, dem.d_xRef[i].d_y, dem.d_xRef[i].d_z,
1010 dem.d_x[i].d_x, dem.d_x[i].d_y, dem.d_x[i].d_z, phi, phi_b,
1011 double(arrival[i]));
1012 }
1013 }
1014
1015 const double band_x = 0.45 * W;
1016 const double band_y = 0.55 * H;
1017 const double phi_cut = quick ? 0.20 : 0.35;
1018 const double exclude_r = 2.0 * mesh_size;
1019 const bool use_bond_dmg = bhat;
1020 auto left = fitCrackFromPhi(dem, -notch_half, y_tip, -1.0, phi_cut, band_x, band_y, exclude_r,
1021 mesh_size, use_bond_dmg);
1022 auto right = fitCrackFromPhi(dem, notch_half, y_tip, +1.0, phi_cut, band_x, band_y, exclude_r,
1023 mesh_size, use_bond_dmg);
1024 if (left.n_pts < 4 || right.n_pts < 4) {
1025 std::cerr << "notched_impact: insufficient φ-ridge for path fit (L=" << left.n_pts
1026 << " R=" << right.n_pts << ")\n";
1027 return 1;
1028 }
1029 if (!(left.mean_dx < 0. && left.mean_dy > 0. && right.mean_dx > 0. && right.mean_dy > 0.)) {
1030 std::cerr << std::format(
1031 "notched_impact: tip damage not outward/down "
1032 "(L dx={:.3e} dy={:.3e} R dx={:.3e} dy={:.3e})\n",
1033 left.mean_dx, left.mean_dy, right.mean_dx, right.mean_dy);
1034 return 1;
1035 }
1036
1037 const double ang = 0.5 * (left.angle_to_notch_deg + right.angle_to_notch_deg);
1038 std::cout << std::format(
1039 "notched_impact PASS: prenotch={} new_broken={} ang_to_notch={:.1f}° "
1040 "(L={:.1f}/{} R={:.1f}/{}) max|v|={:.3e}\n",
1041 n_pre, n_extra, ang, left.angle_to_notch_deg, left.n_pts, right.angle_to_notch_deg,
1042 right.n_pts, vmax);
1043
1044 dem.close();
1045 return 0;
1046}
Input command line argument parser.
Definition inputParser.h:28
nlohmann::ordered_json json
json buildBhatInputJson(const std::string &output_path, const std::filesystem::path &mesh_plate, const std::filesystem::path &mesh_impactor, double W, double H, double notch_half, double notch_w, double notch_depth, double Iw, double Ih, double gap, double mesh_size, double horizon, double Rc_factor, double rho, double E, double K, double G, double Gc, double v_impact, double final_time, size_t num_steps)
Definition main.cpp:570
std::string directoryPathWithTrailingSep(const std::filesystem::path &dir)
Definition main.cpp:34
size_t applyNotchMidplanes(PeriDEMModel &dem, double notch_half, double y_tip, double y_top)
Definition main.cpp:57
json buildTraskInputJson(const std::string &output_path, const std::filesystem::path &mesh_plate, double W, double H, double notch_half, double notch_w, double notch_depth, double mesh_size, double horizon, double rho, double E, double K, double G, double Gc, double v_impact, double final_time, size_t num_steps)
Definition main.cpp:292
size_t applyNotchSlots(PeriDEMModel &dem, double notch_half, double notch_w, double y_lo, double y_hi)
Definition main.cpp:48
json buildImpactInputJson(const std::string &output_path, const std::filesystem::path &mesh_plate, const std::filesystem::path &mesh_impactor, double W, double H, double notch_half, double notch_w, double notch_depth, double Iw, double Ih, double gap, double mesh_size, double horizon, double Rc_factor, double Kn, double rho, double E, double K, double G, double Gc, double v_impact, double final_time, size_t num_steps, double thickness=0.)
Definition main.cpp:377
double nodePhi(const PeriDEMModel &dem, size_t i)
Definition main.cpp:79
CrackFit fitCrackFromPhi(const PeriDEMModel &dem, double tip_x, double tip_y, double outward_sign, double phi_cut, double band_x, double band_y, double exclude_r, double bin_h, bool use_bond_count=false)
Definition main.cpp:110
double nodeDamageForFit(const PeriDEMModel &dem, size_t i, bool use_bond_count)
Definition main.cpp:91
bool segmentCrossesVerticalLine(double x0, double y0, double x1, double y1, double xLine, double yLo, double yHi)
Pre-notch by breaking peridynamic bonds.
Definition prenotch.cpp:52
float W
Definition problem.py:39
float H
Definition problem.py:40
float E
Definition problem.py:64
void applyRigidBodyConstraint(data::ModelData &data)
void print(const T &msg, int nt=print_default_tab, int printMpiRank=print_default_mpi_rank)
Prints formatted information.
Definition io.h:171
void initNThreads(unsigned int nThreads=std::thread::hardware_concurrency())
Initializes MpiStatus struct.
void initMpi(int argc=0, char *argv[]=nullptr)
Initializes MPI and also creates MpiStatus struct.
void finalizeMpi()
Call MPI_Finalize if this process initialized MPI.
double normalContactStiffness(const double &K1, const double &K2, const double &horizon, int horizonPower=5)
Silling normal contact stiffness from two bulk moduli and the horizon.
Definition function.cpp:139

References PeriDEMModel::applyDisplacementBC(), PeriDEMModel::applyInitialCondition(), anonymous_namespace{main.cpp}::applyNotchMidplanes(), anonymous_namespace{main.cpp}::applyNotchSlots(), time_int::applyRigidBodyConstraint(), anonymous_namespace{main.cpp}::buildBhatInputJson(), anonymous_namespace{main.cpp}::buildImpactInputJson(), anonymous_namespace{main.cpp}::buildTraskInputJson(), PeriDEMModel::checkStop(), PeriDEMModel::close(), util::io::InputParser::cmdOptionExists(), PeriDEMModel::computeForces(), data::ModelData::currentStep(), data::ModelData::d_fracture_p, data::ModelData::d_neighPd, data::ModelData::d_ptId, data::ModelData::d_time, data::ModelData::d_v, data::ModelData::d_x, data::ModelData::d_xRef, data::ModelData::d_Z, util::parallel::finalizeMpi(), anonymous_namespace{main.cpp}::fitCrackFromPhi(), util::io::InputParser::getCmdOption(), PeriDEMModel::init(), util::parallel::initMpi(), util::parallel::initNThreads(), PeriDEMModel::integrateStep(), main(), anonymous_namespace{main.cpp}::nodeDamageForFit(), anonymous_namespace{main.cpp}::nodePhi(), util::normalContactStiffness(), data::ModelData::numTimeSteps(), PeriDEMModel::output(), data::ModelData::performOutput(), util::io::print(), geometry::segmentCrossesVerticalLine(), data::ModelData::setCurrentDt(), data::ModelData::shouldOutput(), and data::ModelData::timeStep().

Here is the call graph for this function: