|
Sierra Toolkit Version of the Day
|
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 00032 void communicate_field_data( 00033 ParallelMachine machine, 00034 const std::vector<EntityProc> & domain , 00035 const std::vector<EntityProc> & range , 00036 const std::vector< const FieldBase *> & fields ); 00037 00038 void communicate_field_data( 00039 const Ghosting & ghosts , 00040 const std::vector< const FieldBase *> & fields ); 00041 00043 void communicate_field_data( 00044 const BulkData & mesh , 00045 const unsigned field_count , 00046 const FieldBase * fields[] , 00047 CommAll & sparse ); 00048 00049 void communicate_field_data_verify_read( CommAll & ); 00050 00051 //---------------------------------------------------------------------- 00052 00053 namespace { 00054 00055 //---------------------------------------------------------------------- 00064 template< class OpField > 00065 void parallel_reduce( const BulkData & mesh , 00066 const OpField & op ) 00067 { 00068 const FieldBase * fields[1] = { & op.field }; 00069 00070 CommAll sparse ; 00071 00072 communicate_field_data( mesh, 1, fields, sparse ); 00073 00074 op( mesh.entity_comm() , sparse ); 00075 00076 // For debugging: 00077 // communicate_field_data_verify_read( sparse ); 00078 } 00079 00086 template< class OpField1 , class OpField2 > 00087 void parallel_reduce( const BulkData & mesh , 00088 const OpField1 & op1 , 00089 const OpField2 & op2 ) 00090 { 00091 const FieldBase * fields[2] = { & op1.field , & op2.field }; 00092 00093 CommAll sparse ; 00094 00095 communicate_field_data( mesh, 2, fields, sparse ); 00096 00097 op1( mesh.entity_comm() , sparse ); 00098 op2( mesh.entity_comm() , sparse ); 00099 00100 // For debugging: 00101 // communicate_field_data_verify_read( sparse ); 00102 } 00103 00104 //---------------------------------------------------------------------- 00105 00106 template< class ReduceOp , 00107 class Type , class Tag1, class Tag2, class Tag3 , 00108 class Tag4 , class Tag5, class Tag6, class Tag7 > 00109 struct ParallelReduceField { 00110 typedef Field<Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> field_type ; 00111 00112 const field_type & field ; 00113 00114 ParallelReduceField( const field_type & f ) : field(f) {} 00115 ParallelReduceField( const ParallelReduceField & p ) : field(p.field) {} 00116 00117 void operator()( const std::vector<Entity*> & entity_comm , 00118 CommAll & sparse ) const ; 00119 00120 private: 00121 ParallelReduceField & operator = ( const ParallelReduceField & ); 00122 }; 00123 00124 template< class ReduceOp , 00125 class Type , class Tag1, class Tag2, class Tag3 , 00126 class Tag4 , class Tag5, class Tag6, class Tag7 > 00127 void ParallelReduceField< ReduceOp , Type , Tag1, Tag2, Tag3 , 00128 Tag4 , Tag5, Tag6, Tag7 >:: 00129 operator()( const std::vector<Entity*> & entity_comm , 00130 CommAll & sparse ) const 00131 { 00132 typedef EntityArray< field_type > array_type ; 00133 00134 for ( std::vector<Entity*>::const_iterator 00135 i = entity_comm.begin(); i != entity_comm.end() ; ++i ) { 00136 Entity & entity = **i ; 00137 array_type array( field , entity ); 00138 Type * const ptr_beg = array.contiguous_data(); 00139 Type * const ptr_end = ptr_beg + array.size(); 00140 00141 for ( PairIterEntityComm 00142 ec = entity.comm() ; ! ec.empty() && ec->ghost_id == 0 ; ++ec ) { 00143 00144 CommBuffer & b = sparse.recv_buffer( ec->proc ); 00145 00146 for ( Type * ptr = ptr_beg ; ptr < ptr_end ; ++ptr ) { 00147 Type tmp ; 00148 b.template unpack<unsigned char>( (unsigned char *)(&tmp), sizeof(Type) ); 00149 ReduceOp( ptr , & tmp ); 00150 } 00151 } 00152 } 00153 } 00154 00155 } 00156 00157 //---------------------------------------------------------------------- 00158 00159 template< class Type , class Tag1, class Tag2, class Tag3 , 00160 class Tag4 , class Tag5, class Tag6, class Tag7 > 00161 ParallelReduceField<Sum<1>,Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> 00162 inline 00163 sum( const Field<Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> & f ) 00164 { 00165 return ParallelReduceField<Sum<1>,Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>( f ); 00166 } 00167 00168 template< class Type , class Tag1, class Tag2, class Tag3 , 00169 class Tag4 , class Tag5, class Tag6, class Tag7 > 00170 ParallelReduceField<Max<1>,Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> 00171 inline 00172 max( const Field<Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> & f ) 00173 { 00174 return ParallelReduceField<Max<1>,Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>( f ); 00175 } 00176 00177 template< class Type , class Tag1, class Tag2, class Tag3 , 00178 class Tag4 , class Tag5, class Tag6, class Tag7 > 00179 ParallelReduceField<Min<1>,Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> 00180 inline 00181 min( const Field<Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> & f ) 00182 { 00183 return ParallelReduceField<Min<1>,Type,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>( f ); 00184 } 00185 00186 } // namespace mesh 00187 } // namespace stk 00188 00189 #endif 00190