0024624: Lost word in license statement in source files
[occt.git] / src / FEmTool / FEmTool_LinearTension.cxx
1 // Created on: 1998-11-06
2 // Created by: Igor FEOKTISTOV
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <FEmTool_LinearTension.ixx>
18 #include <PLib.hxx>
19 #include <TColStd_HArray2OfInteger.hxx>
20 #include <TColStd_HArray2OfReal.hxx>
21 #include <PLib_JacobiPolynomial.hxx>
22 #include <PLib_HermitJacobi.hxx>
23 #include <FEmTool_ElementsOfRefMatrix.hxx>
24 #include <math_IntegerVector.hxx>
25 #include <math_Vector.hxx>
26 #include <math_GaussSetIntegration.hxx>
27 #include <math.hxx>
28 #include <Standard_ConstructionError.hxx>
29
30 FEmTool_LinearTension::FEmTool_LinearTension(const Standard_Integer WorkDegree,
31                                              const GeomAbs_Shape ConstraintOrder):
32        RefMatrix(0,WorkDegree,0,WorkDegree)
33        
34 {
35   static Standard_Integer Order = -333, WDeg = 14;
36   static math_Vector MatrixElemts(0, ((WDeg+2)*(WDeg+1))/2 -1 );
37
38   myOrder = PLib::NivConstr(ConstraintOrder);
39
40   if (myOrder != Order) {
41     //Calculating RefMatrix
42     if (WorkDegree > WDeg) Standard_ConstructionError::Raise("Degree too high");
43     Order = myOrder;
44     Standard_Integer DerOrder = 1;
45     Handle(PLib_HermitJacobi) theBase = new PLib_HermitJacobi(WDeg, ConstraintOrder);
46     FEmTool_ElementsOfRefMatrix Elem = FEmTool_ElementsOfRefMatrix(theBase, DerOrder);
47     
48     Standard_Integer maxDegree = WDeg+1;
49     math_IntegerVector Order(1,1,Min(4*(maxDegree/2+1),math::GaussPointsMax()));
50     math_Vector Lower(1,1,-1.), Upper(1,1,1.); 
51     
52     math_GaussSetIntegration anInt(Elem, Lower, Upper, Order);
53     MatrixElemts = anInt.Value();
54   }
55
56   Standard_Integer i, j, ii, jj;
57   for(ii = i = 0; i <= WorkDegree; i++) {
58     RefMatrix(i, i) =  MatrixElemts(ii);
59     for(j = i+1, jj = ii+1; j <= WorkDegree; j++, jj++) {
60       RefMatrix(j, i) = RefMatrix(i, j) =  MatrixElemts(jj);
61     }
62     ii += WDeg+1-i;
63   }
64 }
65
66 Handle(TColStd_HArray2OfInteger) FEmTool_LinearTension::DependenceTable() const
67 {
68   if(myCoeff.IsNull()) Standard_DomainError::Raise("FEmTool_LinearTension::DependenceTable");
69
70   Handle(TColStd_HArray2OfInteger) DepTab = 
71     new TColStd_HArray2OfInteger(myCoeff->LowerCol(), myCoeff->UpperCol(),
72                                  myCoeff->LowerCol(), myCoeff->UpperCol(),0);
73   Standard_Integer i;
74   for(i=1; i<=myCoeff->RowLength(); i++) DepTab->SetValue(i,i,1);
75   
76   return DepTab;
77 }
78
79 Standard_Real FEmTool_LinearTension::Value() 
80 {
81   Standard_Integer deg = Min(myCoeff->ColLength() - 1, RefMatrix.UpperRow()), 
82                    i, j, j0 = myCoeff->LowerRow(), degH = Min(2*myOrder+1, deg),
83                    NbDim = myCoeff->RowLength(), dim;
84
85   TColStd_Array2OfReal NewCoeff( 1, NbDim, 0, deg);
86
87   Standard_Real coeff = (myLast - myFirst)/2., cteh3 = 2./coeff, 
88                 mfact, Jline;
89
90   Standard_Integer k1;
91
92
93   Standard_Real J = 0.;
94
95   for(i = 0; i <= degH; i++) {
96     k1 = (i <= myOrder)? i : i - myOrder - 1;
97     mfact = Pow(coeff,k1);
98     for(dim = 1; dim <= NbDim; dim++) 
99       NewCoeff(dim, i) = myCoeff->Value(j0 + i, dim) * mfact;
100   }
101
102   for(i = degH + 1; i <= deg; i++) {
103     for(dim = 1; dim <= NbDim; dim++) 
104       NewCoeff(dim, i) = myCoeff->Value(j0 + i, dim);
105   }
106
107   for(dim = 1; dim <= NbDim; dim++) {
108   
109     for(i = 0; i <= deg; i++) {
110
111       Jline = 0.5 * RefMatrix(i, i) * NewCoeff(dim, i);
112
113       for(j = 0; j < i; j++) 
114         Jline += RefMatrix(i, j) * NewCoeff(dim, j);
115       
116       J += Jline * NewCoeff(dim, i);
117
118     }    
119
120   }
121
122   return cteh3*J;
123
124
125 }
126
127 void FEmTool_LinearTension::Hessian(const Standard_Integer Dimension1,
128                                     const Standard_Integer Dimension2, math_Matrix& H) 
129 {
130  
131   Handle(TColStd_HArray2OfInteger) DepTab = DependenceTable();
132
133   if(Dimension1 < DepTab->LowerRow() || Dimension1 > DepTab->UpperRow() || 
134      Dimension2 < DepTab->LowerCol() || Dimension2 > DepTab->UpperCol()) 
135     Standard_OutOfRange::Raise("FEmTool_LinearTension::Hessian");
136
137   if(DepTab->Value(Dimension1,Dimension2) == 0) 
138     Standard_DomainError::Raise("FEmTool_LinearTension::Hessian");
139
140   Standard_Integer deg = Min(RefMatrix.UpperRow(), H.RowNumber() - 1), degH = Min(2*myOrder+1, deg);
141
142   Standard_Real coeff = (myLast - myFirst)/2., cteh3 = 2./coeff, mfact;
143   Standard_Integer k1, k2, i, j, i0 = H.LowerRow(), j0 = H.LowerCol(), i1, j1;
144
145   H.Init(0.);
146
147   i1 = i0;
148   for(i = 0; i <= degH; i++) {
149     k1 = (i <= myOrder)? i : i - myOrder - 1;
150     mfact = Pow(coeff,k1)*cteh3;
151     // Hermite*Hermite part of matrix
152     j1 = j0 + i;
153     for(j = i; j <= degH; j++) {
154       k2 = (j <= myOrder)? j : j - myOrder - 1;
155       H(i1, j1) = mfact*Pow(coeff, k2)*RefMatrix(i, j);
156       if (i != j) H(j1, i1) = H(i1, j1);
157       j1++;
158     }
159     // Hermite*Jacobi part of matrix
160     j1 = j0 + degH + 1;
161     for(j = degH + 1; j <= deg; j++) {
162       H(i1, j1) = mfact*RefMatrix(i, j);
163       H(j1, i1) = H(i1, j1);
164       j1++;
165     }
166     i1++;
167   }
168
169
170   // Jacoby*Jacobi part of matrix
171   i1 = i0 + degH + 1;
172   for(i = degH+1; i <= deg; i++) {
173     j1 = j0 + i;
174     for(j = i; j <= deg; j++) {
175       H(i1, j1) = cteh3*RefMatrix(i, j);
176       if (i != j) H(j1, i1) = H(i1, j1);
177       j1++;
178     }
179     i1++;
180   }
181
182 }
183
184  void FEmTool_LinearTension::Gradient(const Standard_Integer Dimension, math_Vector& G) 
185 {
186   if(Dimension < myCoeff->LowerCol() || Dimension > myCoeff->UpperCol()) 
187     Standard_OutOfRange::Raise("FEmTool_LinearTension::Gradient");
188
189   Standard_Integer deg = Min(G.Length() - 1, myCoeff->ColLength() - 1);
190
191   math_Vector X(0,deg);
192   Standard_Integer i, i1 = myCoeff->LowerRow();
193   for(i = 0; i <= deg; i++) X(i) = myCoeff->Value(i1+i, Dimension);
194
195   math_Matrix H(0,deg,0,deg);
196   Hessian(Dimension, Dimension, H);
197   
198   G.Multiply(H, X);
199
200
201 }