This file is indexed.

/usr/include/deal.II/hp/fe_collection.h is in libdeal.ii-dev 8.4.2-2+b1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
// ---------------------------------------------------------------------
//
// Copyright (C) 2003 - 2016 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, redistribute
// it, and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE at
// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------

#ifndef dealii__fe_collection_h
#define dealii__fe_collection_h

#include <deal.II/base/config.h>
#include <deal.II/base/std_cxx11/shared_ptr.h>
#include <deal.II/fe/fe.h>
#include <deal.II/fe/fe_values_extractors.h>
#include <deal.II/fe/component_mask.h>

DEAL_II_NAMESPACE_OPEN

namespace hp
{

  /**
   * This class acts as a collection of finite element objects used in the
   * hp::DoFHandler. It is thus to a hp::DoFHandler what a FiniteElement is to
   * a ::DoFHandler.
   *
   * It implements the concepts stated in the
   * @ref hpcollection
   * module described in the doxygen documentation.
   *
   * In addition to offering access to the elements of the collection, this
   * class provides access to the maximal number of degrees of freedom per
   * vertex, line, etc, to allow allocation of as much memory as is necessary
   * in the worst case when using the finite elements associated with the
   * cells of a triangulation.
   *
   * This class has not yet been implemented for the use in the codimension
   * one case (<tt>spacedim != dim </tt>).
   *
   * @ingroup hp hpcollection
   *
   * @author Wolfgang Bangerth, 2003
   */
  template <int dim, int spacedim=dim>
  class FECollection : public Subscriptor
  {
  public:
    /**
     * Default constructor. Leads to an empty collection that can later be
     * filled using push_back().
     */
    FECollection ();

    /**
     * Conversion constructor. This constructor creates a FECollection from a
     * single finite element. More finite element objects can be added with
     * push_back(), if desired, though it would probably be clearer to add all
     * mappings the same way.
     */
    explicit FECollection (const FiniteElement<dim,spacedim> &fe);

    /**
     * Constructor. This constructor creates a FECollection from two finite
     * elements.
     */
    FECollection (const FiniteElement<dim,spacedim> &fe1,
                  const FiniteElement<dim,spacedim> &fe2);

    /**
     * Constructor. This constructor creates a FECollection from three finite
     * elements.
     */
    FECollection (const FiniteElement<dim,spacedim> &fe1,
                  const FiniteElement<dim,spacedim> &fe2,
                  const FiniteElement<dim,spacedim> &fe3);

    /**
     * Constructor. This constructor creates a FECollection from four finite
     * elements.
     */
    FECollection (const FiniteElement<dim,spacedim> &fe1,
                  const FiniteElement<dim,spacedim> &fe2,
                  const FiniteElement<dim,spacedim> &fe3,
                  const FiniteElement<dim,spacedim> &fe4);

    /**
     * Constructor. This constructor creates a FECollection from five finite
     * elements.
     */
    FECollection (const FiniteElement<dim,spacedim> &fe1,
                  const FiniteElement<dim,spacedim> &fe2,
                  const FiniteElement<dim,spacedim> &fe3,
                  const FiniteElement<dim,spacedim> &fe4,
                  const FiniteElement<dim,spacedim> &fe5);

    /**
     * Constructor. Same as above but for any number of elements. Pointers to
     * the elements are passed in a vector to this constructor. As above, the
     * finite element objects pointed to by the argument are not actually used
     * other than to create copies internally. Consequently, you can delete
     * these pointers immediately again after calling this constructor.
     */
    FECollection (const std::vector<const FiniteElement<dim,spacedim>*> &fes);

    /**
     * Copy constructor.
     */
    FECollection (const FECollection<dim,spacedim> &fe_collection);

    /**
     * Add a finite element. This function generates a copy of the given
     * element, i.e. you can do things like <tt>push_back(FE_Q<dim>(1));</tt>.
     * The internal copy is later destroyed by this object upon destruction of
     * the entire collection.
     *
     * When a new element is added, it needs to have the same number of vector
     * components as all other elements already in the collection.
     */
    void push_back (const FiniteElement<dim,spacedim> &new_fe);

    /**
     * Get a reference to the given element in this collection.
     *
     * @pre @p index must be between zero and the number of elements of the
     * collection.
     */
    const FiniteElement<dim,spacedim> &
    operator[] (const unsigned int index) const;

    /**
     * Return the number of finite element objects stored in this collection.
     */
    unsigned int size () const;

    /**
     * Return the number of vector components of the finite elements in this
     * collection.  This number must be the same for all elements in the
     * collection.
     *
     * This function calls FiniteElement::n_components.  See
     * @ref GlossComponent "the glossary"
     * for more information.
     */
    unsigned int n_components () const;

    /**
     * Return the number of vector blocks of the finite elements in this
     * collection. While this class ensures that all elements stored in it
     * have the same number of vector components, there is no such guarantees
     * for the number of blocks each element is made up of (an element may
     * have fewer blocks than vector components; see
     * @ref GlossBlock "the glossary"
     * for more information). For example, you may have an FECollection object
     * that stores one copy of an FESystem with <code>dim</code> FE_Q objects
     * and one copy of an FE_RaviartThomas element. Both have <code>dim</code>
     * vector components but while the former has <code>dim</code> blocks the
     * latter has only one. Consequently, this function will throw an
     * assertion if the number of blocks is not the same for all elements. If
     * they are the same, this function returns the result of
     * FiniteElement::n_blocks().
     */
    unsigned int n_blocks () const;

    /**
     * Return the maximal number of degrees of freedom per vertex over all
     * elements of this collection.
     */
    unsigned int max_dofs_per_vertex () const;

    /**
     * Return the maximal number of degrees of freedom per line over all
     * elements of this collection.
     */
    unsigned int max_dofs_per_line () const;

    /**
     * Return the maximal number of degrees of freedom per quad over all
     * elements of this collection.
     */
    unsigned int max_dofs_per_quad () const;

    /**
     * Return the maximal number of degrees of freedom per hex over all
     * elements of this collection.
     */
    unsigned int max_dofs_per_hex () const;

    /**
     * Return the maximal number of degrees of freedom per face over all
     * elements of this collection.
     */
    unsigned int max_dofs_per_face () const;

    /**
     * Return the maximal number of degrees of freedom per cell over all
     * elements of this collection.
     */
    unsigned int max_dofs_per_cell () const;

    /**
     * Return an estimate for the memory allocated for this object.
     */
    std::size_t memory_consumption () const;


    /**
     * Return whether all elements in this collection implement the hanging
     * node constraints in the new way, which has to be used to make elements
     * "hp compatible". If this is not the case, the function returns false,
     * which implies, that at least one element in the FECollection does not
     * support the new face interface constraints. On the other hand, if this
     * method does return true, this does not imply that the hp method will
     * work!
     *
     * This behaviour is related to the fact, that FiniteElement classes,
     * which provide the new style hanging node constraints might still not
     * provide them for all possible cases. If FE_Q and FE_RaviartThomas
     * elements are included in the FECollection and both properly implement
     * the get_face_interpolation_matrix method, this method will return true.
     * But the get_face_interpolation_matrix might still fail to find an
     * interpolation matrix between these two elements.
     */
    bool hp_constraints_are_implemented () const;

    /**
     * Try to find a least dominant finite element inside this FECollection
     * which dominates other finite elements provided as fe_indices in @p fes
     * . For example, if FECollection consists of {Q1,Q2,Q3,Q4} and we are
     * looking for the least dominant FE for Q3 and Q4 (@p fes is {2,3}), then
     * the answer is Q3 and therefore this function will return its index in
     * FECollection, namely 2.
     *
     * For the purpose of this function by domination we consider either
     * this_element_dominate or either_element_can_dominate ; therefore the
     * element can dominate itself. Thus if FECollection contains
     * {Q1,Q2,Q4,Q3} and @p fes = {3}, the function returns 3.
     *
     * If we were not able to find a finite element, the function returns
     * numbers::invalid_unsigned_int .
     *
     * Note that for the cases like when FECollection consists of {FE_Nothing
     * x FE_Nothing, Q1xQ2, Q2xQ1} with @p fes = {1}, the function will not
     * find the most dominating element as the default behavior of FE_Nothing
     * is to return FiniteElementDomination::no_requirements when comparing
     * for face domination. This, therefore, can't be considered as a
     * dominating element in the sense described above .
     */
    unsigned int
    find_least_face_dominating_fe (const std::set<unsigned int> &fes) const;

    /**
     * Return a component mask with as many elements as this object has vector
     * components and of which exactly the one component is true that
     * corresponds to the given argument.
     *
     * @note This function is the equivalent of
     * FiniteElement::component_mask() with the same arguments. It verifies
     * that it gets the same result from every one of the elements that are
     * stored in this FECollection. If this is not the case, it throws an
     * exception.
     *
     * @param scalar An object that represents a single scalar vector
     * component of this finite element.
     * @return A component mask that is false in all components except for the
     * one that corresponds to the argument.
     */
    ComponentMask
    component_mask (const FEValuesExtractors::Scalar &scalar) const;

    /**
     * Return a component mask with as many elements as this object has vector
     * components and of which exactly the <code>dim</code> components are
     * true that correspond to the given argument.
     *
     * @note This function is the equivalent of
     * FiniteElement::component_mask() with the same arguments. It verifies
     * that it gets the same result from every one of the elements that are
     * stored in this FECollection. If this is not the case, it throws an
     * exception.
     *
     * @param vector An object that represents dim vector components of this
     * finite element.
     * @return A component mask that is false in all components except for the
     * ones that corresponds to the argument.
     */
    ComponentMask
    component_mask (const FEValuesExtractors::Vector &vector) const;

    /**
     * Return a component mask with as many elements as this object has vector
     * components and of which exactly the <code>dim*(dim+1)/2</code>
     * components are true that correspond to the given argument.
     *
     * @note This function is the equivalent of
     * FiniteElement::component_mask() with the same arguments. It verifies
     * that it gets the same result from every one of the elements that are
     * stored in this FECollection. If this is not the case, it throws an
     * exception.
     *
     * @param sym_tensor An object that represents dim*(dim+1)/2 components of
     * this finite element that are jointly to be interpreted as forming a
     * symmetric tensor.
     * @return A component mask that is false in all components except for the
     * ones that corresponds to the argument.
     */
    ComponentMask
    component_mask (const FEValuesExtractors::SymmetricTensor<2> &sym_tensor) const;

    /**
     * Given a block mask (see
     * @ref GlossBlockMask "this glossary entry"
     * ), produce a component mask (see
     * @ref GlossComponentMask "this glossary entry"
     * ) that represents the components that correspond to the blocks selected
     * in the input argument. This is essentially a conversion operator from
     * BlockMask to ComponentMask.
     *
     * @note This function is the equivalent of
     * FiniteElement::component_mask() with the same arguments. It verifies
     * that it gets the same result from every one of the elements that are
     * stored in this FECollection. If this is not the case, it throws an
     * exception.
     *
     * @param block_mask The mask that selects individual blocks of the finite
     * element
     * @return A mask that selects those components corresponding to the
     * selected blocks of the input argument.
     */
    ComponentMask
    component_mask (const BlockMask &block_mask) const;

    /**
     * Return a block mask with as many elements as this object has blocks and
     * of which exactly the one component is true that corresponds to the
     * given argument. See
     * @ref GlossBlockMask "the glossary"
     * for more information.
     *
     * @note This function will only succeed if the scalar referenced by the
     * argument encompasses a complete block. In other words, if, for example,
     * you pass an extractor for the single $x$ velocity and this object
     * represents an FE_RaviartThomas object, then the single scalar object
     * you selected is part of a larger block and consequently there is no
     * block mask that would represent it. The function will then produce an
     * exception.
     *
     * @note This function is the equivalent of
     * FiniteElement::component_mask() with the same arguments. It verifies
     * that it gets the same result from every one of the elements that are
     * stored in this FECollection. If this is not the case, it throws an
     * exception.
     *
     * @param scalar An object that represents a single scalar vector
     * component of this finite element.
     * @return A component mask that is false in all components except for the
     * one that corresponds to the argument.
     */
    BlockMask
    block_mask (const FEValuesExtractors::Scalar &scalar) const;

    /**
     * Return a component mask with as many elements as this object has vector
     * components and of which exactly the <code>dim</code> components are
     * true that correspond to the given argument. See
     * @ref GlossBlockMask "the glossary"
     * for more information.
     *
     * @note This function is the equivalent of
     * FiniteElement::component_mask() with the same arguments. It verifies
     * that it gets the same result from every one of the elements that are
     * stored in this FECollection. If this is not the case, it throws an
     * exception.
     *
     * @note The same caveat applies as to the version of the function above:
     * The extractor object passed as argument must be so that it corresponds
     * to full blocks and does not split blocks of this element.
     *
     * @param vector An object that represents dim vector components of this
     * finite element.
     * @return A component mask that is false in all components except for the
     * ones that corresponds to the argument.
     */
    BlockMask
    block_mask (const FEValuesExtractors::Vector &vector) const;

    /**
     * Return a component mask with as many elements as this object has vector
     * components and of which exactly the <code>dim*(dim+1)/2</code>
     * components are true that correspond to the given argument. See
     * @ref GlossBlockMask "the glossary"
     * for more information.
     *
     * @note The same caveat applies as to the version of the function above:
     * The extractor object passed as argument must be so that it corresponds
     * to full blocks and does not split blocks of this element.
     *
     * @note This function is the equivalent of
     * FiniteElement::component_mask() with the same arguments. It verifies
     * that it gets the same result from every one of the elements that are
     * stored in this FECollection. If this is not the case, it throws an
     * exception.
     *
     * @param sym_tensor An object that represents dim*(dim+1)/2 components of
     * this finite element that are jointly to be interpreted as forming a
     * symmetric tensor.
     * @return A component mask that is false in all components except for the
     * ones that corresponds to the argument.
     */
    BlockMask
    block_mask (const FEValuesExtractors::SymmetricTensor<2> &sym_tensor) const;

    /**
     * Given a component mask (see
     * @ref GlossComponentMask "this glossary entry"
     * ), produce a block mask (see
     * @ref GlossBlockMask "this glossary entry"
     * ) that represents the blocks that correspond to the components selected
     * in the input argument. This is essentially a conversion operator from
     * ComponentMask to BlockMask.
     *
     * @note This function will only succeed if the components referenced by
     * the argument encompasses complete blocks. In other words, if, for
     * example, you pass an component mask for the single $x$ velocity and
     * this object represents an FE_RaviartThomas object, then the single
     * component you selected is part of a larger block and consequently there
     * is no block mask that would represent it. The function will then
     * produce an exception.
     *
     * @note This function is the equivalent of
     * FiniteElement::component_mask() with the same arguments. It verifies
     * that it gets the same result from every one of the elements that are
     * stored in this FECollection. If this is not the case, it throws an
     * exception.
     *
     * @param component_mask The mask that selects individual components of
     * the finite element
     * @return A mask that selects those blocks corresponding to the selected
     * blocks of the input argument.
     */
    BlockMask
    block_mask (const ComponentMask &component_mask) const;


    /**
     * Exception
     */
    DeclException0 (ExcNoFiniteElements);

  private:
    /**
     * Array of pointers to the finite elements stored by this collection.
     */
    std::vector<std_cxx11::shared_ptr<const FiniteElement<dim,spacedim> > > finite_elements;
  };



  /* --------------- inline functions ------------------- */

  template <int dim, int spacedim>
  inline
  unsigned int
  FECollection<dim,spacedim>::size () const
  {
    return finite_elements.size();
  }


  template <int dim, int spacedim>
  inline
  unsigned int
  FECollection<dim,spacedim>::n_components () const
  {
    Assert (finite_elements.size () > 0, ExcNoFiniteElements());

    // note that there is no need
    // here to enforce that indeed
    // all elements have the same
    // number of components since we
    // have already done this when
    // adding a new element to the
    // collection.

    return finite_elements[0]->n_components ();
  }


  template <int dim, int spacedim>
  inline
  const FiniteElement<dim,spacedim> &
  FECollection<dim,spacedim>::operator[] (const unsigned int index) const
  {
    Assert (index < finite_elements.size(),
            ExcIndexRange (index, 0, finite_elements.size()));
    return *finite_elements[index];
  }



  template <int dim, int spacedim>
  unsigned int
  FECollection<dim,spacedim>::max_dofs_per_vertex () const
  {
    Assert (finite_elements.size() > 0, ExcNoFiniteElements());

    unsigned int max = 0;
    for (unsigned int i=0; i<finite_elements.size(); ++i)
      if (finite_elements[i]->dofs_per_vertex > max)
        max = finite_elements[i]->dofs_per_vertex;

    return max;
  }



  template <int dim, int spacedim>
  unsigned int
  FECollection<dim,spacedim>::max_dofs_per_line () const
  {
    Assert (finite_elements.size() > 0, ExcNoFiniteElements());

    unsigned int max = 0;
    for (unsigned int i=0; i<finite_elements.size(); ++i)
      if (finite_elements[i]->dofs_per_line > max)
        max = finite_elements[i]->dofs_per_line;

    return max;
  }



  template <int dim, int spacedim>
  unsigned int
  FECollection<dim,spacedim>::max_dofs_per_quad () const
  {
    Assert (finite_elements.size() > 0, ExcNoFiniteElements());

    unsigned int max = 0;
    for (unsigned int i=0; i<finite_elements.size(); ++i)
      if (finite_elements[i]->dofs_per_quad > max)
        max = finite_elements[i]->dofs_per_quad;

    return max;
  }



  template <int dim, int spacedim>
  unsigned int
  FECollection<dim,spacedim>::max_dofs_per_hex () const
  {
    Assert (finite_elements.size() > 0, ExcNoFiniteElements());

    unsigned int max = 0;
    for (unsigned int i=0; i<finite_elements.size(); ++i)
      if (finite_elements[i]->dofs_per_hex > max)
        max = finite_elements[i]->dofs_per_hex;

    return max;
  }



  template <int dim, int spacedim>
  unsigned int
  FECollection<dim,spacedim>::max_dofs_per_face () const
  {
    Assert (finite_elements.size() > 0, ExcNoFiniteElements());

    unsigned int max = 0;
    for (unsigned int i=0; i<finite_elements.size(); ++i)
      if (finite_elements[i]->dofs_per_face > max)
        max = finite_elements[i]->dofs_per_face;

    return max;
  }



  template <int dim, int spacedim>
  unsigned int
  FECollection<dim,spacedim>::max_dofs_per_cell () const
  {
    Assert (finite_elements.size() > 0, ExcNoFiniteElements());

    unsigned int max = 0;
    for (unsigned int i=0; i<finite_elements.size(); ++i)
      if (finite_elements[i]->dofs_per_cell > max)
        max = finite_elements[i]->dofs_per_cell;

    return max;
  }


  template <int dim, int spacedim>
  bool
  FECollection<dim,spacedim>::hp_constraints_are_implemented () const
  {
    Assert (finite_elements.size() > 0, ExcNoFiniteElements());

    bool hp_constraints = true;
    for (unsigned int i=0; i<finite_elements.size(); ++i)
      hp_constraints = hp_constraints &&
                       finite_elements[i]->hp_constraints_are_implemented();

    return hp_constraints;
  }


} // namespace hp

DEAL_II_NAMESPACE_CLOSE

#endif