00001
00002
00003
00004
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
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);
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
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
00155 pumi_discretization->reNameExodusOutput(str);
00156
00157 remeshFileIndex++;
00158
00159 }
00160
00161
00162
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
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
00187 input->maximumIterations = num_iterations;
00188
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
00207 apf::displaceMesh(mesh,solutionField,-1.0);
00208
00209
00210 FMDB_Mesh_DspSize(pumiMesh);
00211
00212
00213
00214 pumi_discretization->updateMesh();
00215
00216 adaptTimer.~TimeMonitor();
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
00231
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
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
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