src/fem/femaxmesh.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           femaxmesh.cpp  -  description
00003                              -------------------
00004     begin                : Fri Dec 19 2003
00005     copyright            : (C) 2003 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 "Epetra_Map.h"
00019 #include "femaxmesh.h"
00020 
00021 
00022 FemaxMesh::FemaxMesh(mesh::TetMesh& mesh, int order, int sym_plane_config)
00023     : mesh_(mesh),
00024       order_(order),
00025       mesh_nedelec_(new NedelecMesh(&mesh, order, sym_plane_config)),
00026       mesh_lagrange_(new LagrangeMesh(&mesh, order, sym_plane_config))
00027 { 
00028     _pmesh = dynamic_cast<mesh::ParallelTetMesh*>(&mesh_);
00029 }
00030 
00031 FemaxMesh::~FemaxMesh() {
00032     delete mesh_nedelec_;
00033     delete mesh_lagrange_;
00034 }
00035 
00036 void FemaxMesh::constructY(Epetra_FECrsMatrix& Y, Epetra_Map& domain_map, Epetra_Map& range_map) {
00037     double one = 1.0;
00038     double minus_one = -1.0;
00039 
00040     // row and column offset for (2,2)-block
00041     int i_offset22 = mesh_nedelec_->get_num_global_mdofs(1);
00042     int j_offset22 = mesh_lagrange_->get_num_global_mdofs(1);
00043     
00044     mesh::TetMesh::edge_iterator iter = mesh_.edge_begin();
00045     mesh::TetMesh::edge_iterator iter_end = mesh_.edge_end();
00046 
00047     // loop over all edges
00048     for (; iter != iter_end; ++ iter) {
00049         int edge_id_mapped = mesh_nedelec_->map_dof((*iter).get_id());
00050         int node1_id_mapped = mesh_lagrange_->map_dof((*iter).get_start_id());
00051         int node2_id_mapped = mesh_lagrange_->map_dof((*iter).get_end_id());
00052 
00053         if (edge_id_mapped != -1) {
00054             // start node
00055             if (node1_id_mapped != -1) {
00056                 Y.InsertGlobalValues(1, &edge_id_mapped, 1, &node1_id_mapped, &minus_one);
00057             }
00058             // end node            
00059             if (node2_id_mapped != -1) {
00060                 Y.InsertGlobalValues(1, &edge_id_mapped, 1, &node2_id_mapped, &one);
00061             }
00062             
00063             // (2,2)-block: identity matrix
00064             if (order_ == 2) {
00065                 int row = i_offset22 + edge_id_mapped;
00066                 int col = j_offset22 + edge_id_mapped;
00067                 Y.InsertGlobalValues(1, &row, 1, &col, &one);
00068             }
00069         }
00070     }
00071 
00072     Y.GlobalAssemble(false);
00073     Y.FillComplete(domain_map, range_map);
00074     
00075     // Patch entries, which have been inserted multiple times
00076     for (int i_row = 0; i_row < Y.NumMyRows(); i_row++) {
00077         int num_entries;
00078         double* values;
00079         Y.ExtractMyRowView(i_row, num_entries, values);        
00080         for (int j_entry = 0; j_entry < num_entries; j_entry++) {
00081             // assert (values[j_entry] >= 1 || values[j_entry] <= -1);
00082             if (!(values[j_entry] >= 1 || values[j_entry] <= -1))
00083                 rWarningAll("Y[%d,%d] = %g", i_row, j_entry, values[j_entry]);
00084             if (values[j_entry] > 0.0)
00085                 values[j_entry] = 1.0;
00086             else if (values[j_entry] < 0.0)
00087                 values[j_entry] = -1.0;
00088         }
00089     }
00090     // cerr <<endl<<endl<< "!!!!! Y Matrix !!!!!!"<<endl<<Y;
00091 }
00092 
00093 void FemaxMesh::constructY_transp(Epetra_FECrsMatrix& Y_transp, Epetra_Map& domain_map, Epetra_Map& range_map) {
00094     double one = 1.0;
00095     double minus_one = -1.0;
00096 
00097     // row and column offset for (2,2)-block
00098     int i_offset22 = mesh_lagrange_->get_num_global_mdofs(1);
00099     int j_offset22 = mesh_nedelec_->get_num_global_mdofs(1);
00100 
00101     mesh::TetMesh::edge_iterator iter = mesh_.edge_begin();
00102     mesh::TetMesh::edge_iterator iter_end = mesh_.edge_end();
00103 
00104     // loop over all edges
00105     for (; iter != iter_end; ++ iter) {
00106         int edge_id_mapped = mesh_nedelec_->map_dof((*iter).get_id());
00107         int node1_id_mapped = mesh_lagrange_->map_dof((*iter).get_start_id());
00108         int node2_id_mapped = mesh_lagrange_->map_dof((*iter).get_end_id());
00109         
00110         if (edge_id_mapped != -1) {
00111             // start node
00112             if (node1_id_mapped != -1)
00113                 Y_transp.InsertGlobalValues(1, &node1_id_mapped, 1, &edge_id_mapped, &minus_one);
00114             // end node
00115             if (node2_id_mapped != -1)
00116                 Y_transp.InsertGlobalValues(1, &node2_id_mapped, 1, &edge_id_mapped, &one);
00117                 
00118             // (2,2)-block: identity matrix
00119             if (order_ == 2) {
00120                 int row = i_offset22 + edge_id_mapped;
00121                 int col = j_offset22 + edge_id_mapped;
00122                 Y_transp.InsertGlobalValues(1, &row, 1, &col, &one);
00123             }
00124         }
00125     }
00126 
00127     Y_transp.GlobalAssemble(false);
00128     Y_transp.FillComplete(domain_map, range_map);
00129     
00130     // Patch entries, which have been inserted multiple times
00131     for (int i_row = 0; i_row < Y_transp.NumMyRows(); i_row++) {
00132         int num_entries;
00133         double* values;
00134         Y_transp.ExtractMyRowView(i_row, num_entries, values);        
00135         for (int j_entry = 0; j_entry < num_entries; j_entry++) {
00136             // assert (values[j_entry] >= 1 || values[j_entry] <= -1);
00137             if (!(values[j_entry] >= 1 || values[j_entry] <= -1))
00138                 rWarningAll("Y'[%d,%d] = %g", i_row, j_entry, values[j_entry]);
00139             if (values[j_entry] > 0.0)
00140                 values[j_entry] = 1.0;
00141             else if (values[j_entry] < 0.0)
00142                 values[j_entry] = -1.0;
00143         }
00144     }
00145     // cerr <<endl<<endl<< "!!!!! Y_transp Matrix !!!!!!"<<endl<<Y_transp;
00146 }

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