예제 #1
0
    def pointSample(self, x0):
        from dune.generator import algorithm, path
        from dune.common import FieldVector
        import numpy
        x0 = FieldVector(x0)
        if self.pointSampler is None:
            import io
            _pointSampleCode = \
            """
            #ifndef FEMPY_UTILITY_HH
            #define FEMPY_UTILITY_HH
            #include <dune/fem/misc/linesegmentsampler.hh>
            #include <dune/fem/gridpart/common/entitysearch.hh>
            #include <dune/fem/function/localfunction/const.hh>

            template <class GF, class DT>
            typename GF::RangeType sample(const GF &gf, DT &point)
            {
              typedef typename GF::DiscreteFunctionSpaceType::GridPartType GridPartType;
              Dune::Fem::EntitySearch<GridPartType> search(gf.space().gridPart());
              const auto &entity = search(point);
              const auto localPoint = entity.geometry().local(point);
              return constLocalFunction(gf,entity).evaluate(localPoint);
            }
            #endif // FEMPY_UTILITY_HH

            """
            self.pointSampler = algorithm.load('sample',
                                               io.StringIO(_pointSampleCode),
                                               self.gridFunction, x0)

        v = self.pointSampler(self.gridFunction, x0)
        return v
예제 #2
0
def testCppQuad(view, rules, error):
    algo = algorithm.load('l2norm2', io.StringIO(code), view, rules, error)
    start = time.time()
    l2norm2 = algo(view, rules, error)
    # print("C++:",math.sqrt(l2norm2),flush=True)
    # print("time used:", round(time.time()-start,2),flush=True)
    return l2norm2
예제 #3
0
    def lineSample(self, x0, x1, N):
        from dune.generator import algorithm, path
        from dune.common import FieldVector
        import numpy
        x0, x1 = FieldVector(x0), FieldVector(x1)
        if self.lineSampler is None:
            import io
            _lineSampleCode = \
            """
            #ifndef FEMPY_UTILITY_HH
            #define FEMPY_UTILITY_HH
            #include <vector>
            #include <utility>
            #include <dune/fem/misc/linesegmentsampler.hh>
            #include <dune/fem/gridpart/common/entitysearch.hh>
            #include <dune/fem/function/localfunction/const.hh>

            template <class GF, class DT>
            std::pair<std::vector<DT>, std::vector<typename GF::RangeType>>
            sample(const GF &gf, DT &start, DT &end, int n)
            {
              Dune::Fem::LineSegmentSampler<typename GF::GridPartType> sampler(gf.gridPart(),start,end);
              std::vector<DT> coords(n);
              std::vector<typename GF::RangeType> values(n);
              sampler(gf,values);
              sampler.samplePoints(coords);
              return std::make_pair(coords,values);
            }
            #endif

            """
            self.lineSampler = algorithm.load('sample',
                                              io.StringIO(_lineSampleCode),
                                              self.gridFunction, x0, x1, N)

        p, v = self.lineSampler(self.gridFunction, x0, x1, N)
        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]
        return x, y
예제 #4
0
#
# <codecell>

from dune.fem.scheme import galerkin as solutionScheme
spaceZ = solutionSpace(uh.space.grid, order=order + 1)
u = TrialFunction(spaceZ)
v = TestFunction(spaceZ)
x = SpatialCoordinate(spaceZ)
a = dot(grad(u), grad(v)) * dx
dual = solutionScheme([a == 0, DirichletBC(spaceZ, 0)], solver="cg")
z = spaceZ.interpolate(0, name="dual")
zh = uh.copy(name="dual_h")
point = common.FieldVector([0.4, 0.4])
pointFunctional = z.copy("dual_rhs")
eh = expression2GF(uh.space.grid, abs(exact - uh), order=order + 1)
computeFunctional = algorithm.load("pointFunctional", "laplace-dwr.hh", point,
                                   pointFunctional, eh)

# <markdowncell>
# <codecell>

from dune.fem.space import finiteVolume as estimatorSpace
from dune.fem.operator import galerkin as estimatorOp

fvspace = estimatorSpace(uh.space.grid)
estimate = fvspace.interpolate([0], name="estimate")

u = TrialFunction(uh.space.as_ufl())
v = TestFunction(fvspace)
n = FacetNormal(fvspace.cell())
estimator_ufl = abs(div(grad(u)))*abs(z-zh) * v * dx +\
                abs(inner(jump(grad(u)), n('+')))*abs(avg(z-zh)) * avg(v) * dS
예제 #5
0
# computed using an algorithm implemented in C++ otherwise the computation
# is done in Python.
# <codecell>
def calcRadius(surface):
    R, vol = 0, 0
    for e in surface.elements:
        rule = geometry.quadratureRule(e.type, 4)
        for p in rule:
            geo = e.geometry
            weight = geo.volume * p.weight
            R += geo.toGlobal(p.position).two_norm * weight
            vol += weight
    return R / vol

switchCalcRadius = lambda use_cpp,surface: \
             algorithm.load('calcRadius', 'radius.hh', surface) \
             if use_cpp else calcRadius

# <markdowncell>
# Timings for a number of different grid refinements is dumped to disk
# <codecell>
from dune.fem.view import geometryGridView as geoGridView
from dune.fem.space import lagrange as solutionSpace
from dune.fem.scheme import galerkin as solutionScheme


def calculate(use_cpp, gridView):
    # space on Gamma_0 to describe position of Gamma(t)
    space = solutionSpace(gridView, dimRange=gridView.dimWorld, order=order)
    u = TrialFunction(space)
    v = TestFunction(space)
예제 #6
0
rules = dune.geometry.quadratureRules(5)

if False:  # dune.fem type grid functions don't yet have vectorization support
    start = time.time()
    l2norm2 = 0
    for e in yaspView.elements:
        hatxs, hatws = rules(e.type).get()
        weights = hatws * e.geometry.integrationElement(hatxs)
        l2norm2 += numpy.sum(error(e, hatxs)**2 * weights, axis=-1)
    print("Python:", math.sqrt(l2norm2), flush=True)
    print("time used:", round(time.time() - start, 2), flush=True)

if True:
    #algo = algorithm.load('l2norm2', 'test_quad.hh', yaspView, rules, error)
    algo = algorithm.load('l2norm2FemQuad', 'test_quad.hpp', yaspView, rules,
                          error)
    start = time.time()
    l2norm2 = algo(yaspView, rules, error)
    print("C++:", math.sqrt(l2norm2), flush=True)
    print("time used:", round(time.time() - start, 2), flush=True)

try:
    import dune.geometry.quadpy as quadpy
    rules = quadpy.rules({dune.geometry.quadrilateral: ("C2 7-2", "Stroud")})

    if False:
        start = time.time()
        l2norm2 = 0
        for e in yaspView.elements:
            hatxs, hatws = rules(e.type).get()
            weights = hatws * e.geometry.integrationElement(hatxs)
예제 #7
0
std::string callVector(const std::vector<GridViewFunction> & f)
{
    return "vector<GridViewFunction<GV>>";
}
"""


class CppTypeInfo:
    def __init__(self, name, includes):
        self.cppTypeName = name
        self.cppIncludes = includes


scalarTypeName = "GridViewFunction"
vectorTypeName = "std::vector<GridViewFunction>"
callScalar = algorithm.load('callScalar', io.StringIO(code),
                            CppTypeInfo(scalarTypeName, []))
callVector = algorithm.load('callVector', io.StringIO(code),
                            CppTypeInfo(vectorTypeName, []))

# number of grid elements (in one direction)
gridSize = 4

# create a YaspGrid of the unit square
domain = cartesianDomain([0, 0], [1, 1], [gridSize, gridSize])
grid = yaspGrid(domain, dimgrid=2)

# create a nodal Lagrange FE basis of order 1 and order 2
basis1 = dune.functions.defaultGlobalBasis(grid,
                                           dune.functions.Lagrange(order=1))
basis2 = dune.functions.defaultGlobalBasis(grid,
                                           dune.functions.Lagrange(order=2))