Technical Details of Boundary Curve Optimization¶
Herein provides details on the assumptions, mathematics, and algorithms behind the error based, adaptive high order mesh generation option in HOHQMesh.
Introduction: The Accurate Approximation of Boundary Curves¶
The goal is to have an accurate approximation of a boundary curve when written out to the mesh file. Formally, the problem to solve is the following:
Boundary curve optimization
Find the best piecewise polynomial approximation of degree \(N\) of a curve \(\vec{\Gamma}(t)\), \(t\in[0,1]\) such that the error is less than a user-provided tolerance.
In the figure below, \(\vec{\Gamma}(t)\) (blue solid line) is the curve to be approximated and the polynomial approximations \(\vec{P}_i\) (black dashed line) that span intervals \(h_i = t_i - t_{i-1}\) along the curve (red solid lines).
HOHQMesh actually solves two problems:
-
Once a mesh with number of segments \(K\) along a curve and segment lengths \(h_{k}\) is generated, it can find and write to the mesh file the best piecewise polynomial approximation \(\vec{P}_{k}\) , and
-
Before generating a mesh, it can find the best number of segments, \(K\), intervals \(h_{k}\) and polynomials \(\vec{P}_{k}\) so the error is less than a user acceptable tolerance to use to choose the local element size.
To begin, we need to define "best". To include both the boundary error and boundary derivative errors, we define "best" as meaning the approximation with the smallest error in the \(\mathbb H^0\) or \(\mathbb H^{1}\) norm as chosen by the user, where, for \(K\) segments,
The \(\mathbb H^1\) norm includes the error in the position and the error in the derivative. Over an interval \([t_{i-1},t_i]\), that norm is
The \(\mathbb L^{2} = \mathbb H^{0}\) norm drops the derivative term.
There are also constraints on the approximation. The first three ensure a watertight mesh.
-
The first polynomial must match the curve at the left end point.
-
The last polynomial must match the curve at the right end point.
-
At the interior ends of the segments the polynomials must match.
-
Additionally it may be desirable that the derivatives of the polynomials match up to some order \(p\) at the interior ends of the segments.
Global \(\mathbb H^1\) Optimization of a Curve¶
We proceed now to show how to compute the best approximation in steps of increasing complexity. We derive the equations for the \(\mathbb H^{1}\) norm; the \(\mathbb L^{2}\) norm just drops the terms associated with the derivatives. We first derive the systems of equations to solve without constraints, then add endpoint constraints, and finally, add smoothness constraints to ensure that the approximations are continuous up to a user specified derivative.
Optimization without constraints¶
We start with a single polynomial to approximate the curve, without the endpoint constraints. Therefore, we want to find a polynomial
that best approximates a curve \(\vec{\Gamma}(t) = X(t)\hat x + Y(t)\hat y\) in the \(\mathbb H^1\) norm. Here, \(\phi_j\) can be any basis, but we will assume it is an orthogonal polynomial, e.g. Legendre parametrized in arc length along the curve. The choice of an orthogonal basis will keep the condition number of the system to be solved low. The parameter \(t\in[t_{k-1},t_{k}]\) and \(s(t)\in [-1,1]\) are related through the affine transformation
We start with the unconstrained minimization of the \(\mathbb H^1\) error, which is: find \(b_j\) that minimizes the functional
Let's convert the integral with \(\mathrm{d}t = \frac{1}{2}h\,\mathrm{d}s\), where \(h = t_{k} - t_{k-1}\). Then \(ds/dt = 2/h\). Written out,
The objective function is minimized where the gradient with respect to the coefficients \((\vec{b}^x,\vec{b}^y)\) is zero, with some abuse of notation. With respect to the first set,
Gathering knowns and unknowns,
This can be written in matrix-vector form as
where
and
The same formula holds true for the coefficients, \(\mathbf b^y\).
Remark 1
The integrals in the matrix \(\underline{\smash{M}}\) can be computed exactly with a Gauss quadrature of order \(N\). The first part is just orthogonality, so is \(2/(2j+1)\) along the diagonal for the Legendre basis. A recursion formula is used to compute the derivatives of the Legendre polynomials and from that the integrals.
\(\mathbb H^1\) Optimization with endpoint constraints¶
To ensure the corners of an element are fixed by the geometry, we add two constraints. Based on the previous analysis, we can do the \(x\) and \(y\) components separately. So let \(Z\) be one of \(X\) or \(Y\) and \(b\) refer to either \(b^x\) or \(b^y\). Then for either the \(x\) or \(y\) components,
This can also be written in matrix-vector form
where is the \(2\times (N+1)\) matrix
and
The constraints are imposed with a penalty term and a Lagrange multiplier by adding
to \(\mathcal Q\) . Then we define the new objective function with the linear constraints as
which we then minimize with respect to the \(b_i\) and \(\pmb{\lambda}\). For the first,
For the second,
In matrix-vector form, this becomes
The matrices \(\underline{M}\) and \(\underline{C}\) do not change between the \(x\) and \(y\) components. Only \(\mathbf r\) and \(\mathbf d\) do.
Multiple segment \(\mathbb H^1\) optimization¶
Now the curve \(\vec{\Gamma}\) is subdivided into \(K\) subintervals, \([t_{k-1},t_k]\), with length \(h^{(k)}=t_k - t_{k-1}\) where \(t\in[t_0,t_{max}]\) and the best polynomial is sought. With \(s\in[-1,1]\) we can write \(t = t_{k-1} + \frac{1}{2}(s+1)h^{(k)}\). To ensure a watertight mesh we set continuity conditions at the endpoints. We will step through several cases here. As above, we can consider the \(x\) and \(y\) components separately.
We can have three constraint conditions applied:
-
Specified value at endpoints,
\[ \sum_{j=0}^N b^{(1)}_j \phi_j(-1) = Z(t_0),\quad \sum_{j=0}^N b^{(K)}_j \phi_j(1) = Z(t_{max}) \] -
Continuity at interior interfaces,
\[ \sum_{j=0}^N b^{(k-1)}_j \phi_j(1) = \sum_{j=0}^N b^{(k)}_j \phi_j(-1), \]where \(k = 2, 3, \ldots, K\)
-
Smoothness at interfaces,
\[ \sum_{j=0}^N b^{(k-1)}_j \frac{d^m \phi_j(1)}{ds^m}\left(\frac{ds}{dt}\right)^{\! m} = \sum_{j=0}^N b^{(k)}_j \frac{d^m \phi_j(-1)}{ds^m}\left(\frac{ds}{dt}\right)^{\! m}, \]where \(m = 0, 1,\ldots, p < N\) and \(k = 2, 3, \ldots, K\)
-
Periodic conditions at endpoints,
\[ \sum_{j=0}^N b^{(K)}_j \frac{d^m \phi_j(1)}{ds^m}\left(\frac{ds}{dt}\right)^{\! m} = \sum_{j=0}^N b^{(1)}_j \frac{d^m \phi_j(-1)}{ds^m}\left(\frac{ds}{dt}\right)^{\! m}, \]where \(m = 0, 1,\ldots, p < N\).
As above, let us define the two following vectors
Then the fixed value constraints are
and continuity constraints are
Finally, periodic constraints are
For any of these, we can write the constraints as a matrix-vector system,
where the global state vector is
The matrix \(\underline{C}\) and \(\mathbf d\) will depend on the constraints chosen. Options are
-
Fixed endpoint values:
\[ \underline{C}^T = \left[\begin{array}{ccccc}\mathbf C_-^T & \mathbf 0 & \mathbf 0 & \ldots & \mathbf 0 \\-\mathbf C_+^T & \mathbf C_-^T & \mathbf 0 & & \\0 & -\mathbf C_+^T & \mathbf C_-^T & & \\\vdots & \ddots & \ddots & & \\\mathbf 0 & \mathbf 0 & \mathbf 0 & \ldots & \mathbf C_+^T\end{array}\right],\quad \mathbf d = \left[\begin{array}{c}Z(t_0) \\\mathbf 0 \\\mathbf 0 \\\vdots \\Z(t_{max})\end{array}\right]. \] -
Periodic constraints:
\[ \underline{C}^T = \left[\begin{array}{ccccc} \mathbf C_-^T & \mathbf 0 & \mathbf 0 & \ldots &-\mathbf C_+^T \\ -\mathbf C_+^T & \mathbf C_-^T & \mathbf 0 & & \\ 0 & -\mathbf C_+^T & \mathbf C_-^T & & \\ \vdots & \ddots & \ddots & & \\ -\mathbf C_-^T & \mathbf 0 & \mathbf 0 & \ldots & \mathbf C_+^T\end{array}\right] ,\quad \mathbf d = \mathbf 0. \]Note that the matrix \(\underline{C}^T\) is singular, since the first and last rows are the same to within a factor of \(-1\). Since this shows up as giving the same two Lagrange multipliers, we just delete the last row
\[ \underline{C}^T = \left[\begin{array}{ccccc} \mathbf C_-^T & \mathbf 0 & \mathbf 0 & \ldots &-\mathbf C_+^T \\ -\mathbf C_+^T & \mathbf C_-^T & \mathbf 0 & & \\ 0 & -\mathbf C_+^T & \mathbf C_-^T & & \\ \vdots & \ddots & \ddots & & \\ \mathbf 0 & \mathbf 0 & \ldots& -\mathbf C_+^T& \mathbf C_-^T\end{array}\right] ,\quad \mathbf d = \mathbf 0. \]
Fixed element segments and polynomial order¶
Given a subdivision of the parametrization, we find the best piecewise polynomial approximation by splitting the objective function into pieces. The unconstrained objective function is
Taking the gradient with respect to \(b^{(n)}_i\), gives a local system of equations in component form,
where, now,
The constraints are in canonical form, so we write with the Lagrange multiplier
again, in canonical form, which leads to the system
to determine the polynomial coefficients when fixed endpoints are specified.
For periodic constraints the lower part of the right hand side vector is zero for all components and there is one fewer Lagrange multiplier.
Each of the \(\underline{M}\) matrices is of size \((N+1)\times (N+1)\). The matrix \(\underline{C}\) is of size \(K(N+1)\times (K+1)\), while \(\underline{C}^T\) is \((K+1)\times K(N+1)\). Therefore, the full system matrix is of size \(K(N+1) + (K+1)\times K(N+1) + (K+1)\). The upper left block is of size \(K(N+1)\times K(N+1)\).
Remark 2
An approximation like this has a name when applied to data and the \(\mathbb L^{2}\) norm is used: Least squares spline.
Higher order constraints¶
In some applications, especially transition to turbulence problems, the boundary must be very smooth, up to even the fourth derivative. In that case, we want to specify additional smoothness constraints, e.g.
with \(m = 0, 1,\ldots, p < N\), \(k = 2, 3, \ldots, K\), and where, presumably, \(p<N\). This will increase the size of the constraint matrix, with entries that depend on the derivatives of the basis functions.
As above, let us define the two following vectors
Then the continuity constraints are
with \(k = 2,3,\ldots,K\), \(m = 0,1,\ldots\), and \(p < N\). Note, we have explicitly noted the fact that the transformation Jacobian changes from segment to segment. Therefore, we need to construct an array of derivative quantities \(\left\{\phi_j^{(m)}\right\}_{j=0,m=0}^{N,p}\) evaluated at \(\pm 1\).
Then the constraint matrix for fixed endpoints is
Since we are using the Legendre basis,
from the well-known formulas. Hence for any other derivative,
For starting conditions, we know that
Then we compute the derivatives recursively using the following algorithm.
Implementation¶
This section is implemented in the module
ConstrainedMultiH1Optimization contained in the
file
Source/BoundaryOptimization/ConstrainedMultiH1Optimization.f90.
-
The linear systems from Eq. (1) are solved with an LU factorization, implemented in
LUFactorizationandForwardBackwardSolvedefined in that file. -
Setup is done in the procedure
SUBROUTINE ConstructCMH1O, whereas the actual optimization is performed inSUBROUTINE Optimize.
Practical Notes¶
Some observations to pay attention to:
-
For a good approximation, the number of smoothness constraints needs to be smaller than the polynomial order. One cannot have fourth order smoothness with a piecewise second order polynomial. The user should ensure there are enough modal coefficients to account for continuity and accuracy.
-
The systems in Eq. (1) appear to be ill-conditioned for high \(p\), limiting how much smoothness one can get. It appears that only first or second order continuity is possible this way. Some sort of preconditioning or other amelioration should be studied.
Optimal intervals for fixed polynomial order¶
As part of the adaptive mesh generation procedure, HOHQMesh finds the optimal subdivision for a given polynomial order before meshing to get the best element distribution. In this case, the number of subdivisions is computed as part of the optimization process so that the error on each segment, as measured the objective function, satisfies \(\sqrt{\mathcal Q^k} = \sqrt{\mathcal Q_x^k+ \mathcal Q_y^k} \le \tau\), where \(\tau\) is a user specified tolerance.
To find the optimal segmentation of a boundary, HOHQMesh implements a marching scheme where the global error is bounded by a tolerance, and each step along the way is chosen so it contributes a prorated amount along the curve. Note that the true best approximation couples the segments, and marching independently does not.
We can set the tolerance in several ways. For example, each section could contribute an amount of error which we bound in terms of the local error tolerance \(\tau\) as
where \(h_k = t_k - t_{k-1}\) is the length of the interval. Then the problem becomes: For each \(k\) find \(h_{k}\) such that
The desired approximation is global, but the marching scheme is local. HOHQMesh modifies the problem by constraining the approximation to match the curve values at the end points. To account for this later, it includes a safety factor \(\gamma \le 1\) so that it can go back and compute the best approximation given the computed distribution of segments that the full global error with continuity conditions satisfies the tolerance.
The marching algorithm has a disadvantage that it does not look ahead. Therefore, it can end with a "leftover" small segment. To ameliorate this, an estimate of an acceptable segment size is computed and the smaller of that and halfway to the previous segment start location is used. The next to the last segment will decrease in size (but still remain within the tolerance), but the last segment will not have as small a size to create significant time stepping issues due to the resulting mesh.
Implementation¶
-
The procedure
SUBROUTINE OptimizeCurveis found in the fileSource/BoundaryOptimization/CurveOptimization.f90. -
The nonlinear solve for (3) is performed in the
FUNCTION iterate, -
found in the same file, which combines bisection (
FUNCTION bisect) and the Pegasus method, (Dowell, M., Jarratt, P. (1972) The "Pegasus" method for computing the root of an equation, DOI: 10.1007/BF01932959) -
The marching function (2) is implemented in
FUNCTION marchingFunction.
The Adaptive Mesh Procedure¶
The mesh adaptation is performed in the procedure SUBROUTINE GenerateQuadMesh in the file
Source/Mesh/MeshGeneratorMethods.f90
The sequence of events is shown in the following algorithm.
The number of tries to generate a mesh with the user's tolerance is numberOfTries = 3.
Warning
There is no guaranteed convergence of the algorithm to generate a mesh to within the expected error.
However, HOHQMesh does supply the means to print the errors along the boundaries, which could be used to insert a refinement region to further refine the mesh in difficult situations.