Note
Go to the end to download the full example code.
Profiling the code
Using PatchMesher to model a quarter of the plate
# sphinx_gallery_thumbnail_path = '_static/profiler.png'
SPARSE = False
import math
import sys
import numpy as np
from femedu.examples import Example
from femedu.domain import System, Node
from femedu.solver import NewtonRaphsonSolver, SparseSolver
from femedu.elements.linear import Triangle
from femedu.materials import PlaneStress
from femedu.mesher import *
class ExamplePlate14(Example):
def problem(self):
# ========== setting mesh parameters ==============
Nx = 60 # number of elements in the mesh
Ny = 40 # number of elements in the mesh
Lx = 120.0 # length of plate in the x-direction
Ly = 80.0 # length of plate in the y-direction
R = Ly / 2.
# ========== setting material parameters ==============
params = dict(
E = 200., # Young's modulus
nu = 0.450, # Poisson's ratio
t = 1.00 # thickness of the plate
)
# ========== setting load parameters ==============
px = 20.0 # uniform load normal to x=const
py = 0.0 # uniform load normal to y=const
pxy = 0.0 # uniform shear load on x=const and y=const
# ========== setting analysis parameters ==============
target_load_level = 1.00 # reference load
max_steps = 2 # number of load steps: 2 -> [0.0, 1.0]
# define a list of target load levels
load_levels = np.linspace(0, target_load_level, max_steps)
#
# ==== Build the system model ====
#
model = System()
if SPARSE:
model.setSolver(SparseSolver())
else:
model.setSolver(NewtonRaphsonSolver())
# create nodes
# 3---------2
# | |
# | |
# | |
# 1---------1
pts = (
( 0, 0),
(Lx, 0),
(Lx, Ly),
(0, Ly),
)
mesher = PatchMesher(model, pts[0], pts[1], pts[2], pts[3])
nodes, elements = mesher.triangleMesh(Nx, Ny, Triangle, PlaneStress(params))
# define support(s)
## find nodes at y==0 and x==0
for node in nodes:
X = node.getPos()
if math.isclose(X[0], 0.0):
node.fixDOF('ux') # horizontal support left side
if math.isclose(X[1], 0.0):
node.fixDOF('uy') # vertical support at y==0
# ==== build the reference load ====
# the section at the right end
for elem, face in model.findFacesAlongLine((Lx, 0.0), (0.0, 1.0), orientation=+1):
print('+', elem.getID(), face.id, ":", face.area)
face.setLoad(px, pxy)
model.plot(factor=0, title="undeformed system", filename="plate14_undeformed.png", show_bc=1, show_loads=1)
model.setLoadFactor(1.0)
model.solve()
#model.plot(factor=1., filename="plate14_deformed.png")
#model.solver.showKt(filename="plate14_spy_Kt.png")
#np.save("plate14_Kt.npy",model.solver.Kt)
Run the example by creating an instance of the problem and executing it by calling Example.run()
This time, we are running the example in the profiler, writing profiling data to file.
import cProfile
ex = ExamplePlate14()
if SPARSE:
cProfile.run('ex.run()','profile_data_sparse.txt')
else:
cProfile.run('ex.run()','profile_data_full.txt')

+ Elem_1082 1082.2 : [[2 0]]
+ Elem_1202 1202.2 : [[2 0]]
+ Elem_1322 1322.2 : [[2 0]]
+ Elem_1442 1442.2 : [[2 0]]
+ Elem_1562 1562.2 : [[2 0]]
+ Elem_1682 1682.2 : [[2 0]]
+ Elem_1802 1802.2 : [[2 0]]
+ Elem_1922 1922.2 : [[2 0]]
+ Elem_2042 2042.2 : [[2 0]]
+ Elem_2162 2162.2 : [[2 0]]
+ Elem_2282 2282.2 : [[2 0]]
+ Elem_2402 2402.2 : [[2 0]]
+ Elem_2522 2522.2 : [[2 0]]
+ Elem_2642 2642.2 : [[2 0]]
+ Elem_2762 2762.2 : [[2 0]]
+ Elem_2882 2882.2 : [[2 0]]
+ Elem_3002 3002.2 : [[2 0]]
+ Elem_3122 3122.2 : [[2 0]]
+ Elem_3242 3242.2 : [[2 0]]
+ Elem_3362 3362.2 : [[2 0]]
+ Elem_3482 3482.2 : [[2 0]]
+ Elem_3602 3602.2 : [[2 0]]
+ Elem_3722 3722.2 : [[2 0]]
+ Elem_3842 3842.2 : [[2 -1.42109e-14]]
+ Elem_3962 3962.2 : [[2 1.42109e-14]]
+ Elem_4082 4082.2 : [[2 0]]
+ Elem_4202 4202.2 : [[2 0]]
+ Elem_4322 4322.2 : [[2 0]]
+ Elem_4442 4442.2 : [[2 0]]
+ Elem_4562 4562.2 : [[2 0]]
+ Elem_4682 4682.2 : [[2 0]]
+ Elem_4802 4802.2 : [[2 0]]
+ Elem_4922 4922.2 : [[2 1.42109e-14]]
+ Elem_5042 5042.2 : [[2 -1.42109e-14]]
+ Elem_5162 5162.2 : [[2 0]]
+ Elem_5282 5282.2 : [[2 0]]
+ Elem_5402 5402.2 : [[2 0]]
+ Elem_5522 5522.2 : [[2 0]]
+ Elem_5642 5642.2 : [[2 0]]
+ Elem_5762 5762.2 : [[2 0]]
+
Now it’s time to process the profiling data
import pstats
from pstats import SortKey
if SPARSE:
p = pstats.Stats('profile_data_sparse.txt')
p.strip_dirs() #.sort_stats(-1).print_stats()
p.sort_stats(SortKey.NAME)
#p.print_stats()
p.sort_stats(SortKey.CUMULATIVE).print_stats(20)
p.sort_stats(SortKey.TIME).print_stats(20)
else:
p = pstats.Stats('profile_data_full.txt')
p.strip_dirs() #.sort_stats(-1).print_stats()
p.sort_stats(SortKey.NAME)
#p.print_stats()
p.sort_stats(SortKey.CUMULATIVE).print_stats(20)
p.sort_stats(SortKey.TIME).print_stats(20)
Thu Feb 20 17:24:57 2025 profile_data_full.txt
21646815 function calls (20989348 primitive calls) in 8.010 seconds
Ordered by: cumulative time
List reduced from 1350 to 20 due to restriction <20>
ncalls tottime percall cumtime percall filename:lineno(function)
5 0.000 0.000 4.778 0.956 NewtonRaphsonSolver.py:111(assemble)
5 0.405 0.081 4.778 0.956 Solver.py:166(assemble)
1 0.000 0.000 4.624 4.624 System.py:504(solve)
1 0.000 0.000 4.624 4.624 NewtonRaphsonSolver.py:13(solve)
35/3 0.006 0.000 3.247 1.082 text.py:358(_get_layout)
43200 1.201 0.000 2.903 0.000 Triangle.py:80(updateState)
81/7 0.000 0.000 2.274 0.325 text.py:65(_get_text_metrics_with_cache)
9/4 0.000 0.000 2.274 0.569 text.py:73(_get_text_metrics_with_cache_impl)
10/4 0.008 0.001 2.273 0.568 backend_agg.py:206(get_text_width_height_descent)
2 0.000 0.000 2.147 1.073 Solver.py:395(checkResiduum)
24000 0.052 0.000 1.809 0.000 Element.py:271(getForce)
19200 0.072 0.000 1.770 0.000 Element.py:348(getStiffness)
49/2 0.000 0.000 1.754 0.877 text.py:926(get_window_extent)
72000 0.270 0.000 1.158 0.000 Triangle.py:159(computeSurfaceLoads)
663450/182418 0.375 0.000 0.873 0.000 copy.py:119(deepcopy)
4902 0.009 0.000 0.852 0.000 _axes.py:1532(plot)
216000 0.312 0.000 0.682 0.000 Face2D.py:54(computeNodalForces)
28800 0.046 0.000 0.656 0.000 Element.py:286(getLoad)
14706 0.036 0.000 0.611 0.000 lines.py:744(draw)
1 0.036 0.036 0.540 0.540 Solver.py:454(getNodalReactions)
Thu Feb 20 17:24:57 2025 profile_data_full.txt
21646815 function calls (20989348 primitive calls) in 8.010 seconds
Ordered by: internal time
List reduced from 1350 to 20 due to restriction <20>
ncalls tottime percall cumtime percall filename:lineno(function)
43200 1.201 0.000 2.903 0.000 Triangle.py:80(updateState)
5 0.405 0.081 4.778 0.956 Solver.py:166(assemble)
663450/182418 0.375 0.000 0.873 0.000 copy.py:119(deepcopy)
302400 0.340 0.000 0.431 0.000 numeric.py:876(outer)
1 0.327 0.327 0.327 0.327 _linalg.py:320(solve)
1150018 0.320 0.000 0.320 0.000 {built-in method numpy.array}
216000 0.312 0.000 0.682 0.000 Face2D.py:54(computeNodalForces)
72000 0.270 0.000 1.158 0.000 Triangle.py:159(computeSurfaceLoads)
9806 0.248 0.000 0.406 0.000 backend_agg.py:93(draw_path)
192082 0.206 0.000 0.468 0.000 Node.py:455(getDeformedPos)
43201 0.192 0.000 0.270 0.000 PlaneStress.py:28(updateState)
192490 0.161 0.000 0.251 0.000 Node.py:341(getDisp)
244800 0.158 0.000 0.210 0.000 Node.py:506(getIdx4Element)
218462 0.143 0.000 0.193 0.000 numeric.py:64(zeros_like)
1784484 0.112 0.000 0.112 0.000 {method 'append' of 'list' objects}
470592 0.111 0.000 0.158 0.000 copy.py:232(_keep_alive)
68760/34414 0.087 0.000 0.176 0.000 transforms.py:2431(get_affine)
39338 0.084 0.000 0.094 0.000 __init__.py:65(check_isinstance)
1300467 0.082 0.000 0.094 0.000 {built-in method builtins.isinstance}
14400 0.076 0.000 0.076 0.000 {method 'index' of 'list' objects}
Total running time of the script: (0 minutes 7.957 seconds)