259 assert(this->mAssembleMatrix || this->mAssembleVector);
262 if (this->mAssembleMatrix)
264 assemble_event = HeartEventHandler::ASSEMBLE_SYSTEM;
268 assemble_event = HeartEventHandler::ASSEMBLE_RHS;
271 if (this->mAssembleMatrix && this->mMatrixToAssemble==
nullptr)
273 EXCEPTION(
"Matrix to be assembled has not been set");
275 if (this->mAssembleVector && this->mVectorToAssemble==
nullptr)
277 EXCEPTION(
"Vector to be assembled has not been set");
283 if (this->mAssembleVector && this->mZeroVectorBeforeAssembly)
287 if (this->mAssembleMatrix && this->mZeroMatrixBeforeAssembly)
292 const size_t STENCIL_SIZE=PROBLEM_DIM*(ELEMENT_DIM+1);
293 c_matrix<double, STENCIL_SIZE, STENCIL_SIZE> a_elem;
294 c_vector<double, STENCIL_SIZE> b_elem;
304 if (r_element.
GetOwnership() ==
true && ElementAssemblyCriterion(r_element)==
true)
306 AssembleOnElement(r_element, a_elem, b_elem);
308 unsigned p_indices[STENCIL_SIZE];
311 if (this->mAssembleMatrix)
313 PetscMatTools::AddMultipleValues<STENCIL_SIZE>(this->mMatrixToAssemble, p_indices, a_elem);
316 if (this->mAssembleVector)
318 PetscVecTools::AddMultipleValues<STENCIL_SIZE>(this->mVectorToAssemble, p_indices, b_elem);
347 c_matrix<
double, PROBLEM_DIM*(ELEMENT_DIM+1), PROBLEM_DIM*(ELEMENT_DIM+1) >& rAElem,
348 c_vector<
double, PROBLEM_DIM*(ELEMENT_DIM+1)>& rBElem)
355 c_matrix<double, SPACE_DIM, ELEMENT_DIM> jacobian;
356 c_matrix<double, ELEMENT_DIM, SPACE_DIM> inverse_jacobian;
357 double jacobian_determinant;
361 if (this->mAssembleMatrix)
366 if (this->mAssembleVector)
374 c_vector<double, ELEMENT_DIM+1> phi;
375 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1> grad_phi;
378 for (
unsigned quad_index=0; quad_index < mpQuadRule->
GetNumQuadPoints(); quad_index++)
382 BasisFunction::ComputeBasisFunctions(quad_point, phi);
384 if (this->mAssembleMatrix || INTERPOLATION_LEVEL==NONLINEAR)
386 ComputeTransformedBasisFunctionDerivatives(quad_point, inverse_jacobian, grad_phi);
393 c_vector<double,PROBLEM_DIM> u = zero_vector<double>(PROBLEM_DIM);
394 c_matrix<double,PROBLEM_DIM,SPACE_DIM> grad_u = zero_matrix<double>(PROBLEM_DIM,SPACE_DIM);
397 this->ResetInterpolatedQuantities();
400 for (
unsigned i=0; i<num_nodes; i++)
404 if (INTERPOLATION_LEVEL != CARDIAC)
406 const c_vector<double, SPACE_DIM>& r_node_loc = p_node->
rGetLocation();
408 x.rGetLocation() += phi(i)*r_node_loc;
413 if (this->mCurrentSolutionOrGuessReplicated.GetSize() > 0)
415 for (
unsigned index_of_unknown=0; index_of_unknown<(INTERPOLATION_LEVEL!=CARDIAC ? PROBLEM_DIM : 1); index_of_unknown++)
425 double u_at_node = this->GetCurrentSolutionOrGuessValue(node_global_index, index_of_unknown);
426 u(index_of_unknown) += phi(i)*u_at_node;
428 if (INTERPOLATION_LEVEL==NONLINEAR)
430 for (
unsigned j=0; j<SPACE_DIM; j++)
432 grad_u(index_of_unknown,j) += grad_phi(j,i)*u_at_node;
439 this->IncrementInterpolatedQuantities(phi(i), p_node);
440 if (this->mAssembleMatrix || INTERPOLATION_LEVEL==NONLINEAR)
442 this->IncrementInterpolatedGradientQuantities(grad_phi, i, p_node);
446 double wJ = jacobian_determinant * mpQuadRule->
GetWeight(quad_index);
449 if (this->mAssembleMatrix)
451 noalias(rAElem) += ComputeMatrixTerm(phi, grad_phi, x, u, grad_u, &rElement) * wJ;
454 if (this->mAssembleVector)
456 noalias(rBElem) += ComputeVectorTerm(phi, grad_phi, x, u, grad_u, &rElement) * wJ;