|
Sierra Toolkit Version of the Day
|
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