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

Albany_GenericSTKFieldContainer_Def.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 #include <iostream>
00008 
00009 #include "Albany_GenericSTKFieldContainer.hpp"
00010 #include "Albany_STKNodeFieldContainer.hpp"
00011 
00012 #include "Albany_Utils.hpp"
00013 #include "Albany_StateInfoStruct.hpp"
00014 #include <stk_mesh/base/GetBuckets.hpp>
00015 
00016 #ifdef ALBANY_SEACAS
00017 #include <stk_io/IossBridge.hpp>
00018 #endif
00019 
00020 template<bool Interleaved>
00021 Albany::GenericSTKFieldContainer<Interleaved>::GenericSTKFieldContainer(
00022   const Teuchos::RCP<Teuchos::ParameterList>& params_,
00023   stk::mesh::fem::FEMMetaData* metaData_,
00024   stk::mesh::BulkData* bulkData_,
00025   const int neq_,
00026   const int numDim_)
00027   : metaData(metaData_),
00028     bulkData(bulkData_),
00029     params(params_),
00030     neq(neq_),
00031     numDim(numDim_) {
00032 }
00033 
00034 template<bool Interleaved>
00035 Albany::GenericSTKFieldContainer<Interleaved>::~GenericSTKFieldContainer() {
00036 }
00037 
00038 
00039 template<bool Interleaved>
00040 void
00041 Albany::GenericSTKFieldContainer<Interleaved>::buildStateStructs(const Teuchos::RCP<Albany::StateInfoStruct>& sis){
00042 
00043   using namespace Albany;
00044 
00045   // QuadPoint fields
00046   // dim[0] = nCells, dim[1] = nQP, dim[2] = nVec dim[3] = nVec
00047   typedef typename AbstractSTKFieldContainer::QPScalarFieldType QPSFT;
00048   typedef typename AbstractSTKFieldContainer::QPVectorFieldType QPVFT;
00049   typedef typename AbstractSTKFieldContainer::QPTensorFieldType QPTFT;
00050 
00051   // Code to parse the vector of StateStructs and create STK fields
00052   for(std::size_t i = 0; i < sis->size(); i++) {
00053     StateStruct& st = *((*sis)[i]);
00054     StateStruct::FieldDims& dim = st.dim;
00055 
00056     if(st.entity == StateStruct::QuadPoint || st.entity == StateStruct::ElemNode){
00057 
00058         if(dim.size() == 2){ // Scalar at QPs
00059           qpscalar_states.push_back(& metaData->declare_field< QPSFT >(st.name));
00060           stk::mesh::put_field(*qpscalar_states.back() , metaData->element_rank(),
00061                            metaData->universal_part(), dim[1]);
00062         //Debug
00063         //      cout << "Allocating qps field name " << qpscalar_states.back()->name() <<
00064         //            " size: (" << dim[0] << ", " << dim[1] << ")" <<endl;
00065 #ifdef ALBANY_SEACAS
00066 
00067           if(st.output) stk::io::set_field_role(*qpscalar_states.back(), Ioss::Field::TRANSIENT);
00068 
00069 #endif
00070         }
00071         else if(dim.size() == 3){ // Vector at QPs
00072           qpvector_states.push_back(& metaData->declare_field< QPVFT >(st.name));
00073           // Multi-dim order is Fortran Ordering, so reversed here
00074           stk::mesh::put_field(*qpvector_states.back() , metaData->element_rank(),
00075                            metaData->universal_part(), dim[2], dim[1]);
00076           //Debug
00077           //      cout << "Allocating qpv field name " << qpvector_states.back()->name() <<
00078           //            " size: (" << dim[0] << ", " << dim[1] << ", " << dim[2] << ")" <<endl;
00079 #ifdef ALBANY_SEACAS
00080 
00081           if(st.output) stk::io::set_field_role(*qpvector_states.back(), Ioss::Field::TRANSIENT);
00082 
00083 #endif
00084         }
00085         else if(dim.size() == 4){ // Tensor at QPs
00086           qptensor_states.push_back(& metaData->declare_field< QPTFT >(st.name));
00087           // Multi-dim order is Fortran Ordering, so reversed here
00088           stk::mesh::put_field(*qptensor_states.back() , metaData->element_rank(),
00089                            metaData->universal_part(), dim[3], dim[2], dim[1]);
00090           //Debug
00091           //      cout << "Allocating qpt field name " << qptensor_states.back()->name() <<
00092           //            " size: (" << dim[0] << ", " << dim[1] << ", " << dim[2] << ", " << dim[3] << ")" <<endl;
00093 #ifdef ALBANY_SEACAS
00094 
00095           if(st.output) stk::io::set_field_role(*qptensor_states.back(), Ioss::Field::TRANSIENT);
00096 
00097 #endif
00098         }
00099         // Something other than a scalar, vector, or tensor at the QPs is an error
00100         else TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
00101             "Error: GenericSTKFieldContainer - cannot match QPData");
00102     } // end QuadPoint
00103     // Single scalar at center of the workset
00104     else if(dim.size() == 1 && st.entity == StateStruct::WorksetValue) { // A single value that applies over the entire workset (time)
00105       scalarValue_states.push_back(st.name);
00106     } // End scalar at center of element
00107     else if(st.entity == StateStruct::NodalData) { // Data at the node points
00108 
00109         const Teuchos::RCP<Albany::NodeFieldContainer>& nodeContainer 
00110                = sis->getNodalDataBlock()->getNodeContainer();
00111 
00112         (*nodeContainer)[st.name] = Albany::buildSTKNodeField(st.name, dim, metaData, bulkData, st.output);
00113  
00114     } // end Node class - anything else is an error
00115     else TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
00116             "Error: GenericSTKFieldContainer - cannot match unknown entity : " << st.entity << std::endl);
00117 
00118   }
00119 }
00120 
00121 
00122 template<bool Interleaved>
00123 template<class T>
00124 typename boost::disable_if< boost::is_same<T, Albany::AbstractSTKFieldContainer::ScalarFieldType>, void >::type
00125 Albany::GenericSTKFieldContainer<Interleaved>::fillVectorHelper(Epetra_Vector& soln,
00126     T* solution_field,
00127     const Teuchos::RCP<Epetra_Map>& node_map,
00128     const stk::mesh::Bucket& bucket, int offset) {
00129 
00130   // Fill the result vector
00131   // Create a multidimensional array view of the
00132   // solution field data for this bucket of nodes.
00133   // The array is two dimensional ( Cartesian X NumberNodes )
00134   // and indexed by ( 0..2 , 0..NumberNodes-1 )
00135 
00136   stk::mesh::BucketArray<T>
00137   solution_array(*solution_field, bucket);
00138 
00139   const int num_vec_components = solution_array.dimension(0);
00140   const int num_nodes_in_bucket = solution_array.dimension(1);
00141 
00142   for(std::size_t i = 0; i < num_nodes_in_bucket; i++)  {
00143 
00144     //      const unsigned node_gid = bucket[i].identifier();
00145     const int node_gid = bucket[i].identifier() - 1;
00146     int node_lid = node_map->LID(node_gid);
00147 
00148     for(std::size_t j = 0; j < num_vec_components; j++)
00149 
00150       soln[getDOF(node_lid, offset + j)] = solution_array(j, i);
00151 
00152   }
00153 }
00154 
00155 // Specialization for ScalarFieldType
00156 
00157 template<bool Interleaved>
00158 void Albany::GenericSTKFieldContainer<Interleaved>::fillVectorHelper(Epetra_Vector& soln,
00159     ScalarFieldType* solution_field,
00160     const Teuchos::RCP<Epetra_Map>& node_map,
00161     const stk::mesh::Bucket& bucket, int offset) {
00162 
00163   // Fill the result vector
00164   // Create a multidimensional array view of the
00165   // solution field data for this bucket of nodes.
00166   // The array is two dimensional ( Cartesian X NumberNodes )
00167   // and indexed by ( 0..2 , 0..NumberNodes-1 )
00168 
00169   stk::mesh::BucketArray<ScalarFieldType>
00170   solution_array(*solution_field, bucket);
00171 
00172   const int num_nodes_in_bucket = solution_array.dimension(0);
00173 
00174   for(std::size_t i = 0; i < num_nodes_in_bucket; i++)  {
00175 
00176     //      const unsigned node_gid = bucket[i].identifier();
00177     const int node_gid = bucket[i].identifier() - 1;
00178     int node_lid = node_map->LID(node_gid);
00179 
00180     soln[getDOF(node_lid, offset)] = solution_array(i);
00181 
00182   }
00183 }
00184 
00185 template<bool Interleaved>
00186 template<class T>
00187 typename boost::disable_if< boost::is_same<T, Albany::AbstractSTKFieldContainer::ScalarFieldType>, void >::type
00188 Albany::GenericSTKFieldContainer<Interleaved>::saveVectorHelper(const Epetra_Vector& soln,
00189     T* solution_field,
00190     const Teuchos::RCP<Epetra_Map>& node_map,
00191     const stk::mesh::Bucket& bucket, int offset) {
00192 
00193   // Fill the result vector
00194   // Create a multidimensional array view of the
00195   // solution field data for this bucket of nodes.
00196   // The array is two dimensional ( Cartesian X NumberNodes )
00197   // and indexed by ( 0..2 , 0..NumberNodes-1 )
00198 
00199   stk::mesh::BucketArray<T>
00200   solution_array(*solution_field, bucket);
00201 
00202   const int num_vec_components = solution_array.dimension(0);
00203   const int num_nodes_in_bucket = solution_array.dimension(1);
00204 
00205   for(std::size_t i = 0; i < num_nodes_in_bucket; i++)  {
00206 
00207     const int node_gid = bucket[i].identifier() - 1;
00208     int node_lid = node_map->LID(node_gid);
00209 
00210     for(std::size_t j = 0; j < num_vec_components; j++)
00211 
00212       solution_array(j, i) = soln[getDOF(node_lid, offset + j)];
00213 
00214   }
00215 }
00216 
00217 // Specialization for ScalarFieldType
00218 template<bool Interleaved>
00219 void Albany::GenericSTKFieldContainer<Interleaved>::saveVectorHelper(const Epetra_Vector& soln,
00220     ScalarFieldType* solution_field,
00221     const Teuchos::RCP<Epetra_Map>& node_map,
00222     const stk::mesh::Bucket& bucket, int offset) {
00223 
00224   // Fill the result vector
00225   // Create a multidimensional array view of the
00226   // solution field data for this bucket of nodes.
00227   // The array is two dimensional ( Cartesian X NumberNodes )
00228   // and indexed by ( 0..2 , 0..NumberNodes-1 )
00229 
00230   stk::mesh::BucketArray<ScalarFieldType>
00231   solution_array(*solution_field, bucket);
00232 
00233   const int num_nodes_in_bucket = solution_array.dimension(0);
00234 
00235   for(std::size_t i = 0; i < num_nodes_in_bucket; i++)  {
00236 
00237     //      const unsigned node_gid = bucket[i].identifier();
00238     const int node_gid = bucket[i].identifier() - 1;
00239     int node_lid = node_map->LID(node_gid);
00240 
00241     solution_array(i) = soln[getDOF(node_lid, offset)];
00242 
00243   }
00244 }
00245 
00246 template<bool Interleaved>
00247 template<class T>
00248 typename boost::disable_if< boost::is_same<T, Albany::AbstractSTKFieldContainer::ScalarFieldType>, void >::type
00249 Albany::GenericSTKFieldContainer<Interleaved>::copySTKField(const T* source, T* target) {
00250 
00251   const stk::mesh::BucketVector& bv = this->bulkData->buckets(this->metaData->node_rank());
00252 
00253   for(stk::mesh::BucketVector::const_iterator it = bv.begin() ; it != bv.end() ; ++it) {
00254 
00255     const stk::mesh::Bucket& bucket = **it;
00256 
00257     stk::mesh::BucketArray<T>
00258     source_array(*source, bucket);
00259     stk::mesh::BucketArray<T>
00260     target_array(*target, bucket);
00261 
00262     const int num_source_components = source_array.dimension(0);
00263     const int num_target_components = target_array.dimension(0);
00264     const int num_nodes_in_bucket = source_array.dimension(1);
00265 
00266     int downsample = num_source_components / num_target_components;
00267     int uneven_downsampling = num_source_components % num_target_components;
00268 
00269     TEUCHOS_TEST_FOR_EXCEPTION((uneven_downsampling) ||
00270                                (num_nodes_in_bucket != target_array.dimension(1)),
00271                                std::logic_error,
00272                                "Error in stk fields: specification of coordinate vector vs. solution layout is incorrect." 
00273                                << std::endl);
00274 
00275     for(std::size_t i = 0; i < num_nodes_in_bucket; i++) {
00276 
00277 // In source, j varies over neq (num phys vectors * numDim)
00278 // We want target to only vary over the first numDim components
00279 // Not sure how to do this generally...
00280 
00281       for(std::size_t j = 0; j < num_target_components; j++) {
00282 
00283         target_array(j, i) = source_array(j, i);
00284 
00285       }
00286    }
00287 
00288   }
00289 }
00290 
00291 // Specialization for ScalarFieldType
00292 
00293 template<bool Interleaved>
00294 void Albany::GenericSTKFieldContainer<Interleaved>::copySTKField(const ScalarFieldType* source, ScalarFieldType* target) {
00295 
00296   const stk::mesh::BucketVector& bv = this->bulkData->buckets(this->metaData->node_rank());
00297 
00298   for(stk::mesh::BucketVector::const_iterator it = bv.begin() ; it != bv.end() ; ++it) {
00299 
00300     const stk::mesh::Bucket& bucket = **it;
00301 
00302     stk::mesh::BucketArray<ScalarFieldType>
00303     source_array(*source, bucket);
00304     stk::mesh::BucketArray<ScalarFieldType>
00305     target_array(*target, bucket);
00306 
00307     const int num_nodes_in_bucket = source_array.dimension(0);
00308 
00309     TEUCHOS_TEST_FOR_EXCEPTION((num_nodes_in_bucket != target_array.dimension(0)),
00310                                std::logic_error,
00311                                "Error in stk fields: specification of coordinate vector vs. solution layout is incorrect." << std::endl);
00312 
00313     for(std::size_t i = 0; i < num_nodes_in_bucket; i++)
00314 
00315       target_array(i) = source_array(i);
00316 
00317   }
00318 }
00319 

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