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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <FEmTool_ElementsOfRefMatrix.hxx>
19 #include <FEmTool_LinearTension.hxx>
21 #include <math_GaussSetIntegration.hxx>
22 #include <math_IntegerVector.hxx>
23 #include <math_Matrix.hxx>
24 #include <math_Vector.hxx>
26 #include <PLib_HermitJacobi.hxx>
27 #include <PLib_JacobiPolynomial.hxx>
28 #include <Standard_ConstructionError.hxx>
29 #include <Standard_DomainError.hxx>
30 #include <Standard_NotImplemented.hxx>
31 #include <Standard_Type.hxx>
32 #include <TColStd_HArray2OfInteger.hxx>
33 #include <TColStd_HArray2OfReal.hxx>
35 IMPLEMENT_STANDARD_RTTIEXT(FEmTool_LinearTension,FEmTool_ElementaryCriterion)
37 FEmTool_LinearTension::FEmTool_LinearTension(const Standard_Integer WorkDegree,
38 const GeomAbs_Shape ConstraintOrder):
39 RefMatrix(0,WorkDegree,0,WorkDegree)
42 static Standard_Integer Order = -333, WDeg = 14;
43 static math_Vector MatrixElemts(0, ((WDeg+2)*(WDeg+1))/2 -1 );
45 myOrder = PLib::NivConstr(ConstraintOrder);
47 if (myOrder != Order) {
48 //Calculating RefMatrix
49 if (WorkDegree > WDeg) throw Standard_ConstructionError("Degree too high");
51 Standard_Integer DerOrder = 1;
52 Handle(PLib_HermitJacobi) theBase = new PLib_HermitJacobi(WDeg, ConstraintOrder);
53 FEmTool_ElementsOfRefMatrix Elem = FEmTool_ElementsOfRefMatrix(theBase, DerOrder);
55 Standard_Integer maxDegree = WDeg+1;
56 math_IntegerVector anOrder(1,1,Min(4*(maxDegree/2+1),math::GaussPointsMax()));
57 math_Vector Lower(1,1,-1.), Upper(1,1,1.);
59 math_GaussSetIntegration anInt(Elem, Lower, Upper, anOrder);
60 MatrixElemts = anInt.Value();
63 Standard_Integer i, j, ii, jj;
64 for(ii = i = 0; i <= WorkDegree; i++) {
65 RefMatrix(i, i) = MatrixElemts(ii);
66 for(j = i+1, jj = ii+1; j <= WorkDegree; j++, jj++) {
67 RefMatrix(j, i) = RefMatrix(i, j) = MatrixElemts(jj);
73 Handle(TColStd_HArray2OfInteger) FEmTool_LinearTension::DependenceTable() const
75 if(myCoeff.IsNull()) throw Standard_DomainError("FEmTool_LinearTension::DependenceTable");
77 Handle(TColStd_HArray2OfInteger) DepTab =
78 new TColStd_HArray2OfInteger(myCoeff->LowerCol(), myCoeff->UpperCol(),
79 myCoeff->LowerCol(), myCoeff->UpperCol(),0);
81 for(i=1; i<=myCoeff->RowLength(); i++) DepTab->SetValue(i,i,1);
86 Standard_Real FEmTool_LinearTension::Value()
88 Standard_Integer deg = Min(myCoeff->ColLength() - 1, RefMatrix.UpperRow()),
89 i, j, j0 = myCoeff->LowerRow(), degH = Min(2*myOrder+1, deg),
90 NbDim = myCoeff->RowLength(), dim;
92 TColStd_Array2OfReal NewCoeff( 1, NbDim, 0, deg);
94 Standard_Real coeff = (myLast - myFirst)/2., cteh3 = 2./coeff,
100 Standard_Real J = 0.;
102 for(i = 0; i <= degH; i++) {
103 k1 = (i <= myOrder)? i : i - myOrder - 1;
104 mfact = Pow(coeff,k1);
105 for(dim = 1; dim <= NbDim; dim++)
106 NewCoeff(dim, i) = myCoeff->Value(j0 + i, dim) * mfact;
109 for(i = degH + 1; i <= deg; i++) {
110 for(dim = 1; dim <= NbDim; dim++)
111 NewCoeff(dim, i) = myCoeff->Value(j0 + i, dim);
114 for(dim = 1; dim <= NbDim; dim++) {
116 for(i = 0; i <= deg; i++) {
118 Jline = 0.5 * RefMatrix(i, i) * NewCoeff(dim, i);
120 for(j = 0; j < i; j++)
121 Jline += RefMatrix(i, j) * NewCoeff(dim, j);
123 J += Jline * NewCoeff(dim, i);
134 void FEmTool_LinearTension::Hessian(const Standard_Integer Dimension1,
135 const Standard_Integer Dimension2, math_Matrix& H)
138 Handle(TColStd_HArray2OfInteger) DepTab = DependenceTable();
140 if(Dimension1 < DepTab->LowerRow() || Dimension1 > DepTab->UpperRow() ||
141 Dimension2 < DepTab->LowerCol() || Dimension2 > DepTab->UpperCol())
142 throw Standard_OutOfRange("FEmTool_LinearTension::Hessian");
144 if(DepTab->Value(Dimension1,Dimension2) == 0)
145 throw Standard_DomainError("FEmTool_LinearTension::Hessian");
147 Standard_Integer deg = Min(RefMatrix.UpperRow(), H.RowNumber() - 1), degH = Min(2*myOrder+1, deg);
149 Standard_Real coeff = (myLast - myFirst)/2., cteh3 = 2./coeff, mfact;
150 Standard_Integer k1, k2, i, j, i0 = H.LowerRow(), j0 = H.LowerCol(), i1, j1;
155 for(i = 0; i <= degH; i++) {
156 k1 = (i <= myOrder)? i : i - myOrder - 1;
157 mfact = Pow(coeff,k1)*cteh3;
158 // Hermite*Hermite part of matrix
160 for(j = i; j <= degH; j++) {
161 k2 = (j <= myOrder)? j : j - myOrder - 1;
162 H(i1, j1) = mfact*Pow(coeff, k2)*RefMatrix(i, j);
163 if (i != j) H(j1, i1) = H(i1, j1);
166 // Hermite*Jacobi part of matrix
168 for(j = degH + 1; j <= deg; j++) {
169 H(i1, j1) = mfact*RefMatrix(i, j);
170 H(j1, i1) = H(i1, j1);
177 // Jacoby*Jacobi part of matrix
179 for(i = degH+1; i <= deg; i++) {
181 for(j = i; j <= deg; j++) {
182 H(i1, j1) = cteh3*RefMatrix(i, j);
183 if (i != j) H(j1, i1) = H(i1, j1);
191 void FEmTool_LinearTension::Gradient(const Standard_Integer Dimension, math_Vector& G)
193 if(Dimension < myCoeff->LowerCol() || Dimension > myCoeff->UpperCol())
194 throw Standard_OutOfRange("FEmTool_LinearTension::Gradient");
196 Standard_Integer deg = Min(G.Length() - 1, myCoeff->ColLength() - 1);
198 math_Vector X(0,deg);
199 Standard_Integer i, i1 = myCoeff->LowerRow();
200 for(i = 0; i <= deg; i++) X(i) = myCoeff->Value(i1+i, Dimension);
202 math_Matrix H(0,deg,0,deg);
203 Hessian(Dimension, Dimension, H);