1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
/////////////////////////////////////////////////////////////
// //
// Copyright (c) 2003-2011 by The University of Queensland //
// Earth Systems Science Computational Centre (ESSCC) //
// http://www.uq.edu.au/esscc //
// //
// Primary Business: Brisbane, Queensland, Australia //
// Licensed under the Open Software License version 3.0 //
// http://www.opensource.org/licenses/osl-3.0.php //
// //
/////////////////////////////////////////////////////////////
#include "Foundation/console.h"
#include "Geometry/Edge2D.h"
// --- System includes
#include <cmath>
using std::fabs;
using std::endl;
using std::make_pair;
/*!
construct Edge from corner coordinates. Make sure Z=0 for all corners
\param id0 id of the first corner
\param id1 id of the 2nd corner
\param v0 first corner
\param v1 second corner
\param ed_id edge id
\param tag edge tag
*/
Edge2D::Edge2D(int id0,int id1,const Vec3& v0,const Vec3& v1,int ed_id,int tag) : AEdge(v0,v1)
{
m_id0=id0;
m_id1=id1;
m_p0.Z()=0.0;
m_p1.Z()=0.0;
m_edge_id=ed_id;
m_tag=tag;
m_force=Vec3(0.0,0.0,0.0);
m_normal=cross(Vec3(0.0,0.0,1.0),m_p1-m_p0).unit();
}
/*!
Move one of the corners. The identifier for the corner is the global node id.
If the node with the id is not in the edge do nothing.
\param id the global id of the node to be moved
\param d the amount of movement
*/
void Edge2D::moveNode(int id,const Vec3& d)
{
if(id==m_id0){
m_p0+=d;
m_normal=cross(Vec3(0.0,0.0,1.0),m_p1-m_p0).unit();
} else if (id==m_id1) {
m_p1+=d;
m_normal=cross(Vec3(0.0,0.0,1.0),m_p1-m_p0).unit();
}
}
/*!
convert point in local coords to global coords
\param p the point in local coords
*/
Vec3 Edge2D::toGlobal(const Vec3& p)
{
Vec3 res;
res=m_p0+(m_p1-m_p0)*p.X()+m_normal*p.Y();
return res;
}
/*!
convert point in global coords into local (x,y,0) coords
\param p the point in global coords
*/
Vec3 Edge2D::toLocal(const Vec3& p)
{
double x;
double y;
x=((p-m_p0)*(m_p1-m_p0))/(m_p1-m_p0).norm2();
y=(p-m_p0)*m_normal;
return Vec3(x,y,0.0);
}
/*!
Get the Edge2D member function which returns a vector field of a given name. Returns
NULL if a field with that name doesn't exist.
\param name the name of the field
*/
Edge2D::VectorFieldFunction Edge2D::getVectorFieldFunction(const string& name)
{
Edge2D::VectorFieldFunction f;
if(name=="force"){
f=&Edge2D::getForce;
} if(name=="forcedensity"){
f=&Edge2D::getForceDensity;
} else {
f=NULL;
cerr << "ERROR - invalid name for edge vector access function" << endl;
}
return f;
}
/*!
Get the Edge2D member function which returns a scalar field of a given name. Returns
NULL if a field with that name doesn't exist.
\param name the name of the field
*/
Edge2D::ScalarFieldFunction Edge2D::getScalarFieldFunction(const string& name)
{
Edge2D::ScalarFieldFunction f;
if(name=="pressure"){
f=&Edge2D::getPressure;
} else {
f=NULL;
cerr << "ERROR - invalid name for edge scalar access function" << endl;
}
return f;
}
/*!
Get pressure on the edge from interaction forces
*/
double Edge2D::getPressure() const
{
// calculate normal force
double F_n=m_force*m_normal;
// retrun force per area (length)
return F_n/(m_p1-m_p0).norm();
}
/*!
output Edge2D to ostream
*/
ostream& operator<<(ostream& ost,const Edge2D& T)
{
ost << "Edge2D: (" << T.m_p0 << ") - (" << T.m_p1 << ") Normal: (" << T.m_normal << ")";
return ost;
}
/*!
output Edge2D to cout
*/
void Edge2D::print()
{
cout << "Edge2D: (" << m_p0 << ") - (" << m_p1 << ") Normal: (" << m_normal << ")";
}
|