I've added some timings in the sandbox repository with the following results:
Direct iteration: 7.23 Create boundary: 34.27 Iteration over boundary: 0.03 This means direct iteration over facets (and skipping interior facets) is faster than boundary extraction + iteration over boundary. I've modified Assembler (not SystemAssembler) to not use BoundaryMesh. -- Anders
--- Begin Message --------------------------------------------------------------- revno: 4575 committer: Anders Logg <l...@simula.no> branch nick: dolfin-dev timestamp: Fri 2010-02-26 13:59:05 +0100 message: Speedup assembly over exterior facets by not using BoundaryMesh modified: ChangeLog dolfin/fem/Assembler.cpp -- lp:dolfin https://code.launchpad.net/~dolfin-core/dolfin/main Your team DOLFIN Core Team is subscribed to branch lp:dolfin. To unsubscribe from this branch go to https://code.launchpad.net/~dolfin-core/dolfin/main/+edit-subscription.=== modified file 'ChangeLog' --- ChangeLog 2010-02-26 11:00:54 +0000 +++ ChangeLog 2010-02-26 12:59:05 +0000 @@ -1,3 +1,4 @@ + - Speedup assembly over exterior facets by not using BoundaryMesh - Mesh refinement improvements, remove unecessary copying in Python interface - Clean PETSc and Epetra Krylov solvers - Add separate preconditioner classes for PETSc and Epetra solvers === modified file 'dolfin/fem/Assembler.cpp' --- dolfin/fem/Assembler.cpp 2010-02-17 14:34:42 +0000 +++ dolfin/fem/Assembler.cpp 2010-02-26 12:59:05 +0000 @@ -6,7 +6,7 @@ // Modified by Kent-Andre Mardal, 2008 // // First added: 2007-01-17 -// Last changed: 2010-02-17 +// Last changed: 2010-02-26 #include <dolfin/log/dolfin_log.h> #include <dolfin/common/Timer.h> @@ -15,7 +15,6 @@ #include <dolfin/mesh/Cell.h> #include <dolfin/mesh/Facet.h> #include <dolfin/mesh/MeshData.h> -#include <dolfin/mesh/BoundaryMesh.h> #include <dolfin/mesh/MeshFunction.h> #include <dolfin/mesh/SubDomain.h> #include <dolfin/function/GenericFunction.h> @@ -136,6 +135,8 @@ Progress p(AssemblerTools::progress_message(A.rank(), "cells"), mesh.num_cells()); for (CellIterator cell(mesh); !cell.end(); ++cell) { + + // Get integral for sub domain (if any) if (domains && domains->size() > 0) { @@ -146,7 +147,7 @@ continue; } - // Skip integral is zero + // Skip integral if zero if (!integral) continue; // Update to current cell @@ -190,43 +191,41 @@ // Exterior facet integral ufc::exterior_facet_integral* integral = ufc.exterior_facet_integrals[0]; - // Create boundary mesh - BoundaryMesh boundary(mesh); - - // Skip assembly if boundary is empty (may happen when running in parallel) - if (boundary.num_cells() == 0) - return; - - // Get mapping from facets (boundary cells) to mesh cells - MeshFunction<uint>* cell_map = boundary.data().mesh_function("cell map"); - assert(cell_map); + // Compute facets and facet - cell connectivity if not already computed + mesh.init(mesh.topology().dim() - 1); + mesh.init(mesh.topology().dim() - 1, mesh.topology().dim()); + assert(mesh.ordered()); // Assemble over exterior facets (the cells of the boundary) - Progress p(AssemblerTools::progress_message(A.rank(), "exterior facets"), boundary.num_cells()); - for (CellIterator boundary_cell(boundary); !boundary_cell.end(); ++boundary_cell) + Progress p(AssemblerTools::progress_message(A.rank(), "exterior facets"), mesh.num_facets()); + for (FacetIterator facet(mesh); !facet.end(); ++facet) { - // Get mesh facet corresponding to boundary cell - Facet mesh_facet(mesh, (*cell_map)[*boundary_cell]); + // Only consider exterior facets + if (facet->interior()) + { + p++; + continue; + } // Get integral for sub domain (if any) if (domains && domains->size() > 0) { - const uint domain = (*domains)[mesh_facet]; + const uint domain = (*domains)[*facet]; if (domain < ufc.form.num_exterior_facet_integrals()) integral = ufc.exterior_facet_integrals[domain]; else continue; } - // Skip integral is zero + // Skip integral if zero if (!integral) continue; // Get mesh cell to which mesh facet belongs (pick first, there is only one) - assert(mesh_facet.num_entities(mesh.topology().dim()) == 1); - Cell mesh_cell(mesh, mesh_facet.entities(mesh.topology().dim())[0]); + assert(facet->num_entities(mesh.topology().dim()) == 1); + Cell mesh_cell(mesh, facet->entities(mesh.topology().dim())[0]); // Get local index of facet with respect to the cell - const uint local_facet = mesh_cell.index(mesh_facet); + const uint local_facet = mesh_cell.index(*facet); // Update to current cell ufc.update(mesh_cell, local_facet); @@ -282,7 +281,7 @@ Progress p(AssemblerTools::progress_message(A.rank(), "interior facets"), mesh.num_facets()); for (FacetIterator facet(mesh); !facet.end(); ++facet) { - // Check if we have an exterior facet or a facet belonging to another process + // Only consider interior facets if (!facet->interior()) { p++; @@ -299,7 +298,7 @@ continue; } - // Skip integral is zero + // Skip integral if zero if (!integral) continue; // Get cells incident with facet
--- End Message ---
signature.asc
Description: Digital signature
_______________________________________________ Mailing list: https://launchpad.net/~dolfin Post to : dolfin@lists.launchpad.net Unsubscribe : https://launchpad.net/~dolfin More help : https://help.launchpad.net/ListHelp