PeriDEM 0.2.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
particleFLoading.cpp
Go to the documentation of this file.
1/*
2 * -------------------------------------------
3 * Copyright (c) 2021 - 2024 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 "particleFLoading.h"
14#include "util/function.h"
15#include "util/parallelUtil.h"
16#include <taskflow/taskflow/taskflow.hpp>
17#include <taskflow/taskflow/algorithm/for_each.hpp>
18
19namespace {
20
21bool isInList(const size_t &i, const std::vector<size_t> &list) {
22 for (const auto &l : list)
23 if (l == i)
24 return true;
25
26 return false;
27}
28
29} // namespace
30
32 std::vector<inp::PBCData> &bc_data) {
33
34 d_bcData = bc_data;
35}
36
38 // if there is a list, and if particle is not in the list, skip
39 bool skip_condition1 = (bc.d_selectionType == "particle"
40 || bc.d_selectionType == "region_with_include_list")
41 && !isInList(id, bc.d_pList);
42 // if there is an exclusion list, and if particle is in the list, skip
43 bool skip_condition2 = (bc.d_selectionType == "region_with_exclude_list")
44 && isInList(id, bc.d_pNotList);
45 // if there is a inclusion and an exclusion list,
46 // and if particle is either in the exclusion list or not in the inclusion list, skip
47 bool skip_condition3 = (bc.d_selectionType == "region_with_include_list_with_exclude_list")
48 && (isInList(id, bc.d_pNotList) ||
49 !isInList(id, bc.d_pList));
50
51 bool skip = skip_condition1 or skip_condition2 or skip_condition3;
52 return !skip;
53}
54
56 size_t id,
57 const inp::PBCData &bc) {
58
59 if (!bc.d_isRegionActive) {
60 if (bc.d_selectionType == "particle" &&
61 isInList(id, bc.d_pList))
62 return true;
63 }
64 else {
65 if (bc.d_selectionType == "region" && bc.d_regionGeomData.d_geom_p->isInside(x))
66 return true;
67 else if (bc.d_selectionType == "region_with_include_list" &&
68 bc.d_regionGeomData.d_geom_p->isInside(x) &&
69 isInList(id, bc.d_pList))
70 return true;
71 else if (bc.d_selectionType == "region_with_exclude_list" &&
72 bc.d_regionGeomData.d_geom_p->isInside(x) &&
73 !isInList(id, bc.d_pNotList))
74 return true;
75 else if (bc.d_selectionType == "region_with_include_list_with_exclude_list" &&
76 bc.d_regionGeomData.d_geom_p->isInside(x) &&
77 isInList(id, bc.d_pList) &&
78 !isInList(id, bc.d_pNotList))
79 return true;
80 }
81
82 return false;
83}
84
85void loading::ParticleFLoading::apply(const double &time,
87
88 for (size_t s = 0; s < d_bcData.size(); s++) {
89
90 // get alias for bc data
91 const auto &bc = d_bcData[s];
92
93 // check if we need to process this particle
94 if (!needToProcessParticle(particle->getId(), bc))
95 continue;
96
97 // get bounding box (quite possibly be generic)
98 auto reg_box = bc.d_regionGeomData.d_geom_p->box();
99
100 // for (size_t i = 0; i < particle->getNumNodes(); i++) {
101 tf::Executor executor(util::parallel::getNThreads());
102 tf::Taskflow taskflow;
103
104 taskflow.for_each_index(
105 (std::size_t) 0, particle->getNumNodes(), (std::size_t) 1,
106 [time, &particle, bc, reg_box, this](std::size_t i) {
107
108 const auto x = particle->getXRefLocal(i);
109 double fmax = 1.0;
110
111 auto box = reg_box;
112 if (!bc.d_isRegionActive) {
113 // get box from particle
114 box = particle->d_geom_p->box();
115 }
116
117 if (needToComputeDof(x, particle->getId(), bc)) {
118
119 // apply spatial function
120 if (bc.d_spatialFnType == "hat_x") {
121 fmax = bc.d_spatialFnParams[0] *
122 util::hatFunction(x.d_x, box.first.d_x,
123 box.second.d_x);
124 } else if (bc.d_spatialFnType == "hat_y") {
125 fmax = bc.d_spatialFnParams[0] *
126 util::hatFunction(x.d_y, box.first.d_y,
127 box.second.d_y);
128 } else if (bc.d_spatialFnType == "sin_x") {
129 double a = M_PI * bc.d_spatialFnParams[0];
130 fmax = bc.d_spatialFnParams[0] * std::sin(a * x.d_x);
131 } else if (bc.d_spatialFnType == "sin_y") {
132 double a = M_PI * bc.d_spatialFnParams[0];
133 fmax = bc.d_spatialFnParams[0] * std::sin(a * x.d_y);
134 } else if (bc.d_spatialFnType == "linear_x") {
135 double a = bc.d_spatialFnParams[0];
136 fmax = bc.d_spatialFnParams[0] * a * x.d_x;
137 } else if (bc.d_spatialFnType == "linear_y") {
138 double a = bc.d_spatialFnParams[0];
139 fmax = bc.d_spatialFnParams[0] * a * x.d_y;
140 }
141
142 // apply time function
143 if (bc.d_timeFnType == "linear")
144 fmax *= time;
145 else if (bc.d_timeFnType == "linear_step")
146 fmax *= util::linearStepFunc(time, bc.d_timeFnParams[1],
147 bc.d_timeFnParams[2]);
148 else if (bc.d_timeFnType == "linear_slow_fast") {
149 if (util::isGreater(time, bc.d_timeFnParams[1]))
150 fmax *= bc.d_timeFnParams[3] * time;
151 else
152 fmax *= bc.d_timeFnParams[2] * time;
153 } else if (bc.d_timeFnType == "sin") {
154 double a = M_PI * bc.d_timeFnParams[1];
155 fmax *= std::sin(a * time);
156 }
157
158 // multiply by the slope
159 fmax *= bc.d_timeFnParams[0];
160
161 auto force_i = util::Point();
162 for (auto d : bc.d_direction) {
163 force_i[d-1] = fmax;
164 }
165
166 // add force
167 particle->addFLocal(i, force_i);
168 } // if compute force
169 }
170 ); // for_each
171
172 executor.run(taskflow).get();
173 } // loop over bc sets
174}
bool needToComputeDof(const util::Point &x, size_t id, const inp::PBCData &bc)
Function that checks if we need to do computation at a given point x within a particle with id = id.
void apply(const double &time, particle::BaseParticle *particle)
Applies force boundary condition.
ParticleFLoading(std::vector< inp::PBCData > &bc_data)
Constructor.
bool needToProcessParticle(size_t id, const inp::PBCData &bc)
Function that checks if given particle with id = id needs to be processed within boundary condition d...
std::vector< inp::PBCData > d_bcData
List of displacement bcs.
A class to store particle geometry, nodal discretization, and methods.
bool isInList(const size_t &i, const std::vector< size_t > &list)
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.
Definition function.cpp:15
double linearStepFunc(const double &x, const double &x1, const double &x2)
Compute linear step function.
Definition function.cpp:62
User-input data for particle neighbor search.
Definition pBCData.h:24
std::vector< size_t > d_pList
List of particles (if any)
Definition pBCData.h:48
std::string d_selectionType
Method for applying force e.g.
Definition pBCData.h:35
util::geometry::GeomData d_regionGeomData
Region geometry (if any)
Definition pBCData.h:45
std::vector< size_t > d_pNotList
List of particles to not include (if any)
Definition pBCData.h:51
bool d_isRegionActive
Flag that indicates if region-based application of boundary condition is active. So cases of 'region'...
Definition pBCData.h:42
A structure to represent 3d vectors.
Definition point.h:30
std::shared_ptr< util::geometry::GeomObject > d_geom_p
Zone geometry.