1 // --------------------------------------------------------------------- 2 // 3 // Copyright (C) 2006 - 2020 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.md at 12 // the top level directory of deal.II. 13 // 14 // --------------------------------------------------------------------- 15 16 17 #ifndef dealii_mesh_worker_integration_info_h 18 #define dealii_mesh_worker_integration_info_h 19 20 #include <deal.II/base/config.h> 21 22 #include <deal.II/base/quadrature_lib.h> 23 24 #include <deal.II/dofs/block_info.h> 25 26 #include <deal.II/fe/fe_values.h> 27 28 #include <deal.II/meshworker/dof_info.h> 29 #include <deal.II/meshworker/local_results.h> 30 #include <deal.II/meshworker/vector_selector.h> 31 32 #include <memory> 33 34 DEAL_II_NAMESPACE_OPEN 35 36 namespace MeshWorker 37 { 38 /** 39 * Class for objects handed to local integration functions. 40 * 41 * Objects of this class contain one or more objects of type FEValues, 42 * FEFaceValues or FESubfaceValues to be used in local integration. They are 43 * stored in an array of pointers to the base classes FEValuesBase. The 44 * template parameter VectorType allows the use of different data types for 45 * the global system. 46 * 47 * Additionally, this function contains space to store the values of finite 48 * element functions stored in #global_data in the quadrature points. These 49 * vectors are initialized automatically on each cell or face. In order to 50 * avoid initializing unused vectors, you can use initialize_selector() to 51 * select the vectors by name that you actually want to use. 52 * 53 * <h3>Integration models</h3> 54 * 55 * This class supports two local integration models, corresponding to the 56 * data models in the documentation of the Assembler namespace. One is the 57 * standard model suggested by the use of FESystem. Namely, there is one 58 * FEValuesBase object in this class, containing all shape functions of the 59 * whole system, and having as many components as the system. Using this 60 * model involves loops over all system shape functions. It requires to 61 * identify the system components for each shape function and to select the 62 * correct bilinear form, usually in an @p if or @p switch statement. 63 * 64 * The second integration model builds one FEValuesBase object per base 65 * element of the system. The degrees of freedom on each cell are renumbered 66 * by block, such that they represent the same block structure as the global 67 * system. Objects performing the integration can then process each block 68 * separately, which improves reusability of code considerably. 69 * 70 * @note As described in DoFInfo, the use of the local block model is 71 * triggered by calling BlockInfo::initialize_local() before using 72 * initialize() in this class. 73 * 74 * @ingroup MeshWorker 75 */ 76 template <int dim, int spacedim = dim> 77 class IntegrationInfo 78 { 79 private: 80 /// vector of FEValues objects 81 std::vector<std::shared_ptr<FEValuesBase<dim, spacedim>>> fevalv; 82 83 public: 84 static const unsigned int dimension = dim; 85 static const unsigned int space_dimension = spacedim; 86 87 /** 88 * Constructor. 89 */ 90 IntegrationInfo(); 91 92 /** 93 * Copy constructor, creating a clone to be used by WorkStream::run(). 94 */ 95 IntegrationInfo(const IntegrationInfo<dim, spacedim> &other); 96 97 /** 98 * Build all internal structures, in particular the FEValuesBase objects 99 * and allocate space for data vectors. 100 * 101 * @param el is the finite element of the DoFHandler. 102 * 103 * @param mapping is the Mapping object used to map the mesh cells. 104 * 105 * @param quadrature is a Quadrature formula used in the constructor of 106 * the FEVALUES objects. 107 * 108 * @param flags are the UpdateFlags used in the constructor of the 109 * FEVALUES objects. 110 * 111 * @param local_block_info is an optional parameter for systems of PDE. If 112 * it is provided with reasonable data, then the degrees of freedom on the 113 * cells will be re-ordered to reflect the block structure of the system. 114 */ 115 template <class FEVALUES> 116 void 117 initialize(const FiniteElement<dim, spacedim> & el, 118 const Mapping<dim, spacedim> & mapping, 119 const Quadrature<FEVALUES::integral_dimension> &quadrature, 120 const UpdateFlags flags, 121 const BlockInfo *local_block_info = nullptr); 122 123 /** 124 * Initialize the data vector and cache the selector. 125 */ 126 void 127 initialize_data(const std::shared_ptr<VectorDataBase<dim, spacedim>> &data); 128 129 /** 130 * Delete the data created by initialize(). 131 */ 132 void 133 clear(); 134 135 /** 136 * Return a reference to the FiniteElement that was used to initialize 137 * this object. 138 */ 139 const FiniteElement<dim, spacedim> & 140 finite_element() const; 141 142 /// This is true if we are assembling for multigrid 143 bool multigrid; 144 /// Access to finite element 145 /** 146 * This is the access function being used, if initialize() for a single 147 * element was used (without the BlockInfo argument). It throws an 148 * exception, if applied to a vector of elements. 149 */ 150 const FEValuesBase<dim, spacedim> & 151 fe_values() const; 152 153 /// Access to finite elements 154 /** 155 * This access function must be used if the initialize() for a group of 156 * elements was used (with a valid BlockInfo object). 157 */ 158 const FEValuesBase<dim, spacedim> & 159 fe_values(const unsigned int i) const; 160 161 /** 162 * The vector containing the values of finite element functions in the 163 * quadrature points. 164 * 165 * There is one vector per selected finite element function, containing 166 * one vector for each component, containing vectors with values for each 167 * quadrature point. 168 */ 169 std::vector<std::vector<std::vector<double>>> values; 170 171 /** 172 * The vector containing the derivatives of finite element functions in 173 * the quadrature points. 174 * 175 * There is one vector per selected finite element function, containing 176 * one vector for each component, containing vectors with values for each 177 * quadrature point. 178 */ 179 std::vector<std::vector<std::vector<Tensor<1, spacedim>>>> gradients; 180 181 /** 182 * The vector containing the second derivatives of finite element 183 * functions in the quadrature points. 184 * 185 * There is one vector per selected finite element function, containing 186 * one vector for each component, containing vectors with values for each 187 * quadrature point. 188 */ 189 std::vector<std::vector<std::vector<Tensor<2, spacedim>>>> hessians; 190 191 /** 192 * Reinitialize internal data structures for use on a cell. 193 */ 194 template <typename number> 195 void 196 reinit(const DoFInfo<dim, spacedim, number> &i); 197 198 /** 199 * Use the finite element functions in #global_data and fill the vectors 200 * #values, #gradients and #hessians. 201 */ 202 template <typename number> 203 void 204 fill_local_data(const DoFInfo<dim, spacedim, number> &info, 205 bool split_fevalues); 206 207 /** 208 * The global data vector used to compute function values in quadrature 209 * points. 210 */ 211 std::shared_ptr<VectorDataBase<dim, spacedim>> global_data; 212 213 /** 214 * The memory used by this object. 215 */ 216 std::size_t 217 memory_consumption() const; 218 219 private: 220 /** 221 * The pointer to the (system) element used for initialization. 222 */ 223 SmartPointer<const FiniteElement<dim, spacedim>, 224 IntegrationInfo<dim, spacedim>> 225 fe_pointer; 226 227 /** 228 * Use the finite element functions in #global_data and fill the vectors 229 * #values, #gradients and #hessians with values according to the 230 * selector. 231 */ 232 template <typename TYPE> 233 void 234 fill_local_data(std::vector<std::vector<std::vector<TYPE>>> &data, 235 VectorSelector & selector, 236 bool split_fevalues) const; 237 /** 238 * Cache the number of components of the system element. 239 */ 240 unsigned int n_components; 241 }; 242 243 /** 244 * The object holding the scratch data for integrating over cells and faces. 245 * IntegrationInfoBox serves three main purposes: 246 * 247 * <ol> 248 * <li> It provides the interface needed by MeshWorker::loop(), namely the 249 * two functions post_cell() and post_faces(), as well as the data members 250 * #cell, #boundary, #face, #subface, and #neighbor. 251 * 252 * <li> It contains all information needed to initialize the FEValues and 253 * FEFaceValues objects in the IntegrationInfo data members. 254 * 255 * <li> It stores information on finite element vectors and whether their 256 * data should be used to compute values or derivatives of functions at 257 * quadrature points. 258 * 259 * <li> It makes educated guesses on quadrature rules and update flags, so 260 * that minimal code has to be written when default parameters are 261 * sufficient. 262 * </ol> 263 * 264 * In order to allow for sufficient generality, a few steps have to be 265 * undertaken to use this class. 266 * 267 * First, you should consider if you need values from any vectors in a 268 * AnyData object. If so, fill the VectorSelector objects #cell_selector, 269 * #boundary_selector and #face_selector with their names and the data type 270 * (value, gradient, Hessian) to be extracted. 271 * 272 * Afterwards, you will need to consider UpdateFlags for FEValues objects. A 273 * good start is initialize_update_flags(), which looks at the selectors 274 * filled before and adds all the flags needed to get the selection. 275 * Additional flags can be set with add_update_flags(). 276 * 277 * Finally, we need to choose quadrature formulas. In the simplest case, you 278 * might be happy with the default settings, which are <i>n</i>-point Gauss 279 * formulas. If only derivatives of the shape functions are used 280 * (#update_values is not set) <i>n</i> equals the highest polynomial degree 281 * in the FiniteElement, if #update_values is set, <i>n</i> is one higher 282 * than this degree. If you choose to use Gauss formulas of other size, use 283 * initialize_gauss_quadrature() with appropriate values. Otherwise, you can 284 * fill the variables #cell_quadrature, #boundary_quadrature and 285 * #face_quadrature directly. 286 * 287 * In order to save time, you can set the variables boundary_fluxes and 288 * interior_fluxes of the base class to false, thus telling the 289 * Meshworker::loop() not to loop over those faces. 290 * 291 * All the information in here is used to set up IntegrationInfo objects 292 * correctly, typically in an IntegrationInfoBox. 293 * 294 * @ingroup MeshWorker 295 */ 296 template <int dim, int spacedim = dim> 297 class IntegrationInfoBox 298 { 299 public: 300 /** 301 * The type of the @p info object for cells. 302 */ 303 using CellInfo = IntegrationInfo<dim, spacedim>; 304 305 /** 306 * Default constructor. 307 */ 308 IntegrationInfoBox(); 309 310 /** 311 * Initialize the IntegrationInfo objects contained. 312 * 313 * Before doing so, add update flags necessary to produce the data needed 314 * and also set uninitialized quadrature rules to Gauss formulas, which 315 * integrate polynomial bilinear forms exactly. 316 */ 317 void 318 initialize(const FiniteElement<dim, spacedim> &el, 319 const Mapping<dim, spacedim> & mapping, 320 const BlockInfo * block_info = nullptr); 321 322 /** 323 * Initialize the IntegrationInfo objects contained. 324 * 325 * Before doing so, add update flags necessary to produce the data needed 326 * and also set uninitialized quadrature rules to Gauss formulas, which 327 * integrate polynomial bilinear forms exactly. 328 */ 329 template <typename VectorType> 330 void 331 initialize(const FiniteElement<dim, spacedim> &el, 332 const Mapping<dim, spacedim> & mapping, 333 const AnyData & data, 334 const VectorType & dummy, 335 const BlockInfo * block_info = nullptr); 336 /** 337 * Initialize the IntegrationInfo objects contained. 338 * 339 * Before doing so, add update flags necessary to produce the data needed 340 * and also set uninitialized quadrature rules to Gauss formulas, which 341 * integrate polynomial bilinear forms exactly. 342 */ 343 template <typename VectorType> 344 void 345 initialize(const FiniteElement<dim, spacedim> &el, 346 const Mapping<dim, spacedim> & mapping, 347 const AnyData & data, 348 const MGLevelObject<VectorType> & dummy, 349 const BlockInfo * block_info = nullptr); 350 /** 351 * @name FEValues setup 352 */ 353 /* @{ */ 354 355 /** 356 * Call this function before initialize() in order to guess the update 357 * flags needed, based on the data selected. 358 * 359 * When computing face fluxes, we normally can use the geometry 360 * (integration weights and normal vectors) from the original cell and 361 * thus can avoid updating these values on the neighboring cell. Set 362 * <tt>neighbor_geometry</tt> to true in order to initialize these values 363 * as well. 364 */ 365 void 366 initialize_update_flags(bool neighbor_geometry = false); 367 368 /** 369 * Add FEValues UpdateFlags for integration on all objects (cells, 370 * boundary faces and all interior faces). 371 */ 372 void 373 add_update_flags_all(const UpdateFlags flags); 374 375 /** 376 * Add FEValues UpdateFlags for integration on cells. 377 */ 378 void 379 add_update_flags_cell(const UpdateFlags flags); 380 381 /** 382 * Add FEValues UpdateFlags for integration on boundary faces. 383 */ 384 void 385 add_update_flags_boundary(const UpdateFlags flags); 386 387 /** 388 * Add FEValues UpdateFlags for integration on interior faces. 389 */ 390 void 391 add_update_flags_face(const UpdateFlags flags); 392 393 /** 394 * Add additional update flags to the ones already set in this program. 395 * The four boolean flags indicate whether the additional flags should be 396 * set for cell, boundary, interelement face for the cell itself or 397 * neighbor cell, or any combination thereof. 398 */ 399 void 400 add_update_flags(const UpdateFlags flags, 401 const bool cell = true, 402 const bool boundary = true, 403 const bool face = true, 404 const bool neighbor = true); 405 406 /** 407 * Assign n-point Gauss quadratures to each of the quadrature rules. Here, 408 * a size of zero points means that no loop over these grid entities 409 * should be performed. 410 * 411 * If the parameter <tt>force</tt> is true, then all quadrature sets are 412 * filled with new quadrature rules. If it is false, then only empty rules 413 * are changed. 414 */ 415 void 416 initialize_gauss_quadrature(unsigned int n_cell_points, 417 unsigned int n_boundary_points, 418 unsigned int n_face_points, 419 const bool force = true); 420 421 /** 422 * The memory used by this object. 423 */ 424 std::size_t 425 memory_consumption() const; 426 427 /** 428 * The set of update flags for boundary cell integration. 429 * 430 * Defaults to #update_JxW_values. 431 */ 432 UpdateFlags cell_flags; 433 /** 434 * The set of update flags for boundary face integration. 435 * 436 * Defaults to #update_JxW_values and #update_normal_vectors. 437 */ 438 UpdateFlags boundary_flags; 439 440 /** 441 * The set of update flags for interior face integration. 442 * 443 * Defaults to #update_JxW_values and #update_normal_vectors. 444 */ 445 UpdateFlags face_flags; 446 447 /** 448 * The set of update flags for interior face integration. 449 * 450 * Defaults to #update_default, since quadrature weights are taken from 451 * the other cell. 452 */ 453 UpdateFlags neighbor_flags; 454 455 /** 456 * The quadrature rule used on cells. 457 */ 458 Quadrature<dim> cell_quadrature; 459 460 /** 461 * The quadrature rule used on boundary faces. 462 */ 463 Quadrature<dim - 1> boundary_quadrature; 464 465 /** 466 * The quadrature rule used on interior faces. 467 */ 468 Quadrature<dim - 1> face_quadrature; 469 /* @} */ 470 471 /** 472 * @name Data vectors 473 */ 474 /* @{ */ 475 476 /** 477 * Initialize the VectorSelector objects #cell_selector, 478 * #boundary_selector and #face_selector in order to save computational 479 * effort. If no selectors are used, then values for all named vectors in 480 * DoFInfo::global_data will be computed in all quadrature points. 481 * 482 * This function will also add UpdateFlags to the flags stored in this 483 * class. 484 */ 485 /** 486 * Select the vectors from DoFInfo::global_data that should be computed in 487 * the quadrature points on cells. 488 */ 489 MeshWorker::VectorSelector cell_selector; 490 491 /** 492 * Select the vectors from DoFInfo::global_data that should be computed in 493 * the quadrature points on boundary faces. 494 */ 495 MeshWorker::VectorSelector boundary_selector; 496 497 /** 498 * Select the vectors from DoFInfo::global_data that should be computed in 499 * the quadrature points on interior faces. 500 */ 501 MeshWorker::VectorSelector face_selector; 502 503 std::shared_ptr<MeshWorker::VectorDataBase<dim, spacedim>> cell_data; 504 std::shared_ptr<MeshWorker::VectorDataBase<dim, spacedim>> boundary_data; 505 std::shared_ptr<MeshWorker::VectorDataBase<dim, spacedim>> face_data; 506 /* @} */ 507 508 /** 509 * @name Interface for MeshWorker::loop() 510 */ 511 /* @{ */ 512 /** 513 * A callback function which is called in the loop over all cells, after 514 * the action on a cell has been performed and before the faces are dealt 515 * with. 516 * 517 * In order for this function to have this effect, at least either of the 518 * arguments <tt>boundary_worker</tt> or <tt>face_worker</tt> arguments of 519 * loop() should be nonzero. Additionally, <tt>cells_first</tt> should be 520 * true. If <tt>cells_first</tt> is false, this function is called before 521 * any action on a cell is taken. 522 * 523 * And empty function in this class, but can be replaced in other classes 524 * given to loop() instead. 525 * 526 * See loop() and cell_action() for more details of how this function can 527 * be used. 528 */ 529 template <class DOFINFO> 530 void 531 post_cell(const DoFInfoBox<dim, DOFINFO> &); 532 533 /** 534 * A callback function which is called in the loop over all cells, after 535 * the action on the faces of a cell has been performed and before the 536 * cell itself is dealt with (assumes <tt>cells_first</tt> is false). 537 * 538 * In order for this function to have a reasonable effect, at least either 539 * of the arguments <tt>boundary_worker</tt> or <tt>face_worker</tt> 540 * arguments of loop() should be nonzero. Additionally, 541 * <tt>cells_first</tt> should be false. 542 * 543 * And empty function in this class, but can be replaced in other classes 544 * given to loop() instead. 545 * 546 * See loop() and cell_action() for more details of how this function can 547 * be used. 548 */ 549 template <class DOFINFO> 550 void 551 post_faces(const DoFInfoBox<dim, DOFINFO> &); 552 553 /** 554 * The @p info object for a cell. 555 */ 556 CellInfo cell; 557 /** 558 * The @p info object for a boundary face. 559 */ 560 CellInfo boundary; 561 /** 562 * The @p info object for a regular interior face, seen from the first cell. 563 */ 564 CellInfo face; 565 /** 566 * The @p info object for the refined side of an interior face seen from the 567 * first cell. 568 */ 569 CellInfo subface; 570 /** 571 * The @p info object for an interior face, seen from the other cell. 572 */ 573 CellInfo neighbor; 574 575 /* @} */ 576 }; 577 578 579 //----------------------------------------------------------------------// 580 581 template <int dim, int sdim> IntegrationInfo()582 inline IntegrationInfo<dim, sdim>::IntegrationInfo() 583 : fevalv(0) 584 , multigrid(false) 585 , global_data(std::make_shared<VectorDataBase<dim, sdim>>()) 586 , n_components(numbers::invalid_unsigned_int) 587 {} 588 589 590 template <int dim, int sdim> IntegrationInfo(const IntegrationInfo<dim,sdim> & other)591 inline IntegrationInfo<dim, sdim>::IntegrationInfo( 592 const IntegrationInfo<dim, sdim> &other) 593 : multigrid(other.multigrid) 594 , values(other.values) 595 , gradients(other.gradients) 596 , hessians(other.hessians) 597 , global_data(other.global_data) 598 , fe_pointer(other.fe_pointer) 599 , n_components(other.n_components) 600 { 601 fevalv.resize(other.fevalv.size()); 602 for (unsigned int i = 0; i < other.fevalv.size(); ++i) 603 { 604 const FEValuesBase<dim, sdim> &p = *other.fevalv[i]; 605 const FEValues<dim, sdim> * pc = 606 dynamic_cast<const FEValues<dim, sdim> *>(&p); 607 const FEFaceValues<dim, sdim> *pf = 608 dynamic_cast<const FEFaceValues<dim, sdim> *>(&p); 609 const FESubfaceValues<dim, sdim> *ps = 610 dynamic_cast<const FESubfaceValues<dim, sdim> *>(&p); 611 612 if (pc != nullptr) 613 fevalv[i] = 614 std::make_shared<FEValues<dim, sdim>>(pc->get_mapping(), 615 pc->get_fe(), 616 pc->get_quadrature(), 617 pc->get_update_flags()); 618 else if (pf != nullptr) 619 fevalv[i] = 620 std::make_shared<FEFaceValues<dim, sdim>>(pf->get_mapping(), 621 pf->get_fe(), 622 pf->get_quadrature(), 623 pf->get_update_flags()); 624 else if (ps != nullptr) 625 fevalv[i] = std::make_shared<FESubfaceValues<dim, sdim>>( 626 ps->get_mapping(), 627 ps->get_fe(), 628 ps->get_quadrature(), 629 ps->get_update_flags()); 630 else 631 Assert(false, ExcInternalError()); 632 } 633 } 634 635 636 637 template <int dim, int sdim> 638 template <class FEVALUES> 639 inline void initialize(const FiniteElement<dim,sdim> & el,const Mapping<dim,sdim> & mapping,const Quadrature<FEVALUES::integral_dimension> & quadrature,const UpdateFlags flags,const BlockInfo * block_info)640 IntegrationInfo<dim, sdim>::initialize( 641 const FiniteElement<dim, sdim> & el, 642 const Mapping<dim, sdim> & mapping, 643 const Quadrature<FEVALUES::integral_dimension> &quadrature, 644 const UpdateFlags flags, 645 const BlockInfo * block_info) 646 { 647 fe_pointer = ⪙ 648 if (block_info == nullptr || block_info->local().size() == 0) 649 { 650 fevalv.resize(1); 651 fevalv[0] = std::make_shared<FEVALUES>(mapping, el, quadrature, flags); 652 } 653 else 654 { 655 fevalv.resize(el.n_base_elements()); 656 for (unsigned int i = 0; i < fevalv.size(); ++i) 657 fevalv[i] = std::make_shared<FEVALUES>(mapping, 658 el.base_element(i), 659 quadrature, 660 flags); 661 } 662 n_components = el.n_components(); 663 } 664 665 666 template <int dim, int spacedim> 667 inline const FiniteElement<dim, spacedim> & finite_element()668 IntegrationInfo<dim, spacedim>::finite_element() const 669 { 670 Assert(fe_pointer != nullptr, ExcNotInitialized()); 671 return *fe_pointer; 672 } 673 674 template <int dim, int spacedim> 675 inline const FEValuesBase<dim, spacedim> & fe_values()676 IntegrationInfo<dim, spacedim>::fe_values() const 677 { 678 AssertDimension(fevalv.size(), 1); 679 return *fevalv[0]; 680 } 681 682 683 template <int dim, int spacedim> 684 inline const FEValuesBase<dim, spacedim> & fe_values(unsigned int i)685 IntegrationInfo<dim, spacedim>::fe_values(unsigned int i) const 686 { 687 AssertIndexRange(i, fevalv.size()); 688 return *fevalv[i]; 689 } 690 691 692 template <int dim, int spacedim> 693 template <typename number> 694 inline void reinit(const DoFInfo<dim,spacedim,number> & info)695 IntegrationInfo<dim, spacedim>::reinit( 696 const DoFInfo<dim, spacedim, number> &info) 697 { 698 for (unsigned int i = 0; i < fevalv.size(); ++i) 699 { 700 FEValuesBase<dim, spacedim> &febase = *fevalv[i]; 701 if (info.sub_number != numbers::invalid_unsigned_int) 702 { 703 // This is a subface 704 FESubfaceValues<dim, spacedim> &fe = 705 dynamic_cast<FESubfaceValues<dim, spacedim> &>(febase); 706 fe.reinit(info.cell, info.face_number, info.sub_number); 707 } 708 else if (info.face_number != numbers::invalid_unsigned_int) 709 { 710 // This is a face 711 FEFaceValues<dim, spacedim> &fe = 712 dynamic_cast<FEFaceValues<dim, spacedim> &>(febase); 713 fe.reinit(info.cell, info.face_number); 714 } 715 else 716 { 717 // This is a cell 718 FEValues<dim, spacedim> &fe = 719 dynamic_cast<FEValues<dim, spacedim> &>(febase); 720 fe.reinit(info.cell); 721 } 722 } 723 724 const bool split_fevalues = info.block_info != nullptr; 725 if (!global_data->empty()) 726 fill_local_data(info, split_fevalues); 727 } 728 729 730 731 //----------------------------------------------------------------------// 732 733 template <int dim, int sdim> 734 inline void initialize_gauss_quadrature(unsigned int cp,unsigned int bp,unsigned int fp,bool force)735 IntegrationInfoBox<dim, sdim>::initialize_gauss_quadrature(unsigned int cp, 736 unsigned int bp, 737 unsigned int fp, 738 bool force) 739 { 740 if (force || cell_quadrature.size() == 0) 741 cell_quadrature = QGauss<dim>(cp); 742 if (force || boundary_quadrature.size() == 0) 743 boundary_quadrature = QGauss<dim - 1>(bp); 744 if (force || face_quadrature.size() == 0) 745 face_quadrature = QGauss<dim - 1>(fp); 746 } 747 748 749 template <int dim, int sdim> 750 inline void add_update_flags_all(const UpdateFlags flags)751 IntegrationInfoBox<dim, sdim>::add_update_flags_all(const UpdateFlags flags) 752 { 753 add_update_flags(flags, true, true, true, true); 754 } 755 756 757 template <int dim, int sdim> 758 inline void add_update_flags_cell(const UpdateFlags flags)759 IntegrationInfoBox<dim, sdim>::add_update_flags_cell(const UpdateFlags flags) 760 { 761 add_update_flags(flags, true, false, false, false); 762 } 763 764 765 template <int dim, int sdim> 766 inline void add_update_flags_boundary(const UpdateFlags flags)767 IntegrationInfoBox<dim, sdim>::add_update_flags_boundary( 768 const UpdateFlags flags) 769 { 770 add_update_flags(flags, false, true, false, false); 771 } 772 773 774 template <int dim, int sdim> 775 inline void add_update_flags_face(const UpdateFlags flags)776 IntegrationInfoBox<dim, sdim>::add_update_flags_face(const UpdateFlags flags) 777 { 778 add_update_flags(flags, false, false, true, true); 779 } 780 781 782 template <int dim, int sdim> 783 inline void initialize(const FiniteElement<dim,sdim> & el,const Mapping<dim,sdim> & mapping,const BlockInfo * block_info)784 IntegrationInfoBox<dim, sdim>::initialize(const FiniteElement<dim, sdim> &el, 785 const Mapping<dim, sdim> &mapping, 786 const BlockInfo *block_info) 787 { 788 initialize_update_flags(); 789 initialize_gauss_quadrature((cell_flags & update_values) ? 790 (el.tensor_degree() + 1) : 791 el.tensor_degree(), 792 (boundary_flags & update_values) ? 793 (el.tensor_degree() + 1) : 794 el.tensor_degree(), 795 (face_flags & update_values) ? 796 (el.tensor_degree() + 1) : 797 el.tensor_degree(), 798 false); 799 800 cell.template initialize<FEValues<dim, sdim>>( 801 el, mapping, cell_quadrature, cell_flags, block_info); 802 boundary.template initialize<FEFaceValues<dim, sdim>>( 803 el, mapping, boundary_quadrature, boundary_flags, block_info); 804 face.template initialize<FEFaceValues<dim, sdim>>( 805 el, mapping, face_quadrature, face_flags, block_info); 806 subface.template initialize<FESubfaceValues<dim, sdim>>( 807 el, mapping, face_quadrature, face_flags, block_info); 808 neighbor.template initialize<FEFaceValues<dim, sdim>>( 809 el, mapping, face_quadrature, neighbor_flags, block_info); 810 } 811 812 813 template <int dim, int sdim> 814 template <typename VectorType> 815 void initialize(const FiniteElement<dim,sdim> & el,const Mapping<dim,sdim> & mapping,const AnyData & data,const VectorType &,const BlockInfo * block_info)816 IntegrationInfoBox<dim, sdim>::initialize(const FiniteElement<dim, sdim> &el, 817 const Mapping<dim, sdim> &mapping, 818 const AnyData & data, 819 const VectorType &, 820 const BlockInfo *block_info) 821 { 822 initialize(el, mapping, block_info); 823 std::shared_ptr<VectorData<VectorType, dim, sdim>> p; 824 VectorDataBase<dim, sdim> * pp; 825 826 p = std::make_shared<VectorData<VectorType, dim, sdim>>(cell_selector); 827 // Public member function of parent class was not found without 828 // explicit cast 829 pp = &*p; 830 pp->initialize(data); 831 cell_data = p; 832 cell.initialize_data(p); 833 834 p = std::make_shared<VectorData<VectorType, dim, sdim>>(boundary_selector); 835 pp = &*p; 836 pp->initialize(data); 837 boundary_data = p; 838 boundary.initialize_data(p); 839 840 p = std::make_shared<VectorData<VectorType, dim, sdim>>(face_selector); 841 pp = &*p; 842 pp->initialize(data); 843 face_data = p; 844 face.initialize_data(p); 845 subface.initialize_data(p); 846 neighbor.initialize_data(p); 847 } 848 849 template <int dim, int sdim> 850 template <typename VectorType> 851 void initialize(const FiniteElement<dim,sdim> & el,const Mapping<dim,sdim> & mapping,const AnyData & data,const MGLevelObject<VectorType> &,const BlockInfo * block_info)852 IntegrationInfoBox<dim, sdim>::initialize(const FiniteElement<dim, sdim> &el, 853 const Mapping<dim, sdim> &mapping, 854 const AnyData & data, 855 const MGLevelObject<VectorType> &, 856 const BlockInfo *block_info) 857 { 858 initialize(el, mapping, block_info); 859 std::shared_ptr<MGVectorData<VectorType, dim, sdim>> p; 860 VectorDataBase<dim, sdim> * pp; 861 862 p = std::make_shared<MGVectorData<VectorType, dim, sdim>>(cell_selector); 863 // Public member function of parent class was not found without 864 // explicit cast 865 pp = &*p; 866 pp->initialize(data); 867 cell_data = p; 868 cell.initialize_data(p); 869 870 p = 871 std::make_shared<MGVectorData<VectorType, dim, sdim>>(boundary_selector); 872 pp = &*p; 873 pp->initialize(data); 874 boundary_data = p; 875 boundary.initialize_data(p); 876 877 p = std::make_shared<MGVectorData<VectorType, dim, sdim>>(face_selector); 878 pp = &*p; 879 pp->initialize(data); 880 face_data = p; 881 face.initialize_data(p); 882 subface.initialize_data(p); 883 neighbor.initialize_data(p); 884 } 885 886 template <int dim, int sdim> 887 template <class DOFINFO> 888 void post_cell(const DoFInfoBox<dim,DOFINFO> &)889 IntegrationInfoBox<dim, sdim>::post_cell(const DoFInfoBox<dim, DOFINFO> &) 890 {} 891 892 893 template <int dim, int sdim> 894 template <class DOFINFO> 895 void post_faces(const DoFInfoBox<dim,DOFINFO> &)896 IntegrationInfoBox<dim, sdim>::post_faces(const DoFInfoBox<dim, DOFINFO> &) 897 {} 898 899 900 } // namespace MeshWorker 901 902 DEAL_II_NAMESPACE_CLOSE 903 904 #endif 905