⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parallel_ghost_sync.h

📁 一个用来实现偏微分方程中网格的计算库
💻 H
📖 第 1 页 / 共 2 页
字号:
// $Id: parallel_ghost_sync.h 2501 2007-11-20 02:33:29Z benkirk $// The libMesh Finite Element Library.// Copyright (C) 2002-2007  Benjamin S. Kirk, John W. Peterson  // This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.  // This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU// Lesser General Public License for more details.  // You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#ifndef __parallel_ghost_sync_h__#define __parallel_ghost_sync_h__// C++ Includes   -----------------------------------// Local Includes -----------------------------------#include "auto_ptr.h"#include "elem.h"#include "location_maps.h"#include "mesh_base.h"#include "parallel.h"//--------------------------------------------------------------------------namespace Parallel {  //------------------------------------------------------------------------  /**   * Request data about a range of ghost nodes uniquely identified by   * their xyz location or a range of active ghost elements uniquely   * identified by their centroids' xyz location.  Fulfill requests   * with   * sync.gather_data(const std::vector<unsigned int>& ids,    *                  std::vector<sync::datum>& data),   * by resizing and setting the values of the data vector.   * Respond to fulfillment with   * sync.act_on_data(const std::vector<unsigned int>& ids,   *                  std::vector<sync::datum>& data)   * The user must define Parallel::datatype<sync::datum> if   * sync::datum isn't a built-in type.   * The user-provided location_map will be used and left unchanged   * if it is provided, or filled and cleared if it is empty.   */  template <typename Iterator,            typename DofObjType,            typename SyncFunctor>  void sync_dofobject_data_by_xyz(const Iterator&          range_begin,                                  const Iterator&          range_end,                                  LocationMap<DofObjType>* location_map,                                  SyncFunctor&             sync);  //------------------------------------------------------------------------  /**   * Request data about a range of ghost dofobjects uniquely   * identified by their id.  Fulfill requests with   * sync.gather_data(const std::vector<unsigned int>& ids,    *                  std::vector<sync::datum>& data),   * by resizing and setting the values of the data vector.   * Respond to fulfillment with   * sync.act_on_data(const std::vector<unsigned int>& ids,   *                  std::vector<sync::datum>& data)   * The user must define Parallel::datatype<sync::datum> if   * sync::datum isn't a built-in type.   */  template <typename Iterator,            typename SyncFunctor>  void sync_dofobject_data_by_id(const Iterator& range_begin,                                 const Iterator& range_end,                                 SyncFunctor&    sync);  //------------------------------------------------------------------------  /**   * Request data about a range of ghost elements uniquely   * identified by their parent id and which child they are.   * Fulfill requests with   * sync.gather_data(const std::vector<unsigned int>& ids,    *                  std::vector<sync::datum>& data),   * by resizing and setting the values of the data vector.   * Respond to fulfillment with   * sync.act_on_data(const std::vector<unsigned int>& ids,   *                  std::vector<sync::datum>& data)   * The user must define Parallel::datatype<sync::datum> if   * sync::datum isn't a built-in type.   */  template <typename Iterator,            typename SyncFunctor>  void sync_element_data_by_parent_id(MeshBase&       mesh,                                      const Iterator& range_begin,                                      const Iterator& range_end,                                      SyncFunctor&    sync);  //------------------------------------------------------------------------  // Parallel memberstemplate <typename Iterator,          typename DofObjType,          typename SyncFunctor>void sync_dofobject_data_by_xyz(const Iterator&          range_begin,                                const Iterator&          range_end,                                LocationMap<DofObjType>& location_map,                                SyncFunctor&             sync){  // This function must be run on all processors at once  parallel_only();  // We need a valid location_map#ifdef DEBUG  bool need_map_update = (range_begin != range_end && location_map.empty());  Parallel::max(need_map_update);  libmesh_assert(!need_map_update);#endif  // Count the objectss to ask each processor about  std::vector<unsigned int>    ghost_objects_from_proc(libMesh::n_processors(), 0);  for (Iterator it = range_begin; it != range_end; ++it)    {      DofObjType *obj = *it;      libmesh_assert (obj);      unsigned int obj_procid = obj->processor_id();      libmesh_assert (obj_procid != DofObject::invalid_processor_id);      ghost_objects_from_proc[obj_procid]++;    }  // Request sets to send to each processor  std::vector<std::vector<Real> >    requested_objs_x(libMesh::n_processors()),    requested_objs_y(libMesh::n_processors()),    requested_objs_z(libMesh::n_processors());  // Corresponding ids to keep track of  std::vector<std::vector<unsigned int> >    requested_objs_id(libMesh::n_processors());  // We know how many objects live on each processor, so reserve()  // space for each.  for (unsigned int p=0; p != libMesh::n_processors(); ++p)    if (p != libMesh::processor_id())      {        requested_objs_x[p].reserve(ghost_objects_from_proc[p]);        requested_objs_y[p].reserve(ghost_objects_from_proc[p]);        requested_objs_z[p].reserve(ghost_objects_from_proc[p]);        requested_objs_id[p].reserve(ghost_objects_from_proc[p]);      }  for (Iterator it = range_begin; it != range_end; ++it)    {      DofObjType *obj = *it;      unsigned int obj_procid = obj->processor_id();      if (obj_procid == libMesh::processor_id())        continue;      Point p = location_map.point_of(*obj);      requested_objs_x[obj_procid].push_back(p(0));      requested_objs_y[obj_procid].push_back(p(1));      requested_objs_z[obj_procid].push_back(p(2));      requested_objs_id[obj_procid].push_back(obj->id());    }  // Trade requests with other processors  for (unsigned int p=1; p != libMesh::n_processors(); ++p)    {      // Trade my requests with processor procup and procdown      unsigned int procup = (libMesh::processor_id() + p) %                             libMesh::n_processors();      unsigned int procdown = (libMesh::n_processors() +                               libMesh::processor_id() - p) %                               libMesh::n_processors();      std::vector<Real> request_to_fill_x,                        request_to_fill_y,                        request_to_fill_z;      Parallel::send_receive(procup, requested_objs_x[procup],                             procdown, request_to_fill_x);      Parallel::send_receive(procup, requested_objs_y[procup],                             procdown, request_to_fill_y);      Parallel::send_receive(procup, requested_objs_z[procup],                             procdown, request_to_fill_z);      // Find the local id of each requested object      std::vector<unsigned int> request_to_fill_id(request_to_fill_x.size());      for (unsigned int i=0; i != request_to_fill_x.size(); ++i)        {          Point p(request_to_fill_x[i],                  request_to_fill_y[i],                  request_to_fill_z[i]);          // Look for this object in the multimap          DofObjType *obj = location_map.find(p);          // We'd better find every object we're asked for          libmesh_assert (obj);          // Return the object's correct processor id,          // and our (correct if it's local) id for it.          request_to_fill_id[i] = obj->id();        }      // Gather whatever data the user wants      std::vector<typename SyncFunctor::datum> data;      sync.gather_data(request_to_fill_id, data);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -