|
| 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