|
Neko 1.99.9
A portable framework for high-order spectral element flow simulations
|
Coefficients defined on a given (mesh, \( X_h \)) tuple. Arrays use indices (i,j,k,e): element e, local coordinate (i,j,k). More...

Public Member Functions | |
| procedure, pass(this) | free (this) |
| Deallocate coefficients. | |
| procedure, pass(this) | get_normal (this, i, j, k, e, facet) |
| Facet normal at a point. | |
| procedure, pass(this) | get_area (this, i, j, k, e, facet) |
| Facet area at a point. | |
| procedure, pass(this) | require_facets (this, who) |
| Abort unless this coef holds the facet areas and normals. | |
| procedure, pass(this) | generate_cyclic_bc (this) |
| procedure, pass(this) | recompute_metrics (this) |
| Recompute and update geometric factors (ALE) | |
| procedure, pass(this) | metric_condition (this) |
| Compute the metric tensor condition numbers over the mesh. | |
| procedure, pass(this) | enable_b_history (this) |
| Enable separate memory for lagged B matrices if needed. For eg. when mesh moves. | |
| procedure, pass(this) | update_b_history (this) |
| Update history: Blaglag = Blag, Blag = B. | |
| generic | init (this, xh, msh) |
| Initialize empty coefs for a space and a mesh. | |
| generic | init (this, gs_h, scope) |
| Initialize coefficients. | |
Public Attributes | |
| real(kind=rp), dimension(:,:,:,:), allocatable | g11 |
| Geometric factors \( G_{11} \). | |
| real(kind=rp), dimension(:,:,:,:), allocatable | g22 |
| Geometric factors \( G_{22} \). | |
| real(kind=rp), dimension(:,:,:,:), allocatable | g33 |
| Geometric factors \( G_{33} \). | |
| real(kind=rp), dimension(:,:,:,:), allocatable | g12 |
| Geometric factors \( G_{12} \). | |
| real(kind=rp), dimension(:,:,:,:), allocatable | g13 |
| Geometric factors \( G_{13} \). | |
| real(kind=rp), dimension(:,:,:,:), allocatable | g23 |
| Geometric factors \( G_{23} \). | |
| real(kind=rp) | metric_cond = 0.0_rp |
| Largest condition number of the metric tensor over the mesh, global across ranks. Zero until coef_metric_condition() has been called. Governs single precision arithmetic, see NEKO_METRIC_COND_SP. | |
| real(kind=rp) | metric_scaled_cond = 0.0_rp |
| Largest condition number of the Jacobi scaled metric tensor \( C_{ij} = G_{ij}/\sqrt{G_{ii}G_{jj}} \) over the mesh, global across ranks. Zero until coef_metric_condition() has been called. Unlike metric_cond this is independent of the element aspect ratio, and it is the term that governs single precision storage; it enters metric_perturb weighted by the storage roundoff. | |
| integer | metric_degenerate = 0 |
| Quadrature points whose metric tensor is not positive definite, i.e. degenerate or inverted elements. Global across ranks. | |
| real(kind=rp) | metric_perturb = 0.0_rp |
| Predicted relative perturbation of the element Helmholtz operator, in its own energy norm, from holding \( G_{ij} \) in single precision and accumulating in rp, i.e. \( \epsilon_{sp}\kappa(C) + \epsilon_{rp}\kappa(G) \). Zero until coef_metric_condition() has been called. See NEKO_METRIC_PERTURB_MAX. | |
| logical | metric_sp_safe = .false. |
| Whether single precision geometric factors are safe on this mesh, i.e. metric_perturb <= NEKO_METRIC_PERTURB_MAX and no degenerate points. Because metric_perturb carries the accumulation term as well as the storage term, this is correct on an rp = sp build as well as on a double precision build holding \( G_{ij} \) in single. A reduced precision storage path should gate on this flag and report its own decision. coef_metric_condition() logs the flag every run beside the two condition numbers and the estimate that produce it, and warns separately – on definiteness grounds – when a single precision build trips NEKO_METRIC_COND_SP. | |
| real(kind=rp), dimension(:,:,:,:), allocatable | g11_compressed |
| Compressed geometric factors \( G_{11} \). | |
| real(kind=rp), dimension(:,:,:,:), allocatable | g22_compressed |
| Compressed geometric factors \( G_{22} \). | |
| real(kind=rp), dimension(:,:,:,:), allocatable | g33_compressed |
| Compressed geometric factors \( G_{33} \). | |
| real(kind=rp), dimension(:,:,:,:), allocatable | g12_compressed |
| Compressed geometric factors \( G_{12} \). | |
| real(kind=rp), dimension(:,:,:,:), allocatable | g13_compressed |
| Compressed geometric factors \( G_{13} \). | |
| real(kind=rp), dimension(:,:,:,:), allocatable | g23_compressed |
| Compressed geometric factors \( G_{23} \). | |
| integer, dimension(:), allocatable | compression_inds |
| Compressed geometric factors lookup indices. | |
| real(kind=rp), dimension(:,:,:,:), allocatable | mult |
| Multiplicity. | |
| real(kind=rp), dimension(:,:,:,:), allocatable | dxdr |
| generate mapping data between element and reference element \( dx/dr, dy/dr, dz/dr \) \( dx/ds, dy/ds, dz/ds \) \( dx/dt, dy/dt, dz/dt \) | |
| real(kind=rp), dimension(:,:,:,:), allocatable | dydr |
| real(kind=rp), dimension(:,:,:,:), allocatable | dzdr |
| real(kind=rp), dimension(:,:,:,:), allocatable | dxds |
| real(kind=rp), dimension(:,:,:,:), allocatable | dyds |
| real(kind=rp), dimension(:,:,:,:), allocatable | dzds |
| real(kind=rp), dimension(:,:,:,:), allocatable | dxdt |
| real(kind=rp), dimension(:,:,:,:), allocatable | dydt |
| real(kind=rp), dimension(:,:,:,:), allocatable | dzdt |
| real(kind=rp), dimension(:,:,:,:), allocatable | drdx |
| \( dr/dx, dr/dy, dr/dz \) \( ds/dx, ds/dy, ds/dz \) \( dt/dx, dt/dy, dt/dz \) | |
| real(kind=rp), dimension(:,:,:,:), allocatable | drdy |
| real(kind=rp), dimension(:,:,:,:), allocatable | drdz |
| real(kind=rp), dimension(:,:,:,:), allocatable | dsdx |
| real(kind=rp), dimension(:,:,:,:), allocatable | dsdy |
| real(kind=rp), dimension(:,:,:,:), allocatable | dsdz |
| real(kind=rp), dimension(:,:,:,:), allocatable | dtdx |
| real(kind=rp), dimension(:,:,:,:), allocatable | dtdy |
| real(kind=rp), dimension(:,:,:,:), allocatable | dtdz |
| real(kind=rp), dimension(:,:,:,:), allocatable | h1 |
| Stiffness scaling. | |
| real(kind=rp), dimension(:,:,:,:), allocatable | h2 |
| Mass scaling. | |
| logical | ifh2 |
| True if h2 .ne. 0. | |
| real(kind=rp), dimension(:,:,:,:), allocatable | jac |
| Jacobian. | |
| real(kind=rp), dimension(:,:,:,:), allocatable | jacinv |
| Inverted Jacobian. | |
| real(kind=rp), dimension(:,:,:,:), allocatable | b |
| Mass matrix/volume matrix. | |
| real(kind=rp), dimension(:,:,:,:), allocatable | binv |
| Inverted Mass matrix/volume matrix. | |
| real(kind=rp), dimension(:,:,:,:), pointer | blag => null() |
| Lagged Mass matrix/volume matrix. | |
| real(kind=rp), dimension(:,:,:,:), pointer | blaglag => null() |
| lag-lagged Mass matrix/volume matrix | |
| real(kind=rp), dimension(:,:,:,:), allocatable | area |
| Facet area. | |
| real(kind=rp), dimension(:,:,:,:), allocatable | nx |
| x-direction of facet normal | |
| real(kind=rp), dimension(:,:,:,:), allocatable | ny |
| y-direction of facet normal | |
| real(kind=rp), dimension(:,:,:,:), allocatable | nz |
| z-direction of facet normal | |
| logical | cyclic = .false. |
| integer, dimension(:), allocatable | cyc_msk |
| real(kind=rp), dimension(:), allocatable | r11 |
| entry of 2D rotation matrix at index (1,1) | |
| real(kind=rp), dimension(:), allocatable | r12 |
| entry of 2D rotation matrix at index (1,2) | |
| integer | scope = COEF_FULL |
| Which coefficients this instance retains, COEF_FULL or COEF_OPERATOR. Anything not retained is deallocated at the end of init. | |
| real(kind=rp) | volume = 0.0_rp |
| Pointers to main fields. | |
| type(space_t), pointer | xh => null() |
| type(mesh_t), pointer | msh => null() |
| type(dofmap_t), pointer | dof => null() |
| type(gs_t), pointer | gs_h => null() |
| type(c_ptr) | g11_d = C_NULL_PTR |
| type(c_ptr) | g22_d = C_NULL_PTR |
| type(c_ptr) | g33_d = C_NULL_PTR |
| type(c_ptr) | g12_d = C_NULL_PTR |
| type(c_ptr) | g13_d = C_NULL_PTR |
| type(c_ptr) | g23_d = C_NULL_PTR |
| type(c_ptr) | dxdr_d = C_NULL_PTR |
| type(c_ptr) | dydr_d = C_NULL_PTR |
| type(c_ptr) | dzdr_d = C_NULL_PTR |
| type(c_ptr) | dxds_d = C_NULL_PTR |
| type(c_ptr) | dyds_d = C_NULL_PTR |
| type(c_ptr) | dzds_d = C_NULL_PTR |
| type(c_ptr) | dxdt_d = C_NULL_PTR |
| type(c_ptr) | dydt_d = C_NULL_PTR |
| type(c_ptr) | dzdt_d = C_NULL_PTR |
| type(c_ptr) | drdx_d = C_NULL_PTR |
| type(c_ptr) | drdy_d = C_NULL_PTR |
| type(c_ptr) | drdz_d = C_NULL_PTR |
| type(c_ptr) | dsdx_d = C_NULL_PTR |
| type(c_ptr) | dsdy_d = C_NULL_PTR |
| type(c_ptr) | dsdz_d = C_NULL_PTR |
| type(c_ptr) | dtdx_d = C_NULL_PTR |
| type(c_ptr) | dtdy_d = C_NULL_PTR |
| type(c_ptr) | dtdz_d = C_NULL_PTR |
| type(c_ptr) | mult_d = C_NULL_PTR |
| type(c_ptr) | h1_d = C_NULL_PTR |
| type(c_ptr) | h2_d = C_NULL_PTR |
| type(c_ptr) | jac_d = C_NULL_PTR |
| type(c_ptr) | jacinv_d = C_NULL_PTR |
| type(c_ptr) | b_d = C_NULL_PTR |
| type(c_ptr) | blag_d = C_NULL_PTR |
| type(c_ptr) | blaglag_d = C_NULL_PTR |
| type(c_ptr) | binv_d = C_NULL_PTR |
| type(c_ptr) | area_d = C_NULL_PTR |
| type(c_ptr) | nx_d = C_NULL_PTR |
| type(c_ptr) | ny_d = C_NULL_PTR |
| type(c_ptr) | nz_d = C_NULL_PTR |
| type(c_ptr) | cyc_msk_d = C_NULL_PTR |
| type(c_ptr) | r11_d = C_NULL_PTR |
| type(c_ptr) | r12_d = C_NULL_PTR |
| integer | metrics_version = 0 |
| Version of the current geometry. Incremented by recompute_metrics. | |
Private Member Functions | |
| procedure, pass(this), private | init_empty (this, xh, msh) |
| Initialize empty coefs for a space and a mesh. | |
| procedure, pass(this), private | init_all (this, gs_h, scope) |
| Initialize coefficients. | |
Private Attributes | |
| logical, private | coef_metrics_initialized = .false. |
| procedure, pass(this) coefs::coef_t::get_area | ( | class(coef_t), intent(in) | this, |
| integer, intent(in) | i, | ||
| integer, intent(in) | j, | ||
| integer, intent(in) | k, | ||
| integer, intent(in) | e, | ||
| integer, intent(in) | facet | ||
| ) |
| procedure, pass(this) coefs::coef_t::get_normal | ( | class(coef_t), intent(in) | this, |
| integer, intent(in) | i, | ||
| integer, intent(in) | j, | ||
| integer, intent(in) | k, | ||
| integer, intent(in) | e, | ||
| integer, intent(in) | facet | ||
| ) |
The stored geometric factors are \( G = w_3 J M \), where \( M \) is the metric matrix at a quadrature point. Both \( w_3 \) and the Jacobian are scalar multipliers, so \( \kappa(G) = \kappa(M) \) and the condition number of the stored \( G_{ij} \) is a pure property of the element geometry.
Two numbers are computed, because reduced precision arithmetic and reduced precision storage are limited by different properties of the element.
metric_cond is \( \kappa(G) \) and it governs the arithmetic. Applying \( D^T G D \) in precision \( \epsilon \) accumulates a quadratic form whose smallest eigendirection contributes a term of relative size \( 1/\kappa(G) \), which is lost once \( \kappa(G) \gtrsim 1/\epsilon \): about \( 1.7\times 10^{7} \) in single precision against \( 9\times 10^{15} \) in double. Below that the error grows as \( \epsilon\kappa(G) \); past it the local operator can turn indefinite and a Krylov solve breaks down rather than degrading. \( \kappa(G) \) grows as the square of the element aspect ratio, so a wall resolved boundary layer can approach the single precision limit while remaining ten orders clear of the double precision one. The single precision warning below is keyed on it.
metric_scaled_cond is \( \kappa(C) \) for the Jacobi scaled metric \( C_{ij} = G_{ij}/\sqrt{G_{ii}G_{jj}} \), the matrix of cosines between the contravariant basis vectors, and it governs storage. Rounding \( G_{ij} \) to a lower precision is a componentwise relative perturbation, so writing \( G = \Delta C \Delta \) with \( \Delta = \mathrm{diag}(\sqrt{G_{ii}}) \) the diagonal scaling passes through the rounding unchanged and cancels in every quadratic form. What remains bounds the relative perturbation of the element operator in its own energy norm by \( \epsilon\kappa(C) \), independent of the aspect ratio, of \( \kappa(G) \), of h and of the polynomial order: element stretching is invisible to storage rounding and only skew matters. Definiteness survives while \( \lambda_{min}(C) > 3\epsilon \), which in two dimensions means element edges more than about \( 0.02^\circ \) from parallel, so for storage this is a degenerate element test rather than an aspect ratio limit.
The two combine additively rather than as a pair of thresholds, because they are multiplied by different unit roundoffs – that of the precision \( G_{ij} \) is held in, and that of the precision the contraction accumulates in. metric_perturb reports \( \epsilon_{sp}\kappa(C) + \epsilon_{rp}\kappa(G) \), the predicted relative perturbation of the element operator were the factors held in single precision, and metric_sp_safe thresholds that against NEKO_METRIC_PERTURB_MAX. Gating on \( \kappa(G) \) alone is conservative by the square of the aspect ratio on a double precision build; gating on \( \kappa(C) \) alone would call an rp = sp build safe on a wall resolved mesh, which it is not.
| procedure, pass(this) coefs::coef_t::require_facets | ( | class(coef_t), intent(in) | this, |
| character(len=*), intent(in) | who | ||
| ) |
For consumers of the facet metrics to call once at setup, so that being handed a COEF_OPERATOR coef fails at construction with a message naming the consumer, rather than dereferencing a released array mid solve. get_area() and get_normal() are pure and cannot report it themselves, and some consumers read nx, ny and nz directly and never go through them at all.
| who | Name of the consumer, used in the error message. |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::area |
| type(c_ptr) coefs::coef_t::area_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::b |
| type(c_ptr) coefs::coef_t::b_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::binv |
| type(c_ptr) coefs::coef_t::binv_d = C_NULL_PTR |
| type(c_ptr) coefs::coef_t::blag_d = C_NULL_PTR |
| type(c_ptr) coefs::coef_t::blaglag_d = C_NULL_PTR |
| integer, dimension(:), allocatable coefs::coef_t::compression_inds |
| integer, dimension(:), allocatable coefs::coef_t::cyc_msk |
| type(c_ptr) coefs::coef_t::cyc_msk_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::drdx |
| type(c_ptr) coefs::coef_t::drdx_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::drdy |
| type(c_ptr) coefs::coef_t::drdy_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::drdz |
| type(c_ptr) coefs::coef_t::drdz_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dsdx |
| type(c_ptr) coefs::coef_t::dsdx_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dsdy |
| type(c_ptr) coefs::coef_t::dsdy_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dsdz |
| type(c_ptr) coefs::coef_t::dsdz_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dtdx |
| type(c_ptr) coefs::coef_t::dtdx_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dtdy |
| type(c_ptr) coefs::coef_t::dtdy_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dtdz |
| type(c_ptr) coefs::coef_t::dtdz_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dxdr |
| type(c_ptr) coefs::coef_t::dxdr_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dxds |
| type(c_ptr) coefs::coef_t::dxds_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dxdt |
| type(c_ptr) coefs::coef_t::dxdt_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dydr |
| type(c_ptr) coefs::coef_t::dydr_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dyds |
| type(c_ptr) coefs::coef_t::dyds_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dydt |
| type(c_ptr) coefs::coef_t::dydt_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dzdr |
| type(c_ptr) coefs::coef_t::dzdr_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dzds |
| type(c_ptr) coefs::coef_t::dzds_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::dzdt |
| type(c_ptr) coefs::coef_t::dzdt_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::g11 |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::g11_compressed |
| type(c_ptr) coefs::coef_t::g11_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::g12 |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::g12_compressed |
| type(c_ptr) coefs::coef_t::g12_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::g13 |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::g13_compressed |
| type(c_ptr) coefs::coef_t::g13_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::g22 |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::g22_compressed |
| type(c_ptr) coefs::coef_t::g22_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::g23 |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::g23_compressed |
| type(c_ptr) coefs::coef_t::g23_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::g33 |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::g33_compressed |
| type(c_ptr) coefs::coef_t::g33_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::h1 |
| type(c_ptr) coefs::coef_t::h1_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::h2 |
| type(c_ptr) coefs::coef_t::h2_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::jac |
| type(c_ptr) coefs::coef_t::jac_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::jacinv |
| type(c_ptr) coefs::coef_t::jacinv_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::mult |
| type(c_ptr) coefs::coef_t::mult_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::nx |
| type(c_ptr) coefs::coef_t::nx_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::ny |
| type(c_ptr) coefs::coef_t::ny_d = C_NULL_PTR |
| real(kind=rp), dimension(:,:,:,:), allocatable coefs::coef_t::nz |
| type(c_ptr) coefs::coef_t::nz_d = C_NULL_PTR |
| real(kind=rp), dimension(:), allocatable coefs::coef_t::r11 |
| type(c_ptr) coefs::coef_t::r11_d = C_NULL_PTR |
| real(kind=rp), dimension(:), allocatable coefs::coef_t::r12 |
| type(c_ptr) coefs::coef_t::r12_d = C_NULL_PTR |