36 #ifndef ABSTRACTCONTINUUMMECHANICSASSEMBLER_HPP_
37 #define ABSTRACTCONTINUUMMECHANICSASSEMBLER_HPP_
39 #include "AbstractFeAssemblerInterface.hpp"
40 #include "AbstractTetrahedralMesh.hpp"
41 #include "QuadraticMesh.hpp"
42 #include "DistributedQuadraticMesh.hpp"
43 #include "LinearBasisFunction.hpp"
44 #include "QuadraticBasisFunction.hpp"
45 #include "ReplicatableVector.hpp"
46 #include "DistributedVector.hpp"
48 #include "PetscVecTools.hpp"
49 #include "PetscMatTools.hpp"
50 #include "GaussianQuadratureRule.hpp"
86 template<
unsigned DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX>
144 c_vector<double, NUM_NODES_PER_ELEMENT>& rQuadPhi,
145 c_matrix<double, DIM, NUM_NODES_PER_ELEMENT>& rGradQuadPhi,
146 c_vector<double,DIM>& rX,
175 c_vector<double, NUM_NODES_PER_ELEMENT>& rQuadPhi,
176 c_matrix<double, DIM, NUM_NODES_PER_ELEMENT>& rGradQuadPhi,
177 c_vector<double, NUM_VERTICES_PER_ELEMENT>& rLinearPhi,
178 c_matrix<double, DIM, NUM_VERTICES_PER_ELEMENT>& rGradLinearPhi,
179 c_vector<double,DIM>& rX,
206 c_vector<double, NUM_VERTICES_PER_ELEMENT>& rLinearPhi,
207 c_matrix<double, DIM, NUM_VERTICES_PER_ELEMENT>& rGradLinearPhi,
208 c_vector<double,DIM>& rX,
238 c_vector<double, NUM_NODES_PER_ELEMENT>& rQuadPhi,
239 c_matrix<double, DIM, NUM_NODES_PER_ELEMENT>& rGradQuadPhi,
240 c_vector<double,DIM>& rX,
270 c_vector<double, NUM_VERTICES_PER_ELEMENT>& rLinearPhi,
271 c_matrix<double, DIM, NUM_VERTICES_PER_ELEMENT>& rGradLinearPhi,
272 c_vector<double,DIM>& rX,
292 c_matrix<double, STENCIL_SIZE, STENCIL_SIZE >& rAElem,
293 c_vector<double, STENCIL_SIZE>& rBElem);
309 if(p_quad_mesh == NULL && p_distributed_quad_mesh == NULL)
311 EXCEPTION(
"Continuum mechanics assemblers require a quadratic mesh");
350 template<
unsigned DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX>
353 assert(this->mAssembleMatrix || this->mAssembleVector);
354 if (this->mAssembleMatrix)
356 if(this->mMatrixToAssemble==NULL)
358 EXCEPTION(
"Matrix to be assembled has not been set");
362 EXCEPTION(
"Matrix provided to be assembled has size " <<
PetscMatTools::GetSize(this->mMatrixToAssemble) <<
", not expected size of " << (DIM+1)*mpMesh->GetNumNodes() <<
" ((dim+1)*num_nodes)");
366 if (this->mAssembleVector)
368 if(this->mVectorToAssemble==NULL)
370 EXCEPTION(
"Vector to be assembled has not been set");
374 EXCEPTION(
"Vector provided to be assembled has size " <<
PetscVecTools::GetSize(this->mVectorToAssemble) <<
", not expected size of " << (DIM+1)*mpMesh->GetNumNodes() <<
" ((dim+1)*num_nodes)");
379 if (this->mAssembleVector && this->mZeroVectorBeforeAssembly)
385 if (this->mAssembleMatrix && this->mZeroMatrixBeforeAssembly)
392 c_matrix<double, STENCIL_SIZE, STENCIL_SIZE> a_elem = zero_matrix<double>(STENCIL_SIZE,STENCIL_SIZE);
393 c_vector<double, STENCIL_SIZE> b_elem = zero_vector<double>(STENCIL_SIZE);
398 iter != mpMesh->GetElementIteratorEnd();
406 #define COVERAGE_IGNORE
412 #undef COVERAGE_IGNORE
415 AssembleOnElement(r_element, a_elem, b_elem);
419 unsigned p_indices[STENCIL_SIZE];
421 for (
unsigned i=0; i<NUM_NODES_PER_ELEMENT; i++)
423 for (
unsigned j=0; j<DIM; j++)
430 for (
unsigned i=0; i<NUM_VERTICES_PER_ELEMENT; i++)
432 p_indices[DIM*NUM_NODES_PER_ELEMENT + i] = (DIM+1)*r_element.
GetNodeGlobalIndex(i)+DIM;
436 if (this->mAssembleMatrix)
438 PetscMatTools::AddMultipleValues<STENCIL_SIZE>(this->mMatrixToAssemble, p_indices, a_elem);
441 if (this->mAssembleVector)
443 PetscVecTools::AddMultipleValues<STENCIL_SIZE>(this->mVectorToAssemble, p_indices, b_elem);
449 template<
unsigned DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX>
451 c_matrix<double, STENCIL_SIZE, STENCIL_SIZE >& rAElem,
452 c_vector<double, STENCIL_SIZE>& rBElem)
454 static c_matrix<double,DIM,DIM> jacobian;
455 static c_matrix<double,DIM,DIM> inverse_jacobian;
456 double jacobian_determinant;
458 mpMesh->GetInverseJacobianForElement(rElement.
GetIndex(), jacobian, jacobian_determinant, inverse_jacobian);
460 if (this->mAssembleMatrix)
465 if (this->mAssembleVector)
472 static c_vector<double, NUM_VERTICES_PER_ELEMENT> linear_phi;
473 static c_vector<double, NUM_NODES_PER_ELEMENT> quad_phi;
474 static c_matrix<double, DIM, NUM_NODES_PER_ELEMENT> grad_quad_phi;
475 static c_matrix<double, DIM, NUM_VERTICES_PER_ELEMENT> grad_linear_phi;
477 c_vector<double,DIM> body_force;
480 for (
unsigned quadrature_index=0; quadrature_index < mpQuadRule->GetNumQuadPoints(); quadrature_index++)
482 double wJ = jacobian_determinant * mpQuadRule->GetWeight(quadrature_index);
483 const ChastePoint<DIM>& quadrature_point = mpQuadRule->rGetQuadPoint(quadrature_index);
492 c_vector<double,DIM> X = zero_vector<double>(DIM);
493 for (
unsigned vertex_index=0; vertex_index<NUM_VERTICES_PER_ELEMENT; vertex_index++)
495 for(
unsigned j=0; j<DIM; j++)
497 X(j) += linear_phi(vertex_index)*rElement.
GetNode(vertex_index)->rGetLocation()(j);
501 if(this->mAssembleVector)
503 c_vector<double,SPATIAL_BLOCK_SIZE_ELEMENTAL> b_spatial
504 = ComputeSpatialVectorTerm(quad_phi, grad_quad_phi, X, &rElement);
505 c_vector<double,PRESSURE_BLOCK_SIZE_ELEMENTAL> b_pressure = ComputePressureVectorTerm(linear_phi, grad_linear_phi, X, &rElement);
507 for (
unsigned i=0; i<SPATIAL_BLOCK_SIZE_ELEMENTAL; i++)
509 rBElem(i) += b_spatial(i)*wJ;
513 for (
unsigned i=0; i<PRESSURE_BLOCK_SIZE_ELEMENTAL; i++)
515 rBElem(SPATIAL_BLOCK_SIZE_ELEMENTAL + i) += b_pressure(i)*wJ;
520 if(this->mAssembleMatrix)
522 c_matrix<double,SPATIAL_BLOCK_SIZE_ELEMENTAL,SPATIAL_BLOCK_SIZE_ELEMENTAL> a_spatial_spatial
523 = ComputeSpatialSpatialMatrixTerm(quad_phi, grad_quad_phi, X, &rElement);
525 c_matrix<double,SPATIAL_BLOCK_SIZE_ELEMENTAL,PRESSURE_BLOCK_SIZE_ELEMENTAL> a_spatial_pressure
526 = ComputeSpatialPressureMatrixTerm(quad_phi, grad_quad_phi, linear_phi, grad_linear_phi, X, &rElement);
528 c_matrix<double,PRESSURE_BLOCK_SIZE_ELEMENTAL,SPATIAL_BLOCK_SIZE_ELEMENTAL> a_pressure_spatial;
529 if(!BLOCK_SYMMETRIC_MATRIX)
535 c_matrix<double,PRESSURE_BLOCK_SIZE_ELEMENTAL,PRESSURE_BLOCK_SIZE_ELEMENTAL> a_pressure_pressure
536 = ComputePressurePressureMatrixTerm(linear_phi, grad_linear_phi, X, &rElement);
538 for (
unsigned i=0; i<SPATIAL_BLOCK_SIZE_ELEMENTAL; i++)
540 for(
unsigned j=0; j<SPATIAL_BLOCK_SIZE_ELEMENTAL; j++)
542 rAElem(i,j) += a_spatial_spatial(i,j)*wJ;
545 for(
unsigned j=0; j<PRESSURE_BLOCK_SIZE_ELEMENTAL; j++)
547 rAElem(i, SPATIAL_BLOCK_SIZE_ELEMENTAL + j) += a_spatial_pressure(i,j)*wJ;
551 for(
unsigned i=0; i<PRESSURE_BLOCK_SIZE_ELEMENTAL; i++)
553 if(BLOCK_SYMMETRIC_MATRIX)
555 for(
unsigned j=0; j<SPATIAL_BLOCK_SIZE_ELEMENTAL; j++)
557 rAElem(SPATIAL_BLOCK_SIZE_ELEMENTAL + i, j) += a_spatial_pressure(j,i)*wJ;
565 for(
unsigned j=0; j<PRESSURE_BLOCK_SIZE_ELEMENTAL; j++)
567 rAElem(SPATIAL_BLOCK_SIZE_ELEMENTAL + i, SPATIAL_BLOCK_SIZE_ELEMENTAL + j) += a_pressure_pressure(i,j)*wJ;
575 #endif // ABSTRACTCONTINUUMMECHANICSASSEMBLER_HPP_
static const unsigned SPATIAL_BLOCK_SIZE_ELEMENTAL
ElementIterator GetElementIteratorBegin(bool skipDeletedElements=true)
AbstractTetrahedralMesh< DIM, DIM > * mpMesh
virtual c_matrix< double, SPATIAL_BLOCK_SIZE_ELEMENTAL, SPATIAL_BLOCK_SIZE_ELEMENTAL > ComputeSpatialSpatialMatrixTerm(c_vector< double, NUM_NODES_PER_ELEMENT > &rQuadPhi, c_matrix< double, DIM, NUM_NODES_PER_ELEMENT > &rGradQuadPhi, c_vector< double, DIM > &rX, Element< DIM, DIM > *pElement)
static const unsigned PRESSURE_BLOCK_SIZE_ELEMENTAL
GaussianQuadratureRule< DIM > * mpQuadRule
unsigned GetNodeGlobalIndex(unsigned localIndex) const
#define EXCEPTION(message)
static void ComputeTransformedBasisFunctionDerivatives(const ChastePoint< ELEMENT_DIM > &rPoint, const c_matrix< double, ELEMENT_DIM, ELEMENT_DIM > &rInverseJacobian, c_matrix< double, ELEMENT_DIM,(ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2 > &rReturnValue)
AbstractContinuumMechanicsAssembler(AbstractTetrahedralMesh< DIM, DIM > *pMesh)
static const bool BLOCK_SYMMETRIC_MATRIX
bool OptionExists(const std::string &rOption)
Node< SPACE_DIM > * GetNode(unsigned localIndex) const
static void ComputeTransformedBasisFunctionDerivatives(const ChastePoint< ELEMENT_DIM > &rPoint, const c_matrix< double, ELEMENT_DIM, ELEMENT_DIM > &rInverseJacobian, c_matrix< double, ELEMENT_DIM, ELEMENT_DIM+1 > &rReturnValue)
bool GetOwnership() const
static const unsigned STENCIL_SIZE
static void ComputeBasisFunctions(const ChastePoint< ELEMENT_DIM > &rPoint, c_vector< double,(ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2 > &rReturnValue)
virtual c_matrix< double, PRESSURE_BLOCK_SIZE_ELEMENTAL, PRESSURE_BLOCK_SIZE_ELEMENTAL > ComputePressurePressureMatrixTerm(c_vector< double, NUM_VERTICES_PER_ELEMENT > &rLinearPhi, c_matrix< double, DIM, NUM_VERTICES_PER_ELEMENT > &rGradLinearPhi, c_vector< double, DIM > &rX, Element< DIM, DIM > *pElement)
static void ComputeBasisFunctions(const ChastePoint< ELEMENT_DIM > &rPoint, c_vector< double, ELEMENT_DIM+1 > &rReturnValue)
virtual c_vector< double, PRESSURE_BLOCK_SIZE_ELEMENTAL > ComputePressureVectorTerm(c_vector< double, NUM_VERTICES_PER_ELEMENT > &rLinearPhi, c_matrix< double, DIM, NUM_VERTICES_PER_ELEMENT > &rGradLinearPhi, c_vector< double, DIM > &rX, Element< DIM, DIM > *pElement)
virtual c_matrix< double, SPATIAL_BLOCK_SIZE_ELEMENTAL, PRESSURE_BLOCK_SIZE_ELEMENTAL > ComputeSpatialPressureMatrixTerm(c_vector< double, NUM_NODES_PER_ELEMENT > &rQuadPhi, c_matrix< double, DIM, NUM_NODES_PER_ELEMENT > &rGradQuadPhi, c_vector< double, NUM_VERTICES_PER_ELEMENT > &rLinearPhi, c_matrix< double, DIM, NUM_VERTICES_PER_ELEMENT > &rGradLinearPhi, c_vector< double, DIM > &rX, Element< DIM, DIM > *pElement)
static const unsigned NUM_NODES_PER_ELEMENT
virtual ~AbstractContinuumMechanicsAssembler()
unsigned GetIndex() const
static CommandLineArguments * Instance()
void AssembleOnElement(Element< DIM, DIM > &rElement, c_matrix< double, STENCIL_SIZE, STENCIL_SIZE > &rAElem, c_vector< double, STENCIL_SIZE > &rBElem)
virtual c_vector< double, SPATIAL_BLOCK_SIZE_ELEMENTAL > ComputeSpatialVectorTerm(c_vector< double, NUM_NODES_PER_ELEMENT > &rQuadPhi, c_matrix< double, DIM, NUM_NODES_PER_ELEMENT > &rGradQuadPhi, c_vector< double, DIM > &rX, Element< DIM, DIM > *pElement)
static const unsigned NUM_VERTICES_PER_ELEMENT