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