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