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

PartitionTest.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 // Simple mesh partitioning program
00007 //
00008 
00009 // Define only if Zoltan is enabled
00010 #if defined (ALBANY_LCM) && defined(ALBANY_ZOLTAN)
00011 
00012 #include <algorithm>
00013 #include <iomanip>
00014 #include <Teuchos_CommandLineProcessor.hpp>
00015 
00016 #include <LCMPartition.h>
00017 
00018 int main(int ac, char* av[])
00019 {
00020   //
00021   // Initialize Zoltan
00022   //
00023   float
00024   version;
00025 
00026   Zoltan_Initialize(ac, av, &version);
00027 
00028   //
00029   // Create a command line processor and parse command line options
00030   //
00031   Teuchos::CommandLineProcessor
00032   command_line_processor;
00033 
00034   command_line_processor.setDocString(
00035       "Partitioning of Exodus mesh for nonlocal regularization.\n"
00036       "Uses random, geometric, hypergraph or K-means variants "
00037       "partitioning algorithms.\n");
00038 
00039   std::string input_file = "input.e";
00040   command_line_processor.setOption(
00041       "input",
00042       &input_file,
00043       "Input File Name");
00044 
00045   std::string output_file = "output.e";
00046   command_line_processor.setOption(
00047       "output",
00048       &output_file,
00049       "Output File Name");
00050 
00051   const int
00052   number_schemes = 5;
00053 
00054   const LCM::PARTITION::Scheme
00055   scheme_values[] = {
00056       LCM::PARTITION::GEOMETRIC,
00057       LCM::PARTITION::HYPERGRAPH,
00058       LCM::PARTITION::KMEANS,
00059       LCM::PARTITION::SEQUENTIAL,
00060       LCM::PARTITION::KDTREE};
00061 
00062   const char*
00063   scheme_names[] = {
00064       "geometric",
00065       "hypergraph",
00066       "kmeans",
00067       "sequential",
00068       "kdtree"};
00069 
00070   LCM::PARTITION::Scheme
00071   partition_scheme = LCM::PARTITION::KDTREE;
00072 
00073   command_line_processor.setOption(
00074       "scheme",
00075       &partition_scheme,
00076       number_schemes,
00077       scheme_values,
00078       scheme_names,
00079       "Partition Scheme");
00080 
00081   double
00082   length_scale = 0.0017;
00083 
00084   command_line_processor.setOption(
00085       "length-scale",
00086       &length_scale,
00087       "Length Scale");
00088 
00089   double
00090   tolerance = 1.0e-4;
00091 
00092   command_line_processor.setOption(
00093       "tolerance",
00094       &tolerance,
00095       "Tolerance");
00096 
00097   double
00098   requested_cell_size = 0.0001;
00099 
00100   command_line_processor.setOption(
00101       "requested-cell-size",
00102       &requested_cell_size,
00103       "Requested cell size");
00104 
00105   int
00106   maximum_iterations = 64;
00107 
00108   command_line_processor.setOption(
00109       "maximum-iterations",
00110       &maximum_iterations,
00111       "Maximum Iterations");
00112 
00113   const int
00114   number_initializers = 3;
00115 
00116   const LCM::PARTITION::Scheme
00117   initializer_values[] = {
00118       LCM::PARTITION::RANDOM,
00119       LCM::PARTITION::GEOMETRIC,
00120       LCM::PARTITION::HYPERGRAPH};
00121 
00122   const char*
00123   initializer_names[] = {
00124       "random",
00125       "geometric",
00126       "hypergraph"};
00127 
00128   LCM::PARTITION::Scheme
00129   initializer_scheme = LCM::PARTITION::GEOMETRIC;
00130 
00131   command_line_processor.setOption(
00132       "initializer",
00133       &initializer_scheme,
00134       number_initializers,
00135       initializer_values,
00136       initializer_names,
00137       "Initializer Scheme");
00138 
00139   // Throw a warning and not error for unrecognized options
00140   command_line_processor.recogniseAllOptions(true);
00141 
00142   // Don't throw exceptions for errors
00143   command_line_processor.throwExceptions(false);
00144 
00145   // Parse command line
00146   Teuchos::CommandLineProcessor::EParseCommandLineReturn
00147   parse_return = command_line_processor.parse(ac, av);
00148 
00149   if (parse_return == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED) {
00150     return 0;
00151   }
00152 
00153   if (parse_return != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
00154     return 1;
00155   }
00156 
00157   //
00158   // Read mesh
00159   //
00160   LCM::ConnectivityArray
00161   connectivity_array(input_file, output_file);
00162 
00163   //
00164   // Set extra parameters
00165   //
00166   connectivity_array.SetTolerance(tolerance);
00167   connectivity_array.SetCellSize(requested_cell_size);
00168   connectivity_array.SetMaximumIterations(maximum_iterations);
00169   connectivity_array.SetInitializerScheme(initializer_scheme);
00170 
00171   //
00172   // Partition mesh
00173   //
00174   const std::map<int, int>
00175   partitions = connectivity_array.Partition(partition_scheme, length_scale);
00176 
00177   // Get abstract discretization from connectivity array and convert
00178   // to stk discretization to use stk-specific methods.
00179   Albany::AbstractDiscretization &
00180   discretization = connectivity_array.GetDiscretization();
00181 
00182   Albany::STKDiscretization &
00183   stk_discretization = static_cast<Albany::STKDiscretization &>(discretization);
00184 
00185   //
00186   // Output partitions
00187   //
00188 
00189   // Convert partition map to format used by Albany to set internal variables.
00190   // Assumption: numbering of elements is contiguous.
00191 
00192   int
00193   element = 0;
00194 
00195   Albany::StateArrayVec
00196   state_arrays = stk_discretization.getStateArrays().elemStateArrays;
00197 
00198   for (Albany::StateArrayVec::size_type i = 0; i < state_arrays.size(); ++i) {
00199 
00200     Albany::StateArray
00201     state_array = state_arrays[i];
00202 
00203     // Get MDArray which has the "Partition" element variable
00204     Albany::MDArray
00205     stk_partition = state_array["Partition"];
00206 
00207     for (Albany::MDArray::size_type j = 0; j < stk_partition.size(); ++j) {
00208 
00209       const std::map<int, int>::const_iterator
00210       partitions_iterator = partitions.find(element);
00211 
00212       if (partitions_iterator == partitions.end()) {
00213         std::cerr << std::endl;
00214         std::cerr << "Element " << element << " does not have a partition.";
00215         std::cerr << std::endl;
00216         exit(1);
00217       }
00218 
00219       const int
00220       partition = (*partitions_iterator).second;
00221 
00222       element++;
00223       stk_partition[j] = partition;
00224     }
00225 
00226   }
00227 
00228   // Need solution for output call
00229   Teuchos::RCP<Epetra_Vector>
00230   solution_field = stk_discretization.getSolutionField();
00231 
00232   // second arg to output is (pseudo)time
00233   stk_discretization.writeSolution(*solution_field, 1.0);
00234 
00235   // Write report
00236   const double
00237   volume = connectivity_array.GetVolume();
00238 
00239   const double
00240   length_scale_cubed = length_scale * length_scale * length_scale;
00241 
00242   const LCM::ScalarMap
00243   partition_volumes = connectivity_array.GetPartitionVolumes();
00244 
00245   const unsigned int
00246   number_partitions = partition_volumes.size();
00247 
00248   std::cout << std::endl;
00249   std::cout << "==========================================";
00250   std::cout << std::endl;
00251   std::cout << "Total Mesh Volume (V)    : ";
00252   std::cout << std::scientific << std::setw(14) << std::setprecision(8);
00253   std::cout << volume << std::endl;
00254   std::cout << "Length Scale             : ";
00255   std::cout << std::scientific << std::setw(14) << std::setprecision(8);
00256   std::cout << length_scale << std::endl;
00257   std::cout << "Length Scale Cubed (L^3) : ";
00258   std::cout << std::scientific << std::setw(14) << std::setprecision(8);
00259   std::cout << length_scale_cubed << std::endl;
00260   std::cout << "V/L^3                    : ";
00261   std::cout << std::scientific << std::setw(14) << std::setprecision(8);
00262   std::cout << volume / length_scale_cubed << std::endl;
00263   std::cout << "Number of Partitions     : " << number_partitions;
00264   std::cout << std::endl;
00265   std::cout << "------------------------------------------";
00266   std::cout << std::endl;
00267   std::cout << "Partition      Volume (Vi)          Vi/L^3";
00268   std::cout << std::endl;
00269   std::cout << "------------------------------------------";
00270   std::cout << std::endl;
00271   for (LCM::ScalarMap::const_iterator iter = partition_volumes.begin();
00272       iter != partition_volumes.end();
00273       ++iter) {
00274     int partition = (*iter).first;
00275     double volume = (*iter).second;
00276     std::cout << std::setw(10) << partition;
00277     std::cout << std::scientific << std::setw(16) << std::setprecision(8);
00278     std::cout << volume;
00279     std::cout << std::scientific << std::setw(16) << std::setprecision(8);
00280     std::cout << volume / length_scale_cubed << std::endl;
00281   }
00282   std::cout << "==========================================";
00283   std::cout << std::endl;
00284 
00285 #if 0
00286 
00287   std::cout << "Number of elements       : ";
00288   std::cout << std::setw(14);
00289   std::cout << connectivity_array.GetNumberElements() << std::endl;
00290   std::cout << std::endl;
00291   std::cout << "------------------------------------------";
00292   std::cout << std::endl;
00293   std::cout << "Element        Partition";
00294   std::cout << std::endl;
00295   std::cout << "------------------------------------------";
00296   std::cout << std::endl;
00297   for (std::map<int, int>::const_iterator
00298       partitions_iter = partitions.begin();
00299       partitions_iter != partitions.end();
00300       ++partitions_iter) {
00301 
00302     const int
00303     element = (*partitions_iter).first;
00304 
00305     const int
00306     partition = (*partitions_iter).second;
00307 
00308     std::cout << std::setw(16) << element;
00309     std::cout << std::setw(16) << partition;
00310     std::cout << std::endl;
00311   }
00312   std::cout << "==========================================";
00313   std::cout << std::endl;
00314 
00315 
00316   LCM::DualGraph dual_graph(connectivity_array);
00317   dual_graph.Print();
00318 
00319 #endif
00320 
00321   return 0;
00322 
00323 }
00324 
00325 #else // #if defined (ALBANY_LCM) && defined(ALBANY_ZOLTAN)
00326 
00327 // Zoltan not defined, do nothing
00328 int main(int ac, char* av[])
00329 {
00330   return 0;
00331 }
00332 
00333 #endif // #if defined (ALBANY_ZOLTAN)

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