//------------------------------------------------------------------------------ void LocalAssembler::assemble_cell(Eigen::MatrixXd& A, UFC& ufc, const std::vector<double>& vertex_coordinates, const ufc::cell& ufc_cell, const Cell& cell, const MeshFunction<std::size_t>* domains) { // Skip if there are no cell integrals if (!ufc.form.has_cell_integrals()) return; // Extract default cell integral ufc::cell_integral* integral = ufc.default_cell_integral.get(); // Get integral for sub domain (if any) if (domains && !domains->empty()) integral = ufc.get_cell_integral((*domains)[cell]); // Skip integral if zero if (!integral) return; // Update to current cell ufc.update(cell, vertex_coordinates, ufc_cell, integral->enabled_coefficients()); // Tabulate cell tensor integral->tabulate_tensor(ufc.A.data(), ufc.w(), vertex_coordinates.data(), ufc_cell.orientation); // Stuff a_ufc.A into A const std::size_t M = A.rows(); const std::size_t N = A.cols(); for (std::size_t i = 0; i < M; i++) for (std::size_t j = 0; j < N; j++) A(i, j) += ufc.A[N*i + j]; }
//----------------------------------------------------------------------------- void Assembler::assemble_cells( GenericTensor& A, const Form& a, UFC& ufc, std::shared_ptr<const MeshFunction<std::size_t>> domains, std::vector<double>* values) { // Skip assembly if there are no cell integrals if (!ufc.form.has_cell_integrals()) return; // Set timer Timer timer("Assemble cells"); // Extract mesh const Mesh& mesh = a.mesh(); // Form rank const std::size_t form_rank = ufc.form.rank(); // Check if form is a functional const bool is_cell_functional = (values && form_rank == 0) ? true : false; // Collect pointers to dof maps std::vector<const GenericDofMap*> dofmaps; for (std::size_t i = 0; i < form_rank; ++i) dofmaps.push_back(a.function_space(i)->dofmap().get()); // Vector to hold dof map for a cell std::vector<ArrayView<const dolfin::la_index>> dofs(form_rank); // Cell integral ufc::cell_integral* integral = ufc.default_cell_integral.get(); // Check whether integral is domain-dependent bool use_domains = domains && !domains->empty(); // Assemble over cells ufc::cell ufc_cell; std::vector<double> coordinate_dofs; Progress p(AssemblerBase::progress_message(A.rank(), "cells"), mesh.num_cells()); for (CellIterator cell(mesh); !cell.end(); ++cell) { // Get integral for sub domain (if any) if (use_domains) integral = ufc.get_cell_integral((*domains)[*cell]); // Skip if no integral on current domain if (!integral) continue; // Check that cell is not a ghost dolfin_assert(!cell->is_ghost()); // Update to current cell cell->get_cell_data(ufc_cell); cell->get_coordinate_dofs(coordinate_dofs); ufc.update(*cell, coordinate_dofs, ufc_cell, integral->enabled_coefficients()); // Get local-to-global dof maps for cell bool empty_dofmap = false; for (std::size_t i = 0; i < form_rank; ++i) { dofs[i] = dofmaps[i]->cell_dofs(cell->index()); empty_dofmap = empty_dofmap || dofs[i].size() == 0; } // Skip if at least one dofmap is empty if (empty_dofmap) continue; // Tabulate cell tensor integral->tabulate_tensor(ufc.A.data(), ufc.w(), coordinate_dofs.data(), ufc_cell.orientation); // Add entries to global tensor. Either store values cell-by-cell // (currently only available for functionals) if (is_cell_functional) (*values)[cell->index()] = ufc.A[0]; else A.add_local(ufc.A.data(), dofs); p++; } }