dof_object.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 // C++ includes
21 
22 // Local includes
23 #include "libmesh/dof_object.h"
24 
25 
26 namespace libMesh
27 {
28 
29 
30 
31 // ------------------------------------------------------------
32 // DofObject class static member -now initialized in header
36 
37 
38 
39 // ------------------------------------------------------------
40 // DofObject class members
41 // Copy Constructor
42 DofObject::DofObject (const DofObject& dof_obj) :
44 #ifdef LIBMESH_ENABLE_AMR
45  old_dof_object (NULL),
46 #endif
47  _id (dof_obj._id),
48 #ifdef LIBMESH_ENABLE_UNIQUE_ID
49  _unique_id (dof_obj._unique_id),
50 #endif
51  _processor_id (dof_obj._processor_id),
52  _idx_buf (dof_obj._idx_buf)
53 {
54 
55  // Check that everything worked
56 #ifdef DEBUG
57 
58  libmesh_assert_equal_to (this->n_systems(), dof_obj.n_systems());
59 
60  for (unsigned int s=0; s<this->n_systems(); s++)
61  {
62  libmesh_assert_equal_to (this->n_vars(s), dof_obj.n_vars(s));
63  libmesh_assert_equal_to (this->n_var_groups(s), dof_obj.n_var_groups(s));
64 
65  for (unsigned int vg=0; vg<this->n_var_groups(s); vg++)
66  libmesh_assert_equal_to (this->n_vars(s,vg), dof_obj.n_vars(s,vg));
67 
68  for (unsigned int v=0; v<this->n_vars(s); v++)
69  {
70  libmesh_assert_equal_to (this->n_comp(s,v), dof_obj.n_comp(s,v));
71 
72  for (unsigned int c=0; c<this->n_comp(s,v); c++)
73  libmesh_assert_equal_to (this->dof_number(s,v,c), dof_obj.dof_number(s,v,c));
74  }
75  }
76 
77 #endif
78 }
79 
80 
81 // Deep-copying assignment operator
83 {
84 #ifdef LIBMESH_ENABLE_AMR
85  this->clear_old_dof_object();
86 
87  this->old_dof_object = new DofObject(*(dof_obj.old_dof_object));
88 #endif
89 
90  _id = dof_obj._id;
91 #ifdef LIBMESH_ENABLE_UNIQUE_ID
92  _unique_id = dof_obj._unique_id;
93 #endif
94  _processor_id = dof_obj._processor_id;
95  _idx_buf = dof_obj._idx_buf;
96 
97 
98  // Check that everything worked
99 #ifdef DEBUG
100 
101  libmesh_assert_equal_to (this->n_systems(), dof_obj.n_systems());
102 
103  for (unsigned int s=0; s<this->n_systems(); s++)
104  {
105  libmesh_assert_equal_to (this->n_vars(s), dof_obj.n_vars(s));
106  libmesh_assert_equal_to (this->n_var_groups(s), dof_obj.n_var_groups(s));
107 
108  for (unsigned int vg=0; vg<this->n_var_groups(s); vg++)
109  libmesh_assert_equal_to (this->n_vars(s,vg), dof_obj.n_vars(s,vg));
110 
111  for (unsigned int v=0; v<this->n_vars(s); v++)
112  {
113  libmesh_assert_equal_to (this->n_comp(s,v), dof_obj.n_comp(s,v));
114 
115  for (unsigned int c=0; c<this->n_comp(s,v); c++)
116  libmesh_assert_equal_to (this->dof_number(s,v,c), dof_obj.dof_number(s,v,c));
117  }
118  }
119 
120 #endif
121 
122  return *this;
123 }
124 
125 
126 
127 
128 
129 #ifdef LIBMESH_ENABLE_AMR
130 
132 {
133  // If we have been called before...
134  // prevent a memory leak
135  if (old_dof_object != NULL)
136  {
137  delete this->old_dof_object;
138  this->old_dof_object = NULL;
139  }
140 }
141 
142 
143 
145 {
146  this->clear_old_dof_object();
147 
149 
150  // Make a new DofObject, assign a copy of \p this.
151  // Make sure the copy ctor for DofObject works!!
152  this->old_dof_object = new DofObject(*this);
153 }
154 
155 #endif
156 
157 
158 
159 void DofObject::set_n_systems (const unsigned int ns)
160 {
161  // Check for trivial return
162  if (ns == this->n_systems())
163  return;
164 
165  // Clear any existing data. This is safe to call
166  // even if we don't have any data.
167  this->clear_dofs();
168 
169  // Set the new number of systems
170  _idx_buf.resize(ns, ns);
171  _idx_buf[0] = ns;
172 
173 
174 #ifdef DEBUG
175 
176  // check that all systems now exist and that they have 0 size
177  libmesh_assert_equal_to (ns, this->n_systems());
178  for (unsigned int s=0; s<this->n_systems(); s++)
179  {
180  libmesh_assert_equal_to (this->n_vars(s), 0);
181  libmesh_assert_equal_to (this->n_var_groups(s), 0);
182  }
183 
184 #endif
185 }
186 
187 
188 
190 {
191  // quick return?
192  if (this->n_systems() == 0)
193  {
194  this->set_n_systems(1);
195  return;
196  }
197 
198  DofObject::index_buffer_t::iterator it = _idx_buf.begin();
199 
200  std::advance(it, this->n_systems());
201 
202  // this inserts the current vector size at the position for the new system - creating the
203  // entry we need for the new system indicating there are 0 variables.
204  _idx_buf.insert(it, _idx_buf.size());
205 
206  // cache this value before we screw it up!
207  const unsigned int ns_orig = this->n_systems();
208 
209  // incriment the number of systems and the offsets for each of
210  // the systems including the new one we just added.
211  for (unsigned int i=0; i<ns_orig+1; i++)
212  _idx_buf[i]++;
213 
214  libmesh_assert_equal_to (this->n_systems(), (ns_orig+1));
215  libmesh_assert_equal_to (this->n_vars(ns_orig), 0);
216  libmesh_assert_equal_to (this->n_var_groups(ns_orig), 0);
217 }
218 
219 
220 
221 void DofObject::set_n_vars_per_group(const unsigned int s,
222  const std::vector<unsigned int> &nvpg)
223 {
224 
225  libmesh_assert_less (s, this->n_systems());
226 
227  // number of varaible groups for this system - inferred
228  const unsigned int nvg = libmesh_cast_int<unsigned int>(nvpg.size());
229 
230  // BSK - note that for compatibility with the previous implementation
231  // calling this method when (nvars == this->n_vars()) requires that
232  // we invalidate the DOF indices and set the number of components to 0.
233  // Note this was a bit of a suprise to me - there was no quick return in
234  // the old method, which caused removal and readdition of the DOF indices
235  // even in the case of (nvars == this->n_vars()), resulting in n_comp(s,v)
236  // implicitly becoming 0 regardless of any previous value.
237  // quick return?
238  if (nvg == this->n_var_groups(s))
239  {
240  for (unsigned int vg=0; vg<nvg; vg++)
241  {
242  this->set_n_comp_group(s,vg,0);
243  libmesh_assert_equal_to (this->n_vars(s,vg), nvpg[vg]);
244  }
245  return;
246  }
247 
248  // since there is ample opportunity to screw up other systems, let us
249  // cache their current sizes and later assert that they are unchanged.
250 #ifdef DEBUG
251  DofObject::index_buffer_t old_system_sizes;
252  old_system_sizes.reserve(this->n_systems());
253 
254  for (unsigned int s_ctr=0; s_ctr<this->n_systems(); s_ctr++)
255  old_system_sizes.push_back(this->n_var_groups(s_ctr));
256 #endif
257 
258  // remove current indices if we have some
259  if (this->n_var_groups(s) != 0)
260  {
261  const unsigned int old_nvg_s = this->n_var_groups(s);
262 
263  DofObject::index_buffer_t::iterator
264  it = _idx_buf.begin(),
265  end = _idx_buf.begin();
266 
267  std::advance(it, this->start_idx(s));
268  std::advance(end, this->end_idx(s));
269  _idx_buf.erase(it,end);
270 
271  for (unsigned int ctr=(s+1); ctr<this->n_systems(); ctr++)
272  _idx_buf[ctr] -= 2*old_nvg_s;
273  }
274 
275  // better not have any now!
276  libmesh_assert_equal_to (this->n_var_groups(s), 0);
277 
278  // had better not screwed up any of our sizes!
279 #ifdef DEBUG
280  for (unsigned int s_ctr=0; s_ctr<this->n_systems(); s_ctr++)
281  if (s_ctr != s)
282  libmesh_assert_equal_to (this->n_var_groups(s_ctr), old_system_sizes[s_ctr]);
283 #endif
284 
285  // OK, if the user requested 0 that is what we have
286  if (nvg == 0)
287  return;
288 
289  {
290  // array to hold new indices
291  DofObject::index_buffer_t var_idxs(2*nvg);
292  for (unsigned int vg=0; vg<nvg; vg++)
293  {
294  var_idxs[2*vg ] = ncv_magic*nvpg[vg] + 0;
295  var_idxs[2*vg + 1] = invalid_id - 1;
296  }
297 
298  DofObject::index_buffer_t::iterator it = _idx_buf.begin();
299  std::advance(it, this->end_idx(s));
300  _idx_buf.insert(it, var_idxs.begin(), var_idxs.end());
301 
302  for (unsigned int ctr=(s+1); ctr<this->n_systems(); ctr++)
303  _idx_buf[ctr] += 2*nvg;
304 
305  // resize _idx_buf to fit so no memory is wasted.
307  }
308 
309  // that better had worked. Assert stuff.
310  libmesh_assert_equal_to (nvg, this->n_var_groups(s));
311 
312 #ifdef DEBUG
313 
314  // libMesh::out << " [ ";
315  // for (unsigned int i=0; i<_idx_buf.size(); i++)
316  // libMesh::out << _idx_buf[i] << " ";
317  // libMesh::out << "]\n";
318 
319  libmesh_assert_equal_to (this->n_var_groups(s), nvpg.size());
320 
321  for (unsigned int vg=0; vg<this->n_var_groups(s); vg++)
322  {
323  libmesh_assert_equal_to (this->n_vars(s,vg), nvpg[vg]);
324  libmesh_assert_equal_to (this->n_comp_group(s,vg), 0);
325  }
326 
327  for (unsigned int v=0; v<this->n_vars(s); v++)
328  libmesh_assert_equal_to (this->n_comp(s,v), 0);
329 
330  // again, all other system sizes shoudl be unchanged!
331  for (unsigned int s_ctr=0; s_ctr<this->n_systems(); s_ctr++)
332  if (s_ctr != s)
333  libmesh_assert_equal_to (this->n_var_groups(s_ctr), old_system_sizes[s_ctr]);
334 
335 #endif
336 }
337 
338 
339 
340 void DofObject::set_n_comp(const unsigned int s,
341  const unsigned int var,
342  const unsigned int ncomp)
343 {
344  libmesh_assert_less (s, this->n_systems());
345  libmesh_assert_less (var, this->n_vars(s));
346 
347  this->set_n_comp_group(s, this->var_to_vg(s,var), ncomp);
348 }
349 
350 
351 
352 void DofObject::set_n_comp_group(const unsigned int s,
353  const unsigned int vg,
354  const unsigned int ncomp)
355 {
356  libmesh_assert_less (s, this->n_systems());
357  libmesh_assert_less (vg, this->n_var_groups(s));
358 
359  // Check for trivial return
360  if (ncomp == this->n_comp_group(s,vg)) return;
361 
362 #ifndef NDEBUG
363  if (ncomp >= ncv_magic)
364  {
365  const index_t ncvm = ncv_magic;
366  libMesh::err << "ERROR: ncomp must be less than DofObject::ncv_magic!\n"
367  << "ncomp = " << ncomp << ", ncv_magic = " << ncvm
368  << "\nrecompile and try again!\n";
369  libmesh_error();
370  }
371 #endif
372 
373  const unsigned int
374  start_idx_sys = this->start_idx(s),
375  n_vars_group = this->n_vars(s,vg),
376  base_offset = start_idx_sys + 2*vg;
377 
378  libmesh_assert_less ((base_offset + 1), _idx_buf.size());
379 
380  // if (ncomp)
381  // libMesh::out << "s,vg,ncomp="
382  // << s << ","
383  // << vg << ","
384  // << ncomp << '\n';
385 
386  // set the number of components, maintaining the number
387  // of variables in the group
388  _idx_buf[base_offset] = ncv_magic*n_vars_group + ncomp;
389 
390  // We use (invalid_id - 1) to signify no
391  // components for this object
392  _idx_buf[base_offset + 1] = (ncomp == 0) ? invalid_id - 1 : invalid_id;
393 
394  // this->debug_buffer();
395  // libMesh::out << "s,vg = " << s << "," << vg << '\n'
396  // << "base_offset=" << base_offset << '\n'
397  // << "this->n_comp(s,vg)=" << this->n_comp(s,vg) << '\n'
398  // << "this->n_comp_group(s,vg)=" << this->n_comp_group(s,vg) << '\n'
399  // << "this->n_vars(s,vg)=" << this->n_vars(s,vg) << '\n'
400  // << "this->n_var_groups(s)=" << this->n_var_groups(s) << '\n';
401 
402  libmesh_assert_equal_to (ncomp, this->n_comp_group(s,vg));
403 }
404 
405 
406 
407 void DofObject::set_dof_number(const unsigned int s,
408  const unsigned int var,
409  const unsigned int comp,
410  const dof_id_type dn)
411 {
412  libmesh_assert_less (s, this->n_systems());
413  libmesh_assert_less (var, this->n_vars(s));
414  libmesh_assert_less (comp, this->n_comp(s,var));
415 
416  const unsigned int
417  vg = this->var_to_vg(s,var),
418  ncg = this->n_comp_group(s,vg),
419  vig = this->system_var_to_vg_var(s,vg,var),
420  start_idx_sys = this->start_idx(s);
421 
422  libmesh_assert_less ((start_idx_sys + 2*vg + 1), _idx_buf.size());
423 
424  dof_id_type &base_idx = _idx_buf[start_idx_sys + 2*vg + 1];
425 
426  // We intend to change all dof numbers together or not at all
427  if (comp || vig)
428  libmesh_assert ((dn == invalid_id && base_idx == invalid_id) ||
429  (dn == base_idx + vig*ncg + comp));
430 
431  // only explicitly store the base index for vig==0, comp==0
432  else
433  base_idx = dn;
434 
435 // #ifdef DEBUG
436 // libMesh::out << " [ ";
437 // for (unsigned int i=0; i<_idx_buf.size(); i++)
438 // libMesh::out << _idx_buf[i] << " ";
439 // libMesh::out << "]\n";
440 // #endif
441 
442  libmesh_assert_equal_to (this->dof_number(s, var, comp), dn);
443 }
444 
445 
446 
447 // FIXME: it'll be tricky getting this to work with 64-bit dof_id_type
449 {
450  return
451 #ifdef LIBMESH_ENABLE_AMR
452  ((old_dof_object == NULL) ? 0 : old_dof_object->packed_indexing_size()) + 2 +
453 #else
454  1 +
455 #endif
456  _idx_buf.size();
457 }
458 
459 
460 
461 // FIXME: it'll be tricky getting this to work with 64-bit dof_id_type
463  (std::vector<largest_id_type>::const_iterator begin)
464 {
465 #ifdef LIBMESH_ENABLE_AMR
466  const int has_old_dof_object = *begin++;
467 
468  // Either we have an old_dof_object or we don't
469  libmesh_assert(has_old_dof_object == 1 || has_old_dof_object == 0);
470  static const int dof_header_size = 2;
471 #else
472  static const bool has_old_dof_object = false;
473  static const int dof_header_size = 1;
474 #endif
475 
476  const int this_indexing_size = *begin++;
477 
478  return dof_header_size + this_indexing_size +
479  (has_old_dof_object ?
480  unpackable_indexing_size(begin+this_indexing_size) : 0);
481 }
482 
483 
484 // FIXME: it'll be tricky getting this to work with 64-bit dof_id_type
485 void DofObject::unpack_indexing(std::vector<largest_id_type>::const_iterator begin)
486 {
487  _idx_buf.clear();
488 
489 #ifdef LIBMESH_ENABLE_AMR
490  this->clear_old_dof_object();
491  const int has_old_dof_object = *begin++;
492  libmesh_assert(has_old_dof_object == 1 ||
493  has_old_dof_object == 0);
494 #endif
495 
496  const int size = *begin++;
497  _idx_buf.reserve(size);
498  std::copy(begin, begin+size, back_inserter(_idx_buf));
499 
500  // Check as best we can for internal consistency now
501  libmesh_assert(_idx_buf.empty() ||
502  (_idx_buf[0] <= _idx_buf.size()));
503 #ifdef DEBUG
504  if (!_idx_buf.empty())
505  for (unsigned int i=1; i < _idx_buf[0]; ++i)
506  {
507  libmesh_assert_greater_equal (_idx_buf[i], _idx_buf[i-1]);
508  libmesh_assert_equal_to ((_idx_buf[i] - _idx_buf[i-1])%2, 0);
509  libmesh_assert_less_equal (_idx_buf[i], _idx_buf.size());
510  }
511 #endif
512 
513 #ifdef LIBMESH_ENABLE_AMR
514  if (has_old_dof_object)
515  {
516  this->old_dof_object = new DofObject();
517  this->old_dof_object->unpack_indexing(begin+size);
518  }
519 #endif
520 }
521 
522 
523 // FIXME: it'll be tricky getting this to work with 64-bit dof_id_type
525  (std::back_insert_iterator<std::vector<largest_id_type> > target) const
526 {
527 #ifdef LIBMESH_ENABLE_AMR
528  // We might need to pack old_dof_object too
529  *target++ = (old_dof_object == NULL) ? 0 : 1;
530 #endif
531 
532  *target++ = _idx_buf.size();
533  std::copy(_idx_buf.begin(), _idx_buf.end(), target);
534 
535 #ifdef LIBMESH_ENABLE_AMR
536  if (old_dof_object)
537  old_dof_object->pack_indexing(target);
538 #endif
539 }
540 
541 
542 
544 {
545  libMesh::out << " [ ";
546  for (unsigned int i=0; i<_idx_buf.size(); i++)
547  libMesh::out << _idx_buf[i] << " ";
548  libMesh::out << "]\n";
549 }
550 
551 
552 
553 } // namespace libMesh

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:04 UTC

Hosted By:
SourceForge.net Logo