macro_element.h
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 #ifndef OOMPH_MACROELEMENT_HEADER
27 #define OOMPH_MACROELEMENT_HEADER
28 
29 
30 // Config header generated by autoconfig
31 #ifdef HAVE_CONFIG_H
32 #include <oomph-lib-config.h>
33 #endif
34 
35 #ifdef OOMPH_HAS_MPI
36 #include "mpi.h"
37 #endif
38 
39 // oomph-lib headers
40 #include "Vector.h"
41 #include "oomph_utilities.h"
42 #include "quadtree.h"
43 #include "octree.h"
44 
45 namespace oomph
46 {
47  class Domain;
48 
49  //================================================================
50  /// Base class for MacroElement s that are used during mesh refinement
51  /// in domains with curvlinear and/or time-dependent
52  /// boundaries; see the description of the Domain class for more
53  /// details.
54  ///
55  /// A macro element provides a parametrisation of a sub-domain
56  /// by providing a mapping between a set of local coordinates
57  /// \f$ {\bf S} \f$ and global coordinates \f$ {\bf r} ({\bf S}) \f$ . This
58  /// must be implemented in the function
59  ///
60  /// \code MacroElement::macro_map(...) \endcode
61  ///
62  /// The time-dependent version of the macro map returns the mapping
63  /// from local to global coordinates: \f$ {\bf r} (t,{\bf S}) \f$
64  /// where t is the discrete timelevel: t=0: current time; t>0:
65  /// previous timestep.
66  ///
67  /// The MacroElement s establish the current (and previous) domain
68  /// shape via member function pointers to the Domain 's
69  /// \code Domain::macro_element_boundary(...) \endcode
70  /// member function.
71  //=================================================================
73  {
74  public:
75  /// Constructor: Pass pointer to Domain and the number of the
76  /// MacroElement within that Domain.
79  {
80 #ifdef LEAK_CHECK
82 #endif
83  }
84 
85  /// Default constructor (empty and broken)
87  {
88  throw OomphLibError("Don't call empty constructor for MacroElement!",
89  OOMPH_CURRENT_FUNCTION,
90  OOMPH_EXCEPTION_LOCATION);
91  }
92 
93 
94  /// Broken copy constructor
95  MacroElement(const MacroElement& dummy) = delete;
96 
97  /// Broken assignment operator
98  void operator=(const MacroElement&) = delete;
99 
100  /// Empty destructor
101  virtual ~MacroElement()
102  {
103 #ifdef LEAK_CHECK
105 #endif
106  }
107 
108 
109  /// Plot: x,y (or x,y,z) at current time in tecplot
110  /// format
111  void output(std::ostream& outfile, const int& nplot)
112  {
113  unsigned t = 0;
114  output(t, outfile, nplot);
115  }
116 
117 
118  /// Plot: x,y (or x,y,z) in tecplot format at time level t
119  /// (t=0: current; t>0: previous)
120  virtual void output(const unsigned& t,
121  std::ostream& outfile,
122  const unsigned& nplot) = 0;
123 
124 
125  /// The mapping from local to global coordinates at the current time : r(s)
127  {
128  // Evaluate at current timestep
129  unsigned t = 0;
130  macro_map(t, s, r);
131  }
132 
133 
134  /// The time-dependent mapping from local to global coordinates:
135  /// r(t,s).
136  /// t is the discrete timelevel: t=0: current time; t>0: previous timestep.
137  virtual void macro_map(const unsigned& t,
138  const Vector<double>& s,
139  Vector<double>& r) = 0;
140 
141 
142  /// Get global position r(s) at continuous time value, t.
143  virtual void macro_map(const double& t,
144  const Vector<double>& s,
145  Vector<double>& r)
146  {
147  // Create an output stream
148  std::ostringstream error_message_stream;
149 
150  // Create an error message
151  error_message_stream << "The function macro_map(...) is broken virtual\n"
152  << "If you need it, please implement it!"
153  << std::endl;
154 
155  // Throw an error
156  throw OomphLibError(error_message_stream.str(),
157  OOMPH_CURRENT_FUNCTION,
158  OOMPH_EXCEPTION_LOCATION);
159  } // End of macro_map
160 
161 
162  /// Output all macro element boundaries as tecplot zones
163  virtual void output_macro_element_boundaries(std::ostream& outfile,
164  const unsigned& nplot) = 0;
165 
166 
167  /// the jacobian of the mapping from the macro coordinates to the
168  /// global
169  /// coordinates
171  const unsigned& t, const Vector<double>& s, DenseMatrix<double>& jacobian)
172  {
173  // error message stream
174  std::ostringstream error_message;
175  error_message << "assemble_macro_to_eulerian_jacobian(...) not \n"
176  << "implemented for this element\n"
177  << std::endl;
178  // throw error
179  throw OomphLibError(
180  error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
181  }
182 
183 
184  /// Assembles the second derivative jacobian of the mapping from the
185  /// macro coordinates to the global coordinates
187  const unsigned& t,
188  const Vector<double>& s,
189  DenseMatrix<double>& jacobian2)
190  {
191  // error message stream
192  std::ostringstream error_message;
193  error_message << "assemble_macro_to_eulerian_jacobian2(...) not \n"
194  << "implemented for this element\n"
195  << std::endl;
196  // throw error
197  throw OomphLibError(
198  error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
199  }
200 
201 
202  /// Assembles the jacobian of the mapping from the macro coordinates
203  /// to
204  /// the global coordinates
206  DenseMatrix<double>& jacobian)
207  {
208  unsigned t = 0;
210  }
211 
212 
213  /// Assembles the second derivative jacobian of the mapping from the
214  /// macro coordinates to the global coordinates
216  DenseMatrix<double>& jacobian2)
217  {
218  unsigned t = 0;
220  }
221 
222  /// Access function to the Macro_element_number
224  {
225  return Macro_element_number;
226  }
227 
228  /// Access function to the Domain_pt
230  {
231  return Domain_pt;
232  }
233 
234  protected:
235  /// Pointer to domain
237 
238  /// What is the number of the current macro element within its domain
240  };
241 
242 
243  /// ////////////////////////////////////////////////////////////////////////
244  /// ////////////////////////////////////////////////////////////////////////
245  /// ////////////////////////////////////////////////////////////////////////
246 
247 
248  //================================================================
249  /// QMacroElement
250  ///
251  /// QMacroElements are MacroElement s with linear/quadrilateral/hexahedral
252  /// shape. This class is empty and simply establishes the dimension
253  /// as the template parameter.
254  //=================================================================
255  template<int DIM>
257  {
258  };
259 
260 
261  //================================================================
262  /// QMacroElement specialised to 2 spatial dimensions.
263  ///
264  /// The macro element mapping is based on the member function pointer
265  /// to the associated Domain 's
266  /// \code Domain::macro_element_boundary(...) \endcode
267  /// function which provides a parametrisation of the macro element's
268  /// boundaries in the form:
269  /// \f[ {\bf f}_{i} (t,{\bf S}) \f]
270  /// where
271  /// - \f$ i \f$ labels the boundary (N/S/W/E)
272  /// - \f$ {\bf S} \in [-1,1]^1 \f$ is the (1D) Vector of local coordinate(s)
273  /// along the boundary.
274  /// - \f$ {\bf f} \f$ is the position Vector to the boundary.
275  /// - \f$ t \f$ is the time level (t=0: current; t>0 previous timestep)
276  //=================================================================
277  template<>
278  class QMacroElement<2> : public MacroElement
279  {
280  public:
281  /// Constructor: Pass the pointer to the domain and the macro
282  /// element's number within this domain
285 
286 
287  /// Default constructor (empty and broken)
289  {
290  throw OomphLibError("Don't call empty constructor for QMacroElement!",
291  OOMPH_CURRENT_FUNCTION,
292  OOMPH_EXCEPTION_LOCATION);
293  }
294 
295  /// Broken copy constructor
296  QMacroElement(const QMacroElement& dummy) = delete;
297 
298  /// Broken assignment operator
299  void operator=(const QMacroElement&) = delete;
300 
301  /// Empty destructor
302  virtual ~QMacroElement(){};
303 
304  /// Plot: x,y in tecplot format at time level t (t=0: current;
305  /// t>0: previous)
306  void output(const unsigned& t, std::ostream& outfile, const unsigned& nplot)
307  {
308  Vector<double> x(2), f(2);
309  outfile << "ZONE I=" << nplot << ", J=" << nplot << std::endl;
310  for (unsigned i = 0; i < nplot; i++)
311  {
312  x[1] = -1.0 + 2.0 * double(i) / double(nplot - 1);
313  for (unsigned j = 0; j < nplot; j++)
314  {
315  x[0] = -1.0 + 2.0 * double(j) / double(nplot - 1);
316  macro_map(t, x, f);
317  outfile << f[0] << " " << f[1] << std::endl;
318  }
319  }
320  }
321 
322 
323  /// Output all macro element boundaries as tecplot zones
324  void output_macro_element_boundaries(std::ostream& outfile,
325  const unsigned& nplot);
326 
327  /// Get global position r(S) at discrete time level t.
328  /// t=0: Present time; t>0: previous timestep.
329  void macro_map(const unsigned& t,
330  const Vector<double>& S,
331  Vector<double>& r);
332 
333 
334  /// Get global position r(s) at continuous time value, t.
335  void macro_map(const double& t, const Vector<double>& s, Vector<double>& r);
336 
337 
338  /// assemble the jacobian of the mapping from the macro coordinates to
339  /// the global coordinates
341  const unsigned& t,
342  const Vector<double>& s,
343  DenseMatrix<double>& jacobian);
344 
345 
346  /// Assembles the second derivative jacobian of the mapping from the
347  /// macro coordinates to global coordinates x
349  const unsigned& t,
350  const Vector<double>& s,
351  DenseMatrix<double>& jacobian2);
352  };
353 
354 
355  //================================================================
356  /// QMacroElement specialised to 3 spatial dimensions.
357  ///
358  /// The macro element mapping is based on the member function pointer
359  /// to the associated Domain 's
360  /// \code Domain::macro_element_boundary(...) \endcode
361  /// function which provides a parametrisation of the macro element's
362  /// boundaries in the form:
363  /// \f[ {\bf f}_{i} (t,{\bf S}) \f]
364  /// where
365  /// - \f$ i \f$ labels the boundary (L/R/D/U/B/F)
366  /// - \f$ {\bf S} \in [-1,1]^2 \f$ is the (2D) Vector of local coordinate(s)
367  /// along the boundary.
368  /// - \f$ {\bf f} \f$ is the position Vector to the boundary.
369  /// - \f$ t \f$ is the time level (t=0: current; t>0 previous timestep)
370  //=================================================================
371  template<>
372  class QMacroElement<3> : public MacroElement
373  {
374  public:
375  /// Constructor: Pass the pointer to the domain and the macro
376  /// element's number within this domain
379 
380  /// Default constructor (empty and broken)
382  {
383  throw OomphLibError("Don't call empty constructor for QMacroElement!",
384  OOMPH_CURRENT_FUNCTION,
385  OOMPH_EXCEPTION_LOCATION);
386  }
387 
388  /// Broken copy constructor
389  QMacroElement(const QMacroElement& dummy) = delete;
390 
391  /// Broken assignment operator
392  void operator=(const QMacroElement&) = delete;
393 
394  /// Empty destructor
395  virtual ~QMacroElement(){};
396 
397 
398  /// Plot: x,y in tecplot format at time level t (t=0: current;
399  /// t>0: previous)
400  void output(const unsigned& t, std::ostream& outfile, const unsigned& nplot)
401  {
402  Vector<double> x(3), f(3);
403 
404  outfile << "ZONE I=" << nplot << ", J=" << nplot << ", k=" << nplot
405  << std::endl;
406  for (unsigned i = 0; i < nplot; i++)
407  {
408  x[2] = -1.0 + 2.0 * double(i) / double(nplot - 1);
409 
410  for (unsigned j = 0; j < nplot; j++)
411  {
412  x[1] = -1.0 + 2.0 * double(j) / double(nplot - 1);
413 
414  for (unsigned k = 0; k < nplot; k++)
415  {
416  x[0] = -1.0 + 2.0 * double(k) / double(nplot - 1);
417 
418  macro_map(t, x, f);
419 
420  outfile << f[0] << " " << f[1] << " " << f[2] << std::endl;
421  }
422  }
423  }
424  }
425 
426 
427  /// Output all macro element boundaries as tecplot zones
428  void output_macro_element_boundaries(std::ostream& outfile,
429  const unsigned& nplot);
430 
431  /// Get global position r(S) at discrete time level t.
432  /// t=0: Present time; t>0: previous timestep.
433  void macro_map(const unsigned& t,
434  const Vector<double>& S,
435  Vector<double>& r);
436  };
437 
438 } // namespace oomph
439 
440 #endif
static char t char * s
Definition: cfortran.h:568
cstr elem_len * i
Definition: cfortran.h:603
char t
Definition: cfortran.h:568
Base class for Domains with curvilinear and/or time-dependent boundaries. Domain boundaries are typic...
Definition: domain.h:67
Base class for MacroElement s that are used during mesh refinement in domains with curvlinear and/or ...
Definition: macro_element.h:73
Domain * Domain_pt
Pointer to domain.
virtual void assemble_macro_to_eulerian_jacobian2(const unsigned &t, const Vector< double > &s, DenseMatrix< double > &jacobian2)
Assembles the second derivative jacobian of the mapping from the macro coordinates to the global coor...
void assemble_macro_to_eulerian_jacobian(const Vector< double > &s, DenseMatrix< double > &jacobian)
Assembles the jacobian of the mapping from the macro coordinates to the global coordinates.
virtual void output(const unsigned &t, std::ostream &outfile, const unsigned &nplot)=0
Plot: x,y (or x,y,z) in tecplot format at time level t (t=0: current; t>0: previous)
virtual void macro_map(const double &t, const Vector< double > &s, Vector< double > &r)
Get global position r(s) at continuous time value, t.
virtual void output_macro_element_boundaries(std::ostream &outfile, const unsigned &nplot)=0
Output all macro element boundaries as tecplot zones.
void operator=(const MacroElement &)=delete
Broken assignment operator.
virtual void macro_map(const unsigned &t, const Vector< double > &s, Vector< double > &r)=0
The time-dependent mapping from local to global coordinates: r(t,s). t is the discrete timelevel: t=0...
void macro_map(const Vector< double > &s, Vector< double > &r)
The mapping from local to global coordinates at the current time : r(s)
void output(std::ostream &outfile, const int &nplot)
Plot: x,y (or x,y,z) at current time in tecplot format.
unsigned Macro_element_number
What is the number of the current macro element within its domain.
Domain *& domain_pt()
Access function to the Domain_pt.
virtual ~MacroElement()
Empty destructor.
unsigned & macro_element_number()
Access function to the Macro_element_number.
virtual void assemble_macro_to_eulerian_jacobian(const unsigned &t, const Vector< double > &s, DenseMatrix< double > &jacobian)
the jacobian of the mapping from the macro coordinates to the global coordinates
MacroElement(Domain *domain_pt, const unsigned &macro_element_number)
Constructor: Pass pointer to Domain and the number of the MacroElement within that Domain.
Definition: macro_element.h:77
MacroElement(const MacroElement &dummy)=delete
Broken copy constructor.
void assemble_macro_to_eulerian_jacobian2(const Vector< double > &s, DenseMatrix< double > &jacobian2)
Assembles the second derivative jacobian of the mapping from the macro coordinates to the global coor...
MacroElement()
Default constructor (empty and broken)
Definition: macro_element.h:86
An OomphLibError object which should be thrown when an run-time error is encountered....
void output(const unsigned &t, std::ostream &outfile, const unsigned &nplot)
Plot: x,y in tecplot format at time level t (t=0: current; t>0: previous)
void operator=(const QMacroElement &)=delete
Broken assignment operator.
QMacroElement(const QMacroElement &dummy)=delete
Broken copy constructor.
virtual ~QMacroElement()
Empty destructor.
QMacroElement(Domain *domain_pt, const unsigned &macro_element_number)
Constructor: Pass the pointer to the domain and the macro element's number within this domain.
QMacroElement()
Default constructor (empty and broken)
QMacroElement(Domain *domain_pt, const unsigned &macro_element_number)
Constructor: Pass the pointer to the domain and the macro element's number within this domain.
QMacroElement()
Default constructor (empty and broken)
void output(const unsigned &t, std::ostream &outfile, const unsigned &nplot)
Plot: x,y in tecplot format at time level t (t=0: current; t>0: previous)
virtual ~QMacroElement()
Empty destructor.
QMacroElement(const QMacroElement &dummy)=delete
Broken copy constructor.
void operator=(const QMacroElement &)=delete
Broken assignment operator.
//////////////////////////////////////////////////////////////////////// ////////////////////////////...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...