Source code for statescale._containers

from dataclasses import dataclass
from functools import wraps

import numpy as np


[docs] @dataclass class ModelResult: "Snapshot model result data." point_data: list | dict | None = None cell_data: list | dict | None = None field_data: dict | None = None def __len__(self): if self.point_data: return next(iter(self.point_data.values())).shape[0] elif self.cell_data: return next(iter(self.cell_data.values())).shape[0] else: return 0 def __getitem__(self, t): return ModelResult( point_data={k: v[t] for k, v in self.point_data.items()}, cell_data={k: v[t] for k, v in self.cell_data.items()}, field_data=self.field_data, ) def __iter__(self): for t in range(len(self)): yield self[t] @property def T(self): "Return a model result with the data transposed." return ModelResult( point_data={k: v.T for k, v in self.point_data.items()}, cell_data={k: v.T for k, v in self.cell_data.items()}, field_data=self.field_data, )
[docs] def as_view(self, mesh=None, field=None, inplace=False, update=None, **kwargs): """Return a view on a given :class:`felupe.Mesh` or :class:`felupe.FieldContainer` with added point- and cell-data. Parameters ---------- mesh : felupe.Mesh or None, optional A mesh which is used to apply the data. Default is None. field : felupe.FieldContainer or None, optional A field container which is used to apply the data. Default is None. inplace : bool, optional A flag to modify the given field inplace. Default is False. update : str or None, optional The key of the point data to be used for updating the values of the first field. If None, the field values are not updated. Default is None. **kwargs : dict, optional Additional arguments are passed to :meth:`felupe.FieldContainer.view`. Returns ------- view : felupe.ViewMesh or felupe.ViewField A view on the mesh or field with the model result data. The :class:`pyvista. UnstructuredGrid` is available via :attr:`felupe.ViewMesh.mesh` or :attr:`felupe.ViewField.mesh`. """ import felupe if field is not None and mesh is None: if not inplace: field = field.copy() if update is not None: values = self.point_data.get(update) if values is not None: field[0].values[:] = values out = field elif mesh is not None and field is None: out = mesh else: raise ValueError("Either 'mesh' or 'field' must be provided.") return out.view(point_data=self.point_data, cell_data=self.cell_data, **kwargs)
[docs] def apply(self, func, on_point_data=False, on_cell_data=False, on_field_data=False): """Apply any function to the arrays of all or selected data dicts. Parameters ---------- func : callable The function to be applied. on_point_data : bool, optional A flag to apply the function on the point data. Default is False. on_cell_data : bool, optional A flag to apply the function on the cell data. Default is False. on_field_data : bool, optional A flag to apply the function on the field data. Default is False. Returns ------- apply_func : callable A transformed function, which applies the given function to all arrays. Parameters ---------- *args : tuple, optional Additional arguments are passed to the given function. **kwargs : dict, optional Additional arguments are passed to the given function. Notes ----- By default, only the time-dependent point- and cell-data arrays are modified. Examples -------- .. code-block:: >>> import numpy as np >>> import statescale >>> >>> res = statescale.Modelresult(point_data={"u": np.random.rand(25, 100, 8, 3)}) >>> out = res.apply(np.mean, on_point_data=True)(axis=-2) >>> >>> out.point_data["u"].shape (25, 100, 3) """ @wraps(func) def apply_func(*args, **kwargs): point_data = self.point_data cell_data = self.cell_data field_data = self.field_data if on_point_data and self.point_data is not None: point_data = { k: func(v, *args, **kwargs) for k, v in self.point_data.items() } if on_cell_data and self.cell_data is not None: cell_data = { k: func(v, *args, **kwargs) for k, v in self.cell_data.items() } if on_field_data and self.field_data is not None: field_data = { k: func(v, *args, **kwargs) for k, v in self.field_data.items() } return ModelResult( point_data=point_data, cell_data=cell_data, field_data=field_data, ) return apply_func