Sierra Toolkit Version of the Day
FieldParallel.hpp
00001 /*------------------------------------------------------------------------*/
00002 /*                 Copyright 2010 Sandia Corporation.                     */
00003 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00004 /*  license for use of this work by or on behalf of the U.S. Government.  */
00005 /*  Export of this program may require a license from the                 */
00006 /*  United States Government.                                             */
00007 /*------------------------------------------------------------------------*/
00008 
00009 
00010 #ifndef stk_mesh_FieldParallel_hpp
00011 #define stk_mesh_FieldParallel_hpp
00012 
00013 //----------------------------------------------------------------------
00014 
00015 #include <stk_util/util/SimpleArrayOps.hpp>
00016 #include <stk_util/parallel/Parallel.hpp>
00017 #include <stk_util/parallel/ParallelComm.hpp>
00018 
00019 #include <stk_mesh/base/Types.hpp>
00020 #include <stk_mesh/base/Field.hpp>
00021 #include <stk_mesh/base/Entity.hpp>
00022 #include <stk_mesh/base/BulkData.hpp>
00023 
00024 namespace stk {
00025 namespace mesh {
00026 
00037 void communicate_field_data(
00038   ParallelMachine machine,
00039   const std::vector<EntityProc> & domain ,
00040   const std::vector<EntityProc> & range ,
00041   const std::vector< const FieldBase *> & fields );
00042 
00043 void communicate_field_data(
00044   const Ghosting                        & ghosts ,
00045   const std::vector< const FieldBase *> & fields );
00046 
00048 void communicate_field_data(
00049   const BulkData & mesh ,
00050   const unsigned field_count ,
00051   const FieldBase * fields[] ,
00052   CommAll & sparse );
00053 
00054 void communicate_field_data_verify_read( CommAll & );
00055 
00056 //----------------------------------------------------------------------
00057 
00058 namespace {
00059 
00060 //----------------------------------------------------------------------
00069 template< class OpField >
00070 void parallel_reduce( const BulkData & mesh ,
00071                       const OpField  & op )
00072 {
00073   const FieldBase * fields[1] = { & op.field };
00074 
00075   CommAll sparse ;
00076 
00077   communicate_field_data( mesh, 1, fields, sparse );
00078 
00079   op( mesh.entity_comm() , sparse );
00080 
00081   // For debugging:
00082   // communicate_field_data_verify_read( sparse );
00083 }
00084 
00091 template< class OpField1 , class OpField2 >
00092 void parallel_reduce( const BulkData & mesh ,
00093                       const OpField1 & op1 ,
00094                       const OpField2 & op2 )
00095 {
00096   const FieldBase * fields[2] = { & op1.field , & op2.field };
00097 
00098   CommAll sparse ;
00099 
00100   communicate_field_data( mesh, 2, fields, sparse );
00101 
00102   op1( mesh.entity_comm() , sparse );
00103   op2( mesh.entity_comm() , sparse );
00104 
00105   // For debugging:
00106   // communicate_field_data_verify_read( sparse );
00107 }
00108 
00109 //----------------------------------------------------------------------
00110 
00111 template< class ReduceOp ,
00112           class Type , class Tag1, class Tag2, class Tag3 ,
00113           class Tag4 , class Tag5, class Tag6, class Tag7 >
00114 struct ParallelReduceField {
00115   typedef Field<Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> field_type ;
00116 
00117   const field_type & field ;
00118 
00119   ParallelReduceField( const field_type & f ) : field(f) {}
00120   ParallelReduceField( const ParallelReduceField & p ) : field(p.field) {}
00121 
00122   void operator()( const std::vector<Entity*> & entity_comm ,
00123                    CommAll & sparse ) const ;
00124 
00125 private:
00126   ParallelReduceField & operator = ( const ParallelReduceField & );
00127 };
00128 
00129 template< class ReduceOp ,
00130           class Type , class Tag1, class Tag2, class Tag3 ,
00131           class Tag4 , class Tag5, class Tag6, class Tag7 >
00132 void ParallelReduceField< ReduceOp , Type ,  Tag1,  Tag2,  Tag3 ,
00133                                      Tag4 ,  Tag5,  Tag6,  Tag7 >::
00134   operator()( const std::vector<Entity*> & entity_comm ,
00135               CommAll & sparse ) const
00136 {
00137   typedef EntityArray< field_type > array_type ;
00138 
00139   for ( std::vector<Entity*>::const_iterator
00140         i = entity_comm.begin(); i != entity_comm.end() ; ++i ) {
00141     Entity & entity = **i ;
00142     array_type array( field , entity );
00143     Type * const ptr_beg = array.contiguous_data();
00144     Type * const ptr_end = ptr_beg + array.size();
00145 
00146     if (ptr_beg == NULL || ptr_end == NULL) continue;
00147 
00148     for ( PairIterEntityComm
00149           ec = entity.comm() ; ! ec.empty() && ec->ghost_id == 0 ; ++ec ) {
00150 
00151       CommBuffer & b = sparse.recv_buffer( ec->proc );
00152 
00153       for ( Type * ptr = ptr_beg ; ptr < ptr_end ; ++ptr ) {
00154         Type tmp ;
00155         b.template unpack<unsigned char>( (unsigned char *)(&tmp), sizeof(Type) );
00156         ReduceOp( ptr , & tmp );
00157       }
00158     }
00159   }
00160 }
00161 
00162 }
00163 
00164 //----------------------------------------------------------------------
00165 
00166 template< class Type , class Tag1, class Tag2, class Tag3 ,
00167           class Tag4 , class Tag5, class Tag6, class Tag7 >
00168 ParallelReduceField<Sum<1>,Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>
00169 inline
00170 sum( const Field<Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> & f )
00171 {
00172   return ParallelReduceField<Sum<1>,Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>( f );
00173 }
00174 
00175 template< class Type , class Tag1, class Tag2, class Tag3 ,
00176           class Tag4 , class Tag5, class Tag6, class Tag7 >
00177 ParallelReduceField<Max<1>,Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>
00178 inline
00179 max( const Field<Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> & f )
00180 {
00181   return ParallelReduceField<Max<1>,Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>( f );
00182 }
00183 
00184 template< class Type , class Tag1, class Tag2, class Tag3 ,
00185           class Tag4 , class Tag5, class Tag6, class Tag7 >
00186 ParallelReduceField<Min<1>,Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>
00187 inline
00188 min( const Field<Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> & f )
00189 {
00190   return ParallelReduceField<Min<1>,Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>( f );
00191 }
00192 
00193 } // namespace mesh
00194 } // namespace stk
00195 
00196 #endif
00197 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends