30 {
31 if (
data.d_particlesListTypeWall.empty())
32 return;
33
35 tf::Executor executor(n_workers);
36 tf::Taskflow taskflow;
37
38 taskflow.for_each_index(
39 (std::size_t)0,
data.d_fContCompNodes.size(), (std::size_t)1,
40 [&
data, use_node_damping](std::size_t II) {
41 const auto i = data.d_fContCompNodes[II];
42 const auto &ptIdi = data.getPtId(i);
43 auto &pi = data.getParticleFromAllList(ptIdi);
44 if (pi->isWall())
45 return;
46
47 const auto &yi = data.d_x[i];
48 const auto &vi = data.d_v[i];
49 const double voli = data.d_vol[i];
50 util::Point force_i;
51
52 for (auto *wall : data.d_particlesListTypeWall) {
53 if (!wall || !wall->d_geom_p)
54 continue;
55
56 geom::WallContactHit hit;
57 if (!wall->d_geom_p->wallContactQuery(yi, hit) || !hit.active)
58 continue;
59
60 const auto &contact =
61 data.d_particleDeck_p->d_contactDeck.getContact(
62 pi->getGroupId("contact_id"),
63 wall->getGroupId("contact_id"));
64
65
66 const double R = hit.signed_gap;
67 if (!util::isLess(R, contact.d_contactR))
68 continue;
69
70
71 const util::Point en = -1. * hit.outward_n;
72 auto scalar_f = contact.d_Kn * (R - contact.d_contactR) * voli;
73 if (scalar_f > 0.)
74 scalar_f = 0.;
75
76 util::Point f = scalar_f * en;
77
78 if (contact.d_frictionOn) {
79 const util::Point vji = -1. * vi;
80 const double vn = vji * en;
81 util::Point et = vji - vn * en;
82 if (util::isGreater(et.length(), 0.))
83 et = et / et.length();
84 else
85 et = util::Point();
86 f += contact.d_mu * scalar_f * et;
87 }
88
89 if (use_node_damping && contact.d_dampingOn && voli > 0. &&
90 contact.d_K > 0. && contact.d_contactR > 0.) {
91 const util::Point vji = -1. * vi;
92 const double vn = vji * en;
93 if (util::isLess(vn, 0.)) {
94 const double meq =
95 util::equivalentMass(pi->getDensity() * voli,
96 wall->getDensity() * voli);
97 const double beta_n =
98 contact.d_betan *
99 std::sqrt(contact.d_K * contact.d_contactR * meq);
100 f += (beta_n * vn / voli) * en;
101 }
102 }
103
104 force_i += f;
105 }
106
107 data.d_f[i] += force_i;
108 });
109
110 executor.run(taskflow).get();
111}
unsigned int getNThreads()
Get number of threads to be used by taskflow.