Source code for fenicsxconcrete.sensor_definition.strain_sensor

from __future__ import annotations

import os
from typing import TYPE_CHECKING

import numpy as np
import dolfinx as df
import ufl

if TYPE_CHECKING:
    from fenicsxconcrete.finite_element_problem.base_material import MaterialProblem

from fenicsxconcrete.sensor_definition.base_sensor import PointSensor
from fenicsxconcrete.util import project, ureg


[docs] class StrainSensor(PointSensor): """A sensor that measures strain at a specific point Attributes: data: list of measured values time: list of time stamps units : pint definition of the base unit a sensor returns name : name of the sensor, default is class name, but can be changed where: location where the value is measured """
[docs] def measure(self, problem: MaterialProblem) -> None: """ The strain value at the defined point is added to the data list, as well as the time t to the time list Arguments: problem : FEM problem object t : time of measurement for time dependent problems, default is 1 """ try: strain = problem.q_fields.strain assert strain is not None except AssertionError: raise Exception("Strain not defined in problem") strain_tensor_dim = problem.experiment.mesh.topology.dim strain_function = project( strain, # stress fct from problem df.fem.functionspace(problem.experiment.mesh, (problem.q_fields.plot_space_type[0], problem.q_fields.plot_space_type[1], (strain_tensor_dim, strain_tensor_dim))), # tensor space problem.q_fields.measure, ) # project stress onto visualization space # finding the cells corresponding to the point bb_tree = df.geometry.bb_tree(problem.experiment.mesh, problem.experiment.mesh.topology.dim) cells = [] # Find cells whose bounding-box collide with the points point = np.array(self.where, dtype=np.float64) cell_candidates = df.geometry.compute_collisions_points(bb_tree, point) # Choose one of the cells that contains the point colliding_cells = df.geometry.compute_colliding_cells(problem.experiment.mesh, cell_candidates, point) if len(colliding_cells.links(0)) > 0: cells.append(colliding_cells.links(0)[0]) else: raise ValueError(f"cells with point {self.where} not found in mesh") # adding correct units to stress strain_data = strain_function.eval([self.where], cells) self.data.append(strain_data) self.time.append(problem.time)
[docs] def report_metadata(self) -> dict: """Generates dictionary with the metadata of this sensor""" metadata = super().report_metadata() metadata["sensor_file"] = os.path.splitext(os.path.basename(__file__))[0] return metadata
[docs] @staticmethod def base_unit() -> ureg: """Defines the base unit of this sensor Returns: the base unit as pint unit object """ return ureg("")