• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Albany_GenericSTKMeshStruct.cpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
00005 //*****************************************************************//
00006 
00007 #include <iostream>
00008 
00009 #include "Albany_GenericSTKMeshStruct.hpp"
00010 
00011 #include "Albany_OrdinarySTKFieldContainer.hpp"
00012 #include "Albany_MultiSTKFieldContainer.hpp"
00013 
00014 
00015 #ifdef ALBANY_SEACAS
00016 #include <stk_io/IossBridge.hpp>
00017 #endif
00018 
00019 #include "Albany_Utils.hpp"
00020 #include <stk_mesh/base/GetEntities.hpp>
00021 #include <stk_mesh/fem/CreateAdjacentEntities.hpp>
00022 
00023 // Rebalance 
00024 #ifdef ALBANY_ZOLTAN
00025 #include <stk_rebalance/Rebalance.hpp>
00026 #include <stk_rebalance/Partition.hpp>
00027 #include <stk_rebalance/ZoltanPartition.hpp>
00028 #include <stk_rebalance_utils/RebalanceUtils.hpp>
00029 #endif
00030 
00031 // Refinement
00032 #ifdef ALBANY_STK_PERCEPT
00033 #include <stk_adapt/UniformRefiner.hpp>
00034 #include <stk_adapt/UniformRefinerPattern.hpp>
00035 #endif
00036 
00037 static void
00038 printCTD(const CellTopologyData & t )
00039 {
00040   std::cout << t.name ;
00041   std::cout << " { D = " << t.dimension ;
00042   std::cout << " , NV = " << t.vertex_count ;
00043   std::cout << " , K = 0x" << std::hex << t.key << std::dec ;
00044   std::cout << std::endl ;
00045 
00046   for ( unsigned d = 0 ; d < 4 ; ++d ) {
00047     for ( unsigned i = 0 ; i < t.subcell_count[d] ; ++i ) {
00048 
00049       const CellTopologyData_Subcell & sub = t.subcell[d][i] ;
00050 
00051       std::cout << "  subcell[" << d << "][" << i << "] = { " ;
00052 
00053       std::cout << sub.topology->name ;
00054       std::cout << " ," ;
00055       for ( unsigned j = 0 ; j < sub.topology->node_count ; ++j ) {
00056         std::cout << " " << sub.node[j] ;
00057       }
00058       std::cout << " }" << std::endl ;
00059     }
00060   }
00061 
00062   std::cout << "}" << std::endl << std::endl ;
00063 
00064 }
00065 
00066 Albany::GenericSTKMeshStruct::GenericSTKMeshStruct(
00067     const Teuchos::RCP<Teuchos::ParameterList>& params_,
00068     const Teuchos::RCP<Teuchos::ParameterList>& adaptParams_,
00069     int numDim_)
00070     : params(params_),
00071       adaptParams(adaptParams_),
00072       buildEMesh(false),
00073       uniformRefinementInitialized(false)
00074 //      , out(Teuchos::VerboseObjectBase::getDefaultOStream())
00075 {
00076 
00077   metaData = new stk::mesh::fem::FEMMetaData();
00078 
00079   buildEMesh = buildPerceptEMesh();
00080 
00081   // numDim = -1 is default flag value to postpone initialization
00082   if (numDim_>0) {
00083     this->numDim = numDim_;
00084     std::vector<std::string> entity_rank_names = stk::mesh::fem::entity_rank_names(numDim_);
00085     // eMesh needs "FAMILY_TREE" entity
00086     if(buildEMesh)
00087       entity_rank_names.push_back("FAMILY_TREE");
00088     metaData->FEM_initialize(numDim_, entity_rank_names);
00089   }
00090 
00091   interleavedOrdering = params->get("Interleaved Ordering",true);
00092   allElementBlocksHaveSamePhysics = true; 
00093   compositeTet = params->get<bool>("Use Composite Tet 10", false);
00094   
00095   // This is typical, can be resized for multiple material problems
00096   meshSpecs.resize(1);
00097 
00098   bulkData = NULL;
00099 }
00100 
00101 Albany::GenericSTKMeshStruct::~GenericSTKMeshStruct()
00102 {
00103   delete metaData;
00104   delete bulkData;
00105 }
00106 
00107 void Albany::GenericSTKMeshStruct::SetupFieldData(
00108       const Teuchos::RCP<const Epetra_Comm>& comm,
00109                   const int neq_,
00110                   const AbstractFieldContainer::FieldContainerRequirements& req,
00111                   const Teuchos::RCP<Albany::StateInfoStruct>& sis,
00112                   const int worksetSize) 
00113 {
00114   TEUCHOS_TEST_FOR_EXCEPTION(!metaData->is_FEM_initialized(),
00115        std::logic_error,
00116        "LogicError: metaData->FEM_initialize(numDim) not yet called" << std::endl);
00117 
00118   neq = neq_;
00119 
00120   this->nodal_data_block = sis->getNodalDataBlock();
00121 
00122   if (bulkData == NULL)
00123 
00124      bulkData = new stk::mesh::BulkData(stk::mesh::fem::FEMMetaData::get_meta_data(*metaData),
00125                           Albany::getMpiCommFromEpetraComm(*comm), worksetSize );
00126 
00127 #ifdef ALBANY_LCM
00128   // If adaptation in LCM, create a new part for boundary
00129   if (adaptParams.is_null() == false) {
00130     stk::mesh::Part &
00131     boundary_part = metaData->declare_part("boundary");
00132 #ifdef ALBANY_SEACAS
00133     stk::io::put_io_part_attribute(boundary_part);
00134 #endif
00135   }
00136 #endif // ALBANY_LCM
00137 
00138   // Build the container for the STK fields
00139   Teuchos::Array<std::string> default_solution_vector; // Empty
00140   Teuchos::Array<std::string> solution_vector =
00141     params->get<Teuchos::Array<std::string> >("Solution Vector Components", default_solution_vector);
00142 
00143   Teuchos::Array<std::string> default_residual_vector; // Empty
00144   Teuchos::Array<std::string> residual_vector =
00145     params->get<Teuchos::Array<std::string> >("Residual Vector Components", default_residual_vector);
00146 
00147   // Build the usual Albany fields unless the user explicitly specifies the residual or solution vector layout
00148   if(solution_vector.length() == 0 && residual_vector.length() == 0){
00149 
00150       if(interleavedOrdering)
00151         this->fieldContainer = Teuchos::rcp(new Albany::OrdinarySTKFieldContainer<true>(params, 
00152             metaData, bulkData, neq_, req, numDim, sis)); 
00153       else
00154         this->fieldContainer = Teuchos::rcp(new Albany::OrdinarySTKFieldContainer<false>(params,
00155             metaData, bulkData, neq_, req, numDim, sis)); 
00156 
00157   }
00158  
00159   else {
00160 
00161       if(interleavedOrdering)
00162         this->fieldContainer = Teuchos::rcp(new Albany::MultiSTKFieldContainer<true>(params, 
00163             metaData, bulkData, neq_, req, numDim, sis, solution_vector, residual_vector)); 
00164       else
00165         this->fieldContainer = Teuchos::rcp(new Albany::MultiSTKFieldContainer<false>(params,
00166             metaData, bulkData, neq_, req, numDim, sis, solution_vector, residual_vector)); 
00167 
00168   }
00169 
00170 // Exodus is only for 2D and 3D. Have 1D version as well
00171   exoOutput = params->isType<std::string>("Exodus Output File Name");
00172   if (exoOutput)
00173     exoOutFile = params->get<std::string>("Exodus Output File Name");
00174   exoOutputInterval = params->get<int>("Exodus Write Interval", 1);
00175   cdfOutput = params->isType<std::string>("NetCDF Output File Name");
00176   if (cdfOutput) 
00177     cdfOutFile = params->get<std::string>("NetCDF Output File Name");
00178   
00179   nLat       =  params->get("NetCDF Output Number of Latitudes",100);
00180   nLon       =  params->get("NetCDF Output Number of Longitudes",100);
00181   cdfOutputInterval = params->get<int>("NetCDF Write Interval", 1);
00182 
00183 
00184   //get the type of transformation of STK mesh (for FELIX problems)
00185   transformType = params->get("Transform Type", "None"); //get the type of transformation of STK mesh (for FELIX problems)
00186   felixAlpha = params->get("FELIX alpha", 0.0); 
00187   felixL = params->get("FELIX L", 1.0); 
00188  
00189   //boolean specifying if ascii mesh has contiguous IDs; only used for ascii meshes on 1 processor
00190   contigIDs = params->get("Contiguous IDs", true);
00191  
00192   //Does user want to write coordinates to matrix market file (e.g., for ML analysis)? 
00193   writeCoordsToMMFile = params->get("Write Coordinates to MatrixMarket", false); 
00194 
00195   transferSolutionToCoords = params->get<bool>("Transfer Solution to Coordinates", false);
00196 
00197 #ifdef ALBANY_STK_PERCEPT
00198   // Build the eMesh if needed
00199   if(buildEMesh)
00200 
00201    eMesh = Teuchos::rcp(new stk::percept::PerceptMesh(metaData, bulkData, false));
00202 
00203   // Build  the requested refiners 
00204   if(!eMesh.is_null()){
00205 
00206    if(buildUniformRefiner()) // cant currently build both types of refiners (FIXME)
00207 
00208       return;
00209 
00210    buildLocalRefiner();
00211 
00212   }
00213 #endif
00214 
00215 }
00216 
00217 bool Albany::GenericSTKMeshStruct::buildPerceptEMesh(){
00218 
00219    // If there exists a nonempty "refine", "convert", or "enrich" string
00220     std::string refine = params->get<std::string>("STK Initial Refine", "");
00221     if(refine.length() > 0) return true;
00222     std::string convert = params->get<std::string>("STK Initial Enrich", "");
00223     if(convert.length() > 0) return true;
00224     std::string enrich = params->get<std::string>("STK Initial Convert", "");
00225     if(enrich.length() > 0) return true;
00226 
00227     // Or, if a percept mesh is needed to support general adaptation indicated in the "Adaptation" sublist
00228     if(!adaptParams.is_null()){
00229 
00230       std::string& method = adaptParams->get("Method", "");
00231 
00232       if (method == "Unif Size")
00233         return true;
00234 
00235     }
00236 
00237     return false;
00238 
00239 }
00240 
00241 bool Albany::GenericSTKMeshStruct::buildUniformRefiner(){
00242 
00243 #ifdef ALBANY_STK_PERCEPT
00244 
00245     stk::adapt::BlockNamesType block_names(stk::percept::EntityRankEnd+1u);
00246 
00247     std::string refine = params->get<std::string>("STK Initial Refine", "");
00248     std::string convert = params->get<std::string>("STK Initial Convert", "");
00249     std::string enrich = params->get<std::string>("STK Initial Enrich", "");
00250 
00251     std::string convert_options = stk::adapt::UniformRefinerPatternBase::s_convert_options;
00252     std::string refine_options  = stk::adapt::UniformRefinerPatternBase::s_refine_options;
00253     std::string enrich_options  = stk::adapt::UniformRefinerPatternBase::s_enrich_options;
00254 
00255     // Has anything been specified?
00256 
00257     if(refine.length() == 0 && convert.length() == 0 && enrich.length() == 0)
00258 
00259        return false;
00260 
00261     if (refine.length())
00262 
00263       checkInput("refine", refine, refine_options);
00264 
00265     if (convert.length())
00266 
00267       checkInput("convert", convert, convert_options);
00268 
00269     if (enrich.length())
00270 
00271       checkInput("enrich", enrich, enrich_options);
00272 
00273     refinerPattern = stk::adapt::UniformRefinerPatternBase::createPattern(refine, enrich, convert, *eMesh, block_names);
00274     uniformRefinementInitialized = true;
00275 
00276     return true;
00277 
00278 #else
00279     return false;
00280 #endif
00281 
00282 }
00283 
00284 bool Albany::GenericSTKMeshStruct::buildLocalRefiner(){
00285 
00286 #ifdef ALBANY_STK_PERCEPT
00287 
00288     if(adaptParams.is_null()) return false;
00289 
00290 //    stk::adapt::BlockNamesType block_names = stk::adapt::BlockNamesType();
00291     stk::adapt::BlockNamesType block_names(stk::percept::EntityRankEnd+1u);
00292 
00293     std::string adapt_method = adaptParams->get<std::string>("Method", "");
00294 
00295     // Check if adaptation was specified
00296     if(adapt_method.length() == 0) return false; 
00297 
00298     std::string pattern = adaptParams->get<std::string>("Refiner Pattern", "");
00299 
00300     if(pattern == "Local_Tet4_Tet4_N"){
00301 
00302 //      refinerPattern = Teuchos::rcp(new stk::adapt::Local_Tet4_Tet4_N(*eMesh, block_names));
00303       refinerPattern = Teuchos::rcp(new stk::adapt::Local_Tet4_Tet4_N(*eMesh));
00304       return true;
00305 
00306     }
00307     else {
00308 
00309       TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter, std::endl <<
00310          "Error!  Unknown local adaptation pattern in GenericSTKMeshStruct: " << pattern <<
00311          "!" << std::endl << "Supplied parameter list is: " << std::endl << *adaptParams
00312          << "\nValid patterns are: Local_Tet4_Tet4_N" << std::endl);
00313     }
00314 
00315 
00316 #endif
00317 
00318     return false;
00319 
00320 }
00321 
00322 void 
00323 Albany::GenericSTKMeshStruct::cullSubsetParts(std::vector<std::string>& ssNames, 
00324     std::map<std::string, stk::mesh::Part*>& partVec){
00325 
00326 /*
00327 When dealing with sideset lists, it is common to have parts that are subsets of other parts, like:
00328 Part[ surface_12 , 18 ] {
00329   Supersets { {UNIVERSAL} }
00330   Intersection_Of { } }
00331   Subsets { surface_quad4_edge2d2_12 }
00332 
00333 Part[ surface_quad4_edge2d2_12 , 19 ] {
00334   Supersets { {UNIVERSAL} {FEM_ROOT_CELL_TOPOLOGY_PART_Line_2} surface_12 }
00335   Intersection_Of { } }
00336   Subsets { }
00337 
00338 This function gets rid of the subset in the list. 
00339 */
00340 
00341   using std::map;
00342 
00343   map<std::string, stk::mesh::Part*>::iterator it;
00344   std::vector<stk::mesh::Part*>::const_iterator p;
00345 
00346   for(it = partVec.begin(); it != partVec.end(); ++it){ // loop over the parts in the map
00347 
00348     // for each part in turn, get the name of parts that are a subset of it
00349 
00350     const stk::mesh::PartVector & subsets   = it->second->subsets();
00351 
00352     for ( p = subsets.begin() ; p != subsets.end() ; ++p ) {
00353       const std::string & n = (*p)->name();
00354 //      std::cout << "Erasing: " << n << std::endl;
00355       partVec.erase(n); // erase it if it is in the base map
00356     }
00357   }
00358 
00359 //  ssNames.clear();
00360 
00361   // Build the remaining data structures
00362   for(it = partVec.begin(); it != partVec.end(); ++it){ // loop over the parts in the map
00363 
00364     std::string ssn = it->first;
00365     ssNames.push_back(ssn);
00366 
00367   }
00368 }
00369 
00370 
00371 Teuchos::ArrayRCP<Teuchos::RCP<Albany::MeshSpecsStruct> >&
00372 Albany::GenericSTKMeshStruct::getMeshSpecs()
00373 {
00374   TEUCHOS_TEST_FOR_EXCEPTION(meshSpecs==Teuchos::null,
00375        std::logic_error,
00376        "meshSpecs accessed, but it has not been constructed" << std::endl);
00377   return meshSpecs;
00378 }
00379 
00380 int Albany::GenericSTKMeshStruct::computeWorksetSize(const int worksetSizeMax,
00381                                                      const int ebSizeMax) const
00382 {
00383   // Resize workset size down to maximum number in an element block
00384   if (worksetSizeMax > ebSizeMax || worksetSizeMax < 1) return ebSizeMax;
00385   else {
00386      // compute numWorksets, and shrink workset size to minimize padding
00387      const int numWorksets = 1 + (ebSizeMax-1) / worksetSizeMax;
00388      return (1 + (ebSizeMax-1) /  numWorksets);
00389   }
00390 }
00391 
00392 void Albany::GenericSTKMeshStruct::computeAddlConnectivity()
00393 {
00394 
00395   if(adaptParams.is_null()) return;
00396 
00397   std::string& method = adaptParams->get("Method", "");
00398 
00399   // Mesh fracture requires full mesh connectivity, created here
00400   if(method == "Topmod" || method == "Random"){ 
00401 
00402     stk::mesh::PartVector add_parts;
00403     stk::mesh::create_adjacent_entities(*bulkData, add_parts);
00404   
00405     stk::mesh::EntityRank elementRank = metaData->element_rank();
00406     stk::mesh::EntityRank nodeRank = metaData->node_rank();
00407     stk::mesh::EntityRank sideRank = metaData->side_rank();
00408   
00409     std::vector<stk::mesh::Entity*> element_lst;
00410   //  stk::mesh::get_entities(*(bulkData),elementRank,element_lst);
00411     
00412     stk::mesh::Selector select_owned_or_shared = metaData->locally_owned_part() | metaData->globally_shared_part();
00413     stk::mesh::Selector select_owned = metaData->locally_owned_part();
00414   
00415   /*
00416         stk::mesh::Selector select_owned_in_part =
00417         stk::mesh::Selector( metaData->universal_part() ) &
00418         stk::mesh::Selector( metaData->locally_owned_part() );
00419   
00420         stk::mesh::get_selected_entities( select_owned_in_part ,
00421   */
00422   
00423      // Loop through only on-processor elements as we are just deleting entities inside the element
00424      stk::mesh::get_selected_entities( select_owned,
00425         bulkData->buckets( elementRank ) ,
00426         element_lst );
00427   
00428     bulkData->modification_begin();
00429   
00430       // Remove extra relations from element
00431     for (int i = 0; i < element_lst.size(); ++i){
00432         stk::mesh::Entity & element = *(element_lst[i]);
00433         stk::mesh::PairIterRelation relations = element.relations();
00434         std::vector<stk::mesh::Entity*> del_relations;
00435         std::vector<int> del_ids;
00436         for (stk::mesh::PairIterRelation::iterator j = relations.begin();
00437              j != relations.end(); ++j){
00438   
00439           // remove all relationships from element unless to faces(segments
00440           //   in 2D) or nodes 
00441   
00442           if (
00443               j->entity_rank() != elementRank-1 && // element to face relation
00444               j->entity_rank() != nodeRank  
00445              ){
00446   
00447             del_relations.push_back(j->entity());
00448             del_ids.push_back(j->identifier());
00449           }
00450         }
00451   
00452       for (int j = 0; j < del_relations.size(); ++j){
00453         stk::mesh::Entity & entity = *(del_relations[j]);
00454         bulkData->destroy_relation(element,entity,del_ids[j]);
00455       }
00456     }
00457   
00458     if (elementRank == 3){
00459       // Remove extra relations from face
00460       std::vector<stk::mesh::Entity*> face_lst;
00461       //stk::mesh::get_entities(*(bulkData),elementRank-1,face_lst);
00462       // Loop through all faces visible to this processor, as a face can be visible on two processors
00463       stk::mesh::get_selected_entities( select_owned_or_shared,
00464                                         bulkData->buckets( elementRank-1 ) ,
00465                                         face_lst );
00466       stk::mesh::EntityRank entityRank = face_lst[0]->entity_rank(); // This is rank 2 always...
00467   //std::cout << "element rank - 1: " << elementRank - 1 << " face rank: " << entityRank << std::endl;
00468       for (int i = 0; i < face_lst.size(); ++i){
00469         stk::mesh::Entity & face = *(face_lst[i]);
00470         stk::mesh::PairIterRelation relations = face.relations();
00471         std::vector<stk::mesh::Entity*> del_relations;
00472         std::vector<int> del_ids;
00473         for (stk::mesh::PairIterRelation::iterator j = relations.begin();
00474              j != relations.end(); ++j){
00475   
00476           if (
00477               j->entity_rank() != entityRank+1 && // face to element relation
00478               j->entity_rank() != entityRank-1 // && // face to segment relation
00479   //            j->entity_rank() != sideRank     ){
00480              ){
00481   
00482             del_relations.push_back(j->entity());
00483             del_ids.push_back(j->identifier());
00484           }
00485         }
00486   
00487         for (int j = 0; j < del_relations.size(); ++j){
00488           stk::mesh::Entity & entity = *(del_relations[j]);
00489           bulkData->destroy_relation(face, entity, del_ids[j]);
00490   //std::cout << "Deleting rank: " << entity.entity_rank() << " id: " << del_ids[j] << std::endl;
00491         }
00492       }
00493     }
00494   
00495     bulkData->modification_end();
00496   }
00497 
00498 }
00499 
00500 
00501 void Albany::GenericSTKMeshStruct::uniformRefineMesh(const Teuchos::RCP<const Epetra_Comm>& comm){
00502 
00503 #ifdef ALBANY_STK_PERCEPT
00504 // Refine if requested
00505   if(!uniformRefinementInitialized) return;
00506 
00507   AbstractSTKFieldContainer::IntScalarFieldType* proc_rank_field = fieldContainer->getProcRankField();
00508 
00509 
00510   if(!refinerPattern.is_null() && proc_rank_field){
00511 
00512     stk::adapt::UniformRefiner refiner(*eMesh, *refinerPattern, proc_rank_field);
00513 
00514     int numRefinePasses = params->get<int>("Number of Refinement Passes", 1);
00515 
00516     for(int pass = 0; pass < numRefinePasses; pass++){
00517 
00518       if(comm->MyPID() == 0)
00519         std::cout << "Mesh refinement pass: " << pass + 1 << std::endl;
00520 
00521       refiner.doBreak();
00522 
00523     }
00524 
00525 // printCTD(*refinerPattern->getFromTopology());
00526 // printCTD(*refinerPattern->getToTopology());
00527 
00528     // Need to reset cell topology if the cell topology has changed
00529 
00530     if(refinerPattern->getFromTopology()->name != refinerPattern->getToTopology()->name){
00531 
00532       int numEB = partVec.size();
00533 
00534       for (int eb=0; eb<numEB; eb++) {
00535 
00536         meshSpecs[eb]->ctd = *refinerPattern->getToTopology();
00537 
00538       }
00539     }
00540   }
00541 #endif
00542 
00543 }
00544 
00545 
00546 void Albany::GenericSTKMeshStruct::rebalanceInitialMesh(const Teuchos::RCP<const Epetra_Comm>& comm){
00547 
00548 
00549   bool rebalance = params->get<bool>("Rebalance Mesh", false);
00550   bool useSerialMesh = params->get<bool>("Use Serial Mesh", false);
00551 
00552   if(rebalance || (useSerialMesh && comm->NumProc() > 1)){
00553 
00554     rebalanceAdaptedMesh(params, comm);
00555 
00556   }
00557 
00558 }
00559 
00560 void Albany::GenericSTKMeshStruct::rebalanceAdaptedMesh(const Teuchos::RCP<Teuchos::ParameterList>& params_,
00561                                                         const Teuchos::RCP<const Epetra_Comm>& comm){
00562 
00563 // Zoltan is required here
00564 
00565 #ifdef ALBANY_ZOLTAN
00566 
00567     using std::cout; using std::endl;
00568 
00569     if(comm->NumProc() <= 1)
00570 
00571       return;
00572 
00573     double imbalance;
00574 
00575     AbstractSTKFieldContainer::VectorFieldType* coordinates_field = fieldContainer->getCoordinatesField();
00576 
00577     stk::mesh::Selector selector(metaData->universal_part());
00578     stk::mesh::Selector owned_selector(metaData->locally_owned_part());
00579 
00580     if(comm->MyPID() == 0){
00581 
00582       std::cout << "Before rebal nelements " << comm->MyPID() << "  " << 
00583         stk::mesh::count_selected_entities(owned_selector, bulkData->buckets(metaData->element_rank())) << endl;
00584 
00585       std::cout << "Before rebal " << comm->MyPID() << "  " << 
00586         stk::mesh::count_selected_entities(owned_selector, bulkData->buckets(metaData->node_rank())) << endl;
00587     }
00588 
00589 
00590     imbalance = stk::rebalance::check_balance(*bulkData, NULL, 
00591       metaData->node_rank(), &selector);
00592 
00593     if(comm->MyPID() == 0)
00594 
00595       std::cout << "Before rebalance: Imbalance threshold is = " << imbalance << endl;
00596 
00597     // Use Zoltan to determine new partition. Set the desired parameters (if any) from the input file
00598 
00599     Teuchos::ParameterList graph_options;
00600 
00601    //graph_options.sublist(stk::rebalance::Zoltan::default_parameters_name()).set("LOAD BALANCING METHOD"      , "4");
00602     //graph_options.sublist(stk::rebalance::Zoltan::default_parameters_name()).set("ZOLTAN DEBUG LEVEL"      , "10");
00603 
00604     if(params_->isSublist("Rebalance Options")){
00605 
00606       const Teuchos::RCP<Teuchos::ParameterList>& load_balance_method = Teuchos::sublist(params_, "Rebalance Options");
00607 
00608     // Set the desired parameters. The options are shown in
00609     // TRILINOS_ROOT/packages/stk/stk_rebalance/ZontanPartition.cpp
00610 
00611 //      load_balance_method.set("LOAD BALANCING METHOD"      , "4");
00612 //      load_balance_method.set("ZOLTAN DEBUG LEVEL"      , "10");
00613 
00614       graph_options.sublist(stk::rebalance::Zoltan::default_parameters_name()) = *load_balance_method;
00615 
00616     }
00617 
00618     stk::rebalance::Zoltan zoltan_partition(Albany::getMpiCommFromEpetraComm(*comm), numDim, graph_options);
00619     stk::rebalance::rebalance(*bulkData, owned_selector, coordinates_field, NULL, zoltan_partition);
00620 
00621 
00622     imbalance = stk::rebalance::check_balance(*bulkData, NULL, 
00623       metaData->node_rank(), &selector);
00624 
00625     if(comm->MyPID() == 0)
00626       std::cout << "After rebalance: Imbalance threshold is = " << imbalance << endl;
00627 
00628 #if 0 // Other experiments at rebalancing
00629 
00630     // Configure Zoltan to use graph-based partitioning
00631     Teuchos::ParameterList graph;
00632     Teuchos::ParameterList lb_method;
00633     lb_method.set("LOAD BALANCING METHOD"      , "4");
00634     graph.sublist(stk::rebalance::Zoltan::default_parameters_name()) = lb_method;
00635 
00636     stk::rebalance::Zoltan zoltan_partitiona(Albany::getMpiCommFromEpetraComm(*comm), numDim, graph);
00637 
00638     *out << "Universal part " << comm->MyPID() << "  " << 
00639       stk::mesh::count_selected_entities(selector, bulkData->buckets(metaData->element_rank())) << endl;
00640     *out << "Owned part " << comm->MyPID() << "  " << 
00641       stk::mesh::count_selected_entities(owned_selector, bulkData->buckets(metaData->element_rank())) << endl;
00642 
00643     stk::rebalance::rebalance(*bulkData, owned_selector, coordinates_field, NULL, zoltan_partitiona);
00644 
00645     *out << "After rebal " << comm->MyPID() << "  " << 
00646       stk::mesh::count_selected_entities(owned_selector, bulkData->buckets(metaData->node_rank())) << endl;
00647     *out << "After rebal nelements " << comm->MyPID() << "  " << 
00648       stk::mesh::count_selected_entities(owned_selector, bulkData->buckets(metaData->element_rank())) << endl;
00649 
00650 
00651     imbalance = stk::rebalance::check_balance(*bulkData, NULL, 
00652       metaData->node_rank(), &selector);
00653 
00654     if(comm->MyPID() == 0){
00655 
00656       *out << "Before second rebal: Imbalance threshold is = " << imbalance << endl;
00657 
00658     }
00659 #endif
00660 
00661 #endif  //ALBANY_ZOLTAN
00662 
00663 }
00664 
00665 void Albany::GenericSTKMeshStruct::setupMeshBlkInfo()
00666 {
00667 #if 0
00668 
00669    int nBlocks = meshSpecs.size();
00670 
00671    for(int i = 0; i < nBlocks; i++){
00672 
00673       const MeshSpecsStruct &ms = *meshSpecs[i];
00674 
00675       meshDynamicData[i] = Teuchos::rcp(new CellSpecs(ms.ctd, ms.worksetSize, ms.cubatureDegree,
00676                       numDim, neq, 0, useCompositeTet()));
00677 
00678    }
00679 #endif
00680 
00681 }
00682 
00683 
00684 void Albany::GenericSTKMeshStruct::printParts(stk::mesh::fem::FEMMetaData *metaData){
00685 
00686     std::cout << "Printing all part names of the parts found in the metaData:" << std::endl;
00687 
00688     stk::mesh::PartVector all_parts = metaData->get_parts();
00689 
00690     for (stk::mesh::PartVector::iterator i_part = all_parts.begin(); i_part != all_parts.end(); ++i_part)
00691     {
00692        stk::mesh::Part *  part = *i_part ;
00693 
00694        std::cout << "\t" << part->name() << std::endl;
00695 
00696     }
00697 
00698 }
00699 
00700 void
00701 Albany::GenericSTKMeshStruct::checkInput(std::string option, std::string value, std::string allowed_values){
00702 
00703 #ifdef ALBANY_STK_PERCEPT
00704       std::vector<std::string> vals = stk::adapt::Util::split(allowed_values, ", ");
00705       for (unsigned i = 0; i < vals.size(); i++)
00706         {
00707           if (vals[i] == value)
00708             return;
00709         }
00710 
00711        TEUCHOS_TEST_FOR_EXCEPTION(true,
00712          std::runtime_error,
00713          "Adaptation input error in GenericSTKMeshStruct initialization: bar option: " << option << std::endl);
00714 #endif
00715 }
00716 
00717 Teuchos::RCP<Teuchos::ParameterList>
00718 Albany::GenericSTKMeshStruct::getValidGenericSTKParameters(std::string listname) const
00719 {
00720   Teuchos::RCP<Teuchos::ParameterList> validPL = rcp(new Teuchos::ParameterList(listname));;
00721   validPL->set<std::string>("Cell Topology", "Quad" , "Quad or Tri Cell Topology");
00722   validPL->set<std::string>("Exodus Output File Name", "",
00723       "Request exodus output to given file name. Requires SEACAS build");
00724   validPL->set<std::string>("Exodus Solution Name", "",
00725       "Name of solution output vector written to Exodus file. Requires SEACAS build");
00726   validPL->set<std::string>("Exodus Residual Name", "",
00727       "Name of residual output vector written to Exodus file. Requires SEACAS build");
00728   validPL->set<int>("Exodus Write Interval", 3, "Step interval to write solution data to Exodus file");
00729   validPL->set<std::string>("NetCDF Output File Name", "",
00730       "Request NetCDF output to given file name. Requires SEACAS build");
00731   validPL->set<int>("NetCDF Write Interval", 1, "Step interval to write solution data to NetCDF file");
00732   validPL->set<int>("NetCDF Output Number of Latitudes", 1, 
00733       "Number of samples in Latitude direction for NetCDF output. Default is 100.");
00734   validPL->set<int>("NetCDF Output Number of Longitudes", 1, 
00735       "Number of samples in Longitude direction for NetCDF output. Default is 100.");
00736   validPL->set<std::string>("Method", "",
00737     "The discretization method, parsed in the Discretization Factory");
00738   validPL->set<int>("Cubature Degree", 3, "Integration order sent to Intrepid");
00739   validPL->set<int>("Cubature Rule", 0, "Integration rule sent to Intrepid: 0=GAUSS, 1=GAUSS_RADAU_LEFT, 2=GAUSS_RADAU_RIGHT, 3=GAUSS_LOBATTO");
00740   validPL->set<int>("Workset Size", 50, "Upper bound on workset (bucket) size");
00741   validPL->set<bool>("Interleaved Ordering", true, "Flag for interleaved or blocked unknown ordering");
00742   validPL->set<bool>("Separate Evaluators by Element Block", false,
00743                      "Flag for different evaluation trees for each Element Block");
00744   validPL->set<std::string>("Transform Type", "None", "None or ISMIP-HOM Test A"); //for FELIX problem that require tranformation of STK mesh
00745   validPL->set<bool>("Write Coordinates to MatrixMarket", false, "Writing Coordinates to MatrixMarket File"); //for writing coordinates to matrix market file
00746   validPL->set<double>("FELIX alpha", 0.0, "Surface boundary inclination for FELIX problems (in degrees)"); //for FELIX problem that require tranformation of STK mesh
00747   validPL->set<double>("FELIX L", 1, "Domain length for FELIX problems"); //for FELIX problem that require tranformation of STK mesh
00748 
00749   validPL->set<bool>("Contiguous IDs", "true", "Tells Ascii mesh reader is mesh has contiguous global IDs on 1 processor."); //for FELIX problem that require tranformation of STK mesh
00750 
00751   Teuchos::Array<std::string> defaultFields;
00752   validPL->set<Teuchos::Array<std::string> >("Restart Fields", defaultFields, 
00753                      "Fields to pick up from the restart file when restarting");
00754   validPL->set<Teuchos::Array<std::string> >("Solution Vector Components", defaultFields,
00755       "Names and layout of solution output vector written to Exodus file. Requires SEACAS build");
00756   validPL->set<Teuchos::Array<std::string> >("Residual Vector Components", defaultFields,
00757       "Names and layout of residual output vector written to Exodus file. Requires SEACAS build");
00758 
00759   validPL->set<bool>("Use Serial Mesh", false, "Read in a single mesh on PE 0 and rebalance");
00760   validPL->set<bool>("Transfer Solution to Coordinates", false, "Copies the solution vector to the coordinates for output");
00761 
00762   validPL->set<bool>("Use Serial Mesh", false, "Read in a single mesh on PE 0 and rebalance");
00763   validPL->set<bool>("Use Composite Tet 10", false, "Flag to use the composite tet 10 basis in Intrepid");
00764 
00765   // Uniform percept adaptation of input mesh prior to simulation
00766 
00767   validPL->set<std::string>("STK Initial Refine", "", "stk::percept refinement option to apply after the mesh is input");
00768   validPL->set<std::string>("STK Initial Enrich", "", "stk::percept enrichment option to apply after the mesh is input");
00769   validPL->set<std::string>("STK Initial Convert", "", "stk::percept conversion option to apply after the mesh is input");
00770   validPL->set<bool>("Rebalance Mesh", false, "Parallel re-load balance initial mesh after generation");
00771   validPL->set<int>("Number of Refinement Passes", 1, "Number of times to apply the refinement process");
00772 
00773   return validPL;
00774 
00775 }
00776 
00777 

Generated on Wed Mar 26 2014 18:36:36 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1