16#include <taskflow/taskflow/taskflow.hpp>
17#include <taskflow/taskflow/algorithm/for_each.hpp>
22 const std::vector<double> &nodal_vol,
23 const std::vector<std::vector<size_t>> &neighbors,
24 const std::vector<std::vector<float>> &neighbors_sq_dist,
25 const double &mesh_size,
28 double horizon =
material->getHorizon();
29 const auto &xi = nodes[i];
33 auto check_up = horizon + 0.5 * mesh_size;
34 auto check_low = horizon - 0.5 * mesh_size;
37 for (
size_t j : neighbors[i]) {
39 const auto &xj = nodes[j];
40 double rji = (xj - xi).length();
47 auto volj = nodal_vol[j];
50 volj *= (check_up - rji) / mesh_size;
52 m += std::pow(rji, 2) *
material->getInfFn(rji) * volj;
58 std::ostringstream oss;
59 oss <<
"Error: Weighted nodal volume = " << m
60 <<
" should not be too close to zero.\n";
62 oss <<
"Mesh size = " << mesh_size <<
"\n";
63 oss <<
"J = " <<
material->getInfFn(0.5 * horizon) <<
"\n";
64 oss <<
"weighted volume (times 1.0e10) = " << m*1.e+10 <<
"\n";
65 oss <<
"nodal coord = " << xi.printStr() <<
"\n";
68 std::cout << oss.str();
76 const std::vector<util::Point> &nodes_disp,
77 const std::vector<double> &nodal_vol,
78 const std::vector<std::vector<size_t>> &neighbors,
79 const std::vector<std::vector<float>> &neighbors_sq_dist,
80 const double &mesh_size,
83 const std::vector<double> &mx) {
85 double horizon =
material->getHorizon();
86 const auto &xi = nodes[i];
87 const auto &ui = nodes_disp[i];
92 auto check_up = horizon + 0.5 * mesh_size;
93 auto check_low = horizon - 0.5 * mesh_size;
96 for (
size_t j : neighbors[i]) {
98 const auto &xj = nodes[j];
99 const auto &uj = nodes_disp[j];
100 double rji = (xj - xi).length();
108 auto volj = nodal_vol[j];
111 volj *= (check_up - rji) / mesh_size;
114 double bond_state = fracture->
getBondState(i, k) ? 0. : 1.;
119 double change_length = (yj - yi).length() - rji;
121 theta += bond_state * rji * change_length *
127 return 3. * theta / m;
131 const std::vector<util::Point> &nodes_disp,
132 const std::vector<double> &nodal_vol,
133 const std::vector<std::vector<size_t>> &neighbors,
134 const std::vector<std::vector<float>> &neighbors_sq_dist,
135 const double &mesh_size,
140 double horizon =
material->getHorizon();
141 const auto &xi = nodes[i];
142 const auto &ui = nodes_disp[i];
146 auto check_up = horizon + 0.5 * mesh_size;
147 auto check_low = horizon - 0.5 * mesh_size;
150 double vol_ball = std::pow(horizon, 2) * M_PI;
152 vol_ball *= horizon * 4. / 3.;
155 for (
size_t j : neighbors[i]) {
157 const auto &xj = nodes[j];
158 const auto &uj = nodes_disp[j];
159 double rji = (xj - xi).length();
166 auto volj = nodal_vol[j];
169 volj *= (check_up - rji) / mesh_size;
172 double bond_state = fracture->
getBondState(i, k) ? 0. : 1.;
175 double Sji =
material->getS(xj - xi, uj - ui);
177 theta += bond_state * rji * Sji *
178 material->getInfFn(rji) * volj / vol_ball;
187 const std::vector<std::vector<size_t>> &neighbors,
188 const std::vector<util::Point> &nodes_disp,
193 for (
size_t j : neighbors[i]) {
195 double s =
material->getS(nodes[j] - nodes[i], nodes_disp[j] -
197 double sc =
material->getSc((nodes[j] - nodes[i]).length());
214 if (!compute_in_parallel) {
215 for (
size_t i = 0; i <
model->d_x.size(); i++) {
216 const auto &pti =
model->getPtId(i);
228 tf::Taskflow taskflow;
230 taskflow.for_each_index(
231 (std::size_t) 0,
model->d_x.size(), (std::size_t) 1, [
model](std::size_t i) {
232 const auto &pti = model->getPtId(i);
233 const auto &particle = model->getParticleFromAllList(pti);
234 auto mx = computeStateMxI(i, model->d_xRef, model->d_vol,
235 model->d_neighPd, model->d_neighPdSqdDist,
236 particle->getMeshSize(),
237 particle->getMaterial());
243 executor.run(taskflow).get();
250 if (!compute_in_parallel) {
251 for (
size_t i = 0; i <
model->d_x.size(); i++) {
252 const auto &pti =
model->getPtId(i);
260 model->d_fracture_p.get(),
263 model->setThetax(i, thetax);
270 tf::Taskflow taskflow;
272 taskflow.for_each_index(
273 (std::size_t) 0,
model->d_x.size(), (std::size_t) 1, [
model](std::size_t i) {
274 const auto &pti = model->getPtId(i);
275 const auto &particle = model->getParticleFromAllList(pti);
277 auto thetax = computeStateThetaxI(i, model->d_xRef, model->d_u,
279 model->d_neighPd, model->d_neighPdSqdDist,
280 particle->getMeshSize(),
281 particle->getMaterial(),
282 model->d_fracture_p.get(),
285 model->setThetax(i, thetax);
289 executor.run(taskflow).get();
296 if (!compute_in_parallel) {
297 for (
size_t i = 0; i <
model->d_x.size(); i++) {
298 const auto &pti =
model->getPtId(i);
306 model->d_fracture_p.get(),
309 model->setThetax(i, thetax);
314 tf::Taskflow taskflow;
316 taskflow.for_each_index(
317 (std::size_t) 0,
model->d_x.size(), (std::size_t) 1, [
model](std::size_t i) {
318 const auto &pti = model->getPtId(i);
319 const auto &particle = model->getParticleFromAllList(pti);
321 auto thetax = computeHydrostaticStrainI(i,
325 model->d_neighPd, model->d_neighPdSqdDist,
326 particle->getMeshSize(),
327 particle->getMaterial(),
328 model->d_fracture_p.get(),
329 particle->getDimension());
331 model->setThetax(i, thetax);
335 executor.run(taskflow).get();
342 if (!compute_in_parallel) {
343 for (
size_t i = 0; i <
model->d_x.size(); i++) {
344 const auto &pti =
model->getPtId(i);
349 model->d_fracture_p.get());
354 tf::Taskflow taskflow;
356 taskflow.for_each_index(
357 (std::size_t) 0,
model->d_x.size(), (std::size_t) 1, [
model](std::size_t i) {
358 const auto &pti = model->getPtId(i);
359 const auto &particle = model->getParticleFromAllList(pti);
361 updateBondFractureDataI(i,
365 particle->getMaterial(),
366 model->d_fracture_p.get());
370 executor.run(taskflow).get();
A class for fracture state of bonds.
void setBondState(const std::size_t &i, const std::size_t &j, const bool &state)
Sets the bond state.
bool getBondState(const std::size_t &i, const std::size_t &j) const
Read bond state.
Collection of methods and database related to peridynamic material.
A class to store model data.
void updateBondFractureDataI(size_t i, const std::vector< util::Point > &nodes, const std::vector< std::vector< size_t > > &neighbors, const std::vector< util::Point > &nodes_disp, const material::Material *material, geometry::Fracture *fracture)
double computeHydrostaticStrainI(size_t i, const std::vector< util::Point > &nodes, const std::vector< util::Point > &nodes_disp, const std::vector< double > &nodal_vol, const std::vector< std::vector< size_t > > &neighbors, const std::vector< std::vector< float > > &neighbors_sq_dist, const double &mesh_size, const material::Material *material, const geometry::Fracture *fracture, size_t dim)
double computeStateThetaxI(size_t i, const std::vector< util::Point > &nodes, const std::vector< util::Point > &nodes_disp, const std::vector< double > &nodal_vol, const std::vector< std::vector< size_t > > &neighbors, const std::vector< std::vector< float > > &neighbors_sq_dist, const double &mesh_size, const material::Material *material, const geometry::Fracture *fracture, const std::vector< double > &mx)
double computeStateMxI(size_t i, const std::vector< util::Point > &nodes, const std::vector< double > &nodal_vol, const std::vector< std::vector< size_t > > &neighbors, const std::vector< std::vector< float > > &neighbors_sq_dist, const double &mesh_size, const material::Material *material)
void computeStateThetax(model::ModelData *model, bool compute_in_parallel=false)
void computeStateMx(model::ModelData *model, bool compute_in_parallel=false)
Computes the moment term in state-based peridynamic formulation.
void computeHydrostaticStrain(model::ModelData *model, bool compute_in_parallel=false)
void updateBondFractureData(model::ModelData *model, bool compute_in_parallel=false)
Collection of methods and data related to particle object.
unsigned int getNThreads()
Get number of threads to be used by taskflow.
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.