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-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 BlockPrecSpaceTimeUnsteadyHeat elements
28 
29 /// /////////////////////////////////////////////////////////////////////////
30 /// /////////////////////////////////////////////////////////////////////////
31 /// /////////////////////////////////////////////////////////////////////////
32 
33 namespace 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....
//////////////////////////////////////////////////////////////////// ////////////////////////////////...