Beispiel #1
0
//-----------------------------------------------------------------------------
SubSpace::SubSpace(const FunctionSpace& V,
                   const std::vector<std::size_t>& component)
    : FunctionSpace(V.mesh(), V.element(), V.dofmap())
{
    // Extract subspace and assign
    std::shared_ptr<FunctionSpace> _function_space(V.extract_sub_space(component));
    *static_cast<FunctionSpace*>(this) = *_function_space;
}
Beispiel #2
0
Probe::Probe(const Array<double>& x, const FunctionSpace& V) :
  _element(V.element()), _num_evals(0)
{

  const Mesh& mesh = *V.mesh();
  std::size_t gdim = mesh.geometry().dim();
    
  // Find the cell that contains probe
  const Point point(gdim, x.data());
  unsigned int cell_id = mesh.bounding_box_tree()->compute_first_entity_collision(point);

  // If the cell is on this process, then create an instance 
  // of the Probe class. Otherwise raise a dolfin_error.
  if (cell_id != std::numeric_limits<unsigned int>::max())
  {
    // Store position of probe
    for (std::size_t i = 0; i < 3; i++) 
      _x[i] = (i < gdim ? x[i] : 0.0);
    
    // Compute in tensor (one for scalar function, . . .)
    _value_size_loc = 1;
    for (std::size_t i = 0; i < _element->value_rank(); i++)
       _value_size_loc *= _element->value_dimension(i);

    _probes.resize(_value_size_loc);

    // Create cell that contains point
    dolfin_cell.reset(new Cell(mesh, cell_id));
    dolfin_cell->get_cell_data(ufc_cell);
    
    coefficients.resize(_element->space_dimension());
    
    // Cell vertices
    dolfin_cell->get_vertex_coordinates(vertex_coordinates);
        
    // Create work vector for basis
    basis_matrix.resize(_value_size_loc);
    for (std::size_t i = 0; i < _value_size_loc; ++i)
      basis_matrix[i].resize(_element->space_dimension());
        
    std::vector<double> basis(_value_size_loc);
    const int cell_orientation = 0;
    for (std::size_t i = 0; i < _element->space_dimension(); ++i)
    {
      _element->evaluate_basis(i, &basis[0], &x[0], 
                               vertex_coordinates.data(), 
                               cell_orientation);
      for (std::size_t j = 0; j < _value_size_loc; ++j)
        basis_matrix[j][i] = basis[j];
    }
  }  
  else
  {  
    dolfin_error("Probe.cpp","set probe","Probe is not found on processor");
  }
}
Beispiel #3
0
//-----------------------------------------------------------------------------
SubSpace::SubSpace(const FunctionSpace& V,
                   std::size_t component,
                   std::size_t sub_component)
    : FunctionSpace(V.mesh(), V.element(), V.dofmap())
{
    // Create array
    std::vector<std::size_t> c = {{component, sub_component}};

    // Extract subspace and assign
    std::shared_ptr<FunctionSpace> _function_space(V.extract_sub_space(c));
    *static_cast<FunctionSpace*>(this) = *_function_space;
}
StatisticsProbes::StatisticsProbes(const Array<double>& x, const FunctionSpace& V, bool segregated)
{
  const std::size_t Nd = V.mesh()->geometry().dim();
  const std::size_t N = x.size() / Nd;
  Array<double> _x(Nd);
  total_number_probes = N;
  _num_evals = 0;
  _value_size = 1;
  for (std::size_t i = 0; i < V.element()->value_rank(); i++)
    _value_size *= V.element()->value_dimension(i);
  
  if (segregated)
  {
    assert(V.element()->value_rank() == 0);
    _value_size *= V.element()->geometric_dimension();
  }
    
  // Symmetric statistics. Velocity: u, v, w, uu, vv, ww, uv, uw, vw
  _value_size = _value_size*(_value_size+3)/2.;

  for (std::size_t i=0; i<N; i++)
  {
    for (std::size_t j=0; j<Nd; j++)
      _x[j] = x[i*Nd + j];
    try
    {
      StatisticsProbe* probe = new StatisticsProbe(_x, V, segregated);
      std::pair<std::size_t, StatisticsProbe*> newprobe = std::make_pair(i, &(*probe));
      _allprobes.push_back(newprobe);
    } 
    catch (std::exception &e)
    { // do-nothing
    }
  }
  //cout << local_size() << " of " << N  << " probes found on processor " << MPI::process_number() << endl;
}
Beispiel #5
0
 void extract_dof_component_map(std::map<std::size_t, std::size_t>& dof_component_map, 
                                const FunctionSpace& VV, int* component)
 { // Extract sub dofmaps recursively and store dof to component map
   boost::unordered_map<std::size_t, std::size_t> collapsed_map;
   boost::unordered_map<std::size_t, std::size_t>::iterator map_it;
   std::vector<std::size_t> comp(1);
   
   if (VV.element()->num_sub_elements() == 0)
   {
     boost::shared_ptr<GenericDofMap> dummy = VV.dofmap()->collapse(collapsed_map, *VV.mesh());
     (*component)++;
     for (map_it =collapsed_map.begin(); map_it!=collapsed_map.end(); ++map_it)
       dof_component_map[map_it->second] = (*component);  
   }
   else
   {
     for (std::size_t i=0; i<VV.element()->num_sub_elements(); i++)
     {
       comp[0] = i;
       boost::shared_ptr<FunctionSpace> Vs = VV.extract_sub_space(comp);
       extract_dof_component_map(dof_component_map, *Vs, component);
     }
   }
 }
Beispiel #6
0
//-----------------------------------------------------------------------------
void
Extrapolation::add_cell_equations(Eigen::MatrixXd& A,
                                  Eigen::VectorXd& b,
                                  const Cell& cell0,
                                  const Cell& cell1,
                                  const std::vector<double>& coordinate_dofs0,
                                  const std::vector<double>& coordinate_dofs1,
                                  const ufc::cell& c0,
                                  const ufc::cell& c1,
                                  const FunctionSpace& V,
                                  const FunctionSpace& W,
                                  const Function& v,
                                  std::map<std::size_t, std::size_t>& dof2row)
{
  // Extract coefficients for v on patch cell
  dolfin_assert(V.element());
  std::vector<double> dof_values(V.element()->space_dimension());
  v.restrict(&dof_values[0], *V.element(), cell1, coordinate_dofs1.data(),
             c1);

  // Create basis function
  dolfin_assert(W.element());
  BasisFunction phi(0, W.element(), coordinate_dofs0);

  // Iterate over given local dofs for V on patch cell
  for (auto const &it : dof2row)
  {
    const std::size_t i = it.first;
    const std::size_t row = it.second;

    // Iterate over basis functions for W on center cell
    for (std::size_t j = 0; j < W.element()->space_dimension(); ++j)
    {
      // Create basis function
      phi.update_index(j);

      // Evaluate dof on basis function
      const double dof_value
        = V.element()->evaluate_dof(i, phi,  coordinate_dofs1.data(),
                                    c1.orientation, c1);

      // Insert dof_value into matrix
      A(row, j) = dof_value;
    }

    // Insert coefficient into vector
    b[row] = dof_values[i];
  }
}
Beispiel #7
0
//-----------------------------------------------------------------------------
void Extrapolation::add_cell_equations(arma::Mat<double>& A,
                                       arma::Col<double>& b,
                                       const Cell& cell0,
                                       const Cell& cell1,
                                       const ufc::cell& c0,
                                       const ufc::cell& c1,
                                       const FunctionSpace& V,
                                       const FunctionSpace& W,
                                       const Function& v,
                                       std::map<std::size_t, std::size_t>& dof2row)
{
  // Extract coefficents for v on patch cell
  dolfin_assert(V.element());
  std::vector<double> dof_values(V.element()->space_dimension());
  v.restrict(&dof_values[0], *V.element(), cell1, c1);

  // Iterate over given local dofs for V on patch cell
  dolfin_assert(W.element());
  for (std::map<std::size_t, std::size_t>::iterator it = dof2row.begin(); it!= dof2row.end(); it++)
  {
    const std::size_t i = it->first;
    const std::size_t row = it->second;

    // Iterate over basis functions for W on center cell
    for (std::size_t j = 0; j < W.element()->space_dimension(); ++j)
    {

      // Create basis function
      const BasisFunction phi(j, *W.element(), c0);

      // Evaluate dof on basis function
      const int cell_orientation = 0;
      const double dof_value = V.element()->evaluate_dof(i,
                                                         phi,
                                                         &c1.vertex_coordinates[0],
                                                         cell_orientation,
                                                         c1);

      // Insert dof_value into matrix
      A(row, j) = dof_value;
    }

    // Insert coefficient into vector
    b[row] = dof_values[i];
  }
}
Beispiel #8
0
//-----------------------------------------------------------------------------
void Extrapolation::compute_coefficients(
  std::vector<std::vector<double>>& coefficients,
  const Function& v,
  const FunctionSpace& V,
  const FunctionSpace& W,
  const Cell& cell0,
  const std::vector<double>& coordinate_dofs0,
  const ufc::cell& c0,
  const ArrayView<const dolfin::la_index>& dofs,
  std::size_t& offset)
{
  // Call recursively for mixed elements
  dolfin_assert(V.element());
  const std::size_t num_sub_spaces = V.element()->num_sub_elements();
  if (num_sub_spaces > 0)
  {
    for (std::size_t k = 0; k < num_sub_spaces; k++)
    {
      compute_coefficients(coefficients, v[k], *V[k], *W[k], cell0,
                           coordinate_dofs0, c0, dofs, offset);
    }
    return;
  }

  // Build data structures for keeping track of unique dofs
  std::map<std::size_t, std::map<std::size_t, std::size_t>> cell2dof2row;
  std::set<std::size_t> unique_dofs;
  build_unique_dofs(unique_dofs, cell2dof2row, cell0, V);

  // Compute size of linear system
  dolfin_assert(W.element());
  const std::size_t N = W.element()->space_dimension();
  const std::size_t M = unique_dofs.size();

  // Check size of system
  if (M < N)
  {
    dolfin_error("Extrapolation.cpp",
                 "compute extrapolation",
                 "Not enough degrees of freedom on local patch to build extrapolation");
  }

  // Create matrix and vector for linear system
  Eigen::MatrixXd A(M, N);
  Eigen::VectorXd b(M);

  // Add equations on cell and neighboring cells
  dolfin_assert(V.mesh());
  ufc::cell c1;
  std::vector<double> coordinate_dofs1;

  // Get unique set of surrounding cells (including cell0)
  std::set<std::size_t> cell_set;
  for (VertexIterator vtx(cell0); !vtx.end(); ++vtx)
  {
    for (CellIterator cell1(*vtx); !cell1.end(); ++cell1)
      cell_set.insert(cell1->index());
  }

  for (auto cell_it : cell_set)
  {
    if (cell2dof2row[cell_it].empty())
      continue;

    Cell cell1(cell0.mesh(), cell_it);

    cell1.get_coordinate_dofs(coordinate_dofs1);
    cell1.get_cell_data(c1);
    add_cell_equations(A, b, cell0, cell1,
                       coordinate_dofs0, coordinate_dofs1,
                       c0, c1, V, W, v,
                       cell2dof2row[cell_it]);
  }

  // Solve least squares system
  const Eigen::VectorXd x
    = A.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(b);

  // Insert resulting coefficients into global coefficient vector
  dolfin_assert(W.dofmap());
  for (std::size_t i = 0; i < W.dofmap()->num_element_dofs(cell0.index()); ++i)
    coefficients[dofs[i + offset]].push_back(x[i]);

  // Increase offset
  offset += W.dofmap()->num_element_dofs(cell0.index());
}
Beispiel #9
0
//-----------------------------------------------------------------------------
void Extrapolation::compute_coefficients(std::vector<std::vector<double> >& coefficients,
                                         const Function& v,
                                         const FunctionSpace& V,
                                         const FunctionSpace& W,
                                         const Cell& cell0,
                                         const ufc::cell& c0,
                                         const std::vector<dolfin::la_index>& dofs,
                                         std::size_t& offset)
{
  // Call recursively for mixed elements
  dolfin_assert(V.element());
  const std::size_t num_sub_spaces = V.element()->num_sub_elements();
  if (num_sub_spaces > 0)
  {
    for (std::size_t k = 0; k < num_sub_spaces; k++)
    {
      compute_coefficients(coefficients, v[k], *V[k], *W[k], cell0, c0,
                           dofs, offset);
    }
    return;
  }

  // Build data structures for keeping track of unique dofs
  std::map<std::size_t, std::map<std::size_t, std::size_t> > cell2dof2row;
  std::set<std::size_t> unique_dofs;
  build_unique_dofs(unique_dofs, cell2dof2row, cell0, c0, V);

  // Compute size of linear system
  dolfin_assert(W.element());
  const std::size_t N = W.element()->space_dimension();
  const std::size_t M = unique_dofs.size();

  // Check size of system
  if (M < N)
  {
    dolfin_error("Extrapolation.cpp",
                 "compute extrapolation",
                 "Not enough degrees of freedom on local patch to build extrapolation");
  }

  // Create matrix and vector for linear system
  arma::mat A(M, N);
  arma::vec b(M);

  // Add equations on cell and neighboring cells
  add_cell_equations(A, b, cell0, cell0, c0, c0, V, W, v, cell2dof2row[cell0.index()]);
  dolfin_assert(V.mesh());
  UFCCell c1(*V.mesh());
  for (CellIterator cell1(cell0); !cell1.end(); ++cell1)
  {
    if (cell2dof2row[cell1->index()].empty())
      continue;

    c1.update(*cell1);
    add_cell_equations(A, b, cell0, *cell1, c0, c1, V, W, v, cell2dof2row[cell1->index()]);
  }

  // Solve least squares system
  arma::Col<double> x = arma::solve(A, b);

  // Insert resulting coefficients into global coefficient vector
  dolfin_assert(W.dofmap());
  for (std::size_t i = 0; i < W.dofmap()->cell_dimension(cell0.index()); ++i)
    coefficients[dofs[i + offset]].push_back(x[i]);

  // Increase offset
  offset += W.dofmap()->cell_dimension(cell0.index());
}