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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2013-2015:  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 "dof_count.h"
      34              : #ifdef UG_PARALLEL
      35              :         #include "pcl/pcl_process_communicator.h"
      36              : #endif
      37              : 
      38              : namespace ug{
      39              : 
      40              : ////////////////////////////////////////////////////////////////////////////////
      41              : // DoFCount
      42              : ////////////////////////////////////////////////////////////////////////////////
      43              : 
      44            0 : DoFCount::DoFCount(const GridLevel& gl, ConstSmartPtr<DoFDistributionInfo> spDDInfo)
      45            0 :         :       DoFDistributionInfoProvider(spDDInfo), m_gridLevel(gl)
      46              : {
      47            0 :         vvCmpSubset.resize(num_fct());
      48            0 :         for(size_t fct = 0; fct < vvCmpSubset.size(); ++fct)
      49            0 :                 vvCmpSubset[fct].resize(num_subsets());
      50            0 : }
      51              : 
      52            0 : void DoFCount::add(int fct, int si, SurfaceView::SurfaceState ss, byte is, uint64 numDoF)
      53              : {
      54            0 :         if(!(fct < (int)vvCmpSubset.size()))
      55            0 :                 UG_THROW("DoFCount: fct index "<<fct<<" invalid. NumFct: "<<vvCmpSubset.size());
      56              : 
      57            0 :         if(!(si < (int)vvCmpSubset[fct].size()))
      58            0 :                 UG_THROW("DoFCount: subset index "<<si<<" invalid. NumSubset: "<<vvCmpSubset[fct].size());
      59              : 
      60            0 :         vvCmpSubset[fct][si].add(numDoF, ss, is);
      61            0 : }
      62              : 
      63            0 : void DoFCount::sum_values_over_procs(int proc)
      64              : {
      65              :         PROFILE_FUNC();
      66              : #ifdef UG_PARALLEL
      67              :         pcl::ProcessCommunicator commWorld;
      68              : 
      69              :         // collect all serial values
      70              :         std::vector<uint64> vNumLocal;
      71              :         collect_values(vNumLocal);
      72              : 
      73              :         // sum
      74              :         if(proc == -1){
      75              :                 std::vector<uint64> vNumGlobal(vNumLocal.size());
      76              :                 commWorld.allreduce(&vNumLocal[0], &vNumGlobal[0], vNumLocal.size(),
      77              :                                                         PCL_DT_UNSIGNED_LONG_LONG, PCL_RO_SUM);
      78              :                 set_values(vNumGlobal);
      79              :         }
      80              :         else{
      81              :                 std::vector<uint64> vNumGlobal(vNumLocal.size());
      82              :                 commWorld.reduce(&vNumLocal[0], &vNumGlobal[0], vNumLocal.size(),
      83              :                                                         PCL_DT_UNSIGNED_LONG_LONG, PCL_RO_SUM, proc);
      84              :                 set_values(vNumGlobal);
      85              :         }
      86              : #endif
      87            0 : }
      88              : 
      89            0 : void DoFCount::collect_values(std::vector<uint64>& vNum) const
      90              : {
      91              :         PROFILE_FUNC();
      92            0 :         for(size_t fct = 0; fct < vvCmpSubset.size(); ++fct)
      93            0 :                 for(size_t si = 0; si < vvCmpSubset[fct].size(); ++si)
      94            0 :                         vvCmpSubset[fct][si].collect_values(vNum);
      95            0 : }
      96              : 
      97            0 : void DoFCount::set_values(const std::vector<uint64>& vNum)
      98              : {
      99              :         PROFILE_FUNC();
     100            0 :         size_t cnt = 0;
     101            0 :         for(size_t fct = 0; fct < vvCmpSubset.size(); ++fct)
     102            0 :                 for(size_t si = 0; si < vvCmpSubset[fct].size(); ++si)
     103            0 :                         vvCmpSubset[fct][si].set_values(vNum, cnt);
     104            0 : }
     105              : 
     106            0 : uint64 DoFCount::num(int fct, int si, SurfaceView::SurfaceState ss, byte is) const
     107              : {
     108            0 :         if(fct == ALL_FCT){
     109              :                 uint64 cnt = 0;
     110            0 :                 for(size_t fct = 0; fct < vvCmpSubset.size(); ++fct)
     111            0 :                         cnt += num(fct, si, ss, is);
     112            0 :                 return cnt;
     113              :         }
     114              : 
     115            0 :         if(si == ALL_SUBSET){
     116              :                 uint64 cnt = 0;
     117            0 :                 for(size_t si = 0; si < vvCmpSubset[fct].size(); ++si)
     118            0 :                         cnt += num(fct, si, ss, is);
     119            0 :                 return cnt;
     120              :         }
     121              : 
     122            0 :         return vvCmpSubset[fct][si].num(ss, is);
     123              : }
     124              : 
     125            0 : uint64 DoFCount::num_contains(int fct, int si, SurfaceView::SurfaceState ss, byte is) const
     126              : {
     127            0 :         if(fct == ALL_FCT){
     128              :                 uint64 cnt = 0;
     129            0 :                 for(size_t fct = 0; fct < vvCmpSubset.size(); ++fct)
     130            0 :                         cnt += num_contains(fct, si, ss, is);
     131            0 :                 return cnt;
     132              :         }
     133              : 
     134            0 :         if(si == ALL_SUBSET){
     135              :                 uint64 cnt = 0;
     136            0 :                 for(size_t si = 0; si < vvCmpSubset[fct].size(); ++si)
     137            0 :                         cnt += num_contains(fct, si, ss, is);
     138            0 :                 return cnt;
     139              :         }
     140              : 
     141            0 :         return vvCmpSubset[fct][si].num_contains(ss, is);
     142              : }
     143              : 
     144              : 
     145              : ////////////////////////////////////////////////////////////////////////////////
     146              : // DoFCount::Cnt
     147              : ////////////////////////////////////////////////////////////////////////////////
     148              : 
     149            0 : DoFCount::Cnt::Cnt()
     150              : {
     151            0 :         vNumSS.resize(DoFCount::SS_MAX + 1);
     152            0 : }
     153              : 
     154            0 : void DoFCount::Cnt::collect_values(std::vector<uint64>& vNum) const
     155              : {
     156              :         PROFILE_FUNC();
     157            0 :         vNumSS[SurfaceView::MG_SHADOW_PURE].collect_values(vNum);
     158            0 :         vNumSS[SurfaceView::MG_SURFACE_PURE].collect_values(vNum);
     159            0 :         vNumSS[SurfaceView::MG_SURFACE_RIM].collect_values(vNum);
     160            0 :         vNumSS[SurfaceView::MG_SHADOW_RIM_COPY].collect_values(vNum);
     161            0 :         vNumSS[SurfaceView::MG_SHADOW_RIM_NONCOPY].collect_values(vNum);
     162            0 : }
     163              : 
     164            0 : void DoFCount::Cnt::set_values(const std::vector<uint64>& vNum, size_t& cnt)
     165              : {
     166              :         PROFILE_FUNC();
     167            0 :         vNumSS[SurfaceView::MG_SHADOW_PURE].set_values(vNum, cnt);
     168            0 :         vNumSS[SurfaceView::MG_SURFACE_PURE].set_values(vNum, cnt);
     169            0 :         vNumSS[SurfaceView::MG_SURFACE_RIM].set_values(vNum, cnt);
     170            0 :         vNumSS[SurfaceView::MG_SHADOW_RIM_COPY].set_values(vNum, cnt);
     171            0 :         vNumSS[SurfaceView::MG_SHADOW_RIM_NONCOPY].set_values(vNum, cnt);
     172            0 : }
     173              : 
     174              : 
     175            0 : void DoFCount::Cnt::add(uint64 num, SurfaceView::SurfaceState ss, byte is)
     176              : {
     177              :         // restrict to only considered flags:
     178            0 :         size_t ss_index = (size_t)(ss & SS_MAX)();
     179            0 :         size_t is_index = (size_t)(is & ES_MAX);
     180              : 
     181            0 :         if(!(ss_index < vNumSS.size()))
     182            0 :                 UG_THROW("Something wrong with surface state storage: is: "<<
     183              :                          ss_index<<", max: "<<vNumSS.size());
     184              : 
     185            0 :         if(!(is_index < vNumSS[ss_index].vNumIS.size()))
     186            0 :                 UG_THROW("Something wrong with interface state storage: is: "<<
     187              :                          is_index<<", max: "<<vNumSS[ss_index].vNumIS.size());
     188              : 
     189            0 :         vNumSS[ss_index].vNumIS[is_index] += num;
     190            0 : }
     191              : 
     192              : 
     193            0 : uint64 DoFCount::Cnt::num(SurfaceView::SurfaceState ss, byte is) const
     194              : {
     195            0 :         if(ss == ALL_SS){
     196              :                 uint64 cnt = 0;
     197            0 :                 for(byte l = 0; l <= SS_MAX; ++l)
     198            0 :                         cnt += num(l, is);
     199            0 :                 return cnt;
     200              :         }
     201              : 
     202            0 :         if(ss == UNIQUE_SS){
     203            0 :                 return num(SurfaceView::MG_SHADOW_PURE, is)
     204            0 :                                 + num(SurfaceView::MG_SURFACE_PURE, is)
     205            0 :                                 + num(SurfaceView::MG_SURFACE_RIM, is)
     206              :         //                      + num(SurfaceView::SHADOW_COPY, is)     // copies not counted
     207            0 :                                 + num(SurfaceView::MG_SHADOW_RIM_NONCOPY, is);
     208              :         }
     209              : 
     210            0 :         return vNumSS[ss()].num(is);
     211              : }
     212              : 
     213            0 : uint64 DoFCount::Cnt::num_contains(SurfaceView::SurfaceState ss, byte is) const
     214              : {
     215            0 :         if(ss == ALL_SS){
     216              :                 uint64 cnt = 0;
     217            0 :                 for(byte l = 0; l <= SS_MAX; ++l)
     218            0 :                         cnt += vNumSS[l].num_contains(is);
     219            0 :                 return cnt;
     220              :         }
     221              : 
     222            0 :         if(ss == UNIQUE_SS){
     223            0 :                 return vNumSS[SurfaceView::MG_SHADOW_PURE].num_contains(is)
     224            0 :                                 + vNumSS[SurfaceView::MG_SURFACE_PURE].num_contains(is)
     225            0 :                                 + vNumSS[SurfaceView::MG_SURFACE_RIM].num_contains(is)
     226              :         //                      + vNumSS[SurfaceView::SHADOW_COPY].num_contains(is) // copies not counted
     227            0 :                                 + vNumSS[SurfaceView::MG_SHADOW_RIM_NONCOPY].num_contains(is);
     228              :         }
     229              : 
     230              :         uint64 cnt = 0;
     231            0 :         for(byte l = 0; l <= SS_MAX; ++l){
     232            0 :                 if(l & is)
     233            0 :                         cnt += vNumSS[l].num_contains(is);
     234              :         }
     235              :         return cnt;
     236              : }
     237              : 
     238              : ////////////////////////////////////////////////////////////////////////////////
     239              : // DoFCount::Cnt::PCnt
     240              : ////////////////////////////////////////////////////////////////////////////////
     241              : 
     242            0 : uint64 DoFCount::Cnt::PCnt::num(byte is) const
     243              : {
     244            0 :         if(is == ALL_ES){
     245              :                 uint64 cnt = 0;
     246            0 :                 for(byte l = 0; l <= ES_MAX; ++l)
     247            0 :                         cnt += num(l);
     248            0 :                 return cnt;
     249              :         }
     250              : 
     251            0 :         if(is == UNIQUE_ES){
     252            0 :                 return  num(ES_NONE)                                    // one-proc-only dofs
     253            0 :                                 + num(ES_V_SLAVE)                               // pure vert. slaves
     254            0 :                                 + num(ES_V_SLAVE | ES_V_MASTER) // pure vert.
     255            0 :                                 + num_contains(ES_H_MASTER);    // all horiz. masters
     256              :         }
     257              : 
     258            0 :         return vNumIS[is];
     259              : }
     260              : 
     261            0 : uint64 DoFCount::Cnt::PCnt::num_contains(byte is) const
     262              : {
     263            0 :         if(is == ALL_ES){
     264              :                 uint64 cnt = 0;
     265            0 :                 for(byte l = 0; l <= ES_MAX; ++l)
     266            0 :                         cnt += vNumIS[l];
     267            0 :                 return cnt;
     268              :         }
     269              : 
     270            0 :         if(is == UNIQUE_ES){
     271            0 :                 return  num(ES_NONE)                                    // one-proc-only dofs
     272            0 :                                 + num(ES_V_SLAVE)                               // pure vert. slaves
     273            0 :                                 + num(ES_V_SLAVE | ES_V_MASTER) // pure vert.
     274            0 :                                 + num_contains(ES_H_MASTER);    // all horiz. masters
     275              :         }
     276              : 
     277              :         uint64 cnt = 0;
     278            0 :         for(byte l = 0; l <= ES_MAX; ++l){
     279            0 :                 if(l & is)
     280            0 :                         cnt += vNumIS[l];
     281              :         }
     282              :         return cnt;
     283              : }
     284              : 
     285            0 : DoFCount::Cnt::PCnt::PCnt()
     286              : {
     287            0 :         vNumIS.resize(DoFCount::ES_MAX + 1, 0);
     288            0 : }
     289              : 
     290            0 : void DoFCount::Cnt::PCnt::collect_values(std::vector<uint64>& vNum) const
     291              : {
     292              :         PROFILE_FUNC();
     293            0 :         for(byte l = 0; l <= ES_MAX; ++l){
     294              :         //      I think one shouldn't continue for (ES_V_MASTER | ES_V_SLAVE) here, since those
     295              :         //      guys may actually exist in a distributed grid. That's why I commented the line.
     296              :         //      It should be completely removed somewhen soon...(sreiter)
     297              :                 //if((l & (ES_V_MASTER | ES_V_SLAVE)) == (ES_V_MASTER | ES_V_SLAVE)) continue;
     298            0 :                 if((l & (ES_H_MASTER | ES_H_SLAVE)) == (ES_H_MASTER | ES_H_SLAVE)) continue;
     299              : 
     300            0 :                 vNum.push_back(vNumIS[l]);
     301              :         }
     302            0 : }
     303              : 
     304            0 : void DoFCount::Cnt::PCnt::set_values(const std::vector<uint64>& vNum, size_t& cnt)
     305              : {
     306              :         PROFILE_FUNC();
     307            0 :         for(byte l = 0; l <= ES_MAX; ++l){
     308              :         //      I think one shouldn't continue for (ES_V_MASTER | ES_V_SLAVE) here, since those
     309              :         //      guys may actually exist in a distributed grid. That's why I commented the line.
     310              :         //      It should be completely removed somewhen soon...(sreiter)
     311              :                 //if((l & (ES_V_MASTER | ES_V_SLAVE)) == (ES_V_MASTER | ES_V_SLAVE)) continue;
     312            0 :                 if((l & (ES_H_MASTER | ES_H_SLAVE)) == (ES_H_MASTER | ES_H_SLAVE)) continue;
     313              : 
     314            0 :                 vNumIS[l] = vNum[cnt++];
     315              :         }
     316            0 : }
     317              : 
     318              : } // end namespace ug
        

Generated by: LCOV version 2.0-1