mesh_from_tetgen_navier_stokes.cc
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Version 1.0; svn revision $LastChangedRevision: 1097 $
7 //LIC//
8 //LIC// $LastChangedDate: 2015-12-17 11:53:17 +0000 (Thu, 17 Dec 2015) $
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 ///Driver for a 3D navier stokes flow with tetgen
31 
32 //Generic routines
33 #include "generic.h"
34 #include "navier_stokes.h"
35 
36 // Get the mesh
37 #include "meshes/tetgen_mesh.h"
38 
39 using namespace std;
40 
41 using namespace oomph;
42 
43 //=start_of_namespace================================================
44 /// Namespace for physical parameters
45 //===================================================================
46 namespace Global_Physical_Variables
47 {
48  /// Reynolds number
49  double Re=10.0;
50 } // end_of_namespace
51 
52 
53 
54 
55 //=start_of_problem_class=============================================
56 /// Entry flow problem in quarter tube domain
57 //====================================================================
58 template<class ELEMENT>
59 class NavierStokesProblem : public Problem
60 {
61 
62 public:
63 
64  /// Constructor: Pass DocInfo object and file names
65  NavierStokesProblem(DocInfo& doc_info,
66  const string& node_file_name,
67  const string& element_file_name,
68  const string& face_file_name);
69 
70  /// Destructor (empty)
72 
73  /// Doc the solution after solve
75  {
76  // Doc solution after solving
77  doc_solution();
78 
79  // Increment label for output files
80  Doc_info.number()++;
81  }
82 
83  /// \short Update the problem specs before solve
84  void actions_before_newton_solve();
85 
86  /// Doc the solution
87  void doc_solution();
88 
89  //Access function for the specific mesh
91  {
92  return dynamic_cast<TetgenMesh<ELEMENT>*>(Problem::mesh_pt());
93  }
94 
95 
96 private:
97 
98 
99  /// Doc info object
100  DocInfo Doc_info;
101 
102 }; // end_of_problem_class
103 
104 
105 
106 
107 //=start_of_constructor===================================================
108 /// Constructor: Pass DocInfo object mesh files
109 //========================================================================
110 template<class ELEMENT>
112  const string& node_file_name,
113  const string& element_file_name,
114  const string& face_file_name)
115  : Doc_info(doc_info)
116 {
117  //Create mesh
118  Problem::mesh_pt() = new TetgenMesh<ELEMENT>(node_file_name,
119  element_file_name,
120  face_file_name);
121 
122  //Doc the boundaries
123  ofstream some_file;
124  char filename[100];
125  sprintf(filename,"boundaries.dat");
126  some_file.open(filename);
127  mesh_pt()->output_boundaries(some_file);
128  some_file.close();
129 
130 
131  // Set the boundary conditions for this problem: All nodal values are
132  // free by default -- just pin the ones that have Dirichlet conditions
133 
134  // Pin transverse velocities on outer walls -- the outer boundary
135  // behaves like a channel (open along the x-axis) with slippery walls
136  // on the transverse boundaries
137  {
138  unsigned ibound=0;
139  {
140  unsigned num_nod= mesh_pt()->nboundary_node(ibound);
141  for (unsigned inod=0;inod<num_nod;inod++)
142  {
143  mesh_pt()->boundary_node_pt(ibound,inod)->pin(1);
144  mesh_pt()->boundary_node_pt(ibound,inod)->pin(2);
145  }
146  }
147  }
148 
149 
150  // Pin all velocity components on internal block -- behaves like
151  // a rigid body
152  {
153  unsigned ibound=1;
154  {
155  unsigned num_nod= mesh_pt()->nboundary_node(ibound);
156  for (unsigned inod=0;inod<num_nod;inod++)
157  {
158  mesh_pt()->boundary_node_pt(ibound,inod)->pin(0);
159  mesh_pt()->boundary_node_pt(ibound,inod)->pin(1);
160  mesh_pt()->boundary_node_pt(ibound,inod)->pin(2);
161  }
162  }
163  }
164 
165 
166  // Loop over the elements to set up element-specific
167  // things that cannot be handled by constructor
168  unsigned n_element = mesh_pt()->nelement();
169  for(unsigned i=0;i<n_element;i++)
170  {
171  // Upcast from GeneralisedElement to the present element
172  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(i));
173 
174  //Set the Reynolds number, etc
175  el_pt->re_pt() = &Global_Physical_Variables::Re;
176  }
177 
178 
179  //Do equation numbering
180  cout <<"Number of equations: " << assign_eqn_numbers() << std::endl;
181 
182 } // end_of_constructor
183 
184 
185 //=start_of_actions_before_newton_solve==========================================
186 /// Set the inflow boundary conditions
187 //========================================================================
188 template<class ELEMENT>
190 {
191 
192  // Apply conditions on obstacle
193  unsigned ibound=1;
194  unsigned num_nod= mesh_pt()->nboundary_node(ibound);
195  for (unsigned inod=0;inod<num_nod;inod++)
196  {
197  // Block moves in z-direction
198  mesh_pt()->boundary_node_pt(ibound,inod)->set_value(2,1.0);
199 
200  }
201 
202 } // end_of_actions_before_newton_solve
203 
204 
205 //=start_of_doc_solution==================================================
206 /// Doc the solution
207 //========================================================================
208 template<class ELEMENT>
210 {
211 
212  ofstream some_file;
213  char filename[100];
214 
215  // Number of plot points
216  unsigned npts;
217  npts=5;
218 
219  // Output solution
220  sprintf(filename,"%s/soln%i.dat",Doc_info.directory().c_str(),
221  Doc_info.number());
222  some_file.open(filename);
223  mesh_pt()->output(some_file,npts);
224  some_file.close();
225 
226 } // end_of_doc_solution
227 
228 
229 
230 
231 ////////////////////////////////////////////////////////////////////////
232 ////////////////////////////////////////////////////////////////////////
233 ////////////////////////////////////////////////////////////////////////
234 
235 
236 //=start_of_main=======================================================
237 /// 3D Navier Stokes on an unstructured mesh
238 //=====================================================================
239 int main(int argc, char* argv[])
240 {
241 
242  // Store command line arguments
243  CommandLineArgs::setup(argc,argv);
244 
245  // Check number of command line arguments: Need exactly three.
246  if (argc!=4)
247  {
248  std::string error_message =
249  "Wrong number of command line arguments.\n";
250  error_message +=
251  "Must specify the following file names \n";
252  error_message +=
253  "filename.node then filename.ele then filename.face\n";
254 
255  throw OomphLibError(error_message,
256  OOMPH_CURRENT_FUNCTION,
257  OOMPH_EXCEPTION_LOCATION);
258  }
259 
260  // Convert arguments to strings that specify the input file names
261  string node_file_name(argv[1]);
262  string element_file_name(argv[2]);
263  string face_file_name(argv[3]);
264 
265  // Set up doc info
266  DocInfo doc_info;
267 
268  // Set output directory
269  doc_info.set_directory("RESLT");
270 
271  // Build problem
273  problem(doc_info,node_file_name,element_file_name,face_file_name);
274 
275  // Solve the problem
276  problem.newton_solve();
277 
278 
279 } // end_of_main
280 
281 
DocInfo Doc_info
Doc info object.
void actions_before_newton_solve()
Update the problem specs before solve.
int main(int argc, char *argv[])
3D Navier Stokes on an unstructured mesh
void actions_after_newton_solve()
Doc the solution after solve.
NavierStokesProblem(DocInfo &doc_info, const string &node_file_name, const string &element_file_name, const string &face_file_name)
Constructor: Pass DocInfo object and file names.
Unstructured tet mesh based on output from Tetgen: http://wias-berlin.de/software/tetgen//.
~NavierStokesProblem()
Destructor (empty)
TetgenMesh< ELEMENT > * mesh_pt()
Entry flow problem in quarter tube domain.
void doc_solution()
Doc the solution.