예제 #1
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()
예제 #2
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()
예제 #3
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()
예제 #4
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()
예제 #5
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
예제 #6
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()
예제 #7
0
def transform_coordinates(field: Field,
                          rotation_scale,
                          offset,
                          time=0.0) -> bool:
    """
    Transform finite element field coordinates by matrix and offset, handling nodal derivatives and versions.
    Limited to nodal parameters, rectangular cartesian coordinates
    :param field: the coordinate field to transform
    :param rotation_scale: square transformation matrix 2-D array with as many rows and columns as field components.
    :param offset: coordinates offset.
    :param time: time value.
    :return: True on success, otherwise false.
    """
    ncomp = field.getNumberOfComponents()
    if (ncomp != 2) and (ncomp != 3):
        print(
            'zinc.transformCoordinates: field has invalid number of components'
        )
        return False
    if (len(rotation_scale) != ncomp) or (len(offset) != ncomp):
        print(
            'zinc.transformCoordinates: invalid matrix number of columns or offset size'
        )
        return False
    for matRow in rotation_scale:
        if len(matRow) != ncomp:
            print(
                'zinc.transformCoordinates: invalid matrix number of columns')
            return False
    if field.getCoordinateSystemType(
    ) != Field.COORDINATE_SYSTEM_TYPE_RECTANGULAR_CARTESIAN:
        print('zinc.transformCoordinates: field is not rectangular cartesian')
        return False
    fe_field = field.castFiniteElement()
    if not fe_field.isValid():
        print(
            'zinc.transformCoordinates: field is not finite element field type'
        )
        return False
    success = True
    fm = field.getFieldmodule()
    fm.beginChange()
    cache = fm.createFieldcache()
    cache.setTime(time)
    nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
    node_template = nodes.createNodetemplate()
    node_iter = nodes.createNodeiterator()
    node = node_iter.next()
    while node.isValid():
        node_template.defineFieldFromNode(fe_field, node)
        cache.setNode(node)
        for derivative in [
                Node.VALUE_LABEL_VALUE, Node.VALUE_LABEL_D_DS1,
                Node.VALUE_LABEL_D_DS2, Node.VALUE_LABEL_D2_DS1DS2,
                Node.VALUE_LABEL_D_DS3, Node.VALUE_LABEL_D2_DS1DS3,
                Node.VALUE_LABEL_D2_DS2DS3, Node.VALUE_LABEL_D3_DS1DS2DS3
        ]:
            versions = node_template.getValueNumberOfVersions(
                fe_field, -1, derivative)
            for v in range(versions):
                result, values = fe_field.getNodeParameters(
                    cache, -1, derivative, v + 1, ncomp)
                if result != RESULT_OK:
                    success = False
                else:
                    new_values = vectorops.matrixvectormult(
                        rotation_scale, values)
                    if derivative == Node.VALUE_LABEL_VALUE:
                        new_values = vectorops.add(new_values, offset)
                    result = fe_field.setNodeParameters(
                        cache, -1, derivative, v + 1, new_values)
                    if result != RESULT_OK:
                        success = False
        node = node_iter.next()
    fm.endChange()
    if not success:
        print('zinc.transformCoordinates: failed to get/set some values')
    return success
예제 #8
0
 def setDataCoordinatesField(self, dataCoordinatesField: Field):
     finiteElementField = dataCoordinatesField.castFiniteElement()
     assert finiteElementField.isValid() and (
         finiteElementField.getNumberOfComponents() == 3)
     self._dataCoordinatesFieldName = dataCoordinatesField.getName()
     self._dataCoordinatesField = finiteElementField
 def _set_model_coordinates_field(self, model_coordinates_field: Field):
     finite_element_field = model_coordinates_field.castFiniteElement()
     assert finite_element_field.isValid() and (finite_element_field.getNumberOfComponents() == 3)
     self._model_coordinates_field = finite_element_field