refinement#

This submodule’s purpose is to provide support functions for mesh refinement, namely the ones involved in post-solver refinement. Currently heavily work in progress.

Utilities#

For computing Legendre decomposition of functions for error estimation, the function _compute_legendre_coefficients() is provided.

mfv2d.refinement._compute_legendre_coefficients(order_1: int, order_2: int, rule_1: IntegrationRule1D, rule_2: IntegrationRule1D, func_vals: npt.NDArray[np.float64]) npt.NDArray[np.float64][source]#

Compute Legendre coefficients from function values at integration nodes.

Parameters:
  • order_1 (int) – Order of the coefficients in the first direction.

  • order_2 (int) – Order of the coefficients in the second direction.

  • rule_1 (IntegrationRule1D) – Integration rule to use in the first direction.

  • rule_2 (IntegrationRule1D) – Integration rule to use in the second direction.

  • func_vals (array) – Array of function values at the positions of integration rules.

Returns:

Array of coefficients for Legendre basis.

Return type:

(order_1 + 1, order_2 + 1) array

Refinement Settings#

Refinement settings are specified using the type RefinementSettings. There are a few additional types introduced to help type hint and define all parameters (for example ErrorCalculationFunction).

class mfv2d.refinement.RefinementSettings(required_forms: Sequence[KFormUnknown], error_calculation_function: ErrorCalculationFunction, refinement_limit: RefinementLimitUnknownCount | RefinementLimitElementCount | RefinementLimitErrorValue, h_refinement_ratio: float = 0.0, report_error_distribution: bool = False, report_order_distribution: bool = False, reconstruction_orders: tuple[int, int] | None = None)[source]#

Settings pertaining to refinement of a mesh.

error_calculation_function: ErrorCalculationFunction#

Function called to calculate error estimate and h-refinement cost.

h_refinement_ratio: float = 0.0#

Ratio between element error and h-refinement cost where refinement can happen.

reconstruction_orders: tuple[int, int] | None = None#

Order at which error should be reconstructed.

refinement_limit: RefinementLimitUnknownCount | RefinementLimitElementCount | RefinementLimitErrorValue#

Limit for mesh refinement.

report_error_distribution: bool = False#

Should the error distribution be reported.

report_order_distribution: bool = False#

Should the order distribution be reported.

required_forms: Sequence[KFormUnknown]#

Forms that are needed by the error calculation function.

class mfv2d.refinement.ErrorCalculationFunction(*args, **kwargs)[source]#

Type that can compute error.

__call__(x: npt.NDArray[np.float64], y: npt.NDArray[np.float64], w: npt.NDArray[np.float64], **kwargs: npt.NDArray[np.float64]) tuple[float, float][source]#

Compute the error.

Parameters:
  • x (array) – x-coordinates of integration points.

  • y (array) – y-coordinates of integration points.

  • w (array) – Integration weights at the specified points.

  • **kwargs (array) – Values of desired forms at specified positions.

Returns:

  • float – Error measure of the element. Not negative.

  • float – Cost of h-refinement.

Refinement Limits#

To specify when the refineemnt should stop, several different dataclasses are available. RefinementLimitUnknownCount limits it based on number of new degrees of freedom that are introduced, RefinementLimitElementCount is based on the number of elements refined, added, and RefinementLimitErrorValue is based on the error value of elements.

class mfv2d.refinement.RefinementLimitUnknownCount(maximum_fraction: float, maximum_count: int)[source]#

Limit refinement based on change in number of degrees of freedom.

maximum_count: int#
maximum_fraction: float#
class mfv2d.refinement.RefinementLimitElementCount(maximum_fraction: float, maximum_count: int)[source]#

Limit refinement based on the number of elements.

maximum_count: int#
maximum_fraction: float#
class mfv2d.refinement.RefinementLimitErrorValue(minimum_fraction: float, minimum_value: float)[source]#

Limit refinement based on value of the errror.

minimum_fraction: float#
minimum_value: float#

Doing the Refinement#

After the solver obtains a solution for the problem, refinement is performed by invoking the function perform_mesh_refinement(). This takes values computed by the solver, as well as all that is specified through RefinementSettings.

mfv2d.refinement.perform_mesh_refinement(mesh: Mesh, solution: npt.NDArray[np.float64], element_offsets: npt.NDArray[np.uint32], dof_offsets: npt.NDArray[np.uint32], required_unknown_indices: Sequence[int], unknown_forms: Sequence[KFormUnknown], error_calculation_function: ErrorCalculationFunction, h_refinement_ratio: float, refinement_limit: RefinementLimit, unknown_ordering: UnknownOrderings, report_error_distribution: bool, reconstruction_orders: tuple[int | None, int | None]) Mesh[source]#

Perform a round of mesh refinement.

Parameters:
  • mesh (Mesh) – Mesh on which to perform refinement on.

  • settings (RefinementSettings) – Specifications of how the refinement shoud be performed.

  • solution (array) – Solution for degrees of freedom.

  • element_offsets (array) – Array with offsets for the beginning of