DOpE
integrator.h
Go to the documentation of this file.
1 
24 #ifndef _Integrator_H_
25 #define _Integrator_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 
34 #include <base/function.h>
35 
36 #include <vector>
37 
38 #include "elementdatacontainer.h"
39 #include "facedatacontainer.h"
40 #include "dwrdatacontainer.h"
41 #include "residualestimator.h"
42 #include "dopetypes.h"
43 
44 namespace DOpE
45 {
57  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
58  int dim>
59  class Integrator
60  {
61  public:
62  Integrator(INTEGRATORDATACONT& idc1);
68  Integrator(INTEGRATORDATACONT& idc1, INTEGRATORDATACONT& idc2);
69 
70  ~Integrator();
71 
76  void
77  ReInit();
78 
95  template<typename PROBLEM>
96  void
97  ComputeNonlinearResidual(PROBLEM& pde, VECTOR &residual,
98  bool apply_boundary_values = true);
117  template<typename PROBLEM>
118  void
119  ComputeNonlinearLhs(PROBLEM& pde, VECTOR &residual,
120  bool apply_boundary_values = true);
139  template<typename PROBLEM>
140  void
141  ComputeNonlinearRhs(PROBLEM& pde, VECTOR &residual,
142  bool apply_boundary_values = true);
156  template<typename PROBLEM, typename MATRIX>
157  void
158  ComputeMatrix(PROBLEM& pde, MATRIX &matrix);
159 
172  template<typename PROBLEM>
173  void
174  ComputeNonlinearAlgebraicResidual(PROBLEM& pde, VECTOR &residual);
189  template<typename PROBLEM>
190  void
191  ComputeLocalControlConstraints(PROBLEM& pde, VECTOR &constraints);
192 
204  template<typename PROBLEM>
205  SCALAR
206  ComputeDomainScalar(PROBLEM& pde);
219  template<typename PROBLEM>
220  SCALAR
221  ComputePointScalar(PROBLEM& pde);
236  template<typename PROBLEM>
237  SCALAR
238  ComputeBoundaryScalar(PROBLEM& pde);
253  template<typename PROBLEM>
254  SCALAR
255  ComputeFaceScalar(PROBLEM& pde);
270  template<typename PROBLEM>
271  SCALAR
272  ComputeAlgebraicScalar(PROBLEM& pde);
273 
286  template<typename PROBLEM>
287  void
288  ApplyInitialBoundaryValues(PROBLEM& pde, VECTOR &u);
289 
305  template<typename PROBLEM>
306  void
307  ApplyTransposedInitialBoundaryValues(PROBLEM& pde, VECTOR &u);
321  template<typename PROBLEM>
322  void
323  ApplyNewtonBoundaryValues(PROBLEM& pde, VECTOR &u);
340  template<typename PROBLEM, typename MATRIX>
341  void
342  ApplyNewtonBoundaryValues(PROBLEM& pde, MATRIX &matrix, VECTOR &rhs,
343  VECTOR &sol);
344 
356  inline void
357  AddDomainData(std::string name, const VECTOR* new_data);
368  inline void
369  DeleteDomainData(std::string name);
380  inline void
381  AddParamData(std::string name, const dealii::Vector<SCALAR>* new_data);inline void
392  DeleteParamData(std::string name);
393 
410  template<typename PROBLEM, class STH, class EDC, class FDC>
411  void
412  ComputeRefinementIndicators(PROBLEM& pde,
425  template<typename PROBLEM>
426  void
427  ComputeRefinementIndicators(PROBLEM& pde,
429 
430  inline INTEGRATORDATACONT&
432 
433  inline INTEGRATORDATACONT&
435 
436  protected:
442  inline const std::map<std::string, const VECTOR*>&
443  GetDomainData() const;
449  inline const std::map<std::string, const dealii::Vector<SCALAR>*>&
450  GetParamData() const;
451 
452  private:
453  template<template<int, int> class DH>
454  void
455  InterpolateBoundaryValues(
456  const DOpEWrapper::Mapping<dim, DH>& mapping,
457  const DOpEWrapper::DoFHandler<dim, DH>* dof_handler,
458  const unsigned int color, const dealii::Function<dim>& function,
459  std::map<unsigned int, SCALAR>& boundary_values,
460  const std::vector<bool>& comp_mask) const;
461 
472  template<typename ELEMENTITERATOR>
473  bool
474  AtInterface(ELEMENTITERATOR& element, unsigned int face)
475  {
476  if (element[0]->neighbor_index(face) != -1)
477  if (element[0]->material_id()
478  != element[0]->neighbor(face)->material_id())
479  return true;
480  return false;
481  }
482 
483  INTEGRATORDATACONT & _idc1;
484  INTEGRATORDATACONT & _idc2;
485 
486  std::map<std::string, const VECTOR*> _domain_data;
487  std::map<std::string, const dealii::Vector<SCALAR>*> _param_data;
488  };
489 
490  /**********************************Implementation*******************************************/
491 
492  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
493  int dim>
495  INTEGRATORDATACONT& idc)
496  : _idc1(idc), _idc2(idc)
497  {
498  }
499 
500  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
501  int dim>
503  INTEGRATORDATACONT& idc1, INTEGRATORDATACONT& idc2)
504  : _idc1(idc1), _idc2(idc2)
505  {
506  }
507 
508  /**********************************Implementation*******************************************/
509 
510  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
511  int dim>
513  {
514 
515  }
516 
517  /*******************************************************************************************/
518 
519  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
520  int dim>
521  void
523  {
524 
525  }
526 
527  /*******************************************************************************************/
528 
529  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
530  int dim>
531  template<typename PROBLEM>
532  void
534  PROBLEM& pde, VECTOR &residual, bool apply_boundary_values)
535  {
536  residual = 0.;
537  // Begin integration
538  unsigned int dofs_per_element;
539  dealii::Vector<SCALAR> local_vector;
540  std::vector<unsigned int> local_dof_indices;
541 
542  const bool need_point_rhs = pde.HasPoints();
543 
544  const auto& dof_handler =
545  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
546  auto element =
547  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerBeginActive();
548  auto endc =
549  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerEnd();
550 
551  // Generate the data containers.
552  GetIntegratorDataContainer().InitializeEDC(pde.GetUpdateFlags(),
553  *(pde.GetBaseProblem().GetSpaceTimeHandler()), element,
554  this->GetParamData(), this->GetDomainData());
555  auto& edc = GetIntegratorDataContainer().GetElementDataContainer();
556 
557  bool need_faces = pde.HasFaces();
558  bool need_interfaces = pde.HasInterfaces();
559  std::vector<unsigned int> boundary_equation_colors = pde.GetBoundaryEquationColors();
560  bool need_boundary_integrals = (boundary_equation_colors.size() > 0);
561  GetIntegratorDataContainer().InitializeFDC(pde.GetFaceUpdateFlags(),
562  *(pde.GetBaseProblem().GetSpaceTimeHandler()),
563  element,
564  this->GetParamData(),
565  this->GetDomainData(),
566  need_interfaces);
567  auto & fdc = GetIntegratorDataContainer().GetFaceDataContainer();
568 
569  for (; element[0] != endc[0]; element[0]++)
570  {
571  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
572  {
573  if (element[dh] == endc[dh])
574  {
575  throw DOpEException(
576  "Elementnumbers in DoFHandlers are not matching!",
577  "Integrator::ComputeNonlinearResidual");
578  }
579  }
580 
581  edc.ReInit();
582 
583  dofs_per_element = element[0]->get_fe().dofs_per_cell;
584 
585  local_vector.reinit(dofs_per_element);
586  local_vector = 0;
587 
588  local_dof_indices.resize(0);
589  local_dof_indices.resize(dofs_per_element, 0);
590 
591  //the second '1' plays only a role in the stationary case. In the non-stationary
592  //case, scale_ico is set by the time-stepping-scheme
593  pde.ElementEquation(edc, local_vector, 1., 1.);
594  pde.ElementRhs(edc, local_vector, -1.);
595 
596  if(need_boundary_integrals && element[0]->at_boundary())
597  {
598  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
599  {
600  if (element[0]->face(face)->at_boundary()
601  &&
602  (find(boundary_equation_colors.begin(),boundary_equation_colors.end(),
603  element[0]->face(face)->boundary_indicator()) != boundary_equation_colors.end()))
604  {
605  fdc.ReInit(face);
606  pde.BoundaryEquation(fdc,local_vector, 1., 1.);
607  pde.BoundaryRhs(fdc,local_vector,-1.);
608  }
609  }
610  }
611  if(need_faces)
612  {
613  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
614  {
615  if (element[0]->neighbor_index(face) != -1)
616  {
617  fdc.ReInit(face);
618  pde.FaceEquation(fdc, local_vector, 1., 1.);
619  pde.FaceRhs(fdc, local_vector,-1.);
620  }
621  }
622  }
623  if( need_interfaces)
624  {
625 
626  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
627  {
628  // auto face_it = element[0]->face(face);
629  // first, check if we are at an interface, i.e. not the neighbour exists and
630  // it has a different material_id than the actual element
631  if(AtInterface(element, face))
632  {
633  //There exist now 3 different scenarios, given the actual element and face:
634  // The neighbour behind this face is [ more | as much | less] refined
635  // than/as the actual element. We have to distinguish here only between the case 1
636  // and the other two, because these will be distinguished in in the FaceDataContainer.
637 
638  if (element[0]->neighbor(face)->has_children())
639  {
640  //first: neighbour is finer
641 
642  for (unsigned int subface_no=0;
643  subface_no < element[0]->face(face)->n_children();
644  ++subface_no)
645  {
646  //TODO Now here we have to initialise the subface_values on the
647  // actual element and then the facevalues of the neighbours
648  fdc.ReInit(face, subface_no);
649  fdc.ReInitNbr();
650 
651  pde.InterfaceEquation(fdc, local_vector, 1., 1.);
652 
653  }
654  }
655  else
656  {
657  // either neighbor is as fine as this element or
658  // it is coarser
659 
660  fdc.ReInit(face);
661  fdc.ReInitNbr();
662  pde.InterfaceEquation(fdc, local_vector, 1., 1.);
663  }
664 
665  } //endif atinterface
666  } //endfor faces
667  } //endif need_interfaces
668  //LocalToGlobal
669  element[0]->get_dof_indices(local_dof_indices);
670  for (unsigned int i = 0; i < dofs_per_element; ++i)
671  {
672  residual(local_dof_indices[i]) += local_vector(i);
673  }
674 
675  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
676  {
677  element[dh]++;
678  }
679  }
680 
681  //check if we need the evaluation of PointRhs
682  if (need_point_rhs)
683  {
684  VECTOR point_rhs;
685  pde.PointRhs(this->GetParamData(), this->GetDomainData(), point_rhs,
686  -1.);
687  residual += point_rhs;
688  }
689 
690  if (apply_boundary_values)
691  {
692  ApplyNewtonBoundaryValues(pde, residual);
693  }
694  }
695 
696  /*******************************************************************************************/
697 
698  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
699  int dim>
700  template<typename PROBLEM>
701  void
703  PROBLEM& pde, VECTOR &residual, bool apply_boundary_values)
704  {
705  {
706 
707  residual = 0.;
708  // Begin integration
709  unsigned int dofs_per_element;
710 
711  dealii::Vector<SCALAR> local_vector;
712 
713  std::vector<unsigned int> local_dof_indices;
714 
715  const auto& dof_handler =
716  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
717  auto element =
718  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerBeginActive();
719  auto endc =
720  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerEnd();
721 
722  // Generate the data containers.
723  GetIntegratorDataContainer().InitializeEDC(pde.GetUpdateFlags(),
724  *(pde.GetBaseProblem().GetSpaceTimeHandler()), element,
725  this->GetParamData(), this->GetDomainData());
726  auto& edc = GetIntegratorDataContainer().GetElementDataContainer();
727 
728  bool need_faces = pde.HasFaces();
729  bool need_interfaces = pde.HasInterfaces();
730  std::vector<unsigned int> boundary_equation_colors = pde.GetBoundaryEquationColors();
731  bool need_boundary_integrals = (boundary_equation_colors.size() > 0);
732 
733  GetIntegratorDataContainer().InitializeFDC(pde.GetFaceUpdateFlags(),
734  *(pde.GetBaseProblem().GetSpaceTimeHandler()),
735  element,
736  this->GetParamData(),
737  this->GetDomainData(),
738  need_interfaces);
739  auto & fdc = GetIntegratorDataContainer().GetFaceDataContainer();
740 
741  for (; element[0] != endc[0]; element[0]++)
742  {
743  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
744  {
745  if (element[dh] == endc[dh])
746  {
747  throw DOpEException(
748  "Elementnumbers in DoFHandlers are not matching!",
749  "mIntegrator::ComputeNonlinearLhs");
750  }
751  }
752 
753  edc.ReInit();
754  dofs_per_element = element[0]->get_fe().dofs_per_cell;
755 
756  local_vector.reinit(dofs_per_element);
757  local_vector = 0;
758 
759  local_dof_indices.resize(0);
760  local_dof_indices.resize(dofs_per_element, 0);
761 
762  //the second '1' plays only a role in the stationary case. In the non-stationary
763  //case, scale_ico is set by the time-stepping-scheme
764  pde.ElementEquation(edc, local_vector, 1., 1.);
765 
766  if(need_boundary_integrals)
767  {
768  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
769  {
770  if (element[0]->face(face)->at_boundary()
771  &&
772  (find(boundary_equation_colors.begin(),boundary_equation_colors.end(),
773  element[0]->face(face)->boundary_indicator()) != boundary_equation_colors.end()))
774  {
775  fdc.ReInit(face);
776  pde.BoundaryEquation(fdc,local_vector, 1., 1.);
777  }
778  }
779  }
780  if(need_faces)
781  {
782  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
783  {
784  if (element[0]->neighbor_index(face) != -1)
785  {
786  fdc.ReInit(face);
787  pde.FaceEquation(fdc, local_vector, 1., 1.);
788  }
789  }
790  }
791 
792  if( need_interfaces)
793  {
794 
795  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
796  {
797  //auto face_it = element[0]->face(face);
798  // first, check if we are at an interface, i.e. not the neighbour exists and
799  // it has a different material_id than the actual element
800  if(AtInterface(element, face))
801  {
802  //There exist now 3 different scenarios, given the actual element and face:
803  // The neighbour behind this face is [ more | as much | less] refined
804  // than/as the actual element. We have to distinguish here only between the case 1
805  // and the other two, because these will be distinguished in in the FaceDataContainer.
806 
807  if (element[0]->neighbor(face)->has_children())
808  {
809  //first: neighbour is finer
810 
811  for (unsigned int subface_no=0;
812  subface_no < element[0]->face(face)->n_children();
813  ++subface_no)
814  {
815  //TODO Now here we have to initialise the subface_values on the
816  // actual element and then the facevalues of the neighbours
817  fdc.ReInit(face, subface_no);
818  fdc.ReInitNbr();
819 
820  pde.InterfaceEquation(fdc, local_vector, 1., 1.);
821 
822  }
823  }
824  else
825  {
826  // either neighbor is as fine as this element or
827  // it is coarser
828 
829  fdc.ReInit(face);
830  fdc.ReInitNbr();
831  pde.InterfaceEquation(fdc, local_vector, 1., 1.);
832  }
833  } //endif atinterface
834  } //endfor face
835  } //endif need_interfaces
836  //LocalToGlobal
837  element[0]->get_dof_indices(local_dof_indices);
838  for (unsigned int i = 0; i < dofs_per_element; ++i)
839  {
840  residual(local_dof_indices[i]) += local_vector(i);
841  }
842 
843  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
844  {
845  element[dh]++;
846  }
847  }
848 
849  if (apply_boundary_values)
850  {
851  ApplyNewtonBoundaryValues(pde, residual);
852  }
853  }
854  }
855 
856  /*******************************************************************************************/
857 
858  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
859  int dim>
860  template<typename PROBLEM>
861  void
863  PROBLEM& pde, VECTOR &residual, bool apply_boundary_values)
864  {
865  residual = 0.;
866  // Begin integration
867  unsigned int dofs_per_element;
868  dealii::Vector<SCALAR> local_vector;
869  std::vector<unsigned int> local_dof_indices;
870 
871  const bool need_point_rhs = pde.HasPoints();
872 
873  const auto& dof_handler =
874  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
875  auto element =
876  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerBeginActive();
877  auto endc =
878  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerEnd();
879 
880  // Initialize the data containers.
881  GetIntegratorDataContainer().InitializeEDC(pde.GetUpdateFlags(),
882  *(pde.GetBaseProblem().GetSpaceTimeHandler()), element,
883  this->GetParamData(), this->GetDomainData());
884  auto& edc = GetIntegratorDataContainer().GetElementDataContainer();
885 
886  bool need_interfaces = pde.HasInterfaces();
887  if(need_interfaces )
888  {
889  throw DOpEException(" Faces on multiple meshes not implemented yet!",
890  "IntegratorMultiMesh::ComputeNonlinearRhs_Recursive");
891  }
892  bool need_faces = pde.HasFaces();
893  std::vector<unsigned int> boundary_equation_colors = pde.GetBoundaryEquationColors();
894  bool need_boundary_integrals = (boundary_equation_colors.size() > 0);
895 
896  GetIntegratorDataContainer().InitializeFDC(pde.GetFaceUpdateFlags(),
897  *(pde.GetBaseProblem().GetSpaceTimeHandler()),
898  element,
899  this->GetParamData(),
900  this->GetDomainData());
901  auto & fdc = GetIntegratorDataContainer().GetFaceDataContainer();
902 
903  for (; element[0] != endc[0]; element[0]++)
904  {
905  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
906  {
907  if (element[dh] == endc[dh])
908  {
909  throw DOpEException(
910  "Elementnumbers in DoFHandlers are not matching!",
911  "Integrator::ComputeNonlinearRhs");
912  }
913  }
914 
915  edc.ReInit();
916  dofs_per_element = element[0]->get_fe().dofs_per_cell;
917 
918  local_vector.reinit(dofs_per_element);
919  local_vector = 0;
920 
921  local_dof_indices.resize(0);
922  local_dof_indices.resize(dofs_per_element, 0);
923  pde.ElementRhs(edc, local_vector, 1.);
924 
925  if(need_boundary_integrals)
926  {
927  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
928  {
929  if (element[0]->face(face)->at_boundary()
930  &&
931  (find(boundary_equation_colors.begin(),boundary_equation_colors.end(),
932  element[0]->face(face)->boundary_indicator()) != boundary_equation_colors.end()))
933  {
934  fdc.ReInit(face);
935  pde.BoundaryRhs(fdc,local_vector,1.);
936  }
937  }
938  }
939  if(need_faces)
940  {
941  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
942  {
943  if (element[0]->neighbor_index(face) != -1)
944  {
945  fdc.ReInit(face);
946  pde.FaceRhs(fdc, local_vector);
947  }
948  }
949  }
950  //LocalToGlobal
951  element[0]->get_dof_indices(local_dof_indices);
952  for (unsigned int i = 0; i < dofs_per_element; ++i)
953  {
954  residual(local_dof_indices[i]) += local_vector(i);
955  }
956 
957  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
958  {
959  element[dh]++;
960  }
961  }
962 
963  //check if we need the evaluation of PointRhs
964  if (need_point_rhs)
965  {
966  VECTOR point_rhs;
967  pde.PointRhs(this->GetParamData(), this->GetDomainData(), point_rhs,
968  1.);
969  residual += point_rhs;
970  }
971 
972  if (apply_boundary_values)
973  {
974  ApplyNewtonBoundaryValues(pde, residual);
975  }
976  }
977 
978  /*******************************************************************************************/
979 
980  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
981  int dim>
982  template<typename PROBLEM, typename MATRIX>
983  void
985  PROBLEM& pde, MATRIX &matrix)
986  {
987  matrix = 0.;
988  // Begin integration
989  unsigned int dofs_per_element;
990  std::vector<unsigned int> local_dof_indices;
991 
992  const auto& dof_handler =
993  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
994  auto element =
995  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerBeginActive();
996  auto endc =
997  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerEnd();
998 
999  GetIntegratorDataContainer().InitializeEDC(pde.GetUpdateFlags(),
1000  *(pde.GetBaseProblem().GetSpaceTimeHandler()), element,
1001  this->GetParamData(), this->GetDomainData());
1002  auto& edc = GetIntegratorDataContainer().GetElementDataContainer();
1003 
1004  //for the interface-case
1005  unsigned int nbr_dofs_per_element;
1006  std::vector<unsigned int> nbr_local_dof_indices;
1007 
1008  bool need_faces = pde.HasFaces();
1009  bool need_interfaces = pde.HasInterfaces();
1010  std::vector<unsigned int> boundary_equation_colors = pde.GetBoundaryEquationColors();
1011  bool need_boundary_integrals = (boundary_equation_colors.size() > 0);
1012 
1013  GetIntegratorDataContainer().InitializeFDC(pde.GetFaceUpdateFlags(),
1014  *(pde.GetBaseProblem().GetSpaceTimeHandler()),
1015  element,
1016  this->GetParamData(),
1017  this->GetDomainData(),
1018  need_interfaces);
1019  auto & fdc = GetIntegratorDataContainer().GetFaceDataContainer();
1020 
1021  for (; element[0] != endc[0]; element[0]++)
1022  {
1023  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
1024  {
1025  if (element[dh] == endc[dh])
1026  {
1027  throw DOpEException(
1028  "Elementnumbers in DoFHandlers are not matching!",
1029  "Integrator::ComputeMatrix");
1030  }
1031  }
1032  edc.ReInit();
1033  dofs_per_element = element[0]->get_fe().dofs_per_cell;
1034 
1035  dealii::FullMatrix<SCALAR> local_matrix(dofs_per_element,
1036  dofs_per_element);
1037  local_matrix = 0;
1038 
1039  local_dof_indices.resize(0);
1040  local_dof_indices.resize(dofs_per_element, 0);
1041  pde.ElementMatrix(edc, local_matrix);
1042 
1043  if(need_boundary_integrals)
1044  {
1045  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1046  {
1047  if (element[0]->face(face)->at_boundary()
1048  &&
1049  (find(boundary_equation_colors.begin(),boundary_equation_colors.end(),
1050  element[0]->face(face)->boundary_indicator()) != boundary_equation_colors.end()))
1051  {
1052  fdc.ReInit(face);
1053  pde.BoundaryMatrix(fdc, local_matrix);
1054  }
1055  }
1056  }
1057  if(need_faces)
1058  {
1059  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1060  {
1061  if (element[0]->neighbor_index(face) != -1)
1062  {
1063  fdc.ReInit(face);
1064  pde.FaceMatrix(fdc, local_matrix);
1065  }
1066  }
1067  }
1068 
1069  if( need_interfaces)
1070  {
1071  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1072  {
1073  //auto face_it = element[0]->face(face);
1074  // first, check if we are at an interface, i.e. not the neighbour exists and
1075  // it has a different material_id than the actual element
1076  if(AtInterface(element, face))
1077  {
1078  //There exist now 3 different scenarios, given the actual element and face:
1079  // The neighbour behind this face is [ more | as much | less] refined
1080  // than/as the actual element. We have to distinguish here only between the case 1
1081  // and the other two, because these will be distinguished in in the FaceDataContainer.
1082 
1083  if (element[0]->neighbor(face)->has_children())
1084  {
1085  //first: neighbour is finer
1086 
1087  for (unsigned int subface_no=0;
1088  subface_no < element[0]->face(face)->n_children();
1089  ++subface_no)
1090  {
1091  //TODO Now here we have to initialise the subface_values on the
1092  // actual element and then the facevalues of the neighbours
1093  fdc.ReInit(face, subface_no);
1094  fdc.ReInitNbr();
1095 
1096  //TODO auslagern?
1097  nbr_dofs_per_element = fdc.GetNbrNDoFsPerElement();
1098  nbr_local_dof_indices.resize(0);
1099  nbr_local_dof_indices.resize(nbr_dofs_per_element, 0);
1100  dealii::FullMatrix<SCALAR> local_interface_matrix(dofs_per_element,nbr_dofs_per_element );
1101  local_interface_matrix = 0;
1102 
1103  pde.InterfaceMatrix(fdc, local_interface_matrix);
1104 
1105  element[0]->get_dof_indices(local_dof_indices);
1106  element[0]->neighbor(face)->get_dof_indices(nbr_local_dof_indices);
1107 
1108  for (unsigned int i = 0; i < dofs_per_element; ++i)
1109  {
1110  for (unsigned int j = 0; j < nbr_dofs_per_element; ++j)
1111  {
1112  matrix.add(local_dof_indices[i], nbr_local_dof_indices[j],
1113  local_interface_matrix(i, j));
1114  } //endfor j
1115  } //endfor i
1116 
1117  }
1118  }
1119  else
1120  {
1121  // either neighbor is as fine as this element or it is coarser
1122  fdc.ReInit(face);
1123  fdc.ReInitNbr();
1124 
1125  //TODO auslagern?
1126  nbr_dofs_per_element = fdc.GetNbrNDoFsPerElement();
1127  nbr_local_dof_indices.resize(0);
1128  nbr_local_dof_indices.resize(nbr_dofs_per_element, 0);
1129  dealii::FullMatrix<SCALAR> local_interface_matrix(dofs_per_element,nbr_dofs_per_element );
1130  local_interface_matrix = 0;
1131 
1132  pde.InterfaceMatrix(fdc, local_interface_matrix);
1133 
1134  element[0]->get_dof_indices(local_dof_indices);
1135  element[0]->neighbor(face)->get_dof_indices(nbr_local_dof_indices);
1136 
1137  for (unsigned int i = 0; i < dofs_per_element; ++i)
1138  {
1139  for (unsigned int j = 0; j < nbr_dofs_per_element; ++j)
1140  {
1141  matrix.add(local_dof_indices[i], nbr_local_dof_indices[j],
1142  local_interface_matrix(i, j));
1143  } //endfor j
1144  } //endfor i
1145  }
1146  } //endif atinterface
1147 
1148  }
1149  } //endif need_interfaces
1150 
1151  //LocalToGlobal
1152  element[0]->get_dof_indices(local_dof_indices);
1153  for (unsigned int i = 0; i < dofs_per_element; ++i)
1154  {
1155  for (unsigned int j = 0; j < dofs_per_element; ++j)
1156  {
1157  matrix.add(local_dof_indices[i], local_dof_indices[j],
1158  local_matrix(i, j));
1159  }
1160  }
1161 
1162  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
1163  {
1164  element[dh]++;
1165  }
1166  }
1167  }
1168 
1169  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1170  int dim>
1171  template<typename PROBLEM>
1172  SCALAR
1174  PROBLEM& pde)
1175  {
1176  {
1177  SCALAR ret = 0.;
1178 
1179  const auto& dof_handler =
1180  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
1181  auto element =
1182  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerBeginActive();
1183  auto endc =
1184  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerEnd();
1185  GetIntegratorDataContainerFunc().InitializeEDC(pde.GetUpdateFlags(),
1186  *(pde.GetBaseProblem().GetSpaceTimeHandler()), element,
1187  this->GetParamData(), this->GetDomainData());
1188  auto& edc = GetIntegratorDataContainerFunc().GetElementDataContainer();
1189 
1190  bool need_faces = pde.HasFaces();
1191 
1192  for (; element[0] != endc[0]; element[0]++)
1193  {
1194  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
1195  {
1196  if (element[dh] == endc[dh])
1197  {
1198  throw DOpEException(
1199  "Elementnumbers in DoFHandlers are not matching!",
1200  "Integrator::ComputeDomainScalar");
1201  }
1202  }
1203 
1204  edc.ReInit();
1205  ret += pde.ElementFunctional(edc);
1206 
1207  if (need_faces)
1208  {
1209  throw DOpEException("Face Integrals not Implemented!",
1210  "Integrator::ComputeDomainScalar");
1211  }
1212 
1213  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
1214  {
1215  element[dh]++;
1216  }
1217  }
1218  return ret;
1219  }
1220  }
1221  /*******************************************************************************************/
1222 
1223  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1224  int dim>
1225  template<typename PROBLEM>
1226  SCALAR
1228  PROBLEM& pde)
1229  {
1230 
1231  {
1232  SCALAR ret = 0.;
1233  ret += pde.PointFunctional(this->GetParamData(),
1234  this->GetDomainData());
1235 
1236  return ret;
1237  }
1238  }
1239  /*******************************************************************************************/
1240 
1241  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1242  int dim>
1243  template<typename PROBLEM>
1244  SCALAR
1246  PROBLEM& pde
1247  )
1248  {
1249  {
1250  SCALAR ret = 0.;
1251  // Begin integration
1252  const auto& dof_handler =
1253  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
1254  auto element = pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerBeginActive();
1255  auto endc = pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerEnd();
1256 
1257  GetIntegratorDataContainerFunc().InitializeFDC(pde.GetFaceUpdateFlags(),
1258  *(pde.GetBaseProblem().GetSpaceTimeHandler()),
1259  element,
1260  this->GetParamData(),
1261  this->GetDomainData());
1262  auto & fdc = GetIntegratorDataContainerFunc().GetFaceDataContainer();
1263 
1264  std::vector<unsigned int> boundary_functional_colors = pde.GetBoundaryFunctionalColors();
1265  bool need_boundary_integrals = (boundary_functional_colors.size() > 0);
1266  if(!need_boundary_integrals)
1267  {
1268  throw DOpEException("No boundary colors given!","Integrator::ComputeBoundaryScalar");
1269  }
1270 
1271  for (;element[0]!=endc[0]; element[0]++)
1272  {
1273  for(unsigned int dh=1; dh<dof_handler.size(); dh++)
1274  {
1275  if( element[dh] == endc[dh])
1276  {
1277  throw DOpEException("Elementnumbers in DoFHandlers are not matching!","Integrator::ComputeBoundaryScalar");
1278  }
1279  }
1280 
1281  if(need_boundary_integrals)
1282  {
1283  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1284  {
1285  if (element[0]->face(face)->at_boundary()
1286  &&
1287  (find(boundary_functional_colors.begin(),boundary_functional_colors.end(),
1288  element[0]->face(face)->boundary_indicator()) != boundary_functional_colors.end()))
1289  {
1290  fdc.ReInit(face);
1291  ret += pde.BoundaryFunctional(fdc);
1292  }
1293  }
1294  }
1295  for(unsigned int dh=1; dh<dof_handler.size(); dh++)
1296  {
1297  element[dh]++;
1298  }
1299  }
1300 
1301  return ret;
1302 
1303  }
1304  }
1305  /*******************************************************************************************/
1306 
1307  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1308  int dim>
1309  template<typename PROBLEM>
1310  SCALAR
1312  PROBLEM& pde
1313  )
1314  {
1315 
1316  {
1317  SCALAR ret = 0.;
1318  // Begin integration
1319  const auto& dof_handler =
1320  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
1321  auto element = pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerBeginActive();
1322  auto endc = pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerEnd();
1323 
1324  GetIntegratorDataContainerFunc().InitializeFDC(pde.GetFaceUpdateFlags(),
1325  *(pde.GetBaseProblem().GetSpaceTimeHandler()),
1326  element,
1327  this->GetParamData(),
1328  this->GetDomainData());
1329  auto & fdc = GetIntegratorDataContainerFunc().GetFaceDataContainer();
1330 
1331  bool need_faces = pde.HasFaces();
1332  if(!need_faces)
1333  {
1334  throw DOpEException("No faces required!","Integrator::ComputeFaceScalar");
1335  }
1336 
1337  for (;element[0]!=endc[0]; element[0]++)
1338  {
1339  for(unsigned int dh=1; dh<dof_handler.size(); dh++)
1340  {
1341  if( element[dh] == endc[dh])
1342  {
1343  throw DOpEException("Elementnumbers in DoFHandlers are not matching!","Integrator::ComputeFaceScalar");
1344  }
1345  }
1346 
1347  if(need_faces)
1348  {
1349  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1350  {
1351  if (element[0]->neighbor_index(face) != -1)
1352  {
1353  fdc.ReInit(face);
1354  ret +=pde.FaceFunctional(fdc);
1355  }
1356  }
1357  }
1358  for(unsigned int dh=1; dh<dof_handler.size(); dh++)
1359  {
1360  element[dh]++;
1361  }
1362  }
1363  return ret;
1364  }
1365  }
1366  /*******************************************************************************************/
1367 
1368  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1369  int dim>
1370  template<typename PROBLEM>
1371  SCALAR
1373  PROBLEM& pde)
1374  {
1375 
1376  {
1377  SCALAR ret = 0.;
1378  ret = pde.AlgebraicFunctional(this->GetParamData(),
1379  this->GetDomainData());
1380  return ret;
1381  }
1382  }
1383 
1384  /*******************************************************************************************/
1385 
1386  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1387  int dim>
1388  template<typename PROBLEM>
1389  void
1391  PROBLEM& pde, VECTOR &residual)
1392  {
1393  residual = 0.;
1394  pde.AlgebraicResidual(residual, this->GetParamData(),
1395  this->GetDomainData());
1396  }
1397 
1398  /*******************************************************************************************/
1399 
1400  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1401  int dim>
1402  template<typename PROBLEM>
1403  void
1405  PROBLEM& pde, VECTOR &constraints)
1406  {
1407  constraints = 0.;
1408  pde.ComputeLocalControlConstraints(constraints, this->GetParamData(),
1409  this->GetDomainData());
1410  }
1411 
1412  /*******************************************************************************************/
1413 
1414  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1415  int dim>
1416  template<typename PROBLEM>
1417  void
1419  PROBLEM& /*pde*/, VECTOR &/*u*/)
1420  {
1421  //Wird hier nicht gebraucht...
1422  }
1423 
1424  /*******************************************************************************************/
1425 
1426  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1427  int dim>
1428  template<typename PROBLEM>
1429  void
1431  PROBLEM& pde, VECTOR &u)
1432  {
1433  //TODO Apply constraints locally, see, e.g., dealii step-27 ? But howto do this in the newton iter
1434  // e.g. sometimes we need zero sometimes we need other values.
1435 
1436  //Never Condense Nodes Here ! Or All will fail if the state is not initialized with zero!
1437  //pde.GetDoFConstraints().condense(u);
1438  std::vector<unsigned int> dirichlet_colors = pde.GetDirichletColors();
1439  for (unsigned int i = 0; i < dirichlet_colors.size(); i++)
1440  {
1441  unsigned int color = dirichlet_colors[i];
1442  std::vector<bool> comp_mask = pde.GetDirichletCompMask(color);
1443  std::map<unsigned int, SCALAR> boundary_values;
1444 
1445  InterpolateBoundaryValues( pde.GetBaseProblem().GetSpaceTimeHandler()->GetMapping(),
1446  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler()[0],
1447  color,
1448  pde.GetDirichletValues(color, this->GetParamData(),
1449  this->GetDomainData()), boundary_values, comp_mask);
1450 
1451  for (typename std::map<unsigned int, SCALAR>::const_iterator p =
1452  boundary_values.begin(); p != boundary_values.end(); p++)
1453  {
1454  u(p->first) = p->second;
1455  }
1456  }
1457  }
1458 
1459  /*******************************************************************************************/
1460 
1461  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1462  int dim>
1463  template<typename PROBLEM>
1464  void
1466  PROBLEM& pde, VECTOR &u)
1467  {
1468  //TODO Apply constraints locally, see, e.g., dealii step-27 ? But howto do this in the newton iter
1469  // e.g. sometimes we need zero sometimes we need other values.
1470 
1471  pde.GetDoFConstraints().condense(u);
1472  std::vector<unsigned int> dirichlet_colors = pde.GetDirichletColors();
1473  for (unsigned int i = 0; i < dirichlet_colors.size(); i++)
1474  {
1475  unsigned int color = dirichlet_colors[i];
1476  std::vector<bool> comp_mask = pde.GetDirichletCompMask(color);
1477  std::map<unsigned int, SCALAR> boundary_values;
1478 
1479  InterpolateBoundaryValues( pde.GetBaseProblem().GetSpaceTimeHandler()->GetMapping(),
1480  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler()[0],
1481  color, dealii::ZeroFunction<dim>(comp_mask.size()),
1482  boundary_values, comp_mask);
1483 
1484  for (typename std::map<unsigned int, SCALAR>::const_iterator p =
1485  boundary_values.begin(); p != boundary_values.end(); p++)
1486  {
1487  u(p->first) = p->second;
1488  }
1489  }
1490  }
1491  /*******************************************************************************************/
1492 
1493  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1494  int dim>
1495  template<typename PROBLEM, typename MATRIX>
1496  void
1498  PROBLEM& pde, MATRIX& matrix, VECTOR &rhs, VECTOR &sol)
1499  {
1500  //TODO Apply constraints locally, see, e.g., dealii step-27 ? But howto do this in the newton iter
1501  // e.g. sometimes we need zero sometimes we need other values.
1502  pde.GetDoFConstraints().condense(rhs);
1503  pde.GetDoFConstraints().condense(matrix);
1504  std::vector<unsigned int> dirichlet_colors = pde.GetDirichletColors();
1505  for (unsigned int i = 0; i < dirichlet_colors.size(); i++)
1506  {
1507  unsigned int color = dirichlet_colors[i];
1508  std::vector<bool> comp_mask = pde.GetDirichletCompMask(color);
1509  std::map<unsigned int, SCALAR> boundary_values;
1510 
1511  InterpolateBoundaryValues( pde.GetBaseProblem().GetSpaceTimeHandler()->GetMapping(),
1512  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler()[0],
1513  color, dealii::ZeroFunction<dim>(comp_mask.size()),
1514  boundary_values, comp_mask);
1515 
1516  dealii::MatrixTools::apply_boundary_values(boundary_values, matrix,
1517  sol, rhs);
1518  }
1519  }
1520 
1521  /*******************************************************************************************/
1522 
1523  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1524  int dim>
1525  void
1527  std::string name, const VECTOR* new_data)
1528  {
1529  if (_domain_data.find(name) != _domain_data.end())
1530  {
1531  throw DOpEException(
1532  "Adding multiple Data with name " + name + " is prohibited!",
1533  "Integrator::AddDomainData");
1534  }
1535  _domain_data.insert(
1536  std::pair<std::string, const VECTOR*>(name, new_data));
1537  }
1538 
1539  /*******************************************************************************************/
1540 
1541  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1542  int dim>
1543  void
1545  std::string name)
1546  {
1547  typename std::map<std::string, const VECTOR *>::iterator it =
1548  _domain_data.find(name);
1549  if (it == _domain_data.end())
1550  {
1551  throw DOpEException(
1552  "Deleting Data " + name + " is impossible! Data not found",
1553  "Integrator::DeleteDomainData");
1554  }
1555  _domain_data.erase(it);
1556  }
1557 
1558  /*******************************************************************************************/
1559 
1560  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1561  int dim>
1562  const std::map<std::string, const VECTOR*>&
1564  {
1565  return _domain_data;
1566  }
1567 
1568  /*******************************************************************************************/
1569 
1570  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1571  int dim>
1572  void
1574  std::string name, const dealii::Vector<SCALAR>* new_data)
1575  {
1576  if (_param_data.find(name) != _param_data.end())
1577  {
1578  throw DOpEException(
1579  "Adding multiple Data with name " + name + " is prohibited!",
1580  "Integrator::AddParamData");
1581  }
1582  _param_data.insert(
1583  std::pair<std::string, const dealii::Vector<SCALAR>*>(name,
1584  new_data));
1585  }
1586 
1587  /*******************************************************************************************/
1588 
1589  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1590  int dim>
1591  void
1593  std::string name)
1594  {
1595  typename std::map<std::string, const dealii::Vector<SCALAR>*>::iterator it =
1596  _param_data.find(name);
1597  if (it == _param_data.end())
1598  {
1599  throw DOpEException(
1600  "Deleting Data " + name + " is impossible! Data not found",
1601  "Integrator::DeleteParamData");
1602  }
1603  _param_data.erase(it);
1604  }
1605 
1606  /*******************************************************************************************/
1607 
1608  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1609  int dim>
1610  const std::map<std::string, const dealii::Vector<SCALAR>*>&
1612  {
1613  return _param_data;
1614  }
1615 
1616  /*******************************************************************************************/
1617 
1618  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1619  int dim>
1620  template<typename PROBLEM, class STH, class EDC, class FDC>
1621  void
1623  PROBLEM& pde,
1625  {
1626  unsigned int n_error_comps = dwrc.GetNErrorComps();
1627  //for primal and dual part of the error
1628  std::vector<double> element_sum(n_error_comps, 0);
1629  element_sum.resize(n_error_comps, 0);
1630 
1631  // Begin integration
1632  const auto& dof_handler =
1633  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
1634  auto element =
1635  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerBeginActive();
1636  auto endc =
1637  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerEnd();
1638 
1639  const auto& dof_handler_weight = dwrc.GetWeightSTH().GetDoFHandler();
1640  auto element_weight = dwrc.GetWeightSTH().GetDoFHandlerBeginActive();
1641  auto endc_high = dwrc.GetWeightSTH().GetDoFHandlerEnd();
1642 
1643  // Generate the data containers. Notice that we use the quadrature
1644  //formula from the higher order idc!.
1645  GetIntegratorDataContainer().InitializeEDC(
1646  dwrc.GetWeightIDC().GetQuad(), pde.GetUpdateFlags(),
1647  *(pde.GetBaseProblem().GetSpaceTimeHandler()), element,
1648  this->GetParamData(), this->GetDomainData());
1649  auto& edc = GetIntegratorDataContainer().GetElementDataContainer();
1650 
1651  dwrc.GetWeightIDC().InitializeEDC(pde.GetUpdateFlags(),
1652  dwrc.GetWeightSTH(), element_weight, this->GetParamData(),
1653  dwrc.GetWeightData());
1654  auto& edc_weight = dwrc.GetElementWeight();
1655 
1656  // we want to integrate the face-terms only once, so
1657  // we store the values on each face in this map
1658  // and distribute it at the end to the adjacent elements.
1659  typename std::map<typename dealii::Triangulation<dim>::face_iterator,std::vector<double> >
1660  face_integrals;
1661  // initialize the map with a big value to make sure
1662  // that we take notice if we forget to add a face
1663  // during the error estimation process
1664  auto element_it = element[0];
1665  std::vector<double> face_init(n_error_comps,-1e20);
1666  for (; element_it != endc[0]; element_it++)
1667  {
1668  for (unsigned int face_no=0;face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
1669  {
1670  face_integrals[element_it->face(face_no)] = face_init;
1671  }
1672  }
1673 
1674 // bool need_faces = pde.HasFaces();
1675 // bool need_interfaces = pde.HasInterfaces();
1676 // std::vector<unsigned int> boundary_equation_colors = pde.GetBoundaryEquationColors();
1677 // bool need_boundary_integrals = (boundary_equation_colors.size() > 0);
1678 
1679  GetIntegratorDataContainer().InitializeFDC(dwrc.GetWeightIDC().GetFaceQuad(),
1680  pde.GetFaceUpdateFlags(),
1681  *(pde.GetBaseProblem().GetSpaceTimeHandler()),
1682  element,
1683  this->GetParamData(),
1684  this->GetDomainData(),
1685  true);
1686  auto & fdc = GetIntegratorDataContainer().GetFaceDataContainer();
1687 
1688  dwrc.GetWeightIDC().InitializeFDC(pde.GetFaceUpdateFlags(),
1689  dwrc.GetWeightSTH(),
1690  element_weight,
1691  this->GetParamData(),
1692  dwrc.GetWeightData(),
1693  true);
1694 
1695  for (unsigned int element_index = 0; element[0] != endc[0];
1696  element[0]++, element_index++)
1697  {
1698  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
1699  {
1700  if (element[dh] == endc[dh])
1701  {
1702  throw DOpEException(
1703  "Elementnumbers in DoFHandlers are not matching!",
1704  "Integrator::ComputeRefinementIndicators");
1705  }
1706  }
1707  for (unsigned int dh = 0; dh < dof_handler_weight.size(); dh++)
1708  {
1709  if (element_weight[dh] == endc_high[dh])
1710  {
1711  throw DOpEException(
1712  "Elementnumbers in DoFHandlers are not matching!",
1713  "Integrator::ComputeRefinementIndicators");
1714  }
1715  }
1716  element_sum.clear();
1717  element_sum.resize(n_error_comps, 0);
1718 
1719  edc.ReInit();
1720  edc_weight.ReInit();
1721 
1722  //first the element-residual
1723  pde.ElementErrorContribution(edc, dwrc, element_sum, 1.);
1724  for(unsigned int l =0; l < n_error_comps; l ++)
1725  {
1726  dwrc.GetErrorIndicators(l)(element_index) = element_sum[l];
1727  }
1728  //dwrc.GetPrimalErrorIndicators()(element_index) = element_sum[0];
1729  //dwrc.GetDualErrorIndicators()(element_index) = element_sum[1];
1730  element_sum.clear();
1731  element_sum.resize(n_error_comps, 0);
1732 
1733 
1734  //Now to the face terms. We compute them only once for each face and distribute the
1735  //afterwards. We choose always to work from the coarser element, if both neigbors of the
1736  //face are on the same level, we pick the one with the lower index
1737  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1738  {
1739  auto face_it = element[0]->face(face);
1740 
1741  //check if the face lies at a boundary
1742  if(face_it->at_boundary())
1743  {
1744  fdc.ReInit(face);
1745  dwrc.GetFaceWeight().ReInit(face);
1746  pde.BoundaryErrorContribution(fdc, dwrc, element_sum, 1.);
1747 
1748  Assert (face_integrals.find (element[0]->face(face)) != face_integrals.end(),
1749  ExcInternalError());
1750  Assert (face_integrals[element[0]->face(face)] == face_init,
1751  ExcInternalError());
1752 
1753  face_integrals[element[0]->face(face)] = element_sum;
1754  element_sum.clear();
1755  element_sum.resize(n_error_comps,0.);
1756  }
1757  else
1758  {
1759  //There exist now 3 different scenarios, given the actual element and face:
1760  // The neighbour behind this face is [ more | as much | less] refined
1761  // than/as the actual element. We have to distinguish here only between the case 1
1762  // and the other two, because these will be distinguished in in the FaceDataContainer.
1763  if (element[0]->neighbor(face)->has_children())
1764  {
1765  //first: neighbour is finer
1766  std::vector<double> sum(n_error_comps,0.);
1767  for (unsigned int subface_no=0;
1768  subface_no < element[0]->face(face)->n_children();
1769  ++subface_no)
1770  {
1771  //TODO Now here we have to initialise the subface_values on the
1772  // actual element and then the facevalues of the neighbours
1773  fdc.ReInit(face, subface_no);
1774  fdc.ReInitNbr();
1775  dwrc.GetFaceWeight().ReInit(face, subface_no);
1776 
1777  pde.FaceErrorContribution(fdc, dwrc, element_sum, 1.);
1778  for(unsigned int l =0; l < n_error_comps; l ++)
1779  {
1780  sum[l] += element_sum[l];
1781  }
1782  face_integrals[element[0]->neighbor_child_on_subface(face, subface_no)
1783  ->face(element[0]->neighbor_of_neighbor(face))] = element_sum;
1784  element_sum.clear();
1785  element_sum.resize(n_error_comps,0);
1786  }
1787 
1788  Assert (face_integrals.find (element[0]->face(face)) != face_integrals.end(),
1789  ExcInternalError());
1790  Assert (face_integrals[element[0]->face(face)] == face_init,
1791  ExcInternalError());
1792 
1793  face_integrals[element[0]->face(face)] = sum;
1794  element_sum.clear();
1795  element_sum.resize(n_error_comps,0);
1796  }
1797  else
1798  {
1799  // either neighbor is as fine as this element or
1800  // it is coarser
1801  Assert(element[0]->neighbor(face)->level() <= element[0]->level(),ExcInternalError());
1802  //now we work always from the coarser element. if both elements
1803  //are on the same level, we pick the one with the lower index
1804  if(element[0]->level() == element[0]->neighbor(face)->level()
1805  && element[0]->index() < element[0]->neighbor(face)->index())
1806  {
1807  fdc.ReInit(face);
1808  fdc.ReInitNbr();
1809  dwrc.GetFaceWeight().ReInit(face);
1810 
1811  pde.FaceErrorContribution(fdc, dwrc, element_sum, 1.);
1812  Assert (face_integrals.find (element[0]->face(face)) != face_integrals.end(),
1813  ExcInternalError());
1814  Assert (face_integrals[element[0]->face(face)] == face_init,
1815  ExcInternalError());
1816 
1817  face_integrals[element[0]->face(face)] = element_sum;
1818  element_sum.clear();
1819  element_sum.resize(n_error_comps,0);
1820  }
1821  }
1822  }
1823  } //endfor faces
1824  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
1825  {
1826  element[dh]++;
1827  }
1828  for (unsigned int dh = 0; dh < dof_handler_weight.size(); dh++)
1829  {
1830  element_weight[dh]++;
1831  }
1832  } //endfor element
1833  //now we have to incorporate the face and boundary_values
1834  //into
1835  unsigned int present_element = 0;
1836  element =
1837  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerBeginActive();
1838  for (;
1839  element[0] !=endc[0]; element[0]++, ++present_element)
1840  {
1841  for (unsigned int face_no = 0;
1842  face_no < GeometryInfo<dim>::faces_per_cell; ++face_no)
1843  {
1844  Assert(
1845  face_integrals.find(element[0]->face(face_no)) != face_integrals.end(),
1846  ExcInternalError());
1847  if(element[0]->face(face_no)->at_boundary())
1848  {
1849  for(unsigned int l =0; l < n_error_comps; l ++)
1850  {
1851  dwrc.GetErrorIndicators(l)(present_element) +=
1852  face_integrals[element[0]->face(face_no)][l];
1853  }
1854 // dwrc.GetPrimalErrorIndicators()(present_element) +=
1855 // face_integrals[element[0]->face(face_no)][0];
1856 // dwrc.GetDualErrorIndicators()(present_element) +=
1857 // face_integrals[element[0]->face(face_no)][1];
1858  }
1859  else
1860  {
1861  for(unsigned int l =0; l < n_error_comps; l ++)
1862  {
1863  dwrc.GetErrorIndicators(l)(present_element) +=
1864  0.5*face_integrals[element[0]->face(face_no)][l];
1865  }
1866 // dwrc.GetPrimalErrorIndicators()(present_element) +=
1867 // 0.5 * face_integrals[element[0]->face(face_no)][0];
1868 // dwrc.GetDualErrorIndicators()(present_element) +=
1869 // 0.5 * face_integrals[element[0]->face(face_no)][1];
1870  }
1871 
1872  }
1873  }
1874  }
1875  /*******************************************************************************************/
1876 
1877  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
1878  int dim>
1879  template<typename PROBLEM>
1880  void
1882  PROBLEM& pde,
1884  {
1885  //for primal and dual part of the error
1886  std::vector<double> element_sum(2, 0);
1887  element_sum.resize(2, 0);
1888  // Begin integration
1889  const auto& dof_handler =
1890  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandler();
1891  auto element =
1892  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerBeginActive();
1893  auto endc =
1894  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerEnd();
1895 
1896  {
1897  //Add Weights
1898  auto wd = dwrc.GetWeightData().begin();
1899  auto wend = dwrc.GetWeightData().end();
1900  for (; wd != wend; wd++)
1901  {
1902  AddDomainData(wd->first, wd->second);
1903  }
1904  }
1905 
1906  // Generate the data containers. Notice that we use the quadrature
1907  // formula from the higher order idc!.
1908  GetIntegratorDataContainer().InitializeEDC(pde.GetUpdateFlags(),
1909  *(pde.GetBaseProblem().GetSpaceTimeHandler()), element,
1910  this->GetParamData(), this->GetDomainData());
1911  auto& edc = GetIntegratorDataContainer().GetElementDataContainer();
1912 
1913  //we want to integrate the face-terms only once
1914  typename std::map<typename dealii::Triangulation<dim>::face_iterator,std::vector<double> >
1915  face_integrals;
1916  //initialize the map
1917  auto element_it = element[0];
1918  std::vector<double> face_init(2,-1e20);
1919  for (; element_it != endc[0]; element_it++)
1920  {
1921  for (unsigned int face_no=0;face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
1922  {
1923  face_integrals[element_it->face(face_no)] = face_init;
1924  }
1925  }
1926 
1927 // bool need_faces = pde.HasFaces();
1928 // bool need_interfaces = pde.HasInterfaces();
1929 // std::vector<unsigned int> boundary_equation_colors = pde.GetBoundaryEquationColors();
1930 // bool need_boundary_integrals = (boundary_equation_colors.size() > 0);
1931 
1932  GetIntegratorDataContainer().InitializeFDC(
1933  pde.GetFaceUpdateFlags(),
1934  *(pde.GetBaseProblem().GetSpaceTimeHandler()),
1935  element,
1936  this->GetParamData(),
1937  this->GetDomainData(),
1938  true);
1939  auto & fdc = GetIntegratorDataContainer().GetFaceDataContainer();
1940 
1941  for (unsigned int element_index = 0; element[0] != endc[0];
1942  element[0]++, element_index++)
1943  {
1944  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
1945  {
1946  if (element[dh] == endc[dh])
1947  {
1948  throw DOpEException(
1949  "Elementnumbers in DoFHandlers are not matching!",
1950  "Integrator::ComputeRefinementIndicators");
1951  }
1952  }
1953 
1954  element_sum.clear();
1955  element_sum.resize(2, 0);
1956 
1957  edc.ReInit();
1958  dwrc.InitElement(element[0]->diameter());
1959  //first the element-residual
1960  pde.ElementErrorContribution(edc, dwrc, element_sum, 1.);
1961  dwrc.GetPrimalErrorIndicators()(element_index) = element_sum[0];
1962  dwrc.GetDualErrorIndicators()(element_index) = element_sum[1];
1963  element_sum.clear();
1964  element_sum.resize(2, 0);
1965  //Now to the face terms. We compute them only once for each face and distribute the
1966  //afterwards. We choose always to work from the coarser element, if both neigbors of the
1967  //face are on the same level, we pick the one with the lower index
1968 
1969  for (unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
1970  {
1971  auto face_it = element[0]->face(face);
1972 
1973  //check if the face lies at a boundary
1974  if(face_it->at_boundary())
1975  {
1976  fdc.ReInit(face);
1977 #if deal_II_dimension > 1
1978  dwrc.InitFace(element[0]->face(face)->diameter());
1979 #else
1980  dwrc.InitFace(element[0]->diameter());
1981 #endif
1982  pde.BoundaryErrorContribution(fdc, dwrc, element_sum, 1.);
1983 
1984  Assert (face_integrals.find (element[0]->face(face)) != face_integrals.end(),
1985  ExcInternalError());
1986  Assert (face_integrals[element[0]->face(face)] == face_init,
1987  ExcInternalError());
1988  face_integrals[element[0]->face(face)] = element_sum;
1989  element_sum.clear();
1990  element_sum.resize(2,0.);
1991  }
1992  else
1993  {
1994  //There exist now 3 different scenarios, given the actual element and face:
1995  // The neighbour behind this face is [ more | as much | less] refined
1996  // than/as the actual element. We have to distinguish here only between the case 1
1997  // and the other two, because these will be distinguished in in the FaceDataContainer.
1998  if (element[0]->neighbor(face)->has_children())
1999  {
2000  //first: neighbour is finer
2001  std::vector<double> sum(2,0.);
2002  for (unsigned int subface_no=0;
2003  subface_no < element[0]->face(face)->n_children();
2004  ++subface_no)
2005  {
2006  //TODO Now here we have to initialise the subface_values on the
2007  // actual element and then the facevalues of the neighbours
2008  fdc.ReInit(face, subface_no);
2009  fdc.ReInitNbr();
2010 #if deal_II_dimension > 1
2011  dwrc.InitFace(element[0]->face(face)->diameter());
2012 #else
2013  dwrc.InitFace(element[0]->diameter());
2014 #endif
2015 
2016  pde.FaceErrorContribution(fdc, dwrc, element_sum, 1.);
2017  sum[0]= element_sum[0];
2018  sum[1]= element_sum[1];
2019  element_sum.clear();
2020  element_sum.resize(2,0);
2021  face_integrals[element[0]->neighbor_child_on_subface(face, subface_no)
2022  ->face(element[0]->neighbor_of_neighbor(face))] = element_sum;
2023  element_sum.clear();
2024  element_sum.resize(2,0.);
2025  }
2026 
2027  Assert (face_integrals.find (element[0]->face(face)) != face_integrals.end(),
2028  ExcInternalError());
2029  Assert (face_integrals[element[0]->face(face)] == face_init,
2030  ExcInternalError());
2031 
2032  face_integrals[element[0]->face(face)] = sum;
2033 
2034  }
2035  else
2036  {
2037  // either neighbor is as fine as this element or
2038  // it is coarser
2039  Assert(element[0]->neighbor(face)->level() <= element[0]->level(),ExcInternalError());
2040  //now we work always from the coarser element. if both elements
2041  //are on the same level, we pick the one with the lower index
2042  if(element[0]->level() == element[0]->neighbor(face)->level()
2043  && element[0]->index() < element[0]->neighbor(face)->index())
2044  {
2045  fdc.ReInit(face);
2046  fdc.ReInitNbr();
2047 #if deal_II_dimension > 1
2048  dwrc.InitFace(element[0]->face(face)->diameter());
2049 #else
2050  dwrc.InitFace(element[0]->diameter());
2051 #endif
2052 
2053  pde.FaceErrorContribution(fdc, dwrc, element_sum, 1.);
2054  Assert (face_integrals.find (element[0]->face(face)) != face_integrals.end(),
2055  ExcInternalError());
2056  Assert (face_integrals[element[0]->face(face)] == face_init,
2057  ExcInternalError());
2058 
2059  face_integrals[element[0]->face(face)] = element_sum;
2060  element_sum.clear();
2061  element_sum.resize(2,0);
2062  }
2063  }
2064  }
2065  } //endfor faces
2066 // }//end else
2067 
2068  for (unsigned int dh = 1; dh < dof_handler.size(); dh++)
2069  {
2070  element[dh]++;
2071  }
2072  } //endfor element
2073  //now we have to incorporate the face and boundary_values
2074  //into
2075  unsigned int present_element = 0;
2076  element =
2077  pde.GetBaseProblem().GetSpaceTimeHandler()->GetDoFHandlerBeginActive();
2078  for (;
2079  element[0] !=endc[0]; element[0]++, ++present_element)
2080  for (unsigned int face_no = 0;
2081  face_no < GeometryInfo<dim>::faces_per_cell; ++face_no)
2082  {
2083  Assert(
2084  face_integrals.find(element[0]->face(face_no)) != face_integrals.end(),
2085  ExcInternalError());
2086  dwrc.GetPrimalErrorIndicators()(present_element) +=
2087  0.5 * face_integrals[element[0]->face(face_no)][0];
2088  dwrc.GetDualErrorIndicators()(present_element) +=
2089  0.5 * face_integrals[element[0]->face(face_no)][1];
2090  }
2091  {
2092  //Remove Weights
2093  auto wd = dwrc.GetWeightData().begin();
2094  auto wend = dwrc.GetWeightData().end();
2095  for (; wd != wend; wd++)
2096  {
2097  DeleteDomainData(wd->first);
2098  }
2099  }
2100  }
2101 
2102  /*******************************************************************************************/
2103 
2104  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
2105  int dim>
2106  INTEGRATORDATACONT&
2108  {
2109  return _idc1;
2110  }
2111 
2112  /*******************************************************************************************/
2113 
2114  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
2115  int dim>
2116  INTEGRATORDATACONT&
2118  {
2119  return _idc2;
2120  }
2121 
2122  /*******************************************************************************************/
2123 
2124  template<typename INTEGRATORDATACONT, typename VECTOR, typename SCALAR,
2125  int dim>
2126  template<template<int, int> class DH>
2127  void
2129  const DOpEWrapper::Mapping<dim, DH>& mapping,
2130  const DOpEWrapper::DoFHandler<dim, DH>* dof_handler,
2131  const unsigned int color, const dealii::Function<dim>& function,
2132  std::map<unsigned int, SCALAR>& boundary_values,
2133  const std::vector<bool>& comp_mask) const
2134  {
2135  //TODO: mapping[0] is a workaround, as deal does not support interpolate
2136  // boundary_values with a mapping collection at this point.
2137  dealii::VectorTools::interpolate_boundary_values(mapping[0],
2138  dof_handler->GetDEALDoFHandler(), color, function,
2139  boundary_values, comp_mask);
2140  }
2141 
2142 
2143 }
2144 #endif
2145 
SCALAR ComputeDomainScalar(PROBLEM &pde)
Definition: integrator.h:1173
Definition: mapping_wrapper.h:48
const std::map< std::string, const VECTOR * > & GetWeightData() const
Definition: dwrdatacontainer.h:398
SCALAR ComputeBoundaryScalar(PROBLEM &pde)
Definition: integrator.h:1245
void AddParamData(std::string name, const dealii::Vector< SCALAR > *new_data)
Definition: integrator.h:1573
void ComputeNonlinearLhs(PROBLEM &pde, VECTOR &residual, bool apply_boundary_values=true)
Definition: integrator.h:702
virtual EDC & GetElementWeight() const =0
~Integrator()
Definition: integrator.h:512
SCALAR ComputePointScalar(PROBLEM &pde)
Definition: integrator.h:1227
Definition: integrator.h:59
void ApplyInitialBoundaryValues(PROBLEM &pde, VECTOR &u)
Definition: integrator.h:1430
Vector< double > & GetPrimalErrorIndicators()
Definition: dwrdatacontainer.h:233
void ComputeLocalControlConstraints(PROBLEM &pde, VECTOR &constraints)
Definition: integrator.h:1404
void ComputeMatrix(PROBLEM &pde, MATRIX &matrix)
Definition: integrator.h:984
const DOFHANDLER< dim, dim > & GetDEALDoFHandler() const
Definition: dofhandler_wrapper.h:69
void ComputeRefinementIndicators(PROBLEM &pde, DWRDataContainer< STH, INTEGRATORDATACONT, EDC, FDC, VECTOR > &dwrc)
Definition: integrator.h:1622
const Vector< double > & GetErrorIndicators() const
Definition: dwrdatacontainer.h:213
const std::map< std::string, const dealii::Vector< SCALAR > * > & GetParamData() const
Definition: integrator.h:1611
INTEGRATORDATACONT & GetIntegratorDataContainerFunc() const
Definition: integrator.h:2117
Vector< double > & GetDualErrorIndicators()
Definition: dwrdatacontainer.h:251
virtual STH & GetWeightSTH()=0
SCALAR ComputeFaceScalar(PROBLEM &pde)
Definition: integrator.h:1311
void DeleteParamData(std::string name)
Definition: integrator.h:1592
void DeleteDomainData(std::string name)
Definition: integrator.h:1544
Integrator(INTEGRATORDATACONT &idc1)
Definition: integrator.h:494
Definition: residualestimator.h:38
SCALAR ComputeAlgebraicScalar(PROBLEM &pde)
Definition: integrator.h:1372
void AddDomainData(std::string name, const VECTOR *new_data)
Definition: integrator.h:1526
void ApplyTransposedInitialBoundaryValues(PROBLEM &pde, VECTOR &u)
Definition: integrator.h:1418
virtual FDC & GetFaceWeight() const =0
INTEGRATORDATACONT & GetIntegratorDataContainer() const
Definition: integrator.h:2107
unsigned int GetNErrorComps() const
Definition: dwrdatacontainer.h:317
virtual void InitFace(double)=0
void ReInit()
Definition: integrator.h:522
virtual IDC & GetWeightIDC()=0
Definition: dopeexception.h:35
void ApplyNewtonBoundaryValues(PROBLEM &pde, VECTOR &u)
Definition: integrator.h:1465
void ComputeNonlinearAlgebraicResidual(PROBLEM &pde, VECTOR &residual)
Definition: integrator.h:1390
Definition: dwrdatacontainer.h:545
void ComputeNonlinearRhs(PROBLEM &pde, VECTOR &residual, bool apply_boundary_values=true)
Definition: integrator.h:862
virtual void InitElement(double)=0
void ComputeNonlinearResidual(PROBLEM &pde, VECTOR &residual, bool apply_boundary_values=true)
Definition: integrator.h:533
const std::map< std::string, const VECTOR * > & GetDomainData() const
Definition: integrator.h:1563