PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
particleULoading.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 "particleULoading.h"
12#include "particleLoadingUtil.h"
14#include "util/function.h"
17
19 std::vector<inp::BCBaseDeck> &bc_data) {
20
21 d_bcData = bc_data;
22
23 d_pZeroDisplacementApplied = std::vector<bool>(d_bcData.size(), false);
24}
25
27
28 for (size_t s = 0; s < d_bcData.size(); s++) {
29
30 // get alias for bc data
31 const auto &bc = d_bcData[s];
32
33 // check if we need to process this particle
34 if (!needToProcessParticle(particle->getId(), bc))
35 continue;
36
37 for (size_t i = 0; i < particle->getNumNodes(); i++) {
38
39 const auto x = particle->getXRefLocal(i);
40
41 if (!needToComputeDof(x, particle->getId(), bc))
42 continue;
43
44 // set fixity to true
45 for (auto d : bc.d_direction)
46 particle->setFixLocal(i, d - 1, true);
47 } // loop over nodes
48 } // loop over bc sets
49}
50
51void loading::ParticleULoading::apply(const double &time,
53
54 for (size_t s = 0; s < d_bcData.size(); s++) {
55
56 // get alias for bc data
57 const auto &bc = d_bcData[s];
58
59 // if this is zero displacement condition, we do not apply displacement
60 if (bc.d_isDisplacementZero)
61 continue;
62
63 // check if we need to process this particle
64 if (!needToProcessParticle(particle->getId(), bc))
65 continue;
66
67 // get bounding box (quite possibly be generic)
68 auto reg_box = bc.d_regionGeomData.d_geom_p == nullptr ? std::pair<util::Point, util::Point>(util::Point(), util::Point()) : bc.d_regionGeomData.d_geom_p->box();
69
70 for (size_t i = 0; i < particle->getNumNodes(); i++) {
71
72 const auto x = particle->getXRefLocal(i);
73
74 double umax = bc.d_timeFnParams[0];
75 double du = 0.;
76 double dv = 0.;
77
78 auto box = reg_box;
79 if (!bc.d_isRegionActive) {
80 // get box from particle
81 box = particle->d_geom_p->box();
82 }
83
84 if (needToComputeDof(x, particle->getId(), bc)) {
85
86 // apply spatial function
87 if (bc.d_spatialFnType == "hat_x") {
88 umax = bc.d_spatialFnParams[0] *
89 util::hatFunction(x.d_x, box.first.d_x,
90 box.second.d_x);
91 } else if (bc.d_spatialFnType == "hat_y") {
92 umax = bc.d_spatialFnParams[0] *
93 util::hatFunction(x.d_y, box.first.d_y,
94 box.second.d_y);
95 } else if (bc.d_spatialFnType == "sin_x") {
96 double a = M_PI * bc.d_spatialFnParams[0];
97 umax = umax * std::sin(a * x.d_x);
98 } else if (bc.d_spatialFnType == "sin_y") {
99 double a = M_PI * bc.d_spatialFnParams[0];
100 umax = umax * std::sin(a * x.d_y);
101 } else if (bc.d_spatialFnType == "linear_x") {
102 double a = bc.d_spatialFnParams[0];
103 umax = umax * a * x.d_x;
104 } else if (bc.d_spatialFnType == "linear_y") {
105 double a = bc.d_spatialFnParams[0];
106 umax = umax * a * x.d_y;
107 }
108
109 // apply time function
110 if (bc.d_timeFnType == "constant")
111 du = umax;
112 else if (bc.d_timeFnType == "linear") {
113 du = umax * time;
114 dv = umax;
115 } else if (bc.d_timeFnType == "quadratic") {
116 du = umax * time + bc.d_timeFnParams[1] * time * time;
117 dv = umax + bc.d_timeFnParams[1] * time;
118 } else if (bc.d_timeFnType == "sin") {
119 double a = M_PI * bc.d_timeFnParams[1];
120 du = umax * std::sin(a * time);
121 dv = umax * a * std::cos(a * time);
122 }
123
124 auto u_i = util::Point();
125 auto v_i = util::Point();
126 for (auto d : bc.d_direction) {
127 u_i[d-1] = du;
128 v_i[d-1] = dv;
129 }
130
131 if (bc.d_timeFnType == "rotation") {
132 auto x0 = util::Point(bc.d_timeFnParams[1], bc.d_timeFnParams[2],
133 bc.d_timeFnParams[3]);
134 auto dx = x - x0;
135 auto r_x = util::rotate2D(
136 dx, bc.d_timeFnParams[0] * time);
137 auto dr_x = util::derRotate2D(
138 dx, bc.d_timeFnParams[0] * time);
139
140 u_i += r_x - dx;
141 v_i += bc.d_timeFnParams[0] * dr_x;
142 }
143
144 for (auto d : bc.d_direction) {
145 particle->setULocal(i, d-1, u_i[d-1]);
146 particle->setVLocal(i, d-1, v_i[d-1]);
147 auto xref = particle->getXRefLocal(i)[d-1];
148 particle->setXLocal(i, d-1, u_i[d-1] + xref);
149 }
150 } // if compute displacement
151 }
152 } // loop over bc sets
153}
std::vector< inp::BCBaseDeck > d_bcData
List of displacement bcs.
void apply(const double &time, particle::BaseParticle *particle)
Applies displacement boundary condition.
ParticleULoading(std::vector< inp::BCBaseDeck > &bc_data)
Constructor.
void setFixity(particle::BaseParticle *particle)
Sets fixity mask.
std::vector< bool > d_pZeroDisplacementApplied
Flag to indicate whether particles are fixed.
A class to store particle geometry, nodal discretization, and methods.
bool needToProcessParticle(size_t id, const inp::BCBaseDeck &bc)
Function that checks if given particle with id = id needs to be processed within boundary condition d...
bool needToComputeDof(const util::Point &x, size_t id, const inp::BCBaseDeck &bc)
Function that checks if we need to do computation at a given point x within a particle with id = id.
Collection of methods and data related to particle object.
Definition modelData.h:36
std::vector< double > rotate2D(const std::vector< double > &x, const double &theta)
Rotates a vector in xy-plane assuming ACW convention.
double hatFunction(const double &x, const double &x_min, const double &x_max)
Computes hat function at given point.
Definition function.cpp:27
util::Point derRotate2D(const util::Point &x, const double &theta)
Computes derivative of rotation wrt to time.
A structure to represent 3d vectors.
Definition point.h:30