:py:mod:`FELiCS.Fields.Field` ============================= .. py:module:: FELiCS.Fields.Field Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: FELiCS.Fields.Field.Field Attributes ~~~~~~~~~~ .. autoapisummary:: FELiCS.Fields.Field.logger .. py:data:: logger .. py:class:: Field(FEMSpace, mesh, name=None, isStateVector=False, m=None) Class representing a finite element field. This class provides methods for handling finite element fields, including coefficient manipulation, boundary condition application, and expression evaluation. It supports complex-valued fields and can optionally represent a state vector in a mixed formulation. The class also supports an optional spectral dimension via a wave number. The class interacts with ``dolfinx.fem.Function`` for finite element operations and includes utilities for working with PETSc vectors and UFL expressions. **Initialize the Field object** :param FEMSpace: The finite element function space. :type FEMSpace: :py:class:`dolfinx.fem.FunctionSpace` :param mesh: FELiCS mesh associated with the function space. :type mesh: :py:class:`FELiCS.SpaceDisc.FELiCSMesh` :param name: Name of the field. If not provided, a default name is chosen based on the field type (scalar, vector, or mixed). :type name: :py:class:`str`, *optional* :param isStateVector: If True, the field is interpreted as a state vector in a mixed space, and subfield names may be taken from ``space.stateVectorNames`` where available. Default is False. :type isStateVector: :py:class:`bool`, *optional* :param m: Wave number associated with a spectral spatial dimension. If this is set (even to zero), the field is assumed to have one spectral spatial dimension, and ``hasSpectralDimension`` is set to True. :type m: :py:class:`int`, *optional* .. py:property:: name .. py:method:: getNamesOfSubFields() Return the list of subfield names for vector or mixed spaces. For scalar fields, an empty list is returned and a warning is logged. For vector fields, names are generated from the base field name and the mesh axis names (e.g. ``u_x``, ``u_y``). For mixed fields, names are taken from previously set values, from ``stateVectorNames`` (when ``isStateVector`` is True), or reasonable defaults such as ``scalar1``, ``vector1``, etc. :returns: List of subfield names. Empty for pure scalar fields. :rtype: :py:class:`list` of :py:class:`str` .. py:method:: setNamesOfSubFields(nameList) Assign explicit names to the subfields of a mixed or vector field. :param nameList: List of subfield names. The length must match the number of subspaces in the underlying function space; otherwise, a warning is logged and the names are not changed. :type nameList: :py:class:`list` of :py:class:`str` .. py:method:: getTensor() Wrap the field as a tensor-aware object. :returns: Tensor wrapper around the underlying finite element function, constructed with the mesh coordinate system and the field's spectral settings (``m`` and ``hasSpectralDimension``). :rtype: :py:class:`FELiCS.Misc.tensorUtils.Tensor` .. admonition:: Notes - Mixed functions are not yet fully supported and are treated as a single tensor object. .. py:method:: isReal() Check whether the field is (numerically) real-valued. :returns: True if the imaginary part of the coefficient array has zero norm, False otherwise. :rtype: :py:class:`bool` .. py:method:: getListOfSubFields() Get a list of single-component fields. :returns: A list containing individual scalar fields if the function space has multiple subspaces. Otherwise, returns a list containing only this field. :rtype: :py:class:`list` .. admonition:: Notes - If the space has multiple subspaces, each subspace is extracted as an individual field. .. py:method:: setListOfSubFields(listOfFields, name=[]) Set the field coefficients from a list of single-component fields. :param listOfFields: A list of `Field` objects representing individual subspaces. :type listOfFields: :py:class:`list` :param name: The name of the new field that contains all the given fields as subfields. :type name: :py:class:`string`, *optional* .. admonition:: Notes - This only works if the "listOfFields" contains fields with the correct spaces, which are subspaces of the space which which this field has been initialized. - If the space has multiple subspaces, their coefficients are mapped back. - Throws an error if the input list does not match the expected size. .. py:method:: describeFunctionSpace() Describe the structure of the function space and its subspaces. :returns: A dictionary containing: - 'type': str - 'scalar', 'vector', or 'mixed' - 'num_subspaces': int - Number of subspaces - 'subspaces': list - List of subspace descriptions for mixed spaces - 'value_size': int - Total number of components - 'description': str - Human-readable description :rtype: :py:class:`dict` .. admonition:: Examples For a scalar field: {'type': 'scalar', 'num_subspaces': 0, 'value_size': 1, 'description': 'Single scalar space'} For a vector field: {'type': 'vector', 'num_subspaces': 3, 'value_size': 3, 'description': 'Single vector space with 3 components'} For a mixed field: {'type': 'mixed', 'num_subspaces': 2, 'subspaces': [...], 'value_size': 4, 'description': 'Mixed space with 2 subspaces'} .. py:method:: getSize() Get the length of the coefficient array from the underlying function. :returns: length of coefficient array :rtype: :py:class:`integer` .. py:method:: getCoefficientArray() Get the coefficient array of the field. :returns: A complex-valued array representing the field coefficients. :rtype: :py:class:`numpy.ndarray` .. py:method:: getRealCoefficientArray() Get the real part of the coefficient array of the field. :returns: A float-valued array representing the field coefficients. :rtype: :py:class:`numpy.ndarray` .. py:method:: getImagCoefficientArray() Get the imaginary part of the coefficient array of the field. :returns: A float-valued array representing the field coefficients. :rtype: :py:class:`numpy.ndarray` .. py:method:: setCoefficientArray(array) Set the coefficient array of the field. :param array: A complex-valued array of coefficients. :type array: :py:class:`numpy.ndarray` .. py:method:: setConstantValue(value) Set all coefficients to a constant value. :param value: The constant value to assign to all coefficients. :type value: :py:class:`complex` or :py:class:`float` .. py:method:: getPetscVector() Convert the field to a PETSc vector. :returns: A PETSc vector created from the coefficient array. :rtype: :py:class:`petsc4py.PETSc.Vec` .. py:method:: conjugate() Compute the complex conjugate of the field. .. py:method:: setBoundaryConditions(bcs) Apply boundary conditions to the field. :param bcs: A list of Dirichlet boundary conditions to be applied. :type bcs: :py:class:`list` .. py:method:: getGradientField() Compute the gradient of a scalar field as a new Field. The gradient is obtained in a vector-valued function space with dimension equal to the geometric dimension of the mesh (plus an additional spectral dimension if present). The result is computed via a tensor-based weak form and projection. :returns: A new Field instance representing the gradient of the original field. :rtype: :py:class:`Field` .. py:method:: calculateL2Norm() Compute the L2 norm of the field (and its subfields, if mixed). For mixed or vector-valued fields, the norm is computed by summing the contributions of each scalar subfield in the mixed decomposition. :returns: The L2 norm of the field. :rtype: :py:class:`float` .. py:method:: getVorticityField() Compute the vorticity field associated with a velocity field. For a 2D velocity field, this returns a scalar vorticity field (ω_z = ∂v/∂x − ∂u/∂y). For a 3D velocity field, a vector-valued vorticity field is constructed component-wise using the curl of the velocity. :returns: Vorticity field as a scalar (2D) or vector (3D) Field. Returns None if the number of components is less than 2. :rtype: :py:class:`Field` or :py:obj:`None` .. admonition:: Notes - 3D behaviour is marked as experimental in the implementation and may not be fully tested. - No explicit error is raised if the field is not a velocity-type vector; it is the caller's responsibility to ensure consistency. .. py:method:: exportToH5(writer, fileName=None) Export the field to an HDF5 file using a FELiCS writer. :param writer: Writer object providing an ``exportFieldToH5(field, fileName)`` method. :type writer: :py:class:`object` :param fileName: Base name for the exported dataset or file. If None, the field's ``name`` attribute is used. :type fileName: :py:class:`str`, *optional* .. py:method:: importData(reader, importFilePath, groupName=None) Import data into the field using a FELiCS reader. This is a convenience wrapper around the reader's :meth:`importInField` method. :param reader: Reader object providing an ``importInField(field, filePath, groupName)`` method. :type reader: :py:class:`object` :param importFilePath: Path to the file containing the data to be imported. :type importFilePath: :py:class:`str` :param groupName: Optional group name inside the file from which to read. :type groupName: :py:class:`str` or :py:obj:`None`, *optional* :returns: * :py:class:`Field` -- The updated field (self). * :py:class:`list` of :py:class:`str` -- List of variable names that were not found in the file. .. py:method:: evaluateUflExpression(ufl_expression, bcs=[], restartSolver=False) Evaluate a UFL expression and update the field accordingly. :param ufl_expression: The UFL expression to evaluate. :type ufl_expression: :py:class:`ufl.Form` :param bcs: A list of boundary conditions to apply. :type bcs: :py:class:`list`, *optional* :param restartSolver: Whether to restart the solver instead of reusing an existing one. :type restartSolver: :py:class:`bool`, *optional* .. py:method:: evaluateUflTensorExpression(ufl_expression, bcs=[], restartSolver=False) Evaluate a tensor-based UFL expression and update the field accordingly. :param ufl_expression: The UFL expression to be evaluated. :type ufl_expression: :py:class:`ufl.Form` :param bcs: A list of boundary conditions to be applied. :type bcs: :py:class:`list`, *optional* :param restartSolver: Whether to restart the solver instead of reusing an existing one. :type restartSolver: :py:class:`bool`, *optional* .. admonition:: Notes - This method assembles and solves a tensor-based weak form. - Uses a predefined solver if available to improve performance. - The weak form includes integration over the computational domain. .. py:method:: smoothUflTensorExpression(ufl_expression, smoothFactor, bcs=[], restartSolver=False) Smooth a tensor-based UFL expression using a diffusion-like approach. :param ufl_expression: The UFL expression to be smoothed. :type ufl_expression: :py:class:`ufl.Form` :param smoothFactor: A smoothing factor controlling the influence of the gradient term. :type smoothFactor: :py:class:`float` :param bcs: A list of boundary conditions to apply. :type bcs: :py:class:`list`, *optional* :param restartSolver: Whether to restart the solver instead of reusing an existing one. :type restartSolver: :py:class:`bool`, *optional* .. admonition:: Notes - This method applies a smoothing operation by adding a gradient-based regularization term to the weak form. - It is particularly useful for regularizing noisy numerical solutions. .. py:method:: smooth(smoothFactor, bcs=[], restartSolver=False) Smooth the field using a diffusion-like approach. This method constructs a smoothing operator that combines an identity term with a gradient-based regularization term, and then applies it to the current field by solving the corresponding weak form. :param smoothFactor: Smoothing factor controlling the influence of the gradient term. :type smoothFactor: :py:class:`float` :param bcs: List of boundary conditions to apply. :type bcs: :py:class:`list`, *optional* :param restartSolver: If True, rebuild the smoothing solver even if one already exists. :type restartSolver: :py:class:`bool`, *optional* .. admonition:: Notes - Particularly useful for regularizing noisy numerical solutions. - The same solver is reused between calls unless ``restartSolver`` is True. .. py:method:: plot(xlim=None, ylim=None, imaginaryPart=False) Plotting function for debugging purposes. This function can be used, to check if a field looks as expected and rule out e.g. import problems. .. admonition:: Notes - This method provides a simple visualization of the field.