36 #ifndef ABSTRACTFEVOLUMEINTEGRALASSEMBLER_HPP_
37 #define ABSTRACTFEVOLUMEINTEGRALASSEMBLER_HPP_
39 #include "AbstractFeAssemblerCommon.hpp"
40 #include "GaussianQuadratureRule.hpp"
41 #include "BoundaryConditionsContainer.hpp"
42 #include "PetscVecTools.hpp"
43 #include "PetscMatTools.hpp"
77 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX, InterpolationLevel INTERPOLATION_LEVEL>
79 public AbstractFeAssemblerCommon<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM,CAN_ASSEMBLE_VECTOR,CAN_ASSEMBLE_MATRIX,INTERPOLATION_LEVEL>
111 const c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian,
112 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1>& rReturnValue);
142 virtual c_matrix<double,PROBLEM_DIM*(ELEMENT_DIM+1),PROBLEM_DIM*(ELEMENT_DIM+1)>
ComputeMatrixTerm(
143 c_vector<double, ELEMENT_DIM+1>& rPhi,
144 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1>& rGradPhi,
146 c_vector<double,PROBLEM_DIM>& rU,
147 c_matrix<double, PROBLEM_DIM, SPACE_DIM>& rGradU,
153 return zero_matrix<double>(PROBLEM_DIM*(ELEMENT_DIM+1),PROBLEM_DIM*(ELEMENT_DIM+1));
176 c_vector<double, ELEMENT_DIM+1>& rPhi,
177 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1>& rGradPhi,
179 c_vector<double,PROBLEM_DIM>& rU,
180 c_matrix<double, PROBLEM_DIM, SPACE_DIM>& rGradU,
186 return zero_vector<double>(PROBLEM_DIM*(ELEMENT_DIM+1));
205 c_matrix<
double, PROBLEM_DIM*(ELEMENT_DIM+1), PROBLEM_DIM*(ELEMENT_DIM+1) >& rAElem,
206 c_vector<
double, PROBLEM_DIM*(ELEMENT_DIM+1)>& rBElem);
239 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX, InterpolationLevel INTERPOLATION_LEVEL>
242 :
AbstractFeAssemblerCommon<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM, CAN_ASSEMBLE_VECTOR, CAN_ASSEMBLE_MATRIX, INTERPOLATION_LEVEL>(),
254 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX, InterpolationLevel INTERPOLATION_LEVEL>
257 assert(this->mAssembleMatrix || this->mAssembleVector);
260 if (this->mAssembleMatrix)
262 assemble_event = HeartEventHandler::ASSEMBLE_SYSTEM;
266 assemble_event = HeartEventHandler::ASSEMBLE_RHS;
269 if (this->mAssembleMatrix && this->mMatrixToAssemble==NULL)
271 EXCEPTION(
"Matrix to be assembled has not been set");
273 if (this->mAssembleVector && this->mVectorToAssemble==NULL)
275 EXCEPTION(
"Vector to be assembled has not been set");
281 if (this->mAssembleVector && this->mZeroVectorBeforeAssembly)
285 if (this->mAssembleMatrix && this->mZeroMatrixBeforeAssembly)
290 const size_t STENCIL_SIZE=PROBLEM_DIM*(ELEMENT_DIM+1);
291 c_matrix<double, STENCIL_SIZE, STENCIL_SIZE> a_elem;
292 c_vector<double, STENCIL_SIZE> b_elem;
296 iter != mpMesh->GetElementIteratorEnd();
302 if ( r_element.
GetOwnership() ==
true && ElementAssemblyCriterion(r_element)==true )
304 AssembleOnElement(r_element, a_elem, b_elem);
306 unsigned p_indices[STENCIL_SIZE];
309 if (this->mAssembleMatrix)
311 PetscMatTools::AddMultipleValues<STENCIL_SIZE>(this->mMatrixToAssemble, p_indices, a_elem);
314 if (this->mAssembleVector)
316 PetscVecTools::AddMultipleValues<STENCIL_SIZE>(this->mVectorToAssemble, p_indices, b_elem);
329 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX, InterpolationLevel INTERPOLATION_LEVEL>
332 const c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian,
333 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1>& rReturnValue)
335 assert(ELEMENT_DIM < 4 && ELEMENT_DIM > 0);
336 static c_matrix<double, ELEMENT_DIM, ELEMENT_DIM+1> grad_phi;
339 rReturnValue = prod(trans(rInverseJacobian), grad_phi);
342 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX, InterpolationLevel INTERPOLATION_LEVEL>
345 c_matrix<
double, PROBLEM_DIM*(ELEMENT_DIM+1), PROBLEM_DIM*(ELEMENT_DIM+1) >& rAElem,
346 c_vector<
double, PROBLEM_DIM*(ELEMENT_DIM+1)>& rBElem)
353 c_matrix<double, SPACE_DIM, ELEMENT_DIM> jacobian;
354 c_matrix<double, ELEMENT_DIM, SPACE_DIM> inverse_jacobian;
355 double jacobian_determinant;
357 mpMesh->GetInverseJacobianForElement(rElement.
GetIndex(), jacobian, jacobian_determinant, inverse_jacobian);
359 if (this->mAssembleMatrix)
364 if (this->mAssembleVector)
372 c_vector<double, ELEMENT_DIM+1> phi;
373 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1> grad_phi;
376 for (
unsigned quad_index=0; quad_index < mpQuadRule->GetNumQuadPoints(); quad_index++)
380 BasisFunction::ComputeBasisFunctions(quad_point, phi);
382 if ( this->mAssembleMatrix || INTERPOLATION_LEVEL==NONLINEAR )
384 ComputeTransformedBasisFunctionDerivatives(quad_point, inverse_jacobian, grad_phi);
391 c_vector<double,PROBLEM_DIM> u = zero_vector<double>(PROBLEM_DIM);
392 c_matrix<double,PROBLEM_DIM,SPACE_DIM> grad_u = zero_matrix<double>(PROBLEM_DIM,SPACE_DIM);
395 this->ResetInterpolatedQuantities();
398 for (
unsigned i=0; i<num_nodes; i++)
402 if (INTERPOLATION_LEVEL != CARDIAC)
404 const c_vector<double, SPACE_DIM>& r_node_loc = p_node->
rGetLocation();
411 if (this->mCurrentSolutionOrGuessReplicated.GetSize() > 0)
413 for (
unsigned index_of_unknown=0; index_of_unknown<(INTERPOLATION_LEVEL!=CARDIAC ? PROBLEM_DIM : 1); index_of_unknown++)
423 double u_at_node = this->GetCurrentSolutionOrGuessValue(node_global_index, index_of_unknown);
424 u(index_of_unknown) += phi(i)*u_at_node;
426 if (INTERPOLATION_LEVEL==NONLINEAR)
428 for (
unsigned j=0; j<SPACE_DIM; j++)
430 grad_u(index_of_unknown,j) += grad_phi(j,i)*u_at_node;
437 this->IncrementInterpolatedQuantities(phi(i), p_node);
438 if ( this->mAssembleMatrix || INTERPOLATION_LEVEL==NONLINEAR )
440 this->IncrementInterpolatedGradientQuantities(grad_phi, i, p_node);
444 double wJ = jacobian_determinant * mpQuadRule->GetWeight(quad_index);
447 if (this->mAssembleMatrix)
449 noalias(rAElem) += ComputeMatrixTerm(phi, grad_phi, x, u, grad_u, &rElement) * wJ;
452 if (this->mAssembleVector)
454 noalias(rBElem) += ComputeVectorTerm(phi, grad_phi, x, u, grad_u, &rElement) * wJ;
virtual ~AbstractFeVolumeIntegralAssembler()
c_vector< double, DIM > & rGetLocation()
unsigned GetNodeGlobalIndex(unsigned localIndex) const
#define EXCEPTION(message)
static void BeginEvent(unsigned event)
LinearBasisFunction< ELEMENT_DIM > BasisFunction
static void ComputeBasisFunctionDerivatives(const ChastePoint< ELEMENT_DIM > &rPoint, c_matrix< double, ELEMENT_DIM, ELEMENT_DIM+1 > &rReturnValue)
virtual c_vector< double, PROBLEM_DIM *(ELEMENT_DIM+1)> ComputeVectorTerm(c_vector< double, ELEMENT_DIM+1 > &rPhi, c_matrix< double, SPACE_DIM, ELEMENT_DIM+1 > &rGradPhi, ChastePoint< SPACE_DIM > &rX, c_vector< double, PROBLEM_DIM > &rU, c_matrix< double, PROBLEM_DIM, SPACE_DIM > &rGradU, Element< ELEMENT_DIM, SPACE_DIM > *pElement)
Node< SPACE_DIM > * GetNode(unsigned localIndex) const
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * mpMesh
bool GetOwnership() const
GaussianQuadratureRule< ELEMENT_DIM > * mpQuadRule
unsigned GetNumNodes() const
void GetStiffnessMatrixGlobalIndices(unsigned problemDim, unsigned *pIndices) const
virtual void AssembleOnElement(Element< ELEMENT_DIM, SPACE_DIM > &rElement, c_matrix< double, PROBLEM_DIM *(ELEMENT_DIM+1), PROBLEM_DIM *(ELEMENT_DIM+1) > &rAElem, c_vector< double, PROBLEM_DIM *(ELEMENT_DIM+1)> &rBElem)
virtual bool ElementAssemblyCriterion(Element< ELEMENT_DIM, SPACE_DIM > &rElement)
void ComputeTransformedBasisFunctionDerivatives(const ChastePoint< ELEMENT_DIM > &rPoint, const c_matrix< double, ELEMENT_DIM, SPACE_DIM > &rInverseJacobian, c_matrix< double, SPACE_DIM, ELEMENT_DIM+1 > &rReturnValue)
const c_vector< double, SPACE_DIM > & rGetLocation() const
virtual c_matrix< double, PROBLEM_DIM *(ELEMENT_DIM+1), PROBLEM_DIM *(ELEMENT_DIM+1)> ComputeMatrixTerm(c_vector< double, ELEMENT_DIM+1 > &rPhi, c_matrix< double, SPACE_DIM, ELEMENT_DIM+1 > &rGradPhi, ChastePoint< SPACE_DIM > &rX, c_vector< double, PROBLEM_DIM > &rU, c_matrix< double, PROBLEM_DIM, SPACE_DIM > &rGradU, Element< ELEMENT_DIM, SPACE_DIM > *pElement)
unsigned GetIndex() const
static void EndEvent(unsigned event)
AbstractFeVolumeIntegralAssembler(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > *pMesh)