1#ifndef VOLUMEMEMBRANE_HPP
2#define VOLUMEMEMBRANE_HPP
6#include "cellcellconnectionmanager.hpp"
11#define FOUR_THIRD_PI 4.1887902047863909846168578443726705
13#define MIN_MODEL_CONNECTION_SIMILARITY 0.8
20 template <
typename C>
struct SFINAE {
22 C, double(C *,
double,
double), float(C *,
float,
float),
23 double(
const C *,
double,
double), float(
const C *,
float,
float)>::value;
25 has_getAdhesionWith_signatures<C, double(C *), float(C *), double(
const C *),
26 float(
const C *)>::value;
30 template <
typename T =
double>
31 static inline typename enable_if<hasPreciseAdhesion, T>::type
getAdhesion(
33 const auto B = a->getOrientation();
34 bool zNeg = ABnorm.
dot(B.X.cross(B.Y)) < 0;
35 double phi =
acos(ABnorm.
dot(B.Y));
36 double teta = zNeg ?
acos(ABnorm.
dot(B.X)) : M_PI * 2.0 -
acos(ABnorm.
dot(B.X));
37 return a->getAdhesionWith(b, teta, phi);
40 template <
typename T = double,
typename... Whatever>
41 static inline typename enable_if<!hasPreciseAdhesion && hasAdhesion, T>::type
43 return a->getAdhesionWith(b);
46 template <
typename T = double,
typename... Whatever>
48 typename enable_if<!hasPreciseAdhesion && !hasAdhesion, T>::type
getAdhesion(
55 using CCCM = CellCellConnectionManager_map<Cell, ContactSurface<Cell>>;
126 Cell *closestCell =
nullptr;
128 for (
auto &cc :
cccm.cellConnections) {
129 auto con = CCCM::getConnection(cc);
130 auto normal =
cell == con->cells.first ? -con->normal : con->normal;
131 double dot = normal.dot(d);
133 const auto &midpoint =
134 cell == con->cells.first ? con->midpoint.first : con->midpoint.second;
135 double l = -midpoint / dot;
136 if (l < closestDist) {
138 closestCell = con->cells.first ==
cell ? con->cells.second : con->cells.first;
142 return {closestCell, closestDist};
165 double volumeLoss = 0;
167 for (
auto &cc :
cccm.cellConnections) {
168 auto con = CCCM::getConnection(cc);
170 cell == con->cells.first ? con->midpoint.first : con->midpoint.second;
172 volumeLoss += (M_PI * h / 6.0) * (3.0 * con->sqradius + h * h);
184 double surfaceLoss = 0;
185 for (
auto &cc :
cccm.cellConnections) {
186 auto con = CCCM::getConnection(cc);
188 cell == con->cells.first ? con->midpoint.first : con->midpoint.second;
194 const double minArea =
228 cell->receiveTorque(-
cell->getAngularVelocity() * 50.0);
229 Integrator::updatePosition(*
cell, dt);
230 Integrator::updateOrientation(*
cell, dt);
231 cell->markAsNotTested();
249 template <
typename C =
Cell,
typename... T>
254 template <
typename SpacePartition>
257 SpacePartition &grid) {
260 for (
const auto &c : cells) grid.insert(c);
261 auto gridCells = grid.getThreadSafeGrid();
262 for (
auto &batch : gridCells) {
263 for (
size_t i = 0; i < batch.size(); ++i) {
264 for (
size_t j = 0; j < batch[i].size(); ++j) {
265 for (
size_t k = j + 1; k < batch[i].size(); ++k) {
267 Vec AB = op.second->position - op.first->position;
269 if (sqDistance <
pow(op.first->getConstMembrane().dynamicRadius +
270 op.second->getConstMembrane().dynamicRadius,
272 if (!CCCM::areConnected(op.first, op.second) &&
273 !
isInVector(op, newConnections) && op.first != op.second) {
274 double dist =
sqrt(sqDistance);
276 auto d0 = op.first->getConstMembrane().getPreciseMembraneDistance(dir);
277 auto d1 = op.second->getConstMembrane().getPreciseMembraneDistance(-dir);
278 if (dist < 0.99999999 * (d0 + d1)) {
287 for (
const auto &nc : newConnections) {
288 CCCM::createConnection(cellCellConnections, nc,
297 for (
auto &cc : concon) {
300 if (con->area <= 0) {
305 CCCM::disconnect(concon, c->cells.first, c->cells.second, c);
311 auto cop = c0->membrane.cccm.cellConnections;
312 for (
auto &cc : cop) {
313 CCCM::disconnect(con, cc->cells.first, cc->cells.second, cc);
PrimoCell< CellBody > Cell
general purpose 3D vector/point class.
double sqlength() const
compute the square length of the current vector (faster than length)
static Vector3D zero()
constructs a zero vector
double dot(const Vector3D &v) const
dot product calculation
pair< Cell *, double > getConnectedCellAndMembraneDistance(const Vec &d) const
void setIncompressibility(double i)
static const bool forcesOnMembrane
void updatePositionsAndOrientations(double dt)
double getMomentOfInertia() const
CellCellConnectionManager_map< Cell, ContactSurface< Cell > > CCCM
double getBoundingBoxRadius() const
double getVolumeVariation() const
double getDynamicRadius() const
double getPressure() const
static double getAdhesion(T &&... t)
double getCurrentArea() const
double getPreciseMembraneDistance(const Vec &d) const
void setStiffness(double k)
double getBaseRadius() const
static void checkForCellCellConnections(vector< Cell * > &cells, CellCellConnectionContainer &cellCellConnections, SpacePartition &grid)
double getRestVolume() const
static void updateCellCellConnections(CellCellConnectionContainer &concon, double dt)
VolumeMembrane(Cell *c, const VolumeMembrane &sm)
double getDeducedRadius() const
double getCurrentVolume() const
static void disconnectAndDeleteAllConnections(Cell *c0, CellCellConnectionContainer &con)
void setRadiusRatio(double r)
double getRestRadius() const
double getRestArea() const
CREATE_METHOD_CHECKS(getAdhesionWith)
typename CCCM::CellCellConnectionContainer CellCellConnectionContainer
Cell * getConnectedCell(const Vec &d) const
void computeAreaAndDeduceRadius()
CCCM & getCellCellConnectionManager()
static constexpr double MAX_DYN_RADIUS_RATIO
typename CCCM::ConnectionType CellCellConnectionType
double getBaseVolume() const
void computeCurrentVolume()
void setBaseRadius(double r)
double getSqRestRadius() const
double getRestMomentOfInertia() const
double getStiffness() const
Represents a cell in the simulation.
A simple vector class template.
void push_back(const T &value)
Adds an element to the end of the vector.
void clear()
Clears the contents of the vector.
this file contains various miscellanious utility functions & helpers *
bool isInVector(const T &elem, const std::vector< T > &vec)
ordered_pair< T * > make_ordered_cell_pair(T *a, T *b)
double cbrt(double x)
Computes the cube root of a number.
double acos(double x)
Computes the arc cosine of a number.
double sqrt(double x)
Computes the square root of a number.
double pow(double base, double exponent)
Computes the power of a number.
static constexpr double DEFAULT_CELL_RADIUS
static constexpr bool hasPreciseAdhesion
static enable_if< hasPreciseAdhesion, T >::type getAdhesion(const Cell *a, const Cell *b, const Vec &ABnorm)
static enable_if<!hasPreciseAdhesion &&!hasAdhesion, T >::type getAdhesion(Whatever...)
static constexpr bool hasAdhesion
static enable_if<!hasPreciseAdhesion &&hasAdhesion, T >::type getAdhesion(const Cell *a, const Cell *b, Whatever...)