DOpE
integrator_multimesh.h
Go to the documentation of this file.
1 
24 #ifndef _IntegratorMultiMesh_H_
25 #define _IntegratorMultiMesh_H_
26 
27 #include <lac/vector.h>
28 #include <lac/block_sparsity_pattern.h>
29 #include <lac/block_sparse_matrix.h>
30 
31 #include <numerics/matrix_tools.h>
32 #include <numerics/vector_tools.h>
33 #include <deal.II/grid/grid_tools.h>
34 #include <base/function.h>
35 
36 #include <vector>
37 
40 
41 namespace DOpE
42 {
60  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
61  int dim>
63  {
64  public:
65  IntegratorMultiMesh(INTEGRATORDATACONT& idc);
66 
68 
69  void
70  ReInit();
71 
72  template<typename PROBLEM>
73  void
74  ComputeNonlinearResidual(PROBLEM& pde, VECTOR &residual,
75  bool apply_boundary_values = true);
76  template<typename PROBLEM>
77  void
78  ComputeNonlinearLhs(PROBLEM& pde, VECTOR &residual,
79  bool apply_boundary_values = true);
80  template<typename PROBLEM>
81  void
82  ComputeNonlinearRhs(PROBLEM& pde, VECTOR &residual,
83  bool apply_boundary_values = true);
84  template<typename PROBLEM, typename MATRIX>
85  void
86  ComputeMatrix(PROBLEM& pde, MATRIX &matrix);
87 
88  template<typename PROBLEM>
89  void ComputeNonlinearAlgebraicResidual (PROBLEM& pde, VECTOR &residual);
90  template<typename PROBLEM>
91  void ComputeLocalControlConstraints (PROBLEM& pde, VECTOR &constraints);
92 
93  template<typename PROBLEM>
94  SCALAR
95  ComputeDomainScalar(PROBLEM& pde);
96  template<typename PROBLEM>
97  SCALAR
98  ComputePointScalar(PROBLEM& pde);
99  template<typename PROBLEM>
100  SCALAR
101  ComputeBoundaryScalar(PROBLEM& pde);
102  template<typename PROBLEM>
103  SCALAR
104  ComputeFaceScalar(PROBLEM& pde);
105  template<typename PROBLEM>
106  SCALAR
107  ComputeAlgebraicScalar(PROBLEM& pde);
108 
109  template<typename PROBLEM>
110  void
111  ApplyInitialBoundaryValues(PROBLEM& pde, VECTOR &u);
112  template<typename PROBLEM>
113  void
114  ApplyNewtonBoundaryValues(PROBLEM& pde, VECTOR &u);
115  template<typename PROBLEM, typename MATRIX>
116  void
117  ApplyNewtonBoundaryValues(PROBLEM& pde, MATRIX &matrix, VECTOR &rhs,
118  VECTOR &sol);
119 
120  inline void
121  AddDomainData(std::string name, const VECTOR* new_data);
122  inline void
123  DeleteDomainData(std::string name);
124  inline const std::map<std::string, const VECTOR*>&
125  GetDomainData() const;
126 
127  inline void
128  AddParamData(std::string name, const dealii::Vector<SCALAR>* new_data);
129  inline void
130  DeleteParamData(std::string name);
131  inline const std::map<std::string, const dealii::Vector<SCALAR>*>&
132  GetParamData() const;
133 
134  inline INTEGRATORDATACONT&
136 
137  private:
138  template<template<int, int> class DH>
139  void
140  InterpolateBoundaryValues(
141  const DOpEWrapper::DoFHandler<dim, DH>* dof_handler,
142  const unsigned int color, const dealii::Function<dim>& function,
143  std::map<unsigned int, SCALAR>& boundary_values,
144  const std::vector<bool>& comp_mask) const;
145 
150  template<typename PROBLEM, template<int, int> class DH>
151  inline void ComputeNonlinearResidual_Recursive(
152  PROBLEM& pde,
153  VECTOR& residual,
154  typename std::vector<typename DH<dim, dim>::cell_iterator>& element_iter,
155  typename std::vector<typename dealii::Triangulation<dim>::cell_iterator>& tria_element_iter,
156  const FullMatrix<SCALAR>& prolong_matrix,unsigned int coarse_index,unsigned int fine_index,
159 
164  template<typename PROBLEM, template<int, int> class DH>
165  inline void ComputeNonlinearRhs_Recursive(
166  PROBLEM& pde,
167  VECTOR& residual,
168  typename std::vector<typename DH<dim, dim>::cell_iterator>& element_iter,
169  typename std::vector<typename dealii::Triangulation<dim>::cell_iterator>& tria_element_iter,
170  const FullMatrix<SCALAR>& prolong_matrix,unsigned int coarse_index,unsigned int fine_index,
173 
178  template<typename PROBLEM, typename MATRIX, template<int, int> class DH>
179  inline void ComputeMatrix_Recursive(
180  PROBLEM& pde,
181  MATRIX& matrix,
182  typename std::vector<typename DH<dim, dim>::cell_iterator>& element_iter,
183  typename std::vector<typename dealii::Triangulation<dim>::cell_iterator>& tria_element_iter,
184  const FullMatrix<SCALAR>& prolong_matrix,unsigned int coarse_index,unsigned int fine_index,
187 
192  template<typename PROBLEM, template<int, int> class DH>
193  inline SCALAR ComputeDomainScalar_Recursive(
194  PROBLEM& pde,
195  typename std::vector<typename DH<dim, dim>::cell_iterator>& element_iter,
196  typename std::vector<typename dealii::Triangulation<dim>::cell_iterator>& tria_element_iter,
197  const FullMatrix<SCALAR>& prolong_matrix,unsigned int coarse_index,unsigned int fine_index,
199 
204  template<typename PROBLEM, template<int, int> class DH>
205  inline SCALAR ComputeBoundaryScalar_Recursive(
206  PROBLEM& pde,
207  typename std::vector<typename DH<dim, dim>::cell_iterator>& element_iter,
208  typename std::vector<typename dealii::Triangulation<dim>::cell_iterator>& tria_element_iter,
209  const FullMatrix<SCALAR>& prolong_matrix,unsigned int coarse_index,unsigned int fine_index,
211 
212  INTEGRATORDATACONT & _idc;
213 
214  std::map<std::string, const VECTOR*> _domain_data;
215  std::map<std::string, const dealii::Vector<SCALAR>*> _param_data;
216  };
217 
218  /**********************************Implementation*******************************************/
219 
220  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
221  int dim>
223  INTEGRATORDATACONT& idc) :
224  _idc(idc)
225  {
226  }
227 
228  /**********************************Implementation*******************************************/
229 
230  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
231  int dim>
233  {
234 
235  }
236 
237  /*******************************************************************************************/
238 
239  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
240  int dim>
241  void
243  {
244 
245  }
246 
247  /*******************************************************************************************/
248 
249  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
250  int dim>
251  template<typename PROBLEM>
252  void
254  PROBLEM& pde, VECTOR &residual, bool apply_boundary_values)
255  {
256  residual = 0.;
257 
258  const auto& dof_handler =
259  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
260 
261  assert(dof_handler.size() == 2);
262 
263  const auto tria_element_list = GridTools::get_finest_common_cells (dof_handler[0]->GetDEALDoFHandler().get_tria(),
264  dof_handler[1]->GetDEALDoFHandler().get_tria());
265  const auto element_list = GridTools::get_finest_common_cells (dof_handler[0]->GetDEALDoFHandler(),
266  dof_handler[1]->GetDEALDoFHandler());
267 
268  auto element_iter = element_list.begin();
269  auto tria_element_iter = tria_element_list.begin();
270 
271  std::vector<decltype(tria_element_iter->first)> tria_element(2);
272  tria_element[0] = tria_element_iter->first;
273  tria_element[1] = tria_element_iter->second;
274 
275  std::vector<decltype(element_iter->first)> element(2);
276  element[0] = element_iter->first;
277  element[1] = element_iter->second;
278  int coarse_index = 0; //element[coarse_index] is the coarser of the two.
279  int fine_index = 0; //element[fine_index] is the finer of the two (both indices are 2 = element.size() if they are equally refined.
280 
281  // Generate the data containers.
282  _idc.InitializeMMEDC(pde.GetUpdateFlags(),
283  *(pde.GetBaseProblem().GetSpaceTimeHandler()), element, tria_element,
284  this->GetParamData(), this->GetDomainData());
285  auto& edc = _idc.GetMultimeshElementDataContainer();
286 
287  bool need_interfaces = pde.HasInterfaces();
288  _idc.InitializeMMFDC(pde.GetFaceUpdateFlags(),
289  *(pde.GetBaseProblem().GetSpaceTimeHandler()),
290  element,
291  tria_element,
292  this->GetParamData(),
293  this->GetDomainData(),
294  need_interfaces);
295  auto& fdc = _idc.GetMultimeshFaceDataContainer();
296 
297  for(; element_iter != element_list.end(); element_iter++)
298  {
299  element[0] = element_iter->first;
300  element[1] = element_iter->second;
301  tria_element[0] = tria_element_iter->first;
302  tria_element[1] = tria_element_iter->second;
303  FullMatrix<SCALAR> prolong_matrix;
304 
305  if(element[0]->has_children())
306  {
307  prolong_matrix = IdentityMatrix(element[1]->get_fe().dofs_per_cell);
308  coarse_index =1;
309  fine_index = 0;
310  }
311  else
312  {
313  if(element[1]->has_children())
314  {
315  prolong_matrix = IdentityMatrix(element[0]->get_fe().dofs_per_cell);
316  coarse_index =0;
317  fine_index = 1;
318  }
319  else
320  {
321  assert(element.size() ==2);
322  coarse_index = fine_index = 2;
323  }
324  }
325  ComputeNonlinearResidual_Recursive(pde,residual,element,tria_element,prolong_matrix,coarse_index,fine_index,edc,fdc);
326  tria_element_iter++;
327  }
328 
329  if (apply_boundary_values)
330  {
331  ApplyNewtonBoundaryValues(pde, residual);
332  }
333  }
334 
335  /*******************************************************************************************/
336 
337  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
338  int dim>
339  template<typename PROBLEM>
340  void
342  PROBLEM& pde, VECTOR &residual, bool apply_boundary_values)
343  {
344  {
345  throw DOpEException("This function needs to be implemented!", "IntegratorMultiMesh::ComputeNonlinearLhs");
346  }
347  }
348 
349  /*******************************************************************************************/
350 
351  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
352  int dim>
353  template<typename PROBLEM>
354  void
356  PROBLEM& pde, VECTOR &residual, bool apply_boundary_values)
357  {
358  residual = 0.;
359 
360  const auto& dof_handler =
361  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
362 
363  assert(dof_handler.size() == 2);
364 
365  const auto tria_element_list = GridTools::get_finest_common_cells (dof_handler[0]->GetDEALDoFHandler().get_tria(),
366  dof_handler[1]->GetDEALDoFHandler().get_tria());
367  const auto element_list = GridTools::get_finest_common_cells (dof_handler[0]->GetDEALDoFHandler(),
368  dof_handler[1]->GetDEALDoFHandler());
369 
370  auto element_iter = element_list.begin();
371  auto tria_element_iter = tria_element_list.begin();
372 
373  std::vector<decltype(tria_element_iter->first)> tria_element(2);
374  tria_element[0] = tria_element_iter->first;
375  tria_element[1] = tria_element_iter->second;
376 
377  std::vector<decltype(element_iter->first)> element(2);
378  element[0] = element_iter->first;
379  element[1] = element_iter->second;
380  int coarse_index = 0; //element[coarse_index] is the coarser of the two.
381  int fine_index = 0; //element[fine_index] is the finer of the two (both indices are 2 = element.size() if they are equally refined.
382 
383  // Generate the data containers.
384  _idc.InitializeMMEDC(pde.GetUpdateFlags(),
385  *(pde.GetBaseProblem().GetSpaceTimeHandler()), element, tria_element,
386  this->GetParamData(), this->GetDomainData());
387  auto& edc = _idc.GetMultimeshElementDataContainer();
388 
389  _idc.InitializeMMFDC(pde.GetFaceUpdateFlags(),
390  *(pde.GetBaseProblem().GetSpaceTimeHandler()),
391  element,
392  tria_element,
393  this->GetParamData(),
394  this->GetDomainData());
395  auto& fdc = _idc.GetMultimeshFaceDataContainer();
396 
397  for(; element_iter != element_list.end(); element_iter++)
398  {
399  element[0] = element_iter->first;
400  element[1] = element_iter->second;
401  tria_element[0] = tria_element_iter->first;
402  tria_element[1] = tria_element_iter->second;
403  FullMatrix<SCALAR> prolong_matrix;
404 
405  if(element[0]->has_children())
406  {
407  prolong_matrix = IdentityMatrix(element[1]->get_fe().dofs_per_cell);
408  coarse_index =1;
409  fine_index = 0;
410  }
411  else
412  {
413  if(element[1]->has_children())
414  {
415  prolong_matrix = IdentityMatrix(element[0]->get_fe().dofs_per_cell);
416  coarse_index =0;
417  fine_index = 1;
418  }
419  else
420  {
421  assert(element.size() ==2);
422  coarse_index = fine_index = 2;
423  }
424  }
425  ComputeNonlinearRhs_Recursive(pde,residual,element,tria_element,prolong_matrix,coarse_index,fine_index,edc,fdc);
426  tria_element_iter++;
427  }
428 
429  if (apply_boundary_values)
430  {
431  ApplyNewtonBoundaryValues(pde, residual);
432  }
433  }
434 
435  /*******************************************************************************************/
436 
437  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
438  int dim>
439  template<typename PROBLEM, typename MATRIX>
440  void
442  PROBLEM& pde, MATRIX &matrix)
443  {
444  matrix = 0.;
445 
446  const auto& dof_handler =
447  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
448 
449  assert(dof_handler.size() == 2);
450 
451  const auto tria_element_list = GridTools::get_finest_common_cells (dof_handler[0]->GetDEALDoFHandler().get_tria(),
452  dof_handler[1]->GetDEALDoFHandler().get_tria());
453  const auto element_list = GridTools::get_finest_common_cells (dof_handler[0]->GetDEALDoFHandler(),
454  dof_handler[1]->GetDEALDoFHandler());
455 
456  auto element_iter = element_list.begin();
457  auto tria_element_iter = tria_element_list.begin();
458 
459  std::vector<decltype(tria_element_iter->first)> tria_element(2);
460  tria_element[0] = tria_element_iter->first;
461  tria_element[1] = tria_element_iter->second;
462 
463  std::vector<decltype(element_iter->first)> element(2);
464  element[0] = element_iter->first;
465  element[1] = element_iter->second;
466  int coarse_index = 0; //element[coarse_index] is the coarser of the two.
467  int fine_index = 0; //element[fine_index] is the finer of the two (both indices are 2 = element.size() if they are equally refined.
468 
469  // Generate the data containers.
470  _idc.InitializeMMEDC(pde.GetUpdateFlags(),
471  *(pde.GetBaseProblem().GetSpaceTimeHandler()), element, tria_element,
472  this->GetParamData(), this->GetDomainData());
473  auto& edc = _idc.GetMultimeshElementDataContainer();
474 
475  bool need_interfaces = pde.HasInterfaces();
476  _idc.InitializeMMFDC(pde.GetFaceUpdateFlags(),
477  *(pde.GetBaseProblem().GetSpaceTimeHandler()),
478  element,
479  tria_element,
480  this->GetParamData(),
481  this->GetDomainData(),
482  need_interfaces);
483  auto & fdc = _idc.GetMultimeshFaceDataContainer();
484 
485  for(; element_iter != element_list.end(); element_iter++)
486  {
487  element[0] = element_iter->first;
488  element[1] = element_iter->second;
489  tria_element[0] = tria_element_iter->first;
490  tria_element[1] = tria_element_iter->second;
491  FullMatrix<SCALAR> prolong_matrix;
492 
493  if(element[0]->has_children())
494  {
495  prolong_matrix = IdentityMatrix(element[1]->get_fe().dofs_per_cell);
496  coarse_index =1;
497  fine_index = 0;
498  }
499  else
500  {
501  if(element[1]->has_children())
502  {
503  prolong_matrix = IdentityMatrix(element[0]->get_fe().dofs_per_cell);
504  coarse_index =0;
505  fine_index = 1;
506  }
507  else
508  {
509  assert(element.size() ==2);
510  coarse_index = fine_index = 2;
511  }
512  }
513  ComputeMatrix_Recursive(pde,matrix,element,tria_element,prolong_matrix,coarse_index,fine_index,edc,fdc);
514  tria_element_iter++;
515  }
516  }
517 
518  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
519  int dim>
520  template<typename PROBLEM>
521  SCALAR
523  PROBLEM& pde)
524  {
525  SCALAR ret = 0.;
526 
527  const auto& dof_handler =
528  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
529 
530  assert(dof_handler.size() == 2);
531 
532  const auto tria_element_list = GridTools::get_finest_common_cells (dof_handler[0]->GetDEALDoFHandler().get_tria(),
533  dof_handler[1]->GetDEALDoFHandler().get_tria());
534  const auto element_list = GridTools::get_finest_common_cells (dof_handler[0]->GetDEALDoFHandler(),
535  dof_handler[1]->GetDEALDoFHandler());
536 
537  auto element_iter = element_list.begin();
538  auto tria_element_iter = tria_element_list.begin();
539 
540  std::vector<decltype(tria_element_iter->first)> tria_element(2);
541  tria_element[0] = tria_element_iter->first;
542  tria_element[1] = tria_element_iter->second;
543 
544  std::vector<decltype(element_iter->first)> element(2);
545  element[0] = element_iter->first;
546  element[1] = element_iter->second;
547  int coarse_index = 0; //element[coarse_index] is the coarser of the two.
548  int fine_index = 0; //element[fine_index] is the finer of the two (both indices are 2 = element.size() if they are equally refined.
549 
550  if (pde.HasFaces())
551  {
552  throw DOpEException("This function should not be called when faces are needed!",
553  "IntegratorMultiMesh::ComputeDomainScalar");
554  }
555 
556  // Generate the data containers.
557  _idc.InitializeMMEDC(pde.GetUpdateFlags(),
558  *(pde.GetBaseProblem().GetSpaceTimeHandler()), element, tria_element,
559  this->GetParamData(), this->GetDomainData());
560  auto& edc = _idc.GetMultimeshElementDataContainer();
561 
562  for(; element_iter != element_list.end(); element_iter++)
563  {
564  element[0] = element_iter->first;
565  element[1] = element_iter->second;
566  tria_element[0] = tria_element_iter->first;
567  tria_element[1] = tria_element_iter->second;
568  FullMatrix<SCALAR> prolong_matrix;
569 
570  if(element[0]->has_children())
571  {
572  prolong_matrix = IdentityMatrix(element[1]->get_fe().dofs_per_cell);
573  coarse_index =1;
574  fine_index = 0;
575  }
576  else
577  {
578  if(element[1]->has_children())
579  {
580  prolong_matrix = IdentityMatrix(element[0]->get_fe().dofs_per_cell);
581  coarse_index =0;
582  fine_index = 1;
583  }
584  else
585  {
586  assert(element.size() ==2);
587  coarse_index = fine_index = 2;
588  }
589  }
590  ret += ComputeDomainScalar_Recursive(pde,element,tria_element,prolong_matrix,coarse_index,fine_index,edc);
591  tria_element_iter++;
592  }
593  return ret;
594  }
595 
596 
597  /*******************************************************************************************/
598 
599  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
600  int dim>
601  template<typename PROBLEM>
602  SCALAR
604  PROBLEM& pde)
605  {
606 
607  {
608  SCALAR ret = 0.;
609  ret += pde.PointFunctional(this->GetParamData(),
610  this->GetDomainData());
611 
612  return ret;
613  }
614  }
615  /*******************************************************************************************/
616 
617  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
618  int dim>
619  template<typename PROBLEM>
620  SCALAR
622  PROBLEM& pde
623  )
624  {
625  SCALAR ret = 0.;
626  // Begin integration
627  const auto& dof_handler =
628  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
629 
630  const auto tria_element_list = GridTools::get_finest_common_cells (dof_handler[0]->GetDEALDoFHandler().get_tria(),
631  dof_handler[1]->GetDEALDoFHandler().get_tria());
632  const auto element_list = GridTools::get_finest_common_cells (dof_handler[0]->GetDEALDoFHandler(),
633  dof_handler[1]->GetDEALDoFHandler());
634 
635  auto element_iter = element_list.begin();
636  auto tria_element_iter = tria_element_list.begin();
637 
638  std::vector<decltype(tria_element_iter->first)> tria_element(2);
639  tria_element[0] = tria_element_iter->first;
640  tria_element[1] = tria_element_iter->second;
641 
642  std::vector<decltype(element_iter->first)> element(2);
643  element[0] = element_iter->first;
644  element[1] = element_iter->second;
645  int coarse_index = 0; //element[coarse_index] is the coarser of the two.
646  int fine_index = 0; //element[fine_index] is the finer of the two (both indices are 2 = element.size() if they are equally refined.
647 
648 
649  _idc.InitializeMMFDC(pde.GetFaceUpdateFlags(),
650  *(pde.GetBaseProblem().GetSpaceTimeHandler()),
651  element, tria_element,
652  this->GetParamData(),
653  this->GetDomainData());
654  auto & fdc = _idc.GetMultimeshFaceDataContainer();
655 
656  std::vector<unsigned int> boundary_functional_colors = pde.GetBoundaryFunctionalColors();
657  bool need_boundary_integrals = (boundary_functional_colors.size() > 0);
658  if(!need_boundary_integrals)
659  {
660  throw DOpEException("No boundary colors given!","IntegratorMultiMesh::ComputeBoundaryScalar");
661  }
662 
663  for(; element_iter != element_list.end(); element_iter++)
664  {
665  element[0] = element_iter->first;
666  element[1] = element_iter->second;
667  tria_element[0] = tria_element_iter->first;
668  tria_element[1] = tria_element_iter->second;
669  FullMatrix<SCALAR> prolong_matrix;
670 
671  if(element[0]->has_children())
672  {
673  prolong_matrix = IdentityMatrix(element[1]->get_fe().dofs_per_cell);
674  coarse_index =1;
675  fine_index = 0;
676  }
677  else
678  {
679  if(element[1]->has_children())
680  {
681  prolong_matrix = IdentityMatrix(element[0]->get_fe().dofs_per_cell);
682  coarse_index =0;
683  fine_index = 1;
684  }
685  else
686  {
687  assert(element.size() ==2);
688  coarse_index = fine_index = 2;
689  }
690  }
691  ret += ComputeBoundaryScalar_Recursive(pde,element,tria_element,prolong_matrix,coarse_index,fine_index,fdc);
692  tria_element_iter++;
693  }
694 
695  return ret;
696  }
697  /*******************************************************************************************/
698 
699  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
700  int dim>
701  template<typename PROBLEM>
702  SCALAR
704  PROBLEM& /*pde*/
705  )
706  {
707  throw DOpEException("This function needs to be implemented!", "IntegratorMultiMesh::ComputeFaceScalar");
708 // {
709 // SCALAR ret = 0.;
710 //#if deal_II_dimension == 2 || deal_II_dimension == 3
711 // // Begin integration
712 // const auto& dof_handler =
713 // pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
714 // auto element = pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerBeginActive();
715 // auto endc = pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerEnd();
716 //
717 // _idc.InitializeFDC(pde.GetFaceUpdateFlags(),
718 // *(pde.GetBaseProblem().GetSpaceTimeHandler()),
719 // element,
720 // this->GetParamData(),
721 // this->GetDomainData());
722 // auto & fdc = _idc.GetFaceDataContainer();
723 //
724 // bool need_faces = pde.HasFaces();
725 // if(!need_faces)
726 // {
727 // throw DOpEException("No faces required!","IntegratorMultiMesh::ComputeFaceScalar");
728 // }
729 //
730 // for (;element[0]!=endc[0]; element[0]++)
731 // {
732 // for(unsigned int dh=1; dh<dof_handler.size(); dh++)
733 // {
734 // if( element[dh] == endc[dh])
735 // {
736 // throw DOpEException("Elementnumbers in DoFHandlers are not matching!","IntegratorMultiMesh::ComputeFaceScalar");
737 // }
738 // }
739 //
740 // if(need_faces)
741 // {
742 // for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
743 // {
744 // if (element[0]->neighbor_index(face) != -1)
745 // {
746 // fdc.ReInit(face);
747 // ret +=pde.FaceFunctional(fdc);
748 // }
749 // }
750 // }
751 // for(unsigned int dh=1; dh<dof_handler.size(); dh++)
752 // {
753 // element[dh]++;
754 // }
755 // }
756 //#else
757 // throw DOpEException("Not implemented in this dimension!",
758 // "IntegratorMultiMesh::ComputeFaceScalar");
759 //#endif
760 // return ret;
761 // }
762  }
763  /*******************************************************************************************/
764 
765  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
766  int dim>
767  template<typename PROBLEM>
768  SCALAR
770  PROBLEM& pde)
771  {
772 
773  {
774  SCALAR ret = 0.;
775  ret = pde.AlgebraicFunctional(this->GetParamData(),
776  this->GetDomainData());
777  return ret;
778  }
779  }
780 
781  /*******************************************************************************************/
782 
783  template <typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,int dim>
784  template<typename PROBLEM>
786  ::ComputeNonlinearAlgebraicResidual (PROBLEM& pde, VECTOR &residual)
787  {
788  residual = 0.;
789  pde.AlgebraicResidual(residual,this->GetParamData(),this->GetDomainData());
790  }
791 
792  /*******************************************************************************************/
793 
794  template <typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,int dim>
795  template<typename PROBLEM>
797  ::ComputeLocalControlConstraints (PROBLEM& pde, VECTOR &constraints)
798  {
799  constraints = 0.;
800  pde.ComputeLocalControlConstraints(constraints,this->GetParamData(),this->GetDomainData());
801  }
802 
803  /*******************************************************************************************/
804 
805  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
806  int dim>
807  template<typename PROBLEM>
808  void
810  PROBLEM& pde, VECTOR &u)
811  {
812  //TODO Apply constraints locally, see, e.g., dealii step-27 ? But howto do this in the newton iter
813  // e.g. sometimes we need zero sometimes we need other values.
814 
815  //Never Condense Nodes Here ! Or All will fail if the state is not initialized with zero!
816  //pde.GetDoFConstraints().condense(u);
817  std::vector<unsigned int> dirichlet_colors = pde.GetDirichletColors();
818  for (unsigned int i = 0; i < dirichlet_colors.size(); i++)
819  {
820  unsigned int color = dirichlet_colors[i];
821  std::vector<bool> comp_mask = pde.GetDirichletCompMask(color);
822  std::map<unsigned int, SCALAR> boundary_values;
823 
824  InterpolateBoundaryValues(pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler()[0], color, pde.GetDirichletValues(color, this->GetParamData(),
825  this->GetDomainData()), boundary_values, comp_mask );
826 
827  for (typename std::map<unsigned int, SCALAR>::const_iterator p =
828  boundary_values.begin(); p != boundary_values.end(); p++)
829  {
830  u(p->first) = p->second;
831  }
832  }
833  }
834 
835  /*******************************************************************************************/
836 
837  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
838  int dim>
839  template<typename PROBLEM>
840  void
842  PROBLEM& pde, VECTOR &u)
843  {
844  //TODO Apply constraints locally, see, e.g., dealii step-27 ? But howto do this in the newton iter
845  // e.g. sometimes we need zero sometimes we need other values.
846 
847  pde.GetDoFConstraints().condense(u);
848  std::vector<unsigned int> dirichlet_colors = pde.GetDirichletColors();
849  for (unsigned int i = 0; i < dirichlet_colors.size(); i++)
850  {
851  unsigned int color = dirichlet_colors[i];
852  std::vector<bool> comp_mask = pde.GetDirichletCompMask(color);
853  std::map<unsigned int, SCALAR> boundary_values;
854 
855 
856  InterpolateBoundaryValues(
857  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler()[0],
858  color, dealii::ZeroFunction<dim>(comp_mask.size()),
859  boundary_values, comp_mask);
860 
861  for (typename std::map<unsigned int, SCALAR>::const_iterator p =
862  boundary_values.begin(); p != boundary_values.end(); p++)
863  {
864  u(p->first) = p->second;
865  }
866  }
867  }
868  /*******************************************************************************************/
869 
870  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
871  int dim>
872  template<typename PROBLEM, typename MATRIX>
873  void
875  PROBLEM& pde, MATRIX& matrix, VECTOR &rhs, VECTOR &sol)
876  {
877  //TODO Apply constraints locally, see, e.g., dealii step-27 ? But howto do this in the newton iter
878  // e.g. sometimes we need zero sometimes we need other values.
879  pde.GetDoFConstraints().condense(rhs);
880  pde.GetDoFConstraints().condense(matrix);
881  std::vector<unsigned int> dirichlet_colors = pde.GetDirichletColors();
882  for (unsigned int i = 0; i < dirichlet_colors.size(); i++)
883  {
884  unsigned int color = dirichlet_colors[i];
885  std::vector<bool> comp_mask = pde.GetDirichletCompMask(color);
886  std::map<unsigned int, SCALAR> boundary_values;
887 
888  InterpolateBoundaryValues(
889  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler()[0],
890  color, dealii::ZeroFunction<dim>(comp_mask.size()),
891  boundary_values, comp_mask);
892 
893  dealii::MatrixTools::apply_boundary_values(boundary_values, matrix,
894  sol, rhs);
895  }
896  }
897 
898  /*******************************************************************************************/
899 
900  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
901  int dim>
902  void
904  std::string name, const VECTOR* new_data)
905  {
906  if (_domain_data.find(name) != _domain_data.end())
907  {
908  throw DOpEException(
909  "Adding multiple Data with name " + name + " is prohibited!",
910  "IntegratorMultiMesh::AddDomainData");
911  }
912  _domain_data.insert(std::pair<std::string, const VECTOR*>(name, new_data));
913  }
914 
915  /*******************************************************************************************/
916 
917  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
918  int dim>
919  void
921  std::string name)
922  {
923  typename std::map<std::string, const VECTOR *>::iterator it =
924  _domain_data.find(name);
925  if (it == _domain_data.end())
926  {
927  throw DOpEException(
928  "Deleting Data " + name + " is impossible! Data not found",
929  "IntegratorMultiMesh::DeleteDomainData");
930  }
931  _domain_data.erase(it);
932  }
933 
934  /*******************************************************************************************/
935 
936  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
937  int dim>
938  const std::map<std::string, const VECTOR*>&
940  {
941  return _domain_data;
942  }
943 
944  /*******************************************************************************************/
945 
946  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
947  int dim>
948  void
950  std::string name, const dealii::Vector<SCALAR>* new_data)
951  {
952  if (_param_data.find(name) != _param_data.end())
953  {
954  throw DOpEException(
955  "Adding multiple Data with name " + name + " is prohibited!",
956  "IntegratorMultiMesh::AddParamData");
957  }
958  _param_data.insert(
959  std::pair<std::string, const dealii::Vector<SCALAR>*>(name, new_data));
960  }
961 
962  /*******************************************************************************************/
963 
964  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
965  int dim>
966  void
968  std::string name)
969  {
970  typename std::map<std::string, const dealii::Vector<SCALAR>*>::iterator
971  it = _param_data.find(name);
972  if (it == _param_data.end())
973  {
974  throw DOpEException(
975  "Deleting Data " + name + " is impossible! Data not found",
976  "IntegratorMultiMesh::DeleteParamData");
977  }
978  _param_data.erase(it);
979  }
980 
981  /*******************************************************************************************/
982 
983  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
984  int dim>
985  const std::map<std::string, const dealii::Vector<SCALAR>*>&
987  {
988  return _param_data;
989  }
990 
991  /*******************************************************************************************/
992 
993  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
994  int dim>
995  INTEGRATORDATACONT&
997  {
998  return _idc;
999  }
1000 
1001 
1002  /*******************************************************************************************/
1003 
1004  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1005  int dim>
1006  template<template<int, int> class DH>
1007  void
1009  const DOpEWrapper::DoFHandler<dim, DH>* dof_handler,
1010  const unsigned int color, const dealii::Function<dim>& function,
1011  std::map<unsigned int, SCALAR>& boundary_values,
1012  const std::vector<bool>& comp_mask) const
1013  {
1014  dealii::VectorTools::interpolate_boundary_values(
1015  dof_handler->GetDEALDoFHandler(), color, function,
1016  boundary_values, comp_mask);
1017  }
1018 
1019  /*******************************************************************************************/
1020 
1021  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,int dim>
1022  template<typename PROBLEM, template<int, int> class DH>
1023  void IntegratorMultiMesh<INTEGRATORDATACONT, VECTOR, SCALAR, dim>::ComputeNonlinearResidual_Recursive(
1024  PROBLEM& pde,
1025  VECTOR& residual,
1026  typename std::vector<typename DH<dim, dim>::cell_iterator> &element,
1027  typename std::vector<typename dealii::Triangulation<dim>::cell_iterator> &tria_element,
1028  const FullMatrix<SCALAR>& prolong_matrix,unsigned int coarse_index,unsigned int fine_index,
1029  Multimesh_ElementDataContainer<DH, VECTOR, dim>& edc,Multimesh_FaceDataContainer<DH, VECTOR, dim>& fdc)
1030  {
1031  if(!element[0]->has_children() && ! element[1]->has_children())
1032  {
1033  unsigned int dofs_per_element;
1034  dealii::Vector<SCALAR> local_vector;
1035  std::vector<unsigned int> local_dof_indices;
1036 
1037  bool need_faces = pde.HasFaces();
1038  std::vector<unsigned int> boundary_equation_colors = pde.GetBoundaryEquationColors();
1039  bool need_boundary_integrals = (boundary_equation_colors.size() > 0);
1040  bool need_interfaces = pde.HasInterfaces();
1041 
1042  edc.ReInit(coarse_index,fine_index,prolong_matrix);
1043 
1044  dofs_per_element = element[0]->get_fe().dofs_per_cell;
1045 
1046  local_vector.reinit(dofs_per_element);
1047  local_vector = 0;
1048 
1049  local_dof_indices.resize(0);
1050  local_dof_indices.resize(dofs_per_element, 0);
1051 
1052  //the second '1' plays only a role in the stationary case. In the non-stationary
1053  //case, scale_ico is set by the time-stepping-scheme
1054  pde.ElementEquation(edc, local_vector, 1., 1.);
1055  pde.ElementRhs(edc, local_vector, -1.);
1056 
1057  //FIXME Integrate on Faces of Element[0] that contain a fine-element face.
1058  if(need_faces || need_interfaces)
1059  {
1060  throw DOpEException(" Faces on multiple meshes not implemented yet!",
1061  "IntegratorMultiMesh::ComputeNonlinearResidual_Recursive");
1062  }
1063  unsigned int b_index = fine_index%2; //This takes care that if fine_index ==2 then we select the
1064  //zeros entry in the element vector
1065 
1066  if(need_boundary_integrals && element[b_index]->at_boundary())
1067  {
1068  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1069  {
1070  if (element[b_index]->face(face)->at_boundary()
1071  &&
1072  (find(boundary_equation_colors.begin(),boundary_equation_colors.end(),
1073  element[b_index]->face(face)->boundary_indicator()) != boundary_equation_colors.end()))
1074  {
1075  fdc.ReInit(coarse_index,fine_index,prolong_matrix,face);
1076  pde.BoundaryEquation(fdc,local_vector, 1., 1.);
1077  pde.BoundaryRhs(fdc,local_vector,-1.);
1078  }
1079  }
1080  }
1081  // if(need_faces)
1082  // {
1083  // for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1084  // {
1085  // if (element[0]->neighbor_index(face) != -1)
1086  // {
1087  // fdc.ReInit(face);
1088  // pde.FaceEquation(fdc, local_vector);
1089  // pde.FaceRhs(fdc, local_vector,-1.);
1090  // }
1091  // }
1092  // }
1093  // if( need_interfaces)
1094  // {
1095  // for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1096  // {
1097  // fdc.ReInit(face);
1098  // if (element[0]->neighbor_index(face) != -1
1099  // &&
1100  // fdc.GetMaterialId()!= fdc.GetNbrMaterialId())
1101  // {
1102  // fdc.ReInitNbr();
1103  // pde.InterfaceEquation(fdc, local_vector);
1104  // }
1105  // }
1106  // }
1107  if(coarse_index == 0) //Need to transfer the computed residual to the one on the coarse element
1108  {
1109  dealii::Vector<SCALAR> tmp(dofs_per_element);
1110  prolong_matrix.Tvmult(tmp,local_vector);
1111 
1112  //LocalToGlobal
1113  element[0]->get_dof_indices(local_dof_indices);
1114  for (unsigned int i = 0; i < dofs_per_element; ++i)
1115  {
1116  residual(local_dof_indices[i]) += tmp(i);
1117  }
1118  }
1119  else //Testfunctions are already the right ones...
1120  {
1121  //LocalToGlobal
1122  element[0]->get_dof_indices(local_dof_indices);
1123  for (unsigned int i = 0; i < dofs_per_element; ++i)
1124  {
1125  residual(local_dof_indices[i]) += local_vector(i);
1126  }
1127  }
1128 
1129  }//Endof the case on the finest level
1130  else
1131  {
1132  assert(fine_index != coarse_index);
1133  assert(element[fine_index]->has_children());
1134  assert(!element[coarse_index]->has_children());
1135  assert(tria_element[fine_index]->has_children());
1136  assert(!tria_element[coarse_index]->has_children());
1137 
1138  unsigned int local_n_dofs = element[coarse_index]->get_fe().dofs_per_cell;
1139 
1140  typename DH<dim, dim>::cell_iterator dofh_fine = element[fine_index];
1141  typename dealii::Triangulation<dim>::cell_iterator tria_fine = tria_element[fine_index];
1142 
1143  for (unsigned int child=0; child<GeometryInfo<dim>::max_children_per_cell;++child)
1144  {
1145  FullMatrix<SCALAR> new_matrix(local_n_dofs);
1146  element[coarse_index]->get_fe().get_prolongation_matrix(child).mmult (new_matrix,
1147  prolong_matrix);
1148  element[fine_index] = dofh_fine->child(child);
1149  tria_element[fine_index] = tria_fine->child(child);
1150 
1151  ComputeNonlinearResidual_Recursive(pde,residual,element,tria_element,new_matrix, coarse_index, fine_index, edc, fdc);
1152  }
1153  }
1154  }
1155  /*******************************************************************************************/
1156 
1157  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,int dim>
1158  template<typename PROBLEM, template<int, int> class DH>
1159  void IntegratorMultiMesh<INTEGRATORDATACONT, VECTOR, SCALAR, dim>::ComputeNonlinearRhs_Recursive(
1160  PROBLEM& pde,
1161  VECTOR& residual,
1162  typename std::vector<typename DH<dim, dim>::cell_iterator> &element,
1163  typename std::vector<typename dealii::Triangulation<dim>::cell_iterator> &tria_element,
1164  const FullMatrix<SCALAR>& prolong_matrix,unsigned int coarse_index,unsigned int fine_index,
1165  Multimesh_ElementDataContainer<DH, VECTOR, dim>& edc,Multimesh_FaceDataContainer<DH, VECTOR, dim>& fdc)
1166  {
1167  if(!element[0]->has_children() && ! element[1]->has_children())
1168  {
1169  unsigned int dofs_per_element;
1170  dealii::Vector<SCALAR> local_vector;
1171  std::vector<unsigned int> local_dof_indices;
1172 
1173  bool need_faces = pde.HasFaces();
1174  std::vector<unsigned int> boundary_equation_colors = pde.GetBoundaryEquationColors();
1175  bool need_boundary_integrals = (boundary_equation_colors.size() > 0);
1176  bool need_interfaces = pde.HasInterfaces();
1177 
1178  edc.ReInit(coarse_index,fine_index,prolong_matrix);
1179 
1180  dofs_per_element = element[0]->get_fe().dofs_per_cell;
1181 
1182  local_vector.reinit(dofs_per_element);
1183  local_vector = 0;
1184 
1185  local_dof_indices.resize(0);
1186  local_dof_indices.resize(dofs_per_element, 0);
1187 
1188  //the second '1' plays only a role in the stationary case. In the non-stationary
1189  //case, scale_ico is set by the time-stepping-scheme
1190  pde.ElementRhs(edc, local_vector, 1.);
1191 
1192  //FIXME Integrate on Faces of Element[0] that contain a fine-element face.
1193  if(need_faces )
1194  {
1195  throw DOpEException(" Faces on multiple meshes not implemented yet!",
1196  "IntegratorMultiMesh::ComputeNonlinearRhs_Recursive");
1197  }
1198  if(need_interfaces )
1199  {
1200  throw DOpEException(" Faces on multiple meshes not implemented yet!",
1201  "IntegratorMultiMesh::ComputeNonlinearRhs_Recursive");
1202  }
1203  unsigned int b_index = fine_index%2; //This takes care that if fine_index ==2 then we select the
1204  //zeros entry in the element vector
1205 
1206  if(need_boundary_integrals && element[b_index]->at_boundary())
1207  {
1208  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1209  {
1210  if (element[b_index]->face(face)->at_boundary()
1211  &&
1212  (find(boundary_equation_colors.begin(),boundary_equation_colors.end(),
1213  element[b_index]->face(face)->boundary_indicator()) != boundary_equation_colors.end()))
1214  {
1215  fdc.ReInit(coarse_index,fine_index,prolong_matrix,face);
1216  pde.BoundaryRhs(fdc,local_vector,1.);
1217  }
1218  }
1219  }
1220  // if(need_faces)
1221  // {
1222  // for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1223  // {
1224  // if (element[0]->neighbor_index(face) != -1)
1225  // {
1226  // fdc.ReInit(face);
1227  // pde.FaceRhs(fdc, local_vector,1.);
1228  // }
1229  // }
1230  // }
1231  if(coarse_index == 0) //Need to transfer the computed residual to the one on the coarse element
1232  {
1233  dealii::Vector<SCALAR> tmp(dofs_per_element);
1234  prolong_matrix.Tvmult(tmp,local_vector);
1235 
1236  //LocalToGlobal
1237  element[0]->get_dof_indices(local_dof_indices);
1238  for (unsigned int i = 0; i < dofs_per_element; ++i)
1239  {
1240  residual(local_dof_indices[i]) += tmp(i);
1241  }
1242  }
1243  else //Testfunctions are already the right ones...
1244  {
1245  //LocalToGlobal
1246  element[0]->get_dof_indices(local_dof_indices);
1247  for (unsigned int i = 0; i < dofs_per_element; ++i)
1248  {
1249  residual(local_dof_indices[i]) += local_vector(i);
1250  }
1251  }
1252 
1253  }//Endof the case on the finest level
1254  else
1255  {
1256  assert(fine_index != coarse_index);
1257  assert(element[fine_index]->has_children());
1258  assert(!element[coarse_index]->has_children());
1259  assert(tria_element[fine_index]->has_children());
1260  assert(!tria_element[coarse_index]->has_children());
1261 
1262  unsigned int local_n_dofs = element[coarse_index]->get_fe().dofs_per_cell;
1263 
1264  typename DH<dim, dim>::cell_iterator dofh_fine = element[fine_index];
1265  typename dealii::Triangulation<dim>::cell_iterator tria_fine = tria_element[fine_index];
1266 
1267  for (unsigned int child=0; child<GeometryInfo<dim>::max_children_per_cell;++child)
1268  {
1269  FullMatrix<SCALAR> new_matrix(local_n_dofs);
1270  element[coarse_index]->get_fe().get_prolongation_matrix(child).mmult (new_matrix,
1271  prolong_matrix);
1272  element[fine_index] = dofh_fine->child(child);
1273  tria_element[fine_index] = tria_fine->child(child);
1274 
1275  ComputeNonlinearRhs_Recursive(pde,residual,element,tria_element,new_matrix, coarse_index, fine_index, edc, fdc);
1276  }
1277  }
1278  }
1279 
1280  /*******************************************************************************************/
1281 
1282  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1283  int dim>
1284  template<typename PROBLEM, typename MATRIX, template<int, int> class DH>
1285  void
1286  IntegratorMultiMesh<INTEGRATORDATACONT, VECTOR, SCALAR, dim>::ComputeMatrix_Recursive(
1287  PROBLEM& pde, MATRIX &matrix, typename std::vector<typename DH<dim, dim>::cell_iterator>& element,
1288  typename std::vector<typename dealii::Triangulation<dim>::cell_iterator>& tria_element,
1289  const FullMatrix<SCALAR>& prolong_matrix,unsigned int coarse_index,unsigned int fine_index,
1290  Multimesh_ElementDataContainer<DH, VECTOR, dim>& edc,
1291  Multimesh_FaceDataContainer<DH, VECTOR, dim>& fdc)
1292  {
1293 
1294  if(!element[0]->has_children() && ! element[1]->has_children())
1295  {
1296  unsigned int dofs_per_element;
1297  std::vector<unsigned int> local_dof_indices;
1298 
1299  bool need_faces = pde.HasFaces();
1300  bool need_interfaces = pde.HasInterfaces();
1301  std::vector<unsigned int> boundary_equation_colors = pde.GetBoundaryEquationColors();
1302  bool need_boundary_integrals = (boundary_equation_colors.size() > 0);
1303 
1304  edc.ReInit(coarse_index,fine_index,prolong_matrix);
1305  dofs_per_element = element[0]->get_fe().dofs_per_cell;
1306 
1307  dealii::FullMatrix<SCALAR> local_matrix(dofs_per_element,
1308  dofs_per_element);
1309  local_matrix = 0;
1310 
1311  local_dof_indices.resize(0);
1312  local_dof_indices.resize(dofs_per_element, 0);
1313  pde.ElementMatrix(edc, local_matrix);
1314 
1315  //FIXME Integrate on Faces of Element[0] that contain a fine-element face.
1316  if(need_faces || need_interfaces)
1317  {
1318  throw DOpEException(" Faces on multiple meshes not implemented yet!",
1319  "IntegratorMultiMesh::ComputeMatrix_Recursive");
1320  }
1321  unsigned int b_index = fine_index%2; //This takes care that if fine_index ==2 then we select the
1322  //zeros entry in the element vector
1323  if(need_boundary_integrals && element[b_index]->at_boundary())
1324  {
1325 
1326  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1327  {
1328  if (element[b_index]->face(face)->at_boundary()
1329  &&
1330  (find(boundary_equation_colors.begin(),boundary_equation_colors.end(),
1331  element[b_index]->face(face)->boundary_indicator()) != boundary_equation_colors.end()))
1332  {
1333  fdc.ReInit(coarse_index,fine_index,prolong_matrix,face);
1334  pde.BoundaryMatrix(fdc, local_matrix);
1335  }
1336  }
1337  }
1338  // if(need_faces)
1339  // {
1340  // for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1341  // {
1342  // if (element[0]->neighbor_index(face) != -1)
1343  // {
1344  // fdc.ReInit(face);
1345  // pde.FaceMatrix(fdc, local_matrix);
1346  // }
1347  // }
1348  // }
1349  // if( need_interfaces)
1350  // {
1351  // for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1352  // {
1353  // fdc.ReInit(face);
1354  // if (element[0]->neighbor_index(face) != -1
1355  // &&
1356  // fdc.GetMaterialId()!= fdc.GetNbrMaterialId())
1357  // {
1358  // fdc.ReInitNbr();
1359  //
1360  // nbr_dofs_per_element = fdc.GetNbrNDoFsPerElement();
1361  // nbr_local_dof_indices.resize(0);
1362  // nbr_local_dof_indices.resize(nbr_dofs_per_element, 0);
1363  // dealii::FullMatrix<SCALAR> local_interface_matrix(dofs_per_element,nbr_dofs_per_element );
1364  // local_interface_matrix = 0;
1365  //
1366  // pde.InterfaceMatrix(fdc, local_interface_matrix);
1367  //
1368  // element[0]->get_dof_indices(local_dof_indices);
1369  // element[0]->neighbor(face)->get_dof_indices(nbr_local_dof_indices);
1370  //
1371  // for (unsigned int i = 0; i < dofs_per_element; ++i)
1372  // {
1373  // for (unsigned int j = 0; j < nbr_dofs_per_element; ++j)
1374  // {
1375  // matrix.add(local_dof_indices[i], nbr_local_dof_indices[j],
1376  // local_interface_matrix(i, j));
1377  // } //endfor j
1378  // } //endfor i
1379  // }
1380  // }
1381  // }
1382  if(coarse_index == 0) //Need to transfer the computed residual to the one on the coarse element
1383  {
1384  dealii::FullMatrix<SCALAR> tmp(dofs_per_element);
1385  tmp = 0.;
1386  prolong_matrix.Tmmult(tmp,local_matrix);
1387  local_matrix = 0.;
1388  tmp.mmult(local_matrix,prolong_matrix);
1389 
1390  //LocalToGlobal
1391  element[0]->get_dof_indices(local_dof_indices);
1392  for (unsigned int i = 0; i < dofs_per_element; ++i)
1393  {
1394  for (unsigned int j = 0; j < dofs_per_element; ++j)
1395  {
1396  matrix.add(local_dof_indices[i], local_dof_indices[j],
1397  local_matrix(i, j));
1398  }
1399  }
1400  }
1401  else
1402  {
1403  //LocalToGlobal
1404  element[0]->get_dof_indices(local_dof_indices);
1405  for (unsigned int i = 0; i < dofs_per_element; ++i)
1406  {
1407  for (unsigned int j = 0; j < dofs_per_element; ++j)
1408  {
1409  matrix.add(local_dof_indices[i], local_dof_indices[j],
1410  local_matrix(i, j));
1411  }
1412  }
1413  }
1414 
1415  }//Endof the case on the finest level
1416  else
1417  {
1418  assert(fine_index != coarse_index);
1419  assert(element[fine_index]->has_children());
1420  assert(!element[coarse_index]->has_children());
1421  assert(tria_element[fine_index]->has_children());
1422  assert(!tria_element[coarse_index]->has_children());
1423 
1424  unsigned int local_n_dofs = element[coarse_index]->get_fe().dofs_per_cell;
1425 
1426  typename DH<dim, dim>::cell_iterator dofh_fine = element[fine_index];
1427  typename dealii::Triangulation<dim>::cell_iterator tria_fine = tria_element[fine_index];
1428 
1429  for (unsigned int child=0; child<GeometryInfo<dim>::max_children_per_cell;++child)
1430  {
1431  FullMatrix<SCALAR> new_matrix(local_n_dofs);
1432  element[coarse_index]->get_fe().get_prolongation_matrix(child).mmult (new_matrix,
1433  prolong_matrix);
1434  element[fine_index] = dofh_fine->child(child);
1435  tria_element[fine_index] = tria_fine->child(child);
1436 
1437  ComputeMatrix_Recursive(pde,matrix,element,tria_element,new_matrix, coarse_index, fine_index, edc, fdc);
1438  }
1439  }
1440  }
1441 
1442  /*******************************************************************************************/
1443 
1444  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,int dim>
1445  template<typename PROBLEM, template<int, int> class DH>
1446  SCALAR IntegratorMultiMesh<INTEGRATORDATACONT, VECTOR, SCALAR, dim>::ComputeDomainScalar_Recursive(
1447  PROBLEM& pde,
1448  typename std::vector<typename DH<dim, dim>::cell_iterator> &element,
1449  typename std::vector<typename dealii::Triangulation<dim>::cell_iterator> &tria_element,
1450  const FullMatrix<SCALAR>& prolong_matrix,unsigned int coarse_index,unsigned int fine_index,
1451  Multimesh_ElementDataContainer<DH, VECTOR, dim>& edc)
1452  {
1453  if(!element[0]->has_children() && ! element[1]->has_children())
1454  {
1455  SCALAR ret = 0.;
1456  edc.ReInit(coarse_index,fine_index,prolong_matrix);
1457  ret += pde.ElementFunctional(edc);
1458  return ret;
1459  } //Endof the case on the finest level
1460  else
1461  {
1462  assert(fine_index != coarse_index);
1463  assert(element[fine_index]->has_children());
1464  assert(!element[coarse_index]->has_children());
1465  assert(tria_element[fine_index]->has_children());
1466  assert(!tria_element[coarse_index]->has_children());
1467 
1468  unsigned int local_n_dofs = element[coarse_index]->get_fe().dofs_per_cell;
1469 
1470  typename DH<dim, dim>::cell_iterator dofh_fine = element[fine_index];
1471  typename dealii::Triangulation<dim>::cell_iterator tria_fine = tria_element[fine_index];
1472  SCALAR ret = 0.;
1473  for (unsigned int child=0; child<GeometryInfo<dim>::max_children_per_cell;++child)
1474  {
1475  FullMatrix<SCALAR> new_matrix(local_n_dofs);
1476  element[coarse_index]->get_fe().get_prolongation_matrix(child).mmult (new_matrix,
1477  prolong_matrix);
1478  element[fine_index] = dofh_fine->child(child);
1479  tria_element[fine_index] = tria_fine->child(child);
1480 
1481  ret += ComputeDomainScalar_Recursive(pde,element,tria_element,new_matrix, coarse_index, fine_index, edc);
1482  }
1483  return ret;
1484  }
1485  }
1486  /*******************************************************************************************/
1487 
1488  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,int dim>
1489  template<typename PROBLEM, template<int, int> class DH>
1490  SCALAR IntegratorMultiMesh<INTEGRATORDATACONT, VECTOR, SCALAR, dim>::ComputeBoundaryScalar_Recursive(
1491  PROBLEM& pde,
1492  typename std::vector<typename DH<dim, dim>::cell_iterator> &element,
1493  typename std::vector<typename dealii::Triangulation<dim>::cell_iterator> &tria_element,
1494  const FullMatrix<SCALAR>& prolong_matrix,unsigned int coarse_index,unsigned int fine_index,
1495  Multimesh_FaceDataContainer<DH, VECTOR, dim>& fdc)
1496  {
1497  if(!element[0]->has_children() && ! element[1]->has_children())
1498  {
1499  SCALAR ret = 0.;
1500  std::vector<unsigned int> boundary_functional_colors = pde.GetBoundaryFunctionalColors();
1501  unsigned int b_index = fine_index%2; //This takes care that if fine_index ==2 then we select the
1502  //zeros entry in the element vector
1503  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1504  {
1505  if (element[b_index]->face(face)->at_boundary()
1506  &&
1507  (find(boundary_functional_colors.begin(),boundary_functional_colors.end(),
1508  element[b_index]->face(face)->boundary_indicator()) != boundary_functional_colors.end()))
1509  {
1510  fdc.ReInit(coarse_index,fine_index,prolong_matrix,face);
1511  ret += pde.BoundaryFunctional(fdc);
1512  }
1513  }
1514  return ret;
1515  } //Endof the case on the finest level
1516  else
1517  {
1518  assert(fine_index != coarse_index);
1519  assert(element[fine_index]->has_children());
1520  assert(!element[coarse_index]->has_children());
1521  assert(tria_element[fine_index]->has_children());
1522  assert(!tria_element[coarse_index]->has_children());
1523 
1524  unsigned int local_n_dofs = element[coarse_index]->get_fe().dofs_per_cell;
1525 
1526  typename DH<dim, dim>::cell_iterator dofh_fine = element[fine_index];
1527  typename dealii::Triangulation<dim>::cell_iterator tria_fine = tria_element[fine_index];
1528  SCALAR ret = 0.;
1529  for (unsigned int child=0; child<GeometryInfo<dim>::max_children_per_cell;++child)
1530  {
1531  FullMatrix<SCALAR> new_matrix(local_n_dofs);
1532  element[coarse_index]->get_fe().get_prolongation_matrix(child).mmult (new_matrix,
1533  prolong_matrix);
1534  element[fine_index] = dofh_fine->child(child);
1535  tria_element[fine_index] = tria_fine->child(child);
1536 
1537  ret += ComputeBoundaryScalar_Recursive(pde,element,tria_element,new_matrix, coarse_index, fine_index, fdc);
1538  }
1539  return ret;
1540  }
1541  }
1542 //ENDOF NAMESPACE DOpE
1543 }
1544 #endif
1545 
const std::map< std::string, const VECTOR * > & GetDomainData() const
Definition: integrator_multimesh.h:939
void ComputeLocalControlConstraints(PROBLEM &pde, VECTOR &constraints)
Definition: integrator_multimesh.h:797
SCALAR ComputeBoundaryScalar(PROBLEM &pde)
Definition: integrator_multimesh.h:621
Definition: integrator_multimesh.h:62
SCALAR ComputeFaceScalar(PROBLEM &pde)
Definition: integrator_multimesh.h:703
SCALAR ComputeDomainScalar(PROBLEM &pde)
Definition: integrator_multimesh.h:522
void ComputeNonlinearLhs(PROBLEM &pde, VECTOR &residual, bool apply_boundary_values=true)
Definition: integrator_multimesh.h:341
Definition: multimesh_elementdatacontainer.h:55
void ComputeNonlinearRhs(PROBLEM &pde, VECTOR &residual, bool apply_boundary_values=true)
Definition: integrator_multimesh.h:355
void ComputeNonlinearResidual(PROBLEM &pde, VECTOR &residual, bool apply_boundary_values=true)
Definition: integrator_multimesh.h:253
SCALAR ComputeAlgebraicScalar(PROBLEM &pde)
Definition: integrator_multimesh.h:769
void AddParamData(std::string name, const dealii::Vector< SCALAR > *new_data)
Definition: integrator_multimesh.h:949
const DOFHANDLER< dim, dim > & GetDEALDoFHandler() const
Definition: dofhandler_wrapper.h:69
SCALAR ComputePointScalar(PROBLEM &pde)
Definition: integrator_multimesh.h:603
void ApplyNewtonBoundaryValues(PROBLEM &pde, VECTOR &u)
Definition: integrator_multimesh.h:841
void ComputeMatrix(PROBLEM &pde, MATRIX &matrix)
Definition: integrator_multimesh.h:441
~IntegratorMultiMesh()
Definition: integrator_multimesh.h:232
void DeleteParamData(std::string name)
Definition: integrator_multimesh.h:967
void ReInit()
Definition: integrator_multimesh.h:242
void DeleteDomainData(std::string name)
Definition: integrator_multimesh.h:920
void ApplyInitialBoundaryValues(PROBLEM &pde, VECTOR &u)
Definition: integrator_multimesh.h:809
IntegratorMultiMesh(INTEGRATORDATACONT &idc)
Definition: integrator_multimesh.h:222
void AddDomainData(std::string name, const VECTOR *new_data)
Definition: integrator_multimesh.h:903
void ComputeNonlinearAlgebraicResidual(PROBLEM &pde, VECTOR &residual)
Definition: integrator_multimesh.h:786
Definition: multimesh_facedatacontainer.h:53
INTEGRATORDATACONT & GetIntegratorDataContainer() const
Definition: integrator_multimesh.h:996
Definition: dopeexception.h:35
const std::map< std::string, const dealii::Vector< SCALAR > * > & GetParamData() const
Definition: integrator_multimesh.h:986