From 4465bdf588cfb48f7060da98de2d493bf1bf6b29 Mon Sep 17 00:00:00 2001 From: hugtalbot Date: Tue, 16 Sep 2025 19:42:12 +0200 Subject: [PATCH 1/3] Update timer example introducing the Newton Raphson --- examples/advanced_timer.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/advanced_timer.py b/examples/advanced_timer.py index 6551a6a4..5506a6de 100644 --- a/examples/advanced_timer.py +++ b/examples/advanced_timer.py @@ -28,10 +28,10 @@ def onAnimateEndEvent(self, event): step_time = records['solve']['Mechanical (meca)']['total_time'] print(f"Step took {step_time:.2f} ms") - nb_iterations = records['solve']['Mechanical (meca)']['StaticSolver::Solve']['nb_iterations'] + nb_iterations = records['solve']['Mechanical (meca)']['NewtonStep']['StaticSolver::Solve']['nb_iterations'] for i in range(int(nb_iterations)): - total_time = records['solve']['Mechanical (meca)']['StaticSolver::Solve']['NewtonStep'][i]['total_time'] - CG_iterations = records['solve']['Mechanical (meca)']['StaticSolver::Solve']['NewtonStep'][i]['MBKSolve']['CG iterations'] + total_time = records['solve']['Mechanical (meca)']['NewtonStep']['StaticSolver::Solve'][i]['total_time'] + CG_iterations = records['solve']['Mechanical (meca)']['NewtonStep']['StaticSolver::Solve'][i]['MBKSolve']['CG iterations'] print(f" Newton iteration #{i} took {total_time:.2f} ms using {int(CG_iterations)} CG iterations") if not self.use_sofa_profiler_timer: @@ -70,7 +70,8 @@ def createScene(root): # Create our mechanical node root.addChild("meca") - root.meca.addObject("StaticSolver", newton_iterations=5, printLog=False) + root.meca.addObject("NewtonRaphsonSolver", name="newtonSolver_springs", maxNbIterationsNewton=5, maxNbIterationsLineSearch=1, warnWhenLineSearchFails=False, printLog=False) + root.meca.addObject("StaticSolver", newtonSolver="@newtonSolver_springs") root.meca.addObject("CGLinearSolver", iterations=25, tolerance=1e-5, threshold=1e-5) root.meca.addObject('MechanicalObject', name='mo', position='@../grid.position') From 2110c52923ed87ea4eaa3ee8686edaeb5ab4da9d Mon Sep 17 00:00:00 2001 From: hugtalbot Date: Tue, 16 Sep 2025 20:10:03 +0200 Subject: [PATCH 2/3] fix timer end --- examples/advanced_timer.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/advanced_timer.py b/examples/advanced_timer.py index 5506a6de..a7c13f0e 100644 --- a/examples/advanced_timer.py +++ b/examples/advanced_timer.py @@ -34,7 +34,9 @@ def onAnimateEndEvent(self, event): CG_iterations = records['solve']['Mechanical (meca)']['NewtonStep']['StaticSolver::Solve'][i]['MBKSolve']['CG iterations'] print(f" Newton iteration #{i} took {total_time:.2f} ms using {int(CG_iterations)} CG iterations") - if not self.use_sofa_profiler_timer: + if self.use_sofa_profiler_timer: + Timer.end("Animate") + else: Timer.end("cg_timer") From 019930de6cc14e1e0b455830070e903405028b88 Mon Sep 17 00:00:00 2001 From: hugtalbot Date: Sun, 14 Dec 2025 14:52:31 +0100 Subject: [PATCH 3/3] fix all warnings, remove the timer Animate and the associated option self.use_sofa_profiler_timer, add a dump_records function --- examples/advanced_timer.py | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/examples/advanced_timer.py b/examples/advanced_timer.py index a7c13f0e..b9bb8b59 100644 --- a/examples/advanced_timer.py +++ b/examples/advanced_timer.py @@ -3,41 +3,41 @@ from SofaRuntime import Timer +def dump_records(records, indent=0): + for k, v in records.items(): + if isinstance(v, dict): + print(" " * indent + f"- {k}") + dump_records(v, indent + 1) + else: + print(" " * indent + f"- {k}: {v}") + # This controller will extract the timer records from the simulation at each steps class TimerController(Sofa.Core.Controller): def __init__(self, *args, **kwargs): Sofa.Core.Controller.__init__(self, *args, **kwargs) - # This is needed to avoid a conflict with the timer of runSofa - self.use_sofa_profiler_timer = False - def onAnimateBeginEvent(self, event): - if len(Timer.getRecords('Animate')): - self.use_sofa_profiler_timer = True - else: - Timer.setEnabled("cg_timer", True) - Timer.begin("cg_timer") + Timer.setEnabled("timer", True) + Timer.begin("timer") def onAnimateEndEvent(self, event): - if self.use_sofa_profiler_timer: - records = Timer.getRecords("Animate") - else: - records = Timer.getRecords("cg_timer") - + records = Timer.getRecords("timer") + + # Optional function to dump the full record + # dump_records(records) + step_time = records['solve']['Mechanical (meca)']['total_time'] print(f"Step took {step_time:.2f} ms") - nb_iterations = records['solve']['Mechanical (meca)']['NewtonStep']['StaticSolver::Solve']['nb_iterations'] - for i in range(int(nb_iterations)): - total_time = records['solve']['Mechanical (meca)']['NewtonStep']['StaticSolver::Solve'][i]['total_time'] - CG_iterations = records['solve']['Mechanical (meca)']['NewtonStep']['StaticSolver::Solve'][i]['MBKSolve']['CG iterations'] + nb_iterations = int(records['solve']['Mechanical (meca)']['StaticSolver::Solve']['nb_iterations']) + + for i in range(nb_iterations): + total_time = records['solve']['Mechanical (meca)']['StaticSolver::Solve']['NewtonStep'][i]['total_time'] + CG_iterations = records['solve']['Mechanical (meca)']['StaticSolver::Solve']['NewtonStep'][i]['MBKSolve']['CG iterations'] print(f" Newton iteration #{i} took {total_time:.2f} ms using {int(CG_iterations)} CG iterations") - if self.use_sofa_profiler_timer: - Timer.end("Animate") - else: - Timer.end("cg_timer") + Timer.end("timer") # Scene creation - This is automatically called by SofaPython3 when using runSofa