Exemplo n.º 1
0
//------------------------------------------------------------------------------
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];
}
Exemplo n.º 2
0
//-----------------------------------------------------------------------------
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++;
  }
}