src/fem/lagrangemesh.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           lagrangemesh.cpp  -  description
00003                              -------------------
00004     begin                : Fri Feb 13 2004
00005     copyright            : (C) 2004 by Roman Geus
00006     email                : roman.geus@psi.ch
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
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     // Order should be equal to 1 or 2.    
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     // Global dofs
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     // Create global elimination array
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     // 1st order gdofs only
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         // Recompute mgids using all gdofs
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     // debug
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 }

Generated on Fri Oct 26 13:35:11 2007 for FEMAXX (Finite Element Maxwell Eigensolver) by  doxygen 1.4.7