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
00030
00031
00032
00033
00034
00035
00036 #ifndef STOKESFLOWASSEMBLER_HPP_
00037 #define STOKESFLOWASSEMBLER_HPP_
00038
00039 #include "AbstractContinuumMechanicsAssembler.hpp"
00040 #include "StokesFlowProblemDefinition.hpp"
00041
00042
00061 template<unsigned DIM>
00062 class StokesFlowAssembler : public AbstractContinuumMechanicsAssembler<DIM,true,true>
00063 {
00064 friend class TestStokesFlowAssembler;
00065
00066 private:
00068 static const unsigned NUM_VERTICES_PER_ELEMENT = DIM+1;
00069
00071 static const unsigned NUM_NODES_PER_ELEMENT = (DIM+1)*(DIM+2)/2;
00072
00077 static const unsigned SPATIAL_BLOCK_SIZE_ELEMENTAL = DIM*NUM_NODES_PER_ELEMENT;
00078
00083 static const unsigned PRESSURE_BLOCK_SIZE_ELEMENTAL = NUM_VERTICES_PER_ELEMENT;
00084
00086 StokesFlowProblemDefinition<DIM>* mpProblemDefinition;
00087
00095 double mScaleFactor;
00096
00097
00113 c_matrix<double,SPATIAL_BLOCK_SIZE_ELEMENTAL,SPATIAL_BLOCK_SIZE_ELEMENTAL> ComputeSpatialSpatialMatrixTerm(
00114 c_vector<double, NUM_NODES_PER_ELEMENT>& rQuadPhi,
00115 c_matrix<double, DIM, NUM_NODES_PER_ELEMENT>& rGradQuadPhi,
00116 c_vector<double,DIM>& rX,
00117 Element<DIM,DIM>* pElement)
00118 {
00119 c_matrix<double,SPATIAL_BLOCK_SIZE_ELEMENTAL,SPATIAL_BLOCK_SIZE_ELEMENTAL> ret = zero_matrix<double>(SPATIAL_BLOCK_SIZE_ELEMENTAL,SPATIAL_BLOCK_SIZE_ELEMENTAL);
00120
00121 double mu = mpProblemDefinition->GetViscosity();
00122
00123 for (unsigned index1=0; index1<NUM_NODES_PER_ELEMENT*DIM; index1++)
00124 {
00125 unsigned spatial_dim1 = index1%DIM;
00126 unsigned node_index1 = (index1-spatial_dim1)/DIM;
00127
00128 for (unsigned index2=0; index2<NUM_NODES_PER_ELEMENT*DIM; index2++)
00129 {
00130 unsigned spatial_dim2 = index2%DIM;
00131 unsigned node_index2 = (index2-spatial_dim2)/DIM;
00132
00133 ret(index1,index2) += mu
00134 * mScaleFactor
00135 * rGradQuadPhi(spatial_dim1, node_index2)
00136 * rGradQuadPhi(spatial_dim2, node_index1);
00137
00138 for(unsigned k=0; k<DIM; k++)
00139 {
00140 ret(index1,index2) += mu
00141 * (spatial_dim1==spatial_dim2)
00142 * rGradQuadPhi(k, node_index1)
00143 * rGradQuadPhi(k, node_index2);
00144 }
00145 }
00146 }
00147 return ret;
00148
00149 }
00150
00168 c_matrix<double,SPATIAL_BLOCK_SIZE_ELEMENTAL,PRESSURE_BLOCK_SIZE_ELEMENTAL> ComputeSpatialPressureMatrixTerm(
00169 c_vector<double, NUM_NODES_PER_ELEMENT>& rQuadPhi,
00170 c_matrix<double, DIM, NUM_NODES_PER_ELEMENT>& rGradQuadPhi,
00171 c_vector<double, NUM_VERTICES_PER_ELEMENT>& rLinearPhi,
00172 c_matrix<double, DIM, NUM_VERTICES_PER_ELEMENT>& rGradLinearPhi,
00173 c_vector<double,DIM>& rX,
00174 Element<DIM,DIM>* pElement)
00175 {
00176 c_matrix<double,SPATIAL_BLOCK_SIZE_ELEMENTAL,PRESSURE_BLOCK_SIZE_ELEMENTAL> ret = zero_matrix<double>(SPATIAL_BLOCK_SIZE_ELEMENTAL,PRESSURE_BLOCK_SIZE_ELEMENTAL);
00177
00178 for (unsigned index1=0; index1<NUM_NODES_PER_ELEMENT*DIM; index1++)
00179 {
00180 unsigned spatial_dim1 = index1%DIM;
00181 unsigned node_index1 = (index1-spatial_dim1)/DIM;
00182
00183 for (unsigned index2=0; index2<NUM_VERTICES_PER_ELEMENT; index2++)
00184 {
00185 ret(index1,index2) += -rGradQuadPhi(spatial_dim1, node_index1) * rLinearPhi(index2);
00186 }
00187 }
00188
00189 return ret;
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00217 c_vector<double,SPATIAL_BLOCK_SIZE_ELEMENTAL> ComputeSpatialVectorTerm(
00218 c_vector<double, NUM_NODES_PER_ELEMENT>& rQuadPhi,
00219 c_matrix<double, DIM, NUM_NODES_PER_ELEMENT>& rGradQuadPhi,
00220 c_vector<double,DIM>& rX,
00221 Element<DIM,DIM>* pElement)
00222 {
00223 c_vector<double,SPATIAL_BLOCK_SIZE_ELEMENTAL> ret = zero_vector<double>(SPATIAL_BLOCK_SIZE_ELEMENTAL);
00224
00225 c_vector<double,DIM> body_force = mpProblemDefinition->GetBodyForce(rX, 0.0);
00226
00227 for (unsigned index=0; index<NUM_NODES_PER_ELEMENT*DIM; index++)
00228 {
00229 unsigned spatial_dim = index%DIM;
00230 unsigned node_index = (index-spatial_dim)/DIM;
00231
00232 ret(index) += body_force(spatial_dim) * rQuadPhi(node_index);
00233 }
00234
00235 return ret;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245 public:
00251 StokesFlowAssembler(AbstractTetrahedralMesh<DIM,DIM>* pMesh,
00252 StokesFlowProblemDefinition<DIM>* pProblemDefinition)
00253 : AbstractContinuumMechanicsAssembler<DIM,true,true>(pMesh),
00254 mpProblemDefinition(pProblemDefinition),
00255 mScaleFactor(1.0)
00256 {
00257 }
00258 };
00259
00260 #endif // STOKESFLOWASSEMBLER_HPP_