PRAgMaTIc  master
coarsen_mesh_3d.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2010 Imperial College London and others.
2  *
3  * Please see the AUTHORS file in the main source directory for a
4  * full list of copyright holders.
5  *
6  * Gerard Gorman
7  * Applied Modelling and Computation Group
8  * Department of Earth Science and Engineering
9  * Imperial College London
10  *
11  * g.gorman@imperial.ac.uk
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above
19  * copyright notice, this list of conditions and the following
20  * disclaimer in the documentation and/or other materials provided
21  * with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
28  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
30  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
32  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
33  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
34  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 
38 #include <iostream>
39 
40 #include <getopt.h>
41 
42 #include "Mesh.h"
43 #include "VTKTools.h"
44 #include "MetricField.h"
45 
46 #include "Coarsen.h"
47 #include "Smooth.h"
48 #include "Swapping.h"
49 #include "ticker.h"
50 
51 #include <mpi.h>
52 
53 void usage(char *cmd){
54  std::cout<<"Usage: "<<cmd<<" [options] infile\n"
55  <<"\nOptions:\n"
56  <<" -h, --help\n\tHelp! Prints this message.\n"
57  <<" -v, --verbose\n\tVerbose output.\n"
58  <<" -c factor, --coarsen factor\n\tCoarsening factor is some number greater than 1, e.g. -c 2 with half the mesh resolution.\n"
59  <<" -o filename, --output filename\n\tName of outfile -- without the extension.\n";
60  return;
61 }
62 
63 int parse_arguments(int argc, char **argv, std::string &infilename, std::string &outfilename, bool &verbose, double &factor){
64 
65  // Set defaults
66  verbose = false;
67  factor = 1.0;
68 
69  if(argc==1){
70  usage(argv[0]);
71  exit(0);
72  }
73 
74  struct option longOptions[] = {
75  {"help", 0, 0, 'h'},
76  {"verbose", 0, 0, 'v'},
77  {"coarsen", optional_argument, 0, 'c'},
78  {"output", optional_argument, 0, 'o'},
79  {0, 0, 0, 0}
80  };
81 
82  int optionIndex = 0;
83  int c;
84  const char *shortopts = "hvc:o:";
85 
86  // Set opterr to nonzero to make getopt print error messages
87  opterr=1;
88  while (true){
89  c = getopt_long(argc, argv, shortopts, longOptions, &optionIndex);
90 
91  if (c == -1) break;
92 
93  switch (c){
94  case 'h':
95  usage(argv[0]);
96  break;
97  case 'v':
98  verbose = true;
99  break;
100  case 'c':
101  factor = atof(optarg);
102  break;
103  case 'o':
104  outfilename = std::string(optarg);
105  break;
106  case '?':
107  // missing argument only returns ':' if the option string starts with ':'
108  // but this seems to stop the printing of error messages by getopt?
109  std::cerr<<"ERROR: unknown option or missing argument\n";
110  usage(argv[0]);
111  exit(-1);
112  case ':':
113  std::cerr<<"ERROR: missing argument\n";
114  usage(argv[0]);
115  exit(-1);
116  default:
117  // unexpected:
118  std::cerr<<"ERROR: getopt returned unrecognized character code\n";
119  exit(-1);
120  }
121  }
122 
123  infilename = std::string(argv[argc-1]);
124 
125  return 0;
126 }
127 
128 void cout_quality(const Mesh<double> *mesh, std::string operation){
129  double qmean = mesh->get_qmean();
130  double qmin = mesh->get_qmin();
131 
132  int rank;
133  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
134 
135  if(rank==0)
136  std::cout<<operation<<": step in quality (mean, min): ("<<qmean<<", "<<qmin<<")"<<std::endl;
137 }
138 
139 int main(int argc, char **argv){
140  int required_thread_support=MPI_THREAD_SINGLE;
141  int provided_thread_support;
142  MPI_Init_thread(&argc, &argv, required_thread_support, &provided_thread_support);
143  assert(required_thread_support==provided_thread_support);
144 
145  int rank;
146  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
147 
148  if(argc==1){
149  usage(argv[0]);
150  exit(-1);
151  }
152 
153  std::string infilename, outfilename;
154  bool verbose=false;
155  double factor=1.0;
156 
157  parse_arguments(argc, argv, infilename, outfilename, verbose, factor);
158 
159  Mesh<double> *mesh=VTKTools<double>::import_vtu(infilename.c_str());
160  mesh->create_boundary();
161 
162  MetricField<double,3> metric_field(*mesh);
163 
164  double time_metric = get_wtime();
165  metric_field.generate_mesh_metric(factor);
166  time_metric = (get_wtime() - time_metric);
167 
168  metric_field.update_mesh();
169 
170  if(verbose){
171  cout_quality(mesh, "Initial quality");
172  VTKTools<double>::export_vtu("initial_mesh_3d", mesh);
173  }
174 
175  double L_up = sqrt(2.0);
176 
177  Coarsen<double, 3> coarsen(*mesh);
178  Smooth<double, 3> smooth(*mesh);
179  Swapping<double, 3> swapping(*mesh);
180 
181  double time_coarsen=0, time_swapping=0;
182  for(size_t i=0;i<5;i++){
183  if(verbose)
184  std::cout<<"INFO: Sweep "<<i<<std::endl;
185 
186  double tic = get_wtime();
187  coarsen.coarsen(L_up, L_up, true);
188  time_coarsen += (get_wtime()-tic);
189  if(verbose)
190  cout_quality(mesh, "Quality after coarsening");
191 
192  tic = get_wtime();
193  swapping.swap(0.1);
194  time_swapping += (get_wtime()-tic);
195  if(verbose)
196  cout_quality(mesh, "Quality after swapping");
197  }
198 
199  mesh->defragment();
200 
201  double time_smooth=get_wtime();
202  smooth.smart_laplacian(20);
203  smooth.optimisation_linf(20);
204  time_smooth = (get_wtime() - time_smooth);
205  if(verbose)
206  cout_quality(mesh, "Quality after final smoothening");
207 
208  if(verbose)
209  std::cout<<"Times for metric, coarsen, swapping, smoothing = "<<time_metric<<", "<<time_coarsen<<", "<<time_swapping<<", "<<time_smooth<<std::endl;
210 
211  if(outfilename.size()==0)
212  VTKTools<double>::export_vtu("scaled_mesh_3d", mesh);
213  else
214  VTKTools<double>::export_vtu(outfilename.c_str(), mesh);
215 
216  delete mesh;
217 
218  MPI_Finalize();
219 
220  return 0;
221 }
void smart_laplacian(int max_iterations=10, double quality_tol=-1.0)
Definition: Smooth.h:111
int main(int argc, char **argv)
static Mesh< real_t > * import_vtu(std::string filename)
Definition: VTKTools.h:97
void update_mesh()
Update the metric field on the mesh.
Definition: MetricField.h:394
void create_boundary()
Definition: Mesh.h:204
void cout_quality(const Mesh< double > *mesh, std::string operation)
Performs 2D mesh coarsening.
Definition: Coarsen.h:59
double get_qmean() const
Get the element mean quality in metric space.
Definition: Mesh.h:764
Performs edge/face swapping.
Definition: Swapping.h:56
Manages mesh data.
Definition: Mesh.h:70
double get_qmin() const
Get the element minimum quality in metric space.
Definition: Mesh.h:825
static void export_vtu(const char *basename, const Mesh< real_t > *mesh, const real_t *psi=NULL)
Definition: VTKTools.h:356
void coarsen(real_t L_low, real_t L_max, bool enable_sliver_deletion=false)
Definition: Coarsen.h:126
Constructs metric tensor field which encodes anisotropic edge size information.
Definition: MetricField.h:73
double get_wtime()
Definition: ticker.cpp:34
void generate_mesh_metric(double resolution_scaling_factor)
Definition: MetricField.h:134
void swap(real_t quality_tolerance)
Definition: Swapping.h:124
Toolkit for importing and exporting VTK files. This is mostly used as part of the internal unit testi...
Definition: VTKTools.h:95
Applies Laplacian smoothen in metric space.
Definition: Smooth.h:67
void usage(char *cmd)
void defragment()
Definition: Mesh.h:958
int parse_arguments(int argc, char **argv, std::string &infilename, std::string &outfilename, bool &verbose, double &factor)
void optimisation_linf(int max_iterations=10, double quality_tol=-1.0)
Definition: Smooth.h:240