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,
267 c_vector<double, NUM_VERTICES_PER_ELEMENT>& rLinearPhi,
268 c_matrix<double, DIM, NUM_VERTICES_PER_ELEMENT>& rGradLinearPhi,
269 c_vector<double,DIM>& rX,
287 c_matrix<double, STENCIL_SIZE, STENCIL_SIZE >& rAElem,
288 c_vector<double, STENCIL_SIZE>& rBElem);
304 if ((p_quad_mesh == NULL) && (p_distributed_quad_mesh == NULL))
306 EXCEPTION(
"Continuum mechanics assemblers require a quadratic mesh");
343 template<
unsigned DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX>
346 assert(this->mAssembleMatrix || this->mAssembleVector);
347 if (this->mAssembleMatrix)
349 if (this->mMatrixToAssemble == NULL)
351 EXCEPTION(
"Matrix to be assembled has not been set");
355 EXCEPTION(
"Matrix provided to be assembled has size " <<
PetscMatTools::GetSize(this->mMatrixToAssemble) <<
", not expected size of " << (DIM+1)*mpMesh->GetNumNodes() <<
" ((dim+1)*num_nodes)");
359 if (this->mAssembleVector)
361 if (this->mVectorToAssemble == NULL)
363 EXCEPTION(
"Vector to be assembled has not been set");
367 EXCEPTION(
"Vector provided to be assembled has size " <<
PetscVecTools::GetSize(this->mVectorToAssemble) <<
", not expected size of " << (DIM+1)*mpMesh->GetNumNodes() <<
" ((dim+1)*num_nodes)");
372 if (this->mAssembleVector && this->mZeroVectorBeforeAssembly)
378 if (this->mAssembleMatrix && this->mZeroMatrixBeforeAssembly)
385 c_matrix<double, STENCIL_SIZE, STENCIL_SIZE> a_elem = zero_matrix<double>(STENCIL_SIZE,STENCIL_SIZE);
386 c_vector<double, STENCIL_SIZE> b_elem = zero_vector<double>(STENCIL_SIZE);
391 iter != mpMesh->GetElementIteratorEnd();
407 AssembleOnElement(r_element, a_elem, b_elem);
411 unsigned p_indices[STENCIL_SIZE];
413 for (
unsigned i=0; i<NUM_NODES_PER_ELEMENT; i++)
415 for (
unsigned j=0; j<DIM; j++)
422 for (
unsigned i=0; i<NUM_VERTICES_PER_ELEMENT; i++)
424 p_indices[DIM*NUM_NODES_PER_ELEMENT + i] = (DIM+1)*r_element.
GetNodeGlobalIndex(i)+DIM;
428 if (this->mAssembleMatrix)
430 PetscMatTools::AddMultipleValues<STENCIL_SIZE>(this->mMatrixToAssemble, p_indices, a_elem);
433 if (this->mAssembleVector)
435 PetscVecTools::AddMultipleValues<STENCIL_SIZE>(this->mVectorToAssemble, p_indices, b_elem);
441 template<
unsigned DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX>
443 c_matrix<double, STENCIL_SIZE, STENCIL_SIZE >& rAElem,
444 c_vector<double, STENCIL_SIZE>& rBElem)
446 static c_matrix<double,DIM,DIM> jacobian;
447 static c_matrix<double,DIM,DIM> inverse_jacobian;
448 double jacobian_determinant;
450 mpMesh->GetInverseJacobianForElement(rElement.
GetIndex(), jacobian, jacobian_determinant, inverse_jacobian);
452 if (this->mAssembleMatrix)
457 if (this->mAssembleVector)
463 static c_vector<double, NUM_VERTICES_PER_ELEMENT> linear_phi;
464 static c_vector<double, NUM_NODES_PER_ELEMENT> quad_phi;
465 static c_matrix<double, DIM, NUM_NODES_PER_ELEMENT> grad_quad_phi;
466 static c_matrix<double, DIM, NUM_VERTICES_PER_ELEMENT> grad_linear_phi;
468 c_vector<double,DIM> body_force;
471 for (
unsigned quadrature_index=0; quadrature_index < mpQuadRule->GetNumQuadPoints(); quadrature_index++)
473 double wJ = jacobian_determinant * mpQuadRule->GetWeight(quadrature_index);
474 const ChastePoint<DIM>& quadrature_point = mpQuadRule->rGetQuadPoint(quadrature_index);
483 c_vector<double,DIM> X = zero_vector<double>(DIM);
484 for (
unsigned vertex_index=0; vertex_index<NUM_VERTICES_PER_ELEMENT; vertex_index++)
486 for (
unsigned j=0; j<DIM; j++)
488 X(j) += linear_phi(vertex_index)*rElement.
GetNode(vertex_index)->rGetLocation()(j);
492 if (this->mAssembleVector)
494 c_vector<double,SPATIAL_BLOCK_SIZE_ELEMENTAL> b_spatial
495 = ComputeSpatialVectorTerm(quad_phi, grad_quad_phi, X, &rElement);
496 c_vector<double,PRESSURE_BLOCK_SIZE_ELEMENTAL> b_pressure = ComputePressureVectorTerm(linear_phi, grad_linear_phi, X, &rElement);
498 for (
unsigned i=0; i<SPATIAL_BLOCK_SIZE_ELEMENTAL; i++)
500 rBElem(i) += b_spatial(i)*wJ;
503 for (
unsigned i=0; i<PRESSURE_BLOCK_SIZE_ELEMENTAL; i++)
505 rBElem(SPATIAL_BLOCK_SIZE_ELEMENTAL + i) += b_pressure(i)*wJ;
509 if (this->mAssembleMatrix)
511 c_matrix<double,SPATIAL_BLOCK_SIZE_ELEMENTAL,SPATIAL_BLOCK_SIZE_ELEMENTAL> a_spatial_spatial
512 = ComputeSpatialSpatialMatrixTerm(quad_phi, grad_quad_phi, X, &rElement);
514 c_matrix<double,SPATIAL_BLOCK_SIZE_ELEMENTAL,PRESSURE_BLOCK_SIZE_ELEMENTAL> a_spatial_pressure
515 = ComputeSpatialPressureMatrixTerm(quad_phi, grad_quad_phi, linear_phi, grad_linear_phi, X, &rElement);
517 c_matrix<double,PRESSURE_BLOCK_SIZE_ELEMENTAL,SPATIAL_BLOCK_SIZE_ELEMENTAL> a_pressure_spatial;
518 if (!BLOCK_SYMMETRIC_MATRIX)
524 c_matrix<double,PRESSURE_BLOCK_SIZE_ELEMENTAL,PRESSURE_BLOCK_SIZE_ELEMENTAL> a_pressure_pressure
525 = ComputePressurePressureMatrixTerm(linear_phi, grad_linear_phi, X, &rElement);
527 for (
unsigned i=0; i<SPATIAL_BLOCK_SIZE_ELEMENTAL; i++)
529 for (
unsigned j=0; j<SPATIAL_BLOCK_SIZE_ELEMENTAL; j++)
531 rAElem(i,j) += a_spatial_spatial(i,j)*wJ;
534 for (
unsigned j=0; j<PRESSURE_BLOCK_SIZE_ELEMENTAL; j++)
536 rAElem(i, SPATIAL_BLOCK_SIZE_ELEMENTAL + j) += a_spatial_pressure(i,j)*wJ;
540 for (
unsigned i=0; i<PRESSURE_BLOCK_SIZE_ELEMENTAL; i++)
542 if (BLOCK_SYMMETRIC_MATRIX)
544 for (
unsigned j=0; j<SPATIAL_BLOCK_SIZE_ELEMENTAL; j++)
546 rAElem(SPATIAL_BLOCK_SIZE_ELEMENTAL + i, j) += a_spatial_pressure(j,i)*wJ;
554 for (
unsigned j=0; j<PRESSURE_BLOCK_SIZE_ELEMENTAL; j++)
556 rAElem(SPATIAL_BLOCK_SIZE_ELEMENTAL + i, SPATIAL_BLOCK_SIZE_ELEMENTAL + j) += a_pressure_pressure(i,j)*wJ;
563 #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
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)=0
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)
static const unsigned NUM_VERTICES_PER_ELEMENT