Cool! -- Anders
On Sat, May 01, 2010 at 03:27:19PM -0000, [email protected] wrote: > ------------------------------------------------------------ > revno: 14 > committer: Kristian B. Ølgaard <[email protected]> > branch nick: fenics-doc > timestamp: Sat 2010-05-01 17:25:57 +0200 > message: > Added script to check code blocks in the demo directories and fixed some > inconsistencies that the script found. > added: > source/demos/python/pde/poisson/demo.py > verify_code_snippets.py > modified: > source/demos/cpp/pde/cahn-hilliard/cahn-hilliard.rst > source/demos/cpp/pde/poisson/poisson.rst > source/demos/python/pde/cahn-hilliard/cahn-hilliard.rst > source/demos/python/pde/poisson/poisson.rst > > > === modified file 'source/demos/cpp/pde/cahn-hilliard/cahn-hilliard.rst' > --- source/demos/cpp/pde/cahn-hilliard/cahn-hilliard.rst 2010-04-29 > 11:35:24 +0000 > +++ source/demos/cpp/pde/cahn-hilliard/cahn-hilliard.rst 2010-05-01 > 15:25:57 +0000 > @@ -56,47 +56,51 @@ > > .. code-block:: c++ > > - #include <dolfin.h> > - #include "Poisson.h" > + #include <dolfin.h> > + #include "CahnHilliard2D.h" > + #include "CahnHilliard3D.h" > > - using namespace dolfin; > + using namespace dolfin; > > Some more C++ > > .. code-block:: c++ > > - // Source term (right-hand side) > - class Source : public Expression > - { > - void eval(Array<double>& values, const Array<double>& x) const > - { > - double dx = x[0] - 0.5; > - double dy = x[1] - 0.5; > - values[0] = 10*exp(-(dx*dx + dy*dy) / 0.02); > - } > - }; > - > - // Boundary flux (Neumann boundary condition) > - class Flux : public Expression > - { > - void eval(Array<double>& values, const Array<double>& x) const > - { > - values[0] = -sin(5*x[0]); > - } > - }; > + // Initial conditions > + class InitialConditions : public Expression > + { > + public: > + > + InitialConditions(const Mesh& mesh) : Expression(mesh.topology().dim()) > + { > + dolfin::seed(2); > + } > + > + void eval(Array<double>& values, const Data& data) const > + { > + values[0]= 0.0; > + values[1]= 0.63 + 0.02*(0.5 - dolfin::rand()); > + } > + > + }; > > Yet more C++ > > .. code-block:: c++ > > - // Sub domain for Dirichlet boundary condition > - class DirichletBoundary : public SubDomain > + // Solve > + while (t < T) > { > - bool inside(const Array<double>& x, bool on_boundary) const > - { > - return x[0] < DOLFIN_EPS or x[0] > 1.0 - DOLFIN_EPS; > - } > - }; > + // Update for next time step > + t += dt; > + u0.vector() = u.vector(); > + > + // Solve > + newton_solver.solve(cahn_hilliard, u.vector()); > + > + // Save function to file > + file << u[1]; > + } > > All this should be in the same :download:`main.cpp` file. > > > === modified file 'source/demos/cpp/pde/poisson/poisson.rst' > --- source/demos/cpp/pde/poisson/poisson.rst 2010-04-29 11:35:24 +0000 > +++ source/demos/cpp/pde/poisson/poisson.rst 2010-05-01 15:25:57 +0000 > @@ -24,7 +24,7 @@ > g = Coefficient(element) > > a = inner(grad(v), grad(u))*dx > - L = v*f*dx + v*h*ds > + L = v*f*dx + v*g*ds > > > Some C++ > > === modified file 'source/demos/python/pde/cahn-hilliard/cahn-hilliard.rst' > --- source/demos/python/pde/cahn-hilliard/cahn-hilliard.rst 2010-04-29 > 11:35:24 +0000 > +++ source/demos/python/pde/cahn-hilliard/cahn-hilliard.rst 2010-05-01 > 15:25:57 +0000 > @@ -10,3 +10,6 @@ > .. include:: ../../../common/pde/cahn-hilliard/cahn-hilliard.txt > > This text is Python specific > + > + > + > > === added file 'source/demos/python/pde/poisson/demo.py' > --- source/demos/python/pde/poisson/demo.py 1970-01-01 00:00:00 +0000 > +++ source/demos/python/pde/poisson/demo.py 2010-05-01 15:25:57 +0000 > @@ -0,0 +1,51 @@ > +"""This demo program solves Poisson's equation > + > + - div grad u(x, y) = f(x, y) > + > +on the unit square with source f given by > + > + f(x, y) = 10*exp(-((x - 0.5)^2 + (y - 0.5)^2) / 0.02) > + > +and boundary conditions given by > + > + u(x, y) = 0 for x = 0 or x = 1 > +du/dn(x, y) = -sin(5*x) for y = 0 or y = 1 > +""" > + > +__author__ = "Anders Logg ([email protected])" > +__date__ = "2007-08-16 -- 2010-03-05" > +__copyright__ = "Copyright (C) 2007-2009 Anders Logg" > +__license__ = "GNU LGPL Version 2.1" > + > +from dolfin import * > + > +# Create mesh and define function space > +mesh = UnitSquare(32, 32) > +V = FunctionSpace(mesh, "CG", 1) > + > +# Define Dirichlet boundary (x = 0 or x = 1) > +def boundary(x): > + return x[0] < DOLFIN_EPS or x[0] > 1.0 - DOLFIN_EPS > + > +# Define boundary condition > +u0 = Constant(0.0) > +bc = DirichletBC(V, u0, boundary) > + > +# Define variational problem > +v = TestFunction(V) > +u = TrialFunction(V) > +f = Expression("10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)") > +g = Expression("-sin(5*x[0])") > +a = inner(grad(v), grad(u))*dx > +L = v*f*dx + v*g*ds > + > +# Compute solution > +problem = VariationalProblem(a, L, bc) > +u = problem.solve() > + > +# Save solution in VTK format > +file = File("poisson.pvd") > +file << u > + > +# Plot solution > +plot(u, interactive=True) > > === modified file 'source/demos/python/pde/poisson/poisson.rst' > --- source/demos/python/pde/poisson/poisson.rst 2010-04-29 11:35:24 > +0000 > +++ source/demos/python/pde/poisson/poisson.rst 2010-05-01 15:25:57 > +0000 > @@ -9,4 +9,16 @@ > > .. include:: ../../../common/pde/poisson/poisson.txt > > -This text is Python specific > +This text is Python specific. > +Here is a code snippet from the Poisson :download:`demo.py`: > + > +.. code-block:: python > + > + # Define variational problem > + v = TestFunction(V) > + u = TrialFunction(V) > + f = Expression("10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / > 0.02)") > + g = Expression("-sin(5*x[0])") > + a = inner(grad(v), grad(u))*dx > + L = v*f*dx + v*g*ds > + > > === added file 'verify_code_snippets.py' > --- verify_code_snippets.py 1970-01-01 00:00:00 +0000 > +++ verify_code_snippets.py 2010-05-01 15:25:57 +0000 > @@ -0,0 +1,138 @@ > +#!usr/bin/env python > + > +"""This utility script will find all *.rst files in the source/demo > +directory and check that any code snippets highlighted by the .. code-block:: > +directive is legal in the sense that it is present in at least one of the > +source files (.ufl, .py, .cpp) that is associated with the demo.""" > + > +from os import chdir, path, getcwd, curdir, pardir, listdir > +from sys import stderr > + > +# We currently only verifies demo code. > +chdir(path.join("source","demos")) > + > +# Save current location (needed?). > +demo_dir = getcwd() > + > +# We have C++ and Python versions of the demos. > +directories = ["cpp", "python"] > + > +# Dictionary of code blocks that has to be checked for each subdirectory > +# including information about file types of the source. > +block_source = {"cpp": {"c++": ".cpp", "python": ".ufl"}, > + "python": {"python": ".py"} > + } > + > +def verify_blocks(rst_file, source_files, source_dict): > + """Check that any code blocks in the rst file is present in at least one > of > + the source files.""" > + > + for block_type, source_type in source_dict.items(): > + # Extract code blocks from rst file. > + blocks = get_blocks(rst_file, block_type) > + for block in blocks: > + # Check if block is in the list of files of correct type. > + block_in_source(block, [sf for sf in source_files\ > + if path.splitext(sf)[-1] == source_type]) > + > +def get_blocks(rst_file, block_type): > + "Extract any code blocks of given type from the rst file." > + > + blocks = [] > + > + # Open file and read lines. > + f = open(rst_file, "r") > + lines = f.read().split("\n") > + > + code = False > + block = [] > + for l in lines: > + # Get start of code block. > + if "code-block::" in l and block_type in l: > + code = True > + block = [] > + continue > + # The first line which is not an indented line terminates the code > + # block. > + if code and l and l[0] != " ": > + code = False > + # Join the block that we have and add to list of blocks. > + # Remove any whitespace. > + blocks.append(remove_whitespace("\n".join(block))) > + # If code is still True, then the line is part of the code block. > + if code: > + block.append(l) > + > + # Add block of code if found at the end of the rst file. > + if code: > + blocks.append(remove_whitespace("\n".join(block))) > + > + # Close file and return blocks. > + f.close() > + return blocks > + > +def remove_whitespace(code): > + "Remove blank lines and whitespace in front of lines." > + return "\n".join([" ".join(l.split())\ > + for l in code.split("\n") if l != ""]) > + > +def block_in_source(block, source_files): > + """Check that the code block is present in at least one of > + the source files.""" > + > + present = False > + code = "" > + for sf in source_files: > + f = open(sf, "r") > + # Read code and remove whitespace before comparing block and code. > + code = remove_whitespace(f.read()) > + > + if block in code: > + present = True > + f.close() > + > + # If code is present, look no further. > + if present: > + return > + > + # Just crash the test, no need to proceed. We MUST fix the > + if not present: > + if not source_files: > + raise RuntimeError("No source file!") > + > + print "\nError:" > + print "\ncode block:\n", block > + print "\ncode:\n", code > + print "source_files:", source_files > + print "in directory: ", getcwd() > + raise RuntimeError("Illegal code block.") > + > +if __name__ == "__main__": > + > + print "\nTesting that all code snippets are valid.\n" > + # Loop directories/categories/demos > + for directory in directories: > + chdir(directory) > + # Get all demo categories > + categories = [d for d in listdir(curdir) if path.isdir(d)] > + for category in categories: > + chdir(category) > + demos = [d for d in listdir(curdir) if path.isdir(d)] > + for demo in demos: > + chdir(demo) > + stderr.write(" "*2 + path.join(directory, category, demo)) > + # Get files in demo directory and sort in rst and source > files. > + files = listdir(curdir) > + rst_files = [f for f in files if path.splitext(f)[-1] == > ".rst"] > + source_files = [f for f in files if path.splitext(f)[-1] in\ > + (".py", ".ufl", ".cpp")] > + # Loop files, check if code blocks are present in source > files. > + for rst_file in rst_files: > + verify_blocks(rst_file, source_files, > block_source[directory]) > + stderr.write(", " + "OK.\n") > + chdir(pardir) > + chdir(pardir) > + chdir(pardir) > + > + print "\nOK.\n" > + >
signature.asc
Description: Digital signature
_______________________________________________ Mailing list: https://launchpad.net/~fenics Post to : [email protected] Unsubscribe : https://launchpad.net/~fenics More help : https://help.launchpad.net/ListHelp

