37 #include "AbstractTetrahedralElement.hpp"
46 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
51 EXCEPTION(
"Attempting to Refresh a deleted element");
53 for (
unsigned i=0; i<SPACE_DIM; i++)
55 for (
unsigned j=0; j!=ELEMENT_DIM; j++)
57 rJacobian(i,j) = this->GetNodeLocation(j+1,i) - this->GetNodeLocation(0,i);
62 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
67 unsigned num_vectices = ELEMENT_DIM+1;
71 if (SPACE_DIM == ELEMENT_DIM)
75 c_matrix<double, SPACE_DIM, ELEMENT_DIM> jacobian;
85 this->
mNodes[num_vectices-1] = rNodes[num_vectices-2];
86 this->
mNodes[num_vectices-2] = rNodes[num_vectices-1];
97 c_vector<double, SPACE_DIM> weighted_direction;
103 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
108 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
112 assert(ELEMENT_DIM <= SPACE_DIM);
113 RefreshJacobian(rJacobian);
117 if (rJacobianDeterminant <= DBL_EPSILON)
119 std::stringstream message;
120 message <<
"Jacobian determinant is non-positive: "
121 <<
"determinant = " << rJacobianDeterminant
122 <<
" for element " << this->mIndex <<
" (" << ELEMENT_DIM
123 <<
"D element in " << SPACE_DIM <<
"D space). Nodes are at:" << std::endl;
125 for (
unsigned local_node_index=0u; local_node_index != ELEMENT_DIM+1; local_node_index++)
127 c_vector<double, SPACE_DIM> location = this->GetNodeLocation(local_node_index);
128 message <<
"Node " << this->GetNodeGlobalIndex(local_node_index) <<
":\t";
130 for (
unsigned i=0; i<SPACE_DIM; i++)
132 message << location[i];
133 if (i==SPACE_DIM - 1u)
135 message << std::endl;
148 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
152 if (ELEMENT_DIM >= SPACE_DIM)
154 assert(ELEMENT_DIM == SPACE_DIM);
155 EXCEPTION(
"WeightedDirection undefined for fully dimensional element");
158 c_matrix<double, SPACE_DIM, ELEMENT_DIM> jacobian;
159 RefreshJacobian(jacobian);
176 rWeightedDirection=matrix_column<c_matrix<double,SPACE_DIM,ELEMENT_DIM> >(jacobian, 0);
180 assert(SPACE_DIM == 3);
188 rJacobianDeterminant = norm_2(rWeightedDirection);
190 if (rJacobianDeterminant < DBL_EPSILON)
192 EXCEPTION(
"Jacobian determinant is zero");
197 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
200 if (ELEMENT_DIM == 1 && SPACE_DIM == 3)
202 EXCEPTION(
"Don't have enough information to calculate a normal vector");
204 c_vector<double, SPACE_DIM> normal;
206 CalculateWeightedDirection(normal, determinant);
207 normal /= determinant;
208 if (ELEMENT_DIM == 1)
211 double x = normal[0];
212 normal[0] = normal[1];
218 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
221 c_vector<double, SPACE_DIM> centroid = zero_vector<double>(SPACE_DIM);
222 for (
unsigned i=0; i<=ELEMENT_DIM; i++)
224 centroid += this->mNodes[i]->rGetLocation();
226 return centroid/((
double)(ELEMENT_DIM + 1));
229 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
232 assert(ELEMENT_DIM <= SPACE_DIM);
233 CalculateJacobian(rJacobian, rJacobianDeterminant);
236 assert(rJacobianDeterminant > 0.0);
237 rInverseJacobian =
Inverse(rJacobian);
240 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
244 if (this->mIsDeleted)
249 double scale_factor = 1.0;
251 if (ELEMENT_DIM == 2)
255 else if (ELEMENT_DIM == 3)
259 return determinant/scale_factor;
262 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
265 for (
unsigned local_index=0; local_index<ELEMENT_DIM+1; local_index++)
267 unsigned node = this->GetNodeGlobalIndex(local_index);
269 for (
unsigned problem_index=0; problem_index<problemDim; problem_index++)
272 pIndices[local_index*problemDim + problem_index] = node*problemDim + problem_index;
286 template<
unsigned SPACE_DIM>
292 assert(this->
mNodes.size() == 1);
293 assert(SPACE_DIM > 0);
297 c_vector<double, SPACE_DIM> weighted_direction;
307 template<
unsigned SPACE_DIM>
313 template<
unsigned SPACE_DIM>
315 c_vector<double, SPACE_DIM>& rWeightedDirection,
316 double& rJacobianDeterminant)
318 assert(SPACE_DIM > 0);
321 rWeightedDirection = zero_vector<double>(SPACE_DIM);
322 rWeightedDirection(0) = 1.0;
324 rJacobianDeterminant = 1.0;
327 template<
unsigned SPACE_DIM>
330 assert(SPACE_DIM > 0);
333 c_vector<double, SPACE_DIM> normal = zero_vector<double>(SPACE_DIM);
338 template<
unsigned SPACE_DIM>
341 c_vector<double, SPACE_DIM> centroid = this->
mNodes[0]->rGetLocation();
345 template<
unsigned SPACE_DIM>
348 for (
unsigned local_index=0; local_index<1; local_index++)
352 for (
unsigned problem_index=0; problem_index<problemDim; problem_index++)
355 pIndices[local_index*problemDim + problem_index] = node*problemDim + problem_index;
void CalculateWeightedDirection(c_vector< double, SPACE_DIM > &rWeightedDirection, double &rJacobianDeterminant)
double GetVolume(double determinant) const
boost::numeric::ublas::c_matrix< T, 1, 1 > Inverse(const boost::numeric::ublas::c_matrix< T, 1, 1 > &rM)
unsigned GetNodeGlobalIndex(unsigned localIndex) const
#define EXCEPTION(message)
void RefreshJacobian(c_matrix< double, SPACE_DIM, ELEMENT_DIM > &rJacobian)
T Determinant(const boost::numeric::ublas::c_matrix< T, 1, 1 > &rM)
c_vector< double, SPACE_DIM > CalculateCentroid() const
void CalculateInverseJacobian(c_matrix< double, SPACE_DIM, ELEMENT_DIM > &rJacobian, double &rJacobianDeterminant, c_matrix< double, ELEMENT_DIM, SPACE_DIM > &rInverseJacobian)
std::vector< Node< SPACE_DIM > * > mNodes
AbstractTetrahedralElement(unsigned index, const std::vector< Node< SPACE_DIM > * > &rNodes)
void GetStiffnessMatrixGlobalIndices(unsigned problemDim, unsigned *pIndices) const
c_vector< double, SPACE_DIM > CalculateNormal()
T SubDeterminant(const boost::numeric::ublas::c_matrix< T, 1, 1 > &rM, const unsigned missrow, const unsigned misscol)
void CalculateJacobian(c_matrix< double, SPACE_DIM, ELEMENT_DIM > &rJacobian, double &rJacobianDeterminant)