|
| 1 | +import math |
| 2 | + |
| 3 | +from cmlibs.zinc.element import Element |
1 | 4 | from cmlibs.zinc.field import FieldGroup, Field |
| 5 | +from cmlibs.zinc.result import RESULT_OK |
2 | 6 |
|
3 | 7 | from cmlibs.utils.zinc.finiteelement import get_highest_dimension_mesh |
4 | 8 | from cmlibs.utils.zinc.general import ChangeManager |
@@ -181,7 +185,6 @@ def _find_connected(element_nodes, seed_index=None, ignore_element_indices=None, |
181 | 185 |
|
182 | 186 | update_indexes = {} |
183 | 187 | if progress_callback is not None: |
184 | | - |
185 | 188 | update_interval = max(1, int(num_elements * 0.01)) |
186 | 189 | update_indexes = set([i for i in range(update_interval)] + [i for i in range(update_interval, num_elements, update_interval)]) |
187 | 190 |
|
@@ -279,3 +282,57 @@ def undefine_field(field): |
279 | 282 | mesh = fm.findMeshByDimension(i) |
280 | 283 | mesh_group = mesh |
281 | 284 | _undefine_field_on_elements(field, mesh_group) |
| 285 | + |
| 286 | + |
| 287 | +def calculate_jacobian(coordinates): |
| 288 | + jacobian = None |
| 289 | + if coordinates.getNumberOfComponents() == 3: |
| 290 | + fm = coordinates.getFieldmodule() |
| 291 | + jacobian = fm.createFieldDotProduct( |
| 292 | + fm.createFieldCrossProduct( |
| 293 | + fm.createFieldDerivative(coordinates, 1), |
| 294 | + fm.createFieldDerivative(coordinates, 2)), |
| 295 | + fm.createFieldDerivative(coordinates, 3)) |
| 296 | + jacobian.setName("Jacobian") |
| 297 | + |
| 298 | + return jacobian |
| 299 | + |
| 300 | + |
| 301 | +def report_on_lowest_value(real_field, group_field=None): |
| 302 | + """ |
| 303 | + Evaluate the 3D mesh associated with the given field and |
| 304 | + report back on the element with the lowest field value. |
| 305 | + Returns (-1, inf) if the evaluation of the mesh failed. |
| 306 | + :param real_field: A real value field to find the lowest value of. |
| 307 | + :param group_field: A group of 3D elements from the associated mesh (optional, default None). |
| 308 | + :return: A tuple of element identifier and minimum value within that element. |
| 309 | + """ |
| 310 | + fm = real_field.getFieldmodule() |
| 311 | + mesh_3d = fm.findMeshByDimension(3) |
| 312 | + with ChangeManager(fm): |
| 313 | + fc = fm.createFieldcache() |
| 314 | + fr = fc.createFieldrange() |
| 315 | + |
| 316 | + if group_field is not None: |
| 317 | + if group_field.castGroup().isValid(): |
| 318 | + mesh_group = group_field.castGroup().getMeshGroup(mesh_3d) |
| 319 | + element_iter = mesh_group.createElementiterator() |
| 320 | + else: |
| 321 | + return -1, math.inf |
| 322 | + else: |
| 323 | + element_iter = mesh_3d.createElementiterator() |
| 324 | + element = element_iter.next() |
| 325 | + minimum_element_id = -1 |
| 326 | + minimum_element_value = math.inf |
| 327 | + while element.isValid(): |
| 328 | + fc.setElement(element) |
| 329 | + result = real_field.evaluateFieldrange(fc, fr) |
| 330 | + if result == RESULT_OK: |
| 331 | + result, min_value, max_value = fr.getRangeReal(1) |
| 332 | + if result == RESULT_OK and min_value < minimum_element_value: |
| 333 | + minimum_element_id = element.getIdentifier() |
| 334 | + minimum_element_value = min_value |
| 335 | + |
| 336 | + element = element_iter.next() |
| 337 | + |
| 338 | + return minimum_element_id, minimum_element_value |
0 commit comments