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:
63
src/FEmTool/FEmTool.cdl
Executable file
63
src/FEmTool/FEmTool.cdl
Executable 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;
|
85
src/FEmTool/FEmTool_Assembly.cdl
Executable file
85
src/FEmTool/FEmTool_Assembly.cdl
Executable 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
582
src/FEmTool/FEmTool_Assembly.cxx
Executable 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
97
src/FEmTool/FEmTool_Curve.cdl
Executable 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
464
src/FEmTool/FEmTool_Curve.cxx
Executable 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;
|
||||
}
|
||||
}
|
||||
}
|
66
src/FEmTool/FEmTool_ElementaryCriterion.cdl
Executable file
66
src/FEmTool/FEmTool_ElementaryCriterion.cdl
Executable 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;
|
||||
|
||||
|
||||
|
19
src/FEmTool/FEmTool_ElementaryCriterion.cxx
Executable file
19
src/FEmTool/FEmTool_ElementaryCriterion.cxx
Executable 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;
|
||||
}
|
||||
|
||||
|
63
src/FEmTool/FEmTool_ElementsOfRefMatrix.cdl
Executable file
63
src/FEmTool/FEmTool_ElementsOfRefMatrix.cdl
Executable 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;
|
64
src/FEmTool/FEmTool_ElementsOfRefMatrix.cxx
Executable file
64
src/FEmTool/FEmTool_ElementsOfRefMatrix.cxx
Executable 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;
|
||||
}
|
||||
|
50
src/FEmTool/FEmTool_LinearFlexion.cdl
Executable file
50
src/FEmTool/FEmTool_LinearFlexion.cdl
Executable 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;
|
192
src/FEmTool/FEmTool_LinearFlexion.cxx
Executable file
192
src/FEmTool/FEmTool_LinearFlexion.cxx
Executable 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);
|
||||
}
|
||||
|
59
src/FEmTool/FEmTool_LinearJerk.cdl
Executable file
59
src/FEmTool/FEmTool_LinearJerk.cdl
Executable 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;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
194
src/FEmTool/FEmTool_LinearJerk.cxx
Executable file
194
src/FEmTool/FEmTool_LinearJerk.cxx
Executable 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);
|
||||
|
||||
}
|
||||
|
50
src/FEmTool/FEmTool_LinearTension.cdl
Executable file
50
src/FEmTool/FEmTool_LinearTension.cdl
Executable 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;
|
191
src/FEmTool/FEmTool_LinearTension.cxx
Executable file
191
src/FEmTool/FEmTool_LinearTension.cxx
Executable 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);
|
||||
|
||||
|
||||
}
|
85
src/FEmTool/FEmTool_ProfileMatrix.cdl
Executable file
85
src/FEmTool/FEmTool_ProfileMatrix.cdl
Executable 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;
|
269
src/FEmTool/FEmTool_ProfileMatrix.cxx
Executable file
269
src/FEmTool/FEmTool_ProfileMatrix.cxx
Executable 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;
|
||||
}
|
||||
}
|
67
src/FEmTool/FEmTool_SparseMatrix.cdl
Executable file
67
src/FEmTool/FEmTool_SparseMatrix.cdl
Executable 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;
|
7
src/FEmTool/FEmTool_SparseMatrix.cxx
Executable file
7
src/FEmTool/FEmTool_SparseMatrix.cxx
Executable 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>
|
Reference in New Issue
Block a user