00001
00002
00003
00004
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
00046
00047 typedef typename AbstractSTKFieldContainer::QPScalarFieldType QPSFT;
00048 typedef typename AbstractSTKFieldContainer::QPVectorFieldType QPVFT;
00049 typedef typename AbstractSTKFieldContainer::QPTensorFieldType QPTFT;
00050
00051
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){
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
00063
00064
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){
00072 qpvector_states.push_back(& metaData->declare_field< QPVFT >(st.name));
00073
00074 stk::mesh::put_field(*qpvector_states.back() , metaData->element_rank(),
00075 metaData->universal_part(), dim[2], dim[1]);
00076
00077
00078
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){
00086 qptensor_states.push_back(& metaData->declare_field< QPTFT >(st.name));
00087
00088 stk::mesh::put_field(*qptensor_states.back() , metaData->element_rank(),
00089 metaData->universal_part(), dim[3], dim[2], dim[1]);
00090
00091
00092
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
00100 else TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
00101 "Error: GenericSTKFieldContainer - cannot match QPData");
00102 }
00103
00104 else if(dim.size() == 1 && st.entity == StateStruct::WorksetValue) {
00105 scalarValue_states.push_back(st.name);
00106 }
00107 else if(st.entity == StateStruct::NodalData) {
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 }
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
00131
00132
00133
00134
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
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
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
00164
00165
00166
00167
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
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
00194
00195
00196
00197
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
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
00225
00226
00227
00228
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
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
00278
00279
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
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