macro_element_free_boundary_poisson.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-2025 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 solution of "free boundary" 2D Poisson equation in
27// fish-shaped domain with adaptivity
28
29
30// Generic oomph-lib headers
31#include "generic.h"
32
33// The Poisson equations
34#include "poisson.h"
35
36// The fish mesh
37#include "meshes/fish_mesh.h"
38
39// Circle as generalised element:
41
42using namespace std;
43
44using namespace oomph;
45
46
47///////////////////////////////////////////////////////////////////////
48///////////////////////////////////////////////////////////////////////
49///////////////////////////////////////////////////////////////////////
50
51
52
53//=============start_of_namespace=====================================
54/// Namespace for const source term in Poisson equation
55//====================================================================
57{
58
59/// Const source function
60 void get_source(const Vector<double>& x, double& source)
61 {
62 source = -1.0;
63 }
64
65} // end of namespace
66
67
68
69
70
71
72
73////////////////////////////////////////////////////////////////////
74////////////////////////////////////////////////////////////////////
75// MacroElementNodeUpdate-version of RefineableFishMesh
76////////////////////////////////////////////////////////////////////
77////////////////////////////////////////////////////////////////////
78
79
80
81//==========start_of_mesh=================================================
82/// Refineable, fish-shaped mesh with MacroElement-based node update.
83//========================================================================
84template<class ELEMENT>
86 public virtual RefineableFishMesh<ELEMENT>,
87 public virtual MacroElementNodeUpdateMesh
88{
89
90public:
91
92 /// Constructor: Pass pointer to GeomObject that defines
93 /// the fish's back and pointer to timestepper
94 /// (defaults to (Steady) default timestepper defined in the Mesh
95 /// base class).
97 TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper) :
99 RefineableFishMesh<ELEMENT>(time_stepper_pt)
100 {
101 // Set up all the information that's required for MacroElement-based
102 // node update: Tell the elements that their geometry depends on the
103 // fishback geometric object.
104 unsigned n_element = this->nelement();
105 for(unsigned i=0;i<n_element;i++)
106 {
107 // Upcast from FiniteElement to the present element
108 ELEMENT *el_pt = dynamic_cast<ELEMENT*>(this->element_pt(i));
109
110 // There's just one GeomObject
112 geom_object_pt[0] = back_pt;
113
114 // Tell the element which geom objects its macro-element-based
115 // node update depends on
116 el_pt->set_node_update_info(geom_object_pt);
117 }
118
119 } //end of constructor
120
121 /// Destructor: empty
123
124 /// Resolve mesh update: Node update current nodal
125 /// positions via sparse MacroElement-based update.
126 //void node_update()
127 // {
128 // MacroElementNodeUpdateMesh::node_update();
129 // }
130
131}; // end of mesh class
132
133
134
135////////////////////////////////////////////////////////////////////////
136////////////////////////////////////////////////////////////////////////
137////////////////////////////////////////////////////////////////////////
138
139
140
141//==========start_of_problem_class====================================
142/// Refineable "free-boundary" Poisson problem in deformable
143/// fish-shaped domain. Template parameter identifies the element.
144//====================================================================
145template<class ELEMENT>
146class FreeBoundaryPoissonProblem : public Problem
147{
148
149public:
150
151 /// Constructor
153
154 /// Destructor (empty)
156
157 /// Update the problem specs before solve (empty)
159
160 /// Update the problem specs after solve (empty)
162
163 /// Access function for the fish mesh
168
169 /// Doc the solution
170 void doc_solution();
171
172 /// Before checking the new residuals in Newton's method
173 /// we have to update nodal positions in response to possible
174 /// changes in the position of the domain boundary
176 {
177 fish_mesh_pt()->node_update();
178 }
179
180private:
181
182 /// Pointer to fish mesh
184
185 /// Pointer to single-element mesh that stores the GeneralisedElement
186 /// that represents the fish's back
188
189}; // end of problem class
190
191
192
193
194//=========start_of_constructor===========================================
195/// Constructor for adaptive free-boundary Poisson problem in
196/// deformable fish-shaped domain.
197//========================================================================
198template<class ELEMENT>
200{
201
202 // Set coordinates and radius for the circle that will become the fish back
203 double x_c=0.5;
204 double y_c=0.0;
205 double r_back=1.0;
206
207 // Build geometric object that will become the fish back
210
211 // Build fish mesh with geometric object that specifies the fish back
212 Fish_mesh_pt=new
214
215 // Add the fish mesh to the problem's collection of submeshes:
216 add_sub_mesh(Fish_mesh_pt);
217
218 // Create/set error estimator for the fish mesh
219 fish_mesh_pt()->spatial_error_estimator_pt()=new Z2ErrorEstimator;
220
221 // Build mesh that will store only the geometric wall element
222 Fish_back_mesh_pt=new Mesh;
223
224 // So far, the mesh is completely empty. Let's add the
225 // GeneralisedElement that represents the shape
226 // of the fish's back to it:
227 Fish_back_mesh_pt->add_element_pt(fish_back_pt);
228
229 // Add the fish back mesh to the problem's collection of submeshes:
230 add_sub_mesh(Fish_back_mesh_pt);
231
232 // Now build global mesh from the submeshes
234
235 // Choose a control node: We'll use the
236 // central node that is shared by all four elements in
237 // the base mesh because it exists at all refinement levels.
238
239 // How many nodes does element 0 have?
240 unsigned nnod=fish_mesh_pt()->finite_element_pt(0)->nnode();
241
242 // The central node is the last node in element 0:
243 Node* control_node_pt=fish_mesh_pt()->finite_element_pt(0)->node_pt(nnod-1);
244
245 // Use the solution (value 0) at the control node as the load
246 // that acts on the ring. [Note: Node == Data by inheritance]
247 dynamic_cast<ElasticallySupportedRingElement*>(Fish_mesh_pt->fish_back_pt())->
248 set_load_pt(control_node_pt);
249
250 // Set the boundary conditions for this problem: All nodes are
251 // free by default -- just pin the ones that have Dirichlet conditions
252 // here. Set homogeneous boundary conditions everywhere
253 unsigned num_bound = fish_mesh_pt()->nboundary();
254 for(unsigned ibound=0;ibound<num_bound;ibound++)
255 {
256 unsigned num_nod= fish_mesh_pt()->nboundary_node(ibound);
257 for (unsigned inod=0;inod<num_nod;inod++)
258 {
259 fish_mesh_pt()->boundary_node_pt(ibound,inod)->pin(0);
260 fish_mesh_pt()->boundary_node_pt(ibound,inod)->set_value(0,0.0);
261
262 }
263 }
264
265 /// Loop over elements and set pointers to source function
266 unsigned n_element = fish_mesh_pt()->nelement();
267 for(unsigned i=0;i<n_element;i++)
268 {
269 // Upcast from FiniteElement to the present element
270 ELEMENT *el_pt = dynamic_cast<ELEMENT*>(fish_mesh_pt()->element_pt(i));
271
272 //Set the source function pointer
273 el_pt->source_fct_pt() = &ConstSourceForPoisson::get_source;
274 }
275
276 // Do equation numbering
277 cout << "Number of equations: " << assign_eqn_numbers() << std::endl;
278
279} // end of constructor
280
281
282
283
284//============start_of_doc================================================
285/// Doc the solution in tecplot format.
286//========================================================================
287template<class ELEMENT>
289{
290
291 // Number of plot points in each coordinate direction.
292 unsigned npts=5;
293
294 // Output solution
295 ofstream some_file("RESLT/soln0.dat");
296 fish_mesh_pt()->output(some_file,npts);
297 some_file.close();
298
299} // end of doc
300
301
302
303
304
305//==================start_of_main=========================================
306/// Driver for "free-boundary" fish poisson solver with adaptation.
307//========================================================================
308int main()
309{
310
311 // Shorthand for element type
313 ELEMENT;
314
315 // Build problem
317
318 // Do some uniform mesh refinement first
319 problem.refine_uniformly();
320 problem.refine_uniformly();
321
322 // Solve/doc fully coupled problem, allowing for up to two spatial
323 // adaptations.
324 unsigned max_solve=2;
325 problem.newton_solve(max_solve);
327
328} // end of main
329
330
void demo_fish_poisson(const string &directory_name)
Demonstrate how to solve 2D Poisson problem in deformable fish-shaped domain with mesh adaptation.
Refineable "free-boundary" Poisson problem in deformable fish-shaped domain. Template parameter ident...
virtual ~FreeBoundaryPoissonProblem()
Destructor (empty)
void actions_before_newton_convergence_check()
Before checking the new residuals in Newton's method we have to update nodal positions in response to...
void actions_after_newton_solve()
Update the problem specs after solve (empty)
Mesh * Fish_back_mesh_pt
Pointer to single-element mesh that stores the GeneralisedElement that represents the fish's back.
MyMacroElementNodeUpdateRefineableFishMesh< ELEMENT > * Fish_mesh_pt
Pointer to fish mesh.
MyMacroElementNodeUpdateRefineableFishMesh< ELEMENT > * fish_mesh_pt()
Access function for the fish mesh.
void actions_before_newton_solve()
Update the problem specs before solve (empty)
Refineable, fish-shaped mesh with MacroElement-based node update.
MyMacroElementNodeUpdateRefineableFishMesh(GeomObject *back_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to GeomObject that defines the fish's back and pointer to timestepper (defa...
GeneralCircle "upgraded" to a GeneralisedElement: Circular ring whose position is given by.
int main()
Driver for "free-boundary" fish poisson solver with adaptation.
Namespace for const source term in Poisson equation.
void get_source(const Vector< double > &x, double &source)
Const source function.
Definition circle.h:34