36 #ifndef ABSTRACTFECABLEINTEGRALASSEMBLER_HPP_
37 #define ABSTRACTFECABLEINTEGRALASSEMBLER_HPP_
39 #include "AbstractFeAssemblerCommon.hpp"
40 #include "GaussianQuadratureRule.hpp"
41 #include "PetscVecTools.hpp"
42 #include "PetscMatTools.hpp"
50 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX, InterpolationLevel INTERPOLATION_LEVEL>
84 const c_matrix<double, CABLE_ELEMENT_DIM, SPACE_DIM>& rInverseJacobian,
85 c_matrix<double, SPACE_DIM, NUM_CABLE_ELEMENT_NODES>& rReturnValue);
117 c_vector<double, NUM_CABLE_ELEMENT_NODES>& rPhi,
118 c_matrix<double, SPACE_DIM, NUM_CABLE_ELEMENT_NODES>& rGradPhi,
120 c_vector<double,PROBLEM_DIM>& rU,
121 c_matrix<double, PROBLEM_DIM, SPACE_DIM>& rGradU,
151 c_vector<double, NUM_CABLE_ELEMENT_NODES>& rPhi,
152 c_matrix<double, SPACE_DIM, NUM_CABLE_ELEMENT_NODES>& rGradPhi,
154 c_vector<double,PROBLEM_DIM>& rU,
155 c_matrix<double, PROBLEM_DIM, SPACE_DIM>& rGradU,
179 c_matrix<double, PROBLEM_DIM*NUM_CABLE_ELEMENT_NODES, PROBLEM_DIM*NUM_CABLE_ELEMENT_NODES >& rAElem,
180 c_vector<double, PROBLEM_DIM*NUM_CABLE_ELEMENT_NODES>& rBElem);
215 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX, InterpolationLevel INTERPOLATION_LEVEL>
218 :
AbstractFeAssemblerCommon<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM, CAN_ASSEMBLE_VECTOR, CAN_ASSEMBLE_MATRIX, INTERPOLATION_LEVEL>(),
222 assert(CAN_ASSEMBLE_VECTOR || CAN_ASSEMBLE_MATRIX);
230 assert(INTERPOLATION_LEVEL!=NONLINEAR);
234 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX, InterpolationLevel INTERPOLATION_LEVEL>
238 if (this->mAssembleMatrix)
240 assemble_event = HeartEventHandler::ASSEMBLE_SYSTEM;
244 assemble_event = HeartEventHandler::ASSEMBLE_RHS;
247 if (this->mAssembleMatrix && this->mMatrixToAssemble==NULL)
249 EXCEPTION(
"Matrix to be assembled has not been set");
251 if (this->mAssembleVector && this->mVectorToAssemble==NULL)
253 EXCEPTION(
"Vector to be assembled has not been set");
260 if (this->mAssembleVector && this->mZeroVectorBeforeAssembly)
264 if (this->mAssembleMatrix && this->mZeroMatrixBeforeAssembly)
269 const size_t STENCIL_SIZE=PROBLEM_DIM*NUM_CABLE_ELEMENT_NODES;
270 c_matrix<double, STENCIL_SIZE, STENCIL_SIZE> a_elem;
271 c_vector<double, STENCIL_SIZE> b_elem;
274 if (this->mAssembleMatrix || this->mAssembleVector)
277 iter != mpMesh->GetCableElementIteratorEnd();
283 if ( r_element.
GetOwnership() ==
true && ElementAssemblyCriterion(r_element)==true )
285 AssembleOnCableElement(r_element, a_elem, b_elem);
287 unsigned p_indices[STENCIL_SIZE];
290 if (this->mAssembleMatrix)
292 PetscMatTools::AddMultipleValues<STENCIL_SIZE>(this->mMatrixToAssemble, p_indices, a_elem);
295 if (this->mAssembleVector)
297 PetscVecTools::AddMultipleValues<STENCIL_SIZE>(this->mVectorToAssemble, p_indices, b_elem);
310 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX, InterpolationLevel INTERPOLATION_LEVEL>
313 const c_matrix<double, CABLE_ELEMENT_DIM, SPACE_DIM>& rInverseJacobian,
314 c_matrix<double, SPACE_DIM, NUM_CABLE_ELEMENT_NODES>& rReturnValue)
316 static c_matrix<double, CABLE_ELEMENT_DIM, NUM_CABLE_ELEMENT_NODES> grad_phi;
319 rReturnValue = prod(trans(rInverseJacobian), grad_phi);
322 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM,
bool CAN_ASSEMBLE_VECTOR,
bool CAN_ASSEMBLE_MATRIX, InterpolationLevel INTERPOLATION_LEVEL>
325 c_matrix<double, PROBLEM_DIM*NUM_CABLE_ELEMENT_NODES, PROBLEM_DIM*NUM_CABLE_ELEMENT_NODES >& rAElem,
326 c_vector<double, PROBLEM_DIM*NUM_CABLE_ELEMENT_NODES>& rBElem)
333 c_matrix<double, SPACE_DIM, CABLE_ELEMENT_DIM> jacobian;
334 c_matrix<double, CABLE_ELEMENT_DIM, SPACE_DIM> inverse_jacobian;
335 double jacobian_determinant;
343 if (this->mAssembleMatrix)
348 if (this->mAssembleVector)
356 c_vector<double, NUM_CABLE_ELEMENT_NODES> phi;
357 c_matrix<double, SPACE_DIM, NUM_CABLE_ELEMENT_NODES> grad_phi;
360 for (
unsigned quad_index=0; quad_index < mpCableQuadRule->GetNumQuadPoints(); quad_index++)
364 CableBasisFunction::ComputeBasisFunctions(quad_point, phi);
366 if ( this->mAssembleMatrix || INTERPOLATION_LEVEL==NONLINEAR )
368 ComputeTransformedBasisFunctionDerivatives(quad_point, inverse_jacobian, grad_phi);
375 c_vector<double,PROBLEM_DIM> u = zero_vector<double>(PROBLEM_DIM);
376 c_matrix<double,PROBLEM_DIM,SPACE_DIM> grad_u = zero_matrix<double>(PROBLEM_DIM,SPACE_DIM);
379 this->ResetInterpolatedQuantities();
382 for (
unsigned i=0; i<num_nodes; i++)
386 if (INTERPOLATION_LEVEL != CARDIAC)
388 const c_vector<double, SPACE_DIM>& r_node_loc = p_node->
rGetLocation();
395 if (this->mCurrentSolutionOrGuessReplicated.GetSize() > 0)
397 for (
unsigned index_of_unknown=0; index_of_unknown<(INTERPOLATION_LEVEL!=CARDIAC ? PROBLEM_DIM : 1); index_of_unknown++)
407 double u_at_node = this->GetCurrentSolutionOrGuessValue(node_global_index, index_of_unknown);
408 u(index_of_unknown) += phi(i)*u_at_node;
422 this->IncrementInterpolatedQuantities(phi(i), p_node);
425 double wJ = jacobian_determinant * mpCableQuadRule->GetWeight(quad_index);
428 if (this->mAssembleMatrix)
430 noalias(rAElem) += ComputeCableMatrixTerm(phi, grad_phi, x, u, grad_u, &rElement) * wJ;
433 if (this->mAssembleVector)
435 noalias(rBElem) += ComputeCableVectorTerm(phi, grad_phi, x, u, grad_u, &rElement) * wJ;
c_vector< double, DIM > & rGetLocation()
virtual c_matrix< double, PROBLEM_DIM *NUM_CABLE_ELEMENT_NODES, PROBLEM_DIM *NUM_CABLE_ELEMENT_NODES > ComputeCableMatrixTerm(c_vector< double, NUM_CABLE_ELEMENT_NODES > &rPhi, c_matrix< double, SPACE_DIM, NUM_CABLE_ELEMENT_NODES > &rGradPhi, ChastePoint< SPACE_DIM > &rX, c_vector< double, PROBLEM_DIM > &rU, c_matrix< double, PROBLEM_DIM, SPACE_DIM > &rGradU, Element< CABLE_ELEMENT_DIM, SPACE_DIM > *pElement)
unsigned GetNodeGlobalIndex(unsigned localIndex) const
#define EXCEPTION(message)
static void BeginEvent(unsigned event)
static const unsigned NUM_CABLE_ELEMENT_NODES
static void ComputeBasisFunctionDerivatives(const ChastePoint< ELEMENT_DIM > &rPoint, c_matrix< double, ELEMENT_DIM, ELEMENT_DIM+1 > &rReturnValue)
void CalculateInverseJacobian(c_matrix< double, SPACE_DIM, ELEMENT_DIM > &rJacobian, double &rJacobianDeterminant, c_matrix< double, ELEMENT_DIM, SPACE_DIM > &rInverseJacobian)
Node< SPACE_DIM > * GetNode(unsigned localIndex) const
virtual ~AbstractFeCableIntegralAssembler()
bool GetOwnership() const
static const unsigned CABLE_ELEMENT_DIM
virtual bool ElementAssemblyCriterion(Element< CABLE_ELEMENT_DIM, SPACE_DIM > &rElement)
unsigned GetNumNodes() const
void GetStiffnessMatrixGlobalIndices(unsigned problemDim, unsigned *pIndices) const
LinearBasisFunction< 1 > CableBasisFunction
MixedDimensionMesh< ELEMENT_DIM, SPACE_DIM > * mpMesh
const c_vector< double, SPACE_DIM > & rGetLocation() const
virtual c_vector< double, PROBLEM_DIM *NUM_CABLE_ELEMENT_NODES > ComputeCableVectorTerm(c_vector< double, NUM_CABLE_ELEMENT_NODES > &rPhi, c_matrix< double, SPACE_DIM, NUM_CABLE_ELEMENT_NODES > &rGradPhi, ChastePoint< SPACE_DIM > &rX, c_vector< double, PROBLEM_DIM > &rU, c_matrix< double, PROBLEM_DIM, SPACE_DIM > &rGradU, Element< CABLE_ELEMENT_DIM, SPACE_DIM > *pElement)
void ComputeTransformedBasisFunctionDerivatives(const ChastePoint< CABLE_ELEMENT_DIM > &rPoint, const c_matrix< double, CABLE_ELEMENT_DIM, SPACE_DIM > &rInverseJacobian, c_matrix< double, SPACE_DIM, NUM_CABLE_ELEMENT_NODES > &rReturnValue)
AbstractFeCableIntegralAssembler(MixedDimensionMesh< ELEMENT_DIM, SPACE_DIM > *pMesh)
virtual void AssembleOnCableElement(Element< CABLE_ELEMENT_DIM, SPACE_DIM > &rElement, c_matrix< double, PROBLEM_DIM *NUM_CABLE_ELEMENT_NODES, PROBLEM_DIM *NUM_CABLE_ELEMENT_NODES > &rAElem, c_vector< double, PROBLEM_DIM *NUM_CABLE_ELEMENT_NODES > &rBElem)
static void EndEvent(unsigned event)
GaussianQuadratureRule< 1 > * mpCableQuadRule
std::vector< Element< 1, SPACE_DIM > * >::const_iterator CableElementIterator