def PrintProblemTest(problem): includes = problem._includes + ["test/python/test_boundaryloop.hh"] typeName = "Dumux::Python::PrintProblemTest<{}>".format(problem._typeName) moduleName = moduleName = "printbs_" + hashIt(problem._typeName) generator = SimpleGenerator("PrintProblemTest", "Dumux::Python") module = generator.load(includes, typeName, moduleName) return module.PrintProblemTest(problem)
def module(dim): typeName = "Dune::Geo::ReferenceElement<Dune::Geo::ReferenceElementImplementation<double," + str(dim) + "> >" includes = ["dune/python/geometry/referenceelements.hh"] typeHash = "referenceelements_" + hashIt(typeName) generator = SimpleGenerator("ReferenceElements", "Dune::Python") m = generator.load(includes, typeName, typeHash) return m
def _createPorousMediumFlowVelocityOutput(*, gridVariables): """Create a PorousMediumFlowVelocityOutput""" includes = gridVariables._includes includes += [ "dumux/python/porousmediumflow/velocityoutput.hh", "dumux/io/velocityoutput.hh" ] fluxVarsType = ( f"Dumux::GetPropType<{gridVariables.model.cppType}, Dumux::Properties::FluxVariables>" ) typeName = f"Dumux::PorousMediumFlowVelocityOutput<{gridVariables._typeName}, {fluxVarsType}>" moduleName = "porousmediumflowvelocityoutput_" + hashIt(typeName) baseClass = [f"Dumux::VelocityOutput<{gridVariables._typeName}>"] generator = SimpleGenerator("PorousMediumFlowVelocityOutput", "Dumux::Python") module = generator.load( includes, typeName, moduleName, holder="std::shared_ptr", preamble=gridVariables.model.cppHeader, baseClasses=baseClass, ) return module.PorousMediumFlowVelocityOutput(gridVariables)
def skeleton(interfaceFunction, grid=None): """Return the skeleton representation of a discrete function on the interface grid. Args: interfaceFunction: The discrete function on the interface grid. grid (Grid, optional): The bulk grid. Necessary, if wrapped. Returns: Skeleton representation of given interface function. Note: This function has to be restricted when evaluated on facets, e.g. using avg(skeleton). """ if grid == None: grid = interfaceFunction.space.grid.hierarchicalGrid.bulkGrid includes = ["dune/mmesh/misc/pyskeletontrace.hh"] includes += interfaceFunction._includes + grid._includes generator = SimpleGenerator("SkeletonGF", "Dune::Fem") typeName = "Dune::Fem::SkeletonGF< " + grid._typeName + ", " + interfaceFunction._typeName + " >" moduleName = "skeleton_" + hashlib.md5(typeName.encode('utf8')).hexdigest() cls = generator.load(includes, typeName, moduleName) skeleton = cls.SkeletonGF(grid, interfaceFunction) import dune.ufl skeleton = dune.ufl.GridFunction(skeleton) interfaceFunction.skeleton = skeleton return skeleton
def _createComponent(name, *, scalar="double", componentId=0): """Create a new component of the given name""" if name == "Constant": typeName = f"Dumux::Components::{name} <{componentId}, {scalar}>" else: typeName = f"Dumux::Components::{name} <{scalar}>" moduleName = f"{name.lower()}_{hashIt(typeName)}" includes = ["dumux/python/material/components/component.hh"] includes += [_components[name]] generator = SimpleGenerator("Component", "Dumux::Python") module = generator.load(includes, typeName, moduleName) return module.Component()
def _loadVec(includes, typeName, constructors=None, methods=None): from dune.generator.generator import SimpleGenerator from dune.common.hashit import hashIt generator = SimpleGenerator("FieldVector", "Dune::Python") includes = includes + ["dune/python/common/fvector.hh"] typeHash = "fieldvector_" + hashIt(typeName) return generator.load(includes, typeName, typeHash, constructors, methods, bufferProtocol=True)
def BoundaryTypes(numEq=1): # only copmile this once per numEq cacheKey = "BoundaryTypes_{}".format(numEq) try: return globals()[cacheKey]() except KeyError: includes = ["dumux/python/common/boundarytypes.hh"] typeName = "Dumux::BoundaryTypes<{}>".format(numEq) moduleName = "boundarytypes_" + hashIt(typeName) generator = SimpleGenerator("BoundaryTypes", "Dumux::Python") module = generator.load(includes, typeName, moduleName) globals().update({cacheKey: module.BoundaryTypes}) return globals()[cacheKey]()
def _createVtkOutputModule(*, gridVariables, solutionVector, name): """Construct a VtkOutputModule""" includes = gridVariables._includes + solutionVector._includes includes += [ "dumux/python/io/vtkoutputmodule.hh", "dumux/io/vtkoutputmodule.hh" ] typeName = f"Dumux::VtkOutputModule<{gridVariables._typeName}, {solutionVector._typeName}>" moduleName = "vtkoutputmodule_" + hashIt(typeName) generator = SimpleGenerator("VtkOutputModule", "Dumux::Python") module = generator.load(includes, typeName, moduleName, preamble=gridVariables.model.cppHeader) return module.VtkOutputModule(gridVariables, solutionVector, name)
def _createBoundaryTypes(numEq=1): """Create BoundaryTypes instances""" # only compile this once per numEq cacheKey = f"BoundaryTypes_{numEq}" try: return globals()[cacheKey]() except KeyError: includes = ["dumux/python/common/boundarytypes.hh"] typeName = f"Dumux::BoundaryTypes<{numEq}>" moduleName = "boundarytypes_" + hashIt(typeName) generator = SimpleGenerator("BoundaryTypes", "Dumux::Python") module = generator.load(includes, typeName, moduleName) globals().update({cacheKey: module.BoundaryTypes}) return globals()[cacheKey]()
def trace(bulkFunction, igrid=None): """Return the trace representation of a discrete function on the bulk grid. Args: bulkFunction: The discrete function on the bulk grid. igrid (InterfaceGrid, optional): The interface grid. Returns: Trace representation of a given interface function. This function has to be restricted to positive ('+') or negative side ('-'). """ if igrid == None: igrid = bulkFunction.space.grid.hierarchicalGrid.interfaceGrid traces = {} includes = ["dune/mmesh/misc/pyskeletontrace.hh"] includes += bulkFunction._includes generator = SimpleGenerator(["TraceGF","TraceGF"], "Dune::Fem", pythonname=["TraceGFP","TraceGFM"]) typeName = [] for side in [ "in", "out" ]: sideStr = "Dune::Fem::IntersectionSide::" + side typeName += ["Dune::Fem::TraceGF< " + igrid._typeName + ", " + bulkFunction._typeName + ", " + sideStr + " >"] moduleName = "skeleton_"+hashlib.md5(''.join(typeName).encode('utf8')).hexdigest() module = generator.load(includes, typeName, moduleName) traces["in"] = module.TraceGFP(igrid, bulkFunction) traces["out"] = module.TraceGFM(igrid, bulkFunction) import ufl import dune.ufl trace_p = dune.ufl.GridFunction(traces["in"]) trace_m = dune.ufl.GridFunction(traces["out"]) if bulkFunction.scalar: trace_p = trace_p.toVectorCoefficient() trace_m = trace_m.toVectorCoefficient() trace = trace_p predefined = {} predefined[trace('+')] = trace_p predefined[trace('-')] = trace_m predefined[ufl.grad(trace)('+')] = ufl.grad(trace_p) predefined[ufl.grad(trace)('-')] = ufl.grad(trace_m) predefined[ufl.grad(ufl.grad(trace))('+')] = ufl.grad(ufl.grad(trace_p)) predefined[ufl.grad(ufl.grad(trace))('-')] = ufl.grad(ufl.grad(trace_m)) trace.predefined = predefined if bulkFunction.scalar: trace = trace[0] bulkFunction.trace = trace return trace
def createModule(numEq): priVarType = f"Dune::FieldVector<double, {numEq}>" ggType = gridGeometry._typeName enableIntDirConstraint = "true" if enableInternalDirichletConstraints else "false" problemType = f"Dumux::Python::FVProblem<{ggType}, {priVarType}, {enableIntDirConstraint}>" includes = gridGeometry._includes + [ "dumux/python/common/fvproblem.hh" ] moduleName = "fvproblem_" + hashIt(problemType) holderType = f"std::shared_ptr<{problemType}>" generator = SimpleGenerator("FVProblem", "Dumux::Python") module = generator.load(includes, problemType, moduleName, options=[holderType]) return module
def createModule(numEq): priVarType = "Dune::FieldVector<double, {}>".format(numEq) ggType = gridGeometry._typeName problemType = "Dumux::Python::FVProblem<{}, {}>".format( ggType, priVarType) includes = gridGeometry._includes + [ "dumux/python/common/fvproblem.hh" ] moduleName = "fvproblem_" + hashIt(problemType) holderType = "std::shared_ptr<{}>".format(problemType) generator = SimpleGenerator("FVProblem", "Dumux::Python") module = generator.load(includes, problemType, moduleName, options=[holderType]) return module
def _createFVAssembler(*, problem, gridVariables, model, diffMethod="numeric", isImplicit=True): """ Create an FVAssembler object Args: problem: A problem instance (boundary & initial conditions) gridVariables: A grid variable instance (primary & secondary variables defined on a grid) model: A DuMux model configuration instance diffMethod (str): The method to compute derivatives of the residual (numeric or analytic) isImplicit (bool): If the time discretization method is implicit or explicit Returns: An assembler object (Python-bindings of the corresponding C++ type) Usage: assembler = FVAssembler( problem=problem, gridVariables=gridVars, model=model, diffMethod=diffMethod ) """ if diffMethod == "numeric": cppDiffMethod = "Dumux::DiffMethod::numeric" elif diffMethod == "analytic": cppDiffMethod = "Dumux::DiffMethod::analytic" else: raise ValueError(f"Unknown diffMethod {diffMethod}") assemblerType = f"Dumux::FVAssembler<{model.cppType}, {cppDiffMethod}, {int(isImplicit)}>" includes = (problem._includes + problem.gridGeometry()._includes + ["dumux/assembly/fvassembler.hh"]) includes += ["dumux/python/assembly/fvassembler.hh"] moduleName = "fvassembler_" + hashIt(assemblerType) generator = SimpleGenerator("FVAssembler", "Dumux::Python") module = generator.load( includes, assemblerType, moduleName, holder="std::shared_ptr", preamble=model.cppHeader, ) return module.FVAssembler(problem, problem.gridGeometry(), gridVariables)
def _createGridGeometry(gridView, discMethod="cctpfa"): """Construct a GridGeometry from a gridView""" includes = gridView._includes + ["dumux/python/discretization/gridgeometry.hh"] if discMethod == "cctpfa": includes += ["dumux/discretization/cellcentered/tpfa/fvgridgeometry.hh"] typeName = "Dumux::CCTpfaFVGridGeometry<" + gridView._typeName + ">" elif discMethod == "box": includes += ["dumux/discretization/box/fvgridgeometry.hh"] typeName = "Dumux::BoxFVGridGeometry<double, " + gridView._typeName + ">" else: raise ValueError(f"Unknown discMethod {discMethod}") moduleName = "gridgeometry_" + hashIt(typeName) holderType = f"std::shared_ptr<{typeName}>" generator = SimpleGenerator("GridGeometry", "Dumux::Python") module = generator.load(includes, typeName, moduleName, options=[holderType]) return module.GridGeometry(gridView)
def createModule(numEq): priVars = f"Dune::FieldVector<double, {numEq}>" ggType = gridGeometry._typeName spType = spatialParams._typeName enableIDC = "true" if enableInternalDirichletConstraints else "false" problemType = ("Dumux::Python::PorousMediumFlowProblem" f"<{ggType}, {priVars}, {spType}, {enableIDC}>") includes = [ *(gridGeometry._includes), *(spatialParams._includes), *["dumux/python/porousmediumflow/problem.hh"], ] moduleName = "fvproblem_" + hashIt(problemType) generator = SimpleGenerator("PorousMediumFlowProblem", "Dumux::Python") module = generator.load(includes, problemType, moduleName, holder="std::shared_ptr") return module
def decorateOnePSpatialParams(cls): generator = SimpleGenerator("OnePSpatialParams", "Dumux::Python") module = generator.load(includes, typeName, moduleName, holder="std::shared_ptr") def maybeConvertScalarToMatrix(permeabilityValue): if isinstance(permeabilityValue, float): matrix = np.zeros(shape=(dim, dim)) np.fill_diagonal(matrix, permeabilityValue) return matrix.tolist() return permeabilityValue class Permeability: """Permeability decorator to make sure permeability has correct type""" def __init__(self, permeabilityFunction): self.permeabilityFunction = permeabilityFunction def __call__(self, element, scv, elemSol): result = self.permeabilityFunction(element, scv, elemSol) return maybeConvertScalarToMatrix(result) class PermeabilityAtPos: """PermeabilityAtPos decorator to make sure permeability has correct type""" def __init__(self, permeabilityFunction): self.permeabilityFunction = permeabilityFunction def __call__(self, globalPos): result = self.permeabilityFunction(globalPos) return maybeConvertScalarToMatrix(result) def createSpatialParams(): spatialParams = cls() if hasattr(cls, "permeability"): cls.permeability = Permeability(spatialParams.permeability) if hasattr(cls, "permeabilityAtPos"): cls.permeabilityAtPos = PermeabilityAtPos( spatialParams.permeabilityAtPos) return module.OnePSpatialParams(gridGeometry, spatialParams) return createSpatialParams
def _createGridVariables(*, problem, model): """Construct a GridGeometry from problem and the model""" includes = [ "dumux/discretization/fvgridvariables.hh", "dumux/python/discretization/gridvariables.hh", ] ggeo = f"Dumux::GetPropType<{model.cppType}, Dumux::Properties::GridGeometry>" gvv = f"Dumux::GetPropType<{model.cppType}, Dumux::Properties::GridVolumeVariables>" gfc = f"Dumux::GetPropType<{model.cppType}, Dumux::Properties::GridFluxVariablesCache>" typeName = f"Dumux::FVGridVariables<{ggeo}, {gvv}, {gfc}>" moduleName = "gridvariables_" + hashIt(typeName) holderType = f"std::shared_ptr<{typeName}>" generator = SimpleGenerator("GridVariables", "Dumux::Python") module = generator.load( includes, typeName, moduleName, options=[holderType], preamble=model.cppHeader ) module.GridVariables.model = property(lambda self: model) return module.GridVariables(problem, problem.gridGeometry())
def _createFluidSystem(name, *, component, scalar: Property = None): """Construct a FluidSystem""" includes = component._includes + [ "dumux/python/material/fluidsystems/fluidsystem.hh" ] if scalar is None: scalar = Property.fromCppType("double") scalarType = scalar.cppType availableFluidSystems = { "OnePLiquid": { "includes": ["dumux/material/fluidsystems/1pliquid.hh"], "type": f"Dumux::FluidSystems::OnePLiquid<{scalarType}, {component._typeName}>", }, "OnePGas": { "includes": ["dumux/material/fluidsystems/1pgas.hh"], "type": f"Dumux::FluidSystems::OnePGas<{scalarType}, {component._typeName}>", }, } if name not in availableFluidSystems: raise NotImplementedError("FluidSystem of type " + name + " not implemented.\n" "Available types are " + ", ".join(availableFluidSystems.keys())) includes += availableFluidSystems[name]["includes"] typeName = availableFluidSystems[name]["type"] moduleName = "fluidsystem_" + hashIt(typeName) generator = SimpleGenerator("FluidSystem", "Dumux::Python") module = generator.load(includes, typeName, moduleName) return module.FluidSystem()