public:
Implicit(const FullMatrix<double> &matrix);
void operator() (AnyData &out, const AnyData &in);
-
- private:
+
+private:
SmartPointer<const FullMatrix<double>, Implicit> matrix;
FullMatrix<double> m;
};
void
Explicit::operator() (AnyData &out, const AnyData &in)
{
- const double timestep = *in.read_ptr<double>("Timestep");
+ const double timestep = *in.read_ptr<double>("Timestep");
if (this->notifications.test(Events::initial) || this->notifications.test(Events::new_timestep_size))
{
m.equ(-timestep, *matrix);
}
this->notifications.clear();
m.vmult(*out.entry<Vector<double>*>(0),
- *in.read_ptr<Vector<double> >("Previous iterate"));
+ *in.read_ptr<Vector<double> >("Previous iterate"));
}
void
Implicit::operator() (AnyData &out, const AnyData &in)
{
- const double timestep = *in.read_ptr<double>("Timestep");
+ const double timestep = *in.read_ptr<double>("Timestep");
if (this->notifications.test(Events::initial) || this->notifications.test(Events::new_timestep_size))
{
m.equ(timestep, *matrix);
}
this->notifications.clear();
m.vmult(*out.entry<Vector<double>*>(0),
- *in.read_ptr<Vector<double> >("Previous time"));
+ *in.read_ptr<Vector<double> >("Previous time"));
}
cell = triangulation.begin_active(),
endc = triangulation.end();
for (; cell!=endc; ++cell)
- {
- // @note Writing a loop like this requires a lot of typing, but it
- // is the only way of doing it in C++98 and C++03. However, if you
- // have a C++11-compliant compiler, you can also use the C++11
- // range-based for loop style that requires significantly less
- // typing. Take a look at @ref CPP11 "the deal.II C++11 page" to see
- // how this works.
- //
- // Next, we want to loop over all vertices of the cells. Since we are
- // in 2d, we know that each cell has exactly four vertices. However,
- // instead of penning down a 4 in the loop bound, we make a first
- // attempt at writing it in a dimension-independent way by which we
- // find out about the number of vertices of a cell. Using the
- // GeometryInfo class, we will later have an easier time getting the
- // program to also run in 3d: we only have to change all occurrences
- // of <code><2></code> to <code><3></code>, and do not
- // have to audit our code for the hidden appearance of magic numbers
- // like a 4 that needs to be replaced by an 8:
- for (unsigned int v=0;
- v < GeometryInfo<2>::vertices_per_cell;
- ++v)
- {
- // If this cell is at the inner boundary, then at least one of its
- // vertices must sit on the inner ring and therefore have a radial
- // distance from the center of exactly 0.5, up to floating point
- // accuracy. Compute this distance, and if we have found a vertex
- // with this property flag this cell for later refinement. We can
- // then also break the loop over all vertices and move on to the
- // next cell.
- const double distance_from_center
- = center.distance (cell->vertex(v));
-
- if (std::fabs(distance_from_center - inner_radius) < 1e-10)
- {
- cell->set_refine_flag ();
- break;
- }
- }
- }
-
+ {
+ // @note Writing a loop like this requires a lot of typing, but it
+ // is the only way of doing it in C++98 and C++03. However, if you
+ // have a C++11-compliant compiler, you can also use the C++11
+ // range-based for loop style that requires significantly less
+ // typing. Take a look at @ref CPP11 "the deal.II C++11 page" to see
+ // how this works.
+ //
+ // Next, we want to loop over all vertices of the cells. Since we are
+ // in 2d, we know that each cell has exactly four vertices. However,
+ // instead of penning down a 4 in the loop bound, we make a first
+ // attempt at writing it in a dimension-independent way by which we
+ // find out about the number of vertices of a cell. Using the
+ // GeometryInfo class, we will later have an easier time getting the
+ // program to also run in 3d: we only have to change all occurrences
+ // of <code><2></code> to <code><3></code>, and do not
+ // have to audit our code for the hidden appearance of magic numbers
+ // like a 4 that needs to be replaced by an 8:
+ for (unsigned int v=0;
+ v < GeometryInfo<2>::vertices_per_cell;
+ ++v)
+ {
+ // If this cell is at the inner boundary, then at least one of its
+ // vertices must sit on the inner ring and therefore have a radial
+ // distance from the center of exactly 0.5, up to floating point
+ // accuracy. Compute this distance, and if we have found a vertex
+ // with this property flag this cell for later refinement. We can
+ // then also break the loop over all vertices and move on to the
+ // next cell.
+ const double distance_from_center
+ = center.distance (cell->vertex(v));
+
+ if (std::fabs(distance_from_center - inner_radius) < 1e-10)
+ {
+ cell->set_refine_flag ();
+ break;
+ }
+ }
+ }
+
// Now that we have marked all the cells that we want refined, we let
// the triangulation actually do this refinement. The function that does
// so owes its long name to the fact that one can also mark cells for
GridOut grid_out;
grid_out.write_eps (triangulation, out);
- std::cout << "Grid written to grid-2.eps" << std::endl;
+ std::cout << "Grid written to grid-2.eps" << std::endl;
// At this point, all objects created in this function will be destroyed in
// reverse order. Unfortunately, we defined the boundary object after the
// calls the virtual function assembling the right hand side.
struct AssemblyScratchData
{
- AssemblyScratchData (const FiniteElement<dim> &fe,
- const Quadrature<dim> &quadrature);
- AssemblyScratchData (const AssemblyScratchData &scratch_data);
+ AssemblyScratchData (const FiniteElement<dim> &fe,
+ const Quadrature<dim> &quadrature);
+ AssemblyScratchData (const AssemblyScratchData &scratch_data);
- FEValues<dim> fe_values;
+ FEValues<dim> fe_values;
};
struct AssemblyCopyData
{
- FullMatrix<double> cell_matrix;
- std::vector<types::global_dof_index> local_dof_indices;
+ FullMatrix<double> cell_matrix;
+ std::vector<types::global_dof_index> local_dof_indices;
};
void
void
local_assemble_matrix (const typename DoFHandler<dim>::active_cell_iterator &cell,
- AssemblyScratchData &scratch_data,
- AssemblyCopyData ©_data) const;
+ AssemblyScratchData &scratch_data,
+ AssemblyCopyData ©_data) const;
void
copy_local_to_global(const AssemblyCopyData ©_data,
Solver<dim>::assemble_linear_system (LinearSystem &linear_system)
{
Threads::Task<> rhs_task = Threads::new_task (&Solver<dim>::assemble_rhs,
- *this,
- linear_system.rhs);
+ *this,
+ linear_system.rhs);
WorkStream::run(dof_handler.begin_active(),
- dof_handler.end(),
- std_cxx1x::bind(&Solver<dim>::local_assemble_matrix,
- this,
- std_cxx1x::_1,
- std_cxx1x::_2,
- std_cxx1x::_3),
- std_cxx1x::bind(&Solver<dim>::copy_local_to_global,
- this,
- std_cxx1x::_1,
- std_cxx1x::ref(linear_system)),
- AssemblyScratchData(*fe, *quadrature),
- AssemblyCopyData());
+ dof_handler.end(),
+ std_cxx1x::bind(&Solver<dim>::local_assemble_matrix,
+ this,
+ std_cxx1x::_1,
+ std_cxx1x::_2,
+ std_cxx1x::_3),
+ std_cxx1x::bind(&Solver<dim>::copy_local_to_global,
+ this,
+ std_cxx1x::_1,
+ std_cxx1x::ref(linear_system)),
+ AssemblyScratchData(*fe, *quadrature),
+ AssemblyCopyData());
linear_system.hanging_node_constraints.condense (linear_system.matrix);
// The syntax above using <code>std_cxx1x::bind</code> requires
template <int dim>
Solver<dim>::AssemblyScratchData::
AssemblyScratchData (const FiniteElement<dim> &fe,
- const Quadrature<dim> &quadrature)
- :
- fe_values (fe,
- quadrature,
- update_gradients | update_JxW_values)
+ const Quadrature<dim> &quadrature)
+ :
+ fe_values (fe,
+ quadrature,
+ update_gradients | update_JxW_values)
{}
template <int dim>
Solver<dim>::AssemblyScratchData::
AssemblyScratchData (const AssemblyScratchData &scratch_data)
- :
- fe_values (scratch_data.fe_values.get_fe(),
- scratch_data.fe_values.get_quadrature(),
- update_gradients | update_JxW_values)
+ :
+ fe_values (scratch_data.fe_values.get_fe(),
+ scratch_data.fe_values.get_quadrature(),
+ update_gradients | update_JxW_values)
{}
template <int dim>
void
Solver<dim>::local_assemble_matrix (const typename DoFHandler<dim>::active_cell_iterator &cell,
- AssemblyScratchData &scratch_data,
- AssemblyCopyData ©_data) const
+ AssemblyScratchData &scratch_data,
+ AssemblyCopyData ©_data) const
{
const unsigned int dofs_per_cell = fe->dofs_per_cell;
const unsigned int n_q_points = quadrature->size();
for (unsigned int i=0; i<dofs_per_cell; ++i)
for (unsigned int j=0; j<dofs_per_cell; ++j)
copy_data.cell_matrix(i,j) += (scratch_data.fe_values.shape_grad(i,q_point) *
- scratch_data.fe_values.shape_grad(j,q_point) *
- scratch_data.fe_values.JxW(q_point));
+ scratch_data.fe_values.shape_grad(j,q_point) *
+ scratch_data.fe_values.JxW(q_point));
cell->get_dof_indices (copy_data.local_dof_indices);
}
LinearSystem &linear_system) const
{
for (unsigned int i=0; i<copy_data.local_dof_indices.size(); ++i)
- for (unsigned int j=0; j<copy_data.local_dof_indices.size(); ++j)
- linear_system.matrix.add (copy_data.local_dof_indices[i],
- copy_data.local_dof_indices[j],
- copy_data.cell_matrix(i,j));
+ for (unsigned int j=0; j<copy_data.local_dof_indices.size(); ++j)
+ linear_system.matrix.add (copy_data.local_dof_indices[i],
+ copy_data.local_dof_indices[j],
+ copy_data.cell_matrix(i,j));
}
hanging_node_constraints.clear ();
void (*mhnc_p) (const DoFHandler<dim> &,
- ConstraintMatrix &)
+ ConstraintMatrix &)
= &DoFTools::make_hanging_node_constraints;
// Start a side task then continue on the main thread
Threads::Task<> side_task(std_cxx1x::bind(mhnc_p,std_cxx1x::cref(dof_handler),
- std_cxx1x::ref(hanging_node_constraints)));
+ std_cxx1x::ref(hanging_node_constraints)));
sparsity_pattern.reinit (dof_handler.n_dofs(),
dof_handler.n_dofs(),
for (unsigned int i = 0; i < dofs_per_cell; ++i)
cell_residual(i) -= (fe_values.shape_grad(i, q_point)
- * coeff
- * gradients[q_point]
- * fe_values.JxW(q_point));
+ * coeff
+ * gradients[q_point]
+ * fe_values.JxW(q_point));
}
cell->get_dof_indices (local_dof_indices);
{
public:
LaplaceIntegrator();
- virtual void cell(MeshWorker::DoFInfo<dim> &dinfo, MeshWorker::IntegrationInfo<dim> &info) const;
+ virtual void cell(MeshWorker::DoFInfo<dim> &dinfo, MeshWorker::IntegrationInfo<dim> &info) const;
};
// LocalIntegrators::Laplace::cell_matrix() or
// LocalIntegrators::L2::L2(). Since we are assembling only a single
// PDE, there is also only one of these objects with index zero.
-
+
// In addition, we note that this integrator serves to compute the
// matrices for the multilevel preconditioner as well as the matrix
// and the right hand side for the global system. Since the
dof_handler.distribute_mg_dofs (fe);
deallog << " Number of degrees of freedom: "
- << dof_handler.n_dofs()
- << " (by level: ";
+ << dof_handler.n_dofs()
+ << " (by level: ";
for (unsigned int level=0; level<triangulation.n_levels(); ++level)
deallog << dof_handler.n_dofs(level)
- << (level == triangulation.n_levels()-1
- ? ")" : ", ");
+ << (level == triangulation.n_levels()-1
+ ? ")" : ", ");
deallog << std::endl;
sparsity_pattern.reinit (dof_handler.n_dofs(),
refine_grid ();
deallog << " Number of active cells: "
- << triangulation.n_active_cells()
- << std::endl;
+ << triangulation.n_active_cells()
+ << std::endl;
setup_system ();
// step number, and finally the processor id (encoded as a three digit
// number):
std::string filename = "solution-" + Utilities::int_to_string(timestep_no,4)
- + "." + Utilities::int_to_string(this_mpi_process,3)
- + ".vtu";
-
+ + "." + Utilities::int_to_string(this_mpi_process,3)
+ + ".vtu";
+
// The following assertion makes sure that there are less than 1000
// processes (a very conservative check, but worth having anyway) as our
// scheme of generating process numbers would overflow if there were 1000
// the largest computations with the most processors in optimized mode,
// and we should check our assumptions in this particular case, and not
// only when running in debug mode:
- AssertThrow (n_mpi_processes < 1000, ExcNotImplemented());
+ AssertThrow (n_mpi_processes < 1000, ExcNotImplemented());
// With the so-completed filename, let us open a file and write the data
// we have generated into it:
// so we do this on processor 0:
if (this_mpi_process==0)
{
- // Here we collect all filenames of the current timestep (same format as above)
- std::vector<std::string> filenames;
+ // Here we collect all filenames of the current timestep (same format as above)
+ std::vector<std::string> filenames;
for (unsigned int i=0; i<n_mpi_processes; ++i)
filenames.push_back ("solution-" + Utilities::int_to_string(timestep_no,4)
- + "." + Utilities::int_to_string(i,3)
- + ".vtu");
+ + "." + Utilities::int_to_string(i,3)
+ + ".vtu");
- // Now we write the .visit file. The naming is similar to the .vtu files, only
- // that the file obviously doesn't contain a processor id.
+ // Now we write the .visit file. The naming is similar to the .vtu files, only
+ // that the file obviously doesn't contain a processor id.
const std::string
visit_master_filename = ("solution-" +
- Utilities::int_to_string(timestep_no,4) +
+ Utilities::int_to_string(timestep_no,4) +
".visit");
std::ofstream visit_master (visit_master_filename.c_str());
data_out.write_visit_record (visit_master, filenames);
- // Similarly, we write the paraview .pvtu:
+ // Similarly, we write the paraview .pvtu:
const std::string
pvtu_master_filename = ("solution-" +
- Utilities::int_to_string(timestep_no,4) +
+ Utilities::int_to_string(timestep_no,4) +
".pvtu");
std::ofstream pvtu_master (pvtu_master_filename.c_str());
data_out.write_pvtu_record (pvtu_master, filenames);
- // Finally, we write the paraview record, that references all .pvtu files and
- // their respective time. Note that the variable times_and_names is declared
- // static, so it will retain the entries from the pervious timesteps.
- static std::vector<std::pair<double,std::string> > times_and_names;
- times_and_names.push_back (std::pair<double,std::string> (present_time, pvtu_master_filename));
- std::ofstream pvd_output ("solution.pvd");
- data_out.write_pvd_record (pvd_output, times_and_names);
+ // Finally, we write the paraview record, that references all .pvtu files and
+ // their respective time. Note that the variable times_and_names is declared
+ // static, so it will retain the entries from the pervious timesteps.
+ static std::vector<std::pair<double,std::string> > times_and_names;
+ times_and_names.push_back (std::pair<double,std::string> (present_time, pvtu_master_filename));
+ std::ofstream pvd_output ("solution.pvd");
+ data_out.write_pvd_record (pvd_output, times_and_names);
}
-
+
}
}
- // For the right-hand side we use the fact that the shape
- // functions are only non-zero in one component (because our
- // elements are primitive). Instead of multiplying the tensor
- // representing the dim+1 values of shape function i with the
- // whole right-hand side vector, we only look at the only
- // non-zero component. The Function
- // FiniteElement::system_to_component_index(i) will return
- // which component this shape function lives in (0=x velocity,
- // 1=y velocity, 2=pressure in 2d), which we use to pick out
- // the correct component of the right-hand side vector to
- // multiply with.
+ // For the right-hand side we use the fact that the shape
+ // functions are only non-zero in one component (because our
+ // elements are primitive). Instead of multiplying the tensor
+ // representing the dim+1 values of shape function i with the
+ // whole right-hand side vector, we only look at the only
+ // non-zero component. The Function
+ // FiniteElement::system_to_component_index(i) will return
+ // which component this shape function lives in (0=x velocity,
+ // 1=y velocity, 2=pressure in 2d), which we use to pick out
+ // the correct component of the right-hand side vector to
+ // multiply with.
const unsigned int component_i =
fe.system_to_component_index(i).first;
{}
virtual double value (const Point<dim> &p,
- const unsigned int component = 0) const;
+ const unsigned int component = 0) const;
private:
const double period;
template<int dim>
double RightHandSide<dim>::value (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component == 0, ExcInternalError());
Assert (dim == 2, ExcNotImplemented());
{
public:
virtual double value (const Point<dim> &p,
- const unsigned int component = 0) const;
+ const unsigned int component = 0) const;
};
-
+
template<int dim>
double BoundaryValues<dim>::value (const Point<dim> &/*p*/,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert(component == 0, ExcInternalError());
return 0;
// global right hand side to zero, before we fill them:
cell_matrix = 0;
cell_rhs = 0;
-
+
// Now it is time to start integration over the cell, which we
// do by looping over all quadrature points, which we will
// number by q_index.
for (unsigned int q_index=0; q_index<n_q_points; ++q_index)
- {
- // First assemble the matrix: For the Laplace problem, the
- // matrix on each cell is the integral over the gradients of
- // shape function i and j. Since we do not integrate, but
- // rather use quadrature, this is the sum over all
- // quadrature points of the integrands times the determinant
- // of the Jacobian matrix at the quadrature point times the
- // weight of this quadrature point. You can get the gradient
- // of shape function $i$ at quadrature point with number q_index by
- // using <code>fe_values.shape_grad(i,q_index)</code>; this
- // gradient is a 2-dimensional vector (in fact it is of type
- // Tensor@<1,dim@>, with here dim=2) and the product of two
- // such vectors is the scalar product, i.e. the product of
- // the two shape_grad function calls is the dot
- // product. This is in turn multiplied by the Jacobian
- // determinant and the quadrature point weight (that one
- // gets together by the call to FEValues::JxW() ). Finally,
- // this is repeated for all shape functions $i$ and $j$:
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- cell_matrix(i,j) += (fe_values.shape_grad (i, q_index) *
- fe_values.shape_grad (j, q_index) *
- fe_values.JxW (q_index));
-
- // We then do the same thing for the right hand side. Here,
- // the integral is over the shape function i times the right
- // hand side function, which we choose to be the function
- // with constant value one (more interesting examples will
- // be considered in the following programs).
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- cell_rhs(i) += (fe_values.shape_value (i, q_index) *
- 1 *
- fe_values.JxW (q_index));
- }
+ {
+ // First assemble the matrix: For the Laplace problem, the
+ // matrix on each cell is the integral over the gradients of
+ // shape function i and j. Since we do not integrate, but
+ // rather use quadrature, this is the sum over all
+ // quadrature points of the integrands times the determinant
+ // of the Jacobian matrix at the quadrature point times the
+ // weight of this quadrature point. You can get the gradient
+ // of shape function $i$ at quadrature point with number q_index by
+ // using <code>fe_values.shape_grad(i,q_index)</code>; this
+ // gradient is a 2-dimensional vector (in fact it is of type
+ // Tensor@<1,dim@>, with here dim=2) and the product of two
+ // such vectors is the scalar product, i.e. the product of
+ // the two shape_grad function calls is the dot
+ // product. This is in turn multiplied by the Jacobian
+ // determinant and the quadrature point weight (that one
+ // gets together by the call to FEValues::JxW() ). Finally,
+ // this is repeated for all shape functions $i$ and $j$:
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ cell_matrix(i,j) += (fe_values.shape_grad (i, q_index) *
+ fe_values.shape_grad (j, q_index) *
+ fe_values.JxW (q_index));
+
+ // We then do the same thing for the right hand side. Here,
+ // the integral is over the shape function i times the right
+ // hand side function, which we choose to be the function
+ // with constant value one (more interesting examples will
+ // be considered in the following programs).
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ cell_rhs(i) += (fe_values.shape_value (i, q_index) *
+ 1 *
+ fe_values.JxW (q_index));
+ }
// Now that we have the contribution of this cell, we have to transfer
// it to the global matrix and right hand side. To this end, we first
// have to find out which global numbers the degrees of freedom on this
double global_temperature[2];
for (unsigned int i=distributed_temperature_solution.local_range().first;
- i < distributed_temperature_solution.local_range().second; ++i)
+ i < distributed_temperature_solution.local_range().second; ++i)
{
temperature[0] = std::min<double> (temperature[0],
distributed_temperature_solution(i));
{
switch (parameters.solver)
{
- // If the parameter file specified that a direct solver shall be used,
- // then we'll get here. The process is straightforward, since deal.II
- // provides a wrapper class to the Amesos direct solver within
- // Trilinos. All we have to do is to create a solver control object
- // (which is just a dummy object here, since we won't perform any
- // iterations), and then create the direct solver object. When
- // actually doing the solve, note that we don't pass a
- // preconditioner. That wouldn't make much sense for a direct solver
- // anyway. At the end we return the solver control statistics —
- // which will tell that no iterations have been performed and that the
- // final linear residual is zero, absent any better information that
- // may be provided here:
+ // If the parameter file specified that a direct solver shall be used,
+ // then we'll get here. The process is straightforward, since deal.II
+ // provides a wrapper class to the Amesos direct solver within
+ // Trilinos. All we have to do is to create a solver control object
+ // (which is just a dummy object here, since we won't perform any
+ // iterations), and then create the direct solver object. When
+ // actually doing the solve, note that we don't pass a
+ // preconditioner. That wouldn't make much sense for a direct solver
+ // anyway. At the end we return the solver control statistics —
+ // which will tell that no iterations have been performed and that the
+ // final linear residual is zero, absent any better information that
+ // may be provided here:
case Parameters::Solver::direct:
{
SolverControl solver_control (1,0);
// We've chosen by default a SSOR preconditioner as it appears to
// provide the fastest solver convergence characteristics for this
// problem on a single-thread machine. However, this might not be
- // true for different problem sizes.
+ // true for different problem sizes.
PreconditionSelector<SparseMatrix<double>, Vector<double> >
preconditioner (parameters.preconditioner_type,
parameters.preconditioner_relaxation);
template <>
const Point<1>
SolutionBase<1>::source_centers[SolutionBase<1>::n_source_centers]
- = { Point<1>(-1.0 / 3.0),
- Point<1>(0.0),
- Point<1>(+1.0 / 3.0)
- };
+ = { Point<1>(-1.0 / 3.0),
+ Point<1>(0.0),
+ Point<1>(+1.0 / 3.0)
+ };
template <>
const Point<2>
SolutionBase<2>::source_centers[SolutionBase<2>::n_source_centers]
- = { Point<2>(-0.5, +0.5),
- Point<2>(-0.5, -0.5),
- Point<2>(+0.5, -0.5)
- };
+ = { Point<2>(-0.5, +0.5),
+ Point<2>(-0.5, -0.5),
+ Point<2>(+0.5, -0.5)
+ };
template <>
const Point<3>
SolutionBase<3>::source_centers[SolutionBase<3>::n_source_centers]
- = { Point<3>(-0.5, +0.5, 0.25),
- Point<3>(-0.6, -0.5, -0.125),
- Point<3>(+0.5, -0.5, 0.5)
- };
+ = { Point<3>(-0.5, +0.5, 0.25),
+ Point<3>(-0.6, -0.5, -0.125),
+ Point<3>(+0.5, -0.5, 0.5)
+ };
template <int dim>
const double SolutionBase<dim>::width = 1./5.;
// Dirichlet boundary conditions, just as in a continuous Galerkin finite
// element method. We can enforce the boundary conditions in an analogous
// manner through the use of <code>ConstrainMatrix</code> constructs. In
- // addition, hanging nodes are handled in the same way as for
+ // addition, hanging nodes are handled in the same way as for
// continuous finite elements: For the face elements which
// only define degrees of freedom on the face, this process sets the
// solution on the refined to be the one from the coarse side.
for (unsigned int q=0; q<n_q_points; ++q)
{
const double rhs_value
- = scratch.right_hand_side.value(scratch.fe_values_local.quadrature_point(q));
+ = scratch.right_hand_side.value(scratch.fe_values_local.quadrature_point(q));
const Tensor<1,dim> convection
- = scratch.convection_velocity.value(scratch.fe_values_local.quadrature_point(q));
+ = scratch.convection_velocity.value(scratch.fe_values_local.quadrature_point(q));
const double JxW = scratch.fe_values_local.JxW(q);
for (unsigned int k=0; k<loc_dofs_per_cell; ++k)
{
scratch.fe_face_values.quadrature_point(q);
const Point<dim> normal = scratch.fe_face_values.normal_vector(q);
const Tensor<1,dim> convection
- = scratch.convection_velocity.value(quadrature_point);
+ = scratch.convection_velocity.value(quadrature_point);
// Here we compute the stabilization parameter discussed in the
// introduction: since the diffusion is one and the diffusion
const unsigned int jj=scratch.fe_local_support_on_face[face][j];
scratch.ll_matrix(ii,jj) += tau_stab * scratch.u_phi[i] * scratch.u_phi[j] * JxW;
}
-
+
// When @p trace_reconstruct=true, we are solving for the local
// solutions on an element by element basis. The local
// right-hand-side is calculated by replacing the basis functions @p
component_interpretation
(dim+1, DataComponentInterpretation::component_is_part_of_vector);
component_interpretation[dim]
- = DataComponentInterpretation::component_is_scalar;
+ = DataComponentInterpretation::component_is_scalar;
data_out.add_data_vector (dof_handler_local, solution_local,
names, component_interpretation);
// this class are not new and have been explained in previous tutorials.
class Diffusion
{
- public:
- Diffusion();
-
- void run();
-
- private:
- void setup_system();
-
- void assemble_system();
-
- double get_source(double time,const Point<2> &point) const;
-
- // This function evaluates the diffusion equation $M^{-1}(f(t,y))$ at a given time and
- // for a given y.
- Vector<double> evaluate_diffusion(const double time, const Vector<double> &y) const;
-
- // Evaluate $\left(I-\tau M^{-1} \frac{\partial f(t,y)}{\partial y}\right)^{-1}$ or
- // equivalently $\left(M-\tau \frac{\partial f}{\partial y}\right)^{-1} M$ at a given
- // time, for a given $\tau$ and y.
- Vector<double> id_minus_tau_J_inverse(const double time,
- const double tau,
- const Vector<double> &y);
-
- void output_results(unsigned int time_step,TimeStepping::runge_kutta_method method) const;
-
- // The next three functions are the driver for the explicit methods, the
- // implicit methods, and the embedded explicit methods respectively. The
- // driver function for embedded explicit methods returns the number of
- // steps executed since this number is adapted.
- void explicit_method(TimeStepping::runge_kutta_method method,
- const unsigned int n_time_steps,
- const double initial_time,
- const double final_time);
-
- void implicit_method(TimeStepping::runge_kutta_method method,
- const unsigned int n_time_steps,
- const double initial_time,
- const double final_time);
-
- unsigned int embedded_explicit_method(TimeStepping::runge_kutta_method method,
- const unsigned int n_time_steps,
- const double initial_time,
- const double final_time);
-
-
- unsigned int fe_degree;
-
- double diffusion_coefficient;
- double absorption_xs;
-
- Triangulation<2> triangulation;
-
- FE_Q<2> fe;
-
- DoFHandler<2> dof_handler;
-
- ConstraintMatrix constraint_matrix;
-
- SparsityPattern sparsity_pattern;
-
- SparseMatrix<double> system_matrix;
- SparseMatrix<double> mass_matrix;
- SparseMatrix<double> mass_minus_tau_Jacobian;
-
- SparseDirectUMFPACK inverse_mass_matrix;
-
- Vector<double> solution;
+ public:
+ Diffusion();
+
+ void run();
+
+ private:
+ void setup_system();
+
+ void assemble_system();
+
+ double get_source(double time,const Point<2> &point) const;
+
+ // This function evaluates the diffusion equation $M^{-1}(f(t,y))$ at a given time and
+ // for a given y.
+ Vector<double> evaluate_diffusion(const double time, const Vector<double> &y) const;
+
+ // Evaluate $\left(I-\tau M^{-1} \frac{\partial f(t,y)}{\partial y}\right)^{-1}$ or
+ // equivalently $\left(M-\tau \frac{\partial f}{\partial y}\right)^{-1} M$ at a given
+ // time, for a given $\tau$ and y.
+ Vector<double> id_minus_tau_J_inverse(const double time,
+ const double tau,
+ const Vector<double> &y);
+
+ void output_results(unsigned int time_step,TimeStepping::runge_kutta_method method) const;
+
+ // The next three functions are the driver for the explicit methods, the
+ // implicit methods, and the embedded explicit methods respectively. The
+ // driver function for embedded explicit methods returns the number of
+ // steps executed since this number is adapted.
+ void explicit_method(TimeStepping::runge_kutta_method method,
+ const unsigned int n_time_steps,
+ const double initial_time,
+ const double final_time);
+
+ void implicit_method(TimeStepping::runge_kutta_method method,
+ const unsigned int n_time_steps,
+ const double initial_time,
+ const double final_time);
+
+ unsigned int embedded_explicit_method(TimeStepping::runge_kutta_method method,
+ const unsigned int n_time_steps,
+ const double initial_time,
+ const double final_time);
+
+
+ unsigned int fe_degree;
+
+ double diffusion_coefficient;
+ double absorption_xs;
+
+ Triangulation<2> triangulation;
+
+ FE_Q<2> fe;
+
+ DoFHandler<2> dof_handler;
+
+ ConstraintMatrix constraint_matrix;
+
+ SparsityPattern sparsity_pattern;
+
+ SparseMatrix<double> system_matrix;
+ SparseMatrix<double> mass_matrix;
+ SparseMatrix<double> mass_minus_tau_Jacobian;
+
+ SparseDirectUMFPACK inverse_mass_matrix;
+
+ Vector<double> solution;
};
// We choose quadratic finite elements and we initialize the parameters.
Diffusion::Diffusion()
:
- fe_degree(2),
- diffusion_coefficient(1./30.),
- absorption_xs(1.),
- fe(fe_degree),
- dof_handler(triangulation)
+ fe_degree(2),
+ diffusion_coefficient(1./30.),
+ absorption_xs(1.),
+ fe(fe_degree),
+ dof_handler(triangulation)
{}
// @sect5{<code>Diffusion::assemble_system</code>}
- // In this function, we compute
- // $-\int D \nabla b_i \cdot \nabla b_j d\boldsymbol{r} - \int \Sigma_a b_i b_j d\boldsymbol{r}$
+ // In this function, we compute
+ // $-\int D \nabla b_i \cdot \nabla b_j d\boldsymbol{r} - \int \Sigma_a b_i b_j d\boldsymbol{r}$
// and the mass matrix $\int b_i b_j d\boldsymbol{r}$. The mass matrix is then
// inverted using a direct solver.
void Diffusion::assemble_system()
const QGauss<2> quadrature_formula(fe_degree+1);
FEValues<2> fe_values(fe, quadrature_formula,
- update_values | update_gradients | update_JxW_values);
+ update_values | update_gradients | update_JxW_values);
const unsigned int dofs_per_cell = fe.dofs_per_cell;
typename DoFHandler<2>::active_cell_iterator
cell = dof_handler.begin_active(),
endc = dof_handler.end();
-
- for (; cell!=endc; ++cell)
- {
- cell_matrix = 0.;
- cell_mass_matrix = 0.;
-
- fe_values.reinit (cell);
-
- for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- {
- cell_matrix(i,j) += ((-diffusion_coefficient * fe_values.shape_grad(i,q_point) *
- fe_values.shape_grad(j,q_point) - absorption_xs *
- fe_values.shape_value(i,q_point) * fe_values.shape_value(j,q_point)) *
- fe_values.JxW(q_point));
- cell_mass_matrix(i,j) += fe_values.shape_value(i,q_point) *
- fe_values.shape_value(j,q_point) *
- fe_values.JxW(q_point);
- }
-
- cell->get_dof_indices(local_dof_indices);
- constraint_matrix.distribute_local_to_global(cell_matrix,local_dof_indices,system_matrix);
- constraint_matrix.distribute_local_to_global(cell_mass_matrix,local_dof_indices,mass_matrix);
- }
+ for (; cell!=endc; ++cell)
+ {
+ cell_matrix = 0.;
+ cell_mass_matrix = 0.;
+
+ fe_values.reinit (cell);
+
+ for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ {
+ cell_matrix(i,j) += ((-diffusion_coefficient * fe_values.shape_grad(i,q_point) *
+ fe_values.shape_grad(j,q_point) - absorption_xs *
+ fe_values.shape_value(i,q_point) * fe_values.shape_value(j,q_point)) *
+ fe_values.JxW(q_point));
+ cell_mass_matrix(i,j) += fe_values.shape_value(i,q_point) *
+ fe_values.shape_value(j,q_point) *
+ fe_values.JxW(q_point);
+ }
+
+ cell->get_dof_indices(local_dof_indices);
+
+ constraint_matrix.distribute_local_to_global(cell_matrix,local_dof_indices,system_matrix);
+ constraint_matrix.distribute_local_to_global(cell_mass_matrix,local_dof_indices,mass_matrix);
+ }
inverse_mass_matrix.initialize(mass_matrix);
}
double source = 0.;
source = intensity*(frequency*std::cos(frequency*time)*(b*x-x*x) + std::sin(frequency*time) *
- (absorption_xs*(b*x-x*x)+2.*diffusion_coefficient));
-
+ (absorption_xs*(b*x-x*x)+2.*diffusion_coefficient));
+
return source;
}
const QGauss<2> quadrature_formula(fe_degree+1);
FEValues<2> fe_values(fe, quadrature_formula,
- update_values | update_quadrature_points | update_JxW_values);
+ update_values | update_quadrature_points | update_JxW_values);
const unsigned int dofs_per_cell = fe.dofs_per_cell;
typename DoFHandler<2>::active_cell_iterator
cell = dof_handler.begin_active(),
endc = dof_handler.end();
-
+
for (; cell!=endc; ++cell)
- {
- cell_source = 0.;
+ {
+ cell_source = 0.;
- fe_values.reinit (cell);
+ fe_values.reinit (cell);
- for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
- {
- double source = get_source(time,fe_values.quadrature_point(q_point)) ;
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- cell_source(i) += source * fe_values.shape_value(i,q_point) *
- fe_values.JxW(q_point);
- }
+ for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
+ {
+ double source = get_source(time,fe_values.quadrature_point(q_point)) ;
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ cell_source(i) += source * fe_values.shape_value(i,q_point) *
+ fe_values.JxW(q_point);
+ }
- cell->get_dof_indices(local_dof_indices);
+ cell->get_dof_indices(local_dof_indices);
+
+ constraint_matrix.distribute_local_to_global(cell_source,local_dof_indices,tmp);
+ }
- constraint_matrix.distribute_local_to_global(cell_source,local_dof_indices,tmp);
- }
-
Vector<double> value(dof_handler.n_dofs());
inverse_mass_matrix.vmult(value,tmp);
// is done in several steps:
// - compute $M-\tau \frac{\partial f}{\partial y}$
// - inverse the matrix to get $\left(M-\tau \frac{\partial f}{\partial y}\right)^{-1}$
- // - compute $tmp=My$
- // - compute $\left(M-\tau \frac{\partial f}{\partial y}\right)^{-1} tmp = \left(M-\tau \frac{\partial f}{\partial y}\right)^{-1} My$.
- Vector<double> Diffusion::id_minus_tau_J_inverse(const double time, const double tau,
- const Vector<double> &y)
+ // - compute $tmp=My$
+ // - compute $\left(M-\tau \frac{\partial f}{\partial y}\right)^{-1} tmp = \left(M-\tau \frac{\partial f}{\partial y}\right)^{-1} My$.
+ Vector<double> Diffusion::id_minus_tau_J_inverse(const double time, const double tau,
+ const Vector<double> &y)
{
Vector<double> tmp(dof_handler.n_dofs());
Vector<double> result(y);
mass_minus_tau_Jacobian.copy_from(mass_matrix);
mass_minus_tau_Jacobian.add(-tau,system_matrix);
-
+
inverse_mass_minus_tau_Jacobian.initialize(mass_minus_tau_Jacobian);
mass_matrix.vmult(tmp,y);
std::string method_name;
switch (method)
- {
+ {
case TimeStepping::FORWARD_EULER :
- {
- method_name = "forward_euler";
- break;
- }
+ {
+ method_name = "forward_euler";
+ break;
+ }
case TimeStepping::RK_THIRD_ORDER :
- {
- method_name = "rk3";
- break;
- }
+ {
+ method_name = "rk3";
+ break;
+ }
case TimeStepping::RK_CLASSIC_FOURTH_ORDER :
- {
- method_name = "rk4";
- break;
- }
+ {
+ method_name = "rk4";
+ break;
+ }
case TimeStepping::BACKWARD_EULER :
- {
- method_name = "backward_euler";
- break;
- }
+ {
+ method_name = "backward_euler";
+ break;
+ }
case TimeStepping::IMPLICIT_MIDPOINT :
- {
- method_name = "implicit_midpoint";
- break;
- }
+ {
+ method_name = "implicit_midpoint";
+ break;
+ }
case TimeStepping::SDIRK_TWO_STAGES :
- {
- method_name = "sdirk";
- break;
- }
+ {
+ method_name = "sdirk";
+ break;
+ }
case TimeStepping::HEUN_EULER :
- {
- method_name = "heun_euler";
- break;
- }
+ {
+ method_name = "heun_euler";
+ break;
+ }
case TimeStepping::BOGACKI_SHAMPINE :
- {
- method_name = "bocacki_shampine";
- break;
- }
+ {
+ method_name = "bocacki_shampine";
+ break;
+ }
case TimeStepping::DOPRI :
- {
- method_name = "dopri";
- break;
- }
+ {
+ method_name = "dopri";
+ break;
+ }
case TimeStepping::FEHLBERG :
- {
- method_name = "fehlberg";
- break;
- }
+ {
+ method_name = "fehlberg";
+ break;
+ }
case TimeStepping::CASH_KARP :
- {
- method_name = "cash_karp";
- break;
- }
+ {
+ method_name = "cash_karp";
+ break;
+ }
default :
- {
- break;
- }
- }
+ {
+ break;
+ }
+ }
DataOut<2> data_out;
TimeStepping::ExplicitRungeKutta<Vector<double> > explicit_runge_kutta(method);
output_results(0,method);
for (unsigned int i=0; i<n_time_steps; ++i)
- {
- time = explicit_runge_kutta.evolve_one_time_step(
- std_cxx1x::bind(&Diffusion::evaluate_diffusion,this,std_cxx1x::_1,std_cxx1x::_2),
- time,time_step,solution);
+ {
+ time = explicit_runge_kutta.evolve_one_time_step(
+ std_cxx1x::bind(&Diffusion::evaluate_diffusion,this,std_cxx1x::_1,std_cxx1x::_2),
+ time,time_step,solution);
- if ((i+1)%10==0)
- output_results(i+1,method);
- }
+ if ((i+1)%10==0)
+ output_results(i+1,method);
+ }
}
// @sect5{<code>Diffusion::implicit_method</code>}
// This function is equivalent to explicit_method but for implicit methods.
- // When using implicit methods, we need to evaluate $M^{-1}(f(t,y))$ and
+ // When using implicit methods, we need to evaluate $M^{-1}(f(t,y))$ and
// $\left(I-\tau M^{-1} \frac{\partial f(t,y)}{\partial y}\right)^{-1}$.
void Diffusion::implicit_method(TimeStepping::runge_kutta_method method,
const unsigned int n_time_steps,
TimeStepping::ImplicitRungeKutta<Vector<double> > implicit_runge_kutta(method);
output_results(0,method);
for (unsigned int i=0; i<n_time_steps; ++i)
- {
- time = implicit_runge_kutta.evolve_one_time_step(
- std_cxx1x::bind(&Diffusion::evaluate_diffusion,this,std_cxx1x::_1,std_cxx1x::_2),
- std_cxx1x::bind(&Diffusion::id_minus_tau_J_inverse,this,std_cxx1x::_1,std_cxx1x::_2,
- std_cxx1x::_3),
- time,time_step,solution);
-
- if ((i+1)%10==0)
- output_results(i+1,method);
- }
+ {
+ time = implicit_runge_kutta.evolve_one_time_step(
+ std_cxx1x::bind(&Diffusion::evaluate_diffusion,this,std_cxx1x::_1,std_cxx1x::_2),
+ std_cxx1x::bind(&Diffusion::id_minus_tau_J_inverse,this,std_cxx1x::_1,std_cxx1x::_2,
+ std_cxx1x::_3),
+ time,time_step,solution);
+
+ if ((i+1)%10==0)
+ output_results(i+1,method);
+ }
}
// - refine_param: factor multiplying the current time step when the error
// is above the threshold.
// - min_delta: smallest time step acceptable.
- // - max_delta: largest time step acceptable.
+ // - max_delta: largest time step acceptable.
// - refine_tol: threshold above which the time step is refined.
// - coarsen_tol: threshold below which the time step is coarsen.
// Embedded methods use a guessed time step. If the error using this time step
output_results(0,method);
unsigned int n_steps=0;
while (time<final_time)
- {
- // We choose the last time step such that the final time is exactly
- // reached.
- if (time+time_step>final_time)
- time_step = final_time-time;
+ {
+ // We choose the last time step such that the final time is exactly
+ // reached.
+ if (time+time_step>final_time)
+ time_step = final_time-time;
- time = embedded_explicit_runge_kutta.evolve_one_time_step(
- std_cxx1x::bind(&Diffusion::evaluate_diffusion,this,std_cxx1x::_1,std_cxx1x::_2),
- time,time_step,solution);
+ time = embedded_explicit_runge_kutta.evolve_one_time_step(
+ std_cxx1x::bind(&Diffusion::evaluate_diffusion,this,std_cxx1x::_1,std_cxx1x::_2),
+ time,time_step,solution);
- if ((n_steps+1)%10==0)
- output_results(n_steps+1,method);
+ if ((n_steps+1)%10==0)
+ output_results(n_steps+1,method);
- time_step = embedded_explicit_runge_kutta.get_status().delta_t_guess;
- ++n_steps;
- }
+ time_step = embedded_explicit_runge_kutta.get_status().delta_t_guess;
+ ++n_steps;
+ }
return n_steps;
}
typename Triangulation<2>::active_cell_iterator
cell = triangulation.begin_active(),
endc = triangulation.end();
-
+
for (; cell!=endc; ++cell)
for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
if (cell->face(f)->at_boundary())
- {
- if ((cell->face(f)->center()[0]==0.) || (cell->face(f)->center()[0]==5.))
- cell->face(f)->set_boundary_indicator(1);
- else
- cell->face(f)->set_boundary_indicator(0);
- }
+ {
+ if ((cell->face(f)->center()[0]==0.) || (cell->face(f)->center()[0]==5.))
+ cell->face(f)->set_boundary_indicator(1);
+ else
+ cell->face(f)->set_boundary_indicator(0);
+ }
setup_system();
// Next, we solve the diffusion problem using different Runge-Kutta methods.
std::cout << "Explicit methods:" << std::endl;
explicit_method (TimeStepping::FORWARD_EULER,
- n_time_steps,
- initial_time,
- final_time);
+ n_time_steps,
+ initial_time,
+ final_time);
std::cout << "Forward Euler: error=" << solution.l2_norm() << std::endl;
-
+
explicit_method (TimeStepping::RK_THIRD_ORDER,
- n_time_steps,
- initial_time,
- final_time);
+ n_time_steps,
+ initial_time,
+ final_time);
std::cout << "Third order Runge-Kutta: error=" << solution.l2_norm() << std::endl;
explicit_method (TimeStepping::RK_CLASSIC_FOURTH_ORDER,
- n_time_steps,
- initial_time,
- final_time);
+ n_time_steps,
+ initial_time,
+ final_time);
std::cout << "Fourth order Runge-Kutta: error=" << solution.l2_norm() << std::endl;
std::cout << std::endl;
std::cout << "Implicit methods:" << std::endl;
implicit_method (TimeStepping::BACKWARD_EULER,
- n_time_steps,
- initial_time,
- final_time);
+ n_time_steps,
+ initial_time,
+ final_time);
std::cout << "Backward Euler: error=" << solution.l2_norm() << std::endl;
implicit_method (TimeStepping::IMPLICIT_MIDPOINT,
- n_time_steps,
- initial_time,
- final_time);
+ n_time_steps,
+ initial_time,
+ final_time);
std::cout << "Implicit Midpoint: error=" << solution.l2_norm() << std::endl;
implicit_method (TimeStepping::CRANK_NICOLSON,
- n_time_steps,
- initial_time,
- final_time);
+ n_time_steps,
+ initial_time,
+ final_time);
std::cout << "Crank-Nicolson: error=" << solution.l2_norm() << std::endl;
implicit_method (TimeStepping::SDIRK_TWO_STAGES,
- n_time_steps,
- initial_time,
- final_time);
+ n_time_steps,
+ initial_time,
+ final_time);
std::cout << "SDIRK: error=" << solution.l2_norm() << std::endl;
std::cout << std::endl;
-
+
std::cout << "Embedded explicit methods:" << std::endl;
n_steps = embedded_explicit_method (TimeStepping::HEUN_EULER,
- n_time_steps,
- initial_time,
- final_time);
+ n_time_steps,
+ initial_time,
+ final_time);
std::cout << "Heun-Euler: error=" << solution.l2_norm() << std::endl;
std::cout << " steps performed=" << n_steps << std::endl;
-
+
n_steps = embedded_explicit_method (TimeStepping::BOGACKI_SHAMPINE,
- n_time_steps,
- initial_time,
- final_time);
+ n_time_steps,
+ initial_time,
+ final_time);
std::cout << "Bogacki-Shampine: error=" << solution.l2_norm() << std::endl;
std::cout << " steps performed=" << n_steps << std::endl;
n_steps = embedded_explicit_method (TimeStepping::DOPRI,
- n_time_steps,
- initial_time,
- final_time);
+ n_time_steps,
+ initial_time,
+ final_time);
std::cout << "Dopri: error=" << solution.l2_norm() << std::endl;
std::cout << " steps performed=" << n_steps << std::endl;
n_steps = embedded_explicit_method (TimeStepping::FEHLBERG,
- n_time_steps,
- initial_time,
- final_time);
+ n_time_steps,
+ initial_time,
+ final_time);
std::cout << "Fehlberg: error=" << solution.l2_norm() << std::endl;
std::cout << " steps performed=" << n_steps << std::endl;
-
+
n_steps = embedded_explicit_method (TimeStepping::CASH_KARP,
- n_time_steps,
- initial_time,
- final_time);
+ n_time_steps,
+ initial_time,
+ final_time);
std::cout << "Cash-Karp: error=" << solution.l2_norm() << std::endl;
std::cout << " steps performed=" << n_steps << std::endl;
}
}
-
+
// @sect3{The <code>main()</code> function}
int main ()
{
try
- {
- Step52::Diffusion diffusion;
- diffusion.run();
- }
+ {
+ Step52::Diffusion diffusion;
+ diffusion.run();
+ }
catch (std::exception &exc)
- {
- std::cerr << std::endl << std::endl
- << "----------------------------------------------------"
- << std::endl;
- std::cerr << "Exception on processing: " << std::endl
- << exc.what() << std::endl
- << "Aborting!" << std::endl
- << "----------------------------------------------------"
- << std::endl;
- return 1;
- }
+ {
+ std::cerr << std::endl << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ std::cerr << "Exception on processing: " << std::endl
+ << exc.what() << std::endl
+ << "Aborting!" << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ return 1;
+ }
catch (...)
- {
- std::cerr << std::endl << std::endl
- << "----------------------------------------------------"
- << std::endl;
- std::cerr << "Unknown exception!" << std::endl
- << "Aborting!" << std::endl
- << "----------------------------------------------------"
- << std::endl;
- return 1;
- };
+ {
+ std::cerr << std::endl << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ std::cerr << "Unknown exception!" << std::endl
+ << "Aborting!" << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ return 1;
+ };
return 0;
}
class SphereGeometry : public Boundary<dim>
{
public:
- SphereGeometry (const Point<dim> ¢er);
+ SphereGeometry (const Point<dim> ¢er);
virtual
Point<dim>
get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) const;
template <int dim>
SphereGeometry<dim>::SphereGeometry (const Point<dim> ¢er)
-:
-center (center)
+ :
+ center (center)
{}
const double r = relative_point.norm();
const double phi = std::atan2 (relative_point[1], relative_point[0]);
const double theta = std::atan2 (relative_point[2], std::sqrt (relative_point[0]*relative_point[0] +
- relative_point[1]*relative_point[1]));
+ relative_point[1]*relative_point[1]));
std_cxx1x::array<double,3> result;
result[0] = r;
get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) const
{
std_cxx1x::array<double,dim> preimages[2] = { pull_back (line->vertex(0)),
- pull_back (line->vertex(1)) };
+ pull_back (line->vertex(1))
+ };
return push_forward(average (preimages));
}
std_cxx1x::array<double,dim> preimages[4] = { pull_back (quad->vertex(0)),
pull_back (quad->vertex(1)),
pull_back (quad->vertex(2)),
- pull_back (quad->vertex(3)) };
+ pull_back (quad->vertex(3))
+ };
return push_forward(average(preimages));
}
triangulation.refine_global(1);
for (typename Triangulation<dim>::active_cell_iterator cell=triangulation.begin_active();
- cell!=triangulation.end(); ++cell)
+ cell!=triangulation.end(); ++cell)
{
if (cell->center().distance(center)< radius)
cell->set_manifold_id(1);
}
-
+
// @sect3{The main function}
// @p cell_rhs into the global objects.
cell->get_dof_indices (local_dof_indices);
constraints.distribute_local_to_global (cell_matrix,
- cell_rhs,
- local_dof_indices,
- system_matrix,
- system_rhs);
+ cell_rhs,
+ local_dof_indices,
+ system_matrix,
+ system_rhs);
}
// Now we are done assembling the linear system. The constraint matrix took
// care of applying the boundary conditions and also eliminated hanging node
template <int dim>
void HelmholtzProblem<dim>::run ()
{
- const unsigned int n_cycles = (refinement_mode==global_refinement)?5:9;
+ const unsigned int n_cycles = (refinement_mode==global_refinement)?5:9;
for (unsigned int cycle=0; cycle<n_cycles; ++cycle)
{
if (cycle == 0)
template <int dim>
GradientEstimation::EstimateScratchData<dim>::
EstimateScratchData (const FiniteElement<dim> &fe,
- const Vector<double> &solution)
+ const Vector<double> &solution)
:
fe_midpoint_value(fe,
QMidpoint<dim> (),
SynchronousIterators<IteratorTuple>
begin_sync_it (IteratorTuple (dof_handler.begin_active(),
error_per_cell.begin())),
- end_sync_it (IteratorTuple (dof_handler.end(),
- error_per_cell.end()));
+ end_sync_it (IteratorTuple (dof_handler.end(),
+ error_per_cell.end()));
WorkStream::run (begin_sync_it,
end_sync_it,
template <int dim>
void
GradientEstimation::estimate_cell (const SynchronousIterators<std_cxx1x::tuple<typename DoFHandler<dim>::active_cell_iterator,
- Vector<float>::iterator> > &cell,
+ Vector<float>::iterator> > &cell,
EstimateScratchData<dim> &scratch_data,
- const EstimateCopyData &)
+ const EstimateCopyData &)
{
// We need space for the tensor <code>Y</code>, which is the sum of
// outer products of the y-vectors.
/// List the contents to a stream
template <class STREAM>
- void list (STREAM& os) const;
-
+ void list (STREAM &os) const;
+
/// Conversion from old NamedData
template <typename type>
AnyData(const NamedData<type> &);
template <class STREAM>
inline
-void AnyData::list(STREAM& os) const
+void AnyData::list(STREAM &os) const
{
- for (unsigned int i=0;i<names.size();++i)
+ for (unsigned int i=0; i<names.size(); ++i)
{
os << i
- << '\t' << names[i]
- << '\t' << data[i].type().name()
- << std::endl;
+ << '\t' << names[i]
+ << '\t' << data[i].type().name()
+ << std::endl;
}
}
if (debug_vectors)
{
- NamedData<VECTOR *> out;
- VECTOR *p = &u;
- out.add(p, "solution");
- p = Du;
- out.add(p, "update");
- p = res;
- out.add(p, "residual");
- *data_out << step;
- *data_out << out;
+ NamedData<VECTOR *> out;
+ VECTOR *p = &u;
+ out.add(p, "solution");
+ p = Du;
+ out.add(p, "update");
+ p = res;
+ out.add(p, "residual");
+ *data_out << step;
+ *data_out << out;
}
while (control.check(step++, resnorm) == SolverControl::iterate)
// never arrive here because they are non-trivial).
if (std_cxx1x::is_trivial<T>::value == true)
- std::memcpy ((void*)(destination_+begin), source_+begin,
+ std::memcpy ((void *)(destination_+begin), source_+begin,
(end-begin)*sizeof(T));
else if (copy_only_ == false)
for (std::size_t i=begin; i<end; ++i)
// cast element to (void*) to silence compiler warning for virtual
// classes (they will never arrive here because they are
// non-trivial).
- if (std::memcmp(zero, (void*)&element, sizeof(T)) == 0)
+ if (std::memcmp(zero, (void *)&element, sizeof(T)) == 0)
trivial_element = true;
}
if (size < minimum_parallel_grain_size)
// classes (they will never arrive here because they are
// non-trivial).
if (std_cxx1x::is_trivial<T>::value == true && trivial_element)
- std::memset ((void*)(destination_+begin), 0, (end-begin)*sizeof(T));
+ std::memset ((void *)(destination_+begin), 0, (end-begin)*sizeof(T));
else
// initialize memory and set
for (std::size_t i=begin; i<end; ++i)
template < class T >
inline
-AlignedVector<T>&
+AlignedVector<T> &
AlignedVector<T>::operator = (const AlignedVector<T> &vec)
{
resize(0);
if (_end_data != _data)
{
dealii::internal::AlignedVectorMove<T>(new_data, new_data + old_size,
- _data);
+ _data);
#if DEAL_II_COMPILER_VECTORIZATION_LEVEL > 0
_mm_free(new_data);
#else
AlignedVector<T>::memory_consumption () const
{
size_type memory = sizeof(*this);
- for (const T* t = _data ; t != _end_data; ++t)
+ for (const T *t = _data ; t != _end_data; ++t)
memory += dealii::MemoryConsumption::memory_consumption(*t);
memory += sizeof(T) * (_end_allocated-_end_data);
return memory;
if (lhs.size() != rhs.size())
return false;
for (typename AlignedVector<T>::const_iterator lit = lhs.begin(),
- rit = rhs.begin(); lit != lhs.end(); ++lit, ++rit)
+ rit = rhs.begin(); lit != lhs.end(); ++lit, ++rit)
if (*lit != *rit)
return false;
return true;
const EpsFlags &flags,
std::ostream &out);
-
+
/**
* Write the given list of patches to the output stream in
* GMV format.
* new.
*/
extern const Event initial;
-
+
/**
* The mesh has changed.
*/
extern const Event remesh;
-
+
/**
* The current derivative leads
* to slow convergence of
*/
template <int dim, typename Number=double>
class Function : public FunctionTime<Number>,
- public Subscriptor
+ public Subscriptor
{
public:
/**
* given point.
*/
virtual Tensor<1,dim, Number> gradient (const Point<dim, Number> &p,
- const unsigned int component = 0) const;
+ const unsigned int component = 0) const;
/**
* Return the gradient of all components of the function at the given
std::vector<Vector<Number> > &values) const;
virtual Tensor<1,dim, Number> gradient (const Point<dim, Number> &p,
- const unsigned int component = 0) const;
+ const unsigned int component = 0) const;
virtual void vector_gradient (const Point<dim, Number> &p,
std::vector<Tensor<1,dim, Number> > &gradients) const;
template <int dim>
class InterpolatedTensorProductGridData : public Function<dim>
{
- public:
- /**
- * Constructor.
- * @param coordinate_values An array of dim arrays. Each of the inner
- * arrays contains the coordinate values $x_0,\ldotx, x_{K-1}$ and
- * similarly for the other coordinate directions. These arrays
- * need not have the same size. Obviously, we need dim such arrays
- * for a dim-dimensional function object. The coordinate values
- * within this array are assumed to be strictly ascending to allow
- * for efficient lookup.
- * @param data_values A dim-dimensional table of data at each of the
- * mesh points defined by the coordinate arrays above. Note that the
- * Table class has a number of conversion constructors that allow
- * converting other data types into a table where you specify this
- * argument.
- */
- InterpolatedTensorProductGridData (const std_cxx1x::array<std::vector<double>,dim> &coordinate_values,
- const Table<dim,double> &data_values);
-
- /**
- * Compute the value of the function set by bilinear interpolation of the
- * given data set.
- *
- * @param p The point at which the function is to be evaluated.
- * @param component The vector component. Since this function is scalar,
- * only zero is a valid argument here.
- * @return The interpolated value at this point. If the point lies outside
- * the set of coordinates, the function is extended by a constant.
- */
- virtual
- double
- value (const Point<dim> &p,
- const unsigned int component = 0) const;
-
- private:
- /**
- * The set of coordinate values in each of the coordinate directions.
- */
- const std_cxx1x::array<std::vector<double>,dim> coordinate_values;
-
- /**
- * The data that is to be interpolated.
- */
- const Table<dim,double> data_values;
+ public:
+ /**
+ * Constructor.
+ * @param coordinate_values An array of dim arrays. Each of the inner
+ * arrays contains the coordinate values $x_0,\ldotx, x_{K-1}$ and
+ * similarly for the other coordinate directions. These arrays
+ * need not have the same size. Obviously, we need dim such arrays
+ * for a dim-dimensional function object. The coordinate values
+ * within this array are assumed to be strictly ascending to allow
+ * for efficient lookup.
+ * @param data_values A dim-dimensional table of data at each of the
+ * mesh points defined by the coordinate arrays above. Note that the
+ * Table class has a number of conversion constructors that allow
+ * converting other data types into a table where you specify this
+ * argument.
+ */
+ InterpolatedTensorProductGridData (const std_cxx1x::array<std::vector<double>,dim> &coordinate_values,
+ const Table<dim,double> &data_values);
+
+ /**
+ * Compute the value of the function set by bilinear interpolation of the
+ * given data set.
+ *
+ * @param p The point at which the function is to be evaluated.
+ * @param component The vector component. Since this function is scalar,
+ * only zero is a valid argument here.
+ * @return The interpolated value at this point. If the point lies outside
+ * the set of coordinates, the function is extended by a constant.
+ */
+ virtual
+ double
+ value (const Point<dim> &p,
+ const unsigned int component = 0) const;
+
+ private:
+ /**
+ * The set of coordinate values in each of the coordinate directions.
+ */
+ const std_cxx1x::array<std::vector<double>,dim> coordinate_values;
+
+ /**
+ * The data that is to be interpolated.
+ */
+ const Table<dim,double> data_values;
};
template <int dim>
class InterpolatedUniformGridData : public Function<dim>
{
- public:
- /**
- * Constructor
- * @param interval_endpoints The left and right end points of the (uniformly
- * subdivided) intervals in each of the coordinate directions.
- * @param n_subdivisions The number of subintervals of the subintervals
- * in each coordinate direction. A value of one for a coordinate
- * means that the interval is considered as one subinterval consisting
- * of the entire range. A value of two means that there are two subintervals
- * each with one half of the range, etc.
- * @param data_values A dim-dimensional table of data at each of the
- * mesh points defined by the coordinate arrays above. Note that the
- * Table class has a number of conversion constructors that allow
- * converting other data types into a table where you specify this
- * argument.
- */
- InterpolatedUniformGridData (const std_cxx1x::array<std::pair<double,double>,dim> &interval_endpoints,
- const std_cxx1x::array<unsigned int,dim> &n_subintervals,
- const Table<dim,double> &data_values);
-
- /**
- * Compute the value of the function set by bilinear interpolation of the
- * given data set.
- *
- * @param p The point at which the function is to be evaluated.
- * @param component The vector component. Since this function is scalar,
- * only zero is a valid argument here.
- * @return The interpolated value at this point. If the point lies outside
- * the set of coordinates, the function is extended by a constant.
- */
- virtual
- double
- value (const Point<dim> &p,
- const unsigned int component = 0) const;
-
- private:
- /**
- * The set of interval endpoints in each of the coordinate directions.
- */
- const std_cxx1x::array<std::pair<double,double>,dim> interval_endpoints;
-
- /**
- * The number of subintervals in each of the coordinate directions.
- */
- const std_cxx1x::array<unsigned int,dim> n_subintervals;
-
- /**
- * The data that is to be interpolated.
- */
- const Table<dim,double> data_values;
+ public:
+ /**
+ * Constructor
+ * @param interval_endpoints The left and right end points of the (uniformly
+ * subdivided) intervals in each of the coordinate directions.
+ * @param n_subdivisions The number of subintervals of the subintervals
+ * in each coordinate direction. A value of one for a coordinate
+ * means that the interval is considered as one subinterval consisting
+ * of the entire range. A value of two means that there are two subintervals
+ * each with one half of the range, etc.
+ * @param data_values A dim-dimensional table of data at each of the
+ * mesh points defined by the coordinate arrays above. Note that the
+ * Table class has a number of conversion constructors that allow
+ * converting other data types into a table where you specify this
+ * argument.
+ */
+ InterpolatedUniformGridData (const std_cxx1x::array<std::pair<double,double>,dim> &interval_endpoints,
+ const std_cxx1x::array<unsigned int,dim> &n_subintervals,
+ const Table<dim,double> &data_values);
+
+ /**
+ * Compute the value of the function set by bilinear interpolation of the
+ * given data set.
+ *
+ * @param p The point at which the function is to be evaluated.
+ * @param component The vector component. Since this function is scalar,
+ * only zero is a valid argument here.
+ * @return The interpolated value at this point. If the point lies outside
+ * the set of coordinates, the function is extended by a constant.
+ */
+ virtual
+ double
+ value (const Point<dim> &p,
+ const unsigned int component = 0) const;
+
+ private:
+ /**
+ * The set of interval endpoints in each of the coordinate directions.
+ */
+ const std_cxx1x::array<std::pair<double,double>,dim> interval_endpoints;
+
+ /**
+ * The number of subintervals in each of the coordinate directions.
+ */
+ const std_cxx1x::array<unsigned int,dim> n_subintervals;
+
+ /**
+ * The data that is to be interpolated.
+ */
+ const Table<dim,double> data_values;
};
}
DEAL_II_NAMESPACE_CLOSE
template <int dim>
class FunctionParser : public Function<dim>
{
- public:
- /**
- * Constructor for Parsed functions. Its arguments are the same of the
- * base class Function. The only difference is that this object needs to
- * be initialized with initialize() method before you can use it. If an
- * attempt to use this function is made before the initialize() method has
- * been called, then an exception is thrown.
- */
- FunctionParser (const unsigned int n_components = 1,
- const double initial_time = 0.0);
-
- /**
- * Destructor. Explicitly delete the FunctionParser objects (there is one
- * for each component of the function).
- */
- ~FunctionParser();
-
- /**
- * Type for the constant map. Used by the initialize() method.
- */
- typedef std::map<std::string, double> ConstMap;
-
- /**
- * Iterator for the constants map. Used by the initialize() method.
- */
- typedef ConstMap::iterator ConstMapIterator;
-
- /**
- * Initialize the function. This methods accepts the following
- * parameters:
- *
- * <b>vars</b>: a string with the variables that will be used by the
- * expressions to be evaluated. Note that the variables can have any name
- * (of course different from the function names defined above!), but the
- * order IS important. The first variable will correspond to the first
- * component of the point in which the function is evaluated, the second
- * variable to the second component and so forth. If this function is also
- * time dependent, then it is necessary to specify it by setting the
- * <tt>time_dependent</tt> parameter to true. An exception is thrown if
- * the number of variables specified here is different from dim (if this
- * function is not time-dependent) or from dim+1 (if it is time-
- * dependent).
- *
- * <b>expressions</b>: a list of strings containing the expressions that
- * will be byte compiled by the internal parser (FunctionParser). Note
- * that the size of this vector must match exactly the number of
- * components of the FunctionParser, as declared in the constructor. If
- * this is not the case, an exception is thrown.
- *
- *
- * <b>constants</b>: a map of constants used to pass any necessary
- * constant that we want to specify in our expressions (in the example
- * above the number pi). An expression is valid if and only if it contains
- * only defined variables and defined constants (other than the functions
- * specified above). If a constant is given whose name is not valid (eg:
- * <tt>constants["sin"] = 1.5;</tt>) an exception is thrown.
- *
- * <b>time_dependent</b>. If this is a time dependent function, then the
- * last variable declared in <b>vars</b> is assumed to be the time
- * variable, and this->get_time() is used to initialize it when evaluating
- * the function. Naturally the number of variables parsed by the
- * initialize() method in this case is dim+1. The value of this parameter
- * defaults to false, i.e. do not consider time.
- */
- void initialize (const std::string &vars,
- const std::vector<std::string> &expressions,
- const ConstMap &constants,
- const bool time_dependent = false);
-
- /**
- * Same as above, but with an additional parameter: <b>use_degrees</b>.
- * Parameter to decide if the trigonometric functions work in radians or
- * degrees. The default for this parameter is false, i.e. use radians and
- * not degrees.
- *
- * @note: this function is deprecated. Use the function without this
- * argument instead (which has the default use_degrees=false).
- */
- void initialize (const std::string &vars,
- const std::vector<std::string> &expressions,
- const ConstMap &constants,
- const bool time_dependent,
- const bool use_degrees) DEAL_II_DEPRECATED;
-
-
- /**
- * Initialize the function. Same as above, but with an additional argument
- * <b> units </b> - a map of units passed to FunctionParser via AddUnint.
- *
- * Can be used as "3cm". Have higher precedence in parsing, i.e. if cm=10
- * then 3/2cm is 3 /(2*10).
- */
- void initialize (const std::string &vars,
- const std::vector<std::string> &expressions,
- const ConstMap &constants,
- const ConstMap &units,
- const bool time_dependent = false,
- const bool use_degrees = false) DEAL_II_DEPRECATED;
-
- /**
- * Initialize the function. Same as above, but accepts a string rather
- * than a vector of strings. If this is a vector valued function, its
- * components are expected to be separated by a semicolon. An exception is
- * thrown if this method is called and the number of components
- * successfully parsed does not match the number of components of the base
- * function.
- */
- void initialize (const std::string &vars,
- const std::string &expression,
- const ConstMap &constants,
- const bool time_dependent = false);
-
- /**
- * Same as above, but with an additional parameter: <b>use_degrees</b>.
- * Parameter to decide if the trigonometric functions work in radians or
- * degrees. The default for this parameter is false, i.e. use radians and
- * not degrees.
- *
- * @note: this function is deprecated. Use the function without this
- * argument instead (which has the default use_degrees=false).
- */
- void initialize (const std::string &vars,
- const std::string &expression,
- const ConstMap &constants,
- const bool time_dependent,
- const bool use_degrees) DEAL_II_DEPRECATED;
-
- /**
- * Initialize the function. Same as above, but with <b>units</b>.
- */
- void initialize (const std::string &vars,
- const std::string &expression,
- const ConstMap &constants,
- const ConstMap &units,
- const bool time_dependent = false,
- const bool use_degrees = false) DEAL_II_DEPRECATED;
-
- /**
- * A function that returns default names for variables, to be used in the
- * first argument of the initialize() functions: it returns "x" in 1d,
- * "x,y" in 2d, and "x,y,z" in 3d.
- */
- static
- std::string
- default_variable_names ();
-
- /**
- * Return the value of the function at the given point. Unless there is
- * only one component (i.e. the function is scalar), you should state the
- * component you want to have evaluated; it defaults to zero, i.e. the
- * first component.
- */
- virtual double value (const Point<dim> &p,
- const unsigned int component = 0) const;
-
- /**
- * Return all components of a vector-valued function at the given point @p
- * p.
- *
- * <tt>values</tt> shall have the right size beforehand, i.e.
- * #n_components.
- */
- virtual void vector_value (const Point<dim> &p,
- Vector<double> &values) const;
-
- /**
- * @addtogroup Exceptions
- * @{
- */
- DeclException2 (ExcParseError,
- int, char *,
- << "Parsing Error at Column " << arg1
- << ". The parser said: " << arg2);
-
- DeclException2 (ExcInvalidExpressionSize,
- int, int,
- << "The number of components (" << arg1
- << ") is not equal to the number of expressions ("
- << arg2 << ").");
-
- //@}
-
- private:
+public:
+ /**
+ * Constructor for Parsed functions. Its arguments are the same of the
+ * base class Function. The only difference is that this object needs to
+ * be initialized with initialize() method before you can use it. If an
+ * attempt to use this function is made before the initialize() method has
+ * been called, then an exception is thrown.
+ */
+ FunctionParser (const unsigned int n_components = 1,
+ const double initial_time = 0.0);
+
+ /**
+ * Destructor. Explicitly delete the FunctionParser objects (there is one
+ * for each component of the function).
+ */
+ ~FunctionParser();
+
+ /**
+ * Type for the constant map. Used by the initialize() method.
+ */
+ typedef std::map<std::string, double> ConstMap;
+
+ /**
+ * Iterator for the constants map. Used by the initialize() method.
+ */
+ typedef ConstMap::iterator ConstMapIterator;
+
+ /**
+ * Initialize the function. This methods accepts the following
+ * parameters:
+ *
+ * <b>vars</b>: a string with the variables that will be used by the
+ * expressions to be evaluated. Note that the variables can have any name
+ * (of course different from the function names defined above!), but the
+ * order IS important. The first variable will correspond to the first
+ * component of the point in which the function is evaluated, the second
+ * variable to the second component and so forth. If this function is also
+ * time dependent, then it is necessary to specify it by setting the
+ * <tt>time_dependent</tt> parameter to true. An exception is thrown if
+ * the number of variables specified here is different from dim (if this
+ * function is not time-dependent) or from dim+1 (if it is time-
+ * dependent).
+ *
+ * <b>expressions</b>: a list of strings containing the expressions that
+ * will be byte compiled by the internal parser (FunctionParser). Note
+ * that the size of this vector must match exactly the number of
+ * components of the FunctionParser, as declared in the constructor. If
+ * this is not the case, an exception is thrown.
+ *
+ *
+ * <b>constants</b>: a map of constants used to pass any necessary
+ * constant that we want to specify in our expressions (in the example
+ * above the number pi). An expression is valid if and only if it contains
+ * only defined variables and defined constants (other than the functions
+ * specified above). If a constant is given whose name is not valid (eg:
+ * <tt>constants["sin"] = 1.5;</tt>) an exception is thrown.
+ *
+ * <b>time_dependent</b>. If this is a time dependent function, then the
+ * last variable declared in <b>vars</b> is assumed to be the time
+ * variable, and this->get_time() is used to initialize it when evaluating
+ * the function. Naturally the number of variables parsed by the
+ * initialize() method in this case is dim+1. The value of this parameter
+ * defaults to false, i.e. do not consider time.
+ */
+ void initialize (const std::string &vars,
+ const std::vector<std::string> &expressions,
+ const ConstMap &constants,
+ const bool time_dependent = false);
+
+ /**
+ * Same as above, but with an additional parameter: <b>use_degrees</b>.
+ * Parameter to decide if the trigonometric functions work in radians or
+ * degrees. The default for this parameter is false, i.e. use radians and
+ * not degrees.
+ *
+ * @note: this function is deprecated. Use the function without this
+ * argument instead (which has the default use_degrees=false).
+ */
+ void initialize (const std::string &vars,
+ const std::vector<std::string> &expressions,
+ const ConstMap &constants,
+ const bool time_dependent,
+ const bool use_degrees) DEAL_II_DEPRECATED;
+
+
+ /**
+ * Initialize the function. Same as above, but with an additional argument
+ * <b> units </b> - a map of units passed to FunctionParser via AddUnint.
+ *
+ * Can be used as "3cm". Have higher precedence in parsing, i.e. if cm=10
+ * then 3/2cm is 3 /(2*10).
+ */
+ void initialize (const std::string &vars,
+ const std::vector<std::string> &expressions,
+ const ConstMap &constants,
+ const ConstMap &units,
+ const bool time_dependent = false,
+ const bool use_degrees = false) DEAL_II_DEPRECATED;
+
+ /**
+ * Initialize the function. Same as above, but accepts a string rather
+ * than a vector of strings. If this is a vector valued function, its
+ * components are expected to be separated by a semicolon. An exception is
+ * thrown if this method is called and the number of components
+ * successfully parsed does not match the number of components of the base
+ * function.
+ */
+ void initialize (const std::string &vars,
+ const std::string &expression,
+ const ConstMap &constants,
+ const bool time_dependent = false);
+
+ /**
+ * Same as above, but with an additional parameter: <b>use_degrees</b>.
+ * Parameter to decide if the trigonometric functions work in radians or
+ * degrees. The default for this parameter is false, i.e. use radians and
+ * not degrees.
+ *
+ * @note: this function is deprecated. Use the function without this
+ * argument instead (which has the default use_degrees=false).
+ */
+ void initialize (const std::string &vars,
+ const std::string &expression,
+ const ConstMap &constants,
+ const bool time_dependent,
+ const bool use_degrees) DEAL_II_DEPRECATED;
+
+ /**
+ * Initialize the function. Same as above, but with <b>units</b>.
+ */
+ void initialize (const std::string &vars,
+ const std::string &expression,
+ const ConstMap &constants,
+ const ConstMap &units,
+ const bool time_dependent = false,
+ const bool use_degrees = false) DEAL_II_DEPRECATED;
+
+ /**
+ * A function that returns default names for variables, to be used in the
+ * first argument of the initialize() functions: it returns "x" in 1d,
+ * "x,y" in 2d, and "x,y,z" in 3d.
+ */
+ static
+ std::string
+ default_variable_names ();
+
+ /**
+ * Return the value of the function at the given point. Unless there is
+ * only one component (i.e. the function is scalar), you should state the
+ * component you want to have evaluated; it defaults to zero, i.e. the
+ * first component.
+ */
+ virtual double value (const Point<dim> &p,
+ const unsigned int component = 0) const;
+
+ /**
+ * Return all components of a vector-valued function at the given point @p
+ * p.
+ *
+ * <tt>values</tt> shall have the right size beforehand, i.e.
+ * #n_components.
+ */
+ virtual void vector_value (const Point<dim> &p,
+ Vector<double> &values) const;
+
+ /**
+ * @addtogroup Exceptions
+ * @{
+ */
+ DeclException2 (ExcParseError,
+ int, char *,
+ << "Parsing Error at Column " << arg1
+ << ". The parser said: " << arg2);
+
+ DeclException2 (ExcInvalidExpressionSize,
+ int, int,
+ << "The number of components (" << arg1
+ << ") is not equal to the number of expressions ("
+ << arg2 << ").");
+
+ //@}
+
+private:
#ifdef DEAL_II_WITH_MUPARSER
- /**
- * place for the variables for each thread
- */
- mutable Threads::ThreadLocalStorage<std::vector<double> > vars;
- /**
- * the muParser objects for each thread (and one for each component)
- */
- mutable Threads::ThreadLocalStorage<std::vector<mu::Parser> > fp;
-
- /**
- * keep track of all the constants, required to initialize fp in each
- * thread
- */
- std::map<std::string, double> constants;
- /**
- * variable names, required to initialize fp in each thread
- */
- std::vector<std::string> var_names;
- /**
- * the expressions, required to initialize fp in each thread
- */
- std::vector<std::string> expressions;
- /**
- * this function will initialize fp on the current thread
- */
- void init_muparser() const;
+ /**
+ * place for the variables for each thread
+ */
+ mutable Threads::ThreadLocalStorage<std::vector<double> > vars;
+ /**
+ * the muParser objects for each thread (and one for each component)
+ */
+ mutable Threads::ThreadLocalStorage<std::vector<mu::Parser> > fp;
+
+ /**
+ * keep track of all the constants, required to initialize fp in each
+ * thread
+ */
+ std::map<std::string, double> constants;
+ /**
+ * variable names, required to initialize fp in each thread
+ */
+ std::vector<std::string> var_names;
+ /**
+ * the expressions, required to initialize fp in each thread
+ */
+ std::vector<std::string> expressions;
+ /**
+ * this function will initialize fp on the current thread
+ */
+ void init_muparser() const;
#endif
- /**
- * State of usability. This variable is checked every time the function is
- * called for evaluation. It's set to true in the initialize() methods.
- */
- bool initialized;
-
- /**
- * Number of variables. If this is also a function of time, then the
- * number of variables is dim+1, otherwise it is dim. In the case that
- * this is a time dependent function, the time is supposed to be the last
- * variable. If #n_vars is not identical to the number of the variables
- * parsed by the initialize() method, then an exception is thrown.
- */
- unsigned int n_vars;
+ /**
+ * State of usability. This variable is checked every time the function is
+ * called for evaluation. It's set to true in the initialize() methods.
+ */
+ bool initialized;
+
+ /**
+ * Number of variables. If this is also a function of time, then the
+ * number of variables is dim+1, otherwise it is dim. In the case that
+ * this is a time dependent function, the time is supposed to be the last
+ * variable. If #n_vars is not identical to the number of the variables
+ * parsed by the initialize() method, then an exception is thrown.
+ */
+ unsigned int n_vars;
};
FunctionParser<dim>::default_variable_names ()
{
switch (dim)
- {
- case 1:
- return "x";
- case 2:
- return "x,y";
- case 3:
- return "x,y,z";
- default:
- Assert (false, ExcNotImplemented());
- }
+ {
+ case 1:
+ return "x";
+ case 2:
+ return "x,y";
+ case 3:
+ return "x,y,z";
+ default:
+ Assert (false, ExcNotImplemented());
+ }
return "";
}
* as discussed in the design sections of the IteratorRange class.
*/
class IteratorOverIterators : public std::iterator<std::forward_iterator_tag, Iterator,
- typename Iterator::difference_type>
+ typename Iterator::difference_type>
{
public:
/**
* Dereferencing operator.
* @return The iterator within the collection currently pointed to.
*/
- const BaseIterator * operator-> () const;
+ const BaseIterator *operator-> () const;
/**
* Prefix increment operator. Move the current iterator to the next
* element of the collection and return the new value.
*/
- IteratorOverIterators & operator ++ ();
+ IteratorOverIterators &operator ++ ();
/**
* Postfix increment operator. Move the current iterator to the next
NamedData<DATA>::add(DATA &v, const std::string &n)
{
// see operator() below
-
+
// Assert(!is_constant, ExcConstantObject());
names.push_back(n);
data.push_back(v);
NamedData<DATA>::add(const DATA &v, const std::string &n)
{
// see operator() below
-
+
// Assert(!is_constant, ExcConstantObject());
DATA &aux = const_cast<DATA &>(v);
data.push_back(aux);
NamedData<DATA>::merge(NamedData<DATA2> &other)
{
// see operator() below
-
+
// Assert(!is_constant, ExcConstantObject());
for (unsigned int i=0; i<other.size(); ++i)
NamedData<DATA>::merge(const NamedData<DATA2> &other)
{
// see operator() below
-
+
// Assert(!is_constant, ExcConstantObject());
for (unsigned int i=0; i<other.size(); ++i)
{
* In <tt>XML</tt> format, the output starts with one root element
* <tt>ParameterHandler</tt> in order to get a valid XML document
* and all subsections under it.
- *
+ *
* In <tt>Text</tt> format, the output contains the same information but
* in a format so that the resulting file can be input into a latex
* document such as a manual for the code for which this object handles
* the higher subsection elements are printed. In <tt>XML</tt> format
* this is required to get a valid XML document and output starts
* with one root element <tt>ParameterHandler</tt>.
- *
+ *
* In most cases, you will not want to use this function directly, but
* have it called recursively by the previous function.
*/
public:
/** The constructor takes an arbitrary quadrature formula. */
QSorted (const Quadrature<dim>);
-
+
/** A rule to reorder pairs of points and weights.*/
bool operator()(const std::pair<double, Point<dim> > &a,
- const std::pair<double, Point<dim> > &b);
+ const std::pair<double, Point<dim> > &b);
};
Accessor<rank,dim,constness,P,Number>::
Accessor ()
:
- tensor (*static_cast<tensor_type*>(0)),
+ tensor (*static_cast<tensor_type *>(0)),
previous_indices ()
{
Assert (false, ExcMessage ("You can't call the default constructor of this class."));
Accessor<rank,dim,constness,1,Number>::
Accessor ()
:
- tensor (*static_cast<tensor_type*>(0)),
+ tensor (*static_cast<tensor_type *>(0)),
previous_indices ()
{
Assert (false, ExcMessage ("You can't call the default constructor of this class."));
* then called <tt>vector2d</tt>.
*/
typename AlignedVector<T>::reference el (const unsigned int i,
- const unsigned int j);
+ const unsigned int j);
/**
* Return the value of the
* then called <tt>vector2d</tt>.
*/
typename AlignedVector<T>::const_reference el (const unsigned int i,
- const unsigned int j) const;
+ const unsigned int j) const;
};
template <typename InputIterator, typename T, int N>
void fill_Fortran_style (InputIterator,
- TableBase<N,T> &)
+ TableBase<N,T> &)
{
Assert (false, ExcNotImplemented());
}
if (C_style_indexing)
for (typename AlignedVector<T>::iterator p = values.begin();
- p != values.end(); ++p)
+ p != values.end(); ++p)
*p = *entries++;
else
internal::Table::fill_Fortran_style (entries, *this);
* @relates Tensor
*/
template <int rank, int dim>
- inline
- Tensor<rank,dim,std::complex<double> >
- operator * (const std::complex<double> factor,
- const Tensor<rank,dim> &t)
+inline
+Tensor<rank,dim,std::complex<double> >
+operator * (const std::complex<double> factor,
+ const Tensor<rank,dim> &t)
{
Tensor<rank,dim,std::complex<double> > tt;
for (unsigned int d=0; d<dim; ++d)
* @relates Tensor
*/
template <int rank, int dim>
- inline
- Tensor<rank,dim,std::complex<double> >
- operator * (const Tensor<rank,dim> &t,
- const std::complex<double> factor)
+inline
+Tensor<rank,dim,std::complex<double> >
+operator * (const Tensor<rank,dim> &t,
+ const std::complex<double> factor)
{
Tensor<rank,dim,std::complex<double> > tt;
for (unsigned int d=0; d<dim; ++d)
template <int dim>
inline
Tensor<1,dim,std::complex<double> >
- operator * (const Tensor<1,dim> &t,
- const std::complex<double> factor)
-{
+operator * (const Tensor<1,dim> &t,
+ const std::complex<double> factor)
+{
Tensor<1,dim,std::complex<double> > tt (false);
for (unsigned int d=0; d<dim; ++d)
tt[d] = t[d] * factor;
template <int dim>
inline
Tensor<1,dim,std::complex<double> >
- operator * (const std::complex<double> factor,
- const Tensor<1,dim> &t)
-{
+operator * (const std::complex<double> factor,
+ const Tensor<1,dim> &t)
+{
Tensor<1,dim,std::complex<double> > tt (false);
for (unsigned int d=0; d<dim; ++d)
tt[d] = t[d] * factor;
*/
virtual double evolve_one_time_step(
std::vector<std_cxx1x::function<VECTOR (const double, const VECTOR &)> > &F,
- std::vector<std_cxx1x::function<VECTOR (const double, const double, const VECTOR &)> > & J_inverse,
+ std::vector<std_cxx1x::function<VECTOR (const double, const double, const VECTOR &)> > &J_inverse,
double t,
double delta_t,
VECTOR &y) = 0;
*/
double evolve_one_time_step(
std::vector<std_cxx1x::function<VECTOR (const double, const VECTOR &)> > &F,
- std::vector<std_cxx1x::function<VECTOR (const double, const double, const VECTOR &)> > & J_inverse,
+ std::vector<std_cxx1x::function<VECTOR (const double, const double, const VECTOR &)> > &J_inverse,
double t,
double delta_t,
VECTOR &y);
template <typename VECTOR>
double RungeKutta<VECTOR>::evolve_one_time_step(
std::vector<std_cxx1x::function<VECTOR (const double, const VECTOR &)> > &F,
- std::vector<std_cxx1x::function<VECTOR (const double, const double, const VECTOR &)> > & J_inverse,
+ std::vector<std_cxx1x::function<VECTOR (const double, const double, const VECTOR &)> > &J_inverse,
double t,
double delta_t,
VECTOR &y)
// Linear combinations of the stages.
for (unsigned int i=0; i<this->n_stages; ++i)
- y.sadd(1.,delta_t*this->b[i],f_stages[i]);
+ y.sadd(1.,delta_t *this->b[i],f_stages[i]);
return (t+delta_t);
}
{
VECTOR Y(y);
for (unsigned int j=0; j<i; ++j)
- Y.sadd(1.,delta_t*this->a[i][j],f_stages[j]);
+ Y.sadd(1.,delta_t *this->a[i][j],f_stages[j]);
// Evaluate the function f at the point (t+c[i]*delta_t,Y).
f_stages[i] = f(t+this->c[i]*delta_t,Y);
}
{
y = old_y;
for (unsigned int i=0; i<this->n_stages; ++i)
- y.sadd(1.,delta_t*this->b[i],f_stages[i]);
+ y.sadd(1.,delta_t *this->b[i],f_stages[i]);
}
return (t+delta_t);
{
VECTOR old_y(z);
for (unsigned int j=0; j<i; ++j)
- old_y.sadd(1.,delta_t*this->a[i][j],f_stages[j]);
+ old_y.sadd(1.,delta_t *this->a[i][j],f_stages[j]);
// Solve the nonlinear system using Newton's method
const double new_t = t+this->c[i]*delta_t;
for (unsigned int i=0; i<this->n_stages; ++i)
{
- y.sadd(1.,delta_t*this->b1[i],f_stages[i]);
- error.sadd(1.,delta_t*(b2[i]-b1[i]),f_stages[i]);
+ y.sadd(1.,delta_t *this->b1[i],f_stages[i]);
+ error.sadd(1.,delta_t *(b2[i]-b1[i]),f_stages[i]);
}
error_norm = error.l2_norm();
{
done = true;
// Increase the guessed time step
- double new_delta_t = delta_t*coarsen_param;
+ double new_delta_t = delta_t *coarsen_param;
// Check that the guessed time step is smaller than the maximum time
// step allowed.
if (new_delta_t>max_delta_t)
{
Y = y;
for (unsigned int j = 0; j < i; ++j)
- Y.sadd(1.0,delta_t*this->a[i][j],f_stages[j]);
+ Y.sadd(1.0,delta_t *this->a[i][j],f_stages[j]);
f_stages[i] = f(t+this->c[i]*delta_t,Y);
}
}
* @see @ref GlossBoundaryIndicator "Glossary entry on boundary indicators"
*/
typedef unsigned char boundary_id;
-
+
/**
* The type used to denote manifold indicators associated with every
* object of the mesh.
*/
typedef unsigned int manifold_id;
-
+
/**
* @deprecated Old name for the typedef above.
*/
* @see @ref GlossManifoldIndicator "Glossary entry on manifold indicators"
*/
const types::manifold_id invalid_manifold_id = static_cast<types::manifold_id>(-1);
-
+
/**
* A manifold_id we reserve for the default flat Cartesian manifold.
*
* the given address. The memory need not be aligned by 64 bytes, as opposed
* to casting a double address to VectorizedArray<double>*.
*/
- void load (const double* ptr)
+ void load (const double *ptr)
{
data = _mm512_loadu_pd (ptr);
}
* 64 bytes, as opposed to casting a double address to
* VectorizedArray<double>*.
*/
- void store (double* ptr) const
+ void store (double *ptr) const
{
_mm512_storeu_pd (ptr, data);
}
* the given address. The memory need not be aligned by 64 bytes, as opposed
* to casting a float address to VectorizedArray<float>*.
*/
- void load (const float* ptr)
+ void load (const float *ptr)
{
data = _mm512_loadu_ps (ptr);
}
* 64 bytes, as opposed to casting a float address to
* VectorizedArray<float>*.
*/
- void store (float* ptr) const
+ void store (float *ptr) const
{
_mm512_storeu_ps (ptr, data);
}
* the given address. The memory need not be aligned by 32 bytes, as opposed
* to casting a double address to VectorizedArray<double>*.
*/
- void load (const double* ptr)
+ void load (const double *ptr)
{
data = _mm256_loadu_pd (ptr);
}
* 32 bytes, as opposed to casting a double address to
* VectorizedArray<double>*.
*/
- void store (double* ptr) const
+ void store (double *ptr) const
{
_mm256_storeu_pd (ptr, data);
}
* the given address. The memory need not be aligned by 32 bytes, as opposed
* to casting a float address to VectorizedArray<float>*.
*/
- void load (const float* ptr)
+ void load (const float *ptr)
{
data = _mm256_loadu_ps (ptr);
}
* 32 bytes, as opposed to casting a float address to
* VectorizedArray<float>*.
*/
- void store (float* ptr) const
+ void store (float *ptr) const
{
_mm256_storeu_ps (ptr, data);
}
* the given address. The memory need not be aligned by 16 bytes, as opposed
* to casting a double address to VectorizedArray<double>*.
*/
- void load (const double* ptr)
+ void load (const double *ptr)
{
data = _mm_loadu_pd (ptr);
}
* 16 bytes, as opposed to casting a double address to
* VectorizedArray<double>*.
*/
- void store (double* ptr) const
+ void store (double *ptr) const
{
_mm_storeu_pd (ptr, data);
}
* the given address. The memory need not be aligned by 16 bytes, as opposed
* to casting a float address to VectorizedArray<float>*.
*/
- void load (const float* ptr)
+ void load (const float *ptr)
{
data = _mm_loadu_ps (ptr);
}
* 16 bytes, as opposed to casting a float address to
* VectorizedArray<float>*.
*/
- void store (float* ptr) const
+ void store (float *ptr) const
{
_mm_storeu_ps (ptr, data);
}
* in the vectorized array, as opposed to casting a double address to
* VectorizedArray<double>*.
*/
- void load (const Number* ptr)
+ void load (const Number *ptr)
{
data = *ptr;
}
* the amount of bytes in the vectorized array, as opposed to casting a
* double address to VectorizedArray<double>*.
*/
- void store (Number* ptr) const
+ void store (Number *ptr) const
{
*ptr = data;
}
// and have set the ring buffer to have exactly this size. so
// if this function is called, we know that less than the
// maximal number of items in currently in flight
- //
- // note that we need not lock access to this array since
- // the current stage is run sequentially and we can therefore
- // enter the following block only once at any given time.
- // thus, there can be no race condition between checking that
- // a flag is false and setting it to true. (there may be
- // another thread where we release items and set 'false'
- // flags to 'true', but that too does not produce any
- // problems)
+ //
+ // note that we need not lock access to this array since
+ // the current stage is run sequentially and we can therefore
+ // enter the following block only once at any given time.
+ // thus, there can be no race condition between checking that
+ // a flag is false and setting it to true. (there may be
+ // another thread where we release items and set 'false'
+ // flags to 'true', but that too does not produce any
+ // problems)
ItemType *current_item = 0;
for (unsigned int i=0; i<item_buffer.size(); ++i)
if (item_buffer[i].currently_in_use == false)
namespace ParallelFor
{
template <typename Iterator,
- typename ScratchData,
- typename CopyData>
+ typename ScratchData,
+ typename CopyData>
class Worker
{
public:
- /**
- * Constructor.
- */
- Worker (const std_cxx1x::function<void (const Iterator &,
- ScratchData &,
- CopyData &)> &worker,
- const ScratchData &sample_scratch_data,
- const CopyData &sample_copy_data)
- :
- worker (worker),
- sample_scratch_data (sample_scratch_data),
- sample_copy_data (sample_copy_data)
- {}
-
-
- /**
- * The function that calls the worker function on a
- * range of items denoted by the two arguments.
- */
- void operator() (const tbb::blocked_range<typename std::vector<Iterator>::const_iterator> &range)
- {
- // we need to find an unused scratch and corresponding copy
- // data object in the list that
- // corresponds to the current thread and then mark it as used. if
- // we can't find one, create one
- //
- // as discussed in the discussion of the documentation of the
- // IteratorRangeToItemStream::scratch_data variable, there is no
- // need to synchronize access to this variable using a mutex
- // as long as we have no yield-point in between. this means that
- // we can't take an iterator into the list now and expect it to
- // still be valid after calling the worker, but we at least do
- // not have to lock the following section
- ScratchData *scratch_data = 0;
- CopyData *copy_data = 0;
- {
- typename ItemType::ScratchAndCopyDataList &
- scratch_and_copy_data_list = data.get();
-
- // see if there is an unused object. if so, grab it and mark
- // it as used
- for (typename ItemType::ScratchAndCopyDataList::iterator
- p = scratch_and_copy_data_list.begin();
- p != scratch_and_copy_data_list.end(); ++p)
- if (p->currently_in_use == false)
- {
- scratch_data = p->scratch_data.get();
- copy_data = p->copy_data.get();
- p->currently_in_use = true;
- break;
- }
-
- // if no element in the list was found, create one and mark it as used
- if (scratch_data == 0)
- {
- Assert (copy_data==0, ExcInternalError());
- scratch_data = new ScratchData(sample_scratch_data);
- copy_data = new CopyData(sample_copy_data);
-
- typename ItemType::ScratchAndCopyDataList::value_type
- new_scratch_object (scratch_data, copy_data, true);
- scratch_and_copy_data_list.push_back (new_scratch_object);
- }
- }
-
- // then call the worker and copier function on each
- // element of the chunk we were given. since these
- // functions are called on separate threads, nothing good
- // can happen if they throw an exception and we are best
- // off catching it and showing an error message
- for (typename std::vector<Iterator>::const_iterator p=range.begin();
- p != range.end(); ++p)
- {
- try
- {
- worker (*p,
- *scratch_data,
- *copy_data);
- }
- catch (const std::exception &exc)
- {
- Threads::internal::handle_std_exception (exc);
- }
- catch (...)
- {
- Threads::internal::handle_unknown_exception ();
- }
- }
-
- // finally mark the scratch object as unused again. as above, there
- // is no need to lock anything here since the object we work on
- // is thread-local
- {
- typename ItemType::ScratchAndCopyDataList &
- scratch_and_copy_data_list = data.get();
-
- for (typename ItemType::ScratchAndCopyDataList::iterator p =
- scratch_and_copy_data_list.begin(); p != scratch_and_copy_data_list.end();
- ++p)
- if (p->scratch_data.get() == scratch_data)
- {
- Assert(p->currently_in_use == true, ExcInternalError());
- p->currently_in_use = false;
- }
- }
-
- }
+ /**
+ * Constructor.
+ */
+ Worker (const std_cxx1x::function<void (const Iterator &,
+ ScratchData &,
+ CopyData &)> &worker,
+ const ScratchData &sample_scratch_data,
+ const CopyData &sample_copy_data)
+ :
+ worker (worker),
+ sample_scratch_data (sample_scratch_data),
+ sample_copy_data (sample_copy_data)
+ {}
+
+
+ /**
+ * The function that calls the worker function on a
+ * range of items denoted by the two arguments.
+ */
+ void operator() (const tbb::blocked_range<typename std::vector<Iterator>::const_iterator> &range)
+ {
+ // we need to find an unused scratch and corresponding copy
+ // data object in the list that
+ // corresponds to the current thread and then mark it as used. if
+ // we can't find one, create one
+ //
+ // as discussed in the discussion of the documentation of the
+ // IteratorRangeToItemStream::scratch_data variable, there is no
+ // need to synchronize access to this variable using a mutex
+ // as long as we have no yield-point in between. this means that
+ // we can't take an iterator into the list now and expect it to
+ // still be valid after calling the worker, but we at least do
+ // not have to lock the following section
+ ScratchData *scratch_data = 0;
+ CopyData *copy_data = 0;
+ {
+ typename ItemType::ScratchAndCopyDataList &
+ scratch_and_copy_data_list = data.get();
+
+ // see if there is an unused object. if so, grab it and mark
+ // it as used
+ for (typename ItemType::ScratchAndCopyDataList::iterator
+ p = scratch_and_copy_data_list.begin();
+ p != scratch_and_copy_data_list.end(); ++p)
+ if (p->currently_in_use == false)
+ {
+ scratch_data = p->scratch_data.get();
+ copy_data = p->copy_data.get();
+ p->currently_in_use = true;
+ break;
+ }
+
+ // if no element in the list was found, create one and mark it as used
+ if (scratch_data == 0)
+ {
+ Assert (copy_data==0, ExcInternalError());
+ scratch_data = new ScratchData(sample_scratch_data);
+ copy_data = new CopyData(sample_copy_data);
+
+ typename ItemType::ScratchAndCopyDataList::value_type
+ new_scratch_object (scratch_data, copy_data, true);
+ scratch_and_copy_data_list.push_back (new_scratch_object);
+ }
+ }
+
+ // then call the worker and copier function on each
+ // element of the chunk we were given. since these
+ // functions are called on separate threads, nothing good
+ // can happen if they throw an exception and we are best
+ // off catching it and showing an error message
+ for (typename std::vector<Iterator>::const_iterator p=range.begin();
+ p != range.end(); ++p)
+ {
+ try
+ {
+ worker (*p,
+ *scratch_data,
+ *copy_data);
+ }
+ catch (const std::exception &exc)
+ {
+ Threads::internal::handle_std_exception (exc);
+ }
+ catch (...)
+ {
+ Threads::internal::handle_unknown_exception ();
+ }
+ }
+
+ // finally mark the scratch object as unused again. as above, there
+ // is no need to lock anything here since the object we work on
+ // is thread-local
+ {
+ typename ItemType::ScratchAndCopyDataList &
+ scratch_and_copy_data_list = data.get();
+
+ for (typename ItemType::ScratchAndCopyDataList::iterator p =
+ scratch_and_copy_data_list.begin(); p != scratch_and_copy_data_list.end();
+ ++p)
+ if (p->scratch_data.get() == scratch_data)
+ {
+ Assert(p->currently_in_use == true, ExcInternalError());
+ p->currently_in_use = false;
+ }
+ }
+
+ }
private:
- typedef
- typename Implementation3::IteratorRangeToItemStream<Iterator,ScratchData,CopyData>::ItemType
- ItemType;
+ typedef
+ typename Implementation3::IteratorRangeToItemStream<Iterator,ScratchData,CopyData>::ItemType
+ ItemType;
- typedef
- typename ItemType::ScratchAndCopyDataList
- ScratchAndCopyDataList;
+ typedef
+ typename ItemType::ScratchAndCopyDataList
+ ScratchAndCopyDataList;
- Threads::ThreadLocalStorage<ScratchAndCopyDataList> data;
+ Threads::ThreadLocalStorage<ScratchAndCopyDataList> data;
/**
* Pointer to the function
ScratchData &,
CopyData &)> worker;
- /**
- * References to sample scratch and copy data for
- * when we need them.
- */
- const ScratchData &sample_scratch_data;
- const CopyData &sample_copy_data;
+ /**
+ * References to sample scratch and copy data for
+ * when we need them.
+ */
+ const ScratchData &sample_scratch_data;
+ const CopyData &sample_copy_data;
};
}
{
// create the three stages of the pipeline
internal::Implementation2::IteratorRangeToItemStream<Iterator,ScratchData,CopyData>
- iterator_range_to_item_stream (begin, end,
- queue_length,
- chunk_size,
- sample_scratch_data,
- sample_copy_data);
+ iterator_range_to_item_stream (begin, end,
+ queue_length,
+ chunk_size,
+ sample_scratch_data,
+ sample_copy_data);
internal::Implementation2::Worker<Iterator, ScratchData, CopyData> worker_filter (worker);
internal::Implementation2::Copier<Iterator, ScratchData, CopyData> copier_filter (copier);
// loop over the various colors of what we're given
for (unsigned int color=0; color<colored_iterators.size(); ++color)
if (colored_iterators[color].size() > 0)
- {
- if (static_cast<const std_cxx1x::function<void (const CopyData &)>& >(copier))
- {
- // there is a copier function, so we have to go with
- // the full three-stage design of the pipeline
- internal::Implementation3::IteratorRangeToItemStream<Iterator,ScratchData,CopyData>
- iterator_range_to_item_stream (colored_iterators[color].begin(),
- colored_iterators[color].end(),
- queue_length,
- chunk_size,
- sample_scratch_data,
- sample_copy_data);
-
-
- internal::Implementation3::WorkerAndCopier<Iterator, ScratchData, CopyData>
- worker_and_copier_filter (worker, copier);
-
- // now create a pipeline from these stages
- tbb::pipeline assembly_line;
- assembly_line.add_filter (iterator_range_to_item_stream);
- assembly_line.add_filter (worker_and_copier_filter);
-
- // and run it
- assembly_line.run (queue_length);
-
- assembly_line.clear ();
- }
- else
- {
- // no copier function, we can implement things as a parallel for
- Assert (static_cast<const std_cxx1x::function<void (const Iterator &,
- ScratchData &,
- CopyData &)>& >(worker),
- ExcMessage ("It makes no sense to call this function with "
- "empty functions for both the worker and the "
- "copier!"));
-
- typedef
- internal::ParallelFor::Worker<Iterator,ScratchData,CopyData>
- ParallelForWorker;
-
- typedef
- typename std::vector<Iterator>::const_iterator
- RangeType;
-
- ParallelForWorker parallel_for_worker (worker,
- sample_scratch_data,
- sample_copy_data);
-
- tbb::parallel_for (tbb::blocked_range<RangeType>
- (colored_iterators[color].begin(),
- colored_iterators[color].end(),
- /*grain_size=*/chunk_size),
- std_cxx1x::bind (&ParallelForWorker::operator(),
- std_cxx1x::ref(parallel_for_worker),
- std_cxx1x::_1),
- tbb::auto_partitioner());
- }
- }
+ {
+ if (static_cast<const std_cxx1x::function<void (const CopyData &)>& >(copier))
+ {
+ // there is a copier function, so we have to go with
+ // the full three-stage design of the pipeline
+ internal::Implementation3::IteratorRangeToItemStream<Iterator,ScratchData,CopyData>
+ iterator_range_to_item_stream (colored_iterators[color].begin(),
+ colored_iterators[color].end(),
+ queue_length,
+ chunk_size,
+ sample_scratch_data,
+ sample_copy_data);
+
+
+ internal::Implementation3::WorkerAndCopier<Iterator, ScratchData, CopyData>
+ worker_and_copier_filter (worker, copier);
+
+ // now create a pipeline from these stages
+ tbb::pipeline assembly_line;
+ assembly_line.add_filter (iterator_range_to_item_stream);
+ assembly_line.add_filter (worker_and_copier_filter);
+
+ // and run it
+ assembly_line.run (queue_length);
+
+ assembly_line.clear ();
+ }
+ else
+ {
+ // no copier function, we can implement things as a parallel for
+ Assert (static_cast<const std_cxx1x::function<void (const Iterator &,
+ ScratchData &,
+ CopyData &)>& >(worker),
+ ExcMessage ("It makes no sense to call this function with "
+ "empty functions for both the worker and the "
+ "copier!"));
+
+ typedef
+ internal::ParallelFor::Worker<Iterator,ScratchData,CopyData>
+ ParallelForWorker;
+
+ typedef
+ typename std::vector<Iterator>::const_iterator
+ RangeType;
+
+ ParallelForWorker parallel_for_worker (worker,
+ sample_scratch_data,
+ sample_copy_data);
+
+ tbb::parallel_for (tbb::blocked_range<RangeType>
+ (colored_iterators[color].begin(),
+ colored_iterators[color].end(),
+ /*grain_size=*/chunk_size),
+ std_cxx1x::bind (&ParallelForWorker::operator(),
+ std_cxx1x::ref(parallel_for_worker),
+ std_cxx1x::_1),
+ tbb::auto_partitioner());
+ }
+ }
}
#endif
}
*
* @note This class does not support anisotropic refinement, because
* it relies on the p4est library that does not support this. Attempts
- * to refine cells anisotropically will result in errors.
+ * to refine cells anisotropically will result in errors.
* @note There is currently no support for distributing 1d triangulations.
*
*
class Triangulation : public dealii::Triangulation<dim,spacedim>
{
public:
- /**
- * A typedef that is used to to identify cell iterators. The
- * concept of iterators is discussed at length in the
- * @ref Iterators "iterators documentation module".
- *
- * The current typedef identifies cells in a triangulation. You
- * can find the exact type it refers to in the base class's own
- * typedef, but it should be TriaIterator<CellAccessor<dim,spacedim> >. The
- * TriaIterator class works like a pointer that when you
- * dereference it yields an object of type CellAccessor.
- * CellAccessor is a class that identifies properties that
- * are specific to cells in a triangulation, but it is derived
- * (and consequently inherits) from TriaAccessor that describes
- * what you can ask of more general objects (lines, faces, as
- * well as cells) in a triangulation.
- *
- * @ingroup Iterators
- */
+ /**
+ * A typedef that is used to to identify cell iterators. The
+ * concept of iterators is discussed at length in the
+ * @ref Iterators "iterators documentation module".
+ *
+ * The current typedef identifies cells in a triangulation. You
+ * can find the exact type it refers to in the base class's own
+ * typedef, but it should be TriaIterator<CellAccessor<dim,spacedim> >. The
+ * TriaIterator class works like a pointer that when you
+ * dereference it yields an object of type CellAccessor.
+ * CellAccessor is a class that identifies properties that
+ * are specific to cells in a triangulation, but it is derived
+ * (and consequently inherits) from TriaAccessor that describes
+ * what you can ask of more general objects (lines, faces, as
+ * well as cells) in a triangulation.
+ *
+ * @ingroup Iterators
+ */
typedef typename dealii::Triangulation<dim,spacedim>::cell_iterator cell_iterator;
/**
*/
enum CellStatus
{
- /**
- * The cell will not be refined or coarsened and might or might
- * not move to a different processor.
- */
+ /**
+ * The cell will not be refined or coarsened and might or might
+ * not move to a different processor.
+ */
CELL_PERSIST,
- /**
- * The cell will be or was refined.
- */
- CELL_REFINE,
- /**
- * The children of this cell will be or were coarsened into this cell.
- */
- CELL_COARSEN,
- /**
- * Invalid status. Will not occur for the user.
- */
- CELL_INVALID
+ /**
+ * The cell will be or was refined.
+ */
+ CELL_REFINE,
+ /**
+ * The children of this cell will be or were coarsened into this cell.
+ */
+ CELL_COARSEN,
+ /**
+ * Invalid status. Will not occur for the user.
+ */
+ CELL_INVALID
};
/**
* Callers need to store the return value. It specifies an
* offset of the position at which data can later be retrieved
* during a call to notify_ready_to_unpack().
- *
+ *
* The CellStatus argument in the callback function will tell you if the
* given cell will be coarsened, refined, or will persist as is (this
* can be different than the coarsen and refine flags set by you). If it
* is
- *
+ *
* - CELL_PERIST: the cell won't be refined/coarsened, but might be
* moved to a different processor
* - CELL_REFINE: this cell will be refined into 4/8 cells, you can not
* access the children (because they don't exist yet)
* - CELL_COARSEN: the children of this cell will be coarsened into the
* given cell (you can access the active children!)
- *
+ *
* When unpacking the data with notify_ready_to_unpack() you can access
* the children of the cell if the status is CELL_REFINE but not for
* CELL_COARSEN. As a consequence you need to handle coarsening while
dof_handler(0)
{
Assert (false, ExcMessage("You are trying to assign iterators that are incompatible. "
- "Reasons for incompatibility are that they point to different "
- "types of DoFHandlers (e.g., dealii::DoFHandler and "
- "dealii::hp::DoFHandler) or that the refer to objects of "
- "different dimensionality (e.g., assigning a line iterator "
- "to a quad iterator)."));
+ "Reasons for incompatibility are that they point to different "
+ "types of DoFHandlers (e.g., dealii::DoFHandler and "
+ "dealii::hp::DoFHandler) or that the refer to objects of "
+ "different dimensionality (e.g., assigning a line iterator "
+ "to a quad iterator)."));
}
inline
types::global_dof_index
DoFAccessor<dim,DH,level_dof_access>::dof_index (const unsigned int i,
- const unsigned int fe_index) const
+ const unsigned int fe_index) const
{
// access the respective DoF
return dealii::internal::DoFAccessor::Implementation::get_dof_index (*this->dof_handler,
inline
types::global_dof_index
DoFAccessor<structdim, DH,level_dof_access>::mg_dof_index (const int level,
- const unsigned int i) const
+ const unsigned int i) const
{
return this->dof_handler->template get_dof_index<structdim> (level, this->present_index, 0, i);
}
inline
void
DoFAccessor<dim,DH,level_dof_access>::set_dof_index (const unsigned int i,
- const types::global_dof_index index,
- const unsigned int fe_index) const
+ const types::global_dof_index index,
+ const unsigned int fe_index) const
{
// access the respective DoF
dealii::internal::DoFAccessor::Implementation::set_dof_index (*this->dof_handler,
inline
types::global_dof_index
DoFAccessor<structdim, DH,level_dof_access>::vertex_dof_index (const unsigned int vertex,
- const unsigned int i,
- const unsigned int fe_index) const
+ const unsigned int i,
+ const unsigned int fe_index) const
{
return
dealii::internal::DoFAccessor::Implementation::get_vertex_dof_index
inline
types::global_dof_index
DoFAccessor<structdim, DH,level_dof_access>::mg_vertex_dof_index (const int level,
- const unsigned int vertex,
- const unsigned int i,
- const unsigned int fe_index) const
+ const unsigned int vertex,
+ const unsigned int i,
+ const unsigned int fe_index) const
{
Assert (this->dof_handler != 0, ExcInvalidObject ());
Assert (&this->dof_handler->get_fe () != 0, ExcInvalidObject ());
inline
void
DoFAccessor<structdim, DH,level_dof_access>::set_vertex_dof_index (const unsigned int vertex,
- const unsigned int i,
- const types::global_dof_index index,
- const unsigned int fe_index) const
+ const unsigned int i,
+ const types::global_dof_index index,
+ const unsigned int fe_index) const
{
dealii::internal::DoFAccessor::Implementation::set_vertex_dof_index
(*this->dof_handler,
inline
void
DoFAccessor<structdim, DH,level_dof_access>::set_mg_vertex_dof_index (const int level,
- const unsigned int vertex,
- const unsigned int i,
- const types::global_dof_index index,
- const unsigned int fe_index) const
+ const unsigned int vertex,
+ const unsigned int i,
+ const types::global_dof_index index,
+ const unsigned int fe_index) const
{
Assert (this->dof_handler != 0, ExcInvalidObject ());
Assert (&this->dof_handler->get_fe () != 0, ExcInvalidObject ());
inline
void
DoFAccessor<structdim, DH,level_dof_access>::set_mg_dof_index (const int level,
- const unsigned int i,
- const types::global_dof_index index) const
+ const unsigned int i,
+ const types::global_dof_index index) const
{
this->dof_handler->template set_dof_index<structdim> (level, this->present_index, 0, i, index);
}
inline
void
DoFAccessor<structdim,DH,level_dof_access>::get_dof_indices (std::vector<types::global_dof_index> &dof_indices,
- const unsigned int fe_index) const
+ const unsigned int fe_index) const
{
Assert (this->dof_handler != 0, ExcNotInitialized());
Assert (&this->dof_handler->get_fe() != 0, ExcMessage ("DoFHandler not initialized"));
template<int structdim, class DH, bool level_dof_access>
inline
void DoFAccessor<structdim, DH,level_dof_access>::get_mg_dof_indices (const int level,
- std::vector<types::global_dof_index> &dof_indices,
- const unsigned int fe_index) const
+ std::vector<types::global_dof_index> &dof_indices,
+ const unsigned int fe_index) const
{
Assert (this->dof_handler != 0, ExcInvalidObject ());
Assert (&this->dof_handler->get_fe () != 0, ExcInvalidObject ());
template<int structdim, class DH, bool level_dof_access>
inline
void DoFAccessor<structdim, DH,level_dof_access>::set_mg_dof_indices (const int level,
- const std::vector<types::global_dof_index> &dof_indices,
- const unsigned int fe_index)
+ const std::vector<types::global_dof_index> &dof_indices,
+ const unsigned int fe_index)
{
Assert (this->dof_handler != 0, ExcInvalidObject ());
Assert (&this->dof_handler->get_fe () != 0, ExcInvalidObject ());
inline
void
DoFCellAccessor<DH,level_dof_access>::get_dof_values (const InputVector &values,
- Vector<number> &local_values) const
+ Vector<number> &local_values) const
{
get_dof_values (values, local_values.begin(), local_values.end());
}
inline
void
DoFCellAccessor<DH,level_dof_access>::get_dof_values (const InputVector &values,
- ForwardIterator local_values_begin,
- ForwardIterator local_values_end) const
+ ForwardIterator local_values_begin,
+ ForwardIterator local_values_end) const
{
Assert (this->is_artificial() == false,
ExcMessage ("Can't ask for DoF indices on artificial cells."));
inline
void
DoFCellAccessor<DH,level_dof_access>::get_dof_values (const ConstraintMatrix &constraints,
- const InputVector &values,
- ForwardIterator local_values_begin,
- ForwardIterator local_values_end) const
+ const InputVector &values,
+ ForwardIterator local_values_begin,
+ ForwardIterator local_values_end) const
{
Assert (this->is_artificial() == false,
ExcMessage ("Can't ask for DoF indices on artificial cells."));
inline
void
DoFCellAccessor<DH,level_dof_access>::set_dof_values (const Vector<number> &local_values,
- OutputVector &values) const
+ OutputVector &values) const
{
Assert (this->is_artificial() == false,
ExcMessage ("Can't ask for DoF indices on artificial cells."));
DoFCellAccessor<DH,level_dof_access>::get_fe () const
{
Assert ((dynamic_cast<const dealii::DoFHandler<DH::dimension,DH::space_dimension>*>
- (this->dof_handler) != 0)
- ||
- (this->has_children() == false),
+ (this->dof_handler) != 0)
+ ||
+ (this->has_children() == false),
ExcMessage ("In hp::DoFHandler objects, finite elements are only associated "
- "with active cells. Consequently, you can not ask for the "
- "active finite element on cells with children."));
+ "with active cells. Consequently, you can not ask for the "
+ "active finite element on cells with children."));
return dealii::internal::DoFAccessor::get_fe (this->dof_handler->get_fe(), active_fe_index());
}
DoFCellAccessor<DH,level_dof_access>::active_fe_index () const
{
Assert ((dynamic_cast<const dealii::DoFHandler<DH::dimension,DH::space_dimension>*>
- (this->dof_handler) != 0)
- ||
- (this->has_children() == false),
+ (this->dof_handler) != 0)
+ ||
+ (this->has_children() == false),
ExcMessage ("You can not ask for the active_fe_index on a cell that has "
"children because no degrees of freedom are assigned "
"to this cell and, consequently, no finite element "
- "is associated with it."));
+ "is associated with it."));
return dealii::internal::DoFCellAccessor::Implementation::active_fe_index (*this);
}
DoFCellAccessor<DH,level_dof_access>::set_active_fe_index (const unsigned int i)
{
Assert ((dynamic_cast<const dealii::DoFHandler<DH::dimension,DH::space_dimension>*>
- (this->dof_handler) != 0)
- ||
- (this->has_children() == false),
+ (this->dof_handler) != 0)
+ ||
+ (this->has_children() == false),
ExcMessage ("You can not set the active_fe_index on a cell that has "
"children because no degrees of freedom will be assigned "
"to this cell."));
* @name Identifying subsets of degrees of freedom with particular properties
* @{
*/
-
+
/**
* Extract the indices of the degrees of freedom belonging to
* certain vector components of a vector-valued finite element. The
extract_constant_modes (const DH &dof_handler,
const ComponentMask &component_mask,
std::vector<std::vector<bool> > &constant_modes);
-
+
/**
* @}
*/
std::vector<types::global_dof_index> &dofs_per_component,
std::vector<unsigned int> target_component) DEAL_II_DEPRECATED;
-
+
/**
* For each active cell of a DoFHandler or hp::DoFHandler, extract
* the active finite element index and fill the vector given as
/**
* @}
*/
-
+
/**
* Create a mapping from degree of freedom indices to the index of
* that degree of freedom on the boundary. After this operation,
* Set a particular entry in the mask to a value.
*/
void set (const unsigned int index, const bool value);
-
+
/**
* If this component mask has been initialized with a mask of
* size greater than zero, then return the size of the mask
template <class POLY, int dim, int spacedim>
bool
FE_DGVector<POLY,dim,spacedim>::has_support_on_face (const unsigned int,
- const unsigned int) const
+ const unsigned int) const
{
return true;
}
typename Mapping<1,spacedim>::InternalDataBase *
get_face_data (const UpdateFlags,
const Mapping<1,spacedim> &mapping,
- const Quadrature<0>& quadrature) const ;
+ const Quadrature<0> &quadrature) const ;
typename Mapping<1,spacedim>::InternalDataBase *
get_subface_data (const UpdateFlags,
const Mapping<1,spacedim> &mapping,
- const Quadrature<0>& quadrature) const ;
+ const Quadrature<0> &quadrature) const ;
virtual void
fill_fe_values (const Mapping<1,spacedim> &mapping,
if (flags & update_values)
for (unsigned int i=0; i<quadrature.size(); ++i)
{
- for (unsigned int k=0; k<this->dofs_per_cell; ++k)
+ for (unsigned int k=0; k<this->dofs_per_cell; ++k)
data.shape_values(k,i) = 0.;
- switch (dim)
- {
- case 3:
- {
- // Fill data for quad shape functions
- if (this->dofs_per_quad !=0)
- {
- const unsigned int foffset = this->first_quad_index + this->dofs_per_quad * face;
- for (unsigned int k=0; k<this->dofs_per_quad; ++k)
- data.shape_values(foffset+k,i) = fe_data.shape_values[k+this->first_face_quad_index][i];
- }
- }
- case 2:
- {
- // Fill data for line shape functions
- if (this->dofs_per_line != 0)
- {
- const unsigned int foffset = this->first_line_index;
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_face; ++line)
- {
- for (unsigned int k=0; k<this->dofs_per_line; ++k)
- data.shape_values(foffset+GeometryInfo<dim>::face_to_cell_lines(face, line)*this->dofs_per_line+k,i) = fe_data.shape_values[k+(line*this->dofs_per_line)+this->first_face_line_index][i];
- }
- }
- }
- case 1:
- {
- // Fill data for vertex shape functions
- if (this->dofs_per_vertex != 0)
- for (unsigned int lvertex=0; lvertex<GeometryInfo<dim>::vertices_per_face; ++lvertex)
- data.shape_values(GeometryInfo<dim>::face_to_cell_vertices(face, lvertex),i) = fe_data.shape_values[lvertex][i];
- break;
- }
- }
+ switch (dim)
+ {
+ case 3:
+ {
+ // Fill data for quad shape functions
+ if (this->dofs_per_quad !=0)
+ {
+ const unsigned int foffset = this->first_quad_index + this->dofs_per_quad * face;
+ for (unsigned int k=0; k<this->dofs_per_quad; ++k)
+ data.shape_values(foffset+k,i) = fe_data.shape_values[k+this->first_face_quad_index][i];
+ }
+ }
+ case 2:
+ {
+ // Fill data for line shape functions
+ if (this->dofs_per_line != 0)
+ {
+ const unsigned int foffset = this->first_line_index;
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_face; ++line)
+ {
+ for (unsigned int k=0; k<this->dofs_per_line; ++k)
+ data.shape_values(foffset+GeometryInfo<dim>::face_to_cell_lines(face, line)*this->dofs_per_line+k,i) = fe_data.shape_values[k+(line*this->dofs_per_line)+this->first_face_line_index][i];
+ }
+ }
+ }
+ case 1:
+ {
+ // Fill data for vertex shape functions
+ if (this->dofs_per_vertex != 0)
+ for (unsigned int lvertex=0; lvertex<GeometryInfo<dim>::vertices_per_face; ++lvertex)
+ data.shape_values(GeometryInfo<dim>::face_to_cell_vertices(face, lvertex),i) = fe_data.shape_values[lvertex][i];
+ break;
+ }
+ }
}
}
* @dealiiRequiresUpdateFlags{update_inverse_jacobians}
*/
const std::vector<DerivativeForm<1,spacedim,dim> > &get_inverse_jacobians () const;
-
+
/**
* For a face, return the outward normal vector to the cell at the
* <tt>i</tt>th quadrature point.
void hyper_cube (Triangulation<dim,spacedim> &tria,
const double left = 0.,
const double right= 1.,
- const bool colorize= false);
+ const bool colorize= false);
/**
* Same as hyper_cube(), but with the difference that not only one cell is
*/
template <int dim, int spacedim1, int spacedim2>
void flatten_triangulation(const Triangulation<dim,spacedim1> &in_tria,
- Triangulation<dim,spacedim2> &out_tria);
+ Triangulation<dim,spacedim2> &out_tria);
/**
* @}
template <template <int,int> class Container, int dim, int spacedim>
struct ExtractBoundaryMesh
{
- typedef
- std::map<typename Container<dim-1,spacedim>::cell_iterator,
- typename Container<dim,spacedim>::face_iterator>
- return_type;
+ typedef
+ std::map<typename Container<dim-1,spacedim>::cell_iterator,
+ typename Container<dim,spacedim>::face_iterator>
+ return_type;
};
#endif
/// The factor determining the vertical distance between levels (default = 0.3)
float level_height_factor;
-
+
/**
* Cell labeling (fixed order).
*
* @name Finding cells and vertices of a triangulation
*/
/*@{*/
-
+
/**
* Find and return the number of
* the used vertex in a given
* @name Partitions and subdomains of triangulations
*/
/*@{*/
-
+
/**
* Produce a sparsity pattern in which
* nonzero entries indicate that two
/*@}*/
/**
- * @name Lower-dimensional meshes for parts of higher-dimensional meshes
+ * @name Lower-dimensional meshes for parts of higher-dimensional meshes
*/
/*@{*/
template <template <int,int> class Container, int dim, int spacedim>
struct ExtractBoundaryMesh
{
- typedef
- std::map<typename Container<dim-1,spacedim>::cell_iterator,
- typename Container<dim,spacedim>::face_iterator>
- return_type;
+ typedef
+ std::map<typename Container<dim-1,spacedim>::cell_iterator,
+ typename Container<dim,spacedim>::face_iterator>
+ return_type;
};
#endif
for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
if (cell->face(face)->has_children() &&
!cell->face(face)->at_boundary())
- { // this line has children
+ {
+ // this line has children
cell->face(face)->child(0)->vertex(1)
- = (cell->face(face)->vertex(0) +
- cell->face(face)->vertex(1)) / 2;
+ = (cell->face(face)->vertex(0) +
+ cell->face(face)->vertex(1)) / 2;
}
}
else if (dim==3)
for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
if (cell->face(face)->has_children() &&
!cell->face(face)->at_boundary())
- { // this face has hanging nodes
+ {
+ // this face has hanging nodes
cell->face(face)->child(0)->vertex(1)
- = (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)) / 2.0;
+ = (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)) / 2.0;
cell->face(face)->child(0)->vertex(2)
- = (cell->face(face)->vertex(0) + cell->face(face)->vertex(2)) / 2.0;
+ = (cell->face(face)->vertex(0) + cell->face(face)->vertex(2)) / 2.0;
cell->face(face)->child(1)->vertex(3)
- = (cell->face(face)->vertex(1) + cell->face(face)->vertex(3)) / 2.0;
+ = (cell->face(face)->vertex(1) + cell->face(face)->vertex(3)) / 2.0;
cell->face(face)->child(2)->vertex(3)
- = (cell->face(face)->vertex(2) + cell->face(face)->vertex(3)) / 2.0;
+ = (cell->face(face)->vertex(2) + cell->face(face)->vertex(3)) / 2.0;
// center of the face
cell->face(face)->child(0)->vertex(3)
- = (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)
- + cell->face(face)->vertex(2) + cell->face(face)->vertex(3)) / 4.0;
+ = (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)
+ + cell->face(face)->vertex(2) + cell->face(face)->vertex(3)) / 4.0;
}
}
}
/**
* Manifold description derived from ChartManifold, based on explicit
* Function<spacedim> and Function<chartdim> objects describing the
- * push_forward() and pull_back() functions.
+ * push_forward() and pull_back() functions.
*
* You can use this Manifold object to describe any arbitray shape
* domain, as long as you can express it in terms of an invertible
*
* In debug mode, a check is performed to verify that the
* tranformations are actually one the inverse of the other.
- *
+ *
* @ingroup manifold
*
* @author Luca Heltai, 2014
*/
template <int dim, int spacedim=dim, int chartdim=dim>
-class FunctionManifold : public ChartManifold<dim, spacedim, chartdim>
+class FunctionManifold : public ChartManifold<dim, spacedim, chartdim>
{
public:
/**
* that the two functions are one the inverse of the other.
*/
FunctionManifold(const Function<chartdim> &push_forward_function,
- const Function<spacedim> &pull_back_function,
- const Point<chartdim> periodicity=Point<chartdim>(),
- const double tolerance=1e-10);
+ const Function<spacedim> &pull_back_function,
+ const Point<chartdim> periodicity=Point<chartdim>(),
+ const double tolerance=1e-10);
/**
* Expressions constructor. Takes the expressions of the
* that the two functions are one the inverse of the other.
*/
FunctionManifold(const std::string push_forward_expression,
- const std::string pull_back_expression,
- const Point<chartdim> periodicity=Point<chartdim>(),
- const typename FunctionParser<spacedim>::ConstMap = typename FunctionParser<spacedim>::ConstMap(),
- const std::string chart_vars=FunctionParser<chartdim>::default_variable_names(),
- const std::string space_vars=FunctionParser<spacedim>::default_variable_names(),
- const double tolerance=1e-10);
+ const std::string pull_back_expression,
+ const Point<chartdim> periodicity=Point<chartdim>(),
+ const typename FunctionParser<spacedim>::ConstMap = typename FunctionParser<spacedim>::ConstMap(),
+ const std::string chart_vars=FunctionParser<chartdim>::default_variable_names(),
+ const std::string space_vars=FunctionParser<spacedim>::default_variable_names(),
+ const double tolerance=1e-10);
/**
* If needed, we delete the pointers we own.
*/
~FunctionManifold();
-
+
/**
* Given a point in the chartdim coordinate system, uses the
* push_forward_function to compute the push_forward of points in
* Pointer to the push_forward function.
*/
SmartPointer<const Function<chartdim>,
- FunctionManifold<dim,spacedim,chartdim> > push_forward_function;
-
+ FunctionManifold<dim,spacedim,chartdim> > push_forward_function;
+
/**
* Pointer to the pull_back function.
*/
- SmartPointer<const Function<spacedim>,
- FunctionManifold<dim,spacedim,chartdim> > pull_back_function;
-
+ SmartPointer<const Function<spacedim>,
+ FunctionManifold<dim,spacedim,chartdim> > pull_back_function;
+
/**
* Relative tolerance. In debug mode, we check that the two
* functions provided at construction time are actually one the
* this check.
*/
const double tolerance;
-
+
/**
* Check ownership of the smart pointers. Indicates whether this
* class is the owner of the objects pointed to by the previous two
*/
const bool owns_pointers;
};
-
-
+
+
DEAL_II_NAMESPACE_CLOSE
#endif
AssertDimension(fetest.get_fe().n_components(), dim);
AssertVectorVectorDimension(input, dim, fetest.n_quadrature_points);
-
+
for (unsigned int k=0; k<fetest.n_quadrature_points; ++k)
{
const double dx = factor * fetest.JxW(k);
for (unsigned int i=0; i<n_dofs; ++i)
- {
- double dv = 0.;
- double du = 0.;
- for (unsigned int d=0; d<dim; ++d)
- {
- dv += fetest.shape_grad_component(i,k,d)[d];
- du += input[d][k][d];
- }
-
- result(i) += dx * du * dv;
- }
+ {
+ double dv = 0.;
+ double du = 0.;
+ for (unsigned int d=0; d<dim; ++d)
+ {
+ dv += fetest.shape_grad_component(i,k,d)[d];
+ du += input[d][k][d];
+ }
+
+ result(i) += dx * du * dv;
+ }
}
}
AssertDimension(M.m(), n_dofs);
AssertDimension(M.n(), n_dofs);
AssertDimension(weights.size(), fe.n_quadrature_points);
-
+
for (unsigned int k=0; k<fe.n_quadrature_points; ++k)
{
const double dx = fe.JxW(k) * weights[k];
const size_type reduced_row = row/chunk_size;
SparsityPattern::iterator it = cols->sparsity_pattern.begin(reduced_row),
- itend = cols->sparsity_pattern.end(reduced_row);
+ itend = cols->sparsity_pattern.end(reduced_row);
const number *val_ptr = &val[(it-cols->sparsity_pattern.begin(0))*chunk_size*chunk_size
+(row%chunk_size)*chunk_size];
sparsity_pattern.add_entries(actual_dof_indices[i],
actual_dof_indices.begin(),
actual_dof_indices.end(),
- true);
+ true);
// need to add the whole row and column structure in case we keep
// constrained entries. Unfortunately, we can't use the nice matrix
* same argument list as this present function.
*/
void reinit (const size_type rows,
- const size_type cols);
+ const size_type cols);
/**
* Return the dimension of the range space. @note The matrix is of
* to be told to use LAPACK.
*/
void compute_eigenvalues_symmetric (const number lower_bound,
- const number upper_bound,
- const number abs_accuracy,
- Vector<number> &eigenvalues,
- FullMatrix<number> &eigenvectors);
+ const number upper_bound,
+ const number abs_accuracy,
+ Vector<number> &eigenvalues,
+ FullMatrix<number> &eigenvectors);
/**
* Compute generalized eigenvalues and eigenvectors of a real generalized
* to be told to use LAPACK.
*/
void compute_generalized_eigenvalues_symmetric (LAPACKFullMatrix<number> &B,
- const number lower_bound,
- const number upper_bound,
- const number abs_accuracy,
- Vector<number> &eigenvalues,
- std::vector<Vector<number> > &eigenvectors,
- const int itype = 1);
+ const number lower_bound,
+ const number upper_bound,
+ const number abs_accuracy,
+ Vector<number> &eigenvalues,
+ std::vector<Vector<number> > &eigenvectors,
+ const int itype = 1);
/**
* Same as the other compute_generalized_eigenvalues_symmetric function
* to be told to use LAPACK.
*/
void compute_generalized_eigenvalues_symmetric (LAPACKFullMatrix<number> &B,
- std::vector<Vector<number> > &eigenvectors,
- const int itype = 1);
+ std::vector<Vector<number> > &eigenvectors,
+ const int itype = 1);
/**
* Compute the singular value decomposition of the matrix using LAPACK
const double threshold = 0.) const;
private:
-
+
/**
* Since LAPACK operations notoriously change the meaning of the
* matrix entries, we record the current state after the last
template <class MATRIX>
void
reinit(MatrixBlock<MATRIX> &v,
- const BlockSparsityPattern &p);
+ const BlockSparsityPattern &p);
template <typename number>
void
reinit(MatrixBlock<dealii::SparseMatrix<number> > &v,
- const BlockSparsityPattern &p);
+ const BlockSparsityPattern &p);
}
/**
template <class OTHER_MATRIX>
friend
void dealii::internal::reinit(MatrixBlock<OTHER_MATRIX> &,
- const BlockSparsityPattern &);
+ const BlockSparsityPattern &);
template <typename number>
friend
void internal::reinit(MatrixBlock<dealii::SparseMatrix<number> > &v,
- const BlockSparsityPattern &p);
+ const BlockSparsityPattern &p);
};
template <class MATRIX>
void
reinit(MatrixBlock<MATRIX> &v,
- const BlockSparsityPattern &p)
+ const BlockSparsityPattern &p)
{
v.row_indices = p.get_row_indices();
v.column_indices = p.get_column_indices();
template <typename number>
void
reinit(MatrixBlock<dealii::SparseMatrix<number> > &v,
- const BlockSparsityPattern &p)
+ const BlockSparsityPattern &p)
{
v.row_indices = p.get_row_indices();
v.column_indices = p.get_column_indices();
class FullMatrix : public MatrixBase
{
public:
-
+
/**
* Declare type for container size.
*/
/**
* @copydoc PETScWrappers::VectorBase::all_zero()
- *
+ *
* @note This function overloads the one in the base class
* to make this a collective operation.
*/
{
// make sure left- and right-hand side of the assignment are compress()'ed:
Assert(v.last_action == VectorOperation::unknown,
- internal::VectorReference::ExcWrongMode (VectorOperation::unknown,
- v.last_action));
+ internal::VectorReference::ExcWrongMode (VectorOperation::unknown,
+ v.last_action));
Assert(last_action == VectorOperation::unknown,
- internal::VectorReference::ExcWrongMode (VectorOperation::unknown,
- last_action));
+ internal::VectorReference::ExcWrongMode (VectorOperation::unknown,
+ last_action));
if (v.size()==0)
{
out << "Iterative method reported convergence failure in step "
<< last_step << ". The residual in the last step was " << last_residual
- << ".\n\n"
- << "This error message can indicate that you have simply not allowed "
- << "a sufficiently large number of iterations for your iterative solver "
- << "to converge. This often happens when you increase the size of your "
- << "problem. In such cases, the last residual will likely still be very "
- << "small, and you can make the error go away by increasing the allowed "
- << "number of iterations when setting up the SolverControl object that "
- << "determines the maximal number of iterations you allow."
- << "\n\n"
- << "The other situation where this error may occur is when your matrix "
- << "is not invertible (e.g., your matrix has a null-space), or if you "
- << "try to apply the wrong solver to a matrix (e.g., using CG for a "
- << "matrix that is not symmetric or not positive definite). In these "
- << "cases, the residual in the last iteration is likely going to be large."
- << std::endl;
+ << ".\n\n"
+ << "This error message can indicate that you have simply not allowed "
+ << "a sufficiently large number of iterations for your iterative solver "
+ << "to converge. This often happens when you increase the size of your "
+ << "problem. In such cases, the last residual will likely still be very "
+ << "small, and you can make the error go away by increasing the allowed "
+ << "number of iterations when setting up the SolverControl object that "
+ << "determines the maximal number of iterations you allow."
+ << "\n\n"
+ << "The other situation where this error may occur is when your matrix "
+ << "is not invertible (e.g., your matrix has a null-space), or if you "
+ << "try to apply the wrong solver to a matrix (e.g., using CG for a "
+ << "matrix that is not symmetric or not positive definite). In these "
+ << "cases, the residual in the last iteration is likely going to be large."
+ << std::endl;
}
/**
&B.val[new_cols-&sp_B.colnums[sp_B.rowstart[0]]];
const numberB *const end_cols = &B.val[sp_B.rowstart[col+1]];
for (; B_val_ptr != end_cols; ++B_val_ptr)
- *new_ptr++ = A_val * *B_val_ptr * (use_vector ? V(col) : 1);
+ *new_ptr++ = A_val **B_val_ptr * (use_vector ? V(col) : 1);
C.add (i, new_ptr-&new_entries[0], new_cols, &new_entries[0],
false, true);
const unsigned int smoother_sweeps = 2,
const unsigned int smoother_overlap = 0,
const bool output_details = false,
- const char* smoother_type = "Chebyshev",
- const char* coarse_type = "Amesos-KLU");
+ const char *smoother_type = "Chebyshev",
+ const char *coarse_type = "Amesos-KLU");
/**
* Determines whether the AMG preconditioner should be optimized for
* <li> "IFPACK-Block Chebyshev" </li>
* </ul>
*/
- const char* smoother_type;
+ const char *smoother_type;
/**
* Determines which solver to use on the coarsest level. The same
* settings as for the smoother type are possible.
*/
- const char* coarse_type;
+ const char *coarse_type;
};
/**
<< (row_partitioner().MyGID(static_cast<TrilinosWrappers::types::int_type>(row)) == false ? "(nonlocal part)" : "")
<< " has the following indices:" << std::endl;
std::vector<TrilinosWrappers::types::int_type> indices;
- const Epetra_CrsGraph* graph =
+ const Epetra_CrsGraph *graph =
(nonlocal_matrix.get() != 0 &&
row_partitioner().MyGID(static_cast<TrilinosWrappers::types::int_type>(row)) == false) ?
&nonlocal_matrix->Graph() : &matrix->Graph();
}
else
ierr = graph->InsertGlobalIndices
- (1, (TrilinosWrappers::types::int_type *)&row, n_cols, col_index_ptr);
+ (1, (TrilinosWrappers::types::int_type *)&row, n_cols, col_index_ptr);
AssertThrow (ierr >= 0, ExcTrilinosError(ierr));
}
// use pre-allocated vector for non-local entries if it exists for
// addition operation
const TrilinosWrappers::types::int_type my_row = nonlocal_vector->Map().LID(static_cast<TrilinosWrappers::types::int_type>(row));
- Assert(my_row != -1,
+ Assert(my_row != -1,
ExcMessage("Attempted to write into off-processor vector entry "
"that has not be specified as being writable upon "
- "initialization"));
+ "initialization"));
(*nonlocal_vector)[0][my_row] += values[i];
compressed = false;
}
Assert (numbers::is_finite(s), ExcNumberNotFinite());
- if(local_size() == v.local_size())
- {
- const int ierr = vector->Update(1., *(v.vector), s);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- }
+ if (local_size() == v.local_size())
+ {
+ const int ierr = vector->Update(1., *(v.vector), s);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+ }
else
- {
- VectorBase tmp = v;
- tmp *= s;
- this->add(tmp, true);
- }
+ {
+ VectorBase tmp = v;
+ tmp *= s;
+ this->add(tmp, true);
+ }
}
Assert (numbers::is_finite(s), ExcNumberNotFinite());
Assert (numbers::is_finite(a), ExcNumberNotFinite());
- if(local_size() == v.local_size())
- {
- const int ierr = vector->Update(a, *(v.vector), s);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- }
+ if (local_size() == v.local_size())
+ {
+ const int ierr = vector->Update(a, *(v.vector), s);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+ }
else
- {
- (*this)*=s;
- VectorBase tmp = v;
- tmp *= a;
- this->add(tmp, true);
- }
+ {
+ (*this)*=s;
+ VectorBase tmp = v;
+ tmp *= a;
+ this->add(tmp, true);
+ }
}
Assert (numbers::is_finite(s), ExcNumberNotFinite());
Assert (numbers::is_finite(a), ExcNumberNotFinite());
Assert (numbers::is_finite(b), ExcNumberNotFinite());
-
- if(local_size() == v.local_size() && local_size() == w.local_size())
- {
- const int ierr = vector->Update(a, *(v.vector), b, *(w.vector), s);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- }
- else
- {
- (*this)*=s;
+
+ if (local_size() == v.local_size() && local_size() == w.local_size())
{
- VectorBase tmp = v;
- tmp *= a;
- this->add(tmp, true);
+ const int ierr = vector->Update(a, *(v.vector), b, *(w.vector), s);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
}
+ else
{
- VectorBase tmp = w;
- tmp *= b;
- this->add(tmp, true);
+ (*this)*=s;
+ {
+ VectorBase tmp = v;
+ tmp *= a;
+ this->add(tmp, true);
+ }
+ {
+ VectorBase tmp = w;
+ tmp *= b;
+ this->add(tmp, true);
+ }
}
- }
}
Assert (numbers::is_finite(b), ExcNumberNotFinite());
Assert (numbers::is_finite(c), ExcNumberNotFinite());
- if(local_size() == v.local_size()
- && local_size() == w.local_size()
- && local_size() == x.local_size())
- {
- // Update member can only
- // input two other vectors so
- // do it in two steps
- const int ierr = vector->Update(a, *(v.vector), b, *(w.vector), s);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
-
- const int jerr = vector->Update(c, *(x.vector), 1.);
- Assert (jerr == 0, ExcTrilinosError(jerr));
- (void)jerr; // removes -Wunused-parameter warning in optimized mode
- }
- else
- {
- (*this)*=s;
- {
- VectorBase tmp = v;
- tmp *= a;
- this->add(tmp, true);
- }
+ if (local_size() == v.local_size()
+ && local_size() == w.local_size()
+ && local_size() == x.local_size())
{
- VectorBase tmp = w;
- tmp *= b;
- this->add(tmp, true);
+ // Update member can only
+ // input two other vectors so
+ // do it in two steps
+ const int ierr = vector->Update(a, *(v.vector), b, *(w.vector), s);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+
+ const int jerr = vector->Update(c, *(x.vector), 1.);
+ Assert (jerr == 0, ExcTrilinosError(jerr));
+ (void)jerr; // removes -Wunused-parameter warning in optimized mode
}
+ else
{
- VectorBase tmp = x;
- tmp *= c;
- this->add(tmp, true);
+ (*this)*=s;
+ {
+ VectorBase tmp = v;
+ tmp *= a;
+ this->add(tmp, true);
+ }
+ {
+ VectorBase tmp = w;
+ tmp *= b;
+ this->add(tmp, true);
+ }
+ {
+ VectorBase tmp = x;
+ tmp *= c;
+ this->add(tmp, true);
+ }
}
- }
}
// nothing here, assume all cells to belong to the zero partition (that
// we otherwise use for MPI boundary cells)
unsigned int start_up = 0,
- start_nonboundary = numbers::invalid_unsigned_int;
+ start_nonboundary = numbers::invalid_unsigned_int;
if (task_info.use_coloring_only == false)
{
start_nonboundary =
* or before distributing them into a result vector). The methods
* get_dof_value() and submit_dof_value() read from or write to this field.
*/
- VectorizedArray<Number>* values_dofs[n_components];
+ VectorizedArray<Number> *values_dofs[n_components];
/**
* This field stores the values of the finite element function on quadrature
* integrating. The methods get_value() and submit_value() access this
* field.
*/
- VectorizedArray<Number>* values_quad[n_components];
+ VectorizedArray<Number> *values_quad[n_components];
/**
* This field stores the gradients of the finite element function on
* some specializations like get_symmetric_gradient() or get_divergence())
* access this field.
*/
- VectorizedArray<Number>* gradients_quad[n_components][dim];
+ VectorizedArray<Number> *gradients_quad[n_components][dim];
/**
* This field stores the Hessians of the finite element function on
* quadrature points after applying unit cell transformations. The methods
* get_hessian(), get_laplacian(), get_hessian_diagonal() access this field.
*/
- VectorizedArray<Number>* hessians_quad[n_components][(dim*(dim+1))/2];
+ VectorizedArray<Number> *hessians_quad[n_components][(dim*(dim+1))/2];
/**
* Stores the number of the quadrature formula of the present cell.
* A temporary data structure necessary to read degrees of freedom when no
* MatrixFree object was given at initialization.
*/
- mutable std::vector<types::global_dof_index> local_dof_indices;
+ mutable std::vector<types::global_dof_index> local_dof_indices;
};
FEEvaluationGeneral (const MatrixFree<dim,Number> &matrix_free,
const unsigned int fe_no = 0,
const unsigned int quad_no = 0) DEAL_II_DEPRECATED
- :
- BaseClass (matrix_free, fe_no, quad_no)
+:
+ BaseClass (matrix_free, fe_no, quad_no)
{}
/**
FEEvaluationGeneral (const MappingFEEvaluation<dim,Number> &geometry,
const DoFHandler<dim> &dof_handler,
const unsigned int first_selected_component = 0) DEAL_II_DEPRECATED
- :
- BaseClass (geometry, dof_handler, first_selected_component)
+:
+ BaseClass (geometry, dof_handler, first_selected_component)
{}
};
FEEvaluationGL (const MatrixFree<dim,Number> &matrix_free,
const unsigned int fe_no = 0,
const unsigned int quad_no = 0) DEAL_II_DEPRECATED
- :
- BaseClass (matrix_free, fe_no, quad_no)
+:
+ BaseClass (matrix_free, fe_no, quad_no)
{}
/**
FEEvaluationGL (const MappingFEEvaluation<dim,Number> &geometry,
const DoFHandler<dim> &dof_handler,
const unsigned int first_selected_component = 0) DEAL_II_DEPRECATED
- :
- BaseClass (geometry, dof_handler, first_selected_component)
+:
+ BaseClass (geometry, dof_handler, first_selected_component)
{}
};
FEEvaluationDGP (const MatrixFree<dim,Number> &matrix_free,
const unsigned int fe_no = 0,
const unsigned int quad_no = 0) DEAL_II_DEPRECATED
- :
- BaseClass (matrix_free, fe_no, quad_no)
+:
+ BaseClass (matrix_free, fe_no, quad_no)
{}
/**
FEEvaluationDGP (const MappingFEEvaluation<dim,Number> &geometry,
const DoFHandler<dim> &dof_handler,
const unsigned int first_selected_component = 0) DEAL_II_DEPRECATED
- :
- BaseClass (geometry, dof_handler, first_selected_component)
+:
+ BaseClass (geometry, dof_handler, first_selected_component)
{}
};
template <int dim, typename Number>
inline
FEEvaluationAccess<dim,1,Number>
-::FEEvaluationAccess (const FEEvaluationAccess<dim,1,Number>&other)
+::FEEvaluationAccess (const FEEvaluationAccess<dim,1,Number> &other)
:
FEEvaluationBase <dim,1,Number>(other)
{}
template <int dim, typename Number>
inline
FEEvaluationAccess<dim,dim,Number>
-::FEEvaluationAccess (const FEEvaluationAccess<dim,dim,Number>&other)
+::FEEvaluationAccess (const FEEvaluationAccess<dim,dim,Number> &other)
:
FEEvaluationBase <dim,dim,Number>(other)
{}
* products are implemented.
*/
enum EvaluatorVariant
- {
- evaluate_general,
- evaluate_symmetric,
- evaluate_evenodd
- };
+ {
+ evaluate_general,
+ evaluate_symmetric,
+ evaluate_evenodd
+ };
/**
* Generic evaluator framework
const Number in [],
Number out []);
- const Number * shape_values;
- const Number * shape_gradients;
- const Number * shape_hessians;
+ const Number *shape_values;
+ const Number *shape_gradients;
+ const Number *shape_hessians;
};
// evaluates the given shape data in 1d-3d using the tensor product
hessians (const Number in [],
Number out[]) const;
- const Number * shape_values;
- const Number * shape_gradients;
- const Number * shape_hessians;
+ const Number *shape_values;
+ const Number *shape_gradients;
+ const Number *shape_hessians;
};
const Number in [],
Number out []);
- const Number * shape_values;
- const Number * shape_gradients;
- const Number * shape_hessians;
+ const Number *shape_values;
+ const Number *shape_gradients;
+ const Number *shape_hessians;
};
const EvaluatorVariant variant =
EvaluatorSelector<type,(fe_degree+n_q_points_1d>4)>::variant;
typedef EvaluatorTensorProduct<variant, dim, fe_degree, n_q_points_1d,
- VectorizedArray<Number> > Eval;
+ VectorizedArray<Number> > Eval;
Eval eval (variant == evaluate_evenodd ? shape_info.shape_val_evenodd :
shape_info.shape_values,
variant == evaluate_evenodd ? shape_info.shape_gra_evenodd :
const EvaluatorVariant variant =
EvaluatorSelector<type,(fe_degree+n_q_points_1d>4)>::variant;
typedef EvaluatorTensorProduct<variant, dim, fe_degree, n_q_points_1d,
- VectorizedArray<Number> > Eval;
+ VectorizedArray<Number> > Eval;
Eval eval (variant == evaluate_evenodd ? shape_info.shape_val_evenodd :
shape_info.shape_values,
variant == evaluate_evenodd ? shape_info.shape_gra_evenodd :
VectorizedArray<Number> temp2[temp_size];
// expand dof_values to tensor product for truncated tensor products
- VectorizedArray<Number> ** values_dofs = values_dofs_actual;
+ VectorizedArray<Number> **values_dofs = values_dofs_actual;
VectorizedArray<Number> data_array[type!=MatrixFreeFunctions::truncated_tensor ? 1 :
n_components*Eval::dofs_per_cell];
VectorizedArray<Number> *expanded_dof_values[n_components];
// operation is identity, which allows us to write shorter code.
template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename Number>
struct FEEvaluationImpl<MatrixFreeFunctions::tensor_gausslobatto, dim,
- fe_degree, n_q_points_1d, n_components, Number>
+ fe_degree, n_q_points_1d, n_components, Number>
{
static
void evaluate (const MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
void
FEEvaluationImpl<MatrixFreeFunctions::tensor_gausslobatto, dim,
fe_degree, n_q_points_1d, n_components, Number>
- ::evaluate (const MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
- VectorizedArray<Number> *values_dofs[],
- VectorizedArray<Number> *values_quad[],
- VectorizedArray<Number> *gradients_quad[][dim],
- VectorizedArray<Number> *hessians_quad[][(dim*(dim+1))/2],
- const bool evaluate_val,
- const bool evaluate_grad,
- const bool evaluate_lapl)
+ ::evaluate (const MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
+ VectorizedArray<Number> *values_dofs[],
+ VectorizedArray<Number> *values_quad[],
+ VectorizedArray<Number> *gradients_quad[][dim],
+ VectorizedArray<Number> *hessians_quad[][(dim*(dim+1))/2],
+ const bool evaluate_val,
+ const bool evaluate_grad,
+ const bool evaluate_lapl)
{
typedef EvaluatorTensorProduct<evaluate_evenodd, dim, fe_degree, fe_degree+1,
- VectorizedArray<Number> > Eval;
+ VectorizedArray<Number> > Eval;
Eval eval (shape_info.shape_val_evenodd, shape_info.shape_gra_evenodd,
shape_info.shape_hes_evenodd);
void
FEEvaluationImpl<MatrixFreeFunctions::tensor_gausslobatto, dim,
fe_degree, n_q_points_1d, n_components, Number>
- ::integrate (const MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
- VectorizedArray<Number> *values_dofs[],
- VectorizedArray<Number> *values_quad[],
- VectorizedArray<Number> *gradients_quad[][dim],
- const bool integrate_val,
- const bool integrate_grad)
+ ::integrate (const MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
+ VectorizedArray<Number> *values_dofs[],
+ VectorizedArray<Number> *values_quad[],
+ VectorizedArray<Number> *gradients_quad[][dim],
+ const bool integrate_val,
+ const bool integrate_grad)
{
typedef EvaluatorTensorProduct<evaluate_evenodd, dim, fe_degree, fe_degree+1,
- VectorizedArray<Number> > Eval;
+ VectorizedArray<Number> > Eval;
Eval eval (shape_info.shape_val_evenodd, shape_info.shape_gra_evenodd,
shape_info.shape_hes_evenodd);
values_dofs[comp]);
}
break;
-
+
default:
AssertThrow(false, ExcNotImplemented());
}
case internal::MatrixFreeFunctions::tensor_symmetric:
evaluate_funct =
internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_symmetric,
- dim, fe_degree, n_q_points_1d, n_components_,
- Number>::evaluate;
+ dim, fe_degree, n_q_points_1d, n_components_,
+ Number>::evaluate;
integrate_funct =
internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_symmetric,
- dim, fe_degree, n_q_points_1d, n_components_,
- Number>::integrate;
+ dim, fe_degree, n_q_points_1d, n_components_,
+ Number>::integrate;
break;
case internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0:
evaluate_funct =
internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0,
- dim, fe_degree, n_q_points_1d, n_components_,
- Number>::evaluate;
+ dim, fe_degree, n_q_points_1d, n_components_,
+ Number>::evaluate;
integrate_funct =
internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0,
- dim, fe_degree, n_q_points_1d, n_components_,
- Number>::integrate;
+ dim, fe_degree, n_q_points_1d, n_components_,
+ Number>::integrate;
break;
case internal::MatrixFreeFunctions::tensor_general:
evaluate_funct =
internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_general,
- dim, fe_degree, n_q_points_1d, n_components_,
- Number>::evaluate;
+ dim, fe_degree, n_q_points_1d, n_components_,
+ Number>::evaluate;
integrate_funct =
internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_general,
- dim, fe_degree, n_q_points_1d, n_components_,
- Number>::integrate;
+ dim, fe_degree, n_q_points_1d, n_components_,
+ Number>::integrate;
break;
case internal::MatrixFreeFunctions::tensor_gausslobatto:
evaluate_funct =
internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_gausslobatto,
- dim, fe_degree, n_q_points_1d, n_components_,
- Number>::evaluate;
+ dim, fe_degree, n_q_points_1d, n_components_,
+ Number>::evaluate;
integrate_funct =
internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_gausslobatto,
- dim, fe_degree, n_q_points_1d, n_components_,
- Number>::integrate;
+ dim, fe_degree, n_q_points_1d, n_components_,
+ Number>::integrate;
break;
case internal::MatrixFreeFunctions::truncated_tensor:
evaluate_funct =
internal::FEEvaluationImpl<internal::MatrixFreeFunctions::truncated_tensor,
- dim, fe_degree, n_q_points_1d, n_components_,
- Number>::evaluate;
+ dim, fe_degree, n_q_points_1d, n_components_,
+ Number>::evaluate;
integrate_funct =
internal::FEEvaluationImpl<internal::MatrixFreeFunctions::truncated_tensor,
- dim, fe_degree, n_q_points_1d, n_components_,
- Number>::integrate;
+ dim, fe_degree, n_q_points_1d, n_components_,
+ Number>::integrate;
break;
default:
* quadrature points are accessible, as no finite element data is actually
* used).
*/
- const FEValues<dim>& get_fe_values () const;
+ const FEValues<dim> &get_fe_values () const;
/**
* Return a vector of inverse transpose Jacobians. For compatibility with
* FEEvaluation, it returns tensors of vectorized arrays, even though all
* components are equal.
*/
- const AlignedVector<Tensor<2,dim,VectorizedArray<Number> > >&
+ const AlignedVector<Tensor<2,dim,VectorizedArray<Number> > > &
get_inverse_jacobians() const;
/**
* (JxW). For compatibility with FEEvaluation, it returns tensors of
* vectorized arrays, even though all components are equal.
*/
- const AlignedVector<VectorizedArray<Number> >&
+ const AlignedVector<VectorizedArray<Number> > &
get_JxW_values() const;
/**
* cell. For compatibility with FEEvaluation, it returns tensors of
* vectorized arrays, even though all components are equal.
*/
- const AlignedVector<Point<dim,VectorizedArray<Number> > >&
+ const AlignedVector<Point<dim,VectorizedArray<Number> > > &
get_quadrature_points() const;
/**
* cell. For compatibility with FEEvaluation, it returns tensors of
* vectorized arrays, even though all components are equal.
*/
- const AlignedVector<Tensor<1,dim,VectorizedArray<Number> > >&
+ const AlignedVector<Tensor<1,dim,VectorizedArray<Number> > > &
get_normal_vectors() const;
/**
* Return a reference to 1D quadrature underlying this object.
*/
- const Quadrature<1>&
+ const Quadrature<1> &
get_quadrature () const;
private:
template <int dim, typename Number>
inline
-const FEValues<dim>&
+const FEValues<dim> &
MappingFEEvaluation<dim,Number>::get_fe_values() const
{
return fe_values;
template <int dim, typename Number>
inline
-const AlignedVector<Tensor<2,dim,VectorizedArray<Number> > >&
+const AlignedVector<Tensor<2,dim,VectorizedArray<Number> > > &
MappingFEEvaluation<dim,Number>::get_inverse_jacobians() const
{
return inverse_jacobians;
template <int dim, typename Number>
inline
-const AlignedVector<Tensor<1,dim,VectorizedArray<Number> > >&
+const AlignedVector<Tensor<1,dim,VectorizedArray<Number> > > &
MappingFEEvaluation<dim,Number>::get_normal_vectors() const
{
return normal_vectors;
template <int dim, typename Number>
inline
-const AlignedVector<Point<dim,VectorizedArray<Number> > >&
+const AlignedVector<Point<dim,VectorizedArray<Number> > > &
MappingFEEvaluation<dim,Number>::get_quadrature_points() const
{
return quadrature_points;
template <int dim, typename Number>
inline
-const AlignedVector<VectorizedArray<Number> >&
+const AlignedVector<VectorizedArray<Number> > &
MappingFEEvaluation<dim,Number>::get_JxW_values() const
{
return jxw_values;
template <int dim, typename Number>
inline
-const Quadrature<1>&
+const Quadrature<1> &
MappingFEEvaluation<dim,Number>::get_quadrature() const
{
return quadrature_1d;
static UpdateFlags
compute_update_flags (const UpdateFlags update_flags,
const std::vector<dealii::hp::QCollection<1> > &quad =
- std::vector<dealii::hp::QCollection<1> >());
+ std::vector<dealii::hp::QCollection<1> >());
/**
* Returns the type of a given cell as detected during initialization.
tbb::task *execute ()
{
tbb::empty_task *root = new( tbb::task::allocate_root() )
- tbb::empty_task;
+ tbb::empty_task;
unsigned int evens = task_info.partition_evens[partition];
unsigned int odds = task_info.partition_odds[partition];
unsigned int n_blocked_workers =
for (unsigned int j=0; j<evens; j++)
{
worker[j] = new(root->allocate_child())
- CellWork<Worker>(function, task_info.
- partition_color_blocks_row_index[partition]+2*j,
- task_info, false);
+ CellWork<Worker>(function, task_info.
+ partition_color_blocks_row_index[partition]+2*j,
+ task_info, false);
if (j>0)
{
worker[j]->set_ref_count(2);
blocked_worker[j-1]->dummy = new(worker[j]->allocate_child())
- tbb::empty_task;
+ tbb::empty_task;
worker[j-1]->spawn(*blocked_worker[j-1]);
}
else
if (j<evens-1)
{
blocked_worker[j] = new(worker[j]->allocate_child())
- CellWork<Worker>(function, task_info.
- partition_color_blocks_row_index
- [partition] + 2*j+1, task_info, true);
+ CellWork<Worker>(function, task_info.
+ partition_color_blocks_row_index
+ [partition] + 2*j+1, task_info, true);
}
else
{
if (odds==evens)
{
worker[evens] = new(worker[j]->allocate_child())
- CellWork<Worker>(function, task_info.
- partition_color_blocks_row_index[partition]+2*j+1,
- task_info, false);
+ CellWork<Worker>(function, task_info.
+ partition_color_blocks_row_index[partition]+2*j+1,
+ task_info, false);
worker[j]->spawn(*worker[evens]);
}
else
{
tbb::empty_task *child = new(worker[j]->allocate_child())
- tbb::empty_task();
+ tbb::empty_task();
worker[j]->spawn(*child);
}
}
Assert(dim == 2 || dim == 3, ExcNotImplemented());
internal::EvaluatorTensorProduct<internal::evaluate_evenodd,dim,fe_degree,
- fe_degree+1, VectorizedArray<Number> >
- evaluator(inverse_shape, inverse_shape, inverse_shape);
+ fe_degree+1, VectorizedArray<Number> >
+ evaluator(inverse_shape, inverse_shape, inverse_shape);
const unsigned int shift_coefficient =
inverse_coefficients.size() > dofs_per_cell ? dofs_per_cell : 0;
VectorizedArray<Number> temp_data_field[dofs_per_cell];
for (unsigned int d=0; d<n_actual_components; ++d)
{
- const VectorizedArray<Number>* in = in_array+d*dofs_per_cell;
- VectorizedArray<Number>* out = out_array+d*dofs_per_cell;
+ const VectorizedArray<Number> *in = in_array+d*dofs_per_cell;
+ VectorizedArray<Number> *out = out_array+d*dofs_per_cell;
// Need to select 'apply' method with hessian slot because values
// assume symmetries that do not exist in the inverse shapes
evaluator.template hessians<0,false,false> (in, temp_data_field);
* based on the given element type.
*/
enum ElementType
- {
- tensor_general,
- tensor_symmetric,
- truncated_tensor,
- tensor_symmetric_plus_dg0,
- tensor_gausslobatto
- };
+ {
+ tensor_general,
+ tensor_symmetric,
+ truncated_tensor,
+ tensor_symmetric_plus_dg0,
+ tensor_gausslobatto
+ };
/**
* The class that stores the shape functions, gradients and Hessians
* type.
*/
ElementType element_type;
-
+
/**
* Stores the shape values of the 1D finite element evaluated on all 1D
* quadrature points in vectorized format, i.e., as an array of
dynamic_cast<const FE_Poly<TensorProductPolynomials<dim>,dim,dim>*>(fe);
const FE_Poly<TensorProductPolynomials<dim,Polynomials::
- PiecewisePolynomial<double> >,dim,dim> *fe_poly_piece =
+ PiecewisePolynomial<double> >,dim,dim> *fe_poly_piece =
dynamic_cast<const FE_Poly<TensorProductPolynomials<dim,
Polynomials::PiecewisePolynomial<double> >,dim,dim>*> (fe);
for (unsigned int j=0; j<n_q_points_1d; ++j)
if (std::fabs(shape_values[i*n_q_points_1d+j][0] -
shape_values[(n_dofs_1d-i)*n_q_points_1d
- -j-1][0]) > zero_tol)
+ -j-1][0]) > zero_tol)
return false;
// shape values should be zero at x=0.5 for all basis functions except
{
for (unsigned int i=0; i<n_dofs_1d/2; ++i)
if (std::fabs(shape_values[i*n_q_points_1d+
- n_q_points_1d/2][0]) > zero_tol)
+ n_q_points_1d/2][0]) > zero_tol)
return false;
if (std::fabs(shape_values[(n_dofs_1d/2)*n_q_points_1d+
- n_q_points_1d/2][0]-1.)> zero_tol)
+ n_q_points_1d/2][0]-1.)> zero_tol)
return false;
}
for (unsigned int j=0; j<n_q_points_1d; ++j)
if (std::fabs(shape_gradients[i*n_q_points_1d+j][0] +
shape_gradients[(n_dofs_1d-i)*n_q_points_1d-
- j-1][0]) > zero_tol)
+ j-1][0]) > zero_tol)
return false;
if (n_dofs_1d%2 == 1 && n_q_points_1d%2 == 1)
if (std::fabs(shape_gradients[(n_dofs_1d/2)*n_q_points_1d+
- (n_q_points_1d/2)][0]) > zero_tol)
+ (n_q_points_1d/2)][0]) > zero_tol)
return false;
// symmetry for Laplacian
for (unsigned int j=0; j<n_q_points_1d; ++j)
if (std::fabs(shape_hessians[i*n_q_points_1d+j][0] -
shape_hessians[(n_dofs_1d-i)*n_q_points_1d-
- j-1][0]) > zero_tol)
+ j-1][0]) > zero_tol)
return false;
const unsigned int stride = (n_q_points_1d+1)/2;
else
{
if (std::fabs(shape_values[i*n_points_1d+
- j][0]-1.)>zero_tol)
+ j][0]-1.)>zero_tol)
return false;
}
for (unsigned int i=1; i<n_points_1d-1; ++i)
std::size_t memory = sizeof(*this);
memory += MemoryConsumption::memory_consumption(shape_values);
memory += MemoryConsumption::memory_consumption(shape_gradients);
- memory += MemoryConsumption::memory_consumption(shape_hessians);
+ memory += MemoryConsumption::memory_consumption(shape_hessians);
memory += MemoryConsumption::memory_consumption(shape_val_evenodd);
memory += MemoryConsumption::memory_consumption(shape_gra_evenodd);
memory += MemoryConsumption::memory_consumption(shape_hes_evenodd);
* initialized with a cell.
*/
unsigned int face_number;
-
+
/**
* The number of the current
* subface on the current
* active data.
*/
bool level_cell;
-
+
private:
/**
* Standard constructor, not setting any block indices. Use of
/// Set up local block indices
void set_block_indices ();
-
+
/// Fill index vector with active indices
template <class DHCellIterator>
void get_indices(const DHCellIterator &c);
template <int dim, int spacedim, typename number>
DoFInfo<dim,spacedim,number>::DoFInfo(const DoFHandler<dim,spacedim> &dof_handler)
- :
- level_cell (false)
+ :
+ level_cell (false)
{
std::vector<types::global_dof_index> aux(1);
aux[0] = dof_handler.get_fe().dofs_per_cell;
inline void
DoFInfoBox<dim, DOFINFO>::reset ()
{
- cell_valid = false;
+ cell_valid = false;
for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
{
interior_face_available[i] = false;
DoFInfo<dim,spacedim,number>::DoFInfo(const BlockInfo &info)
:
block_info(&info, typeid(*this).name()),
- level_cell (false)
+ level_cell (false)
{
indices_by_block.resize(info.local().size());
for (unsigned int i=0; i<indices_by_block.size(); ++i)
*/
void initialize(AnyData &results, bool separate_faces = true);
- /**
- * @deprecated
- */
- void initialize(NamedData<BlockVector<number>*> &results,
+ /**
+ * @deprecated
+ */
+ void initialize(NamedData<BlockVector<number>*> &results,
bool separate_faces = true);
/**
* Initialize the local data
{
Assert(r.name(1) == "faces", AnyData::ExcNameMismatch(1, "faces"));
AssertDimension(r.entry<BlockVector<double>*>(0)->n_blocks(),
- r.entry<BlockVector<double>*>(1)->n_blocks());
+ r.entry<BlockVector<double>*>(1)->n_blocks());
}
results = r;
inline void
CellsAndFaces<number>::assemble(const DOFINFO &info)
{
- BlockVector<double>* v;
+ BlockVector<double> *v;
if (separate_faces &&
- info.face_number != deal_II_numbers::invalid_unsigned_int)
- v = results.entry<BlockVector<double>*>(1);
+ info.face_number != deal_II_numbers::invalid_unsigned_int)
+ v = results.entry<BlockVector<double>*>(1);
else
- v = results.entry<BlockVector<double>*>(0);
-
+ v = results.entry<BlockVector<double>*>(0);
+
for (unsigned int i=0; i<info.n_values(); ++i)
- v->block(i)(info.cell->user_index()) += info.value(i);
+ v->block(i)(info.cell->user_index()) += info.value(i);
}
{
if (separate_faces)
{
- BlockVector<double>* v1 = results.entry<BlockVector<double>*>(1);
+ BlockVector<double> *v1 = results.entry<BlockVector<double>*>(1);
const double J = info1.value(i) + info2.value(i);
v1->block(i)(info1.face->user_index()) += J;
if (info2.face != info1.face)
}
else
{
- BlockVector<double>* v0 = results.entry<BlockVector<double>*>(0);
+ BlockVector<double> *v0 = results.entry<BlockVector<double>*>(0);
v0->block(i)(info1.cell->user_index()) += .5*info1.value(i);
v0->block(i)(info2.cell->user_index()) += .5*info2.value(i);
}
* Return a reference to the FiniteElement that was used to
* initialize this object.
*/
- const FiniteElement<dim, spacedim>& finite_element() const;
-
+ const FiniteElement<dim, spacedim> &finite_element() const;
+
/// This is true if we are assembling for multigrid
bool multigrid;
/// Access to finite element
std::size_t memory_consumption () const;
private:
- /**
- * The pointer to the (system) element used for initialization.
- */
- SmartPointer<const FiniteElement<dim, spacedim>, IntegrationInfo<dim, spacedim> > fe_pointer;
-
+ /**
+ * The pointer to the (system) element used for initialization.
+ */
+ SmartPointer<const FiniteElement<dim, spacedim>, IntegrationInfo<dim, spacedim> > fe_pointer;
+
/**
* Use the finite element functions in #global_data and fill the
* vectors #values, #gradients and #hessians with values according
void initialize(const FiniteElement<dim, spacedim> &el,
const Mapping<dim, spacedim> &mapping,
const AnyData &data,
- const VECTOR& dummy,
+ const VECTOR &dummy,
const BlockInfo *block_info = 0);
/**
* @deprecated Use AnyData instead of NamedData.
Assert (fe_pointer !=0, ExcNotInitialized());
return *fe_pointer;
}
-
+
template <int dim, int spacedim>
inline const FEValuesBase<dim, spacedim> &
IntegrationInfo<dim,spacedim>::fe_values() const
const FiniteElement<dim,sdim> &el,
const Mapping<dim,sdim> &mapping,
const AnyData &data,
- const VECTOR& dummy,
+ const VECTOR &dummy,
const BlockInfo *block_info)
{
initialize(el, mapping, block_info);
std_cxx1x::shared_ptr<VectorData<VECTOR, dim, sdim> > p;
- VectorDataBase<dim,sdim>* pp;
-
+ VectorDataBase<dim,sdim> *pp;
+
p = std_cxx1x::shared_ptr<VectorData<VECTOR, dim, sdim> >(new VectorData<VECTOR, dim, sdim> (cell_selector));
// Public member function of parent class was not found without
// explicit cast
* it is provided to help develop application programs.
*/
std::vector<std::string> output_names;
-
+
/**
* This error is thrown if one of the virtual functions cell(),
* boundary(), or face() is called without being overloaded in a
*/
class LoopControl
{
- public:
+ public:
- /**
- * Constructor.
- */
- LoopControl()
+ /**
+ * Constructor.
+ */
+ LoopControl()
: own_cells(true), ghost_cells(false),
faces_to_ghost(LoopControl::one), own_faces(LoopControl::one),
- cells_first(true)
- {
- }
+ cells_first(true)
+ {
+ }
- /**
- * Loop over cells owned by this process. Defaults to <code>true</code>.
- */
- bool own_cells;
- /**
- * Loop over cells not owned by this process. Defaults to <code>false</code>.
- */
- bool ghost_cells;
+ /**
+ * Loop over cells owned by this process. Defaults to <code>true</code>.
+ */
+ bool own_cells;
+ /**
+ * Loop over cells not owned by this process. Defaults to <code>false</code>.
+ */
+ bool ghost_cells;
- enum FaceOption
- {
- never,
- one,
- both
- };
-
- /**
- * Loop over faces between a locally owned cell and a ghost cell:
- * - never: do not assembly these faces
- * - one: only one of the processes will assemble these faces (
- * from the finer side or the process with the lower mpi rank)
- * - both: both processes will assemble these faces
- * Note that these faces are never assembled from both sides on a single
- * process.
- * Default is one.
- */
- FaceOption faces_to_ghost;
-
- /**
- * Loop over faces between two locally owned cells:
- * - never: do not assemble face terms
- * - one: assemble once (always coming from the finer side)
- * - both: assemble each face twice (not implemented for hanging nodes!)
- * Default is one.
- */
- FaceOption own_faces;
-
-
- /**
- * Flag to determine if cells integrals should be done before or after
- * face integrals. Default is t
- */
- bool cells_first;
+ enum FaceOption
+ {
+ never,
+ one,
+ both
+ };
+
+ /**
+ * Loop over faces between a locally owned cell and a ghost cell:
+ * - never: do not assembly these faces
+ * - one: only one of the processes will assemble these faces (
+ * from the finer side or the process with the lower mpi rank)
+ * - both: both processes will assemble these faces
+ * Note that these faces are never assembled from both sides on a single
+ * process.
+ * Default is one.
+ */
+ FaceOption faces_to_ghost;
+
+ /**
+ * Loop over faces between two locally owned cells:
+ * - never: do not assemble face terms
+ * - one: assemble once (always coming from the finer side)
+ * - both: assemble each face twice (not implemented for hanging nodes!)
+ * Default is one.
+ */
+ FaceOption own_faces;
+
+
+ /**
+ * Flag to determine if cells integrals should be done before or after
+ * face integrals. Default is t
+ */
+ bool cells_first;
};
-
+
/**
const std_cxx1x::function<void (DOFINFO &, DOFINFO &,
typename INFOBOX::CellInfo &,
typename INFOBOX::CellInfo &)> &face_worker,
- const LoopControl & loop_control)
+ const LoopControl &loop_control)
{
const bool ignore_subdomain = (cell->get_triangulation().locally_owned_subdomain()
- == numbers::invalid_subdomain_id);
-
- types::subdomain_id csid = (cell->is_level_cell())
- ? cell->level_subdomain_id()
- : cell->subdomain_id();
-
- const bool own_cell = ignore_subdomain || (csid == cell->get_triangulation().locally_owned_subdomain());
-
- dof_info.reset();
-
- if ((!ignore_subdomain) && (csid == numbers::artificial_subdomain_id))
- return;
-
- dof_info.cell.reinit(cell);
- dof_info.cell_valid = true;
-
+ == numbers::invalid_subdomain_id);
+
+ types::subdomain_id csid = (cell->is_level_cell())
+ ? cell->level_subdomain_id()
+ : cell->subdomain_id();
+
+ const bool own_cell = ignore_subdomain || (csid == cell->get_triangulation().locally_owned_subdomain());
+
+ dof_info.reset();
+
+ if ((!ignore_subdomain) && (csid == numbers::artificial_subdomain_id))
+ return;
+
+ dof_info.cell.reinit(cell);
+ dof_info.cell_valid = true;
+
const bool integrate_cell = (cell_worker != 0);
const bool integrate_boundary = (boundary_worker != 0);
const bool integrate_interior_face = (face_worker != 0);
neighbid = neighbor->subdomain_id();
const bool own_neighbor = ignore_subdomain ||
- (neighbid == cell->get_triangulation().locally_owned_subdomain());
+ (neighbid == cell->get_triangulation().locally_owned_subdomain());
// skip all faces between two ghost cells
if (!own_cell && !own_neighbor)
// skip face to ghost
if (own_cell != own_neighbor && loop_control.faces_to_ghost==LoopControl::never)
- continue;
+ continue;
// Deal with
// refinement edges
if (internal::is_active_iterator(cell) && neighbor->has_children())
{
Assert(loop_control.own_faces != LoopControl::both, ExcMessage(
- "Assembling from both sides for own_faces is not "
- "supported with hanging nodes!"));
+ "Assembling from both sides for own_faces is not "
+ "supported with hanging nodes!"));
continue;
}
if (own_cell && !own_neighbor
&& loop_control.faces_to_ghost == LoopControl::one
&& (neighbid < csid))
- continue;
+ continue;
const unsigned int neighbor_face_no = cell->neighbor_face_no(face_no);
Assert (neighbor->face(neighbor_face_no) == face, ExcInternalError());
// Execute this, if faces
// have to be handled first
if (integrate_cell && !loop_control.cells_first &&
- ((loop_control.own_cells && own_cell) || (loop_control.ghost_cells && !own_cell)))
+ ((loop_control.own_cells && own_cell) || (loop_control.ghost_cells && !own_cell)))
cell_worker(dof_info.cell, info.cell);
}
* @author Guido Kanschat, 2009
*/
template<int dim, int spacedim, class DOFINFO, class INFOBOX, class ASSEMBLER, class ITERATOR>
- void loop(ITERATOR begin,
- typename identity<ITERATOR>::type end,
- DOFINFO &dinfo,
- INFOBOX &info,
- const std_cxx1x::function<void (DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker,
- const std_cxx1x::function<void (DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker,
- const std_cxx1x::function<void (DOFINFO &, DOFINFO &,
- typename INFOBOX::CellInfo &,
- typename INFOBOX::CellInfo &)> &face_worker,
- ASSEMBLER &assembler,
- const LoopControl &lctrl = LoopControl())
- {
- DoFInfoBox<dim, DOFINFO> dof_info(dinfo);
+ void loop(ITERATOR begin,
+ typename identity<ITERATOR>::type end,
+ DOFINFO &dinfo,
+ INFOBOX &info,
+ const std_cxx1x::function<void (DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker,
+ const std_cxx1x::function<void (DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker,
+ const std_cxx1x::function<void (DOFINFO &, DOFINFO &,
+ typename INFOBOX::CellInfo &,
+ typename INFOBOX::CellInfo &)> &face_worker,
+ ASSEMBLER &assembler,
+ const LoopControl &lctrl = LoopControl())
+ {
+ DoFInfoBox<dim, DOFINFO> dof_info(dinfo);
- assembler.initialize_info(dof_info.cell, false);
- for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
- {
- assembler.initialize_info(dof_info.interior[i], true);
- assembler.initialize_info(dof_info.exterior[i], true);
- }
-
- // Loop over all cells
- #ifdef DEAL_II_MESHWORKER_PARALLEL
- WorkStream::run(begin, end,
- std_cxx1x::bind(&cell_action<INFOBOX, DOFINFO, dim, spacedim, ITERATOR>,
- std_cxx1x::_1, std_cxx1x::_3, std_cxx1x::_2,
- cell_worker, boundary_worker, face_worker, lctrl),
- std_cxx1x::bind(&internal::assemble<dim,DOFINFO,ASSEMBLER>, std_cxx1x::_1, &assembler),
- info, dof_info);
- #else
- for (ITERATOR cell = begin; cell != end; ++cell)
- {
- cell_action<INFOBOX,DOFINFO,dim,spacedim>(cell, dof_info,
- info, cell_worker,
- boundary_worker, face_worker,
- lctrl);
- dof_info.assemble(assembler);
- }
- #endif
- }
+ assembler.initialize_info(dof_info.cell, false);
+ for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
+ {
+ assembler.initialize_info(dof_info.interior[i], true);
+ assembler.initialize_info(dof_info.exterior[i], true);
+ }
+
+ // Loop over all cells
+#ifdef DEAL_II_MESHWORKER_PARALLEL
+ WorkStream::run(begin, end,
+ std_cxx1x::bind(&cell_action<INFOBOX, DOFINFO, dim, spacedim, ITERATOR>,
+ std_cxx1x::_1, std_cxx1x::_3, std_cxx1x::_2,
+ cell_worker, boundary_worker, face_worker, lctrl),
+ std_cxx1x::bind(&internal::assemble<dim,DOFINFO,ASSEMBLER>, std_cxx1x::_1, &assembler),
+ info, dof_info);
+#else
+ for (ITERATOR cell = begin; cell != end; ++cell)
+ {
+ cell_action<INFOBOX,DOFINFO,dim,spacedim>(cell, dof_info,
+ info, cell_worker,
+ boundary_worker, face_worker,
+ lctrl);
+ dof_info.assemble(assembler);
+ }
+#endif
+ }
template<int dim, int spacedim, class DOFINFO, class INFOBOX, class ASSEMBLER, class ITERATOR>
void loop(ITERATOR begin,
template<int dim, int spacedim, class DOFINFO, class INFOBOX, class ASSEMBLER, class ITERATOR>
void loop(ITERATOR begin,
- typename identity<ITERATOR>::type end,
- DOFINFO &dinfo,
- INFOBOX &info,
- const std_cxx1x::function<void (DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker,
- const std_cxx1x::function<void (DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker,
- const std_cxx1x::function<void (DOFINFO &, DOFINFO &,
- typename INFOBOX::CellInfo &,
- typename INFOBOX::CellInfo &)> &face_worker,
- ASSEMBLER &assembler,
- bool cells_first,
- bool unique_faces_only)
+ typename identity<ITERATOR>::type end,
+ DOFINFO &dinfo,
+ INFOBOX &info,
+ const std_cxx1x::function<void (DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker,
+ const std_cxx1x::function<void (DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker,
+ const std_cxx1x::function<void (DOFINFO &, DOFINFO &,
+ typename INFOBOX::CellInfo &,
+ typename INFOBOX::CellInfo &)> &face_worker,
+ ASSEMBLER &assembler,
+ bool cells_first,
+ bool unique_faces_only)
{
- LoopControl lctrl;
- lctrl.cells_first = cells_first;
- lctrl.own_faces = (unique_faces_only)
- ? LoopControl::one
- : LoopControl::both;
+ LoopControl lctrl;
+ lctrl.cells_first = cells_first;
+ lctrl.own_faces = (unique_faces_only)
+ ? LoopControl::one
+ : LoopControl::both;
- loop<dim,spacedim>(begin, end, dinfo, info, cell_worker, boundary_worker, face_worker, assembler, lctrl);
+ loop<dim,spacedim>(begin, end, dinfo, info, cell_worker, boundary_worker, face_worker, assembler, lctrl);
}
/**
const LocalIntegrator<dim, spacedim> &integrator,
ASSEMBLER &assembler,
bool cells_first)
-DEAL_II_DEPRECATED;
+ DEAL_II_DEPRECATED;
template<int dim, int spacedim, class ITERATOR, class ASSEMBLER>
void integration_loop(ITERATOR begin,
class ResidualSimple
{
public:
- /**
- * Initialize with an AnyData object holding the result of
- * assembling.
- *
- * Assembling currently writes into the first vector of <tt>results</tt>.
- */
- void initialize(AnyData& results);
+ /**
+ * Initialize with an AnyData object holding the result of
+ * assembling.
+ *
+ * Assembling currently writes into the first vector of <tt>results</tt>.
+ */
+ void initialize(AnyData &results);
/**
* @deprecated Use initialize(AnyData&) instead.
{
for (unsigned int k=0; k<residuals.size(); ++k)
{
- VECTOR* v = residuals.entry<VECTOR*>(k);
+ VECTOR *v = residuals.entry<VECTOR *>(k);
if (constraints == 0)
{
for (unsigned int i=0; i<info.vector(k).block(0).size(); ++i)
{
for (unsigned int k=0; k<residuals.size(); ++k)
{
- VECTOR* v = residuals.entry<VECTOR*>(k);
+ VECTOR *v = residuals.entry<VECTOR *>(k);
if (constraints == 0)
{
for (unsigned int i=0; i<info1.vector(k).block(0).size(); ++i)
{
for (unsigned int j=0; j<i1.size(); ++j)
for (unsigned int k=0; k<i2.size(); ++k)
- {
- // Only enter the local values into the global matrix,
- // if the value is larger than the threshold
- if (std::fabs(M(j,k)) < threshold)
- continue;
-
- // Do not enter, if either the row or the column
- // corresponds to an index on the refinement edge. The
- // level problems are solved with homogeneous
- // Dirichlet boundary conditions, therefore we
- // eliminate these rows and columns. The corresponding
- // matrix entries are entered by assemble_in() and
- // assemble_out().
+ {
+ // Only enter the local values into the global matrix,
+ // if the value is larger than the threshold
+ if (std::fabs(M(j,k)) < threshold)
+ continue;
+
+ // Do not enter, if either the row or the column
+ // corresponds to an index on the refinement edge. The
+ // level problems are solved with homogeneous
+ // Dirichlet boundary conditions, therefore we
+ // eliminate these rows and columns. The corresponding
+ // matrix entries are entered by assemble_in() and
+ // assemble_out().
if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) ||
mg_constrained_dofs->at_refinement_edge(level, i2[k]))
- continue;
-
- // At the boundary, only enter the term on the
- // diagonal, but not the coupling terms
- if ((mg_constrained_dofs->is_boundary_index(level, i1[j]) ||
- mg_constrained_dofs->is_boundary_index(level, i2[k])) &&
- (i1[j] != i2[k]))
- continue;
-
- G.add(i1[j], i2[k], M(j,k));
- }
- }
+ continue;
+
+ // At the boundary, only enter the term on the
+ // diagonal, but not the coupling terms
+ if ((mg_constrained_dofs->is_boundary_index(level, i1[j]) ||
+ mg_constrained_dofs->is_boundary_index(level, i2[k])) &&
+ (i1[j] != i2[k]))
+ continue;
+
+ G.add(i1[j], i2[k], M(j,k));
+ }
+ }
}
-
+
template <class MATRIX>
inline void
if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) &&
!mg_constrained_dofs->at_refinement_edge(level, i2[k]))
{
- if ((!mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
- !mg_constrained_dofs->is_boundary_index(level, i2[k]))
- ||
- (mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
- mg_constrained_dofs->is_boundary_index(level, i2[k]) &&
- i1[j] == i2[k]))
- G.add(i1[j], i2[k], M(j,k));
+ if ((!mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
+ !mg_constrained_dofs->is_boundary_index(level, i2[k]))
+ ||
+ (mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
+ mg_constrained_dofs->is_boundary_index(level, i2[k]) &&
+ i1[j] == i2[k]))
+ G.add(i1[j], i2[k], M(j,k));
}
}
if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) &&
!mg_constrained_dofs->at_refinement_edge(level, i2[k]))
{
- if ((!mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
- !mg_constrained_dofs->is_boundary_index(level, i2[k]))
- ||
- (mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
- mg_constrained_dofs->is_boundary_index(level, i2[k]) &&
- i1[j] == i2[k]))
- G.add(i1[j], i2[k], M(k,j));
+ if ((!mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
+ !mg_constrained_dofs->is_boundary_index(level, i2[k]))
+ ||
+ (mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
+ mg_constrained_dofs->is_boundary_index(level, i2[k]) &&
+ i1[j] == i2[k]))
+ G.add(i1[j], i2[k], M(k,j));
}
}
{
if (level1 == level2)
{
- assemble((*matrix)[level1], info1.matrix(0,false).matrix, info1.indices, info1.indices, level1);
- assemble((*matrix)[level1], info1.matrix(0,true).matrix, info1.indices, info2.indices, level1);
- assemble((*matrix)[level1], info2.matrix(0,false).matrix, info2.indices, info2.indices, level1);
- assemble((*matrix)[level1], info2.matrix(0,true).matrix, info2.indices, info1.indices, level1);
- }
+ assemble((*matrix)[level1], info1.matrix(0,false).matrix, info1.indices, info1.indices, level1);
+ assemble((*matrix)[level1], info1.matrix(0,true).matrix, info1.indices, info2.indices, level1);
+ assemble((*matrix)[level1], info2.matrix(0,false).matrix, info2.indices, info2.indices, level1);
+ assemble((*matrix)[level1], info2.matrix(0,true).matrix, info2.indices, info1.indices, level1);
+ }
else
{
Assert(level1 > level2, ExcInternalError());
if (level1 == level2)
{
- assemble((*matrix)[level1], info1.matrix(k,false).matrix, info1.indices_by_block[row], info1.indices_by_block[column], level1);
- assemble((*matrix)[level1], info1.matrix(k,true).matrix, info1.indices_by_block[row], info2.indices_by_block[column], level1);
- assemble((*matrix)[level1], info2.matrix(k,false).matrix, info2.indices_by_block[row], info2.indices_by_block[column], level1);
- assemble((*matrix)[level1], info2.matrix(k,true).matrix, info2.indices_by_block[row], info1.indices_by_block[column], level1);
+ assemble((*matrix)[level1], info1.matrix(k,false).matrix, info1.indices_by_block[row], info1.indices_by_block[column], level1);
+ assemble((*matrix)[level1], info1.matrix(k,true).matrix, info1.indices_by_block[row], info2.indices_by_block[column], level1);
+ assemble((*matrix)[level1], info2.matrix(k,false).matrix, info2.indices_by_block[row], info2.indices_by_block[column], level1);
+ assemble((*matrix)[level1], info2.matrix(k,true).matrix, info2.indices_by_block[row], info1.indices_by_block[column], level1);
}
else
{
* @note Make sure the VectorSelector base class was filled with
* reasonable data before calling this function.
*/
- void initialize(const AnyData&);
+ void initialize(const AnyData &);
/**
* Virtual, but empty destructor.
const unsigned int start,
const unsigned int size) const;
- /**
- * The memory used by this object.
- */
+ /**
+ * The memory used by this object.
+ */
std::size_t memory_consumption () const;
};
*/
template <class VECTOR, int dim, int spacedim = dim>
class MGVectorData :
- public VectorData<VECTOR, dim, spacedim>
+ public VectorData<VECTOR, dim, spacedim>
{
public:
/**
AssertDimension(gradients.size(), this->n_gradients());
AssertDimension(hessians.size(), this->n_hessians());
- const AnyData& data = this->data;
+ const AnyData &data = this->data;
for (unsigned int i=0; i<this->n_values(); ++i)
{
- const VECTOR* src = data.read_ptr<VECTOR>(this->value_index(i));
+ const VECTOR *src = data.read_ptr<VECTOR>(this->value_index(i));
VectorSlice<std::vector<std::vector<double> > > dst(values[i], component, n_comp);
fe.get_function_values(*src, make_slice(index, start, size), dst, true);
}
for (unsigned int i=0; i<this->n_gradients(); ++i)
{
- const VECTOR* src = data.read_ptr<VECTOR>(this->gradient_index(i));
+ const VECTOR *src = data.read_ptr<VECTOR>(this->gradient_index(i));
VectorSlice<std::vector<std::vector<Tensor<1,dim> > > > dst(gradients[i], component, n_comp);
fe.get_function_gradients(*src, make_slice(index, start, size), dst, true);
}
for (unsigned int i=0; i<this->n_hessians(); ++i)
{
- const VECTOR* src = data.read_ptr<VECTOR>(this->hessian_index(i));
+ const VECTOR *src = data.read_ptr<VECTOR>(this->hessian_index(i));
VectorSlice<std::vector<std::vector<Tensor<2,dim> > > > dst(hessians[i], component, n_comp);
fe.get_function_hessians(*src, make_slice(index, start, size), dst, true);
}
template <class VECTOR, int dim, int spacedim>
MGVectorData<VECTOR, dim, spacedim>::MGVectorData(const VectorSelector &s)
- :
- VectorData<VECTOR, dim, spacedim>(s)
+ :
+ VectorData<VECTOR, dim, spacedim>(s)
{}
AssertDimension(gradients.size(), this->n_gradients());
AssertDimension(hessians.size(), this->n_hessians());
- const AnyData& data = this->data;
+ const AnyData &data = this->data;
for (unsigned int i=0; i<this->n_values(); ++i)
{
- const MGLevelObject<VECTOR>* src = data.read_ptr<MGLevelObject<VECTOR> >(this->value_index(i));
+ const MGLevelObject<VECTOR> *src = data.read_ptr<MGLevelObject<VECTOR> >(this->value_index(i));
VectorSlice<std::vector<std::vector<double> > > dst(values[i], component, n_comp);
fe.get_function_values((*src)[level], make_slice(index, start, size), dst, true);
}
for (unsigned int i=0; i<this->n_gradients(); ++i)
{
- const MGLevelObject<VECTOR>* src = data.read_ptr<MGLevelObject<VECTOR> >(this->value_index(i));
+ const MGLevelObject<VECTOR> *src = data.read_ptr<MGLevelObject<VECTOR> >(this->value_index(i));
VectorSlice<std::vector<std::vector<Tensor<1,dim> > > > dst(gradients[i], component, n_comp);
fe.get_function_gradients((*src)[level], make_slice(index, start, size), dst, true);
}
for (unsigned int i=0; i<this->n_hessians(); ++i)
{
- const MGLevelObject<VECTOR>* src = data.read_ptr<MGLevelObject<VECTOR> >(this->value_index(i));
+ const MGLevelObject<VECTOR> *src = data.read_ptr<MGLevelObject<VECTOR> >(this->value_index(i));
VectorSlice<std::vector<std::vector<Tensor<2,dim> > > > dst(hessians[i], component, n_comp);
fe.get_function_hessians((*src)[level], make_slice(index, start, size), dst, true);
}
* Initialize the constraints to be used in build_matrices().
*/
void initialize_constraints (const ConstraintMatrix &constraints,
- const MGConstrainedDoFs &mg_constrained_dofs);
+ const MGConstrainedDoFs &mg_constrained_dofs);
/**
* Reset the object to the state it had right after the default constructor.
*/
void clear ();
-
+
/**
* Actually build the prolongation
* matrices for each level.
* and DoFHandler are embedded in.
*/
static const unsigned int space_dimension = DH::space_dimension;
-
+
/**
* Typedef to the iterator type
* of the dof handler class under
*/
template<typename VECTOR, typename DH>
void
- interpolate_based_on_material_id(const Mapping<DH::dimension, DH::space_dimension>& mapping,
- const DH& dof_handler,
- const std::map< types::material_id, const Function<DH::space_dimension,double>* >& function_map,
- VECTOR& dst,
- const ComponentMask& component_mask = ComponentMask());
+ interpolate_based_on_material_id(const Mapping<DH::dimension, DH::space_dimension> &mapping,
+ const DH &dof_handler,
+ const std::map< types::material_id, const Function<DH::space_dimension,double>* > &function_map,
+ VECTOR &dst,
+ const ComponentMask &component_mask = ComponentMask());
/**
* Gives the interpolation of a
* once.
*
* The forth parameter describes the boundary function that is used for
- * computing these constraints.
+ * computing these constraints.
*
* The mapping argument is used to compute the boundary points where the
* function needs to request the normal vector $\vec n$ from the boundary
typename FunctionMap<spacedim>::type &function_map,
ConstraintMatrix &constraints,
const Mapping<dim, spacedim> &mapping = StaticMappingQ1<dim>::mapping);
-
+
/**
* Same as above for homogeneous tangential-flux constraints.
*
template<typename VECTOR, typename DH>
void
- interpolate_based_on_material_id(const Mapping<DH::dimension, DH::space_dimension>& mapping,
- const DH& dof,
- const std::map< types::material_id, const Function<DH::space_dimension>* >& function_map,
- VECTOR& dst,
- const ComponentMask& component_mask)
+ interpolate_based_on_material_id(const Mapping<DH::dimension, DH::space_dimension> &mapping,
+ const DH &dof,
+ const std::map< types::material_id, const Function<DH::space_dimension>* > &function_map,
+ VECTOR &dst,
+ const ComponentMask &component_mask)
{
const unsigned int dim = DH::dimension;
Assert( component_mask.represents_n_components(dof.get_fe().n_components()),
ExcMessage("The number of components in the mask has to be either "
- "zero or equal to the number of components in the finite "
- "element.") );
+ "zero or equal to the number of components in the finite "
+ "element.") );
- if( function_map.size() == 0 )
+ if ( function_map.size() == 0 )
return;
Assert( function_map.find(numbers::invalid_material_id) == function_map.end(),
ExcInvalidMaterialIndicator() );
- for( typename std::map< types::material_id, const Function<DH::space_dimension>* >::const_iterator
- iter = function_map.begin();
- iter != function_map.end();
- ++iter )
+ for ( typename std::map< types::material_id, const Function<DH::space_dimension>* >::const_iterator
+ iter = function_map.begin();
+ iter != function_map.end();
+ ++iter )
{
Assert( dof.get_fe().n_components() == iter->second->n_components,
- ExcDimensionMismatch(dof.get_fe().n_components(), iter->second->n_components) );
+ ExcDimensionMismatch(dof.get_fe().n_components(), iter->second->n_components) );
}
const hp::FECollection<DH::dimension, DH::space_dimension> fe(dof.get_fe());
const bool fe_is_system = (n_components != 1);
typename DH::active_cell_iterator cell = dof.begin_active(),
- endc = dof.end();
+ endc = dof.end();
std::vector< std::vector< Point<dim> > > unit_support_points(fe.size());
- for(unsigned int fe_index = 0; fe_index < fe.size(); ++fe_index)
+ for (unsigned int fe_index = 0; fe_index < fe.size(); ++fe_index)
{
unit_support_points[fe_index] = fe[fe_index].get_unit_support_points();
Assert( unit_support_points[fe_index].size() != 0,
std::vector< std::vector<unsigned int> > dof_to_rep_index_table(fe.size());
std::vector<unsigned int> n_rep_points(fe.size(), 0);
- for(unsigned int fe_index = 0; fe_index < fe.size(); ++fe_index)
+ for (unsigned int fe_index = 0; fe_index < fe.size(); ++fe_index)
{
- for(unsigned int i = 0; i < fe[fe_index].dofs_per_cell; ++i)
+ for (unsigned int i = 0; i < fe[fe_index].dofs_per_cell; ++i)
{
bool representative = true;
- for(unsigned int j = dofs_of_rep_points[fe_index].size(); j > 0; --j)
- if( unit_support_points[fe_index][i] == unit_support_points[fe_index][dofs_of_rep_points[fe_index][j-1]] )
+ for (unsigned int j = dofs_of_rep_points[fe_index].size(); j > 0; --j)
+ if ( unit_support_points[fe_index][i] == unit_support_points[fe_index][dofs_of_rep_points[fe_index][j-1]] )
{
dof_to_rep_index_table[fe_index].push_back(j-1);
representative = false;
break;
}
- if(representative)
+ if (representative)
{
dof_to_rep_index_table[fe_index].push_back(dofs_of_rep_points[fe_index].size());
dofs_of_rep_points[fe_index].push_back(i);
std::vector< std::vector< Vector<double> > > function_values_system(fe.size());
hp::QCollection<dim> support_quadrature;
- for(unsigned int fe_index = 0; fe_index < fe.size(); ++fe_index)
+ for (unsigned int fe_index = 0; fe_index < fe.size(); ++fe_index)
support_quadrature.push_back( Quadrature<dim>(unit_support_points[fe_index]) );
hp::MappingCollection<dim, DH::space_dimension> mapping_collection(mapping);
hp::FEValues<dim, DH::space_dimension> fe_values(mapping_collection,
- fe,
- support_quadrature,
- update_quadrature_points);
+ fe,
+ support_quadrature,
+ update_quadrature_points);
- for( ; cell != endc; ++cell)
- if( cell->is_locally_owned() )
- if( function_map.find(cell->material_id()) != function_map.end() )
+ for ( ; cell != endc; ++cell)
+ if ( cell->is_locally_owned() )
+ if ( function_map.find(cell->material_id()) != function_map.end() )
{
const unsigned int fe_index = cell->active_fe_index();
fe_values.reinit(cell);
- const std::vector< Point<DH::space_dimension> >& support_points = fe_values.get_present_fe_values().get_quadrature_points();
+ const std::vector< Point<DH::space_dimension> > &support_points = fe_values.get_present_fe_values().get_quadrature_points();
rep_points.resize( dofs_of_rep_points[fe_index].size() );
- for(unsigned int i = 0; i < dofs_of_rep_points[fe_index].size(); ++i)
+ for (unsigned int i = 0; i < dofs_of_rep_points[fe_index].size(); ++i)
rep_points[i] = support_points[dofs_of_rep_points[fe_index][i]];
dofs_on_cell.resize( fe[fe_index].dofs_per_cell );
cell->get_dof_indices(dofs_on_cell);
- if(fe_is_system)
+ if (fe_is_system)
{
function_values_system[fe_index].resize( n_rep_points[fe_index],
- Vector<double>(fe[fe_index].n_components()) );
+ Vector<double>(fe[fe_index].n_components()) );
function_map.find(cell->material_id())->second->vector_value_list(rep_points,
function_values_system[fe_index]);
- for(unsigned int i = 0; i < fe[fe_index].dofs_per_cell; ++i)
+ for (unsigned int i = 0; i < fe[fe_index].dofs_per_cell; ++i)
{
const unsigned int component = fe[fe_index].system_to_component_index(i).first;
- if( component_mask[component] )
+ if ( component_mask[component] )
{
const unsigned int rep_dof = dof_to_rep_index_table[fe_index][i];
dst(dofs_on_cell[i]) = function_values_system[fe_index][rep_dof](component);
function_values_scalar[fe_index].resize(n_rep_points[fe_index]);
function_map.find(cell->material_id())->second->value_list(rep_points,
- function_values_scalar[fe_index],
- 0);
+ function_values_scalar[fe_index],
+ 0);
- for(unsigned int i = 0; i < fe[fe_index].dofs_per_cell; ++i)
+ for (unsigned int i = 0; i < fe[fe_index].dofs_per_cell; ++i)
dst(dofs_on_cell[i]) = function_values_scalar[fe_index][dof_to_rep_index_table[fe_index][i]];
}
}
// will be used
template <class DH,
template <int,int> class M_or_MC,
- int dim_>
+ int dim_>
static inline
void
do_interpolate_boundary_values (const M_or_MC<DH::dimension, DH::space_dimension> &mapping,
constraints.add_entry (dof_indices.dof_indices[0],
dof_indices.dof_indices[1],
-constraining_vector[1]/constraining_vector[0]);
-
+
if (std::fabs (inhomogeneity/constraining_vector[0])
> std::numeric_limits<double>::epsilon())
constraints.set_inhomogeneity(dof_indices.dof_indices[0],
- inhomogeneity/constraining_vector[0]);
+ inhomogeneity/constraining_vector[0]);
}
}
else
constraints.add_entry (dof_indices.dof_indices[1],
dof_indices.dof_indices[0],
-constraining_vector[0]/constraining_vector[1]);
-
+
if (std::fabs (inhomogeneity/constraining_vector[1])
> std::numeric_limits<double>::epsilon())
constraints.set_inhomogeneity(dof_indices.dof_indices[1],
- inhomogeneity/constraining_vector[1]);
+ inhomogeneity/constraining_vector[1]);
}
}
break;
if (std::fabs (inhomogeneity/constraining_vector[2])
> std::numeric_limits<double>::epsilon())
constraints.set_inhomogeneity(dof_indices.dof_indices[2],
- inhomogeneity/constraining_vector[2]);
+ inhomogeneity/constraining_vector[2]);
}
}
template <int dim>
void
add_tangentiality_constraints
- (const VectorDoFTuple<dim> &dof_indices,
- const Tensor<1,dim> &tangent_vector,
- ConstraintMatrix &constraints,
- const Vector<double> &b_values = Vector<double>(dim))
+ (const VectorDoFTuple<dim> &dof_indices,
+ const Tensor<1,dim> &tangent_vector,
+ ConstraintMatrix &constraints,
+ const Vector<double> &b_values = Vector<double>(dim))
{
// choose the DoF that has the
typename FunctionMap<spacedim>::type function_map;
std::set<types::boundary_id>::const_iterator it
= boundary_ids.begin();
- for (;it != boundary_ids.end(); ++it)
+ for (; it != boundary_ids.end(); ++it)
function_map[*it] = &zero_function;
- compute_nonzero_normal_flux_constraints(dof_handler,
- first_vector_component,
+ compute_nonzero_normal_flux_constraints(dof_handler,
+ first_vector_component,
boundary_ids,
function_map,
- constraints,
+ constraints,
mapping);
}
-
+
template <int dim, template <int, int> class DH, int spacedim>
void
compute_nonzero_normal_flux_constraints (const DH<dim,spacedim> &dof_handler,
// FE
hp::QCollection<dim-1> face_quadrature_collection;
for (unsigned int i=0; i<fe_collection.size(); ++i)
- {
- const std::vector<Point<dim-1> > &
- unit_support_points = fe_collection[i].get_unit_face_support_points();
+ {
+ const std::vector<Point<dim-1> > &
+ unit_support_points = fe_collection[i].get_unit_face_support_points();
- Assert (unit_support_points.size() == fe_collection[i].dofs_per_face,
- ExcInternalError());
+ Assert (unit_support_points.size() == fe_collection[i].dofs_per_face,
+ ExcInternalError());
- face_quadrature_collection.push_back (Quadrature<dim-1> (unit_support_points));
- }
+ face_quadrature_collection.push_back (Quadrature<dim-1> (unit_support_points));
+ }
// now create the object with which we will generate the normal vectors
hp::FEFaceValues<dim,spacedim> x_fe_face_values (mapping_collection,
std::pair<Tensor<1,dim>, typename DH<dim,spacedim>::active_cell_iterator> >
DoFToNormalsMap;
std::map<internal::VectorDoFTuple<dim>, Vector<double> >
- dof_vector_to_b_values;
+ dof_vector_to_b_values;
DoFToNormalsMap dof_to_normals_map;
++face_no)
if ((b_id=boundary_ids.find(cell->face(face_no)->boundary_indicator()))
!= boundary_ids.end())
- {
- const FiniteElement<dim> &fe = cell->get_fe ();
- typename DH<dim,spacedim>::face_iterator face = cell->face(face_no);
-
- // get the indices of the dofs on this cell...
- face_dofs.resize (fe.dofs_per_face);
- face->get_dof_indices (face_dofs, cell->active_fe_index());
+ {
+ const FiniteElement<dim> &fe = cell->get_fe ();
+ typename DH<dim,spacedim>::face_iterator face = cell->face(face_no);
- x_fe_face_values.reinit (cell, face_no);
- const FEFaceValues<dim> &fe_values = x_fe_face_values.get_present_fe_values();
+ // get the indices of the dofs on this cell...
+ face_dofs.resize (fe.dofs_per_face);
+ face->get_dof_indices (face_dofs, cell->active_fe_index());
- // then identify which of them correspond to the selected set of
- // vector components
- for (unsigned int i=0; i<face_dofs.size(); ++i)
- if (fe.face_system_to_component_index(i).first ==
- first_vector_component)
- {
- // find corresponding other components of vector
- internal::VectorDoFTuple<dim> vector_dofs;
- vector_dofs.dof_indices[0] = face_dofs[i];
-
- Assert(first_vector_component+dim<=fe.n_components(),
- ExcMessage("Error: the finite element does not have enough components "
- "to define a normal direction."));
-
- for (unsigned int k=0; k<fe.dofs_per_face; ++k)
- if ((k != i)
- &&
- (face_quadrature_collection[cell->active_fe_index()].point(k) ==
- face_quadrature_collection[cell->active_fe_index()].point(i))
- &&
- (fe.face_system_to_component_index(k).first >=
- first_vector_component)
- &&
- (fe.face_system_to_component_index(k).first <
- first_vector_component + dim))
- vector_dofs.dof_indices[fe.face_system_to_component_index(k).first -
- first_vector_component]
- = face_dofs[k];
+ x_fe_face_values.reinit (cell, face_no);
+ const FEFaceValues<dim> &fe_values = x_fe_face_values.get_present_fe_values();
- for (unsigned int d=0; d<dim; ++d)
- Assert (vector_dofs.dof_indices[d] < dof_handler.n_dofs(),
- ExcInternalError());
-
- // we need the normal vector on this face. we know that it
- // is a vector of length 1 but at least with higher order
- // mappings it isn't always possible to guarantee that
- // each component is exact up to zero tolerance. in
- // particular, as shown in the deal.II/no_flux_06 test, if
- // we just take the normal vector as given by the
- // fe_values object, we can get entries in the normal
- // vectors of the unit cube that have entries up to
- // several times 1e-14.
- //
- // the problem with this is that this later yields
- // constraints that are circular (e.g., in the testcase,
- // we get constraints of the form
- //
- // x22 = 2.93099e-14*x21 + 2.93099e-14*x23
- // x21 = -2.93099e-14*x22 + 2.93099e-14*x21
- //
- // in both of these constraints, the small numbers should
- // be zero and the constraints should simply be
- // x22 = x21 = 0
- //
- // to achieve this, we utilize that we know that the
- // normal vector has (or should have) length 1 and that we
- // can simply set small elements to zero (without having
- // to check that they are small *relative to something
- // else*). we do this and then normalize the length of the
- // vector back to one, just to be on the safe side
- //
- // one more point: we would like to use the "real" normal
- // vector here, as provided by the boundary description
- // and as opposed to what we get from the FEValues object.
- // we do this in the immediately next line, but as is
- // obvious, the boundary only has a vague idea which side
- // of a cell it is on -- indicated by the face number. in
- // other words, it may provide the inner or outer normal.
- // by and large, there is no harm from this, since the
- // tangential vector we compute is still the same. however,
- // we do average over normal vectors from adjacent cells
- // and if they have recorded normal vectors from the inside
- // once and from the outside the other time, then this
- // averaging is going to run into trouble. as a consequence
- // we ask the mapping after all for its normal vector,
- // but we only ask it so that we can possibly correct the
- // sign of the normal vector provided by the boundary
- // if they should point in different directions. this is the
- // case in tests/deal.II/no_flux_11.
- Point<dim> normal_vector
- = (cell->face(face_no)->get_boundary().normal_vector
- (cell->face(face_no), fe_values.quadrature_point(i)));
- if (normal_vector * fe_values.normal_vector(i) < 0)
- normal_vector *= -1;
- Assert (std::fabs(normal_vector.norm() - 1) < 1e-14,
- ExcInternalError());
- for (unsigned int d=0; d<dim; ++d)
- if (std::fabs(normal_vector[d]) < 1e-13)
- normal_vector[d] = 0;
- normal_vector /= normal_vector.norm();
-
- const Point<dim> point
- = fe_values.quadrature_point(i);
- Vector<double> b_values(dim);
- function_map[*b_id]->vector_value(point, b_values);
-
- // now enter the (dofs,(normal_vector,cell)) entry into
- // the map
- dof_to_normals_map.insert
- (std::make_pair (vector_dofs,
- std::make_pair (normal_vector,cell)));
- dof_vector_to_b_values.insert
- (std::make_pair(vector_dofs, b_values));
+ // then identify which of them correspond to the selected set of
+ // vector components
+ for (unsigned int i=0; i<face_dofs.size(); ++i)
+ if (fe.face_system_to_component_index(i).first ==
+ first_vector_component)
+ {
+ // find corresponding other components of vector
+ internal::VectorDoFTuple<dim> vector_dofs;
+ vector_dofs.dof_indices[0] = face_dofs[i];
+
+ Assert(first_vector_component+dim<=fe.n_components(),
+ ExcMessage("Error: the finite element does not have enough components "
+ "to define a normal direction."));
+
+ for (unsigned int k=0; k<fe.dofs_per_face; ++k)
+ if ((k != i)
+ &&
+ (face_quadrature_collection[cell->active_fe_index()].point(k) ==
+ face_quadrature_collection[cell->active_fe_index()].point(i))
+ &&
+ (fe.face_system_to_component_index(k).first >=
+ first_vector_component)
+ &&
+ (fe.face_system_to_component_index(k).first <
+ first_vector_component + dim))
+ vector_dofs.dof_indices[fe.face_system_to_component_index(k).first -
+ first_vector_component]
+ = face_dofs[k];
+
+ for (unsigned int d=0; d<dim; ++d)
+ Assert (vector_dofs.dof_indices[d] < dof_handler.n_dofs(),
+ ExcInternalError());
+
+ // we need the normal vector on this face. we know that it
+ // is a vector of length 1 but at least with higher order
+ // mappings it isn't always possible to guarantee that
+ // each component is exact up to zero tolerance. in
+ // particular, as shown in the deal.II/no_flux_06 test, if
+ // we just take the normal vector as given by the
+ // fe_values object, we can get entries in the normal
+ // vectors of the unit cube that have entries up to
+ // several times 1e-14.
+ //
+ // the problem with this is that this later yields
+ // constraints that are circular (e.g., in the testcase,
+ // we get constraints of the form
+ //
+ // x22 = 2.93099e-14*x21 + 2.93099e-14*x23
+ // x21 = -2.93099e-14*x22 + 2.93099e-14*x21
+ //
+ // in both of these constraints, the small numbers should
+ // be zero and the constraints should simply be
+ // x22 = x21 = 0
+ //
+ // to achieve this, we utilize that we know that the
+ // normal vector has (or should have) length 1 and that we
+ // can simply set small elements to zero (without having
+ // to check that they are small *relative to something
+ // else*). we do this and then normalize the length of the
+ // vector back to one, just to be on the safe side
+ //
+ // one more point: we would like to use the "real" normal
+ // vector here, as provided by the boundary description
+ // and as opposed to what we get from the FEValues object.
+ // we do this in the immediately next line, but as is
+ // obvious, the boundary only has a vague idea which side
+ // of a cell it is on -- indicated by the face number. in
+ // other words, it may provide the inner or outer normal.
+ // by and large, there is no harm from this, since the
+ // tangential vector we compute is still the same. however,
+ // we do average over normal vectors from adjacent cells
+ // and if they have recorded normal vectors from the inside
+ // once and from the outside the other time, then this
+ // averaging is going to run into trouble. as a consequence
+ // we ask the mapping after all for its normal vector,
+ // but we only ask it so that we can possibly correct the
+ // sign of the normal vector provided by the boundary
+ // if they should point in different directions. this is the
+ // case in tests/deal.II/no_flux_11.
+ Point<dim> normal_vector
+ = (cell->face(face_no)->get_boundary().normal_vector
+ (cell->face(face_no), fe_values.quadrature_point(i)));
+ if (normal_vector * fe_values.normal_vector(i) < 0)
+ normal_vector *= -1;
+ Assert (std::fabs(normal_vector.norm() - 1) < 1e-14,
+ ExcInternalError());
+ for (unsigned int d=0; d<dim; ++d)
+ if (std::fabs(normal_vector[d]) < 1e-13)
+ normal_vector[d] = 0;
+ normal_vector /= normal_vector.norm();
+
+ const Point<dim> point
+ = fe_values.quadrature_point(i);
+ Vector<double> b_values(dim);
+ function_map[*b_id]->vector_value(point, b_values);
+
+ // now enter the (dofs,(normal_vector,cell)) entry into
+ // the map
+ dof_to_normals_map.insert
+ (std::make_pair (vector_dofs,
+ std::make_pair (normal_vector,cell)));
+ dof_vector_to_b_values.insert
+ (std::make_pair(vector_dofs, b_values));
#ifdef DEBUG_NO_NORMAL_FLUX
- std::cout << "Adding normal vector:" << std::endl
- << " dofs=" << vector_dofs << std::endl
- << " cell=" << cell << " at " << cell->center() << std::endl
- << " normal=" << normal_vector << std::endl;
+ std::cout << "Adding normal vector:" << std::endl
+ << " dofs=" << vector_dofs << std::endl
+ << " cell=" << cell << " at " << cell->center() << std::endl
+ << " normal=" << normal_vector << std::endl;
#endif
- }
- }
+ }
+ }
// Now do something with the collected information. To this end, loop
// through all sets of pairs (dofs,normal_vector) and identify which
p = dof_to_normals_map.begin();
while (p != dof_to_normals_map.end())
- {
- // first find the range of entries in the multimap that corresponds to
- // the same vector-dof tuple. as usual, we define the range
- // half-open. the first entry of course is 'p'
- typename DoFToNormalsMap::const_iterator same_dof_range[2] = { p };
- for (++p; p != dof_to_normals_map.end(); ++p)
- if (p->first != same_dof_range[0]->first)
- {
- same_dof_range[1] = p;
- break;
- }
- if (p == dof_to_normals_map.end())
- same_dof_range[1] = dof_to_normals_map.end();
+ {
+ // first find the range of entries in the multimap that corresponds to
+ // the same vector-dof tuple. as usual, we define the range
+ // half-open. the first entry of course is 'p'
+ typename DoFToNormalsMap::const_iterator same_dof_range[2] = { p };
+ for (++p; p != dof_to_normals_map.end(); ++p)
+ if (p->first != same_dof_range[0]->first)
+ {
+ same_dof_range[1] = p;
+ break;
+ }
+ if (p == dof_to_normals_map.end())
+ same_dof_range[1] = dof_to_normals_map.end();
#ifdef DEBUG_NO_NORMAL_FLUX
- std::cout << "For dof indices <" << p->first << ">, found the following normals"
- << std::endl;
- for (typename DoFToNormalsMap::const_iterator
- q = same_dof_range[0];
- q != same_dof_range[1]; ++q)
- std::cout << " " << q->second.first
- << " from cell " << q->second.second
+ std::cout << "For dof indices <" << p->first << ">, found the following normals"
<< std::endl;
+ for (typename DoFToNormalsMap::const_iterator
+ q = same_dof_range[0];
+ q != same_dof_range[1]; ++q)
+ std::cout << " " << q->second.first
+ << " from cell " << q->second.second
+ << std::endl;
#endif
- // now compute the reverse mapping: for each of the cells that
- // contributed to the current set of vector dofs, add up the normal
- // vectors. the values of the map are pairs of normal vectors and
- // number of cells that have contributed
- typedef std::map<typename DH<dim,spacedim>::active_cell_iterator,
- std::pair<Tensor<1,dim>, unsigned int> >
- CellToNormalsMap;
+ // now compute the reverse mapping: for each of the cells that
+ // contributed to the current set of vector dofs, add up the normal
+ // vectors. the values of the map are pairs of normal vectors and
+ // number of cells that have contributed
+ typedef std::map<typename DH<dim,spacedim>::active_cell_iterator,
+ std::pair<Tensor<1,dim>, unsigned int> >
+ CellToNormalsMap;
- CellToNormalsMap cell_to_normals_map;
- for (typename DoFToNormalsMap::const_iterator
- q = same_dof_range[0];
- q != same_dof_range[1]; ++q)
- if (cell_to_normals_map.find (q->second.second)
+ CellToNormalsMap cell_to_normals_map;
+ for (typename DoFToNormalsMap::const_iterator
+ q = same_dof_range[0];
+ q != same_dof_range[1]; ++q)
+ if (cell_to_normals_map.find (q->second.second)
== cell_to_normals_map.end())
cell_to_normals_map[q->second.second]
= std::make_pair (q->second.first, 1U);
- else
- {
- const Tensor<1,dim> old_normal
+ else
+ {
+ const Tensor<1,dim> old_normal
= cell_to_normals_map[q->second.second].first;
- const unsigned int old_count
+ const unsigned int old_count
= cell_to_normals_map[q->second.second].second;
- Assert (old_count > 0, ExcInternalError());
+ Assert (old_count > 0, ExcInternalError());
- // in the same entry, store again the now averaged normal vector
- // and the new count
- cell_to_normals_map[q->second.second]
- = std::make_pair ((old_normal * old_count + q->second.first) / (old_count + 1),
- old_count + 1);
- }
- Assert (cell_to_normals_map.size() >= 1, ExcInternalError());
+ // in the same entry, store again the now averaged normal vector
+ // and the new count
+ cell_to_normals_map[q->second.second]
+ = std::make_pair ((old_normal * old_count + q->second.first) / (old_count + 1),
+ old_count + 1);
+ }
+ Assert (cell_to_normals_map.size() >= 1, ExcInternalError());
#ifdef DEBUG_NO_NORMAL_FLUX
- std::cout << " cell_to_normals_map:" << std::endl;
- for (typename CellToNormalsMap::const_iterator
- x = cell_to_normals_map.begin();
- x != cell_to_normals_map.end(); ++x)
- std::cout << " " << x->first << " -> ("
- << x->second.first << ',' << x->second.second << ')'
- << std::endl;
+ std::cout << " cell_to_normals_map:" << std::endl;
+ for (typename CellToNormalsMap::const_iterator
+ x = cell_to_normals_map.begin();
+ x != cell_to_normals_map.end(); ++x)
+ std::cout << " " << x->first << " -> ("
+ << x->second.first << ',' << x->second.second << ')'
+ << std::endl;
#endif
- // count the maximum number of contributions from each cell
- unsigned int max_n_contributions_per_cell = 1;
- for (typename CellToNormalsMap::const_iterator
- x = cell_to_normals_map.begin();
- x != cell_to_normals_map.end(); ++x)
+ // count the maximum number of contributions from each cell
+ unsigned int max_n_contributions_per_cell = 1;
+ for (typename CellToNormalsMap::const_iterator
+ x = cell_to_normals_map.begin();
+ x != cell_to_normals_map.end(); ++x)
max_n_contributions_per_cell
= std::max (max_n_contributions_per_cell,
x->second.second);
- // verify that each cell can have only contributed at most dim times,
- // since that is the maximum number of faces that come together at a
- // single place
- Assert (max_n_contributions_per_cell <= dim, ExcInternalError());
+ // verify that each cell can have only contributed at most dim times,
+ // since that is the maximum number of faces that come together at a
+ // single place
+ Assert (max_n_contributions_per_cell <= dim, ExcInternalError());
- switch (max_n_contributions_per_cell)
- {
- // first deal with the case that a number of cells all have
- // registered that they have a normal vector defined at the
- // location of a given vector dof, and that each of them have
- // encountered this vector dof exactly once while looping over all
- // their faces. as stated in the documentation, this is the case
- // where we want to simply average over all normal vectors
- //
- // the typical case is in 2d where multiple cells meet at one
- // vertex sitting on the boundary. same in 3d for a vertex that
- // is associated with only one of the boundary indicators passed
- // to this function
- case 1:
- {
- // compute the average normal vector from all the ones that have
- // the same set of dofs. we could add them up and divide them by
- // the number of additions, or simply normalize them right away
- // since we want them to have unit length anyway
- Tensor<1,dim> normal;
- for (typename CellToNormalsMap::const_iterator
- x = cell_to_normals_map.begin();
- x != cell_to_normals_map.end(); ++x)
- normal += x->second.first;
- normal /= normal.norm();
-
- // normalize again
- for (unsigned int d=0; d<dim; ++d)
- if (std::fabs(normal[d]) < 1e-13)
- normal[d] = 0;
- normal /= normal.norm();
-
- // then construct constraints from this:
- const internal::VectorDoFTuple<dim> &
- dof_indices = same_dof_range[0]->first;
- double normal_value = 0.;
- const Vector<double> b_values = dof_vector_to_b_values[dof_indices];
- for (unsigned int i=0; i<dim; ++i)
- normal_value += b_values[i]*normal[i];
- internal::add_constraint (dof_indices, normal,
- constraints, normal_value);
-
- break;
- }
+ switch (max_n_contributions_per_cell)
+ {
+ // first deal with the case that a number of cells all have
+ // registered that they have a normal vector defined at the
+ // location of a given vector dof, and that each of them have
+ // encountered this vector dof exactly once while looping over all
+ // their faces. as stated in the documentation, this is the case
+ // where we want to simply average over all normal vectors
+ //
+ // the typical case is in 2d where multiple cells meet at one
+ // vertex sitting on the boundary. same in 3d for a vertex that
+ // is associated with only one of the boundary indicators passed
+ // to this function
+ case 1:
+ {
+ // compute the average normal vector from all the ones that have
+ // the same set of dofs. we could add them up and divide them by
+ // the number of additions, or simply normalize them right away
+ // since we want them to have unit length anyway
+ Tensor<1,dim> normal;
+ for (typename CellToNormalsMap::const_iterator
+ x = cell_to_normals_map.begin();
+ x != cell_to_normals_map.end(); ++x)
+ normal += x->second.first;
+ normal /= normal.norm();
- // this is the slightly more complicated case that a single cell has
- // contributed with exactly DIM normal vectors to the same set of
- // vector dofs. this is what happens in a corner in 2d and 3d (but
- // not on an edge in 3d, where we have only 2, i.e. <DIM,
- // contributions. Here we do not want to average the normal
- // vectors. Since we have DIM contributions, let's assume (and
- // verify) that they are in fact all linearly independent; in that
- // case, all vector components are constrained and we need to set all
- // of them to the corresponding boundary values
- case dim:
- {
- // assert that indeed only a single cell has contributed
- Assert (cell_to_normals_map.size() == 1,
- ExcInternalError());
+ // normalize again
+ for (unsigned int d=0; d<dim; ++d)
+ if (std::fabs(normal[d]) < 1e-13)
+ normal[d] = 0;
+ normal /= normal.norm();
- // check linear independence by computing the determinant of the
- // matrix created from all the normal vectors. if they are
- // linearly independent, then the determinant is nonzero. if they
- // are orthogonal, then the matrix is in fact equal to 1 (since
- // they are all unit vectors); make sure the determinant is larger
- // than 1e-3 to avoid cases where cells are degenerate
- {
- Tensor<2,dim> t;
-
- typename DoFToNormalsMap::const_iterator x = same_dof_range[0];
- for (unsigned int i=0; i<dim; ++i, ++x)
- for (unsigned int j=0; j<dim; ++j)
- t[i][j] = x->second.first[j];
-
- Assert (std::fabs(determinant (t)) > 1e-3,
- ExcMessage("Found a set of normal vectors that are nearly collinear."));
+ // then construct constraints from this:
+ const internal::VectorDoFTuple<dim> &
+ dof_indices = same_dof_range[0]->first;
+ double normal_value = 0.;
+ const Vector<double> b_values = dof_vector_to_b_values[dof_indices];
+ for (unsigned int i=0; i<dim; ++i)
+ normal_value += b_values[i]*normal[i];
+ internal::add_constraint (dof_indices, normal,
+ constraints, normal_value);
+
+ break;
}
- // so all components of this vector dof are constrained. enter
- // this into the constraint matrix
- //
- // ignore dofs already constrained
- const internal::VectorDoFTuple<dim> &
- dof_indices = same_dof_range[0]->first;
- const Vector<double> b_values = dof_vector_to_b_values[dof_indices];
- for (unsigned int i=0; i<dim; ++i)
- if (!constraints.is_constrained(same_dof_range[0]->first.dof_indices[i])
- &&
- constraints.can_store_line(same_dof_range[0]->first.dof_indices[i]))
+ // this is the slightly more complicated case that a single cell has
+ // contributed with exactly DIM normal vectors to the same set of
+ // vector dofs. this is what happens in a corner in 2d and 3d (but
+ // not on an edge in 3d, where we have only 2, i.e. <DIM,
+ // contributions. Here we do not want to average the normal
+ // vectors. Since we have DIM contributions, let's assume (and
+ // verify) that they are in fact all linearly independent; in that
+ // case, all vector components are constrained and we need to set all
+ // of them to the corresponding boundary values
+ case dim:
+ {
+ // assert that indeed only a single cell has contributed
+ Assert (cell_to_normals_map.size() == 1,
+ ExcInternalError());
+
+ // check linear independence by computing the determinant of the
+ // matrix created from all the normal vectors. if they are
+ // linearly independent, then the determinant is nonzero. if they
+ // are orthogonal, then the matrix is in fact equal to 1 (since
+ // they are all unit vectors); make sure the determinant is larger
+ // than 1e-3 to avoid cases where cells are degenerate
{
- const types::global_dof_index line
- = dof_indices.dof_indices[i];
- constraints.add_line (line);
- if (std::fabs(b_values[i])
- > std::numeric_limits<double>::epsilon())
- constraints.set_inhomogeneity(line, b_values[i]);
- // no add_entries here
+ Tensor<2,dim> t;
+
+ typename DoFToNormalsMap::const_iterator x = same_dof_range[0];
+ for (unsigned int i=0; i<dim; ++i, ++x)
+ for (unsigned int j=0; j<dim; ++j)
+ t[i][j] = x->second.first[j];
+
+ Assert (std::fabs(determinant (t)) > 1e-3,
+ ExcMessage("Found a set of normal vectors that are nearly collinear."));
}
+ // so all components of this vector dof are constrained. enter
+ // this into the constraint matrix
+ //
+ // ignore dofs already constrained
+ const internal::VectorDoFTuple<dim> &
+ dof_indices = same_dof_range[0]->first;
+ const Vector<double> b_values = dof_vector_to_b_values[dof_indices];
+ for (unsigned int i=0; i<dim; ++i)
+ if (!constraints.is_constrained(same_dof_range[0]->first.dof_indices[i])
+ &&
+ constraints.can_store_line(same_dof_range[0]->first.dof_indices[i]))
+ {
+ const types::global_dof_index line
+ = dof_indices.dof_indices[i];
+ constraints.add_line (line);
+ if (std::fabs(b_values[i])
+ > std::numeric_limits<double>::epsilon())
+ constraints.set_inhomogeneity(line, b_values[i]);
+ // no add_entries here
+ }
+
break;
}
- // this is the case of an edge contribution in 3d, i.e. the vector
- // is constrained in two directions but not the third.
- default:
- {
- Assert (dim >= 3, ExcNotImplemented());
- Assert (max_n_contributions_per_cell == 2, ExcInternalError());
-
- // as described in the documentation, let us first collect what
- // each of the cells contributed at the current point. we use a
- // std::list instead of a std::set (which would be more natural)
- // because std::set requires that the stored elements are
- // comparable with operator<
- typedef std::map<typename DH<dim,spacedim>::active_cell_iterator,
- std::list<Tensor<1,dim> > >
- CellContributions;
- CellContributions cell_contributions;
-
- for (typename DoFToNormalsMap::const_iterator
- q = same_dof_range[0];
- q != same_dof_range[1]; ++q)
- cell_contributions[q->second.second].push_back (q->second.first);
- Assert (cell_contributions.size() >= 1, ExcInternalError());
-
- // now for each cell that has contributed determine the number of
- // normal vectors it has contributed. we currently only implement
- // if this is dim-1 for all cells (if a single cell has
- // contributed dim, or if all adjacent cells have contributed 1
- // normal vector, this is already handled above).
- //
- // we only implement the case that all cells contribute
- // dim-1 because we assume that we are following an edge
- // of the domain (think: we are looking at a vertex
- // located on one of the edges of a refined cube where the
- // boundary indicators of the two adjacent faces of the
- // cube are both listed in the set of boundary indicators
- // passed to this function). in that case, all cells along
- // that edge of the domain are assumed to have contributed
- // dim-1 normal vectors. however, there are cases where
- // this assumption is not justified (see the lengthy
- // explanation in test no_flux_12.cc) and in those cases
- // we simply ignore the cell that contributes only
- // once. this is also discussed at length in the
- // documentation of this function.
- //
- // for each contributing cell compute the tangential vector that
- // remains unconstrained
- std::list<Tensor<1,dim> > tangential_vectors;
- for (typename CellContributions::const_iterator
- contribution = cell_contributions.begin();
- contribution != cell_contributions.end();
- ++contribution)
+ // this is the case of an edge contribution in 3d, i.e. the vector
+ // is constrained in two directions but not the third.
+ default:
{
+ Assert (dim >= 3, ExcNotImplemented());
+ Assert (max_n_contributions_per_cell == 2, ExcInternalError());
+
+ // as described in the documentation, let us first collect what
+ // each of the cells contributed at the current point. we use a
+ // std::list instead of a std::set (which would be more natural)
+ // because std::set requires that the stored elements are
+ // comparable with operator<
+ typedef std::map<typename DH<dim,spacedim>::active_cell_iterator,
+ std::list<Tensor<1,dim> > >
+ CellContributions;
+ CellContributions cell_contributions;
+
+ for (typename DoFToNormalsMap::const_iterator
+ q = same_dof_range[0];
+ q != same_dof_range[1]; ++q)
+ cell_contributions[q->second.second].push_back (q->second.first);
+ Assert (cell_contributions.size() >= 1, ExcInternalError());
+
+ // now for each cell that has contributed determine the number of
+ // normal vectors it has contributed. we currently only implement
+ // if this is dim-1 for all cells (if a single cell has
+ // contributed dim, or if all adjacent cells have contributed 1
+ // normal vector, this is already handled above).
+ //
+ // we only implement the case that all cells contribute
+ // dim-1 because we assume that we are following an edge
+ // of the domain (think: we are looking at a vertex
+ // located on one of the edges of a refined cube where the
+ // boundary indicators of the two adjacent faces of the
+ // cube are both listed in the set of boundary indicators
+ // passed to this function). in that case, all cells along
+ // that edge of the domain are assumed to have contributed
+ // dim-1 normal vectors. however, there are cases where
+ // this assumption is not justified (see the lengthy
+ // explanation in test no_flux_12.cc) and in those cases
+ // we simply ignore the cell that contributes only
+ // once. this is also discussed at length in the
+ // documentation of this function.
+ //
+ // for each contributing cell compute the tangential vector that
+ // remains unconstrained
+ std::list<Tensor<1,dim> > tangential_vectors;
+ for (typename CellContributions::const_iterator
+ contribution = cell_contributions.begin();
+ contribution != cell_contributions.end();
+ ++contribution)
+ {
#ifdef DEBUG_NO_NORMAL_FLUX
- std::cout << " Treating edge case with dim-1 contributions." << std::endl
- << " Looking at cell " << contribution->first
- << " which has contributed these normal vectors:"
- << std::endl;
- for (typename std::list<Tensor<1,dim> >::const_iterator
- t = contribution->second.begin();
- t != contribution->second.end();
- ++t)
- std::cout << " " << *t << std::endl;
+ std::cout << " Treating edge case with dim-1 contributions." << std::endl
+ << " Looking at cell " << contribution->first
+ << " which has contributed these normal vectors:"
+ << std::endl;
+ for (typename std::list<Tensor<1,dim> >::const_iterator
+ t = contribution->second.begin();
+ t != contribution->second.end();
+ ++t)
+ std::cout << " " << *t << std::endl;
#endif
- // as mentioned above, simply ignore cells that only
- // contribute once
- if (contribution->second.size() < dim-1)
- continue;
-
- Tensor<1,dim> normals[dim-1];
- {
- unsigned int index=0;
- for (typename std::list<Tensor<1,dim> >::const_iterator
- t = contribution->second.begin();
- t != contribution->second.end();
- ++t, ++index)
- normals[index] = *t;
- Assert (index == dim-1, ExcInternalError());
- }
+ // as mentioned above, simply ignore cells that only
+ // contribute once
+ if (contribution->second.size() < dim-1)
+ continue;
- // calculate the tangent as the outer product of the normal
- // vectors. since these vectors do not need to be orthogonal
- // (think, for example, the case of the deal.II/no_flux_07
- // test: a sheared cube in 3d, with Q2 elements, where we have
- // constraints from the two normal vectors of two faces of the
- // sheared cube that are not perpendicular to each other), we
- // have to normalize the outer product
- Tensor<1,dim> tangent;
- switch (dim)
- {
- case 3:
- // take cross product between normals[0] and
- // normals[1]. write it in the current form (with [dim-2])
- // to make sure that compilers don't warn about
- // out-of-bounds accesses -- the warnings are bogus since
- // we get here only for dim==3, but at least one isn't
- // quite smart enough to notice this and warns when
- // compiling the function in 2d
- cross_product (tangent, normals[0], normals[dim-2]);
- break;
- default:
- Assert (false, ExcNotImplemented());
- }
+ Tensor<1,dim> normals[dim-1];
+ {
+ unsigned int index=0;
+ for (typename std::list<Tensor<1,dim> >::const_iterator
+ t = contribution->second.begin();
+ t != contribution->second.end();
+ ++t, ++index)
+ normals[index] = *t;
+ Assert (index == dim-1, ExcInternalError());
+ }
- Assert (std::fabs (tangent.norm()) > 1e-12,
- ExcMessage("Two normal vectors from adjacent faces are almost "
- "parallel."));
- tangent /= tangent.norm();
+ // calculate the tangent as the outer product of the normal
+ // vectors. since these vectors do not need to be orthogonal
+ // (think, for example, the case of the deal.II/no_flux_07
+ // test: a sheared cube in 3d, with Q2 elements, where we have
+ // constraints from the two normal vectors of two faces of the
+ // sheared cube that are not perpendicular to each other), we
+ // have to normalize the outer product
+ Tensor<1,dim> tangent;
+ switch (dim)
+ {
+ case 3:
+ // take cross product between normals[0] and
+ // normals[1]. write it in the current form (with [dim-2])
+ // to make sure that compilers don't warn about
+ // out-of-bounds accesses -- the warnings are bogus since
+ // we get here only for dim==3, but at least one isn't
+ // quite smart enough to notice this and warns when
+ // compiling the function in 2d
+ cross_product (tangent, normals[0], normals[dim-2]);
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ }
- tangential_vectors.push_back (tangent);
- }
+ Assert (std::fabs (tangent.norm()) > 1e-12,
+ ExcMessage("Two normal vectors from adjacent faces are almost "
+ "parallel."));
+ tangent /= tangent.norm();
- // go through the list of tangents and make sure that they all
- // roughly point in the same direction as the first one (i.e. have
- // an angle less than 90 degrees); if they don't then flip their
- // sign
- {
- const Tensor<1,dim> first_tangent = tangential_vectors.front();
- typename std::list<Tensor<1,dim> >::iterator
+ tangential_vectors.push_back (tangent);
+ }
+
+ // go through the list of tangents and make sure that they all
+ // roughly point in the same direction as the first one (i.e. have
+ // an angle less than 90 degrees); if they don't then flip their
+ // sign
+ {
+ const Tensor<1,dim> first_tangent = tangential_vectors.front();
+ typename std::list<Tensor<1,dim> >::iterator
t = tangential_vectors.begin();
- ++t;
- for (; t != tangential_vectors.end(); ++t)
- if (*t * first_tangent < 0)
- *t *= -1;
- }
+ ++t;
+ for (; t != tangential_vectors.end(); ++t)
+ if (*t * first_tangent < 0)
+ *t *= -1;
+ }
- // now compute the average tangent and normalize it
- Tensor<1,dim> average_tangent;
- for (typename std::list<Tensor<1,dim> >::const_iterator
- t = tangential_vectors.begin();
- t != tangential_vectors.end();
- ++t)
- average_tangent += *t;
- average_tangent /= average_tangent.norm();
-
- // now all that is left is that we add the constraints that the
- // vector is parallel to the tangent
- const internal::VectorDoFTuple<dim> &
+ // now compute the average tangent and normalize it
+ Tensor<1,dim> average_tangent;
+ for (typename std::list<Tensor<1,dim> >::const_iterator
+ t = tangential_vectors.begin();
+ t != tangential_vectors.end();
+ ++t)
+ average_tangent += *t;
+ average_tangent /= average_tangent.norm();
+
+ // now all that is left is that we add the constraints that the
+ // vector is parallel to the tangent
+ const internal::VectorDoFTuple<dim> &
dof_indices = same_dof_range[0]->first;
- const Vector<double> b_values = dof_vector_to_b_values[dof_indices];
- internal::add_tangentiality_constraints (dof_indices,
- average_tangent,
- constraints,
- b_values);
- }
+ const Vector<double> b_values = dof_vector_to_b_values[dof_indices];
+ internal::add_tangentiality_constraints (dof_indices,
+ average_tangent,
+ constraints,
+ b_values);
+ }
+ }
}
- }
}
typename FunctionMap<spacedim>::type function_map;
std::set<types::boundary_id>::const_iterator it
= boundary_ids.begin();
- for (;it != boundary_ids.end(); ++it)
+ for (; it != boundary_ids.end(); ++it)
function_map[*it] = &zero_function;
compute_nonzero_tangential_flux_constraints(dof_handler,
first_vector_component,
hp::MappingCollection<dim,spacedim> mapping_collection;
for (unsigned int i=0; i<fe_collection.size(); ++i)
mapping_collection.push_back (mapping);
-
+
// now also create a quadrature collection for the faces of a cell. fill
// it with a quadrature formula with the support points on faces for each
// FE
hp::QCollection<dim-1> face_quadrature_collection;
for (unsigned int i=0; i<fe_collection.size(); ++i)
- {
- const std::vector<Point<dim-1> > &
- unit_support_points = fe_collection[i].get_unit_face_support_points();
-
- Assert (unit_support_points.size() == fe_collection[i].dofs_per_face,
- ExcInternalError());
-
- face_quadrature_collection.push_back (Quadrature<dim-1> (unit_support_points));
- }
-
+ {
+ const std::vector<Point<dim-1> > &
+ unit_support_points = fe_collection[i].get_unit_face_support_points();
+
+ Assert (unit_support_points.size() == fe_collection[i].dofs_per_face,
+ ExcInternalError());
+
+ face_quadrature_collection.push_back (Quadrature<dim-1> (unit_support_points));
+ }
+
// now create the object with which we will generate the normal vectors
hp::FEFaceValues<dim,spacedim> x_fe_face_values (mapping_collection,
fe_collection,
std::vector<types::global_dof_index> face_dofs;
std::map<std_cxx1x::array<types::global_dof_index,dim>, Vector<double> >
- dof_vector_to_b_values;
+ dof_vector_to_b_values;
std::set<types::boundary_id>::iterator b_id;
std::vector<std_cxx1x::array<types::global_dof_index,dim> > cell_vector_dofs;
const FEFaceValues<dim> &fe_values = x_fe_face_values.get_present_fe_values();
std::map<types::global_dof_index, double> dof_to_b_value;
-
+
unsigned int n_scalar_indices = 0;
cell_vector_dofs.resize(fe.dofs_per_face);
for (unsigned int i=0; i<fe.dofs_per_face; ++i)
- {
- if (fe.face_system_to_component_index(i).first >= first_vector_component &&
- fe.face_system_to_component_index(i).first < first_vector_component + dim)
{
- const unsigned int component
- = fe.face_system_to_component_index(i).first
- -first_vector_component;
- n_scalar_indices =
- std::max(n_scalar_indices,
- fe.face_system_to_component_index(i).second+1);
- cell_vector_dofs[fe.face_system_to_component_index(i).second]
- [component]
- = face_dofs[i];
-
- const Point<dim> point
- = fe_values.quadrature_point(i);
- const double b_value
- = function_map[*b_id]->value(point, component);
- dof_to_b_value.insert
- (std::make_pair(face_dofs[i], b_value));
+ if (fe.face_system_to_component_index(i).first >= first_vector_component &&
+ fe.face_system_to_component_index(i).first < first_vector_component + dim)
+ {
+ const unsigned int component
+ = fe.face_system_to_component_index(i).first
+ -first_vector_component;
+ n_scalar_indices =
+ std::max(n_scalar_indices,
+ fe.face_system_to_component_index(i).second+1);
+ cell_vector_dofs[fe.face_system_to_component_index(i).second]
+ [component]
+ = face_dofs[i];
+
+ const Point<dim> point
+ = fe_values.quadrature_point(i);
+ const double b_value
+ = function_map[*b_id]->value(point, component);
+ dof_to_b_value.insert
+ (std::make_pair(face_dofs[i], b_value));
+ }
}
- }
// now we identified the vector indices on the cell, so next
// insert them into the set (it would be expensive to directly
// insert incomplete points into the set)
for (unsigned int i=0; i<n_scalar_indices; ++i)
- {
- vector_dofs.insert(cell_vector_dofs[i]);
- Vector<double> b_values(dim);
- for (unsigned int j=0; j<dim; ++j)
- b_values[j]=dof_to_b_value[cell_vector_dofs[i][j]];
- dof_vector_to_b_values.insert
+ {
+ vector_dofs.insert(cell_vector_dofs[i]);
+ Vector<double> b_values(dim);
+ for (unsigned int j=0; j<dim; ++j)
+ b_values[j]=dof_to_b_value[cell_vector_dofs[i][j]];
+ dof_vector_to_b_values.insert
(std::make_pair(cell_vector_dofs[i], b_values));
- }
+ }
}
{
const Vector<double> b_value = dof_vector_to_b_values[*it];
for (unsigned int d=0; d<dim; ++d)
- {
- constraints.add_line((*it)[d]);
- constraints.set_inhomogeneity((*it)[d], b_value(d));
- }
+ {
+ constraints.add_line((*it)[d]);
+ constraints.set_inhomogeneity((*it)[d], b_value(d));
+ }
continue;
}
{
OperatorBase::~OperatorBase()
{}
-
+
void OperatorBase::notify(const Event &e)
{
notifications += e;
}
-
+
void
OperatorBase::clear_events ()
{
notifications.clear();
}
-
+
#include "operator.inst"
}
double hmax=patches[0].data(0,0);
for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
- patch != patches.end(); ++patch)
+ patch != patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
AssertThrow (dim==2, ExcNotImplemented());
}
-
+
template <int spacedim>
void write_eps (const std::vector<Patch<2,spacedim> > &patches,
const std::vector<std::string> &/*data_names*/,
template <int dim, typename Number>
Function<dim, Number>::Function (const unsigned int n_components,
- const Number initial_time)
+ const Number initial_time)
:
FunctionTime<Number>(initial_time),
n_components(n_components)
template <int dim, typename Number>
Number Function<dim, Number>::value (const Point<dim, Number> &,
- const unsigned int) const
+ const unsigned int) const
{
Assert (false, ExcPureFunctionCalled());
return 0;
template <int dim, typename Number>
void Function<dim, Number>::vector_value (const Point<dim, Number> &p,
- Vector<Number> &v) const
+ Vector<Number> &v) const
{
AssertDimension(v.size(), this->n_components);
for (unsigned int i=0; i<this->n_components; ++i)
template <int dim, typename Number>
void Function<dim, Number>::value_list (const std::vector<Point<dim, Number> > &points,
- std::vector<Number> &values,
- const unsigned int component) const
+ std::vector<Number> &values,
+ const unsigned int component) const
{
// check whether component is in
// the valid range is up to the
template <int dim, typename Number>
void Function<dim, Number>::vector_value_list (const std::vector<Point<dim, Number> > &points,
- std::vector<Vector<Number> > &values) const
+ std::vector<Vector<Number> > &values) const
{
// check whether component is in
// the valid range is up to the
template <int dim, typename Number>
Tensor<1,dim,Number> Function<dim, Number>::gradient (const Point<dim, Number> &,
- const unsigned int) const
+ const unsigned int) const
{
Assert (false, ExcPureFunctionCalled());
return Point<dim, Number>();
template <int dim, typename Number>
void Function<dim, Number>::gradient_list (const std::vector<Point<dim, Number> > &points,
- std::vector<Tensor<1,dim,Number> > &gradients,
- const unsigned int component) const
+ std::vector<Tensor<1,dim,Number> > &gradients,
+ const unsigned int component) const
{
Assert (gradients.size() == points.size(),
ExcDimensionMismatch(gradients.size(), points.size()));
template <int dim, typename Number>
void Function<dim, Number>::vector_gradient_list (const std::vector<Point<dim, Number> > &points,
- std::vector<std::vector<Tensor<1,dim,Number> > > &gradients) const
+ std::vector<std::vector<Tensor<1,dim,Number> > > &gradients) const
{
Assert (gradients.size() == points.size(),
ExcDimensionMismatch(gradients.size(), points.size()));
template <int dim, typename Number>
Number Function<dim, Number>::laplacian (const Point<dim, Number> &,
- const unsigned int) const
+ const unsigned int) const
{
Assert (false, ExcPureFunctionCalled());
return 0;
template <int dim, typename Number>
void Function<dim, Number>::vector_laplacian (const Point<dim, Number> &,
- Vector<Number> &) const
+ Vector<Number> &) const
{
Assert (false, ExcPureFunctionCalled());
}
template <int dim, typename Number>
void Function<dim, Number>::laplacian_list (const std::vector<Point<dim, Number> > &points,
- std::vector<Number> &laplacians,
- const unsigned int component) const
+ std::vector<Number> &laplacians,
+ const unsigned int component) const
{
// check whether component is in
// the valid range is up to the
template <int dim, typename Number>
void Function<dim, Number>::vector_laplacian_list (const std::vector<Point<dim, Number> > &points,
- std::vector<Vector<Number> > &laplacians) const
+ std::vector<Vector<Number> > &laplacians) const
{
// check whether component is in
// the valid range is up to the
template <int dim, typename Number>
Number ZeroFunction<dim, Number>::value (const Point<dim, Number> &,
- const unsigned int) const
+ const unsigned int) const
{
return 0.;
}
template <int dim, typename Number>
void ZeroFunction<dim, Number>::vector_value (const Point<dim, Number> &,
- Vector<Number> &return_value) const
+ Vector<Number> &return_value) const
{
Assert (return_value.size() == this->n_components,
ExcDimensionMismatch (return_value.size(), this->n_components));
template <int dim, typename Number>
void ZeroFunction<dim, Number>::value_list (const std::vector<Point<dim, Number> > &points,
- std::vector<Number> &values,
- const unsigned int /*component*/) const
+ std::vector<Number> &values,
+ const unsigned int /*component*/) const
{
Assert (values.size() == points.size(),
ExcDimensionMismatch(values.size(), points.size()));
template <int dim, typename Number>
void ZeroFunction<dim, Number>::vector_value_list (const std::vector<Point<dim, Number> > &points,
- std::vector<Vector<Number> > &values) const
+ std::vector<Vector<Number> > &values) const
{
Assert (values.size() == points.size(),
ExcDimensionMismatch(values.size(), points.size()));
template <int dim, typename Number>
Tensor<1,dim,Number> ZeroFunction<dim, Number>::gradient (const Point<dim, Number> &,
- const unsigned int) const
+ const unsigned int) const
{
return Tensor<1,dim,Number>();
}
template <int dim, typename Number>
void ZeroFunction<dim, Number>::vector_gradient (const Point<dim, Number> &,
- std::vector<Tensor<1,dim,Number> > &gradients) const
+ std::vector<Tensor<1,dim,Number> > &gradients) const
{
Assert (gradients.size() == this->n_components,
ExcDimensionMismatch(gradients.size(), this->n_components));
template <int dim, typename Number>
void ZeroFunction<dim, Number>::gradient_list (const std::vector<Point<dim, Number> > &points,
- std::vector<Tensor<1,dim,Number> > &gradients,
- const unsigned int /*component*/) const
+ std::vector<Tensor<1,dim,Number> > &gradients,
+ const unsigned int /*component*/) const
{
Assert (gradients.size() == points.size(),
ExcDimensionMismatch(gradients.size(), points.size()));
template <int dim, typename Number>
void ZeroFunction<dim, Number>::vector_gradient_list (const std::vector<Point<dim, Number> > &points,
- std::vector<std::vector<Tensor<1,dim,Number> > > &gradients) const
+ std::vector<std::vector<Tensor<1,dim,Number> > > &gradients) const
{
Assert (gradients.size() == points.size(),
ExcDimensionMismatch(gradients.size(), points.size()));
template <int dim, typename Number>
ConstantFunction<dim, Number>::ConstantFunction (const Number value,
- const unsigned int n_components)
+ const unsigned int n_components)
:
ZeroFunction<dim, Number> (n_components),
function_value (value)
template <int dim, typename Number>
Number ConstantFunction<dim, Number>::value (const Point<dim, Number> &,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component < this->n_components,
ExcIndexRange (component, 0, this->n_components));
template <int dim, typename Number>
void ConstantFunction<dim, Number>::vector_value (const Point<dim, Number> &,
- Vector<Number> &return_value) const
+ Vector<Number> &return_value) const
{
Assert (return_value.size() == this->n_components,
ExcDimensionMismatch (return_value.size(), this->n_components));
template <int dim, typename Number>
void ConstantFunction<dim, Number>::value_list (const std::vector<Point<dim, Number> > &points,
- std::vector<Number> &values,
- const unsigned int component) const
+ std::vector<Number> &values,
+ const unsigned int component) const
{
Assert (component < this->n_components,
ExcIndexRange (component, 0, this->n_components));
template <int dim, typename Number>
void ConstantFunction<dim, Number>::vector_value_list (const std::vector<Point<dim, Number> > &points,
- std::vector<Vector<Number> > &values) const
+ std::vector<Vector<Number> > &values) const
{
Assert (values.size() == points.size(),
ExcDimensionMismatch(values.size(), points.size()));
template <int dim, typename Number>
void ComponentSelectFunction<dim, Number>::vector_value (const Point<dim, Number> &,
- Vector<Number> &return_value) const
+ Vector<Number> &return_value) const
{
Assert (return_value.size() == this->n_components,
ExcDimensionMismatch (return_value.size(), this->n_components));
template <int dim, typename Number>
void ComponentSelectFunction<dim, Number>::vector_value_list (const std::vector<Point<dim, Number> > &points,
- std::vector<Vector<Number> > &values) const
+ std::vector<Vector<Number> > &values) const
{
Assert (values.size() == points.size(),
ExcDimensionMismatch(values.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
ComponentSelectFunction<dim, Number>::vector_value (points[i],
- values[i]);
+ values[i]);
}
template <int dim, typename Number>
Number
ScalarFunctionFromFunctionObject<dim, Number>::value (const Point<dim, Number> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component == 0,
ExcMessage ("This object represents only scalar functions"));
template <int dim, typename Number>
Number
VectorFunctionFromScalarFunctionObject<dim, Number>::value (const Point<dim, Number> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component < this->n_components,
ExcIndexRange (component, 0, this->n_components));
template <int dim, typename Number>
inline
Number VectorFunctionFromTensorFunction<dim, Number>::value (const Point<dim, Number> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component<this->n_components,
ExcIndexRange(component, 0, this->n_components));
template <int dim, typename Number>
inline
void VectorFunctionFromTensorFunction<dim, Number>::vector_value (const Point<dim, Number> &p,
- Vector<Number> &values) const
+ Vector<Number> &values) const
{
Assert(values.size() == this->n_components,
ExcDimensionMismatch(values.size(),this->n_components));
const Point<1> &xi)
{
return ((1-xi[0])*data_values[ix[0]]
- +
- xi[0]*data_values[ix[0]+1]);
+ +
+ xi[0]*data_values[ix[0]+1]);
}
double interpolate (const Table<2,double> &data_values,
InterpolatedTensorProductGridData<dim>::
InterpolatedTensorProductGridData(const std_cxx1x::array<std::vector<double>,dim> &coordinate_values,
const Table<dim,double> &data_values)
- :
- coordinate_values (coordinate_values),
- data_values (data_values)
+ :
+ coordinate_values (coordinate_values),
+ data_values (data_values)
{
for (unsigned int d=0; d<dim; ++d)
{
ExcMessage ("Coordinate arrays must have at least two coordinate values!"));
for (unsigned int i=0; i<coordinate_values[d].size()-1; ++i)
Assert (coordinate_values[d][i] < coordinate_values[d][i+1],
- ExcMessage ("Coordinate arrays must be sorted in strictly ascending order."));
+ ExcMessage ("Coordinate arrays must be sorted in strictly ascending order."));
Assert (data_values.size()[d] == coordinate_values[d].size(),
ExcMessage ("Data and coordinate tables do not have the same size."));
const unsigned int component) const
{
Assert (component == 0,
- ExcMessage ("This is a scalar function object, the component can only be zero."));
+ ExcMessage ("This is a scalar function object, the component can only be zero."));
// find out where this data point lies, relative to the given
// points. if we run all the way to the end of the range,
// to consider the last box which has index size()-2
if (ix[d] == coordinate_values[d].size())
ix[d] = coordinate_values[d].size()-2;
- else
- if (ix[d] > 0)
- --ix[d];
+ else if (ix[d] > 0)
+ --ix[d];
}
// now compute the relative point within the interval/rectangle/box
InterpolatedUniformGridData(const std_cxx1x::array<std::pair<double,double>,dim> &interval_endpoints,
const std_cxx1x::array<unsigned int,dim> &n_subintervals,
const Table<dim,double> &data_values)
- :
- interval_endpoints (interval_endpoints),
- n_subintervals (n_subintervals),
- data_values (data_values)
+ :
+ interval_endpoints (interval_endpoints),
+ n_subintervals (n_subintervals),
+ data_values (data_values)
{
for (unsigned int d=0; d<dim; ++d)
{
const unsigned int component) const
{
Assert (component == 0,
- ExcMessage ("This is a scalar function object, the component can only be zero."));
+ ExcMessage ("This is a scalar function object, the component can only be zero."));
// find out where this data point lies, relative to the given
// subdivision points
for (unsigned int d=0; d<dim; ++d)
{
const double delta_x = ((interval_endpoints[d].second - interval_endpoints[d].first) /
- n_subintervals[d]);
- p_unit[d] = std::max(std::min((p[d]-interval_endpoints[d].first-ix[d]*delta_x)/delta_x,
- 1.),
- 0.);
+ n_subintervals[d]);
+ p_unit[d] = std::max(std::min((p[d]-interval_endpoints[d].first-ix[d]*delta_x)/delta_x,
+ 1.),
+ 0.);
}
-
+
return interpolate (data_values, ix, p_unit);
}
template <int dim>
void FunctionParser<dim>::initialize (const std::string &vars,
- const std::vector<std::string> &expressions,
- const std::map<std::string, double> &constants,
- const bool time_dependent)
+ const std::vector<std::string> &expressions,
+ const std::map<std::string, double> &constants,
+ const bool time_dependent)
{
initialize(vars, expressions, constants, time_dependent, false);
}
{
return static_cast<int>(val + ((val>=0.0) ? 0.5 : -0.5) );
}
-
+
double mu_if(double condition, double thenvalue, double elsevalue)
{
if (mu_round(condition))
else
return elsevalue;
}
-
+
double mu_or(double left, double right)
{
return (mu_round(left)) || (mu_round(right));
}
-
+
double mu_and(double left, double right)
{
return (mu_round(left)) && (mu_round(right));
}
-
+
double mu_int(double value)
{
return static_cast<double>(mu_round(value));
{
if (fp.get().size()>0)
return;
-
+
fp.get().resize(this->n_components);
vars.get().resize(var_names.size());
for (unsigned int component=0; component<this->n_components; ++component)
{
for (std::map< std::string, double >::const_iterator constant = constants.begin();
- constant != constants.end(); ++constant)
+ constant != constants.end(); ++constant)
{
- fp.get()[component].DefineConst(constant->first.c_str(), constant->second);
- }
+ fp.get()[component].DefineConst(constant->first.c_str(), constant->second);
+ }
- for (unsigned int iv=0;iv<var_names.size();++iv)
- fp.get()[component].DefineVar(var_names[iv].c_str(), &vars.get()[iv]);
+ for (unsigned int iv=0; iv<var_names.size(); ++iv)
+ fp.get()[component].DefineVar(var_names[iv].c_str(), &vars.get()[iv]);
// define some compatibility functions:
fp.get()[component].DefineFun("if",internal::mu_if, true);
fp.get()[component].DefineFun("floor", internal::mu_floor, true);
fp.get()[component].DefineFun("sec", internal::mu_sec, true);
fp.get()[component].DefineFun("log", internal::mu_log, true);
-
+
try
- {
+ {
// muparser expects that functions have no
// space between the name of the function and the opening
// parenthesis. this is awkward because it is not backward
// we may find after function names
std::string transformed_expression = expressions[component];
- const char *function_names[] = {
- // functions predefined by muparser
- "sin",
- "cos",
- "tan",
- "asin",
- "acos",
- "atan",
- "sinh",
- "cosh",
- "tanh",
- "asinh",
- "acosh",
- "atanh",
- "atan2",
- "log2",
- "log10",
- "log",
- "ln",
- "exp",
- "sqrt",
- "sign",
- "rint",
- "abs",
- "min",
- "max",
- "sum",
- "avg",
- // functions we define ourselves above
- "if",
- "int",
- "ceil",
- "cot",
- "csc",
- "floor",
- "sec" };
+ const char *function_names[] =
+ {
+ // functions predefined by muparser
+ "sin",
+ "cos",
+ "tan",
+ "asin",
+ "acos",
+ "atan",
+ "sinh",
+ "cosh",
+ "tanh",
+ "asinh",
+ "acosh",
+ "atanh",
+ "atan2",
+ "log2",
+ "log10",
+ "log",
+ "ln",
+ "exp",
+ "sqrt",
+ "sign",
+ "rint",
+ "abs",
+ "min",
+ "max",
+ "sum",
+ "avg",
+ // functions we define ourselves above
+ "if",
+ "int",
+ "ceil",
+ "cot",
+ "csc",
+ "floor",
+ "sec"
+ };
for (unsigned int f=0; f<sizeof(function_names)/sizeof(function_names[0]); ++f)
{
const std::string function_name = function_names[f];
// replace whitespace until there no longer is any
while ((pos+function_name_length<transformed_expression.size())
- &&
- ((transformed_expression[pos+function_name_length] == ' ')
+ &&
+ ((transformed_expression[pos+function_name_length] == ' ')
||
(transformed_expression[pos+function_name_length] == '\t')))
transformed_expression.erase (transformed_expression.begin()+pos+function_name_length);
}
// now use the transformed expression
- fp.get()[component].SetExpr(transformed_expression);
- }
+ fp.get()[component].SetExpr(transformed_expression);
+ }
catch (mu::ParserError &e)
- {
+ {
std::cerr << "Message: " << e.GetMsg() << "\n";
- std::cerr << "Formula: " << e.GetExpr() << "\n";
- std::cerr << "Token: " << e.GetToken() << "\n";
- std::cerr << "Position: " << e.GetPos() << "\n";
- std::cerr << "Errc: " << e.GetCode() << std::endl;
- AssertThrow(false, ExcParseError(e.GetCode(), e.GetMsg().c_str()));
- }
+ std::cerr << "Formula: " << e.GetExpr() << "\n";
+ std::cerr << "Token: " << e.GetToken() << "\n";
+ std::cerr << "Position: " << e.GetPos() << "\n";
+ std::cerr << "Errc: " << e.GetCode() << std::endl;
+ AssertThrow(false, ExcParseError(e.GetCode(), e.GetMsg().c_str()));
+ }
}
}
const bool use_degrees)
{
this->fp.clear(); // this will reset all thread-local objects
-
+
this->constants = constants;
this->var_names = Utilities::split_string_list(variables, ',');
this->expressions = expressions;
AssertThrow(((time_dependent)?dim+1:dim) == var_names.size(),
- ExcMessage("wrong number of variables"));
+ ExcMessage("wrong number of variables"));
AssertThrow(!use_degrees, ExcNotImplemented());
// We check that the number of
n_vars = dim;
init_muparser();
-
+
// Now set the initialization bit.
initialized = true;
}
std::cerr << "Formula: " << e.GetExpr() << "\n";
std::cerr << "Token: " << e.GetToken() << "\n";
std::cerr << "Position: " << e.GetPos() << "\n";
- std::cerr << "Errc: " << e.GetCode() << std::endl;
+ std::cerr << "Errc: " << e.GetCode() << std::endl;
AssertThrow(false, ExcParseError(e.GetCode(), e.GetMsg().c_str()));
return 0.0;
}
vars.get()[i] = p(i);
if (dim != n_vars)
vars.get()[dim] = this->get_time();
-
+
for (unsigned int component = 0; component < this->n_components;
++component)
values(component) = fp.get()[component].Eval();
std::string s = get (entry_string);
char *endptr;
const long int i = std::strtol (s.c_str(), &endptr, 10);
-
+
// assert that there was no error. an error would be if
// either there was no string to begin with, or if
// strtol set the endptr to anything but the end of
// the string
AssertThrow ((s.size()>0) && (*endptr == '\0'),
- ExcConversionError(s));
+ ExcConversionError(s));
return i;
}
// strtol set the endptr to anything but the end of
// the string
AssertThrow ((s.size()>0) && (*endptr == '\0'),
- ExcConversionError(s));
+ ExcConversionError(s));
return d;
}
// between the last entry and the first
// subsection
if (style != XML)
- {
- unsigned int n_parameters = 0;
- unsigned int n_sections = 0;
- for (boost::property_tree::ptree::const_iterator
- p = current_section.begin();
- p != current_section.end(); ++p)
- if (is_parameter_node (p->second) == true)
- ++n_parameters;
- else
- ++n_sections;
-
- if ((style != Description)
- &&
- (!(style & 128))
- &&
- (n_parameters != 0)
- &&
- (n_sections != 0))
- out << std::endl << std::endl;
+ {
+ unsigned int n_parameters = 0;
+ unsigned int n_sections = 0;
+ for (boost::property_tree::ptree::const_iterator
+ p = current_section.begin();
+ p != current_section.end(); ++p)
+ if (is_parameter_node (p->second) == true)
+ ++n_parameters;
+ else
+ ++n_sections;
- // now traverse subsections tree,
- // in alphabetical order
- for (boost::property_tree::ptree::const_assoc_iterator
- p = current_section.ordered_begin();
- p != current_section.not_found(); ++p)
- if (is_parameter_node (p->second) == false)
- {
- // first print the subsection header
- switch (style)
+ if ((style != Description)
+ &&
+ (!(style & 128))
+ &&
+ (n_parameters != 0)
+ &&
+ (n_sections != 0))
+ out << std::endl << std::endl;
+
+ // now traverse subsections tree,
+ // in alphabetical order
+ for (boost::property_tree::ptree::const_assoc_iterator
+ p = current_section.ordered_begin();
+ p != current_section.not_found(); ++p)
+ if (is_parameter_node (p->second) == false)
{
- case Text:
- case Description:
- case ShortText:
+ // first print the subsection header
+ switch (style)
+ {
+ case Text:
+ case Description:
+ case ShortText:
out << std::setw(overall_indent_level*2) << ""
- << "subsection " << demangle(p->first) << std::endl;
- break;
- case LaTeX:
- {
- out << std::endl
- << "\\subsection{Parameters in section \\tt ";
-
- // find the path to the
- // current section so that we
- // can print it in the
- // \subsection{...} heading
- for (unsigned int i=0; i<subsection_path.size(); ++i)
- out << subsection_path[i] << "/";
- out << demangle(p->first);
-
- out << "}" << std::endl;
- out << "\\label{parameters:";
- for (unsigned int i=0; i<subsection_path.size(); ++i)
- out << mangle(subsection_path[i]) << "/";
- out << p->first << "}";
- out << std::endl;
+ << "subsection " << demangle(p->first) << std::endl;
+ break;
+ case LaTeX:
+ {
+ out << std::endl
+ << "\\subsection{Parameters in section \\tt ";
- out << std::endl;
- break;
- }
+ // find the path to the
+ // current section so that we
+ // can print it in the
+ // \subsection{...} heading
+ for (unsigned int i=0; i<subsection_path.size(); ++i)
+ out << subsection_path[i] << "/";
+ out << demangle(p->first);
- default:
- Assert (false, ExcNotImplemented());
- };
+ out << "}" << std::endl;
+ out << "\\label{parameters:";
+ for (unsigned int i=0; i<subsection_path.size(); ++i)
+ out << mangle(subsection_path[i]) << "/";
+ out << p->first << "}";
+ out << std::endl;
- // then the contents of the
- // subsection
- enter_subsection (demangle(p->first));
+ out << std::endl;
+ break;
+ }
+
+ default:
+ Assert (false, ExcNotImplemented());
+ };
+
+ // then the contents of the
+ // subsection
+ enter_subsection (demangle(p->first));
print_parameters_section (out, style, overall_indent_level+1);
- leave_subsection ();
- switch (style)
- {
- case Text:
- // write end of
- // subsection. one
- // blank line after
- // each subsection
+ leave_subsection ();
+ switch (style)
+ {
+ case Text:
+ // write end of
+ // subsection. one
+ // blank line after
+ // each subsection
out << std::setw(overall_indent_level*2) << ""
- << "end" << std::endl
- << std::endl;
+ << "end" << std::endl
+ << std::endl;
- // if this is a toplevel
- // subsection, then have two
- // newlines
+ // if this is a toplevel
+ // subsection, then have two
+ // newlines
if (overall_indent_level == 0)
- out << std::endl;
+ out << std::endl;
- break;
- case Description:
- break;
- case ShortText:
- // write end of
- // subsection.
+ break;
+ case Description:
+ break;
+ case ShortText:
+ // write end of
+ // subsection.
out << std::setw(overall_indent_level*2) << ""
- << "end" << std::endl;
- break;
- case LaTeX:
- break;
- default:
- Assert (false, ExcNotImplemented());
+ << "end" << std::endl;
+ break;
+ case LaTeX:
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ }
}
- }
-}
+ }
// close top level elements, if there are any
switch (style)
std::vector< std::pair<double, Point<dim> > > wp;
for (unsigned int i=0; i<quad.size(); ++i)
wp.push_back(std::pair<double, Point<dim> >(quad.weight(i),
- quad.point(i)));
+ quad.point(i)));
sort(wp.begin(), wp.end(), *this);
- for(unsigned int i=0; i<quad.size(); ++i)
+ for (unsigned int i=0; i<quad.size(); ++i)
{
this->weights[i] = wp[i].first;
this->quadrature_points[i] = wp[i].second;
template <int dim>
bool QSorted<dim>::operator()(const std::pair<double, Point<dim> > &a,
- const std::pair<double, Point<dim> > &b)
+ const std::pair<double, Point<dim> > &b)
{
return (a.first < b.first);
}
template <int rank, int dim, typename Number>
void
TensorFunction<rank, dim, Number>::value_list (const std::vector<Point<dim,Number> > &points,
- std::vector<value_type> &values) const
+ std::vector<value_type> &values) const
{
Assert (values.size() == points.size(),
ExcDimensionMismatch(values.size(), points.size()));
template <int rank, int dim, typename Number>
void
TensorFunction<rank, dim, Number>::gradient_list (const std::vector<Point<dim,Number> > &points,
- std::vector<gradient_type> &gradients) const
+ std::vector<gradient_type> &gradients) const
{
Assert (gradients.size() == points.size(),
ExcDimensionMismatch(gradients.size(), points.size()));
template <int rank, int dim, typename Number>
ConstantTensorFunction<rank, dim, Number>::ConstantTensorFunction (const Tensor<rank, dim, Number> &value,
- const Number initial_time)
+ const Number initial_time)
:
TensorFunction<rank, dim, Number> (initial_time),
_value(value)
template <int rank, int dim, typename Number>
void
ConstantTensorFunction<rank, dim, Number>::value_list (const std::vector<Point<dim,Number> > &points,
- std::vector<typename TensorFunction<rank, dim, Number>::value_type> &values) const
+ std::vector<typename TensorFunction<rank, dim, Number>::value_type> &values) const
{
Assert (values.size() == points.size(),
ExcDimensionMismatch(values.size(), points.size()));
template <int rank, int dim, typename Number>
void
ConstantTensorFunction<rank, dim, Number>::gradient_list (const std::vector<Point<dim,Number> > &points,
- std::vector<typename TensorFunction<rank, dim, Number>::gradient_type> &gradients) const
+ std::vector<typename TensorFunction<rank, dim, Number>::gradient_type> &gradients) const
{
Assert (gradients.size() == points.size(),
ExcDimensionMismatch(gradients.size(), points.size()));
types<2>::balance_type btype,
p4est_init_t init_fn);
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
static
p4est_gloidx_t (&partition) (types<2>::forest *p4est,
int partition_for_coarsening,
p4est_weight_t weight_fn);
-#else
+#else
static
void (&partition) (types<2>::forest *p4est,
int partition_for_coarsening,
p4est_weight_t weight_fn);
-#endif
+#endif
static
void (&save) (const char *filename,
types<2>::forest *p4est,
int save_data);
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
static
types<2>::forest *(&load_ext) (const char *filename,
- MPI_Comm mpicomm,
- size_t data_size,
- int load_data,
- int autopartition,
- int broadcasthead,
- void *user_pointer,
- types<2>::connectivity **p4est);
+ MPI_Comm mpicomm,
+ size_t data_size,
+ int load_data,
+ int autopartition,
+ int broadcasthead,
+ void *user_pointer,
+ types<2>::connectivity **p4est);
#else
static
types<2>::forest *(&load) (const char *filename,
types<2>::connectivity **p4est);
#endif
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
static
int (&connectivity_save) (const char *filename,
types<2>::connectivity *connectivity);
-#else
+#else
static
void (&connectivity_save) (const char *filename,
types<2>::connectivity *connectivity);
-#endif
+#endif
static
int (&connectivity_is_valid) (types<2>::connectivity *connectivity);
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
static
types<2>::connectivity *(&connectivity_load) (const char *filename,
long unsigned *length);
-#else
+#else
static
types<2>::connectivity *(&connectivity_load) (const char *filename,
long *length);
-#endif
+#endif
static
unsigned int (&checksum) (types<2>::forest *p4est);
p4est_init_t init_fn)
= p4est_balance;
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
- p4est_gloidx_t (&functions<2>::partition) (types<2>::forest *p4est,
- int partition_for_coarsening,
- p4est_weight_t weight_fn)
- = p4est_partition_ext;
-#else
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+ p4est_gloidx_t (&functions<2>::partition) (types<2>::forest *p4est,
+ int partition_for_coarsening,
+ p4est_weight_t weight_fn)
+ = p4est_partition_ext;
+#else
void (&functions<2>::partition) (types<2>::forest *p4est,
int partition_for_coarsening,
p4est_weight_t weight_fn)
= p4est_partition_ext;
-#endif
+#endif
void (&functions<2>::save) (const char *filename,
types<2>::forest *p4est,
int save_data)
= p4est_save;
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
types<2>::forest *
(&functions<2>::load_ext) (const char *filename,
- MPI_Comm mpicomm,
- std::size_t data_size,
- int load_data,
- int autopartition,
- int broadcasthead,
- void *user_pointer,
- types<2>::connectivity **p4est)
+ MPI_Comm mpicomm,
+ std::size_t data_size,
+ int load_data,
+ int autopartition,
+ int broadcasthead,
+ void *user_pointer,
+ types<2>::connectivity **p4est)
= p4est_load_ext;
#else
types<2>::forest *
= p4est_load;
#endif
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
- int (&functions<2>::connectivity_save) (const char *filename,
- types<2>::connectivity *connectivity)
- = p4est_connectivity_save;
-#else
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+ int (&functions<2>::connectivity_save) (const char *filename,
+ types<2>::connectivity *connectivity)
+ = p4est_connectivity_save;
+#else
void (&functions<2>::connectivity_save) (const char *filename,
types<2>::connectivity *connectivity)
= p4est_connectivity_save;
-#endif
+#endif
int (&functions<2>::connectivity_is_valid) (types<2>::connectivity
*connectivity)
= p4est_connectivity_is_valid;
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
types<2>::connectivity *
(&functions<2>::connectivity_load) (const char *filename,
long unsigned *length)
= p4est_connectivity_load;
-#else
+#else
types<2>::connectivity *
(&functions<2>::connectivity_load) (const char *filename,
long *length)
= p4est_connectivity_load;
-#endif
+#endif
unsigned int (&functions<2>::checksum) (types<2>::forest *p4est)
= p4est_checksum;
types<3>::balance_type btype,
p8est_init_t init_fn);
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
static
p4est_gloidx_t (&partition) (types<3>::forest *p8est,
int partition_for_coarsening,
p8est_weight_t weight_fn);
-#else
+#else
static
void (&partition) (types<3>::forest *p8est,
int partition_for_coarsening,
p8est_weight_t weight_fn);
-#endif
+#endif
static
void (&save) (const char *filename,
types<3>::forest *p4est,
int save_data);
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
static
types<3>::forest *(&load_ext) (const char *filename,
- MPI_Comm mpicomm,
- std::size_t data_size,
- int load_data,
- int autopartition,
- int broadcasthead,
- void *user_pointer,
- types<3>::connectivity **p4est);
+ MPI_Comm mpicomm,
+ std::size_t data_size,
+ int load_data,
+ int autopartition,
+ int broadcasthead,
+ void *user_pointer,
+ types<3>::connectivity **p4est);
#else
static
types<3>::forest *(&load) (const char *filename,
types<3>::connectivity **p4est);
#endif
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
static
int (&connectivity_save) (const char *filename,
types<3>::connectivity *connectivity);
-#else
+#else
static
void (&connectivity_save) (const char *filename,
types<3>::connectivity *connectivity);
-#endif
+#endif
static
int (&connectivity_is_valid) (types<3>::connectivity *connectivity);
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
static
types<3>::connectivity *(&connectivity_load) (const char *filename,
long unsigned *length);
-#else
+#else
static
types<3>::connectivity *(&connectivity_load) (const char *filename,
long *length);
-#endif
+#endif
static
unsigned int (&checksum) (types<3>::forest *p8est);
p8est_init_t init_fn)
= p8est_balance;
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
p4est_gloidx_t (&functions<3>::partition) (types<3>::forest *p8est,
int partition_for_coarsening,
p8est_weight_t weight_fn)
= p8est_partition_ext;
-#else
+#else
void (&functions<3>::partition) (types<3>::forest *p8est,
int partition_for_coarsening,
p8est_weight_t weight_fn)
= p8est_partition_ext;
-#endif
+#endif
void (&functions<3>::save) (const char *filename,
types<3>::forest *p4est,
int save_data)
= p8est_save;
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
types<3>::forest *
(&functions<3>::load_ext) (const char *filename,
- MPI_Comm mpicomm,
- std::size_t data_size,
- int load_data,
- int autopartition,
- int broadcasthead,
- void *user_pointer,
- types<3>::connectivity **p4est)
+ MPI_Comm mpicomm,
+ std::size_t data_size,
+ int load_data,
+ int autopartition,
+ int broadcasthead,
+ void *user_pointer,
+ types<3>::connectivity **p4est)
= p8est_load_ext;
#else
types<3>::forest *
= p8est_load;
#endif
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
int (&functions<3>::connectivity_save) (const char *filename,
types<3>::connectivity *connectivity)
= p8est_connectivity_save;
-#else
+#else
void (&functions<3>::connectivity_save) (const char *filename,
types<3>::connectivity *connectivity)
= p8est_connectivity_save;
-#endif
+#endif
int (&functions<3>::connectivity_is_valid) (types<3>::connectivity
*connectivity)
= p8est_connectivity_is_valid;
-#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
+#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
types<3>::connectivity *
(&functions<3>::connectivity_load) (const char *filename,
long unsigned *length)
= p8est_connectivity_load;
-#else
+#else
types<3>::connectivity *
(&functions<3>::connectivity_load) (const char *filename,
long *length)
= p8est_connectivity_load;
-#endif
+#endif
unsigned int (&functions<3>::checksum) (types<3>::forest *p8est)
= p8est_checksum;
// instead need to filter over locally owned cells
bool res_local = false;
for (typename Triangulation<dim, spacedim>::active_cell_iterator cell = this->begin_active();
- (cell != this->end()) && (cell->level() < (int)(n_global_levels()-1));
- cell++)
- if (cell->is_locally_owned())
- {
- res_local = true;
- break;
- }
+ (cell != this->end()) && (cell->level() < (int)(n_global_levels()-1));
+ cell++)
+ if (cell->is_locally_owned())
+ {
+ res_local = true;
+ break;
+ }
// reduce over MPI
bool res;
#if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
#else
AssertThrow(numcpus <= Utilities::MPI::n_mpi_processes (mpi_communicator),
- ExcMessage("parallel::distributed::Triangulation::load() only supports loading "
- "saved data with a greater or equal number of processes than were used to "
- "save() when using p4est 0.3.4.2."));
+ ExcMessage("parallel::distributed::Triangulation::load() only supports loading "
+ "saved data with a greater or equal number of processes than were used to "
+ "save() when using p4est 0.3.4.2."));
#endif
attached_data_size = 0;
const CellStatus,
const void *)> &unpack_callback)
{
- Assert (offset >= sizeof(CellStatus),
+ Assert (offset >= sizeof(CellStatus),
ExcMessage ("invalid offset in notify_ready_to_unpack()"));
- Assert (offset < sizeof(CellStatus)+attached_data_size,
+ Assert (offset < sizeof(CellStatus)+attached_data_size,
ExcMessage ("invalid offset in notify_ready_to_unpack()"));
Assert (n_attached_datas > 0, ExcMessage ("notify_ready_to_unpack() called too often"));
// the first two arguments to the type p[48]est_iterate wants to see. this
// cast is the identity cast in each of the two branches, so it is safe.
switch (dim)
- {
- case 2:
- p4est_iterate (reinterpret_cast<dealii::internal::p4est::types<2>::forest*>(this->parallel_forest),
- reinterpret_cast<dealii::internal::p4est::types<2>::ghost*>(this->parallel_ghost),
- static_cast<void *>(&fg),
- NULL, find_ghosts_face<2,spacedim>, find_ghosts_corner<2,spacedim>);
- break;
-
- case 3:
- p8est_iterate (reinterpret_cast<dealii::internal::p4est::types<3>::forest*>(this->parallel_forest),
- reinterpret_cast<dealii::internal::p4est::types<3>::ghost*>(this->parallel_ghost),
- static_cast<void *>(&fg),
- NULL, find_ghosts_face<3,spacedim>, find_ghosts_edge<3,spacedim>, find_ghosts_corner<3,spacedim>);
- break;
-
- default:
- Assert (false, ExcNotImplemented());
- }
+ {
+ case 2:
+ p4est_iterate (reinterpret_cast<dealii::internal::p4est::types<2>::forest *>(this->parallel_forest),
+ reinterpret_cast<dealii::internal::p4est::types<2>::ghost *>(this->parallel_ghost),
+ static_cast<void *>(&fg),
+ NULL, find_ghosts_face<2,spacedim>, find_ghosts_corner<2,spacedim>);
+ break;
+
+ case 3:
+ p8est_iterate (reinterpret_cast<dealii::internal::p4est::types<3>::forest *>(this->parallel_forest),
+ reinterpret_cast<dealii::internal::p4est::types<3>::ghost *>(this->parallel_ghost),
+ static_cast<void *>(&fg),
+ NULL, find_ghosts_face<3,spacedim>, find_ghosts_edge<3,spacedim>, find_ghosts_corner<3,spacedim>);
+ break;
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
sc_array_destroy (fg.subids);
}
for (unsigned int child=0; child<this->n_children(); ++child)
{
- if (tmp.size() > 0)
- fe.get_prolongation_matrix(child, this->refinement_case())
- .vmult (tmp, local_values);
+ if (tmp.size() > 0)
+ fe.get_prolongation_matrix(child, this->refinement_case())
+ .vmult (tmp, local_values);
this->child(child)->set_dof_values_by_interpolation (tmp, values, fe_index);
}
}
// level as the cell, at least for for isotropic
// refinement
for (typename DoFHandler<2,spacedim>::level_cell_iterator cell = dof_handler.begin(level);
- cell != dof_handler.end(level); ++cell)
+ cell != dof_handler.end(level); ++cell)
for (unsigned int line=0; line < GeometryInfo<2>::faces_per_cell; ++line)
cell->face(line)->set_user_flag();
//mark all own cells for transfer
for (typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof_handler.begin_active();
- cell != dof_handler.end(); ++cell)
+ cell != dof_handler.end(); ++cell)
if (!cell->is_artificial())
cell->set_user_flag();
std::vector<dealii::types::global_dof_index> local_dof_indices;
for (typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof_handler.begin_active();
- cell != dof_handler.end(); ++cell)
+ cell != dof_handler.end(); ++cell)
if (!cell->is_artificial())
{
local_dof_indices.resize (cell->get_fe().dofs_per_cell);
// TODO: We might be able to extend this also for elements which do not
// have the same constant modes, but that is messy...
const dealii::hp::FECollection<DH::dimension,DH::space_dimension>
- fe_collection (dof_handler.get_fe());
+ fe_collection (dof_handler.get_fe());
std::vector<Table<2,bool> > element_constant_modes;
std::vector<std::vector<std::pair<unsigned int, unsigned int> > >
- constant_mode_to_component_translation(n_components);
+ constant_mode_to_component_translation(n_components);
unsigned int n_constant_modes = 0;
for (unsigned int f=0; f<fe_collection.size(); ++f)
{
for (unsigned int i=0; i<data.second.size(); ++i)
if (component_mask[data.second[i]])
constant_mode_to_component_translation[data.second[i]].
- push_back(std::make_pair(n_constant_modes++,i));
+ push_back(std::make_pair(n_constant_modes++,i));
AssertDimension(element_constant_modes.back().n_rows(),
element_constant_modes[0].n_rows());
}
if (component_mask[comp])
for (unsigned int j=0; j<constant_mode_to_component_translation[comp].size(); ++j)
constant_modes[constant_mode_to_component_translation[comp][j].first]
- [component_numbering[loc_index]] =
+ [component_numbering[loc_index]] =
element_constant_modes[cell->active_fe_index()]
(constant_mode_to_component_translation[comp][j].second,i);
}
// loop over the cells in the patch and get the DoFs on each.
// add all of them to a std::set which automatically makes sure
// all duplicates are ignored
- for(unsigned int i=0; i<patch.size(); ++i)
+ for (unsigned int i=0; i<patch.size(); ++i)
{
const typename DH::active_cell_iterator cell = patch[i];
Assert (cell->is_artificial() == false,
std::vector<types::global_dof_index>
get_dofs_on_patch (const std::vector<typename DH::active_cell_iterator> &patch)
{
- std::set<types::global_dof_index> dofs_on_patch;
- std::vector<types::global_dof_index> local_dof_indices;
+ std::set<types::global_dof_index> dofs_on_patch;
+ std::vector<types::global_dof_index> local_dof_indices;
- // loop over the cells in the patch and get the DoFs on each.
- // add all of them to a std::set which automatically makes sure
- // all duplicates are ignored
- for(unsigned int i=0; i<patch.size(); ++i)
- {
- const typename DH::active_cell_iterator cell = patch[i];
- Assert (cell->is_artificial() == false,
- ExcMessage("This function can not be called with cells that are "
- "not either locally owned or ghost cells."));
- local_dof_indices.resize (cell->get_fe().dofs_per_cell);
- cell->get_dof_indices (local_dof_indices);
- dofs_on_patch.insert (local_dof_indices.begin(),
- local_dof_indices.end());
- }
+ // loop over the cells in the patch and get the DoFs on each.
+ // add all of them to a std::set which automatically makes sure
+ // all duplicates are ignored
+ for (unsigned int i=0; i<patch.size(); ++i)
+ {
+ const typename DH::active_cell_iterator cell = patch[i];
+ Assert (cell->is_artificial() == false,
+ ExcMessage("This function can not be called with cells that are "
+ "not either locally owned or ghost cells."));
+ local_dof_indices.resize (cell->get_fe().dofs_per_cell);
+ cell->get_dof_indices (local_dof_indices);
+ dofs_on_patch.insert (local_dof_indices.begin(),
+ local_dof_indices.end());
+ }
Assert (dofs_on_patch.size() == count_dofs_on_patch<DH>(patch),
ExcInternalError());
(neighbor->subdomain_id() != cell->subdomain_id()))
{
constraints.add_entries_local_to_global
- (dofs_on_other_cell, dofs_on_this_cell,
- sparsity, keep_constrained_dofs);
+ (dofs_on_other_cell, dofs_on_this_cell,
+ sparsity, keep_constrained_dofs);
if (neighbor->subdomain_id() != cell->subdomain_id())
constraints.add_entries_local_to_global
(dofs_on_other_cell, sparsity, keep_constrained_dofs);
ExcIndexRange(face_index, 0, this->dofs_per_face));
Assert (face < GeometryInfo<dim>::faces_per_cell,
ExcIndexRange(face, 0, GeometryInfo<dim>::faces_per_cell));
-
+
//TODO: we could presumably solve the 3d case below using the
// adjust_quad_dof_index_for_face_orientation_table field. for the
// 2d case, we can't use adjust_line_dof_index_for_line_orientation_table
// DoFTools::make_periodicity_constraints, for example). so we
// would need to either fill this field, or rely on derived classes
// implementing this function, as we currently do
-
+
// see the function's documentation for an explanation of this
// assertion -- in essence, derived classes have to implement
// an overloaded version of this function if we are to use any
"Rather, the derived class you are using must provide "
"an overloaded version but apparently hasn't done so. See "
"the documentation of this function for more information."));
-
+
// we need to distinguish between DoFs on vertices, lines and in 3d quads.
// do so in a sequence of if-else statements
if (face_index < this->first_face_line_index)
// along with the number of the DoF on this vertex
const unsigned int face_vertex = face_index / this->dofs_per_vertex;
const unsigned int dof_index_on_vertex = face_index % this->dofs_per_vertex;
-
+
// then get the number of this vertex on the cell and translate
// this to a DoF number on the cell
return (GeometryInfo<dim>::face_to_cell_vertices(face, face_vertex,
// do the same kind of translation as before. we need to only consider
// DoFs on the lines, i.e., ignoring those on the vertices
const unsigned int index = face_index - this->first_face_line_index;
-
+
const unsigned int face_line = index / this->dofs_per_line;
const unsigned int dof_index_on_line = index % this->dofs_per_line;
-
+
return (this->first_line_index
+ GeometryInfo<dim>::face_to_cell_lines(face, face_line,
face_orientation,
// DoF is on a quad
{
Assert (dim >= 3, ExcInternalError());
-
+
// ignore vertex and line dofs
const unsigned int index = face_index - this->first_face_quad_index;
-
+
return (this->first_quad_index
+ face * this->dofs_per_quad
+ index);
}
}
-
-
-
-
+
+
+
+
template <int dim, int spacedim>
unsigned int
FiniteElement<dim,spacedim>::adjust_quad_dof_index_for_face_orientation (const unsigned int index,
{
Assert (false, ExcNotImplemented());
return std::pair<Table<2,bool>, std::vector<unsigned int> >
- (Table<2,bool>(this->n_components(), this->dofs_per_cell),
- std::vector<unsigned int>(this->n_components()));
+ (Table<2,bool>(this->n_components(), this->dofs_per_cell),
+ std::vector<unsigned int>(this->n_components()));
}
std::ostringstream namebuf;
namebuf << "FE_DGQ<"
- << Utilities::dim_string(dim,spacedim)
- << ">(" << this->degree << ")";
+ << Utilities::dim_string(dim,spacedim)
+ << ">(" << this->degree << ")";
return namebuf.str();
}
if (refinement_case == RefinementCase<dim>::isotropic_refinement)
{
std::vector<std::vector<FullMatrix<double> > >
- isotropic_matrices(RefinementCase<dim>::isotropic_refinement);
+ isotropic_matrices(RefinementCase<dim>::isotropic_refinement);
isotropic_matrices.back().
- resize(GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case)),
- FullMatrix<double>(this->dofs_per_cell, this->dofs_per_cell));
+ resize(GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case)),
+ FullMatrix<double>(this->dofs_per_cell, this->dofs_per_cell));
if (dim == spacedim)
FETools::compute_embedding_matrices (*this, isotropic_matrices, true);
else
if (refinement_case == RefinementCase<dim>::isotropic_refinement)
{
std::vector<std::vector<FullMatrix<double> > >
- isotropic_matrices(RefinementCase<dim>::isotropic_refinement);
+ isotropic_matrices(RefinementCase<dim>::isotropic_refinement);
isotropic_matrices.back().
- resize(GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case)),
- FullMatrix<double>(this->dofs_per_cell, this->dofs_per_cell));
+ resize(GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case)),
+ FullMatrix<double>(this->dofs_per_cell, this->dofs_per_cell));
if (dim == spacedim)
FETools::compute_projection_matrices (*this, isotropic_matrices, true);
else
FETools::compute_projection_matrices (FE_DGQ<dim>(this->degree),
- isotropic_matrices, true);
+ isotropic_matrices, true);
this_nonconst.restriction[refinement_case-1].swap(isotropic_matrices.back());
}
else
Table<2,bool> constant_modes(1, this->dofs_per_cell);
constant_modes.fill(true);
return std::pair<Table<2,bool>, std::vector<unsigned int> >
- (constant_modes, std::vector<unsigned int>(1, 0));
+ (constant_modes, std::vector<unsigned int>(1, 0));
}
const typename Triangulation<1,spacedim>::cell_iterator &,
const unsigned int ,
const unsigned int ,
- const Quadrature<0> & ,
+ const Quadrature<0> &,
typename Mapping<1,spacedim>::InternalDataBase &,
typename Mapping<1,spacedim>::InternalDataBase &,
FEValuesData<1,spacedim> &) const
// indices of the degrees of
// freedom.
if (dim == 3)
- {
- const unsigned int p = source_fe.degree;
- const unsigned int q = this->degree;
+ {
+ const unsigned int p = source_fe.degree;
+ const unsigned int q = this->degree;
- for (unsigned int i = 0; i <q; ++i)
- {
- for (int j = 1; j < (int) GeometryInfo<dim>::lines_per_face; ++j)
- interpolation_matrix (j * p + i,
- j * q + i) = 1.0;
+ for (unsigned int i = 0; i <q; ++i)
+ {
+ for (int j = 1; j < (int) GeometryInfo<dim>::lines_per_face; ++j)
+ interpolation_matrix (j * p + i,
+ j * q + i) = 1.0;
- for (unsigned int j = 0; j < q-1; ++j)
- {
- interpolation_matrix (GeometryInfo<dim>::lines_per_face * p + i * (p - 1) + j,
- GeometryInfo<dim>::lines_per_face * q + i * (q - 1) + j)
+ for (unsigned int j = 0; j < q-1; ++j)
+ {
+ interpolation_matrix (GeometryInfo<dim>::lines_per_face * p + i * (p - 1) + j,
+ GeometryInfo<dim>::lines_per_face * q + i * (q - 1) + j)
= 1.0;
- interpolation_matrix (GeometryInfo<dim>::lines_per_face * p + i + (j + p - 1) * p,
- GeometryInfo<dim>::lines_per_face * q + i + (j + q - 1) * q)
+ interpolation_matrix (GeometryInfo<dim>::lines_per_face * p + i + (j + p - 1) * p,
+ GeometryInfo<dim>::lines_per_face * q + i + (j + q - 1) * q)
= 1.0;
- }
- }
- }
+ }
+ }
+ }
}
// Restriction only for isotropic
// refinement
#ifdef DEBUG_NEDELEC
- deallog << "Embedding" << std::endl;
+ deallog << "Embedding" << std::endl;
#endif
this_nonconst.reinit_restriction_and_prolongation_matrices ();
// Fill prolongation matrices with embedding operators
FETools::compute_embedding_matrices (this_nonconst, this_nonconst.prolongation, true);
#ifdef DEBUG_NEDELEC
- deallog << "Restriction" << std::endl;
+ deallog << "Restriction" << std::endl;
#endif
this_nonconst.initialize_restriction ();
}
// Restriction only for isotropic
// refinement
#ifdef DEBUG_NEDELEC
- deallog << "Embedding" << std::endl;
+ deallog << "Embedding" << std::endl;
#endif
this_nonconst.reinit_restriction_and_prolongation_matrices ();
// Fill prolongation matrices with embedding operators
FETools::compute_embedding_matrices (this_nonconst, this_nonconst.prolongation, true);
#ifdef DEBUG_NEDELEC
- deallog << "Restriction" << std::endl;
+ deallog << "Restriction" << std::endl;
#endif
this_nonconst.initialize_restriction ();
}
for (unsigned int d=0; d<dim; ++d)
components.push_back(d);
return std::pair<Table<2,bool>, std::vector<unsigned int> >
- (constant_modes, components);
+ (constant_modes, components);
}
}
if (flags & update_hessians && cell_similarity != CellSimilarity::translation)
- this->compute_2nd (mapping, cell,
- typename QProjector<dim>::DataSetDescriptor().cell(),
- mapping_data, fe_data, data);
+ this->compute_2nd (mapping, cell,
+ typename QProjector<dim>::DataSetDescriptor().cell(),
+ mapping_data, fe_data, data);
}
}
if (flags & update_hessians)
- this->compute_2nd (mapping, cell, offset, mapping_data, fe_data, data);
+ this->compute_2nd (mapping, cell, offset, mapping_data, fe_data, data);
}
}
if (flags & update_hessians)
- this->compute_2nd (mapping, cell, offset, mapping_data, fe_data, data);
+ this->compute_2nd (mapping, cell, offset, mapping_data, fe_data, data);
}
AssertDimension(this->dofs_per_cell, Utilities::fixed_power<dim>(this->degree+1));
constant_modes.fill(true);
return std::pair<Table<2,bool>, std::vector<unsigned int> >
- (constant_modes, std::vector<unsigned int>(1, 0));
+ (constant_modes, std::vector<unsigned int>(1, 0));
}
}
if (type == true)
- namebuf << "FE_Q_DG0<"
- << Utilities::dim_string(dim,spacedim)
- << ">(" << this->degree << ")";
+ namebuf << "FE_Q_DG0<"
+ << Utilities::dim_string(dim,spacedim)
+ << ">(" << this->degree << ")";
else
{
break;
}
if (type == true)
- namebuf << "FE_Q_DG0<"
- << Utilities::dim_string(dim,spacedim)
- << ">(QGaussLobatto(" << this->degree+1 << "))";
+ namebuf << "FE_Q_DG0<"
+ << Utilities::dim_string(dim,spacedim)
+ << ">(QGaussLobatto(" << this->degree+1 << "))";
else
- namebuf << "FE_Q_DG0<"
- << Utilities::dim_string(dim,spacedim)
- << ">(QUnknownNodes(" << this->degree << "))";
+ namebuf << "FE_Q_DG0<"
+ << Utilities::dim_string(dim,spacedim)
+ << ">(QUnknownNodes(" << this->degree << "))";
}
return namebuf.str();
}
constant_modes(1, this->dofs_per_cell-1) = true;
return std::pair<Table<2,bool>, std::vector<unsigned int> >
- (constant_modes, std::vector<unsigned int> (2, 0));
+ (constant_modes, std::vector<unsigned int> (2, 0));
}
for (unsigned int i=GeometryInfo<dim>::vertices_per_cell; i<this->dofs_per_cell; ++i)
constant_modes(0,i) = false;
return std::pair<Table<2,bool>, std::vector<unsigned int> >
- (constant_modes, std::vector<unsigned int>(1, 0));
+ (constant_modes, std::vector<unsigned int>(1, 0));
}
// kept in synch
std::ostringstream namebuf;
- namebuf << "FE_Q_iso_Q1<"
- << Utilities::dim_string(dim,spacedim)
- << ">(" << this->degree << ")";
+ namebuf << "FE_Q_iso_Q1<"
+ << Utilities::dim_string(dim,spacedim)
+ << ">(" << this->degree << ")";
return namebuf.str();
}
for (unsigned int d=0; d<dim; ++d)
components.push_back(d);
return std::pair<Table<2,bool>, std::vector<unsigned int> >
- (constant_modes, components);
+ (constant_modes, components);
}
std::ostringstream namebuf;
- namebuf << "FESystem<"
- << Utilities::dim_string(dim,spacedim)
- << ">[";
+ namebuf << "FESystem<"
+ << Utilities::dim_string(dim,spacedim)
+ << ">[";
for (unsigned int i=0; i< this->n_base_elements(); ++i)
{
namebuf << base_element(i).get_name();
// to m==n==0 internally. this may happen when we use a FE_Nothing,
// so write the test in a more lenient way
Assert ((interpolation_matrix.m() == this->dofs_per_cell)
- ||
- (x_source_fe.dofs_per_cell == 0),
+ ||
+ (x_source_fe.dofs_per_cell == 0),
ExcDimensionMismatch (interpolation_matrix.m(),
this->dofs_per_cell));
Assert ((interpolation_matrix.n() == x_source_fe.dofs_per_cell)
- ||
- (this->dofs_per_cell == 0),
+ ||
+ (this->dofs_per_cell == 0),
ExcDimensionMismatch (interpolation_matrix.m(),
x_source_fe.dofs_per_cell));
for (unsigned int i=0; i<base_elements.size(); ++i)
{
std::pair<Table<2,bool>, std::vector<unsigned int> >
- base_table = base_elements[i].first->get_constant_modes();
+ base_table = base_elements[i].first->get_constant_modes();
AssertDimension(base_table.first.n_rows(), base_table.second.size());
const unsigned int element_multiplicity = this->element_multiplicity(i);
template <int dim>
void
- fill_no_codim_fe_names (std::map<std::string,std_cxx1x::shared_ptr<const Subscriptor> >& result)
+ fill_no_codim_fe_names (std::map<std::string,std_cxx1x::shared_ptr<const Subscriptor> > &result)
{
typedef std_cxx1x::shared_ptr<const Subscriptor> FEFactoryPointer;
// nonzero codimension.
template <int dim, int spacedim>
void
- fill_codim_fe_names (std::map<std::string,std_cxx1x::shared_ptr<const Subscriptor> >& result)
+ fill_codim_fe_names (std::map<std::string,std_cxx1x::shared_ptr<const Subscriptor> > &result)
{
typedef std_cxx1x::shared_ptr<const Subscriptor> FEFactoryPointer;
// through all legal dimension/spacedimension pairs and fills
// fe_name_map[dimension][spacedimension] with the maps generated
// by the functions above.
-std::vector<std::vector<
- std::map<std::string,
- std_cxx1x::shared_ptr<const Subscriptor> > > >
-fill_default_map()
-{
std::vector<std::vector<
+ std::map<std::string,
+ std_cxx1x::shared_ptr<const Subscriptor> > > >
+ fill_default_map()
+ {
+ std::vector<std::vector<
std::map<std::string,
- std_cxx1x::shared_ptr<const Subscriptor> > > >
- result(4);
-
- for (unsigned int d=0;d<4;++d)
- result[d].resize(4);
-
- fill_no_codim_fe_names<1> (result[1][1]);
- fill_no_codim_fe_names<2> (result[2][2]);
- fill_no_codim_fe_names<3> (result[3][3]);
-
- fill_codim_fe_names<1,2> (result[1][2]);
- fill_codim_fe_names<1,3> (result[1][3]);
- fill_codim_fe_names<2,3> (result[2][3]);
-
- return result;
-}
-
+ std_cxx1x::shared_ptr<const Subscriptor> > > >
+ result(4);
+
+ for (unsigned int d=0; d<4; ++d)
+ result[d].resize(4);
+
+ fill_no_codim_fe_names<1> (result[1][1]);
+ fill_no_codim_fe_names<2> (result[2][2]);
+ fill_no_codim_fe_names<3> (result[3][3]);
+
+ fill_codim_fe_names<1,2> (result[1][2]);
+ fill_codim_fe_names<1,3> (result[1][3]);
+ fill_codim_fe_names<2,3> (result[2][3]);
+
+ return result;
+ }
+
// have a lock that guarantees that at most one thread is changing
// and accessing the fe_name_map variable. make this lock local to
// each dimension and then separate between them further down
static
std::vector<std::vector<
- std::map<std::string,
- std_cxx1x::shared_ptr<const Subscriptor> > > >
- fe_name_map = fill_default_map();
+ std::map<std::string,
+ std_cxx1x::shared_ptr<const Subscriptor> > > >
+ fe_name_map = fill_default_map();
}
for (unsigned int m=0; m<element.element_multiplicity(b); ++m)
{
block_data[count++] = (return_start_indices)
- ? k
- : (element.base_element(b).n_dofs_per_cell());
+ ? k
+ : (element.base_element(b).n_dofs_per_cell());
k += element.base_element(b).n_dofs_per_cell();
}
Assert (count == element.n_blocks(), ExcInternalError());
for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
{
const unsigned int offset_c = GeometryInfo<dim>::face_to_cell_vertices(face_coarse, i)
- *fe.dofs_per_vertex;
+ *fe.dofs_per_vertex;
const unsigned int offset_f = GeometryInfo<dim>::face_to_cell_vertices(face_fine, i)
- *fe.dofs_per_vertex;
+ *fe.dofs_per_vertex;
for (unsigned int j=0; j<fe.dofs_per_vertex; ++j)
{
face_c_dofs[face_dof] = offset_c + j;
for (unsigned int i=1; i<=GeometryInfo<dim>::lines_per_face; ++i)
{
const unsigned int offset_c = fe.first_line_index
- + GeometryInfo<dim>::face_to_cell_lines(face_coarse, i-1)
- *fe.dofs_per_line;
+ + GeometryInfo<dim>::face_to_cell_lines(face_coarse, i-1)
+ *fe.dofs_per_line;
const unsigned int offset_f = fe.first_line_index
- + GeometryInfo<dim>::face_to_cell_lines(face_fine, i-1)
- *fe.dofs_per_line;
+ + GeometryInfo<dim>::face_to_cell_lines(face_fine, i-1)
+ *fe.dofs_per_line;
for (unsigned int j=0; j<fe.dofs_per_line; ++j)
{
face_c_dofs[face_dof] = offset_c + j;
for (unsigned int i=1; i<=GeometryInfo<dim>::quads_per_face; ++i)
{
const unsigned int offset_c = fe.first_quad_index
- + face_coarse
- *fe.dofs_per_quad;
+ + face_coarse
+ *fe.dofs_per_quad;
const unsigned int offset_f = fe.first_quad_index
- + face_fine
- *fe.dofs_per_quad;
+ + face_fine
+ *fe.dofs_per_quad;
for (unsigned int j=0; j<fe.dofs_per_quad; ++j)
{
face_c_dofs[face_dof] = offset_c + j;
// argument, which defaults to 1,
// so this properly returns
// FE_Nothing()
- const Subscriptor* ptr = fe_name_map.find(name_part)->second.get();
- const FEFactoryBase<dim,spacedim>* fef=dynamic_cast<const FEFactoryBase<dim,spacedim>*>(ptr);
+ const Subscriptor *ptr = fe_name_map.find(name_part)->second.get();
+ const FEFactoryBase<dim,spacedim> *fef=dynamic_cast<const FEFactoryBase<dim,spacedim>*>(ptr);
return fef->get(1);
}
else
const std::pair<int,unsigned int> tmp
= Utilities::get_integer_at_position (name, 0);
name.erase(0, tmp.second+1);
- const Subscriptor* ptr = fe_name_map.find(name_part)->second.get();
- const FEFactoryBase<dim,spacedim>* fef=dynamic_cast<const FEFactoryBase<dim,spacedim>*>(ptr);
- return fef->get(tmp.first);
+ const Subscriptor *ptr = fe_name_map.find(name_part)->second.get();
+ const FEFactoryBase<dim,spacedim> *fef=dynamic_cast<const FEFactoryBase<dim,spacedim>*>(ptr);
+ return fef->get(tmp.first);
}
else
{
= Utilities::get_integer_at_position (name, 0);
// delete "))"
name.erase(0, tmp.second+2);
- const Subscriptor* ptr = fe_name_map.find(name_part)->second.get();
- const FEFactoryBase<dim,spacedim>* fef=dynamic_cast<const FEFactoryBase<dim,spacedim>*>(ptr);
- return fef->get(QGaussLobatto<1>(tmp.first));
+ const Subscriptor *ptr = fe_name_map.find(name_part)->second.get();
+ const FEFactoryBase<dim,spacedim> *fef=dynamic_cast<const FEFactoryBase<dim,spacedim>*>(ptr);
+ return fef->get(QGaussLobatto<1>(tmp.first));
}
else
{
template <int dim,int spacedim>
FiniteElement<dim,spacedim> *get_fe_from_name (std::string &name)
{
- return get_fe_from_name_ext<dim,spacedim> (name, fe_name_map[dim][spacedim]);
+ return get_fe_from_name_ext<dim,spacedim> (name, fe_name_map[dim][spacedim]);
}
}
}
{
return get_fe_by_name<dim,dim> (parameter_name);
}
-
+
template <int dim, int spacedim>
void
template <int dim>
void
- hierarchic_to_lexicographic_numbering (unsigned int degree, std::vector<unsigned int>& h2l)
+ hierarchic_to_lexicographic_numbering (unsigned int degree, std::vector<unsigned int> &h2l)
{
// number of support points in each
// direction
const unsigned int n = degree+1;
unsigned int dofs_per_cell = n;
- for (unsigned int i=1;i<dim;++i)
+ for (unsigned int i=1; i<dim; ++i)
dofs_per_cell *= n;
// Assert size maches degree
// we're in 2d, so the formula for the curl is simple:
if (shape_function_data[shape_function].single_nonzero_component_index == 0)
for (unsigned int q_point = 0;
- q_point < n_quadrature_points; ++q_point)
+ q_point < n_quadrature_points; ++q_point)
curls[q_point][0] -= value * (*shape_gradient_ptr++)[1];
else
for (unsigned int q_point = 0;
- q_point < n_quadrature_points; ++q_point)
+ q_point < n_quadrature_points; ++q_point)
curls[q_point][0] += value * (*shape_gradient_ptr++)[0];
}
else
const unsigned int dofs_per_cell = fe.dofs_per_cell;
if (dofs_per_cell == 0)
return;
-
+
const unsigned int n_quadrature_points = shape_values.n_cols();
const unsigned int n_components = fe.n_components();
void hyper_cube (Triangulation<dim,spacedim> &tria,
const double left,
const double right,
- const bool colorize)
+ const bool colorize)
{
Assert (left < right,
ExcMessage ("Invalid left-to-right bounds of hypercube"));
SubCellData subcell_data;
std::vector<unsigned int> considered_vertices;
GridTools::delete_duplicated_vertices (vertices, cells,
- subcell_data,
- considered_vertices);
+ subcell_data,
+ considered_vertices);
// reorder the cells to ensure that they satisfy the convention for
// edge and face directions
// fill these maps using the data
// given by new_points
typename DoFHandler<dim>::cell_iterator cell=dof_handler.begin_active(),
- endc=dof_handler.end();
+ endc=dof_handler.end();
for (; cell!=endc; ++cell)
{
for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
// loop over all vertices of the cell and see if it is listed in the map
// given as first argument of the function
for (unsigned int vertex_no=0;
- vertex_no<GeometryInfo<dim>::vertices_per_face; ++vertex_no)
+ vertex_no<GeometryInfo<dim>::vertices_per_face; ++vertex_no)
{
const unsigned int vertex_index=face->vertex_index(vertex_no);
const typename std::map<unsigned int,Point<dim> >::const_iterator map_iter
- = new_points.find(vertex_index);
+ = new_points.find(vertex_index);
if (map_iter!=map_end)
for (unsigned int i=0; i<dim; ++i)
m[i].insert(std::pair<unsigned int,double> (
- face->vertex_dof_index(vertex_no, 0), map_iter->second(i)));
+ face->vertex_dof_index(vertex_no, 0), map_iter->second(i)));
}
}
}
}
}
}
-
+
template <int dim, int spacedim1, int spacedim2>
void flatten_triangulation(const Triangulation<dim, spacedim1> &in_tria,
- Triangulation<dim,spacedim2> &out_tria)
+ Triangulation<dim,spacedim2> &out_tria)
{
- const parallel::distributed::Triangulation<dim, spacedim1> * pt =
+ const parallel::distributed::Triangulation<dim, spacedim1> *pt =
dynamic_cast<const parallel::distributed::Triangulation<dim, spacedim1> *>(&in_tria);
-
- Assert (pt == NULL,
- ExcMessage("Cannot use this function on parallel::distributed::Triangulation."));
+
+ Assert (pt == NULL,
+ ExcMessage("Cannot use this function on parallel::distributed::Triangulation."));
std::vector<Point<spacedim2> > v;
std::vector<CellData<dim> > cells;
SubCellData subcelldata;
-
+
const unsigned int spacedim = std::min(spacedim1,spacedim2);
const std::vector<Point<spacedim1> > &in_vertices = in_tria.get_vertices();
-
+
v.resize(in_vertices.size());
- for(unsigned int i=0; i<in_vertices.size(); ++i)
- for(unsigned int d=0; d<spacedim; ++d)
- v[i][d] = in_vertices[i][d];
+ for (unsigned int i=0; i<in_vertices.size(); ++i)
+ for (unsigned int d=0; d<spacedim; ++d)
+ v[i][d] = in_vertices[i][d];
cells.resize(in_tria.n_active_cells());
- typename Triangulation<dim,spacedim1>::active_cell_iterator
- cell = in_tria.begin_active(),
- endc = in_tria.end();
-
- for(unsigned int id=0; cell != endc; ++cell, ++id)
+ typename Triangulation<dim,spacedim1>::active_cell_iterator
+ cell = in_tria.begin_active(),
+ endc = in_tria.end();
+
+ for (unsigned int id=0; cell != endc; ++cell, ++id)
{
- for(unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- cells[id].vertices[i] = cell->vertex_index(i);
- cells[id].material_id = cell->material_id();
- cells[id].manifold_id = cell->manifold_id();
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ cells[id].vertices[i] = cell->vertex_index(i);
+ cells[id].material_id = cell->material_id();
+ cells[id].manifold_id = cell->manifold_id();
}
- if(dim>1) {
- typename Triangulation<dim,spacedim1>::active_face_iterator
- face = in_tria.begin_active_face(),
- endf = in_tria.end_face();
-
- // Face counter for both dim == 2 and dim == 3
- unsigned int f=0;
- switch(dim) {
- case 2:
- {
- subcelldata.boundary_lines.resize(in_tria.n_active_faces());
- for(; face != endf; ++face)
- if(face->at_boundary())
- {
- for(unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
- subcelldata.boundary_lines[f].vertices[i] = face->vertex_index(i);
- subcelldata.boundary_lines[f].boundary_id = face->boundary_indicator();
- subcelldata.boundary_lines[f].manifold_id = face->manifold_id();
- ++f;
- }
- subcelldata.boundary_lines.resize(f);
- }
- break;
- case 3:
- {
- subcelldata.boundary_quads.resize(in_tria.n_active_faces());
- for(; face != endf; ++face)
- if(face->at_boundary())
- {
- for(unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
- subcelldata.boundary_quads[f].vertices[i] = face->vertex_index(i);
- subcelldata.boundary_quads[f].boundary_id = face->boundary_indicator();
- subcelldata.boundary_quads[f].manifold_id = face->manifold_id();
- ++f;
- }
- subcelldata.boundary_quads.resize(f);
- }
- break;
- default:
- Assert(false, ExcInternalError());
+ if (dim>1)
+ {
+ typename Triangulation<dim,spacedim1>::active_face_iterator
+ face = in_tria.begin_active_face(),
+ endf = in_tria.end_face();
+
+ // Face counter for both dim == 2 and dim == 3
+ unsigned int f=0;
+ switch (dim)
+ {
+ case 2:
+ {
+ subcelldata.boundary_lines.resize(in_tria.n_active_faces());
+ for (; face != endf; ++face)
+ if (face->at_boundary())
+ {
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
+ subcelldata.boundary_lines[f].vertices[i] = face->vertex_index(i);
+ subcelldata.boundary_lines[f].boundary_id = face->boundary_indicator();
+ subcelldata.boundary_lines[f].manifold_id = face->manifold_id();
+ ++f;
+ }
+ subcelldata.boundary_lines.resize(f);
+ }
+ break;
+ case 3:
+ {
+ subcelldata.boundary_quads.resize(in_tria.n_active_faces());
+ for (; face != endf; ++face)
+ if (face->at_boundary())
+ {
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
+ subcelldata.boundary_quads[f].vertices[i] = face->vertex_index(i);
+ subcelldata.boundary_quads[f].boundary_id = face->boundary_indicator();
+ subcelldata.boundary_quads[f].manifold_id = face->manifold_id();
+ ++f;
+ }
+ subcelldata.boundary_quads.resize(f);
+ }
+ break;
+ default:
+ Assert(false, ExcInternalError());
+ }
}
- }
out_tria.create_triangulation(v, cells, subcelldata);
}
// This anonymous namespace contains utility functions to extract the
// triangulation from any container such as DoFHandler
// and the like
- namespace
+ namespace
+ {
+ template<int dim, int spacedim>
+ const Triangulation<dim, spacedim> &
+ get_tria(const Triangulation<dim, spacedim> &tria)
{
- template<int dim, int spacedim>
- const Triangulation<dim, spacedim> &
- get_tria(const Triangulation<dim, spacedim> &tria)
- {
- return tria;
- }
+ return tria;
+ }
- template<int dim, int spacedim>
- const Triangulation<dim, spacedim> &
- get_tria(const parallel::distributed::Triangulation<dim, spacedim> &tria)
- {
- return tria;
- }
+ template<int dim, int spacedim>
+ const Triangulation<dim, spacedim> &
+ get_tria(const parallel::distributed::Triangulation<dim, spacedim> &tria)
+ {
+ return tria;
+ }
- template<int dim, template<int, int> class Container, int spacedim>
- const Triangulation<dim,spacedim> &
- get_tria(const Container<dim,spacedim> &container)
- {
- return container.get_tria();
- }
+ template<int dim, template<int, int> class Container, int spacedim>
+ const Triangulation<dim,spacedim> &
+ get_tria(const Container<dim,spacedim> &container)
+ {
+ return container.get_tria();
+ }
- template<int dim, int spacedim>
- Triangulation<dim, spacedim> &
- get_tria(Triangulation<dim, spacedim> &tria)
- {
- return tria;
- }
+ template<int dim, int spacedim>
+ Triangulation<dim, spacedim> &
+ get_tria(Triangulation<dim, spacedim> &tria)
+ {
+ return tria;
+ }
- template<int dim, int spacedim>
- Triangulation<dim, spacedim> &
- get_tria(parallel::distributed::Triangulation<dim, spacedim> &tria)
- {
- return tria;
- }
+ template<int dim, int spacedim>
+ Triangulation<dim, spacedim> &
+ get_tria(parallel::distributed::Triangulation<dim, spacedim> &tria)
+ {
+ return tria;
+ }
- template<int dim, template<int, int> class Container, int spacedim>
- const Triangulation<dim,spacedim> &
- get_tria(Container<dim,spacedim> &container)
- {
- return container.get_tria();
- }
+ template<int dim, template<int, int> class Container, int spacedim>
+ const Triangulation<dim,spacedim> &
+ get_tria(Container<dim,spacedim> &container)
+ {
+ return container.get_tria();
}
+ }
bool changed = false;
for (typename Container<dim-1,spacedim>::active_cell_iterator
- cell = surface_mesh.begin_active(); cell!=surface_mesh.end(); ++cell)
+ cell = surface_mesh.begin_active(); cell!=surface_mesh.end(); ++cell)
if (surface_to_volume_mapping[cell]->has_children() == true )
{
cell->set_refine_flag ();
.execute_coarsening_and_refinement();
for (typename Container<dim-1,spacedim>::cell_iterator
- surface_cell = surface_mesh.begin(); surface_cell!=surface_mesh.end(); ++surface_cell)
+ surface_cell = surface_mesh.begin(); surface_cell!=surface_mesh.end(); ++surface_cell)
for (unsigned int c=0; c<surface_cell->n_children(); c++)
if (surface_to_volume_mapping.find(surface_cell->child(c)) == surface_to_volume_mapping.end())
surface_to_volume_mapping[surface_cell->child(c)]
// expectations. the second line of the file may essentially be
// anything the author of the file chose to identify what's in
// there, so we just ensure that we can read it
- {
+ {
std::string text[4];
text[0] = "# vtk DataFile Version 3.0";
text[1] = "****";
text[3] = "DATASET UNSTRUCTURED_GRID";
for (unsigned int i = 0; i < 4; ++i)
- {
- getline(in,line);
- if (i != 1)
- AssertThrow (line.compare(text[i]) == 0,
- ExcMessage(std::string("While reading VTK file, failed to find a header line with text <") +
- text[i] + ">"));
- }
+ {
+ getline(in,line);
+ if (i != 1)
+ AssertThrow (line.compare(text[i]) == 0,
+ ExcMessage(std::string("While reading VTK file, failed to find a header line with text <") +
+ text[i] + ">"));
+ }
}
///////////////////Declaring storage and mappings//////////////////
{
getline(in, linenew);
if (i == 0)
- if (linenew.size() > textnew[0].size())
- linenew.resize(textnew[0].size());
+ if (linenew.size() > textnew[0].size())
+ linenew.resize(textnew[0].size());
- AssertThrow (linenew.compare(textnew[i]) == 0,
- ExcMessage (std::string("While reading VTK file, failed to find <") +
- textnew[i] + "> section"));
+ AssertThrow (linenew.compare(textnew[i]) == 0,
+ ExcMessage (std::string("While reading VTK file, failed to find <") +
+ textnew[i] + "> section"));
}
for (unsigned int i = 0; i < no_cells; i++) //assigning IDs to cells.
const bool label_subdomain_id,
const bool draw_colorbar,
const bool draw_legend)
- :
- height(1000),
- width(0),
- line_thickness(line_thickness),
- boundary_line_thickness(boundary_line_thickness),
- margin(margin),
- background(background),
- azimuth_angle(azimuth_angle),
- polar_angle(polar_angle),
- coloring(coloring),
- convert_level_number_to_height(convert_level_number_to_height),
- level_height_factor(0.3f),
- label_level_number(label_level_number),
- label_cell_index(label_cell_index),
- label_material_id(label_material_id),
- label_subdomain_id(label_subdomain_id),
- label_level_subdomain_id(false),
- draw_colorbar(draw_colorbar),
- draw_legend(draw_legend)
+ :
+ height(1000),
+ width(0),
+ line_thickness(line_thickness),
+ boundary_line_thickness(boundary_line_thickness),
+ margin(margin),
+ background(background),
+ azimuth_angle(azimuth_angle),
+ polar_angle(polar_angle),
+ coloring(coloring),
+ convert_level_number_to_height(convert_level_number_to_height),
+ level_height_factor(0.3f),
+ label_level_number(label_level_number),
+ label_cell_index(label_cell_index),
+ label_material_id(label_material_id),
+ label_subdomain_id(label_subdomain_id),
+ label_level_subdomain_id(false),
+ draw_colorbar(draw_colorbar),
+ draw_legend(draw_legend)
{}
MathGL::MathGL ()
for (unsigned int level_index = min_level; level_index <= max_level; level_index++)
{
Triangulation<2,2>::cell_iterator
- cell = tria.begin(level_index),
- endc = tria.end(level_index);
+ cell = tria.begin(level_index),
+ endc = tria.end(level_index);
for (; cell != endc; ++cell)
{
// convert each of the active cells into a patch
for (typename Triangulation<dim,spacedim>::active_cell_iterator cell = triangulation.begin_active();
- cell != triangulation.end(); ++cell)
+ cell != triangulation.end(); ++cell)
{
DataOutBase::Patch<dim,spacedim> patch;
patch.n_subdivisions = 1;
template <int dim, int spacedim>
void GridOut::write_vtk (const Triangulation<dim,spacedim> &tria,
- std::ostream &out) const
+ std::ostream &out) const
{
AssertThrow (out, ExcIO ());
case 2:
{
for (typename dealii::Triangulation<dim, spacedim>::active_cell_iterator
- cell=tria.begin_active();
- cell!=tria.end(); ++cell)
+ cell=tria.begin_active();
+ cell!=tria.end(); ++cell)
for (unsigned int line_no=0;
line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
{
// generate the info from
// them
for (typename dealii::Triangulation<dim, spacedim>::active_cell_iterator
- cell=tria.begin_active();
- cell!=tria.end(); ++cell)
+ cell=tria.begin_active();
+ cell!=tria.end(); ++cell)
for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
{
const typename dealii::Triangulation<dim, spacedim>::face_iterator
// Find closest vertex and determine
// all adjacent cells
std::vector<active_cell_iterator> adjacent_cells_tmp
- = find_cells_adjacent_to_vertex(container,
- find_closest_vertex(container, p));
+ = find_cells_adjacent_to_vertex(container,
+ find_closest_vertex(container, p));
// Make sure that we have found
// at least one cell adjacent to vertex.
get_patch_around_cell(const typename Container::active_cell_iterator &cell)
{
Assert (cell->is_locally_owned(),
- ExcMessage ("This function only makes sense if the cell for "
- "which you are asking for a patch, is locally "
- "owned."));
-
+ ExcMessage ("This function only makes sense if the cell for "
+ "which you are asking for a patch, is locally "
+ "owned."));
+
std::vector<typename Container::active_cell_iterator> patch;
patch.push_back (cell);
for (unsigned int face_number=0; face_number<GeometryInfo<Container::dimension>::faces_per_cell; ++face_number)
// in 1d, we need to work a bit harder: iterate until we find
// the child by going from cell to child to child etc
typename Container::cell_iterator neighbor
- = cell->neighbor (face_number);
+ = cell->neighbor (face_number);
while (neighbor->has_children())
neighbor = neighbor->child(1-face_number);
// volume relative to |v01|*|v02|*|v03|. the test checks the
// squares of these to avoid taking norms/square roots:
if (std::abs((v03 * normal) * (v03 * normal) /
- (v03.square() * v01.square() * v02.square()))
- >=
- 1e-24)
+ (v03.square() * v01.square() * v02.square()))
+ >=
+ 1e-24)
{
- Assert (false,
- ExcMessage("Computing the measure of a nonplanar face is not implemented!"));
- return std::numeric_limits<double>::quiet_NaN();
+ Assert (false,
+ ExcMessage("Computing the measure of a nonplanar face is not implemented!"));
+ return std::numeric_limits<double>::quiet_NaN();
}
// the face is planar. then its area is 1/2 of the norm of the
}
-
+
template <int structdim, int dim, int spacedim>
double
measure (const TriaAccessor<structdim, dim, spacedim> &)
IteratorRange<typename DoFHandler<dim, spacedim>::active_cell_iterator>
(begin_active(level), end_active(level));
}
-
+
for (; cell != endc; ++cell)
next_free_dof
= dealii::internal::hp::DoFHandler::Implementation::distribute_dofs_on_cell<spacedim> (cell,
- next_free_dof);
+ next_free_dof);
number_cache.n_global_dofs = next_free_dof;
}
// checking whether it has children now but didn't have
// children before refinement (the has_children array is
// set in pre-refinement action)
- //
+ //
// Note: Although one level is added to
// the DoFHandler levels, when the
// triangulation got one, for the buffer
// allowed for inactive cells, but we can access this
// information from the DoFLevels directly
for (unsigned int i = 0; i < cell->n_children(); ++i)
- cell->child (i)->set_active_fe_index
- (levels[cell->level()]->active_fe_index (cell->index()));
+ cell->child (i)->set_active_fe_index
+ (levels[cell->level()]->active_fe_index (cell->index()));
}
}
}
template <typename number>
LAPACKFullMatrix<number>::LAPACKFullMatrix (const size_type m,
- const size_type n)
+ const size_type n)
:
TransposeTable<number> (m, n),
state (matrix)
template <typename number>
void
LAPACKFullMatrix<number>::reinit (const size_type m,
- const size_type n)
+ const size_type n)
{
this->TransposeTable<number>::reinit (m, n);
state = LAPACKSupport::matrix;
template <typename number>
void
LAPACKFullMatrix<number>::compute_eigenvalues(const bool right,
- const bool left)
+ const bool left)
{
Assert(state == matrix, ExcState(state));
const int nn = this->n_cols();
template <typename number>
void
LAPACKFullMatrix<number>::compute_eigenvalues_symmetric(const number lower_bound,
- const number upper_bound,
- const number abs_accuracy,
- Vector<number> &eigenvalues,
- FullMatrix<number> &eigenvectors)
+ const number upper_bound,
+ const number abs_accuracy,
+ Vector<number> &eigenvalues,
+ FullMatrix<number> &eigenvectors)
{
Assert(state == matrix, ExcState(state));
const int nn = (this->n_cols() > 0 ? this->n_cols() : 1);
void
FullMatrix::reinit (const size_type m,
- const size_type n)
+ const size_type n)
{
// get rid of old matrix and generate a
// new one
void
FullMatrix::do_reinit (const size_type m,
- const size_type n)
+ const size_type n)
{
// use the call sequence indicating only a maximal number of
// elements per row for all rows globally
const int ierr
= MatCreateSeqDense (PETSC_COMM_SELF, m, n, PETSC_NULL,
- &matrix);
+ &matrix);
AssertThrow (ierr == 0, ExcPETScError(ierr));
}
#if DEBUG
{
- // test ghost allocation in debug mode
- PetscInt begin, end;
+ // test ghost allocation in debug mode
+ PetscInt begin, end;
- ierr = VecGetOwnershipRange (vector, &begin, &end);
+ ierr = VecGetOwnershipRange (vector, &begin, &end);
- Assert(local_size==(size_type)(end-begin), ExcInternalError());
+ Assert(local_size==(size_type)(end-begin), ExcInternalError());
- Vec l;
- ierr = VecGhostGetLocalForm(vector, &l);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ Vec l;
+ ierr = VecGhostGetLocalForm(vector, &l);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
- PetscInt lsize;
- ierr = VecGetSize(l, &lsize);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ PetscInt lsize;
+ ierr = VecGetSize(l, &lsize);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
- ierr = VecGhostRestoreLocalForm(vector, &l);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = VecGhostRestoreLocalForm(vector, &l);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
- Assert (lsize==end-begin+(PetscInt)ghost_indices.n_elements(),
- ExcInternalError());
+ Assert (lsize==end-begin+(PetscInt)ghost_indices.n_elements(),
+ ExcInternalError());
}
#endif
{
unsigned int has_nonzero = VectorBase::all_zero()?0:1;
#ifdef DEAL_II_WITH_MPI
- // in parallel, check that the vector
- // is zero on _all_ processors.
- unsigned int num_nonzero = Utilities::MPI::sum(has_nonzero, communicator);
- return num_nonzero == 0;
+ // in parallel, check that the vector
+ // is zero on _all_ processors.
+ unsigned int num_nonzero = Utilities::MPI::sum(has_nonzero, communicator);
+ return num_nonzero == 0;
#else
- return has_nonzero == 0;
+ return has_nonzero == 0;
#endif
}
const unsigned int smoother_sweeps,
const unsigned int smoother_overlap,
const bool output_details,
- const char* smoother_type,
- const char* coarse_type)
+ const char *smoother_type,
+ const char *coarse_type)
:
elliptic (elliptic),
higher_order_elements (higher_order_elements),
AssertThrow(
Factory.Query(additional_data.solver_type.c_str()),
ExcMessage (std::string ("You tried to select the solver type <") +
- additional_data.solver_type +
- "> but this solver is not supported by Trilinos either "
- "because it does not exist, or because Trilinos was not "
- "configured for its use.")
+ additional_data.solver_type +
+ "> but this solver is not supported by Trilinos either "
+ "because it does not exist, or because Trilinos was not "
+ "configured for its use.")
);
solver.reset (
nonlocal_matrix->FillComplete(*column_space_map, matrix->RowMap());
if (nonlocal_matrix_exporter.get() == 0)
nonlocal_matrix_exporter.reset
- (new Epetra_Export(nonlocal_matrix->RowMap(), matrix->RowMap()));
+ (new Epetra_Export(nonlocal_matrix->RowMap(), matrix->RowMap()));
ierr = matrix->Export(*nonlocal_matrix, *nonlocal_matrix_exporter, mode);
AssertThrow(ierr == 0, ExcTrilinosError(ierr));
ierr = matrix->FillComplete(*column_space_map, matrix->RowMap());
#if DEAL_II_TRILINOS_VERSION_GTE(11,9,0)
, true
#endif
- ));
+ ));
else
graph.reset (new Epetra_FECrsGraph(Copy, input_row_map, input_col_map,
n_entries_per_row, false));
#if DEAL_II_TRILINOS_VERSION_GTE(11,9,0)
, true
#endif
- ));
+ ));
else
graph.reset(new Epetra_FECrsGraph(Copy, input_row_map, input_col_map,
n_entries_per_row[max_my_gid(input_row_map)],
{
// insert dummy element
TrilinosWrappers::types::int_type row = nonlocal_graph->RowMap().MyGID(
- static_cast<TrilinosWrappers::types::int_type> (0));
+ static_cast<TrilinosWrappers::types::int_type> (0));
nonlocal_graph->InsertGlobalIndices(row, 1, &row);
}
Assert(nonlocal_graph->IndicesAreGlobal() == true,
if (v.nonlocal_vector.get() != 0)
nonlocal_vector.reset(new Epetra_MultiVector(v.nonlocal_vector->Map(), 1));
-
+
return *this;
}
ExcDimensionMismatch (size(), v.size()));
#if DEAL_II_TRILINOS_VERSION_GTE(11,11,0)
- Epetra_Import data_exchange (vector->Map(), v.vector->Map());
- int ierr = vector->Import(*v.vector, data_exchange, Epetra_AddLocalAlso);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- last_action = Add;
+ Epetra_Import data_exchange (vector->Map(), v.vector->Map());
+ int ierr = vector->Import(*v.vector, data_exchange, Epetra_AddLocalAlso);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+ last_action = Add;
#else
// In versions older than 11.11 the Import function is broken for adding
// Hence, we provide a workaround in this case
nfe.first_block_of_base(base) + mult) != DoFTools::none)
{
const unsigned int dof_increment = nfe.base_element(base).dofs_per_cell
- - nfe.base_element(base).dofs_per_face;
+ - nfe.base_element(base).dofs_per_face;
row_lengths[cell_indices[local_dof]] += dof_increment;
}
}
}
-
+
template <int dim, int spacedim>
void
extract_inner_interface_dofs (const DoFHandler<dim,spacedim> &mg_dof_handler,
{
std::vector<IndexSet> temp;
temp.resize(interface_dofs.size());
- for (unsigned int l=0;l<interface_dofs.size();++l)
+ for (unsigned int l=0; l<interface_dofs.size(); ++l)
temp[l] = IndexSet(interface_dofs[l].size());
extract_inner_interface_dofs(mg_dof_handler, temp);
- for (unsigned int l=0;l<interface_dofs.size();++l)
+ for (unsigned int l=0; l<interface_dofs.size(); ++l)
{
Assert (interface_dofs[l].size() == mg_dof_handler.n_dofs(l),
ExcDimensionMismatch (interface_dofs[l].size(),
mg_dof_handler.get_tria().n_global_levels()));
std::vector<std::vector<types::global_dof_index> >
- tmp_interface_dofs(interface_dofs.size());
+ tmp_interface_dofs(interface_dofs.size());
const FiniteElement<dim,spacedim> &fe = mg_dof_handler.get_fe();
if (has_coarser_neighbor == false)
continue;
-
+
const unsigned int level = cell->level();
cell->get_mg_dof_indices (local_dof_indices);
{
// in the rare case that someone has a DGP(0) attached, we can not decide what she wants here:
Assert((dofs == 0) || (triangulation->n_active_cells() != dofs->n_dofs()),
- ExcMessage("Unable to determine the type of vector automatically because the number of DoFs "
- "is equal to the number of cells. Please specify DataVectorType."));
+ ExcMessage("Unable to determine the type of vector automatically because the number of DoFs "
+ "is equal to the number of cells. Please specify DataVectorType."));
if (vec.size() == triangulation->n_active_cells())
actual_type = type_cell_data;
surface_only(so)
{
Assert (dim == DH::dimension,
- ExcNotImplemented());
+ ExcNotImplemented());
}
for (unsigned int i=0; i<=n_patches_per_circle; ++i)
{
angle_directions[i][dimension-1] = std::cos(2*numbers::PI *
- i/n_patches_per_circle);
+ i/n_patches_per_circle);
angle_directions[i][dimension] = std::sin(2*numbers::PI *
- i/n_patches_per_circle);
+ i/n_patches_per_circle);
}
for (unsigned int angle=0; angle<n_patches_per_circle; ++angle)
template <int dim>
class Gradient
{
- public:
- /**
- * Declare which data fields have to be updated for the function @p
- * get_projected_derivative to work.
- */
- static const UpdateFlags update_flags;
-
- /**
- * Declare the data type which holds the derivative described by this
- * class.
- */
- typedef Tensor<1,dim> Derivative;
-
- /**
- * Likewise declare the data type that holds the derivative projected to a
- * certain directions.
- */
- typedef double ProjectedDerivative;
-
- /**
- * Given an FEValues object initialized to a cell, and a solution vector,
- * extract the desired derivative at the first quadrature point (which is
- * the only one, as we only evaluate the finite element field at the
- * center of each cell).
- */
- template <class InputVector, int spacedim>
- static ProjectedDerivative
- get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component);
-
- /**
- * Return the norm of the derivative object. Here, for the gradient, we
- * choose the Euclidian norm of the gradient vector.
- */
- static double derivative_norm (const Derivative &d);
-
- /**
- * If for the present derivative order, symmetrization of the derivative
- * tensor is necessary, then do so on the argument.
- *
- * For the first derivatives, no such thing is necessary, so this function
- * is a no-op.
- */
- static void symmetrize (Derivative &derivative_tensor);
+ public:
+ /**
+ * Declare which data fields have to be updated for the function @p
+ * get_projected_derivative to work.
+ */
+ static const UpdateFlags update_flags;
+
+ /**
+ * Declare the data type which holds the derivative described by this
+ * class.
+ */
+ typedef Tensor<1,dim> Derivative;
+
+ /**
+ * Likewise declare the data type that holds the derivative projected to a
+ * certain directions.
+ */
+ typedef double ProjectedDerivative;
+
+ /**
+ * Given an FEValues object initialized to a cell, and a solution vector,
+ * extract the desired derivative at the first quadrature point (which is
+ * the only one, as we only evaluate the finite element field at the
+ * center of each cell).
+ */
+ template <class InputVector, int spacedim>
+ static ProjectedDerivative
+ get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
+ const InputVector &solution,
+ const unsigned int component);
+
+ /**
+ * Return the norm of the derivative object. Here, for the gradient, we
+ * choose the Euclidian norm of the gradient vector.
+ */
+ static double derivative_norm (const Derivative &d);
+
+ /**
+ * If for the present derivative order, symmetrization of the derivative
+ * tensor is necessary, then do so on the argument.
+ *
+ * For the first derivatives, no such thing is necessary, so this function
+ * is a no-op.
+ */
+ static void symmetrize (Derivative &derivative_tensor);
};
// static variables
typename Gradient<dim>::ProjectedDerivative
Gradient<dim>::
get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component)
+ const InputVector &solution,
+ const unsigned int component)
+ {
+ if (fe_values.get_fe().n_components() == 1)
{
- if (fe_values.get_fe().n_components() == 1)
- {
- std::vector<ProjectedDerivative> values (1);
- fe_values.get_function_values (solution, values);
- return values[0];
- }
- else
- {
- std::vector<Vector<double> > values
- (1, Vector<double>(fe_values.get_fe().n_components()));
- fe_values.get_function_values (solution, values);
- return values[0](component);
- }
+ std::vector<ProjectedDerivative> values (1);
+ fe_values.get_function_values (solution, values);
+ return values[0];
+ }
+ else
+ {
+ std::vector<Vector<double> > values
+ (1, Vector<double>(fe_values.get_fe().n_components()));
+ fe_values.get_function_values (solution, values);
+ return values[0](component);
}
+ }
template <int dim>
class SecondDerivative
{
- public:
- /**
- * Declare which data fields have to be updated for the function @p
- * get_projected_derivative to work.
- */
- static const UpdateFlags update_flags;
-
- /**
- * Declare the data type which holds the derivative described by this
- * class.
- */
- typedef Tensor<2,dim> Derivative;
-
- /**
- * Likewise declare the data type that holds the derivative projected to a
- * certain directions.
- */
- typedef Tensor<1,dim> ProjectedDerivative;
-
- /**
- * Given an FEValues object initialized to a cell, and a solution vector,
- * extract the desired derivative at the first quadrature point (which is
- * the only one, as we only evaluate the finite element field at the
- * center of each cell).
- */
- template <class InputVector, int spacedim>
- static ProjectedDerivative
- get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component);
-
- /**
- * Return the norm of the derivative object. Here, for the (symmetric)
- * tensor of second derivatives, we choose the absolute value of the
- * largest eigenvalue, which is the matrix norm associated to the $l_2$
- * norm of vectors. It is also the largest value of the curvature of the
- * solution.
- */
- static double derivative_norm (const Derivative &d);
-
- /**
- * If for the present derivative order, symmetrization of the derivative
- * tensor is necessary, then do so on the argument.
- *
- * For the second derivatives, each entry of the tensor is set to the mean
- * of its value and the value of the transpose element.
- *
- * Note that this function actually modifies its argument.
- */
- static void symmetrize (Derivative &derivative_tensor);
+ public:
+ /**
+ * Declare which data fields have to be updated for the function @p
+ * get_projected_derivative to work.
+ */
+ static const UpdateFlags update_flags;
+
+ /**
+ * Declare the data type which holds the derivative described by this
+ * class.
+ */
+ typedef Tensor<2,dim> Derivative;
+
+ /**
+ * Likewise declare the data type that holds the derivative projected to a
+ * certain directions.
+ */
+ typedef Tensor<1,dim> ProjectedDerivative;
+
+ /**
+ * Given an FEValues object initialized to a cell, and a solution vector,
+ * extract the desired derivative at the first quadrature point (which is
+ * the only one, as we only evaluate the finite element field at the
+ * center of each cell).
+ */
+ template <class InputVector, int spacedim>
+ static ProjectedDerivative
+ get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
+ const InputVector &solution,
+ const unsigned int component);
+
+ /**
+ * Return the norm of the derivative object. Here, for the (symmetric)
+ * tensor of second derivatives, we choose the absolute value of the
+ * largest eigenvalue, which is the matrix norm associated to the $l_2$
+ * norm of vectors. It is also the largest value of the curvature of the
+ * solution.
+ */
+ static double derivative_norm (const Derivative &d);
+
+ /**
+ * If for the present derivative order, symmetrization of the derivative
+ * tensor is necessary, then do so on the argument.
+ *
+ * For the second derivatives, each entry of the tensor is set to the mean
+ * of its value and the value of the transpose element.
+ *
+ * Note that this function actually modifies its argument.
+ */
+ static void symmetrize (Derivative &derivative_tensor);
};
template <int dim>
typename SecondDerivative<dim>::ProjectedDerivative
SecondDerivative<dim>::
get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component)
+ const InputVector &solution,
+ const unsigned int component)
+ {
+ if (fe_values.get_fe().n_components() == 1)
{
- if (fe_values.get_fe().n_components() == 1)
- {
- std::vector<ProjectedDerivative> values (1);
- fe_values.get_function_gradients (solution, values);
- return values[0];
- }
- else
- {
- std::vector<std::vector<ProjectedDerivative> > values
- (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
- fe_values.get_function_gradients (solution, values);
- return values[0][component];
- };
+ std::vector<ProjectedDerivative> values (1);
+ fe_values.get_function_gradients (solution, values);
+ return values[0];
}
+ else
+ {
+ std::vector<std::vector<ProjectedDerivative> > values
+ (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
+ fe_values.get_function_gradients (solution, values);
+ return values[0][component];
+ };
+ }
// if the d_11=a, d_22=b,
// d_12=d_21=c
const double radicand = dealii::sqr(d[0][0] - d[1][1]) +
- 4*dealii::sqr(d[0][1]);
+ 4*dealii::sqr(d[0][1]);
const double eigenvalues[2]
- = { 0.5*(d[0][0] + d[1][1] + std::sqrt(radicand)),
- 0.5*(d[0][0] + d[1][1] - std::sqrt(radicand))
- };
+ = { 0.5*(d[0][0] + d[1][1] + std::sqrt(radicand)),
+ 0.5*(d[0][0] + d[1][1] - std::sqrt(radicand))
+ };
return std::max (std::fabs (eigenvalues[0]),
std::fabs (eigenvalues[1]));
PROGRAM MAIN
- C FIND EIGENVALUES OF REAL SYMMETRIC MATRIX
- C (ROGER YOUNG, 2001)
+ C FIND EIGENVALUES OF REAL SYMMETRIC MATRIX
+ C (ROGER YOUNG, 2001)
IMPLICIT NONE
REAL*8 A,B,C, TOL
PARAMETER (TOL=1.D-14)
- C DEFINE A TEST MATRIX
+ C DEFINE A TEST MATRIX
A11 = -1.D0
A12 = 5.D0
s[i][i] -= am;
const double ss01 = s[0][1] * s[0][1],
- ss12 = s[1][2] * s[1][2],
- ss02 = s[0][2] * s[0][2];
+ ss12 = s[1][2] * s[1][2],
+ ss02 = s[0][2] * s[0][2];
const double J2 = (s[0][0]*s[0][0] + s[1][1]*s[1][1] + s[2][2]*s[2][2]
- + 2 * (ss01 + ss02 + ss12)) / 2.;
+ + 2 * (ss01 + ss02 + ss12)) / 2.;
const double J3 = (std::pow(s[0][0],3) + std::pow(s[1][1],3) + std::pow(s[2][2],3)
- + 3. * s[0][0] * (ss01 + ss02)
- + 3. * s[1][1] * (ss01 + ss12)
- + 3. * s[2][2] * (ss02 + ss12)
- + 6. * s[0][1] * s[0][2] * s[1][2]) / 3.;
+ + 3. * s[0][0] * (ss01 + ss02)
+ + 3. * s[1][1] * (ss01 + ss12)
+ + 3. * s[2][2] * (ss02 + ss12)
+ + 6. * s[0][1] * s[0][2] * s[1][2]) / 3.;
const double R = std::sqrt (4. * J2 / 3.);
template <int dim>
class ThirdDerivative
{
- public:
- /**
- * Declare which data fields have to be updated for the function @p
- * get_projected_derivative to work.
- */
- static const UpdateFlags update_flags;
-
- /**
- * Declare the data type which
- * holds the derivative described
- * by this class.
- */
- typedef Tensor<3,dim> Derivative;
-
- /**
- * Likewise declare the data type that holds the derivative projected to a
- * certain directions.
- */
- typedef Tensor<2,dim> ProjectedDerivative;
-
- /**
- * Given an FEValues object initialized to a cell, and a solution vector,
- * extract the desired derivative at the first quadrature point (which is
- * the only one, as we only evaluate the finite element field at the
- * center of each cell).
- */
- template <class InputVector, int spacedim>
- static ProjectedDerivative
- get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component);
-
- /**
- * Return the norm of the derivative object. Here, for the (symmetric)
- * tensor of second derivatives, we choose the absolute value of the
- * largest eigenvalue, which is the matrix norm associated to the $l_2$
- * norm of vectors. It is also the largest value of the curvature of the
- * solution.
- */
- static double derivative_norm (const Derivative &d);
-
- /**
- * If for the present derivative order, symmetrization of the derivative
- * tensor is necessary, then do so on the argument.
- *
- * For the second derivatives, each entry of the tensor is set to the mean
- * of its value and the value of the transpose element.
- *
- * Note that this function actually modifies its argument.
- */
- static void symmetrize (Derivative &derivative_tensor);
+ public:
+ /**
+ * Declare which data fields have to be updated for the function @p
+ * get_projected_derivative to work.
+ */
+ static const UpdateFlags update_flags;
+
+ /**
+ * Declare the data type which
+ * holds the derivative described
+ * by this class.
+ */
+ typedef Tensor<3,dim> Derivative;
+
+ /**
+ * Likewise declare the data type that holds the derivative projected to a
+ * certain directions.
+ */
+ typedef Tensor<2,dim> ProjectedDerivative;
+
+ /**
+ * Given an FEValues object initialized to a cell, and a solution vector,
+ * extract the desired derivative at the first quadrature point (which is
+ * the only one, as we only evaluate the finite element field at the
+ * center of each cell).
+ */
+ template <class InputVector, int spacedim>
+ static ProjectedDerivative
+ get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
+ const InputVector &solution,
+ const unsigned int component);
+
+ /**
+ * Return the norm of the derivative object. Here, for the (symmetric)
+ * tensor of second derivatives, we choose the absolute value of the
+ * largest eigenvalue, which is the matrix norm associated to the $l_2$
+ * norm of vectors. It is also the largest value of the curvature of the
+ * solution.
+ */
+ static double derivative_norm (const Derivative &d);
+
+ /**
+ * If for the present derivative order, symmetrization of the derivative
+ * tensor is necessary, then do so on the argument.
+ *
+ * For the second derivatives, each entry of the tensor is set to the mean
+ * of its value and the value of the transpose element.
+ *
+ * Note that this function actually modifies its argument.
+ */
+ static void symmetrize (Derivative &derivative_tensor);
};
template <int dim>
typename ThirdDerivative<dim>::ProjectedDerivative
ThirdDerivative<dim>::
get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component)
+ const InputVector &solution,
+ const unsigned int component)
+ {
+ if (fe_values.get_fe().n_components() == 1)
{
- if (fe_values.get_fe().n_components() == 1)
- {
- std::vector<ProjectedDerivative> values (1);
- fe_values.get_function_hessians (solution, values);
- return values[0];
- }
- else
- {
- std::vector<std::vector<ProjectedDerivative> > values
- (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
- fe_values.get_function_hessians (solution, values);
- return values[0][component];
- };
+ std::vector<ProjectedDerivative> values (1);
+ fe_values.get_function_hessians (solution, values);
+ return values[0];
}
+ else
+ {
+ std::vector<std::vector<ProjectedDerivative> > values
+ (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
+ fe_values.get_function_hessians (solution, values);
+ return values[0][component];
+ };
+ }
for (unsigned int k=j+1; k<dim; ++k)
{
const double s = (d[i][j][k] +
- d[i][k][j] +
- d[j][i][k] +
- d[j][k][i] +
- d[k][i][j] +
- d[k][j][i]) / 6;
+ d[i][k][j] +
+ d[j][i][k] +
+ d[j][k][i] +
+ d[k][i][j] +
+ d[k][j][i]) / 6;
d[i][j][k]
- = d[i][k][j]
- = d[j][i][k]
- = d[j][k][i]
- = d[k][i][j]
- = d[k][j][i]
- = s;
+ = d[i][k][j]
+ = d[j][i][k]
+ = d[j][k][i]
+ = d[k][i][j]
+ = d[k][j][i]
+ = s;
}
// now do the case, where two indices are
// equal
// case 1: index i (lower one) is
// double
const double s = (d[i][i][j] +
- d[i][j][i] +
- d[j][i][i] ) / 3;
+ d[i][j][i] +
+ d[j][i][i] ) / 3;
d[i][i][j]
- = d[i][j][i]
- = d[j][i][i]
- = s;
+ = d[i][j][i]
+ = d[j][i][i]
+ = s;
// case 2: index j (higher one) is
// double
const double t = (d[i][j][j] +
- d[j][i][j] +
- d[j][j][i] ) / 3;
+ d[j][i][j] +
+ d[j][j][i] ) / 3;
d[i][j][j]
- = d[j][i][j]
- = d[j][j][i]
- = t;
+ = d[j][i][j]
+ = d[j][j][i]
+ = t;
}
}
template <int order, int dim>
class DerivativeSelector
{
- public:
- /**
- * typedef to select the DerivativeDescription corresponding to the
- * <tt>order</tt>th derivative. In this general template we set an unvalid
- * typedef to void, the real typedefs have to be specialized.
- */
- typedef void DerivDescr;
+ public:
+ /**
+ * typedef to select the DerivativeDescription corresponding to the
+ * <tt>order</tt>th derivative. In this general template we set an unvalid
+ * typedef to void, the real typedefs have to be specialized.
+ */
+ typedef void DerivDescr;
};
template <int dim>
class DerivativeSelector<1,dim>
{
- public:
+ public:
- typedef Gradient<dim> DerivDescr;
+ typedef Gradient<dim> DerivDescr;
};
template <int dim>
class DerivativeSelector<2,dim>
{
- public:
+ public:
- typedef SecondDerivative<dim> DerivDescr;
+ typedef SecondDerivative<dim> DerivDescr;
};
template <int dim>
class DerivativeSelector<3,dim>
{
- public:
+ public:
- typedef ThirdDerivative<dim> DerivDescr;
+ typedef ThirdDerivative<dim> DerivDescr;
};
}
}
{
struct Scratch
{
- Scratch() {}
+ Scratch() {}
};
struct CopyData
{
- CopyData() {}
+ CopyData() {}
};
}
}
* derivative tensor.
*/
template <class DerivativeDescription, int dim,
- template <int, int> class DH, class InputVector, int spacedim>
+ template <int, int> class DH, class InputVector, int spacedim>
void
approximate_cell (const Mapping<dim,spacedim> &mapping,
const DH<dim,spacedim> &dof_handler,
const typename DH<dim,spacedim>::active_cell_iterator &cell,
typename DerivativeDescription::Derivative &derivative)
{
- QMidpoint<dim> midpoint_rule;
-
- // create collection objects from
- // single quadratures, mappings,
- // and finite elements. if we have
- // an hp DoFHandler,
- // dof_handler.get_fe() returns a
- // collection of which we do a
- // shallow copy instead
- const hp::QCollection<dim> q_collection (midpoint_rule);
- const hp::FECollection<dim> fe_collection(dof_handler.get_fe());
- const hp::MappingCollection<dim> mapping_collection (mapping);
-
- hp::FEValues<dim> x_fe_midpoint_value (mapping_collection, fe_collection,
- q_collection,
- DerivativeDescription::update_flags |
- update_quadrature_points);
-
- // matrix Y=sum_i y_i y_i^T
- Tensor<2,dim> Y;
-
-
- // vector to hold iterators to all
- // active neighbors of a cell
- // reserve the maximal number of
- // active neighbors
- std::vector<typename DH<dim,spacedim>::active_cell_iterator> active_neighbors;
- active_neighbors.reserve (GeometryInfo<dim>::faces_per_cell *
- GeometryInfo<dim>::max_children_per_face);
-
- // vector
- // g=sum_i y_i (f(x+y_i)-f(x))/|y_i|
- // or related type for higher
- // derivatives
- typename DerivativeDescription::Derivative projected_derivative;
-
- // reinit fe values object...
- x_fe_midpoint_value.reinit (cell);
- const FEValues<dim> &fe_midpoint_value
+ QMidpoint<dim> midpoint_rule;
+
+ // create collection objects from
+ // single quadratures, mappings,
+ // and finite elements. if we have
+ // an hp DoFHandler,
+ // dof_handler.get_fe() returns a
+ // collection of which we do a
+ // shallow copy instead
+ const hp::QCollection<dim> q_collection (midpoint_rule);
+ const hp::FECollection<dim> fe_collection(dof_handler.get_fe());
+ const hp::MappingCollection<dim> mapping_collection (mapping);
+
+ hp::FEValues<dim> x_fe_midpoint_value (mapping_collection, fe_collection,
+ q_collection,
+ DerivativeDescription::update_flags |
+ update_quadrature_points);
+
+ // matrix Y=sum_i y_i y_i^T
+ Tensor<2,dim> Y;
+
+
+ // vector to hold iterators to all
+ // active neighbors of a cell
+ // reserve the maximal number of
+ // active neighbors
+ std::vector<typename DH<dim,spacedim>::active_cell_iterator> active_neighbors;
+ active_neighbors.reserve (GeometryInfo<dim>::faces_per_cell *
+ GeometryInfo<dim>::max_children_per_face);
+
+ // vector
+ // g=sum_i y_i (f(x+y_i)-f(x))/|y_i|
+ // or related type for higher
+ // derivatives
+ typename DerivativeDescription::Derivative projected_derivative;
+
+ // reinit fe values object...
+ x_fe_midpoint_value.reinit (cell);
+ const FEValues<dim> &fe_midpoint_value
+ = x_fe_midpoint_value.get_present_fe_values();
+
+ // ...and get the value of the
+ // projected derivative...
+ const typename DerivativeDescription::ProjectedDerivative
+ this_midpoint_value
+ = DerivativeDescription::get_projected_derivative (fe_midpoint_value,
+ solution,
+ component);
+ // ...and the place where it lives
+ const Point<dim> this_center = fe_midpoint_value.quadrature_point(0);
+
+ // loop over all neighbors and
+ // accumulate the difference
+ // quotients from them. note
+ // that things get a bit more
+ // complicated if the neighbor
+ // is more refined than the
+ // present one
+ //
+ // to make processing simpler,
+ // first collect all neighbor
+ // cells in a vector, and then
+ // collect the data from them
+ GridTools::get_active_neighbors<DH<dim,spacedim> >(cell, active_neighbors);
+
+ // now loop over all active
+ // neighbors and collect the
+ // data we need
+ typename std::vector<typename DH<dim,spacedim>::active_cell_iterator>::const_iterator
+ neighbor_ptr = active_neighbors.begin();
+ for (; neighbor_ptr!=active_neighbors.end(); ++neighbor_ptr)
+ {
+ const typename DH<dim,spacedim>::active_cell_iterator
+ neighbor = *neighbor_ptr;
+
+ // reinit fe values object...
+ x_fe_midpoint_value.reinit (neighbor);
+ const FEValues<dim> &neighbor_fe_midpoint_value
= x_fe_midpoint_value.get_present_fe_values();
- // ...and get the value of the
- // projected derivative...
- const typename DerivativeDescription::ProjectedDerivative
- this_midpoint_value
- = DerivativeDescription::get_projected_derivative (fe_midpoint_value,
- solution,
- component);
- // ...and the place where it lives
- const Point<dim> this_center = fe_midpoint_value.quadrature_point(0);
-
- // loop over all neighbors and
- // accumulate the difference
- // quotients from them. note
- // that things get a bit more
- // complicated if the neighbor
- // is more refined than the
- // present one
- //
- // to make processing simpler,
- // first collect all neighbor
- // cells in a vector, and then
- // collect the data from them
- GridTools::get_active_neighbors<DH<dim,spacedim> >(cell, active_neighbors);
-
- // now loop over all active
- // neighbors and collect the
- // data we need
- typename std::vector<typename DH<dim,spacedim>::active_cell_iterator>::const_iterator
- neighbor_ptr = active_neighbors.begin();
- for (; neighbor_ptr!=active_neighbors.end(); ++neighbor_ptr)
- {
- const typename DH<dim,spacedim>::active_cell_iterator
- neighbor = *neighbor_ptr;
-
- // reinit fe values object...
- x_fe_midpoint_value.reinit (neighbor);
- const FEValues<dim> &neighbor_fe_midpoint_value
- = x_fe_midpoint_value.get_present_fe_values();
-
- // ...and get the value of the
- // solution...
- const typename DerivativeDescription::ProjectedDerivative
- neighbor_midpoint_value
- = DerivativeDescription::get_projected_derivative (neighbor_fe_midpoint_value,
- solution, component);
-
- // ...and the place where it lives
- const Point<dim>
- neighbor_center = neighbor_fe_midpoint_value.quadrature_point(0);
-
-
- // vector for the
- // normalized
- // direction between
- // the centers of two
- // cells
- Point<dim> y = neighbor_center - this_center;
- const double distance = std::sqrt(y.square());
- // normalize y
- y /= distance;
- // *** note that unlike in
- // the docs, y denotes the
- // normalized vector
- // connecting the centers
- // of the two cells, rather
- // than the normal
- // difference! ***
-
- // add up the
- // contribution of
- // this cell to Y
- for (unsigned int i=0; i<dim; ++i)
- for (unsigned int j=0; j<dim; ++j)
- Y[i][j] += y[i] * y[j];
-
- // then update the sum
- // of difference
- // quotients
- typename DerivativeDescription::ProjectedDerivative
- projected_finite_difference
- = (neighbor_midpoint_value -
- this_midpoint_value);
- projected_finite_difference /= distance;
-
- typename DerivativeDescription::Derivative projected_derivative_update;
- outer_product (projected_derivative_update,
- y,
- projected_finite_difference);
- projected_derivative += projected_derivative_update;
- };
-
- // can we determine an
- // approximation of the
- // gradient for the present
- // cell? if so, then we need to
- // have passed over vectors y_i
- // which span the whole space,
- // otherwise we would not have
- // all components of the
- // gradient
- AssertThrow (determinant(Y) != 0,
- ExcInsufficientDirections());
-
- // compute Y^-1 g
- const Tensor<2,dim> Y_inverse = invert(Y);
-
- contract (derivative, Y_inverse, projected_derivative);
-
- // finally symmetrize the derivative
- DerivativeDescription::symmetrize (derivative);
+ // ...and get the value of the
+ // solution...
+ const typename DerivativeDescription::ProjectedDerivative
+ neighbor_midpoint_value
+ = DerivativeDescription::get_projected_derivative (neighbor_fe_midpoint_value,
+ solution, component);
+
+ // ...and the place where it lives
+ const Point<dim>
+ neighbor_center = neighbor_fe_midpoint_value.quadrature_point(0);
+
+
+ // vector for the
+ // normalized
+ // direction between
+ // the centers of two
+ // cells
+ Point<dim> y = neighbor_center - this_center;
+ const double distance = std::sqrt(y.square());
+ // normalize y
+ y /= distance;
+ // *** note that unlike in
+ // the docs, y denotes the
+ // normalized vector
+ // connecting the centers
+ // of the two cells, rather
+ // than the normal
+ // difference! ***
+
+ // add up the
+ // contribution of
+ // this cell to Y
+ for (unsigned int i=0; i<dim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ Y[i][j] += y[i] * y[j];
+
+ // then update the sum
+ // of difference
+ // quotients
+ typename DerivativeDescription::ProjectedDerivative
+ projected_finite_difference
+ = (neighbor_midpoint_value -
+ this_midpoint_value);
+ projected_finite_difference /= distance;
+
+ typename DerivativeDescription::Derivative projected_derivative_update;
+ outer_product (projected_derivative_update,
+ y,
+ projected_finite_difference);
+ projected_derivative += projected_derivative_update;
+ };
+
+ // can we determine an
+ // approximation of the
+ // gradient for the present
+ // cell? if so, then we need to
+ // have passed over vectors y_i
+ // which span the whole space,
+ // otherwise we would not have
+ // all components of the
+ // gradient
+ AssertThrow (determinant(Y) != 0,
+ ExcInsufficientDirections());
+
+ // compute Y^-1 g
+ const Tensor<2,dim> Y_inverse = invert(Y);
+
+ contract (derivative, Y_inverse, projected_derivative);
+
+ // finally symmetrize the derivative
+ DerivativeDescription::symmetrize (derivative);
}
* on the cell.
*/
template <class DerivativeDescription, int dim,
- template <int, int> class DH, class InputVector, int spacedim>
+ template <int, int> class DH, class InputVector, int spacedim>
void
approximate (SynchronousIterators<std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,Vector<float>::iterator> > const &cell,
- const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- const unsigned int component)
+ const Mapping<dim,spacedim> &mapping,
+ const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ const unsigned int component)
{
- // if the cell is not locally owned, then there is nothing to do
- if (std_cxx1x::get<0>(cell.iterators)->is_locally_owned() == false)
- *std_cxx1x::get<1>(cell.iterators) = 0;
- else
- {
- typename DerivativeDescription::Derivative derivative;
- // call the function doing the actual
- // work on this cell
- approximate_cell<DerivativeDescription,dim,DH,InputVector>
- (mapping,dof_handler,solution,component,std_cxx1x::get<0>(cell.iterators),derivative);
- // evaluate the norm and fill the vector
- //*derivative_norm_on_this_cell
- *std_cxx1x::get<1>(cell.iterators) = DerivativeDescription::derivative_norm (derivative);
- }
+ // if the cell is not locally owned, then there is nothing to do
+ if (std_cxx1x::get<0>(cell.iterators)->is_locally_owned() == false)
+ *std_cxx1x::get<1>(cell.iterators) = 0;
+ else
+ {
+ typename DerivativeDescription::Derivative derivative;
+ // call the function doing the actual
+ // work on this cell
+ approximate_cell<DerivativeDescription,dim,DH,InputVector>
+ (mapping,dof_handler,solution,component,std_cxx1x::get<0>(cell.iterators),derivative);
+ // evaluate the norm and fill the vector
+ //*derivative_norm_on_this_cell
+ *std_cxx1x::get<1>(cell.iterators) = DerivativeDescription::derivative_norm (derivative);
+ }
}
* we are to work on.
*/
template <class DerivativeDescription, int dim,
- template <int, int> class DH, class InputVector, int spacedim>
+ template <int, int> class DH, class InputVector, int spacedim>
void
approximate_derivative (const Mapping<dim,spacedim> &mapping,
const DH<dim,spacedim> &dof_handler,
const unsigned int component,
Vector<float> &derivative_norm)
{
- Assert (derivative_norm.size() == dof_handler.get_tria().n_active_cells(),
- ExcInvalidVectorLength (derivative_norm.size(),
- dof_handler.get_tria().n_active_cells()));
- Assert (component < dof_handler.get_fe().n_components(),
- ExcIndexRange (component, 0, dof_handler.get_fe().n_components()));
-
- typedef std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,Vector<float>::iterator>
- Iterators;
- SynchronousIterators<Iterators> begin(Iterators(dof_handler.begin_active(),
- derivative_norm.begin())),
- end(Iterators(dof_handler.end(),
- derivative_norm.end()));
-
- // There is no need for a copier because there is no conflict between threads
- // to write in derivative_norm. Scratch and CopyData are also useless.
- WorkStream::run(begin,
- end,
- static_cast<std_cxx1x::function<void (SynchronousIterators<Iterators> const &,
- Assembler::Scratch const &, Assembler::CopyData &)> >
- (std_cxx1x::bind(&approximate<DerivativeDescription,dim,DH,InputVector,spacedim>,
- std_cxx1x::_1,
- std_cxx1x::cref(mapping),
- std_cxx1x::cref(dof_handler),
- std_cxx1x::cref(solution),component)),
- std_cxx1x::function<void (internal::Assembler::CopyData const &)> (),
- internal::Assembler::Scratch (),internal::Assembler::CopyData ());
+ Assert (derivative_norm.size() == dof_handler.get_tria().n_active_cells(),
+ ExcInvalidVectorLength (derivative_norm.size(),
+ dof_handler.get_tria().n_active_cells()));
+ Assert (component < dof_handler.get_fe().n_components(),
+ ExcIndexRange (component, 0, dof_handler.get_fe().n_components()));
+
+ typedef std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,Vector<float>::iterator>
+ Iterators;
+ SynchronousIterators<Iterators> begin(Iterators(dof_handler.begin_active(),
+ derivative_norm.begin())),
+ end(Iterators(dof_handler.end(),
+ derivative_norm.end()));
+
+ // There is no need for a copier because there is no conflict between threads
+ // to write in derivative_norm. Scratch and CopyData are also useless.
+ WorkStream::run(begin,
+ end,
+ static_cast<std_cxx1x::function<void (SynchronousIterators<Iterators> const &,
+ Assembler::Scratch const &, Assembler::CopyData &)> >
+ (std_cxx1x::bind(&approximate<DerivativeDescription,dim,DH,InputVector,spacedim>,
+ std_cxx1x::_1,
+ std_cxx1x::cref(mapping),
+ std_cxx1x::cref(dof_handler),
+ std_cxx1x::cref(solution),component)),
+ std_cxx1x::function<void (internal::Assembler::CopyData const &)> (),
+ internal::Assembler::Scratch (),internal::Assembler::CopyData ());
}
} // namespace internal
Vector<float> &derivative_norm,
const unsigned int component)
{
- internal::approximate_derivative<internal::Gradient<dim>,dim> (mapping,
- dof_handler,
- solution,
- component,
- derivative_norm);
+ internal::approximate_derivative<internal::Gradient<dim>,dim> (mapping,
+ dof_handler,
+ solution,
+ component,
+ derivative_norm);
}
Vector<float> &derivative_norm,
const unsigned int component)
{
- internal::approximate_derivative<internal::Gradient<dim>,dim> (StaticMappingQ1<dim>::mapping,
- dof_handler,
- solution,
- component,
- derivative_norm);
+ internal::approximate_derivative<internal::Gradient<dim>,dim> (StaticMappingQ1<dim>::mapping,
+ dof_handler,
+ solution,
+ component,
+ derivative_norm);
}
Vector<float> &derivative_norm,
const unsigned int component)
{
- internal::approximate_derivative<internal::SecondDerivative<dim>,dim> (mapping,
- dof_handler,
- solution,
- component,
- derivative_norm);
+ internal::approximate_derivative<internal::SecondDerivative<dim>,dim> (mapping,
+ dof_handler,
+ solution,
+ component,
+ derivative_norm);
}
Vector<float> &derivative_norm,
const unsigned int component)
{
- internal::approximate_derivative<internal::SecondDerivative<dim>,dim> (StaticMappingQ1<dim>::mapping,
- dof_handler,
- solution,
- component,
- derivative_norm);
+ internal::approximate_derivative<internal::SecondDerivative<dim>,dim> (StaticMappingQ1<dim>::mapping,
+ dof_handler,
+ solution,
+ component,
+ derivative_norm);
}
Tensor<order,DH::dimension> &derivative,
const unsigned int component)
{
- internal::approximate_cell<typename internal::DerivativeSelector<order,DH::dimension>::DerivDescr>
- (mapping,
- dof,
- solution,
- component,
- cell,
- derivative);
+ internal::approximate_cell<typename internal::DerivativeSelector<order,DH::dimension>::DerivDescr>
+ (mapping,
+ dof,
+ solution,
+ component,
+ cell,
+ derivative);
}
Tensor<order,DH::dimension> &derivative,
const unsigned int component)
{
- // just call the respective function with Q1 mapping
- approximate_derivative_tensor<DH,InputVector,order>
- (StaticMappingQ1<DH::dimension,DH::space_dimension>::mapping,
- dof,
- solution,
- cell,
- derivative,
- component);
+ // just call the respective function with Q1 mapping
+ approximate_derivative_tensor<DH,InputVector,order>
+ (StaticMappingQ1<DH::dimension,DH::space_dimension>::mapping,
+ dof,
+ solution,
+ cell,
+ derivative,
+ component);
}
&&
(p->column() == dof_number),
ExcMessage("This function is trying to access an element of the "
- "matrix that doesn't seem to exist. Are you using a "
- "nonsymmetric sparsity pattern? If so, you are not "
- "allowed to set the eliminate_column argument of this "
- "function, see the documentation."));
+ "matrix that doesn't seem to exist. Are you using a "
+ "nonsymmetric sparsity pattern? If so, you are not "
+ "allowed to set the eliminate_column argument of this "
+ "function, see the documentation."));
// correct right hand side
right_hand_side(row) -= p->value() /
if (boundary_values.size() > 0)
{
const std::pair<types::global_dof_index, types::global_dof_index> local_range
- = matrix.local_range();
+ = matrix.local_range();
Assert (local_range == right_hand_side.local_range(),
ExcInternalError());
Assert (local_range == solution.local_range(),
// have to eliminate on this processor
std::vector<types::global_dof_index> constrained_rows;
for (std::map<types::global_dof_index,double>::const_iterator
- dof = boundary_values.begin();
- dof != boundary_values.end();
- ++dof)
+ dof = boundary_values.begin();
+ dof != boundary_values.end();
+ ++dof)
if ((dof->first >= local_range.first) &&
(dof->first < local_range.second))
constrained_rows.push_back (dof->first);
std::vector<types::global_dof_index> indices;
std::vector<PetscScalar> solution_values;
for (std::map<types::global_dof_index,double>::const_iterator
- dof = boundary_values.begin();
- dof != boundary_values.end();
- ++dof)
+ dof = boundary_values.begin();
+ dof != boundary_values.end();
+ ++dof)
if ((dof->first >= local_range.first) &&
(dof->first < local_range.second))
{
right_hand_side.set (indices, solution_values);
}
- else
- {
+ else
+ {
// clear_rows() is a collective operation so we still have to call
// it:
std::vector<types::global_dof_index> constrained_rows;
matrix.clear_rows (constrained_rows, 1.);
- }
-
+ }
+
// clean up
matrix.compress ();
solution.compress (VectorOperation::insert);
// jump straight to the compress() calls that we still have
// to perform because they are collective operations
if (boundary_values.size() > 0)
- {
- const std::pair<types::global_dof_index, types::global_dof_index> local_range
- = matrix.local_range();
- Assert (local_range == right_hand_side.local_range(),
- ExcInternalError());
- Assert (local_range == solution.local_range(),
- ExcInternalError());
-
- // we have to read and write from this
- // matrix (in this order). this will only
- // work if we compress the matrix first,
- // done here
- matrix.compress ();
-
- // determine the first nonzero diagonal
- // entry from within the part of the
- // matrix that we can see. if we can't
- // find such an entry, take one
- TrilinosScalar average_nonzero_diagonal_entry = 1;
- for (types::global_dof_index i=local_range.first; i<local_range.second; ++i)
- if (matrix.diag_element(i) != 0)
- {
- average_nonzero_diagonal_entry = std::fabs(matrix.diag_element(i));
- break;
- }
-
- // figure out which rows of the matrix we
- // have to eliminate on this processor
- std::vector<types::global_dof_index> constrained_rows;
- for (std::map<types::global_dof_index,double>::const_iterator
- dof = boundary_values.begin();
- dof != boundary_values.end();
- ++dof)
- if ((dof->first >= local_range.first) &&
- (dof->first < local_range.second))
- constrained_rows.push_back (dof->first);
-
- // then eliminate these rows and
- // set their diagonal entry to
- // what we have determined
- // above. if the value already is
- // nonzero, it will be preserved,
- // in accordance with the basic
- // matrix classes in deal.II.
- matrix.clear_rows (constrained_rows, average_nonzero_diagonal_entry);
-
- std::vector<types::global_dof_index> indices;
- std::vector<TrilinosScalar> solution_values;
- for (std::map<types::global_dof_index,double>::const_iterator
- dof = boundary_values.begin();
- dof != boundary_values.end();
- ++dof)
- if ((dof->first >= local_range.first) &&
- (dof->first < local_range.second))
- {
- indices.push_back (dof->first);
- solution_values.push_back (dof->second);
- }
- solution.set (indices, solution_values);
-
- // now also set appropriate
- // values for the rhs
- for (unsigned int i=0; i<solution_values.size(); ++i)
- solution_values[i] *= matrix.diag_element(indices[i]);
-
- right_hand_side.set (indices, solution_values);
- }
- else
- {
+ {
+ const std::pair<types::global_dof_index, types::global_dof_index> local_range
+ = matrix.local_range();
+ Assert (local_range == right_hand_side.local_range(),
+ ExcInternalError());
+ Assert (local_range == solution.local_range(),
+ ExcInternalError());
+
+ // we have to read and write from this
+ // matrix (in this order). this will only
+ // work if we compress the matrix first,
+ // done here
+ matrix.compress ();
+
+ // determine the first nonzero diagonal
+ // entry from within the part of the
+ // matrix that we can see. if we can't
+ // find such an entry, take one
+ TrilinosScalar average_nonzero_diagonal_entry = 1;
+ for (types::global_dof_index i=local_range.first; i<local_range.second; ++i)
+ if (matrix.diag_element(i) != 0)
+ {
+ average_nonzero_diagonal_entry = std::fabs(matrix.diag_element(i));
+ break;
+ }
+
+ // figure out which rows of the matrix we
+ // have to eliminate on this processor
+ std::vector<types::global_dof_index> constrained_rows;
+ for (std::map<types::global_dof_index,double>::const_iterator
+ dof = boundary_values.begin();
+ dof != boundary_values.end();
+ ++dof)
+ if ((dof->first >= local_range.first) &&
+ (dof->first < local_range.second))
+ constrained_rows.push_back (dof->first);
+
+ // then eliminate these rows and
+ // set their diagonal entry to
+ // what we have determined
+ // above. if the value already is
+ // nonzero, it will be preserved,
+ // in accordance with the basic
+ // matrix classes in deal.II.
+ matrix.clear_rows (constrained_rows, average_nonzero_diagonal_entry);
+
+ std::vector<types::global_dof_index> indices;
+ std::vector<TrilinosScalar> solution_values;
+ for (std::map<types::global_dof_index,double>::const_iterator
+ dof = boundary_values.begin();
+ dof != boundary_values.end();
+ ++dof)
+ if ((dof->first >= local_range.first) &&
+ (dof->first < local_range.second))
+ {
+ indices.push_back (dof->first);
+ solution_values.push_back (dof->second);
+ }
+ solution.set (indices, solution_values);
+
+ // now also set appropriate
+ // values for the rhs
+ for (unsigned int i=0; i<solution_values.size(); ++i)
+ solution_values[i] *= matrix.diag_element(indices[i]);
+
+ right_hand_side.set (indices, solution_values);
+ }
+ else
+ {
// clear_rows() is a collective operation so we still have to call
// it:
- std::vector<types::global_dof_index> constrained_rows;
- matrix.clear_rows (constrained_rows, 1.);
- }
-
+ std::vector<types::global_dof_index> constrained_rows;
+ matrix.clear_rows (constrained_rows, 1.);
+ }
+
// clean up
matrix.compress ();
solution.compress (VectorOperation::insert);
}
for (std::map <std::string, std::vector <std::vector <double> > >::iterator
- data_store_begin = data_store.begin (); data_store_begin != data_store.end (); ++data_store_begin)
+ data_store_begin = data_store.begin (); data_store_begin != data_store.end (); ++data_store_begin)
{
typename std::map <std::string, ComponentMask>::iterator mask = component_mask.find(data_store_begin->first);
unsigned int n_stored = mask->second.n_selected_components();
}
for (std::map <std::string, std::vector <std::vector <double> > >::iterator
- data_store_begin = data_store.begin ();
+ data_store_begin = data_store.begin ();
data_store_begin != data_store.end (); ++data_store_begin)
{
typename std::map <std::string, ComponentMask>::iterator mask = component_mask.find(data_store_begin->first);
// which is both done by one
// function
{
- const unsigned int this_fe_index = pointerstruct->second.active_fe_index;
+ const unsigned int this_fe_index = pointerstruct->second.active_fe_index;
const unsigned int dofs_per_cell=cell->get_dof_handler().get_fe()[this_fe_index].dofs_per_cell;
local_values.reinit(dofs_per_cell, true);
- // make sure that the size of the
+ // make sure that the size of the
// stored indices is the same as
// dofs_per_cell. this is kind of a
// test if we use the same fe in the
unsigned int n_cells_to_coarsen=0;
unsigned int n_cells_to_stay_or_refine=0;
for (typename DH::active_cell_iterator act_cell = dof_handler->begin_active();
- act_cell!=dof_handler->end(); ++act_cell)
+ act_cell!=dof_handler->end(); ++act_cell)
{
if (act_cell->coarsen_flag_set())
++n_cells_to_coarsen;
unsigned int n_coarsen_fathers=0;
for (typename DH::cell_iterator cell=dof_handler->begin();
- cell!=dof_handler->end(); ++cell)
+ cell!=dof_handler->end(); ++cell)
if (!cell->active() && cell->child(0)->coarsen_flag_set())
++n_coarsen_fathers;
Assert(n_cells_to_coarsen>=2*n_coarsen_fathers, ExcInternalError());
// the 'coarsen_fathers' cells 'n_cf',
unsigned int n_sr=0, n_cf=0;
for (typename DH::cell_iterator cell=dof_handler->begin();
- cell!=dof_handler->end(); ++cell)
+ cell!=dof_handler->end(); ++cell)
{
// CASE 1: active cell that remains as it is
if (cell->active() && !cell->coarsen_flag_set())