ContinuumMechanicsNeumannBcsAssembler.hpp
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 CONTINUUMMECHANICSNEUMANNBCSASSEMBLER_HPP_
00037 #define CONTINUUMMECHANICSNEUMANNBCSASSEMBLER_HPP_
00038
00039 #include "AbstractFeAssemblerInterface.hpp"
00040 #include "AbstractTetrahedralMesh.hpp"
00041 #include "QuadraticMesh.hpp"
00042 #include "DistributedQuadraticMesh.hpp"
00043 #include "LinearBasisFunction.hpp"
00044 #include "QuadraticBasisFunction.hpp"
00045 #include "ReplicatableVector.hpp"
00046 #include "DistributedVector.hpp"
00047 #include "PetscTools.hpp"
00048 #include "PetscVecTools.hpp"
00049 #include "PetscMatTools.hpp"
00050 #include "GaussianQuadratureRule.hpp"
00051 #include "ContinuumMechanicsProblemDefinition.hpp"
00052
00053
00069 template<unsigned DIM>
00070 class ContinuumMechanicsNeumannBcsAssembler : public AbstractFeAssemblerInterface<true,false>
00071 {
00073 static const unsigned NUM_VERTICES_PER_ELEMENT = DIM;
00074
00076 static const unsigned NUM_NODES_PER_ELEMENT = DIM*(DIM+1)/2;
00077
00079 static const unsigned SPATIAL_BLOCK_SIZE_ELEMENTAL = DIM*NUM_NODES_PER_ELEMENT;
00081 static const unsigned PRESSURE_BLOCK_SIZE_ELEMENTAL = NUM_VERTICES_PER_ELEMENT;
00082
00084 static const unsigned STENCIL_SIZE = DIM*NUM_NODES_PER_ELEMENT + NUM_VERTICES_PER_ELEMENT;
00085
00086 protected:
00088 AbstractTetrahedralMesh<DIM,DIM>* mpMesh;
00089
00091 ContinuumMechanicsProblemDefinition<DIM>* mpProblemDefinition;
00092
00094 GaussianQuadratureRule<DIM-1>* mpQuadRule;
00095
00100 void DoAssemble();
00101
00102
00113 void AssembleOnBoundaryElement(BoundaryElement<DIM-1,DIM>& rElement,
00114 c_vector<double, STENCIL_SIZE>& rBElem,
00115 unsigned boundaryConditionIndex);
00116
00117 public:
00122 ContinuumMechanicsNeumannBcsAssembler(AbstractTetrahedralMesh<DIM,DIM>* pMesh,
00123 ContinuumMechanicsProblemDefinition<DIM>* pProblemDefinition)
00124 : AbstractFeAssemblerInterface<true,false>(),
00125 mpMesh(pMesh),
00126 mpProblemDefinition(pProblemDefinition)
00127 {
00128 assert(pMesh);
00129 assert(pProblemDefinition);
00130
00131
00132 QuadraticMesh<DIM>* p_quad_mesh = dynamic_cast<QuadraticMesh<DIM>* >(pMesh);
00133 DistributedQuadraticMesh<DIM>* p_distributed_quad_mesh = dynamic_cast<DistributedQuadraticMesh<DIM>* >(pMesh);
00134
00135 if(p_quad_mesh == NULL && p_distributed_quad_mesh == NULL)
00136 {
00137 EXCEPTION("Continuum mechanics solvers require a quadratic mesh");
00138 }
00139
00140
00141 mpQuadRule = new GaussianQuadratureRule<DIM-1>(3);
00142 }
00143
00144
00148 virtual ~ContinuumMechanicsNeumannBcsAssembler()
00149 {
00150 delete mpQuadRule;
00151 }
00152 };
00153
00154
00155 template<unsigned DIM>
00156 void ContinuumMechanicsNeumannBcsAssembler<DIM>::DoAssemble()
00157 {
00158 if(this->mVectorToAssemble==NULL)
00159 {
00160 EXCEPTION("Vector to be assembled has not been set");
00161 }
00162
00163 if( PetscVecTools::GetSize(this->mVectorToAssemble) != (DIM+1)*mpMesh->GetNumNodes() )
00164 {
00165 EXCEPTION("Vector provided to be assembled has size " << PetscVecTools::GetSize(this->mVectorToAssemble) << ", not expected size of " << (DIM+1)*mpMesh->GetNumNodes() << " ((dim+1)*num_nodes)");
00166 }
00167
00168
00169 if (this->mZeroVectorBeforeAssembly)
00170 {
00171 PetscVecTools::Zero(this->mVectorToAssemble);
00172 }
00173
00174
00175 if (mpProblemDefinition->GetTractionBoundaryConditionType() != NO_TRACTIONS)
00176 {
00177 c_vector<double, STENCIL_SIZE> b_elem = zero_vector<double>(STENCIL_SIZE);
00178
00179 for (unsigned bc_index=0; bc_index<mpProblemDefinition->rGetTractionBoundaryElements().size(); bc_index++)
00180 {
00181 BoundaryElement<DIM-1,DIM>& r_boundary_element = *(mpProblemDefinition->rGetTractionBoundaryElements()[bc_index]);
00182 AssembleOnBoundaryElement(r_boundary_element, b_elem, bc_index);
00183
00184 unsigned p_indices[STENCIL_SIZE];
00185 for (unsigned i=0; i<NUM_NODES_PER_ELEMENT; i++)
00186 {
00187 for (unsigned j=0; j<DIM; j++)
00188 {
00189 p_indices[DIM*i+j] = (DIM+1)*r_boundary_element.GetNodeGlobalIndex(i) + j;
00190 }
00191 }
00192
00193
00194 for (unsigned i=0; i<DIM ; i++)
00195 {
00196 p_indices[DIM*NUM_NODES_PER_ELEMENT + i] = (DIM+1)*r_boundary_element.GetNodeGlobalIndex(i)+DIM;
00197 }
00198
00199 PetscVecTools::AddMultipleValues<STENCIL_SIZE>(this->mVectorToAssemble, p_indices, b_elem);
00200 }
00201 }
00202 }
00203
00204
00205
00206 template<unsigned DIM>
00207 void ContinuumMechanicsNeumannBcsAssembler<DIM>::AssembleOnBoundaryElement(BoundaryElement<DIM-1,DIM>& rBoundaryElement,
00208 c_vector<double,STENCIL_SIZE>& rBelem,
00209 unsigned boundaryConditionIndex)
00210 {
00211 rBelem.clear();
00212
00213 c_vector<double, DIM> weighted_direction;
00214 double jacobian_determinant;
00215 mpMesh->GetWeightedDirectionForBoundaryElement(rBoundaryElement.GetIndex(), weighted_direction, jacobian_determinant);
00216
00217 c_vector<double,NUM_NODES_PER_ELEMENT> phi;
00218
00219 for (unsigned quad_index=0; quad_index<mpQuadRule->GetNumQuadPoints(); quad_index++)
00220 {
00221 double wJ = jacobian_determinant * mpQuadRule->GetWeight(quad_index);
00222 const ChastePoint<DIM-1>& quad_point = mpQuadRule->rGetQuadPoint(quad_index);
00223 QuadraticBasisFunction<DIM-1>::ComputeBasisFunctions(quad_point, phi);
00224
00225 c_vector<double,DIM> traction = zero_vector<double>(DIM);
00226 switch (mpProblemDefinition->GetTractionBoundaryConditionType())
00227 {
00228 case ELEMENTWISE_TRACTION:
00229 {
00230 traction = mpProblemDefinition->rGetElementwiseTractions()[boundaryConditionIndex];
00231 break;
00232 }
00233 default:
00234
00235 NEVER_REACHED;
00236 }
00237
00238 for (unsigned index=0; index<NUM_NODES_PER_ELEMENT*DIM; index++)
00239 {
00240 unsigned spatial_dim = index%DIM;
00241 unsigned node_index = (index-spatial_dim)/DIM;
00242
00243 assert(node_index < NUM_NODES_PER_ELEMENT);
00244
00245 rBelem(index) += traction(spatial_dim) * phi(node_index) * wJ;
00246 }
00247 }
00248 }
00249
00250
00251 #endif // CONTINUUMMECHANICSNEUMANNBCSASSEMBLER_HPP_