00001
00002
00003
00004
00005
00006
00007
00008 #ifndef ALBANY_STKNODEFIELDCONTAINER_HPP
00009 #define ALBANY_STKNODEFIELDCONTAINER_HPP
00010
00011 #include "Teuchos_RCP.hpp"
00012 #include "Albany_AbstractNodeFieldContainer.hpp"
00013 #include "Albany_StateInfoStruct.hpp"
00014
00015 #include <stk_mesh/fem/FEMMetaData.hpp>
00016 #include <stk_mesh/base/Field.hpp>
00017 #include <stk_mesh/base/FieldTraits.hpp>
00018 #include <stk_mesh/fem/CoordinateSystems.hpp>
00019
00020 namespace Albany {
00021
00027 class AbstractSTKNodeFieldContainer : public AbstractNodeFieldContainer {
00028
00029 public:
00030
00031 AbstractSTKNodeFieldContainer(){}
00032 virtual ~AbstractSTKNodeFieldContainer(){}
00033
00034 virtual void saveField(const Teuchos::RCP<const Epetra_Vector>& block_mv,
00035 int offset, int blocksize = -1) = 0;
00036 virtual Albany::MDArray getMDA(const stk::mesh::Bucket& buck) = 0;
00037
00038 };
00039
00040
00041 Teuchos::RCP<Albany::AbstractNodeFieldContainer>
00042 buildSTKNodeField(const std::string& name, const std::vector<int>& dim,
00043 stk::mesh::fem::FEMMetaData* metaData,
00044 stk::mesh::BulkData* bulkData, const bool output);
00045
00046
00047
00048 template<typename DataType, unsigned ArrayDim>
00049 struct NodeData_Traits { };
00050
00051 template<typename DataType, unsigned ArrayDim, class traits = NodeData_Traits<DataType, ArrayDim> >
00052 class STKNodeField : public AbstractSTKNodeFieldContainer {
00053
00054 public:
00055
00057 typedef traits traits_type;
00058
00060 typedef typename traits_type::field_type field_type;
00061
00062
00063 STKNodeField(const std::string& name, const std::vector<int>& dim,
00064 stk::mesh::fem::FEMMetaData* metaData, stk::mesh::BulkData* bulkData,
00065 const bool output = false);
00066
00067 virtual ~STKNodeField(){}
00068
00069 void saveField(const Teuchos::RCP<const Epetra_Vector>& block_mv, int offset, int blocksize = -1);
00070
00071 Albany::MDArray getMDA(const stk::mesh::Bucket& buck);
00072
00073 private:
00074
00075 std::string name;
00076 field_type *node_field;
00077 std::vector<int> dims;
00078 stk::mesh::fem::FEMMetaData* metaData;
00079 stk::mesh::BulkData* bulkData;
00080
00081 };
00082
00083
00084
00085
00086 template <typename T>
00087 struct NodeData_Traits<T, 1> {
00088
00089 enum { size = 1 };
00090 typedef stk::mesh::Field<T> field_type ;
00091 static field_type* createField(const std::string& name, const std::vector<int>& dim,
00092 stk::mesh::fem::FEMMetaData* metaData){
00093
00094 field_type *fld = & metaData->declare_field<field_type>(name);
00095
00096 stk::mesh::put_field(*fld , metaData->node_rank(), metaData->universal_part());
00097
00098 return fld;
00099
00100 }
00101
00102 static void saveFieldData(const Teuchos::RCP<const Epetra_Vector>& overlap_node_vec,
00103 const stk::mesh::BucketVector& all_elements,
00104 field_type *fld, int offset, int blocksize){
00105
00106 const Epetra_BlockMap& overlap_node_map = overlap_node_vec->Map();
00107 if(blocksize < 0)
00108 blocksize = overlap_node_map.ElementSize();
00109
00110 for(stk::mesh::BucketVector::const_iterator it = all_elements.begin() ; it != all_elements.end() ; ++it) {
00111
00112 const stk::mesh::Bucket& bucket = **it;
00113
00114 stk::mesh::BucketArray<field_type> solution_array(*fld, bucket);
00115
00116 const int num_nodes_in_bucket = solution_array.dimension(0);
00117
00118 for(std::size_t i = 0; i < num_nodes_in_bucket; i++) {
00119
00120 const int node_gid = bucket[i].identifier() - 1;
00121 int local_node = overlap_node_map.LID(node_gid);
00122 int block_start = local_node * blocksize;
00123
00124 solution_array(i) = (*overlap_node_vec)[block_start + offset];
00125
00126 }
00127 }
00128 }
00129
00130 };
00131
00132
00133 template <typename T>
00134 struct NodeData_Traits<T, 2> {
00135
00136 enum { size = 2 };
00137 typedef stk::mesh::Field<T, stk::mesh::Cartesian> field_type ;
00138 static field_type* createField(const std::string& name, const std::vector<int>& dim,
00139 stk::mesh::fem::FEMMetaData* metaData){
00140
00141 field_type *fld = & metaData->declare_field<field_type>(name);
00142
00143 stk::mesh::put_field(*fld , metaData->node_rank(),
00144 metaData->universal_part(), dim[1]);
00145
00146 return fld;
00147
00148 }
00149
00150 static void saveFieldData(const Teuchos::RCP<const Epetra_Vector>& overlap_node_vec,
00151 const stk::mesh::BucketVector& all_elements,
00152 field_type *fld, int offset, int blocksize){
00153
00154 const Epetra_BlockMap& overlap_node_map = overlap_node_vec->Map();
00155 if(blocksize < 0)
00156 blocksize = overlap_node_map.ElementSize();
00157
00158 for(stk::mesh::BucketVector::const_iterator it = all_elements.begin() ; it != all_elements.end() ; ++it) {
00159
00160 const stk::mesh::Bucket& bucket = **it;
00161
00162 stk::mesh::BucketArray<field_type> solution_array(*fld, bucket);
00163
00164 const int num_vec_components = solution_array.dimension(0);
00165 const int num_nodes_in_bucket = solution_array.dimension(1);
00166
00167 for(std::size_t i = 0; i < num_nodes_in_bucket; i++) {
00168
00169 const int node_gid = bucket[i].identifier() - 1;
00170 int local_node = overlap_node_map.LID(node_gid);
00171 int block_start = local_node * blocksize;
00172
00173 for(std::size_t j = 0; j < num_vec_components; j++){
00174
00175 solution_array(j, i) = (*overlap_node_vec)[block_start + offset + j];
00176
00177 }
00178 }
00179 }
00180 }
00181
00182 };
00183
00184
00185 template <typename T>
00186 struct NodeData_Traits<T, 3> {
00187
00188 enum { size = 3 };
00189 typedef stk::mesh::Field<T, stk::mesh::Cartesian, stk::mesh::Cartesian> field_type ;
00190 static field_type* createField(const std::string& name, const std::vector<int>& dim,
00191 stk::mesh::fem::FEMMetaData* metaData){
00192
00193 field_type *fld = & metaData->declare_field<field_type>(name);
00194
00195 stk::mesh::put_field(*fld , metaData->node_rank(),
00196 metaData->universal_part(), dim[2], dim[1]);
00197
00198 return fld;
00199
00200 }
00201
00202 static void saveFieldData(const Teuchos::RCP<const Epetra_Vector>& overlap_node_vec,
00203 const stk::mesh::BucketVector& all_elements,
00204 field_type *fld, int offset, int blocksize){
00205
00206 const Epetra_BlockMap& overlap_node_map = overlap_node_vec->Map();
00207 if(blocksize < 0)
00208 blocksize = overlap_node_map.ElementSize();
00209
00210 for(stk::mesh::BucketVector::const_iterator it = all_elements.begin() ; it != all_elements.end() ; ++it) {
00211
00212 const stk::mesh::Bucket& bucket = **it;
00213
00214 stk::mesh::BucketArray<field_type> solution_array(*fld, bucket);
00215
00216 const int num_i_components = solution_array.dimension(0);
00217 const int num_j_components = solution_array.dimension(1);
00218 const int num_nodes_in_bucket = solution_array.dimension(2);
00219
00220 for(std::size_t i = 0; i < num_nodes_in_bucket; i++) {
00221
00222 const int node_gid = bucket[i].identifier() - 1;
00223 int local_node = overlap_node_map.LID(node_gid);
00224 int block_start = local_node * blocksize;
00225
00226 for(std::size_t j = 0; j < num_j_components; j++)
00227 for(std::size_t k = 0; k < num_i_components; k++)
00228
00229 solution_array(k, j, i) = (*overlap_node_vec)[block_start + offset + j*num_i_components + k];
00230
00231 }
00232 }
00233 }
00234
00235 };
00236
00237
00238 }
00239
00240
00241 #define STKNODEFIELDCONTAINER_INSTANTIATE_TEMPLATE_CLASS_SCAL(name, type) \
00242 template class name<type, 1>;
00243 #define STKNODEFIELDCONTAINER_INSTANTIATE_TEMPLATE_CLASS_VEC(name, type) \
00244 template class name<type, 2>;
00245 #define STKNODEFIELDCONTAINER_INSTANTIATE_TEMPLATE_CLASS_TENS(name, type) \
00246 template class name<type, 3>;
00247
00248
00249 #define STKNODEFIELDCONTAINER_INSTANTIATE_TEMPLATE_CLASS(name) \
00250 STKNODEFIELDCONTAINER_INSTANTIATE_TEMPLATE_CLASS_SCAL(name, double) \
00251 STKNODEFIELDCONTAINER_INSTANTIATE_TEMPLATE_CLASS_VEC(name, double) \
00252 STKNODEFIELDCONTAINER_INSTANTIATE_TEMPLATE_CLASS_TENS(name, double)
00253
00254 #endif // ALBANY_STKNODEFIELDCONTAINER_HPP