void ADRAssembler< mesh_type, matrix_type, vector_type>:: addMassRhs (vector_type& rhs, const vector_type& f) { // f has to be repeated! if (f.mapType() == Unique) { addMassRhs (rhs, vector_type (f, Repeated) ); return; } // Check that the fespace is set ASSERT (M_fespace != 0, "No FE space for assembling the right hand side (mass)!"); M_massRhsAssemblyChrono.start(); // Some constants const UInt nbElements (M_fespace->mesh()->numElements() ); const UInt fieldDim (M_fespace->fieldDim() ); const UInt nbFEDof (M_massRhsCFE->nbFEDof() ); const UInt nbQuadPt (M_massRhsCFE->nbQuadPt() ); const UInt nbTotalDof (M_fespace->dof().numTotalDof() ); // Temporaries Real localValue (0.0); std::vector<Real> fValues (nbQuadPt, 0.0); // Loop over the elements for (UInt iterElement (0); iterElement < nbElements; ++iterElement) { // Update the diffusion current FE M_massRhsCFE->update ( M_fespace->mesh()->element (iterElement), UPDATE_PHI | UPDATE_WDET ); // Clean the local matrix M_localMassRhs->zero(); // Assemble the local diffusion for (UInt iterFDim (0); iterFDim < fieldDim; ++iterFDim) { localVector_type::vector_view localView = M_localMassRhs->block (iterFDim); // Compute the value of f in the quadrature nodes for (UInt iQuadPt (0); iQuadPt < nbQuadPt; ++iQuadPt) { fValues[iQuadPt] = 0.0; for (UInt iDof (0); iDof < nbFEDof ; ++iDof) { fValues[iQuadPt] += f[ M_fespace->dof().localToGlobalMap (iterElement, iDof) + iterFDim * nbTotalDof] * M_massRhsCFE->phi (iDof, iQuadPt); } } // Loop over the basis functions for (UInt iDof (0); iDof < nbFEDof ; ++iDof) { localValue = 0.0; //Loop on the quadrature nodes for (UInt iQuadPt (0); iQuadPt < nbQuadPt; ++iQuadPt) { localValue += fValues[iQuadPt] * M_massRhsCFE->phi (iDof, iQuadPt) * M_massRhsCFE->wDetJacobian (iQuadPt); } // Add on the local matrix localView (iDof) = localValue; } } // Here add in the global rhs for (UInt iterFDim (0); iterFDim < fieldDim; ++iterFDim) { assembleVector ( rhs, iterElement, *M_localMassRhs, nbFEDof, M_fespace->dof(), iterFDim, iterFDim * M_fespace->dof().numTotalDof() ); } } M_massRhsAssemblyChrono.stop(); }
void ADRAssembler< mesh_type, matrix_type, vector_type>:: addAdvection (matrix_ptrType matrix, const vector_type& beta, const UInt& offsetLeft, const UInt& offsetUp) { // Beta has to be repeated! if (beta.mapType() == Unique) { addAdvection (matrix, vector_type (beta, Repeated), offsetLeft, offsetUp); return; } // Check that the fespace is set ASSERT (M_fespace != 0, "No FE space for assembling the advection!"); ASSERT (M_betaFESpace != 0, "No FE space (beta) for assembling the advection!"); M_advectionAssemblyChrono.start(); // Some constants const UInt nbElements (M_fespace->mesh()->numElements() ); const UInt fieldDim (M_fespace->fieldDim() ); const UInt betaFieldDim (M_betaFESpace->fieldDim() ); const UInt nbTotalDof (M_fespace->dof().numTotalDof() ); const UInt nbQuadPt (M_advCFE->nbQuadPt() ); // Temporaries //Real localValue(0); std::vector< std::vector< Real > > localBetaValue (nbQuadPt, std::vector<Real> ( betaFieldDim, 0.0 ) ); // Loop over the elements for (UInt iterElement (0); iterElement < nbElements; ++iterElement) { // Update the advection current FEs M_advCFE->update ( M_fespace->mesh()->element (iterElement), UPDATE_PHI | UPDATE_DPHI | UPDATE_WDET ); M_advBetaCFE->update (M_fespace->mesh()->element (iterElement), UPDATE_PHI ); // Clean the local matrix M_localAdv->zero(); // Interpolate beta in the quadrature points AssemblyElemental::interpolate (localBetaValue, *M_advBetaCFE, betaFieldDim, M_betaFESpace->dof(), iterElement, beta); // Assemble the advection AssemblyElemental::advection (*M_localAdv, *M_advCFE, 1.0, localBetaValue, fieldDim); // Assembly for (UInt iFieldDim (0); iFieldDim < fieldDim; ++iFieldDim) { assembleMatrix ( *matrix, *M_localAdv, *M_advCFE, *M_advCFE, M_fespace->dof(), M_fespace->dof(), iFieldDim, iFieldDim, iFieldDim * nbTotalDof + offsetLeft, iFieldDim * nbTotalDof + offsetUp ); } } M_advectionAssemblyChrono.stop(); }