18#include <taskflow/taskflow/taskflow.hpp>
19#include <taskflow/taskflow/algorithm/for_each.hpp>
24 const std::vector<double> &nodal_vol,
25 const std::vector<std::vector<size_t>> &neighbors,
26 const std::vector<std::vector<float>> &neighbors_sq_dist,
27 const double &mesh_size,
30 double horizon =
material->getHorizon();
31 const auto &xi = nodes[i];
35 auto check_up = horizon + 0.5 * mesh_size;
36 auto check_low = horizon - 0.5 * mesh_size;
39 for (
size_t j : neighbors[i]) {
41 const auto &xj = nodes[j];
42 double rji = (xj - xi).length();
49 auto volj = nodal_vol[j];
52 volj *= (check_up - rji) / mesh_size;
54 m += std::pow(rji, 2) *
material->getInfFn(rji) * volj;
60 std::ostringstream oss;
61 oss <<
"Error: Weighted nodal volume = " << m
62 <<
" should not be too close to zero.\n";
64 oss <<
"Mesh size = " << mesh_size <<
"\n";
65 oss <<
"J = " <<
material->getInfFn(0.5 * horizon) <<
"\n";
66 oss <<
"weighted volume (times 1.0e10) = " << m*1.e+10 <<
"\n";
67 oss <<
"nodal coord = " << xi.printStr() <<
"\n";
70 throw std::runtime_error(
78 const std::vector<util::Point> &nodes_disp,
79 const std::vector<double> &nodal_vol,
80 const std::vector<std::vector<size_t>> &neighbors,
81 const std::vector<std::vector<float>> &neighbors_sq_dist,
82 const double &mesh_size,
85 const std::vector<double> &mx) {
87 double horizon =
material->getHorizon();
88 const auto &xi = nodes[i];
89 const auto &ui = nodes_disp[i];
94 auto check_up = horizon + 0.5 * mesh_size;
95 auto check_low = horizon - 0.5 * mesh_size;
98 for (
size_t j : neighbors[i]) {
100 const auto &xj = nodes[j];
101 const auto &uj = nodes_disp[j];
102 double rji = (xj - xi).length();
110 auto volj = nodal_vol[j];
113 volj *= (check_up - rji) / mesh_size;
116 double bond_state = fracture->
getBondState(i, k) ? 0. : 1.;
121 double change_length = (yj - yi).length() - rji;
123 theta += bond_state * rji * change_length *
130 return double(
material->getDimension()) * theta / m;
134 const std::vector<util::Point> &nodes_disp,
135 const std::vector<double> &nodal_vol,
136 const std::vector<std::vector<size_t>> &neighbors,
137 const std::vector<std::vector<float>> &neighbors_sq_dist,
138 const double &mesh_size,
143 double horizon =
material->getHorizon();
144 const auto &xi = nodes[i];
145 const auto &ui = nodes_disp[i];
149 auto check_up = horizon + 0.5 * mesh_size;
150 auto check_low = horizon - 0.5 * mesh_size;
153 double vol_ball = std::pow(horizon, 2) * M_PI;
155 vol_ball *= horizon * 4. / 3.;
158 for (
size_t j : neighbors[i]) {
160 const auto &xj = nodes[j];
161 const auto &uj = nodes_disp[j];
162 double rji = (xj - xi).length();
169 auto volj = nodal_vol[j];
172 volj *= (check_up - rji) / mesh_size;
175 double bond_state = fracture->
getBondState(i, k) ? 0. : 1.;
178 double Sji =
material->getS(xj - xi, uj - ui);
180 theta += bond_state * rji * Sji *
181 material->getInfFn(rji) * volj / vol_ball;
190 const std::vector<std::vector<size_t>> &neighbors,
191 const std::vector<util::Point> &nodes_disp,
196 for (
size_t j : neighbors[i]) {
198 double s =
material->getS(nodes[j] - nodes[i], nodes_disp[j] -
200 double sc =
material->getSc((nodes[j] - nodes[i]).length());
216 model->
d_mX.resize(model->
d_x.size());
217 if (!compute_in_parallel) {
218 for (
size_t i = 0; i < model->
d_x.size(); i++) {
219 const auto &pti = model->
getPtId(i);
231 tf::Taskflow taskflow;
233 taskflow.for_each_index(
234 (std::size_t) 0, model->
d_x.size(), (std::size_t) 1, [model](std::size_t i) {
235 const auto &pti = model->getPtId(i);
236 const auto &particle = model->getParticleFromAllList(pti);
237 auto mx = computeStateMxI(i, model->d_xRef, model->d_vol,
238 model->d_neighPd, model->d_neighPdSqdDist,
239 particle->getMeshSize(),
240 particle->getMaterial());
246 executor.run(taskflow).get();
253 if (!compute_in_parallel) {
254 for (
size_t i = 0; i < model->
d_x.size(); i++) {
255 const auto &pti = model->
getPtId(i);
273 tf::Taskflow taskflow;
275 taskflow.for_each_index(
276 (std::size_t) 0, model->
d_x.size(), (std::size_t) 1, [model](std::size_t i) {
277 const auto &pti = model->getPtId(i);
278 const auto &particle = model->getParticleFromAllList(pti);
280 auto thetax = computeStateThetaxI(i, model->d_xRef, model->d_u,
282 model->d_neighPd, model->d_neighPdSqdDist,
283 particle->getMeshSize(),
284 particle->getMaterial(),
285 model->d_fracture_p.get(),
288 model->setThetax(i, thetax);
292 executor.run(taskflow).get();
299 if (!compute_in_parallel) {
300 for (
size_t i = 0; i < model->
d_x.size(); i++) {
301 const auto &pti = model->
getPtId(i);
317 tf::Taskflow taskflow;
319 taskflow.for_each_index(
320 (std::size_t) 0, model->
d_x.size(), (std::size_t) 1, [model](std::size_t i) {
321 const auto &pti = model->getPtId(i);
322 const auto &particle = model->getParticleFromAllList(pti);
324 auto thetax = computeHydrostaticStrainI(i,
328 model->d_neighPd, model->d_neighPdSqdDist,
329 particle->getMeshSize(),
330 particle->getMaterial(),
331 model->d_fracture_p.get(),
332 particle->getDimension());
334 model->setThetax(i, thetax);
338 executor.run(taskflow).get();
345 if (!compute_in_parallel) {
346 for (
size_t i = 0; i < model->
d_x.size(); i++) {
347 const auto &pti = model->
getPtId(i);
357 tf::Taskflow taskflow;
359 taskflow.for_each_index(
360 (std::size_t) 0, model->
d_x.size(), (std::size_t) 1, [model](std::size_t i) {
361 const auto &pti = model->getPtId(i);
362 const auto &particle = model->getParticleFromAllList(pti);
364 updateBondFractureDataI(i,
368 particle->getMaterial(),
369 model->d_fracture_p.get());
373 executor.run(taskflow).get();
A class to store model data.
std::vector< util::Point > d_x
Current positions of the nodes.
std::vector< util::Point > d_xRef
reference positions of the nodes
std::vector< util::Point > d_u
Displacement of the nodes.
std::vector< double > d_mX
Weighted volume.
size_t & getPtId(size_t i)
Get particle id given the location in particle list.
std::vector< std::vector< float > > d_neighPdSqdDist
Square distance neighbor data for peridynamic forces.
std::unique_ptr< geometry::Fracture > d_fracture_p
Fracture state of bonds.
std::vector< double > d_thetaX
Dilation.
std::vector< std::vector< size_t > > d_neighPd
Neighbor data for peridynamic forces.
void setMx(size_t i, const double &mx)
Set weighted-volume (mx) of the node.
void setThetax(size_t i, const double &thetax)
Set volumetric deformation (thetax) of the node.
std::vector< double > d_vol
Nodal volumes.
const particle::BaseParticle * getParticleFromAllList(size_t i) const
Get pointer to base particle.
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.
Collects a message with stream syntax for use in an exception.
std::string str() const
The message built so far.
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 computeHydrostaticStrain(data::ModelData *model, bool compute_in_parallel=false)
void computeStateMx(data::ModelData *model, bool compute_in_parallel=false)
Computes the moment term in state-based peridynamic formulation.
void updateBondFractureData(data::ModelData *model, bool compute_in_parallel=false)
void computeStateThetax(data::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.