Skip to content

Commit f2185b3

Browse files
committed
Added notes that trace a solve call
1 parent bab0654 commit f2185b3

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

Notes.md

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Notes
2+
3+
## Example code
4+
5+
```
6+
def poisson():
7+
# Create mesh and define function space
8+
mesh = RectangleMesh.create(MPI.comm_world,
9+
[Point(0, 0), Point(1, 1)], [32, 32],
10+
CellType.Type.triangle, dolfin.cpp.mesh.GhostMode.none)
11+
V = FunctionSpace(mesh, "Lagrange", 1)
12+
13+
cmap = dolfin.fem.create_coordinate_map(mesh.ufl_domain())
14+
mesh.geometry.coord_mapping = cmap
15+
16+
# Define Dirichlet boundary (x = 0 or x = 1)
17+
def boundary(x):
18+
return np.logical_or(x[:, 0] < DOLFIN_EPS, x[:, 0] > 1.0 - DOLFIN_EPS)
19+
20+
# Define boundary condition
21+
u0 = Constant(0.0)
22+
bc = DirichletBC(V, u0, boundary)
23+
24+
# Define variational problem
25+
u = TrialFunction(V)
26+
v = TestFunction(V)
27+
f = Expression("10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)", degree=2)
28+
g = Expression("sin(5*x[0])", degree=2)
29+
a = inner(grad(u), grad(v)) * dx
30+
L = f * v * dx + g * v * ds
31+
32+
# Compute solution
33+
u = Function(V)
34+
form = a == L
35+
solve(form, u, bc, petsc_options={"ksp_type": "preonly", "pc_type": "lu"}, form_compiler_parameters=fcp)
36+
37+
# Save solution in XDMF format
38+
#file = XDMFFile(MPI.comm_world, "poisson.xdmf")
39+
#file.write(u, XDMFFile.Encoding.HDF5)
40+
41+
return
42+
```
43+
44+
## Trace of solve call
45+
46+
**User code:**
47+
- User makes call `solve(form, u, bc, petsc_options={"ksp_type": "preonly", "pc_type": "lu"}, form_compiler_parameters=fcp)`
48+
49+
**Dolfin:**
50+
- `solve` method is in `dolfinx/python/dolfin/fem/solving.py`
51+
- `_solve_varproblem()`
52+
- `a = Form(eq.lhs, ...)` with `Form` constructor in `dolfinx/python/dolfin/fem/form.py`
53+
54+
**FFC:**
55+
- `ufc_form = ffc_jit(...)` which calls `ffc.jit()` in `ffcx/ffc/jitcompiler.py`
56+
- `build()`
57+
58+
**Dijitso:**
59+
- `dijitso.jit()` in `dijitso/dijitso/jit.py`, gets `generate` from `ffcx/ffc/jitcompiler.py` as parameter
60+
61+
**FFC:** (traced only for the bilinear form)
62+
- `generate()` in `ffcx/ffc/jitcompiler.py`
63+
- `compile_form()` in `ffcx/ffc/compiler.py`
64+
- `compile_ufl_objects(forms, "form",...)` in `ffcx/ffc/compiler.py`
65+
1. `analyze_ufl_objects()` in `ffcx/ffc/analysis.py`, already generates integral:
66+
```
67+
weight * |(J[0, 0] * J[1, 1] + -1 * J[0, 1] * J[1, 0])| * (sum_{i_8} ({ A | A_{i_9} = sum_{i_{10}} ({ A | A_{i_{13}, i_{14}} = ([
68+
[J[1, 1], -1 * J[0, 1]],
69+
[-1 * J[1, 0], J[0, 0]]
70+
])[i_{13}, i_{14}] / (J[0, 0] * J[1, 1] + -1 * J[0, 1] * J[1, 0]) })[i_{10}, i_9] * (reference_grad(reference_value(v_0)))[i_{10}] })[i_8] * ({ A | A_{i_{11}} = sum_{i_{12}} ({ A | A_{i_{13}, i_{14}} = ([
71+
[J[1, 1], -1 * J[0, 1]],
72+
[-1 * J[1, 0], J[0, 0]]
73+
])[i_{13}, i_{14}] / (J[0, 0] * J[1, 1] + -1 * J[0, 1] * J[1, 0]) })[i_{12}, i_{11}] * (reference_grad(reference_value(v_1)))[i_{12}] })[i_8] )
74+
```
75+
and corresponding UFL operator "AST"
76+
2. `compute_ir()` in `ffcx/ffc/representation.py`
77+
3. `optimize_ir()` in `ffcx/ffc/optimization.py`
78+
4. `generate_code()` in `ffcx/ffc/codegeneration.py`
79+
- `ufc_integral_generator()` in `ffcx/ffc/backends/ufc/integrals.py` calls `r = pick_representation()` from `ffcx/ffc/representation.py` followed by `r.generate_integral_code(ir,...)`
80+
- Usually `generate_integral_code()` from `ffcx/ffc/uflacs/uflacsgenerator.py`
81+
- `IntegralGenerator.generate()` to generate code AST for `tabulate_tensor`
82+
- `generate()` in `ffcx/ffc/uflacs/integralgenerator.py`
83+
- Calls several AST generation functions, for example `generate_preintegrated_dofblock_partition()`
84+
- `ufc_form_generator()` in `ffcx/ffc/backends/ufc/form.py`
85+
5. `format_code()` in `ffcx/ffc/formatting.py`, this generates the final source and header files for compilation

0 commit comments

Comments
 (0)