www.mooseframework.org
MooseVariableScalar.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "MooseVariableScalar.h"
11 #include "SubProblem.h"
12 #include "SystemBase.h"
13 #include "Assembly.h"
14 #include "SystemBase.h"
15 
16 // libMesh
17 #include "libmesh/numeric_vector.h"
18 #include "libmesh/dof_map.h"
19 
20 #include <limits>
21 
23  const FEType & fe_type,
24  SystemBase & sys,
25  Assembly & assembly,
26  Moose::VarKindType var_kind,
27  THREAD_ID tid)
28  : MooseVariableBase(var_num, fe_type, sys, var_kind, tid),
29  _assembly(assembly),
30  _need_u_dot(false),
31  _need_u_dotdot(false),
32  _need_u_dot_old(false),
33  _need_u_dotdot_old(false),
34  _need_du_dot_du(false),
35  _need_du_dotdot_du(false)
36 {
37  auto num_vector_tags = _sys.subproblem().numVectorTags();
38 
39  _vector_tag_u.resize(num_vector_tags);
40  _need_vector_tag_u.resize(num_vector_tags);
41 
42  auto num_matrix_tags = _sys.subproblem().numMatrixTags();
43 
44  _matrix_tag_u.resize(num_matrix_tags);
45  _need_matrix_tag_u.resize(num_matrix_tags);
46 }
47 
49 {
50  _u.release();
51  _u_old.release();
52  _u_older.release();
53 
54  _u_dot.release();
60 
61  for (auto & _tag_u : _vector_tag_u)
62  _tag_u.release();
63 
64  _vector_tag_u.clear();
65 
66  for (auto & _tag_u : _matrix_tag_u)
67  _tag_u.release();
68 
69  _matrix_tag_u.clear();
70 }
71 
72 void
74 {
75  const NumericVector<Real> & current_solution = *_sys.currentSolution();
76  const NumericVector<Real> & solution_old = _sys.solutionOld();
77  const NumericVector<Real> & solution_older = _sys.solutionOlder();
78  const NumericVector<Real> * u_dot = _sys.solutionUDot();
79  const NumericVector<Real> * u_dotdot = _sys.solutionUDotDot();
80  const NumericVector<Real> * u_dot_old = _sys.solutionUDotOld();
81  const NumericVector<Real> * u_dotdot_old = _sys.solutionUDotDotOld();
82  const Real & du_dot_du = _sys.duDotDu();
83  const Real & du_dotdot_du = _sys.duDotDotDu();
84  auto safe_access_tagged_vectors = _sys.subproblem().safeAccessTaggedVectors();
85  auto safe_access_tagged_matrices = _sys.subproblem().safeAccessTaggedMatrices();
86  auto & active_coupleable_matrix_tags =
88  auto & active_coupleable_vector_tags =
90 
91  _dof_map.SCALAR_dof_indices(_dof_indices, _var_num);
92 
93  unsigned int n = _dof_indices.size();
94  _u.resize(n);
95  _u_old.resize(n);
96  _u_older.resize(n);
97 
98  for (auto & _tag_u : _vector_tag_u)
99  _tag_u.resize(n);
100 
101  for (auto & _tag_u : _matrix_tag_u)
102  _tag_u.resize(n);
103 
104  _du_dot_du.clear();
105  _du_dot_du.resize(n, du_dot_du);
106 
107  if (_need_u_dot)
108  _u_dot.resize(n);
109 
110  if (_need_u_dotdot)
111  _u_dotdot.resize(n);
112 
113  if (_need_u_dot_old)
115 
116  if (_need_u_dotdot_old)
118 
119  if (_need_du_dot_du)
120  {
121  _du_dot_du.clear();
122  _du_dot_du.resize(n, du_dot_du);
123  }
124 
125  if (_need_du_dotdot_du)
126  {
128  _du_dotdot_du.resize(n, du_dotdot_du);
129  }
130 
131  // If we have an empty partition, or if we have a partition which
132  // does not include any of the subdomains of a subdomain-restricted
133  // variable, then we do not have access to that variable! Hopefully
134  // we won't need the indices we lack.
135  if (_dof_map.all_semilocal_indices(_dof_indices))
136  {
137  current_solution.get(_dof_indices, &_u[0]);
138  solution_old.get(_dof_indices, &_u_old[0]);
139  solution_older.get(_dof_indices, &_u_older[0]);
140 
141  if (safe_access_tagged_vectors)
142  {
143  for (auto tag : active_coupleable_vector_tags)
144  if (_sys.hasVector(tag) && _need_vector_tag_u[tag])
145  _sys.getVector(tag).get(_dof_indices, &_vector_tag_u[tag][0]);
146  }
147 
148  if (safe_access_tagged_matrices)
149  {
150  for (auto tag : active_coupleable_matrix_tags)
151  if (_sys.hasMatrix(tag) && _sys.getMatrix(tag).closed() && _need_matrix_tag_u[tag])
152  for (std::size_t i = 0; i != n; ++i)
153  {
154  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
155  _matrix_tag_u[tag][i] = _sys.getMatrix(tag)(_dof_indices[i], _dof_indices[i]);
156  }
157  }
158 
159  if (_need_u_dot)
160  (*u_dot).get(_dof_indices, &_u_dot[0]);
161 
162  if (_need_u_dotdot)
163  (*u_dotdot).get(_dof_indices, &_u_dotdot[0]);
164 
165  if (_need_u_dot_old)
166  (*u_dot_old).get(_dof_indices, &_u_dot_old[0]);
167 
168  if (_need_u_dotdot_old)
169  (*u_dotdot_old).get(_dof_indices, &_u_dotdot_old[0]);
170  }
171  else
172  {
173  for (std::size_t i = 0; i != n; ++i)
174  {
175  const dof_id_type dof_index = _dof_indices[i];
176  std::vector<dof_id_type> one_dof_index(1, dof_index);
177  if (_dof_map.all_semilocal_indices(one_dof_index))
178  {
179  libmesh_assert_less(i, _u.size());
180 
181  current_solution.get(one_dof_index, &_u[i]);
182  solution_old.get(one_dof_index, &_u_old[i]);
183  solution_older.get(one_dof_index, &_u_older[i]);
184 
185  if (safe_access_tagged_vectors)
186  {
187  for (auto tag : active_coupleable_vector_tags)
188  if (_sys.hasVector(tag) && _need_vector_tag_u[tag])
189  _sys.getVector(tag).get(one_dof_index, &_vector_tag_u[tag][i]);
190  }
191 
192  if (safe_access_tagged_matrices)
193  {
194  for (auto tag : active_coupleable_matrix_tags)
195  if (_sys.hasMatrix(tag) && _sys.getMatrix(tag).closed() && _need_matrix_tag_u[tag])
196  {
197  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
198  _matrix_tag_u[tag][i] = _sys.getMatrix(tag)(dof_index, dof_index);
199  }
200  }
201 
202  if (_need_u_dot)
203  (*u_dot).get(one_dof_index, &_u_dot[i]);
204 
205  if (_need_u_dotdot)
206  (*u_dotdot).get(one_dof_index, &_u_dotdot[i]);
207 
208  if (_need_u_dot_old)
209  (*u_dot_old).get(one_dof_index, &_u_dot_old[i]);
210 
211  if (_need_u_dotdot_old)
212  (*u_dotdot_old).get(one_dof_index, &_u_dotdot_old[i]);
213  }
214  else
215  {
216 #ifdef _GLIBCXX_DEBUG
217  // Let's make it possible to catch invalid accesses to these
218  // variables immediately via a thrown exception, if our
219  // libstdc++ compiler flags allow for that.
220  _u.resize(i);
221  _u_old.resize(i);
222  _u_older.resize(i);
223 
224  for (auto tag : active_coupleable_vector_tags)
225  if (_sys.hasVector(tag) && _need_vector_tag_u[tag])
226  _vector_tag_u[tag].resize(i);
227 
228  for (auto tag : active_coupleable_matrix_tags)
229  if (_sys.hasMatrix(tag) && _sys.getMatrix(tag).closed() && _need_matrix_tag_u[tag])
230  _matrix_tag_u[tag].resize(i);
231 
232  if (_need_u_dot)
233  _u_dot.resize(i);
234 
235  if (_need_u_dotdot)
236  _u_dotdot.resize(i);
237 
238  if (_need_u_dot_old)
239  _u_dot_old.resize(i);
240 
241  if (_need_u_dotdot_old)
243 #else
244  // If we can't catch errors at run-time, we can at least
245  // propagate NaN values rather than invalid values, so that
246  // users won't trust the result.
247  _u[i] = std::numeric_limits<Real>::quiet_NaN();
248  _u_old[i] = std::numeric_limits<Real>::quiet_NaN();
249  _u_older[i] = std::numeric_limits<Real>::quiet_NaN();
250 
251  for (auto tag : active_coupleable_vector_tags)
252  if (_sys.hasVector(tag) && _need_vector_tag_u[tag])
253  _vector_tag_u[tag][i] = std::numeric_limits<Real>::quiet_NaN();
254 
255  for (auto tag : active_coupleable_matrix_tags)
256  if (_sys.hasMatrix(tag) && _sys.getMatrix(tag).closed() && _need_matrix_tag_u[tag])
257  _matrix_tag_u[tag][i] = std::numeric_limits<Real>::quiet_NaN();
258 
259  if (_need_u_dot)
260  _u_dot[i] = std::numeric_limits<Real>::quiet_NaN();
261 
262  if (_need_u_dotdot)
263  _u_dotdot[i] = std::numeric_limits<Real>::quiet_NaN();
264 
265  if (_need_u_dot_old)
266  _u_dot_old[i] = std::numeric_limits<Real>::quiet_NaN();
267 
268  if (_need_u_dotdot_old)
269  _u_dotdot_old[i] = std::numeric_limits<Real>::quiet_NaN();
270 #endif
271  }
272  }
273  }
274 }
275 
276 void
277 MooseVariableScalar::setValue(unsigned int i, Number value)
278 {
279 // In debug modes, we might have set a "trap" to catch reads of
280 // uninitialized values, but this trap shouldn't prevent setting
281 // values.
282 #ifdef DEBUG
283  if (i >= _u.size())
284  {
285  libmesh_assert_less(i, _dof_indices.size());
286  _u.resize(i + 1);
287  }
288 #endif
289  _u[i] = value; // update variable value
290 }
291 
292 void
294 {
295  unsigned int n = _dof_indices.size();
296 // In debug modes, we might have set a "trap" to catch reads of
297 // uninitialized values, but this trap shouldn't prevent setting
298 // values.
299 #ifdef DEBUG
300  _u.resize(n);
301 #endif
302  for (unsigned int i = 0; i < n; i++)
303  _u[i] = value;
304 }
305 
306 void
307 MooseVariableScalar::insert(NumericVector<Number> & soln)
308 {
309  // We may have redundantly computed this value on many different
310  // processors, but only the processor which actually owns it should
311  // be saving it to the solution vector, to avoid O(N_scalar_vars)
312  // unnecessary communication.
313 
314  const dof_id_type first_dof = _dof_map.first_dof();
315  const dof_id_type end_dof = _dof_map.end_dof();
316  if (_dof_indices.size() > 0 && first_dof <= _dof_indices[0] && _dof_indices[0] < end_dof)
317  soln.insert(&_u[0], _dof_indices);
318 }
virtual bool hasMatrix(TagID tag) const
Check if the tagged matrix exists in the system.
Definition: SystemBase.C:805
virtual const NumericVector< Number > *const & currentSolution() const =0
The solution vector that is currently being operated on.
virtual NumericVector< Number > * solutionUDot()=0
bool hasVector(const std::string &tag_name) const
Check if the named vector exists in the system.
Definition: SystemBase.C:701
Keeps track of stuff related to assembling.
Definition: Assembly.h:62
const DofMap & _dof_map
DOF map.
void resize(unsigned int size)
Change the number of elements the array can store.
Definition: MooseArray.h:218
virtual NumericVector< Number > & solutionOld()=0
VariableValue _u
The value of scalar variable.
bool safeAccessTaggedVectors() const
Is it safe to access the tagged vectors.
Definition: SubProblem.h:589
virtual NumericVector< Number > * solutionUDotDotOld()=0
VariableValue _u_older
The older value of scalar variable.
const std::set< TagID > & getActiveScalarVariableCoupleableMatrixTags(THREAD_ID tid) const
Definition: SubProblem.C:224
Base class for a system (of equations)
Definition: SystemBase.h:92
MooseVariableScalar(unsigned int var_num, const FEType &fe_type, SystemBase &sys, Assembly &assembly, Moose::VarKindType var_kind, THREAD_ID tid)
THREAD_ID _tid
Thread ID.
std::vector< dof_id_type > _dof_indices
DOF indices.
std::vector< VariableValue > _vector_tag_u
Tagged vectors.
std::vector< bool > _need_vector_tag_u
Only cache data when need it.
virtual Number & duDotDu()
Definition: SystemBase.h:168
unsigned int size() const
The number of elements that can currently be stored in the array.
Definition: MooseArray.h:259
virtual Number & duDotDotDu()
Definition: SystemBase.h:169
SystemBase & _sys
System this variable is part of.
VarKindType
Framework-wide stuff.
Definition: MooseTypes.h:481
void setValue(unsigned int i, Number value)
Set the nodal value for this variable (to keep everything up to date.
void setValues(Number value)
Set all of the values of this scalar variable to the same value.
virtual SubProblem & subproblem()
Definition: SystemBase.h:105
std::vector< bool > _need_matrix_tag_u
Only cache data when need it.
virtual unsigned int numVectorTags() const
The total number of tags.
Definition: SubProblem.h:122
std::vector< VariableValue > _matrix_tag_u
Tagged matrices.
virtual unsigned int numMatrixTags() const
The total number of tags.
Definition: SubProblem.h:157
const std::set< TagID > & getActiveScalarVariableCoupleableVectorTags(THREAD_ID tid) const
Definition: SubProblem.C:230
PetscInt n
void release()
Manually deallocates the data pointer.
Definition: MooseArray.h:61
virtual SparseMatrix< Number > & getMatrix(TagID tag)
Get a raw SparseMatrix.
Definition: SystemBase.C:811
unsigned int _var_num
variable number (from libMesh)
virtual NumericVector< Number > & solutionOlder()=0
void insert(NumericVector< Number > &soln)
virtual NumericVector< Number > * solutionUDotOld()=0
virtual NumericVector< Number > * solutionUDotDot()=0
void clear()
Change the number of elements the array can store to zero.
Definition: MooseArray.h:211
bool safeAccessTaggedMatrices() const
Is it safe to access the tagged matrices.
Definition: SubProblem.h:586
virtual NumericVector< Number > & getVector(const std::string &name)
Get a raw NumericVector.
Definition: SystemBase.C:751
unsigned int THREAD_ID
Definition: MooseTypes.h:161
VariableValue _u_old
The old value of scalar variable.