Chaste Release::3.1
|
00001 /* 00002 00003 Copyright (c) 2005-2012, University of Oxford. 00004 All rights reserved. 00005 00006 University of Oxford means the Chancellor, Masters and Scholars of the 00007 University of Oxford, having an administrative office at Wellington 00008 Square, Oxford OX1 2JD, UK. 00009 00010 This file is part of Chaste. 00011 00012 Redistribution and use in source and binary forms, with or without 00013 modification, are permitted provided that the following conditions are met: 00014 * Redistributions of source code must retain the above copyright notice, 00015 this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright notice, 00017 this list of conditions and the following disclaimer in the documentation 00018 and/or other materials provided with the distribution. 00019 * Neither the name of the University of Oxford nor the names of its 00020 contributors may be used to endorse or promote products derived from this 00021 software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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; // assuming quadratic 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 00112 c_matrix<double,SPATIAL_BLOCK_SIZE_ELEMENTAL,SPATIAL_BLOCK_SIZE_ELEMENTAL> ComputeSpatialSpatialMatrixTerm( 00113 c_vector<double, NUM_NODES_PER_ELEMENT>& rQuadPhi, 00114 c_matrix<double, DIM, NUM_NODES_PER_ELEMENT>& rGradQuadPhi, 00115 c_vector<double,DIM>& rX, 00116 Element<DIM,DIM>* pElement) 00117 { 00118 c_matrix<double,SPATIAL_BLOCK_SIZE_ELEMENTAL,SPATIAL_BLOCK_SIZE_ELEMENTAL> ret = zero_matrix<double>(SPATIAL_BLOCK_SIZE_ELEMENTAL,SPATIAL_BLOCK_SIZE_ELEMENTAL); 00119 00120 double mu = mpProblemDefinition->GetViscosity(); 00121 00122 for (unsigned index1=0; index1<NUM_NODES_PER_ELEMENT*DIM; index1++) 00123 { 00124 unsigned spatial_dim1 = index1%DIM; 00125 unsigned node_index1 = (index1-spatial_dim1)/DIM; 00126 00127 for (unsigned index2=0; index2<NUM_NODES_PER_ELEMENT*DIM; index2++) 00128 { 00129 unsigned spatial_dim2 = index2%DIM; 00130 unsigned node_index2 = (index2-spatial_dim2)/DIM; 00131 00132 ret(index1,index2) += mu 00133 * mScaleFactor // virtually always 1, see doxygen for this variable 00134 * rGradQuadPhi(spatial_dim1, node_index2) 00135 * rGradQuadPhi(spatial_dim2, node_index1); 00136 00137 for(unsigned k=0; k<DIM; k++) 00138 { 00139 ret(index1,index2) += mu 00140 * (spatial_dim1==spatial_dim2) 00141 * rGradQuadPhi(k, node_index1) 00142 * rGradQuadPhi(k, node_index2); 00143 } 00144 } 00145 } 00146 return ret; 00147 00148 } 00149 00166 c_matrix<double,SPATIAL_BLOCK_SIZE_ELEMENTAL,PRESSURE_BLOCK_SIZE_ELEMENTAL> ComputeSpatialPressureMatrixTerm( 00167 c_vector<double, NUM_NODES_PER_ELEMENT>& rQuadPhi, 00168 c_matrix<double, DIM, NUM_NODES_PER_ELEMENT>& rGradQuadPhi, 00169 c_vector<double, NUM_VERTICES_PER_ELEMENT>& rLinearPhi, 00170 c_matrix<double, DIM, NUM_VERTICES_PER_ELEMENT>& rGradLinearPhi, 00171 c_vector<double,DIM>& rX, 00172 Element<DIM,DIM>* pElement) 00173 { 00174 c_matrix<double,SPATIAL_BLOCK_SIZE_ELEMENTAL,PRESSURE_BLOCK_SIZE_ELEMENTAL> ret = zero_matrix<double>(SPATIAL_BLOCK_SIZE_ELEMENTAL,PRESSURE_BLOCK_SIZE_ELEMENTAL); 00175 00176 for (unsigned index1=0; index1<NUM_NODES_PER_ELEMENT*DIM; index1++) 00177 { 00178 unsigned spatial_dim1 = index1%DIM; 00179 unsigned node_index1 = (index1-spatial_dim1)/DIM; 00180 00181 for (unsigned index2=0; index2<NUM_VERTICES_PER_ELEMENT; index2++) 00182 { 00183 ret(index1,index2) += -rGradQuadPhi(spatial_dim1, node_index1) * rLinearPhi(index2); 00184 } 00185 } 00186 00187 return ret; 00188 } 00189 00190 // We don't implement this method - so it is a zero block 00191 //c_matrix<double,PRESSURE_BLOCK_SIZE_ELEMENTAL,PRESSURE_BLOCK_SIZE_ELEMENTAL> ComputePressurePressureMatrixTerm( 00192 // c_vector<double, NUM_VERTICES_PER_ELEMENT>& rLinearPhi, 00193 // c_matrix<double, DIM, NUM_VERTICES_PER_ELEMENT>& rGradLinearPhi, 00194 // c_vector<double,DIM>& rX, 00195 // Element<DIM,DIM>* pElement) 00196 00197 00214 c_vector<double,SPATIAL_BLOCK_SIZE_ELEMENTAL> ComputeSpatialVectorTerm( 00215 c_vector<double, NUM_NODES_PER_ELEMENT>& rQuadPhi, 00216 c_matrix<double, DIM, NUM_NODES_PER_ELEMENT>& rGradQuadPhi, 00217 c_vector<double,DIM>& rX, 00218 Element<DIM,DIM>* pElement) 00219 { 00220 c_vector<double,SPATIAL_BLOCK_SIZE_ELEMENTAL> ret = zero_vector<double>(SPATIAL_BLOCK_SIZE_ELEMENTAL); 00221 00222 c_vector<double,DIM> body_force = mpProblemDefinition->GetBodyForce(rX, 0.0); 00223 00224 for (unsigned index=0; index<NUM_NODES_PER_ELEMENT*DIM; index++) 00225 { 00226 unsigned spatial_dim = index%DIM; 00227 unsigned node_index = (index-spatial_dim)/DIM; 00228 00229 ret(index) += body_force(spatial_dim) * rQuadPhi(node_index); 00230 } 00231 00232 return ret; 00233 } 00234 00235 // We don't implement this method - so it is a zero block of the vector: 00236 //c_vector<double,PRESSURE_BLOCK_SIZE_ELEMENTAL> ComputePressureVectorTerm( 00237 // c_vector<double, NUM_VERTICES_PER_ELEMENT>& rLinearPhi, 00238 // c_matrix<double, DIM, NUM_VERTICES_PER_ELEMENT>& rGradLinearPhi, 00239 // c_vector<double,DIM>& rX, 00240 // Element<DIM,DIM>* pElement) 00241 00242 public: 00248 StokesFlowAssembler(QuadraticMesh<DIM>* pMesh, 00249 StokesFlowProblemDefinition<DIM>* pProblemDefinition) 00250 : AbstractContinuumMechanicsAssembler<DIM,true,true>(pMesh), 00251 mpProblemDefinition(pProblemDefinition), 00252 mScaleFactor(1.0) 00253 { 00254 } 00255 }; 00256 00257 #endif // STOKESFLOWASSEMBLER_HPP_