LCOV - code coverage report
Current view: top level - ugbase/lib_grid - global_attachments.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 114 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 242 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       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              : #ifndef __H__UG_global_attachments
      34              : #define __H__UG_global_attachments
      35              : 
      36              : #include "attachments/attachment_info_traits.h"
      37              : #include "attachments/attachment_io_traits.h"
      38              : #include "algorithms/serialization.h"
      39              : #include <algorithm>
      40              : 
      41              : namespace ug{
      42              : 
      43              : ///     Global attachments are automatically read/written from/to files and are considered during redistribution
      44              : class GlobalAttachments {
      45              :         public:
      46              :                 template <class TAttachment>
      47            0 :                 static void declare_attachment (const std::string& name,
      48              :                                                                                 bool passOnBehaviour = false)
      49              :                 {
      50              :                         const char* typeName = attachment_info_traits<TAttachment>::type_name();
      51            0 :                         if(attachments()[name].attachment != NULL) {
      52            0 :                                 UG_COND_THROW(
      53              :                                         dynamic_cast<TAttachment*> (attachments()[name].attachment) == NULL,
      54              :                                                   "Attachment with name '" << name
      55              :                                                   << "' was already declared in GlobalAttachments with a different type. "
      56              :                                                   << "Old type: " << attachments()[name].type <<
      57              :                                                   ", new type: " << typeName);
      58              :                                 return;
      59              :                         }
      60              : 
      61            0 :                         int fi = static_cast<int> (attachment_names().size());
      62            0 :                         attachment_names().push_back(name);
      63            0 :                         attachments()[name] =
      64            0 :                                 AttachmentEntry(new TAttachment(passOnBehaviour), typeName, fi);
      65            0 :                         functions<Vertex>().push_back(FunctionEntry<Vertex, TAttachment>());
      66            0 :                         functions<Edge>().push_back(FunctionEntry<Edge, TAttachment>());
      67            0 :                         functions<Face>().push_back(FunctionEntry<Face, TAttachment>());
      68            0 :                         functions<Volume>().push_back(FunctionEntry<Volume, TAttachment>());
      69              :                 }
      70              : 
      71              :                 template <class TAttachment>
      72              :                 static void undeclare_attachment(const std::string& name) {
      73              :                         UG_COND_THROW(!is_declared(name), "Trying undeclaring a non-declared attachment.");
      74              :                         AttachmentEntry& ae = attachment_entry(name);
      75              :                         remove_function_entry<Volume>(ae);
      76              :                         remove_function_entry<Face>(ae);
      77              :                         remove_function_entry<Edge>(ae);
      78              :                         remove_function_entry<Vertex>(ae);
      79              :                         attachment_names().erase(std::remove(attachment_names().begin(), attachment_names().end(), name), attachment_names().end());
      80              :                         attachments().erase(name);
      81              :                         const char* typeName = attachment_info_traits<TAttachment>::type_name();
      82              :                         attachment_types().erase(typeName);
      83              :                 }
      84              : 
      85            0 :                 static void declare_attachment (const std::string& name,
      86              :                                                                                 const std::string& typeName,
      87              :                                                                                 bool passOnBehaviour = false)
      88              :                 {
      89            0 :                         UG_COND_THROW(attachment_types()[typeName].declareFunc == 0,
      90              :                                                   "Unregistered attachment type used in "
      91              :                                                   << "GlobalAttachments::declare_attachment: '"
      92              :                                                   << typeName << "' during declaration of attachment '"
      93              :                                                   << name << "'.");
      94            0 :                         attachment_types()[typeName].declareFunc(name, passOnBehaviour);
      95            0 :                 }
      96              : 
      97              :                 template <class TAttachment>
      98            0 :                 static void register_attachment_type ()
      99              :                 {
     100            0 :                         std::string typeName = attachment_info_traits<TAttachment>::type_name();
     101            0 :                         attachment_types()[typeName] = AttachmentType<TAttachment>();
     102            0 :                 }
     103              : 
     104              :                 static const std::vector<std::string>&
     105              :                 declared_attachment_names ()
     106              :                 {
     107              :                         return attachment_names();
     108              :                 }
     109              : 
     110              :                 static
     111            0 :                 bool is_declared(const std::string& name)
     112              :                 {
     113            0 :                         return attachments().find(name) != attachments().end();
     114              :                 }
     115              : 
     116              :                 static
     117            0 :                 bool attachment_pass_on_behaviour(const std::string& name)
     118              :                 {
     119            0 :                         UG_COND_THROW(!is_declared(name), "Undeclared attachment queried: " << name);
     120            0 :                         return attachments()[name].attachment->default_pass_on_behaviour();
     121              :                 }
     122              : 
     123              :                 static
     124            0 :                 bool type_is_registered(const std::string& typeName)
     125              :                 {
     126            0 :                         return attachment_types().find(typeName) != attachment_types().end();
     127              :                 }
     128              :                 
     129              :                 #ifdef UG_PARALLEL
     130              :                 static void SynchronizeDeclaredGlobalAttachments(Grid& grid, int procId)
     131              :                 {
     132              :                         if (procId < 0) return; // this is not a parallel run
     133              :                         
     134              :                         //declare global attachments on all processors
     135              :                         pcl::ProcessCommunicator procComm;
     136              :                         std::vector<std::string> possible_attachment_names = GlobalAttachments::declared_attachment_names();
     137              :                         // only master proc loaded the grid
     138              :                         if (procId == 0)
     139              :                                 procComm.broadcast<std::vector<std::string> >(possible_attachment_names, procId);
     140              :                         else
     141              :                                 UG_THROW("There are more than one proc loading the grid"<<
     142              :                                                 "please make sure all processes broadcast their GlobalAttachments");
     143              :                                                 
     144              :                         std::vector<byte> locDeclared(possible_attachment_names.size(), 0);
     145              :                         std::vector<byte> globDeclared(possible_attachment_names.size(), 0);
     146              :                         // record local info
     147              :                         for(size_t i = 0; i < possible_attachment_names.size(); ++i){
     148              :                                 byte& b = locDeclared[i];
     149              :                                 if(GlobalAttachments::is_declared(possible_attachment_names[i])){
     150              :                                         b |= 1;
     151              :                                         if(GlobalAttachments::is_attached<Vertex>(grid, possible_attachment_names[i]))
     152              :                                                 b |= 1<<1;
     153              :                                         if(GlobalAttachments::is_attached<Edge>(grid, possible_attachment_names[i]))
     154              :                                                 b |= 1<<2;
     155              :                                         if(GlobalAttachments::is_attached<Face>(grid, possible_attachment_names[i]))
     156              :                                                 b |= 1<<3;
     157              :                                         if(GlobalAttachments::is_attached<Volume>(grid, possible_attachment_names[i]))
     158              :                                                 b |= 1<<4;
     159              :                                 }
     160              :                         }
     161              :                         // sum up all the local to the global
     162              :                         procComm.allreduce(locDeclared, globDeclared, PCL_RO_BOR);
     163              :                         // update the local with the global
     164              :                         for(size_t i = 0; i < possible_attachment_names.size(); ++i){
     165              :                                 byte& b = globDeclared[i];
     166              :                                 if(b & 1){
     167              :                                         if(!GlobalAttachments::is_declared(possible_attachment_names[i]))
     168              :                                                 GlobalAttachments::declare_attachment(possible_attachment_names[i], "double", true);
     169              :                                         if(b & 1<<1)
     170              :                                                 GlobalAttachments::attach<Vertex>(grid, possible_attachment_names[i]);
     171              :                                         if(b & 1<<2)
     172              :                                                 GlobalAttachments::attach<Edge>(grid, possible_attachment_names[i]);      
     173              :                                         if(b & 1<<3)
     174              :                                                 GlobalAttachments::attach<Face>(grid, possible_attachment_names[i]);      
     175              :                                         if(b & 1<<4)
     176              :                                                 GlobalAttachments::attach<Volume>(grid, possible_attachment_names[i]);    
     177              :                                 }
     178              :                         }
     179              : 
     180              :                 }
     181              :                 #endif
     182              :                 
     183              :                 template <class TElem>
     184              :                 static
     185              :                 void attach(Grid& g, const std::string& name)
     186              :                 {
     187              :                         AttachmentEntry& ae = attachment_entry(name);
     188              :                         IFunctionEntry& fe = function_entry<TElem>(ae);
     189              :                         fe.attach(g, *ae.attachment);
     190              :                 }
     191              : 
     192              :                 template <class TElem>
     193              :                 static
     194            0 :                 bool is_attached(Grid& g, const std::string& name)
     195              :                 {
     196            0 :                         AttachmentEntry& ae = attachment_entry(name);
     197            0 :                         return g.has_attachment<TElem>(*ae.attachment);
     198              :                 }
     199              : 
     200              :                 template <class TAttachment>
     201              :                 static
     202            0 :                 TAttachment attachment (const std::string& name)
     203              :                 {
     204            0 :                         AttachmentEntry& e = attachment_entry(name);
     205            0 :                         TAttachment* a = dynamic_cast<TAttachment*>(e.attachment);
     206            0 :                         UG_COND_THROW(!a, "Attachment with invalid type queried. Given type "
     207              :                                                   "is " << e.type << ", queried type is " <<
     208              :                                                   attachment_info_traits<TAttachment>::type_name());
     209            0 :                         return *a;
     210              :                 }
     211              : 
     212              :                 static
     213              :                 const char* type_name (const std::string& name)
     214              :                 {
     215            0 :                         AttachmentEntry& e = attachment_entry(name);
     216            0 :                         return e.type;
     217              :                 }
     218              : 
     219              :                 template <class TElem>
     220              :                 static
     221            0 :                 void read_attachment_values (std::istream& in,
     222              :                                                                          Grid& grid,
     223              :                                                                          const std::string& name)
     224              :                 {
     225            0 :                         AttachmentEntry& ae = attachment_entry(name);
     226            0 :                         IFunctionEntry& fe = function_entry<TElem>(ae);
     227            0 :                         fe.readFunc(in, grid, *ae.attachment);
     228            0 :                 }
     229              : 
     230              : 
     231              :                 template <class TElem>
     232              :                 static
     233            0 :                 void write_attachment_values (std::ostream& out,
     234              :                                                                           Grid& grid,
     235              :                                                                           const std::string& name)
     236              :                 {
     237            0 :                         AttachmentEntry& ae = attachment_entry(name);
     238            0 :                         function_entry<TElem>(ae).writeFunc(out, grid, *ae.attachment);
     239            0 :                 }
     240              : 
     241              :                 template <class TElem>
     242              :                 static
     243              :                 void add_data_serializer(GridDataSerializationHandler& handler,
     244              :                                                                  Grid& grid,
     245              :                                                                  const std::string& name)
     246              :                 {
     247              :                         AttachmentEntry& ae = attachment_entry(name);
     248              :                         IFunctionEntry& fe = function_entry<TElem>(ae);
     249              :                         fe.addSerializer(handler, grid, *ae.attachment);
     250              :                 }
     251              : 
     252              : 
     253              :         private:
     254              :         ////////////////////////////////////////
     255              :         //      TYPES
     256              :                 struct AttachmentEntry {
     257            0 :                         AttachmentEntry () : attachment(NULL), type(""), functionIndex(-1) {}
     258              :                         AttachmentEntry (IAttachment* a, const char* t, int fi) :
     259              :                                 attachment(a), type(t), functionIndex(fi) {}
     260              :                         IAttachment*    attachment;
     261              :                         const char*             type;
     262              :                         int                             functionIndex;
     263              :                 };
     264              : 
     265              :                 struct IFunctionEntry {
     266            0 :                         IFunctionEntry() : readFunc(0), writeFunc(0), addSerializer(0), attach(0) {}
     267              :                         void (*readFunc )               (std::istream&, Grid&, IAttachment&);
     268              :                         void (*writeFunc)               (std::ostream&, Grid&, IAttachment&);
     269              :                         void (*addSerializer)   (GridDataSerializationHandler&, Grid&, IAttachment&);
     270              :                         void (*attach)                  (Grid&, IAttachment&);
     271              :                 };
     272              : 
     273              :                 template <class TElem, class TAttachment>
     274              :                 struct FunctionEntry : public IFunctionEntry {
     275              :                         FunctionEntry() {
     276            0 :                                 readFunc =              &read_attachment_from_stream<TElem, TAttachment>;
     277            0 :                                 writeFunc =     &write_attachment_to_stream<TElem, TAttachment>;
     278            0 :                                 addSerializer = &add_attachment_serializer<TElem, TAttachment>;
     279            0 :                                 attach =                &cast_and_attach<TElem, TAttachment>;
     280              :                         }
     281              :                 };
     282              : 
     283              :                 struct IAttachmentType {
     284            0 :                         IAttachmentType() : declareFunc(0)      {}
     285              :                         void (*declareFunc)     (const std::string&, bool);
     286              :                 };
     287              : 
     288              :                 template <class TAttachment>
     289              :                 struct AttachmentType : public IAttachmentType {
     290              :                         AttachmentType() {
     291              :                                 declareFunc =   &declare_attachment<TAttachment>;
     292              :                         }
     293              :                 };
     294              : 
     295              : 
     296              :                 typedef std::map<std::string, AttachmentEntry>    AttachmentMap;
     297              :                 typedef std::map<std::string, IAttachmentType>    AttachmentTypeMap;
     298              :                 typedef std::vector<IFunctionEntry>                               FunctionVec;
     299              : 
     300              : 
     301              :         ////////////////////////////////////////
     302              :         //      METHODS
     303              :                 static
     304            0 :                 GlobalAttachments& inst ()
     305              :                 {
     306            0 :                         static GlobalAttachments h;
     307            0 :                         return h;
     308              :                 }
     309              : 
     310            0 :                 GlobalAttachments ()    {}
     311              : 
     312            0 :                 ~GlobalAttachments ()
     313            0 :                 {
     314              :                         AttachmentMap& m = attachments();
     315            0 :                         for(AttachmentMap::iterator i = m.begin(); i != m.end(); ++i) {
     316            0 :                                 if(i->second.attachment)
     317            0 :                                         delete i->second.attachment;
     318              :                         }
     319            0 :                 }
     320              : 
     321              :                 static
     322              :                 std::vector<std::string>& attachment_names() {
     323            0 :                         return inst().m_attachmentNames;
     324              :                 }
     325              : 
     326              :                 static
     327              :                 AttachmentMap& attachments() {
     328            0 :                         return inst().m_attachmentMap;
     329              :                 }
     330              : 
     331              :                 static
     332            0 :                 AttachmentTypeMap& attachment_types() {
     333              :                         static bool initialized = false;
     334            0 :                         if(!initialized){
     335            0 :                                 initialized = true;
     336            0 :                                 register_standard_attachment_types();
     337              :                         }
     338            0 :                         return inst().m_attachmentTypeMap;
     339              :                 }
     340              : 
     341              :                 template <class TElem>
     342              :                 static
     343              :                 FunctionVec& functions() {
     344            0 :                         return inst().m_functionVecs[TElem::BASE_OBJECT_ID];
     345              :                 }
     346              : 
     347              :                 static
     348            0 :                 AttachmentEntry& attachment_entry(const std::string& name)
     349              :                 {
     350            0 :                         AttachmentEntry& e = attachments()[name];
     351            0 :                         UG_COND_THROW(!e.attachment, "Undeclared attachment queried: " << name);
     352            0 :                         return e;
     353              :                 }
     354              : 
     355              :                 template <class TElem>
     356              :                 static
     357              :                 IFunctionEntry& function_entry(const std::string& name)
     358              :                 {
     359              :                         return function_entry<TElem>(attachment_entry(name));
     360              :                 }
     361              : 
     362              :                 template <class TElem>
     363              :                 static
     364            0 :                 IFunctionEntry& function_entry(const AttachmentEntry& ae)
     365              :                 {
     366            0 :                         return functions<TElem>().at(ae.functionIndex);
     367              :                 }
     368              : 
     369              :                 template <class TElem>
     370              :                 static
     371              :                 void remove_function_entry(const AttachmentEntry& ae) {
     372              :                         functions<TElem>().erase(functions<TElem>().begin() + ae.functionIndex);
     373              :                 }
     374              : 
     375              :                 template <class TElem, class TAttachment>
     376              :                 static
     377            0 :                 void read_attachment_from_stream (
     378              :                                 std::istream& in,
     379              :                                 Grid& grid,
     380              :                                 IAttachment& attachment)
     381              :                 {
     382            0 :                         TAttachment& a = dynamic_cast<TAttachment&>(attachment);
     383              :                         
     384            0 :                         if(!grid.has_attachment<TElem>(a))
     385            0 :                                 grid.attach_to<TElem>(a);
     386              : 
     387              :                         Grid::AttachmentAccessor<TElem, TAttachment> aaVal(grid, a);
     388              :                         
     389              :                         for(typename Grid::traits<TElem>::iterator iter = grid.begin<TElem>();
     390            0 :                                 iter != grid.end<TElem>(); ++iter)
     391              :                         {
     392            0 :                                 attachment_io_traits<TAttachment>::read_value(in, aaVal[*iter]);
     393            0 :                                 UG_COND_THROW(!in, "Failed to read attachment entry.\n");
     394              :                         }
     395            0 :                 }
     396              : 
     397              : 
     398              :                 template <class TElem, class TAttachment>
     399              :                 static
     400            0 :                 void write_attachment_to_stream (
     401              :                                 std::ostream& out,
     402              :                                 Grid& grid,
     403              :                                 IAttachment& attachment)
     404              :                 {
     405            0 :                         TAttachment& a = dynamic_cast<TAttachment&>(attachment);
     406              :                         
     407            0 :                         if(!grid.has_attachment<TElem>(a))
     408              :                                 return;
     409              : 
     410              :                         Grid::AttachmentAccessor<TElem, TAttachment> aaVal(grid, a);
     411              : 
     412              :                         const typename Grid::traits<TElem>::iterator iterEnd = grid.end<TElem>();
     413              :                         for(typename Grid::traits<TElem>::iterator iter = grid.begin<TElem>();
     414            0 :                                 iter != iterEnd;)
     415              :                         {
     416            0 :                                 attachment_io_traits<TAttachment>::write_value(out, aaVal[*iter]);
     417            0 :                                 UG_COND_THROW(!out, "Failed to write attachment entry.\n");
     418              :                                 ++iter;
     419            0 :                                 if(iter != iterEnd)
     420            0 :                                         out << " ";
     421              :                         }
     422              :                 }
     423              : 
     424              :                 template <class TElem, class TAttachment>
     425              :                 static
     426              :                 void//SmartPtr<GeomObjDataSerializer<TElem> >
     427            0 :                 add_attachment_serializer (
     428              :                         GridDataSerializationHandler& handler,
     429              :                         Grid& g,
     430              :                         IAttachment& attachment)
     431              :                 {
     432            0 :                         TAttachment& a = dynamic_cast<TAttachment&>(attachment);
     433            0 :                         handler.add(GeomObjAttachmentSerializer<TElem, TAttachment>::
     434              :                                                                         create(g, a));
     435            0 :                 }
     436              : 
     437              :                 template <class TElem, class TAttachment>
     438              :                 static
     439            0 :                 void cast_and_attach (
     440              :                                 Grid& grid,
     441              :                                 IAttachment& attachment)
     442              :                 {
     443            0 :                         TAttachment& a = dynamic_cast<TAttachment&>(attachment);
     444              :                         
     445            0 :                         if(!grid.has_attachment<TElem>(a))
     446            0 :                                 grid.attach_to<TElem>(a);
     447            0 :                 }
     448              : 
     449              :                 static
     450            0 :                 void register_standard_attachment_types()
     451              :                 {
     452              :                 //todo: explicit registration of common types in
     453              :                 //              GlobalAttachments itself isn't really the best way to go
     454              :                 //              (e.g. requires inclusion of 'ugmath_types.h').
     455            0 :                         register_attachment_type<Attachment<bool> >();
     456            0 :                         register_attachment_type<Attachment<char> >();
     457            0 :                         register_attachment_type<Attachment<byte> >();
     458            0 :                         register_attachment_type<Attachment<int> >();
     459            0 :                         register_attachment_type<Attachment<uint> >();
     460            0 :                         register_attachment_type<Attachment<float> >();
     461            0 :                         register_attachment_type<Attachment<double> >();
     462              : 
     463            0 :                         register_attachment_type<Attachment<vector1> >();
     464            0 :                         register_attachment_type<Attachment<vector2> >();
     465            0 :                         register_attachment_type<Attachment<vector3> >();
     466            0 :                         register_attachment_type<Attachment<vector4> >();
     467            0 :                 }
     468              :         ////////////////////////////////////////
     469              :         //      VARIABLES
     470              :                 std::vector<std::string>  m_attachmentNames;
     471              :                 AttachmentMap                           m_attachmentMap;
     472              :                 AttachmentTypeMap                       m_attachmentTypeMap;
     473              :                 FunctionVec                                     m_functionVecs[4];
     474              : };
     475              : 
     476              : }//     end of namespace
     477              : 
     478              : #endif  //__H__UG_global_attachments
        

Generated by: LCOV version 2.0-1