Sierra Toolkit Version of the Day
LinsysFunctions.cpp
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 #include <stk_linsys/FeiBaseIncludes.hpp>
00011 #include <stk_linsys/LinsysFunctions.hpp>
00012 #include <stk_linsys/ImplDetails.hpp>
00013 
00014 #include <stk_mesh/base/GetBuckets.hpp>
00015 #include <stk_mesh/base/FieldData.hpp>
00016 
00017 #include <stk_mesh/fem/TopologyHelpers.hpp>
00018 
00019 #include <fei_trilinos_macros.hpp>
00020 #include <fei_Solver_AztecOO.hpp>
00021 #include <fei_Trilinos_Helpers.hpp>
00022 
00023 
00024 namespace stk {
00025 namespace linsys {
00026 
00027 void add_connectivities(stk::linsys::LinearSystemInterface& ls,
00028                         stk::mesh::EntityRank entity_rank,
00029                         stk::mesh::EntityRank connected_entity_rank,
00030                         const stk::mesh::FieldBase& field,
00031                         const stk::mesh::Selector& selector,
00032                         const stk::mesh::BulkData& mesh_bulk)
00033 {
00034   const std::vector<mesh::Bucket*>& mesh_buckets = mesh_bulk.buckets(entity_rank);
00035   std::vector<mesh::Bucket*> part_buckets;
00036   stk::mesh::get_buckets(selector, mesh_buckets, part_buckets);
00037 
00038   if (part_buckets.empty()) return;
00039 
00040   DofMapper& dof_mapper = ls.get_DofMapper();
00041 
00042   dof_mapper.add_dof_mappings(mesh_bulk, selector, connected_entity_rank, field);
00043 
00044   int field_id = dof_mapper.get_field_id(field);
00045 
00046   stk::mesh::Entity& first_entity = *(part_buckets[0]->begin());
00047   stk::mesh::PairIterRelation rel = first_entity.relations(connected_entity_rank);
00048   int num_connected = rel.second - rel.first;
00049 
00050   fei::SharedPtr<fei::MatrixGraph> matgraph = ls.get_fei_MatrixGraph();
00051 
00052   int pattern_id = matgraph->definePattern(num_connected, connected_entity_rank, field_id);
00053 
00054   int num_entities = 0;
00055   for(size_t i=0; i<part_buckets.size(); ++i) {
00056     num_entities += part_buckets[i]->size();
00057   }
00058 
00059   int block_id = matgraph->initConnectivityBlock(num_entities, pattern_id);
00060 
00061   std::vector<int> connected_ids(num_connected);
00062 
00063   for(size_t i=0; i<part_buckets.size(); ++i) {
00064     stk::mesh::Bucket::iterator
00065       b_iter = part_buckets[i]->begin(),
00066       b_end  = part_buckets[i]->end();
00067     for(; b_iter != b_end; ++b_iter) {
00068       stk::mesh::Entity& entity = *b_iter;
00069       rel = entity.relations(connected_entity_rank);
00070       for(int j=0; rel.first != rel.second; ++rel.first, ++j) {
00071         connected_ids[j] = rel.first->entity()->identifier();
00072       }
00073       int conn_id = entity.identifier();
00074       matgraph->initConnectivity(block_id, conn_id, &connected_ids[0]);
00075     }
00076   }
00077 }
00078 
00079 void dirichlet_bc(stk::linsys::LinearSystemInterface& ls,
00080                   const stk::mesh::BulkData& mesh,
00081                   const stk::mesh::Part& bcpart,
00082                   stk::mesh::EntityRank entity_rank,
00083                   const stk::mesh::FieldBase& field,
00084                   unsigned field_component,
00085                   double prescribed_value)
00086 {
00087   std::vector<stk::mesh::Bucket*> buckets;
00088   stk::mesh::Selector selector(bcpart);
00089   stk::mesh::get_buckets(selector, mesh.buckets(entity_rank), buckets);
00090 
00091   int field_id = ls.get_DofMapper().get_field_id(field);
00092   std::vector<int> entity_ids;
00093 
00094   for(size_t i=0; i<buckets.size(); ++i) {
00095     stk::mesh::Bucket::iterator
00096       iter = buckets[i]->begin(), iend = buckets[i]->end();
00097     for(; iter!=iend; ++iter) {
00098       const stk::mesh::Entity& entity = *iter;
00099       entity_ids.push_back(stk::linsys::impl::entityid_to_int(entity.identifier()));
00100     }
00101   }
00102 
00103   std::vector<double> prescribed_values(entity_ids.size(), prescribed_value);
00104 
00105   ls.get_fei_LinearSystem()->loadEssentialBCs(entity_ids.size(),
00106                                        &entity_ids[0],
00107                                        stk::linsys::impl::entitytype_to_int(entity_rank),
00108                                        field_id, field_component,
00109                                        &prescribed_values[0]);
00110 }
00111 
00112 int fei_solve(int & status, fei::LinearSystem &fei_ls, const Teuchos::ParameterList & params )
00113 {
00114 //Note: hard-coded to Trilinos/Aztec!!!
00115   Solver_AztecOO solver_az;
00116 
00117   fei::ParameterSet param_set;
00118 
00119   Trilinos_Helpers::copy_parameterlist(params, param_set);
00120 
00121   int iterationsTaken = 0;
00122 
00123   return solver_az.solve( & fei_ls,
00124                      NULL,
00125                      param_set,
00126                      iterationsTaken,
00127                      status
00128                   );
00129 }
00130 
00131 void copy_vector_to_mesh( fei::Vector & vec,
00132                           const DofMapper & dof,
00133                           stk::mesh::BulkData & mesh_bulk_data
00134                         )
00135 {
00136   vec.scatterToOverlap();
00137 
00138   std::vector<int> shared_and_owned_indices;
00139 
00140   vec.getVectorSpace()->getIndices_SharedAndOwned(shared_and_owned_indices);
00141 
00142   size_t num_values = shared_and_owned_indices.size();
00143 
00144   if(num_values == 0) {
00145     return;
00146   }
00147 
00148   std::vector<double> values(num_values);
00149   vec.copyOut(num_values,&shared_and_owned_indices[0],&values[0]);
00150 
00151   stk::mesh::EntityRank ent_type;
00152   stk::mesh::EntityId ent_id;
00153   const stk::mesh::FieldBase * field;
00154   int offset_into_field;
00155 
00156   for(size_t i = 0; i < num_values; ++i)
00157   {
00158 
00159     dof.get_dof( shared_and_owned_indices[i],
00160                  ent_type,
00161                  ent_id,
00162                  field,
00163                  offset_into_field
00164                 );
00165 
00166     stk::mesh::Entity & entity = *mesh_bulk_data.get_entity(ent_type, ent_id);
00167 
00168     void * data = stk::mesh::field_data(*field,entity);
00169 
00170     if(!(field->type_is<double>()) || data == NULL) {
00171       std::ostringstream oss;
00172       oss << "stk::linsys::copy_vector_to_mesh ERROR, bad data type, or ";
00173       oss << " field (" << field->name() << ") not found on entity with type " << entity.entity_rank();
00174       oss << " and ID " << entity.identifier();
00175       std::string str = oss.str();
00176       throw std::runtime_error(str.c_str());
00177     }
00178 
00179     double * double_data = reinterpret_cast<double *>(data);
00180 
00181     double_data[offset_into_field] = values[i];
00182 
00183   }
00184 }
00185 
00186 void scale_matrix(double scalar, fei::Matrix& matrix)
00187 {
00188   fei::SharedPtr<fei::VectorSpace> vspace = matrix.getMatrixGraph()->getRowSpace();
00189 
00190   int numRows = vspace->getNumIndices_Owned();
00191   std::vector<int> rows(numRows);
00192   vspace->getIndices_Owned(numRows, &rows[0], numRows);
00193 
00194   std::vector<int> indices;
00195   std::vector<double> coefs;
00196 
00197   for(size_t i=0; i<rows.size(); ++i) {
00198     int rowlen = 0;
00199     matrix.getRowLength(rows[i], rowlen);
00200 
00201     if ((int)indices.size() < rowlen) {
00202       indices.resize(rowlen);
00203       coefs.resize(rowlen);
00204     }
00205 
00206     matrix.copyOutRow(rows[i], rowlen, &coefs[0], &indices[0]);
00207 
00208     for(int j=0; j<rowlen; ++j) {
00209       coefs[j] *= scalar;
00210     }
00211 
00212     double* coefPtr = &coefs[0];
00213     matrix.copyIn(1, &rows[i], rowlen, &indices[0], &coefPtr);
00214   }
00215 }
00216 
00217 void add_matrix_to_matrix(double scalar,
00218                           const fei::Matrix& src_matrix,
00219                           fei::Matrix& dest_matrix)
00220 {
00221   fei::SharedPtr<fei::VectorSpace> vspace = src_matrix.getMatrixGraph()->getRowSpace();
00222 
00223   int numRows = vspace->getNumIndices_Owned();
00224   std::vector<int> rows(numRows);
00225   vspace->getIndices_Owned(numRows, &rows[0], numRows);
00226 
00227   std::vector<int> indices;
00228   std::vector<double> coefs;
00229 
00230   for(size_t i=0; i<rows.size(); ++i) {
00231     int rowlen = 0;
00232     src_matrix.getRowLength(rows[i], rowlen);
00233 
00234     if ((int)indices.size() < rowlen) {
00235       indices.resize(rowlen);
00236       coefs.resize(rowlen);
00237     }
00238 
00239     src_matrix.copyOutRow(rows[i], rowlen, &coefs[0], &indices[0]);
00240 
00241     for(int j=0; j<rowlen; ++j) {
00242       coefs[j] *= scalar;
00243     }
00244 
00245     double* coefPtr = &coefs[0];
00246     dest_matrix.sumIn(1, &rows[i], rowlen, &indices[0], &coefPtr);
00247   }
00248 }
00249 
00250 void scale_vector(double scalar,
00251                   fei::Vector& vec)
00252 {
00253   fei::SharedPtr<fei::VectorSpace> vspace = vec.getVectorSpace();
00254 
00255   int numIndices = vspace->getNumIndices_Owned();
00256   std::vector<int> indices(numIndices);
00257   vspace->getIndices_Owned(numIndices, &indices[0], numIndices);
00258 
00259   std::vector<double> coefs(numIndices);
00260 
00261   vec.copyOut(numIndices, &indices[0], &coefs[0]);
00262 
00263   for(size_t j=0; j<coefs.size(); ++j) {
00264     coefs[j] *= scalar;
00265   }
00266 
00267   vec.copyIn(numIndices, &indices[0], &coefs[0]);
00268 }
00269 
00270 void add_vector_to_vector(double scalar,
00271                           const fei::Vector& src_vector,
00272                           fei::Vector& dest_vector)
00273 {
00274   fei::SharedPtr<fei::VectorSpace> vspace = src_vector.getVectorSpace();
00275 
00276   int numIndices = vspace->getNumIndices_Owned();
00277   std::vector<int> indices(numIndices);
00278   vspace->getIndices_Owned(numIndices, &indices[0], numIndices);
00279 
00280   std::vector<double> coefs(numIndices);
00281 
00282   src_vector.copyOut(numIndices, &indices[0], &coefs[0]);
00283 
00284   for(size_t j=0; j<coefs.size(); ++j) {
00285     coefs[j] *= scalar;
00286   }
00287 
00288   dest_vector.sumIn(numIndices, &indices[0], &coefs[0]);
00289 }
00290 
00291 }//namespace linsys
00292 }//namespace stk
00293 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends