def test_numpyvector(): """ Test correct exchange of numpy arrays to C++ side. """ from dune.generator.algorithm import run x = array([0.] * 100) run("run", StringIO(runVec), x) for i in range(len(x)): assert x[i] == float(i)
def test_class_export(): from dune.generator.importclass import load from dune.generator.algorithm import run from dune.generator import path from dune.typeregistry import generateTypeName cls = load("MyClassA",StringIO(classACode),10,20) assert run("run",StringIO(runCode),cls) == 10*20 clsName,includes = generateTypeName("MyClassB",cls) cls = load(clsName,StringIO(classBCode),cls,2) assert run("run",StringIO(runCode),cls) == 10**2*20**2
def test_class_export(): from dune.generator.importclass import load from dune.generator.algorithm import run from dune.typeregistry import generateTypeName a = 2. x = array([2.] * 10) cls = load("MyClassA", StringIO(classACode), 10, 20) assert run("run", StringIO(runCode), cls) == 10 * 20 clsName, _ = generateTypeName("MyClassB", cls) cls = load(clsName, StringIO(classBCode), cls, 2, x) assert run("run", StringIO(runCode), cls) == 10**2 * 10 * a x[:] = array([3.] * 10)[:] assert run("run", StringIO(runCode), cls) == 10**2 * 10 * 3 # the following does not work x = array([4.] * 10) # the 'B' class still keeps the old vector 'x' alive assert run("run", StringIO(runCode), cls) == 10**2 * 10 * 3
def dfAssign(self, other): """ assign dofs of other discrete function to self Args: self: discrete function other: other discrete function """ try: # try natural, when dof vectors match # (which is slightly more than df's match) self.dofVector.assign(other.dofVector) except: # this is the case when storage is different import io from dune.generator import algorithm _assignCode = \ """ template <class A, class B> void assignDF( A& a, const B& b ) { a.assign( b ); } """ algorithm.run('assignDF', io.StringIO(_assignCode), self, other)
grid.size(0), sum(estimate.dofVector), hTol, "# timestep", flush=True) plot(solution[1], figsize=(15, 4)) saveStep += 100 # <markdowncell> # Postprocessing # Show solution along a given line # <codecell> x0 = FieldVector([0.25, 0.65]) x1 = FieldVector([0.775, 0.39]) p, v = algorithm.run('sample', 'utility.hh', solution, x0, x1, 1000) from matplotlib import pyplot import numpy x = numpy.zeros(len(p)) y = numpy.zeros(len(p)) l = (x1 - x0).two_norm for i in range(len(x)): x[i] = (p[i] - x0).two_norm / l y[i] = v[i][1] pyplot.plot(x, y) pyplot.show() # <markdowncell>
# <markdowncell> # Instead of plotting this using paraview we want to only study the # solution along a single line. This requires findings points # $x_i = x_0+\frac{i}{N}(x1-x0)$ for $i=0,\dots,N$ within the unstructured # grid. This would be expensive to compute on the Python so we implement # this algorithm in C++ using the `LineSegmentSampler` class available in # `Dune-Fem`. The resulting `algorithm` returns a pair of two lists with # coordinates $x_i$ and the values of the grid function at these points: # # .. literalinclude:: utility.hh # # <codecell> import dune.generator.algorithm as algorithm from dune.common import FieldVector x0, x1 = FieldVector([0, 0, 0]), FieldVector([0, 0, 1]) p, v = algorithm.run('sample', 'utility.hh', uh3d, x0, x1, 100) x, y = numpy.zeros(len(p)), numpy.zeros(len(p)) length = (x1 - x0).two_norm for i in range(len(x)): x[i] = (p[i] - x0).two_norm / length y[i] = v[i][0] pyplot.plot(x, y) pyplot.show() # <markdowncell> # **Note**: the coordinates returned are always in the interval $[0,1]$ so # if physical coordinates are required, they need to be rescaled. # Also, function values returned by the `sample` function # are always of a `FieldVector` type, so that even for a scalar example # a `v[i]` is a vector of dimension one, so that `y[i]=v[i][0]` has to be # used.
w = spc.interpolate([0],name="tmp") op(uh, w) dgError = [ math.sqrt( integrate(grid,(uh[0]-exact[0])**2,order=7) ), math.sqrt( integrate(grid,inner(grad(uh[0]-exact[0]),grad(uh[0]-exact[0])),order=7)\ + w.scalarProductDofs(uh)) ] l2Errors = [dgError[0]] h1Errors = [dgError[1]] zh = spc.interpolate([0],name="dual_h") dualOp = create.scheme("galerkin", [adjoint(a)==0], spc, solver="cg", parameters={"newton." + k: v for k, v in newtonParameter.items()}) pointFunctional = spc.interpolate([0],name="pointFunctional") point = FieldVector([0.6,0.4]) errors = [ expression2GF(grid, exact-s, reconOrder) for s in solutions ] dualErrors = algorithm.run('pointFunctional', 'pointfunctional.hh', point, pointFunctional, *errors) dualOp.solve(target=zh, rhs=pointFunctional) dualWeight.project(zh-zh) for i in range(levels): if error[2][useEstimate] < tolerance: print("COMPLETED:",error[2][useEstimate],"<",tolerance) break marked = mark(estimate, error[2][useEstimate]/grid.size(0)) print("elements marked:", marked,"/",grid.size(0),flush=True) if sum(marked)==0: break adapt(uh) loadBalance(uh) level += 1 _, solutions, error = compute(uh)
gamma = delta/oldDelta d *= gamma d += r velocity.plot(colorbar="horizontal") ############################################################### # Note: the models are virtualize so op.model().nu() will not work on the C++ side # so we either need to 'devirtualize' or pass in nu,mu from dune.generator import algorithm velocity = spcU.interpolate([0,]*spcU.dimRange, name="velocity") pressure = spcP.interpolate([0], name="pressure") # get main forcing and set constraints mainOp(velocity,rhsVelo) rhsVelo *= -1 G(pressure,xi) rhsVelo -= xi mainOp.setConstraints(rhsVelo) mainOp.setConstraints(velocity) uzawa = algorithm.run('uzawa', 'uzawa.hh', mainOp.model.nu,mainOp.model.mu, mainOp, G, D, Ainv, Minv, Pinv, rhsVelo, xi, rhsPress, r, d, precon, velocity, pressure) fig = pyplot.figure(figsize=(20,10)) velocity.plot(colorbar="horizontal", figure=(fig, 121)) pressure.plot(colorbar="horizontal", figure=(fig, 122)) pyplot.show()