Reference documentation for deal.II version 9.0.0
data_out.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/work_stream.h>
17 #include <deal.II/numerics/data_out.h>
18 #include <deal.II/grid/tria.h>
19 #include <deal.II/dofs/dof_handler.h>
20 #include <deal.II/dofs/dof_accessor.h>
21 #include <deal.II/hp/dof_handler.h>
22 #include <deal.II/grid/tria_iterator.h>
23 #include <deal.II/fe/fe.h>
24 #include <deal.II/fe/fe_dgq.h>
25 #include <deal.II/fe/fe_values.h>
26 #include <deal.II/hp/fe_values.h>
27 #include <deal.II/fe/mapping_q1.h>
28 
29 #include <sstream>
30 
31 DEAL_II_NAMESPACE_OPEN
32 
33 
34 namespace internal
35 {
36  namespace DataOutImplementation
37  {
38  template <int dim, int spacedim>
39  ParallelData<dim,spacedim>::
40  ParallelData (const unsigned int n_datasets,
41  const unsigned int n_subdivisions,
42  const std::vector<unsigned int> &n_postprocessor_outputs,
43  const Mapping<dim,spacedim> &mapping,
44  const std::vector<std::shared_ptr<::hp::FECollection<dim,spacedim> > > &finite_elements,
45  const UpdateFlags update_flags,
46  const std::vector<std::vector<unsigned int> > &cell_to_patch_index_map)
47  :
48  ParallelDataBase<dim,spacedim> (n_datasets,
49  n_subdivisions,
50  n_postprocessor_outputs,
51  mapping,
52  finite_elements,
53  update_flags,
54  false),
55  cell_to_patch_index_map (&cell_to_patch_index_map)
56  {}
57  }
58 }
59 
60 
61 
62 template <int dim, typename DoFHandlerType>
63 void
66 (const std::pair<cell_iterator, unsigned int> *cell_and_index,
68  const unsigned int n_subdivisions,
69  const CurvedCellRegion curved_cell_region)
70 {
71  // first create the output object that we will write into
73  patch.n_subdivisions = n_subdivisions;
74 
75  // set the vertices of the patch. if the mapping does not preserve locations
76  // (e.g. MappingQEulerian), we need to compute the offset of the vertex for
77  // the graphical output. Otherwise, we can just use the vertex info.
78  for (unsigned int vertex=0; vertex<GeometryInfo<DoFHandlerType::dimension>::vertices_per_cell; ++vertex)
79  if (scratch_data.mapping_collection[0].preserves_vertex_locations())
80  patch.vertices[vertex] = cell_and_index->first->vertex(vertex);
81  else
82  patch.vertices[vertex] = scratch_data.mapping_collection[0].transform_unit_to_real_cell
83  (cell_and_index->first,
85 
86  // create DoFHandlerType::active_cell_iterator and initialize FEValues
87  scratch_data.reinit_all_fe_values(this->dof_data, cell_and_index->first);
88 
90  = scratch_data.get_present_fe_values (0);
91 
92  const unsigned int n_q_points = fe_patch_values.n_quadrature_points;
93 
94  // depending on the requested output of curved cells, if necessary
95  // append the quadrature points to the last rows of the patch.data
96  // member. This is the case if we want to produce curved cells at the
97  // boundary and this cell actually is at the boundary, or else if we
98  // want to produce curved cells everywhere
99  //
100  // note: a cell is *always* at the boundary if dim<spacedim
101  if (curved_cell_region==curved_inner_cells
102  ||
103  (curved_cell_region==curved_boundary
104  &&
105  (cell_and_index->first->at_boundary()
106  ||
107  (DoFHandlerType::dimension != DoFHandlerType::space_dimension))))
108  {
109  Assert(patch.space_dim==DoFHandlerType::space_dimension, ExcInternalError());
110 
111  // set the flag indicating that for this cell the points are
112  // explicitly given
113  patch.points_are_available = true;
114 
115  // then resize the patch.data member in order to have enough memory for
116  // the quadrature points as well, and copy the quadrature points there
117  const std::vector<Point<DoFHandlerType::space_dimension> > &q_points
118  = fe_patch_values.get_quadrature_points();
119 
120  patch.data.reinit (scratch_data.n_datasets+DoFHandlerType::space_dimension, n_q_points);
121  for (unsigned int i=0; i<DoFHandlerType::space_dimension; ++i)
122  for (unsigned int q=0; q<n_q_points; ++q)
123  patch.data(patch.data.size(0)-DoFHandlerType::space_dimension+i,q) = q_points[q][i];
124  }
125  else
126  {
127  patch.data.reinit(scratch_data.n_datasets, n_q_points);
128  patch.points_are_available = false;
129  }
130 
131 
132  if (scratch_data.n_datasets > 0)
133  {
134  // counter for data records
135  unsigned int offset=0;
136 
137  // first fill dof_data
138  for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
139  {
141  = scratch_data.get_present_fe_values (dataset);
142  const unsigned int n_components =
143  this_fe_patch_values.get_fe().n_components();
144 
146  = this->dof_data[dataset]->postprocessor;
147 
148  if (postprocessor != nullptr)
149  {
150  // we have to postprocess the data, so determine, which fields
151  // have to be updated
152  const UpdateFlags update_flags=postprocessor->get_needed_update_flags();
153  if (n_components == 1)
154  {
155  // at each point there is only one component of value,
156  // gradient etc.
157  if (update_flags & update_values)
158  this->dof_data[dataset]->get_function_values (this_fe_patch_values,
159  internal::DataOutImplementation::ComponentExtractor::real_part,
160  scratch_data.patch_values_scalar.solution_values);
161  if (update_flags & update_gradients)
162  this->dof_data[dataset]->get_function_gradients (this_fe_patch_values,
163  internal::DataOutImplementation::ComponentExtractor::real_part,
164  scratch_data.patch_values_scalar.solution_gradients);
165  if (update_flags & update_hessians)
166  this->dof_data[dataset]->get_function_hessians (this_fe_patch_values,
167  internal::DataOutImplementation::ComponentExtractor::real_part,
168  scratch_data.patch_values_scalar.solution_hessians);
169 
170  if (update_flags & update_quadrature_points)
171  scratch_data.patch_values_scalar.evaluation_points = this_fe_patch_values.get_quadrature_points();
172 
173  const typename DoFHandlerType::active_cell_iterator dh_cell(&cell_and_index->first->get_triangulation(),
174  cell_and_index->first->level(),
175  cell_and_index->first->index(),
176  this->dof_data[dataset]->dof_handler);
177  scratch_data.patch_values_scalar.template set_cell<DoFHandlerType> (dh_cell);
178 
179  postprocessor->
180  evaluate_scalar_field(scratch_data.patch_values_scalar,
181  scratch_data.postprocessed_values[dataset]);
182  }
183  else
184  {
185  scratch_data.resize_system_vectors (n_components);
186 
187  // at each point there is a vector valued function and its
188  // derivative...
189  if (update_flags & update_values)
190  this->dof_data[dataset]->get_function_values (this_fe_patch_values,
191  internal::DataOutImplementation::ComponentExtractor::real_part,
192  scratch_data.patch_values_system.solution_values);
193  if (update_flags & update_gradients)
194  this->dof_data[dataset]->get_function_gradients (this_fe_patch_values,
195  internal::DataOutImplementation::ComponentExtractor::real_part,
196  scratch_data.patch_values_system.solution_gradients);
197  if (update_flags & update_hessians)
198  this->dof_data[dataset]->get_function_hessians (this_fe_patch_values,
199  internal::DataOutImplementation::ComponentExtractor::real_part,
200  scratch_data.patch_values_system.solution_hessians);
201 
202  if (update_flags & update_quadrature_points)
203  scratch_data.patch_values_system.evaluation_points = this_fe_patch_values.get_quadrature_points();
204 
205  const typename DoFHandlerType::active_cell_iterator dh_cell(&cell_and_index->first->get_triangulation(),
206  cell_and_index->first->level(),
207  cell_and_index->first->index(),
208  this->dof_data[dataset]->dof_handler);
209  scratch_data.patch_values_system.template set_cell<DoFHandlerType> (dh_cell);
210 
211  postprocessor->
212  evaluate_vector_field(scratch_data.patch_values_system,
213  scratch_data.postprocessed_values[dataset]);
214  }
215 
216  for (unsigned int q=0; q<n_q_points; ++q)
217  for (unsigned int component=0;
218  component<this->dof_data[dataset]->n_output_variables;
219  ++component)
220  patch.data(offset+component,q)
221  = scratch_data.postprocessed_values[dataset][q](component);
222  }
223  else
224  // use the given data vector directly, without a postprocessor. again,
225  // we treat single component functions separately for efficiency
226  // reasons.
227  if (n_components == 1)
228  {
229  // first output the real part of the solution vector
230  this->dof_data[dataset]->get_function_values (this_fe_patch_values,
231  internal::DataOutImplementation::ComponentExtractor::real_part,
232  scratch_data.patch_values_scalar.solution_values);
233  for (unsigned int q=0; q<n_q_points; ++q)
234  patch.data(offset,q) = scratch_data.patch_values_scalar.solution_values[q];
235 
236  // and if there is one, also output the imaginary part
237  if (this->dof_data[dataset]->is_complex_valued() == true)
238  {
239  this->dof_data[dataset]->get_function_values (this_fe_patch_values,
240  internal::DataOutImplementation::ComponentExtractor::imaginary_part,
241  scratch_data.patch_values_scalar.solution_values);
242  for (unsigned int q=0; q<n_q_points; ++q)
243  patch.data(offset+1,q) = scratch_data.patch_values_scalar.solution_values[q];
244  }
245  }
246  else
247  {
248  scratch_data.resize_system_vectors(n_components);
249 
250  // same as above: first the real part
251  const unsigned int stride = (this->dof_data[dataset]->is_complex_valued() ? 2 : 1);
252  this->dof_data[dataset]->get_function_values (this_fe_patch_values,
253  internal::DataOutImplementation::ComponentExtractor::real_part,
254  scratch_data.patch_values_system.solution_values);
255  for (unsigned int component=0; component<n_components;
256  ++component)
257  for (unsigned int q=0; q<n_q_points; ++q)
258  patch.data(offset+component*stride,q) =
259  scratch_data.patch_values_system.solution_values[q](component);
260 
261  // and if there is one, also output the imaginary part
262  if (this->dof_data[dataset]->is_complex_valued() == true)
263  {
264  this->dof_data[dataset]->get_function_values (this_fe_patch_values,
265  internal::DataOutImplementation::ComponentExtractor::imaginary_part,
266  scratch_data.patch_values_system.solution_values);
267  for (unsigned int component=0; component<n_components;
268  ++component)
269  for (unsigned int q=0; q<n_q_points; ++q)
270  patch.data(offset+component*stride+1,q) =
271  scratch_data.patch_values_system.solution_values[q](component);
272  }
273  }
274 
275  // increment the counter for the actual data record
276  offset += this->dof_data[dataset]->n_output_variables *
277  (this->dof_data[dataset]->is_complex_valued() ? 2 : 1);
278  }
279 
280  // then do the cell data. only compute the number of a cell if needed;
281  // also make sure that we only access cell data if the
282  // first_cell/next_cell functions only return active cells
283  if (this->cell_data.size() != 0)
284  {
285  Assert (!cell_and_index->first->has_children(), ExcNotImplemented());
286 
287  for (unsigned int dataset=0; dataset<this->cell_data.size(); ++dataset)
288  {
289  // as above, first output the real part
290  {
291  const double value
292  = this->cell_data[dataset]->get_cell_data_value (cell_and_index->second,
293  internal::DataOutImplementation::ComponentExtractor::real_part);
294  for (unsigned int q=0; q<n_q_points; ++q)
295  patch.data(offset,q) = value;
296  }
297 
298  // and if there is one, also output the imaginary part
299  if (this->cell_data[dataset]->is_complex_valued() == true)
300  {
301  const double value
302  = this->cell_data[dataset]->get_cell_data_value (cell_and_index->second,
303  internal::DataOutImplementation::ComponentExtractor::imaginary_part);
304  for (unsigned int q=0; q<n_q_points; ++q)
305  patch.data(offset+1,q) = value;
306  }
307 
308  offset += (this->cell_data[dataset]->is_complex_valued() ? 2 : 1);
309  }
310  }
311  }
312 
313 
314  for (unsigned int f=0; f<GeometryInfo<DoFHandlerType::dimension>::faces_per_cell; ++f)
315  {
316  // let's look up whether the neighbor behind that face is noted in the
317  // table of cells which we treat. this can only happen if the neighbor
318  // exists, and is on the same level as this cell, but it may also happen
319  // that the neighbor is not a member of the range of cells over which we
320  // loop, in which case the respective entry in the
321  // cell_to_patch_index_map will have the value no_neighbor. (note that
322  // since we allocated only as much space in this array as the maximum
323  // index of the cells we loop over, not every neighbor may have its
324  // space in it, so we have to assume that it is extended by values
325  // no_neighbor)
326  if (cell_and_index->first->at_boundary(f)
327  ||
328  (cell_and_index->first->neighbor(f)->level() != cell_and_index->first->level()))
329  {
331  continue;
332  }
333 
334  const cell_iterator neighbor = cell_and_index->first->neighbor(f);
335  Assert (static_cast<unsigned int>(neighbor->level()) <
336  scratch_data.cell_to_patch_index_map->size(),
337  ExcInternalError());
338  if ((static_cast<unsigned int>(neighbor->index()) >=
339  (*scratch_data.cell_to_patch_index_map)[neighbor->level()].size())
340  ||
341  ((*scratch_data.cell_to_patch_index_map)[neighbor->level()][neighbor->index()]
342  ==
344  {
346  continue;
347  }
348 
349  // now, there is a neighbor, so get its patch number and set it for the
350  // neighbor index
351  patch.neighbors[f]
352  = (*scratch_data.cell_to_patch_index_map)[neighbor->level()][neighbor->index()];
353  }
354 
355  const unsigned int patch_idx =
356  (*scratch_data.cell_to_patch_index_map)[cell_and_index->first->level()][cell_and_index->first->index()];
357  // did we mess up the indices?
358  Assert(patch_idx < this->patches.size(), ExcInternalError());
359  patch.patch_index = patch_idx;
360 
361  // Put the patch into the patches vector. instead of copying the data,
362  // simply swap the contents to avoid the penalty of writing into another
363  // processor's memory
364  this->patches[patch_idx].swap (patch);
365 }
366 
367 
368 
369 template <int dim, typename DoFHandlerType>
370 void DataOut<dim,DoFHandlerType>::build_patches (const unsigned int n_subdivisions)
371 {
373  n_subdivisions, no_curved_cells);
374 }
375 
376 
377 
378 template <int dim, typename DoFHandlerType>
381  const unsigned int n_subdivisions_,
382  const CurvedCellRegion curved_region)
383 {
384  // Check consistency of redundant template parameter
385  Assert (dim==DoFHandlerType::dimension, ExcDimensionMismatch(dim, DoFHandlerType::dimension));
386 
387  Assert (this->triangulation != nullptr,
389 
390  const unsigned int n_subdivisions = (n_subdivisions_ != 0)
391  ? n_subdivisions_
392  : this->default_subdivisions;
393  Assert (n_subdivisions >= 1,
395 
396  this->validate_dataset_names();
397 
398  // First count the cells we want to create patches of. Also fill the object
399  // that maps the cell indices to the patch numbers, as this will be needed
400  // for generation of neighborship information.
401  // Note, there is a confusing mess of different indices here at play:
402  // patch_index - the index of a patch in all_cells
403  // cell->index - only unique on each level, used in cell_to_patch_index_map
404  // active_index - index for a cell when counting from begin_active() using ++cell
405  // cell_index - unique index of a cell counted using next_locally_owned_cell()
406  // starting from first_locally_owned_cell()
407  //
408  // It turns out that we create one patch for each selected cell, so patch_index==cell_index.
409  //
410  // will be cell_to_patch_index_map[cell->level][cell->index] = patch_index
411  std::vector<std::vector<unsigned int> > cell_to_patch_index_map;
412  cell_to_patch_index_map.resize (this->triangulation->n_levels());
413  for (unsigned int l=0; l<this->triangulation->n_levels(); ++l)
414  {
415  // max_index is the largest cell->index on level l
416  unsigned int max_index = 0;
417  for (cell_iterator cell=first_locally_owned_cell(); cell != this->triangulation->end();
418  cell = next_locally_owned_cell(cell))
419  if (static_cast<unsigned int>(cell->level()) == l)
420  max_index = std::max (max_index,
421  static_cast<unsigned int>(cell->index()));
422 
423  cell_to_patch_index_map[l].resize (max_index+1,
424  ::DataOutBase::Patch<DoFHandlerType::dimension,
425  DoFHandlerType::space_dimension>::no_neighbor);
426  }
427 
428  // will be all_cells[patch_index] = pair(cell, active_index)
429  std::vector<std::pair<cell_iterator, unsigned int> > all_cells;
430  {
431  // important: we need to compute the active_index of the cell in the range
432  // 0..n_active_cells() because this is where we need to look up cell
433  // data from (cell data vectors do not have the length distance computed by
434  // first_locally_owned_cell/next_locally_owned_cell because this might skip
435  // some values (FilteredIterator).
436  active_cell_iterator active_cell = this->triangulation->begin_active();
437  unsigned int active_index = 0;
438  cell_iterator cell = first_locally_owned_cell();
439  for (; cell != this->triangulation->end();
440  cell = next_locally_owned_cell(cell))
441  {
442  // move forward until active_cell points at the cell (cell) we are looking
443  // at to compute the current active_index
444  while (active_cell!=this->triangulation->end()
445  && cell->active()
446  && active_cell_iterator(cell) != active_cell)
447  {
448  ++active_cell;
449  ++active_index;
450  }
451 
452  Assert (static_cast<unsigned int>(cell->level()) <
453  cell_to_patch_index_map.size(),
454  ExcInternalError());
455  Assert (static_cast<unsigned int>(cell->index()) <
456  cell_to_patch_index_map[cell->level()].size(),
457  ExcInternalError());
458  Assert (active_index < this->triangulation->n_active_cells(),
459  ExcInternalError());
460  cell_to_patch_index_map[cell->level()][cell->index()] = all_cells.size();
461 
462  all_cells.emplace_back (cell, active_index);
463  }
464  }
465 
466  this->patches.clear ();
467  this->patches.resize(all_cells.size());
468 
469  // now create a default object for the WorkStream object to work with
470  unsigned int n_datasets = 0;
471  for (unsigned int i=0; i<this->cell_data.size(); ++i)
472  n_datasets += (this->cell_data[i]->is_complex_valued() ? 2 : 1);
473  for (unsigned int i=0; i<this->dof_data.size(); ++i)
474  n_datasets += (this->dof_data[i]->n_output_variables
475  * (this->dof_data[i]->is_complex_valued() ? 2 : 1));
476 
477  std::vector<unsigned int> n_postprocessor_outputs (this->dof_data.size());
478  for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
479  if (this->dof_data[dataset]->postprocessor)
480  n_postprocessor_outputs[dataset] = this->dof_data[dataset]->n_output_variables;
481  else
482  n_postprocessor_outputs[dataset] = 0;
483 
484  const CurvedCellRegion curved_cell_region
485  = (n_subdivisions<2 ? no_curved_cells : curved_region);
486 
487  UpdateFlags update_flags = update_values;
488  if (curved_cell_region != no_curved_cells)
489  update_flags |= update_quadrature_points;
490 
491  for (unsigned int i=0; i<this->dof_data.size(); ++i)
492  if (this->dof_data[i]->postprocessor)
493  update_flags |= this->dof_data[i]->postprocessor->get_needed_update_flags();
494  // perhaps update_normal_vectors is present, which would only be useful on
495  // faces, but we may not use it here.
496  Assert (!(update_flags & update_normal_vectors),
497  ExcMessage("The update of normal vectors may not be requested for evaluation of "
498  "data on cells via DataPostprocessor."));
499 
501  thread_data (n_datasets, n_subdivisions,
502  n_postprocessor_outputs,
503  mapping,
504  this->get_fes(),
505  update_flags,
506  cell_to_patch_index_map);
507 
508  // now build the patches in parallel
509  if (all_cells.size() > 0)
510  WorkStream::run (&all_cells[0],
511  &all_cells[0]+all_cells.size(),
513  this,
514  std::placeholders::_1,
515  std::placeholders::_2,
516  /* no std::placeholders::_3, since this function doesn't actually need a
517  copy data object -- it just writes everything right into the
518  output array */
519  n_subdivisions,
520  curved_cell_region),
521  // no copy-local-to-global function needed here
522  std::function<void (const int &)>(),
523  thread_data,
524  /* dummy CopyData object = */ 0,
525  // experimenting shows that we can make things run a bit
526  // faster if we increase the number of cells we work on
527  // per item (i.e., WorkStream's chunk_size argument,
528  // about 10% improvement) and the items in flight at any
529  // given time (another 5% on the testcase discussed in
530  // @ref workstream_paper, on 32 cores) and if
532  64);
533 }
534 
535 
536 
537 template <int dim, typename DoFHandlerType>
540 {
541  return this->triangulation->begin_active ();
542 }
543 
544 
545 
546 template <int dim, typename DoFHandlerType>
550 {
551  // convert the iterator to an active_iterator and advance this to the next
552  // active cell
554  active_cell_iterator active_cell = cell;
555  ++active_cell;
556  return active_cell;
557 }
558 
559 
560 
561 template <int dim, typename DoFHandlerType>
564 {
566  cell = first_cell();
567 
568  // skip cells if the current one has no children (is active) and is a ghost
569  // or artificial cell
570  while ((cell != this->triangulation->end()) &&
571  (cell->has_children() == false) &&
572  !cell->is_locally_owned())
573  cell = next_cell(cell);
574 
575  return cell;
576 }
577 
578 
579 
580 template <int dim, typename DoFHandlerType>
584 {
586  cell = next_cell(old_cell);
587  while ((cell != this->triangulation->end()) &&
588  (cell->has_children() == false) &&
589  !cell->is_locally_owned())
590  cell = next_cell(cell);
591  return cell;
592 }
593 
594 
595 // explicit instantiations
596 #include "data_out.inst"
597 
598 DEAL_II_NAMESPACE_CLOSE
Shape function values.
static const unsigned int invalid_unsigned_int
Definition: types.h:173
static ::ExceptionBase & ExcNoTriangulationSelected()
void build_one_patch(const std::pair< cell_iterator, unsigned int > *cell_and_index, internal::DataOutImplementation::ParallelData< DoFHandlerType::dimension, DoFHandlerType::space_dimension > &scratch_data, const unsigned int n_subdivisions, const CurvedCellRegion curved_cell_region)
Definition: data_out.cc:66
unsigned int neighbors[dim > 0 ? GeometryInfo< dim >::faces_per_cell :1]
virtual cell_iterator next_cell(const cell_iterator &cell)
Definition: data_out.cc:549
const FiniteElement< dim, spacedim > & get_fe() const
Transformed quadrature points.
static ::ExceptionBase & ExcInvalidNumberOfSubdivisions(int arg1)
Point< spacedim > vertices[GeometryInfo< dim >::vertices_per_cell]
virtual void build_patches(const unsigned int n_subdivisions=0)
Definition: data_out.cc:370
const std::vector< Point< spacedim > > & get_quadrature_points() const
unsigned int patch_index
static ::ExceptionBase & ExcMessage(std::string arg1)
virtual cell_iterator first_locally_owned_cell()
Definition: data_out.cc:563
void reinit(const TableIndices< N > &new_size, const bool omit_default_initialization=false)
#define Assert(cond, exc)
Definition: exceptions.h:1142
UpdateFlags
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
Abstract base class for mapping classes.
Definition: dof_tools.h:46
virtual cell_iterator first_cell()
Definition: data_out.cc:539
unsigned int n_subdivisions
DataOut_DoFData< DoFHandler< dim >, DoFHandler< dim > ::dimension, DoFHandler< dim > ::space_dimension >::cell_iterator cell_iterator
Definition: data_out.h:164
Second derivatives of shape functions.
const unsigned int n_quadrature_points
Definition: fe_values.h:1840
size_type size(const unsigned int i) const
static const unsigned int space_dim
Shape function gradients.
Normal vectors.
void run(const std::vector< std::vector< Iterator > > &colored_iterators, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length=2 *MultithreadInfo::n_threads(), const unsigned int chunk_size=8)
Definition: work_stream.h:1106
static ::ExceptionBase & ExcNotImplemented()
static unsigned int n_threads()
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
virtual cell_iterator next_locally_owned_cell(const cell_iterator &cell)
Definition: data_out.cc:583
Table< 2, float > data
static ::ExceptionBase & ExcInternalError()
virtual UpdateFlags get_needed_update_flags() const =0