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);
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;