7fd59977 |
1 | // File: GProp_TFunction.gxx |
2 | // Created: Fri Dec 9 16:23:25 2005 |
3 | // Author: Sergey KHROMOV |
4 | // <skv@dimox> |
5 | |
6 | |
7 | #include <TColStd_HArray1OfReal.hxx> |
8 | #include <math_KronrodSingleIntegration.hxx> |
9 | #include <Precision.hxx> |
10 | #include <math.hxx> |
11 | |
12 | //======================================================================= |
13 | //function : Constructor. |
14 | //purpose : |
15 | //======================================================================= |
16 | |
17 | GProp_TFunction::GProp_TFunction(const Face &theSurface, |
18 | const gp_Pnt &theVertex, |
19 | const Standard_Boolean IsByPoint, |
20 | const Standard_Address theCoeffs, |
21 | const Standard_Real theUMin, |
22 | const Standard_Real theTolerance) |
23 | : mySurface(theSurface), |
24 | myUFunction(mySurface, theVertex, IsByPoint, theCoeffs), |
25 | myUMin(theUMin), |
26 | myTolerance(theTolerance), |
27 | myTolReached(0.), |
28 | myErrReached(0.), |
29 | myAbsError(0.), |
30 | myValueType(GProp_Unknown), |
31 | myIsByPoint(IsByPoint), |
32 | myNbPntOuter(3) |
33 | { |
34 | } |
35 | |
36 | //======================================================================= |
37 | //function : Init |
38 | //purpose : |
39 | //======================================================================= |
40 | |
41 | void GProp_TFunction::Init() |
42 | { |
43 | myTolReached = 0.; |
44 | myErrReached = 0.; |
45 | myAbsError = 0.; |
46 | } |
47 | |
48 | //======================================================================= |
49 | //function : Value |
50 | //purpose : |
51 | //======================================================================= |
52 | |
53 | Standard_Boolean GProp_TFunction::Value(const Standard_Real X, |
54 | Standard_Real &F) |
55 | { |
56 | |
57 | const Standard_Real tolU = 1.e-9; |
58 | |
59 | gp_Pnt2d aP2d; |
60 | gp_Vec2d aV2d; |
61 | Standard_Real aUMax; |
62 | Handle(TColStd_HArray1OfReal) anUKnots; |
63 | |
64 | mySurface.D12d(X, aP2d, aV2d); |
65 | aUMax = aP2d.X(); |
66 | |
67 | if(aUMax - myUMin < tolU) { |
68 | F = 0.; |
69 | return Standard_True; |
70 | } |
71 | |
72 | mySurface.GetUKnots(myUMin, aUMax, anUKnots); |
73 | myUFunction.SetVParam(aP2d.Y()); |
74 | |
75 | // Compute the integral from myUMin to aUMax of myUFunction. |
76 | Standard_Integer i; |
77 | Standard_Real aCoeff = aV2d.Y(); |
6e6cd5d9 |
78 | //Standard_Integer aNbUIntervals = anUKnots->Length() - 1; |
7fd59977 |
79 | //Standard_Real aTol = myTolerance/aNbUIntervals; |
80 | Standard_Real aTol = myTolerance; |
81 | |
82 | //aTol /= myNbPntOuter; |
83 | |
84 | if (myValueType == GProp_Mass) { |
85 | if (myIsByPoint) |
86 | aCoeff /= 3.; |
87 | } else if (myValueType == GProp_CenterMassX || |
88 | myValueType == GProp_CenterMassY || |
89 | myValueType == GProp_CenterMassZ) { |
90 | if (myIsByPoint) |
91 | aCoeff *= 0.25; |
92 | } else if (myValueType == GProp_InertiaXX || |
93 | myValueType == GProp_InertiaYY || |
94 | myValueType == GProp_InertiaZZ || |
95 | myValueType == GProp_InertiaXY || |
96 | myValueType == GProp_InertiaXZ || |
97 | myValueType == GProp_InertiaYZ) { |
98 | if (myIsByPoint) |
99 | aCoeff *= 0.2; |
100 | } else |
101 | return Standard_False; |
102 | |
103 | Standard_Real aAbsCoeff = Abs(aCoeff); |
104 | |
105 | if (aAbsCoeff <= Precision::Angular()) { |
106 | // No need to compute the integral. The value will be equal to 0. |
107 | F = 0.; |
108 | return Standard_True; |
109 | } |
110 | //else if (aAbsCoeff > 10.*aTol) |
111 | // aTol /= aAbsCoeff; |
112 | //else |
113 | // aTol = 0.1; |
114 | |
115 | Standard_Integer iU = anUKnots->Upper(); |
116 | Standard_Integer aNbPntsStart; |
117 | Standard_Integer aNbMaxIter = 1000; |
118 | math_KronrodSingleIntegration anIntegral; |
119 | Standard_Real aLocalErr = 0.; |
120 | |
121 | i = anUKnots->Lower(); |
122 | F = 0.; |
123 | |
124 | // Epmirical criterion |
125 | aNbPntsStart = Min(15, mySurface.UIntegrationOrder()/(anUKnots->Length() - 1)+1); |
126 | aNbPntsStart = Max(5, aNbPntsStart); |
127 | |
128 | while (i < iU) { |
129 | Standard_Real aU1 = anUKnots->Value(i++); |
130 | Standard_Real aU2 = anUKnots->Value(i); |
131 | |
132 | if(aU2 - aU1 < tolU) continue; |
133 | |
134 | anIntegral.Perform(myUFunction, aU1, aU2, aNbPntsStart, aTol, aNbMaxIter); |
135 | |
136 | if (!anIntegral.IsDone()) |
137 | return Standard_False; |
138 | |
139 | F += anIntegral.Value(); |
140 | aLocalErr += anIntegral.AbsolutError(); |
141 | //cout << " TFunction : " << anIntegral.NbIterReached() << " " << anIntegral.AbsolutError() << endl; |
142 | } |
143 | |
144 | F *= aCoeff; |
145 | aLocalErr *= aAbsCoeff; |
146 | myAbsError = Max(myAbsError, aLocalErr); |
147 | |
148 | myTolReached += aLocalErr; |
149 | |
150 | if(Abs(F) > Epsilon(1.)) aLocalErr /= Abs(F); |
151 | |
152 | myErrReached = Max(myErrReached, aLocalErr); |
153 | |
154 | |
155 | return Standard_True; |
156 | } |
157 | |
158 | //======================================================================= |
159 | //function : GetStateNumber |
160 | //purpose : |
161 | //======================================================================= |
162 | |
163 | Standard_Integer GProp_TFunction::GetStateNumber() |
164 | { |
165 | //myErrReached = myTolReached; |
166 | //myTolReached = 0.; |
167 | //myNbPntOuter += RealToInt(0.5*myNbPntOuter); |
168 | |
169 | //if (myNbPntOuter%2 == 0) |
170 | //myNbPntOuter++; |
171 | |
172 | return 0; |
173 | } |