diff --git a/HySoP/CMakeLists.txt b/HySoP/CMakeLists.txt index 7fcf50c30c6d435a629a241f8148837bc419fa1a..5753b09376a98f4ff3cfd1ae41511813272b6ef1 100644 --- a/HySoP/CMakeLists.txt +++ b/HySoP/CMakeLists.txt @@ -36,10 +36,10 @@ option(WITH_TESTS "Enable testing. Default = off" OFF) option(BUILD_SHARED_LIBS "Enable dynamic library build, default = ON" ON) # cmake project name -set(PROJECT_NAME parmespy) +set(PROJECT_NAME parmepy) # --- Name for the package --- # This name will be used as the Python Package name -set(PYPACKAGE_NAME "parmespy") +set(PYPACKAGE_NAME "parmepy") # --- Set a version number for the package --- set(${PYPACKAGE_NAME}_version 1.0.0) # --- The name (without extension) of the lib to be created --- @@ -69,21 +69,35 @@ add_subdirectory(src) # ============= Generates setup.py ============= # The file setup.py will be generated from setup.py.in. if(EXISTS ${CMAKE_SOURCE_DIR}/setup.py.in) -# if(NOT CONFIG_H_GLOBAL_CONFIGURED) - message(STATUS "Generate setup.py file ...") -# set(CONFIG_H_GLOBAL_CONFIGURED 1 CACHE BOOL "setup.py generation." ) - configure_file(setup.py.in setup.py) -# endif() + message(STATUS "Generate setup.py file ...") + configure_file(setup.py.in setup.py) +endif() + + +#Install dir for python (default = --user) +execute_process( + COMMAND python -c "import site ; print site.USER_SITE" + OUTPUT_VARIABLE ${PROJECT_NAME}_INSTALL_DIR) +string(STRIP ${${PROJECT_NAME}_INSTALL_DIR} ${PROJECT_NAME}_INSTALL_DIR) +set(CMAKE_INSTALL_PREFIX ${${PROJECT_NAME}_INSTALL_DIR}) +# The file __init__.py will be generated from __init__.py.in. +if(EXISTS ${CMAKE_SOURCE_DIR}/parmepy/__init__.py.in) + message(STATUS "Generate __init__.py file ...") + configure_file(parmepy/__init__.py.in ${CMAKE_SOURCE_DIR}/parmepy/__init__.py) endif() set(PYTHON_EXECUTABLE python) +set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/build) -ADD_CUSTOM_TARGET(python-build COMMAND python ${CMAKE_CURRENT_BINARY_DIR}/setup.py build --user config_fc --f90exec=${CMAKE_Fortran_COMPILER} +ADD_CUSTOM_TARGET(python-build ALL COMMAND python ${CMAKE_CURRENT_BINARY_DIR}/setup.py build config_fc --f90exec=${CMAKE_Fortran_COMPILER} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "build parmepy package") ADD_CUSTOM_TARGET(python-install COMMAND python ${CMAKE_CURRENT_BINARY_DIR}/setup.py install --user config_fc --f90exec=${CMAKE_Fortran_COMPILER} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "build/install parmepy package") +ADD_CUSTOM_TARGET(python-cleaninstall COMMAND rm -rf ${${PROJECT_NAME}_INSTALL_DIR}/${PROJECT_NAME}* + COMMENT "remove parmepy package and its dependencies") + add_dependencies(python-build ${PARMES_LIBRARY_NAME}) add_dependencies(python-install ${PARMES_LIBRARY_NAME}) @@ -102,6 +116,7 @@ set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") # which point to directories outside the build tree to the install RPATH set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + # ============= Summary ============= if(VERBOSE_MODE) message(STATUS "====================== Summary ======================") @@ -110,7 +125,7 @@ if(VERBOSE_MODE) message(STATUS " Project uses MPI : ${USE_MPI}") message(STATUS " Project uses Scales : ${WITH_SCALES}") message(STATUS " Project uses PPM : ${WITH_PPM}") - message(STATUS " Project will be installed in ${CMAKE_INSTALL_PREFIX}") + message(STATUS " Python packages will be installed in ${${PROJECT_NAME}_INSTALL_DIR}") message(STATUS "====================== ======= ======================") endif() diff --git a/HySoP/INSTALL b/HySoP/INSTALL index 6db0240a304616ccca5dd53bc766887a9e140b1b..8caef903e5ed8d911943f77849019481b9c5c7b3 100644 --- a/HySoP/INSTALL +++ b/HySoP/INSTALL @@ -1,19 +1,95 @@ +=========================== +Parmepy package install +=========================== -1- create a "build" directory anywhere +1 - Introduction +2 - Configuration +3 - Build +4 - Install +5 - Summary +=================================================================================================================== +1 - Introduction -2- cmake path-to-sources-of-Parmes -DPPMCore_DIR=/home/perignon/install/ppmcore/share/CMake/ -DPPMNumerics_DIR=/home/perignon/install/ppmnumerics/share/CMake/ -3- make -j 8 +Requirements : -4- mpirun -np 8 ./parmesRun +- a fortran compiler and a proper mpi implementation +- fftw +- cmake > 2.8 +- a python implementation including numpy and mpi4py. +The install consists in 3 steps. First configuration of the package, makefile, setup.py and other files generation, then build of the underlying fortran libraries and of the python package and finally copy of the required files in the appropriate place. -Options : +We denote : -debug -> cmake -DCMAKE_BUILD_TYPE=Debug +- SOURCEDIR as the directory which contains the sources (and this INSTALL file) +- BUILDDIR the directory where the package will be configured and build +- INSTALLDIR the directory where the package will be installed. +Those 3 locations must be different. -verbose-> make VERBOSE=1 +=================================================================================================================== +2 - configuration : +You need to generate some makefile and a setup.py that fits with your platform, your compilers, +the libraries versions and so on. That will take place in BUILDDIR. + a - get SOURCEDIR (i.e. download the package any way you want) + b - create BUILDDIR. Any place, preferably local to your machine for efficiency reasons. + c - enforce a fortran compiler using FC environment variable + c - Change to BUILDDIR and run cmake +mkdir BUILDIR +cd BUILDDIR +export FC=mpif90 +cmake SOURCEDIR + +At the end of this step BUILDDIR contains all makefiles, setup.py and other required files for compilation. + +Some useful options for cmake : + +-DFFTW_DIR : where to find fftw if it's not in a "standard" place. +-DWITH_SCALES=ON/OFF : to compile a parmepy version including scales (default = on) +-DWITH_PPM=ON/OFF : to compile a parmepy version including scales (default = off) +-DWITH_TESTS=ON/OFF: enable testing (i.e. prepare target "make test", default = off) + +example : + +mkdir /home/mylogin/buildParmes +cd /home/mylogin/buildParmes +export FC=mpif90 +module load cmake-2.8 +cmake -DFFTW_DIR=/softs/install/fftw3.1 ~/Softs/Parmes + +=================================================================================================================== +3 - Build + +You need to build the underlying fortran libraries (mainly libparmes) and the python package. +Just run "make" to do both. +make python-build will run only python package building. + +=================================================================================================================== +4 - Install + +Run make python-install + +=================================================================================================================== +5 - Summary + +Default process : + +mkdir BUILDDIR +cd BUILDDIR +export FC=mpif90 +cmake SOURCEDIR +make -jN +make python-install + +Note : -jN for make command runs the build process on N processus. Choose a value of N that fits with your machine. + +Other useful commands : + +make python-cleaninstall : to remove all installed files for the current build. +make clean : to clean the build (remove modules, .o ...) + +=================================================================================================================== diff --git a/HySoP/hysop/__init__.py b/HySoP/hysop/__init__.py deleted file mode 100644 index 1e4759b42a4c6d978d2f1bea66955b9e6c92caa1..0000000000000000000000000000000000000000 --- a/HySoP/hysop/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -""" -@package ParMePy - -Python package dedicated to flow simulation using particular methods on hybrid architectures (MPI-GPU) - -""" -__version__=1.00 -__all__=['Box','CartesianTopology','ScalarField'] - -import constants - -import domain.box -## Box-type physical domain -Box = domain.box.Box - -## Cartesian grid -import fields.discrete -ScalarField = fields.discrete.ScalarField - -## MPI topologies and associated meshes -import domain.topology -CartesianTopology = domain.topology.CartesianTopology - -## Fields -import fields.discrete -ScalarField = fields.discrete.ScalarField diff --git a/HySoP/hysop/__init__.py.in b/HySoP/hysop/__init__.py.in new file mode 100755 index 0000000000000000000000000000000000000000..c190e9bb712ee9f8ad742dd996ad7ea11a5ddc68 --- /dev/null +++ b/HySoP/hysop/__init__.py.in @@ -0,0 +1,36 @@ +""" +@package ParMePy + +Python package dedicated to flow simulation using particular methods on hybrid architectures (MPI-GPU) + +""" +__version__=1.00 +__all__=['Box','CartesianTopology','ScalarField'] + +import os +import site +import mpi4py.MPI as MPI + +os.environ['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']+':'+"@CMAKE_INSTALL_PREFIX@" + +rank_world = MPI.COMM_WORLD.Get_rank() +if(rank_world == 0): + print "Starting @PACKAGE_NAME@ version "+str(__version__)+".\n" + +import constants + +import domain.box +## Box-type physical domain +Box = domain.box.Box + +## Cartesian grid + +## MPI topologies and associated meshes +import fields.topology +CartesianTopology = fields.topology.CartesianTopology + +## Fields +import fields.discrete +import fields.continuous +ScalarField = fields.discrete.ScalarField +ContinuousField = fields.continuous.ContinuousField diff --git a/HySoP/hysop/domain/box.py b/HySoP/hysop/domain/box.py index 2905edf4ba03929082e1cf5221893e502d969387..f08fdd47c479441806916ce6c5f43f927a19f97f 100644 --- a/HySoP/hysop/domain/box.py +++ b/HySoP/hysop/domain/box.py @@ -11,24 +11,24 @@ class Box(Domain): """ - def __init__(self,dimension=3,length=[1.0,1.0,1.0], minPosition=[0.,0.,0.]): + def __init__(self,dimension=3,length=[1.0,1.0,1.0], origin=[0.,0.,0.]): """ Constructor. Create a Box from a dimension, length and minimum position. Parameters dimensions must coincide. Raise ValueError in case of inconsistent parameters dimensions. @param length : Box length. - @param minPosition : Box minimum position. + @param origin : Box minimum position. """ - if not (dimension == len(length) and dimension == len(minPosition)): + if not (dimension == len(length) and dimension == len(origin)): raise ValueError("Box parameters inconsistents dimensions") Domain.__init__(self, dimension) ## Box length. length = max - min. self.length = np.array(length) ## Minimum Box position. - self.min = np.array(minPosition) + self.origin = np.array(origin) ## Maximum Box position. - self.max = self.min + self.length + self.max = self.origin + self.length # Boundary conditions type : self.boundaries = np.zeros((self.dimension)) self.boundaries[:] = PERIODIC @@ -42,7 +42,7 @@ class Box(Domain): def __str__(self): """ Doc display. """ s = str(self.dimension)+"D box (parallelepipedic or rectangular) domain : \n" - s += " minPosition : "+str(self.min)+", maxPosition :"+str(self.max)+", lengthes :"+str(self.length)+"." + s += " origin : "+str(self.origin)+", maxPosition :"+str(self.max)+", lengthes :"+str(self.length)+"." return s if __name__ == "__main__": diff --git a/HySoP/hysop/fields/continuous.py b/HySoP/hysop/fields/continuous.py index bad14fe29943c5239c56d071405d7b596e475a74..bfbbd78c507f8f7a4b435f9c1cbcc219bbc8e941 100644 --- a/HySoP/hysop/fields/continuous.py +++ b/HySoP/hysop/fields/continuous.py @@ -4,36 +4,51 @@ Continuous variable description """ +from .discrete import ScalarField + class ContinuousField(object): - """ - A variable defined on a physical domain - - """ + """ A variable defined on a physical domain """ - def __init__(self, dimension, domain): + def __init__(self,domain,name="?"): """ Constructor. Create a ContinuousField. - @param dimension integer : variable dimension. - @param domain : variable application domain. + @param domain : variable application domain. + @param name : name of the variable (used for vtk output). """ ## Application domain of the variable. self.domain = domain ## Field dimension. - self.dimension = dimension + self.dimension = self.domain.dimension ## Discretisation of this field self.discreteField = None - self.name = "" - - def discretize(self, spec=None): + ## Name of this field + self.name = name + # number of different discretizations + self.__fieldId = -1 + ## list of the various discretizations of this field + self.discreteField = [] + + def discretize(self,topology=None): """ - Abstract method. - Must be implemented by sub-class. - - @param spec : discretization specifications + discretization of the field on a topology + """ - raise NotImplementedError("Need to override method in a subclass of " + providedClass) + self.__fieldId += 1 + self.discreteField.append(ScalarField(topology,name=self.name+"_D_"+str(self.__fieldId),parent=self,idFromParent=self.__fieldId)) + return self.discreteField[self.__fieldId],self.__fieldId + + def __str__(self): + """ Field info display """ + s = self.name + ' , ' + str(self.dimension)+'D field with the following discretizations:\n' + if len(self.discreteField) != 0: + for i in range(len(self.discreteField)): + s += self.discreteField[i].__str__() + else : + s+="None." + return s + if __name__ == "__main__": print __doc__ diff --git a/HySoP/hysop/fields/discrete.py b/HySoP/hysop/fields/discrete.py index 3b2641b3169f5d94fc751b6df2b4d359ed7b015e..35a6f1c46531f74c7cb0d4ff4e8a12d5b4b2a83b 100644 --- a/HySoP/hysop/fields/discrete.py +++ b/HySoP/hysop/fields/discrete.py @@ -6,6 +6,7 @@ import numpy as np from ..constants import * +import evtk.hl as evtk class ScalarField(object): """ @@ -13,16 +14,22 @@ class ScalarField(object): """ - def __init__(self,topology,name=""): + def __init__(self,topology,name="?",parent=None,idFromParent=None): self.topology = topology self.name = name self.dimension = topology.domain.dimension resolution = self.topology.mesh.resolution - self.data = np.zeros((resolution),dtype=PARMES_REAL) + self.data = np.zeros((resolution),dtype=PARMES_REAL,order='F') + self.__parentField=parent + self.__idFromParent = idFromParent def __str__(self): """ Display class information """ - s = self.name+": "+str(self.dimension)+"D scalar field of shape " + str(self.data.shape) + s = '['+str(self.topology.rank)+'] ' + if(self.__parentField is not None): + s += " id "+ str(self.__idFromParent)+", " + s+= self.name+" "+str(self.dimension)+'D discrete field with resolution ' + s += str(self.data.shape)+"." return s + "\n" def __getitem__(self,i): @@ -37,6 +44,10 @@ class ScalarField(object): A[2,1,1] = 12.0 # Calls A.data[2,1,1] = 12.0 """ self.data.__setitem__(i,value) + + + def tofile(self,filename): + evtk.imageToVTK(filename, pointData = {"scalar" : self.data} ) class VectorField(object): """ @@ -68,9 +79,6 @@ class VectorField(object): A[2,1,1] = 12.0 # Calls A.data[2,1,1] = 12.0 """ self.data.__setitem__(i,value) - - - if __name__ == "__main__": print __doc__ diff --git a/HySoP/hysop/fields/topology.py b/HySoP/hysop/fields/topology.py index 14ad0c79cc3737fa1ece293960f435bd01e8267c..1eabed2883832f045ff1b0091d724e5eff5ad843 100644 --- a/HySoP/hysop/fields/topology.py +++ b/HySoP/hysop/fields/topology.py @@ -19,17 +19,26 @@ class CartesianTopology(object): - ghosts : number of poinst in the ghost layer """ - def __init__(self,domain,resolution,dim=3,comm=MPI.COMM_WORLD,periods=3*(True,),ghosts=np.zeros((3))): + def __init__(self,domain,resolution,dim=None,dims=None,comm=MPI.COMM_WORLD,periods=None,ghosts=None): - # Topology dimension - self.dim=dim ## Associated domain self.domain=domain # Compute the "optimal" processus distribution for each direction of the grid topology nbprocs = comm.Get_size() - self.dims=np.asarray(MPI.Compute_dims(nbprocs,dim)) + if(dims is None): + assert(dim is not None) + self.dims=np.asarray(MPI.Compute_dims(nbprocs,dim)) + # Topology dimension + self.dim=dim + else: + self.dims=np.asarray(dims) + self.dim = self.dims.size # Define the topology - self.topo = comm.Create_cart(self.dims,periods=periods[0:dim]) + # default period status is periodic + if(periods is None): + self.periods = self.dim*(True,) + self.topo = comm.Create_cart(self.dims,periods=self.periods) + # Size of the topology self.size = self.topo.Get_size() # Rank of the current process, in the new topology @@ -39,19 +48,20 @@ class CartesianTopology(object): # Neighbours # self.neighbours = np.zeros((dim,2)) self.down,self.up=self.topo.Shift(XDIR,1) - if(dim>1) : + if(self.dim>1) : self.west,self.east=self.topo.Shift(YDIR,1) - if(dim>2) : + if(self.dim>2) : self.south,self.north=self.topo.Shift(ZDIR,1) - # ghost layer - self.ghosts = ghosts[0:dim] + # ghost layer (default = 0) + if(ghosts is None): + self.ghosts = np.zeros((self.domain.dimension)) # Global resolution - self.resolution = resolution + self.resolution = np.asarray(resolution) nbpoints = self.resolution[:self.dim]//self.dims remainingPoints = self.resolution[:self.dim]%self.dims localResolution = self.resolution.copy() localResolution[:self.dim] = nbpoints - for i in range(dim): + for i in range(self.dim): if(self.coords[i] == self.dims[i]-1): localResolution[i] = nbpoints[i]+remainingPoints[i] start = np.zeros((domain.dimension)) diff --git a/HySoP/hysop/scales2py/scales2py.f90 b/HySoP/hysop/scales2py/scales2py.f90 index aa540b12aab21112bc314b5505daee8b2eba0528..6ac09b15b91ddd92f552e02ecd66681f687c418d 100755 --- a/HySoP/hysop/scales2py/scales2py.f90 +++ b/HySoP/hysop/scales2py/scales2py.f90 @@ -13,10 +13,11 @@ end module parmepyparameters !> Interface to scale code from Legi module scales2py -use cart_topology, only : cart_create,set_group_size,discretisation_create,N_proc,coord +use cart_topology, only : cart_create,set_group_size,discretisation_create,N_proc,coord,cart_rank use advec, only : advec_init,advec_step !!use precision, only : wp use parmepyparameters +use mpi implicit none @@ -76,9 +77,12 @@ contains real(mk), dimension(:,:,:), intent(in) :: Vx, Vy, Vz real(mk), dimension(:,:,:), intent(inout) :: scal character(len=*), optional, intent(in) :: dim_split + + real(mk) :: t0 + t0 = MPI_Wtime() call advec_step(timeStep,Vx,Vy,Vz,scal,dim_split) - + print *, "inside ...", cart_rank, ":", MPI_Wtime()-t0 end subroutine advecStep end module scales2py diff --git a/HySoP/setup.py.in b/HySoP/setup.py.in index 126ff240a0b87d5558bbfd70f99d1da72e1c2284..9720cc48ff40850f0b8536180d8478d69ddb3a3d 100644 --- a/HySoP/setup.py.in +++ b/HySoP/setup.py.in @@ -31,6 +31,7 @@ parmes_libdir=['@CMAKE_BINARY_DIR@/src'] parmeslib=['@PARMES_LIBRARY_NAME@'] #f2py_options=['-DF2PY_REPORT_ON_ARRAY_COPY'] f2py_options=['--no-lower'] +define_macros = [('F2PY_REPORT_ON_ARRAY_COPY','1')], sys.path.extend('config_fc -DF2PY_REPORT_ON_ARRAY_COPY'.split()) #,f2py_options=['-c --f90exec=/Users/Franck/Softs/install-gnu/openmpi-1.5.3/bin/mpif90']) #f2py_options=['skip: discretisation_init :'] @@ -43,9 +44,11 @@ sys.path.extend('config_fc -DF2PY_REPORT_ON_ARRAY_COPY'.split()) #parpyModule=Extension(name='ParMePy.scales2py',sources=fortran_src,include_dirs=[legi_dir],library_dirs=legi_lib,libraries=['parmeslegi']) #parpyModule=Extension(name='parpy',sources=fortran_src)#,f2py_options=f2py_options) -parpyModule=Extension(name='parmepy.fftw2py',f2py_options=f2py_options,sources=fortran_src,include_dirs=parmes_dir,library_dirs=parmes_libdir,libraries=parmeslib) +parpyModule=Extension(name='parmepy.fftw2py',f2py_options=f2py_options,sources=fortran_src,include_dirs=parmes_dir, + library_dirs=parmes_libdir,libraries=parmeslib,define_macros = [('F2PY_REPORT_ON_ARRAY_COPY','1')]) scales_src = glob.glob('@CMAKE_SOURCE_DIR@/parmepy/scales2py/*.f90') -scalesModule=Extension(name='parmepy.scales2py',f2py_options=f2py_options,sources=scales_src,include_dirs=parmes_dir,library_dirs=parmes_libdir,libraries=parmeslib) +scalesModule=Extension(name='parmepy.scales2py',f2py_options=f2py_options,sources=scales_src,include_dirs=parmes_dir, + library_dirs=parmes_libdir,libraries=parmeslib,define_macros = [('F2PY_REPORT_ON_ARRAY_COPY','1')]) #ppm_lib_dir=[os.path.join(ppm_dir,'lib')] #ppm_lib=['ppm_core'] diff --git a/HySoP/src/scalesInterface/particles/advec.f90 b/HySoP/src/scalesInterface/particles/advec.f90 index 7875217db9e6814ca7d3f3cce0a8c21f187e8bbe..a7013979d119df691d159da4809dd4285d8e6eec 100644 --- a/HySoP/src/scalesInterface/particles/advec.f90 +++ b/HySoP/src/scalesInterface/particles/advec.f90 @@ -132,27 +132,29 @@ subroutine advec_step(dt, Vx, Vy, Vz, scal, dim_split) if (type_solv=='spectral') then print*, 'Solveur non implémenté' end if - - select case(splitting) - case('classic') - call advecX_calc(dt, Vx, scal, type_part_solv) - call advecY_calc(dt, Vy, scal, type_part_solv) - call advecZ_calc(dt, Vz, scal, type_part_solv) - case('Strang') - call advecX_calc(dt/2.0, Vx, scal, type_part_solv) - call advecY_calc(dt/2.0, Vy, scal, type_part_solv) - call advecZ_calc(dt/2.0, Vz, scal, type_part_solv) - call advecZ_calc(dt/2.0, Vz, scal, type_part_solv) - call advecY_calc(dt/2.0, Vy, scal, type_part_solv) - call advecX_calc(dt/2.0, Vx, scal, type_part_solv) - case default - call advecX_calc(dt/2.0, Vx, scal, type_part_solv) - call advecY_calc(dt/2.0, Vy, scal, type_part_solv) - call advecZ_calc(dt/2.0, Vz, scal, type_part_solv) - call advecZ_calc(dt/2.0, Vz, scal, type_part_solv) - call advecY_calc(dt/2.0, Vy, scal, type_part_solv) - call advecX_calc(dt/2.0, Vx, scal, type_part_solv) - end select + + print *, "salut", dt, minval(Vx),maxval(Vx),minval(scal),maxval(scal) + call advecX_calc(dt, Vx, scal, type_part_solv) +!!$ select case(splitting) +!!$ case('classic') +!!$ call advecX_calc(dt, Vx, scal, type_part_solv) +!!$ call advecY_calc(dt, Vy, scal, type_part_solv) +!!$ call advecZ_calc(dt, Vz, scal, type_part_solv) +!!$ case('Strang') +!!$ call advecX_calc(dt/2.0, Vx, scal, type_part_solv) +!!$ call advecY_calc(dt/2.0, Vy, scal, type_part_solv) +!!$ call advecZ_calc(dt/2.0, Vz, scal, type_part_solv) +!!$ call advecZ_calc(dt/2.0, Vz, scal, type_part_solv) +!!$ call advecY_calc(dt/2.0, Vy, scal, type_part_solv) +!!$ call advecX_calc(dt/2.0, Vx, scal, type_part_solv) +!!$ case default +!!$ call advecX_calc(dt/2.0, Vx, scal, type_part_solv) +!!$ call advecY_calc(dt/2.0, Vy, scal, type_part_solv) +!!$ call advecZ_calc(dt/2.0, Vz, scal, type_part_solv) +!!$ call advecZ_calc(dt/2.0, Vz, scal, type_part_solv) +!!$ call advecY_calc(dt/2.0, Vy, scal, type_part_solv) +!!$ call advecX_calc(dt/2.0, Vx, scal, type_part_solv) +!!$ end select end subroutine advec_step