LCOV - code coverage report
Current view: top level - ugbase/lib_disc/spatial_disc/user_data - data_evaluator.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 119 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 39 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2011-2017:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Andreas Vogel
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #include <sstream>
      34              : 
      35              : #include "data_evaluator.h"
      36              : #include "lib_disc/common/groups_util.h"
      37              : 
      38              : namespace ug{
      39              : 
      40              : DebugID DID_DATA_EVALUATOR("DATA_EVALUATOR");
      41              : 
      42              : ///////////////////////////////////////////////////////////////////////////////
      43              : // prepare / finish
      44              : ///////////////////////////////////////////////////////////////////////////////
      45              : 
      46              : template <typename TDomain>
      47            0 : void DataEvaluator<TDomain>::
      48              : prepare_elem_loop(const ReferenceObjectID id, int si)
      49              : {
      50              : //      prepare loop (elem disc set local ip series here)
      51              :         try{
      52            0 :                 for(size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
      53            0 :                         m_vElemDisc[PT_ALL][i]->do_prep_elem_loop(id, si);
      54              :         }
      55            0 :         UG_CATCH_THROW("DataEvaluatorBase::prepare_elem_loop: "
      56              :                                                 "Cannot prepare element loop.");
      57              : 
      58              : //      extract data imports and userdatas
      59              :         try{
      60            0 :                 extract_imports_and_userdata(si, m_discPart);
      61              :         }
      62            0 :         UG_CATCH_THROW("DataEvaluatorBase::prepare_elem_loop: "
      63              :                                         "Cannot extract imports and userdata.");
      64              : 
      65              : //      check setup of imports
      66              :         try{
      67            0 :                 for(size_t i = 0; i < m_vImport[PT_ALL][MASS].size(); ++i)
      68            0 :                         m_vImport[PT_ALL][MASS][i]->check_setup();
      69            0 :                 for(size_t i = 0; i < m_vImport[PT_ALL][STIFF].size(); ++i)
      70            0 :                         m_vImport[PT_ALL][STIFF][i]->check_setup();
      71            0 :                 for(size_t i = 0; i < m_vImport[PT_ALL][RHS].size(); ++i)
      72            0 :                         m_vImport[PT_ALL][RHS][i]->check_setup();
      73              :         }
      74            0 :         UG_CATCH_THROW("DataEvaluatorBase::prepare_elem_loop: Import correctly implemented.");
      75              : 
      76              : //      prepare and check dependent data
      77              :         try{
      78            0 :                 for(size_t i = 0; i < m_vDependentData.size(); ++i){
      79            0 :                         m_vDependentData[i]->check_setup();
      80              :                 }
      81              :         }
      82            0 :         UG_CATCH_THROW("DataEvaluatorBase::prepare_elem_loop: Dependent UserData "
      83              :                                    " (e.g. Linker or Export) is not ready for evaluation.");
      84              : 
      85              : //      evaluate constant data
      86            0 :         for(size_t i = 0; i < m_vConstData.size(); ++i)
      87            0 :                 m_vConstData[i]->compute((LocalVector*)NULL, NULL, NULL, false);
      88            0 : }
      89              : 
      90              : template <typename TDomain>
      91            0 : void DataEvaluator<TDomain>::finish_elem_loop()
      92              : {
      93              : //      finish each elem disc
      94              :         try{
      95            0 :                 for(size_t d = 0; d < m_vElemDisc[PT_ALL].size(); ++d)
      96              :                 {
      97            0 :                         IElemDisc<TDomain>* disc = m_vElemDisc[PT_ALL][d];
      98              :                         
      99            0 :                         disc->do_fsh_elem_loop();
     100              :                         
     101              :                         /* TODO:
     102              :                          * In prepare_elem_loop, the elemdiscs initialize the local ip's independently
     103              :                          * on if they are used. For ex., the ip's used only for the mass matrix are
     104              :                          * initialized, too, even if only the stiffness part is assembled. These ip's
     105              :                          * are not cleared below as they do not get into the lists, and this creates
     106              :                          * issues with the linkers that share subordinated userdata objects. For that,
     107              :                          * we clear here all the assigned ip's.
     108              :                          *
     109              :                          * Should it be done here on in do_fsh_elem_loop?
     110              :                          */
     111            0 :                         for (size_t i = 0; i < disc->num_imports(); ++i)
     112              :                         {
     113              :                                 IDataImport<dim>& imp = disc->get_import(i);
     114            0 :                                 if(imp.data_given())
     115            0 :                                         imp.data()->clear();
     116              :                         }
     117              :                 }
     118              :         }
     119            0 :         UG_CATCH_THROW("DataEvaluatorBase::fsh_elem_loop: Cannot finish element loop");
     120              : 
     121              : //      clear positions at user data
     122              :         /* TODO:
     123              :          * Could it be done in a more elegant way? For ex., why clearing here all the ip
     124              :          * series and not only the ones assigned to the particular userdata objects?
     125              :          */
     126            0 :         clear_positions_in_user_data();
     127            0 : }
     128              : 
     129              : 
     130              : ///////////////////////////////////////////////////////////////////////////////
     131              : // Assemble routines
     132              : ///////////////////////////////////////////////////////////////////////////////
     133              : 
     134              : template <typename TDomain>
     135            0 : void DataEvaluator<TDomain>::prepare_timestep(number future_time, const number time, VectorProxyBase* u, size_t algebra_id)
     136              : {
     137              :         try
     138              :         {
     139            0 :                 for (size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
     140            0 :                         m_vElemDisc[PT_ALL][i]->do_prep_timestep(future_time, time, u, algebra_id);
     141              :         }
     142            0 :         UG_CATCH_THROW("DataEvaluatorBase::prep_timestep: Cannot prepare time step.");
     143            0 : }
     144              : 
     145              : template <typename TDomain>
     146            0 : void DataEvaluator<TDomain>::
     147              : prepare_timestep_elem(const number time, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
     148              : {
     149              :         try{
     150            0 :                 for(size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
     151            0 :                         m_vElemDisc[PT_ALL][i]->do_prep_timestep_elem(time, u, elem, vCornerCoords);
     152              :         }
     153            0 :         UG_CATCH_THROW("DataEvaluatorBase::prep_timestep_elem: Cannot prepare timestep.");
     154            0 : }
     155              : 
     156              : 
     157              : template <typename TDomain>
     158            0 : void DataEvaluator<TDomain>::
     159              : prepare_elem(LocalVector& u, GridObject* elem, const ReferenceObjectID roid, const MathVector<dim> vCornerCoords[],
     160              :              const LocalIndices& ind,
     161              :              bool bDeriv)
     162              : {
     163              : //      prepare element
     164              :         try{
     165            0 :                 for(size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i){
     166              :                         UG_DLOG(DID_DATA_EVALUATOR, 2, ">>OCT_DISC_DEBUG: " << "data_evaluator.cpp: " << "DataEvaluatorBase.prepare_elem(): m_vElemDisc[PT_ALL][i]->do_prep_elem() " << roid << std::endl);
     167            0 :                         m_vElemDisc[PT_ALL][i]->do_prep_elem(u, elem, roid, vCornerCoords);
     168              :                 }
     169              :         }
     170            0 :         UG_CATCH_THROW("DataEvaluatorBase::prep_elem: Cannot prepare element.");
     171              : 
     172              : //      adjust lin defect array of imports and derivative array of exports
     173              : //      INFO: This is place here, since the 'prepare_elem' method of an element
     174              : //                      disc may change the number of integration points, even if the type
     175              : //                      of the element (e.g. triangle, quad) stays the same. This is the
     176              : //                      case for, e.g., the NeumannBoundary element disc.
     177            0 :         if(bDeriv)
     178              :         {
     179            0 :                 for(size_t i = 0; i < m_vImport[PT_ALL][MASS].size(); ++i)
     180            0 :                         m_vImport[PT_ALL][MASS][i]->update_dof_sizes(ind);
     181            0 :                 for(size_t i = 0; i < m_vImport[PT_ALL][STIFF].size(); ++i)
     182            0 :                         m_vImport[PT_ALL][STIFF][i]->update_dof_sizes(ind);
     183            0 :                 for(size_t i = 0; i < m_vImport[PT_ALL][RHS].size(); ++i)
     184            0 :                         m_vImport[PT_ALL][RHS][i]->update_dof_sizes(ind);
     185              : 
     186            0 :                 for(size_t i = 0; i < m_vDependentData.size(); ++i)
     187            0 :                         m_vDependentData[i]->update_dof_sizes(ind);
     188              :         }
     189              : 
     190              : //      evaluate position data
     191            0 :         for(size_t i = 0; i < m_vPosData.size(); ++i)
     192            0 :                 m_vPosData[i]->compute(&u, elem, vCornerCoords, false);
     193              : 
     194              : //      process dependent data:
     195              : //      We can not simply compute exports first, then Linker, because an export
     196              : //      itself could depend on other data if implemented somehow in the IElemDisc
     197              : //      (e.g. using data from some DataImport). Thus, we have to loop the sorted
     198              : //      vector of all dependent data (that is correctly sorted the way that always
     199              : //      needed data has previously computed).
     200              : 
     201              : //      compute the data
     202              :         try{
     203            0 :                 if (! time_series_needed ()) { // assemble for the given LocalVector
     204            0 :                         for(size_t i = 0; i < m_vDependentData.size(); ++i){
     205            0 :                                 u.access_by_map(m_vDependentData[i]->map());
     206            0 :                                 m_vDependentData[i]->compute(&u, elem, vCornerCoords, bDeriv);
     207              :                         }
     208              :                 }
     209              :                 else { // assemble for LocalVectorTimeSeries
     210            0 :                         for(size_t i = 0; i < m_vDependentData.size(); ++i){
     211            0 :                                 u.access_by_map(m_vDependentData[i]->map());
     212            0 :                                 m_vDependentData[i]->compute(m_pLocTimeSeries, elem, vCornerCoords, bDeriv);
     213              :                         }
     214              :                 }
     215              :         }
     216            0 :         UG_CATCH_THROW("DataEvaluatorBase::prep_elem: Cannot compute data for Export or Linker.");
     217            0 : }
     218              : 
     219              : template <typename TDomain>
     220            0 : void DataEvaluator<TDomain>::finish_timestep(const number time, VectorProxyBase* u, size_t algebra_id)
     221              : {
     222              :         try
     223              :         {
     224            0 :                 for (size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
     225            0 :                         m_vElemDisc[PT_ALL][i]->do_fsh_timestep(time, u, algebra_id);
     226              :         }
     227            0 :         UG_CATCH_THROW("DataEvaluatorBase::finish_timestep: Cannot prepare time step.");
     228            0 : }
     229              : 
     230              : template <typename TDomain>
     231            0 : void DataEvaluator<TDomain>::
     232              : finish_timestep_elem(const number time, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
     233              : {
     234              :         try{
     235            0 :                 for(size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
     236            0 :                         m_vElemDisc[PT_ALL][i]->do_fsh_timestep_elem(time, u, elem, vCornerCoords);
     237              :         }
     238            0 :         UG_CATCH_THROW("DataEvaluatorBase::fsh_timestep_elem: Cannot finish timestep.");
     239            0 : }
     240              : 
     241              : template <typename TDomain>
     242            0 : void DataEvaluator<TDomain>::
     243              : add_jac_A_elem(LocalMatrix& J, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[], ProcessType type)
     244              : {
     245              :         UG_ASSERT(m_discPart & STIFF, "Using add_jac_A_elem, but not STIFF requested.");
     246              : 
     247              :         // compute elem-owned contribution
     248              :         try{
     249            0 :                 for(size_t i = 0; i < m_vElemDisc[type].size(); ++i)
     250            0 :                         m_vElemDisc[type][i]->do_add_jac_A_elem(J, u, elem, vCornerCoords);
     251              :         }
     252            0 :         UG_CATCH_THROW("DataEvaluatorBase::add_jac_A_elem: Cannot assemble Jacobian (A)");
     253              : 
     254              :         //      compute linearized defect
     255              :         try{
     256            0 :                 for(size_t i = 0; i < m_vImport[type][STIFF].size(); ++i)
     257            0 :                         m_vImport[type][STIFF][i]->compute_lin_defect(u);
     258              : 
     259            0 :                 for(size_t i = 0; i < m_vImport[type][RHS].size(); ++i)
     260            0 :                         m_vImport[type][RHS][i]->compute_lin_defect(u);
     261              :         }
     262            0 :         UG_CATCH_THROW("DataEvaluatorBase::add_jac_A_elem: Cannot compute"
     263              :                         " linearized defect for Import.");
     264              : 
     265              :         //      add off diagonal coupling
     266              :         try{
     267              :                 //      loop all imports located in the stiffness part
     268            0 :                 for(size_t i = 0; i < m_vImport[type][STIFF].size(); ++i)
     269            0 :                         m_vImport[type][STIFF][i]->add_jacobian(J, 1.0);
     270              : 
     271              :                 //      loop all imports located in the rhs part
     272            0 :                 for(size_t i = 0; i < m_vImport[type][RHS].size(); ++i)
     273            0 :                         m_vImport[type][RHS][i]->add_jacobian(J, -1.0);
     274              :         }
     275            0 :         UG_CATCH_THROW("DataEvaluatorBase::add_jac_A_elem: Cannot add couplings.");
     276            0 : }
     277              : 
     278              : template <typename TDomain>
     279            0 : void DataEvaluator<TDomain>::
     280              : add_jac_M_elem(LocalMatrix& J, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[], ProcessType type)
     281              : {
     282              :         UG_ASSERT(m_discPart & MASS, "Using add_jac_M_elem, but not MASS requested.");
     283              : 
     284              :         // compute elem-owned contribution
     285              :         try{
     286            0 :                 for(size_t i = 0; i < m_vElemDisc[type].size(); ++i)
     287            0 :                         m_vElemDisc[type][i]->do_add_jac_M_elem(J, u, elem, vCornerCoords);
     288              :         }
     289            0 :         UG_CATCH_THROW("DataEvaluatorBase::add_jac_M_elem: Cannot assemble Jacobian (M)");
     290              : 
     291              :         //      compute linearized defect
     292              :         try{
     293            0 :                 for(size_t i = 0; i < m_vImport[type][MASS].size(); ++i)
     294            0 :                         m_vImport[type][MASS][i]->compute_lin_defect(u);
     295              :         }
     296            0 :         UG_CATCH_THROW("DataEvaluatorBase::add_coupl_JM: Cannot compute"
     297              :                         " linearized defect for Import.");
     298              : 
     299              :         //      add off diagonal coupling
     300              :         try{
     301              :                 //      loop all imports located in the mass part
     302            0 :                 for(size_t i = 0; i < m_vImport[type][MASS].size(); ++i)
     303            0 :                         m_vImport[type][MASS][i]->add_jacobian(J, 1.0);
     304              :         }
     305            0 :         UG_CATCH_THROW("DataEvaluatorBase::add_coupl_JM: Cannot add couplings.");
     306            0 : }
     307              : 
     308              : template <typename TDomain>
     309            0 : void DataEvaluator<TDomain>::
     310              : add_def_A_elem(LocalVector& d, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[], ProcessType type)
     311              : {
     312              :         UG_ASSERT(m_discPart & STIFF, "Using add_def_A_elem, but not STIFF requested.");
     313              : 
     314              :         try{
     315            0 :                 for(size_t i = 0; i < m_vElemDisc[type].size(); ++i)
     316            0 :                         m_vElemDisc[type][i]->do_add_def_A_elem(d, u, elem, vCornerCoords);
     317              :         }
     318            0 :         UG_CATCH_THROW("DataEvaluatorBase::add_def_A_elem: Cannot assemble Defect (A)");
     319            0 : }
     320              : 
     321              : template <typename TDomain>
     322            0 : void DataEvaluator<TDomain>::
     323              : add_def_A_expl_elem(LocalVector& d, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[], ProcessType type)
     324              : {
     325              :         UG_ASSERT(m_discPart & EXPL, "Using add_def_A_elem, but not EXPL requested.");
     326              : 
     327              :         try{
     328            0 :                 for(size_t i = 0; i < m_vElemDisc[type].size(); ++i)
     329            0 :                         m_vElemDisc[type][i]->do_add_def_A_expl_elem(d, u, elem, vCornerCoords);
     330              :         }
     331            0 :         UG_CATCH_THROW("DataEvaluatorBase::add_def_A_expl_elem: Cannot assemble Defect (A)");
     332            0 : }
     333              : 
     334              : template <typename TDomain>
     335            0 : void DataEvaluator<TDomain>::
     336              : add_def_M_elem(LocalVector& d, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[], ProcessType type)
     337              : {
     338              :         UG_ASSERT(m_discPart & MASS, "Using add_def_M_elem, but not MASS requested.");
     339              : 
     340              :         try{
     341            0 :                 for(size_t i = 0; i < m_vElemDisc[type].size(); ++i)
     342            0 :                         m_vElemDisc[type][i]->do_add_def_M_elem(d, u, elem, vCornerCoords);
     343              :         }
     344            0 :         UG_CATCH_THROW("DataEvaluatorBase::add_def_M_elem: Cannot assemble Defect (M)");
     345            0 : }
     346              : 
     347              : template <typename TDomain>
     348            0 : void DataEvaluator<TDomain>::
     349              : add_rhs_elem(LocalVector& rhs, GridObject* elem, const MathVector<dim> vCornerCoords[], ProcessType type)
     350              : {
     351              :         UG_ASSERT(m_discPart & RHS, "Using add_rhs_elem, but not RHS requested.");
     352              : 
     353              :         try{
     354            0 :                 for(size_t i = 0; i < m_vElemDisc[type].size(); ++i)
     355            0 :                         m_vElemDisc[type][i]->do_add_rhs_elem(rhs, elem, vCornerCoords);
     356              :         }
     357            0 :         UG_CATCH_THROW("DataEvaluatorBase::add_rhs_elem: Cannot assemble rhs");
     358            0 : }
     359              : 
     360              : ////////////////////////////////////////////////////////////////////////////////
     361              : //      explicit template instantiations
     362              : ////////////////////////////////////////////////////////////////////////////////
     363              : 
     364              : #ifdef UG_DIM_1
     365              : template class DataEvaluatorBase<Domain1d, IElemDisc<Domain1d> >;
     366              : template class ErrorEvaluator<Domain1d>;
     367              : template class DataEvaluator<Domain1d>;
     368              : #endif
     369              : #ifdef UG_DIM_2
     370              : template class DataEvaluatorBase<Domain2d, IElemDisc<Domain2d> >;
     371              : template class ErrorEvaluator<Domain2d>;
     372              : template class DataEvaluator<Domain2d>;
     373              : #endif
     374              : #ifdef UG_DIM_3
     375              : template class DataEvaluatorBase<Domain3d, IElemDisc<Domain3d> >;
     376              : template class ErrorEvaluator<Domain3d>;
     377              : template class DataEvaluator<Domain3d>;
     378              : #endif
     379              : 
     380              : } // end namespace ug
     381              : 
        

Generated by: LCOV version 2.0-1