Thanks to visit codestin.com
Credit goes to github.com

Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. The format
- Add `newtonrhapson.callback(dx, x, iteration, xnorm, fnorm, success)` to provide a callback after each completed Newton iteration. This is available as `Job.evaluate(callback=newton_callback)`, whereas a callback after each completed substep has to be provided in `Job(callback=substep_callback)`.
- Add a flag to plot MPC and point load either on the deformed (default) or undeformed mesh-points, `MultiPointConstraint.plot(..., deformed=True)`, `MultiPointContact.plot(..., deformed=True)`, `PointLoad.plot(..., deformed=True)`.
- Add `math.svd()` for the singular value decomposition of arrays with trailing axes.
- Add `newtonrhapson(..., progress_bar=None)` which re-uses an existing tqdm progress bar. If provided, this progress bar must be manually closed. If None and `verbose` is True, a new progress bar is created.

### Changed
- Allow field containers to be included in the list of `fields` in `FieldContainer(fields)`. If a field container is included, its sub-fields are unpacked.
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/examples/extut02_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
# :class:`~felupe.CharacteristicCurve`-job logs the displacement and sum of reaction
# forces on a given boundary condition.
job = fem.CharacteristicCurve(steps=[uniaxial], boundary=boundaries["move"])
job.evaluate(filename="result.xdmf", verbose=True)
job.evaluate(filename="result.xdmf")

field.plot("Principal Values of Logarithmic Strain").show()

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/examples/extut03_multiple-solids.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
# This step is now added to a :class:`~felupe.Job`. The top-level field ``x0`` is passed
# to :meth:`~felupe.Job.evaluate`.
job = fem.Job(steps=[uniaxial])
job.evaluate(x0=x0, verbose=True)
job.evaluate(x0=x0)

plotter = solid_1.plot(style="wireframe")
plotter = solid_3.plot(style="wireframe", plotter=plotter)
Expand Down
20 changes: 18 additions & 2 deletions src/felupe/mechanics/_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,13 +279,28 @@ def evaluate(

if verbose == 1:
total = sum([step.nsubsteps for step in self.steps])
progress_bar = tqdm(total=total, desc="Step ", unit="substep")
progress_bar = tqdm(
total=total,
desc="Step ",
unit="substep",
colour="green",
)
progress_bar_newton = tqdm(
total=100,
desc="Substep",
colour="cyan",
unit="%",
)
else:
progress_bar_newton = None

for j, step in enumerate(self.steps):
if verbose == 2:
print(f"Begin Evaluation of Step {j + 1}.")

substeps = step.generate(verbose=verbose, **kwargs)
substeps = step.generate(
verbose=verbose, progress_bar=progress_bar_newton, **kwargs
)
for i, substep in enumerate(substeps):
self.fnorms.append(substep.fnorms)
if verbose == 2:
Expand Down Expand Up @@ -318,5 +333,6 @@ def evaluate(

if verbose == 1:
progress_bar.close()
progress_bar_newton.close()

return self
32 changes: 23 additions & 9 deletions src/felupe/tools/_newton.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ def newtonrhapson(
verbose=None,
callback=None,
callback_kwargs=None,
progress_bar=None,
):
r"""Find a root of a real function using the Newton-Raphson method.

Expand Down Expand Up @@ -277,6 +278,9 @@ def newtonrhapson(
An optional callback function with function signature
``callback = lambda dx, x, iteration, xnorm, fnorm, success: None``, which is
called after each completed iteration. Default is None.
progress_bar : str or None, optional
A progress bar if verbose is True. If None and verbose is True, a new bar is
created.

Returns
-------
Expand Down Expand Up @@ -400,7 +404,13 @@ def newtonrhapson(
verbose = 2 # pragma: no cover

if verbose == 1:
progress_bar = tqdm(total=100, desc="Solver", leave=False, unit="%")
if progress_bar is None:
progress_bar = tqdm(total=100, colour="yellow", unit="%")
close_bar = True
else:
progress_bar.reset()
close_bar = False

progress0 = 0
progress = 0

Expand Down Expand Up @@ -476,15 +486,17 @@ def newtonrhapson(
callback(dx, x, iteration, xnorm, fnorm, success)

# update progress bar if norm of residuals is available
if verbose == 1 and fnorm > 0.0:
if verbose == 1:
completion = 0.1

# initial log. ratio of first residual norm vs. tolerance norm
if decades is None:
decades = max(1.0, np.log10(fnorm) - np.log10(tol))
if fnorm > 0.0:
# initial log. ratio of first residual norm vs. tolerance norm
if decades is None:
decades = max(1.0, np.log10(fnorm) - np.log10(tol))

# current log. ratio of first residual norm vs. tolerance norm
dfnorm = np.log10(fnorm) - np.log10(tol)
completion = 1 - dfnorm / decades
# current log. ratio of first residual norm vs. tolerance norm
dfnorm = np.log10(fnorm) - np.log10(tol)
completion += 0.9 * (1 - dfnorm / decades)

# progress in percent, ensure lower equal 100%
progress = np.clip(100 * completion, 0, 100).astype(int)
Expand Down Expand Up @@ -513,7 +525,9 @@ def newtonrhapson(
)

if verbose == 1:
progress_bar.close()
progress_bar.update(100 - progress)
if close_bar:
progress_bar.close()

if verbose == 2:
runtimes.append(perf_counter())
Expand Down