node.C
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 00020 // C++ includes 00021 #include <sstream> 00022 00023 // Local includes 00024 #include "libmesh/node.h" 00025 00026 namespace libMesh 00027 { 00028 00029 00030 00031 00032 // ------------------------------------------------------------ 00033 // Node class static member initialization 00034 //const unsigned int Node::invalid_id = libMesh::invalid_uint; 00035 00036 00037 bool Node::operator==(const Node& rhs) const 00038 { 00039 // Explicitly calling the operator== defined in Point 00040 return this->Point::operator==(rhs); 00041 } 00042 00043 00044 00045 void Node::print_info (std::ostream& os) const 00046 { 00047 os << this->get_info() 00048 << std::endl; 00049 } 00050 00051 00052 00053 std::string Node::get_info () const 00054 { 00055 std::ostringstream oss; 00056 00057 oss << " Node id()="; 00058 00059 if (this->valid_id()) 00060 oss << this->id(); 00061 else 00062 oss << "invalid"; 00063 00064 oss << ", processor_id()=" << this->processor_id() << 00065 ", Point=" << *static_cast<const Point*>(this) << '\n'; 00066 00067 oss << " DoFs="; 00068 for (unsigned int s=0; s != this->n_systems(); ++s) 00069 for (unsigned int v=0; v != this->n_vars(s); ++v) 00070 for (unsigned int c=0; c != this->n_comp(s,v); ++c) 00071 oss << '(' << s << '/' << v << '/' << this->dof_number(s,v,c) << ") "; 00072 00073 return oss.str(); 00074 } 00075 00076 00077 00078 #ifdef LIBMESH_HAVE_MPI 00079 MPI_Datatype Node::PackedNode::create_mpi_datatype () 00080 { 00081 MPI_Datatype packed_node_type; 00082 MPI_Datatype types[] = { MPI_UNSIGNED, MPI_REAL }; 00083 int blocklengths[] = { 2, 3 }; 00084 MPI_Aint displs[2]; 00085 00086 // create a Packed node and get the addresses of the elements. 00087 // this will properly handle id/pid getting padded, for example, 00088 // in which case id and x may not be 2*sizeof(unsigned int) apart. 00089 Node::PackedNode pn; 00090 00091 MPI_Address (&pn.id, &displs[0]); 00092 MPI_Address (&pn.x, &displs[1]); 00093 displs[1] -= displs[0]; 00094 displs[0] = 0; 00095 00096 #if MPI_VERSION > 1 00097 MPI_Type_create_struct (2, blocklengths, displs, types, &packed_node_type); 00098 #else 00099 MPI_Type_struct (2, blocklengths, displs, types, &packed_node_type); 00100 #endif // #if MPI_VERSION > 1 00101 00102 return packed_node_type; 00103 } 00104 00105 00106 void Node::PackedNode::pack (std::vector<int> &conn, const Node* node) 00107 { 00108 libmesh_assert(node); 00109 00110 conn.reserve (conn.size() + node->packed_size()); 00111 00112 conn.push_back (static_cast<int>(node->processor_id())); 00113 conn.push_back (static_cast<int>(node->id())); 00114 00115 // use "(a+b-1)/b" trick to get a/b to round up 00116 static const unsigned int ints_per_Real = 00117 (sizeof(Real) + sizeof(int) - 1) / sizeof(int); 00118 00119 for (unsigned int i=0; i != LIBMESH_DIM; ++i) 00120 { 00121 const int* Real_as_ints = reinterpret_cast<const int*>(&((*node)(i))); 00122 for (unsigned int j=0; j != ints_per_Real; ++j) 00123 { 00124 conn.push_back(Real_as_ints[j]); 00125 } 00126 } 00127 00128 node->pack_indexing(std::back_inserter(conn)); 00129 } 00130 00131 00132 void Node::PackedNode::unpack (std::vector<int>::const_iterator start, Node& node) 00133 { 00134 unsigned int processor_id = static_cast<unsigned int>(*start++); 00135 libmesh_assert(processor_id == DofObject::invalid_processor_id || 00136 processor_id < libMesh::n_processors()); 00137 00138 unsigned int id = static_cast<unsigned int>(*start++); 00139 00140 // use "(a+b-1)/b" trick to get a/b to round up 00141 static const unsigned int ints_per_Real = 00142 (sizeof(Real) + sizeof(int) - 1) / sizeof(int); 00143 00144 std::vector<Real> xyz(3,0.); 00145 00146 for (unsigned int i=0; i != LIBMESH_DIM; ++i) 00147 { 00148 const Real* ints_as_Real = reinterpret_cast<const Real*>(&(*start)); 00149 node(i) = *ints_as_Real; 00150 start += ints_per_Real; 00151 } 00152 00153 node.set_id() = id; 00154 node.processor_id() = processor_id; 00155 00156 node.unpack_indexing(start); 00157 } 00158 00159 #endif // #ifdef LIBMESH_HAVE_MPI 00160 00161 } // namespace libMesh
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:48 UTC
Hosted By: