|
1 | 1 | """ |
2 | 2 | Utilities for creating and working with Zinc Finite Elements. |
3 | 3 | """ |
| 4 | +import math |
| 5 | + |
4 | 6 | from cmlibs.maths import vectorops |
5 | 7 | from cmlibs.utils.zinc.general import ChangeManager |
6 | 8 | from cmlibs.zinc.element import Element, Elementbasis, Elementfieldtemplate, Mesh |
@@ -617,6 +619,47 @@ def interpolate_cubic_hermite_derivative(v1, d1, v2, d2, xi): |
617 | 619 | return [(f1 * v1[i] + f2 * d1[i] + f3 * v2[i] + f4 * d2[i]) for i in range(len(v1))] |
618 | 620 |
|
619 | 621 |
|
| 622 | +def _is_real_scalar_field(field): |
| 623 | + return field is not None and field.isValid() and (field.getValueType() == Field.VALUE_TYPE_REAL) and (field.getNumberOfComponents() == 1) |
| 624 | + |
| 625 | + |
| 626 | +def get_scalar_field_minimum_in_mesh(real_field, mesh=None): |
| 627 | + """ |
| 628 | + Evaluate the 3D mesh associated with the given (real) field and |
| 629 | + report back on the element with the lowest field value. If the optional |
| 630 | + mesh (or mesh_group) is not given then the highest dimension mesh available will be used. |
| 631 | + Returns (-1, inf) if the evaluation is invalid. |
| 632 | + :param real_field: A real scalar value field to find the lowest value of. |
| 633 | + :param mesh: A mesh or mesh_group (optional, default None). |
| 634 | + :return: A tuple of element identifier and minimum value within that element. |
| 635 | + """ |
| 636 | + minimum_element_id = -1 |
| 637 | + minimum_element_value = math.inf |
| 638 | + if _is_real_scalar_field(real_field): |
| 639 | + fm = real_field.getFieldmodule() |
| 640 | + fc = fm.createFieldcache() |
| 641 | + fr = fc.createFieldrange() |
| 642 | + |
| 643 | + in_use_mesh = mesh if mesh else get_highest_dimension_mesh(fm) |
| 644 | + if in_use_mesh is None or not hasattr(in_use_mesh, "createElementiterator"): |
| 645 | + return minimum_element_id, minimum_element_value |
| 646 | + |
| 647 | + element_iter = in_use_mesh.createElementiterator() |
| 648 | + element = element_iter.next() |
| 649 | + while element.isValid(): |
| 650 | + fc.setElement(element) |
| 651 | + result = real_field.evaluateFieldrange(fc, fr) |
| 652 | + if result == RESULT_OK: |
| 653 | + result, min_value, max_value = fr.getRangeReal(1) |
| 654 | + if result == RESULT_OK and min_value < minimum_element_value: |
| 655 | + minimum_element_id = element.getIdentifier() |
| 656 | + minimum_element_value = min_value |
| 657 | + |
| 658 | + element = element_iter.next() |
| 659 | + |
| 660 | + return minimum_element_id, minimum_element_value |
| 661 | + |
| 662 | + |
620 | 663 | createCubeElement = create_cube_element |
621 | 664 | createSquareElement = create_square_element |
622 | 665 | createLineElement = create_line_element |
|
0 commit comments