Input files specification

Rhoxyz, version 2020.3

File format

JavaScript Object Notation (JSON) open–standard file format, that uses human readable text in form of attribute–value pairs and array data types, is used as an input for the solver. Graphical setting up of simulations may be implemented, but JSON format is intuitive enough to make as rapid changes as graphical interface could.

The table describing data types used for parameters is given below:

NameDescriptionExample
integerSimple non-decimal value.3
numberAny decimal or non-decimal value.1.234
stringText stored in quotes."this is a string"
list of numbersList of any number of values.[3.2, 4, 566.3, 0.0]
list of stringsList of quoted texts.["qwe", "asd", "xcv"]
vectorList of 2 or 3 numbers.[2.0, 44.53, 0.0]
timeline of scalarsList of time–scalar pairs.[ [0, 2.0], [1.2, -1.0] ]
timeline of vectorsList of time–vector pairs.[ [0, [2.0, 2.3]], [1.2, [-1.0, 2.1]] ]
booleanValue saying something is enabled or disabled.true or false
objectSomething that contains multiple data information."object_name": { data goes here }

Note: When a default value is available for some parameter, user does not need to specify the parameter (unless they want to override it).

Note: The document is an object, i.e. it must start with curly brackets ’{’ and ’}’. Also, the last element in a list or object must not have comma after its definition.

General parameters

Global parameters of the simulation are listed as follows:

Parameter nameData typeDefault valueWhat to input
“dimensions”integermust be specified2 (for 2D simulations) or 3 (for 3D simulations).
“precision”stringsingleMachine representation of numbers. single (for 32-bit precision) double (for 64-bit precision).
“description”stringOptional textual description of the simulation.
“name”stringfile nameThe name of the simulation is by default same as the file name. User can override it.
“device”stringbestOn which device to execute the simulation. cpu (to use CPU cores) gpu (to execute it on a NVIDIA GPU) best to execute on the best device in the system.

Note: The modern GPU can execute simulations > 20 times faster than the modern CPU. This holds for typical GPUs optimized for 32-bit precision operations (GTX, RTX, etc.). If double precision is needed, GPUs like Quadro, Tesla, etc. will perform better.

Note: 32-bit precision is usually enough if fast approximated/engineering results are needed. For extra large simulations, the implementation of accurate computation independent of precision is a work-in-process.

Example: JSON file with some general parameters.

   {
      "description": "Sway sloshing experiment blah blah",
      "dimensions": 3,
      "precision": "single",

  ... other parameters go here ...

  }

Relaxation

Relaxation is tightly connected to the scheme and pressure parameters. It says how strong factors dictate the simulation convergence within the time step.

“relaxation”: {

Parameter nameData typeDefault valueWhat to input
“space”number1.0How strong to force divergence cleaning based on the points arrangement information.
“time”number1.0How strong to force divergence cleaning in the current time step.
“walls”number1.0How strong to adapt to no-slip boundary condition in a single time step, i.e. adapt fluid acceleration near wall to the wall movement.
“diagonal”number0.0How much to relax or smooth–out the system of linear equations (and the solution), by artificially scaling matrix diagonal to achieve better diagonal dominance. This should be a small number, e.g. from 1e-6 up to 1e-4.

}

Note: The scheme takes minimum value of space– and time–based relaxation. Space–based relaxation is preferable, since it’s less prone to induce oscillations.

Note: Diagonal scaling may help solvability of the system of equations, but yields a bit lower or smoothed out results than they should be.

Example:

   "relaxation": {
      "space": 0.9,
      "walls": 1.0
  }

Pressure

Smooth and accurate pressure field is obtained by solving a Poisson equation. The equation is transformed to a system of linear equations, which is solved by using an iterative solver.

“pressure”: {

Parameter nameData typeDefault valueWhat to input
“solver”stringbicgstabType of the iterative solver: bicgstab non-preconditioned BiCGStab pbicgstab diagonally-preconditioned BiCGStab qmrcgstab non-preconditioned QMRCGStab pqmrcgstab diagonally-preconditioned QMRCGStab cg non-preconditioned CG pcg diagonally-preconditioned CG jacobi Jacobi solver
“max_iterations”integer150Maximum number of iterations for trying to reach error lower than specified.
“max_error”number1e-3Tolerance or maximum allowed relative error trying to be reached.
“gradient_limiter”number0.0How much to limit overshooting within strong pressure gradient-areas. It is usually a value between 0.0 and 2.0, where higher values may be used for violent pressure fields to achieve large time-steps.

}

Example:

   "pressure": {
      "solver": "bicgstab",
      "max_iterations": 300,
      "max_error": 1e-4,
      "gradient_limiter": 1.0
  }

Velocity

Velocity is calculated from the momentum equation. For convection-dominated flows, it may be calculated directly, by explicitly approximating the diffusion. For diffusion-dominated flows, the velocity field should be solved implicitly using an iterative solver.

“velocity”: {

Parameter nameData typeDefault valueWhat to input
“solver”stringexplicitType of the solver: explicit for solving velocity explicitly jacobi implicit Jacobi solver
“max_iterations”integer100If using the implicit solver, maximum number of iterations trying to reach error lower than specified.
“max_error”number1e-4If using the implicit solver, maximum allowed relative error trying to be reached.

}

Example:

   "velocity": {
      "solver": "jacobi",
      "max_iterations": 300,
      "max_error": 1e-4
  }

Resolution

This category specifies the spacing between nearest neighbors, and the interaction radius. Each point can be connected to only first ring of its neighbours (fast, less diffusive), but better stability may be achieved by enlarging the radius to reach second ring of its neighbours (slower, more diffusive).

“resolution”: {

Parameter nameData typeDefault valueWhat to input
“spacing”numbermust be specifiedThe initial spacing between neighbouring points. This is analogous to the base cell size in mesh–based methods.
“truncation”number1.8Interaction radius in terms of “number of spacings” to reach neighbouring points. It should be a value between 1.3 and 2.9.

}

Note: Currently the point cloud resolution is constant in space and time, adaptive refinement is work in progress.

Example:

   "resolution": {
      "spacing": 0.02,
      "truncation": 2.1
  }

Reordering

Each time step points perform Lagrangian advection, i.e. they move along solved streamlines. It can lead to distortion of the point distribution, and therefore mass conservation errors (imagine a rotating disc where points move in the tangential direction and increase the volume of the disc). On the Lagrangian movement, points are trying to keep equidistant neighbours to optimally conserve mass at all time.

“reordering”: {

Parameter nameData typeDefault valueWhat to input
“iterations”integer4Number of iterations to converge to constant neighbour spacing. The number may be from 1 to 20.
“radius”number1.5Interaction radius in terms of “number of spacings” for optimizing the point spacing. The value may be from 1.35 up to 1.80.
“compression”number1.0Allowed relative compression compared to the initial neighbourhood. Smaller compression may lead to better, but more aggressive re-organization of points.

}

External acceleration

Here we use term gravity as constant acceleration imposed to whole fluid in the domain, at all time. On the other hand, user may impose variable domain movement, which yields variable domain acceleration in time. This may be achieved by setting movement keyframes, or by analytically defining harmonic oscillator.

Note: During the simulation, gravity constant, keyframe motion, and oscillation motion are superposed.

Parameter nameData typeDefault valueWhat to input
“gravity”vector[0, 0, 0]Constant external acceleration vector.
“impose_position”timeline of vectors[]Domain position keyframes. Converted to external acceleration by second derivative.
“impose_velocity”timeline of vectors[]Domain velocity keyframes. Converted to external acceleration by first derivative.
“impose_acceleration”timeline of vectors[]Directly impose acceleration
“impose_oscillation”object{}See explanation below.

The harmonic oscillator object is created as follows:

“impose_oscillation”: {

Parameter nameData typeDefault valueWhat to input
“frequency”numberOscillation frequency, rad/s. Not needed if the period is specified.
“period”numberOscillation period, s. Not needed if the frequency is specified.
“direction”vectorVector specifying the direction of translationj. It’s magnitude defines the amplitude of movement.
“axis”vectorVector specifying the axis of rotation. It’s magnitude defines the amplitude of movement.
“damping”numberDamping ratio.

}

Note: Setting domain rotation through keyframes is work-in-progress.

Domain

The domain is an axis-aligned minimum bounding box (or AABB), defined by the starting and ending coordinates of its diagonal. It specifies the space where fluid flow is allowed. Currently, the domain size is static, dynamic adaptation of the domain size will be implemented.

“domain”: {

Parameter nameData typeDefault valueWhat to input
“min”vectormust be specifiedMinimum coordinates of the domain AABB.
“max”vectormust be specifiedMaximum coordinates of the domain AABB.

}

Note: Points leaving the domain boundaries are removed from the simulation.

Note: Performance will suffer if user specifies too large domain compared to the space of the fluid body.

Example:

   "domain": {
      "min": [0, 0, 1],
      "max": [5, 1, 3.2]
  }

Patches

The simulation input file does not incorporate any volumetric mesh, but only bounding surfaces (patches) of the domain and objects in the scene. These surfaces can be defined using primitives (list of connected line–segments, quadrilaterals) or imported from the commonly used mesh file formats. Patches can be moveable, i.e. their motions can be imposed similarly as domain motions.

Note: The input is an object patches containing any number of named boundary surfaces.

“patches:” {

“name_of_patch:” {

Parameter nameData typeDefault valueWhat to input
“type”stringsolidType of the boundary surface. Currently available values are: solid that marks walls free_surface that marks the free boundary of the fluid body
“cog”vector[0, 0, 0]Initial center-of-gravity location around which the object rotates, and calculates the torque.
“geometry”stringmust be specifiedHow to define the geometry of the patch: polyline to define 2D connected line segments triangle to define a single 3D triangle quad to define a single 3D quad box to define a 3D box mesh_relative_path.stl to load triangulated 3D surface from STL format mesh_relative_path.obj to load triangulated 3D surface from OBJ format mesh_relative_path.off to load triangulated 3D surface from OFF format
“position”vector[0, 0, 0]Initial translation.
“rotation”vector[0, 0, 0]Initial rotation.
“points”list of vectors[]Manually input list of: vertices for the polyline, triangle or quad, min and max vertices for 3D box (like the domain is defined)
“probes”list of vectors[]List of positions where to measure the pressure. The specified probes move with the patch.
“impose_position”timeline of vectors[]Impose motion of the patch as translation keyframes.
“impose_velocity”timeline of vectors[]Impose motion of the patch as translation velocity keyframes.
“impose_acceleration”timeline of vectors[]Impose motion of the patch as translation acceleration keyframes.
“impose_rotation”timeline of vectors[]Impose motion of the patch as translation keyframes.
“impose_angular_velocity”timeline of vectors[]Impose motion of the patch as translation velocity keyframes.
“impose_angular_acceleration”timeline of vectors[]Impose motion of the patch as translation acceleration keyframes.
“impose_oscillation”object{}See explanation above in section Domain.

},

“another_patch: { … }”

}

Note: Generally, it’s not wise to use STL meshes (anywhere!) as they do not incorporate triangle connectivity information. The solver automatically connects triangles in such case.

Example:

   "patches": {
      "tank": {
          "type": "solid",
          "geometry": "polyline",
          "points": [
              [-0.3, 0.3], [-0.3, 0.0], [ 0.3, 0.0], [ 0.3, 0.3], [-0.3, 0.3]
          ],
          "oscillation": {
              "period": 1.5,
              "direction": [0.05, 0]
          },
          "probes": [
              [-0.3, 0.1],
              [0.3, 0.1]
          ]
      },

      "water": {
          "type": "free_surface",
          "geometry": "polyline",
          "points": [ [-1, 0.12], [1, 0.12] ]
      }
  }

Fluid

Currently a single fluid phase is supported, but soon multi-phase and variable-phase calculation will be implemented. The specified single fluid moves in the domain specified above. When the boundary surfaces are defined, user may fill the domain space with fluid.

Note: The fluid set-up follows the same as idea as bucket fill or flood fill tools in painting programs. Fluid is filled from some source point until it reaches wall and free-surface boundaries, defined above.

Parameter nameData typeDefault valueWhat to input
“density”number1000Constant density of the fluid phase.
“viscosity”number1e-6Constant kinematic viscosity of the fluid phase.
“surface_tension”number0.0Surface tension coefficient between the fluid phase and (unmodeled) other light phase.
“flood_point”vector[]The point where to start flooding from.
“flood_points”list of vectors[]If multiple separated spaces need to be filled with same fluid, then specify a list of points where to flood from.
   "fluid": {
      "density": 998.6,
      "viscosity": 1.14e-6,
      "flood_point": [0.0, 0.05]
  }

Output

Besides real-time viewing of the results, the results may be written to hard drive to postprocess them in another software. Currently the results may be written to VTK legacy ASCII file–format, which can be read by ParaView.

Parameter nameData typeDefault valueWhat to input
“time_step”numberTime interval to repeatedly output results. Zero value ignores outputting.
“times”list of numbersIf not via the time–step, user may require simulation to write its results at specific times.
“boundary_points”booleantrueWhether to export points generated for boundary conditions or not.
“fields”list of strings["pressure", "velocity"]List of solved information to export. Available values are: pressure pressure_gradient velocity velocity_divergence vorticity

Note: The folder for outputting is created where the input file is located.

Note: Along with output fields, the solver writes: log, forces & torques, pressure probes.

Example:

   "output": {
      "time_step": 0.2,
      "times": [0.1666, 1.53],
      "fields": ["velocity", "vorticity"]
  }