00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "UblasCustomFunctions.hpp"
00030
00031 #include "AbstractTetrahedralElement.hpp"
00032
00033 #include "Exception.hpp"
00034
00035 #include <cassert>
00036
00038
00040
00041 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00042 void AbstractTetrahedralElement<ELEMENT_DIM, SPACE_DIM>::RefreshJacobian(c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian)
00043 {
00044 if (this->mIsDeleted)
00045 {
00046 EXCEPTION("Attempting to Refresh a deleted element");
00047 }
00048 for (unsigned i=0; i<SPACE_DIM; i++)
00049 {
00050 for (unsigned j=0; j!=ELEMENT_DIM; j++)
00051 {
00052 rJacobian(i,j) = this->GetNodeLocation(j+1,i) - this->GetNodeLocation(0,i);
00053 }
00054 }
00055 }
00056
00057 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00058 AbstractTetrahedralElement<ELEMENT_DIM, SPACE_DIM>::AbstractTetrahedralElement(unsigned index, const std::vector<Node<SPACE_DIM>*>& rNodes)
00059 : AbstractElement<ELEMENT_DIM, SPACE_DIM>(index, rNodes)
00060 {
00061
00062 unsigned num_vectices = ELEMENT_DIM+1;
00063
00064
00065
00066
00068 c_matrix<double, SPACE_DIM, ELEMENT_DIM> jacobian;
00069
00070 if (SPACE_DIM == ELEMENT_DIM)
00071 {
00072 double det;
00073 try
00074 {
00075 CalculateJacobian(jacobian, det);
00076 }
00077 catch (Exception)
00078 {
00079
00080
00081
00082 this->mNodes[num_vectices-1] = rNodes[num_vectices-2];
00083 this->mNodes[num_vectices-2] = rNodes[num_vectices-1];
00084
00085 CalculateJacobian(jacobian, det);
00086
00087
00088 assert(det > 0.0);
00089 }
00090 }
00091
00092 }
00093
00094 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00095 AbstractTetrahedralElement<ELEMENT_DIM, SPACE_DIM>::AbstractTetrahedralElement(unsigned index)
00096 : AbstractElement<ELEMENT_DIM,SPACE_DIM>(index)
00097 {}
00098
00099 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00100 void AbstractTetrahedralElement<ELEMENT_DIM, SPACE_DIM>::CalculateJacobian(c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian, double& rJacobianDeterminant)
00101 {
00102
00103 assert(ELEMENT_DIM <= SPACE_DIM);
00104 RefreshJacobian(rJacobian);
00105
00106 {
00107 rJacobianDeterminant = Determinant(rJacobian);
00108 if (rJacobianDeterminant <= DBL_EPSILON)
00109 {
00110 std::stringstream string_stream;
00111 string_stream << "Jacobian determinant is non-positive: "
00112 << "determinant = " << rJacobianDeterminant
00113 << " for element " << this->mIndex;
00114 EXCEPTION(string_stream.str());
00115 }
00116 }
00117 }
00118
00119 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00120 void AbstractTetrahedralElement<ELEMENT_DIM, SPACE_DIM>::CalculateWeightedDirection(c_vector<double, SPACE_DIM>& rWeightedDirection, double& rJacobianDeterminant)
00121 {
00122
00123 if (ELEMENT_DIM >= SPACE_DIM)
00124 {
00125 assert(ELEMENT_DIM == SPACE_DIM);
00126 EXCEPTION("WeightedDirection undefined for fully dimensional element");
00127 }
00128
00129 c_matrix<double, SPACE_DIM, ELEMENT_DIM> jacobian;
00130 RefreshJacobian(jacobian);
00131
00132
00133
00134
00135
00136
00137 switch (ELEMENT_DIM)
00138 {
00139 case 0:
00140 NEVER_REACHED;
00141 break;
00142 case 1:
00143
00144
00145 rWeightedDirection=matrix_column<c_matrix<double,SPACE_DIM,ELEMENT_DIM> >(jacobian, 0);
00146 break;
00147 case 2:
00148
00149 assert(SPACE_DIM == 3);
00150 rWeightedDirection(0) = -SubDeterminant(jacobian, 0, 2);
00151 rWeightedDirection(1) = SubDeterminant(jacobian, 1, 2);
00152 rWeightedDirection(2) = -SubDeterminant(jacobian, 2, 2);
00153 break;
00154 default:
00155 ;
00156 }
00157 rJacobianDeterminant = norm_2(rWeightedDirection);
00158
00159 if (rJacobianDeterminant < DBL_EPSILON)
00160 {
00161 EXCEPTION("Jacobian determinant is zero");
00162 }
00163 }
00164
00165 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00166 c_vector<double, SPACE_DIM> AbstractTetrahedralElement<ELEMENT_DIM, SPACE_DIM>::CalculateCentroid() const
00167 {
00168 c_vector<double, SPACE_DIM> centroid = zero_vector<double>(SPACE_DIM);
00169 for (unsigned i=0; i<=ELEMENT_DIM; i++)
00170 {
00171 centroid += this->mNodes[i]->rGetLocation();
00172 }
00173 return centroid/((double)(ELEMENT_DIM + 1));
00174 }
00175
00176 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00177 void AbstractTetrahedralElement<ELEMENT_DIM, SPACE_DIM>::CalculateInverseJacobian(c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian, double& rJacobianDeterminant, c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian)
00178 {
00179 assert(ELEMENT_DIM <= SPACE_DIM);
00180 CalculateJacobian(rJacobian, rJacobianDeterminant);
00181
00182
00183 assert(rJacobianDeterminant > 0.0);
00184 rInverseJacobian = Inverse(rJacobian);
00185 }
00186
00187 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00188 double AbstractTetrahedralElement<ELEMENT_DIM, SPACE_DIM>::GetVolume(double determinant) const
00189 {
00190 assert(SPACE_DIM == ELEMENT_DIM);
00191
00192 if (this->mIsDeleted)
00193 {
00194 return 0.0;
00195 }
00196
00197 double scale_factor = 1.0;
00198
00199 if (ELEMENT_DIM == 2)
00200 {
00201 scale_factor = 2.0;
00202 }
00203 else if (ELEMENT_DIM == 3)
00204 {
00205 scale_factor = 6.0;
00206 }
00207 return determinant/scale_factor;
00208 }
00209
00210 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00211 void AbstractTetrahedralElement<ELEMENT_DIM, SPACE_DIM>::GetStiffnessMatrixGlobalIndices(unsigned problemDim, unsigned* pIndices) const
00212 {
00213 for (unsigned local_index=0; local_index<ELEMENT_DIM+1; local_index++)
00214 {
00215 unsigned node = this->GetNodeGlobalIndex(local_index);
00216
00217 for (unsigned problem_index=0; problem_index<problemDim; problem_index++)
00218 {
00219
00220 pIndices[local_index*problemDim + problem_index] = node*problemDim + problem_index;
00221 }
00222 }
00223 }
00224
00225
00227
00229
00230 template class AbstractTetrahedralElement<0,1>;
00231 template class AbstractTetrahedralElement<1,1>;
00232 template class AbstractTetrahedralElement<0,2>;
00233 template class AbstractTetrahedralElement<1,2>;
00234 template class AbstractTetrahedralElement<2,2>;
00235 template class AbstractTetrahedralElement<0,3>;
00236 template class AbstractTetrahedralElement<1,3>;
00237 template class AbstractTetrahedralElement<2,3>;
00238 template class AbstractTetrahedralElement<3,3>;