1from __future__ import absolute_import, division, print_function, unicode_literals
2
3import sys,os
4import logging
5logger = logging.getLogger(__name__)
6
7import dune.common.checkconfiguration as checkconfiguration
8import dune.generator
9
10from . import _solvers as solvers
11
12def adaptive():
13    dfType = lambda space: "Dune::Fem::AdaptiveDiscreteFunction< " + space._typeName + " >"
14    rdfType = lambda space,rspace: dfType(space if rspace is None else rspace)
15    return lambda space, rspace=None:[\
16        "fem",\
17        ["dune/fem/function/adaptivefunction.hh","dune/fem/operator/linear/spoperator.hh"] +\
18              space._includes,\
19        dfType(space),\
20        "Dune::Fem::SparseRowLinearOperator< " + dfType(space) + "," +\
21        rdfType(space,rspace) + "," + "Dune::Fem::SparseRowMatrix<" + space.field + ",int>" ">",\
22        solvers.femsolver,\
23        "as_numpy"
24    ]
25
26def eigen():
27    try:
28        checkconfiguration.preprocessorAssert([ ("#if HAVE_EIGEN","Eigen package is not available") ])
29    except checkconfiguration.ConfigurationError as err:
30        print("configuration error while creating a discrete function with storage=eigen exiting...")
31        print("You need to install the `eigen` package and reconfigure dune-py")
32        print("adding -DEigen3_DIR='Path-to-eigen` to the CMAKE_FLAGS")
33        raise
34
35    dfType = lambda space: "Dune::Fem::ManagedDiscreteFunction< Dune::Fem::VectorDiscreteFunction< " +\
36                           space._typeName + ", Dune::Fem::EigenVector< " + space.field + " > > >"
37    rdfType = lambda space,rspace: dfType(space if rspace is None else rspace)
38    return lambda space,rspace=None:[\
39        "eigen",\
40        ["dune/fem/function/vectorfunction/managedvectorfunction.hh",\
41                "dune/fem/storage/eigenvector.hh",\
42                "dune/fem/operator/linear/eigenoperator.hh"] +\
43              space._includes,\
44        dfType(space),\
45        "Dune::Fem::EigenLinearOperator< " + dfType(space) + "," + rdfType(space,rspace) + ">",\
46        solvers.eigensolver,\
47        "as_numpy"
48    ]
49
50def istl():
51    dfType = lambda space: "Dune::Fem::ISTLBlockVectorDiscreteFunction< " + space._typeName + " >"
52    rdfType = lambda space,rspace: dfType(space if rspace is None else rspace)
53    return lambda space,rspace=None:[\
54        "istl",\
55        ["dune/fem/function/blockvectorfunction.hh", "dune/fem/operator/linear/istloperator.hh"] +\
56              space._includes,\
57        dfType(space),\
58        "Dune::Fem::ISTLLinearOperator< " + dfType(space) + "," + rdfType(space,rspace) + ">",
59        solvers.istlsolver,\
60        "as_istl"
61    ]
62
63from dune.common.checkconfiguration import assertHave, ConfigurationError
64try:
65    assertHave("HAVE_PETSC")
66    def petsc():
67        dfType = lambda space: "Dune::Fem::PetscDiscreteFunction< " + space._typeName + " >"
68        rdfType = lambda space,rspace: dfType(space if rspace is None else rspace)
69        def equalSpaces(space,rspace):
70            # if not space==rspace and not rspace is None:
71            #     raise NotImplementedError("Operator with petsc storage only with equal domain and range spaces implemented")
72            return "Dune::Fem::PetscLinearOperator< " + dfType(space) + "," + rdfType(space,rspace) + ">"
73        try:
74            import petsc4py
75            return lambda space, rspace=None:[\
76                "petsc",\
77                ["dune/fem/function/petscdiscretefunction.hh", "dune/fem/operator/linear/petscoperator.hh"] +\
78                      [os.path.dirname(petsc4py.__file__)+"/include/petsc4py/petsc4py.h"] +\
79                      space._includes,\
80                dfType(space),\
81                equalSpaces(space,rspace),\
82                solvers.petscsolver,\
83                "as_petsc"
84            ]
85        except:
86            return lambda space,rspace=None:[\
87                "petsc",\
88                ["dune/fem/function/petscdiscretefunction.hh", "dune/fem/operator/linear/petscoperator.hh"] +\
89                      space._includes,\
90                dfType(space),\
91                equalSpaces(space,rspace),\
92                solvers.petscsolver,\
93                "as_petsc"
94            ]
95
96    def petscadapt():
97        dfType = lambda space: "Dune::Fem::AdaptiveDiscreteFunction< " + space._typeName + " >"
98        rdfType = lambda space,rspace: dfType(space if rspace is None else rspace)
99        def equalSpaces(space,rspace):
100            if not space==rspace and not rspace is None:
101                raise NotImplementedError("Operator with petsc storage only with equal domain and range spaces implemented")
102            return "Dune::Fem::PetscLinearOperator< " + dfType(space) + "," + rdfType(space,rspace) + ">"
103        return lambda space,rspace=None:[\
104            "petscadapt",\
105            ["dune/fem/function/adaptivefunction.hh", "dune/fem/operator/linear/petscoperator.hh"] +\
106                  space._includes,\
107            dfType(space),\
108            equalSpaces(space,rspace),\
109            solvers.petscsolver,\
110            "as_numpy"
111        ]
112except ConfigurationError:
113    def petsc():
114        raise ConfigurationError("petsc has not been found during configuration of dune - please add the path to petsc to the DUNE_CMAKE_FLAGS")
115    def petscadapt():
116        raise ConfigurationError("petsc has not been found during configuration of dune - please add the path to petsc to the DUNE_CMAKE_FLAGS")
117