libMesh
composite_function_test.C
Go to the documentation of this file.
1 // Ignore unused parameter warnings coming from cppunit headers
2 #include <libmesh/ignore_warnings.h>
3 #include <cppunit/extensions/HelperMacros.h>
4 #include <cppunit/TestCase.h>
5 #include <libmesh/restore_warnings.h>
6 
7 // libmesh includes
8 #include <libmesh/composite_function.h>
9 #include <libmesh/const_function.h>
10 #include <libmesh/dense_vector.h>
11 #include <libmesh/parsed_function.h>
12 #include <libmesh/zero_function.h>
13 
14 // THE CPPUNIT_TEST_SUITE_END macro expands to code that involves
15 // std::auto_ptr, which in turn produces -Wdeprecated-declarations
16 // warnings. These can be ignored in GCC as long as we wrap the
17 // offending code in appropriate pragmas. We can't get away with a
18 // single ignore_warnings.h inclusion at the beginning of this file,
19 // since the libmesh headers pull in a restore_warnings.h at some
20 // point. We also don't bother restoring warnings at the end of this
21 // file since it's not a header.
22 #include <libmesh/ignore_warnings.h>
23 
24 using namespace libMesh;
25 
26 class CompositeFunctionTest : public CppUnit::TestCase
27 {
28 public:
29  void setUp() {}
30 
31  void tearDown() {}
32 
33  CPPUNIT_TEST_SUITE(CompositeFunctionTest);
34 
35  CPPUNIT_TEST(testRemap);
36  CPPUNIT_TEST(testTimeDependence);
37 
38  CPPUNIT_TEST_SUITE_END();
39 
40 
41 private:
42  void testRemap()
43  {
44  std::vector<std::vector<unsigned int>> index_sets(4);
45  index_sets[0].resize(2);
46  index_sets[0][0] = 3;
47  index_sets[0][1] = 4;
48  index_sets[1].resize(3);
49  index_sets[1][0] = 0;
50  index_sets[1][1] = 1;
51  index_sets[1][2] = 2;
52  index_sets[2].resize(3);
53  index_sets[2][0] = 0;
54  index_sets[2][1] = 2;
55  index_sets[2][2] = 4;
56  index_sets[3].resize(5);
57  index_sets[3][0] = 5;
58  index_sets[3][1] = 1;
59  index_sets[3][2] = 3;
60  index_sets[3][3] = 6;
61  index_sets[3][4] = 7;
62 
63  CompositeFunction<Real> composite_outer;
64 
65  {
66  CompositeFunction<Real> composite_inner;
67  composite_inner.attach_subfunction
68  (ConstFunction<Real>(1), index_sets[0]);
69  composite_inner.attach_subfunction
70  (ConstFunction<Real>(2), index_sets[1]);
71  composite_outer.attach_subfunction
72  (composite_inner, index_sets[3]);
73 
74  DenseVector<Real> test_one(5);
75 
76  composite_inner(Point(0), 0, test_one);
77 
78  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_one(0), 2, 1.e-12);
79  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_one(1), 2, 1.e-12);
80  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_one(2), 2, 1.e-12);
81  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_one(3), 1, 1.e-12);
82  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_one(4), 1, 1.e-12);
83  }
84  composite_outer.attach_subfunction
85  (ConstFunction<Real>(3), index_sets[2]);
86 
87  DenseVector<Real> test_two(8);
88  composite_outer(Point(0), 0, test_two);
89 
90  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_two(0), 3, 1.e-12);
91  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_two(2), 3, 1.e-12);
92  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_two(4), 3, 1.e-12);
93  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_two(5), 2, 1.e-12);
94  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_two(1), 2, 1.e-12);
95  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_two(3), 2, 1.e-12);
96  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_two(6), 1, 1.e-12);
97  CPPUNIT_ASSERT_DOUBLES_EQUAL(test_two(7), 1, 1.e-12);
98  }
99 
101  {
102 
103  // We'll test the order of adding these functions to
104  // make sure time dependence gets detected/updated correctly
105  // for each
106  ParsedFunction<Real> no_t("x*2+y^2-tanh(z)+atan(x-y)");
107  ParsedFunction<Real> no_t2("x*2+y^2+z^2");
109 
110  ParsedFunction<Real> xyt("x+y+t");
111  ParsedFunction<Real> x2y2t2("x*2+y^2+t^2");
112 
113 
114  std::vector<unsigned int> index_set(1,0);
115 
116  {
117  // composite should not be time dependent since this is the first subfunction
118  // added and it's not time-dependent
119  CompositeFunction<Real> composite;
120  composite.attach_subfunction(no_t, index_set);
121  CPPUNIT_ASSERT(!composite.is_time_dependent());
122 
123  // Now composite should be time-dependent since we've now added a time dependent function
124  index_set[0] = 1;
125  composite.attach_subfunction(xyt, index_set);
126  CPPUNIT_ASSERT(composite.is_time_dependent());
127 
128  // Composite should still be time-dependent
129  index_set[0] = 2;
130  composite.attach_subfunction(x2y2t2, index_set);
131  CPPUNIT_ASSERT(composite.is_time_dependent());
132  }
133 
134 
135  {
136  CompositeFunction<Real> composite;
137 
138  // composite should be time-dependent since we've added a time dependent function
139  index_set[0] = 0;
140  composite.attach_subfunction(xyt, index_set);
141  CPPUNIT_ASSERT(composite.is_time_dependent());
142 
143  // composite should still be time-dependent since the previous function was time-dependent
144  index_set[0] = 1;
145  composite.attach_subfunction(no_t, index_set);
146  CPPUNIT_ASSERT(composite.is_time_dependent());
147 
148  // Composite should still be time-dependent
149  index_set[0] = 2;
150  composite.attach_subfunction(x2y2t2, index_set);
151  CPPUNIT_ASSERT(composite.is_time_dependent());
152  }
153 
154  {
155  CompositeFunction<Real> composite;
156 
157  // composite should not be time-dependent since we've added a time independent function
158  index_set[0] = 0;
159  composite.attach_subfunction(no_t, index_set);
160  CPPUNIT_ASSERT(!composite.is_time_dependent());
161 
162  // composite should still be time-independent
163  index_set[0] = 1;
164  composite.attach_subfunction(no_t2, index_set);
165  CPPUNIT_ASSERT(!composite.is_time_dependent());
166 
167  // Composite should still be time-independent
168  index_set[0] = 2;
169  composite.attach_subfunction(zero, index_set);
170  CPPUNIT_ASSERT(!composite.is_time_dependent());
171  }
172 
173  }
174 };
175 
void attach_subfunction(const FunctionBase< Output > &f, const std::vector< unsigned int > &index_map)
Attach a new subfunction, along with a map from the indices of that subfunction to the indices of the...
ConstFunction that simply returns 0.
Definition: zero_function.h:35
A Function generated (via FParser) by parsing a mathematical expression.
The libMesh namespace provides an interface to certain functionality in the library.
const Number zero
.
Definition: libmesh.h:178
bool is_time_dependent() const
Function which is a function of another function.
CPPUNIT_TEST_SUITE_REGISTRATION(CompositeFunctionTest)
Function that returns a single value that never changes.
Defines a dense vector for use in Finite Element-type computations.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38