spacetime_navier_stokes_block_preconditionable_elements.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 // Non-inline functions for BlockPrecSpaceTimeNavierStokes elements
28 
29 /// /////////////////////////////////////////////////////////////////////////
30 /// /////////////////////////////////////////////////////////////////////////
31 /// /////////////////////////////////////////////////////////////////////////
32 
33 namespace oomph
34 {
35  //=====start_of_setup=========================================================
36  /// The setup function...
37  //============================================================================
39  std::list<std::pair<unsigned long, unsigned>>& dof_lookup_list) const
40  {
41  // Number of nodes
42  unsigned n_node = this->nnode();
43 
44  // Temporary pair (used to store dof lookup prior to being added to list)
45  std::pair<unsigned, unsigned> dof_lookup;
46 
47  // The number of nodes in the each direction
48  unsigned n_node_1d = this->nnode_1d();
49 
50  // Make sure that we're using quadratic interpolation otherwise this might
51  // go wrong...
52  if (n_node_1d != 3)
53  {
54  // Create an output stream
55  std::ostringstream error_message_stream;
56 
57  // Create an error message
58  error_message_stream
59  << "Can only deal with Navier-Stokes elements which "
60  << "use quadratic interpolation at the moment. Using " << n_node_1d
61  << " nodes in each direction" << std::endl;
62 
63  // Throw an error
64  throw OomphLibError(error_message_stream.str(),
65  OOMPH_CURRENT_FUNCTION,
66  OOMPH_EXCEPTION_LOCATION);
67  }
68 
69  // Loop over the nodes
70  for (unsigned j = 0; j < n_node; j++)
71  {
72  // Only bother if the node isn't a copy...
73  if (!(this->node_pt(j)->is_a_copy()))
74  {
75  // Storage for the local time slice ID (0<i_local<n_node_1d)
76  unsigned i_local = 0;
77 
78  // If we're on the first time slice
79  if (j < n_node_1d * n_node_1d)
80  {
81  // In the first local time slice
82  i_local = 0;
83  }
84  // If we're in the second time slice (already excluded the first time
85  // slice)
86  else if (j < 2 * n_node_1d * n_node_1d)
87  {
88  // In the second local time slice
89  i_local = 1;
90  }
91  // If we're in the final time slice (already excluded the first/second
92  // slice)
93  else if (j < 3 * n_node_1d * n_node_1d)
94  {
95  // In the final local time slice
96  i_local = 2;
97  }
98  // We should never get here
99  else
100  {
101  // Create an output stream
102  std::ostringstream error_message_stream;
103 
104  // Create an error message
105  error_message_stream << "Looping over too many nodes!" << std::endl;
106 
107  // Throw an error
108  throw OomphLibError(error_message_stream.str(),
109  OOMPH_CURRENT_FUNCTION,
110  OOMPH_EXCEPTION_LOCATION);
111  }
112 
113  // The number of dofs at this node
114  unsigned n_dof = this->node_pt(j)->nvalue();
115 
116  // Loop over components
117  for (unsigned i = 0; i < n_dof; i++)
118  {
119  // Determine local eqn number
120  int local_eqn_number = this->nodal_local_eqn(j, i);
121 
122  // Ignore pinned values - far away degrees of freedom resulting
123  // from hanging nodes can be ignored since these are be dealt
124  // with by the element containing their master nodes
125  if (local_eqn_number >= 0)
126  {
127  // The id shift (depending on which elemental time slice we're in)
128  unsigned elemental_id_shift = 5 * Time_slab_id;
129 
130  // Store dof lookup in temporary pair: Global equation number
131  // is the first entry in pair
132  dof_lookup.first = this->eqn_number(local_eqn_number);
133 
134  // If we're on the first time slice
135  if (i_local == 0)
136  {
137  // Here i can range only between 0 and 2 (but it's also an
138  // unsigned so we only need to check if it's strictly greater than
139  // 2)
140  if (i > 2)
141  {
142  // Create an output stream
143  std::ostringstream error_message_stream;
144 
145  // Create an error message
146  error_message_stream
147  << "Don't know what to do when i=" << i
148  << ". Can only handle when i is between 0 and 2!"
149  << std::endl;
150 
151  // Throw an error
152  throw OomphLibError(error_message_stream.str(),
153  OOMPH_CURRENT_FUNCTION,
154  OOMPH_EXCEPTION_LOCATION);
155  }
156 
157  // Set dof numbers: Dof number is the second entry in pair
158  dof_lookup.second = elemental_id_shift + i;
159  }
160  // If we're on the second time slice
161  else if (i_local == 1)
162  {
163  // Here i can range only between 0 and 1
164  if (i > 1)
165  {
166  // Create an output stream
167  std::ostringstream error_message_stream;
168 
169  // Create an error message
170  error_message_stream
171  << "Don't know what to do when i=" << i
172  << ". Can only handle when i is either 0 or 1!" << std::endl;
173 
174  // Throw an error
175  throw OomphLibError(error_message_stream.str(),
176  OOMPH_CURRENT_FUNCTION,
177  OOMPH_EXCEPTION_LOCATION);
178  }
179 
180  // The local dof shift given which local time slice we're on (i.e.
181  // which node we're on in the time-direction). We've already
182  // covered 2 velocities and 1 pressure so the dof shift is 3.
183  unsigned local_id_shift = 3;
184 
185  // Set dof numbers: Dof number is the second entry in pair
186  dof_lookup.second = elemental_id_shift + local_id_shift + i;
187  }
188  // If we're on the final time slice
189  else if (i_local == 2)
190  {
191  // Here i can range only between 0 and 2
192  if (i > 2)
193  {
194  // Create an output stream
195  std::ostringstream error_message_stream;
196 
197  // Create an error message
198  error_message_stream
199  << "Don't know what to do when i=" << i
200  << ". Can only handle when i is between 0 and 2!"
201  << std::endl;
202 
203  // Throw an error
204  throw OomphLibError(error_message_stream.str(),
205  OOMPH_CURRENT_FUNCTION,
206  OOMPH_EXCEPTION_LOCATION);
207  }
208 
209  // The local dof shift given which local time slice we're on (i.e.
210  // which node we're on in the time-direction). We've already
211  // covered 4 velocities and 1 pressure so the dof shift is 5.
212  unsigned local_id_shift = 5;
213 
214  // Set dof numbers: Dof number is the second entry in pair
215  dof_lookup.second = elemental_id_shift + local_id_shift + i;
216  } // if (i_local==0)
217 
218  // Add to list
219  dof_lookup_list.push_front(dof_lookup);
220  }
221  } // for (unsigned i=0;i<DIM;i++)
222  } // if (!(this->node_pt(j)->is_a_copy()))
223  } // for (unsigned j=0;j<n_node;j++)
224  } // End of get_dof_numbers_for_unknowns
225 } // End of namespace oomph
cstr elem_len * i
Definition: cfortran.h:603
void get_dof_numbers_for_unknowns(std::list< std::pair< unsigned long, unsigned >> &dof_lookup_list) const
Overload the pure virtual base class implementation. Create a list of pairs for all unknowns in this ...
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
Definition: nodes.h:483
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Return the local equation number corresponding to the i-th value at the n-th local node.
Definition: elements.h:1432
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
virtual unsigned nnode_1d() const
Return the number of nodes along one edge of the element Default is to return zero — must be overload...
Definition: elements.h:2218
unsigned long eqn_number(const unsigned &ieqn_local) const
Return the global equation number corresponding to the ieqn_local-th local equation number.
Definition: elements.h:704
int local_eqn_number(const unsigned long &ieqn_global) const
Return the local equation number corresponding to the ieqn_global-th global equation number....
Definition: elements.h:726
An OomphLibError object which should be thrown when an run-time error is encountered....
//////////////////////////////////////////////////////////////////// ////////////////////////////////...