00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <cassert>
00019 #include "lagrangemesh.h"
00020 #include "tetmesh/point.h"
00021 #include "tetmesh/edge.h"
00022
00023 LagrangeMesh::LagrangeMesh(mesh::TetMesh* mesh, int order, int sym_plane_config)
00024 : _mesh(mesh), _order(order) {
00025
00026 _pmesh = dynamic_cast<mesh::ParallelTetMesh*>(_mesh);
00027
00028
00029 assert(1 <= order && order <= 2);
00030
00031 _nof_orig_dofs.resize(order + 1);
00032 _nof_orig_dofs[1] = _mesh->get_nof_points();
00033 switch (order) {
00034 case 1:
00035 _nof_orig_dofs[0] = _nof_orig_dofs[1];
00036 break;
00037 case 2:
00038 _nof_orig_dofs[2] = _mesh->get_nof_edges();
00039 _nof_orig_dofs[0] = _nof_orig_dofs[1] + _nof_orig_dofs[2];
00040 break;
00041 }
00042
00043
00044
00045
00046 _num_global_dofs.resize(order + 1);
00047 _num_global_dofs[1] = _pmesh->get_num_global_points();
00048 switch (order) {
00049 case 1:
00050 _num_global_dofs[0] = _num_global_dofs[1];
00051 break;
00052 case 2:
00053 _num_global_dofs[2] = _pmesh->get_num_global_edges();
00054 _num_global_dofs[0] = _num_global_dofs[1] + _num_global_dofs[2];
00055 }
00056
00057 set_map(sym_plane_config);
00058 }
00059
00060 LagrangeMesh::~LagrangeMesh()
00061 { }
00062
00063 mesh::id_t LagrangeMesh::get_num_my_dofs(int order) const {
00064 return _nof_orig_dofs.at(order);
00065 }
00066
00067 mesh::id_t LagrangeMesh::get_num_global_mdofs(int order) const {
00068 return _nof_mapped_dofs.at(order);
00069 }
00070
00071 mesh::id_t LagrangeMesh::get_num_global_dofs(int order) const {
00072 return _num_global_dofs.at(order);
00073 }
00074
00075 void LagrangeMesh::set_map(unsigned int sym_plane_config) {
00076 rDebugAll("num_my_dofs in lagrange mesh = %d", get_num_my_dofs(0));
00077
00078
00079 std::vector<bool> elim(get_num_my_dofs(0));
00080 for (mesh::id_t i = 0; i < _mesh->get_nof_points(); i ++) {
00081 mesh::Point* point = _mesh->get_point(i);
00082 if (point->on_boundary()) {
00083 elim[i] = true;
00084 } else if ((sym_plane_config ^ 0x7) & point->on_symmetry_planes()) {
00085 elim[i] = true;
00086 } else {
00087 elim[i] = false;
00088 }
00089 }
00090
00091 if (_order > 1) {
00092 for (mesh::id_t i = 0; i < _mesh->get_nof_edges(); i ++) {
00093 mesh::Edge* edge = _mesh->get_edge(i);
00094 if (edge->on_boundary()) {
00095 elim[get_num_my_dofs(1) + i] = true;
00096 } else if ((sym_plane_config ^ 0x7) & edge->on_symmetry_planes()) {
00097 elim[get_num_my_dofs(1) + i] = true;
00098 } else {
00099 elim[get_num_my_dofs(1) + i] = false;
00100 }
00101 }
00102 }
00103
00104 _nof_mapped_dofs.resize(_order + 1);
00105
00106
00107
00108
00109 std::vector<mesh::id_t> eliminated_dofs;
00110 for (mesh::id_t ldof = 0; ldof < get_num_my_dofs(1); ++ ldof) {
00111 if(elim[ldof])
00112 eliminated_dofs.push_back(gdof(ldof));
00113 }
00114 parallel::compute_mgid_map(get_num_global_dofs(1), _pmesh->get_node_gids(), eliminated_dofs,
00115 &_nof_mapped_dofs[1], _mgid_map, _pmesh->get_comm());
00116
00117 if (_order == 1) {
00118 _nof_mapped_dofs[0] = _nof_mapped_dofs[1];
00119 } else {
00120
00121
00122
00123 rAssert(_order == 2);
00124 for (mesh::id_t ldof = get_num_my_dofs(1); ldof < get_num_my_dofs(0); ++ ldof) {
00125 if(elim[ldof])
00126 eliminated_dofs.push_back(gdof(ldof));
00127 }
00128 std::vector<mesh::id_t> all_my_gdofs;
00129 for (mesh::id_t ldof = 0; ldof < get_num_my_dofs(0); ++ ldof)
00130 all_my_gdofs.push_back(gdof(ldof));
00131 parallel::compute_mgid_map(get_num_global_dofs(0), all_my_gdofs, eliminated_dofs,
00132 &_nof_mapped_dofs[0], _mgid_map, _pmesh->get_comm());
00133 _nof_mapped_dofs[2] = _nof_mapped_dofs[0] - _nof_mapped_dofs[1];
00134 }
00135
00136 rDebugAll("lagrange: num_my_dofs=%d, num_my_eliminated_dofs=%d",
00137 get_num_my_dofs(0) , static_cast<int>(eliminated_dofs.size()));
00138 rDebugAll("lagrange mesh: #gdofs=%d, #mgdofs=%d", get_num_global_dofs(0), _nof_mapped_dofs[0]);
00139
00140
00141 #if 0
00142 for (std::map<id_t, id_t>::iterator it=_mgid_map.begin(); it != _mgid_map.end(); ++ it) {
00143 rDebugAll("lagrange mesh _mgid_map[%d] = %d", (*it).first, (*it).second);
00144 }
00145 rDebugAll("lagrange mesh num_global_mgids = %d", num_global_mgids);
00146 for (int i = 0; i < num_my_dofs; ++ i) {
00147 rDebugAll("lagrange mesh lid:%d, gid:%d, mgid:%d", i, _pmesh->point_gid(i), map_dof(i));
00148 }
00149 #endif
00150 }
00151
00152 mesh::id_t LagrangeMesh::gdof(mesh::id_t ldof) const {
00153 if (ldof < _mesh->get_nof_points())
00154 return _pmesh->point_gid(ldof);
00155 else
00156 return _pmesh->get_num_global_points() \
00157 + _pmesh->edge_gid(ldof - _mesh->get_nof_points());
00158 }
00159
00160 bool LagrangeMesh::is_owned_gdof(mesh::id_t gdof) const {
00161 rAssert(0 <= gdof && gdof < get_num_global_dofs(0));
00162
00163 if (gdof < get_num_global_dofs(1)) {
00164 return _pmesh->is_owned_point(gdof);
00165 } else {
00166 return _pmesh->is_owned_edge(gdof - get_num_global_dofs(1));
00167 }
00168 }
00169
00170 mesh::id_t LagrangeMesh::map_dof(mesh::id_t ldof) const {
00171 std::map<mesh::id_t, mesh::id_t>::const_iterator found = _mgid_map.find(gdof(ldof));
00172 if (found == _mgid_map.end())
00173 return mesh::ID_NONE;
00174 else
00175 return (*found).second;
00176 }