felupe.plugins._animation_writer のソースコード

# -*- coding: utf-8 -*-
"""
This file is part of FElupe.

FElupe is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

FElupe is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with FElupe.  If not, see <http://www.gnu.org/licenses/>.
"""

import os

from ..__about__ import __version__ as version
from ._plugin import Plugin


[ドキュメント] class AnimationWriterPlugin(Plugin): r"""A job plugin to write an animation file during job evaluation. Parameters ---------- items : list The items to plot. filename : str or None, optional The filename of the animation file. Default is "animation.gif". Supported formats are GIF and MP4 (or any other format supported by PyVista). If None, no animation file will be written. Default is "animation.gif". framerate : int, optional The framerate of the animation. Default is 5. quality : int, optional The quality of the movie. Default is 5. This is only used for movie formats, not for GIFs. zoom_camera : float, optional The zoom factor for the camera. Default is 1.0. reset_camera : bool, optional Whether to reset the camera before each frame. Default is True. show_text : bool, optional Whether to show text on the plot. Default is True. take_screenshots : bool or None, optional Whether to take screenshots for all substeps per step. If True, the screenshots will be saved in the "figures" folder. Default is False. **kwargs : dict, optional Additional keyword arguments to pass to the plot method of the items. Notes ----- This plugin should be used with ``off_screen=True``. While it is possible to show the plotter during the job evaluation, it may flicker. Examples -------- .. pyvista-plot:: :force_static: >>> import felupe as fem >>> >>> mesh = fem.Cube(n=6) >>> region = fem.RegionHexahedron(mesh) >>> field = fem.FieldContainer([fem.Field(region, dim=3)]) >>> >>> boundaries = fem.dof.uniaxial( ... field, clamped=True, return_loadcase=False ... ) >>> umat = fem.NeoHooke(mu=1, bulk=2) >>> solid = fem.SolidBody(umat=umat, field=field) >>> >>> move = fem.math.linsteps([0, 1, 0], num=5) >>> ramp = {boundaries["move"]: move} >>> step = fem.Step(items=[solid], ramp=ramp, boundaries=boundaries) >>> >>> animation = fem.AnimationWriterPlugin( ... items=[field], ... filename="animation.gif", ... name="Principal Values of Logarithmic Strain", ... ) >>> job = fem.Job(steps=[step], plugins=[animation]) >>> job.evaluate() See Also -------- felupe.Job : A job with a list of steps and a method to evaluate them. """ def __init__( self, items, filename="animation.gif", framerate=5, quality=5, zoom_camera=1.0, reset_camera=True, show_text=True, take_screenshots=False, **kwargs, ): self.items = items self.filename = filename self.framerate = framerate self.quality = quality self.zoom_camera = zoom_camera self.reset_camera = reset_camera self.show_text = show_text self.take_screenshots = take_screenshots self.kwargs = kwargs self.plotter = None self.write_frame = False def _close_plotter(self): if self.plotter is not None: self.plotter.close() self.plotter = None
[ドキュメント] def before_job(self, context, state): self.plotter = self.kwargs.pop("plotter", None) for item in self.items: self.plotter = item.plot(plotter=self.plotter, **self.kwargs) if self.zoom_camera != 1.0: self.plotter.camera.zoom(self.zoom_camera) if self.filename is not None: _, extension = os.path.splitext(self.filename) if extension == ".gif": self.write_frame = True self.plotter.open_gif(self.filename, fps=self.framerate) elif extension == ".mp4": self.write_frame = True self.plotter.open_movie( self.filename, framerate=self.framerate, quality=self.quality, ) else: raise TypeError('File extension must be either ".gif" or ".mp4".')
[ドキュメント] def after_iteration(self, context, state): if state.error: self._close_plotter()
[ドキュメント] def after_substep(self, context, state): # pragma: no cover self.plotter.clear_actors() # pragma: no cover for item in self.items: # pragma: no cover self.plotter = item.plot( plotter=self.plotter, **self.kwargs ) # pragma: no cover if self.reset_camera: # pragma: no cover self.plotter.reset_camera() # pragma: no cover if self.zoom_camera != 1.0: # pragma: no cover self.plotter.camera.zoom(self.zoom_camera) # pragma: no cover if self.show_text: # pragma: no cover text = [ # pragma: no cover f"FElupe {version}", # pragma: no cover f"Step {1 + state.stepnumber}, " # pragma: no cover f"Substep { 1 + state.substepnumber}", # pragma: no cover ] # pragma: no cover for mesh in self.plotter.meshes: # pragma: no cover name = mesh.active_scalars_name # pragma: no cover if name is not None: # pragma: no cover break # pragma: no cover if name is not None: # pragma: no cover text.append(f"Min. Value {mesh[name].min():.3e}") # pragma: no cover text.append(f"Max. Value {mesh[name].max():.3e}") # pragma: no cover self.plotter.add_text("\n".join(text), font_size=10) # pragma: no cover if self.write_frame: # pragma: no cover self.plotter.write_frame() # pragma: no cover if self.take_screenshots: # pragma: no cover path = "figures/" # pragma: no cover os.makedirs(path, exist_ok=True) # pragma: no cover _ = self.plotter.screenshot( # pragma: no cover path # pragma: no cover + f"step-{(1 + state.stepnumber):02d}_" # pragma: no cover + f"substep-{(1 + state.substepnumber):03d}" # pragma: no cover + ".png" # pragma: no cover ) # pragma: no cover
[ドキュメント] def after_job(self, context, state): self._close_plotter()