mixed_order_petrov_galerkin_space_time_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  //============================================================================
40  std::list<std::pair<unsigned long, unsigned>>& dof_lookup_list) const
41  {
42  // Number of nodes
43  unsigned n_node = this->nnode();
44 
45  // Temporary pair (used to store dof lookup prior to being added to list)
46  std::pair<unsigned, unsigned> dof_lookup;
47 
48  // The number of nodes in the each direction
49  unsigned n_node_1d = this->nnode_1d();
50 
51  // Make sure that we're using quadratic interpolation otherwise this might
52  // go wrong...
53  if (n_node_1d != 3)
54  {
55  // Create an output stream
56  std::ostringstream error_message_stream;
57 
58  // Create an error message
59  error_message_stream
60  << "Can only deal with Navier-Stokes elements which "
61  << "use quadratic interpolation at the moment. Using " << n_node_1d
62  << " nodes in each direction" << std::endl;
63 
64  // Throw an error
65  throw OomphLibError(error_message_stream.str(),
66  OOMPH_CURRENT_FUNCTION,
67  OOMPH_EXCEPTION_LOCATION);
68  }
69 
70  // Loop over the nodes
71  for (unsigned j = 0; j < n_node; j++)
72  {
73  // Only bother if the node isn't a copy...
74  if (!(this->node_pt(j)->is_a_copy()))
75  {
76  // Storage for the local time slice ID (0<i_local<n_node_1d)
77  unsigned i_local = 0;
78 
79  // If we're on the first time slice
80  if (j < n_node_1d * n_node_1d)
81  {
82  // In the first local time slice
83  i_local = 0;
84  }
85  // If we're in the second time slice (already excluded the first time
86  // slice)
87  else if (j < 2 * n_node_1d * n_node_1d)
88  {
89  // In the second local time slice
90  i_local = 1;
91  }
92  // If we're in the final time slice (already excluded the first/second
93  // slice)
94  else if (j < 3 * n_node_1d * n_node_1d)
95  {
96  // In the final local time slice
97  i_local = 2;
98  }
99  // We should never get here
100  else
101  {
102  // Create an output stream
103  std::ostringstream error_message_stream;
104 
105  // Create an error message
106  error_message_stream << "Looping over too many nodes!" << std::endl;
107 
108  // Throw an error
109  throw OomphLibError(error_message_stream.str(),
110  OOMPH_CURRENT_FUNCTION,
111  OOMPH_EXCEPTION_LOCATION);
112  }
113 
114  // The number of dofs at this node
115  unsigned n_dof = this->node_pt(j)->nvalue();
116 
117  // Loop over components
118  for (unsigned i = 0; i < n_dof; i++)
119  {
120  // Determine local eqn number
121  int local_eqn_number = this->nodal_local_eqn(j, i);
122 
123  // Ignore pinned values - far away degrees of freedom resulting
124  // from hanging nodes can be ignored since these are be dealt
125  // with by the element containing their master nodes
126  if (local_eqn_number >= 0)
127  {
128  // The id shift (depending on which elemental time slice we're in)
129  unsigned elemental_id_shift = 3 * Time_slab_id;
130 
131  // Store dof lookup in temporary pair: Global equation number
132  // is the first entry in pair
133  dof_lookup.first = this->eqn_number(local_eqn_number);
134 
135  // If we're on the first time slice
136  if (i_local == 0)
137  {
138  // Set dof numbers: Dof number is the second entry in pair
139  dof_lookup.second = elemental_id_shift + i;
140  }
141  // If we're on the second time slice
142  else if (i_local == 1)
143  {
144  // Create an output stream
145  std::ostringstream error_message_stream;
146 
147  // Create an error message
148  error_message_stream
149  << "All nodes strictly on the interior of the "
150  << "elements temporal\nboundaries should be pinned "
151  << "in the mixed order element!" << std::endl;
152 
153  // Throw an error
154  throw OomphLibError(error_message_stream.str(),
155  OOMPH_CURRENT_FUNCTION,
156  OOMPH_EXCEPTION_LOCATION);
157  }
158  // If we're on the final time slice
159  else if (i_local == 2)
160  {
161  // The local dof shift given which local time slice we're on (i.e.
162  // which node we're on in the time-direction). We've already
163  // covered 2 velocities and 1 pressure so the dof shift is 3.
164  unsigned local_id_shift = 3;
165 
166  // Set dof numbers: Dof number is the second entry in pair
167  dof_lookup.second = elemental_id_shift + local_id_shift + i;
168  } // if (i_local==0)
169 
170  // Add to list
171  dof_lookup_list.push_front(dof_lookup);
172  }
173  } // for (unsigned i=0;i<DIM;i++)
174  } // if (!(this->node_pt(j)->is_a_copy()))
175  } // for (unsigned j=0;j<n_node;j++)
176  } // End of get_dof_numbers_for_unknowns
177 } // 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....
//////////////////////////////////////////////////////////////////// ////////////////////////////////...