.. tutmathematica: **************************** Pencil Mathematica Tutorials **************************** Here you can find some tutorials on using Mathematica for post-processing. Loading the package =================== We need to modify ``init.m`` so that the path to the package is automatically added to the ``$Path`` variable in Mathematica. First, type .. code:: FileNameJoin[{$UserBaseDirectory, "Kernel", "init.m"}] in Mathematica to locate this ``init.m`` file. Then, add lines .. code:: AppendTo[$Path, "your/pencil/home/mathematica"] AppendTo[$Path, "your/pencil/home/mathematica/special"] in this file and save it. In general the path will be ``$PENCIL_HOME/mathematica/``, but of course you may put it somewhere else. Mathematica will not search in subdirectories, so make sure the package in right in the folder. After updating ``init.m``, restart the Mathematica kernel (``Evaluation`` -> ``Quit Kernel``). To use the package, call ``Needs["pc`"]`` and then ``pcInitialize[]`` in a notebook or a script. To use the package on subkernels, call ``pcParallelize[n]``. This will launch ``n`` subkernels and load the package on each of them. Then you can do things like ``ParallelTable[readTS[...],...]``. Only loading the package on the master kernel is not enough. See the discussions `here `_, and the 'Possible issues' section `here `_. Each time you have updated the data, remember to do ``pcInitialize[]`` and ``pcParallelize[n]`` again. These two functions remove some persistent variables defined. Pencil Code Commands in General =============================== For a list of all Pencil Code commands, load the package and type ``pcFunction[]``. To access the help of any command just type '?' followed by the command, e.g. ``?readTS``. You can also check the full definition of the command by typing '??' followed by the command. Reading and Plotting Time Series ================================ To read the time series, type .. code:: data = readTS[sim,var1,var2,...] where ``var1``, ``var2`` etc. are entries in the time series. The return of the right side is a ``List`` object, with its elements corresponding to ``var1``, ``var2`` etc. You can then access, for example, the time series of ``var2`` through ``data[[2]]`` (indexing in Mathematica starts from ``1``). Alternatively, you may also put a ``List`` object on the left side so that ``var1``, ``var2`` etc. will be assigned to each of its elements. For example, .. code :: {t,urms} = readTS[sim,"t","urms"] Make sure that ``Length`` of the left side is equal to the number of ``var``; otherwise Mathematica will complain. To plot the data, you can say .. code :: fig = ListPlot[Transpose[{t,urms}],Joined->True] or, in a one-line command, .. code :: (** same as ListPlot[Transpose[readTS[sim,"t","urms"]]] **) fig = readTS[sim,"t","urms"]//Transpose//ListPlot A few options for some internal plotting functions have been reset by the package. For details check ``??pcLabelStyle`` and ``??pcPlotStyle``. To export the figure in ``.eps`` format, .. code :: Export["directory/to/export/figure.eps",fig] Reading VAR files ================================ VAR files can be read using .. code :: data = readVARN[sim,iVAR] Here ``iVAR`` is the index of the VAR file and starts from 0. By default, ghost zones will not be trimmed. You can do it using the option ``"ltrim"->True``, or ``"ltrim"->More``; the latter will trim ``2*nghost`` cells on each boundary. To compute "magic" variables, you can use .. code :: data = readVARN[sim,iVAR,{"oo","bb","jj"}] Here "oo", "bb", "jj" refer to vorticity, magnetic, and current fields, respectively. The return of ``readVARN`` is an ``Association`` object (i.e., ``Head[data]=Association``). You can obtain all of its keys by ``Keys[data]``. Here is an example of its return: .. code :: data = readVARN[sim,iVAR,{"oo","bb","jj"}]; Keys[data] (* {"t", "dx", "dy", "dz", "deltay", "lx", "ly", "lz", "x", "y", "z", "uu1", "uu2", "uu3", "lnrho", "ooo1", "ooo2", "ooo3", "bbb1", "bbb2", "bbb3", "jjj1", "jjj2", "jjj3"} *) Magic variables are named using triple characters, to avoid shadowing the auxilliary ones written by the code (which will be "oo1" etc.). The ``x`` coordinates of the mesh points is then ``data["x"]``, which will have length ``(16+6)^3`` if the resolutoin is ``16^3`` and ``nghost=3``. One can form a three-dimensional map of ``uu1`` using .. code :: uu1 = Transpose[ data/@{"x","y","z","uu1"} ]; (* {{x1,y1,z1,f1},{x2,y2,z2,f2},...} *) Sometimes the following method is also useful: .. code :: Clear[uu1] grid = Transpose[ data/@{"x","y","z"} ]; uu1 = Association[ Thread[ grid->data["uu1"] ] ]; Then ``uu1`` becomes a "function" and its value at ``{x1,y1,z1}`` is simply ``uu1[{x1,y1,z1}]``. Visualizing slices from VAR files =================================== A quick way to make a density plot from ``data`` is .. code :: showSlice[data, "uu1", {"z", 0.2}] Here ``{"z",0.2}`` instructs to plot the ``xy`` slice closest to ``z=0.2``. For vector fields one can also use .. code :: showSliceVector[data, "uu", {"z", 0.2}] Notice the second argument is just ``"uu"`` with no index. The function then makes a density plot of the out-of-plane component of (here ``"uu3"``), and a superposed vector plot of the in-plane components (here ``"uu1"`` and ``"uu2"``). Reading video files ================================ To read video or slice files, one uses .. code :: {slices,times,position}=readSlice[sim,"uu1","xy2"] The returned ``slices`` variable is a ``List`` of all slices at different times, and can be visualized by, say, ``DensityPlot[ slices[[1]] ]``. ``position`` tells you the spatial coordinate of the slices. Here is an example to make a video: .. code :: Clear[makeFrame] makeFrame[ slice_,time_ ] := DensityPlot[ slice, PlotLabel->"t="<>ToString@time] frames = MapThread[ makeFrame, {slices,times} ]; (* to view the video in the notebook; can be slow if too many frames*) ListAnimate[ frame, AnimationRunning->False ] (* output to a movie file *) Export[ "your/output/directory/video.mov", frames, FrameRate->24 ] One can also visualize variables in a 3D box. For more information see the comments of ``makeBox`` and ``makeBoxes``. Running on supercomputers ================================ First, make sure Mathematica is available on the machine. You can check this by saying ``which wolfram`` in the terminal. If it is not installed, contact your administrator to see if it can be loaded. Once you have loaded the Mathematica module, try ``wolfram`` in the terminal. It should bring you to the text-based interface of Mathematica. You can then follow the steps in the previous sections to set up the package. There is a sample script in the directory ``$PENCIL_HOME/mathematica/sample_script.wls``. Modify its first line according to where your ``wolfram`` is. Remember to include the ``-script`` option. To run a script, use ``wolframscript your_script.wls``.