-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathdivgrad_unit.C
155 lines (125 loc) · 4.71 KB
/
divgrad_unit.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <cstdlib> // rand()
#include <iostream>
#include <limits>
#include "metaphysicl_config.h"
#include "metaphysicl/dualdynamicsparsenumbervector.h"
#include "metaphysicl/dualnumbervector.h"
#include "metaphysicl/dualsparsenumbervector.h"
using namespace MetaPhysicL;
const unsigned int nx = 10, ny = 10, nz = 10;
template <typename Scalar>
bool test_error (Scalar computed,
Scalar analytic)
{
using std::max;
using std::fabs;
static const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 10;
Scalar max_abs_error = fabs(computed - analytic);
// Handle NaNs properly. Testing max_abs_error for NaN is
// impossible because IEEE sucks:
// https://en.wikipedia.org/wiki/IEEE_754_revision#min_and_max
if (max_abs_error > tol || computed != computed)
{
std::cerr << "Value = " << analytic <<
"\nComputed = " << computed <<
"\nTol " << tol << std::endl;
return true; // failure
}
return false; // success
}
template <typename Vector, typename VectorX, typename VectorY, typename VectorZ>
bool vectester (const Vector &,
const VectorX & unit_x,
const VectorY & unit_y,
const VectorZ & unit_z)
{
typedef typename ValueType<Vector>::type ADScalar;
typedef typename RawType<ADScalar>::value_type Scalar;
bool return_failure = false;
for (unsigned int i=0; i != nx; ++i)
{
const Scalar x1 = Scalar(i)/nx;
const ADScalar x = ADScalar(x1, unit_x);
for (unsigned int j=0; j != ny; ++j)
{
const Scalar y1 = Scalar(j)/ny;
const ADScalar y = ADScalar(y1, unit_y);
for (unsigned int k=0; k != nz; ++k)
{
const Scalar z1 = Scalar(k)/nz;
const ADScalar z = ADScalar(z1, unit_z);
Vector U;
U[0] = x*x*x + y*y + z*z;
U[1] = x*x + y*y*y + z*z;
U[2] = x*x + y*y + z*z*z;
Scalar divgrad0 = raw_value(divergence(gradient(U)))[0];
Scalar divgrad1 = raw_value(divergence(gradient(U)))[1];
Scalar divgrad2 = raw_value(divergence(gradient(U)))[2];
Scalar true_divgrad0 = 6*raw_value(x)+4;
Scalar true_divgrad1 = 6*raw_value(y)+4;
Scalar true_divgrad2 = 6*raw_value(z)+4;
return_failure = return_failure ||
test_error(divgrad0, true_divgrad0);
return_failure = return_failure ||
test_error(divgrad1, true_divgrad1);
return_failure = return_failure ||
test_error(divgrad2, true_divgrad2);
}
}
}
return return_failure;
}
template <typename Scalar>
bool dense_tester()
{
typedef DualNumber<Scalar, NumberVector<3, Scalar> >
FirstDerivType;
typedef DualNumber<FirstDerivType, NumberVector<3, FirstDerivType> >
SecondDerivType;
typedef NumberVector<3, Scalar>
PlainVectorType;
typedef NumberVector<3, SecondDerivType>
SecondVectorType;
const PlainVectorType unit_x =
NumberVectorUnitVector <3, 0, Scalar>::value();
const PlainVectorType unit_y =
NumberVectorUnitVector <3, 1, Scalar>::value();
const PlainVectorType unit_z =
NumberVectorUnitVector <3, 2, Scalar>::value();
const SecondVectorType zero_vec = 0;
return vectester(zero_vec, unit_x, unit_y, unit_z);
}
int main(void)
{
int returnval = 0;
returnval = returnval || dense_tester<float>();
returnval = returnval || dense_tester<double>();
returnval = returnval || dense_tester<long double>();
#if 0
returnval = returnval || vectester(SparseNumberVectorOf
<N, 0, DualNumber<double>, 1, DualNumber<double>,
2, DualNumber<double>, 3, DualNumber<double> >::type());
returnval = returnval || vectester(SparseNumberVectorOf
<N, 0, DualNumber<long double>, 1, DualNumber<long double>,
2, DualNumber<long double>, 3, DualNumber<long double> >::type());
DynamicSparseNumberVector<DualNumber<float>, unsigned int> float_dsnv;
float_dsnv.resize(4);
float_dsnv.raw_index(1) = 1;
float_dsnv.raw_index(2) = 2;
float_dsnv.raw_index(3) = 3;
returnval = returnval || vectester(float_dsnv);
DynamicSparseNumberVector<DualNumber<double>, unsigned int> double_dsnv;
double_dsnv.resize(4);
double_dsnv.raw_index(1) = 1;
double_dsnv.raw_index(2) = 2;
double_dsnv.raw_index(3) = 3;
returnval = returnval || vectester(double_dsnv);
DynamicSparseNumberVector<DualNumber<long double>, unsigned int> long_double_dsnv;
long_double_dsnv.resize(4);
long_double_dsnv.raw_index(1) = 1;
long_double_dsnv.raw_index(2) = 2;
long_double_dsnv.raw_index(3) = 3;
returnval = returnval || vectester(long_double_dsnv);
#endif
return returnval;
}