From c79a6a938ef7a2df8a0282d40f73de7da81d601c Mon Sep 17 00:00:00 2001 From: dedner <a.s.dedner@warwick.ac.uk> Date: Wed, 1 Apr 2020 12:42:45 +0100 Subject: [PATCH] added some more test including fv0, fv1 for euler --- .gitignore | 9 + pydemo/CMakeLists.txt | 1 + pydemo/chemicalreaction/CMakeLists.txt | 4 + pydemo/chemicalreaction/test.py | 223 ++++++------------------- pydemo/euler/CMakeLists.txt | 10 +- pydemo/euler/{test.py => testdg.py} | 0 pydemo/euler/testfv0.py | 42 +++++ pydemo/euler/testfv1.py | 45 +++++ python/dune/femdg/testing.py | 5 +- 9 files changed, 168 insertions(+), 171 deletions(-) create mode 100644 pydemo/chemicalreaction/CMakeLists.txt rename pydemo/euler/{test.py => testdg.py} (100%) create mode 100644 pydemo/euler/testfv0.py create mode 100644 pydemo/euler/testfv1.py diff --git a/.gitignore b/.gitignore index f647b035..45b07b3e 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,15 @@ Makefile.in *.lo *.la *.tmp +*.vtu +*.pvtu +__pycache__ +*.dump +*.out +*.log +*.aux +*.pickle +*.png data diff --git a/pydemo/CMakeLists.txt b/pydemo/CMakeLists.txt index b9229f75..d7b63dc8 100644 --- a/pydemo/CMakeLists.txt +++ b/pydemo/CMakeLists.txt @@ -1,3 +1,4 @@ #dune_add_subdirs(scalar) #dune_add_subdirs(shallowWater) dune_add_subdirs(euler) +dune_add_subdirs(chemicalreaction) diff --git a/pydemo/chemicalreaction/CMakeLists.txt b/pydemo/chemicalreaction/CMakeLists.txt new file mode 100644 index 00000000..c7605c1c --- /dev/null +++ b/pydemo/chemicalreaction/CMakeLists.txt @@ -0,0 +1,4 @@ +# add custom target to build tool chain for euler +dune_python_add_test(NAME chemical_python + COMMAND ${PYTHON_EXECUTABLE} test.py + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/pydemo/chemicalreaction/test.py b/pydemo/chemicalreaction/test.py index ee224fd8..4e42272b 100644 --- a/pydemo/chemicalreaction/test.py +++ b/pydemo/chemicalreaction/test.py @@ -1,182 +1,69 @@ -import time, math, sys -from timeit import timeit +import math from ufl import * -from dune.ufl import DirichletBC, Constant -from dune.grid import structuredGrid, cartesianDomain -from dune.alugrid import aluCubeGrid as cubeGrid -from dune.alugrid import aluSimplexGrid as simplexGrid -from dune.fem import parameter -from dune.fem.view import adaptiveLeafGridView as adaptive -from dune.fem.space import lagrange, dgonb, raviartThomas +from dune.ufl import DirichletBC +from dune.grid import cartesianDomain, structuredGrid +from dune.alugrid import aluCubeGrid +from dune.fem.space import lagrange, dgonb from dune.fem.scheme import galerkin from dune.femdg import femDGOperator from dune.femdg.rk import femdgStepper -from dune.grid import reader -#gridView = cubeGrid(cartesianDomain([0,0],[1,1],[50,50])) -domain = (reader.gmsh, "circlemeshquad.msh") -gridView = adaptive( grid=cubeGrid(constructor=domain, dimgrid=2) ) +# gridView = structuredGrid([0,0],[2*math.pi,2*math.pi],[10,10]) +gridView = aluCubeGrid(cartesianDomain([0,0],[2*math.pi,2*math.pi],[10,10])) -dimRange = 3 -space = dgonb( gridView, order=1, dimRange = dimRange) -u_h = space.interpolate(dimRange*[0], name='u_h') -pressureSpace = lagrange(gridView, order=1, dimRange=1) -pressure = pressureSpace.interpolate([1e+7],name="pressure") # Andreas: why not zero? -velocitySpace = raviartThomas(gridView,order=1,dimRange=1) -transportVelocity = velocitySpace.interpolate([0,0],name="velocity") +def computeVelocity(): + streamSpace = lagrange(gridView, order=1, dimRange=1) + Psi = streamSpace.interpolate(0,name="streamFunction") + u,v = TrialFunction(streamSpace), TestFunction(streamSpace) + x = SpatialCoordinate(streamSpace) + form = ( inner(grad(u),grad(v)) - 5*sin(x[0])*sin(x[1]) * v[0] ) * dx + streamScheme = galerkin([form == 0, DirichletBC(streamSpace,[0]) ]) + streamScheme.solve(target=Psi) + return as_vector([-Psi[0].dx(1),Psi[0].dx(0)]) -# Model class Model: - dimDomain = gridView.dimension - dimRange = space.dimRange # three unknowns: (phi, phi cu, phi cb)^T - - # Set up time - secperhour = 3600 - # Andreas: what is t_start? t = Constant(t_start, "time") # time variable - - # reaction, diffusion and other coefficients - phi_crit = 0.1 - rhoc = 2710 # density calcite - Mb = 1.0 # Molar mass suspended biomass - Mc = 0.1 # Molar mass calcite - - Mc_rhoc = Mc / rhoc - - # Well - Qp = 1.25e-3 - Qw = Qp - # source_p = Well(mesh=mesh, Q=Qp, degree=1) # UNCOMMENT - # Pressure (natural) - # p0_in = Constant(1.25e7) - - cu_in = 2000 - Qcu = Qp * cu_in - - cb_in = 0.01 - Qcb = Qp * cb_in - # - # Dispersivity (constant): - # - D_mol = 1.587e-9 # molecular diffusion - alpha_long = 0.01 # longitudinal dispersivity - # CONSTANT - # D_mech = Constant(1e-6) - D = D_mol - - # FULL TENSOR - # I = Identity(dim) - - kub = 0.01 - kurease = 706.7 - ke = kub * kurease - Ku = 355 # Ku = KU * rho_w = 0.355 * 1e3 - - # unspecific attachment rate - ka = 4e-6 - - # Biomass - b0 = 3.18e-7 # decay rate coeff. - - # Biomass - b0 = 3.18e-7 # decay rate coeff. - - K = 1.0e-12 - - # Misc. other parameters - mu = 0.0008 # viscosity of water - - ### initial ### - phi0 = 0.2 - cu0 = 0 - cb0 = 0 - initial = as_vector([phi0, cu0, cb0]) - - ### Model functions ### - def toPrim(U): - # ( phi, phi cu, phi cb ) --> (phi, cu, cb) - return U[0], U[1] / U[0], U[2] / U[0] - - def toCons(U): - # ( phi, cu, cb ) --> (phi, phi cu, phi cb) - return U[0], U[1] * U[0], U[2] * U[0] - - # circle of 0.3 around center - def inlet( x ): - return conditional(sqrt( x[0]*x[0] + x[1]*x[1] ) < 3, 1., 0. ) - - def darcyVelocity( p ): - return -1./Model.mu * Model.K * grad(p[0]) - - # form for pressure equation - def pressureForm( time ): - u = TrialFunction(pressureSpace) - v = TestFunction(pressureSpace) - x = SpatialCoordinate(pressureSpace) - # n = FacetNormal(pressureSpace) - dbc = DirichletBC(pressureSpace,[ 1e7 ]) - phi, cu, cb = Model.toPrim( u_h ) - qu = Model.ke * phi * Model.Mb * cb * cu / (Model.Ku + cu ) - hour = time / Model.secperhour - Qw1_t = Model.inlet( x ) * conditional( hour > 20., conditional( hour < 25., Model.Qw, 0), 0 ) - Qw2_t = Model.inlet( x ) * conditional( hour > 45., conditional( hour < 60., Model.Qw, 0), 0 ) - pressureRhs = as_vector([ qu + Qw1_t + Qw2_t ]) - return [ inner(grad(u),grad(v)) * dx == inner(pressureRhs, v) * dx, - dbc ] - - def S_i(t,x,U,DU): # or S_i for a stiff source - phi, cu, cb = Model.toPrim( U ) - - qu = Model.ke * phi * Model.Mb * cb * cu / (Model.Ku + cu ) - qc = qu # Assumption in the report, before eq 3.12 - qb = cb * ( phi * ( Model.b0 + Model.ka) + qc * Model.Mc_rhoc ) - - hour = t / Model.secperhour - Qu_t = Model.inlet(x) * conditional( hour > 25., conditional( hour < 45., Model.Qcu, 0), 0 ) - Qb_t = Model.inlet(x) * conditional( hour < 20., Model.Qcb, 0 ) - return as_vector([ -qu * Model.Mc_rhoc, - -qu + Qu_t, - -qb + Qb_t - ]) + transportVelocity = computeVelocity() + def S_e(t,x,U,DU): + P1 = as_vector([0.2*pi,0.2*pi]) # midpoint of first source + P2 = as_vector([1.8*pi,1.8*pi]) # midpoint of second source + f1 = conditional(dot(x-P1,x-P1) < 0.2, 1, 0) + f2 = conditional(dot(x-P2,x-P2) < 0.2, 1, 0) + f = conditional(t<5, as_vector([f1,f2,0]), as_vector([0,0,0])) + r = 10*as_vector([U[0]*U[1], U[0]*U[1], -2*U[0]*U[1]]) + return f - r def F_c(t,x,U): - phi, cu, cb = Model.toPrim(U) - # first flux should be zero since porosity is simply an ODE - return as_matrix([ Model.dimDomain*[0], - [*(Model.velocity(t,x,U) * cu)], - [*(Model.velocity(t,x,U) * cb)] - ]) + return as_matrix([ [*(Model.velocity(t,x,U)*u)] for u in U ]) def maxLambda(t,x,U,n): return abs(dot(Model.velocity(t,x,U),n)) def velocity(t,x,U): - return transportVelocity + return Model.transportVelocity def F_v(t,x,U,DU): - # eps * phi^(1/3) * grad U - return Model.D * pow(U[0], 1./3.) * DU - def maxDiffusion(t,x,U): - return Model.D * pow(U[0], 1./3.) + return 0.02*DU def physical(t,x,U): - #phi, cu, cb = Model.toPrim( U ) - # U should be positive - #return conditional( phi>=0,1,0)*conditional(cu>=0,1,0)*conditional(cb>=0,1,0) - return conditional(U[0]>1e-10,1,0)*conditional(U[1]>=0,1,0)*conditional(U[2]>=0,1,0) - def dirichletValue(t,x,u): - return Model.initial - boundary = {1: dirichletValue} - endTime = 250 * secperhour - name = "micap" - -#### main program #### - -operator = femDGOperator(Model, space, limiter=None, threading=True) -stepper = femdgStepper(order=1, rkType="IM") ( operator ) # Andreas: move away from 'EX'? -# odeParam={"fem.verboserank": 0, -# "fem.ode.verbose": "full", -# "fem.solver.verbose": True, -# "fem.solver.newton.verbose": True, -# "fem.solver.method": "gmres"} -# parameter.append( odeParam ) - - -for i in range(4): - gridView.hierarchicalGrid.globalRefine(1) - u_h.interpolate(Model.initial) - print("computing:",i,timeit("stepper(u_h,dt=360)",number=1,globals=globals())) + return conditional(U[0]>=0,1,0)*conditional(U[1]>=0,1,0)*\ + conditional(U[2]>=0,1,0) + boundary = {range(1,5): as_vector([0,0,0])} + +space = dgonb( gridView, order=3, dimRange=3) +u_h = space.interpolate([0,0,0], name='u_h') +operator = femDGOperator(Model, space, limiter="scaling") +stepper = femdgStepper(order=3, operator=operator) +operator.applyLimiter(u_h) + +# velo = expression2GF(gridView,Model.transportVelocity, order=2, name="velocity") +vtk = gridView.sequencedVTK("chemical", subsampling=1, + pointdata=[u_h], + cellvector={"velocity":Model.transportVelocity}) +vtk() + +t = 0 +saveStep = 0.1 +saveTime = saveStep +while t < 0.1: + operator.setTime(t) + t += stepper(u_h) + if t > saveTime: + print(t) + vtk() + saveTime += saveStep +vtk() diff --git a/pydemo/euler/CMakeLists.txt b/pydemo/euler/CMakeLists.txt index f54388e7..4ae92078 100644 --- a/pydemo/euler/CMakeLists.txt +++ b/pydemo/euler/CMakeLists.txt @@ -1,4 +1,10 @@ # add custom target to build tool chain for euler -dune_python_add_test(NAME euler_python - COMMAND ${PYTHON_EXECUTABLE} test.py +dune_python_add_test(NAME eulerdg_python + COMMAND ${PYTHON_EXECUTABLE} testdg.py + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) +dune_python_add_test(NAME eulerfv1_python + COMMAND ${PYTHON_EXECUTABLE} testfv1.py + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) +dune_python_add_test(NAME eulerfv0_python + COMMAND ${PYTHON_EXECUTABLE} testfv0.py WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/pydemo/euler/test.py b/pydemo/euler/testdg.py similarity index 100% rename from pydemo/euler/test.py rename to pydemo/euler/testdg.py diff --git a/pydemo/euler/testfv0.py b/pydemo/euler/testfv0.py new file mode 100644 index 00000000..04b78d05 --- /dev/null +++ b/pydemo/euler/testfv0.py @@ -0,0 +1,42 @@ +import mpi4py.rc +# mpi4py.rc.threaded = False +from dune.fem import parameter +from dune.femdg.testing import run + +# from euler import constant as problem +from euler import sod as problem +# from euler import vortex as problem +# from euler import leVeque as problem +# from euler import radialSod3 as problem + +dim = 2 +gamma = 1.4 + +parameter.append({"fem.verboserank": -1}) + +primitive=lambda Model,uh: {"pressure": Model.toPrim(uh)[2]} +parameters = {"fem.ode.odesolver": "EX", + "fem.timeprovider.factor": 0.25, + "fem.ode.order": 1} +#----------------- +# "dgadvectionflux.method": "EULER-HLLC", "EULER-HLL", "LLF" +# default value is 'LLF' +#----------------- +# femdg.limiter.tolerance: 1 (tolerance for shock indicator) +# femdg.limiter.epsilon: 1e-8 (epsilon to avoid rounding errors) +# femdg.limiter.admissiblefunctions: +# 0 = only dg solution | 1 = only reconstruction | 2 = both +#----------------- + +Model = problem() +# use shorter end time for testing +Model.endTime = 0.025 +Model.exact = None + +run(Model, + startLevel=0, limiter=None, + primitive=primitive, saveStep=0.16, subsamp=2, + dt=None,threading=False,grid="alucube", space="finitevolume", + parameters=parameters) + +# print(str(parameter)) diff --git a/pydemo/euler/testfv1.py b/pydemo/euler/testfv1.py new file mode 100644 index 00000000..9b186a30 --- /dev/null +++ b/pydemo/euler/testfv1.py @@ -0,0 +1,45 @@ +import mpi4py.rc +# mpi4py.rc.threaded = False +from dune.fem import parameter +from dune.femdg.testing import run + +# from euler import constant as problem +from euler import sod as problem +# from euler import vortex as problem +# from euler import leVeque as problem +# from euler import radialSod3 as problem + +dim = 2 +gamma = 1.4 + +parameter.append({"fem.verboserank": -1}) + +primitive=lambda Model,uh: {"pressure": Model.toPrim(uh)[2]} +parameters = {"fem.ode.odesolver": "EX", + "fem.timeprovider.factor": 0.25, + "fem.ode.order": 2, + "femdg.limiter.admissiblefunctions": 1, + "femdg.limiter.tolerance": 1, + "femdg.limiter.epsilon": 1e-8} +#----------------- +# "dgadvectionflux.method": "EULER-HLLC", "EULER-HLL", "LLF" +# default value is 'LLF' +#----------------- +# femdg.limiter.tolerance: 1 (tolerance for shock indicator) +# femdg.limiter.epsilon: 1e-8 (epsilon to avoid rounding errors) +# femdg.limiter.admissiblefunctions: +# 0 = only dg solution | 1 = only reconstruction | 2 = both +#----------------- + +Model = problem() +# use shorter end time for testing +Model.endTime = 0.025 +Model.exact = None + +run(Model, + startLevel=0, limiter="default", + primitive=primitive, saveStep=0.16, subsamp=2, + dt=None,threading=False,grid="alucube", space="finitevolume", + parameters=parameters) + +# print(str(parameter)) diff --git a/python/dune/femdg/testing.py b/python/dune/femdg/testing.py index 7f08c596..69f63f4b 100644 --- a/python/dune/femdg/testing.py +++ b/python/dune/femdg/testing.py @@ -58,7 +58,10 @@ def run(Model, Stepper=None, # create discrete function space try: - space = create.space( space, grid, order=polOrder, dimRange=dimR) + if space.lower() == "finitevolume": + space = create.space( space, grid, dimRange=dimR) + else: + space = create.space( space, grid, order=polOrder, dimRange=dimR) except: assert space.dimRange > 0 if modifyModel is not None: -- GitLab