Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Job: Add progress bar #467

Merged
merged 8 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. The format

## [Unreleased]

### Changed
- Show a progress bar during `Job.evaluate(verbose=True)`. The old output is available with `verbose=2`.

### Removed
- Remove config files for MyBinder. They are now located in a different repository [adtzlr/felupe-web](https://github.com/adtzlr/felupe-web).

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ In order to make use of all features of FElupe, it is suggested to install all o
* `matplotlib` for plotting graphs
* `meshio` for mesh-related I/O
* `pyvista` for interactive visualizations
* `tqdm` for showing progress bars during job evaluation

# Getting Started
This tutorial covers the essential high-level parts of creating and solving problems with FElupe. As an introductory example, a quarter model of a solid cube with hyperelastic material behaviour is subjected to a uniaxial elongation applied at a clamped end-face.
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Another key feature is the easy and straightforward definition of mixed field fo
Installation
------------

Install Python, open the terminal and run ``pip install felupe[all]``, where ``[all]`` installs all optional dependencies. By default, FElupe depends on ``numpy``, ``scipy`` and ``tensortrax``. However, ``einsumt``, ``h5py``, ``matplotlib``, ``meshio`` and ``pyvista`` are highly recommended. In order to make use of all features of FElupe, it is suggested to install all optional dependencies. For more flexible constitutive material definitions using Automatic Differentiation consider also installing `matADi <https://github.com/adtzlr/matadi>`_.
Install Python, open the terminal and run ``pip install felupe[all]``, where ``[all]`` installs all optional dependencies. By default, FElupe depends on ``numpy``, ``scipy`` and ``tensortrax``. However, ``einsumt``, ``h5py``, ``matplotlib``, ``meshio``, ``pyvista`` and ``tqdm`` are highly recommended. In order to make use of all features of FElupe, it is suggested to install all optional dependencies. For more flexible constitutive material definitions using Automatic Differentiation consider also installing `matADi <https://github.com/adtzlr/matadi>`_.

.. code-block:: shell

Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ test = [
"h5py",
"matplotlib",
"meshio",
"pyvista",
"tensortrax",
]
all = [
Expand All @@ -61,6 +60,8 @@ all = [
"matplotlib",
"meshio",
"tensortrax",
"pyvista",
"tqdm",
]

[tool.setuptools.dynamic]
Expand Down
71 changes: 48 additions & 23 deletions src/felupe/mechanics/_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,29 @@ def log_strain(field, substep=None):
return [tovoigt(strain.mean(-2), True).T]


def header(verbose):
if verbose == 1:
return "\n".join([
f"FElupe Version {version}",
f"{platform(terse=True)} {machine()} {architecture()[0]}",
"",
])
elif verbose > 1:
return f"""
_______ _______ ___ __ __ _______ _______
| || || | | | | || || |
| ___|| ___|| | | | | || _ || ___|
| |___ | |___ | | | |_| || |_| || |___
| ___|| ___|| |___ | || ___|| ___|
| | | |___ | || || | | |___
|___| |_______||_______||_______||___| |_______|
FElupe Version {version} ({platform(terse=True)} {machine()} {architecture()[0]})

Run Job
=======
"""


class Job:
"A job with a list of steps."

Expand Down Expand Up @@ -90,30 +113,21 @@ def evaluate(
parallel=False,
**kwargs,
):
try:
from tqdm import tqdm
except ModuleNotFoundError:
verbose = 2

if verbose:
print(
f"""
_______ _______ ___ __ __ _______ _______
| || || | | | | || || |
| ___|| ___|| | | | | || _ || ___|
| |___ | |___ | | | |_| || |_| || |___
| ___|| ___|| |___ | || ___|| ___|
| | | |___ | || || | | |___
|___| |_______||_______||_______||___| |_______|
FElupe Version {version} ({platform(terse=True)} {machine()} {architecture()[0]})

"""
)

print("Run Job")
print("=======\n")
print(header(verbose))

if parallel:
if "kwargs" not in kwargs.keys():
kwargs["kwargs"] = {}
kwargs["kwargs"]["parallel"] = True

increment = 0

if filename is not None:
from meshio.xdmf import TimeSeriesWriter

Expand All @@ -123,8 +137,6 @@ def evaluate(
else:
mesh = self.steps[0].items[0].field.region.mesh.as_meshio()

increment = 0

pdata = point_data_default if point_data_default is True else {}
cdata = cell_data_default if cell_data_default is not None else {}

Expand Down Expand Up @@ -157,16 +169,22 @@ def evaluate(
if filename is not None:
writer.write_points_cells(mesh.points, mesh.cells)

if verbose == 1:
total = sum([step.nsubsteps for step in self.steps])
progress_bar = tqdm(total=total, unit=" substeps")

for j, step in enumerate(self.steps):

if verbose:
newton_verbose = False
if verbose == 2:
print(f"Begin Evaluation of Step {j + 1}.")
newton_verbose = True

substeps = step.generate(verbose=verbose, **kwargs)
substeps = step.generate(verbose=newton_verbose, **kwargs)
for i, substep in enumerate(substeps):

if verbose:
_substep = f"Substep {i}/{step.nsubsteps - 1}"
if verbose == 2:
_substep = f"Substep {i + 1}/{step.nsubsteps}"
_step = f"Step {j + 1}/{self.nsteps}"

print(f"{_substep} of {_step} successful.")
Expand All @@ -186,4 +204,11 @@ def evaluate(
point_data={**pdata, **point_data},
cell_data={**cdata, **cell_data},
)
increment += 1

increment += 1

if verbose == 1:
progress_bar.update(1)

if verbose == 1:
progress_bar.close()
4 changes: 2 additions & 2 deletions tests/test_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def test_job():

field, step = pre()
job = fem.Job(steps=[step])
job.evaluate(parallel=True, kwargs={"parallel": False})
job.evaluate(parallel=True, kwargs={"parallel": False}, verbose=0)


def test_job_xdmf():
Expand All @@ -62,7 +62,7 @@ def test_job_xdmf():

field, step = pre()
job = fem.Job(steps=[step])
job.evaluate(filename="result.xdmf", parallel=True)
job.evaluate(filename="result.xdmf", parallel=True, verbose=2)


def test_job_xdmf_global_field():
Expand Down
6 changes: 3 additions & 3 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ deps =
pytest
pytest-cov
matplotlib
extras = test
extras = all
commands =
pytest {posargs}

[testenv:all]
extras = all
[testenv:test]
extras = test