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