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

AAdapt_MeshAdapt_Def.hpp

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 "AAdapt_MeshAdapt.hpp"
00008 #include "Teuchos_TimeMonitor.hpp"
00009 #include <ma.h>
00010 
00011 template<class SizeField>
00012 Teuchos::RCP<SizeField> AAdapt::MeshAdapt<SizeField>::szField = Teuchos::null;
00013 
00014 template<class SizeField>
00015 AAdapt::MeshAdapt<SizeField>::
00016 MeshAdapt(const Teuchos::RCP<Teuchos::ParameterList>& params_,
00017           const Teuchos::RCP<ParamLib>& paramLib_,
00018           Albany::StateManager& StateMgr_,
00019           const Teuchos::RCP<const Epetra_Comm>& comm_) :
00020   AAdapt::AbstractAdapter(params_, paramLib_, StateMgr_, comm_),
00021   remeshFileIndex(1) {
00022 
00023   disc = StateMgr_.getDiscretization();
00024 
00025   pumi_discretization = Teuchos::rcp_dynamic_cast<AlbPUMI::AbstractPUMIDiscretization>(disc);
00026 
00027   fmdbMeshStruct = pumi_discretization->getFMDBMeshStruct();
00028 
00029   mesh = fmdbMeshStruct->apfMesh;
00030   pumiMesh = fmdbMeshStruct->getMesh();
00031 
00032   szField = Teuchos::rcp(new SizeField(pumi_discretization));
00033 
00034   num_iterations = params_->get<int>("Max Number of Mesh Adapt Iterations", 1);
00035 
00036   // Save the initial output file name
00037   base_exo_filename = fmdbMeshStruct->outputFileName;
00038 
00039   adaptation_method = params_->get<std::string>("Method");
00040 
00041   if ( adaptation_method.compare(0,15,"RPI SPR Size") == 0 )
00042     checkValidStateVariable(params_->get<std::string>("State Variable",""));
00043 
00044   adaptTime = Teuchos::TimeMonitor::getNewTimer("Albany: Mesh Adapt");
00045 
00046 }
00047 
00048 template<class SizeField>
00049 AAdapt::MeshAdapt<SizeField>::
00050 ~MeshAdapt() {
00051 }
00052 
00053 template<class SizeField>
00054 bool
00055 AAdapt::MeshAdapt<SizeField>::queryAdaptationCriteria() {
00056 
00057   if(adapt_params_->get<std::string>("Remesh Strategy", "None").compare("Continuous") == 0){
00058 
00059     if(iter > 1)
00060 
00061       return true;
00062 
00063     else
00064 
00065       return false;
00066 
00067   }
00068 
00069 
00070   Teuchos::Array<int> remesh_iter = adapt_params_->get<Teuchos::Array<int> >("Remesh Step Number");
00071 
00072   for(int i = 0; i < remesh_iter.size(); i++)
00073 
00074     if(iter == remesh_iter[i])
00075 
00076       return true;
00077 
00078   return false;
00079 
00080 }
00081 
00082 template<class SizeField>
00083 void
00084 AAdapt::MeshAdapt<SizeField>::printElementData() {
00085 
00086   Albany::StateArrays& sa = disc->getStateArrays();
00087   Albany::StateArrayVec& esa = sa.elemStateArrays;
00088   int numElemWorksets = esa.size();
00089   Teuchos::RCP<Albany::StateInfoStruct> stateInfo = state_mgr_.getStateInfoStruct();
00090 
00091   for(unsigned int i = 0; i < stateInfo->size(); i++) {
00092 
00093     const std::string stateName = (*stateInfo)[i]->name;
00094     const std::string init_type = (*stateInfo)[i]->initType;
00095     std::vector<int> dims;
00096     esa[0][stateName].dimensions(dims);
00097     int size = dims.size();
00098 
00099     std::cout << "Meshadapt: have element field \"" << stateName << "\" of type \"" << init_type << "\"" << std::endl;
00100 
00101     if(init_type == "scalar") {
00102 
00103 
00104       switch(size) {
00105 
00106         case 1:
00107           std::cout << "esa[ws][stateName](0)" << std::endl;
00108           break;
00109 
00110         case 2:
00111           std::cout << "esa[ws][stateName](cell, qp)" << std::endl;
00112           break;
00113 
00114         case 3:
00115           std::cout << "esa[ws][stateName](cell, qp, i)" << std::endl;
00116           break;
00117 
00118         case 4:
00119           std::cout << "esa[ws][stateName](cell, qp, i, j)" << std::endl;
00120           break;
00121 
00122       }
00123     }
00124 
00125     else if(init_type == "identity") {
00126       std::cout << "Have an identity matrix: " << "esa[ws][stateName](cell, qp, i, j)" << std::endl;
00127     }
00128   }
00129 }
00130 
00131 template<class SizeField>
00132 bool
00133 AAdapt::MeshAdapt<SizeField>::adaptMesh(const Epetra_Vector& sol, const Epetra_Vector& ovlp_sol) {
00134 
00135   Teuchos::TimeMonitor adaptTimer(*adaptTime); // start timer
00136 
00137   if(epetra_comm_->MyPID() == 0){
00138     std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
00139     std::cout << "Adapting mesh using AAdapt::MeshAdapt method        " << std::endl;
00140     std::cout << "Iteration: " << iter                                  << std::endl;
00141     std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
00142   }
00143 
00144  // Create a remeshed output file naming convention by adding the remesh_file_index_ ahead of the period
00145   std::size_t found = base_exo_filename.find("exo");
00146   if(found != std::string::npos){
00147     std::ostringstream ss;
00148     std::string str = base_exo_filename;
00149     ss << "_" << remeshFileIndex << ".";
00150     str.replace(str.find('.'), 1, ss.str());
00151 
00152     *output_stream_ << "Remeshing: renaming exodus output file to - " << str << std::endl;
00153 
00154     // Open the new exodus file for results
00155     pumi_discretization->reNameExodusOutput(str);
00156 
00157     remeshFileIndex++;
00158 
00159   }
00160 
00161 
00162   // display # entities before adaptation
00163 
00164   FMDB_Mesh_DspSize(pumiMesh);
00165 
00166   std::string adaptVector = adapt_params_->get<std::string>("Adaptation Displacement Vector","");
00167   apf::Field* solutionField;
00168   if (adaptVector.length() != 0)
00169     solutionField = mesh->findField(adaptVector.c_str());
00170   else
00171     solutionField = mesh->findField("solution");
00172   
00173   // replace nodes' coordinates with displaced coordinates
00174   if ( ! PCU_Comm_Self())
00175     fprintf(stderr,"assuming deformation problem: displacing coordinates\n");
00176   apf::displaceMesh(mesh,solutionField);
00177 
00178   szField->setParams(&sol, &ovlp_sol,
00179                      adapt_params_->get<double>("Target Element Size", 0.1),
00180          adapt_params_->get<double>("Error Bound", 0.01),
00181          adapt_params_->get<std::string>("State Variable", ""));
00182 
00183   szField->computeError();
00184 
00185   ma::Input* input = ma::configure(mesh,&(*szField));
00186       // Teuchos::RCP to regular pointer ^
00187   input->maximumIterations = num_iterations;
00188   //do not snap on deformation problems even if the model supports it
00189   input->shouldSnap = false;
00190 
00191   loadBalancing = adapt_params_->get<bool>("Load Balancing",true);
00192   lbMaxImbalance = adapt_params_->get<double>("Maximum LB Imbalance",1.30);
00193   if (loadBalancing) {
00194     input->shouldRunPreZoltan = true;
00195     input->shouldRunMidDiffusion = true;
00196     input->shouldRunPostDiffusion = true;
00197     input->maximumImbalance = lbMaxImbalance;
00198   }
00199 
00200   ma::adapt(input);
00201 
00202   if ( adaptation_method.compare(0,15,"RPI SPR Size") == 0 ) {
00203     apf::destroyField(mesh->findField("size"));
00204   }
00205   
00206   // replace nodes' displaced coordinates with coordinates
00207   apf::displaceMesh(mesh,solutionField,-1.0);
00208 
00209   // display # entities after adaptation
00210   FMDB_Mesh_DspSize(pumiMesh);
00211 
00212   // Throw away all the Albany data structures and re-build them from the mesh
00213   // Note that the solution transfer for the QP fields happens in this call
00214   pumi_discretization->updateMesh();
00215 
00216   adaptTimer.~TimeMonitor(); // end timer
00217 
00218   return true;
00219 
00220 }
00221 
00222 
00224 template<class SizeField>
00225 void
00226 AAdapt::MeshAdapt<SizeField>::
00227 solutionTransfer(const Epetra_Vector& oldSolution,
00228                  Epetra_Vector& newSolution) {
00229 
00230 // Lets check the output of the solution transfer, it needs to be complete here as once this function returns LOCA
00231 // begins the equilibration step
00232 
00233   pumi_discretization->debugMeshWrite(newSolution, "debug_output");
00234 
00235 }
00236 
00237 template<class SizeField>
00238 void
00239 AAdapt::MeshAdapt<SizeField>::checkValidStateVariable(const std::string name) {
00240 
00241   if (name.length() > 0) {
00242 
00243     // does state variable exist?
00244     std::string stateName;
00245     
00246     Albany::StateArrays& sa = disc->getStateArrays();
00247     Albany::StateArrayVec& esa = sa.elemStateArrays;
00248     Teuchos::RCP<Albany::StateInfoStruct> stateInfo = state_mgr_.getStateInfoStruct();
00249     bool exists = false;
00250     for(unsigned int i = 0; i < stateInfo->size(); i++) {
00251       stateName = (*stateInfo)[i]->name;
00252       if ( name.compare(0,100,stateName) == 0 ){
00253         exists = true;
00254         break;
00255       }
00256     }
00257     if (!exists)
00258       TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00259           "Error!    Invalid State Variable Parameter!");
00260     
00261     // is state variable a 3x3 tensor?
00262     
00263     std::vector<int> dims;
00264     esa[0][name].dimensions(dims);
00265     int size = dims.size();
00266     if (size != 4)
00267       TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00268       "Error! Invalid State Variable Parameter \"" << name << "\" looking for \"" << stateName << "\"" << std::endl);
00269   }
00270 }
00271 
00272 template<class SizeField>
00273 Teuchos::RCP<const Teuchos::ParameterList>
00274 AAdapt::MeshAdapt<SizeField>::getValidAdapterParameters() const {
00275   Teuchos::RCP<Teuchos::ParameterList> validPL =
00276     this->getGenericAdapterParams("ValidMeshAdaptParams");
00277 
00278   Teuchos::Array<int> defaultArgs;
00279 
00280   validPL->set<Teuchos::Array<int> >("Remesh Step Number", defaultArgs, "Iteration step at which to remesh the problem");
00281   validPL->set<std::string>("Remesh Strategy", "", "Strategy to use when remeshing: Continuous - remesh every step.");
00282   validPL->set<int>("Max Number of Mesh Adapt Iterations", 1, "Number of iterations to limit meshadapt to");
00283   validPL->set<double>("Target Element Size", 0.1, "Seek this element size when isotropically adapting");
00284   validPL->set<double>("Error Bound", 0.1, "Max relative error for error-based adaptivity");
00285   validPL->set<std::string>("State Variable", "", "SPR operates on this variable");
00286   validPL->set<bool>("Load Balancing", true, "Turn on predictive load balancing");
00287   validPL->set<double>("Maximum LB Imbalance", 1.3, "Set maximum imbalance tolerance for predictive laod balancing");
00288   validPL->set<std::string>("Adaptation Displacement Vector", "", "Name of APF displacement field");
00289   
00290   return validPL;
00291 }
00292 
00293 

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