Tissue Forge C++ 0.2.1
Interactive, particle-based physics, chemistry and biology modeling and simulation environment
Loading...
Searching...
No Matches
tf_boundary_eval.h
1/*******************************************************************************
2 * This file is part of mdcore.
3 * Copyright (c) 2022-2024 T.J. Sego
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 ******************************************************************************/
19
20#ifndef _MDCORE_SOURCE_TF_BOUNDARY_EVAL_H_
21#define _MDCORE_SOURCE_TF_BOUNDARY_EVAL_H_
22
23#include "tfParticle.h"
24#include "tfPotential.h"
25#include "tfSpace_cell.h"
26#include "tfEngine.h"
27#include "tf_dpd_eval.h"
28#include "tf_potential_eval.h"
29
30#include <iostream>
31
32
33// velocity boundary conditions:
34//
35// r_new = r_old + 2 d n_w,
36// where d is distance particle penetrated into wall, and
37// n_w is normal vector into simulation domain.
38//
39// v_new = 2 U_wall - v_old
40// where U_wall is wall velocity.
41
42
43namespace TissueForge {
44
45
46 TF_ALWAYS_INLINE bool apply_update_pos_vel(Particle *p, space_cell *c, const FPTYPE* h, int* delta) {
47
48 #define ENFORCE_FREESLIP_LOW(i) \
49 p->position[i] = std::max<FPTYPE>(-p->position[i] * restitution, FPTYPE_ZERO); \
50 p->velocity[i] *= -restitution; \
51 enforced = true; \
52
53 #define ENFORCE_FREESLIP_HIGH(i) \
54 p->position[i] = c->dim[i] - std::max<FPTYPE>((p->position[i] - c->dim[i]) * restitution, FPTYPE_EPSILON); \
55 p->velocity[i] *= -restitution; \
56 enforced = true; \
57
58 #define ENFORCE_VELOCITY_LOW(i, bc) \
59 p->position[i] = std::max<FPTYPE>(-p->position[i] * bc.restore, FPTYPE_ZERO); \
60 p->velocity = bc.velocity - ((p->velocity - bc.velocity) * bc.restore); \
61 enforced = true; \
62
63 #define ENFORCE_VELOCITY_HIGH(i, bc) \
64 p->position[i] = c->dim[i] - std::max<FPTYPE>((p->position[i] - c->dim[i]) * bc.restore, FPTYPE_EPSILON); \
65 p->velocity = bc.velocity - ((p->velocity - bc.velocity) * bc.restore); \
66 enforced = true; \
67
68 static const BoundaryConditions *bc = &_Engine.boundary_conditions;
69
70 static const FPTYPE restitution = 1.0;
71
72 /* Enforce particle position to be within the given boundary */
73 bool enforced = false;
74
75 if(c->flags & cell_active_left && p->x[0] <= 0) {
76 if(bc->left.kind & BOUNDARY_FREESLIP) {
77 ENFORCE_FREESLIP_LOW(0);
78 }
79 else if(bc->left.kind & BOUNDARY_VELOCITY) {
80 ENFORCE_VELOCITY_LOW(0, bc->left);
81 }
82 }
83
84 if(c->flags & cell_active_right && p->x[0] >= c->dim[0]) {
85 if(bc->right.kind & BOUNDARY_FREESLIP) {
86 ENFORCE_FREESLIP_HIGH(0);
87 }
88 else if(bc->right.kind & BOUNDARY_VELOCITY) {
89 ENFORCE_VELOCITY_HIGH(0, bc->right);
90 }
91 }
92
93 if(c->flags & cell_active_front && p->x[1] <= 0) {
94 if(bc->front.kind & BOUNDARY_FREESLIP) {
95 ENFORCE_FREESLIP_LOW(1);
96 }
97 else if(bc->front.kind & BOUNDARY_VELOCITY) {
98 ENFORCE_VELOCITY_LOW(1, bc->front);
99 }
100 }
101
102 if(c->flags & cell_active_back && p->x[1] >= c->dim[1]) {
103 if(bc->back.kind & BOUNDARY_FREESLIP) {
104 ENFORCE_FREESLIP_HIGH(1);
105 }
106 else if(bc->back.kind & BOUNDARY_VELOCITY) {
107 ENFORCE_VELOCITY_HIGH(1, bc->back);
108 }
109 }
110
111 if(c->flags & cell_active_bottom && p->x[2] <= 0) {
112 if(bc->bottom.kind & BOUNDARY_FREESLIP) {
113 ENFORCE_FREESLIP_LOW(2);
114 }
115 else if(bc->bottom.kind & BOUNDARY_VELOCITY) {
116 ENFORCE_VELOCITY_LOW(2, bc->bottom);
117 }
118 }
119
120 if(c->flags & cell_active_top && p->x[2] >= c->dim[2]) {
121 if(bc->top.kind & BOUNDARY_FREESLIP) {
122 ENFORCE_FREESLIP_HIGH(2);
123 }
124 else if(bc->top.kind & BOUNDARY_VELOCITY) {
125 ENFORCE_VELOCITY_HIGH(2, bc->top);
126 }
127 }
128
129 if(enforced) {
130 for (int k = 0 ; k < 3 ; k++ ) {
131 delta[k] = std::isgreaterequal( p->x[k], h[k] ) - std::isless( p->x[k], 0.0 );
132 }
133 }
134
135 return delta[0] == 0 && delta[1] == 0 && delta[2] == 0;
136 };
137
138 TF_ALWAYS_INLINE bool boundary_potential_eval_ex(const struct space_cell *cell,
139 Potential *pot, Particle *part, BoundaryCondition *bc,
140 FPTYPE *dx, FPTYPE r2, FPTYPE *epot);
141
142 static bool _boundary_potential_eval_ex(const struct space_cell *cell,
143 Potential *pot, Particle *part, BoundaryCondition *bc,
144 FPTYPE *dx, FPTYPE r2, FPTYPE *epot)
145 {
146 return boundary_potential_eval_ex(cell, pot, part, bc, dx, r2, epot);
147 }
148
149 bool boundary_potential_eval_ex(const struct space_cell *cell,
150 Potential *pot, Particle *part, BoundaryCondition *bc,
151 FPTYPE *dx, FPTYPE r2, FPTYPE *epot)
152 {
153 FPTYPE e = 0;
154 bool result = false;
155
156 if(pot->kind == POTENTIAL_KIND_DPD) {
157 /* update the forces if part in range */
158 if (dpd_boundary_eval((DPDPotential*)pot, space_cell_gaussian(cell->id), part, bc->radius, bc->velocity.data(), dx, r2, &e)) {
159 /* tabulate the energy */
160 *epot += e;
161 result = true;
162 }
163 }
164 else if(pot->kind == POTENTIAL_KIND_BYPARTICLES) {
165 FPTYPE fv[3] = {0., 0., 0.};
166
167 pot->eval_bypart(pot, part, dx, r2, &e, fv);
168
169 for (int k = 0 ; k < 3 ; k++ ) {
170 part->f[k] += fv[k];
171 }
172
173 /* tabulate the energy */
174 *epot += e;
175 result = true;
176 }
177 else if(pot->kind == POTENTIAL_KIND_COMBINATION) {
178 if(pot->flags & POTENTIAL_SUM) {
179 _boundary_potential_eval_ex(cell, pot->pca, part, bc, dx, r2, epot);
180 _boundary_potential_eval_ex(cell, pot->pcb, part, bc, dx, r2, epot);
181 result = true;
182 }
183 }
184 else {
185 FPTYPE f;
186
187 /* update the forces if part in range */
188 if (potential_eval_ex(pot, part->radius, bc->radius, r2, &e, &f )) {
189
190 for (int k = 0 ; k < 3 ; k++ ) {
191 FPTYPE w = f * dx[k];
192 part->f[k] -= w;
193 }
194
195 /* tabulate the energy */
196 *epot += e;
197 result = true;
198 }
199 }
200 return result;
201 }
202
203
204 TF_ALWAYS_INLINE bool boundary_eval(BoundaryConditions *bc, const struct space_cell *cell, Particle *part, FPTYPE *epot ) {
205
206 Potential *pot;
207 FPTYPE r;
208 bool result = false;
209
210 FPTYPE dx[3] = {0.f, 0.f, 0.f};
211
212 if((cell->flags & cell_active_left) &&
213 (pot = bc->left.potenntials[part->typeId]) &&
214 ((r = part->x[0]) <= pot->b)) {
215 dx[0] = r;
216 result |= boundary_potential_eval_ex(cell, pot, part, &bc->left, dx, r*r, epot);
217 }
218
219 if((cell->flags & cell_active_right) &&
220 (pot = bc->right.potenntials[part->typeId]) &&
221 ((r = cell->dim[0] - part->x[0]) <= pot->b)) {
222 dx[0] = -r;
223 result |= boundary_potential_eval_ex(cell, pot, part, &bc->right, dx, r*r, epot);
224 }
225
226 if((cell->flags & cell_active_front) &&
227 (pot = bc->front.potenntials[part->typeId]) &&
228 ((r = part->x[1]) <= pot->b)) {
229 dx[1] = r;
230 result |= boundary_potential_eval_ex(cell, pot, part, &bc->front, dx, r*r, epot);
231 }
232
233 if((cell->flags & cell_active_back) &&
234 (pot = bc->back.potenntials[part->typeId]) &&
235 ((r = cell->dim[1] - part->x[1]) <= pot->b)) {
236 dx[1] = -r;
237 result |= boundary_potential_eval_ex(cell, pot, part, &bc->back, dx, r*r, epot);
238 }
239
240 if((cell->flags & cell_active_bottom) &&
241 (pot = bc->bottom.potenntials[part->typeId]) &&
242 ((r = part->x[2]) <= pot->b)) {
243 dx[2] = r;
244 result |= boundary_potential_eval_ex(cell, pot, part, &bc->bottom, dx, r*r, epot);
245 }
246
247 if((cell->flags & cell_active_top) &&
248 (pot = bc->top.potenntials[part->typeId]) &&
249 ((r = cell->dim[2] - part->x[2]) <= pot->b)) {
250 dx[2] = -r;
251 result |= boundary_potential_eval_ex(cell, pot, part, &bc->top, dx, r*r, epot);
252 }
253 return result;
254 }
255
256};
257
258#endif // _MDCORE_SOURCE_TF_BOUNDARY_EVAL_H_
Include Python header, disable linking to pythonX_d.lib on Windows in debug mode.
Definition tfAngleConfig.h:26
FPTYPE space_cell_gaussian(int cell_id)
struct TissueForge::space_cell space_cell
the space_cell structure
engine _Engine