Program Listing for File computegeometry.hpp#
↰ Return to documentation for file (pymembrane/cppmodule/src/mesh/computegeometry.hpp
)
#ifndef __computegeometry_hpp__
#define __computegeometry_hpp__
#pragma once
#include "../types/globaltypes.hpp"
#include "../box/pbc.hpp"
namespace pymemb
{
inline
real3 unit_vector(const real3 &v)
{
real norm = sqrt(vdot(v,v));
real3 v_unit = v;
v_unit.x/=norm;
v_unit.y/=norm;
v_unit.z/=norm;
return(v_unit);
}
inline
real3 vector_cross(const real3 &v1, const real3 &v2)
{
real3 v;
vcross(v, v1, v2);
return v;
}
inline
real3 vector_sum(const real3 &v1, const real3 &v2)
{
real3 v;
v.x = v1.x + v2.x;
v.y = v1.y + v2.y;
v.z = v1.z + v2.z;
return v;
}
inline
real3 vector_subtract(const real3 &v1, const real3 &v2)
{
real3 v;
v.x = v1.x - v2.x;
v.y = v1.y - v2.y;
v.z = v1.z - v2.z;
return v;
}
inline
real3 vector_subtract(const real3 &v1, const real3 &v2, const BoxType &box)
{
return (pymemb::minimum_image(v2, v1, box));
}
inline
void compute_form_factor_triangle(real *_metric, const real3 &r1, const real3 &r2, const real3 &r3, const BoxType &box)
{
real3 v12, v13;
v12 = pymemb::minimum_image(r1, r2, box);
v13 = pymemb::minimum_image(r1, r3, box);
_metric[0] = vdot(v12, v12);
_metric[1] = vdot(v12, v13);
_metric[2] = vdot(v13, v13);
}
inline
void compute_form_factor_triangle(real *_metric, const real3 &r1, const real3 &r2, const real3 &r3)
{
real3 v12, v13;
vsub(v12, r2, r1);
vsub(v13, r3, r1);
_metric[0] = vdot(v12, v12);
_metric[1] = vdot(v12, v13);
_metric[2] = vdot(v13, v13);
}
inline
real3 compute_normal_triangle(const real3 &r1, const real3 &r2, const real3 &r3, const BoxType &box)
{
real3 normal, v12, v13;
v12 = pymemb::minimum_image(r1, r2, box);
v13 = pymemb::minimum_image(r1, r3, box);
vcross(normal, v12, v13);
return normal;
}
inline
real3 compute_normal_triangle(const real3 &r1, const real3 &r2, const real3 &r3)
{
real3 normal, v12, v13;
vsub(v12, r2, r1);
vsub(v13, r3, r1);
vcross(normal, v12, v13);
return normal;
}
inline
real3 compute_normal_triangle_unit(const real3 &r1, const real3 &r2, const real3 &r3, const BoxType &box)
{
return (unit_vector(compute_normal_triangle(r1, r2, r3, box)));
}
inline
real3 compute_normal_triangle_unit(const real3 &r1, const real3 &r2, const real3 &r3)
{
return (unit_vector(compute_normal_triangle(r1, r2, r3)));
}
inline
real compute_area_triangle_from_vertex(const real3 &r1, const real3 &r2, const real3 &r3, const BoxType &box)
{
real3 normal = compute_normal_triangle(r1, r2, r3, box);
return (0.5 * sqrt(vdot(normal, normal)));
}
inline
real compute_area_triangle_from_vertex(const real3 &r1, const real3 &r2, const real3 &r3)
{
real3 normal = compute_normal_triangle(r1, r2, r3);
return (0.5 * sqrt(vdot(normal, normal)));
}
inline
real compute_area_triangle_from_metric(const real *_metric)
{
return (0.5 * sqrt(_metric[0] * _metric[2] - _metric[1] * _metric[1]));
}
inline
real compute_angle_vertex(const real3 &r1, const real3 &r2, const real3 &r3, const BoxType &box)
{
real3 v12, v13;
v12 = pymemb::minimum_image(r1, r2, box);
v13 = pymemb::minimum_image(r1, r3, box);
real angle = acos(vdot(v12, v13) / sqrt(vdot(v12, v12) * vdot(v13, v13)));
return angle;
}
inline
real compute_angle_vertex(const real3 &r1, const real3 &r2, const real3 &r3)
{
real3 v12, v13;
vsub(v12, r2, r1);
vsub(v13, r3, r1);
real angle = acos(vdot(v12, v13) / sqrt(vdot(v12, v12) * vdot(v13, v13)));
return angle;
}
inline bool is_equiangular(const real3 &r0, const real3 &r1, const real3 &r2, const real3 &r3, const BoxType &box)
{
// We use the notation of Brakke's paper
// a; edge length
// b, c; lengths of other two edges of triangle 1
// d, e; lengths of other two edges of triangle 2
auto r02 = vector_subtract(r2, r0, box);
auto a2 = vdot(r02, r02);
auto r03 = vector_subtract(r3, r0, box);
auto b2 = vdot(r03, r03);
auto r23 = vector_subtract(r3, r2, box);
auto c2 = vdot(r23, r23);
auto r01 = vector_subtract(r1, r0, box);
auto d2 = vdot(r01, r01);
auto r21 = vector_subtract(r1, r2, box);
auto e2 = vdot(r21, r21);
if ((b2 + c2 - a2)/(sqrt(b2*c2)) + (d2 + e2 - a2)/sqrt(d2*e2) < 0.0)
return false;
else
return true;
}
inline void arrange_vertices_by_smallest(int& v1, int& v2, int& v3)
{
int _v1, _v2, _v3;
if (v1 < v2 && v1 < v3)
{
_v1 = v1;
_v2 = v2;
_v3 = v3;
}
else if (v2 < v1 && v2 < v3)
{
_v1 = v2;
_v2 = v3;
_v3 = v1;
}
else
{
_v1 = v3;
_v2 = v1;
_v3 = v2;
}
v1 = _v1;
v2 = _v2;
v3 = _v3;
}
inline
void compute_matrix_F(real *F, const real *g_reference_inv, const real *g_now)
{
/*
_ _ _ _ _ _
| g_reference_inv[0] g_reference_inv[1] | | g_now[0] g_now[1] | | 1 0 |
F = | | x | | - | |
|_ g_reference_inv[1] g_reference_inv[2] _| |_ g_now[1] g_now[2] _| |_ 0 1 _|
*/
F[0] = g_reference_inv[0] * g_now[0] + g_reference_inv[1] * g_now[1] - 1.0; //F11
F[1] = g_reference_inv[0] * g_now[1] + g_reference_inv[1] * g_now[2]; //F12
F[2] = g_reference_inv[1] * g_now[0] + g_reference_inv[2] * g_now[1]; //F21
F[3] = g_reference_inv[1] * g_now[1] + g_reference_inv[2] * g_now[2] - 1.0; //F22
}
inline
real3 cmassT(const real3 &r1, const real3 &r2, const real3 &r3)
{
real3 vcm;
vcm.x = (r1.x + r2.x + r3.x) / 3.0;
vcm.y = (r1.y + r2.y + r3.y) / 3.0;
vcm.z = (r1.z + r2.z + r3.z) / 3.0;
return vcm;
}
inline
void RefMatrixFromCartesian(const real theta, const real *__restrict__ grefCart, real *grefCylin)
{
real a = sin(theta);
real b = cos(theta);
real grr = b * (b * grefCart[0] + a * grefCart[1]) + a * (b * grefCart[1] + a * grefCart[2]); //grr
real grt = b * (b * grefCart[1] + a * grefCart[2]) - a * (b * grefCart[0] + a * grefCart[1]); //grt
real gtt = b * (b * grefCart[2] - a * grefCart[1]) - a * (b * grefCart[1] - a * grefCart[0]); //gtt
grefCylin[0] = grr;
grefCylin[1] = grt;
grefCylin[2] = gtt;
}
inline
void RefMatrixFromCylindrical(const real theta, const real *__restrict__ grefCylin, real *grefCart)
{
real a = sin(theta);
real b = cos(theta);
real g11 = b * (b * grefCylin[0] - a * grefCylin[1]) - a * (b * grefCylin[1] - a * grefCylin[2]);
real g12 = a * (b * grefCylin[0] - a * grefCylin[1]) + b * (b * grefCylin[1] - a * grefCylin[2]);
//real g21 = b*(a*grefCylin[0] + b*grefCylin[1]) - a*(a*grefCylin[1] + b*grefCylin[2]);
real g22 = a * (a * grefCylin[0] + b * grefCylin[1]) + b * (a * grefCylin[1] + b * grefCylin[2]);
grefCart[0] = g11;
grefCart[1] = g12;
grefCart[2] = g22;
}
inline bool need_wrapping(const real3 &r1, const real3 &r2, const BoxType &box)
{
real3 rij;
vsub(rij, r2, r1);
bool _need_wrapping = false;
if (box.periodic.x)
{
if (rij.x > box.Lhi.x)
_need_wrapping = true;
else if (rij.x < box.Llo.x)
_need_wrapping = true;
}
if (box.periodic.y)
{
if (rij.y > box.Lhi.y)
_need_wrapping = true;
else if (rij.y < box.Llo.y)
_need_wrapping = true;
}
if (box.periodic.z)
{
if (rij.z > box.Lhi.z)
_need_wrapping = true;
else if (rij.z < box.Llo.z)
_need_wrapping = true;
}
return _need_wrapping;
}
}
#endif