Defining a new SETUP ===================== This section is a small tutorial on how to define a setup from scratch. In this tutorial we will implement a hydrodynamics setup. The setup we will define is "blob", that comes implemented in the public version of FARGO3D. Blob test ---------- This is a 2D test characterized by a uniform fluid, with a denser fluid disk embedded. The system is force-balanced (ie in pressure equilibrium) if there is no velocity between the two fluids. The disk is moving at a supersonic speed. In order to compare our results, we will develop the same parameters as http://www.astrosim.net/code/doku.php?id=home:codetest:hydrotest:wengen:wengen3. Parameters of the test: * Mach number: 2.7 * Density jump: 10 * Pressure equilibria * gamma: 5/3 We will do the test in the XY plane, and we will implement periodic boundaries in X and reflexive boundaries in Y. We will do a second test with free outflow boundaries in Y. In order to implement this setup we need: 1) A setup name: In this case will be "myblob". 2) Therefore a directory inside ``setups/`` called ``myblob``. 3) the ``.bound`` file in that directory, called ``myblob.bound.0``. 4) the ``.par`` file in that directory, called ``myblob.par``. 5) the ``.opt`` file in that directory, called ``myblob.opt``. 6) the file called ``condinit.c`` in that directory. This is where the fields are initialized. Optionally: * the ``.units`` file, called ``myblob.units``. * the ``.mandatory`` file, called ``myblob.mandatory``. * the ``.objects`` file, called ``myblob.objects``. * A ``boundaries.txt`` file (if it is not present it will be taken from the ``std/`` directory). Making the setup directory: ..................................................... We start by creating the setup directory ``myblob``:: $: cd setups/ $: mkdir myblob Defining boundaries: ....................................... We define from scratch all the boundaries in the setup. In order to do that we create a file called ``boundaries.txt`` inside ``setups/myblob/``:: $: emacs boundaries.txt Naturally, you may use your favorite editor instead of emacs... Now, we write these lines:: SYMMETRIC: Centered: |a|a| Staggered: |a|a|a| ANTISYMMETRIC: Staggered: |-a|0|a| We will use the SYMMETRIC boundary for both reflective and free outflow boundaries, and ANTISYMMETRIC only for the normal velocity Vy in the reflective case. We must create the file myblob.bound:: $: emacs myblob.bound.0 And write this lines:: Density: Ymin: SYMMETRIC Ymax: SYMMETRIC Energy: Ymin: SYMMETRIC Ymax: SYMMETRIC Vx: Ymin: SYMMETRIC Ymax: SYMMETRIC Vy: Ymin: ANTISYMMETRIC Ymax: ANTISYMMETRIC We say that all our fields are symmetric, but vy should be reflected in Y. This set is the reflective boundary condition on Y. The free outflow is the same, except for:: Vy: Ymin: SYMMETRIC Ymax: SYMMETRIC .. _parfile: Defining the parameter file ..................................................... The parameter file is very useful when we want to change a value inside the code but you do not want to recompile the code. It is used in much the same way as with the former FARGO code. Yet in that code, parameters were defined in a rather manual way, in a file called ``var.c``. With FARGO3D we do not have to edit this file. Rather, we provide in the SETUP sub directory a template parameter file that has same name as the setup plus the .par extension. From this file, a Python script will automagically draw a list of all global variables and guess their type, and will make a ``var.c`` accordingly, in a manner transparent to the user. At run time the user is free to run the code either with this .par file, or any other .par file in another directory, without rebuilt. There are a set of minimal requirement in a .par file, related with the mesh size, and output parameters. We will start with the basic parameters: We edit the new file ``myblob.par``:: $: touch myblob.par and write inside something similar to:: Setup myblob Nx 400 Ny 100 Xmin -2.0 Xmax 2.0 Ymin -0.5 Ymax 0.5 Ntot 1000 Ninterm 1 DT 0.05 OutputDir outputs/myblob .. warning:: Because a Python script will automagically create a ``var.c`` file (similar to that of the former FARGO code) out of this newly created parameter file, we must help the script to guess correctly the type of each variable. For instance, if we write "Xmin -2" instead of "Xmin -2.0", it will wrongly deduce that *Xmin* is an integer, not a floating point value, with highly unpleasant consequences at run time. Similarly, the figure "-0.5" is correctly recognized by the script, but "-.5" would not be. Now, we will define the parameters specific to our setup. They are:: gamma 1.666667 rho21 10.0 mach 2.7 rblob 0.15 xblob -1.0 yblob 0.0 where gamma is the adiabatic index, rho21 is the quotient between the density in the circle (2) and outside (1), and the same for the temperature; rblob is the radius of the initial blob, normalized by the vertical size of the box; [xy]blob is the initial position of the blob. The observant reader will notice that *gamma* is already defined in ``std/stdpar.par``, with the same value. Since both sets of parameters are used (those of ``std/stdpar.par`` and those of ``setups/myblob/myblob.par``), the first line in the block above is actually redundant and could have been omitted. .opt file. .......... Our setup is 2D, and we want to use the energy equation. In the code's jargon, we refer to this as an *adiabatic* situation. We work in Cartesian coordinates:: $: emacs myblob.opt The minimal ``.opt`` file should be similar to:: FLUIDS := 0 NFLUIDS = 1 FARGO_OPT += -DNFLUIDS=${NFLUIDS} FARGO_OPT += -DX FARGO_OPT += -DY FARGO_OPT += -DADIABATIC FARGO_OPT += -DCARTESIAN ifeq (${GPU}, 1) FARGO_OPT += -DBLOCK_X=16 FARGO_OPT += -DBLOCK_Y=16 FARGO_OPT += -DBLOCK_Z=1 endif If you want to use simple precision, you can set:: FARGO_OPT += -DFLOAT Initial state: -------------- Now we must fill all the primitive fields with the initial conditions. The standard method is as follow, step by step: 1) Make a file called condinit.c inside your setup directory. (setups/myblob/condinit.c). 2) At the top of this file include the ``fargo3d.h`` header. 3) Define a function called CondInit() that returns a ``void``. 4) Fill the Field_variable->field_cpu with the data, for each field of the problem. **step by step** 1) Start by opening the new file for initial conditions:: $: emacs condinit.c 2) In the top line include FARGO3D's header file:: #include "fargo3d.h" 3) Subsequently add lines similar to these:: void Init() { } 4) Write inside the function something similar to:: int i,j,k; real* rho = Density->field_cpu; real* vx = Vx->field_cpu; real* vy = Vy->field_cpu; real* e = Energy->field_cpu; i = j = k = 0; for (k = 0; kfield_cpu; real* vx = Vx->field_cpu; real* vy = Vy->field_cpu; real* e = Energy->field_cpu; #define Q1 (xmed(i) - XBLOB) #define Q2 (ymed(j) - YBLOB) i = j = k = 0; for (k = 0; k