25 {
28 for (
auto &pi :
data.d_particlesListTypeParticle) {
29
30 if (!pi->d_computeForce)
31 continue;
32
33
35 continue;
36
37 auto pi_id = pi->getId();
38
39 double Ri = pi->d_geom_p->boundingRadius();
40 double vol_pi = M_PI * Ri * Ri;
41 auto pi_xc = pi->getXCenter();
42 auto pi_vc = pi->getVCenter();
43 auto rhoi = pi->getDensity();
45
46 for (
auto &pj :
data.d_particlesListTypeParticle) {
47 if (pj->getId() != pi->getId()) {
48 auto Rj = pj->d_geom_p->boundingRadius();
49 auto xc_ji = pj->getXCenter() - pi_xc;
50 auto dist_xcji = xc_ji.length();
51
52 const auto &
contact =
data.d_particleDeck_p->d_contactDeck.getContact(pi->getGroupId(
"contact_id"), pj->getGroupId(
"contact_id"));
53
55 continue;
56
58
59 auto vol_pj = M_PI * Rj * Rj;
60 auto rhoj = pj->getDensity();
62
65
68 hat_xc_ji = xc_ji / dist_xcji;
69 else
71
72 auto vc_ji = pj->getVCenter() - pi_vc;
73 auto vc_mag = vc_ji * hat_xc_ji;
74 if (vc_mag > 0.)
75 vc_mag = 0.;
76
77 force_i += beta_n * vc_mag * hat_xc_ji / vol_pi;
78 }
79 }
80 }
81
82 data.d_neighWallNodesCondensed[pi->getId()].clear();
83 {
84 for (
size_t j=0; j<
data.d_neighWallNodes[pi_id].size(); j++) {
85
86 const auto &j_id = pi->getNodeId(j);
87 const auto &yj =
data.d_x[j_id];
88
89 for (
size_t k=0; k<
data.d_neighWallNodes[pi_id][j].size(); k++) {
90
91 const auto &k_id =
data.d_neighWallNodes[pi_id][j][k];
92 const auto &pk =
data.d_particlesListTypeAll[
data.d_ptId[k_id]];
93
94 double Rjk = (
data.d_x[k_id] - yj).length();
95
97 data.d_particleDeck_p->d_contactDeck.getContact(pi->getGroupId(
"contact_id"), pk->getGroupId(
"contact_id"));
98
101
102 }
103 }
104 }
105
106 for (
auto &j :
data.d_neighWallNodesCondensed[pi_id]) {
107
108 auto &ptIdj =
data.d_ptId[j];
109 auto &pj =
data.d_particlesListTypeAll[ptIdj];
110 auto meq = rhoi * vol_pi;
111
113 =
data.d_particleDeck_p->d_contactDeck.getContact(pi->getGroupId(
"contact_id"), pj->getGroupId(
"contact_id"));
114
116 continue;
117
118 auto beta_n =
contact.d_betan *
120
121 auto xc_ji =
data.d_x[j] - pi_xc;
124 hat_xc_ji = xc_ji / xc_ji.length();
125
126 auto vc_ji =
data.d_v[j] - pi_vc;
127 auto vc_mag = vc_ji * hat_xc_ji;
128 if (vc_mag > 0.)
129 vc_mag = 0.;
130
131 force_i += beta_n * vc_mag * hat_xc_ji / vol_pi;
132 }
133
134 for (size_t i = 0; i < pi->getNumNodes(); i++) {
135 const size_t g = pi->getNodeId(i);
136 if (
data.d_pdDofMpi &&
137 (
data.d_pdNodePartition.size() !=
data.d_x.size() ||
138 static_cast<int>(
data.d_pdNodePartition[g]) != mpi_rank))
139 continue;
140 data.d_f[g] += force_i;
141 }
142 }
143}
bool isLocallyOwned(const BaseParticle &p)
True if this rank updates / assembles forces for the particle. Walls are replicated on every rank....
void log(std::ostringstream &oss, bool screen_out=false, int printMpiRank=print_default_mpi_rank)
Global method to log the message.
void addToList(const T &i, std::vector< T > &list)
Add element to the list.
int mpiRank()
get rank (id) of this processor
bool isGreater(const double &a, const double &b)
Returns true if a > b.
double equivalentMass(const double &m1, const double &m2)
Compute harmonic mean of m1 and m2.
bool isLess(const double &a, const double &b)
Returns true if a < b.
A structure to represent 3d vectors.