mesh_from_triangle_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-2024 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 flow past rectangular box -- meshed with triangle
27
28//Generic includes
29#include "generic.h"
30#include "navier_stokes.h"
31
32// The mesh
33#include "meshes/triangle_mesh.h"
34
35using namespace std;
36
37using namespace oomph;
38
39//==start_of_namespace==============================
40/// Namespace for physical parameters
41//==================================================
43{
44
45 /// Reynolds number
46 double Re=10.0;
47
48} // end_of_namespace
49
50
51
52/// /////////////////////////////////////////////////////////////////////
53/// /////////////////////////////////////////////////////////////////////
54/// /////////////////////////////////////////////////////////////////////
55
56
57
58//==start_of_problem_class============================================
59/// Flow past a box in a channel
60//====================================================================
61template<class ELEMENT>
62class FlowPastBoxProblem : public Problem
63{
64
65public:
66
67
68 /// Constructor: Pass filenames for mesh
69 FlowPastBoxProblem(const string& node_file_name,
70 const string& element_file_name,
71 const string& poly_file_name);
72
73 /// Destructor (empty)
75
76 /// Update the after solve (empty)
78
79 /// Update the problem specs before solve.
80 /// Re-set velocity boundary conditions just to be on the safe side...
82 {
83 // Find max. and min y-coordinate at inflow
84 double y_min=1.0e20;
85 double y_max=-1.0e20;
86 unsigned ibound=0;
87 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
88 for (unsigned inod=0;inod<num_nod;inod++)
89 {
90 double y=mesh_pt()->boundary_node_pt(ibound,inod)->x(1);
91 if (y>y_max)
92 {
93 y_max=y;
94 }
95 if (y<y_min)
96 {
97 y_min=y;
98 }
99 }
100
101 // Loop over all boundaries
102 for (unsigned ibound=0;ibound<mesh_pt()->nboundary();ibound++)
103 {
104 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
105 for (unsigned inod=0;inod<num_nod;inod++)
106 {
107 // Parabolic horizontal flow at inflow
108 if (ibound==0)
109 {
110 double y=mesh_pt()->boundary_node_pt(ibound,inod)->x(1);
111 double veloc=(y-y_min)*(y_max-y);
112 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(0,veloc);
113 }
114 // Zero horizontal flow elsewhere (either as IC or otherwise)
115 else
116 {
117 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(0,0.0);
118 }
119 // Zero vertical flow on all boundaries
120 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(1,0.0);
121 }
122 }
123 } // end_of_actions_before_newton_solve
124
125#ifdef ADAPT
126 // Perform actions after mesh adaptation
127 void actions_after_adapt();
128#endif
129
130#ifdef ADAPT
131 /// Access function for the specific mesh
133 {
134 return dynamic_cast<RefineableTriangleMesh<ELEMENT>*>(Problem::mesh_pt());
135 }
136#else
137 /// Access function for the specific mesh
139 {
140 return dynamic_cast<TriangleMesh<ELEMENT>*>(Problem::mesh_pt());
141 }
142#endif
143
144 /// Doc the solution
145 void doc_solution(DocInfo& doc_info);
146
147#ifdef ADAPT
148private:
149 /// Pointer to the bulk mesh
151
152 /// Error estimator
153 Z2ErrorEstimator* error_estimator_pt;
154
155#endif
156
157}; // end_of_problem_class
158
159
160//==start_of_constructor==================================================
161/// Constructor for FlowPastBox problem. Pass filenames for mesh
162//========================================================================
163template<class ELEMENT>
165 const string& node_file_name,
166 const string& element_file_name,
167 const string& poly_file_name)
168{
169
170 Problem::Max_residuals=1000.0;
171
172#ifdef ADAPT
173 //Create mesh
177
178 // Set error estimator for bulk mesh
179 Z2ErrorEstimator* error_estimator_pt=new Z2ErrorEstimator;
180 Bulk_mesh_pt->spatial_error_estimator_pt() = error_estimator_pt;
181
182 // Set the problem mesh pointer to the bulk mesh
183 Problem::mesh_pt() = Bulk_mesh_pt;
184
185#else
186 //Create mesh
187 Problem::mesh_pt() = new TriangleMesh<ELEMENT>(node_file_name,
190#endif
191
192 // Set the boundary conditions for this problem: All nodes are
193 // free by default -- just pin the ones that have Dirichlet conditions
194 // here.
195 unsigned num_bound = mesh_pt()->nboundary();
196 for(unsigned ibound=0;ibound<num_bound;ibound++)
197 {
198 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
199 for (unsigned inod=0;inod<num_nod;inod++)
200 {
201 // Pin horizontal velocity everywhere apart from pure outflow
202 if ((ibound!=2))
203 {
204 mesh_pt()->boundary_node_pt(ibound,inod)->pin(0);
205 }
206
207 // Pin vertical velocity everywhere
208 mesh_pt()->boundary_node_pt(ibound,inod)->pin(1);
209 }
210 } // end loop over boundaries
211
212 // Complete the build of all elements so they are fully functional
213
214 //Find number of elements in mesh
215 unsigned n_element = mesh_pt()->nelement();
216
217 // Loop over the elements to set up element-specific
218 // things that cannot be handled by constructor
219 for(unsigned e=0;e<n_element;e++)
220 {
221 // Upcast from GeneralisedElement to the present element
222 ELEMENT* el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e));
223
224 //Set the Reynolds number
226 } // end loop over elements
227
228
229 // Setup equation numbering scheme
230 cout <<"Number of equations: " << assign_eqn_numbers() << std::endl;
231
232} // end_of_constructor
233
234#ifdef ADAPT
235//========================================================================
236// Perform actions after mesh adaptation
237//========================================================================
238template<class ELEMENT>
240{
241
242 // Pin the nodes and make all the element fully functional since the
243 // mesh adaptation generated a new mesh
244
245 // Set the boundary conditions for this problem: All nodes are
246 // free by default -- just pin the ones that have Dirichlet conditions
247 // here.
248 unsigned num_bound = mesh_pt()->nboundary();
249 for(unsigned ibound=0;ibound<num_bound;ibound++)
250 {
251 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
252 for (unsigned inod=0;inod<num_nod;inod++)
253 {
254 // Pin horizontal velocity everywhere apart from pure outflow
255 if ((ibound!=2))
256 {
257 mesh_pt()->boundary_node_pt(ibound,inod)->pin(0);
258 }
259
260 // Pin vertical velocity everywhere
261 mesh_pt()->boundary_node_pt(ibound,inod)->pin(1);
262 }
263 } // end loop over boundaries
264
265 // Complete the build of all elements so they are fully functional
266
267 //Find number of elements in mesh
268 unsigned n_element = mesh_pt()->nelement();
269
270 // Loop over the elements to set up element-specific
271 // things that cannot be handled by constructor
272 for(unsigned e=0;e<n_element;e++)
273 {
274 // Upcast from GeneralisedElement to the present element
275 ELEMENT* el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e));
276
277 //Set the Reynolds number
279 } // end loop over elements
280
281
282 // Setup equation numbering scheme
283 cout <<"Number of equations: " << assign_eqn_numbers() << std::endl;
284
285}
286#endif
287
288
289//==start_of_doc_solution=================================================
290/// Doc the solution
291//========================================================================
292template<class ELEMENT>
294{
296 char filename[100];
297
298 // Number of plot points
299 unsigned npts;
300 npts=5;
301
302 // Output solution
303 sprintf(filename,"%s/soln%i.dat",doc_info.directory().c_str(),
304 doc_info.number());
305 some_file.open(filename);
306 mesh_pt()->output(some_file,npts);
307 some_file.close();
308
309 // Get norm of solution
310 sprintf(filename,"%s/norm%i.dat",doc_info.directory().c_str(),
311 doc_info.number());
312 some_file.open(filename);
313 double norm_soln=0.0;
314 mesh_pt()->compute_norm(norm_soln);
315 some_file << sqrt(norm_soln) << std::endl;
316 cout << "Norm of computed solution: " << sqrt(norm_soln) << endl;
317 some_file.close();
318
319
320} // end_of_doc_solution
321
322
323
324
325
326/// /////////////////////////////////////////////////////////////////////
327/// /////////////////////////////////////////////////////////////////////
328/// /////////////////////////////////////////////////////////////////////
329
330
331
332
333
334
335
336//==start_of_main======================================================
337/// Driver for FlowPastBox test problem
338//=====================================================================
339int main(int argc, char* argv[])
340{
341
342// Store command line arguments
343 CommandLineArgs::setup(argc,argv);
344
345
346 // Check number of command line arguments: Need exactly two.
347 if (argc!=4)
348 {
349 std::string error_message =
350 "Wrong number of command line arguments.\n";
352 "Must specify the following file names \n";
353 error_message +=
354 "filename.node then filename.ele then filename.poly\n";
355
359 }
360
361
362 // Convert arguments to strings that specify the input file names
363 string node_file_name(argv[1]);
364 string element_file_name(argv[2]);
365 string poly_file_name(argv[3]);
366
367
368 // Set up doc info
369 // ---------------
370
371 // Label for output
373
374 // Set output directory
375 doc_info.set_directory("RESLT");
376
377 // Step number
378 doc_info.number()=0;
379
380#ifdef ADAPT
381 const unsigned max_adapt = 3;
382#endif
383
384// Doing TTaylorHoodElements
385 {
386#ifdef ADAPT
387 // Build the problem with TTaylorHoodElements
390#else
391 // Build the problem with TTaylorHoodElements
394#endif
395 // Output boundaries
396 problem.mesh_pt()->output_boundaries("RESLT/boundaries.dat");
397
398 // Outpt the solution
399 problem.doc_solution(doc_info);
400
401 // Step number
402 doc_info.number()++;
403
404#ifdef ADAPT
405 // Solve the problem
406 problem.newton_solve(max_adapt);
407#else
408 // Solve the problem
409 problem.newton_solve();
410#endif
411
412 // Outpt the solution
413 problem.doc_solution(doc_info);
414
415 // Step number
416 doc_info.number()++;
417
418 } // end of QTaylorHoodElements
419
420
421} // end_of_main
422
423
424
425
426
427
428
429
430
431
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
RefineableTriangleMesh< ELEMENT > * mesh_pt()
Access function for the specific mesh.
Z2ErrorEstimator * error_estimator_pt
Error estimator.
void actions_after_newton_solve()
Update the after solve (empty)
RefineableTriangleMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the bulk mesh.
void actions_before_newton_solve()
Update the problem specs before solve. Re-set velocity boundary conditions just to be on the safe sid...
FlowPastBoxProblem(const string &node_file_name, const string &element_file_name, const string &poly_file_name)
Constructor: Pass filenames for mesh.
void doc_solution(DocInfo &doc_info)
Doc the solution.
TriangleMesh< ELEMENT > * mesh_pt()
Access function for the specific mesh.
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
int main(int argc, char *argv[])
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
Namespace for physical parameters.
////////////////////////////////////////////////////////////////////// //////////////////////////////...