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-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 //============================================================================
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
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....
//////////////////////////////////////////////////////////////////// ////////////////////////////////...