space_time_unsteady_heat_mixed_order_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 BlockPrecSpaceTimeUnsteadyHeat elements
28
29/// /////////////////////////////////////////////////////////////////////////
30/// /////////////////////////////////////////////////////////////////////////
31/// /////////////////////////////////////////////////////////////////////////
32
33namespace oomph
34{
35 //=====start_of_setup=========================================================
36 /// The setup function...
37 //============================================================================
38 template<unsigned SPATIAL_DIM, unsigned NNODE_1D>
41 std::list<std::pair<unsigned long, unsigned>>& dof_lookup_list) const
42 {
43 // Number of nodes
44 unsigned n_node = this->nnode();
45
46 // Temporary pair (used to store dof lookup prior to being added to list)
47 std::pair<unsigned, unsigned> dof_lookup;
48
49 // Loop over the nodes but ignore the nodes on the first local time-slice
50 // because their dof number will either be set by elements from the
51 // previous space-time slab (including on time-periodic meshes) or they'll
52 // be pinned through an initial condition.
53 for (unsigned i = NNODE_1D * NNODE_1D; i < n_node; i++)
54 {
55 // Storage for the local time slice ID (0<=i_temporal<=NNODE_1D-1)
56 unsigned i_temporal = 0;
57
58 // The spatial node number
59 unsigned i_spatial = i % (NNODE_1D * NNODE_1D);
60
61 // Which local time slice are we in?
62 i_temporal = (i - i_spatial) / (NNODE_1D * NNODE_1D);
63
64 // Find the index at which the variable is stored
65 unsigned u_nodal_index = this->u_index_ust_heat();
66
67 // Determine local eqn number
68 int local_eqn_number = this->nodal_local_eqn(i, u_nodal_index);
69
70 // Ignore pinned values - far away degrees of freedom resulting
71 // from hanging nodes can be ignored since these are be dealt
72 // with by the element containing their master nodes
73 if (local_eqn_number >= 0)
74 {
75 // The only unpinned dofs we should encounter at this point should be
76 // those on the final temporal boundary of the space-time element
77 if (i_temporal != NNODE_1D - 1)
78 {
79 // Create an output stream
80 std::ostringstream error_message_stream;
81
82 // Create an error message
83 error_message_stream << "All nodes strictly on the interior of the "
84 << "elements temporal boundaries\nshould be "
85 << "pinned in the mixed order element!"
86 << std::endl;
87
88 // Throw an error
89 throw OomphLibError(error_message_stream.str(),
90 OOMPH_CURRENT_FUNCTION,
91 OOMPH_EXCEPTION_LOCATION);
92 }
93
94 // Store dof lookup in temporary pair: Global equation number
95 // is the first entry in pair
96 dof_lookup.first = this->eqn_number(local_eqn_number);
97
98 // Set dof numbers: dof number is the second entry in pair
99 dof_lookup.second = (this->Time_slab_id);
100
101 // Add to list
102 dof_lookup_list.push_front(dof_lookup);
103 } // if (local_eqn_number>=0)
104 } // for (unsigned i=NNODE_1D*NNODE_1D; i<n_node; i++)
105 } // End of get_dof_numbers_for_unknowns
106
107
108 //=====start_of_setup=========================================================
109 /// The setup function...
110 //============================================================================
111 template<unsigned SPATIAL_DIM, unsigned NNODE_1D>
113 NNODE_1D>::
114 get_dof_numbers_for_unknowns(
115 std::list<std::pair<unsigned long, unsigned>>& dof_lookup_list) const
116 {
117 // Number of nodes
118 unsigned n_node = this->nnode();
119
120 // Temporary pair (used to store dof lookup prior to being added to list)
121 std::pair<unsigned, unsigned> dof_lookup;
122
123 // Loop over the nodes but ignore the nodes on the first local time-slice
124 // because their dof number will either be set by elements from the
125 // previous space-time slab (including on time-periodic meshes) or they'll
126 // be pinned through an initial condition.
127 for (unsigned i = NNODE_1D * NNODE_1D; i < n_node; i++)
128 {
129 // Storage for the local time slice ID (0<=i_temporal<=NNODE_1D-1)
130 unsigned i_temporal = 0;
131
132 // The spatial node number
133 unsigned i_spatial = i % (NNODE_1D * NNODE_1D);
134
135 // Which local time slice are we in?
136 i_temporal = (i - i_spatial) / (NNODE_1D * NNODE_1D);
137
138 // Find the index at which the variable is stored
139 unsigned u_nodal_index = this->u_index_ust_heat();
140
141 // Determine local eqn number
142 int local_eqn_number = this->nodal_local_eqn(i, u_nodal_index);
143
144 // Ignore pinned values - far away degrees of freedom resulting
145 // from hanging nodes can be ignored since these are be dealt
146 // with by the element containing their master nodes
147 if (local_eqn_number >= 0)
148 {
149 // The only unpinned dofs we should encounter at this point should be
150 // those on the final temporal boundary of the space-time element
151 if (i_temporal != NNODE_1D - 1)
152 {
153 // Create an output stream
154 std::ostringstream error_message_stream;
155
156 // Create an error message
157 error_message_stream << "All nodes strictly on the interior of the "
158 << "elements temporal boundaries\nshould be "
159 << "pinned in the mixed order element!"
160 << std::endl;
161
162 // Throw an error
163 throw OomphLibError(error_message_stream.str(),
164 OOMPH_CURRENT_FUNCTION,
165 OOMPH_EXCEPTION_LOCATION);
166 }
167
168 // Store dof lookup in temporary pair: Global equation number
169 // is the first entry in pair
170 dof_lookup.first = this->eqn_number(local_eqn_number);
171
172 // Set dof numbers: dof number is the second entry in pair
173 dof_lookup.second = (this->Time_slab_id);
174
175 // Add to list
176 dof_lookup_list.push_front(dof_lookup);
177 } // if (local_eqn_number>=0)
178 } // for (unsigned i=NNODE_1D*NNODE_1D; i<n_node; i++)
179 } // End of get_dof_numbers_for_unknowns
180
181
182 //====================================================================
183 // Force build of templates
184 //====================================================================
189 2>;
191 3>;
193 4>;
194} // 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 ...
An OomphLibError object which should be thrown when an run-time error is encountered....
//////////////////////////////////////////////////////////////////// ////////////////////////////////...