From 06761b0d9e17a8e4d191b8487e7f164b9a0d8872 Mon Sep 17 00:00:00 2001 From: Chloe Mimeau <Chloe.Mimeau@imag.fr> Date: Mon, 7 Apr 2014 14:54:28 +0000 Subject: [PATCH] update example for flow past sphere --- Examples/NSDebug.py | 274 +++++++++++++++++++++++++------------------- 1 file changed, 158 insertions(+), 116 deletions(-) diff --git a/Examples/NSDebug.py b/Examples/NSDebug.py index be6101baa..43328a9bb 100755 --- a/Examples/NSDebug.py +++ b/Examples/NSDebug.py @@ -12,24 +12,26 @@ from parmepy.f2py import fftw2py import numpy as np from parmepy.fields.continuous import Field from parmepy.mpi.topology import Cartesian +from parmepy.fields.variable_parameter import VariableParameter from parmepy.domain.obstacle.sphere import Sphere from parmepy.operator.advection import Advection from parmepy.operator.stretching import Stretching from parmepy.operator.poisson import Poisson from parmepy.operator.velocity_correction import VelocityCorrection +#from parmepy.operator.vorticity_correction import VorticityCorrection from parmepy.operator.diffusion import Diffusion from parmepy.operator.penalization import Penalization from parmepy.operator.differential import Curl from parmepy.operator.redistribute import Redistribute from parmepy.operator.monitors import Printer, Energy_enstrophy, DragAndLift,\ - Reprojection_criterion + Reprojection_criterion, ProfilesOutput from parmepy.problem.simulation import Simulation from parmepy.constants import VTK, HDF5 -from parmepy.domain.obstacle.planes import PlaneBoundaries +from parmepy.domain.obstacle.planes import PlaneBoundaries, SubPlane +from parmepy.domain.obstacle.controlBox import ControlBox from dataNS_bb import dim, nb, NBGHOSTS, ADVECTION_METHOD, VISCOSITY, \ OUTPUT_FREQ, FILENAME, PROJ, LCFL, CFL, CURL_METHOD, \ TIMESTEP_METHOD, OBST_Ox, OBST_Oy, OBST_Oz, RADIUS -from parmepy.domain.obstacle.controlBox import ControlBox import parmepy.tools.numpywrappers as npw import parmepy.tools.io_utils as io ## ----------- A 3d problem ----------- @@ -41,17 +43,35 @@ cos = np.cos sin = np.sin ## Domain -boxlength = npw.realarray([2.0 * pi, 2 * pi, 2 * pi]) -boxorigin = npw.realarray([0., 0., 0.]) +#boxlength = npw.realarray([8.0 * pi, 2.0 * pi, 2.0 * pi]) +#boxorigin = npw.realarray([-2.0, -pi, -pi]) +boxlength = npw.realarray([10.24, 5.12, 5.12]) +boxorigin = npw.realarray([-2.0, -2.56, -2.56]) box = pp.Box(dim, length=boxlength, origin=boxorigin) ## Global resolutionsimu -nbElem = [129]*3 +#nbElem = [1025, 513, 513] +nbElem = [129, 65, 65] -# Upstream flow velocity + +# Initial upstream flow velocity uinf = 1.0 -# Function to compute potential flow past a sphere +def computeFlowrate(simu): + ##Time-dependant flow rate + t = simu.tk + Tstart = 3.0 + flowrate = np.zeros(3) + flowrate[0] = uinf * box.length[1] * box.length[2] + if t >= Tstart and t <= Tstart + 1.0: + flowrate[1] = sin(pi * (t - Tstart)) * \ + box.length[1] * box.length[2] + ##constant flow rate +# flowrate = np.zeros(3) +# flowrate[0] = uinf * box.length[1] * box.length[2] + return flowrate + +# Function to compute initial velocity def computeVel(res, x, y, z, t): res[0][...] = uinf res[1][...] = 0. @@ -72,16 +92,23 @@ velo = Field(domain=box, formula=computeVel, vorti = Field(domain=box, formula=computeVort, name='Vorticity', isVector=True) -# Topo for operators that required ghosts points (stretching) +## Usual Cartesian topology definition +# At the moment we use two (or three?) topologies : +# - "topo" for Stretching and all operators based on finite differences. +# --> ghost layer = 2 +# - topo from Advection operator for all the other operators. +# --> no ghost layer +# - topo from fftw for Poisson and Diffusion. +# Todo : check compat between scales and fft operators topologies. ghosts = np.ones((box.dimension)) * NBGHOSTS -topostr = Cartesian(box, box.dimension, nbElem, ghosts=ghosts) +topo = Cartesian(box, box.dimension, nbElem, + ghosts=ghosts) ## === Obstacles (sphere + up and down plates) === -sphere_pos = (boxlength - boxorigin) * 0.5 +#sphere_pos = (boxlength - boxorigin) * 0.5 +sphere_pos = [0., 0., 0.] sphere = Sphere(box, position=sphere_pos, radius=RADIUS) -bc = PlaneBoundaries(box, 2, thickness=0.1) - ## === Computational Operators === op = {} op['advection'] = Advection(velo, vorti, @@ -90,7 +117,7 @@ op['advection'] = Advection(velo, vorti, op['stretching'] = Stretching(velo, vorti, resolutions={velo: nbElem, vorti: nbElem}, - topo=topostr) + topo=topo) op['diffusion'] = Diffusion(vorti, resolution=nbElem, viscosity=VISCOSITY) @@ -108,15 +135,20 @@ opfft = op['poisson'] topofft = opfft.discreteFields[opfft.vorticity].topology topocurl = op['curl'].discreteFields[op['curl'].invar].topology topoadvec = op['advection'].discreteFields[op['advection'].velocity].topology +# space step +ref_step = topofft.mesh.space_step +step_dir = ref_step[0] -op['penalization'] = Penalization(velo, [sphere, bc], coeff=[1e8], +## Penalization velocity +op['penalization'] = Penalization(velo, [sphere], coeff=[1e8], topo=topofft, resolutions={velo: nbElem}) -ref_rate = uinf * box.length[1] * box.length[2] +## Time-dependant required-flowrate (Variable Parameter) +req_flowrate = VariableParameter(formula=computeFlowrate) op['correction'] = VelocityCorrection(velo, vorti, resolutions={velo: nbElem, vorti: nbElem}, - req_flowrate=ref_rate, topo=topofft) + req_flowrate=req_flowrate, topo=topofft) op['penalization'].discretize() op['correction'].discretize() @@ -126,37 +158,73 @@ distr = {} distr['fft2curl'] = Redistribute([velo], op['penalization'], op['curl']) distr['curl2fft'] = Redistribute([vorti], op['curl'], op['poisson']) + +# 1 - Curl to stretching (velocity only) +#distr['curl2str'] = Redistribute([velo], op['curl'], op['stretching']) +# 2 - Advection to stretching +# velocity only +#distr['adv2str_v'] = Redistribute([velo], op['advection'], op['stretching']) +# vorticity only +#distr['adv2str_w'] = Redistribute([vorti], op['advection'], op['stretching']) +# Both distr['adv2str'] = Redistribute([velo, vorti], op['advection'], op['stretching']) +# 3 - Stretching to Diffusion distr['str2diff'] = Redistribute([vorti], op['stretching'], op['diffusion']) distr['curl2adv'] = Redistribute([velo, vorti], op['curl'], op['advection']) distr['curl2str'] = Redistribute([velo, vorti], op['curl'], op['stretching']) +#distr['adv2corr'] = Redistribute([velo, vorti], +# op['advection'], op['correc_vorti']) + for ope in distr.values(): ope.discretize() # === Simulation setup === -simu = Simulation(tinit=0.0, tend=10., nbIter=2000, iterMax=1000000) +simu = Simulation(tinit=0.0, tend=75., timeStep=0.0125, iterMax=1000000) ## === Monitoring operators === monitors = {} # Save velo and vorti values on topofft monitors['printerFFT'] = Printer(variables=[velo, vorti], topo=topofft, - formattype=HDF5, prefix='fft_io') + formattype=HDF5) monitors['printerCurl'] = Printer(variables=[velo, vorti], topo=topocurl, - formattype=HDF5, prefix='curl_io') -monitors['printerAdvec'] = Printer(variables=[velo, vorti], topo=topoadvec, - formattype=HDF5, prefix='advec_io', + formattype=HDF5, prefix='curl_io_vorti') + +monitors['printerAdvec'] = Printer(variables=[velo, vorti], topo=topofft, + frequency=1, formattype=HDF5, prefix='advec_io', xmfalways=True) -monitors['printerStr'] = Printer(variables=[velo, vorti], topo=topostr, - formattype=HDF5, prefix='str_io', - xmfalways=True) + +thickSliceXY = ControlBox(box, origin=[-2.0, -2.56, -2.0 * step_dir], + lengths=[10.24, 5.12, 4.0 * step_dir]) +#thickSliceXY = ControlBox(box, origin=[-2.0, -pi, -2.0 * step_dir], +# lengths=[8.0*pi, 2.0*pi, 4.0 * step_dir]) +monitors['printerSliceXY'] = Printer(variables=[velo, vorti], topo=topofft, + frequency=100, formattype=HDF5, prefix='sliceXY', + subset=thickSliceXY, xmfalways=True) + +thickSliceXZ = ControlBox(box, origin=[-2.0, -2.0 * step_dir, -2.56], + lengths=[10.24, 4.0 * step_dir, 5.12]) +monitors['printerSliceXZ'] = Printer(variables=[velo, vorti], topo=topofft, + frequency=100, formattype=HDF5, prefix='sliceXZ', + subset=thickSliceXZ, xmfalways=True) + +subBox = ControlBox(box, origin=[-0.7, -1.25, -1.25], lengths=[7.0, 2.5, 2.5]) +monitors['printerSubBox'] = Printer(variables=[velo, vorti], topo=topofft, + frequency=100, formattype=HDF5, prefix='subBox', + subset=subBox, xmfalways=True) # Compute and save enstrophy/Energy, on topofft io_default = {} -monitors['energy'] = Energy_enstrophy(velo, vorti, topo=topoadvec, +monitors['energy'] = Energy_enstrophy(velo, vorti, topo=topofft, io_params={}, viscosity=VISCOSITY, isNormalized=False) + +# Compute velocity and vorticity magnitude on topofft and print it in data file +io_default = {} +monitors['profiles'] = ProfilesOutput(velo, vorti, obstacles=[sphere], + topo=topofft, io_params={"frequency":1000}) + # Setup for reprojection reprojection_constant = 0.04 reprojection_rate = 1 @@ -172,19 +240,17 @@ vdfft = velo.discreteFields[topofft].data # Compute and save drag and lift on topofft # 3D Control box -ref_step = topofft.mesh.space_step cbpos = boxorigin + 10 * ref_step -cblength = boxlength - 20 * ref_step +cblength = boxlength - 25 * ref_step cb = ControlBox(box, cbpos, cblength) coeffForce = 1. / (0.5 * uinf ** 2 * pi * RADIUS ** 2) -print coeffForce +#print coeffForce # Monitor for forces -## monitors['forces'] = DragAndLift(velo, vorti, VISCOSITY, coeffForce, -## topo, cb, -## obstacles=[sphere], io_params={}) monitors['forces'] = DragAndLift(velo, vorti, VISCOSITY, coeffForce, - topostr, cb, io_params={}) + topo, cb, obstacles=[sphere], io_params={}) +#monitors['forces'] = DragAndLift(velo, vorti, VISCOSITY, coeffForce, +# topo, cb, io_params={}) # === Setup for all declared operators === for ope in op.values(): @@ -205,21 +271,18 @@ allops = dict(op.items() + distr.items() + monitors.items()) # - compute vorticity with curl def initFields_mode1(): # The velocity is initialized on the fftw topology - # penalized and distributed to curl topo + # penalized and distributed on curl topo velo.initialize(topo=topofft) op['penalization'].apply(simu) distr['fft2curl'].apply(simu) # Vorticity is initialized after penalization of velocity op['curl'].apply(simu) - # Distribute vorticity and velocity on topostr - distr['curl2str'].apply(simu) - # Warning : distribute operators do not update ghost points. This is done - # by computational operators. So a synchronize call may be required - # to monitor proper values. - #op['stretching'].discreteOperator._synchronize(op['stretching'].discreteOperator.velocity.data + op['stretching'].discreteOperator.vorticity.data) - op['stretching'].updateGhosts() + op['advection'].apply(simu) + # Distribute vorticity on topofft + distr['adv2str'].apply(simu) +# distr['curl2adv'].apply(simu) # From this point both velocity and vorticity are initialized - # on topostr and topocurl. velocity is also init. on topofft. + # on topocurl and topoadvec. velocity is also init. on topofft. ## Call initialization initFields_mode1() @@ -227,73 +290,70 @@ initFields_mode1() ##### Check initialize process results ##### norm_vel_fft = velo.norm(topofft) norm_vel_curl = velo.norm(topocurl) -norm_vel_str = velo.norm(topostr) - +norm_vort_fft = vorti.norm(topofft) norm_vort_curl = vorti.norm(topocurl) -norm_vort_str = vorti.norm(topostr) - -print norm_vort_curl, norm_vort_str -print norm_vel_curl, norm_vel_fft -assert np.allclose(norm_vort_curl, norm_vort_str) -assert np.allclose(norm_vel_curl, norm_vel_fft) -assert np.allclose(norm_vel_curl, norm_vel_str) - -wref = np.asarray([0., 4354.98713193, 612.8061093], dtype=np.float64) -vref = np.asarray([1418.04337028, 0., 0.], dtype=np.float64) -assert np.allclose(norm_vel_curl, vref) -assert np.allclose(norm_vort_str, wref) + +#print norm_vort_curl, norm_vort_fft +#print norm_vel_curl, norm_vel_fft +#assert np.allclose(norm_vort_curl, norm_vort_fft) +#assert np.allclose(norm_vel_curl, norm_vel_fft) + # Print initial state -for mon in monitors.values(): - mon.apply(simu) +#for mon in monitors.values(): +# mon.apply(simu) ## Note Franck : tests init ok, same values on both topologies, for v and w. # === After init === # -# v,w init on topostr +# v init on topocurl (which may be equal to topofft) # # === Definition of the 'one-step' sequence of operators === # -# A - w = stretching(v,w), topostr -# B -# 1 - w = diffusion(w), topofft -# 2 - w = reprojection(w), topofft -# 3 - v = poisson(w), topofft -# 4 - v = correction(v, w), topofft -# 5 - v = penalization(v), topofft -# C - w = curl(v), topocurl -# D - w = advection(v,w), topoadvec +# 1 - w = curl(v), topocurl +# 2 - w = advection(v,w), topo-advec +# 3 - w = stretching(v,w), topostr +# 4 - w = diffusion(w), topofft +# 5 - v = poisson(w), topofft +# 6 - v = correction(v, w), topofft +# 7 - v = penalization(v), topofft # - -# Required bridges and in/out var: -# A, IN : v, w on topostr -# OUT : w on topostr -# A - B bridge topostr-topofft for w -# B, IN : w -# OUT : w, v on topofft -# B - C : bridge topofft - topocurl for v -# C, IN : v on topocurl -# OUT : w on topocurl -# C - D : bridge topocurl - topoadvec for v and w -# D, IN : v,w on topoadvec -# OUT : w on topoadvec -# D - A : bridge topoadvec - topostr for v and w - - -# Monitors : -# - energy(v,w), works for any topo -# - reprojection(w), needs ghost points -# - printer(v,w), works for any topo -# - forces(v,w), needs ghost points - -fullseq = ['stretching', - 'str2diff', 'diffusion', 'reprojection', 'poisson', 'correction', +# Required bridges : +# 1 --> 2 : (v,w) on topo-advec +# 2 --> 3 : (v,w) on topostr +# 3 --> 4 : w on topofft +# 7 --> 1 : v on topocurl + +#fullseq = ['advection', # in: v,w out: w, on topoadvec +# 'adv2str', 'stretching', # in: v,w out: w on topostr +# # in: w, out: v, w on topofft +# 'str2diff', 'diffusion', 'reprojection', 'poisson', 'correction', +# 'penalization', +# 'fft2curl', 'curl', 'forces', +# 'curl2adv', 'energy', 'profiles', 'printerAdvec', +# ] + +fullseq = ['stretching', + 'str2diff', 'diffusion', 'poisson', 'correction', 'penalization', - 'fft2curl', 'curl', - 'curl2adv', + 'fft2curl', 'curl', + 'curl2fft', 'poisson', 'correction', 'advection', - 'energy', 'printerAdvec', +# 'printerSliceXY', 'printerSliceXZ', 'printerSubBox', + 'energy', 'adv2str', 'forces'] +#fullseq = ['advection', +# 'diffusion', +# 'poisson', +# 'correction', +# 'penalization', +# 'fft2curl', +# 'curl', +# 'curl2fft', +# 'poisson', +# 'correction', +# 'printerSlice'] + def run(sequence): for name in sequence: @@ -302,12 +362,12 @@ def run(sequence): allops[name].apply(simu) seq = fullseq -seq = [] + simu.initialize() while not simu.isOver: - #if topocurl.rank == 0: - # simu.printState() + if topocurl.rank == 0: + simu.printState() run(seq) simu.advance() @@ -343,21 +403,3 @@ for ope in distr.values(): ope.finalize() for monit in monitors.values(): monit.finalize() - -from abc import ABCMeta, abstractmethod - - -class A(object): - - def toto(self): - print "toto A " - - def titi(self): - self.toto() - - -class B(A): - - def toto(self): - print "toto B" - -- GitLab