prescribed_displ_lagr_mult2.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 Solid deformation -- driven by boundary motion which
27// is imposed directly (without Lagrange multipliers)
28
29//Oomph-lib includes
30#include "generic.h"
31#include "solid.h"
32#include "constitutive.h"
33
34//The mesh
35#include "meshes/rectangular_quadmesh.h"
36
37using namespace std;
38
39using namespace oomph;
40
41
42//======Start_of_warped_line===============================================
43/// Warped line in 2D space
44//=========================================================================
45class WarpedLine : public GeomObject
46{
47
48public:
49
50 /// Constructor: Specify amplitude of deflection from straight horizontal line
51 WarpedLine(const double& ampl) : GeomObject(1,2)
52 {
53 Ampl=ampl;
54 }
55
56 /// Broken copy constructor
57 WarpedLine(const WarpedLine& dummy)
58 {
59 BrokenCopy::broken_copy("WarpedLine");
60 }
61
62 /// Broken assignment operator
63 void operator=(const WarpedLine&)
64 {
65 BrokenCopy::broken_assign("WarpedLine");
66 }
67
68
69 /// Empty Destructor
71
72 /// Position vector at Lagrangian coordinate zeta
73 void position(const Vector<double>& zeta, Vector<double>& r) const
74 {
75 // Position vector
76 r[0] = zeta[0]+5.0*Ampl*zeta[0]*(zeta[0]-1.0)*(zeta[0]-0.7);
77 r[1] = 1.0+Ampl*0.5*(1.0-cos(2.0*MathematicalConstants::Pi*zeta[0]));
78 }
79
80 /// Parametrised position on object: r(zeta). Evaluated at
81 /// previous timestep. t=0: current time; t>0: previous
82 /// timestep. Forward to steady version
83 void position(const unsigned& t, const Vector<double>& zeta,
84 Vector<double>& r) const
85 {
86 position(zeta,r);
87 }
88
89 /// Access to amplitude
90 double& ampl() {return Ampl;}
91
92private:
93
94 /// Amplitude of perturbation
95 double Ampl;
96
97};
98
99
100
101///////////////////////////////////////////////////////////////////////
102///////////////////////////////////////////////////////////////////////
103///////////////////////////////////////////////////////////////////////
104
105
106
107//=======start_namespace==========================================
108/// Global parameters
109//================================================================
111{
112
113 /// GeomObject specifying the shape of the boundary: Initially it's flat.
115
116 /// Poisson's ratio
117 double Nu=0.3;
118
119 // Generalised Hookean constitutive equations
120 GeneralisedHookean Constitutive_law(&Global_Physical_Variables::Nu);
121
122} //end namespace
123
124
125
126//=============begin_problem============================================
127/// Problem class for deformation of elastic block by prescribed
128/// boundary motion.
129//======================================================================
130template<class ELEMENT>
131class PrescribedBoundaryDisplacementProblem : public Problem
132{
133
134public:
135
136 /// Constructor:
138
139 /// Update function (empty)
141
142 /// Update boundary position directly
144 {
145
146 // Loop over all nodes on top boundary (boundary 2)
147 unsigned b=2;
148 unsigned n_nod = solid_mesh_pt()->nboundary_node(b);
149 for(unsigned i=0;i<n_nod;i++)
150 {
151 Node* nod_pt= solid_mesh_pt()->boundary_node_pt(b,i);
152
153 // Get boundary coordinate associated with boundary 2
154 Vector<double> zeta(1);
155 nod_pt->get_coordinates_on_boundary(b,zeta);
156
157 // Get prescribed position from GeomObject
158 Vector<double> r(2);
160
161 // Update position
162 nod_pt->x(0)=r[0];
163 nod_pt->x(1)=r[1];
164 }
165
166 } // end actions_before_newton_solve
167
168 /// Access function for the solid mesh
169 ElasticRefineableRectangularQuadMesh<ELEMENT>*& solid_mesh_pt()
170 {return Solid_mesh_pt;}
171
172 /// Actions after adapt: Pin the redundant solid pressures (if any)
174 {
175 PVDEquationsBase<2>::pin_redundant_nodal_solid_pressures(
176 solid_mesh_pt()->element_pt());
177 }
178
179 /// Doc the solution
181
182private:
183
184 /// Pointer to solid mesh
185 ElasticRefineableRectangularQuadMesh<ELEMENT>* Solid_mesh_pt;
186
187 /// DocInfo object for output
188 DocInfo Doc_info;
189
190};
191
192
193//===========start_of_constructor=======================================
194/// Constructor:
195//======================================================================
196template<class ELEMENT>
198{
199
200 // Create the mesh
201
202 // # of elements in x-direction
203 unsigned n_x=5;
204
205 // # of elements in y-direction
206 unsigned n_y=5;
207
208 // Domain length in x-direction
209 double l_x=1.0;
210
211 // Domain length in y-direction
212 double l_y=1.0;
213
214 //Now create the mesh
215 solid_mesh_pt() = new ElasticRefineableRectangularQuadMesh<ELEMENT>(
216 n_x,n_y,l_x,l_y);
217
218 // Copy across
219 Problem::mesh_pt()=solid_mesh_pt();
220
221 // Set error estimator
222 solid_mesh_pt()->spatial_error_estimator_pt()=new Z2ErrorEstimator;
223
224 //Assign the physical properties to the elements before any refinement
225 //Loop over the elements in the main mesh
226 unsigned n_element =solid_mesh_pt()->nelement();
227 for(unsigned i=0;i<n_element;i++)
228 {
229 //Cast to a solid element
230 ELEMENT *el_pt = dynamic_cast<ELEMENT*>(solid_mesh_pt()->element_pt(i));
231
232 // Set the constitutive law
233 el_pt->constitutive_law_pt()=&Global_Physical_Variables::Constitutive_law;
234 }
235
236 // Refine the mesh uniformly
237 solid_mesh_pt()->refine_uniformly();
238
239
240
241 // Pin nodal positions on all boundaries including the top one
242 for (unsigned b=0;b<4;b++)
243 {
244 unsigned n_side = solid_mesh_pt()->nboundary_node(b);
245
246 //Loop over the nodes
247 for(unsigned i=0;i<n_side;i++)
248 {
249 solid_mesh_pt()->boundary_node_pt(b,i)->pin_position(0);
250 solid_mesh_pt()->boundary_node_pt(b,i)->pin_position(1);
251 }
252 }
253
254
255// Pin the redundant solid pressures (if any)
256 PVDEquationsBase<2>::pin_redundant_nodal_solid_pressures(
257 solid_mesh_pt()->element_pt());
258
259 // Setup equation numbering scheme
260 cout << "Number of dofs: " << assign_eqn_numbers() << std::endl;
261
262 // Set output directory
263 Doc_info.set_directory("RESLT");
264
265} //end of constructor
266
267
268
269//==============start_doc===========================================
270/// Doc the solution
271//==================================================================
272template<class ELEMENT>
274{
275
276 ofstream some_file;
277 char filename[100];
278
279 // Number of plot points
280 unsigned n_plot = 5;
281
282 // Output shape of deformed body
283 //------------------------------
284 snprintf(filename, sizeof(filename), "%s/soln%i.dat",Doc_info.directory().c_str(),
285 Doc_info.number());
286 some_file.open(filename);
287 solid_mesh_pt()->output(some_file,n_plot);
288 some_file.close();
289
290 // Increment label for output files
291 Doc_info.number()++;
292
293} //end doc
294
295
296
297//=======start_of_main==================================================
298/// Driver code
299//======================================================================
300int main()
301{
302
303 //Set up the problem
305
306 // Doc initial domain shape
307 problem.doc_solution();
308
309 // Max. number of adaptations per solve
310 unsigned max_adapt=1;
311
312 //Parameter incrementation
313 unsigned nstep=2; // 16;
314 for(unsigned i=0;i<nstep;i++)
315 {
316 // Increment imposed boundary displacement
318
319 // Solve the problem with Newton's method, allowing
320 // up to max_adapt mesh adaptations after every solve.
321 problem.newton_solve(max_adapt);
322
323 // Doc solution
324 problem.doc_solution();
325
326 // For maximum stability: Reset the current nodal positions to be
327 // the "stress-free" ones -- this assignment means that the
328 // parameter study no longer corresponds to a physical experiment
329 // but is what we'd do if we wanted to use the solid solve
330 // to update a fluid mesh in an FSI problem, say.
331 problem.solid_mesh_pt()->set_lagrangian_nodal_coordinates();
332
333 }
334
335} //end of main
336
337
338
339
340
341
342
343
Problem class for deformation of elastic block by prescribed boundary motion.
ElasticRefineableRectangularQuadMesh< ELEMENT > *& solid_mesh_pt()
Access function for the solid mesh.
void actions_after_newton_solve()
Update function (empty)
ElasticRefineableRectangularQuadMesh< ELEMENT > * Solid_mesh_pt
Pointer to solid mesh.
void actions_after_adapt()
Actions after adapt: Pin the redundant solid pressures (if any)
void doc_solution()
Doc the solution.
PrescribedBoundaryDisplacementProblem()
Constructor:
void actions_before_newton_solve()
Update boundary position directly.
Warped line in 2D space.
void position(const unsigned &t, const Vector< double > &zeta, Vector< double > &r) const
Parametrised position on object: r(zeta). Evaluated at previous timestep. t=0: current time; t>0: pre...
~WarpedLine()
Empty Destructor.
WarpedLine(const WarpedLine &dummy)
Broken copy constructor.
WarpedLine(const double &ampl)
Constructor: Specify amplitude of deflection from straight horizontal line.
void position(const Vector< double > &zeta, Vector< double > &r) const
Position vector at Lagrangian coordinate zeta.
double Ampl
Amplitude of perturbation.
void operator=(const WarpedLine &)
Broken assignment operator.
double & ampl()
Access to amplitude.
WarpedLine Boundary_geom_object(0.0)
GeomObject specifying the shape of the boundary: Initially it's flat.
int main()
Driver code.