PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
prenotch.cpp
Go to the documentation of this file.
1/*
2 * -------------------------------------------
3 * Copyright (c) 2021 - 2026 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 "prenotch.h"
12
13#include <stdexcept>
14
15namespace {
16
18template <typename Predicate>
19std::size_t breakBondsIf(
20 geometry::Fracture &fracture, const std::vector<util::Point> &xRef,
21 const std::vector<std::vector<std::size_t>> &neighbors,
22 const std::vector<std::size_t> &nodeParticleId, std::size_t particleId,
23 Predicate crosses) {
24 if (neighbors.size() > xRef.size() ||
25 nodeParticleId.size() < neighbors.size())
26 throw std::invalid_argument(
27 "prenotch: node arrays are inconsistent with the neighbour list");
28
29 std::size_t broken = 0;
30 for (std::size_t i = 0; i < neighbors.size(); ++i) {
31 if (nodeParticleId[i] != particleId)
32 continue;
33 const auto &xi = xRef[i];
34 for (std::size_t k = 0; k < neighbors[i].size(); ++k) {
35 const std::size_t j = neighbors[i][k];
36 if (j >= nodeParticleId.size() || nodeParticleId[j] != particleId)
37 continue;
38 const auto &xj = xRef[j];
39 if (crosses(xi.d_x, xi.d_y, xj.d_x, xj.d_y)) {
40 fracture.setBondState(i, k, true);
41 ++broken;
42 }
43 }
44 }
45 return broken;
46}
47
48} // namespace
49
50namespace geometry {
51
52bool segmentCrossesVerticalLine(double x0, double y0, double x1, double y1,
53 double xLine, double yLo, double yHi) {
54 // The endpoints lie on opposite sides of the line. This excludes x1 == x0,
55 // so the division is defined and the parameter lies in (0, 1).
56 if ((x0 - xLine) * (x1 - xLine) >= 0.)
57 return false;
58 const double t = (xLine - x0) / (x1 - x0);
59 const double y = y0 + t * (y1 - y0);
60 return y >= yLo && y <= yHi;
61}
62
63bool segmentEntersSlot(double x0, double y0, double x1, double y1,
64 double xCenter, double halfWidth, double yLo,
65 double yHi, int nSamples) {
66 const double xa = xCenter - halfWidth, xb = xCenter + halfWidth;
67 auto inSlot = [&](double x, double y) {
68 return x >= xa && x <= xb && y >= yLo && y <= yHi;
69 };
70 if (inSlot(x0, y0) || inSlot(x1, y1))
71 return true;
72 if (nSamples > 0) {
73 for (int s = 0; s <= nSamples; ++s) {
74 const double t = static_cast<double>(s) / nSamples;
75 if (inSlot(x0 + t * (x1 - x0), y0 + t * (y1 - y0)))
76 return true;
77 }
78 }
79 // A slot narrower than the sample spacing can be crossed with no sample
80 // inside it.
81 return segmentCrossesVerticalLine(x0, y0, x1, y1, xCenter, yLo, yHi);
82}
83
85 Fracture &fracture, const std::vector<util::Point> &xRef,
86 const std::vector<std::vector<std::size_t>> &neighbors,
87 const std::vector<std::size_t> &nodeParticleId, std::size_t particleId,
88 const std::vector<double> &xLines, double yLo, double yHi) {
89 return breakBondsIf(
90 fracture, xRef, neighbors, nodeParticleId, particleId,
91 [&](double x0, double y0, double x1, double y1) {
92 for (double xl : xLines)
93 if (segmentCrossesVerticalLine(x0, y0, x1, y1, xl, yLo, yHi))
94 return true;
95 return false;
96 });
97}
98
100 Fracture &fracture, const std::vector<util::Point> &xRef,
101 const std::vector<std::vector<std::size_t>> &neighbors,
102 const std::vector<std::size_t> &nodeParticleId, std::size_t particleId,
103 const std::vector<double> &xCenters, double width, double yLo,
104 double yHi) {
105 if (width < 0.)
106 throw std::invalid_argument("prenotch: slot width must not be negative");
107 const double hw = 0.5 * width;
108 return breakBondsIf(
109 fracture, xRef, neighbors, nodeParticleId, particleId,
110 [&](double x0, double y0, double x1, double y1) {
111 for (double xc : xCenters)
112 if (segmentEntersSlot(x0, y0, x1, y1, xc, hw, yLo, yHi))
113 return true;
114 return false;
115 });
116}
117
118} // namespace geometry
A class for fracture state of bonds.
Definition fracture.h:26
void setBondState(const std::size_t &i, const std::size_t &j, const bool &state)
Sets the bond state.
Definition fracture.cpp:51
std::size_t breakBondsIf(geometry::Fracture &fracture, const std::vector< util::Point > &xRef, const std::vector< std::vector< std::size_t > > &neighbors, const std::vector< std::size_t > &nodeParticleId, std::size_t particleId, Predicate crosses)
Definition prenotch.cpp:19
Collection of methods and data related to geometry.
Definition fracture.h:20
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
bool segmentEntersSlot(double x0, double y0, double x1, double y1, double xCenter, double halfWidth, double yLo, double yHi, int nSamples)
Checks whether the segment enters the open slot centred on xCenter.
Definition prenotch.cpp:63
std::size_t breakBondsCrossingVerticalLines(Fracture &fracture, const std::vector< util::Point > &xRef, const std::vector< std::vector< std::size_t > > &neighbors, const std::vector< std::size_t > &nodeParticleId, std::size_t particleId, const std::vector< double > &xLines, double yLo, double yHi)
Break the bonds of one particle that cross vertical cut lines.
Definition prenotch.cpp:84
std::size_t breakBondsInSlots(Fracture &fracture, const std::vector< util::Point > &xRef, const std::vector< std::vector< std::size_t > > &neighbors, const std::vector< std::size_t > &nodeParticleId, std::size_t particleId, const std::vector< double > &xCenters, double width, double yLo, double yHi)
Break the bonds of one particle that enter open notch slots.
Definition prenotch.cpp:99