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

MinSurfaceOutput.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 
00008 
00009 
00010 //#include "Topology.h"
00011 #include "topology/Topology.h"
00012 
00013 #include <iostream>
00014 #include <fstream>
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string>
00018 #include <sstream>
00019 typedef stk::mesh::Entity Entity;
00020 
00021 #include <boost/numeric/ublas/matrix.hpp>
00022 #include <boost/numeric/ublas/io.hpp>
00023 #include <boost/numeric/ublas/matrix_proxy.hpp>
00024 
00025 int main(int ac, char* av[]){
00026 
00027   std::string input_file;
00028   std::string results_file;
00029   typedef stk::mesh::Entity Entity;
00030   std::string output_file;// = "output.e";
00031 
00032   using namespace std;
00033 
00034   if (ac == 3){
00035     std::cout <<  "Generating the msh file with mesh " << av[1] << " and from text file: " << av[2] << std::endl;
00036     stringstream ss1;
00037     stringstream ss2;
00038     ss1 << av[1]; //insert the char
00039     ss1 >> input_file; //extract -convert char into string
00040     ss2 << av[2];
00041     ss2 >> results_file;
00042 
00043     //Check if third parameter from command line is a .txt file
00044     string s2 = ".txt";
00045     if (results_file.find(s2) == std::string::npos) {
00046       std::cout << "Missing extension .txt for the third input" << '\n';
00047       throw(0);
00048     }
00049   }
00050 
00051   else {
00052     std::cout << "Usage: MinsurfaceOutput Mesh.exo ResultsFile.txt" << std::endl; //USAGE OF THIS FILE FROM THE COMMAND LINE
00053     return 1;
00054   }
00055 
00056 
00057   //
00058   // Read the mesh
00059   //
00060   // Copied from Partition.cc
00061   Teuchos::GlobalMPISession mpiSession(&ac, &av);
00062   LCM::Topology topology(input_file, output_file);
00063 
00064   //------------------------------------------------------------------------------------------------------------------------------------
00065   //Obtain the results from the solver
00066   //BASED ON THE OUTPUT USING CLP LINEAR SOLVER (./clp mps_file -dualsimplex -solu outputFileName)
00067 
00068   using namespace std;
00069 
00070   //Obtain the number of columns of the boundary operator
00071   std::vector<std::vector<int> > facesDirec =  topology.facesDirections();
00072   cout << "The number of columns of the boundary operator is: " <<facesDirec.size()*2<<endl;
00073 
00074     //Read input from text file
00075   std::ifstream solSolver(results_file.c_str()); //Read the file that comes from the solver
00076   std::string line, dummyLine1, dummyLine2;
00077   std::vector<string> vectorStrings;
00078 
00079   //Read the first and second line from text file.
00080   std::getline(solSolver, dummyLine1);
00081   std::getline(solSolver, dummyLine2);
00082 
00083   //Define the vector that holds the results from linear solver
00084   std::vector<int> resutsFromSolver;
00085   int i;
00086 
00087   //Read from third line
00088   while (std::getline(solSolver, line))
00089   {
00090     std::string col1,col2;
00091     std::istringstream ss(line);
00092     ss >> col1 >> col2;
00093     std::string Finalstring = col2.substr(1,col2.length()); //Get the appropriate string from text file
00094     i = atoi(Finalstring.c_str()); //Convert string to integer
00095     resutsFromSolver.push_back(i); //Push back the numbers from text file to resutsFromSolver vector
00096   }
00097 
00098   //Record ones (1s) at the corresponding positions specified by the solver
00099   std::vector<int> resultsVector(facesDirec.size()*2,0); //Initialize vector with zeros
00100 
00101     for (unsigned int i = 0 ; i < resutsFromSolver.size(); i++)
00102     {
00103       resultsVector[resutsFromSolver[i]-1]=1;
00104     }
00105 
00106 
00107   //Call the function "MinimumSurfaceFaces" that returns the entities associated with the solution given by the solver
00108   std::vector<Entity*> EntitiesMinSurface = topology.MinimumSurfaceFaces(resultsVector);
00109 
00110 
00111     //Debug: return the number of repeated entities if there are any
00112   std::vector<Entity*> NumberRepeatedEntities;
00113   std::vector<Entity*>::const_iterator I_Entities;
00114   for (I_Entities = EntitiesMinSurface.begin();I_Entities != EntitiesMinSurface.end(); I_Entities++)
00115   {
00116         if (topology.NumberOfRepetitions(EntitiesMinSurface,*I_Entities) != 1)
00117     {
00118       cout <<"Warning repeated entities" <<*I_Entities <<endl;
00119     }
00120   }
00121 
00122   //Check that the 1s in the solver file match the required number of entities
00123   cout << "The number of faces that belong to the minimum surface are: " <<EntitiesMinSurface.size() << endl;
00124 
00125   //Create a matrix that contains the boundary nodes of each Entity
00126   //This is also the connectivity matrix
00127   std::vector<std::vector<int> > boundaryNodes_;
00128   std::vector<Entity*>::const_iterator I_entities;
00129   for (I_entities = EntitiesMinSurface.begin(); I_entities != EntitiesMinSurface.end(); I_entities++)
00130   {
00131     std::vector<Entity*> temp;
00132     //Obtain all the entities of rank 0
00133     temp = topology.getBoundaryEntities(*(*I_entities),0);
00134     std::vector<int> temp2; std::vector<Entity*>::const_iterator I_nodes;
00135     //Get the identifiers of the entities above
00136     for (I_nodes = temp.begin(); I_nodes != temp.end(); I_nodes++)
00137     {
00138       temp2.push_back((*I_nodes)->identifier());
00139     }
00140     boundaryNodes_.push_back(temp2); //Connectivity matrix
00141   }
00142 
00143   //Compute the total area of the faces that conform the minimum surface
00144   //Initialize MinSurfaceAreas as a vector of zeros
00145   std::vector<double> MinSurfaceAreas;
00146   for(unsigned int i = 0;i<(EntitiesMinSurface.size());i++)
00147   {
00148     MinSurfaceAreas.push_back(0);
00149   }
00150 
00151   //Iterate through the vector of Entities that build the minimum surface
00152   for (unsigned int i = 0;i<(EntitiesMinSurface.size());i++)
00153   {
00154     //Compute the area
00155     std::vector<Entity*> Nodes =  topology.getBoundaryEntities(*EntitiesMinSurface[i],0);
00156     double a =  topology.getDistanceBetweenNodes(Nodes[0], Nodes[1]);
00157     double b =  topology.getDistanceBetweenNodes(Nodes[1], Nodes[2]);
00158     double c =  topology.getDistanceBetweenNodes(Nodes[2], Nodes[0]);
00159     double p = (a+ b+ c)/2;
00160     double Area = sqrt(p*(p-a)*(p-b)*(p-c));
00161 
00162     //Put the area into the array the right index
00163     MinSurfaceAreas[i] = Area;
00164   }
00165 
00166   //Add up all the areas of the faces that represent the minimum surface
00167   std::vector<double>::const_iterator I_areas;
00168   double MinSurfaceArea = 0;
00169   for (I_areas = MinSurfaceAreas.begin(); I_areas!= MinSurfaceAreas.end();I_areas++)
00170   {
00171     MinSurfaceArea += *I_areas;
00172   }
00173 
00174   cout << endl;
00175   cout << "The area of the minimum surface computed is :" << MinSurfaceArea <<endl;
00176 
00177 
00178 
00179   //Create a set based on boundaryNodes. This is to avoid having
00180   //repeated node identifiers
00181   std::set<int> boundaryNodes; std::vector<std::vector<int> >::const_iterator I_rows;
00182   std::vector<int>::const_iterator I_cols;
00183   for (I_rows = boundaryNodes_.begin();I_rows != boundaryNodes_.end();I_rows++)
00184   {
00185     for (I_cols = I_rows->begin();I_cols != I_rows->end();I_cols++)
00186     {
00187       boundaryNodes.insert(*I_cols);//All nodes organized in ascending order. Starting from 1
00188     }
00189   }
00190 
00191   //Create the msh output file
00192   //Extract the input file name
00193   string txtFile = ".txt";//Define the string with the extension file of input mesh
00194   std::size_t Position = results_file.find(txtFile); //Find the position where .txt starts
00195   std::string file_name_1 = results_file.substr(0, Position); //sets part of the name of the output file
00196     std::string file_name_2 = "MinSurface_"+file_name_1+".msh";
00197 
00198 
00199   ofstream outputToVtk (file_name_2.c_str(),std::ofstream::out);
00200   if (outputToVtk.is_open())
00201   {
00202     int dimension = 3;
00203     int NumberNodesPerElement = 3;
00204 
00205     outputToVtk << dimension << " " << NumberNodesPerElement <<endl; //Dimension  NodesPerElement
00206     outputToVtk << boundaryNodes.size() << " " << boundaryNodes_.size()<<endl;//Nnodes  Nelements
00207 
00208     //Create a map that assigns new numbering to the nodes
00209     std::map <int,int> node_map; int counter = 0;
00210     std::set<int>::const_iterator I_setOfNodes;
00211 
00212     //Output a matrix with the coordinates of the nodes
00213     for(I_setOfNodes = boundaryNodes.begin();I_setOfNodes != boundaryNodes.end();++I_setOfNodes)
00214     {
00215       std::vector<double> nodeCoordinates = topology.findCoordinates(*I_setOfNodes);
00216       outputToVtk << nodeCoordinates[0]<<" "<< nodeCoordinates[1]<<" "<<nodeCoordinates[2] << endl;//Coordinates list OUTPUT
00217       node_map[*I_setOfNodes] = counter;
00218       counter++;
00219     }
00220 
00221     //Create the connectivity matrix
00222     for (unsigned int i = 0; i < boundaryNodes_.size(); ++i){
00223       for (unsigned int j = 0; j < boundaryNodes_[i].size(); ++j){
00224         outputToVtk << (node_map.find(boundaryNodes_[i][j])->second)+1 << " "; //List of edges     OUTPUT
00225       }
00226       outputToVtk << endl;
00227     }
00228   }//end if
00229   else cout << "Unable to open file";
00230 
00231   return 0;
00232 }

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