Ejemplo n.º 1
0
def create_square_element(mesh: Mesh, finite_element_field: Field,
                          node_coordinate_set):
    """
    Create a single square 2-D finite element using the supplied
    finite element field and sequence of 4 n-D node coordinates.

    :param mesh: The Zinc Mesh to create elements in.
    :param finite_element_field:  Zinc FieldFiniteElement to interpolate on element.
    :param node_coordinate_set: Sequence of 4 coordinates each with as many components as finite element field.
    :return: None
    """
    assert mesh.getDimension() == 2
    assert finite_element_field.castFiniteElement().isValid()
    assert len(node_coordinate_set) == 4
    fieldmodule = finite_element_field.getFieldmodule()
    nodeset = fieldmodule.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
    node_template = nodeset.createNodetemplate()
    node_template.defineField(finite_element_field)
    element_template = mesh.createElementtemplate()
    element_template.setElementShapeType(Element.SHAPE_TYPE_SQUARE)
    linear_basis = fieldmodule.createElementbasis(
        2, Elementbasis.FUNCTION_TYPE_LINEAR_LAGRANGE)
    eft = mesh.createElementfieldtemplate(linear_basis)
    element_template.defineField(finite_element_field, -1, eft)
    field_cache = fieldmodule.createFieldcache()
    with ChangeManager(fieldmodule):
        node_identifiers = []
        for node_coordinate in node_coordinate_set:
            node = nodeset.createNode(-1, node_template)
            node_identifiers.append(node.getIdentifier())
            field_cache.setNode(node)
            finite_element_field.assignReal(field_cache, node_coordinate)
        element = mesh.createElement(-1, element_template)
        element.setNodesByIdentifier(eft, node_identifiers)
    fieldmodule.defineAllFaces()
Ejemplo n.º 2
0
def field_is_managed_coordinates(field_in: Field):
    """
    Conditional function returning True if the field is Finite Element
    type with 3 components, and is managed.
    """
    return field_in.castFiniteElement().isValid() and (
        field_in.getNumberOfComponents() == 3) and field_in.isManaged()
Ejemplo n.º 3
0
def create_fields_transformations(coordinates: Field,
                                  rotation_angles=None,
                                  scale_value=1.0,
                                  translation_offsets=None):
    """
    Create constant fields for rotation, scale and translation containing the supplied
    values, plus the transformed coordinates applying them in the supplied order.
    :param coordinates: The coordinate field to scale, 3 components.
    :param rotation_angles: List of euler angles, length = number of components.
     See create_field_euler_angles_rotation_matrix.
    :param scale_value: Scalar to multiply all components of coordinates.
    :param translation_offsets: List of offsets, length = number of components.
    :return: 4 fields: transformedCoordinates, rotation, scale, translation
    """
    if rotation_angles is None:
        rotation_angles = [0.0, 0.0, 0.0]
    if translation_offsets is None:
        translation_offsets = [0.0, 0.0, 0.0]
    components_count = coordinates.getNumberOfComponents()
    assert (components_count == 3) and (len(rotation_angles) == components_count) and isinstance(scale_value, float) \
        and (len(translation_offsets) == components_count), "createTransformationFields.  Invalid arguments"
    fieldmodule = coordinates.getFieldmodule()
    with ChangeManager(fieldmodule):
        # scale, translate and rotate model, in that order
        rotation = fieldmodule.createFieldConstant(rotation_angles)
        scale = fieldmodule.createFieldConstant(scale_value)
        translation = fieldmodule.createFieldConstant(translation_offsets)
        rotation_matrix = create_field_euler_angles_rotation_matrix(
            fieldmodule, rotation)
        rotated_coordinates = fieldmodule.createFieldMatrixMultiply(
            components_count, rotation_matrix, coordinates)
        transformed_coordinates = rotated_coordinates * scale + translation
        assert transformed_coordinates.isValid()
    return transformed_coordinates, rotation, scale, translation
Ejemplo n.º 4
0
def field_is_managed_real_1_to_3_components(field_in: Field):
    """
    Conditional function returning True if the field is real-valued
    with up to 3 components, and is managed.
    """
    return (field_in.getValueType() == Field.VALUE_TYPE_REAL) and \
        (field_in.getNumberOfComponents() <= 3) and field_in.isManaged()
Ejemplo n.º 5
0
def createFieldsTransformations(coordinates: Field, rotation_angles=None, scale_value=1.0, \
    translation_offsets=None, translation_scale_factor=1.0):
    """
    Create constant fields for rotation, scale and translation containing the supplied
    values, plus the transformed coordinates applying them in the supplied order.
    :param coordinates: The coordinate field to scale, 3 components.
    :param rotation_angles: List of euler angles, length = number of components.
     See create_field_euler_angles_rotation_matrix.
    :param scale_value: Scalar to multiply all components of coordinates.
    :param translation_offsets: List of offsets, length = number of components.
    :param translation_scale_factor: Scaling to multiply translation by so it's magnitude can remain
    close to other parameters for rotation (radians) and scale (assumed close to unit).
    :return: 4 fields: transformedCoordinates, rotation, scale, translation
    """
    if rotation_angles is None:
        rotation_angles = [0.0, 0.0, 0.0]
    if translation_offsets is None:
        translation_offsets = [0.0, 0.0, 0.0]
    components_count = coordinates.getNumberOfComponents()
    assert (components_count == 3) and (len(rotation_angles) == components_count) and isinstance(scale_value, float) \
        and (len(translation_offsets) == components_count), "createFieldsTransformations.  Invalid arguments"
    fieldmodule = coordinates.getFieldmodule()
    with ChangeManager(fieldmodule):
        # Rotate, scale, and translate model, in that order
        rotation = fieldmodule.createFieldConstant(rotation_angles)
        scale = fieldmodule.createFieldConstant(scale_value)
        translation = fieldmodule.createFieldConstant(translation_offsets)
        rotation_matrix = create_field_euler_angles_rotation_matrix(
            fieldmodule, rotation)
        rotated_coordinates = fieldmodule.createFieldMatrixMultiply(
            components_count, rotation_matrix, coordinates)
        transformed_coordinates = rotated_coordinates*scale + (translation if (translation_scale_factor == 1.0) else \
            translation*fieldmodule.createFieldConstant([ translation_scale_factor ]*components_count))
        assert transformed_coordinates.isValid()
    return transformed_coordinates, rotation, scale, translation
Ejemplo n.º 6
0
def field_is_managed_coordinates(field_in: Field):
    """
    Conditional function returning True if the field is Finite Element
    type, with coordinate type attribute, up to 3 components, and is managed.
    """
    return (field_in is not None) and field_in.isManaged() and\
        (field_in.getNumberOfComponents() <= 3) and\
        field_in.castFiniteElement().isValid() and field_in.isTypeCoordinate()
Ejemplo n.º 7
0
 def setModelCoordinatesField(self, modelCoordinatesField: Field):
     finiteElementField = modelCoordinatesField.castFiniteElement()
     assert finiteElementField.isValid() and (
         finiteElementField.getNumberOfComponents() == 3)
     self._modelCoordinatesField = finiteElementField
     self._modelCoordinatesFieldName = modelCoordinatesField.getName()
     modelReferenceCoordinatesFieldName = "reference_" + self._modelCoordinatesField.getName(
     )
     orphanFieldByName(self._fieldmodule,
                       modelReferenceCoordinatesFieldName)
     self._modelReferenceCoordinatesField = createFieldFiniteElementClone(
         self._modelCoordinatesField, modelReferenceCoordinatesFieldName)
     self._updateMarkerCoordinatesField()
     self._updateMarkerDataLocationCoordinatesField()
Ejemplo n.º 8
0
def create_fields_displacement_gradients(coordinates: Field,
                                         reference_coordinates: Field,
                                         mesh: Mesh):
    """
    :return: 1st and 2nd displacement gradients of (coordinates - referenceCoordinates) w.r.t. referenceCoordinates.
    """
    assert (coordinates.getNumberOfComponents()
            == 3) and (reference_coordinates.getNumberOfComponents() == 3)
    fieldmodule = mesh.getFieldmodule()
    dimension = mesh.getDimension()
    with ChangeManager(fieldmodule):
        if dimension == 3:
            u = coordinates - reference_coordinates
            displacement_gradient = fieldmodule.createFieldGradient(
                u, reference_coordinates)
            displacement_gradient2 = fieldmodule.createFieldGradient(
                displacement_gradient, reference_coordinates)
        elif dimension == 2:
            # Note this needs improvement as missing cross terms
            # assume xi directions are approximately normal;
            # effect is to penalise elements where this is not so, which is also desired
            dX_dxi1 = fieldmodule.createFieldDerivative(
                reference_coordinates, 1)
            dX_dxi2 = fieldmodule.createFieldDerivative(
                reference_coordinates, 2)
            dx_dxi1 = fieldmodule.createFieldDerivative(coordinates, 1)
            dx_dxi2 = fieldmodule.createFieldDerivative(coordinates, 2)
            dS1_dxi1 = fieldmodule.createFieldMagnitude(dX_dxi1)
            dS2_dxi2 = fieldmodule.createFieldMagnitude(dX_dxi2)
            du_dS1 = (dx_dxi1 - dX_dxi1) / dS1_dxi1
            du_dS2 = (dx_dxi2 - dX_dxi2) / dS2_dxi2
            displacement_gradient = fieldmodule.createFieldConcatenate(
                [du_dS1, du_dS2])
            # curvature:
            d2u_dSdxi1 = fieldmodule.createFieldDerivative(
                displacement_gradient, 1)
            d2u_dSdxi2 = fieldmodule.createFieldDerivative(
                displacement_gradient, 2)
            displacement_gradient2 = fieldmodule.createFieldConcatenate(
                [d2u_dSdxi1 / dS1_dxi1, d2u_dSdxi2 / dS2_dxi2])
        else:  # dimension == 1
            dX_dxi1 = fieldmodule.createFieldDerivative(
                reference_coordinates, 1)
            dx_dxi1 = fieldmodule.createFieldDerivative(coordinates, 1)
            dS1_dxi1 = fieldmodule.createFieldMagnitude(dX_dxi1)
            displacement_gradient = (dx_dxi1 - dX_dxi1) / dS1_dxi1
            # curvature:
            displacement_gradient2 = fieldmodule.createFieldDerivative(
                displacement_gradient, 1) / dS1_dxi1
    return displacement_gradient, displacement_gradient2
Ejemplo n.º 9
0
def assign_field_parameters(target_field: Field, source_field: Field):
    """
    Copy parameters from sourceField to targetField.
    Currently only works for node parameters.
    """
    field_assignment = target_field.createFieldassignment(source_field)
    field_assignment.assign()
Ejemplo n.º 10
0
 def setSelectHighlightGroup(self, group: FieldGroup):
     """
     Select and highlight objects in the group.
     :param group: FieldGroup to select, or None to clear selection.
     """
     fieldmodule = self.getFieldmodule()
     with ChangeManager(fieldmodule):
         scene = self.getScene()
         # can't use SUBELEMENT_HANDLING_MODE_FULL as some groups have been tweaked to omit some faces
         selectionGroup = get_scene_selection_group(
             scene,
             subelementHandlingMode=FieldGroup.SUBELEMENT_HANDLING_MODE_NONE
         )
         if group:
             if selectionGroup:
                 selectionGroup.clear()
             else:
                 selectionGroup = create_scene_selection_group(
                     scene,
                     subelementHandlingMode=FieldGroup.
                     SUBELEMENT_HANDLING_MODE_NONE)
             group_add_group_elements(selectionGroup,
                                      group,
                                      highest_dimension_only=False)
             for fieldDomainType in (Field.DOMAIN_TYPE_NODES,
                                     Field.DOMAIN_TYPE_DATAPOINTS):
                 group_add_group_nodes(
                     selectionGroup, group,
                     fieldmodule.findNodesetByFieldDomainType(
                         fieldDomainType))
         else:
             if selectionGroup:
                 selectionGroup.clear()
                 scene.setSelectionField(Field())
Ejemplo n.º 11
0
 def isoscalarFieldChanged(self, index):
     if self._graphics:
         contours = self._graphics.castContours()
         if contours.isValid():
             isoscalarField = self.ui.isoscalar_field_chooser.getField()
             if not isoscalarField:
                 isoscalarField = Field()
             contours.setIsoscalarField(isoscalarField)
 def _setupGroupSettingWidgets(self):
     """
     Set up group setting widgets and display values from fitter object.
     """
     self._ui.groupSettings_fieldChooser.setRegion(self._fitter.getRegion())
     self._ui.groupSettings_fieldChooser.setNullObjectName("-")
     self._ui.groupSettings_fieldChooser.setConditional(field_is_managed_group)
     self._ui.groupSettings_fieldChooser.setField(Field())
Ejemplo n.º 13
0
def getNodesetConditionalSize(nodeset: Nodeset, conditionalField: Field):
    """
    :return: Number of objects in nodeset for which conditionalField is True.
    """
    assert conditionalField.getNumberOfComponents() == 1
    fieldmodule = conditionalField.getFieldmodule()
    fieldcache = fieldmodule.createFieldcache()
    nodeiterator = nodeset.createNodeiterator()
    size = 0
    node = nodeiterator.next()
    while node.isValid():
        fieldcache.setNode(node)
        result, value = conditionalField.evaluateReal(fieldcache, 1)
        if value != 0.0:
            size += 1
        node = nodeiterator.next()
    return size
Ejemplo n.º 14
0
 def labelFieldChanged(self, index):
     if self._graphics:
         pointattributes = self._graphics.getGraphicspointattributes()
         if pointattributes.isValid():
             labelField = self.ui.label_field_chooser.getField()
             if not labelField:
                 labelField = Field()
             pointattributes.setLabelField(labelField)
Ejemplo n.º 15
0
 def pointOrientationScaleFieldChanged(self, index):
     if self._graphics:
         pointattributes = self._graphics.getGraphicspointattributes()
         if pointattributes.isValid():
             orientationScaleField = self.ui.point_orientation_scale_field_chooser.getField(
             )
             if not orientationScaleField:
                 orientationScaleField = Field()
             pointattributes.setOrientationScaleField(orientationScaleField)
Ejemplo n.º 16
0
 def lineOrientationScaleFieldChanged(self, index):
     if self._graphics:
         lineattributes = self._graphics.getGraphicslineattributes()
         if lineattributes.isValid():
             orientationScaleField = self.ui.line_orientation_scale_field_chooser.getField(
             )
             if not orientationScaleField:
                 orientationScaleField = Field()
             lineattributes.setOrientationScaleField(orientationScaleField)
Ejemplo n.º 17
0
 def streamVectorFieldChanged(self, index):
     if self._graphics:
         streamlines = self._graphics.castStreamlines()
         if streamlines.isValid():
             streamVectorField = self.ui.stream_vector_field_chooser.getField(
             )
             if not streamVectorField:
                 streamVectorField = Field()
             streamlines.setStreamVectorField(streamVectorField)
Ejemplo n.º 18
0
 def coordinateFieldChanged(self, index):
     '''
     An item was selected at index in coordinate field chooser widget
     '''
     if self._graphics:
         coordinateField = self.ui.coordinate_field_chooser.getField()
         if coordinateField:
             self._graphics.setCoordinateField(coordinateField)
         else:
             self._graphics.setCoordinateField(Field())
 def clearSelection(self):
     """
     If there is a selection group, clears it and removes it from scene.
     """
     selectionGroup = self.getSelectionGroup()
     if selectionGroup is not None:
         selectionGroup.clear()
         selectionGroup = Field()  # NULL
         scene = self._sceneviewer.getScene()
         scene.setSelectionField(selectionGroup)
Ejemplo n.º 20
0
def get_node_name_centres(nodeset: Nodeset, coordinates_field: Field,
                          name_field: Field):
    """
    Find mean locations of node coordinate with the same names.
    :param nodeset: Zinc Nodeset or NodesetGroup to search.
    :param coordinates_field: The coordinate field to evaluate.
    :param name_field: The name field to match.
    :return: Dict of names -> coordinates.
    """
    components_count = coordinates_field.getNumberOfComponents()
    fieldmodule = nodeset.getFieldmodule()
    fieldcache = fieldmodule.createFieldcache()
    name_records = {}  # name -> (coordinates, count)
    nodeiter = nodeset.createNodeiterator()
    node = nodeiter.next()
    while node.isValid():
        fieldcache.setNode(node)
        name = name_field.evaluateString(fieldcache)
        coordinates_result, coordinates = coordinates_field.evaluateReal(
            fieldcache, components_count)
        if name and (coordinates_result == RESULT_OK):
            name_record = name_records.get(name)
            if name_record:
                name_centre = name_record[0]
                for c in range(components_count):
                    name_centre[c] += coordinates[c]
                name_record[1] += 1
            else:
                name_records[name] = [coordinates, 1]
        node = nodeiter.next()
    # divide centre coordinates by count
    name_centres = {}
    for name in name_records:
        name_record = name_records[name]
        name_count = name_record[1]
        name_centre = name_record[0]
        if name_count > 1:
            scale = 1.0 / name_count
            for c in range(components_count):
                name_centre[c] *= scale
        name_centres[name] = name_centre
    return name_centres
 def reset(self):
     self._node = None
     self._graphics = None
     self._coordinateField = None
     self._orientationField = None
     self._glyphCentre = [0.0, 0.0, 0.0]
     self._glyphSize = [0.0, 0.0, 0.0]
     self._glyphScaleFactors = [0.0, 0.0, 0.0]
     self._variableScaleField = Field()
     self._nearestElement = None
     self._elementCoordinateField = None
     self._createCoordinatesField = None
Ejemplo n.º 22
0
def create_field_finite_element_clone(source_field: Field,
                                      name: str,
                                      managed=False) -> FieldFiniteElement:
    """
    Copy an existing Finite Element Field to a new field of supplied name.
    Note: does not handle time-varying parameters.
    New field is not managed by default.
    :param source_field: Zinc finite element field to copy.
    :param name: The name of the new field, asserts that no field of that name exists.
    :param managed: Managed state of field created here.
    :return: New identically defined field with supplied name.
    """
    assert source_field.castFiniteElement().isValid(), \
        "opencmiss.utils.zinc.field.createFieldFiniteElementClone.  Not a Zinc finite element field"
    fieldmodule = source_field.getFieldmodule()
    field = fieldmodule.findFieldByName(name)
    assert not field.isValid(
    ), "opencmiss.utils.zinc.field.createFieldFiniteElementClone.  Target field name is in use"
    with ChangeManager(fieldmodule):
        # Zinc needs a function to do this efficiently; currently serialise to string, replace field name and reload!
        source_name = source_field.getName()
        region = fieldmodule.getRegion()
        sir = region.createStreaminformationRegion()
        srm = sir.createStreamresourceMemory()
        sir.setFieldNames([source_name])
        region.write(sir)
        result, buffer = srm.getBuffer()
        # small risk of modifying other text here:
        source_bytes = bytes(") " + source_name + ",", "utf-8")
        target_bytes = bytes(") " + name + ",", "utf-8")
        buffer = buffer.replace(source_bytes, target_bytes)
        sir = region.createStreaminformationRegion()
        sir.createStreamresourceMemoryBuffer(buffer)
        result = region.read(sir)
        assert result == RESULT_OK
    # note currently must have called endChange before field can be found
    field = fieldmodule.findFieldByName(name).castFiniteElement()
    field.setManaged(managed)
    assert field.isValid()
    return field
Ejemplo n.º 23
0
def create_field_mesh_integral(coordinates: Field, mesh: Mesh, number_of_points=3):
    """
    Create a field integrating the coordinates to give scalar volume/area/length over
    the mesh, depending on its dimension.
    :param coordinates:
    :param mesh:
    :param number_of_points: Number of Gauss points.
    :return: Field giving volume of coordinates field over mesh via Gaussian quadrature.
    """
    fieldmodule = coordinates.getFieldmodule()
    with ChangeManager(fieldmodule):
        mesh_integral_field = fieldmodule.createFieldMeshIntegral(fieldmodule.createFieldConstant(1.0),
                                                                  coordinates, mesh)
        mesh_integral_field.setNumbersOfPoints(number_of_points)
    return mesh_integral_field
Ejemplo n.º 24
0
def evaluate_field_nodeset_mean(field: Field, nodeset: Nodeset):
    """
    :return: Mean of field over nodeset.
    """
    fieldmodule = nodeset.getFieldmodule()
    components_count = field.getNumberOfComponents()
    with ChangeManager(fieldmodule):
        mean_field = fieldmodule.createFieldNodesetMean(field, nodeset)
        fieldcache = fieldmodule.createFieldcache()
        result, mean_values = mean_field.evaluateReal(fieldcache,
                                                      components_count)
        assert result == RESULT_OK
        del mean_field
        del fieldcache
    return mean_values
Ejemplo n.º 25
0
def create_triangle_elements(mesh: Mesh, finite_element_field: Field,
                             element_node_set):
    """
    Create a linear triangular element for every set of 3 local nodes in element_node_set.

    :param mesh: The Zinc Mesh to create elements in.
    :param finite_element_field: Zinc FieldFiniteElement to interpolate from nodes.
    :param element_node_set: Sequence of 3 node identifiers for each element.
    :return: None
    """
    assert mesh.getDimension() == 2
    assert finite_element_field.castFiniteElement().isValid()
    fieldmodule = finite_element_field.getFieldmodule()
    element_template = mesh.createElementtemplate()
    element_template.setElementShapeType(Element.SHAPE_TYPE_TRIANGLE)
    linear_basis = fieldmodule.createElementbasis(
        2, Elementbasis.FUNCTION_TYPE_LINEAR_SIMPLEX)
    eft = mesh.createElementfieldtemplate(linear_basis)
    element_template.defineField(finite_element_field, -1, eft)
    with ChangeManager(fieldmodule):
        for element_nodes in element_node_set:
            element = mesh.createElement(-1, element_template)
            element.setNodesByIdentifier(eft, element_nodes)
    fieldmodule.defineAllFaces()
Ejemplo n.º 26
0
 def dataFieldChanged(self, index):
     '''
     An item was selected at index in data field chooser widget
     '''
     if self._graphics:
         dataField = self.ui.data_field_chooser.getField()
         if dataField:
             scene = self._graphics.getScene()
             scene.beginChange()
             spectrum = self._graphics.getSpectrum()
             if not spectrum.isValid():
                 spectrummodule = scene.getSpectrummodule()
                 spectrum = spectrummodule.getDefaultSpectrum()
                 self._graphics.setSpectrum(spectrum)
             self._graphics.setDataField(dataField)
             scene.endChange()
         else:
             self._graphics.setDataField(Field())
Ejemplo n.º 27
0
def evaluate_field_nodeset_range(field: Field, nodeset: Nodeset):
    """
    :return: min, max range of field over nodes.
    """
    fieldmodule = nodeset.getFieldmodule()
    components_count = field.getNumberOfComponents()
    with ChangeManager(fieldmodule):
        min_field = fieldmodule.createFieldNodesetMinimum(field, nodeset)
        max_field = fieldmodule.createFieldNodesetMaximum(field, nodeset)
        fieldcache = fieldmodule.createFieldcache()
        result, min_values = min_field.evaluateReal(fieldcache,
                                                    components_count)
        assert result == RESULT_OK
        result, max_values = max_field.evaluateReal(fieldcache,
                                                    components_count)
        assert result == RESULT_OK
        del min_field
        del max_field
        del fieldcache
    return min_values, max_values
Ejemplo n.º 28
0
def evaluate_field_mesh_integral(field: Field, coordinates: Field, mesh: Mesh, number_of_points=4):
    """
    Integrate value of a field over mesh using Gaussian Quadrature.
    :param field: Field to integrate over mesh.
    :param coordinates: Field giving spatial coordinates to integrate over.
    :param mesh: The mesh or mesh group to integrate over.
    :param number_of_points: Number of integration points in each dimension.
    :return: Integral value.
    """
    fieldmodule = mesh.getFieldmodule()
    components_count = field.getNumberOfComponents()
    with ChangeManager(fieldmodule):
        integral = fieldmodule.createFieldMeshIntegral(field, coordinates, mesh)
        integral.setNumbersOfPoints(number_of_points)
        fieldcache = fieldmodule.createFieldcache()
        result, value = integral.evaluateReal(fieldcache, components_count)
        del integral
        del fieldcache
    assert result == RESULT_OK
    return value
Ejemplo n.º 29
0
def create_field_euler_angles_rotation_matrix(fieldmodule: Fieldmodule,
                                              euler_angles: Field) -> Field:
    """
    From OpenCMISS-Zinc graphics_library.cpp, matrix transposed to row major.
    Matrix is product RzRyRx, giving rotation about x, then y, then z with
    positive angles rotating by right hand rule about axis.
    :param fieldmodule: The fieldmodule to create the field in.
    :param euler_angles: 3-component field of angles in radians, components:
    0 = azimuth (about z)
    1 = elevation (about y)
    2 = roll (about x)
    :return: 3x3 rotation matrix field suitable for pre-multiplying vector v
    i.e. v' = Mv
    """
    assert euler_angles.getNumberOfComponents() == 3
    with ChangeManager(fieldmodule):
        azimuth = fieldmodule.createFieldComponent(euler_angles, 1)
        cos_azimuth = fieldmodule.createFieldCos(azimuth)
        sin_azimuth = fieldmodule.createFieldSin(azimuth)
        elevation = fieldmodule.createFieldComponent(euler_angles, 2)
        cos_elevation = fieldmodule.createFieldCos(elevation)
        sin_elevation = fieldmodule.createFieldSin(elevation)
        roll = fieldmodule.createFieldComponent(euler_angles, 3)
        cos_roll = fieldmodule.createFieldCos(roll)
        sin_roll = fieldmodule.createFieldSin(roll)
        minus_one = fieldmodule.createFieldConstant([-1.0])
        cos_azimuth_sin_elevation = cos_azimuth * sin_elevation
        sin_azimuth_sin_elevation = sin_azimuth * sin_elevation
        matrix_components = [
            cos_azimuth * cos_elevation,
            cos_azimuth_sin_elevation * sin_roll - sin_azimuth * cos_roll,
            cos_azimuth_sin_elevation * cos_roll + sin_azimuth * sin_roll,
            sin_azimuth * cos_elevation,
            sin_azimuth_sin_elevation * sin_roll + cos_azimuth * cos_roll,
            sin_azimuth_sin_elevation * cos_roll - cos_azimuth * sin_roll,
            minus_one * sin_elevation, cos_elevation * sin_roll,
            cos_elevation * cos_roll
        ]
        rotation_matrix = fieldmodule.createFieldConcatenate(matrix_components)
    return rotation_matrix
Ejemplo n.º 30
0
def find_node_with_name(nodeset: Nodeset, name_field: Field, name):
    """
    Get single node in nodeset with supplied name.
    :param nodeset: Zinc Nodeset or NodesetGroup to search.
    :param name_field: The name field to match.
    :param name: The name to match in nameField.
    :return: Node with name, or None if 0 or multiple nodes with name.
    """
    fieldmodule = nodeset.getFieldmodule()
    fieldcache = fieldmodule.createFieldcache()
    nodeiter = nodeset.createNodeiterator()
    node_with_name = None
    node = nodeiter.next()
    while node.isValid():
        fieldcache.setNode(node)
        temp_name = name_field.evaluateString(fieldcache)
        if temp_name == name:
            if node_with_name:
                return None
            node_with_name = node
        node = nodeiter.next()
    return node_with_name