1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Integration of OCCT 6.5.0 from SVN

This commit is contained in:
bugmaster
2011-03-16 07:30:28 +00:00
committed by bugmaster
parent 4903637061
commit 7fd59977df
16375 changed files with 3882564 additions and 0 deletions

63
src/FEmTool/FEmTool.cdl Executable file
View File

@@ -0,0 +1,63 @@
-- File: FEmTool.cdl
-- Created: Wed Oct 29 16:49:48 1997
-- Author: Roman BORISOV
-- <rbv@velox.nnov.matra-dtv.fr>
---Copyright: Matra Datavision 1997
package FEmTool
---Purpose: Tool to Finite Element methods
---Level: Advanced
uses
TCollection,
TColStd,
math,
PLib,
GeomAbs
is
class Assembly;
---Purpose: To define Criterium (or Energy) on finite element
deferred class ElementaryCriterion;
class LinearTension;
class LinearFlexion;
class LinearJerk;
---Purpose: To define sparse Matrix
deferred class SparseMatrix;
class ProfileMatrix;
---Purpose: Do define one curves with Finite Element
class Curve;
---Purpose: To define set of functions for calculating matrix
-- elements of RefMatrix by Gauss integration.
class ElementsOfRefMatrix;
-- instantiate classes
---Purpose: To define the table [Freedom's degree] [Dimension,Element]
-- which gives Index of Freedom's degree in the
-- assembly problem.
class AssemblyTable
instantiates Array2 from TCollection (HArray1OfInteger from TColStd);
class HAssemblyTable
instantiates HArray2 from TCollection (HArray1OfInteger from TColStd,
AssemblyTable from FEmTool);
---Purpose: To define list of segments with non-zero coefficients
-- of constraint
class ListOfVectors
instantiates List from TCollection (HArray1OfReal from TColStd);
---Purpose: To define sequence of constraints
class SeqOfLinConstr
instantiates Sequence from TCollection (ListOfVectors from FEmTool);
end FEmTool;

View File

@@ -0,0 +1,85 @@
-- File: FEmTool_Assembly.cdl
-- Created: Wed Oct 29 16:51:32 1997
-- Author: Roman BORISOV
-- <rbv@velox.nnov.matra-dtv.fr>
---Copyright: Matra Datavision 1997
class Assembly from FEmTool
---Purpose: Assemble and solve system from (one dimensional) Finite Elements
uses
Array2OfInteger from TColStd,
HAssemblyTable from FEmTool,
Matrix from math,
Vector from math,
ProfileMatrix from FEmTool,
SeqOfLinConstr from FEmTool,
SequenceOfReal from TColStd
raises
NotDone from StdFail,
DimensionError,
DomainError
is
Create(Dependence : Array2OfInteger from TColStd;
Table : HAssemblyTable from FEmTool)
returns Assembly from FEmTool;
NullifyMatrix(me : in out);
---Purpose: Nullify all Matrix 's Coefficient
AddMatrix(me : in out;
Element : Integer;
Dimension1 : Integer;
Dimension2 : Integer;
Mat : Matrix from math)
---Purpose: Add an elementary Matrix in the assembly Matrix
raises DomainError; -- if Dependence(Dimension1,Dimension2) is False
NullifyVector(me : in out);
---Purpose: Nullify all Coordinate of assembly Vector (second member)
AddVector(me : in out;
Element : Integer;
Dimension : Integer;
Vec : Vector from math);
---Purpose: Add an elementary Vector in the assembly Vector (second member)
ResetConstraint(me : in out);
---Purpose: Delete all Constraints.
NullifyConstraint(me : in out);
---Purpose: Nullify all Constraints.
AddConstraint(me : in out;
IndexofConstraint : Integer;
Element : Integer;
Dimension : Integer;
LinearForm : Vector from math;
Value : Real);
Solve(me : in out) returns Boolean;
---Purpose: Solve the assembly system
-- Returns Standard_False if the computation failed.
Solution(me; Solution : out Vector from math)
raises NotDone from StdFail; -- if the system is not solved.
NbGlobVar(me)
returns Integer;
GetAssemblyTable(me; AssTable : out HAssemblyTable from FEmTool);
fields
myDepTable : Array2OfInteger;
myRefTable : HAssemblyTable;
IsSolved : Boolean;
H : ProfileMatrix from FEmTool;
B : Vector from math;
GHGt : ProfileMatrix from FEmTool;
G : SeqOfLinConstr from FEmTool;
C : SequenceOfReal from TColStd;
end Assembly;

582
src/FEmTool/FEmTool_Assembly.cxx Executable file
View File

@@ -0,0 +1,582 @@
// File: FEmTool_Assembly.cxx
// Created: Tue Nov 17 12:07:58 1998
// Author: Igor FEOKTISTOV
// <ifv@paradox.nnov.matra-dtv.fr>
#include <FEmTool_Assembly.ixx>
#include <FEmTool_ListIteratorOfListOfVectors.hxx>
#include <FEmTool_ListOfVectors.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <math_Matrix.hxx>
//----------------------------------------------------------------------------
// Purpose - to find min index of global variables and define
//----------------------------------------------------------------------------
static Standard_Integer MinIndex(const Handle(FEmTool_HAssemblyTable)& Table)
{
Standard_Integer dim, el, nvar, Imin;
Standard_Integer diml = Table->LowerRow(), dimu = Table->UpperRow(),
ell = Table->LowerCol(), elu = Table->UpperCol(), nvarl, nvaru;
Handle(TColStd_HArray1OfInteger) T = Table->Value(diml, ell);
nvarl = T->Lower();
Imin = T->Value(nvarl);
for(dim = diml; dim <= dimu; dim++)
for(el = ell; el <= elu; el++) {
T = Table->Value(dim, el);
nvarl = T->Lower(); nvaru = T->Upper();
for(nvar = nvarl; nvar <= nvaru; nvar++) {
Imin = Min(Imin, T->Value(nvar));
}
}
return Imin;
}
//----------------------------------------------------------------------------
// Purpose - to find max index of global variables
//----------------------------------------------------------------------------
static Standard_Integer MaxIndex(const Handle(FEmTool_HAssemblyTable)& Table)
{
Standard_Integer dim, el, nvar, Imax;
Standard_Integer diml = Table->LowerRow(), dimu = Table->UpperRow(),
ell = Table->LowerCol(), elu = Table->UpperCol(), nvarl, nvaru;
Handle(TColStd_HArray1OfInteger) T = Table->Value(diml, ell);
nvarl = T->Lower();
Imax = T->Value(nvarl);
for(dim = diml; dim <= dimu; dim++)
for(el = ell; el <= elu; el++) {
T = Table->Value(dim, el);
nvarl = T->Lower(); nvaru = T->Upper();
for(nvar = nvarl; nvar <= nvaru; nvar++) {
Imax = Max(Imax, T->Value(nvar));
}
}
return Imax;
}
//=======================================================================
//function : FEmTool_Assembly
//purpose :
//=======================================================================
FEmTool_Assembly::FEmTool_Assembly(const TColStd_Array2OfInteger& Dependence,
const Handle(FEmTool_HAssemblyTable)& Table):
myDepTable(1, Dependence.ColLength(), 1, Dependence.RowLength()),
B(MinIndex(Table), MaxIndex(Table))
{
IsSolved = Standard_False;
myDepTable = Dependence;
myRefTable = Table;
TColStd_Array1OfInteger FirstIndexes(1, B.Length()); FirstIndexes.Init(B.Length());
#ifdef DEB
Standard_Integer dim, el, nvar, Imax, Imin, I0 = 1 - B.Lower(), i;
#else
Standard_Integer dim, el, nvar, Imin, I0 = 1 - B.Lower(), i;
#endif
Standard_Integer diml = Table->LowerRow(), dimu = Table->UpperRow(),
ell = Table->LowerCol(), elu = Table->UpperCol(), nvarl, nvaru;
Handle(TColStd_HArray1OfInteger) T;
for(dim = diml; dim <= dimu; dim++)
for(el = ell; el <= elu; el++) {
T = Table->Value(dim, el);
nvarl = T->Lower(); nvaru = T->Upper();
Imin = T->Value(nvarl) + I0;
for(nvar = nvarl; nvar <= nvaru; nvar++)
Imin = Min(Imin, T->Value(nvar) + I0);
for(nvar = nvarl; nvar <= nvaru; nvar++) {
i = T->Value(nvar) + I0;
FirstIndexes(i) = Min(FirstIndexes(i), Imin);
}
}
H = new FEmTool_ProfileMatrix(FirstIndexes);
NullifyMatrix();
NullifyVector();
}
void FEmTool_Assembly::NullifyMatrix()
{
H->Init(0.);
IsSolved = Standard_False;
}
//=======================================================================
//function : AddMatrix
//purpose :
//=======================================================================
void FEmTool_Assembly::AddMatrix(const Standard_Integer Element,
const Standard_Integer Dimension1,
const Standard_Integer Dimension2,
const math_Matrix& Mat)
{
if(myDepTable(Dimension1, Dimension2) == 0)
Standard_DomainError::Raise("FEmTool_Assembly::AddMatrix");
const TColStd_Array1OfInteger & T1 = myRefTable->Value(Dimension1,Element)->Array1();
const TColStd_Array1OfInteger & T2 = myRefTable->Value(Dimension2,Element)->Array1();
Standard_Integer nvarl = T1.Lower(), nvaru = Min(T1.Upper(), nvarl + Mat.RowNumber() - 1);
#ifdef DEB
Standard_Integer I, J, I0 = 1 - B.Lower(), i, ii, j, jj,
#else
Standard_Integer I, J, I0 = 1 - B.Lower(), i, ii, j,
#endif
i0 = Mat.LowerRow() - nvarl, j0 = Mat.LowerCol() - nvarl;
for(i = nvarl; i <= nvaru; i++) {
I = T1(i) + I0;
ii = i0+i;
for(j = nvarl; j <= i; j++) {
J = T2(j) + I0;
H->ChangeValue(I, J) += Mat(ii, j0+j);
}
}
IsSolved = Standard_False;
}
//=======================================================================
//function : NullifyVector
//purpose :
//=======================================================================
void FEmTool_Assembly::NullifyVector()
{
B.Init(0.);
}
//=======================================================================
//function : AddVector
//purpose :
//=======================================================================
void FEmTool_Assembly::AddVector(const Standard_Integer Element,
const Standard_Integer Dimension,
const math_Vector& Vec)
{
const TColStd_Array1OfInteger & T = myRefTable->Value(Dimension,Element)->Array1();
Standard_Integer nvarl = T.Lower(), nvaru = Min(T.Upper(), nvarl + Vec.Length() - 1),
i0 = Vec.Lower() - nvarl;
// Standard_Integer I, i;
Standard_Integer i;
for(i = nvarl; i <= nvaru; i++)
B(T(i)) += Vec(i0 + i);
}
//=======================================================================
//function : Solve
//purpose :
//=======================================================================
Standard_Boolean FEmTool_Assembly::Solve()
{
IsSolved = H->Decompose();
#if DEB
if (!IsSolved) {
cout << "Solve Echec H = " << endl;
H->OutM();
}
#endif
/* ????
while(!IsSolved && count < 5) {
Standard_Integer i;
for(i = 1; i <= H->RowNumber(); i++) {
H->ChangeValue(i,i) *= 2.;
}
IsSolved = H->Decompose();
count++;
}
*/
// Standard_Integer count = 0;
if(!G.IsEmpty() && IsSolved) {
// calculating H-1 Gt
math_Vector gi(B.Lower(), B.Upper()), qi(B.Lower(), B.Upper());
if(GHGt.IsNull() || GHGt->RowNumber() != G.Length()) {
TColStd_Array1OfInteger FirstIndexes(1, G.Length());
//-----------------------------------------------------------------
TColStd_Array2OfInteger H1(1, NbGlobVar(), 1, NbGlobVar()); H1.Init(1);
Standard_Integer i, j, k, l, BlockBeg = 1, BlockEnd;
Standard_Boolean Block, Zero;
for(i = 2; i <= NbGlobVar(); i++) {
BlockEnd = i - 1;
if(!H->IsInProfile(i, BlockEnd)) {
// Maybe, begin of block
Block = Standard_True;
for(j = i + 1; j <= NbGlobVar(); j++) {
if(H->IsInProfile(j, BlockEnd)) {
Block = Standard_False;
break;
}
}
if(Block) {
for(j = i; j <= NbGlobVar(); j++) {
for(k = BlockBeg; k <= BlockEnd; k++) {
H1(j, k) = 0; H1(k, j) = 0;
}
}
BlockBeg = BlockEnd + 1;
}
else i = j;
}
}
FEmTool_ListIteratorOfListOfVectors Iter1;
FEmTool_ListIteratorOfListOfVectors Iter2;
for(i = 1; i <= G.Length(); i++) {
const FEmTool_ListOfVectors& Gi = G.Value(i);
for(j = 1; j <= i; j++) {
const FEmTool_ListOfVectors& Gj = G.Value(j);
Zero = Standard_True;
for(Iter1.Initialize(Gi); Iter1.More(); Iter1.Next()) {
const Handle(TColStd_HArray1OfReal)& a = Iter1.Value();
for(k = a->Lower(); k <= a->Upper(); k++) {
for(Iter2.Initialize(Gj); Iter2.More(); Iter2.Next()) {
const Handle(TColStd_HArray1OfReal)& b = Iter2.Value();
for(l = b->Lower(); l <= b->Upper(); l++) {
if(H1(k, l) != 0) {
Zero = Standard_False;
break;
}
}
if(!Zero) break;
}
if(!Zero) break;
}
if(!Zero) break;
}
if(!Zero) {
FirstIndexes(i) = j;
break;
}
}
}
//-----------------------------------------------------------------------
// for(i = FirstIndexes.Lower(); i <= FirstIndexes.Upper(); i++)
// cout << "FirstIndexes(" << i << ") = " << FirstIndexes(i) << endl;
// FirstIndexes.Init(1); // temporary GHGt is full matrix
GHGt = new FEmTool_ProfileMatrix(FirstIndexes);
}
GHGt->Init(0.);
Standard_Integer i, j, k;
FEmTool_ListIteratorOfListOfVectors Iter;
for(i = 1; i <= G.Length(); i++) {
const FEmTool_ListOfVectors& L = G.Value(i);
gi.Init(0.);
// preparing i-th line of G (or column of Gt)
for(Iter.Initialize(L); Iter.More(); Iter.Next()) {
const Handle(TColStd_HArray1OfReal)& a = Iter.Value();
for(j = a->Lower(); j <= a->Upper(); j++) gi(j) = a->Value(j); // gi - full line of G
}
// -1 t
H->Solve(gi, qi); // solving H*qi = gi, qi is column of H G
// -1 t
// Calculation of product M = G H G
// for each i all elements of i-th column of M are calculated for k >= i
for(k = i; k <= G.Length(); k++) {
if(GHGt->IsInProfile(k, i)) {
Standard_Real m = 0.; // m = M(k,i)
const FEmTool_ListOfVectors& L = G.Value(k);
for(Iter.Initialize(L); Iter.More(); Iter.Next()) {
const Handle(TColStd_HArray1OfReal)& a = Iter.Value();
for(j = a->Lower(); j <= a->Upper(); j++) m += qi(j) * a->Value(j); // scalar product of
// k-th line of G and i-th column of H-1 Gt
}
GHGt->ChangeValue(k, i) = m;
}
}
}
IsSolved = GHGt->Decompose();
/* count = 0;
while(!IsSolved && count < 5) {
for(i = 1; i <= GHGt->RowNumber(); i++) {
GHGt->ChangeValue(i,i) *= 2.;
}
IsSolved = GHGt->Decompose();
count++;
}*/
}
return IsSolved;
}
//=======================================================================
//function : Solution
//purpose :
//=======================================================================
void FEmTool_Assembly::Solution(math_Vector& Solution) const
{
if(!IsSolved) StdFail_NotDone::Raise("FEmTool_Assembly::Solution");
if(G.IsEmpty()) H->Solve(B, Solution);
else {
math_Vector v1(B.Lower(), B.Upper());
H->Solve(B, v1);
math_Vector l(1, G.Length()), v2(1, G.Length());
Standard_Integer i, j;
FEmTool_ListIteratorOfListOfVectors Iter;
for(i = 1; i <= G.Length(); i++) {
const FEmTool_ListOfVectors& L = G.Value(i);
Standard_Real m = 0.;
for(Iter.Initialize(L); Iter.More(); Iter.Next()) {
const Handle(TColStd_HArray1OfReal)& a = Iter.Value();
for(j = a->Lower(); j <= a->Upper(); j++)
m += v1(j) * a->Value(j); // scalar product
// G v1
}
v2(i) = m - C.Value(i);
}
GHGt->Solve(v2, l); // Solving M*l = v2
v1 = B;
// Calculation v1 = B-Gt*l
// v1(j) = B(j) - Gt(j,i)*l(i) = B(j) - G(i,j)*l(i)
//
for(i = 1; i <= G.Length(); i++) {
const FEmTool_ListOfVectors& L = G.Value(i);
for(Iter.Initialize(L); Iter.More(); Iter.Next()) {
const Handle(TColStd_HArray1OfReal)& a = Iter.Value();
for(j = a->Lower(); j <= a->Upper(); j++) v1(j) -= l(i) * a->Value(j);
}
}
H->Solve(v1, Solution);
}
}
Standard_Integer FEmTool_Assembly::NbGlobVar() const
{
return B.Length();
}
void FEmTool_Assembly::GetAssemblyTable(Handle(FEmTool_HAssemblyTable)& AssTable) const
{
AssTable = myRefTable;
}
void FEmTool_Assembly::ResetConstraint()
{
G.Clear();
C.Clear();
}
void FEmTool_Assembly::NullifyConstraint()
{
FEmTool_ListIteratorOfListOfVectors Iter;
Standard_Integer i;
for(i = 1; i <= G.Length(); i++) {
C.SetValue(i, 0.);
for(Iter.Initialize(G.Value(i)); Iter.More(); Iter.Next())
Iter.Value()->Init(0.);
}
}
//=======================================================================
//function : AddConstraint
//purpose :
//=======================================================================
void FEmTool_Assembly::AddConstraint(const Standard_Integer IndexofConstraint,
const Standard_Integer Element,
const Standard_Integer Dimension,
const math_Vector& LinearForm,
const Standard_Real Value)
{
while(G.Length() < IndexofConstraint) {
// Add new lines in G
FEmTool_ListOfVectors L;
G.Append(L);
C.Append(0.);
}
FEmTool_ListOfVectors& L = G.ChangeValue(IndexofConstraint);
Handle(TColStd_HArray1OfInteger) Indexes = myRefTable->Value(Dimension,Element);
Standard_Integer i, Imax = 0, Imin = NbGlobVar();
for(i = Indexes->Lower(); i <= Indexes->Upper(); i++) {
Imin = Min(Imin, Indexes->Value(i));
Imax = Max(Imax, Indexes->Value(i));
}
Handle(TColStd_HArray1OfReal) Coeff;
if(L.IsEmpty()) {
Coeff = new TColStd_HArray1OfReal(Imin,Imax);
Coeff->Init(0.);
L.Append(Coeff);
}
else {
FEmTool_ListIteratorOfListOfVectors Iter(L);
Standard_Integer i;
Standard_Real s1 = 0, s2 = 0;
Handle(TColStd_HArray1OfReal) Aux1, Aux2;
for(i=1; Iter.More(); Iter.Next(), i++) {
if(Imin >= Iter.Value()->Lower()) {
s1 = i;
Aux1 = Iter.Value();
if(Imax <= Iter.Value()->Upper()) {
s2 = s1;
Coeff = Iter.Value();
break;
}
}
if(Imax <= Iter.Value()->Upper()) {
s2 = i;
Aux2 = Iter.Value();
}
}
if(s1 != s2) {
if(s1 == 0) {
if(Imax < Aux2->Lower()) {
// inserting before first segment
Coeff = new TColStd_HArray1OfReal(Imin,Imax);
Coeff->Init(0.);
L.Prepend(Coeff);
}
else {
// merge new and first segment
Coeff = new TColStd_HArray1OfReal(Imin, Aux2->Upper());
for(i = Imin; i <= Aux2->Lower() - 1; i++) Coeff->SetValue(i, 0.);
for(i = Aux2->Lower(); i <= Aux2->Upper(); i++) Coeff->SetValue(i, Aux2->Value(i));
L.First() = Coeff;
}
}
else if(s2 == 0) {
if(Imin > Aux1->Upper()) {
// append new
Coeff = new TColStd_HArray1OfReal(Imin,Imax);
Coeff->Init(0.);
L.Append(Coeff);
}
else {
// merge new and last segment
Coeff = new TColStd_HArray1OfReal(Aux1->Lower(), Imax);
for(i = Aux1->Lower(); i <= Aux1->Upper(); i++) Coeff->SetValue(i, Aux1->Value(i));
for(i = Aux1->Upper() + 1; i <= Imax; i++) Coeff->SetValue(i, 0.);
L.Last() = Coeff;
}
}
else if(Imin <= Aux1->Upper() && Imax < Aux2->Lower()) {
// merge s1 and new
Coeff = new TColStd_HArray1OfReal(Aux1->Lower(), Imax);
for(i = Aux1->Lower(); i <= Aux1->Upper(); i++) Coeff->SetValue(i, Aux1->Value(i));
for(i = Aux1->Upper() + 1; i <= Imax; i++) Coeff->SetValue(i, 0.);
Iter.Initialize(L);
for(i = 1; i < s1; Iter.Next(), i++);
Iter.Value() = Coeff;
}
else if(Imin > Aux1->Upper() && Imax >= Aux2->Lower()) {
// merge new and first segment
Coeff = new TColStd_HArray1OfReal(Imin, Aux2->Upper());
for(i = Imin; i <= Aux2->Lower() - 1; i++) Coeff->SetValue(i, 0.);
for(i = Aux2->Lower(); i <= Aux2->Upper(); i++) Coeff->SetValue(i, Aux2->Value(i));
Iter.Initialize(L);
for(i = 1; i < s2; Iter.Next(), i++);
Iter.Value() = Coeff;
}
else if(Imin > Aux1->Upper() && Imax < Aux2->Lower()) {
// inserting new between s1 and s2
Coeff = new TColStd_HArray1OfReal(Imin,Imax);
Coeff->Init(0.);
Iter.Initialize(L);
for(i = 1; i < s1; Iter.Next(), i++);
L.InsertAfter(Coeff,Iter);
}
else {
// merge s1, new, s2 and remove s2
Coeff = new TColStd_HArray1OfReal(Aux1->Lower(), Aux2->Upper());
for(i = Aux1->Lower(); i <= Aux1->Upper(); i++) Coeff->SetValue(i, Aux1->Value(i));
for(i = Aux1->Upper() + 1; i <= Aux2->Lower() - 1; i++) Coeff->SetValue(i, 0.);
for(i = Aux2->Lower(); i <= Aux2->Upper(); i++) Coeff->SetValue(i, Aux2->Value(i));
Iter.Initialize(L);
for(i = 1; i < s1; Iter.Next(), i++);
Iter.Value() = Coeff;
Iter.Next();
L.Remove(Iter);
}
}
}
// adding
Standard_Integer j = LinearForm.Lower();
for(i = Indexes->Lower(); i <= Indexes->Upper(); i++, j++) {
Coeff->ChangeValue(Indexes->Value(i)) += LinearForm(j);
}
C.ChangeValue(IndexofConstraint) += Value;
}

97
src/FEmTool/FEmTool_Curve.cdl Executable file
View File

@@ -0,0 +1,97 @@
-- File: FEmTool_Curve.cdl
-- Created: Fri Sep 12 18:23:02 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
class Curve from FEmTool inherits TShared from MMgt
---Purpose: Curve defined by Polynomial Elements.
uses
Base from PLib,
Array1OfReal from TColStd,
HArray1OfInteger from TColStd,
Array2OfReal from TColStd,
Array1OfInteger from TColStd,
HArray1OfReal from TColStd
raises
DimensionError
is
Create(Dimension : Integer;
NbElements : Integer;
TheBase : Base from PLib;
Tolerance : Real);
Knots(me)
---C++: return &
returns Array1OfReal;
SetElement(me : mutable; IndexOfElement : Integer;
Coeffs : Array2OfReal);
D0(me : mutable; U : Real; Pnt : out Array1OfReal);
D1(me : mutable; U : Real; Vec : out Array1OfReal);
D2(me : mutable; U : Real; Vec : out Array1OfReal);
Length(me : mutable;
FirstU, LastU : Real;
Length : out Real);
GetElement(me : mutable; IndexOfElement : Integer;
Coeffs : out Array2OfReal);
GetPolynom(me : mutable; Coeffs : out Array1OfReal);
---Purpose: returns coefficients of all elements in canonical base.
NbElements(me) returns Integer;
Dimension(me) returns Integer;
Base(me) returns Base from PLib;
Degree(me; IndexOfElement : Integer) returns Integer;
SetDegree(me : mutable;
IndexOfElement : Integer;
Degree : Integer);
ReduceDegree(me : mutable;
IndexOfElement : Integer; Tol : Real;
NewDegree : out Integer; MaxError : out Real);
Update(me:mutable; Element : Integer; Order : Integer)
is private;
fields
myNbElements : Integer;
myDimension : Integer;
myTolerance : Real;
myBase : Base from PLib;
myKnots : HArray1OfReal;
myDegree : Array1OfInteger;
myCoeff : Array1OfReal; -- Coeff in <myBase>
myPoly : Array1OfReal; -- Coeff in the canonnical Bases
myDeri : Array1OfReal; -- Coeff of the first Derivative
-- in the canonical Base
myDsecn : Array1OfReal; -- Coeff of the second Derivative
-- in the canonnical Base
HasPoly : Array1OfInteger; -- Say If the Ith Element
-- has an canonical Representation.
HasDeri : Array1OfInteger; -- Say If the Ith Element
-- has an first Derivative Representation.
HasSecn : Array1OfInteger; -- Say If the Ith Element
-- has an second Derivative Representation.
myLength : Array1OfReal; -- Table of Length Element by Element
Uf, Ul : Real;
Denom, USum : Real;
myIndex, myPtr : Integer;
end Curve;

464
src/FEmTool/FEmTool_Curve.cxx Executable file
View File

@@ -0,0 +1,464 @@
// File: FEmTool_Curve.cxx
// Created: Tue Nov 4 10:45:06 1997
// Author: Roman BORISOV / Igor FEOKTISTOV
// <rbv@redfox.nnov.matra-dtv.fr>
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#include <FEmTool_Curve.ixx>
#include <PLib.hxx>
#include <PLib_JacobiPolynomial.hxx>
#include <PLib_HermitJacobi.hxx>
//=======================================================================
//function : FEmTool_Curve
//purpose :
//=======================================================================
FEmTool_Curve::FEmTool_Curve(const Standard_Integer Dimension,
const Standard_Integer NbElements,
const Handle(PLib_Base)& TheBase,
const Standard_Real Tolerance) :
myNbElements(NbElements), myDimension(Dimension),
myTolerance(Tolerance),
myBase(TheBase), myDegree(1, myNbElements),
myCoeff(1, myDimension*myNbElements*(myBase->WorkDegree() + 1)),
myPoly(1, myDimension*myNbElements*(myBase->WorkDegree() + 1)),
myDeri(1, myDimension*myNbElements*(myBase->WorkDegree())),
myDsecn(1, myDimension*myNbElements*(myBase->WorkDegree() - 1)),
HasPoly(1, myNbElements), HasDeri(1, myNbElements),
HasSecn(1, myNbElements), myLength(1, myNbElements),
myIndex(0)
{
myKnots = new TColStd_HArray1OfReal(1, myNbElements + 1);
myDegree.Init(myBase->WorkDegree());
HasPoly.Init(0);
HasDeri.Init(0);
HasSecn.Init(0);
myLength.Init(-1);
}
TColStd_Array1OfReal& FEmTool_Curve::Knots() const
{
return myKnots->ChangeArray1();
}
//=======================================================================
//function : SetElement
//purpose :
//=======================================================================
void FEmTool_Curve::SetElement(const Standard_Integer IndexOfElement,
const TColStd_Array2OfReal& Coeffs)
{
Standard_Integer i, j, degBase, deg;
if (IndexOfElement > myNbElements || IndexOfElement < 1) Standard_OutOfRange::Raise();
degBase = myBase->WorkDegree();
deg = myDegree(IndexOfElement);
Standard_Integer iBase = (IndexOfElement - 1)*(degBase + 1)*myDimension,
i1 = iBase-myDimension, i2 = Coeffs.LowerRow() - 1,
j1 = Coeffs.LowerCol() - 1;
for(i = 1; i <= deg + 1; i++) {
i1 += myDimension; i2++;
for(j = 1; j <= myDimension; j++)
myCoeff(i1 + j) = Coeffs(i2, j1 + j);
}
Standard_Real stenor = (myKnots->Value(IndexOfElement + 1) - myKnots->Value(IndexOfElement)) / 2.,
mfact;
Handle(PLib_HermitJacobi) myHermitJacobi = (*((Handle(PLib_HermitJacobi)*)&myBase));
i1 = iBase;
i2 = iBase + (myHermitJacobi->NivConstr() + 1) * myDimension;
for(i = 1; i <= myHermitJacobi->NivConstr(); i++) {
i1 += myDimension; i2 += myDimension;
mfact = Pow(stenor, i);
for(j = 1; j <= myDimension; j++) {
myCoeff(i1 + j) *= mfact;
myCoeff(i2 + j) *= mfact;
}
}
HasPoly(IndexOfElement) = HasDeri(IndexOfElement) = HasSecn(IndexOfElement) = 0;
myLength(IndexOfElement) = - 1;
}
//=======================================================================
//function : GetElement
//purpose :
//=======================================================================
void FEmTool_Curve::GetElement(const Standard_Integer IndexOfElement, TColStd_Array2OfReal& Coeffs)
{
Standard_Integer i, j, degBase, deg;
if (IndexOfElement > myNbElements || IndexOfElement < 1) Standard_OutOfRange::Raise();
degBase = myBase->WorkDegree();
deg = myDegree(IndexOfElement);
Standard_Integer iBase = (IndexOfElement - 1)*(degBase + 1)*myDimension,
i1 = iBase-myDimension, i2 = Coeffs.LowerRow() - 1,
j1 = Coeffs.LowerCol() - 1;
for(i = 1; i <= deg + 1; i++) {
i1 += myDimension; i2++;
for(j = 1; j <= myDimension; j++)
Coeffs(i2, j1 + j) = myCoeff.Value(i1 + j);
}
Standard_Real stenor = 2. / (myKnots->Value(IndexOfElement + 1) - myKnots->Value(IndexOfElement)),
mfact;
Handle(PLib_HermitJacobi) myHermitJacobi = (*((Handle(PLib_HermitJacobi)*)&myBase));
i2 = Coeffs.LowerRow();
Standard_Integer i3 = i2 + myHermitJacobi->NivConstr() + 1;
for(i = 1; i <= myHermitJacobi->NivConstr(); i++) {
mfact = Pow(stenor, i);
for(j = j1+1; j <= myDimension; j++) {
Coeffs(i2 + i, j) *= mfact;
Coeffs(i3 + i, j) *= mfact;
}
}
}
//=======================================================================
//function : GetPolynom
//purpose :
//=======================================================================
void FEmTool_Curve::GetPolynom(TColStd_Array1OfReal& Coeffs)
{
Standard_Integer IndexOfElement, i, di = Coeffs.Lower() - myPoly.Lower();
for(IndexOfElement = 1; IndexOfElement <= myNbElements; IndexOfElement++)
if (!HasPoly.Value(IndexOfElement)) Update(IndexOfElement, 0);
for(i = myPoly.Lower(); i <= myPoly.Upper(); i++)
Coeffs(di + i) = myPoly(i);
}
//=======================================================================
//function : D0
//purpose :
//=======================================================================
void FEmTool_Curve::D0(const Standard_Real U, TColStd_Array1OfReal& Pnt)
{
Standard_Integer deg;
Standard_Real S;
if (!myIndex || (U<Uf) || (U>Ul) ||
(myKnots->Value(myIndex)!=Uf) ||
(myKnots->Value(myIndex+1)!=Ul)) {
// Search the span
if(U <= myKnots->Value(2)) myIndex = 1;
else {
for(myIndex = 2; myIndex <= myNbElements; myIndex++)
if(U >= myKnots->Value(myIndex) && U <= myKnots->Value(myIndex+1)) break;
if (myIndex > myNbElements) myIndex = myNbElements;
}
Uf = myKnots->Value(myIndex);
Ul = myKnots->Value(myIndex+1);
Denom = 1. /(Ul-Uf);
USum = Uf+Ul;
myPtr = (myIndex - 1)*(myBase->WorkDegree()+ 1)*myDimension + 1;
}
deg = myDegree(myIndex);
if (!HasPoly.Value(myIndex)) Update(myIndex, 0);
//Parameter normalization: S [-1, 1]
S = (2*U - USum)*Denom;
PLib::NoDerivativeEvalPolynomial(S, deg, myDimension, deg*myDimension,
myPoly(myPtr), Pnt(Pnt.Lower()));
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
void FEmTool_Curve::D1(const Standard_Real U, TColStd_Array1OfReal& Vec)
{
Standard_Integer deg, i;
Standard_Real S;
if (!myIndex || (U<Uf) || (U>Ul) ||
(myKnots->Value(myIndex)!=Uf) ||
(myKnots->Value(myIndex+1)!=Ul)) {
// Search the span
if(U <= myKnots->Value(2)) myIndex = 1;
else {
for(myIndex = 2; myIndex <= myNbElements; myIndex++)
if(U >= myKnots->Value(myIndex) && U <= myKnots->Value(myIndex+1)) break;
if (myIndex > myNbElements) myIndex = myNbElements;
}
Uf = myKnots->Value(myIndex);
Ul = myKnots->Value(myIndex+1);
Denom = 1. /(Ul-Uf);
USum = Uf+Ul;
myPtr = (myIndex - 1)*(myBase->WorkDegree()+ 1)*myDimension + 1;
}
deg = myDegree(myIndex);
if (!HasDeri.Value(myIndex)) Update(myIndex, 1);
//Parameter normalization: S [-1, 1]
S = (2*U - USum) * Denom;
PLib::NoDerivativeEvalPolynomial(S, deg-1, myDimension, (deg-1)*myDimension,
myDeri(1+(myIndex - 1)*myBase->WorkDegree()*
myDimension),
Vec(Vec.Lower()));
S = 2*Denom;
for(i=Vec.Lower(); i<=Vec.Upper(); i++) Vec(i) *= S;
}
//=======================================================================
//function : D2
//purpose :
//=======================================================================
void FEmTool_Curve::D2(const Standard_Real U, TColStd_Array1OfReal& Vec)
{
Standard_Integer deg, i;
Standard_Real S;
if (!myIndex || (U<Uf) || (U>Ul) ||
(myKnots->Value(myIndex)!=Uf) ||
(myKnots->Value(myIndex+1)!=Ul)) {
// Search the span
if(U <= myKnots->Value(2)) myIndex = 1;
else {
for(myIndex = 2; myIndex <= myNbElements; myIndex++)
if(U >= myKnots->Value(myIndex) && U <= myKnots->Value(myIndex+1)) break;
if (myIndex > myNbElements) myIndex = myNbElements;
}
Uf = myKnots->Value(myIndex);
Ul = myKnots->Value(myIndex+1);
Denom = 1. /(Ul-Uf);
USum = Uf+Ul;
myPtr = (myIndex - 1)*(myBase->WorkDegree()+ 1)*myDimension + 1;
}
deg = myDegree(myIndex);
if (!HasSecn.Value(myIndex)) Update(myIndex, 2);
//Parameter normalization: S [-1, 1]
S = (2*U - USum)*Denom;
PLib::NoDerivativeEvalPolynomial(S, deg-2, myDimension, (deg-2)*myDimension,
myDsecn(1+(myIndex - 1)*
(myBase->WorkDegree() - 1)*myDimension),
Vec(Vec.Lower()));
S = 4*Denom*Denom;
for(i=Vec.Lower(); i<=Vec.Upper(); i++) Vec(i) *= S;
}
//=======================================================================
//function : Length
//purpose :
//=======================================================================
void FEmTool_Curve::Length(const Standard_Real FirstU,
const Standard_Real LastU,
Standard_Real& Length)
{
Standard_Integer Low, High, deg, degBase, i, Ptr;
if(FirstU > LastU) Standard_OutOfRange::Raise("FEmTool_Curve::Length");
if(myKnots->Value(1) > FirstU) Low = 1;
else
for(Low = 1; Low <= myNbElements; Low++)
if(FirstU >= myKnots->Value(Low) && FirstU <= myKnots->Value(Low+1)) break;
if(Low > myNbElements) Low = myNbElements;
if(myKnots->Value(1) > LastU) High = 1;
else
for(High = Low; High <= myNbElements; High++)
if(LastU >= myKnots->Value(High) && LastU <= myKnots->Value(High+1)) break;
if(myKnots->Value(myNbElements + 1) < LastU) High = myNbElements;
Standard_Real Li;
degBase = myBase->WorkDegree();
Length = 0;
Standard_Real FirstS, LastS;
FirstS = (2*FirstU - myKnots->Value(Low) - myKnots->Value(Low + 1))/
(myKnots->Value(Low + 1) - myKnots->Value(Low));
LastS = (2*LastU - myKnots->Value(High) - myKnots->Value(High + 1))/
(myKnots->Value(High + 1) - myKnots->Value(High));
if(Low == High) {
Ptr = (Low - 1)*(degBase + 1)*myDimension + 1;
deg = myDegree(Low);
if(!HasPoly(Low)) Update(Low, 0);
PLib::EvalLength(deg, myDimension, myPoly(Ptr),
FirstS, LastS, Length);
return;
}
deg = myDegree(Low);
Ptr = (Low - 1)*(degBase + 1)*myDimension + 1;
if(!HasPoly(Low)) Update(Low, 0);
if(FirstS < -1.) {
PLib::EvalLength(deg, myDimension, myPoly(Ptr), FirstS, -1., Li);
Length += Li;
if(myLength(Low) < 0.) {
PLib::EvalLength(deg, myDimension, myPoly(Ptr), -1., 1.,Li);
myLength(Low) = Li;
}
Length += myLength(Low);
}
else {
PLib::EvalLength(deg, myDimension, myPoly(Ptr), FirstS, 1., Li);
Length += Li;
}
deg = myDegree(High);
Ptr = (High - 1)*(degBase + 1)*myDimension + 1;
if(!HasPoly(High)) Update(High, 0);
if(LastS > 1.) {
PLib::EvalLength(deg, myDimension, myPoly(Ptr), 1., LastS, Li);
Length += Li;
if(myLength(High) < 0.) {
PLib::EvalLength(deg, myDimension, myPoly(Ptr), -1., 1., Li);
myLength(High) = Li;
}
Length += myLength(High);
}
else {
PLib::EvalLength(deg, myDimension, myPoly(Ptr), -1., LastS, Li);
Length += Li;
}
for(i = Low + 1; i < High; i++) {
if (myLength.Value(i) < 0) {
Ptr = (i - 1)*(degBase + 1)*myDimension + 1;
deg = myDegree(i);
if(!HasPoly(i)) Update(i, 0);
PLib::EvalLength(deg, myDimension, myPoly(Ptr), -1., 1., Li);
myLength(i) = Li;
}
Length += myLength(i);
}
}
Standard_Integer FEmTool_Curve::NbElements() const
{
return myNbElements;
}
Standard_Integer FEmTool_Curve::Dimension() const
{
return myDimension;
}
Handle(PLib_Base) FEmTool_Curve::Base() const
{
return myBase;
}
Standard_Integer FEmTool_Curve::Degree(const Standard_Integer IndexOfElement) const
{
return myDegree.Value(IndexOfElement);
}
//=======================================================================
//function : SetDegree
//purpose :
//=======================================================================
void FEmTool_Curve::SetDegree(const Standard_Integer IndexOfElement,
const Standard_Integer Degree)
{
if (Degree <= myBase->WorkDegree()) {
myDegree(IndexOfElement) = Degree;
HasPoly(IndexOfElement) = HasDeri(IndexOfElement) = HasSecn(IndexOfElement) = 0;
myLength(IndexOfElement) = -1;
}
else if(Degree > myBase->WorkDegree()) Standard_OutOfRange::Raise("FEmTool_Curve::SetDegree");
}
//=======================================================================
//function : ReduceDegree
//purpose :
//=======================================================================
void FEmTool_Curve::ReduceDegree(const Standard_Integer IndexOfElement,
const Standard_Real Tol,
Standard_Integer& NewDegree,
Standard_Real& MaxError)
{
Standard_Integer deg = myDegree(IndexOfElement);
Standard_Integer Ptr = (IndexOfElement - 1)*
(myBase->WorkDegree() + 1)*myDimension + 1;
myBase->ReduceDegree(myDimension, deg, Tol, myCoeff.ChangeValue(Ptr), NewDegree, MaxError);
Handle(PLib_HermitJacobi) myHermitJacobi = (*((Handle(PLib_HermitJacobi)*)&myBase));
NewDegree = Max(NewDegree, 2 * myHermitJacobi->NivConstr() + 1);
if (NewDegree < deg) {
myDegree(IndexOfElement) = NewDegree;
HasPoly(IndexOfElement) = HasDeri(IndexOfElement) = HasSecn(IndexOfElement) = 0;
myLength(IndexOfElement) = -1;
}
}
//=======================================================================
//function : Update
//purpose :
//=======================================================================
void FEmTool_Curve::Update(const Standard_Integer Index,
const Standard_Integer Order)
{
Standard_Integer degBase = myBase->WorkDegree(), deg = myDegree(Index);
if (!HasPoly(Index)) {
Standard_Integer Ptr = (Index - 1)*(degBase + 1)*myDimension + 1;
TColStd_Array1OfReal Coeff(myPoly.ChangeValue(Ptr), 0, myDimension*(deg + 1) - 1);
TColStd_Array1OfReal BaseCoeff(myCoeff.ChangeValue(Ptr), 0, myDimension*(deg + 1) - 1);
myBase->ToCoefficients(myDimension, deg, BaseCoeff, Coeff);
HasPoly(Index) = 1;
}
if (Order >=1) {
Standard_Integer i1 = (Index - 1)*(degBase)*myDimension - myDimension,
i2 = (Index - 1)*(degBase + 1)*myDimension;
Standard_Integer i,j;
if (!HasDeri.Value(Index)) {
for(i = 1; i <= deg; i++) {
i1 += myDimension; i2 += myDimension;
for(j = 1; j<= myDimension; j++)
myDeri(i1 + j) = i*myPoly.Value(i2 + j);
}
HasDeri(Index) = 1;
}
if ((Order>=2) &&!HasSecn.Value(Index)) {
i1 = (Index - 1)*(degBase-1)*myDimension - myDimension,
i2 = (Index - 1)*(degBase)*myDimension;
for(i = 1; i < deg; i++) {
i1 += myDimension; i2 += myDimension;
for(j = 1; j<= myDimension; j++)
myDsecn(i1 + j) = i*myDeri.Value(i2 + j);
}
HasSecn(Index) = 1;
}
}
}

View File

@@ -0,0 +1,66 @@
-- File: FEmTool_ElementaryCriterion.cdl
-- Created: Thu Sep 11 18:06:06 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
deferred class ElementaryCriterion from FEmTool inherits TShared from MMgt
---Purpose: defined J Criteria to used in minimisation
uses
Vector from math,
Matrix from math,
HArray2OfReal from TColStd,
HArray2OfInteger from TColStd
raises
NotImplemented,
DomainError
is
Set(me : mutable;
Coeff : HArray2OfReal)
---Purpose: Set the coefficient of the Element (the Curve)
is static;
Set(me : mutable;
FirstKnot : Real;
LastKnot : Real)
---Purpose: Set the definition interval of the Element
is virtual;
DependenceTable(me)
returns HArray2OfInteger from TColStd
---Purpose: To know if two dimension are independent.
is deferred;
Value (me : mutable)
---Purpose: To Compute J(E) where E is the current Element
returns Real is deferred;
Hessian(me : mutable ;
Dim1 : Integer;
Dim2 : Integer;
H : out Matrix from math)
---Purpose: To Compute J(E) the coefficients of Hessian matrix of
-- J(E) wich are crossed derivatives in dimensions <Dim1>
-- and <Dim2>.
raises DomainError -- If DependenceTable(Dimension1,Dimension2) is False
is deferred;
Gradient(me : mutable;
Dim : Integer;
G : out Vector from math)
---Purpose: To Compute the coefficients in the dimension <dim>
-- of the J(E)'s Gradient where E is the current Element
is deferred;
fields
myCoeff : HArray2OfReal is protected;
myFirst, myLast : Real is protected;
end ElementaryCriterion;

View File

@@ -0,0 +1,19 @@
// File: FEmTool_ElementaryCriterion.cxx
// Created: Thu Nov 5 11:28:29 1998
// Author: Igor FEOKTISTOV
// <ifv@paradox.nnov.matra-dtv.fr>
#include <FEmTool_ElementaryCriterion.ixx>
void FEmTool_ElementaryCriterion::Set(const Handle(TColStd_HArray2OfReal)& Coeff)
{
myCoeff = Coeff;
}
void FEmTool_ElementaryCriterion::Set(const Standard_Real FirstKnot, const Standard_Real LastKnot)
{
myFirst = FirstKnot; myLast = LastKnot;
}

View File

@@ -0,0 +1,63 @@
-- File: FEmTool_ElementsOfRefMatrix.cdl
-- Created: Tue Nov 10 11:35:26 1998
-- Author: Igor FEOKTISTOV
-- <ifv@paradox.nnov.matra-dtv.fr>
---Copyright: Matra Datavision 1998
class ElementsOfRefMatrix from FEmTool inherits FunctionSet from math
---Purpose: this class describes the functions needed for
-- calculating matrix elements of RefMatrix for linear
-- criteriums (Tension, Flexsion and Jerk).
-- Each function from set gives value Pi(u)'*Pj(u)' or
-- Pi(u)''*Pj(u)'' or Pi(u)'''*Pj(u)''' for each i and j,
-- where Pi(u) is i-th basis function of expansion and
-- (') means derivative.
uses
Vector from math,
Base from PLib
raises
ConstructionError from Standard
is
Create(TheBase : Base from PLib; DerOrder : Integer from Standard)
-- DerOrder is order of derivative (1, 2, 3)
returns ElementsOfRefMatrix from FEmTool
raises ConstructionError from Standard;
-- if DerOrder is not valid
NbVariables(me)
---Purpose: returns the number of variables of the function.
-- It is supposed that NbVariables = 1.
returns Integer;
NbEquations(me)
---Purpose: returns the number of equations of the function.
returns Integer;
Value(me: in out; X: Vector; F: out Vector)
---Purpose: computes the values <F> of the functions for the
-- variable <X>.
-- returns True if the computation was done successfully,
-- False otherwise.
-- F contains results only for i<=j in following order:
-- P0*P0, P0*P1, P0*P2... P1*P1, P1*P2,... (upper triangle of
-- matrix {PiPj})
returns Boolean;
fields
myBase : Base from PLib;
myDerOrder : Integer;
myNbEquations : Integer;
end ElementsOfRefMatrix;

View File

@@ -0,0 +1,64 @@
// File: FEmTool_ElementsOfRefMatrix.cxx
// Created: Tue Nov 10 12:58:16 1998
// Author: Igor FEOKTISTOV
// <ifv@paradox.nnov.matra-dtv.fr>
#include <FEmTool_ElementsOfRefMatrix.ixx>
#include <PLib_Base.hxx>
#include <TColStd_Array1OfReal.hxx>
FEmTool_ElementsOfRefMatrix::FEmTool_ElementsOfRefMatrix(const Handle(PLib_Base)& TheBase,
const Standard_Integer DerOrder):
myBase(TheBase)
{
if(DerOrder < 0 || DerOrder > 3)
Standard_ConstructionError::Raise("FEmTool_ElementsOfRefMatrix");
myDerOrder = DerOrder;
myNbEquations = (myBase->WorkDegree()+2)*(myBase->WorkDegree()+1)/2;
}
Standard_Integer FEmTool_ElementsOfRefMatrix::NbVariables() const
{
return 1;
}
Standard_Integer FEmTool_ElementsOfRefMatrix::NbEquations() const
{
return myNbEquations;
}
Standard_Boolean FEmTool_ElementsOfRefMatrix::Value(const math_Vector& X, math_Vector& F)
{
if(F.Length() < myNbEquations) Standard_OutOfRange::Raise("FEmTool_ElementsOfRefMatrix::Value");
Standard_Real u = X(X.Lower());
TColStd_Array1OfReal Basis(0,myBase->WorkDegree()), Aux(0,myBase->WorkDegree());
switch (myDerOrder) {
case 0 :
myBase->D0(u, Basis);
break;
case 1 :
myBase->D1(u, Aux, Basis);
break;
case 2 :
myBase->D2(u, Aux, Aux, Basis);
break;
case 3 :
myBase->D3(u, Aux, Aux, Aux, Basis);
break;
}
Standard_Integer i, j, ii = 0;
for(i = 0; i<=myBase->WorkDegree(); i++)
for(j = i; j<=myBase->WorkDegree(); j++) {
F(F.Lower()+ii) = Basis(i)*Basis(j); ii++;
}
return Standard_True;
}

View File

@@ -0,0 +1,50 @@
-- File: FEmTool_LinearFlexion.cdl
-- Created: Thu Sep 18 10:52:37 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
class LinearFlexion from FEmTool inherits ElementaryCriterion from FEmTool
---Purpose: Criterium of LinearFlexion To Hermit-Jacobi elements
uses
Vector from math,
Matrix from math,
Shape from GeomAbs,
HArray2OfReal from TColStd,
HArray2OfInteger from TColStd
raises
NotImplemented,
DomainError
is
Create(WorkDegree : Integer ;
ConstraintOrder : Shape from GeomAbs)
returns LinearFlexion from FEmTool;
DependenceTable(me)
returns HArray2OfInteger from TColStd
is redefined;
Value (me : mutable)
returns Real is redefined;
Hessian(me : mutable ;
Dimension1 : Integer;
Dimension2 : Integer;
H : out Matrix from math)
raises DomainError -- If DependenceTable(Dimension1,Dimension2) is False
is redefined;
Gradient(me : mutable;
Dimension : Integer;
G : out Vector from math)
is redefined;
fields
RefMatrix : Matrix from math;
myOrder : Integer;
end LinearFlexion;

View File

@@ -0,0 +1,192 @@
// File: FEmTool_LinearFlexion.cxx
// Created: Fri Nov 6 15:02:53 1998
// Author: Igor FEOKTISTOV
// <ifv@paradox.nnov.matra-dtv.fr>
#include <FEmTool_LinearFlexion.ixx>
#include <PLib.hxx>
#include <TColStd_HArray2OfInteger.hxx>
#include <TColStd_HArray2OfReal.hxx>
#include <PLib_JacobiPolynomial.hxx>
#include <PLib_HermitJacobi.hxx>
#include <FEmTool_ElementsOfRefMatrix.hxx>
#include <math_IntegerVector.hxx>
#include <math_Vector.hxx>
#include <math_GaussSetIntegration.hxx>
#include <math.hxx>
#include <Standard_ConstructionError.hxx>
//=======================================================================
//function : FEmTool_LinearFlexion
//purpose :
//=======================================================================
FEmTool_LinearFlexion::FEmTool_LinearFlexion(const Standard_Integer WorkDegree,
const GeomAbs_Shape ConstraintOrder)
: RefMatrix(0,WorkDegree,0,WorkDegree)
{
static Standard_Integer Order = -333, WDeg = 14;
static math_Vector MatrixElemts(0, ((WDeg+2)*(WDeg+1))/2 -1 );
myOrder = PLib::NivConstr(ConstraintOrder);
if (myOrder != Order) {
//Calculating RefMatrix
if (WorkDegree > WDeg) Standard_ConstructionError::Raise("Degree too high");
Order = myOrder;
Standard_Integer DerOrder = 2;
Handle(PLib_HermitJacobi) theBase = new PLib_HermitJacobi(WDeg, ConstraintOrder);
FEmTool_ElementsOfRefMatrix Elem = FEmTool_ElementsOfRefMatrix(theBase, DerOrder);
Standard_Integer maxDegree = WDeg+1;
math_IntegerVector Order(1,1,Min(4*(maxDegree/2+1),math::GaussPointsMax()));
math_Vector Lower(1,1,-1.), Upper(1,1,1.);
math_GaussSetIntegration anInt(Elem, Lower, Upper, Order);
MatrixElemts = anInt.Value();
}
Standard_Integer i, j, ii, jj;
for(ii = i = 0; i <= WorkDegree; i++) {
RefMatrix(i, i) = MatrixElemts(ii);
for(j = i+1, jj = ii+1; j <= WorkDegree; j++, jj++) {
RefMatrix(j, i) = RefMatrix(i, j) = MatrixElemts(jj);
}
ii += WDeg+1-i;
}
}
//=======================================================================
//function : DependenceTable
//purpose :
//=======================================================================
Handle(TColStd_HArray2OfInteger) FEmTool_LinearFlexion::DependenceTable() const
{
if(myCoeff.IsNull()) Standard_DomainError::Raise("FEmTool_LinearFlexion::DependenceTable");
Handle(TColStd_HArray2OfInteger) DepTab =
new TColStd_HArray2OfInteger(myCoeff->LowerCol(), myCoeff->UpperCol(),
myCoeff->LowerCol(), myCoeff->UpperCol(),0);
Standard_Integer i;
for(i = myCoeff->LowerCol(); i <= myCoeff->UpperCol(); i++) DepTab->SetValue(i,i,1);
return DepTab;
}
//=======================================================================
//function : Value
//purpose :
//=======================================================================
Standard_Real FEmTool_LinearFlexion::Value()
{
Standard_Integer deg = Min(myCoeff->ColLength() - 1, RefMatrix.UpperRow()),
i, j, j0 = myCoeff->LowerRow(), degH = Min(2*myOrder+1, deg),
NbDim = myCoeff->RowLength(), dim;
TColStd_Array2OfReal NewCoeff( 1, NbDim, 0, deg);
Standard_Real coeff = (myLast - myFirst)/2., cteh3 = 2./Pow(coeff,3),
mfact, Jline;
Standard_Integer k1;
Standard_Real J = 0.;
for(i = 0; i <= degH; i++) {
k1 = (i <= myOrder)? i : i - myOrder - 1;
mfact = Pow(coeff,k1);
for(dim = 1; dim <= NbDim; dim++)
NewCoeff(dim, i) = myCoeff->Value(j0 + i, dim) * mfact;
}
for(i = degH + 1; i <= deg; i++) {
for(dim = 1; dim <= NbDim; dim++)
NewCoeff(dim, i) = myCoeff->Value(j0 + i, dim);
}
for(dim = 1; dim <= NbDim; dim++) {
for(i = 0; i <= deg; i++) {
Jline = 0.5 * RefMatrix(i, i) * NewCoeff(dim, i);
for(j = 0; j < i; j++)
Jline += RefMatrix(i, j) * NewCoeff(dim, j);
J += Jline * NewCoeff(dim, i);
}
}
if(J < 0.) J = 0.;
return cteh3*J;
}
//=======================================================================
//function : Hessian
//purpose :
//=======================================================================
void FEmTool_LinearFlexion::Hessian(const Standard_Integer Dimension1,
const Standard_Integer Dimension2, math_Matrix& H)
{
Handle(TColStd_HArray2OfInteger) DepTab = DependenceTable();
if(Dimension1 < DepTab->LowerRow() || Dimension1 > DepTab->UpperRow() ||
Dimension2 < DepTab->LowerCol() || Dimension2 > DepTab->UpperCol())
Standard_OutOfRange::Raise("FEmTool_LinearJerk::Hessian");
if(DepTab->Value(Dimension1,Dimension2) == 0)
Standard_DomainError::Raise("FEmTool_LinearJerk::Hessian");
Standard_Integer deg = Min(RefMatrix.UpperRow(), H.RowNumber() - 1), degH = Min(2*myOrder+1, deg);
Standard_Real coeff = (myLast - myFirst)/2., cteh3 = 2./Pow(coeff,3), mfact;
Standard_Integer k1, k2, i, j;
H.Init(0.);
for(i = 0; i <= degH; i++) {
k1 = (i <= myOrder)? i : i - myOrder - 1;
mfact = Pow(coeff,k1)*cteh3;
// Hermite*Hermite part of matrix
for(j = i; j <= degH; j++) {
k2 = (j <= myOrder)? j : j - myOrder - 1;
H(i, j) = mfact*Pow(coeff, k2)*RefMatrix(i, j);
if (i != j) H(j, i) = H(i, j);
}
// Hermite*Jacobi part of matrix
for(j = degH + 1; j <= deg; j++) {
H(i, j) = H(j, i) = mfact*RefMatrix(i, j);
}
}
// Jacoby*Jacobi part of matrix
for(i = degH+1; i <= deg; i++) {
for(j = i; j <= deg; j++) {
H(i, j) = cteh3*RefMatrix(i, j);
if (i != j) H(j, i) = H(i, j);
}
}
}
//=======================================================================
//function : Gradient
//purpose :
//=======================================================================
void FEmTool_LinearFlexion::Gradient(const Standard_Integer Dimension,math_Vector& G)
{
if(Dimension < myCoeff->LowerCol() || Dimension > myCoeff->UpperCol())
Standard_OutOfRange::Raise("FEmTool_LinearFlexion::Gradient");
Standard_Integer deg = Min(G.Length() - 1, myCoeff->ColLength() - 1);
math_Vector X(0,deg);
math_Matrix H(0,deg,0,deg);
Standard_Integer i, i1 = myCoeff->LowerRow();
for(i = 0; i <= deg; i++) X(i) = myCoeff->Value(i1+i, Dimension);
Hessian(Dimension, Dimension, H);
G.Multiply(H, X);
}

View File

@@ -0,0 +1,59 @@
-- File: FEmTool_LinearJerk.cdl
-- Created: Thu Sep 18 10:58:03 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
class LinearJerk from FEmTool inherits ElementaryCriterion from FEmTool
---Purpose: Criterion of LinearFlexion To Hermit-Jacobi elements
uses
Vector from math,
Matrix from math,
Shape from GeomAbs,
HArray2OfReal from TColStd,
HArray2OfInteger from TColStd
raises
NotImplemented,
DomainError
is
Create(WorkDegree : Integer ;
ConstraintOrder : Shape from GeomAbs)
returns LinearJerk from FEmTool;
DependenceTable(me)
returns HArray2OfInteger from TColStd
is redefined;
Value (me : mutable)
returns Real is redefined;
Hessian(me : mutable ;
Dimension1 : Integer;
Dimension2 : Integer;
H : out Matrix from math)
raises DomainError -- If DependenceTable(Dimension1,Dimension2) is False
is redefined;
Gradient(me : mutable;
Dimension : Integer;
G : out Vector from math)
is redefined;
fields
RefMatrix : Matrix from math;
myOrder : Integer;
end LinearJerk;

View File

@@ -0,0 +1,194 @@
// File: FEmTool_LinearJerk.cxx
// Created: Fri Nov 6 15:06:41 1998
// Author: Igor FEOKTISTOV
// <ifv@paradox.nnov.matra-dtv.fr>
#include <FEmTool_LinearJerk.ixx>
#include <PLib.hxx>
#include <TColStd_HArray2OfInteger.hxx>
#include <TColStd_HArray2OfReal.hxx>
#include <PLib_JacobiPolynomial.hxx>
#include <PLib_HermitJacobi.hxx>
#include <FEmTool_ElementsOfRefMatrix.hxx>
#include <math_IntegerVector.hxx>
#include <math_Vector.hxx>
#include <math_GaussSetIntegration.hxx>
#include <math.hxx>
#include <Standard_ConstructionError.hxx>
FEmTool_LinearJerk::FEmTool_LinearJerk(const Standard_Integer WorkDegree,
const GeomAbs_Shape ConstraintOrder):
RefMatrix(0,WorkDegree,0,WorkDegree)
{
static Standard_Integer Order = -333, WDeg = 14;
static math_Vector MatrixElemts(0, ((WDeg+2)*(WDeg+1))/2 -1 );
myOrder = PLib::NivConstr(ConstraintOrder);
//Calculating RefMatrix
if (myOrder != Order) {
if (WorkDegree > WDeg) Standard_ConstructionError::Raise("Degree too high");
Order = myOrder;
Standard_Integer DerOrder = 3;
Handle(PLib_HermitJacobi) theBase = new PLib_HermitJacobi(WDeg, ConstraintOrder);
FEmTool_ElementsOfRefMatrix Elem = FEmTool_ElementsOfRefMatrix(theBase, DerOrder);
Standard_Integer maxDegree = WDeg+1;
math_IntegerVector Order(1,1,Min(4*(maxDegree/2+1),math::GaussPointsMax()));
math_Vector Lower(1,1,-1.), Upper(1,1,1.);
math_GaussSetIntegration anInt(Elem, Lower, Upper, Order);
MatrixElemts = anInt.Value();
}
Standard_Integer i, j, ii, jj;
for(ii=i = 0; i <= WorkDegree; i++) {
RefMatrix(i, i) = MatrixElemts(ii);
for(j = i+1, jj = ii+1; j <= WorkDegree; j++, jj++) {
RefMatrix(j, i) = RefMatrix(i, j) = MatrixElemts(jj);
}
ii += WDeg+1-i;
}
}
Handle(TColStd_HArray2OfInteger) FEmTool_LinearJerk::DependenceTable() const
{
if(myCoeff.IsNull()) Standard_DomainError::Raise("FEmTool_LinearJerk::DependenceTable");
Handle(TColStd_HArray2OfInteger) DepTab =
new TColStd_HArray2OfInteger(myCoeff->LowerCol(), myCoeff->UpperCol(),
myCoeff->LowerCol(), myCoeff->UpperCol(),0);
Standard_Integer i;
for(i = myCoeff->LowerCol(); i <= myCoeff->UpperCol(); i++) DepTab->SetValue(i,i,1);
return DepTab;
}
Standard_Real FEmTool_LinearJerk::Value()
{
Standard_Integer deg = Min(myCoeff->ColLength() - 1, RefMatrix.UpperRow()),
i, j, j0 = myCoeff->LowerRow(), degH = Min(2*myOrder+1, deg),
NbDim = myCoeff->RowLength(), dim;
TColStd_Array2OfReal NewCoeff( 1, NbDim, 0, deg);
Standard_Real coeff = (myLast - myFirst)/2., cteh3 = 2./Pow(coeff,5),
mfact, Jline;
Standard_Integer k1;
Standard_Real J = 0.;
for(i = 0; i <= degH; i++) {
k1 = (i <= myOrder)? i : i - myOrder - 1;
mfact = Pow(coeff,k1);
for(dim = 1; dim <= NbDim; dim++)
NewCoeff(dim, i) = myCoeff->Value(j0 + i, dim) * mfact;
}
for(i = degH + 1; i <= deg; i++) {
for(dim = 1; dim <= NbDim; dim++)
NewCoeff(dim, i) = myCoeff->Value(j0 + i, dim);
}
for(dim = 1; dim <= NbDim; dim++) {
for(i = 0; i <= deg; i++) {
Jline = 0.5 * RefMatrix(i, i) * NewCoeff(dim, i);
for(j = 0; j < i; j++)
Jline += RefMatrix(i, j) * NewCoeff(dim, j);
J += Jline * NewCoeff(dim, i);
if(J < 0.) J = 0.;
}
}
return cteh3*J;
}
void FEmTool_LinearJerk::Hessian(const Standard_Integer Dimension1,
const Standard_Integer Dimension2, math_Matrix& H)
{
Handle(TColStd_HArray2OfInteger) DepTab = DependenceTable();
if(Dimension1 < DepTab->LowerRow() || Dimension1 > DepTab->UpperRow() ||
Dimension2 < DepTab->LowerCol() || Dimension2 > DepTab->UpperCol())
Standard_OutOfRange::Raise("FEmTool_LinearJerk::Hessian");
if(DepTab->Value(Dimension1,Dimension2) == 0)
Standard_DomainError::Raise("FEmTool_LinearJerk::Hessian");
Standard_Integer deg = Min(RefMatrix.UpperRow(), H.RowNumber() - 1), degH = Min(2*myOrder+1, deg);
Standard_Real coeff = (myLast - myFirst)/2., cteh3 = 2./Pow(coeff,5), mfact;
Standard_Integer k1, k2, i, j, i0 = H.LowerRow(), j0 = H.LowerCol(), i1, j1;
H.Init(0.);
i1 = i0;
for(i = 0; i <= degH; i++) {
k1 = (i <= myOrder)? i : i - myOrder - 1;
mfact = Pow(coeff,k1)*cteh3;
// Hermite*Hermite part of matrix
j1 = j0 + i;
for(j = i; j <= degH; j++) {
k2 = (j <= myOrder)? j : j - myOrder - 1;
H(i1, j1) = mfact*Pow(coeff, k2)*RefMatrix(i, j);
if (i != j) H(j1, i1) = H(i1, j1);
j1++;
}
// Hermite*Jacobi part of matrix
j1 = j0 + degH + 1;
for(j = degH + 1; j <= deg; j++) {
H(i1, j1) = mfact*RefMatrix(i, j);
H(j1, i1) = H(i1, j1);
j1++;
}
i1++;
}
// Jacoby*Jacobi part of matrix
i1 = i0 + degH + 1;
for(i = degH+1; i <= deg; i++) {
j1 = j0 + i;
for(j = i; j <= deg; j++) {
H(i1, j1) = cteh3*RefMatrix(i, j);
if (i != j) H(j1, i1) = H(i1, j1);
j1++;
}
i1++;
}
}
void FEmTool_LinearJerk::Gradient(const Standard_Integer Dimension,math_Vector& G)
{
if(Dimension < myCoeff->LowerCol() || Dimension > myCoeff->UpperCol())
Standard_OutOfRange::Raise("FEmTool_LinearJerk::Gradient");
Standard_Integer deg = Min(G.Length() - 1, myCoeff->ColLength() - 1);
math_Vector X(0,deg);
Standard_Integer i, i1 = myCoeff->LowerRow();
for(i = 0; i <= deg; i++) X(i) = myCoeff->Value(i1+i, Dimension);
math_Matrix H(0,deg,0,deg);
Hessian(Dimension, Dimension, H);
G.Multiply(H, X);
}

View File

@@ -0,0 +1,50 @@
-- File: FEmTool_LinearTension.cdl
-- Created: Thu Sep 18 09:34:40 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
class LinearTension from FEmTool inherits ElementaryCriterion from FEmTool
---Purpose: Criterium of LinearTension To Hermit-Jacobi elements
uses
Vector from math,
Matrix from math,
Shape from GeomAbs,
HArray2OfReal from TColStd,
HArray2OfInteger from TColStd
raises
NotImplemented,
DomainError
is
Create(WorkDegree : Integer ;
ConstraintOrder : Shape from GeomAbs)
returns LinearTension from FEmTool;
DependenceTable(me)
returns HArray2OfInteger from TColStd
is redefined;
Value (me : mutable)
returns Real is redefined;
Hessian(me : mutable ;
Dimension1 : Integer;
Dimension2 : Integer;
H : out Matrix from math)
raises DomainError -- If DependenceTable(Dimension1,Dimension2) is False
is redefined;
Gradient(me : mutable;
Dimension : Integer;
G : out Vector from math)
is redefined;
fields
RefMatrix : Matrix from math;
myOrder : Integer;
end LinearTension;

View File

@@ -0,0 +1,191 @@
// File: FEmTool_LinearTension.cxx
// Created: Fri Nov 6 10:22:02 1998
// Author: Igor FEOKTISTOV
// <ifv@paradox.nnov.matra-dtv.fr>
#include <FEmTool_LinearTension.ixx>
#include <PLib.hxx>
#include <TColStd_HArray2OfInteger.hxx>
#include <TColStd_HArray2OfReal.hxx>
#include <PLib_JacobiPolynomial.hxx>
#include <PLib_HermitJacobi.hxx>
#include <FEmTool_ElementsOfRefMatrix.hxx>
#include <math_IntegerVector.hxx>
#include <math_Vector.hxx>
#include <math_GaussSetIntegration.hxx>
#include <math.hxx>
#include <Standard_ConstructionError.hxx>
FEmTool_LinearTension::FEmTool_LinearTension(const Standard_Integer WorkDegree,
const GeomAbs_Shape ConstraintOrder):
RefMatrix(0,WorkDegree,0,WorkDegree)
{
static Standard_Integer Order = -333, WDeg = 14;
static math_Vector MatrixElemts(0, ((WDeg+2)*(WDeg+1))/2 -1 );
myOrder = PLib::NivConstr(ConstraintOrder);
if (myOrder != Order) {
//Calculating RefMatrix
if (WorkDegree > WDeg) Standard_ConstructionError::Raise("Degree too high");
Order = myOrder;
Standard_Integer DerOrder = 1;
Handle(PLib_HermitJacobi) theBase = new PLib_HermitJacobi(WDeg, ConstraintOrder);
FEmTool_ElementsOfRefMatrix Elem = FEmTool_ElementsOfRefMatrix(theBase, DerOrder);
Standard_Integer maxDegree = WDeg+1;
math_IntegerVector Order(1,1,Min(4*(maxDegree/2+1),math::GaussPointsMax()));
math_Vector Lower(1,1,-1.), Upper(1,1,1.);
math_GaussSetIntegration anInt(Elem, Lower, Upper, Order);
MatrixElemts = anInt.Value();
}
Standard_Integer i, j, ii, jj;
for(ii = i = 0; i <= WorkDegree; i++) {
RefMatrix(i, i) = MatrixElemts(ii);
for(j = i+1, jj = ii+1; j <= WorkDegree; j++, jj++) {
RefMatrix(j, i) = RefMatrix(i, j) = MatrixElemts(jj);
}
ii += WDeg+1-i;
}
}
Handle(TColStd_HArray2OfInteger) FEmTool_LinearTension::DependenceTable() const
{
if(myCoeff.IsNull()) Standard_DomainError::Raise("FEmTool_LinearTension::DependenceTable");
Handle(TColStd_HArray2OfInteger) DepTab =
new TColStd_HArray2OfInteger(myCoeff->LowerCol(), myCoeff->UpperCol(),
myCoeff->LowerCol(), myCoeff->UpperCol(),0);
Standard_Integer i;
for(i=1; i<=myCoeff->RowLength(); i++) DepTab->SetValue(i,i,1);
return DepTab;
}
Standard_Real FEmTool_LinearTension::Value()
{
Standard_Integer deg = Min(myCoeff->ColLength() - 1, RefMatrix.UpperRow()),
i, j, j0 = myCoeff->LowerRow(), degH = Min(2*myOrder+1, deg),
NbDim = myCoeff->RowLength(), dim;
TColStd_Array2OfReal NewCoeff( 1, NbDim, 0, deg);
Standard_Real coeff = (myLast - myFirst)/2., cteh3 = 2./coeff,
mfact, Jline;
Standard_Integer k1;
Standard_Real J = 0.;
for(i = 0; i <= degH; i++) {
k1 = (i <= myOrder)? i : i - myOrder - 1;
mfact = Pow(coeff,k1);
for(dim = 1; dim <= NbDim; dim++)
NewCoeff(dim, i) = myCoeff->Value(j0 + i, dim) * mfact;
}
for(i = degH + 1; i <= deg; i++) {
for(dim = 1; dim <= NbDim; dim++)
NewCoeff(dim, i) = myCoeff->Value(j0 + i, dim);
}
for(dim = 1; dim <= NbDim; dim++) {
for(i = 0; i <= deg; i++) {
Jline = 0.5 * RefMatrix(i, i) * NewCoeff(dim, i);
for(j = 0; j < i; j++)
Jline += RefMatrix(i, j) * NewCoeff(dim, j);
J += Jline * NewCoeff(dim, i);
}
}
return cteh3*J;
}
void FEmTool_LinearTension::Hessian(const Standard_Integer Dimension1,
const Standard_Integer Dimension2, math_Matrix& H)
{
Handle(TColStd_HArray2OfInteger) DepTab = DependenceTable();
if(Dimension1 < DepTab->LowerRow() || Dimension1 > DepTab->UpperRow() ||
Dimension2 < DepTab->LowerCol() || Dimension2 > DepTab->UpperCol())
Standard_OutOfRange::Raise("FEmTool_LinearTension::Hessian");
if(DepTab->Value(Dimension1,Dimension2) == 0)
Standard_DomainError::Raise("FEmTool_LinearTension::Hessian");
Standard_Integer deg = Min(RefMatrix.UpperRow(), H.RowNumber() - 1), degH = Min(2*myOrder+1, deg);
Standard_Real coeff = (myLast - myFirst)/2., cteh3 = 2./coeff, mfact;
Standard_Integer k1, k2, i, j, i0 = H.LowerRow(), j0 = H.LowerCol(), i1, j1;
H.Init(0.);
i1 = i0;
for(i = 0; i <= degH; i++) {
k1 = (i <= myOrder)? i : i - myOrder - 1;
mfact = Pow(coeff,k1)*cteh3;
// Hermite*Hermite part of matrix
j1 = j0 + i;
for(j = i; j <= degH; j++) {
k2 = (j <= myOrder)? j : j - myOrder - 1;
H(i1, j1) = mfact*Pow(coeff, k2)*RefMatrix(i, j);
if (i != j) H(j1, i1) = H(i1, j1);
j1++;
}
// Hermite*Jacobi part of matrix
j1 = j0 + degH + 1;
for(j = degH + 1; j <= deg; j++) {
H(i1, j1) = mfact*RefMatrix(i, j);
H(j1, i1) = H(i1, j1);
j1++;
}
i1++;
}
// Jacoby*Jacobi part of matrix
i1 = i0 + degH + 1;
for(i = degH+1; i <= deg; i++) {
j1 = j0 + i;
for(j = i; j <= deg; j++) {
H(i1, j1) = cteh3*RefMatrix(i, j);
if (i != j) H(j1, i1) = H(i1, j1);
j1++;
}
i1++;
}
}
void FEmTool_LinearTension::Gradient(const Standard_Integer Dimension, math_Vector& G)
{
if(Dimension < myCoeff->LowerCol() || Dimension > myCoeff->UpperCol())
Standard_OutOfRange::Raise("FEmTool_LinearTension::Gradient");
Standard_Integer deg = Min(G.Length() - 1, myCoeff->ColLength() - 1);
math_Vector X(0,deg);
Standard_Integer i, i1 = myCoeff->LowerRow();
for(i = 0; i <= deg; i++) X(i) = myCoeff->Value(i1+i, Dimension);
math_Matrix H(0,deg,0,deg);
Hessian(Dimension, Dimension, H);
G.Multiply(H, X);
}

View File

@@ -0,0 +1,85 @@
-- File: FEmTool_ProfileMatrix.cdl
-- Created: Wed Oct 29 16:54:05 1997
-- Author: Roman BORISOV
-- <rbv@velox.nnov.matra-dtv.fr>
---Copyright: Matra Datavision 1997
class ProfileMatrix from FEmTool inherits SparseMatrix from FEmTool
---Purpose: Symmetric Sparse ProfileMatrix useful for 1D Finite
-- Element methods
uses
HArray1OfInteger from TColStd,
Array1OfInteger from TColStd,
Array2OfInteger from TColStd,
HArray1OfReal from TColStd,
Vector from math
raises
NotDone from StdFail,
NotImplemented from Standard,
OutOfRange from Standard
is
Create(FirstIndexes : Array1OfInteger)
returns mutable ProfileMatrix from FEmTool;
Init(me: mutable; Value : Real);
ChangeValue(me: mutable; I, J : Integer)
---C++: return &
returns Real
raises OutOfRange;
Decompose(me : mutable)
---Purpose: To make a Factorization of <me>
returns Boolean;
Solve(me; B : Vector; X : in out Vector)
---Purpose: Direct Solve of AX = B
raises NotDone from StdFail; -- if <me> is not decomposed
Prepare(me : mutable)
---Purpose: Make Preparation to iterative solve
returns Boolean
raises NotImplemented from Standard;
Solve(me; B : Vector;
Init : Vector;
X : out Vector;
Residual : out Vector;
Tolerance : Real = 1.0e-8;
NbIterations: Integer = 50)
---Purpose: Iterative solve of AX = B
raises NotDone from StdFail; -- if <me> is not prepared;
Multiplied(me; X: Vector; MX : in out Vector);
---Purpose: returns the product of a SparseMatrix by a vector.
-- An exception is raised if the dimensions are different
RowNumber(me)
---Purpose: returns the row range of a matrix.
returns Integer;
ColNumber(me)
---Purpose: returns the column range of the matrix.
returns Integer;
IsInProfile(me; i, j : Integer)
returns Boolean;
-- for debug
OutM(me);
OutS(me);
fields
profile : Array2OfInteger; -- Like MPOSIT in Fortran
ProfileMatrix : HArray1OfReal; -- Like AMATRI in Fortran
SMatrix : HArray1OfReal; -- Like SMATRI in Fortran
NextCoeff : HArray1OfInteger; -- Like POSUIV in Fortran
IsDecomp : Boolean;
end ProfileMatrix;

View File

@@ -0,0 +1,269 @@
// File: FEmTool_ProfileMatrix.cxx
// Created: Fri Oct 31 10:02:27 1997
// Author: Roman BORISOV
// <rbv@velox.nnov.matra-dtv.fr>
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
#include <FEmTool_ProfileMatrix.ixx>
#include <gp.hxx>
//=======================================================================
//function : :FEmTool_ProfileMatrix
//purpose :
//=======================================================================
FEmTool_ProfileMatrix::FEmTool_ProfileMatrix(const TColStd_Array1OfInteger& FirstIndexes)
: profile(1, 2, 1, FirstIndexes.Length())
{
Standard_Integer i, j, k, l;
profile(1, 1) = 0;
profile(2, 1) = 1;
for(i = 2; i <= FirstIndexes.Length(); i++) {
profile(1, i) = i - FirstIndexes(i);
profile(2, i) = profile(2, i-1) + profile(1, i) + 1;
}
NextCoeff = new TColStd_HArray1OfInteger(1, profile(2, FirstIndexes.Length()));
for(i = 1, k = 1; i <= FirstIndexes.Length(); i++)
for(j = FirstIndexes(i); j <= i; j++) {
for(l = i+1; l <= FirstIndexes.Length() && j < FirstIndexes(l); l++);
if(l > FirstIndexes.Length()) NextCoeff->SetValue(k, 0);
else NextCoeff->SetValue(k, l);
k++;
}
ProfileMatrix = new TColStd_HArray1OfReal(1, profile(2, FirstIndexes.Length()));
SMatrix = new TColStd_HArray1OfReal(1, profile(2, FirstIndexes.Length()));
IsDecomp = Standard_False;
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void FEmTool_ProfileMatrix::Init(const Standard_Real Value)
{
ProfileMatrix->Init(Value);
IsDecomp = Standard_False;
}
//=======================================================================
//function : ChangeValue
//purpose :
//=======================================================================
Standard_Real& FEmTool_ProfileMatrix::ChangeValue(const Standard_Integer I,
const Standard_Integer J)
{
Standard_Integer Ind;
Ind = I-J;
if (Ind < 0) {
Ind = -Ind;
Standard_OutOfRange_Raise_if(Ind>profile(1, J),
"FEmTool_ProfileMatrix::ChangeValue");
Ind = profile(2, J) - Ind;
}
else {
Standard_OutOfRange_Raise_if(Ind>profile(1, I),
"FEmTool_ProfileMatrix::ChangeValue");
Ind = profile(2, I)-Ind;
}
return ProfileMatrix->ChangeValue(Ind);
}
//=======================================================================
//function : Decompose
//purpose : Choleski's decomposition
//=======================================================================
Standard_Boolean FEmTool_ProfileMatrix::Decompose()
{
Standard_Integer i, j, k, ik, jk, DiagAddr, CurrAddr, Kmin, Kj;
Standard_Real Sum, a, Eps = 1.e-32;
SMatrix->Init(0.);
Standard_Real * SMA = &SMatrix->ChangeValue(1);
SMA--;
const Standard_Real * PM = &ProfileMatrix->Value(1);
PM--;
for(j = 1; j <= RowNumber(); j++) {
DiagAddr = profile(2, j);
Kj = j - profile(1, j);
Sum = 0;
for(k = DiagAddr - profile(1, j); k < DiagAddr; k++)
Sum += SMA[k] * SMA[k];
a = PM[DiagAddr] - Sum;
if(a < Eps) {
return IsDecomp = Standard_False;// Matrix is not positive defined
}
a = Sqrt(a);
SMA[DiagAddr] = a;
CurrAddr = DiagAddr;
while ((i = NextCoeff->Value(CurrAddr)) > 0) {
CurrAddr = profile(2, i) - (i - j);
// Computation of Sum of S .S for k = 1,..,j-1
// ik jk
Sum = 0;
Kmin = Max((i - profile(1, i)), Kj);
ik = profile(2, i) - i + Kmin;
jk = DiagAddr - j + Kmin;
for(k = Kmin; k <j; k++,ik++,jk++) {
Sum += SMA[ik]*SMA[jk];
}
SMA[CurrAddr] = (PM[CurrAddr] - Sum)/a;
}
}
return IsDecomp = Standard_True;
}
//=======================================================================
//function : Solve
//purpose : Resolution of the system S*t(S)X = B
//=======================================================================
void FEmTool_ProfileMatrix::Solve(const math_Vector& B,math_Vector& X) const
{
if (!IsDecomp) StdFail_NotDone::Raise("Decomposition must be done");
Standard_Integer i, j, jj,DiagAddr, CurrAddr;
Standard_Real Sum;
Standard_Real * x = &X(X.Lower());
x--;
Standard_Real * b = &B(B.Lower());
b--;
const Standard_Real * SMA = &SMatrix->Value(1);
SMA --;
const Standard_Integer * NC = &NextCoeff->Value(1);
NC--;
// Resolution of Sw = B;
for(i = 1; i <= RowNumber(); i++) {
DiagAddr = profile(2, i);
Sum = 0;
for(j = i - profile(1, i), jj = DiagAddr - (i - j);
j < i; j++, jj++)
Sum += SMA[jj]* x[j];
x[i] = (b[i] - Sum)/SMA[DiagAddr];
}
// Resolution of t(S)X = w;
for(i = ColNumber(); i >= 1; i--) {
DiagAddr = profile(2, i);
j = NC[DiagAddr];
Sum = 0;
while(j > 0) {
CurrAddr = profile(2, j) - (j-i);
Sum += SMA[CurrAddr]*x[j];
j = NC[CurrAddr];
}
x[i] = (x[i] - Sum)/SMA[DiagAddr];
}
}
Standard_Boolean FEmTool_ProfileMatrix::Prepare()
{
Standard_NotImplemented::Raise("FEmTool_ProfileMatrix::Prepare");
return Standard_False;
}
// void FEmTool_ProfileMatrix::Solve(const math_Vector& B,const math_Vector& Init,math_Vector& X,math_Vector& Residual,const Standard_Real Tolerance,const Standard_Integer NbIterations) const
void FEmTool_ProfileMatrix::Solve(const math_Vector& ,const math_Vector& ,math_Vector& ,math_Vector& ,const Standard_Real ,const Standard_Integer ) const
{
Standard_NotImplemented::Raise("FEmTool_ProfileMatrix::Solve");
}
//=======================================================================
//function : Multiplied
//purpose : MX = H*X
//=======================================================================
void FEmTool_ProfileMatrix::Multiplied(const math_Vector& X,math_Vector& MX) const
{
Standard_Integer i, j, jj, DiagAddr, CurrAddr;
Standard_Real * m = &MX(MX.Lower());
m--;
Standard_Real * x = &X(X.Lower());
x--;
const Standard_Real * PM = &ProfileMatrix->Value(1);
PM--;
const Standard_Integer * NC = &NextCoeff->Value(1);
NC--;
for(i = 1; i <= RowNumber(); i++) {
DiagAddr = profile(2, i);
m[i] = 0;
for(j = i - profile(1, i), jj = DiagAddr - (i - j);
j <= i; j++, jj++)
m[i] += PM[jj]*x[j];
CurrAddr = DiagAddr;
for(j = NC[CurrAddr]; j > 0; j = NC[CurrAddr]) {
CurrAddr = profile(2, j) - (j-i);
m[i] += PM[CurrAddr]*x[j];
}
}
}
Standard_Integer FEmTool_ProfileMatrix::RowNumber() const
{
return profile.RowLength();
}
Standard_Integer FEmTool_ProfileMatrix::ColNumber() const
{
return profile.RowLength();
}
Standard_Boolean FEmTool_ProfileMatrix::IsInProfile(const Standard_Integer i,
const Standard_Integer j) const
{
if (j <= i) {
if ((i - j) <= profile(1, i)) return Standard_True;
else return Standard_False;
}
else if ((j - i) <= profile(1, j)) return Standard_True;
return Standard_False;
}
void FEmTool_ProfileMatrix::OutM() const
{
Standard_Integer i, j;
cout<<"Matrix A"<<endl;
for(i = 1; i <= RowNumber(); i++) {
for(j = 1; j < i - profile(1, i); j++)
cout<<"0 ";
for(j = profile(2, i) - profile(1, i); j <= profile(2, i); j++)
cout<<ProfileMatrix->Value(j)<<" ";
cout<<endl;
}
cout<<"NextCoeff"<<endl;
for(i = 1; i <= profile(2, RowNumber()); i++)
cout<<NextCoeff->Value(i)<<" ";
cout<<endl;
}
void FEmTool_ProfileMatrix::OutS() const
{
Standard_Integer i, j;
cout<<"Matrix S"<<endl;
for(i = 1; i <= RowNumber(); i++) {
for(j = 1; j < i - profile(1, i); j++)
cout<<"0 ";
for(j = profile(2, i) - profile(1, i); j <= profile(2, i); j++)
cout<<SMatrix->Value(j)<<" ";
cout<<endl;
}
}

View File

@@ -0,0 +1,67 @@
-- File: FEmTool_SparseMatrix.cdl
-- Created: Wed Oct 29 16:53:14 1997
-- Author: Roman BORISOV
-- <rbv@velox.nnov.matra-dtv.fr>
---Copyright: Matra Datavision 1997
deferred class SparseMatrix from FEmTool inherits TShared from MMgt
---Purpose: Sparse Matrix definition
uses
Vector from math
raises
NotDone from StdFail
is
Init(me: mutable; Value : Real)
is deferred;
ChangeValue(me: mutable; I, J : Integer)
---C++: return &
returns Real is deferred;
Decompose(me : mutable)
---Purpose: To make a Factorization of <me>
returns Boolean
is deferred;
Solve(me; B : Vector; X : in out Vector)
---Purpose: Direct Solve of AX = B
raises NotDone from StdFail -- if <me> is not decomposed
is deferred;
Prepare(me : mutable)
---Purpose: Make Preparation to iterative solve
returns Boolean
is deferred;
Solve(me; B : Vector;
Init : Vector;
X : out Vector;
Residual : out Vector;
Tolerance : Real = 1.0e-8;
NbIterations: Integer = 50)
---Purpose: Iterative solve of AX = B
raises NotDone from StdFail -- if <me> is not prepared;
is deferred;
Multiplied(me; X: Vector; MX : in out Vector)
---Purpose: returns the product of a SparseMatrix by a vector.
-- An exception is raised if the dimensions are different
is deferred;
RowNumber(me)
---Purpose: returns the row range of a matrix.
returns Integer
is deferred;
ColNumber(me)
---Purpose: returns the column range of the matrix.
returns Integer
is deferred;
end SparseMatrix;

View File

@@ -0,0 +1,7 @@
// File: FEmTool_SparseMatrix.cxx
// Created: Fri Oct 31 10:00:59 1997
// Author: Roman BORISOV
// <rbv@velox.nnov.matra-dtv.fr>
#include <FEmTool_SparseMatrix.ixx>