eval#
This submodule is responsible for conversion of system from its abstract syntax
tree (AST) representation, which is the job of mfv2d.kform submodule,
into a form which can be understood and executed by C code in
mfv2d._mfv2d.
This process is done in the following steps:
First, the AST is converted into Python bytecode-like objects (subtypes of
MatOp).Resulting expression is simplified as much as possible by the
simplify_expression()function.Simplified expression is translated into C compatible values (sequence of
int,float, andMatOpCodevalues).
After this is done for each of the blocks of the in the system,
the two-dimensional square sequence can be passed to the
mfv2d._mfv2d.compute_element_matrix() or
mfv2d._mfv2d.compute_element_vector() functions.
Matrix Operations#
For the first step in instruction generation, subtypes of
the MatOp type are used. These are all documented
bellow.
- class mfv2d.eval.MatOp[source]#
Matrix operations which can be created.
This is just a base class for all other matrix operations.
- class mfv2d.eval.MassMat(order: UnknownFormOrder, inv: bool)[source]#
Mass matrix multiplication.
Multiply by either mass matrix or its inverse.
- Parameters:
order (UnknownFormOrder) – Order of the k-form for the mass matrix.
inv (bool) – Should the matrix be inverted.
- order: UnknownFormOrder#
- class mfv2d.eval.Incidence(begin: UnknownFormOrder, transpose: int)[source]#
Incidence matrix.
Specifies application of an incidence matrix.
- Parameters:
begin (UnknownFormOrder) – Order of the k-form for the incidence matrix from which to apply it.
transpose (bool) – Should the incidence matrix be transposed.
- begin: UnknownFormOrder#
- class mfv2d.eval.Push[source]#
Push the matrix on the stack.
Used for matrix multiplication and summation.
- class mfv2d.eval.Scale(k: float)[source]#
Scale the matrix.
Mutliply the entire matrix with a constant.
- Parameters:
k (float) – Value of the constant by which to scale the matrix.
- class mfv2d.eval.Sum(count: int)[source]#
Sum matrices together.
Sum the top
countmatrices on the stack with the current matrix.- Parameters:
count (int) – Number of matrices to sum to the current matrix. As such must be greater than zero.
- class mfv2d.eval.InterProd(starting_order: UnknownFormOrder, field: str | Function2D, transpose: bool)[source]#
Compute interior product.
This is the most complicated operation.
- Parameters:
starting_order (UnknownFormOrder) – Order of the k-form to which the interior product should be applied.
field (str or Function2D) – Index of the vector/scalar field from which the values of are taken.
transpose (bool) – Should the matrix be transposed.
- starting_order: UnknownFormOrder#
AST Translation#
The translation from the AST form into the Python bytecode
is performed by translate_implicit_ksum() function. This
calls _translate_inner_prod() function, which in turn relies on
_translate_form(). The bytecode these produce may be sub-optimal.
As such, the function will (when specified) call
simplify_expression() to simplify the bytecode before returning.
This mainly has do deal with eliminating matrices followed by their inverse.
- mfv2d.eval.translate_implicit_ksum(ks: KSum) dict[KFormUnknown, list[MatOp]][source]#
Compute matrix operations on different unknown blocks.
Parameter#
- ksKSum
Sum to translate.
- returns:
Dictionary mapping forms to either a matrix that represents the operation to perform on them, or
float, if it should be multiplication with a constant.- rtype:
dict of (KFormUnknown, list[MatOp])
- mfv2d.eval._translate_inner_prod(inner: KInnerProduct) list[MatOp][source]#
Translate inner product.
- mfv2d.eval._translate_form(form: KForm) list[MatOp][source]#
Translate form into a sequence of matrix operations to be applied of form DoFs.
To cache these translation results and to be able to explicitly
choose only linear, nonlinear, or explicit terms the type
CompiledSystem is provided.
- class mfv2d.eval.CompiledSystem(system: KFormSystem)[source]#
System of equations compiled.
This is a convenience class which first compiles the system and splits it into explicit, linear implicit, and non-linear implicit equations, which are then further used by different parts of the solver.
- Parameters:
system (KFormSystem) – System to compile.
- lhs_codes: Sequence[Sequence[Sequence[tuple[MatOpCode | int | float | Function2D | str, ...]] | None]]#
All left-hand side codes of the equations. When evaluated, this will produce the full left side of the equation.
- linear_codes: Sequence[Sequence[Sequence[tuple[MatOpCode | int | float | Function2D | str, ...]] | None]]#
All left-hand side codes of the equations, which are linear.
To check if the AST was correctly translated, or when debugging,
the expected result can be obtained by a call to
system_as_string() which will convert the system into instructions,
then print the resulting (simplified) code, exactly as the evaluation code
would. To support this function, support functions
_translate_expr_to_str(),
_translate_codes_to_str(), bytecode_matrix_as_rows(), and
explicit_ksum_as_string() are available.
- mfv2d.eval.system_as_string(system: KFormSystem, /) str[source]#
Create the string representation of the system.
- mfv2d.eval._translate_expr_to_str(*ops: MatOp) str[source]#
Translate operations which may include Sum and Push into a string.
- mfv2d.eval.bytecode_matrix_as_rows(system: KFormSystem, bytecodes: Sequence[Mapping[KFormUnknown, list[MatOp]]]) list[str][source]#
Extract expression rows.
Bytecode Simplifictaion#
Simplifictaion of the bytecode is handled by the simplify_expression()
function. It mainly focuses on eliminating Identity operations,
fusing together Scale, or applying MassMat to its
invers.
Conversion to C Bytecode#
Conversion into “C-friendly” bytecode is done by converting the MatOp
values into MatOpCode, int, or float values.
- class mfv2d.eval.MatOpCode(*values)[source]#
Operation codes.
Notes
These values must be kept in sync with the
matrix_op_tenum in the C code, since that is how Python and C communicate with each other.- INVALID = 0#
- IDENTITY = 1#
- MASS = 2#
- INCIDENCE = 3#
- PUSH = 4#
- SCALE = 5#
- SUM = 6#
- INTERPROD = 7#
The actual translation is handled by the translate_to_c_instructions()
function. Some basic type hits are introduced to allow for type hinting the
output of translate_to_c_instructions().
- mfv2d.eval.translate_to_c_instructions(*ops: MatOp) Sequence[tuple[MatOpCode | int | float | Function2D | str, ...]][source]#
Translate the operations into C-compatible values.
This translation is done since the C code can’t handle arbitrary Python objects and instead only deals with integers (or int enums) and floats.