1 #ifndef __dof_object_test_h__
2 #define __dof_object_test_h__
3 
4 #include "libmesh_cppunit.h"
5 
6 #define DOFOBJECTTEST                           \
7   CPPUNIT_TEST( testSetId );                    \
8   CPPUNIT_TEST( testValidId );                  \
9   CPPUNIT_TEST( testInvalidateId );             \
10   CPPUNIT_TEST( testSetProcId );                \
11   CPPUNIT_TEST( testValidProcId );              \
12   CPPUNIT_TEST( testInvalidateProcId );         \
13   CPPUNIT_TEST( testSetNSystems );              \
14   CPPUNIT_TEST( testSetNVariableGroups );       \
15   CPPUNIT_TEST( testAddExtraData );             \
16   CPPUNIT_TEST( testAddSystemExtraInts );       \
17   CPPUNIT_TEST( testSetNSystemsExtraInts );     \
18   CPPUNIT_TEST( testSetNVariableGroupsExtraInts ); \
19   CPPUNIT_TEST( testManualDofCalculation );     \
20   CPPUNIT_TEST( testJensEftangBug );
21 
22 using namespace libMesh;
23 
24 template <class DerivedClass>
25 class DofObjectTest {
26 
27 private:
28   DerivedClass * instance;
29 
30 public:
setUp(DerivedClass * derived_instance)31   void setUp(DerivedClass * derived_instance)
32   {
33     instance=derived_instance;
34   }
35 
testSetId()36   void testSetId()
37   {
38     DofObject & aobject(*instance);
39 
40     aobject.set_id(1);
41     CPPUNIT_ASSERT_EQUAL( static_cast<dof_id_type>(1) , aobject.id() );
42   }
43 
testValidId()44   void testValidId()
45   {
46     DofObject & aobject(*instance);
47 
48     aobject.set_id(1);
49     CPPUNIT_ASSERT( aobject.valid_id() );
50 
51     aobject.set_id(DofObject::invalid_id);
52     CPPUNIT_ASSERT( !aobject.valid_id() );
53   }
54 
testInvalidateId()55   void testInvalidateId()
56   {
57     DofObject & aobject(*instance);
58 
59     aobject.set_id(1);
60     aobject.invalidate_id();
61 
62     CPPUNIT_ASSERT( !aobject.valid_id() );
63   }
64 
testSetProcId()65   void testSetProcId()
66   {
67     DofObject & aobject(*instance);
68 
69     aobject.processor_id(libMesh::global_processor_id());
70     CPPUNIT_ASSERT_EQUAL( (processor_id_type)libMesh::global_processor_id() , aobject.processor_id() );
71   }
72 
testValidProcId()73   void testValidProcId()
74   {
75     DofObject & aobject(*instance);
76 
77     aobject.processor_id(libMesh::global_processor_id());
78     CPPUNIT_ASSERT(aobject.valid_processor_id());
79 
80     aobject.processor_id(DofObject::invalid_processor_id);
81     CPPUNIT_ASSERT(!aobject.valid_processor_id());
82   }
83 
testInvalidateProcId()84   void testInvalidateProcId()
85   {
86     DofObject & aobject(*instance);
87 
88     aobject.processor_id(libMesh::global_processor_id());
89     aobject.invalidate_processor_id();
90 
91     CPPUNIT_ASSERT( !aobject.valid_processor_id() );
92   }
93 
testSetNSystems()94   void testSetNSystems()
95   {
96     DofObject & aobject(*instance);
97 
98     aobject.set_n_systems (10);
99 
100     CPPUNIT_ASSERT_EQUAL( (unsigned int) 10, aobject.n_systems() );
101   }
102 
testSetNVariableGroups()103   void testSetNVariableGroups()
104   {
105     DofObject & aobject(*instance);
106 
107     aobject.set_n_systems (2);
108 
109     std::vector<unsigned int> nvpg;
110 
111     nvpg.push_back(10);
112     nvpg.push_back(20);
113     nvpg.push_back(30);
114 
115     aobject.set_n_vars_per_group (0, nvpg);
116     aobject.set_n_vars_per_group (1, nvpg);
117 
118     for (unsigned int s=0; s<2; s++)
119       {
120         CPPUNIT_ASSERT_EQUAL( (unsigned int) 60, aobject.n_vars(s) );
121         CPPUNIT_ASSERT_EQUAL( (unsigned int) 3,  aobject.n_var_groups(s) );
122 
123         for (unsigned int vg=0; vg<3; vg++)
124           CPPUNIT_ASSERT_EQUAL( nvpg[vg], aobject.n_vars(s,vg) );
125       }
126   }
127 
testAddExtraData()128   void testAddExtraData()
129   {
130     DofObject & aobject(*instance);
131 
132     aobject.add_extra_integers (9);
133 
134     CPPUNIT_ASSERT(aobject.has_extra_integers());
135 
136     CPPUNIT_ASSERT_EQUAL( (unsigned int) 9, aobject.n_extra_integers() );
137 
138     unsigned int ints_per_Real = (sizeof(Real)-1)/sizeof(dof_id_type) + 1;
139 
140     for (unsigned int i=0; i != 9; ++i)
141       CPPUNIT_ASSERT_EQUAL( DofObject::invalid_id, aobject.get_extra_integer(i) );
142 
143     for (unsigned int i=0; i != 9; ++i)
144       {
145         // Try out a char at i=1
146         if (i == 1)
147           aobject.set_extra_datum<char>(i, '1');
148         // Try out an extra Real at i=2 if we'll have room
149         if (i == 2 && ints_per_Real <= 4)
150           aobject.set_extra_datum<Real>(i, pi);
151         if (i < 1 || i >= (2 + ints_per_Real))
152           {
153             aobject.set_extra_integer(i, i);
154             CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
155           }
156       }
157 
158     aobject.add_extra_integers (6);
159 
160     CPPUNIT_ASSERT(aobject.has_extra_integers());
161 
162     CPPUNIT_ASSERT_EQUAL( (unsigned int) 6, aobject.n_extra_integers() );
163 
164     for (unsigned int i=0; i != 6; ++i)
165       {
166         if (i == 1)
167           CPPUNIT_ASSERT_EQUAL(aobject.get_extra_datum<char>(i), '1');
168         if (i == 2 && ints_per_Real <= 4)
169           CPPUNIT_ASSERT_EQUAL(aobject.get_extra_datum<Real>(i), pi);
170         if (i < 1 || i >= (2 + ints_per_Real))
171           CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
172       }
173   }
174 
testAddSystemExtraInts()175   void testAddSystemExtraInts()
176   {
177     DofObject & aobject(*instance);
178 
179     aobject.add_extra_integers (1);
180 
181     aobject.add_system();
182 
183     CPPUNIT_ASSERT(aobject.has_extra_integers());
184 
185     CPPUNIT_ASSERT_EQUAL( (unsigned int) 1, aobject.n_extra_integers() );
186 
187     CPPUNIT_ASSERT_EQUAL( (unsigned int) 1, aobject.n_systems() );
188 
189     CPPUNIT_ASSERT_EQUAL( (unsigned int) 0, aobject.n_vars(0) );
190 
191     aobject.add_extra_integers (4);
192 
193     aobject.add_system();
194 
195     CPPUNIT_ASSERT(aobject.has_extra_integers());
196 
197     CPPUNIT_ASSERT_EQUAL( (unsigned int) 4, aobject.n_extra_integers() );
198 
199     CPPUNIT_ASSERT_EQUAL( (unsigned int) 2, aobject.n_systems() );
200 
201     CPPUNIT_ASSERT_EQUAL( (unsigned int) 0, aobject.n_vars(0) );
202     CPPUNIT_ASSERT_EQUAL( (unsigned int) 0, aobject.n_vars(1) );
203 
204     for (unsigned int i=0; i != 4; ++i)
205       {
206         CPPUNIT_ASSERT_EQUAL( DofObject::invalid_id, aobject.get_extra_integer(i) );
207         aobject.set_extra_integer(i, i);
208         CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
209       }
210 
211     aobject.add_extra_integers (7);
212 
213     for (unsigned int i=0; i != 4; ++i)
214       CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
215 
216     for (unsigned int i=4; i != 7; ++i)
217       CPPUNIT_ASSERT_EQUAL( DofObject::invalid_id, aobject.get_extra_integer(i) );
218 
219     aobject.add_system();
220 
221     CPPUNIT_ASSERT_EQUAL( (unsigned int) 7, aobject.n_extra_integers() );
222 
223     for (unsigned int i=0; i != 4; ++i)
224       CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
225 
226     for (unsigned int i=4; i != 7; ++i)
227       {
228         CPPUNIT_ASSERT_EQUAL( DofObject::invalid_id, aobject.get_extra_integer(i) );
229         aobject.set_extra_integer(i, i);
230         CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
231       }
232 
233     CPPUNIT_ASSERT_EQUAL( (unsigned int) 3, aobject.n_systems() );
234 
235     CPPUNIT_ASSERT_EQUAL( (unsigned int) 0, aobject.n_vars(0) );
236     CPPUNIT_ASSERT_EQUAL( (unsigned int) 0, aobject.n_vars(1) );
237     CPPUNIT_ASSERT_EQUAL( (unsigned int) 0, aobject.n_vars(2) );
238 
239     for (unsigned int i=0; i != 7; ++i)
240       CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
241   }
242 
testSetNSystemsExtraInts()243   void testSetNSystemsExtraInts()
244   {
245     DofObject & aobject(*instance);
246 
247     aobject.add_extra_integers (5);
248 
249     aobject.set_n_systems (10);
250 
251     CPPUNIT_ASSERT(aobject.has_extra_integers());
252 
253     CPPUNIT_ASSERT_EQUAL( (unsigned int) 5, aobject.n_extra_integers() );
254 
255     CPPUNIT_ASSERT_EQUAL( (unsigned int) 10, aobject.n_systems() );
256 
257     for (unsigned int i=0; i != 5; ++i)
258       {
259         CPPUNIT_ASSERT_EQUAL( DofObject::invalid_id, aobject.get_extra_integer(i) );
260         aobject.set_extra_integer(i, i);
261         CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
262       }
263 
264     aobject.add_extra_integers (9);
265 
266     for (unsigned int i=0; i != 5; ++i)
267       CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
268 
269     for (unsigned int i=5; i != 9; ++i)
270       CPPUNIT_ASSERT_EQUAL( DofObject::invalid_id, aobject.get_extra_integer(i) );
271 
272     aobject.set_n_systems (6);
273 
274     CPPUNIT_ASSERT_EQUAL( (unsigned int) 9, aobject.n_extra_integers() );
275 
276     for (unsigned int i=0; i != 5; ++i)
277       CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
278 
279     for (unsigned int i=5; i != 9; ++i)
280       {
281         CPPUNIT_ASSERT_EQUAL( DofObject::invalid_id, aobject.get_extra_integer(i) );
282         aobject.set_extra_integer(i, i);
283         CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
284       }
285 
286     CPPUNIT_ASSERT_EQUAL( (unsigned int) 6, aobject.n_systems() );
287 
288     for (unsigned int i=0; i != 9; ++i)
289       CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
290   }
291 
testSetNVariableGroupsExtraInts()292   void testSetNVariableGroupsExtraInts()
293   {
294     DofObject & aobject(*instance);
295 
296     aobject.set_n_systems (2);
297 
298     aobject.add_extra_integers (5);
299 
300     for (unsigned int i=0; i != 5; ++i)
301       {
302         CPPUNIT_ASSERT_EQUAL( DofObject::invalid_id, aobject.get_extra_integer(i) );
303         aobject.set_extra_integer(i, i);
304         CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
305       }
306 
307     std::vector<unsigned int> nvpg;
308 
309     nvpg.push_back(10);
310     nvpg.push_back(20);
311     nvpg.push_back(30);
312 
313     aobject.set_n_vars_per_group (0, nvpg);
314     aobject.set_n_vars_per_group (1, nvpg);
315 
316     for (unsigned int s=0; s<2; s++)
317       {
318         CPPUNIT_ASSERT_EQUAL( (unsigned int) 60, aobject.n_vars(s) );
319         CPPUNIT_ASSERT_EQUAL( (unsigned int) 3,  aobject.n_var_groups(s) );
320 
321         for (unsigned int vg=0; vg<3; vg++)
322           CPPUNIT_ASSERT_EQUAL( nvpg[vg], aobject.n_vars(s,vg) );
323       }
324 
325     CPPUNIT_ASSERT_EQUAL( (unsigned int) 5, aobject.n_extra_integers() );
326 
327     for (unsigned int i=0; i != 5; ++i)
328       CPPUNIT_ASSERT_EQUAL( dof_id_type(i), aobject.get_extra_integer(i) );
329   }
330 
331 
testManualDofCalculation()332   void testManualDofCalculation()
333   {
334     DofObject & aobject(*instance);
335 
336     aobject.set_n_systems (2);
337 
338     std::vector<unsigned int> nvpg;
339 
340     nvpg.push_back(2);
341     nvpg.push_back(3);
342 
343     aobject.set_n_vars_per_group (0, nvpg);
344     aobject.set_n_vars_per_group (1, nvpg);
345 
346     aobject.set_n_comp_group (0, 0, 1);
347     aobject.set_n_comp_group (0, 1, 3);
348 
349     aobject.set_n_comp_group (1, 0, 2);
350     aobject.set_n_comp_group (1, 1, 1);
351 
352     aobject.set_vg_dof_base(0, 0, 0);
353     aobject.set_vg_dof_base(0, 1, 120);
354 
355     aobject.set_vg_dof_base(1, 0, 20);
356     aobject.set_vg_dof_base(1, 1, 220);
357 
358     // Make sure the first dof is sane
359     CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(0), aobject.dof_number(0, 0, 0));
360 
361     // Check that we can manually index dofs of variables based on the first dof in a variable group
362     // Using: id = base + var_in_vg*ncomp + comp
363     CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(aobject.vg_dof_base(0, 0) + 1*1 + 0), aobject.dof_number(0, 1, 0));
364 
365     // Another Check that we can manually index dofs of variables based on the first dof in a variable group
366     // Using: id = base + var_in_vg*ncomp + comp
367     CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(aobject.vg_dof_base(0, 1) + 2*3 + 2), aobject.dof_number(0, 4, 2));
368 
369     // One More Check that we can manually index dofs of variables based on the first dof in a variable group
370     // Using: id = base + var_in_vg*ncomp + comp
371     CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(aobject.vg_dof_base(1, 1) + 0*3 + 0), aobject.dof_number(1, 2, 0));
372   }
373 
testJensEftangBug()374   void testJensEftangBug()
375   {
376     // For more information on this bug, see the following email thread:
377     // https://sourceforge.net/p/libmesh/mailman/libmesh-users/thread/50C8EE7C.8090405@gmail.com/
378     DofObject & aobject(*instance);
379     dof_id_type buf0[] = {2, 8, 257, 0, 257, 96, 257, 192, 257, 0};
380     aobject.set_buffer(std::vector<dof_id_type>(buf0, buf0+10));
381 
382     CPPUNIT_ASSERT_EQUAL (aobject.dof_number(0,0,0), static_cast<dof_id_type>(  0));
383     CPPUNIT_ASSERT_EQUAL (aobject.dof_number(0,1,0), static_cast<dof_id_type>( 96));
384     CPPUNIT_ASSERT_EQUAL (aobject.dof_number(0,2,0), static_cast<dof_id_type>(192));
385     CPPUNIT_ASSERT_EQUAL (aobject.dof_number(1,0,0), static_cast<dof_id_type>(  0));
386 
387     dof_id_type buf1[] = {2, 8, 257, 1, 257, 97, 257, 193, 257, 1};
388     aobject.set_buffer(std::vector<dof_id_type>(buf1, buf1+10));
389 
390     CPPUNIT_ASSERT_EQUAL (aobject.dof_number(0,0,0), static_cast<dof_id_type>(  1));
391     CPPUNIT_ASSERT_EQUAL (aobject.dof_number(0,1,0), static_cast<dof_id_type>( 97));
392     CPPUNIT_ASSERT_EQUAL (aobject.dof_number(0,2,0), static_cast<dof_id_type>(193));
393     CPPUNIT_ASSERT_EQUAL (aobject.dof_number(1,0,0), static_cast<dof_id_type>(  1));
394   }
395 };
396 
397 #endif // #ifdef __dof_object_test_h__
398