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

📄 parallel_mesh.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
📖 第 1 页 / 共 2 页
字号:
// $Id: parallel_mesh.C 2803 2008-04-23 21:14:29Z roystgnr $// 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// Local includes#include "boundary_info.h"#include "elem.h"#include "libmesh_logging.h"#include "mesh_communication.h"#include "parallel_mesh.h"#include "parallel.h"// ------------------------------------------------------------// ParallelMesh class member functionsParallelMesh::ParallelMesh (unsigned int d) :  UnstructuredMesh (d), _is_serial(true),  _n_nodes(0), _n_elem(0), _max_node_id(0), _max_elem_id(0),  _next_free_local_node_id(libMesh::processor_id()),  _next_free_local_elem_id(libMesh::processor_id()),  _next_free_unpartitioned_node_id(libMesh::n_processors()),  _next_free_unpartitioned_elem_id(libMesh::n_processors()){}ParallelMesh::~ParallelMesh (){  this->clear();  // Free nodes and elements}// This might be specialized later, but right now it's just here to// make sure the compiler doesn't give us a default (non-deep) copy// constructor instead.ParallelMesh::ParallelMesh (const ParallelMesh &other_mesh) :  UnstructuredMesh (other_mesh){  this->copy_nodes_and_elements(other_mesh);  _n_nodes = other_mesh.n_nodes();  _n_elem  = other_mesh.n_elem();  _max_node_id = other_mesh.max_node_id();  _max_elem_id = other_mesh.max_elem_id();}ParallelMesh::ParallelMesh (const UnstructuredMesh &other_mesh) :  UnstructuredMesh (other_mesh){  this->copy_nodes_and_elements(other_mesh);  _n_nodes = other_mesh.n_nodes();  _n_elem  = other_mesh.n_elem();  _max_node_id = other_mesh.max_node_id();  _max_elem_id = other_mesh.max_elem_id();}// We use cached values for these so they can be called// from one processor without bothering the rest, but// we may need to update those caches before doing a full// renumberingvoid ParallelMesh::update_parallel_id_counts(){  // This function must be run on all processors at once  parallel_only();  _n_elem = this->n_local_elem();  Parallel::sum(_n_elem);  _n_elem += this->n_unpartitioned_elem();  _max_elem_id = _elements.empty() ?    0 : _elements.rbegin()->first + 1;  Parallel::max(_max_elem_id);  _n_nodes = this->n_local_nodes();  Parallel::sum(_n_nodes);  _n_nodes += this->n_unpartitioned_nodes();  _max_node_id = _nodes.empty() ?    0 : _nodes.rbegin()->first + 1;  Parallel::max(_max_node_id);}// Or in debug mode we may want to test the uncached values without// changing the cacheunsigned int ParallelMesh::parallel_n_elem() const{  // This function must be run on all processors at once  parallel_only();  unsigned int n_local = this->n_local_elem();  Parallel::sum(n_local);  n_local += this->n_unpartitioned_elem();  return n_local;}unsigned int ParallelMesh::parallel_max_elem_id() const{  // This function must be run on all processors at once  parallel_only();  unsigned int max_local = _elements.empty() ?    0 : _elements.rbegin()->first + 1;  Parallel::max(max_local);  return max_local;}unsigned int ParallelMesh::parallel_n_nodes() const{  // This function must be run on all processors at once  parallel_only();  unsigned int n_local = this->n_local_nodes();  Parallel::sum(n_local);  n_local += this->n_unpartitioned_nodes();  return n_local;}unsigned int ParallelMesh::parallel_max_node_id() const{  // This function must be run on all processors at once  parallel_only();  unsigned int max_local = _nodes.empty() ?    0 : _nodes.rbegin()->first + 1;  Parallel::max(max_local);  return max_local;}const Point& ParallelMesh::point (const unsigned int i) const{  libmesh_assert (_nodes[i] != NULL);  libmesh_assert (_nodes[i]->id() == i);    return (*_nodes[i]);}const Node& ParallelMesh::node (const unsigned int i) const{  libmesh_assert (_nodes[i] != NULL);  libmesh_assert (_nodes[i]->id() == i);      return (*_nodes[i]);}Node& ParallelMesh::node (const unsigned int i){  libmesh_assert (_nodes[i] != NULL);  libmesh_assert (_nodes[i]->id() == i);    return (*_nodes[i]);}const Node* ParallelMesh::node_ptr (const unsigned int i) const{//  libmesh_assert (_nodes[i] != NULL);  libmesh_assert (_nodes[i] == NULL || _nodes[i]->id() == i);      return _nodes[i];}Node* & ParallelMesh::node_ptr (const unsigned int i){//  libmesh_assert (_nodes[i] != NULL);  libmesh_assert (_nodes[i] == NULL || _nodes[i]->id() == i);  return _nodes[i];}Elem* ParallelMesh::elem (const unsigned int i) const{//  libmesh_assert (_elements[i] != NULL);  libmesh_assert (_elements[i] == NULL || _elements[i]->id() == i);    return _elements[i];}Elem* ParallelMesh::add_elem (Elem *e){  // Don't try to add NULLs!  libmesh_assert(e);  const unsigned int elem_procid = e->processor_id();  if (!e->valid_id())    {      // Use the unpartitioned ids for unpartitioned elems,      // in serial, and temporarily for ghost elems      unsigned int *next_id = &_next_free_unpartitioned_elem_id;      if (elem_procid == libMesh::processor_id() &&          !this->is_serial())        next_id = &_next_free_local_elem_id;      e->set_id (*next_id);      *next_id += libMesh::n_processors() + 1;    }  else    {      if (_next_free_unpartitioned_elem_id <= e->id())        _next_free_unpartitioned_elem_id += libMesh::n_processors() + 1;      if (_next_free_local_elem_id <= e->id())        _next_free_local_elem_id += libMesh::n_processors() + 1;    }  // Don't try to overwrite existing elems  libmesh_assert (!_elements[e->id()]);  _elements[e->id()] = e;  // Make the cached elem data more accurate  _n_elem++;  _max_elem_id = std::max(_max_elem_id, e->id()+1);  // Unpartitioned elems should be added on every processor// And shouldn't be added in the same batch as ghost elems// But we might be just adding on processor 0 to// broadcast later#if 0#ifdef DEBUG  if (elem_procid == DofObject::invalid_processor_id)    {      unsigned int elem_id = e->id();      Parallel::max(elem_id);      libmesh_assert(elem_id == e->id());    }#endif#endif  return e;}Elem* ParallelMesh::insert_elem (Elem* e){  if (_elements[e->id()])    this->delete_elem(_elements[e->id()]);  _elements[e->id()] = e;  return e;}void ParallelMesh::delete_elem(Elem* e){  libmesh_assert (e);  // Delete the element from the BoundaryInfo object  this->boundary_info->remove(e);  // But not yet from the container; we might invalidate  // an iterator that way!  //_elements.erase(e->id());  // Instead, we set it to NULL for now  _elements[e->id()] = NULL;    // delete the element  delete e;}void ParallelMesh::renumber_elem(const unsigned int old_id,                                 const unsigned int new_id){  Elem *elem = _elements[old_id];  libmesh_assert (elem);  libmesh_assert (elem->id() == old_id);  elem->set_id(new_id);  libmesh_assert (!_elements[new_id]);  _elements[new_id] = elem;  _elements.erase(old_id);}Node* ParallelMesh::add_point (const Point& p,			       const unsigned int id,			       const unsigned int proc_id){    if (_nodes.count(id))    {      Node *n = _nodes[id];      libmesh_assert (n);      libmesh_assert (n->id() == id);            *n = p;      n->processor_id() = proc_id;      return n;    }  Node* n = Node::build(p, id).release();  n->processor_id() = proc_id;  return ParallelMesh::add_node(n);}Node* ParallelMesh::add_node (Node *n){  // Don't try to add NULLs!  libmesh_assert(n);  const unsigned int node_procid = n->processor_id();  if (!n->valid_id())    {      // Use the unpartitioned ids for unpartitioned nodes,      // in serial, and temporarily for ghost nodes      unsigned int *next_id = &_next_free_unpartitioned_node_id;      if (node_procid == libMesh::processor_id() &&          !this->is_serial())        next_id = &_next_free_local_node_id;      n->set_id (*next_id);      *next_id += libMesh::n_processors() + 1;    }  else    {      if (_next_free_unpartitioned_node_id <= n->id())        _next_free_unpartitioned_node_id += libMesh::n_processors() + 1;      if (_next_free_local_node_id <= n->id())        _next_free_local_node_id += libMesh::n_processors() + 1;    }  // Don't try to overwrite existing nodes  libmesh_assert (!_nodes[n->id()]);  _nodes[n->id()] = n;    // Make the cached elem data more accurate  _n_nodes++;  _max_node_id = std::max(_max_node_id, n->id()+1);  // Unpartitioned nodes should be added on every processor// And shouldn't be added in the same batch as ghost nodes// But we might be just adding on processor 0 to// broadcast later#if 0#ifdef DEBUG  if (node_procid == DofObject::invalid_processor_id)    {      unsigned int node_id = n->id();      Parallel::max(node_id);      libmesh_assert(node_id == n->id());    }#endif#endif  return n;}Node* ParallelMesh::insert_node (Node* n){  // If we already have this node we cannot  // simply delete it, because we may have elements  // which are attached to its address.  //  // Instead, call the Node = Point assignment operator  // to overwrite the spatial coordinates (but keep its  // address), delete the provided node, and return the  // address of the one we already had.  if (_nodes.count(n->id()))    {      Node *my_n = _nodes[n->id()];      *my_n = static_cast<Point>(*n);      delete n;      n = my_n;    }  else    _nodes[n->id()] = n;  return n;}void ParallelMesh::delete_node(Node* n){  libmesh_assert (n != NULL);  libmesh_assert (_nodes[n->id()] != NULL);  // Delete the node from the BoundaryInfo object  this->boundary_info->remove(n);  // And from the container  _nodes.erase(n->id());    // delete the node  delete n;}void ParallelMesh::renumber_node(const unsigned int old_id,                                 const unsigned int new_id){  Node *node = _nodes[old_id];  libmesh_assert (node);  libmesh_assert (node->id() == old_id);  node->set_id(new_id);  libmesh_assert (!_nodes[new_id]);  _nodes[new_id] = node;  _nodes.erase(old_id);}void ParallelMesh::clear (){  // Call parent clear function  MeshBase::clear();  

⌨️ 快捷键说明

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