driven_cavity.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$
7 //LIC//
8 //LIC// $LastChangedDate$
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 2D rectangular driven cavity
31 
32 //Generic includes
33 #include "generic.h"
34 #include "navier_stokes.h"
35 
36 #include "meshes/simple_rectangular_quadmesh.h"
37 
38 
39 using namespace std;
40 
41 using namespace oomph;
42 
43 
44 //==start_of_namespace==============================
45 /// Namespace for physical parameters
46 //==================================================
48 {
49 
50  /// Reynolds number
51  double Re=100;
52 
53 } // end_of_namespace
54 
55 
56 
57 ////////////////////////////////////////////////////////////////////////
58 ////////////////////////////////////////////////////////////////////////
59 ////////////////////////////////////////////////////////////////////////
60 
61 
62 
63 //==start_of_problem_class============================================
64 /// Driven cavity problem in rectangular domain
65 //====================================================================
66 template<class ELEMENT>
67 class RectangularDrivenCavityProblem : public Problem
68 {
69 
70 public:
71 
72 
73  /// Constructor
75 
76  /// Destructor (empty)
78 
79  ///Fix pressure in element e at pressure dof pdof and set to pvalue
80  void fix_pressure(const unsigned &e, const unsigned &pdof,
81  const double &pvalue)
82  {
83  //Cast to full element type and fix the pressure at that element
84  dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e))->
85  fix_pressure(pdof,pvalue);
86  } // end of fix_pressure
87 
88 
89  /// Update the after solve (empty)
91 
92 
93  /// \short Update the problem specs before solve.
94  /// Re-set velocity boundary conditions just to be on the safe side...
96  {
97  // Setup tangential flow along boundary 0:
98  unsigned ibound=0;
99  unsigned num_nod= mesh_pt()->nboundary_node(ibound);
100  for (unsigned inod=0;inod<num_nod;inod++)
101  {
102  // Tangential flow
103  unsigned i=0;
104  mesh_pt()->boundary_node_pt(ibound,inod)->set_value(i,1.0);
105  // No penetration
106  i=1;
107  mesh_pt()->boundary_node_pt(ibound,inod)->set_value(i,0.0);
108  }
109 
110  // Overwrite with no flow along the other boundaries
111  unsigned num_bound = mesh_pt()->nboundary();
112  for(unsigned ibound=1;ibound<num_bound;ibound++)
113  {
114  unsigned num_nod= mesh_pt()->nboundary_node(ibound);
115  for (unsigned inod=0;inod<num_nod;inod++)
116  {
117  for (unsigned i=0;i<2;i++)
118  {
119  mesh_pt()->boundary_node_pt(ibound,inod)->set_value(i,0.0);
120  }
121  }
122  }
123  } // end_of_actions_before_newton_solve
124 
125  // Access function for the specific mesh
126  SimpleRectangularQuadMesh<ELEMENT>* mesh_pt()
127  {
128  // Upcast from pointer to the Mesh base class to the specific
129  // element type that we're using here.
130  return dynamic_cast<SimpleRectangularQuadMesh<ELEMENT>*>(
131  Problem::mesh_pt());
132  }
133 
134 
135  /// Doc the solution
136  void doc_solution(DocInfo& doc_info);
137 
138 }; // end_of_problem_class
139 
140 
141 //==start_of_constructor==================================================
142 /// Constructor for RectangularDrivenCavity problem
143 //========================================================================
144 template<class ELEMENT>
146 {
147 
148  // Setup mesh
149 
150  // # of elements in x-direction
151  unsigned n_x=10;
152 
153  // # of elements in y-direction
154  unsigned n_y=10;
155 
156  // Domain length in x-direction
157  double l_x=1.0;
158 
159  // Domain length in y-direction
160  double l_y=1.0;
161 
162  // Build and assign mesh
163  Problem::mesh_pt() = new SimpleRectangularQuadMesh<ELEMENT>(n_x,n_y,l_x,l_y);
164 
165  // Set the boundary conditions for this problem: All nodes are
166  // free by default -- just pin the ones that have Dirichlet conditions
167  // here.
168  unsigned num_bound = mesh_pt()->nboundary();
169  for(unsigned ibound=0;ibound<num_bound;ibound++)
170  {
171  unsigned num_nod= mesh_pt()->nboundary_node(ibound);
172  for (unsigned inod=0;inod<num_nod;inod++)
173  {
174  // Loop over values (u and v velocities)
175  for (unsigned i=0;i<2;i++)
176  {
177  mesh_pt()->boundary_node_pt(ibound,inod)->pin(i);
178  }
179  }
180  } // end loop over boundaries
181 
182  // Complete the build of all elements so they are fully functional
183 
184  //Find number of elements in mesh
185  unsigned n_element = mesh_pt()->nelement();
186 
187  // Loop over the elements to set up element-specific
188  // things that cannot be handled by constructor
189  for(unsigned e=0;e<n_element;e++)
190  {
191  // Upcast from GeneralisedElement to the present element
192  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e));
193 
194  //Set the Reynolds number
195  el_pt->re_pt() = &Global_Physical_Variables::Re;
196  } // end loop over elements
197 
198  // Now set the first pressure value in element 0 to 0.0
199  fix_pressure(0,0,0.0);
200 
201  // Setup equation numbering scheme
202  cout <<"Number of equations: " << assign_eqn_numbers() << std::endl;
203 } // end_of_constructor
204 
205 
206 
207 //==start_of_doc_solution=================================================
208 /// Doc the solution
209 //========================================================================
210 template<class ELEMENT>
212 {
213  ofstream some_file;
214  char filename[100];
215 
216  // Number of plot points
217  unsigned npts;
218  npts=5;
219 
220  // Output solution
221  sprintf(filename,"%s/soln%i.dat",doc_info.directory().c_str(),
222  doc_info.number());
223  some_file.open(filename);
224  mesh_pt()->output(some_file,npts);
225  some_file.close();
226 } // end_of_doc_solution
227 
228 
229 
230 
231 
232 ////////////////////////////////////////////////////////////////////////
233 ////////////////////////////////////////////////////////////////////////
234 ////////////////////////////////////////////////////////////////////////
235 
236 
237 
238 
239 
240 
241 
242 //==start_of_main======================================================
243 /// Driver for RectangularDrivenCavity test problem -- test drive
244 /// with two different types of element.
245 //=====================================================================
246 int main()
247 {
248 
249  // Set up doc info
250  // ---------------
251 
252  // Label for output
253  DocInfo doc_info;
254 
255  // Set output directory
256  doc_info.set_directory("RESLT");
257 
258  // Step number
259  doc_info.number()=0;
260 
261  // ---------------
262  // end of Set up doc info
263 
264  // Doing QCrouzeixRaviartElements
265  {
266 
267  // Build the problem with QCrouzeixRaviartElements
269  cout << "Doing QCrouzeixRaviartElement<2>" << std::endl;
270 
271  // Solve the problem
272  problem.newton_solve();
273 
274  // Outpt the solution
275  problem.doc_solution(doc_info);
276 
277  // Step number
278  doc_info.number()++;
279 
280  } // end of QCrouzeixRaviartElements
281 
282  // Doing QTaylorHoodElements
283  {
284 
285  // Build the problem with QTaylorHoodElements
287  cout << "Doing QTaylorHoodElement<2>" << std::endl;
288 
289  // Solve the problem
290  problem.newton_solve();
291 
292  // Outpt the solution
293  problem.doc_solution(doc_info);
294 
295  // Step number
296  doc_info.number()++;
297 
298  } // end of QTaylorHoodElements
299 
300 
301 } // end_of_main
302 
303 
304 
305 
306 
307 
308 
309 
310 
311 
RectangularDrivenCavityProblem()
Constructor.
void actions_after_newton_solve()
Update the after solve (empty)
void doc_solution(DocInfo &doc_info)
Doc the solution.
SimpleRectangularQuadMesh< ELEMENT > * mesh_pt()
~RectangularDrivenCavityProblem()
Destructor (empty)
void actions_before_newton_solve()
Update the problem specs before solve. Re-set velocity boundary conditions just to be on the safe sid...
void fix_pressure(const unsigned &e, const unsigned &pdof, const double &pvalue)
Fix pressure in element e at pressure dof pdof and set to pvalue.
double Re
Reynolds number.
Driven cavity problem in rectangular domain.
Namespace for physical parameters.
int main()