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-2022 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
33namespace 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
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
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
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....
//////////////////////////////////////////////////////////////////// ////////////////////////////////...