|
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_classic { 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_classic 00195 00196 #endif 00197