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