• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

MinimumSurface.cc

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
00005 //*****************************************************************//
00006 
00007 // Define only if ALbany is enabled
00008 #if defined (ALBANY_LCM)
00009 
00010 #include <stk_mesh/base/FieldData.hpp>
00011 #include "Topology.h"
00012 #define _USE_MATH_DEFINES
00013 #include <math.h>
00014 #include <iostream>
00015 #include <fstream>
00016 #include <utility>
00017 #include <vector>
00018 #include <cmath>
00019 #include <string>
00020 #include <sstream>
00021 
00022 #include <boost/config.hpp>
00023 #include <boost/graph/graph_traits.hpp>
00024 #include <boost/graph/dijkstra_shortest_paths.hpp>
00025 #include <boost/graph/adjacency_list.hpp>
00026 #include <boost/lexical_cast.hpp>
00027 #include <boost/numeric/conversion/cast.hpp>
00028 #include <boost/graph/iteration_macros.hpp>
00029 #include <boost/graph/properties.hpp>
00030 #include <boost/property_map/property_map.hpp>
00031 //typedef std::pair<int, int> Edge;
00032 
00033 namespace LCM {
00034 
00035 //---------------------------------------------------------------------------------------------------
00036 //
00037 // \brief Finds the closest nodes(Entities of rank 0) to each of the three points in the input vector
00038 //
00039 std::vector<Entity*> Topology::getClosestNodes(std::vector<std::vector<double> > points)
00040 {
00041   std::vector<Entity*> closestNodes;
00042   Entity* nodeA;
00043   Entity* nodeB;
00044   Entity* nodeC;
00045   std::vector<double> pointA, pointB, pointC;
00046   double minDA, minDB, minDC;
00047 
00048   std::vector<Entity*> entities_D0 = getEntitiesByRank(*(getBulkData()), 0);//get all the nodes
00049   std::vector<Entity*>::const_iterator i_entities_d0;//iterator for the nodes
00050 
00051   //Before iterate, it is necessary to have a distance with which it is possible to compare the new distances to.
00052   nodeA = entities_D0[0];
00053   minDA = getDistanceNodeAndPoint(entities_D0[0], points[0]);
00054 
00055   nodeB = entities_D0[0];
00056   minDB = getDistanceNodeAndPoint(entities_D0[0], points[1]);
00057 
00058   nodeC = entities_D0[0];
00059   minDC = getDistanceNodeAndPoint(entities_D0[0], points[2]);
00060 
00061   //For each of the nodes
00062   //calculate distance from point1, point 2, point 3
00063   //if any distance is less than the min distance to that point
00064   //update the min distance and the closest node for that point
00065   for (i_entities_d0 = entities_D0.begin();i_entities_d0 != entities_D0.end(); ++i_entities_d0)
00066   {
00067     //adist is the distance between the current node and the first point, point A.
00068     double aDist = getDistanceNodeAndPoint(*i_entities_d0, points[0]);
00069     if (aDist<minDA)
00070     {
00071       nodeA = *i_entities_d0;
00072       minDA = aDist;
00073     }
00074 
00075     double bDist = getDistanceNodeAndPoint(*i_entities_d0, points[1]);
00076     if (bDist<minDB)
00077     {
00078       nodeB = *i_entities_d0;
00079       minDB = bDist;
00080     }
00081 
00082     double cDist = getDistanceNodeAndPoint(*i_entities_d0, points[2]);
00083     if (cDist<minDC)
00084     {
00085       nodeC = *i_entities_d0;
00086       minDC = cDist;
00087     }
00088   }
00089   closestNodes.push_back(nodeA);
00090   closestNodes.push_back(nodeB);
00091   closestNodes.push_back(nodeC);
00092   return closestNodes;
00093 }
00094 
00095 //---------------------------------------------------------------------------------------------------
00096 //
00097 // \brief Finds the closest nodes(Entities of rank 0) to each
00098 //        of the three points in the input vectorThese nodes
00099 //        lie over the surface of the mesh
00100 //
00101 std::vector<Entity*> Topology::getClosestNodesOnSurface(std::vector<std::vector<double> > points)
00102 {
00103 
00104   //Obtain all the nodes that lie over the surface
00105   //Obtain all the faces of the mesh
00106   std::vector<Entity*> MeshFaces = getEntitiesByRank(*(getBulkData()), 2);
00107 
00108   //Find the faces (Entities of rank 2) that build the boundary of the given mesh
00109   std::vector<Entity*> BoundaryFaces;
00110   std::vector<Entity*>::const_iterator I_faces;
00111   for (I_faces = MeshFaces.begin(); I_faces != MeshFaces.end(); I_faces++)
00112   {
00113     std::vector<Entity*> temp;
00114     temp = getDirectlyConnectedEntities(*(*I_faces), 3);
00115     //If the number of boundary entities of rank 3 is 1
00116     //then, this is a boundary face
00117     if (temp.size() == 1)
00118     {
00119       BoundaryFaces.push_back(*I_faces);
00120     }
00121   }
00122 
00123   //Obtain the Edges that belong to the Boundary Faces
00124   //delete the repeated edges
00125   std::vector<Entity*> MeshEdges;
00126   std::vector<Entity*>::const_iterator I_BoundaryFaces;
00127   std::vector<Entity*>::const_iterator I_Edges;
00128   for (I_BoundaryFaces = BoundaryFaces.begin(); I_BoundaryFaces !=BoundaryFaces.end(); I_BoundaryFaces++)
00129   {
00130     std::vector<Entity*> boundaryEdges = getDirectlyConnectedEntities(*(*I_BoundaryFaces),1);
00131     for (I_Edges = boundaryEdges.begin();I_Edges != boundaryEdges.end(); I_Edges++)
00132     {
00133       if (findEntityInVector(MeshEdges,*I_Edges) == false)
00134       {
00135         MeshEdges.push_back(*I_Edges);
00136       }
00137     }
00138   }
00139 
00140   //Obtain the nodes that lie on the surface
00141   std::vector<Entity*> entities_D0;//This vector contains all the nodes that lie on the surface
00142   for (unsigned int i = 0; i < MeshEdges.size();++i)
00143   {
00144     std::vector<Entity*> EdgeBoundaryNodes;
00145     EdgeBoundaryNodes = getDirectlyConnectedEntities((*MeshEdges[i]),0);
00146     for(unsigned int i = 0; i < EdgeBoundaryNodes.size() ; i++){
00147       if (findEntityInVector(entities_D0,EdgeBoundaryNodes[i]) == false)
00148       {
00149         entities_D0.push_back(EdgeBoundaryNodes[i]);
00150       }
00151     }
00152   }
00153 
00154   std::vector<Entity*> closestNodes;
00155   Entity* nodeA;
00156   Entity* nodeB;
00157   Entity* nodeC;
00158   std::vector<double> pointA, pointB, pointC;
00159   double minDA, minDB, minDC;
00160 
00161   std::vector<Entity*>::const_iterator i_entities_d0;//iterator for the nodes
00162 
00163   //Before iterate, it is necessary to have a distance with which it is possible to compare the new distances to.
00164   nodeA = entities_D0[0];
00165   minDA = getDistanceNodeAndPoint(entities_D0[0], points[0]);
00166 
00167   nodeB = entities_D0[0];
00168   minDB = getDistanceNodeAndPoint(entities_D0[0], points[1]);
00169 
00170   nodeC = entities_D0[0];
00171   minDC = getDistanceNodeAndPoint(entities_D0[0], points[2]);
00172 
00173   //For each of the nodes
00174   //calculate distance from point1, point 2, point 3
00175   //if any distance is less than the min distance to that point
00176   //update the min distance and the closest node for that point
00177   for (i_entities_d0 = entities_D0.begin();i_entities_d0 != entities_D0.end(); ++i_entities_d0)
00178   {
00179     //adist is the distance between the current node and the first point, point A.
00180     double aDist = getDistanceNodeAndPoint(*i_entities_d0, points[0]);
00181     if (aDist<minDA)
00182     {
00183       nodeA = *i_entities_d0;
00184       minDA = aDist;
00185     }
00186 
00187     double bDist = getDistanceNodeAndPoint(*i_entities_d0, points[1]);
00188     if (bDist<minDB)
00189     {
00190       nodeB = *i_entities_d0;
00191       minDB = bDist;
00192     }
00193 
00194     double cDist = getDistanceNodeAndPoint(*i_entities_d0, points[2]);
00195     if (cDist<minDC)
00196     {
00197       nodeC = *i_entities_d0;
00198       minDC = cDist;
00199     }
00200   }
00201   closestNodes.push_back(nodeA);
00202   closestNodes.push_back(nodeB);
00203   closestNodes.push_back(nodeC);
00204 
00205   return closestNodes;
00206 }
00207 
00208 //----------------------------------------------------------------------------
00209 //
00210 // \brief calculates the distance between a node and a point
00211 //
00212 double Topology::getDistanceNodeAndPoint(Entity* node, std::vector<double> point)
00213 {
00214 
00215   //Declare x, y, and z coordinates of the node
00216   double * entity_coordinates_xyz = getPointerOfCoordinates(node);
00217   double x_Node = entity_coordinates_xyz[0];
00218   double y_Node = entity_coordinates_xyz[1];
00219   double z_Node = entity_coordinates_xyz[2];
00220 
00221   //Declare x,y,and z coordinates of the point
00222   double x_point = point[0];
00223   double y_point = point[1];
00224   double z_point = point[2];
00225 
00226   //Calculate the distance between point and node in the x, y, and z directions
00227   double x_dist = x_point - x_Node;
00228   double y_dist = y_point - y_Node;
00229   double z_dist = z_point - z_Node;
00230 
00231   //Compute the distance between the point and the node (Entity of rank 0)
00232   return sqrt(x_dist*x_dist + y_dist*y_dist + z_dist*z_dist);
00233 }
00234 
00235 
00236 //-------------------------------------------------------------------------------
00237 //
00238 // \brief Returns the coordinates of the points that form a equilateral triangle.
00239 //    This triangle lies on the plane that intersects the ellipsoid.
00240 //
00241 std::vector<std::vector<double> > Topology::getCoordinatesOfTriangle(const std::vector<double> normalToPlane)
00242 {
00243   //vectorA, vectorB, and vectorC are vectors of magnitude R (radius of the circle).
00244   //vectors B1, B2, and C1 are component unit vectors used to find B and C
00245   //xB1, xB, xA, yA, etc. are all eventually components of unit vectors.
00246 
00247 
00248   //Compute the coordinates of the resulting circle.
00249   //This circle results from the intersection of the plane and the ellipsoid
00250   std::vector<double> CoordOfMaxAndMin = getCoordinatesOfMaxAndMin();
00251   double maxX = CoordOfMaxAndMin[0];
00252   double minX = CoordOfMaxAndMin[1];
00253   double maxY = CoordOfMaxAndMin[2];
00254   double minY = CoordOfMaxAndMin[3];
00255   double maxZ = CoordOfMaxAndMin[4];
00256   double minZ = CoordOfMaxAndMin[5];
00257 
00258   //Find the center of the cube of nodes
00259   std::vector<double> coordOfCenter;
00260   double xCenter = (maxX + minX)/2.0;
00261   double yCenter = (maxY + minY)/2.0;
00262   double zCenter = (maxZ + minZ)/2.0;
00263   coordOfCenter.push_back(xCenter);
00264   coordOfCenter.push_back(yCenter);
00265   coordOfCenter.push_back(zCenter);
00266 
00267   //Radius of the circle
00268   double radius = maxX - coordOfCenter[0];
00269   std::vector<double> vectorN;
00270 
00271   //Find a perpendicular vector to the input one
00272 
00273   for (int i = 0; i<3; i++)
00274   {
00275     vectorN.push_back(normalToPlane[i] - coordOfCenter[i]);
00276   }
00277 
00278   std::vector<double> vectorA;
00279 
00280   //Throw exception if input vector is 0,0,0
00281   //CHANGE THIS EXCEPTION SINCE NORMAL CAN COINCIDE WITH COORDINATES
00282   //OF THE CENTER
00283   TEUCHOS_TEST_FOR_EXCEPTION( vectorN[0] == 0 && vectorN[1] == 0 && vectorN[0] == 0, std::logic_error,
00284                                "The input normal vector was 0,0,0 \n");
00285 
00286   double theta_rand = 2 * (3.14159) * randomNumber(0,1);
00287   double x;
00288   double y;
00289   double z;
00290   if (vectorN[2] != 0)
00291   {
00292     x = cos(theta_rand);
00293     y = sin(theta_rand);
00294     z = -(vectorN[0]*x  + vectorN[1]*y )/vectorN[2];
00295   }
00296   else if (vectorN[0] != 0)
00297   {
00298     z = cos(theta_rand);
00299     y = sin(theta_rand);
00300     x = -(vectorN[2]*z  + vectorN[1]*y )/vectorN[0];
00301   }
00302   else
00303   {
00304     x = cos(theta_rand);
00305     z = sin(theta_rand);
00306     y = -(vectorN[0]*x  + vectorN[2]*z )/vectorN[1];
00307   }
00308 
00309 
00310   double L = sqrt(x*x + y*y +z*z);
00311   double xA = x/L ;
00312   vectorA.push_back(xA*radius + xCenter);
00313   double yA = y/L ;
00314   vectorA.push_back(yA*radius + yCenter);
00315   double zA = z/L;
00316   vectorA.push_back(zA*radius +zCenter);
00317 
00318 
00319     //Find a particular unit vector perpendicular to the previous two (normalToPlane X vectorA)
00320   //declare the vector
00321   double xB1;
00322   double yB1;
00323   double zB1;
00324 
00325   //Compute the coordinates of the vector B1, which is a component of vectorB
00326   xB1 = (vectorN[1]*zA - vectorN[2]*yA);
00327   yB1 = (vectorN[2]*xA - vectorN[0]*zA);
00328   zB1 = (vectorN[0]*yA - vectorN[1]*xA);
00329 
00330   //Normalize vectorB1
00331   double magB1 = sqrt(xB1*xB1 + yB1*yB1 + zB1*zB1);
00332   xB1 = xB1/magB1;
00333   yB1 = yB1/magB1;
00334   zB1 = zB1/magB1;
00335 
00336   //Rotate vectorB1 30degrees
00337 
00338   //Find first component of rotated unit vectorB1 (120).
00339   double xB2;
00340   double yB2;
00341   double zB2;
00342 
00343   xB2 = - xA*tan(3.14159/6);
00344   yB2 = - yA*tan(3.14159/6);
00345   zB2 = - zA*tan(3.14159/6);
00346 
00347 
00348   //Add the two components of the 120 degree vectorB (vectorB1 and vectorB2)
00349   std::vector<double> vectorB;
00350   double xB;
00351   double yB;
00352   double zB;
00353 
00354   xB = xB1 + xB2;
00355   yB = yB1 + yB2;
00356   zB = zB1 + zB2;
00357 
00358   //Normalize vector B
00359   double magB = sqrt(xB*xB + yB*yB + zB*zB);
00360   xB = xB/magB;
00361   yB = yB/magB;
00362   zB = zB/magB;
00363 
00364   vectorB.push_back(xB*radius + xCenter);
00365   vectorB.push_back(yB*radius + yCenter);
00366   vectorB.push_back(zB*radius + zCenter);
00367 
00368 
00369   //Find the third vector, vectorC, 120 degrees from vectorA and vectorB;
00370   std::vector<double> vectorC;
00371   double xC;
00372   double yC;
00373   double zC;
00374 
00375   //The first component will be the negative of the first component for B
00376   double xC1 = -xB1;
00377   double yC1 = -yB1;
00378   double zC1 = -zB1;
00379 
00380   //The second component will be the same as the second component for B(xB2, yB2, zB2)
00381   //The components of C are just the sums of each of the components of its component vectors
00382   xC = xC1 + xB2;
00383   yC = yC1 + yB2;
00384   zC = zC1 + zB2;
00385 
00386   double magC = magB;
00387   xC = xC / magC;
00388   yC = yC / magC;
00389   zC = zC / magC;
00390 
00391   vectorC.push_back(xC*radius + xCenter);
00392   vectorC.push_back(yC*radius + yCenter);
00393   vectorC.push_back(zC*radius + zCenter);
00394 
00395 
00396 
00397   std::vector<std::vector<double> > VectorOfPoints;
00398   VectorOfPoints.push_back(vectorA);
00399   VectorOfPoints.push_back(vectorB);
00400   VectorOfPoints.push_back(vectorC);
00401 
00402   return VectorOfPoints;
00403 
00404 }
00405 
00406 //----------------------------------------------------------------------------
00407 //
00408 // \brief Return a random number between two given numbers
00409 //
00410 double Topology::randomNumber(double valMin, double valMax)
00411 {
00412     double value = (double)rand() / RAND_MAX;
00413     return valMin + value * (valMax - valMin);
00414 }
00415 
00416 //----------------------------------------------------------------------------
00417 //
00418 // \brief Returns the distance between two entities of rank 0 (nodes)
00419 //
00420 double Topology::getDistanceBetweenNodes(Entity * node1, Entity * node2)
00421 {
00422   //Declares the x,y,and z coordinates for the first node
00423   double * coordinate1 = getPointerOfCoordinates(node1);
00424   double x1 = coordinate1[0];
00425   double y1 = coordinate1[1];
00426   double z1 = coordinate1[2];
00427 
00428   //Declares the x,y,and z coordinates for the first node
00429   double * coordinate2 = getPointerOfCoordinates(node2);
00430   double x2 = coordinate2[0];
00431   double y2 = coordinate2[1];
00432   double z2 = coordinate2[2];
00433 
00434   //Computes the distance between the two nodes
00435   double distance = sqrt(pow((x1-x2),2.0) + pow((y1-y2),2.0) + pow((z1-z2),2.0));
00436   return distance;
00437 }
00438 
00439 //----------------------------------------------------------------------------
00440 //
00441 // \brief Returns the coordinates of the max and min of x y and z
00442 // in the order max of x, min of x, max of y, min of y, max of z, min of z
00443 //
00444 std::vector<double> Topology::getCoordinatesOfMaxAndMin()
00445 {
00446   std::vector<Entity*> entities_D0 = getEntitiesByRank(*(getBulkData()), 0);//get all the nodes
00447   std::vector<Entity*>::const_iterator i_entities_d0;//iterator for the nodes
00448 
00449   //Get the coordinates of the first node
00450   double * entity_coordinates_xyz = getPointerOfCoordinates(entities_D0[0]);
00451   double x_coordinate = entity_coordinates_xyz[0];
00452   double y_coordinate = entity_coordinates_xyz[1];
00453   double z_coordinate = entity_coordinates_xyz[2];
00454 
00455   //Declare all the variables for the max and min coordinates
00456   //and set them equal to the values of the first coordinates
00457   double maxX = x_coordinate;
00458   double minX = x_coordinate;
00459   double maxY = y_coordinate;
00460   double minY = y_coordinate;
00461   double maxZ = z_coordinate;
00462   double minZ = z_coordinate;
00463 
00464   //Declare the vector that has the coordinates of the center
00465   std::vector<double> coordOfMaxAndMin;
00466 
00467   //Iterate through every node
00468   for(i_entities_d0 = entities_D0.begin(); i_entities_d0 != entities_D0.end();++i_entities_d0)
00469   {
00470     //Get the coordinates of the ith node
00471     double * entity_coordinates_xyz = getPointerOfCoordinates(*i_entities_d0);
00472     double x_coordinate = entity_coordinates_xyz[0];
00473     double y_coordinate = entity_coordinates_xyz[1];
00474     double z_coordinate = entity_coordinates_xyz[2];
00475 
00476     //Compare the x,y, and z coordinates to the max and min for x y and z
00477     //if value is more extreme than max or min update max or min
00478     if (x_coordinate > maxX)
00479     {
00480       maxX = x_coordinate;
00481     }
00482     if (y_coordinate > maxY)
00483     {
00484       maxY = y_coordinate;
00485     }
00486     if (z_coordinate > maxZ)
00487     {
00488       maxZ = z_coordinate;
00489     }
00490 
00491     if (x_coordinate < minX)
00492     {
00493       minX = x_coordinate;
00494     }
00495     if (y_coordinate < minY)
00496     {
00497       minY = y_coordinate;
00498     }
00499     if (z_coordinate < minZ)
00500     {
00501       minZ = z_coordinate;
00502     }
00503   }
00504   coordOfMaxAndMin.push_back(maxX);
00505   coordOfMaxAndMin.push_back(minX);
00506   coordOfMaxAndMin.push_back(maxY);
00507   coordOfMaxAndMin.push_back(minY);
00508   coordOfMaxAndMin.push_back(maxZ);
00509   coordOfMaxAndMin.push_back(minZ);
00510   return coordOfMaxAndMin;
00511 }
00512 
00513 //--------------------------------------------------------------------------------------
00514 //
00515 // \brief Returns the edges necessary to compute the shortest path on the outer surface
00516 //        of the mesh
00517 //
00518 std::vector<Entity*> Topology::MeshEdgesShortestPath()
00519 {
00520 
00521   //Obtain all the faces of the mesh
00522   std::vector<Entity*> MeshFaces = getEntitiesByRank(*(getBulkData()), 2);
00523 
00524   //Find the faces (Entities of rank 2) that build the boundary of the given mesh
00525   std::vector<Entity*> BoundaryFaces;
00526   std::vector<Entity*>::const_iterator I_faces;
00527   for (I_faces = MeshFaces.begin(); I_faces != MeshFaces.end(); I_faces++)
00528   {
00529     std::vector<Entity*> temp;
00530     temp = getDirectlyConnectedEntities(*(*I_faces), 3);
00531     //If the number of boundary entities of rank 3 is 1
00532     //then, this is a boundary face
00533     if (temp.size() == 1)
00534     {
00535       BoundaryFaces.push_back(*I_faces);
00536     }
00537   }
00538 
00539   //Obtain the Edges that belong to the Boundary Faces
00540   //delete the repeated edges
00541   std::vector<Entity*> MeshEdges;
00542   std::vector<Entity*>::const_iterator I_BoundaryFaces;
00543   std::vector<Entity*>::const_iterator I_Edges;
00544   for (I_BoundaryFaces = BoundaryFaces.begin(); I_BoundaryFaces !=BoundaryFaces.end(); I_BoundaryFaces++)
00545   {
00546     std::vector<Entity*> boundaryEdges = getDirectlyConnectedEntities(*(*I_BoundaryFaces),1);
00547     for (I_Edges = boundaryEdges.begin();I_Edges != boundaryEdges.end(); I_Edges++)
00548     {
00549               if (findEntityInVector(MeshEdges,*I_Edges) == false)
00550               {
00551                 MeshEdges.push_back(*I_Edges);
00552               }
00553     }
00554   }
00555 
00556   return MeshEdges;
00557 }
00558 
00559 //---------------------------------------------------------------------------------
00560 //
00561 // \brief Returns the shortest path over the boundary faces given three input nodes
00562 //        and the edges that belong to the outer surface
00563 //
00564 std::vector<std::vector<int> > Topology::shortestpathOnBoundaryFaces(const std::vector<Entity*> & nodes,
00565                                                                  const std::vector<Entity*> & MeshEdgesShortestPath)
00566 {
00567   typedef float Weight;
00568   typedef boost::property<boost::edge_weight_t, Weight> WeightProperty;
00569   typedef boost::property<boost::vertex_name_t, std::string> NameProperty;
00570 
00571   typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS,
00572       NameProperty, WeightProperty > Graph;
00573 
00574   typedef boost::graph_traits < Graph >::vertex_descriptor Vertex;
00575 
00576   typedef boost::property_map < Graph, boost::vertex_index_t >::type IndexMap;
00577   typedef boost::property_map < Graph, boost::vertex_name_t >::type NameMap;
00578 
00579   typedef boost::iterator_property_map < Vertex*, IndexMap, Vertex, Vertex& > PredecessorMap;
00580   typedef boost::iterator_property_map < Weight*, IndexMap, Weight, Weight& > DistanceMap;
00581 
00582 
00583 
00584   //Define the input graph
00585   Graph g;
00586 
00587   //Add the edges weights to the graph
00588   for (unsigned int i = 0; i < MeshEdgesShortestPath.size();++i)
00589   {
00590     std::vector<Entity*> EdgeBoundaryNodes;
00591     EdgeBoundaryNodes = getDirectlyConnectedEntities((*MeshEdgesShortestPath[i]),0);
00592     Weight weight(getDistanceBetweenNodes(EdgeBoundaryNodes[0],EdgeBoundaryNodes[1]));
00593     boost::add_edge((EdgeBoundaryNodes[0]->identifier())-1,(EdgeBoundaryNodes[1]->identifier())-1,weight, g);
00594   }
00595 
00596   // Create predecessors and distances vectors
00597   std::vector<Vertex> predecessors(boost::num_vertices(g)); // Defined to save parents
00598   std::vector<Weight> distances(boost::num_vertices(g)); // Defined to save distances
00599 
00600   IndexMap indexMap = boost::get(boost::vertex_index, g);
00601   PredecessorMap predecessorMap(&predecessors[0], indexMap);
00602   DistanceMap distanceMap(&distances[0], indexMap);
00603 
00604 
00605   //----------------------------------------------------------------------------------------------------------------------------
00606     // NOTE: The dijkstra_shortest_paths function returns the nodes corresponding to the
00607   // shortest path starting from the end node to the start node
00608   //
00609   // Compute the  shortest path between nodes[0] and nodes[1]
00610   //----------------------------------------------------------------------------------------------------------------------------
00611 
00612   Vertex sourceVertex_0 = (nodes[1]->identifier())-1;//Source from where the distance and path are calculated
00613   Vertex goalVertex_0 = (nodes[0]->identifier())-1;
00614   boost::dijkstra_shortest_paths(g, sourceVertex_0, boost::distance_map(distanceMap).predecessor_map(predecessorMap));
00615 
00616   std::vector< boost::graph_traits< Graph >::vertex_descriptor > ShortestPath_0;
00617 
00618   boost::graph_traits< Graph >::vertex_descriptor currentVertex_0=goalVertex_0;
00619   while(currentVertex_0!=sourceVertex_0)
00620   {
00621     ShortestPath_0.push_back(currentVertex_0);
00622     currentVertex_0=predecessorMap[currentVertex_0];
00623   }
00624   //ShortestPath contains the shortest path between the given vertices.
00625   //Vertices are saved starting from end vertex to start vertex. The format of this output is "unsigned long int"
00626   ShortestPath_0.push_back(sourceVertex_0);
00627 
00628   //Change the format of the output from unsigned long int to int
00629   std::vector<int> FV_0;
00630   std::vector<unsigned long int>::const_iterator I_points0;
00631   for (I_points0 = ShortestPath_0.begin();I_points0 != ShortestPath_0.end();++I_points0){
00632     int i =boost::numeric_cast<int>(*I_points0);
00633     FV_0.push_back(i);
00634   }
00635   //Define the vector that holds the shortest path
00636   std::vector<std::vector<int> > ShortestPathFinal;
00637   ShortestPathFinal.push_back(FV_0);
00638 
00639 
00640 
00641   //----------------------------------------------------------------------------------------------------------------------------
00642   //Compute the  shortest path between nodes[1] and nodes[2]
00643   //----------------------------------------------------------------------------------------------------------------------------
00644   Vertex sourceVertex_1 = (nodes[2]->identifier())-1;//Source from where the distance and path are calculated
00645   Vertex goalVertex_1 = (nodes[1]->identifier())-1;
00646   boost::dijkstra_shortest_paths(g, sourceVertex_1, boost::distance_map(distanceMap).predecessor_map(predecessorMap));
00647 
00648   std::vector< boost::graph_traits< Graph >::vertex_descriptor > ShortestPath_1;
00649 
00650   boost::graph_traits< Graph >::vertex_descriptor currentVertex_1=goalVertex_1;
00651   while(currentVertex_1!=sourceVertex_1)
00652   {
00653     ShortestPath_1.push_back(currentVertex_1);
00654     currentVertex_1=predecessorMap[currentVertex_1];
00655   }
00656   //ShortestPath contains the shortest path between the given vertices.
00657   //Vertices are saved starting from end vertex to start vertex. The format of this output is "unsigned long int"
00658   ShortestPath_1.push_back(sourceVertex_1);
00659 
00660   //Change the format of the output from unsigned long int to int
00661   std::vector<int> FV_1;
00662   std::vector<unsigned long int>::const_iterator I_points1;
00663   for (I_points1 = ShortestPath_1.begin();I_points1 != ShortestPath_1.end();++I_points1){
00664     int i =boost::numeric_cast<int>(*I_points1);
00665     FV_1.push_back(i);
00666   }
00667   ShortestPathFinal.push_back(FV_1);
00668 
00669 
00670 
00671   //----------------------------------------------------------------------------------------------------------------------------
00672   //Compute the  shortest path between nodes[2] and nodes[0]
00673   //----------------------------------------------------------------------------------------------------------------------------
00674   Vertex sourceVertex_2 = (nodes[0]->identifier())-1;//Source from where the distance and path are calculated
00675   Vertex goalVertex_2 = (nodes[2]->identifier())-1;
00676   boost::dijkstra_shortest_paths(g, sourceVertex_2, boost::distance_map(distanceMap).predecessor_map(predecessorMap));
00677 
00678   std::vector< boost::graph_traits< Graph >::vertex_descriptor > ShortestPath_2;
00679 
00680   boost::graph_traits< Graph >::vertex_descriptor currentVertex_2=goalVertex_2;
00681   while(currentVertex_2!=sourceVertex_2)
00682   {
00683     ShortestPath_2.push_back(currentVertex_2);
00684     currentVertex_2=predecessorMap[currentVertex_2];
00685   }
00686   //ShortestPath contains the shortest path between the given vertices.
00687   //Vertices are saved starting from end vertex to start vertex. The format of this output is "unsigned long int"
00688   ShortestPath_2.push_back(sourceVertex_2);
00689 
00690   //Change the format of the output from unsigned long int to int
00691   std::vector<int> FV_2;
00692   std::vector<unsigned long int>::const_iterator I_points2;
00693   for (I_points2 = ShortestPath_2.begin();I_points2 != ShortestPath_2.end();++I_points2){
00694     int i =boost::numeric_cast<int>(*I_points2);
00695     FV_2.push_back(i);
00696   }
00697   ShortestPathFinal.push_back(FV_2);
00698 
00699   std::vector<std::vector<int> > ShortestPathOutput;
00700 
00701   for (int j = 0; j<3; j++)
00702     {
00703       for (unsigned int k = 0; k < (ShortestPathFinal[j].size()-1);k++)
00704       {
00705         std::vector<int> temp;
00706         temp.push_back((ShortestPathFinal[j][k])+1);
00707         temp.push_back((ShortestPathFinal[j][k+1])+1);
00708         ShortestPathOutput.push_back(temp);
00709       }
00710     }
00711   return ShortestPathOutput;
00712 }
00713 
00714 //----------------------------------------------------------------------------
00715 //
00716 // \brief Returns the shortest path between three input nodes
00717 //
00718 //
00719 std::vector<std::vector<int> > Topology::shortestpath(const std::vector<Entity*> & nodes)
00720 {
00721   typedef float Weight;
00722   typedef boost::property<boost::edge_weight_t, Weight> WeightProperty;
00723   typedef boost::property<boost::vertex_name_t, std::string> NameProperty;
00724 
00725   typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS,
00726       NameProperty, WeightProperty > Graph;
00727 
00728   typedef boost::graph_traits < Graph >::vertex_descriptor Vertex;
00729 
00730   typedef boost::property_map < Graph, boost::vertex_index_t >::type IndexMap;
00731   typedef boost::property_map < Graph, boost::vertex_name_t >::type NameMap;
00732 
00733   typedef boost::iterator_property_map < Vertex*, IndexMap, Vertex, Vertex& > PredecessorMap;
00734   typedef boost::iterator_property_map < Weight*, IndexMap, Weight, Weight& > DistanceMap;
00735 
00736 
00737 
00738   //Define the input graph
00739   Graph g;
00740 
00741   //Obtain all the faces of the mesh
00742   std::vector<Entity*> MeshFaces = getEntitiesByRank(*(getBulkData()), 2);
00743 
00744   //Find the faces (Entities of rank 2) that build the boundary of the given mesh
00745   std::vector<Entity*> BoundaryFaces;
00746   std::vector<Entity*>::const_iterator I_faces;
00747   for (I_faces = MeshFaces.begin(); I_faces != MeshFaces.end(); I_faces++)
00748   {
00749     std::vector<Entity*> temp;
00750     temp = getDirectlyConnectedEntities(*(*I_faces), 3);
00751     //If the number of boundary entities of rank 3 is 1
00752     //then, this is a boundary face
00753     if (temp.size() == 1)
00754     {
00755       BoundaryFaces.push_back(*I_faces);
00756     }
00757   }
00758 
00759   //Obtain the Edges that belong to the Boundary Faces
00760   //delete the repeated edges
00761   std::vector<Entity*> MeshEdges;
00762   std::vector<Entity*>::const_iterator I_BoundaryFaces;
00763   std::vector<Entity*>::const_iterator I_Edges;
00764   for (I_BoundaryFaces = BoundaryFaces.begin(); I_BoundaryFaces !=BoundaryFaces.end(); I_BoundaryFaces++)
00765   {
00766     std::vector<Entity*> boundaryEdges = getDirectlyConnectedEntities(*(*I_BoundaryFaces),1);
00767     for (I_Edges = boundaryEdges.begin();I_Edges != boundaryEdges.end(); I_Edges++)
00768     {
00769               if (findEntityInVector(MeshEdges,*I_Edges) == false)
00770               {
00771                 MeshEdges.push_back(*I_Edges);
00772               }
00773     }
00774   }
00775 
00776   //Add the edges weights to the graph
00777   for (unsigned int i = 0; i < MeshEdges.size();++i)
00778   {
00779     std::vector<Entity*> EdgeBoundaryNodes;
00780     EdgeBoundaryNodes = getDirectlyConnectedEntities((*MeshEdges[i]),0);
00781     Weight weight(getDistanceBetweenNodes(EdgeBoundaryNodes[0],EdgeBoundaryNodes[1]));
00782     boost::add_edge((EdgeBoundaryNodes[0]->identifier())-1,(EdgeBoundaryNodes[1]->identifier())-1,weight, g);
00783   }
00784 
00785   // Create predecessors and distances vectors
00786   std::vector<Vertex> predecessors(boost::num_vertices(g)); // Defined to save parents
00787   std::vector<Weight> distances(boost::num_vertices(g)); // Defined to save distances
00788 
00789   IndexMap indexMap = boost::get(boost::vertex_index, g);
00790   PredecessorMap predecessorMap(&predecessors[0], indexMap);
00791   DistanceMap distanceMap(&distances[0], indexMap);
00792 
00793 
00794   //----------------------------------------------------------------------------------------------------------------------------
00795     // NOTE: The dijkstra_shortest_paths function returns the nodes corresponding to the
00796   // shortest path starting from the end node to the start node
00797   //
00798   // Compute the  shortest path between nodes[0] and nodes[1]
00799   //----------------------------------------------------------------------------------------------------------------------------
00800 
00801   Vertex sourceVertex_0 = (nodes[1]->identifier())-1;//Source from where the distance and path are calculated
00802   Vertex goalVertex_0 = (nodes[0]->identifier())-1;
00803   boost::dijkstra_shortest_paths(g, sourceVertex_0, boost::distance_map(distanceMap).predecessor_map(predecessorMap));
00804 
00805   std::vector< boost::graph_traits< Graph >::vertex_descriptor > ShortestPath_0;
00806 
00807   boost::graph_traits< Graph >::vertex_descriptor currentVertex_0=goalVertex_0;
00808   while(currentVertex_0!=sourceVertex_0)
00809   {
00810     ShortestPath_0.push_back(currentVertex_0);
00811     currentVertex_0=predecessorMap[currentVertex_0];
00812   }
00813   //ShortestPath contains the shortest path between the given vertices.
00814   //Vertices are saved starting from end vertex to start vertex. The format of this output is "unsigned long int"
00815   ShortestPath_0.push_back(sourceVertex_0);
00816 
00817   //Change the format of the output from unsigned long int to int
00818   std::vector<int> FV_0;
00819   std::vector<unsigned long int>::const_iterator I_points0;
00820   for (I_points0 = ShortestPath_0.begin();I_points0 != ShortestPath_0.end();++I_points0){
00821     int i =boost::numeric_cast<int>(*I_points0);
00822     FV_0.push_back(i);
00823   }
00824   //Define the vector that holds the shortest path
00825   std::vector<std::vector<int> > ShortestPathFinal;
00826   ShortestPathFinal.push_back(FV_0);
00827 
00828 
00829 
00830   //----------------------------------------------------------------------------------------------------------------------------
00831   //Compute the  shortest path between nodes[1] and nodes[2]
00832   //----------------------------------------------------------------------------------------------------------------------------
00833   Vertex sourceVertex_1 = (nodes[2]->identifier())-1;//Source from where the distance and path are calculated
00834   Vertex goalVertex_1 = (nodes[1]->identifier())-1;
00835   boost::dijkstra_shortest_paths(g, sourceVertex_1, boost::distance_map(distanceMap).predecessor_map(predecessorMap));
00836 
00837   std::vector< boost::graph_traits< Graph >::vertex_descriptor > ShortestPath_1;
00838 
00839   boost::graph_traits< Graph >::vertex_descriptor currentVertex_1=goalVertex_1;
00840   while(currentVertex_1!=sourceVertex_1)
00841   {
00842     ShortestPath_1.push_back(currentVertex_1);
00843     currentVertex_1=predecessorMap[currentVertex_1];
00844   }
00845   //ShortestPath contains the shortest path between the given vertices.
00846   //Vertices are saved starting from end vertex to start vertex. The format of this output is "unsigned long int"
00847   ShortestPath_1.push_back(sourceVertex_1);
00848 
00849   //Change the format of the output from unsigned long int to int
00850   std::vector<int> FV_1;
00851   std::vector<unsigned long int>::const_iterator I_points1;
00852   for (I_points1 = ShortestPath_1.begin();I_points1 != ShortestPath_1.end();++I_points1){
00853     int i =boost::numeric_cast<int>(*I_points1);
00854     FV_1.push_back(i);
00855   }
00856   ShortestPathFinal.push_back(FV_1);
00857 
00858 
00859 
00860   //----------------------------------------------------------------------------------------------------------------------------
00861   //Compute the  shortest path between nodes[2] and nodes[0]
00862   //----------------------------------------------------------------------------------------------------------------------------
00863   Vertex sourceVertex_2 = (nodes[0]->identifier())-1;//Source from where the distance and path are calculated
00864   Vertex goalVertex_2 = (nodes[2]->identifier())-1;
00865   boost::dijkstra_shortest_paths(g, sourceVertex_2, boost::distance_map(distanceMap).predecessor_map(predecessorMap));
00866 
00867   std::vector< boost::graph_traits< Graph >::vertex_descriptor > ShortestPath_2;
00868 
00869   boost::graph_traits< Graph >::vertex_descriptor currentVertex_2=goalVertex_2;
00870   while(currentVertex_2!=sourceVertex_2)
00871   {
00872     ShortestPath_2.push_back(currentVertex_2);
00873     currentVertex_2=predecessorMap[currentVertex_2];
00874   }
00875   //ShortestPath contains the shortest path between the given vertices.
00876   //Vertices are saved starting from end vertex to start vertex. The format of this output is "unsigned long int"
00877   ShortestPath_2.push_back(sourceVertex_2);
00878 
00879   //Change the format of the output from unsigned long int to int
00880   std::vector<int> FV_2;
00881   std::vector<unsigned long int>::const_iterator I_points2;
00882   for (I_points2 = ShortestPath_2.begin();I_points2 != ShortestPath_2.end();++I_points2){
00883     int i =boost::numeric_cast<int>(*I_points2);
00884     FV_2.push_back(i);
00885   }
00886   ShortestPathFinal.push_back(FV_2);
00887 
00888   std::vector<std::vector<int> > ShortestPathOutput;
00889 
00890   for (int j = 0; j<3; j++)
00891     {
00892       for (unsigned int k = 0; k < (ShortestPathFinal[j].size()-1);k++)
00893       {
00894         std::vector<int> temp;
00895         temp.push_back((ShortestPathFinal[j][k])+1);
00896         temp.push_back((ShortestPathFinal[j][k+1])+1);
00897         ShortestPathOutput.push_back(temp);
00898       }
00899     }
00900   return ShortestPathOutput;
00901 }
00902 
00903 //----------------------------------------------------------------------------
00904 //
00905 // \brief Returns the directions of all the edges of the input mesh
00906 //
00907 std::vector<std::vector<int> > Topology::edgesDirections()
00908 {
00909     //Get all of the edges
00910     std::vector<Entity*> setOfEdges = getEntitiesByRank(*(getBulkData()),1);
00911 
00912     //Create a map that assigns new numbering to the Edges
00913     std::map <Entity*,int> edge_map; int counter = 0;
00914     std::vector<Entity*>::const_iterator I_setOfEdges;
00915     for(I_setOfEdges = setOfEdges.begin();I_setOfEdges != setOfEdges.end();++I_setOfEdges)
00916     {
00917       edge_map[*I_setOfEdges] = counter;
00918       counter++;
00919     }
00920 
00921     //edgesDirec will be the vector of vectors that is returned, it will be Nx2,
00922     //where N is the number of edges, and each edge has two nodes
00923     std::vector<std::vector<int> > edgesDirec(setOfEdges.size());
00924     std::map <Entity*,int>::const_iterator mapIter;
00925 
00926     //Iterate through the map, at each row of edgesDirec save the integers that identify
00927     //the directions of the edges
00928     for (mapIter = edge_map.begin(); mapIter != edge_map.end(); ++mapIter)
00929     {
00930       int index = mapIter->second;
00931       std::vector<Entity*> connectedNodes = getDirectlyConnectedEntities(*mapIter->first,0);
00932       std::vector<int> tempInt;
00933       tempInt.push_back(connectedNodes[0]->identifier());
00934       tempInt.push_back(connectedNodes[1]->identifier());
00935       edgesDirec[index] = tempInt;
00936     }
00937 
00938   return edgesDirec;
00939 }
00940 
00941 //----------------------------------------------------------------------------
00942 //
00943 // \brief Returns the directions of all the boundary edges of the input mesh
00944 //
00945 std::vector<std::vector<int> > Topology::edgesDirectionsOuterSurface()
00946 {
00947 
00948   //Obtain all the faces of the mesh
00949   std::vector<Entity*> MeshFaces = getEntitiesByRank(*(getBulkData()), 2);
00950 
00951   //Find the faces (Entities of rank 2) that build the boundary of the given mesh
00952   std::vector<Entity*> BoundaryFaces;
00953   std::vector<Entity*>::const_iterator I_faces;
00954   for (I_faces = MeshFaces.begin(); I_faces != MeshFaces.end(); I_faces++)
00955   {
00956     std::vector<Entity*> temp;
00957     temp = getDirectlyConnectedEntities(*(*I_faces), 3);
00958     //If the number of boundary entities of rank 3 is 1
00959     //then, this is a boundary face
00960     if (temp.size() == 1)
00961     {
00962       BoundaryFaces.push_back(*I_faces);
00963     }
00964   }
00965 
00966   //Obtain the Edges that belong to the Boundary Faces
00967   //delete the repeated edges
00968   std::vector<Entity*> setOfEdges;
00969   std::vector<Entity*>::const_iterator I_BoundaryFaces;
00970   std::vector<Entity*>::const_iterator I_Edges;
00971   for (I_BoundaryFaces = BoundaryFaces.begin(); I_BoundaryFaces !=BoundaryFaces.end(); I_BoundaryFaces++)
00972   {
00973     std::vector<Entity*> boundaryEdges = getDirectlyConnectedEntities(*(*I_BoundaryFaces),1);
00974     for (I_Edges = boundaryEdges.begin();I_Edges != boundaryEdges.end(); I_Edges++)
00975     {
00976       if (findEntityInVector(setOfEdges,*I_Edges) == false)
00977       {
00978         setOfEdges.push_back(*I_Edges);
00979       }
00980     }
00981   }
00982 
00983   //Create a map that assigns new numbering to the Edges
00984   std::map <Entity*,int> edge_map; int counter = 0;
00985   std::vector<Entity*>::const_iterator I_setOfEdges;
00986   for(I_setOfEdges = setOfEdges.begin();I_setOfEdges != setOfEdges.end();++I_setOfEdges)
00987   {
00988     edge_map[*I_setOfEdges] = counter;
00989     counter++;
00990   }
00991 
00992   //edgesDirec will be the vector of vectors that is returned, it will be Nx2,
00993   //where N is the number of edges, and each edge has two nodes
00994   std::vector<std::vector<int> > edgesDirec(setOfEdges.size());
00995   std::map <Entity*,int>::const_iterator mapIter;
00996 
00997   //Iterate through the map, at each row of edgesDirec save the integers that identify
00998   //the directions of the edges
00999   for (mapIter = edge_map.begin(); mapIter != edge_map.end(); ++mapIter)
01000   {
01001     int index = mapIter->second;
01002     std::vector<Entity*> connectedNodes = getDirectlyConnectedEntities(*mapIter->first,0);
01003     std::vector<int> tempInt;
01004     tempInt.push_back(connectedNodes[0]->identifier());
01005     tempInt.push_back(connectedNodes[1]->identifier());
01006     edgesDirec[index] = tempInt;
01007   }
01008 
01009   return edgesDirec;
01010 }
01011 
01012 
01013 //----------------------------------------------------------------------------
01014 //
01015 // \brief Returns the directions of all of the faces of the input mesh
01016 //
01017 std::vector<std::vector<int> > Topology::facesDirections()
01018 {
01019     //Get the faces
01020     std::vector<Entity*> setOfFaces = getEntitiesByRank(*(getBulkData()),2);
01021 
01022     //Make a new map, mapping the Entities of Rank 2(faces) to a counter
01023     std::map <Entity*,int> face_map;
01024     int counter = 0;
01025     std::vector<Entity*>::const_iterator I_setOfFaces;
01026     for(I_setOfFaces = setOfFaces.begin();I_setOfFaces != setOfFaces.end();++I_setOfFaces)
01027     {
01028       face_map[*I_setOfFaces] = counter;
01029       counter++;
01030     }
01031 
01032     //facesDirec will be the vector of vectors that is returned, it will be Nx4,
01033     //where N is the number of faces, and each face has three nodes with the first
01034     //node being repeated for a total of 4
01035     std::vector<std::vector<int> > facesDirec(setOfFaces.size());
01036 
01037 
01038     //Iterate through the map, at each row of facesDirec save the integers that
01039     //identify the directions of the face
01040     std::map <Entity*,int>::const_iterator mapIter;
01041     for (mapIter = face_map.begin(); mapIter != face_map.end(); ++mapIter)
01042     {
01043       int index = mapIter->second;
01044       std::vector<Entity*> edgeBoundaryNodes = getBoundaryEntities(*mapIter->first,0);
01045       std::vector<int> temp;
01046       temp.push_back(edgeBoundaryNodes[0]->identifier());
01047       temp.push_back(edgeBoundaryNodes[1]->identifier());
01048       temp.push_back(edgeBoundaryNodes[2]->identifier());
01049       temp.push_back(edgeBoundaryNodes[0]->identifier());
01050       facesDirec[index] = temp;
01051     }
01052 
01053   return facesDirec;
01054 
01055 }
01056 
01057 //----------------------------------------------------------------------------
01058 //
01059 // \brief Returns a vector with the areas of each of the faces of the input mesh
01060 //
01061 std::vector<double> Topology::facesAreas()
01062 {
01063   std::vector<Entity*> setOfFaces = getEntitiesByRank(*(getBulkData()),2);
01064 
01065   //Create the map
01066   std::map <Entity*,int> face_map;
01067   int counter = 0;
01068   std::vector<Entity*>::const_iterator I_setOfFaces;
01069   for(I_setOfFaces = setOfFaces.begin();I_setOfFaces != setOfFaces.end();++I_setOfFaces)
01070   {
01071     face_map[*I_setOfFaces] = counter;
01072     counter++;
01073   }
01074 
01075   //Initialize facesAreas as a vector of zeros
01076   std::vector<double> facesAreas;
01077   for(unsigned int i = 0;i<(setOfFaces.size());i++)
01078   {
01079     facesAreas.push_back(0);
01080   }
01081 
01082   //Iterate through the map
01083   std::map <Entity*,int>::const_iterator mapIter;
01084   for (mapIter = face_map.begin(); mapIter != face_map.end(); ++mapIter)
01085   {
01086     //Obtain the key from the map
01087     int index = mapIter->second;
01088 
01089     //Compute the area
01090     std::vector<Entity*> Nodes =  getBoundaryEntities(*mapIter->first,0);
01091     double a =  getDistanceBetweenNodes(Nodes[0], Nodes[1]);
01092     double b =  getDistanceBetweenNodes(Nodes[1], Nodes[2]);
01093     double c =  getDistanceBetweenNodes(Nodes[2], Nodes[0]);
01094     double p = (a+ b+ c)/2;
01095     double Area = sqrt(p*(p-a)*(p-b)*(p-c));
01096 
01097     //Put the area into the array the right index
01098     facesAreas[index] = Area;
01099   }
01100 
01101   return facesAreas;
01102 }
01103 
01104 //----------------------------------------------------------------------------
01105 //
01106 // \brief Returns the boundary operator of the input mesh.
01107 //        matrix that has nonzeros only
01108 //
01109 std::vector<std::vector<int> > Topology::boundaryOperator()
01110 {
01111   std::vector<std::vector<int> > edgesDirec =  edgesDirections();
01112   std::vector<std::vector<int> > facesDirec =  facesDirections();
01113   std::vector<Entity*> meshFaces =  getEntitiesByRank(*(getBulkData()), 2);
01114   std::vector< std::vector<int> > boundaryOp;
01115 
01116   //Iterate through every row of facesDirec
01117   for(unsigned int i = 0; i<facesDirec.size(); i++)
01118   {
01119     int mIndex = 2*i;
01120     std::vector<int> faceDir = facesDirec[i];
01121 
01122     //Iterate through the ith row of facesDir
01123     for(unsigned int j = 0; j< 3; j++)
01124     {
01125       //Iterate through the rows of edgesDirec to find the appropriate edge
01126       for(unsigned int k = 0; k<edgesDirec.size(); k++)
01127       {
01128         //If the edge is found in the correct direction
01129         if(facesDirec[i][j] == edgesDirec[k][0] && facesDirec[i][j+1] == edgesDirec[k][1])
01130         {
01131           std::vector<int> temp1; std::vector<int> temp2;
01132           temp1.push_back(k+1);temp1.push_back(mIndex+1);temp1.push_back(1); //original positions started from 1 for solver
01133           //temp1.push_back(k);temp1.push_back(mIndex);temp1.push_back(1);   //For testing
01134           boundaryOp.push_back(temp1);
01135           temp2.push_back(k+1);temp2.push_back(mIndex+2);temp2.push_back(-1);//original positions started from 1 for solver
01136           //temp2.push_back(k);temp2.push_back(mIndex+1);temp2.push_back(-1);//For testing
01137           boundaryOp.push_back(temp2);
01138 
01139         }
01140         //If the edge is found in the opposite direction
01141         else if ((facesDirec[i][j+1] == edgesDirec[k][0] && facesDirec[i][j] == edgesDirec[k][1]))
01142         {
01143             std::vector<int> temp3; std::vector<int> temp4;
01144           temp3.push_back(k+1);temp3.push_back(mIndex+1);temp3.push_back(-1);//original positions started from 1 for solver GLPK
01145             //temp3.push_back(k);temp3.push_back(mIndex);temp3.push_back(-1);//For testing
01146           boundaryOp.push_back(temp3);
01147           temp4.push_back(k+1);temp4.push_back(mIndex+2);temp4.push_back(1);//original positions started from 1 for solver
01148           //temp4.push_back(k);temp4.push_back(mIndex+1);temp4.push_back(1);//For testing
01149           boundaryOp.push_back(temp4);
01150         }
01151       }
01152     }
01153   }
01154 
01155   return boundaryOp;
01156 }
01157 
01158 //------------------------------------------------------------------------------------------------------
01159 //
01160 // \brief returns the boundary operator along with the faces areas
01161 //        to create the columns of an mps file
01162 //
01163 std::vector<std::vector<double> > Topology::outputForMpsFile()
01164 {
01165   //Obtain the areas of all the faces of the mesh
01166   std::vector<double> FacesAreas = facesAreas();
01167 
01168   //Define the boundary operator
01169   std::vector<std::vector<int> > edgesDirec =  edgesDirections();
01170   std::vector<std::vector<int> > facesDirec =  facesDirections();
01171   std::vector<Entity*> meshFaces =  getEntitiesByRank(*(getBulkData()), 2);
01172   std::vector< std::vector<double> > matrixForMpsFile;
01173 
01174   //Iterate through every row of facesDirec
01175   for(unsigned int i = 0; i<facesDirec.size(); i++)
01176   {
01177     int mIndex = 2*i;
01178     std::vector<int> faceDir = facesDirec[i];
01179 
01180     //Add the area of the face of analysis
01181         std::vector<double> temp;
01182         temp.push_back(FacesAreas[i]);
01183     matrixForMpsFile.push_back(temp);
01184 
01185     //Iterate through the ith row of facesDir
01186     for(unsigned int j = 0; j< 3; j++)
01187     {
01188       //Iterate through the rows of edgesDirec to find the appropriate edge
01189       for(unsigned int k = 0; k<edgesDirec.size(); k++)
01190       {
01191         //If the edge is found in the correct direction
01192         if(facesDirec[i][j] == edgesDirec[k][0] && facesDirec[i][j+1] == edgesDirec[k][1])
01193         {
01194           std::vector<double> temp1;
01195           //The column position is saved first and then the corresponding column
01196           //And finally the number
01197           temp1.push_back(mIndex+1);
01198           temp1.push_back(k+1);    //original positions started from 1 for solver
01199           temp1.push_back(1);
01200           temp1.push_back(mIndex+2);
01201                 temp1.push_back(k+1);    //original positions started from 1 for solver
01202                 temp1.push_back(-1);
01203           matrixForMpsFile.push_back(temp1);
01204         }
01205         //If the edge is found in the opposite direction
01206         else if ((facesDirec[i][j+1] == edgesDirec[k][0] && facesDirec[i][j] == edgesDirec[k][1]))
01207         {
01208             std::vector<double> temp2;
01209             temp2.push_back(mIndex+1);
01210             temp2.push_back(k+1);    //original positions started from 1 for solver GLPK
01211             temp2.push_back(-1);
01212             temp2.push_back(mIndex+2);
01213             temp2.push_back(k+1);    //original positions started from 1 for solver
01214           temp2.push_back(1);
01215           matrixForMpsFile.push_back(temp2);
01216         }
01217       }
01218     }
01219   }
01220 
01221   return matrixForMpsFile;
01222 }
01223 
01224 //--------------------------------------------------------------------------------------------------
01225 //
01226 // \brief Returns the 1-D boundary required to compute the minimum surface of the
01227 //        input mesh. The input to this function is a shortest path (composed by egdes)
01228 //        between three nodes
01229 //
01230 std::vector<std::vector<int> > Topology::boundaryVector(std::vector<std::vector<int> > & shortPath)
01231 {
01232   std::vector<std::vector<int> > edgesDirec = edgesDirections();
01233 
01234   //Define the Matrix that will hold the edges that build the 1D boundary
01235   //and their respective position
01236   std::vector<std::vector<int> > rVector;
01237 
01238   //Iterate through all the edges of edgesDirections
01239   for(unsigned int i = 0; i<edgesDirec.size(); i++)
01240   {
01241     //temp is the value that will go in the vector at the index i
01242     int temp = 0;
01243     //count is to ensure that a given edge is not in the shortest path more than once
01244     int count = 0;
01245 
01246     //Iterate through all the edges of the shortest path
01247     for(unsigned int j = 0; j<shortPath.size(); j++)
01248     {
01249       //Check if the edge from edges directions matches the ith edge from shortestpath
01250       if (edgesDirec[i][0] == shortPath[j][0] && edgesDirec[i][1] == shortPath[j][1])
01251       {
01252         temp=1;
01253         count ++;
01254       }
01255       //Check if the edge from edges directions matches the reverse of the ith edge from shortestpath
01256       else if (edgesDirec[i][1] == shortPath[j][0] && edgesDirec[i][0] == shortPath[j][1])
01257       {
01258         temp=-1;
01259         count++;
01260       }
01261     }
01262     //Handles the case in which an edge is in the shortest path more than once
01263     if(count <2 && temp !=0)
01264     {
01265       std::vector<int> temp1;
01266       temp1.push_back(i+1);//indexing starts from 1 as required by the Solver
01267       temp1.push_back(temp);
01268       rVector.push_back(temp1);
01269     }
01270   }
01271   return rVector;
01272 }
01273 
01274 //--------------------------------------------------------------------------------------------------
01275 //
01276 // \brief Returns the 1-D boundary required to compute the minimum surface of the input
01277 //        mesh boundary faces. The input to this function is a shortest path
01278 //        (composed by edges) between three nodes
01279 //
01280 std::vector<std::vector<int> > Topology::boundaryVectorOuterSurface(std::vector<std::vector<int> > & shortPath)
01281 {
01282 
01283   std::vector<std::vector<int> > edgesDirec = edgesDirectionsOuterSurface();
01284 
01285   //Define the Matrix that will hold the edges that build the 1D boundary
01286   //and their respective position
01287   std::vector<std::vector<int> > rVector;
01288 
01289   //Iterate through all the edges of edgesDirections
01290   for(unsigned int i = 0; i<edgesDirec.size(); i++)
01291   {
01292     //temp is the value that will go in the vector at the index i
01293     int temp = 0;
01294     //count is to ensure that a given edge is not in the shortest path more than once
01295     int count = 0;
01296 
01297     //Iterate through all the edges of the shortest path
01298     for(unsigned int j = 0; j<shortPath.size(); j++)
01299     {
01300       //Check if the edge from edges directions matches the ith edge from shortestpath
01301       if (edgesDirec[i][0] == shortPath[j][0] && edgesDirec[i][1] == shortPath[j][1])
01302       {
01303         temp=1;
01304         count ++;
01305       }
01306       //Check if the edge from edges directions matches the reverse of the ith edge from shortestpath
01307       else if (edgesDirec[i][1] == shortPath[j][0] && edgesDirec[i][0] == shortPath[j][1])
01308       {
01309         temp=-1;
01310         count++;
01311       }
01312     }
01313     //Handles the case in which an edge is in the shortest path more than once.
01314     if(count <2 && temp !=0)
01315     {
01316       std::vector<int> temp1;
01317       temp1.push_back(i+1);//indexing starts from 1 as required by the Solver
01318       temp1.push_back(temp);
01319       rVector.push_back(temp1);
01320     }
01321   }
01322   return rVector;
01323 }
01324 
01325 //--------------------------------------------------------------------------------------------------
01326 //
01327 // \brief Returns the corresponding entities of rank 2 that build the minimum surface.
01328 //        It takes as an input the resulting vector taken from the solution of the
01329 //        linear programming solver
01330 //
01331 std::vector<Entity*>
01332 Topology::MinimumSurfaceFaces(std::vector<int> VectorFromLPSolver)
01333 {
01334   //Obtain the faces
01335   std::vector<Entity*> setOfFaces = getEntitiesByRank(*(getBulkData()),2);
01336 
01337   //Define the map with the entities and their identifiers
01338   std::map <int,Entity*> face_map;
01339   int counter = 0;
01340   std::vector<Entity*>::const_iterator I_setOfFaces;
01341   for(I_setOfFaces = setOfFaces.begin();I_setOfFaces != setOfFaces.end();++I_setOfFaces)
01342   {
01343     face_map[counter] = *I_setOfFaces;
01344     counter++;
01345   }
01346 
01347   //Use the input vector to obtain the corresponding entities
01348   std::vector<Entity*> MinSurfaceEntities;
01349   int count = 0;
01350   for(unsigned int i = 0; i <VectorFromLPSolver.size(); i += 2)
01351   {
01352 
01353     if (VectorFromLPSolver[i]!=0)
01354     {
01355       MinSurfaceEntities.push_back(face_map.find(count)->second);
01356     }
01357     if(VectorFromLPSolver[i+1]!=0)
01358     {
01359       MinSurfaceEntities.push_back(face_map.find(count)->second);
01360     }
01361     count ++;
01362   }
01363 
01364   return MinSurfaceEntities;
01365 }
01366 
01367 //----------------------------------------------------------------------------
01368 // \brief Returns the number of times an entity is repeated in a vector
01369 //
01370 int
01371 Topology::NumberOfRepetitions(std::vector<Entity*> & entities, Entity * entity)
01372 {
01373   std::vector<Entity*>::iterator iterator_entities;
01374   int count = 0;
01375   for (iterator_entities = entities.begin(); iterator_entities != entities.end();++iterator_entities) {
01376     if (*iterator_entities == entity) {
01377      count++;
01378     }
01379   }
01380   return count;
01381 }
01382 
01383 //----------------------------------------------------------------------------
01384 //
01385 // \brief Returns the coordinates of an input node.
01386 //        The input is the identifier of a node
01387 //
01388 std::vector<double> Topology::findCoordinates(unsigned int nodeIdentifier){
01389 
01390   std::vector<Entity*> MeshNodes = getEntitiesByRank(
01391       *(getBulkData()), 0); //Get all the nodes of the mesh
01392   std::vector<Entity*>::const_iterator Ientities_D0;
01393 
01394   std::vector<double> coordinates_;
01395   for (Ientities_D0 = MeshNodes.begin();Ientities_D0 != MeshNodes.end();Ientities_D0++){
01396     if ((*Ientities_D0)->identifier() == nodeIdentifier){
01397 
01398       double * coordinate = getPointerOfCoordinates(*Ientities_D0);
01399       double x = coordinate[0];
01400       double y = coordinate[1];
01401       double z = coordinate[2];
01402 
01403       coordinates_.push_back(x);
01404       coordinates_.push_back(y);
01405       coordinates_.push_back(z);
01406 
01407       break;
01408     }
01409   }
01410 
01411   return coordinates_;
01412 }
01413 
01414 }//namespace LCM
01415 
01416 #endif // #if defined (ALBANY_LCM)
01417 

Generated on Wed Mar 26 2014 18:36:40 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1