src/LinearFieldInterpolation.cpp

Go to the documentation of this file.
00001 //
00002 // C++ Implementation: %{MODULE}
00003 //
00004 // Description:
00005 //
00006 //
00007 // Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR}
00008 //
00009 // Copyright: See COPYING file that comes with this distribution
00010 //
00011 //
00012 
00013 using namespace std;
00014 
00015 #include "myrlog.h"
00016 #include "LinearFieldInterpolation.h"
00017 
00018 
00019 
00020 namespace postprocess {
00021 
00022   //using namespace std;
00023 using namespace mesh;
00024 
00025 LinearFieldInterpolation::LinearFieldInterpolation(const NedelecMesh& nedelec_mesh, const colarray::Vector<double>& q)
00026     : nedelec_mesh_(nedelec_mesh)
00027 {
00028     TetMesh* mesh(nedelec_mesh_.getTetMesh());
00029     vector<int> node_count_(mesh->get_nof_points(), 0);
00030 
00031     // Initialise field values with zero vectors    
00032     node_values_.resize(mesh->get_nof_points(), Vector3(0.0, 0.0, 0.0));
00033      
00034     // Evaluate field at mesh points    
00035     for (TetMesh::tet_iterator it = mesh->tet_begin(); it != mesh->tet_end(); ++ it) {
00036         Tet& tet = *it;
00037         NedelecElement* elem = nedelec_mesh_.get_element(tet.get_id());
00038         
00039         // build vector of local DOFs
00040         const int* dof_ids = elem->get_dof_ids(mesh, &tet);
00041         colarray::Vector<double> dofs(elem->get_nof_dofs());
00042         for (int i = 0; i < elem->get_nof_dofs(); i ++) {
00043             int mapped_id = nedelec_mesh_.map_dof(dof_ids[i]);
00044             if (mapped_id == -1)
00045                 dofs(i) = 0.0;
00046             else
00047                 dofs(i) = q(mapped_id);
00048         }
00049 
00050         for (int i = 0; i < 4; ++ i) {
00051             mesh::id_t point_id = tet.get_corner_id(i);
00052             node_values_[point_id] += elem->eval(&tet, mesh->get_point(point_id)->get_coord(), dofs);
00053             node_count_[point_id] += 1;
00054         }
00055     }
00056     
00057     // Build average
00058     for (mesh::id_t i = 0; i < mesh->get_nof_points(); ++ i) {
00059         node_values_[i] /= node_count_[i];
00060     }
00061 }
00062 
00063 LinearFieldInterpolation::~LinearFieldInterpolation()
00064 {
00065 }
00066 
00067 mesh::Vector3 postprocess::LinearFieldInterpolation::eval(const mesh::Vector3& x)
00068 {
00069     // identify tetrahedr(on|a) containing x using octree data structure
00070     TetMesh* tet_mesh(nedelec_mesh_.getTetMesh());
00071     std::vector<mesh::Tet *> tets;
00072     tet_mesh->find_tets_by_point(x, tets);
00073     // warn if no x is not in mesh
00074     if (tets.size() == 0) {
00075         rError("eval: No tet found at location (%g,%g,%g).", x.x, x.y, x.z);
00076         return Vector3::ZERO;
00077     }
00078     // Choose first tet. The choice is not critical here, since the interpolated 
00079     // field is contignous
00080     mesh::Tet *tet(tets[0]);
00081     // Compute simplex coordinates in chosen Tet.
00082     Vector4 x_simplex;
00083     tet->cartesian_to_simplex(x, x_simplex);
00084     // Sum field contributions from all 4 corners: field = sum(node_values_[point_id[i]] * x_simplex[i], i==0..3)
00085     Vector3 field(Vector3::ZERO);
00086     for (int i = 0; i < 4; ++ i)
00087         field += node_values_[tet->get_corner_id(i)] * x_simplex[i];
00088     return field;
00089 }
00090 
00091 mesh::Vector3 postprocess::LinearFieldInterpolation::eval_curl(const mesh::Vector3& x)
00092 {
00094     rError("LinearFieldInterpolation::eval_curl not implemented.");
00095     return Vector3::ZERO;
00096 }
00097 
00098 } // namespace postprocess

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