00001
00002
00003
00004
00005
00006
00007 #include "AAdapt_RandomFracture.hpp"
00008 #include "AAdapt_RandomCriterion.hpp"
00009 #include "Teuchos_TimeMonitor.hpp"
00010 #include <stk_util/parallel/ParallelReduce.hpp>
00011
00012 #include <boost/foreach.hpp>
00013
00014 using stk::mesh::EntityKey;
00015 using stk::mesh::Entity;
00016
00017 namespace AAdapt {
00018
00019 typedef stk::mesh::Entity Entity;
00020 typedef stk::mesh::EntityRank EntityRank;
00021 typedef stk::mesh::RelationIdentifier EdgeId;
00022 typedef stk::mesh::EntityKey EntityKey;
00023
00024
00025 AAdapt::RandomFracture::
00026 RandomFracture(const Teuchos::RCP<Teuchos::ParameterList>& params,
00027 const Teuchos::RCP<ParamLib>& param_lib,
00028 Albany::StateManager& state_mgr,
00029 const Teuchos::RCP<const Epetra_Comm>& comm) :
00030 AAdapt::AbstractAdapter(params, param_lib, state_mgr, comm),
00031
00032 remesh_file_index_(1),
00033 fracture_interval_(params->get<int>("Adaptivity Step Interval", 1)),
00034 fracture_probability_(params->get<double>("Fracture Probability", 1.0)) {
00035
00036 discretization_ = state_mgr_.getDiscretization();
00037
00038 stk_discretization_ =
00039 static_cast<Albany::STKDiscretization*>(discretization_.get());
00040
00041 stk_mesh_struct_ = stk_discretization_->getSTKMeshStruct();
00042
00043 bulk_data_ = stk_mesh_struct_->bulkData;
00044 meta_data_ = stk_mesh_struct_->metaData;
00045
00046
00047 node_rank_ = meta_data_->NODE_RANK;
00048 edge_rank_ = meta_data_->EDGE_RANK;
00049 face_rank_ = meta_data_->FACE_RANK;
00050 element_rank_ = meta_data_->element_rank();
00051
00052 fracture_criterion_ =
00053 Teuchos::rcp(new AAdapt::RandomCriterion(num_dim_,
00054 element_rank_,
00055 *stk_discretization_));
00056
00057 num_dim_ = stk_mesh_struct_->numDim;
00058
00059
00060 base_exo_filename_ = stk_mesh_struct_->exoOutFile;
00061
00062
00063 topology_ =
00064 Teuchos::rcp(new LCM::Topology(discretization_, fracture_criterion_));
00065
00066 }
00067
00068
00069 AAdapt::RandomFracture::
00070 ~RandomFracture() {
00071 }
00072
00073
00074 bool
00075 AAdapt::RandomFracture::queryAdaptationCriteria() {
00076
00077 if(iter % fracture_interval_ == 0) {
00078
00079
00080
00081 std::vector<stk::mesh::Entity*> face_list;
00082
00083
00084 stk::mesh::Selector select_owned = meta_data_->locally_owned_part();
00085
00086
00087 stk::mesh::get_selected_entities(select_owned,
00088 bulk_data_->buckets(num_dim_ - 1) ,
00089 face_list);
00090
00091 #ifdef ALBANY_VERBOSE
00092 std::cout << "Num faces : " << face_list.size() << std::endl;
00093 #endif
00094
00095
00096 int total_fractured;
00097
00098
00099 for(int i(0); i < face_list.size(); ++i) {
00100
00101 stk::mesh::Entity& face = *(face_list[i]);
00102
00103 if(fracture_criterion_->
00104 computeFractureCriterion(face, fracture_probability_)) {
00105 fractured_faces_.push_back(face_list[i]);
00106 }
00107 }
00108
00109
00110
00111 if((total_fractured =
00112 accumulateFractured(fractured_faces_.size())) == 0) {
00113
00114 fractured_faces_.clear();
00115
00116 return false;
00117 }
00118
00119 *output_stream_ << "RandomFractureification: Need to split \""
00120 << total_fractured << "\" mesh elements." << std::endl;
00121
00122 return true;
00123 }
00124
00125 return false;
00126 }
00127
00128
00129 bool
00130 AAdapt::RandomFracture::adaptMesh(const Epetra_Vector& solution, const Epetra_Vector& ovlp_solution) {
00131 *output_stream_ << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
00132 *output_stream_ << "Adapting mesh using AAdapt::RandomFracture method " << std::endl;
00133 *output_stream_ << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
00134
00135
00136
00137 std::ostringstream ss;
00138 std::string str = base_exo_filename_;
00139 ss << "_" << remesh_file_index_ << ".";
00140 str.replace(str.find('.'), 1, ss.str());
00141
00142 *output_stream_ << "Remeshing: renaming output file to - " << str << std::endl;
00143
00144
00145 stk_discretization_->reNameExodusOutput(str);
00146
00147
00148 remesh_file_index_++;
00149
00150
00151 topology_->removeElementToNodeConnectivity(old_elem_to_node_);
00152
00153
00154 std::map<EntityKey, bool> local_entity_open;
00155 std::map<EntityKey, bool> global_entity_open;
00156 topology_->setEntitiesOpen(fractured_faces_, local_entity_open);
00157 getGlobalOpenList(local_entity_open, global_entity_open);
00158
00159
00160 bulk_data_->modification_begin();
00161
00162
00163 topology_->splitOpenFaces(global_entity_open);
00164
00165
00166
00167 fractured_faces_.clear();
00168
00169
00170
00171
00172 topology_->restoreElementToNodeConnectivity(new_elem_to_node_);
00173
00174 showTopLevelRelations();
00175
00176
00177 bulk_data_->modification_end();
00178
00179
00180
00181 stk_discretization_->updateMesh();
00182
00183
00184 *output_stream_ << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
00185 *output_stream_ << "Completed mesh adaptation " << std::endl;
00186 *output_stream_ << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
00187
00188 return true;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197 void
00198 AAdapt::RandomFracture::
00199 solutionTransfer(const Epetra_Vector& oldSolution,
00200 Epetra_Vector& newSolution)
00201 {}
00202
00203
00204
00205 Teuchos::RCP<const Teuchos::ParameterList>
00206 AAdapt::RandomFracture::getValidAdapterParameters() const {
00207 Teuchos::RCP<Teuchos::ParameterList> validPL =
00208 this->getGenericAdapterParams("ValidRandomFractureificationParams");
00209
00210 validPL->set<double>("Fracture Probability",
00211 1.0,
00212 "Probability of fracture");
00213 validPL->set<double>("Adaptivity Step Interval",
00214 1,
00215 "Interval to check for fracture");
00216
00217 return validPL;
00218 }
00219
00220
00221 void
00222 AAdapt::RandomFracture::
00223 showTopLevelRelations() {
00224 std::vector<Entity*> element_list;
00225 stk::mesh::get_entities(*(bulk_data_), element_rank_, element_list);
00226
00227
00228 for(int i = 0; i < element_list.size(); ++i) {
00229 Entity& element = *(element_list[i]);
00230 stk::mesh::PairIterRelation relations = element.relations();
00231 std::cout << "Entitiy " << element.identifier() << " relations are :" << std::endl;
00232
00233 for(int j = 0; j < relations.size(); ++j) {
00234 std::cout << "entity:\t" << relations[j].entity()->identifier() << ","
00235 << relations[j].entity()->entity_rank() << "\tlocal id: "
00236 << relations[j].identifier() << "\n";
00237 }
00238 }
00239 }
00240
00241
00242 void
00243 AAdapt::RandomFracture::showRelations() {
00244 std::vector<Entity*> element_list;
00245 stk::mesh::get_entities(*(bulk_data_), element_rank_, element_list);
00246
00247
00248 for(int i = 0; i < element_list.size(); ++i) {
00249 Entity& element = *(element_list[i]);
00250 showRelations(0, element);
00251 }
00252 }
00253
00254
00255 void
00256 AAdapt::RandomFracture::showRelations(int level, const Entity& entity) {
00257 stk::mesh::PairIterRelation relations = entity.relations();
00258
00259 for(int i = 0; i < level; i++) {
00260 std::cout << " ";
00261 }
00262
00263 std::cout << meta_data_->entity_rank_name(entity.entity_rank()) <<
00264 " " << entity.identifier() << " relations are :" << std::endl;
00265
00266 for(int j = 0; j < relations.size(); ++j) {
00267 for(int i = 0; i < level; i++) {
00268 std::cout << " ";
00269 }
00270
00271 std::cout << " " << meta_data_->entity_rank_name(relations[j].entity()->entity_rank()) << ":\t"
00272 << relations[j].entity()->identifier() << ","
00273 << relations[j].entity()->entity_rank() << "\tlocal id: "
00274 << relations[j].identifier() << "\n";
00275 }
00276
00277 for(int j = 0; j < relations.size(); ++j) {
00278 if(relations[j].entity()->entity_rank() <= entity.entity_rank())
00279 showRelations(level + 1, *relations[j].entity());
00280 }
00281 }
00282
00283 #ifdef ALBANY_MPI
00284
00285 int
00286 AAdapt::RandomFracture::accumulateFractured(int num_fractured) {
00287 int total_fractured;
00288
00289 stk::all_reduce_sum(bulk_data_->parallel(), &num_fractured, &total_fractured, 1);
00290
00291 return total_fractured;
00292 }
00293
00294
00295
00296 void
00297 AAdapt::RandomFracture::getGlobalOpenList(std::map<EntityKey, bool>& local_entity_open,
00298 std::map<EntityKey, bool>& global_entity_open) {
00299
00300 assert(sizeof(EntityKey::raw_key_type) >= sizeof(uint64_t));
00301
00302 const unsigned parallel_size = bulk_data_->parallel_size();
00303
00304
00305 std::pair<EntityKey, bool> me;
00306 std::vector<EntityKey::raw_key_type> v;
00307
00308 BOOST_FOREACH(me, local_entity_open) {
00309 v.push_back(me.first.raw_key());
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 }
00322
00323 int num_open_on_pe = v.size();
00324
00325
00326
00327
00328 int* sizes = new int[parallel_size];
00329 MPI_Allgather(&num_open_on_pe, 1, MPI_INT, sizes, 1, MPI_INT, bulk_data_->parallel());
00330
00331
00332 int* offsets = new int[parallel_size];
00333 int count = 0;
00334
00335 for(int i = 0; i < parallel_size; i++) {
00336 offsets[i] = count;
00337 count += sizes[i];
00338 }
00339
00340 int total_number_of_open_entities = count;
00341
00342 EntityKey::raw_key_type* result_array = new EntityKey::raw_key_type[total_number_of_open_entities];
00343 MPI_Allgatherv(&v[0], num_open_on_pe, MPI_UINT64_T, result_array,
00344 sizes, offsets, MPI_UINT64_T, bulk_data_->parallel());
00345
00346
00347 for(int i = 0; i < total_number_of_open_entities; i++) {
00348
00349 EntityKey key = EntityKey(&result_array[i]);
00350 global_entity_open[key] = true;
00351
00352
00353 const unsigned entity_rank = stk::mesh::entity_rank(key);
00354 const stk::mesh::EntityId entity_id = stk::mesh::entity_id(key);
00355 const std::string& entity_rank_name = meta_data_->entity_rank_name(entity_rank);
00356 Entity* entity = bulk_data_->get_entity(key);
00357 std::cout << "Global proc fracture list contains " << " " << entity_rank_name << " [" << entity_id << "] Proc:"
00358 << entity->owner_rank() << std::endl;
00359 }
00360
00361 delete [] sizes;
00362 delete [] offsets;
00363 delete [] result_array;
00364 }
00365
00366 #else
00367 int
00368 AAdapt::RandomFracture::accumulateFractured(int num_fractured) {
00369 return num_fractured;
00370 }
00371
00372
00373 void
00374 AAdapt::RandomFracture::getGlobalOpenList(std::map<EntityKey, bool>& local_entity_open,
00375 std::map<EntityKey, bool>& global_entity_open) {
00376 global_entity_open = local_entity_open;
00377 }
00378 #endif
00379 }