// 输出网格到 VTK 文件 void MeshOpt::writeToVTK(hier::Patch<NDIM>& patch, const double time, const double dt, const bool initial_time) { NULL_USE(dt); NULL_USE(time); NULL_USE(initial_time); const tbox::Pointer< hier::BlockPatchGeometry<NDIM> > pgeom = patch.getPatchGeometry(); int block_index = pgeom->getBlockNumber(); int patch_index = patch.getPatchNumber(); std::stringstream bi, pi, df; bi << block_index; pi << patch_index; df << d_flag; std::string file_name = df.str() + "_block_ " + bi.str()+ "_patch_" + pi.str() + ".vtk"; MsqError err; MeshImpl * mesh = createLocalMesh(patch); mesh->write_vtk(file_name.c_str(), err); return; }
/************************************************************************* * MeshOpt 类的构造函数. * *************************************************************************/ MeshOpt::MeshOpt(const string& object_name, tbox::Pointer<tbox::Database> input_db, tbox::Pointer< appu::DeformingGridInputUtilities2 > grid_tool, tbox::Pointer<geom::MultiblockDeformingGridGeometry<NDIM> > grid_geom) { #ifdef DEBUG_CHECK_ASSERTIONS assert(!object_name.empty()); assert(!input_db.isNull()); assert(!grid_geom.isNull()); assert(!grid_tool.isNull()); #endif d_grid_geometry = grid_geom; d_grid_tool = grid_tool; getFromInput(input_db); d_flag = 0; // 为影像区的宽度赋值. d_zeroghosts = hier::IntVector<NDIM>(0); d_oneghosts = hier::IntVector<NDIM>(1); // 创建所有变量及数据片索引号, 注册可视化数据片. registerModelVariables(); }
void update_triads( const double freq, tbox::Pointer<hier::PatchHierarchy<NDIM> > hierarchy, LDataManager* const l_data_manager, const double current_time, const double /*dt*/) { // The angular velocity. static const double angw = 2.0*M_PI*freq; // The LMesh object provides the set of local Lagrangian nodes. const int finest_ln = hierarchy->getFinestLevelNumber(); const tbox::Pointer<LMesh> mesh = l_data_manager->getLMesh(finest_ln); const std::vector<LNode*>& local_nodes = mesh->getNodes(); // Update the director triads for all anchored points. tbox::Pointer<LData> D_data = l_data_manager->getLData("D", finest_ln); blitz::Array<double,2>& D_array = *D_data->getLocalFormVecArray(); for (std::vector<LNode*>::const_iterator cit = local_nodes.begin(); cit != local_nodes.end(); ++cit) { const LNode& node_idx = **cit; // If spec is NULL, then the IB point is NOT anchored. Otherwise, the // IB point IS anchored. tbox::Pointer<IBAnchorPointSpec> spec = node_idx.getNodeDataItem<IBAnchorPointSpec>(); if (!spec.isNull()) { // `global_idx' is the index of the vertex in the input file. const int global_idx = node_idx.getLagrangianIndex(); NULL_USE(global_idx); // `local_petsc_idx' is the index of the vertex in the internal // IBAMR data structures. Generally, global_idx != local_petsc_idx. const int local_petsc_idx = node_idx.getLocalPETScIndex(); double* D1 = &D_array(local_petsc_idx,0); D1[0] = cos(angw*current_time); D1[1] = sin(angw*current_time); D1[2] = 0.0; double* D2 = &D_array(local_petsc_idx,3); D2[0] = -sin(angw*current_time); D2[1] = cos(angw*current_time); D2[2] = 0.0; double* D3 = &D_array(local_petsc_idx,6); D3[0] = 0.0; D3[1] = 0.0; D3[2] = 1.0; } } D_data->restoreArrays(); return; }// update_triads
FACPreconditioner::FACPreconditioner( const std::string& object_name, Pointer<FACPreconditionerStrategy> fac_strategy, tbox::Pointer<tbox::Database> input_db) : d_object_name(object_name), d_is_initialized(false), d_fac_strategy(fac_strategy), d_hierarchy(NULL), d_coarsest_ln(0), d_finest_ln(0), d_cycle_type(V_CYCLE), d_num_pre_sweeps(1), d_num_post_sweeps(1), d_f(), d_r(), d_do_log(false) { /* * Register this class with the FACPreconditionerStrategy object. */ d_fac_strategy->setFACPreconditioner(Pointer<FACPreconditioner>(this,false)); /* * Initialize object with data read from input database. */ if (!input_db.isNull()) { getFromInput(input_db); } return; }// FACPreconditioner
void FACPreconditioner::getFromInput( tbox::Pointer<tbox::Database> db) { if (db.isNull()) return; MGCycleType cycle_type = string_to_enum<MGCycleType>(db->getStringWithDefault("cycle_type", enum_to_string<MGCycleType>(d_cycle_type))); setMGCycleType(cycle_type); int num_pre_sweeps = db->getIntegerWithDefault("num_pre_sweeps", d_num_pre_sweeps); setNumPreSmoothingSweeps(num_pre_sweeps); int num_post_sweeps = db->getIntegerWithDefault("num_post_sweeps", d_num_post_sweeps); setNumPostSmoothingSweeps(num_post_sweeps); bool logging = db->getBoolWithDefault("enable_logging", d_do_log); enableLogging(logging); return; }// getFromInput
void FACPreconditioner::getFromInput( tbox::Pointer<tbox::Database> db) { if (!db) return; if (db->keyExists("cycle_type")) setMGCycleType(string_to_enum<MGCycleType>(db->getString("cycle_type"))); if (db->keyExists("num_pre_sweeps")) setNumPreSmoothingSweeps(db->getInteger("num_pre_sweeps")); if (db->keyExists("num_post_sweeps")) setNumPostSmoothingSweeps(db->getInteger("num_post_sweeps")); if (db->keyExists("enable_logging")) setLoggingEnabled(db->getBool("enable_logging")); return; }// getFromInput
void output_data( tbox::Pointer<hier::PatchHierarchy<NDIM> > patch_hierarchy, LDataManager* l_data_manager, const int iteration_num, const double loop_time, const string& data_dump_dirname) { tbox::pout << "writing hierarchy data at iteration " << iteration_num << " to disk" << endl; tbox::pout << "simulation time is " << loop_time << endl; const int finest_hier_level = patch_hierarchy->getFinestLevelNumber(); string file_name; char temp_buf[128]; /* * Write Lagrangian data. */ tbox::Pointer<LData> X_data = l_data_manager->getLData("X", finest_hier_level); Vec X_petsc_vec = X_data->getVec(); Vec X_lag_vec; VecDuplicate(X_petsc_vec, &X_lag_vec); l_data_manager->scatterPETScToLagrangian(X_petsc_vec, X_lag_vec, finest_hier_level); file_name = data_dump_dirname + "/" + "X."; sprintf(temp_buf, "%05d", iteration_num); file_name += temp_buf; for (int rank = 0; rank < tbox::SAMRAI_MPI::getNodes(); ++rank) { if (tbox::SAMRAI_MPI::getRank() == rank) { ofstream str(file_name.c_str(), rank == 0 ? ios_base::trunc : ios_base::app); if (rank == 0) { str << X_data->getGlobalNodeCount() << "\n"; } int size; VecGetLocalSize(X_lag_vec, &size); if (size > 0) { str.precision(12); str.setf(ios::scientific); str.setf(ios::showpos); double* X_lag_arr; VecGetArray(X_lag_vec, &X_lag_arr); const int depth = NDIM; for (int k = 0; k < size/depth; ++k) { for (int d = 0; d < depth; ++d) { str << X_lag_arr[depth*k+d]; if (d < depth-1) { str << " "; } else { str << "\n"; } } } VecRestoreArray(X_lag_vec, &X_lag_arr); } } tbox::SAMRAI_MPI::barrier(); } VecDestroy(X_lag_vec); tbox::Pointer<LData> D_data = l_data_manager->getLData("D", finest_hier_level); Vec D_petsc_vec = D_data->getVec(); Vec D_lag_vec; VecDuplicate(D_petsc_vec, &D_lag_vec); l_data_manager->scatterPETScToLagrangian(D_petsc_vec, D_lag_vec, finest_hier_level); file_name = data_dump_dirname + "/" + "D."; sprintf(temp_buf, "%05d", iteration_num); file_name += temp_buf; for (int rank = 0; rank < tbox::SAMRAI_MPI::getNodes(); ++rank) { if (tbox::SAMRAI_MPI::getRank() == rank) { ofstream str(file_name.c_str(), rank == 0 ? ios_base::trunc : ios_base::app); if (rank == 0) { str << D_data->getGlobalNodeCount() << "\n"; } int size; VecGetLocalSize(D_lag_vec, &size); if (size > 0) { str.precision(12); str.setf(ios::scientific); str.setf(ios::showpos); double* D_lag_arr; VecGetArray(D_lag_vec, &D_lag_arr); const int depth = 3; for (int k = 0; k < size/depth; ++k) { for (int d = 0; d < depth; ++d) { str << D_lag_arr[depth*k+d]; if (d < depth-1) { str << " "; } else { str << "\n"; } } } VecRestoreArray(D_lag_vec, &D_lag_arr); } } tbox::SAMRAI_MPI::barrier(); } VecDestroy(D_lag_vec); return; }// output_data
void update_target_point_positions( tbox::Pointer<hier::PatchHierarchy<NDIM> > hierarchy, LDataManager* const l_data_manager, const double current_time, const double dt) { const int finest_ln = hierarchy->getFinestLevelNumber(); static const double pi = 4*atan(1); static const double V = 0.2; //velocity of the wing during translation (meters/sec) //////////////////////////////////////////////////////////////////////////////////////// // these parameters require modification to match the desired geometry and motion static const double L1 = 1; // length of computational domain (meters) static const int N1 = 512; // number of cartesian grid meshwidths at the finest level of the AMR grid static const double diameter = 0.1; // diameter of tube static const double R2 = 0.1; // distance from middle of domain to inner wall static const double R1 = R2+diameter; // distance from middle of domain to outer wall static const double pamp = 0.8; //percent occlusion of the tube static const double amp = pamp*diameter/2.0; //amplitude of contraction of each piece of the actuator static const double freq = 1.0; //////////////////////////////////////////////////////////////////////////////////////////////// // Find out the Lagrangian index ranges. const std::pair<int,int>& actuator_top_idxs = l_data_manager->getLagrangianStructureIndexRange(0, finest_ln); const std::pair<int,int>& actuator_bot_idxs = l_data_manager->getLagrangianStructureIndexRange(1, finest_ln); // Get the LMesh (which we assume to be associated with the finest level of // the patch hierarchy). Note that we currently need to update both "local" // and "ghost" node data. Pointer<LMesh> mesh = l_data_manager->getLMesh(finest_ln); vector<LNode*> nodes; nodes.insert(nodes.end(), mesh->getLocalNodes().begin(), mesh->getLocalNodes().end()); nodes.insert(nodes.end(), mesh->getGhostNodes().begin(), mesh->getGhostNodes().end()); // Update the target point positions in their associated target point force // specs. tbox::Pointer<hier::PatchLevel<NDIM> > level = hierarchy->getPatchLevel(finest_ln); for (vector<LNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it) { LNode* node_idx = *it; IBTargetPointForceSpec* force_spec = node_idx->getNodeDataItem<IBTargetPointForceSpec>(); if (force_spec == NULL) continue; // skip to next node // Here we update the position of the target point. // // NOTES: lag_idx is the "index" of the Lagrangian point (lag_idx = 0, 1, ..., N-1, where N is the number of Lagrangian points) // X_target is the target position of the target point // X_target[0] is the x component of the target position // X_target[1] is the y component of the target position // X_target[2] is the z component of the target position (for a 3D simulation) // // The target position is shifted to the left or right by the // increment dt*V const int lag_idx = node_idx->getLagrangianIndex(); //Depending on the version of IBAMR, you need to select one of the ways of accessing target point positions. //TinyVector<double,NDIM>& X_target = force_spec->getTargetPointPosition(); //IBTK::Vector<double,NDIM>& X_target = force_spec->getTargetPointPosition(); Point& X_target = force_spec->getTargetPointPosition(); //move the top piece if (actuator_top_idxs.first <= lag_idx && lag_idx < actuator_top_idxs.second) { X_target[1] = -R2-V*dt; //(amp/2)*(1+sin(2*pi*freq*current_time - pi/2)); } //move the bottom piece if (actuator_bot_idxs.first <= lag_idx && lag_idx < actuator_bot_idxs.second) { X_target[1] = -R1+V*dt; //(amp/2)*(1+sin(2*pi*freq*current_time - pi/2)); } } return; }// update_target_point_positions