• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Albany_STKNodeFieldContainer.hpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
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   // Helper class for NodeData
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;      // Name of data field
00076     field_type *node_field;  // stk::mesh::field
00077     std::vector<int> dims;
00078     stk::mesh::fem::FEMMetaData* metaData;
00079     stk::mesh::BulkData* bulkData;
00080 
00081   };
00082 
00083 // Explicit template definitions in support of the above
00084 
00085   // Node Scalar
00086   template <typename T>
00087   struct NodeData_Traits<T, 1> {
00088 
00089     enum { size = 1 }; // Three array dimension tags (Node, Dim, Dim), store type T values
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         // Multi-dim order is Fortran Ordering, so reversed here
00096         stk::mesh::put_field(*fld , metaData->node_rank(), metaData->universal_part());
00097 
00098         return fld; // Address is held by stk
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   // Node Vector
00133   template <typename T>
00134   struct NodeData_Traits<T, 2> {
00135 
00136     enum { size = 2 }; // Two array dimension tags (Node, Dim), store type T values
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         // Multi-dim order is Fortran Ordering, so reversed here
00143         stk::mesh::put_field(*fld , metaData->node_rank(),
00144                            metaData->universal_part(), dim[1]);
00145 
00146         return fld; // Address is held by stk
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   // Node Tensor
00185   template <typename T>
00186   struct NodeData_Traits<T, 3> {
00187 
00188     enum { size = 3 }; // Three array dimension tags (Node, Dim, Dim), store type T values
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         // Multi-dim order is Fortran Ordering, so reversed here
00195         stk::mesh::put_field(*fld , metaData->node_rank(),
00196                            metaData->universal_part(), dim[2], dim[1]);
00197 
00198         return fld; // Address is held by stk
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 // Define macro for explicit template instantiation
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

Generated on Wed Mar 26 2014 18:36:36 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1