Go to the documentation of this file.
65 const scalar Vtri = tet.
mag();
66 const scalar stab =
sqrt(
sqr(Vtri) +
K);
67 const scalar Vstab = 0.5 * (Vtri + stab);
69 func += LSqrTri /
pow(Vstab, 2./3.);
79 scalar Vmin(VGREAT), LSqMax(0.0);
92 const scalar Vtri = tet.
mag();
106 if( Vmin < SMALL * LSqMax )
121 const scalar
K = evaluateStabilisationFactor();
124 gradGradLsq.
xx() = 6.0;
125 gradGradLsq.
yy() = 6.0;
126 gradGradLsq.
zz() = 6.0;
128 const point&
p = points_[pointI_];
130 const scalar
C = 2./3. *
pow(0.5, 2./3.);
131 const scalar C1 =
C / 3.;
135 const partTet& pt = tets_[tetI];
149 (tet.
b() - tet.
a()) ^
163 const scalar Vtri = tet.
mag();
166 const scalar stab =
sqrt(
sqr(Vtri) +
K);
169 const scalar Vs = 0.5 * (Vtri + stab);
181 "void nodeDisplacementVolumeOptimizer()"
186 const vector gradStab = Vtri * gradV / stab;
189 const vector gradLsq = 2. * (3. *
p - tet.
a() - tet.
b() - tet.
c());
192 const vector gradVs = 0.5 * (gradV + gradStab);
195 const scalar Vs13 =
pow(2. * Vs, 1./3.);
196 const scalar Vstab =
pow(Vs, 2./3.);
197 const scalar sqrVstab =
sqr(Vstab);
198 const vector gradVstab =
C * (2. * gradVs) / Vs13;
200 gradF += gradLsq / Vstab - LSqrTri * gradVstab / sqrVstab;
203 const tensor gradGradStab =
204 (gradV * gradV) / stab -
205 sqr(Vtri) * (gradV * gradV) /
pow(stab, 3);
209 const tensor gradGradVstab =
210 C * (gradGradStab / Vs13) -
211 C1 * 4. * (gradVs * gradVs) /
pow(Vs13, 4);
215 gradGradLsq / Vstab -
216 twoSymm(gradLsq * (gradVstab / sqrVstab)) -
217 LSqrTri * gradGradVstab / sqrVstab +
218 2.0 * LSqrTri * (gradVstab * gradVstab) / (sqrVstab * Vstab);
227 point currCentre = pOpt;
239 funcBefore = funcAfter;
244 for(
label i=0;i<8;++i)
246 pOpt.
x() = currCentre.
x() + 0.5 *
dirVecs[i].
x() * dx;
247 pOpt.
y() = currCentre.
y() + 0.5 *
dirVecs[i].
y() * dy;
248 pOpt.
z() = currCentre.
z() + 0.5 *
dirVecs[i].
z() * dz;
252 if(
func < funcAfter )
261 currCentre = minCentre;
270 const scalar t =
mag(funcAfter - funcBefore) / funcAfter;
273 Info <<
"Point position " << pOpt <<
endl;
274 Info <<
"Func before " << funcBefore <<
endl;
275 Info <<
"Func after " << funcAfter <<
endl;
276 Info <<
"Normalised difference " << t <<
endl;
281 }
while( ++iter < 100 );
294 <<
" with coordinates " <<
p <<
endl;
295 scalar Vmina(VGREAT);
298 Info <<
"Vmin before " << Vmina <<
endl;
313 funcBefore = funcAfter;
317 const scalar determinant =
Foam::det(gradGradF);
318 if( determinant > SMALL )
320 disp = (
inv(gradGradF, determinant) & gradF);
328 Info <<
"gradGradF " << gradGradF <<
endl;
329 Info <<
"det(gradGradF) " << determinant <<
endl;
331 Info <<
"Func before " << funcBefore <<
endl;
332 Info <<
"Func after " << funcAfter <<
endl;
338 while( funcAfter > funcBefore )
344 if( funcAfter < funcBefore )
353 funcAfter = funcBefore;
357 if(
mag(funcBefore - funcAfter) / funcBefore < tol )
380 const scalar d =
mag(
n);
383 disp += 0.01 * (
n / d);
390 }
while( (++iter < 100) && !finished );
397 Info <<
nl <<
"New coordinates for point "
399 Info <<
"Num iterations " << iter <<
" gradient " << gradF <<
endl;
void evaluateGradientsExact(vector &, tensor &) const
evaluate gradients of the functional
Templated 3D tensor derived from VectorSpace adding construction from 9 components,...
scalar optimiseSteepestDescent(const scalar tol)
optimise using the steepest descent
const point & max() const
Maximum describing the bounding box.
#define forAll(list, i)
Loop across all elements in list.
scalar evaluateStabilisationFactor() const
find appropriate value of K
Template functions to aid in the implementation of demand driven data.
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< scalar > mag(const dimensioned< Type > &)
CGAL::Exact_predicates_exact_constructions_kernel K
A triangle primitive used to calculate face normals and swept volumes.
scalar evaluateFunc() const
evaluate functional
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
vector normal() const
Return vector normal.
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
DynList< point, 128 > & points_
mesh points
void func(FieldField< Field, Type > &f, const FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
const point & min() const
Minimum describing the bounding box.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
const label pointI_
label of the point
const DynList< partTet, 128 > & tets_
list tets around the given vertex
static const vector dirVecs[8]
direction vectors for divide and conquer algorithm
errorManipArg< error, int > exit(error &err, const int errNo=1)
const Point & a() const
Return vertices.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
scalar mag(const PointField &) const
Return volume.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
static unsigned int defaultPrecision()
Return the default precision.
dimensionedScalar sqrt(const dimensionedScalar &ds)
scalar optimiseDivideAndConquer(const scalar tol)
optimize position using a divide and conquer algorithm
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
dimensionedScalar det(const dimensionedSphericalTensor &dt)
Graphite solid properties.
label a() const
Return vertices.
scalar mag() const
Return volume.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
dimensionedSymmTensor twoSymm(const dimensionedSymmTensor &dt)
dimensioned< scalar > magSqr(const dimensioned< Type > &)