commit 4a0f56a691eb27017d8f349f92350c1ad5af9a0c
parent 3539f5feb76e5e3fd4c9df894e55ba6c52f7d8b3
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 24 Apr 2026 18:25:17 +0200
Convert man pages to the mandoc format
Diffstat:
10 files changed, 2569 insertions(+), 2211 deletions(-)
diff --git a/doc/solstice-input.5 b/doc/solstice-input.5
@@ -0,0 +1,1327 @@
+.\" SPDX-License-Identifier: GPL-3.0-or-later
+.\" Copyright (C) 2016-2018 CNRS, 2018-2019 |Méso|Star>
+.\"
+.\" This is free documentation: you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation, either version 3 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
+.Dd $Mdocdate$
+.Dt SOLSTICE-INPUT 5
+.Os
+.Sh NAME
+.Nm solstice-input
+.Nd solar plant description for solstice
+.Sh DESCRIPTION
+The
+.Nm
+format is used by the
+.Xr solstice 1
+program to represent a solar plant.
+It relies on the YAML 1.1 data serialization standard
+.Po
+see
+.Sx NOTES ,
+reference 1
+.Pc ;
+assuming that the file is compatible with the
+.Nm
+semantic, a solar plant can be described by using the whole YAML 1.1
+functionalities including compact notation and data tagging.
+.Pp
+A solar plant is composed of a
+.Em sun ,
+an optional
+.Em atmosphere
+and a collection of
+.Em geometries ,
+i.e.\&
+.Em shapes
+with their associated
+.Em material .
+Beside the raw description of the aforementioned data, the
+.Nm
+format provides the
+.Em entity
+item to efficiently structure the geometries in the scene.
+An entity is a node in a tree data structure where the position of each
+child entity is relative to the position of its parent.
+An entity can either encapsulate a
+.Em geometry
+or a
+.Em pivot
+that controls the dynamic positioning of its child entities with respect
+to the pivot constraints and the sun direction submitted to the
+.Xr solstice 1
+program.
+.Sh GRAMMAR
+.Bd -literal
+<solar-plant> ::= - <sun>
+ - <item>
+ [ - <item> ... ]
+ [ - <atmosphere> ]
+
+<item> ::= <entity>
+ | <geometry>
+ | <material>
+ | <medium>
+ | <spectrum>
+ | <template>
+.Ed
+.Bd -literal
+<geometry> ::= geometry:
+ - <object>
+ [ - <object> ... ]
+
+<object> ::= <shape>
+ <material>
+ [ <transform> ]
+
+<x_pivot> ::= x_pivot:
+ <target>
+ [ ref_point: <real3> ] # Default is [0,0,0]
+
+<zx_pivot> ::= zx_pivot:
+ <target>
+ [ spacing: REAL ] # in [0, INF). Default 0
+ [ ref_point: <real3> ] # Default is [0,0,0]
+
+<target> ::= target:
+ anchor: <anchor-identifier>
+ | direction: <real3>
+ | position: <real3>
+ | <sun>
+.Ed
+.Bd -literal
+<shape> ::= <cuboid>
+ | <cylinder>
+ | <hemisphere>
+ | <hyperbol>
+ | <parabol>
+ | <parabolic-cylinder>
+ | <plane>
+ | <sphere>
+ | <stl>
+
+<cuboid> ::= cuboid:
+ size: <real3> # in ]0, INF]^3
+
+<cylinder> ::= cylinder:
+ height: REAL # in ]0, INF)
+ radius: REAL # in ]0, INF)
+ [ slices: INTEGER ] # in [4, 4096]. Default is 16
+ [ stacks: INTEGER ] # in [1, 4096]. Default is 1
+
+<hemisphere> ::= hemisphere:
+ radius: REAL # in ]0, INF)
+ [ clip: <polyclip-list> ]
+ [ slices: INTEGER ] # in [4, 4096]
+
+<hyperbol> ::= hyperbol:
+ focals: <hyperboloid-focals>
+ clip: <polyclip-list>
+ [ slices: INTEGER ] # in [4, 4096]
+
+<parabol> ::= parabol:
+ focal: REAL # in ]0, INF)
+ clip: <polyclip-list>
+ [ slices: INTEGER ] # in [4, 4096]
+
+<parabolic-cylinder> ::= parabolic-cylinder:
+ focal: REAL # in ]0, INF)
+ clip: <polyclip-list>
+ [ slices: INTEGER ] # in [4, 4096]
+
+<plane> ::= plane:
+ clip: <polyclip-list>
+ [ slices: INTEGER ] # in [1, 4096]. Default is 1
+
+<sphere> ::= sphere:
+ radius: REAL # in ]0, INF)
+ [ slices: INTEGER ] # in [4, 4096]. Default is 16
+ [ stacks: INTEGER ] # in [2, 4096]. Default is slices/2
+
+<stl> ::= stl:
+ path: PATH
+
+<hyperboloid-focals> ::= real: REAL # in ]0, INF)
+ image: REAL # in ]0, INF)
+.Ed
+.Bd -literal
+<polyclip-list> ::= - <polyclip>
+ [ - <polyclip> ... ]
+
+<polyclip> ::= operation: <AND|SUB>
+ <contour-descriptor>
+
+<contour-descriptor> ::= <circle-descriptor>
+ | <vertices-descriptor>
+
+<vertices-descriptor> ::= vertices: <vertices-list>
+
+<circle-descriptor> ::= circle:
+ radius: REAL # in ]0, INF)
+ [ center: <real2> ] # Default is 0,0
+ [ segments: INTEGER ] # in [3, 4096]. Default is 64
+
+<vertices-list> ::= - <real2>
+ - <real2>
+ - <real2>
+ [ - <real2> ... ]
+.Ed
+.Bd -literal
+<material> ::= material:
+ <material-descriptor>
+ | <double-sided-mtl>
+
+<double-sided-mtl> ::= front: <material-descriptor>
+ back: <material-descriptor>
+
+<material-descriptor> ::= <dielectric>
+ | <matte>
+ | <mirror>
+ | <thin-dielectric>
+ | <virtual>
+
+<dielectric> ::= dielectric:
+ medium_i: <medium-descriptor>
+ medium_t: <medium-descriptor>
+ [ <normal-map> ]
+
+<matte> ::= matte:
+ reflectivity: <mtl-data> # in [0, 1]
+ [ <normal-map> ]
+
+<mirror> ::= mirror:
+ reflectivity: <mtl-data> # in [0, 1]
+ slope_error: <mtl-data>
+ [ microfacet: <normal-distrib> ] # Default is BECKMANN
+ [ <normal-map> ]
+
+<normal-distrib> ::= BECKMANN
+ | PILLBOX
+
+<virtual> ::= virtual: EMPTY-STRING
+
+<thin-dielectric> ::= thin_dielectric:
+ thickness: REAL # in [0, INF)
+ medium_i: <medium-descriptor>
+ medium_t: <medium-descriptor>
+ [ <normal-map> ]
+
+<normal-map> ::= normal_map:
+ path: PATH
+.Ed
+.Bd -literal
+<medium> ::= medium: <medium-descriptor>
+
+<medium-descriptor> ::= refractive_index: <mtl-data> # in ]0, INF)
+ extinction: <mtl-data> # in [0, INF)
+.Ed
+.Bd -literal
+<entity> ::= entity: <entity-data>
+
+<template> ::= template: <entity-data>
+
+<entity-data> ::= name: STRING
+ [ <geometry-data> | <x_pivot> | <zx_pivot> ]
+ [ <anchors> ]
+ [ <transform> ]
+ [ <children> ]
+
+<geometry-data> ::= primary: INTEGER # in [0, 1]
+ <geometry>
+
+<children> ::= children:
+ - <entity-data>
+ [ - <entity-data> ... ]
+
+<anchors> ::= anchors:
+ - <anchor-data>
+ [ - <anchor-data> ... ]
+
+<anchor-data> ::= name: STRING
+ <position-descriptor>
+
+<position-descriptor> ::= position: <real3>
+ | hyperboloid_image_focals: <hyperboloid_focals>
+
+<entity-identifier> ::= <self|STRING>[.STRING ... ]
+
+<anchor-identifier> ::= <entity-identifier>.STRING
+.Ed
+.Bd -literal
+<sun> ::= sun:
+ dni: REAL # Direct Normal Irradiance in ]0, INF)
+ [ <spectrum> ] # Default is the smarts295 spectrum
+ [ <sun-shape> ]
+
+<sun-shape> ::= <pillbox> | <gaussian> | <buie>
+
+<buie> ::= buie:
+ csr: REAL # in [1e-6, 0.849]
+
+<pillbox> ::= pillbox:
+ half_angle: REAL # in ]0, 90]
+
+<gaussian> ::= gaussian:
+ std_dev: REAL # in ]0, INF)
+.Ed
+.Bd -literal
+<atmosphere> ::= atmosphere:
+ extinction: <mtl-data> # in [0, 1]
+.Ed
+.Bd -literal
+<mtl-data> ::= REAL
+ | <spectrum-data-list>
+
+<transform> ::= transform:
+ translation: <real3>
+ rotation: <real3>
+
+<real2> ::= - REAL
+ - REAL
+
+<real3> ::= - REAL
+ - REAL
+ - REAL
+
+<spectrum> ::= spectrum: <spectrum-data-list>
+
+<spectrum-data-list> ::= - <spectrum-data>
+ [ - <spectrum-data> ... ]
+
+<spectrum-data> ::= wavelength: REAL # in [0, INF)
+ data: REAL # in [0, INF)
+.Ed
+.Sh SUN
+The
+.Em sun
+describes the source of the solar plant.
+Its direction is not defined in the
+.Nm
+file but is provided by the
+.Xr solstice 1
+command.
+This allows the same unmodified
+.Nm
+file to be used for several simulations with different sun directions.
+.Pp
+The main
+.Em sun
+property is its direct normal irradiance, or
+.Em dni
+in W\(md m\u\s-2\-2\s0\d.
+Its value is a scalar defining the direct irradiance received on a plane
+perpendicular to the main sun direction.
+The optional
+.Em spectrum
+parameter describes the per-wavelength distribution of the sun
+.Em dni .
+Note that this distribution is automatically normalized by
+.Xr solstice 1 .
+If the
+.Em spectrum
+attribute is not defined,
+.Xr solstice 1
+uses a default spectrum computed with the SMARTS software
+.Po
+see
+.Sx NOTES ,
+reference 2
+.Pc
+between 0.28 and 4 micrometres.
+The total
+.Em dni
+(integrated over the spectral range) was set to 1000 W\(md m\u\s-2\-2\s0\d.
+The standard Mid-Latitude-Summer atmosphere was used with most gas
+concentrations set as default (CO2 concentration assumed 400 ppmv).
+.Pp
+Even if an atmosphere is provided, the atmospheric effects from the top
+of the atmosphere to ground level are not computed using the atmosphere
+description.
+As a result, the sun description
+.Pq Em dni No and optional Em spectrum
+is expected to include all atmospheric effects (sun irradiance available
+at ground level).
+.Pp
+The
+.Em sun-shape
+parameter controls the angular distribution of the sun light intensity
+across the sun's disk.
+If not defined, the distribution is assumed to be a Dirac distribution
+(infinite directional source).
+The available sun shapes are:
+.Bl -tag -width Ds
+.It Em pillbox
+The
+.Em pillbox
+distribution defines a uniform intensity over the sun's disk.
+Its single
+.Em half_angle
+parameter is the sun's disk half-angle in degrees, linked to the
+apparent size of the sun.
+A typical
+.Em half_angle
+is 0.2664.
+.It Em gaussian
+The
+.Em gaussian
+distribution defines a Gaussian distribution of the solar incoming
+direction.
+Its single
+.Em std_dev
+parameter is the standard deviation of the distribution in degrees.
+Values around 0.2 are typical.
+As the Gaussian distribution is not truncated, the resulting sun vector
+can theoretically be oriented away from the sun, especially with a
+large, non-typical
+.Em std_dev
+value.
+.It Em buie
+The
+.Em buie
+distribution, as first described in reference 3
+.Pq see Sx NOTES .
+Its single
+.Em csr
+parameter is the ratio between the circumsolar irradiance and the sum
+of the circumsolar and sun's disk irradiance.
+An analysis of typical
+.Em csr
+values can be found in reference 4
+.Pq see Sx NOTES .
+.El
+.Sh ATMOSPHERE
+The
+.Em atmosphere ,
+when provided, describes the medium surrounding the solar plant.
+Its only parameter is its extinction coefficient in m\u\s-2\-1\s0\d,
+which can either be a scalar if the extinction is constant over the
+spectrum, or can be spectrally described.
+The extinction along light paths is only computed after the first
+reflector, as the sun description must include all atmospheric effects
+before the first reflector (see
+.Sx SUN
+for more details).
+.Pp
+If no atmosphere is provided, atmospheric extinction after the first
+reflector is not taken into account.
+.Sh MATERIAL
+A
+.Em material
+describes the properties of an interface.
+These properties can be the same for both sides of the interface or may
+be differentiated with a
+.Em double-sided-mtl .
+The material behaviour is controlled by a
+.Em material-descriptor
+that specifies the physical properties of the interface as well as its
+optional normal perturbation.
+Note that the physical properties can be either scalars or spectral data.
+.Ss Material descriptors
+The available material descriptors are:
+.Bl -tag -width Ds
+.It Em dielectric
+Interface between two dielectric media.
+Its
+.Em medium_i
+parameter defines the current medium (the medium the ray travels in),
+while
+.Em medium_t
+represents the opposite medium.
+Incoming rays are either specularly reflected or refracted according to
+a Fresnel term:
+.Bd -literal -offset indent
+Fr = 1/2 * (Rs^2 + Rp^2)
+.Ed
+.Pp
+with Rs and Rp the reflectance for light polarized with its electric
+field perpendicular or parallel to the plane of incidence, respectively:
+.Bd -literal -offset indent
+Rs = (n1 * |wi.N| - n2 * |wt.N|) / (n1 * |wi.N| + n2 * |wt.N|)
+Rp = (n2 * |wi.N| - n1 * |wt.N|) / (n2 * |wi.N| + n1 * |wt.N|)
+.Ed
+.Pp
+with n1 and n2 the indices of refraction of the incident and transmitted
+media, and wi and wt the incident and transmitted direction.
+.Pp
+Be careful to ensure media consistency in the
+.Nm
+file: a ray travelling in a medium
+.Em A
+can only encounter a medium interface whose
+.Em medium_i
+attribute is
+.Em A .
+Consequently, a
+.Em dielectric
+material must be defined as a double-sided material whose front and back
+interfaces are dielectrics with inverted media:
+.Bd -literal -offset indent
+material:
+ front:
+ dielectric:
+ medium_i: &vacuum { refractive_index: 1, extinction: 0 }
+ medium_t: &glass { refractive_index: 1.5, extinction: 20 }
+ back:
+ dielectric:
+ medium_i: *glass
+ medium_t: *vacuum
+.Ed
+.Pp
+If media consistency is not ensured,
+.Xr solstice 1
+will fail to run simulations.
+Note that by default, the surrounding medium is assumed to be vacuum,
+i.e.\& its refractive index and extinction are scalars with values 1 and
+0, respectively.
+If an atmosphere is defined, the refractive index of the surrounding
+medium is still the scalar 1 but its extinction is that of the
+atmosphere.
+.It Em matte
+Diffuse surface.
+Reflects the same intensity in all directions independently of the
+incoming direction.
+.It Em mirror
+Specular or glossy reflection, depending on whether the
+.Em slope_error
+parameter is 0 or not.
+Glossy reflections are controlled by a microfacet BRDF.
+The microfacet normals are distributed according to the Beckmann or
+Pillbox distribution, as specified by the
+.Em normal-distrib
+attribute.
+.Pp
+Let S be the
+.Em slope_error
+parameter in ]0,\ 1].
+The Beckmann distribution is defined as:
+.Bd -literal -offset indent
+D(wh) = exp(-tan^2(a) / m^2) / (PI * m^2 * cos^4(a))
+.Ed
+.Pp
+with a = arccos(wh.N) and m = sqrt(2)*S, while the Pillbox distribution
+is defined as:
+.Bd -literal -offset indent
+ | 0; if |wh.N| >= S
+D(wh) = |
+ | 1 / (PI * (1 - cos^2(S))); if |wh.N| < S
+.Ed
+.It Em thin-dielectric
+The interface is assumed to be a thin slab of a dielectric material.
+The
+.Em medium_i
+parameter defines the outside dielectric medium while
+.Em medium_t
+is the medium of the thin slab.
+Incoming rays are either specularly reflected or transmitted (without
+deviation) according to a Fresnel term (see
+.Em dielectric
+above for the formula).
+The underlying scattering function correctly handles the multiple
+refraction effects within the thin slab.
+.Pp
+The same media consistency rules as for
+.Em dielectric
+apply: if not ensured,
+.Xr solstice 1
+will fail to run simulations.
+By default, the surrounding medium is vacuum (refractive index 1,
+extinction 0).
+If an atmosphere is defined, the refractive index of the surrounding
+medium is still 1, but its extinction is that of the atmosphere.
+.It Em virtual
+Fully transparent interface.
+.El
+.Ss Normal map
+All material descriptors except
+.Em virtual
+provide an optional
+.Em normal-map
+attribute that defines a path to a Portable PixMap image
+.Po
+see
+.Sx NOTES ,
+reference 5
+.Pc
+whose pixels store a normal expressed in the tangent space of the
+interface.
+By default, the unperturbed tangent space normal is {0,0,1}.
+The PPM image can be encoded on 8 or 16 bits per component either in
+ASCII or binary.
+The parameterization of this 2D image onto the shape surfaces depends
+on the type of shape.
+For the
+.Em hemisphere , hyperbol , parabol , plane
+and
+.Em parabolic-cylinder
+shapes, the image is mapped in the {X,Y} plane.
+Other shapes are not parameterized; applying a normal-mapped material to
+them leads to undefined behaviour.
+.Sh SHAPE
+A
+.Em shape
+describes a geometric model defined in its local coordinate system,
+whose origin is proper to the shape.
+No spatial transformation can be introduced through the declaration of
+a shape: it should be transformed externally through an
+.Em object
+and/or
+.Em entity .
+.Pp
+Two types of shape are provided: quadric and mesh.
+The former is used to declare parametric surfaces; the latter describes
+triangulated surfaces.
+.Ss Quadric
+A quadric shape is defined from a quadric equation and a set of 2D
+clipping operations performed in its {X,Y} plane.
+By convention, the front side of the quadric surface looks toward the
+positive Z axis.
+Internally, the clipped quadric surface is discretized into a triangular
+mesh according to the quadric's discretization parameters.
+This mesh is used by
+.Xr solstice 1
+as a proxy to speed up access to the quadric shape; the exact position
+and normal are ultimately computed from the quadric equation.
+.Pp
+The quadric surface is parameterized in the {X,Y} plane:
+.Bd -literal -offset indent
+u = (x - lowerX) / (upperX - lowerX)
+v = (y - lowerY) / (upperY - lowerY)
+.Ed
+.Pp
+with
+.Em u
+and
+.Em v
+the mapped 2D coordinates from a 3D position {x,y,z} onto the quadric,
+and
+.Em lower Ns <X|Y>
+and
+.Em upper Ns <X|Y>
+the lower and upper bounds of the clipped quadric along the X and Y
+axes.
+The available quadrics are:
+.Bl -tag -width Ds
+.It Em hemisphere
+Hemispheric shape defined along the Z axis whose minimum is at the
+origin.
+The
+.Em slices
+parameter controls the number of divisions along the Z axis.
+.Bd -literal -offset indent
+x^2 + y^2 + (z-radius)^2 = radius^2
+.Ed
+.It Em hyperbol
+Hyperbolic quadric defined along the Z axis whose minimum is at the
+origin.
+The
+.Em slices
+parameter controls the discretization of the hyperbol.
+If not defined, it is automatically computed from the hyperbol
+curvature.
+.Bd -literal -offset indent
+(x^2 + y^2) / a^2 - (z + z0 - g/2)^2 / b^2 + 1 = 0
+
+a^2 = g^2(f - f^2)
+b = g(f - 1/2)
+z0 = |b| + g/2
+g = focals.real + focals.image
+f = focals.real / g
+.Ed
+.It Em parabol
+Parabolic quadric defined along the Z axis whose minimum is at the
+origin.
+The
+.Em slices
+parameter controls the discretization of the parabol.
+If not defined, it is automatically computed from the parabol curvature.
+.Bd -literal -offset indent
+x^2 + y^2 - 4 * focal * z = 0
+.Ed
+.It Em parabolic-cylinder
+Parabolic cylinder oriented along the Z axis, with its main axis along
+the X axis and minimum at the origin.
+The
+.Em slices
+parameter controls the discretization.
+If not defined, it is automatically computed from the curvature.
+.Bd -literal -offset indent
+y^2 - 4 * focal * z = 0
+.Ed
+.It Em plane
+Plane whose normal points along the positive Z axis.
+The
+.Em slices
+attribute controls the discretization of the clipped plane.
+.El
+.Ss Clipping
+A clipping operation, or
+.Em polyclip ,
+removes parts of the quadric surface.
+It is defined by a 2D
+.Em contour-descriptor
+expressed in the {X,Y} plane and a clipping
+.Em operation .
+The
+.Em AND
+operand retains the portion of the quadric that intersects the
+contour; the
+.Em SUB
+operand removes the portion that intersects the contour.
+The available contour descriptors are:
+.Bl -tag -width Ds
+.It Em circle-descriptor
+Circular contour whose size is defined by the
+.Em radius
+parameter.
+.Xr solstice 1
+discretizes the circular contour using the
+.Em segments
+attribute as the number of segments used to approximate the circle.
+.It Em vertices-descriptor
+Polygonal contour described by a list of 2D vertices.
+Polygon edges connect each vertex to its predecessor; an additional
+edge automatically closes the polygon between the last and first vertex.
+Note that
+.Xr solstice 1
+assumes the polygon does not self-intersect.
+.El
+.Pp
+The
+.Em clip
+parameter of a quadric lists a set of
+.Em polyclips
+applied successively in declaration order.
+For example, the following uses 5 clipping operations on a plane to
+build a rectangle with a circular hole at each corner:
+.Bd -literal -offset indent
+plane:
+ clip:
+ - {operation: AND, vertices: [[-4,-2],[-4,2],[4,2],[4,-2]]}
+ - {operation: SUB, circle: {radius: 0.5, center: [-3,-1]}}
+ - {operation: SUB, circle: {radius: 0.5, center: [-3, 1]}}
+ - {operation: SUB, circle: {radius: 0.5, center: [ 3,-1]}}
+ - {operation: SUB, circle: {radius: 0.5, center: [ 3, 1]}}
+.Ed
+.Ss Triangular mesh
+Triangular meshes are generated by
+.Xr solstice 1
+from a shape description or loaded from a CAO file.
+Their normals are defined per triangle and are thus discontinuous even
+for smooth shapes.
+Triangular meshes are not parameterized; applying a normal-mapped
+material to them produces undefined behaviour.
+The available triangular meshes are:
+.Bl -tag -width Ds
+.It Em cuboid
+Axis-aligned cuboid centered at the origin, whose corner positions and
+dimensions along the three axes are defined by the
+.Em size
+parameter.
+The front side of the surface looks outside the cuboid.
+.It Em cylinder
+Cylinder centered at the origin whose
+.Em height
+is along the positive Z axis.
+Top and bottom are capped.
+The
+.Em stacks
+and
+.Em slices
+parameters control the number of divisions along and around the Z axis,
+respectively.
+The front side looks outside the cylinder.
+.It Em sphere
+Triangulated sphere centered at the origin.
+The
+.Em stacks
+and
+.Em slices
+parameters control the number of divisions along and around the Z axis,
+respectively.
+The front side looks outside the sphere.
+.It Em stl
+Path to an external mesh file in ASCII
+.Em ST Ns ereo Ns Em L Ns ithography
+(STL) format.
+The front side of each triangle is determined by the vertex ordering in
+the STL file: a triangle is front-facing when its vertices are
+clockwise-ordered.
+.El
+.Sh ENTITY
+An
+.Em entity
+is used to declare and position shapes in the solar plant.
+An entity is the only item that effectively instantiates a
+.Em geometry
+into the solar plant: a geometry declared but not referenced by an
+entity is ignored by
+.Xr solstice 1 .
+An entity is a hierarchical data structure whose child entities'
+transformation is relative to their parent.
+If not defined, the
+.Em transform
+of an entity is the identity (null rotation and translation).
+.Pp
+Each entity has a
+.Em name
+which must be unique per hierarchy level.
+The name string cannot contain dots, spaces or tabulations.
+A child entity is identified in the solar plant by concatenating, with
+the
+.Sq .\&
+character, the names of its ancestors with its own name.
+For instance, the identifier of a child entity named
+.Em level2
+is
+.Em level0.level1.level2 :
+.Bd -literal -offset indent
+entity:
+ name: level0
+ child:
+ - name: level1
+ child:
+ - name: level2
+.Ed
+.Pp
+An entity encapsulates either a
+.Em geometry
+(a collection of
+.Em objects )
+or a
+.Em pivot .
+Each entity can also have a list of
+.Em anchors
+defining positions relative to the entity.
+.Pp
+For a geometric entity, one must specify whether the encapsulated
+geometry is a
+.Em primary
+geometry (i.e.\& directly lit by the sun and used to concentrate solar
+flux, such as a primary mirror).
+Correctly tagging primary geometries drastically improves the
+convergence speed of
+.Xr solstice 1
+simulations.
+.Ss Template
+A
+.Em template
+is a first-level entity with no existence in the solar plant itself.
+It is used to pre-declare an entity hierarchy that can then be
+instantiated multiple times by referencing it through common entities
+with YAML data tagging:
+.Bd -literal -offset indent
+- template: &my-template
+ name: bar
+ primary: 1
+ geometry: ...
+- entity:
+ name: foo0
+ transform: {translation: [-10.5, 0, 0]}
+ children: [*my-template]
+- entity:
+ name: foo1
+ transform: {translation: [0, 0, 0]}
+ children: [*my-template]
+- entity:
+ name: foo2
+ transform: {translation: [10.5, 0, 0]}
+ children: [*my-template]
+.Ed
+.Ss Pivot
+A
+.Em pivot
+is a special kind of node that automatically orients its child geometry
+according to the sun position and pivot parameters.
+It is typically (but not mandatorily) the parent of a reflector that,
+once pivoted, will redirect sun light toward a
+.Em target .
+A pivot cannot be the child of another pivot.
+.Pp
+The
+.Em target
+parameter is the most important pivot parameter.
+Four types of target are available:
+.Bl -tag -width Ds
+.It Em position
+The target is an absolute point in world coordinates.
+.It Em anchor
+The target is a position relative to an entity (see
+.Sx Anchor ) .
+.It Em sun
+The target is the center of the sun.
+.It Em direction
+The pivot reflects light in the given direction, specified in world
+coordinates.
+.El
+.Pp
+Pivots can also have an optional
+.Em ref_point
+parameter defining a 3D point in the coordinate system of the pivot's
+children that is used by the pointing algorithm.
+If not provided, it defaults to the origin.
+.Pp
+Two flavours of pivot are available:
+.Bl -tag -width Ds
+.It Em x_pivot
+Single-axis pivot rotating around the +X axis in its local coordinate
+system.
+Its pointing algorithm considers an incoming ray from the center of the
+sun and rotates its children so that a specular reflection at
+.Em ref_point
+using +Z as the local normal hits the target, or produces the specified
+direction.
+.It Em zx_pivot
+Two-axis pivot: first a rotation around the +Z axis in its local
+coordinate system, then a rotation around the +X axis in the resulting
+coordinate system.
+The optional
+.Em spacing
+parameter defines a translation along the +Y axis applied after the
+first rotation (default: 0).
+Its pointing algorithm considers an incoming ray from the center of the
+sun and rotates its children so that a specular reflection at
+.Em ref_point
+using +Y as the local normal hits the target, or produces the specified
+direction.
+.El
+.Ss Anchor
+An
+.Em anchor
+defines a relative position in the entity hierarchy.
+Anchors are particularly useful for pivots and hyperbolic shapes that
+must reference a position relative to an entity whose transformation may
+depend on its ancestors.
+An anchor's
+.Em name
+must be unique among all anchors in its entity and cannot contain dots,
+spaces or tabulations.
+An anchor is identified in the solar plant by concatenating its name to
+the
+.Em entity-identifier
+of the entity in which it is declared, using
+.Sq .\&
+as separator.
+For example, the identifier of an anchor named
+.Em anchor0
+declared in
+.Em level0.level1
+is
+.Em level0.level1.anchor0 .
+.Pp
+When the root entity name of a template is unknown (because the template
+has not yet been instantiated), the
+.Em self
+reserved keyword can be used to reference the unknown root entity.
+For example:
+.Bd -literal -offset indent
+- template: &my-template
+ name: level0
+ anchor: [{name: anchor0, position: [1, 2, 3]}]
+ child:
+ - name: level1
+ pivot:
+ x_pivot:
+ ref_point: {0, 0, 0}
+ target: {anchor: self.level0.anchor0}
+
+- entity: {name: entity0, child: [*my-template]}
+- entity: {name: entity1, child: [*my-template]}
+.Ed
+.Ss Transform
+A
+.Em transform
+moves an
+.Em object
+or an
+.Em entity
+in space.
+The
+.Em rotation
+parameter lists 3 angles in degrees defining rotations around the X, Y
+and Z axes.
+The
+.Em translation
+attribute describes offsets along the X, Y and Z axes.
+Given a local frame
+.Em p
+of an object,
+.Em p
+is transformed into
+.Em p'
+as:
+.Bd -literal -offset indent
+p' = Rx * Ry * Rz * (T + p)
+.Ed
+.Pp
+with
+.Em T
+the translation vector and
+.Em Rx , Ry , Rz
+the rotation matrices around the X, Y and Z axes:
+.Bd -literal -offset indent
+ | 1 0 0 | | cY 0 sY | | cZ -sZ 0 |
+Rx = | 0 cX -sX |; Ry = | 0 1 0 |; Rz = | sZ cZ 0 |
+ | 0 sX cX | |-sY 0 cY | | 0 0 1 |
+.Ed
+.Pp
+where
+.Em c Ns <X|Y|Z>
+and
+.Em s Ns <X|Y|Z>
+are the cosine and sine of the rotation angles around the X, Y and Z
+axes, respectively.
+.Sh EXAMPLES
+Declare 2 entities and a point-source sun.
+The first entity is a purely specular square of size 10 centered at the
+origin.
+The second is a purely transparent square used as a receiver; its size
+is 1 and its center is at {0,0,2}:
+.Bd -literal -offset indent
+- sun: {dni: 1000}
+
+- entity:
+ name: reflector
+ primary: 1
+ geometry:
+ - material:
+ mirror:
+ reflectivity: 1
+ slope_error: 0
+ plane:
+ clip:
+ - operation: AND
+ vertices:
+ - [-5.0,-5.0]
+ - [-5.0, 5.0]
+ - [ 5.0, 5.0]
+ - [ 5.0,-5.0]
+
+- entity:
+ name: receiver
+ primary: 0
+ transform:
+ translation: [0, 0, 2]
+ geometry:
+ - material:
+ virtual: # No attrib
+ plane:
+ clip:
+ - operation: AND
+ vertices:
+ - [-0.5,-0.5]
+ - [-0.5, 0.5]
+ - [ 0.5, 0.5]
+ - [ 0.5,-0.5]
+.Ed
+.Pp
+Define a circular diffuse reflector surrounded by a virtual sphere, with
+a pillbox-shaped sun of
+.Em half_angle
+0.1 degree.
+Use anchors and YAML tags to reference a pre-declared geometry, and the
+YAML compact notation to reduce the number of lines:
+.Bd -literal -offset indent
+- sun: {dni: 1000, pillbox: {half_angle: 0.1}}
+
+- geometry: &small-circle
+ - material: {matte: {reflectivity: 1}}
+ plane: {clip: [{operation: AND, circle: {radius: 0.5}}]}
+
+- geometry: &big-sphere
+ - material: {virtual: ""}
+ sphere: {radius: 2, slices: 128}
+
+- entity: {name: reflector, primary: 1, geometry: *small-circle}
+- entity: {name: receiver, primary: 0, geometry: *big-sphere}
+.Ed
+.Pp
+Declare 2 parabolic reflectors from a templated parabola whose
+orientation is controlled by a
+.Em zx_pivot
+targeting an anchor defined relative to the receiver:
+.Bd -literal -offset indent
+- sun: {dni: 1000}
+
+- entity: # Receiver
+ name: square_receiver
+ primary: 0
+ transform: { rotation: [0,90,0], translation: [100,0,10] }
+ anchors: [{name: anchor0, position: [0,0,0]}]
+ geometry:
+ - material: {virtual: ""}
+ plane:
+ clip:
+ - operation: AND
+ vertices: [[-.5,-.5],[-.5,.5],[.5,.5],[.5,-.5]]
+
+- template: &self_oriented_parabol # Reflector
+ name: pivot
+ transform: {translation: [0, 0, 4], rotation: [0, 0, 90]}
+ zx_pivot: {target: {anchor: square_receiver.anchor0}}
+ children:
+ - name: parabol
+ transform: {rotation: [-90, 0, 0]}
+ primary: 1
+ geometry:
+ - material: {mirror: {reflectivity: 1, slope_error: 0}}
+ parabol:
+ focal: 100
+ clip:
+ - operation: AND
+ vertices: [[-5,-5],[-5,5],[5,5],[5,-5]]
+
+# Instantiate the reflector template
+- entity:
+ name: reflector1
+ transform: {translation: [0,0,0]}
+ children: [*self_oriented_parabol]
+- entity:
+ name: reflector2
+ transform: {translation: [10,43.6,0]}
+ children: [*self_oriented_parabol]
+.Ed
+.Pp
+Declare a solar furnace with 9 heliostats instantiated from the same
+template.
+Their position is controlled by a
+.Em zx_pivot
+to ensure that incoming sun rays are reflected toward the negative X
+axis.
+Reflected rays are then concentrated by a parabola toward a purely
+absorptive receiver.
+The heliostats and the parabola share the same double-sided material:
+front faces are purely specular, back faces are diffuse:
+.Bd -literal -offset indent
+- sun: {dni: 1000}
+
+- material: &specular
+ front: {mirror: {reflectivity: 1, slope_error: 0}}
+ back: {matte: {reflectivity: 1}}
+
+- template: &H # Template of a heliostat
+ name: heliostat
+ transform: {translation: [0,0,5.5]}
+ zx_pivot: {target: {direction: [-1,0,0]}}
+ children:
+ - name: reflector
+ transform: {rotation: [-90,0,0]}
+ primary: 1
+ geometry:
+ - material: *specular
+ plane:
+ clip: [{operation: AND, vertices: [[-5,-5],[-5,5],[5,5],[5,-5]]}]
+
+- entity: # Receiver entity
+ name: receiver
+ primary: 0
+ transform: {translation: [18,0,20], rotation: [0,90,0]}
+ geometry:
+ - material: {matte: {reflectivity: 0}}
+ plane:
+ clip:
+ - operation: AND
+ vertices: [[-.5,-.5],[-.5,.5],[.5,.5],[.5,-.5]]
+
+- entity: # Great parabola
+ name: parabola
+ primary: 0
+ transform: {translation: [0,0,20], rotation: [0,90,90]}
+ geometry:
+ - material: *specular
+ parabol:
+ focal: 18
+ clip: [{operation: AND, vertices: [[-30,-20],[-30,20],[30,20],[30,-20]]}]
+
+# Instantiate the heliostat template
+- entity: {name: H1, children: [*H], transform: {translation: [40,-20, 0]}}
+- entity: {name: H2, children: [*H], transform: {translation: [40, 0, 0]}}
+- entity: {name: H3, children: [*H], transform: {translation: [40, 20, 0]}}
+- entity: {name: H4, children: [*H], transform: {translation: [60,-20,10]}}
+- entity: {name: H5, children: [*H], transform: {translation: [60, 0,10]}}
+- entity: {name: H6, children: [*H], transform: {translation: [60, 20,10]}}
+- entity: {name: H7, children: [*H], transform: {translation: [80,-20,20]}}
+- entity: {name: H8, children: [*H], transform: {translation: [80, 0, 20]}}
+- entity: {name: H9, children: [*H], transform: {translation: [80, 20,20]}}
+.Ed
+.Pp
+Three partial parabols with various focal distances concentrate incoming
+radiation at a common focal position.
+A hyperbol is located between the parabols and their common focal, which
+is also one of the two focals of the hyperbol.
+Radiation is redirected to the second focal of the hyperbol where the
+square target is located.
+A cuboid using a glass material is located between the hyperbol and the
+target.
+This example also illustrates the use of
+.Em spectrum
+for refractive index and extinction:
+.Bd -literal -offset indent
+# Spectra
+- spectrum: &solar_spectrum
+ - {wavelength: 0.3, data: 1.0}
+ - {wavelength: 0.4, data: 2.0}
+ - {wavelength: 0.5, data: 0.5}
+ - {wavelength: 0.6, data: 3.5}
+ - {wavelength: 0.7, data: 1.5}
+ - {wavelength: 0.8, data: 0.8}
+
+- spectrum: &air_kabs
+ - {wavelength: 0.3, data: 1.0e-4}
+ - {wavelength: 0.4, data: 1.0e-5}
+ - {wavelength: 0.5, data: 2.0e-5}
+ - {wavelength: 0.6, data: 2.0e-4}
+ - {wavelength: 0.7, data: 3.0e-5}
+ - {wavelength: 0.8, data: 1.0e-4}
+
+- spectrum: &glass_kabs
+ - {wavelength: 0.3, data: 1.0e-2}
+ - {wavelength: 0.4, data: 1.0e-3}
+ - {wavelength: 0.5, data: 2.0e-3}
+ - {wavelength: 0.6, data: 2.0e-2}
+ - {wavelength: 0.7, data: 3.0e-3}
+ - {wavelength: 0.8, data: 1.0e-3}
+
+- spectrum: &glass_ref_index
+ - {wavelength: 0.30, data: 1.40}
+ - {wavelength: 0.40, data: 1.39}
+ - {wavelength: 0.50, data: 1.37}
+ - {wavelength: 0.60, data: 1.34}
+ - {wavelength: 0.70, data: 1.30}
+ - {wavelength: 0.80, data: 1.25}
+
+# Media
+- medium: &air_medium
+ refractive_index: 1
+ extinction: *air_kabs
+
+- medium: &glass_medium
+ refractive_index: *glass_ref_index
+ extinction: *glass_kabs
+
+# Sun & atmosphere
+- sun: {dni: 1, spectrum: *solar_spectrum}
+- atmosphere: {extinction: *air_kabs}
+
+# Materials
+- material: &specular {mirror: {reflectivity: 1, slope_error: 0}}
+- material: &black {matte: {reflectivity: 0}}
+- material: &glass
+ front: {dielectric: {medium_i: *air_medium, medium_t: *glass_medium}}
+ back: {dielectric: {medium_i: *glass_medium, medium_t: *air_medium}}
+
+# Primary reflectors
+- entity:
+ name: "primary_reflector1"
+ primary: 1
+ transform: {translation: [0, 0, -2.0]}
+ geometry:
+ - material: *specular
+ parabol:
+ focal: 12
+ clip:
+ - {operation: AND, circle: {radius: 10}}
+ - {operation: SUB, circle: {radius: 5}}
+
+- entity:
+ name: "primary_reflector2"
+ primary: 1
+ transform: {translation: [0, 0, -4]}
+ geometry:
+ - material: *specular
+ parabol:
+ focal: 14
+ clip:
+ - {operation: AND, circle: {radius: 15}}
+ - {operation: SUB, circle: {radius: 10}}
+
+- entity:
+ name: "primary_reflector3"
+ primary: 1
+ transform: {translation: [0, 0, -6]}
+ geometry:
+ - material: *specular
+ parabol:
+ focal: 16
+ clip:
+ - {operation: AND, circle: {radius: 20}}
+ - {operation: SUB, circle: {radius: 15}}
+
+# Secondary reflector
+- entity:
+ name: "secondary_reflector"
+ primary: 0
+ transform: {translation: [0, 0, 6]}
+ geometry:
+ - material: *specular
+ hyperbol:
+ focals: {real: 16.0, image: 4}
+ clip: [{operation: AND, circle: {radius: 5}}]
+
+# Glass box
+- entity:
+ name: "glass_slide"
+ primary: 0
+ geometry:
+ - material: *glass
+ cuboid: {size: [10,10,0.5]}
+ transform: {translation: [0, 0, 0.25]}
+
+# Receiver
+- entity:
+ name: "square_receiver"
+ primary: 0
+ transform: {translation: [0, 0, -10] }
+ geometry:
+ - material: *black
+ plane:
+ clip:
+ - operation: AND
+ vertices: [[-0.5,-0.5],[-0.5,0.5],[0.5,0.5],[0.5,-0.5]]
+.Ed
+.Sh NOTES
+.Bl -enum
+.It
+YAML Ain't Markup Language \(em
+.Lk http://yaml.org
+.It
+SMARTS, Simple Model of the Atmospheric Radiative Transfer of Sunshine \(em
+.Lk http://www.nrel.gov/rredc/smarts/
+.It
+D.\& Buie, A.G.\& Monger, C.J.\& Dey.
+.Dq Sunshape distributions for terrestrial solar simulations .
+.Em Solar Energy ,
+2003, 74, pp.\& 113\(en122.
+.It
+D.\& Buie, C.J.\& Dey, S.\& Bosi.
+.Dq The effective size of the solar cone for solar concentrating systems .
+.Em Solar Energy ,
+2003, 74, pp.\& 417\(en427.
+.It
+Portable PixMap \(em
+.Lk http://netpbm.sourceforge.net/doc/ppm.html
+.El
+.Sh SEE ALSO
+.Xr solstice 1 ,
+.Xr solstice-receiver 5
+.Sh HISTORY
+.Nm
+was initially developed with funding from the
+.Em SOLSTICE LabEx
+.Pq Laboratory of Excellence ,
+in collaboration with the PROMES Laboratory of the
+French National Centre for Scientific Research
+.Pq CNRS .
+.Sh AUTHORS
+.Nm
+was written and is maintained by
+.An |M\['e]so|Star> Aq Mt contact@meso-star.com .
diff --git a/doc/solstice-input.5.txt b/doc/solstice-input.5.txt
@@ -1,1179 +0,0 @@
-// Copyright (C) 2016-2018 CNRS, 2018-2019 |Meso|Star>
-//
-// This is free documentation: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This manual is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-:toc:
-
-solstice-input(5)
-=================
-
-NAME
-----
-solstice-input - solar plant description for solstice(1)
-
-DESCRIPTION
------------
-The *solstice-input* is the format used by the *solstice*(1) program to
-represent a solar plant. It relies on the YAML 1.1 data serialization standard
-[1]; assuming that the file is compatible with the *solstice-input* semantic, a
-solar plant can be described by using the whole YAML 1.1 functionalities
-including compact notation and data tagging.
-
-A solar plant is composed of a *sun*, an optional *atmosphere* and a collection
-of *geometries*, i.e. *shapes* with their associated *material*. Beside the raw
-description of the aforementioned data, the *solstice-input* format provides
-the *entity* item to efficiently structure the geometries in the scene. An
-entity is a node in a tree data structure where the position of each child
-entity is relative to the position of its parent. An entity can either
-encapsulate a *geometry* or a *pivot* that controls the dynamic positioning of
-its child entities with respect to the pivot constraints and the sun direction
-submitted to the *solstice*(1) program.
-
-GRAMMAR
--------
-
-[verse]
-_______
-<solar-plant> ::= - <sun>
- - <item>
- [ - <item> ... ]
- [ - <atmosphere> ]
-
-<item> ::= <entity>
- | <geometry>
- | <material>
- | <medium>
- | <spectrum>
- | <template>
-
--------------------------------------
-
-<geometry> ::= geometry:
- - <object>
- [ - <object> ... ]
-
-<object> ::= <shape>
- <material>
- [ <transform> ]
-
-<x_pivot> ::= x_pivot:
- <target>
- [ ref_point: <real3> ] # Default is [0,0,0]
-
-<zx_pivot> ::= zx_pivot:
- <target>
- [ spacing: REAL ] # in [0, INF). Default 0
- [ ref_point: <real3> ] # Default is [0,0,0]
-
-<target> ::= target:
- anchor: <anchor-identifier>
- | direction: <real3>
- | position: <real3>
- | <sun>
-
--------------------------------------
-
-<shape> ::= <cuboid>
- | <cylinder>
- | <hemisphere>
- | <hyperbol>
- | <parabol>
- | <parabolic-cylinder>
- | <plane>
- | <sphere>
- | <stl>
-
-<cuboid> ::= cuboid:
- size: <real3> # in ]0, INF]^3
-
-<cylinder> ::= cylinder:
- height: REAL # in ]0, INF)
- radius: REAL # in ]0, INF)
- [ slices: INTEGER ] # in [4, 4096]. Default is 16
- [ stacks: INTEGER ] # in [1, 4096]. Default is 1
-
-<hemisphere> ::= hemisphere:
- radius: REAL # in ]0, INF)
- [ clip: <polyclip-list> ]
- [ slices: INTEGER ] # in [4, 4096]
-
-<hyperbol> ::= hyperbol:
- focals: <hyperboloid-focals>
- clip: <polyclip-list>
- [ slices: INTEGER ] # in [4, 4096]
-
-<parabol> ::= parabol:
- focal: REAL # in ]0, INF)
- clip: <polyclip-list>
- [ slices: INTEGER ] # in [4, 4096]
-
-<parabolic-cylinder> ::= parabolic-cylinder:
- focal: REAL # in ]0, INF)
- clip: <polyclip-list>
- [ slices: INTEGER ] # in [4, 4096]
-
-<plane> ::= plane:
- clip: <polyclip-list>
- [ slices: INTEGER ] # in [1, 4096]. Default is 1
-
-<sphere> ::= sphere:
- radius: REAL # in ]0, INF)
- [ slices: INTEGER ] # in [4, 4096]. Default is 16
- [ stacks: INTEGER ] # in [2, 4096]. Default is slices/2
-
-<stl> ::= stl:
- path: PATH
-
-<hyperboloid-focals> ::= real: REAL # in ]0, INF)
- image: REAL # in ]0, INF)
-
-----------------------------------------
-
-<polyclip-list> ::= - <polyclip>
- [ - <polyclip> ... ]
-
-<polyclip> ::= operation: <AND|SUB>
- <contour-descriptor>
-
-<contour-descriptor> ::= <circle-descriptor>
- | <vertices-descriptor>
-
-<vertices-descriptor> ::= vertices: <vertices-list>
-
-<circle-descriptor> ::= circle:
- radius: REAL # in ]0, INF)
- [ center: <real2> ] # Default is 0,0
- [ segments: INTEGER ] # in [3, 4096]. Default is 64
-
-<vertices-list> ::= - <real2>
- - <real2>
- - <real2>
- [ - <real2> ... ]
-
-----------------------------------------
-
-<material> ::= material:
- <material-descriptor>
- | <double-sided-mtl>
-
-<double-sided-mtl> ::= front: <material-descriptor>
- back: <material-descriptor>
-
-<material-descriptor> ::= <dielectric>
- | <matte>
- | <mirror>
- | <thin-dielectric>
- | <virtual>
-
-<dielectric> ::= dielectric:
- medium_i: <medium-descriptor>
- medium_t: <medium-descriptor>
- [ <normal-map> ]
-
-<matte> ::= matte:
- reflectivity: <mtl-data> # in [0, 1]
- [ <normal-map> ]
-
-<mirror> ::= mirror:
- reflectivity: <mtl-data> # in [0, 1]
- slope_error: <mtl-data>
- [ microfacet: <normal-distrib> ] # Default is BECKMANN
- [ <normal-map> ]
-
-<normal-distrib> ::= BECKMANN
- | PILLBOX
-
-<virtual> ::= virtual: EMPTY-STRING
-
-<thin-dielectric> ::= thin_dielectric:
- thickness: REAL # in [0, INF)
- medium_i: <medium-descriptor>
- medium_t: <medium-descriptor>
- [ <normal-map> ]
-
-<normal-map> ::= normal_map:
- path: PATH
-
-----------------------------------------
-
-<medium> ::= medium: <medium-descriptor>
-
-<medium-descriptor> ::= refractive_index: <mtl-data> # in ]0, INF)
- extinction: <mtl-data> # in [0, INF)
-
-----------------------------------------
-
-<entity> ::= entity: <entity-data>
-
-<template> ::= template: <entity-data>
-
-<entity-data> ::= name: STRING
- [ <geometry-data> | <x_pivot> | <zx_pivot> ]
- [ <anchors> ]
- [ <transform> ]
- [ <children> ]
-
-<geometry-data> ::= primary: INTEGER # in [0, 1]
- <geometry>
-
-<children> ::= children:
- - <entity-data>
- [ - <entity-data> ... ]
-
-<anchors> ::= anchors:
- - <anchor-data>
- [ - <anchor-data> ... ]
-
-<anchor-data> ::= name: STRING
- <position-descriptor>
-
-<position-descriptor> ::= position: <real3>
- | hyperboloid_image_focals: <hyperboloid_focals>
-
-<entity-identifier> ::= <self|STRING>[.STRING ... ]
-
-<anchor-identifier> ::= <entity-identifier>.STRING
-
-----------------------------------------
-
-<sun> ::= sun:
- dni: REAL # Direct Normal Irradiance in ]0, INF)
- [ <spectrum> ] # Default is the smarts295 spectrum
- [ <sun-shape> ]
-
-<sun-shape> ::= <pillbox> | <gaussian> | <buie>
-
-<buie> ::= buie:
- csr: REAL # in [1e-6, 0.849]
-
-<pillbox> ::= pillbox:
- half_angle: REAL # in ]0, 90]
-
-<gaussian> ::= gaussian:
- std_dev: REAL # in ]0, INF)
-
-----------------------------------------
-
-<atmosphere> ::= atmosphere:
- extinction: <mtl-data> # in [0, 1]
-
-----------------------------------------
-
-<mtl-data> ::= REAL
- | <spectrum-data-list>
-
-<transform> ::= transform:
- translation: <real3>
- rotation: <real3>
-
-<real2> ::= - REAL
- - REAL
-
-<real3> ::= - REAL
- - REAL
- - REAL
-
-<spectrum> ::= spectrum: <spectrum-data-list>
-
-<spectrum-data-list> ::= - <spectrum-data>
- [ - <spectrum-data> ... ]
-
-<spectrum-data> ::= wavelength: REAL # in [0, INF)
- data: REAL # in [0, INF)
-_______
-
-SUN
----
-
-The *sun* describes the source of the solar plant. Its direction is not defined
-into the *solstice-input*(5) file but is provided by the *solstice*(1) command.
-This allows to use the same unmodified *solstice-input*(5) file for several
-simulations with different sun directions.
-
-The main *sun* property is its direct normal irradiance, or *dni* in W.m\^-2.
-Its value is a scalar defining the direct irradiance received on a plane
-perpendicular to the main sun direction. The optional *spectrum* parameter
-describes the per wavelength distribution of the sun *dni*. Note that this
-distribution is automatically normalized by *solstice*(1). If the *spectrum*
-attribute is not defined, *solstice*(1) uses a default spectrum computed with
-the SMARTS software [2] between 0.28 and 4 micro-meters. The total *dni*
-(integrated over the spectral range) was set to 1000 W.m^-2. The standard
-Mid-Latitude-Summer atmosphere was used with most of gases concentration set
-as default (the CO2 concentration was assumed 400ppmv in the atmosphere
-column).
-
-Even if an atmosphere is provided, the atmospheric effects from the top of the
-atmosphere to ground level are not computed using the atmosphere description.
-As a result, the sun description (*dni* and optional *spectrum*) is expected to
-include all the atmospheric effects (sun irradiance available at ground
-level).
-
-The *sun-shape* parameter controls the angular distribution of the sun light
-intensity across the sun's disk. If not defined, the distribution is assumed to
-be a dirac distribution (infinite directional source). The available sun
-shapes are:
-
-*pillbox*::
- The *pillbox* distribution defines an uniform intensity over the sun's disk.
- Its single *half_angle* parameter is the sun's disk half-angle in degrees, that
- is linked to the apparent size of the sun. A typical half_angle is 0.2664.
-
-*gaussian*::
- The *gaussian* distribution defines a gaussian distribution of the solar
- incoming direction. Its single *std_dev* parameter is the standard deviation
- of the distribution in degrees. Values around 0.2 are typical.
- As the gaussian distribution is not truncated, the resulting sun vector can
- theoreticaly be oriented towards the sun, especially with a big, non-typical
- *std_dev* value.
-
-*buie*::
- The *buie* distribution, as first discribed in [3]. Its single *csr*
- parameter is the ratio between the circumsolar irradiance and the sum of
- the circumsolar and sun's disk irradiance. An analysis on typical *csr*
- values can be found in [4].
-
-ATMOSPHERE
-----------
-
-The *atmosphere*, when provided, describes the medium surrounding the
-solar plant. Its only parameter is its extinction coefficient in m^-1, that
-can either be a scalar if the *extinction* is constant over the spectrum, or
-can be spectrally described. The extinction along light paths is only computed
-after the first reflector, as sun description must include all the atmospheric
-effects before the first reflector (see sun description for more details).
-
-If no atmosphere is provided, atmospheric extinction after the first reflector
-is not taken into account.
-
-MATERIAL
---------
-
-A *material* describes the properties of an interface. These properties can be
-the same for the two sides of the interface or may be differentiated with a
-*double-sided-mtl*. The material comportment is controlled by a
-*material-descriptor* that specifies the physical properties of the interface
-as well as its optional normal perturbation. Note that the physical properties
-can be either scalars or spectral data.
-
-Material descriptors
-~~~~~~~~~~~~~~~~~~~~
-
-The available material descriptors are:
-
-*dielectric*::
-Interface between 2 dielectric media. Its *medium_i* parameter defines the
-current medium, i.e. the medium the ray travels in, while *medium_t*
-represents the opposite medium. Incoming rays are either specularly reflected
-or refracted according to a Fresnel term computed with respect to the
-refractive indices of the 2 media as:
-+
-.......
-Fr = 1/2 * (Rs^2 + Rp^2)
-.......
-+
-with Rs and Rp the reflectance for the light polarized with its electric
-field perpendicular or parallel to the plane of incidence, respectively.
-+
-.......
-Rs = (n1 * |wi.N| - n2 * |wt.N|) / (n1 * |wi.N| + n2 * |wt.N|)
-Rp = (n2 * |wi.N| - n1 * |wt.N|) / (n2 * |wi.N| + n1 * |wt.N|)
-.......
-+
-with n1 and n2 the indices of refraction of the incident and transmitted
-media, and wi and wt the incident and transmitted direction.
-+
-Be careful to ensure the media consistency in the *solstice-input*(5) file; a
-ray travelling in a medium _A_ can only encounter a medium interface whose
-*medium_i* attribute is _A_. Consequently, a *dielectric* material must be
-defined as a double sided material whose front and back interfaces are
-dielectrics with inverted media:
-+
-.......
-material:
- front:
- dielectric:
- medium_i: &vacuum { refractive_index: 1, extinction: 0 }
- medium_t: &glass { refractive_index: 1.5, extinction: 20 }
- back:
- dielectric:
- medium_i: *glass
- medium_t: *vacuum
-.......
-+
-If the media consistency is not ensured, *solstice*(1) will fail to run
-simulations. Note that by default, the surrounding medium is assumed to be
-the vacuum, i.e. its refractive index and its extinction are scalars whose
-values are 1 and 0, respectively. If an atmosphere is defined, the refractive
-index of the surrounding medium is still the scalar 1 but its extinction is
-the one of the atmosphere. In other words, to reference the surrounding medium
-in the *medium_i* or the *medium_t* attribute of a *dielectric* interface, one
-has to define a medium whose refractive index is the scalar 1 and extinction
-is either 0 or the extinction of the atmosphere if the latter is defined or
-not, respectively.
-
-*matte*::
-Diffuse surface. Reflects the same intensity in all directions independently
-of the incoming direction.
-
-*mirror*::
-Specular or glossy reflection whether the *slope_error* parameter is 0 or not,
-respectively. Glossy reflections are controlled by a microfacet BRDF. The
-microfacet normals are distributed with respect to the Beckmann or the Pillbox
-distribution according to the *normal-distrib* attribute.
-+
-Let S the *slope_error* parameter in ]0, 1]. The Beckmann distribution is
-defined as:
-+
-.......
-D(wh) = exp(-tan^2(a) / m^2) / (PI * m^2 * cos^4(a))
-.......
-+
-with a = arccos(wh.N), and m = sqrt(2)*S while the pillbox distribution is
-defined as:
-+
-.......
- | 0; if |wh.N| >= S
-D(wh) = |
- | 1 / (PI * (1 - cos^2(S))); if |wh.N| < S
-.......
-
-*thin-dielectric*::
-The interface is assumed to be a thin slab of a dielectric material. The
-*medium_i* parameter defines the outside dielectric medium while *medium_t*
-is the medium of the thin slab. Incoming rays are either specularly reflected
-or transmitted (without deviation) according to a Fresnel term computed with
-respect to the refractive indices of the 2 media as:
-+
-.......
-Fr = 1/2 * (Rs^2 + Rp^2)
-.......
-+
-with Rs and Rp the reflectance for the light polarized with its electric
-field perpendicular or parallel to the plane of incidence, respectively.
-+
-.......
-Rs = (n1 * |wi.N| - n2 * |wt.N|) / (n1 * |wi.N| + n2 * |wt.N|)
-Rp = (n2 * |wi.N| - n1 * |wt.N|) / (n2 * |wi.N| + n1 * |wt.N|)
-.......
-+
-with n1 and n2 the indices of refraction of the incident and transmitted
-media, and wi and wt the incident and transmitted direction. Note that the
-underlying scattering function correctly handles the multiple refraction
-effects into the thin slab.
-+
-Be careful to ensure the media consistency in the *solstice-input*(5) file; a
-ray travelling in a medium _A_ can only encounter a medium interface whose
-*medium_i* attribute is _A_. If the media consistency is not ensured,
-*solstice*(1) will fail to run simulations. Note that by default, the
-surrounding medium is assumed to be the vacuum, i.e. its refractive index and
-its extinction are scalars whose values are 1 and 0, respectively. If an
-atmosphere is defined, the refractive index of the surrounding medium is still
-the scalar 1 but its extinction is the one of the atmosphere. In other words,
-to reference the surrounding medium in the *medium_i* attribute of a
-*thin-dielectric* interface, one has to define a medium whose refractive
-index is the scalar 1 and extinction is either 0 or the extinction of the
-atmosphere if the latter is defined.
-
-*virtual*::
-Fully transparent interface.
-
-Normal map
-~~~~~~~~~~
-
-All the material descriptors, excepted the *virtual*, provide an optional
-*normal-map* attribute that defines a path toward a Portable PixMap image [5]
-whose pixels store a normal expressed in the tangent space of the interface. By
-default the unperturbed tangent space normal is {0,0,1}. The PPM image can
-be encoded on 8 or 16-bits per component either in ASCII or binary. The
-parameterization of this 2D image onto the shape surfaces depends on the type
-of the shape. For the *hemisphere*, *hyperbol*, *parabol*, *plane* and
-*parabolic-cylinder* shapes, the image is mapped in the {X,Y} plane. The other
-shapes are not parameterized and consequently, applying a normal-mapped
-material on these shapes leads to undefined behaviors.
-
-SHAPE
------
-
-A *shape* describes a geometric model. It is defined in its local space, i.e.
-in a coordinate system whose origin is proper to the shape. No space
-transformation can be introduced through the declaration of a shape: it should
-be transformed externally through an *object* and/or *entities*.
-*solstice-input*(1) provides 2 types of shape: quadric and mesh. The former is
-used to declare parametric surfaces, while the latter describes triangulated
-surfaces.
-
-Quadric
-~~~~~~~
-
-A quadric shape is defined from a quadric equation and a set of 2D clipping
-operations performed in their {X,Y} plane. By convention, the front side of the
-quadric surface looks toward the positive Z axis. Internally, the clipped
-quadric surface is discretized in a triangular mesh with respect to the
-discretisation parameters of the quadric. This mesh is used by *solstice*(1)
-as a "proxy" to speed up the access toward the quadric shape: the quadric
-position and its associated normal are in fine computed from the quadric
-equation.
-
-The quadric surface is parameterized in the {X,Y} plane. Its parameterization
-domain is defined from the bounds of its clipped mesh in the {X,Y} plane:
-
- u = (x - lowerX) / (upperX-lowerX)
- v = (y - lowerY) / (upperY-lowerY)
-
-with *u* and *v* the mapped 2D coordinates from a 3D position {*x*,*y*,*z*}
-onto the quadric, and *lower*<**X**|**Y**> and *upper*<**X**|**Y**> the lower
-and upper bounds of the clipped quadric along the X and Y axis. The available
-quadrics are:
-
-*hemisphere*::
-Hemispheric shape defined along the Z axis whose minimum is positioned at
-the origin. The *slices* parameter controls the number of divisions along
-the Z axis.
-+
-.......
-x^2 + y^2 + (z-radius)^2 = radius^2
-.......
-
-*hyperbol*::
-Hyperbolic quadric defined along the Z axis whose minimum is positioned at
-the origin. The *slices* parameter controls the discretisation of the
-hyperbol. If not defined, it is automatically computed with respect to the
-hyperbol curvature.
-+
-.......
-(x^2 + y^2) / a^2 - (z + z0 - g/2)^2 / b^2 + 1 = 0
-
-a^2 = g^2(f - f^2)
-b = g(f - 1/2)
-z0 = |b| + g/2
-g = focals.real + focals.image
-f = focals.real / g
-.......
-
-*parabol*::
-Parabolic quadric defined along the Z axis whose minimum is positioned at the
-origin. The *slices* parameter controls the discretisation of the parabol. If
-not defined, it is automatically computed with respect to the parabol
-curvature.
-+
-.......
-x^2 + y^2 - 4 * focal * z = 0
-.......
-
-*parabolic-cylinder*::
-Parabolic cylinder oriented along the Z axis whose main axis is along the X
-axis and minimum is positioned at the origin. The *slices* parameter
-controls the discretisation of the parabolic cylinder. If not defined, it is
-automatically computed with respect to the parabolic cylinder curvature.
-+
-.......
-y^2 - 4 * focal * z = 0
-.......
-
-*plane*::
-Plane whose normal points along the positive Z axis. The *slices* attribute
-controls the discretisation of the clipped plane.
-
-Clipping
-~~~~~~~~
-
-A clipping operation, or *polyclip*, is used to remove some parts of the
-quadric surface. It is defined by a 2D *contour-descriptor* expressed in the
-{X,Y} plane and a clipping *operation*. The *AND* and *SUB* clip operands,
-remove the quadric surface that intersects or does not intersect the
-*contour-descriptor*, respectively. The available *countour-descriptors* are:
-
-*circle-descriptor*::
-Circular contour whose size is defined by the *radius* parameter. Actually,
-*solstice*(1) discretized the circular contour with respect to the *segments*
-attribute that defines the overall number of segments used to approximate the
-circle.
-
-*vertices-descriptor*::
-Polygonal contour described by a list of 2D vertices. The polygon edges are
-defined by connecting each vertex to its previous one. To ensure that the
-polygon is closed, an additional edge is automatically created between the
-first and the last vertex. Note that *solstice*(1) assumes that the defined
-polygon does not overlap itself, i.e. their non consecutive edges are not
-intersecting.
-
-The *clip* parameter of the quadrics lists a set of the aforementioned 2D
-*polyclips*. Each of these clipping operations is successively applied on the
-remaining quadric surface, in the order on which they are declared. For
-instance, the following example uses 5 clipping operations on a plane to build
-a rectangle with a circular hole at each of its corner. The first *polyclip*
-limits the infinite plane to a rectangle centered in 0 whose size in X and Y is
-8 and 4, respectively. The 4 subsequent *polyclips* drill the
-rectangle near of its corner with circles whose radius is 0.5:
-
-.......
-plane:
- clip:
- - {operation: AND, vertices: [[-4,-2],[-4,2],[4,2],[4,-2]]}
- - {operation: SUB, circle: {radius: 0.5, center: [-3,-1]}}
- - {operation: SUB, circle: {radius: 0.5, center: [-3, 1]}}
- - {operation: SUB, circle: {radius: 0.5, center: [ 3,-1]}}
- - {operation: SUB, circle: {radius: 0.5, center: [ 3, 1]}}
-.......
-
-Triangular mesh
-~~~~~~~~~~~~~~~
-
-Triangular meshes are generated by *solstice*(1) from a shape description or
-loaded from a CAO file. Their normals are defined per triangle and are thus
-discontinuous even for smooth shapes as spheres. The triangular meshes are not
-parameterized, i.e. they do not provide a mapping from a 3D position onto its
-surface to a 2D coordinates. Applying a normal-mapped material to a triangular
-mesh will thus produce undefined behaviors.
-
-The available triangular meshes are:
-
-*cuboid*::
- Axis aligned cuboid centered in 0 whose corner positions and dimensions along
- the 3 axis are defined by the *size* parameter. The front side of the cuboid
- surface looks outside the cuboid.
-
-*cylinder*::
- Cylinder centered in 0 whose *height* is along the positive Z axis. The top
- and the bottom of the cylinder is capped. The *stacks* and *slices*
- parameters control the discretisation, i.e. the number of divisions, along or
- around the Z axis, respectively. The front side of the cylinder surface looks
- outside the cylinder.
-
-*sphere*::
- Triangulated sphere centered in 0. The *stacks* and *slices* parameters
- control the discretisation, i.e. the number of divisions, along or around the
- Z axis, respectively. The front side of the sphere surface looks outside the
- sphere.
-
-*stl*::
- Path toward an external mesh file defined with respect to the ASCII
- **ST**ereo **L**ithography file format. The front side of the loaded
- triangles is defined with respect to their vertex ordering into the STL
- file: a triangle is front facing when their vertices are clock wise ordered.
-
-ENTITY
-------
-
-An *entity* is used to declare and position shapes into the solar plant.
-Actually, the entity is the only item that effectively spawns a *geometry* into
-the solar plant: if a geometry is declared but not referenced by an entity, it
-is ignored by *solstice*(1). An entity is a hierarchical data structure that
-can have child entities whose transformation is relative to their parent. If
-not defined, the *transform* parameter of an entity is assumed to be the
-identity, i.e. its *rotation* and *translation* are nulls.
-
-Each entity has a *name* which must be unique per hierarchy level: 2 root
-entities (i.e. entities without parent) cannot have the same name as well as
-the children of a same parent entity. In addition, the name string cannot
-contain dots, spaces or tabulations. A child entity is identified into the
-solar plant by successively concatenating, with the \'.' character, the name
-of its ancestors with its own name. This naming convention is used in the
-*solstice-receiver*(5) format to define the entities to track during the
-*solstice*(1) computations. For instance, in the following example, the
-*entity-identifier* of the child entity named *level2* is
-*level0.level1.level2*:
-.......
-entity:
- name: level0
- child:
- - name: level1
- child:
- - name: level2
-.......
-
-An entity encapsulates either a *geometry* or a *pivot*. The former is a
-collection of *objects*, i.e. *shapes* with their associated *material* and an
-optional *transformation*. The latter is used to control the dynamic
-positioning of the child entities with respect to some constraints defined by
-the pivot type, and the sun directions submitted by *solstice*(1). Each entity
-can also have a list of *anchors*. An anchor is used to define a position
-relative to the entity into which it is declared.
-
-For a geometric entity one has to define if the encapsulated geometry is a
-*primary* geometry, i.e. a geometry directly lit by the sun and used to
-concentrate the solar flux (e.g. a primary mirror). One can define all the
-solar plant geometric entities as primaries but a well designed solar plant
-with correctly tagged primary geometries will drastically improve the
-convergence speed of the *solstice*(1) simulations.
-
-Template
-~~~~~~~~
-
-A *template* is a first level entity with no existence into the solar plant. It
-is used to pre-declare an entity hierarchy that can then be instantiated
-several times in the solar plant by referencing it through common entities with
-YAML data tagging. In the following example, the templated entity *my-template*
-is instantiated 3 times into the scene:
-.......
-- template: &my-template
- name: bar
- primary: 1
- geometry: ...
-- entity:
- name: foo0
- transform: {translation: [-10.5, 0, 0]}
- children: [*my-template]
-- entity:
- name: foo1
- transform: {translation: [0, 0, 0]}
- children: [*my-template]
-- entity:
- name: foo2
- transform: {translation: [10.5, 0, 0]}
- children: [*my-template]
-.......
-
-Pivot
-~~~~~
-
-A *pivot* is a special kind of node that can be used in the tree data
-structure describing an entity to automatically point its child geometry
-according to the sun position and to the pivot parameters. It is supposed (but
-not mandatory) that the children of a pivot includes a reflector, that,
-once pivoted, will reflect the sun light towards a *target*. You should
-note that a pivot cannot be the child of another pivot.
-
-The most noticeable pivot parameter is its *target*. Four different types of
-targets are available:
-
-*position*::
- Define the target as being an absolute point in world coordinates.
-
-*anchor*::
- Define the target as being a position relative to an entity (see the
- *anchor* section).
-
-*sun*::
- Define the target as being the center of the sun.
-
-*direction*::
- The pivot reflects light in the given direction, specified in world
- coordinates.
-
-Pivots can also have a *ref_point* optional parameter defining a 3D point in
-the coordinate system the pivot children that will be used by the pointing algorithm.
-If not provided, it is set to the origin.
-
-Two different flavours of *pivots* are available: *x_pivot* and *zx_pivot*,
-each with its own set of parameters and behaviour.
-
-*x_pivot*::
- Pivot with a single rotation axis: the +X axis in its local coordinate
- system. It has a *target* and can have a *ref_point*. Its pointing algorithm
- considers an incoming ray of light from the center of the sun and rotates
- its children so that a specular reflection at *ref_point* using +Z as
- local normal will hit the target point of the pivot, or will have the
- specified direction (depending of the kind of target).
-
-*zx_pivot*::
- Pivot with two rotation axis: the +Z axis in its local coordinate system,
- then the +X axis in the coordinate system resulting of the Z rotation.
- It has a *target* and can have a *ref_point* and a *spacing* that defines
- the translation along the +Y axis after the first rotation. If not
- defined, *spacing* is 0. The *zx_pivot* pointing algorithm considers an
- incoming ray of light from the center of the sun and rotates its
- children so that a specular reflection at *ref_point* using
- +Y as local normal will hit the target point of the pivot, or will have
- the specified direction (depending of the kind of target).
-
-Anchor
-~~~~~~
-
-An *anchor* defines a relative position into the entity hierarchy. They are
-particularly useful for pivots and hyperbolic shapes that may have to
-reference a position relative to an entity whose transformations may also
-depends of its ancestor. An anchor has a *name* that must be unique for the
-whole sets of per entity anchors. In addition, a name cannot contain
-dots, spaces or tabulations. An anchor is identified into the solar plant by
-concatenating, with the \'.' character, its name to the *entity-identifier* of
-the entity into which it is declared. For instance, in the following example,
-the *anchor-identifier* of the anchor named *anchor0* is
-*level0.level1.anchor0*:
-.......
-entity:
- name: level0
- child:
- - name: level1
- anchor:
- - {name: anchor0, position: [0, 0, 0]}
- - {name: anchor1, position: [1, 2, 3]}
-.......
-
-In some situations, the *anchor-identifier* cannot be fully determined. Let a
-templated entity with a descendant referencing an anchor of one of its
-ancestors. On its declaration, the template is still not instantiated through a
-parent entity and consequently the name of the root entity is unknown.
-Moreover, the name of the root entity cannot be fixed since it changes for each
-instance of the template. To handle these cases, the *self* reserved keyword
-allows to reference the unknown root entity of the currently declared
-hierarchy. In the following example, the entities *entity0.level0.level1* and
-*entity1.level0.level1* encapsulate a pivot that references the anchor
-*anchor0* defined in their respective parent *entity0.level0* and
-*entity1.level0*:
-.......
-- template: &my-template
- name: level0
- anchor: [{name: anchor0, position: [1, 2, 3]}]
- child:
- - name: level1
- pivot:
- x_pivot:
- ref_point: {0, 0, 0}
- target: {anchor: self.level0.anchor0}
-
-- entity: {name: entity0, child: [*my-template]}
-- entity: {name: entity1, child: [*my-template]}
-.......
-
-Transform
-~~~~~~~~~
-
-A *transform* is used to move an *object* or an *entity* in space. The
-*rotation* parameter list 3 angles in degrees defining the rotation to perform
-around the X, Y and Z axis. The *translation* attribute describes the offsets
-to apply along the X, Y and Z axis. Let the local repair *p* of an object, *p*
-is transformed in *p'* with respect to its associated *transform* as follow:
-
- p' = Rx * Ry * Rz * (T + p)
-
-with *T* the translation vector and *Rx*, *Ry* and *Rz* the rotation matrices
-around the X, Y and Z axis defined as:
-
- | 1 0 0 | | cY 0 sY | | cZ -sZ 0 |
- Rx = | 0 cX -sX |; Ry = | 0 1 0 |; Rz = | sZ cZ 0 |
- | 0 sX cX | |-sY 0 cY | | 0 0 1 |
-
-where *c*<**X**|**Y**|**Z**> and *s*<**X**|**Y**|**Z**> are the cosine and the
-sinus, respectively, of the rotation angles around the X, Y and Z axis.
-
-EXAMPLES
---------
-
-Declare 2 entities and a point source sun. The first entity is a purely
-specular square of size 10, whose center is at the origin. The second entity
-is a purely transparent square used as a receiver of the solar flux. Its size
-is 1 and its center is positioned at {0,0,2}:
-.......
-- sun: {dni: 1000}
-
-- entity:
- name: reflector
- primary: 1
- geometry:
- - material:
- mirror:
- reflectivity: 1
- slope_error: 0
- plane:
- clip:
- - operation: AND
- vertices:
- - [-5.0,-5.0]
- - [-5.0, 5.0]
- - [ 5.0, 5.0]
- - [ 5.0,-5.0]
-
-- entity:
- name: receiver
- primary: 0
- transform:
- translation: [0, 0, 2]
- geometry:
- - material:
- virtual: # No attrib
- plane:
- clip:
- - operation: AND
- vertices:
- - [-0.5,-0.5]
- - [-0.5, 0.5]
- - [ 0.5, 0.5]
- - [ 0.5,-0.5]
-.......
-
-Define a circular diffuse reflector surrounded by a virtual sphere and a
-pillbox-shaped sun whose *half_angle* is 0.1 degree. Use anchors and tags of the
-YAML format to reference into the entities a pre-declared geometry. Rely on
-the YAML compact notation to reduce the number of lines required to describe
-the scene:
-.......
-- sun: {dni: 1000, pillbox: {half_angle: 0.1}}
-
-- geometry: &small-circle
- - material: {matte: {reflectivity: 1}}
- plane: {clip: [{operation: AND, circle: {radius: 0.5}}]}
-
-- geometry: &big-sphere
- - material: {?virtual}
- sphere: {radius: 2, slices: 128}
-
-- entity: {name: reflector, primary: 1, geometry: *small-circle}
-- entity: {name: receiver, primary: 0, geometry: *big-sphere}
-.......
-
-Declare 2 parabolic reflectors from a *templated* parabola whose orientation is
-controlled by a *zx_pivot*. This pivot ensures that the reflector points toward
-the receiver, independently of its position, by targeting an *anchor* whose
-position is defined relatively to the receiver:
-.......
-- sun: {dni: 1000}
-
-- entity: # Receiver
- name: square_receiver
- primary: 0
- transform: { rotation: [0,90,0], translation: [100,0,10] }
- anchors: [{name: anchor0, position: [0,0,0]}]
- geometry:
- - material: {?virtual}
- plane:
- clip:
- - operation: AND
- vertices: [[-.5,-.5],[-.5,.5],[.5,.5],[.5,-.5]]
-
-- template: &self_oriented_parabol # Reflector
- name: pivot
- transform: {translation: [0, 0, 4], rotation: [0, 0, 90]}
- zx_pivot: {target: {anchor: square_receiver.anchor0}}
- children:
- - name: parabol
- transform: {rotation: [-90, 0, 0]}
- primary: 1
- geometry:
- - material: {mirror: {reflectivity: 1, slope_error: 0}}
- parabol:
- focal: 100
- clip:
- - operation: AND
- vertices: [[-5,-5],[-5,5],[5,5],[5,-5]]
-
-# Instantiate the reflector template
-- entity:
- name: reflector1
- transform: {translation: [0,0,0]}
- children: [*self_oriented_parabol]
-- entity:
- name: reflector2
- transform: {translation: [10,43.6,0]}
- children: [*self_oriented_parabol]
-.......
-
-Declare a solar furnace with 9 heliostats instantiated from the same
-*template*. Their position is controlled by a *zx_pivot* to ensure that the
-incoming sun rays are reflected toward the negative X axis. Reflected rays are
-then concentrated by a parabola toward a purely absorptive receiver. The
-heliostats and the parabola share the same material: the front faces are
-purely specular while the back faces are diffuse:
-.......
-- sun: {dni: 1000}
-
-- material: &specular
- front: {mirror: {reflectivity: 1, slope_error: 0}}
- back: {matte: {reflectivity: 1}}
-
-- template: &H # Template of an heliostat
- name: heliostat
- transform: {translation: [0,0,5.5]}
- zx_pivot: {target: {direction: [-1,0,0]}}
- children:
- - name: reflector
- transform: {rotation: [-90,0,0]}
- primary: 1
- geometry:
- - material: *specular
- plane:
- clip: [{operation: AND, vertices: [[-5,-5],[-5,5],[5,5],[5,-5]]}]
-
-- entity: # Receiver entity
- name: receiver
- primary: 0
- transform: {translation: [18,0,20], rotation: [0,90,0]}
- geometry:
- - material: {matte: {reflectivity: 0}}
- plane:
- clip:
- - operation: AND
- vertices: [[-.5,-.5],[-.5,.5],[.5,.5],[.5,-.5]]
-
-- entity: # Great parabola
- name: parabola
- primary: 0
- transform: {translation: [0,0,20], rotation: [0,90,90]}
- geometry:
- - material: *specular
- parabol:
- focal: 18
- clip: [{operation: AND, vertices: [[-30,-20],[-30,20],[30,20],[30,-20]]}]
-
-# Instantiate the heliostat template
-- entity: {name: H1, children: [*H], transform: {translation: [40,-20, 0]}}
-- entity: {name: H2, children: [*H], transform: {translation: [40, 0, 0]}}
-- entity: {name: H3, children: [*H], transform: {translation: [40, 20, 0]}}
-- entity: {name: H4, children: [*H], transform: {translation: [60,-20,10]}}
-- entity: {name: H5, children: [*H], transform: {translation: [60, 0,10]}}
-- entity: {name: H6, children: [*H], transform: {translation: [60, 20,10]}}
-- entity: {name: H7, children: [*H], transform: {translation: [80,-20,20]}}
-- entity: {name: H8, children: [*H], transform: {translation: [80, 0, 20]}}
-- entity: {name: H9, children: [*H], transform: {translation: [80, 20,20]}}
-.......
-
-This example illustrates the use of quadrics and refractive materials: in this
-example, three partial *parabols* with various focal distances and positions
-concentrate incoming radiation at a common focal position. But a *hyperbol* is
-located between the parabols and their common focal position, which is also
-one of the two focals of the hyperbol. Radiation is therefore redirected to
-the second focal of the hyperbol, where the square target is located. Finally,
-a *cuboid* using a glass material is located between the hyperbol and the
-target. In this example, a small fraction of incoming power is absorbed by the
-target. The rest is either missing the target, absorbed or refracted by the
-glass. Furthermore, this example illustrates the use of a *spectrum* for
-*refractive index* and *extinction* by various *media* (air and glass).
-.......
-# Spectra
-- spectrum: &solar_spectrum
- - {wavelength: 0.3, data: 1.0}
- - {wavelength: 0.4, data: 2.0}
- - {wavelength: 0.5, data: 0.5}
- - {wavelength: 0.6, data: 3.5}
- - {wavelength: 0.7, data: 1.5}
- - {wavelength: 0.8, data: 0.8}
-
-- spectrum: &air_kabs
- - {wavelength: 0.3, data: 1.0e-4}
- - {wavelength: 0.4, data: 1.0e-5}
- - {wavelength: 0.5, data: 2.0e-5}
- - {wavelength: 0.6, data: 2.0e-4}
- - {wavelength: 0.7, data: 3.0e-5}
- - {wavelength: 0.8, data: 1.0e-4}
-
-- spectrum: &glass_kabs
- - {wavelength: 0.3, data: 1.0e-2}
- - {wavelength: 0.4, data: 1.0e-3}
- - {wavelength: 0.5, data: 2.0e-3}
- - {wavelength: 0.6, data: 2.0e-2}
- - {wavelength: 0.7, data: 3.0e-3}
- - {wavelength: 0.8, data: 1.0e-3}
-
-- spectrum: &glass_ref_index
- - {wavelength: 0.30, data: 1.40}
- - {wavelength: 0.40, data: 1.39}
- - {wavelength: 0.50, data: 1.37}
- - {wavelength: 0.60, data: 1.34}
- - {wavelength: 0.70, data: 1.30}
- - {wavelength: 0.80, data: 1.25}
-
-# Media
-- medium: &air_medium
- refractive_index: 1
- extinction: *air_kabs
-
-- medium: &glass_medium
- refractive_index: *glass_ref_index
- extinction: *glass_kabs
-
-# Sun & atmosphere
-- sun: {dni: 1, spectrum: *solar_spectrum}
-- atmosphere: {extinction: *air_kabs}
-
-# Materials
-- material: &specular {mirror: {reflectivity: 1, slope_error: 0}}
-- material: &black {matte: {reflectivity: 0}}
-- material: &glass
- front: {dielectric: {medium_i: *air_medium, medium_t: *glass_medium}}
- back: {dielectric: {medium_i: *glass_medium, medium_t: *air_medium}}
-
-# Primary reflectors
-- entity:
- name: "primary_reflector1"
- primary: 1
- transform: {translation: [0, 0, -2.0]}
- geometry:
- - material: *specular
- parabol:
- focal: 12
- clip:
- - {operation: AND, circle: {radius: 10}}
- - {operation: SUB, circle: {radius: 5}}
-
-- entity:
- name: "primary_reflector2"
- primary: 1
- transform: {translation: [0, 0, -4]}
- geometry:
- - material: *specular
- parabol:
- focal: 14
- clip:
- - {operation: AND, circle: {radius: 15}}
- - {operation: SUB, circle: {radius: 10}}
-
-- entity:
- name: "primary_reflector3"
- primary: 1
- transform: {translation: [0, 0, -6]}
- geometry:
- - material: *specular
- parabol:
- focal: 16
- clip:
- - {operation: AND, circle: {radius: 20}}
- - {operation: SUB, circle: {radius: 15}}
-
-# Secondary reflector
-- entity:
- name: "secondary_reflector"
- primary: 0
- transform: {translation: [0, 0, 6]}
- geometry:
- - material: *specular
- hyperbol:
- focals: {real: 16.0, image: 4}
- clip: [{operation: AND, circle: {radius: 5}}]
-
-# Glass box
-- entity:
- name: "glass_slide"
- primary: 0 # The entity is not sampled as a primary reflector
- geometry:
- - material: *glass
- cuboid: {size: [10,10,0.5]}
- transform: {translation: [0, 0, 0.25]}
-
-# Receiver
-- entity:
- name: "square_receiver"
- primary: 0 # The entity is not sampled as a primary reflector
- transform: {translation: [0, 0, -10] }
- geometry:
- - material: *black
- plane:
- clip:
- - operation: AND
- vertices: [[-0.5,-0.5],[-0.5,0.5],[0.5,0.5],[0.5,-0.5]]
-.......
-
-
-NOTES
------
-1. YAML Ain't Markup Language - <http://yaml.org>
-2. SMARTS, Simple Model of the Atmospheric Radiative Transfer of Sunshine -
- <http://www.nrel.gov/rredc/smarts/>
-3. D. Buie, A.G. Monger, C.J. Dey. "Sunshape distributions for
- terrestrial solar simulations". Solar Energy, 2003, 74, pp. 113-122.
-4. D. Buie, C.J. Dey, S. Bosi. "The effective size of the solar cone for
- solar concentrating systems". Solar Energy, 2003, 74, pp. 417-427.
-5. Portable PixMap - <http://netpbm.sourceforge.net/doc/ppm.html>
-
-SEE ALSO
---------
-*solstice*(1), *solstice-receiver*(5)
diff --git a/doc/solstice-man.css b/doc/solstice-man.css
@@ -1,96 +0,0 @@
-/* Copyright (C) 2016-2018 CNRS
- *
- * This is free style sheet: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This CSS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/. */
-
-body.manpage {
- font-family:"Liberation Sans",sans-serif;
- font-size:10pt;
- text-align: justify;
- max-width: 55em;
- margin: 1em;
- background: #ffffff
-}
-
-body.manpage .monospaced, .literalblock {
- margin: 2em;
- color: #636261
-}
-
-body.manpage em {
- color: #660000
-}
-
-body.manpage div.verseblock > pre.content {
- font-family: "Liberation Mono",monospace;
-}
-
-body.manpage h1 {
- padding-bottom: 0.5em;
-}
-body.manpage h2 {
- border-style: none;
-}
-body.manpage div.sectionbody {
- margin-left: 3em;
-}
-
-body.manpage code {
- font-family: "Liberation Mono",monospace;
-}
-
-body.manpage #footer { display: none; }
-
-body.manpage div#toctitle { display: none; }
-
-body.manpage div#toc {
- display: block;
- position:fixed;
- top:0;
- left:60em;
- height:100%;
- width: 100%;
- padding:3em 0 0 0;
- border-left:1px solid #dbdbdb;
- background: #eeeeee
-}
-
-body.manpage a {
- font-weight: bold;
- color: #225588;
-}
-
-body.manpage div#toc a, div#toc a:link, div#toc a:visited {
- margin:0;
- padding-left: 2em;
- color:#999999;
- text-decoration:none;
- font-weight: normal;
-}
-
-body.manpage div.toclevel1 {
- line-height: 1.5em;
-}
-
-body.manpage div.toclevel2 {
- margin-left: 2em;
-}
-
-body.manpage div#toc a:hover {
- color:#666666;
-}
-
-@media print {
- body.manpage div#toc { display: none; }
-}
-
diff --git a/doc/solstice-output.5 b/doc/solstice-output.5
@@ -0,0 +1,665 @@
+.\" SPDX-License-Identifier: GPL-3.0-or-later
+.\" Copyright (C) 2016-2018 CNRS, 2018-2019 |Méso|Star>
+.\"
+.\" This is free documentation: you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation, either version 3 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
+.Dd $Mdocdate$
+.Dt SOLSTICE-OUTPUT 5
+.Os
+.Sh NAME
+.Nm solstice-output
+.Nd output format of solstice
+.Sh DESCRIPTION
+The
+.Nm
+format describes the output produced by the
+.Xr solstice 1
+program.
+All data generated by a
+.Xr solstice 1
+invocation are written to a single file or to standard output, depending
+on whether an
+.Ar output
+file is specified through the
+.Fl o
+option or not.
+Submitting several sun directions to
+.Xr solstice 1
+through the
+.Fl D
+option produces as many outputs as sun directions: invoking
+.Xr solstice 1
+with N sun directions is equivalent to calling it N times and
+concatenating the associated outputs.
+.Pp
+The type of data generated depends on the mode in which
+.Xr solstice 1
+is invoked.
+By default,
+.Xr solstice 1
+evaluates the power collected by the submitted solar plant.
+When invoked with the
+.Fl g
+option, it converts the solar plant geometries into a list of CAO files.
+The
+.Fl p
+option tracks the sampled radiative paths, and the
+.Fl r
+option renders an image of the solar facility.
+.Sh GRAMMAR
+Output values are mainly ASCII data formatted line by line.
+By convention, line data in the following grammar are listed between
+quote marks.
+The grammar may span multiple lines for formatting purposes, but data
+are on a single line until a closing quote mark.
+.Bd -literal
+<o> ::= <simulation-output>
+ | <dump-geometry-output> # -g option
+ | <dump-radiative-paths-output> # -p option
+ | <rendering-output> # -r option
+
+<simulation-output>
+ ::= <sun-direction>
+ <counts>
+ <global>
+ [ <receivers-list> ]
+ [ <primaries-list> ]
+ [ <rcvXprims-list> ]
+ [ <receiver-maps> ]
+ [ <simulation-output> ... ]
+
+<dump-geometry-output>
+ ::= <sun-direction>
+ <geometry-data>
+ [ <dump-geometry-output> ... ]
+
+<dump-radiative-paths-output>
+ ::= <sun-direction>
+ VTK-RADIATIVE-PATHS
+ [ <dump-radiative-paths-output> ... ]
+
+<rendering-output>
+ ::= <sun-direction>
+ PPM-FILE # ASCII PPM with 8-bits per component [1]
+ [ <rendering-output> ... ]
+.Ed
+.Bd -literal
+<sun-direction> ::= "#--- Sun direction: <alpha> <beta> (<sun-vector>)"
+
+<counts> ::= "<#globals> <#receivers> <#primaries>
+ <#samples> <#failed>"
+
+<#globals> ::= 7
+<#receivers> ::= INTEGER # in [0, INF)
+<#primaries> ::= INTEGER # in [0, INF)
+<#samples> ::= INTEGER # in [0, INF)
+<#failed> ::= INTEGER # in [0, INF)
+
+<global> ::= <potential-flux>
+ <absorbed-flux>
+ <cos-factor>
+ <shadow-loss>
+ <missing-loss>
+ <materials-loss>
+ <atmospheric-loss>
+.Ed
+.Bd -literal
+<receivers-list> ::= <receiver>
+ [ <receiver> ... ]
+
+<receiver> ::= "<receiver-name> <receiver-id> <area>
+ <front> <back>"
+
+<receiver-name> ::= <entity-identifier>
+<receiver-id> ::= INTEGER
+
+<front> ::= <side>
+<back> ::= <side>
+
+<side> ::= "<incoming-flux> <in-if-no-mat-loss>
+ <in-if-no-atm-loss> <in-mat-loss> <in-atm-loss>
+ <absorbed-flux> <abs-if-no-mat-loss>
+ <abs-if-no-atm-loss> <abs-mat-loss> <abs-atm-loss>
+ <efficiency>"
+.Ed
+.Bd -literal
+<primaries-list> ::= <primary>
+ [ <primary> ... ]
+
+<primary> ::= "<primary-name> <primary-id> <area> <#samples>
+ <cos-factor> <shadow-loss>"
+
+<primary-name> ::= <entity-identifier>
+<primary-id> ::= INTEGER
+.Ed
+.Bd -literal
+<rcvXprims-list> ::= <rcvXprim>
+ [ <rcvXprim> ... ]
+
+<rcvXprim> ::= "<receiver-id> <primary-id>
+ <rcvXprim-front> <rcvXprim-back>"
+
+<rcvXprim-front> ::= <rcvXprim-side>
+<rcvXprim-back> ::= <rcvXprim-side>
+
+<rcvXprim-side> ::= "<incoming-flux> <in-if-no-mat-loss>
+ <in-if-no-atm-loss> <in-mat-loss> <in-atm-loss>
+ <absorbed-flux> <abs-if-no-mat-loss>
+ <abs-if-no-atm-loss> <abs-mat-loss> <abs-atm-loss>"
+.Ed
+.Bd -literal
+<receiver-maps> ::= VTK-RECEIVER-MAP
+ [ <receiver-maps> ... ]
+
+<geometry-data> ::= OBJ-FILE
+ [ ---
+ <geometry-data> ... ]
+.Ed
+.Bd -literal
+<area> ::= REAL # in ]0, INF)
+<real3> ::= REAL REAL REAL
+
+<alpha> ::= REAL # Degrees in [0, 360[
+<beta> ::= REAL # Degrees in [0, 90]
+<sun-vector> ::= <real3>
+
+<incoming-flux> ::= <estimate>
+<in-if-no-mat-loss> ::= <estimate>
+<in-if-no-atm-loss> ::= <estimate>
+<in-mat-loss> ::= <estimate>
+<in-atm-loss> ::= <estimate>
+<absorbed-flux> ::= <estimate>
+<abs-if-no-mat-loss> ::= <estimate>
+<abs-if-no-atm-loss> ::= <estimate>
+<abs-mat-loss> ::= <estimate>
+<abs-atm-loss> ::= <estimate>
+<cos-factor> ::= <estimate>
+<missing-loss> ::= <estimate>
+<materials-loss> ::= <estimate>
+<atmospheric-loss> ::= <estimate>
+<shadow-loss> ::= <estimate>
+<efficiency> ::= <estimate>
+
+<estimate> ::= <expected-value> <standard-error>
+<expected-value> ::= REAL
+<standard-error> ::= REAL # in [0, INF)
+
+<entity-identifier> # Defined in solstice-input(5)
+.Ed
+.Sh SIMULATION
+A
+.Em simulation-output
+begins with two header lines.
+The first reports the sun direction used in the simulation (two angles
+in degrees, plus the corresponding sun vector).
+The second lists the numbers of global, per-receiver and per-primary
+results, as well as the overall number of Monte-Carlo experiments and
+the number of experiments that failed due to unforeseen errors such as
+numerical imprecisions.
+As soon as the number of failed experiments reaches 1% of the required
+number of Monte-Carlo experiments, the code exits with an
+.Qq Error in integrating the solar flux
+message, and the validity of subsequent results is questionable:
+estimates are produced using the number of successful experiments, which
+is necessarily smaller than the required number.
+.Ss Global results
+After the two header lines, the output includes various
+.Em global
+result lines; the exact number is given in the header (currently 7).
+Each global result is a pair of real numbers: the expected value and its
+standard error.
+The global results are, in order:
+.Bl -tag -width Ds
+.It Em potential-flux
+Maximum flux that all primary geometries could intercept if properly
+oriented and flat-shaped.
+.It Em absorbed-flux
+Absorbed part of the flux reaching any receiver geometry.
+At most equal to the potential flux.
+.It Em cos-factor
+Cosine of the angle between the sun direction and the normal of the
+primary surfaces (average over all primary geometries).
+.It Em shadow-loss
+Potential flux intercepted by another geometry before reaching a primary
+geometry.
+.It Em missing-loss
+Part of the flux that reaches a primary geometry and follows a radiative
+path but is not absorbed; this flux may have bounced on geometries,
+including receivers, without being absorbed.
+.It Em materials-loss
+Total flux absorbed by non-receivers along radiative paths; includes
+both surface and volume absorption.
+.It Em atmospheric-loss
+Total flux extinction by the atmosphere along radiative paths.
+.El
+.Pp
+These results can be used to check conservation of energy:
+.Em potential-flux No * Em cos-factor
+and
+.Pq Em absorbed-flux No + Em shadow-loss No + Em missing-loss No + Em materials-loss No + Em atmospheric-loss
+should be equal within their respective uncertainty ranges.
+.Ss Per receiver results
+Following the global results, the output includes one line per receiver,
+sorted according to the order of the receivers as defined in the
+submitted
+.Xr solstice-receiver 5
+file.
+Each line contains:
+.Bl -tag -width Ds
+.It Em receiver-name
+Name of the receiver, i.e.\& the
+.Em entity-identifier
+of the entity in which the receiving geometry is defined (see
+.Xr solstice-input 5 ) .
+.It Em receiver-id
+Unique integer identifying the receiver.
+.It Em area
+Area of the receiver.
+.It Em front
+Estimated results for the front side of the receiver.
+.It Em back
+Estimated results for the back side of the receiver.
+.El
+.Pp
+The estimates for the
+.Em front
+and
+.Em back
+sides are as follows (each is a pair: expected value and standard
+error):
+.Bl -tag -width Ds
+.It Em incoming-flux
+Flux that reaches the receiver side.
+.It Em in-if-no-mat-loss
+Incoming flux if absorption on non-receivers is not taken into account.
+.It Em in-if-no-atm-loss
+Incoming flux if atmospheric extinction is not taken into account.
+.It Em in-mat-loss
+.Em in-if-no-mat-loss No \- Em incoming-flux .
+.It Em in-atm-loss
+.Em in-if-no-atm-loss No \- Em incoming-flux .
+.It Em absorbed-flux
+Flux absorbed by the receiver side.
+.It Em abs-if-no-mat-loss
+Absorbed flux if absorption by non-receivers is not taken into account.
+.It Em abs-if-no-atm-loss
+Absorbed flux if atmospheric extinction is not taken into account.
+.It Em abs-mat-loss
+.Em abs-if-no-mat-loss No \- Em absorbed-flux .
+.It Em abs-atm-loss
+.Em abs-if-no-atm-loss No \- Em absorbed-flux .
+.It Em efficiency
+Fraction of the potential flux absorbed by this receiver side.
+.El
+.Pp
+Both
+.Em front
+and
+.Em back
+side estimates are always output, even if the receiver has only a single
+receiving side.
+In that case, the results of the non-receiving side are meaningless
+(invalid \-1 value).
+.Ss Per primary results
+Following the per-receiver results, the output includes one line per
+primary geometry.
+Each line contains:
+.Bl -tag -width Ds
+.It Em primary-name
+Name of the primary geometry, i.e.\& the
+.Em entity-identifier
+of the entity in which the primary geometry is defined (see
+.Xr solstice-input 5 ) .
+.It Em primary-id
+Unique integer identifying the primary geometry.
+.It Em area
+Area of the primary geometry.
+.It Em #samples
+Number of Monte-Carlo experiments sampled on the primary geometry.
+.It Em cos-factor
+Cosine of the angle between the sun direction and the normal of the
+primary surface (average over the primary geometry).
+.It Em shadow-loss
+Potential flux intercepted by another geometry before reaching this
+primary geometry.
+.El
+.Ss Per receiver and per primary results
+Following the per-primary results, the output includes result lines
+describing the contribution of each primary geometry to each receiver.
+The total number of such lines is the number of receivers times the
+number of primary geometries.
+Each line contains:
+.Bl -tag -width Ds
+.It Em receiver-id
+Identifier of the involved receiver.
+.It Em primary-id
+Identifier of the involved primary geometry.
+.It Em rcvXprim-front
+Estimated results for the receiver front side.
+.It Em rcvXprim-back
+Estimated results for the receiver back side.
+.El
+.Pp
+The estimated values of
+.Em rcvXprim-front
+and
+.Em rcvXprim-back
+are as follows (each is a pair: expected value and standard error):
+.Bl -tag -width Ds
+.It Em incoming-flux
+Flux that reaches the receiver side.
+.It Em in-if-no-mat-loss
+Incoming flux if absorption on non-receivers is not taken into account.
+.It Em in-if-no-atm-loss
+Incoming flux if atmospheric extinction is not taken into account.
+.It Em in-mat-loss
+.Em in-if-no-mat-loss No \- Em incoming-flux .
+.It Em in-atm-loss
+.Em in-if-no-atm-loss No \- Em incoming-flux .
+.It Em absorbed-flux
+Flux absorbed by the receiver side.
+.It Em abs-if-no-mat-loss
+Absorbed flux if absorption by non-receivers is not taken into account.
+.It Em abs-if-no-atm-loss
+Absorbed flux if atmospheric extinction is not taken into account.
+.It Em abs-mat-loss
+.Em abs-if-no-mat-loss No \- Em absorbed-flux .
+.It Em abs-atm-loss
+.Em abs-if-no-atm-loss No \- Em absorbed-flux .
+.El
+.Pp
+Both front and back side estimates are always output, even if the
+receiver has only a single receiving side.
+In that case, the results of the non-receiving side are meaningless
+(invalid \-1 value).
+.Ss Receiver map
+A receiver defined in the submitted
+.Xr solstice-receiver 5
+file can have a per-primitive estimate of its incoming flux density
+and/or absorbed flux density if its
+.Em per_primitive
+flag is active.
+In this case,
+.Xr solstice 1
+generates a
+.Em receiver-map :
+an ASCII VTK file
+.Po
+see
+.Sx NOTES ,
+reference 2
+.Pc
+that stores the triangular mesh of the receiver and, for each triangle,
+the estimate of its associated incoming and/or absorbed flux density.
+The resolution of the receiver map is thus controlled by the
+discretization of the receiver's shape as described in the
+.Xr solstice-input 5
+file.
+To obtain a good estimate of the per-triangle flux densities, the
+number of per-triangle experiments must be sufficient; since only a
+small fraction of the overall sampled radiative paths reach a given
+triangle, the total number of experiments specified through the
+.Fl n
+option of
+.Xr solstice 1
+should be increased significantly, by 1 or 2 orders of magnitude.
+.Pp
+The number of written per-triangle flux density estimates depends on
+the receiver's parameters: both front and back sides can be active, and
+each side can produce an estimate for both incoming and absorbed flux
+density.
+As a consequence, the output can include up to 4 different estimates,
+written in the order: incoming front, absorbed front, incoming back,
+absorbed back.
+The following grammar describes the formatting of a
+.Em VTK-RECEIVER-MAP .
+Refer to the VTK format specification
+.Po
+reference 2
+.Pc
+for more information on the VTK file format.
+.Bd -literal
+VTK-RECEIVER-MAP ::= # vtk DataFile Version 2.0
+ <receiver-name>
+ ASCII
+ DATASET POLYDATA
+ POINTS <#vertices> float
+ <map-vertices>
+ POLYGONS <#triangles> <#triangles*4>
+ <map-triangles>
+ CELL_DATA <#triangles>
+ <map-triangle-data>
+
+<map-vertices> ::= <real3>
+ [ <real3> ... ] # up to <#vertices>
+
+<map-triangles> ::= 3 <triangle-indices>
+ [ 3 <triangle-indices> ... ] # up to <#triangles>
+
+<map-triangle-data> ::= <map-front-data>
+ | <map-back-data>
+ | <map-front-data> <map-back-data>
+
+<map-front-data> ::= <map-side-data>
+<map-back-data> ::= <map-side-data>
+
+<map-side-data> ::= <incoming-flux>
+ | <absorbed-flux>
+ | <incoming-flux> <absorbed-flux>
+
+<incoming-flux> ::= <flux-density-data>
+<absorbed-flux> ::= <flux-density-data>
+
+<flux-density-data> ::= SCALARS <side-and-flux-names> float 2
+ LOOKUP_TABLE default
+ <estimate>
+ [ <estimate> ... ]
+
+<side-and-flux-names> ::= Front_faces_Incoming_flux
+ | Front_faces_Absorbed_flux
+ | Back_faces_Incoming_flux
+ | Back_faces_Absorbed_flux
+
+<#triangles> ::= INTEGER
+<#vertices> ::= INTEGER
+<triangle-indices> ::= INTEGER INTEGER INTEGER
+.Ed
+.Sh DUMP GEOMETRY
+A
+.Em dump-geometry-output
+is generated when
+.Xr solstice 1
+is invoked with the
+.Fl g
+option.
+For each submitted sun direction,
+.Xr solstice 1
+converts the geometry of the submitted
+.Xr solstice-input 5
+file into triangular meshes written to the output in the format
+specified by the
+.Cm format
+sub-option of
+.Fl g .
+The only currently supported format is Alias Wavefront OBJ
+.Po
+reference 3
+.Pc .
+With no further sub-option, a single OBJ file containing the whole mesh
+of the solar plant is generated.
+The
+.Cm split
+sub-option of
+.Fl g
+allows generating several OBJ descriptions, one per
+.Cm geometry
+or per
+.Cm object
+as defined in the
+.Xr solstice-input 5
+format; each description is then followed by a line containing
+.Qq ---
+to mark the end of the current OBJ.
+.Pp
+Regardless of the
+.Cm split
+strategy, each geometry is an OBJ group whose name is the
+.Em entity-identifier
+of the entity in which it is encapsulated.
+The
+.Em usemtl
+OBJ directive associates to each mesh the name of its material type.
+The following grammar describes the formatting of an
+.Em OBJ-FILE .
+Refer to the OBJ format specification
+.Po
+reference 3
+.Pc
+for more information.
+.Bd -literal
+OBJ-FILE ::= g <entity-identifier>
+ <obj-mesh>
+ [ <obj-mesh> ... ]
+
+<obj-mesh> ::= usemtl <material-type>
+ <obj-vertices>
+ <obj-faces>
+
+<obj-vertices> ::= v <real3>
+ [ v <real3> ... ]
+
+<obj-indices> ::= f <triangle-indices>
+ [ f <triangle-indices> ... ]
+
+<material-type> ::= dielectric
+ | matte
+ | mirror
+ | thin_dielectric
+ | virtual
+.Ed
+.Sh DUMP RADIATIVE PATHS
+For each sun direction, the
+.Em dump-radiative-paths-output
+lists the geometric data of the radiative paths sampled during a
+simulation.
+Each path is coloured according to its type:
+.Bl -tag -width Ds
+.It Yellow
+The first segment (the ray from the sun toward a primary geometry) is
+occluded by a non-virtual object.
+.It Blue
+The path is not occluded and reaches a receiver.
+.It Turquoise
+The path is not occluded and does not reach a receiver.
+.It Red
+The path was cancelled due to a topologically incoherent impact (an
+impact on a surface not at the boundary of the medium in which the ray
+was propagating).
+.El
+.Pp
+The following grammar describes the formatting of a
+.Em VTK-RADIATIVE-PATHS
+file.
+Refer to the VTK format specification
+.Po
+reference 2
+.Pc
+for more information.
+.Bd -literal
+VTK-RADIATIVE-PATHS ::= # vtk DataFile Version 2.0
+ Radiative paths
+ ASCII
+ DATASET POLYDATA
+ POINTS <#vertices> float
+ <paths-vertices>
+ LINES <#paths> <#paths+#vertices>
+ <paths-lists>
+ CELL_DATA <#paths>
+ SCALAR Radiative_path_type float 1
+ LOOKUP_TABLE path_type
+ <paths-type>
+ LOOKUP_TABLE path_type 5
+ <color-error>
+ <color-unused>
+ <color-success>
+ <color-missing>
+ <color-occluded>
+
+<paths-vertices> ::= <real3>
+ [ <real3> ... ] # up to <#vertices>
+
+<paths-lists> ::= <radiative-path>
+ [ <radiative-path> ... ] # up to <#paths>
+
+<radiative-path> ::= <#path-segments> <path-vertex-id> ...
+
+<paths-type> ::= <color-id>
+ [ <color-id> ... ] # up to <#paths>
+
+<color-id> ::= 0.0 # Red: for error paths
+ | 0.25 # Green: unused
+ | 0.5 # Blue: for success paths
+ | 0.75 # Turquoise: for missing paths
+ | 1.0 # Yellow: for occluded paths
+
+<color-error> ::= 1.0 0.0 0.0 1.0
+<color-unused> ::= 0.0 1.0 0.0 1.0
+<color-success> ::= 0.0 0.0 1.0 1.0
+<color-missing> ::= 0.0 1.0 1.0 1.0
+<color-occluded> ::= 1.0 1.0 0.0 1.0
+
+<#paths> ::= INTEGER
+<#path-segments> ::= INTEGER
+<path-vertex-id> ::= INTEGER
+.Ed
+.Sh RENDERING
+When invoked with the
+.Fl r
+option,
+.Xr solstice 1
+generates one image of the solar facility per submitted sun direction.
+Each image is preceded by its associated sun direction and saved in the
+ASCII PPM file format
+.Po
+reference 1
+.Pc .
+The output images are greyscale images whose pixels store the average
+normalized radiance that reaches them.
+.Sh NOTES
+.Bl -enum
+.It
+Portable PixMap \(em
+.Lk http://netpbm.sourceforge.net/doc/ppm.html
+.It
+VTK file format \(em
+.Lk http://www.vtk.org/wp-content/uploads/2015/04/file-formats.pdf
+.It
+OBJ file format \(em
+.Lk http://www.martinreddy.net/gfx/3d/OBJ.spec
+.El
+.Sh SEE ALSO
+.Xr solstice 1 ,
+.Xr solstice-input 5 ,
+.Xr solstice-receiver 5
+.Sh HISTORY
+.Nm
+was initially developed with funding from the
+.Em SOLSTICE LabEx
+.Pq Laboratory of Excellence ,
+in collaboration with the PROMES Laboratory of the
+French National Centre for Scientific Research
+.Pq CNRS .
+.Sh AUTHORS
+.Nm
+was written and is maintained by
+.An |M\['e]so|Star> Aq Mt contact@meso-star.com .
diff --git a/doc/solstice-output.5.txt b/doc/solstice-output.5.txt
@@ -1,541 +0,0 @@
-// Copyright (C) 2016-2018 CNRS, 2018-2019 |Meso|Star>
-//
-// This is free documentation: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This manual is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-:toc:
-
-solstice-output(5)
-==================
-
-NAME
-----
-solstice-output - output format of solstice(1) results
-
-DESCRIPTION
------------
-The *solstice-output* describes the output format of the *solstice*(1) program.
-All the data generated by a *solstice*(1) invocation are written in a single
-file or on the standard output whether an _output_ file is defined through the
-*-o* option or not, respectively. Note that submitting several sun directions
-to *solstice*(1), through the *-D* option, will produce as many outputs as sun
-directions. In other words, invoking *solstice*(1) with _N_ sun directions
-looks like calling *solstice*(1) _N_ times and concatenating their associated
-output.
-
-The type of the data that are generated depends on the mode in which
-*solstice*(1) is invoked. By default, *solstice*(1) evaluates the power
-collected by the submitted solar plant. When invoked with the *-g* option,
-*solstice*(1) converts the solar plant geometries in a list of CAO files. The
-*-p* option is used to track the sampled radiative paths while, finally, the
-*-r* option allows to render an image of the solar facility.
-
-GRAMMAR
--------
-The output values are mainly ASCII data formatted line by line. By convention,
-in the following grammar the line data are listed between quote marks. The
-grammar may use new lines for formatting constraints, but data are actually on
-the same line while a closed quote mark is not defined.
-
-[verse]
-_______
-<output> ::= <simulation-output>
- | <dump-geometry-output> # -g option
- | <dump-radiative-paths-output> # -p option
- | <rendering-output> # -r option
-
-<simulation-output> ::= <sun-direction>
- <counts>
- <global>
- [ <receivers-list> ]
- [ <primaries-list> ]
- [ <rcvXprims-list> ]
- [ <receiver-maps> ]
- [ <simulation-output> ... ]
-
-<dump-geometry-output>
- ::= <sun-direction>
- <geometry-data>
- [ <dump-geometry-output> ... ]
-
-<dump-radiative-paths-output>
- ::= <sun-direction>
- VTK-RADIATIVE-PATHS
- [ <dump-radiative-paths-output> ... ]
-
-<rendering-output> ::= <sun-direction>
- PPM-FILE # ASCII PPM with 8-bits per component [1]
- [ <rendering-output> ... ]
-
--------------------------------------
-
-<sun-direction> ::= "#--- Sun direction: <alpha> <beta> (<sun-vector>)"
-
-<counts> ::= "<#globals> <#receivers> <#primaries>
- <#samples> <#failed>"
-
-<#globals> ::= 7
-<#receivers> ::= INTEGER # in [0, INF)
-<#primaries> ::= INTEGER # in [0, INF)
-<#samples> ::= INTEGER # in [0, INF)
-<#failed> ::= INTEGER # in [0, INF)
-
-<global> ::= <potential-flux>
- <absorbed-flux>
- <cos-factor>
- <shadow-loss>
- <missing-loss>
- <materials-loss>
- <atmospheric-loss>
-
--------------------------------------
-
-<receivers-list> ::= <receiver>
- [ <receiver> ... ]
-
-<receiver> ::= "<receiver-name> <receiver-id> <area>
- <front> <back>"
-
-<receiver-name> ::= <entity-identifier>
-
-<receiver-id> ::= INTEGER
-
-<front> ::= <side>
-<back> ::= <side>
-
-<side> ::= "<incoming-flux> <in-if-no-mat-loss>
- <in-if-no-atm-loss> <in-mat-loss> <in-atm-loss>
- <absorbed-flux> <abs-if-no-mat-loss>
- <abs-if-no-atm-loss> <abs-mat-loss> <abs-atm-loss>
- <efficiency>"
-
--------------------------------------
-
-<primaries-list> ::= <primary>
- [ <primary> ... ]
-
-<primary> ::= "<primary-name> <primary-id> <area> <#samples>
- <cos-factor> <shadow-loss>"
-
-<primary-name> ::= <entity-identifier>
-
-<primary-id> ::= INTEGER
-
--------------------------------------
-
-<rcvXprims-list> ::= <rcvXprim>
- [ <rcvXprim> ... ]
-
-<rcvXprim> ::= "<receiver-id> <primary-id>
- <rcvXprim-front> <rcvXprim-back>"
-
-<rcvXprim-front> ::= <rcvXprim-side>
-<rcvXprim-back> ::= <rcvXprim-side>
-
-<rcvXprim-side> ::= "<incoming-flux> <in-if-no-mat-loss>
- <in-if-no-atm-loss> <in-mat-loss> <in-atm-loss>
- <absorbed-flux> <abs-if-no-mat-loss>
- <abs-if-no-atm-loss> <abs-mat-loss> <abs-atm-loss>"
-
--------------------------------------
-
-<receiver-maps> ::= VTK-RECEIVER-MAP
- [ <receiver-maps> ... ]
-
-<geometry-data> ::= OBJ-FILE
- [ ---
- <geometry-data> ... ]
-
--------------------------------------
-
-<area> ::= REAL # in ]0, INF)
-
-<real3> ::= REAL REAL REAL
-
-<alpha> ::= REAL # Degrees in [0, 360[
-<beta> ::= REAL # Degrees in [0, 90]
-<sun-vector> ::= <real3>
-
-<incoming-flux> ::= <estimate>
-<in-if-no-mat-loss> ::= <estimate>
-<in-if-no-atm-loss> ::= <estimate>
-<in-mat-loss> ::= <estimate>
-<in-atm-loss> ::= <estimate>
-<absorbed-flux> ::= <estimate>
-<abs-if-no-mat-loss> ::= <estimate>
-<abs-if-no-atm-loss> ::= <estimate>
-<abs-mat-loss> ::= <estimate>
-<abs-atm-loss> ::= <estimate>
-<cos-factor> ::= <estimate>
-<missing-loss> ::= <estimate>
-<materials-loss> ::= <estimate>
-<atmospheric-loss> ::= <estimate>
-<shadow-loss> ::= <estimate>
-<efficiency> ::= <estimate>
-
-<estimate> ::= <expected-value> <standard-error>
-<expected-value> ::= REAL
-<standard-error> ::= REAL # in [0, INF)
-
-<entity-identifier> # Defined in *solstice-input*(5)
-_______
-
-SIMULATION
-----------
-
-A *simulation-output* begins with two header lines. The first one reports the
-sun direction used in the simulation (two angles in degrees, plus the
-corresponding sun vector),
-and the second one lists the numbers of global, per receiver and per
-primary results as well as the overall number of Monte-Carlo experiments used
-by the simulation and the number of experiments that failed due to unforeseen
-errors as numerical imprecisions. As soon as the number of failed experiments
-reaches 1% of the required number of Monte-Carlo experiments, the code exits
-with a "Error in integrating the solar flux" message, and the validity of
-subsequent results is questionable: estimates are produced using the number of
-Monte-Carlo experiments that have been successful, which is necessarily smaller
-than the required number of experiments.
-
-Global results
-~~~~~~~~~~~~~~
-
-After the 2 header lines, the output includes various *global* result lines,
-the exact number of lines being part of the headers. Currently this number is
-7. Each global result is a pair of real numbers: the expected value and its
-standard error. The global results are, in this order:
-
-- *potential-flux*: maximum flux that all the primary geometries could
- intercept if properly oriented and flat-shaped;
-- *absorbed-flux*: absorbed part of the flux reaching any receiver geometry.
- At most equal to the potential flux;
-- *cos-factor*: cos of the angle between the sun direction and the normal of
- the primary surfaces (average cos over all primary geometries);
-- *shadow-loss*: potential flux intercepted by another geometry before
- reaching a primary geometry;
-- *missing-loss*: part of the flux that reaches a primary geometry, follows a
- radiative path, but is not absorbed; this flux could have bounced on
- geometries, including receivers, but without being absorbed;
-- *materials-loss*: total flux absorbed by non-receivers along radiative
- paths; includes both surface and volume absorption;
-- *atmospheric-loss*: total flux extinction by the atmosphere along radiative
- paths.
-
-This results can be used to check conservation of energy:
-
-potential-flux * cos-factor and (absorbed-flux + shadow-loss +
-missing-loss + materials-loss + atmospheric-loss)
-should be equal within their respective uncertainty ranges.
-
-Per receiver results
-~~~~~~~~~~~~~~~~~~~~
-
-Following global results, the output includes various per-receiver lines, one
-line per receiver, the exact number of lines being part of the headers. The
-per-receiver results are sorted according to the order of the receivers as
-defined in the submitted *solstice-receiver*(5) file. Each line contains the
-following data:
-
-- *receiver-name*: name of the receiver, i.e. *entity-identifier* of the
- entity in which the receiving geometry is defined (see the
- *solstice-input*(5) format);
-- *receiver-id*: unique integer identifying the receiver;
-- *area*: area of the receiver;
-- *front*: estimated results for the front side of the receiver;
-- *back*: estimated results for the back side of the receiver.
-
-The estimates of the *front* and *back* sides are listed bellow. Note that
-each of the following estimates is actually a pair of real numbers: the
-expected value and its standard error.
-
-- *incoming-flux*: flux that reaches the receiver side;
-- *in-if-no-mat-loss*: incoming-flux if absorption on non-receivers is not
- taken into account;
-- *in-if-no-atm-loss*: incoming-flux if atmospheric extinction is not taken
- into account;
-- *in-mat-loss*: in-if-no-mat-loss - incoming-flux;
-- *in-atm-loss*: in-if-no-atm-loss - incoming-flux;
-- *absorbed-flux*: flux absorbed by the receiver side;
-- *abs-if-no-mat-loss*: absorbed-flux if absorption by non-receivers is not
- taken into account;
-- *abs-if-no-atm-loss*: absorbed-flux if atmospheric extinction is not taken
- into account;
-- *abs-mat-loss*: abs-if-no-mat-loss - absorbed-flux;
-- *abs-atm-loss*: abs-if-no-atm-loss - absorbed-flux;
-- *efficiency*: fraction of the potential flux absorbed by this receiver side.
-
-Both *front* and *back* side estimates are output, even if the receiver has
-only a single receiving side. In this case, the results of the non-receiving
-side are meaningless (invalid -1 value).
-
-Per primary results
-~~~~~~~~~~~~~~~~~~~
-
-Following the per-receiver results, the output includes various per-primary
-result lines, one line per primary geometry, the exact number of lines being
-part of the headers. Each line contains:
-
-- *primary-name*: name of the primary geometry, i.e. *entity-identifier* of
- the entity in in which the primary geometry is defined (see the
- *solstice-input*(5) format);
-- *primary-id*: unique integer identifying the primary geometry;
-- *area*: area of the primary geometry;
-- *#sample*: number of Monte-Carlo experiments sampled on the primary
- geometry;
-- *cos-factor*: cos of the angle between the sun direction and the normal of
- the primary surface (average cos on the primary geometry);
-- *shadow-loss*: potential flux intercepted by another geometry before reaching
- the primary geometry of interest.
-
-Per receiver and per primary results
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Following the per-primary results, the output includes various result lines,
-each describing the contribution of a primary geometry to a given receiver.
-The total number of such lines is the number of receivers times the number of
-primary geometries. Each line contains:
-
-- *receiver-id*: identifier of the involved receiver;
-- *primary-id*: identifier of the involved primary geometry;
-- *rcvXprim-front*: estimated results for the receiver front side;
-- *rcvXprim-back*: estimated results for the receiver back side;
-
-The estimated values of *rcvXprim-front* and *rcvXprim-back* are listed
-bellow. Each of these estimates is actually a pair of real numbers: the
-expected value and its standard error.
-
-- *incoming-flux*: flux that reaches the receiver side;
-- *in-if-no-mat-loss*: incoming-flux if absorption on non-receivers is not
- taken into account;
-- *in-if-no-atm-loss*: incoming-flux if atmospheric extinction is not taken
- into account;
-- *in-mat-loss*: in-if-no-mat-loss - incoming-flux;
-- *in-atm-loss*: in-if-no-atm-loss - incoming-flux;
-- *absorbed-flux*: flux absorbed by the receiver side;
-- *abs-if-no-mat-loss*: absorbed-flux if absorption by non-receivers is not
- taken into account;
-- *abs-if-no-atm-loss*: absorbed-flux if atmospheric extinction is not taken
- into account;
-- *abs-mat-loss*: abs-if-no-mat-loss - absorbed-flux;
-- *abs-atm-loss*: abs-if-no-atm-loss - absorbed-flux;
-
-Both front and back side estimates are output, even if the receiver has only a
-single receiving side. In this case, the results of the non-receiving side are
-meaningless (invalid -1 value).
-
-Receiver map
-~~~~~~~~~~~~
-
-A receiver defined in the submitted *solstice-receiver*(5) file, can have a
-per-primitive estimate of its incoming flux density and/or absorbed flux
-density if its *per_primitive* flag is active. In this case, *solstice*(1)
-generates a *receiver-map* that is actually an ASCII VTK file [2] that stores
-the triangular mesh of the receiver and, for each triangle, the estimate of
-its associated incoming flux density and/or absorbed flux density. The
-"definition" of the receiver map is thus controlled by the discretisation of
-the receiver's shape, as described in the *solstice-input*(5) file. Note that
-to obtain a good estimate of the per-triangle flux densities, one have to
-ensure that the number of per-triangle experiments is sufficient regarding the
-targeted accuracy. Since only a small fraction of the overall sampled
-radiative paths reach a given triangle, the total number of experiments
-required through the *-n* option of *solstice*(1) should be increased
-significantly, as 1 or 2 order of magnitude.
-
-The number of written per-triangle flux density estimates depends on the
-receiver's parameters: both front and back sides of the receiver can be active
-and each side can produce an estimate both for the incoming flux density and
-for the absorbed flux density. As a consequence, the output can include up to
-4 different estimates that are written in the order: incoming front, absorbed
-front, incoming back, absorbed back. The following grammar gives a brief
-description of the formatting of a *VTK-RECEIVER-MAP*. Please refer to the VTK
-format specification [2] for more informations on the VTK file format.
-
-[verse]
-_______
-VTK-RECEIVER-MAP ::= # vtk DataFile Version 2.0
- <receiver-name>
- ASCII
- DATASET POLYDATA
- POINTS <#vertices> float
- <map-vertices>
- POLYGONS <#triangles> <#triangles*4>
- <map-triangles>
- CELL_DATA <#triangles>
- <map-triangle-data>
-
-<map-vertices> ::= <real3>
- [ <real3> ... ] # up to <#vertices>
-
-<map-triangles> ::= 3 <triangle-indices>
- [ 3 <triangle-indices> ... ] # up to <#triangles>
-
-<map-triangle-data> ::= <map-front-data>
- | <map-back-data>
- | <map-front-data> <map-back-data>
-
-<map-front-data> ::= <map-side-data>
-<map-back-data> ::= <map-side-data>
-
-<map-side-data> ::= <incoming-flux>
- | <absorbed-flux>
- | <incoming-flux> <absorbed-flux>
-
-<incoming-flux> ::= <flux-density-data>
-<absorbed-flux> ::= <flux-density-data>
-
-<flux-density-data> ::= SCALARS <side-and-flux-names> float 2
- LOOKUP_TABLE default
- <estimate>
- [ <estimate> ... ]
-
-<side-and-flux-names> ::= Front_faces_Incoming_flux
- | Front_faces_Absorbed_flux
- | Back_faces_Incoming_flux
- | Back_faces_Absorbed_flux
-
-<#triangles> ::= INTEGER
-<#vertices> ::= INTEGER
-<triangle-indices> ::= INTEGER INTEGER INTEGER
-_______
-
-DUMP GEOMETRY
--------------
-
-A *dump-geometry-output* is generated when *solstice*(1) is invoked with the
-*-g* option. In this mode, for each submitted sun direction, *solstice*(1)
-converts the geometry of the submitted *solstice-input*(5) file in triangular
-meshes that are then written to the output with respect to the format provided
-by the *format* parameter of the *-g* option. The only format currently
-supported by *solstice*(1) is the Alias Wavefront OBJ [3] format. With no more
-sub-option, *solstice*(1) will thus generate one OBJ file containing the whole
-mesh of the solar plant. However, the *split* parameter of the *-g* option
-allows to generate several OBJ files: one description is generated per
-*geometry* or per *object*, as defined in the *solstice-input*(5) format,
-whether the *split* sub-option is set to *geometry* or *object*. In this
-situation, each OBJ description is followed by a line with 3 minus characters
-in order to identify the end of the current OBJ.
-
-Independently of the *split* strategy, each *solstice-input*(1) geometry is an
-OBJ group whose name is the *entity-identifier* of the entity in which it is
-encapsulated. Finally, the *dump-geometry-output* uses the *usemtl* directive
-of the OBJ format to associate to a mesh the name of its material type. The
-following grammar succinctly describes the formatting of an *OBJ-FILE*. Please
-refer to the OBJ format specification [3] for more informations on the OBJ file
-format.
-
-[verse]
-_______
-OBJ-FILE ::= g <entity-identifier>
- <obj-mesh>
- [ <obj-mesh> ... ]
-
-<obj-mesh> ::= usemtl <material-type>
- <obj-vertices>
- <obj-faces>
-
-<obj-vertices> ::= v <real3>
- [ v <real3> ... ]
-
-<obj-indices> ::= f <triangle-indices>
- [ f <triangle-indices> ... ]
-
-<material-type> ::= dielectric
- | matte
- | mirror
- | thin_dielectric
- | virtual
-_______
-
-DUMP RADIATIVE PATHS
---------------------
-
-For each sun direction, the *dump-radiative-paths-output* lists the geometric
-data of the radiative paths sampled during a simulation. Each path is colored
-with respect to its type: the path is yellow if its first segment, i.e.
-the ray starting from the sun towards a primary geometry, is occluded by a non
-virtual object. If not occluded, the path can be blue or turquoise whether it
-reaches a receiver or not, respectively. Finally, the path can also be red if
-it was canceled due to a topologically incoherent impact (i.e. an impact on a
-surface not at the boundary of the medium in which the rays was propagating).
-The following grammar describes the formatting of a *VTK-RADIATIVE-PATHS*
-file. Refer to the VTK format specification [2] for more informations on the
-VTK file format.
-
-[verse]
-_______
-VTK-RADIATIVE-PATHS ::= # vtk DataFile Version 2.0
- Radiative paths
- ASCII
- DATASET POLYDATA
- POINTS <#vertices> float
- <paths-vertices>
- LINES <#paths> <#paths+#vertices>
- <paths-lists>
- CELL_DATA <#paths>
- SCALAR Radiative_path_type float 1
- LOOKUP_TABLE path_type
- <paths-type>
- LOOKUP_TABLE path_type 5
- <color-error>
- <color-unused>
- <color-success>
- <color-missing>
- <color-occluded>
-
-<paths-vertices> ::= <real3>
- [ <real3> ... ] # up to <#vertices>
-
-<paths-lists> ::= <radiative-path>
- [ <radiative-path> ... ] # up to <#path>
-
-<radiative-path> ::= <#path-segments> <path-vertex-id> ...
-
-<paths-type> ::= <color-id>
- [ <color-id> ... ] # up to <#paths>
-
-<color-id> ::= 0.0 # Red: for error paths
- | 0.25 # Green: unused
- | 0.5 # Blue: for success paths
- | 0.75 # Turquoise: for missing paths
- | 1.0 # Yellow: for occluded paths
-
-<color-error> ::= 1.0 0.0 0.0 1.0
-<color-unused> ::= 0.0 1.0 0.0 1.0
-<color-success> ::= 0.0 0.0 1.0 1.0
-<color-missing> ::= 0.0 1.0 1.0 1.0
-<color-occluded> ::= 1.0 1.0 0.0 1.0
-
-<#paths> ::= INTEGER
-<#path-segments> ::= INTEGER
-<path-vertex-id> ::= INTEGER
-_______
-
-RENDERING
----------
-When invoked with the *-r* option, *solstice*(1) generates an image of the
-solar facility for each submitted sun direction. Each image is preceded by its
-associated sun direction and is saved with respect to the ASCII PPM file
-format [1]. The output images are actually greyscale images whose pixels store
-the average normalized radiance that reaches them.
-
-NOTES
------
-1. Portable PixMap - <http://netpbm.sourceforge.net/doc/ppm.html>
-2. VTK file format -
- <http://www.vtk.org/wp-content/uploads/2015/04/file-formats.pdf>
-3. OBJ file format -
- <http://www.martinreddy.net/gfx/3d/OBJ.spec>
-
-SEE ALSO
---------
-*solstice*(1),
-*solstice-input*(5),
-*solstice-receiver*(5)
diff --git a/doc/solstice-receiver.5 b/doc/solstice-receiver.5
@@ -0,0 +1,165 @@
+.\" Copyright (C) 2016-2018 CNRS, 2018-2019 |Meso|Star>
+.\"
+.\" This is free documentation: you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation, either version 3 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
+.\"
+.Dd $Mdocdate$
+.Dt SOLSTICE-RECEIVER 5
+.Os
+.Sh NAME
+.Nm solstice-receiver
+.Nd declare solar-plant receivers for solstice
+.Sh DESCRIPTION
+The
+.Nm
+format is used by
+.Xr solstice 1
+to declare which geometric entities defined in a
+.Xr solstice-input 5
+file act as receivers.
+For each receiver,
+.Xr solstice 1
+computes its total intercepted power, associated losses, and efficiency.
+Refer to
+.Xr solstice-output 5
+for details on the per-receiver data produced by
+.Xr solstice 1 .
+Defining receivers separately from the solar plant allows the same
+.Xr solstice-input 5
+file to be reused across multiple simulations with different receiver
+configurations.
+For example, you can create a dedicated
+.Nm
+file that designates certain primary reflectors as receivers to investigate
+unexpected behaviour observed in a prior simulation.
+.Pp
+The
+.Nm
+format follows the YAML 1.1 data serialization standard
+.Po
+see
+.Sx NOTES ,
+reference 1
+.Pc .
+Provided the file conforms to the
+.Nm
+semantic, receivers can be described by using the whole YAML 1.1
+functionalities including compact notation and data tagging.
+.Pp
+A receiver is identified by its
+.Em name ,
+which must be a valid
+.Em entity-identifier
+as defined in
+.Xr solstice-input 5 .
+This identifier must refer to a geometric entity, not a pivot or an empty
+entity.
+The side of the geometry to be tracked is specified by the
+.Em side
+attribute.
+Both the front and back sides of a geometry can be considered by setting
+.Em side
+to
+.Cm FRONT_AND_BACK .
+See
+.Xr solstice-input 5
+for details on which side of a geometry is considered front-facing or
+back-facing.
+.Pp
+If the optional
+.Em per_primitive
+flag is enabled,
+.Xr solstice 1
+estimates the flux density for each triangle of the receiver and uses this data
+to generate a receiver map as described in
+.Xr solstice-output 5 .
+The
+.Em per_primitive
+flag accepts the values
+.Cm INCOMING ,
+.Cm ABSORBED ,
+or
+.Cm INCOMING_AND_ABSORBED
+to produce the incoming flux density map, the absorbed flux density map, or
+both, respectively.
+.Sh GRAMMAR
+.Bd -literal
+<receivers-list> ::= - <receiver>
+ [ - <receiver> ... ]
+
+<receiver> ::= name: <entity-identifier>
+ side: <side-identifier>
+ [ per_primitive: <per-primitive-mode> ] # Default: NONE
+
+<side-identifier> ::= FRONT
+ | BACK
+ | FRONT_AND_BACK
+
+<per-primitive-mode> ::= NONE
+ | INCOMING
+ | ABSORBED
+ | INCOMING_AND_ABSORBED
+
+<entity-identifier> # Defined in solstice-input(5)
+.Ed
+.Sh EXAMPLES
+Designate both the front and back sides of the entity
+.Cm small_square
+as receivers, and enable per-triangle absorbed flux density computation for each
+side:
+.Bd -literal
+- name: small_square
+ side: FRONT_AND_BACK
+ per_primitive: ABSORBED
+.Ed
+.Pp
+Declare the front side of three reflectors as receivers using YAML compact
+notation:
+.Bd -literal
+- {name: H1.heliostat.reflector, side: FRONT}
+- {name: H4.heliostat.reflector, side: FRONT}
+- {name: H7.heliostat.reflector, side: FRONT}
+.Ed
+.Pp
+Designate the back side of
+.Cm receiver
+as a receiver with an incoming flux density map, and make the front side of the
+reflector named
+.Cm LFR0.pivot.reflector
+a receiver:
+.Bd -literal
+- {name: receiver, side: BACK, per_primitive: INCOMING}
+- {name: LFR0.pivot.reflector, side: FRONT}
+.Ed
+.Sh NOTES
+.Bl -enum
+.It
+YAML Ain't Markup Language \(em
+.Lk http://yaml.org
+.El
+.Sh SEE ALSO
+.Xr solstice 1 ,
+.Xr solstice-input 5 ,
+.Xr solstice-output 5
+.Sh HISTORY
+.Nm
+was initially developed with funding from the
+.Em SOLSTICE LabEx
+.Pq Laboratory of Excellence ,
+in collaboration with the PROMES Laboratory of the
+French National Centre for Scientific Research
+.Pq CNRS .
+.Sh AUTHORS
+.Nm
+was written and is maintained by
+.An |M\['e]so|Star> Aq Mt contact@meso-star.com .
diff --git a/doc/solstice-receiver.5.txt b/doc/solstice-receiver.5.txt
@@ -1,122 +0,0 @@
-// Copyright (C) 2016-2018 CNRS, 2018-2019 |Meso|Star>
-//
-// This is free documentation: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This manual is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-:toc:
-
-solstice-receiver(5)
-====================
-
-NAME
-----
-solstice-receiver - declare the solar-plant receivers for solstice(1)
-
-
-DESCRIPTION
------------
-
-The *solstice-receiver* format is used by *solstice*(1) to declare which
-geometric entities defined in a *solstice-input*(5) file are receivers. For
-each receiver, *solstice*(1) computes its overall intercepted power, its
-associated losses as well as its efficiency. Refer to the *solstice-output*(5)
-format for informations on the per receiver data generated by *solstice*(1).
-Declaring the receivers separately of the solar plant, allows to use the same
-*solstice-input*(5) file for several simulations using different receivers. For
-instance, one can define a specific *solstice-receiver* file that declares some
-primary reflectors as receivers in order to track an unforeseen comportment
-observed during a previous simulation.
-
-The *solstice-receiver* format uses the YAML 1.1 data serialization standard
-[1]; assuming that the file is compatible with the *solstice-receiver*
-semantic, the YAML compact notation can thus be used.
-
-A receiver is identified by its *name* that must be a valid *entity-identifier*
-as defined in the *solstice-input*(5) format. This identifier must reference a
-geometric entity and not a pivot or an empty entity. The side of the geometry
-that is tracked is defined by the *side* attribute of the receiver. Note that
-the front and the back side of a geometry can be both considered if the *side*
-attribute is set to *FRONT_AND_BACK*. Refer to the *solstice-input*(5)
-specification for informations on which side of the geometry is front facing or
-back facing. Finally, if the optional *per_primitive* flag is set,
-*solstice*(1) will estimate the irradiance for each triangle of the receiver
-and use these data to generate a receiver map as described in
-*solstice-output*(5). The *per-primitive* flag can be set to *INCOMING*,
-*ABSORBED* or *INCOMING_AND_ABSORBED* to produce the incoming flux density
-map, the absorbed flux density map, or both.
-
-GRAMMAR
--------
-
-[verse]
-_______
-<receivers-list> ::= - <receiver>
- [ - <receiver> ... ]
-
-<receiver> ::= name: <entity-identifier>
- side: <side-identifier>
- [ per_primitive: <per-primitive-mode> ] # Default: NONE
-
-<side-identifier> ::= FRONT
- | BACK
- | FRONT_AND_BACK
-
-<per-primitive-mode> ::= NONE
- | INCOMING
- | ABSORBED
- | INCOMING_AND_ABSORBED
-
-<entity-identifier> # Defined in *solstice-input*(5)
-_______
-
-EXAMPLES
---------
-
-Define that the front and back side of the entity *small_square* are
-receivers. For each side, enable the computation of per triangle absorbed
-irradiance.
-
-.......
-- name: small_square
- side: FRONT_AND_BACK
- per_primitive: ABSORBED
-.......
-
-Declare that the front side of 3 reflectors are receivers. Use the YAML
-compact notation to reduce the number of lines:
-
-......
-- {name: H1.heliostat.reflector, side: FRONT}
-- {name: H4.heliostat.reflector, side: FRONT}
-- {name: H7.heliostat.reflector, side: FRONT}
-......
-
-Declare that the back side of *receiver* is effectively a receiver and enable
-the estimation of its associated incoming irradiance map. Make a receiver from
-the front side of the reflector named *LFR0.pivot.reflector*:
-
-.......
-- {name: receiver, side: BACK, per_primitive: INCOMING}
-- {name: LFR0.pivot.reflector, side: FRONT}
-.......
-
-NOTES
------
-
-1. YAML Ain't Markup Language - <http://yaml.org>
-
-SEE ALSO
---------
-*solstice*(1),
-*solstice-input*(5),
-*solstice-output*(5)
-
diff --git a/doc/solstice.1.in b/doc/solstice.1.in
@@ -0,0 +1,411 @@
+.\" SPDX-License-Identifier: GPL-3.0-or-later
+.\" Copyright (C) 2016-2018 CNRS, 2018-2019 |Méso|Star>
+.\"
+.\" This is free documentation: you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation, either version 3 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
+.Dd $Mdocdate$
+.Dt SOLSTICE 1
+.Os
+.Sh NAME
+.Nm solstice
+.Nd compute the power collected by a concentrated solar plant
+.Sh SYNOPSIS
+.Nm
+.Nm
+.Op Ar option ...
+.Op Ar file
+.Nm
+.Fl g Ar sub-option Ns Op : Ns Ar ...
+.Op Ar option ...
+.Op Ar file
+.Nm
+.Fl p Ar sub-option Ns Op : Ns Ar ...
+.Op Ar option ...
+.Op Ar file
+.Nm
+.Fl r Ar sub-option Ns Op : Ns Ar ...
+.Op Ar option ...
+.Op Ar file
+.Sh DESCRIPTION
+.Nm
+computes the total power collected by a concentrated solar plant, as
+described in the
+.Xr solstice-input 5
+.Ar file .
+If the
+.Ar file
+argument is not provided, the solar plant is read from standard input.
+To evaluate various efficiencies for each primary reflector, it computes
+losses due to cosine effect, shadowing and masking, orientation and surface
+irregularities, materials properties and atmospheric extinction.
+The efficiency for each one of these effects is subsequently computed for
+each reflector.
+.Pp
+The entities on which computations must be performed are listed in the
+.Xr solstice-receiver 5
+file submitted through the
+.Fl R
+option.
+The estimated results follow the
+.Xr solstice-output 5
+format and are written to the
+.Ar output
+file or to the standard output whether the
+.Fl o Ar output
+option is defined or not, respectively.
+Note that the
+.Nm
+algorithm is based on the Monte-Carlo method, which means that every
+result is provided with its numerical accuracy.
+.Pp
+.Nm
+is designed to efficiently handle complex solar facilities: several
+reflectors can be specified (planes, conics, cylindro-parabolic, etc.\&)
+and positioned in 3D space, with a possibility for 1-axis and 2-axis
+auto-orientation.
+Multiple materials can be used, as long as the relevant physical properties
+are provided.
+Spectral effects are also taken into account: it is possible to define the
+spectral distribution of any physical property, including the input solar
+spectrum and the transmissivity of the atmosphere, at any spectral
+resolution.
+Refer to
+.Xr solstice-input 5
+for more information.
+.Pp
+In addition to the aforementioned computations,
+.Nm
+provides three other functionalities.
+The
+.Fl g
+option can be used to convert the
+.Xr solstice-input 5
+geometries into CAO files.
+The
+.Fl p
+option saves the sampled radiative paths used by the estimates, allowing
+to visualise them externally, which may be a great help to identify a
+design issue.
+Finally, the
+.Fl r
+option is used to render an image of the submitted solar facility.
+Note that these three options are mutually exclusive, and once defined,
+they replace the default
+.Nm
+behaviour.
+.Pp
+Any coordinate-related question in
+.Nm
+must be considered with the right-handed convention in mind.
+.Sh OPTIONS
+.Bl -tag -width Ds
+.It Fl D Ar alpha,beta Ns Op : Ns Ar ...
+List of sun directions.
+A direction is defined by two angles in degrees.
+The first one,
+.Ar alpha ,
+is an azimuthal angle in [0,\ 360[ and the second one,
+.Ar beta ,
+is an elevation in [0,\ 90].
+Each provided sun direction triggers a new computation whose results are
+concatenated to the
+.Ar output
+file.
+.Pp
+Following the right-handed convention, azimuthal rotation is
+counter-clockwise, with 0\(de on the X axis.
+Elevation starts from 0\(de for directions in the XY plane, up to 90\(de
+at zenith.
+Thus
+.Fl D Ns Ar 0,0 ,
+.Fl D Ns Ar 90,0 ,
+.Fl D Ns Ar 180,0
+and
+.Fl D Ns Ar 270,0
+produce solar vectors {-1,0,0}, {0,-1,0}, {+1,0,0} and {0,+1,0}
+respectively, while
+.Fl D Ns Ar alpha , Ns 90
+produces {0,0,-1} regardless of the value of
+.Ar alpha .
+.It Fl f
+Force overwrite of the output files, i.e.\& the
+.Ar output
+file and the file where the state of the random number generator is saved
+(see the
+.Fl G
+option).
+.It Fl G Ar sub-option Ns Op : Ns Ar ...
+Save and restore the state of the random number generator.
+This option can be used to ensure statistical independence between
+successive simulations on the same system.
+Available sub-options are:
+.Bl -tag -width Ds
+.It Cm istate= Ns Ar input_rng_state
+Define the file from which the initial state of the random number
+generator is read.
+If not defined, the random number generator is initialised with its
+default seed.
+.It Cm ostate= Ns Ar output_rng_state
+Define the file where the final state of the random number generator is
+written.
+If not defined, this state is simply discarded.
+.El
+.It Fl g Ar sub-option Ns Op : Ns Ar ...
+Generate the shape of the geometry defined in the submitted
+.Ar file
+and store it in
+.Ar output .
+Available sub-options are:
+.Bl -tag -width Ds
+.It Cm format=obj
+Define the file format in which the meshes are stored.
+Currently, only the Alias Wavefront OBJ file format is supported.
+.It Cm split= Ns Aq Cm geometry Ns | Ns Cm object Ns | Ns Cm none
+Define how the output mesh is split into sub-meshes.
+A sub-mesh can be generated for each
+.Cm geometry
+or for each
+.Cm object
+as defined in the
+.Xr solstice-input 5
+file format.
+The
+.Cm none
+option means that only one mesh is generated for the whole solar
+facility.
+By default,
+.Cm split
+is set to
+.Cm none .
+.El
+.It Fl h
+List short help and exit.
+.It Fl n Ar samples-count
+Number of Monte-Carlo samples used to estimate the solar flux.
+By default
+.Ar samples-count
+is set to
+.Sy @SOLSTICE_ARGS_DEFAULT_NREALISATIONS@ .
+.It Fl o Ar output
+Write results to
+.Ar output
+with respect to the
+.Xr solstice-output 5
+format.
+If not defined, write results to standard output.
+.It Fl p Ar sub-option Ns Op : Ns Ar ...
+Register the sampled radiative paths for each sun direction and write
+them to
+.Ar output .
+Available sub-options are:
+.Bl -tag -width Ds
+.It Cm default
+Use default sub-options.
+.It Cm irlen= Ns Ar length
+Length of the radiative path segments going to infinity.
+By default, it is computed relative to the scene size.
+.It Cm srlen= Ns Ar length
+Length of the radiative path segments coming from the sun.
+By default, it is computed relative to the scene size.
+.El
+.It Fl q
+Do not print the helper message when no
+.Ar file
+is submitted.
+.It Fl R Ar receivers
+.Xr solstice-receiver 5
+file defining the scene receivers, i.e.\& the solar plant entities for
+which
+.Nm
+computes Monte-Carlo estimates.
+.It Fl r Ar sub-option Ns Op : Ns Ar ...
+Render an image of the scene through a pinhole camera for each submitted
+sun direction.
+Write the resulting images to
+.Ar output .
+Available sub-options are:
+.Bl -tag -width Ds
+.It Cm fov= Ns Ar angle
+Horizontal field of view of the camera in [30,\ 120] degrees.
+By default
+.Ar angle
+is
+.Sy @SOLSTICE_ARGS_DEFAULT_CAMERA_FOV@
+degrees.
+.It Cm img= Ns Ar width Ns x Ns Ar height
+Definition of the rendered image in pixels.
+By default the image definition is
+.Sy @SOLSTICE_ARGS_DEFAULT_IMG_WIDTH@ Ns x Ns Sy @SOLSTICE_ARGS_DEFAULT_IMG_HEIGHT@ .
+.It Cm pos= Ns Ar x , Ns Ar y , Ns Ar z
+Position of the camera.
+By default it is set to
+.Sy { Ns @SOLSTICE_ARGS_DEFAULT_CAMERA_POS@ Ns }
+or it is automatically computed to ensure that the whole scene is
+visible, whether
+.Cm tgt
+is set or not, respectively.
+.It Cm rmode= Ns Aq Cm draft Ns | Ns Cm pt
+Rendering mode.
+In
+.Cm draft
+mode, images are computed by ray-casting; all materials are lambertian,
+the sun is ignored and the only light source is positioned at the camera
+position.
+In
+.Cm pt
+mode, the scene is rendered with the un-biased path-tracing Monte-Carlo
+algorithm; the materials described in the committed
+.Ar file
+as well as the submitted sun directions are correctly handled and a
+uniform skydome is added to simulate the diffuse infinite lighting.
+By default
+.Cm rmode
+is set to
+.Cm draft .
+.It Cm spp= Ns Ar samples-count
+Number of samples per pixel.
+If
+.Cm rmode
+is
+.Cm draft ,
+the sample positions within a pixel are the same for all pixels.
+With
+.Cm rmode=pt
+the pixel samples are generated independently for each pixel.
+By default, @SOLSTICE_ARGS_DEFAULT_IMG_SPP@ sample per pixel is used.
+.It Cm tgt= Ns Ar x , Ns Ar y , Ns Ar z
+Position targeted by the camera.
+By default it is set to
+.Sy { Ns @SOLSTICE_ARGS_DEFAULT_CAMERA_TGT@ Ns }
+or it is automatically computed to ensure that the whole scene is
+visible, whether
+.Cm pos
+is set or not, respectively.
+.It Cm up= Ns Ar x , Ns Ar y , Ns Ar z
+Up vector of the camera.
+If
+.Cm rmode
+is
+.Cm pt ,
+this vector also defines the direction toward the top of the skydome.
+By default,
+.Cm up
+is set to
+.Sy { Ns @SOLSTICE_ARGS_DEFAULT_CAMERA_UP@ Ns } .
+.El
+.It Fl t Ar threads-count
+Hint on the number of threads to use.
+By default, as many threads as CPU cores are used.
+.It Fl v
+Make
+.Nm
+more verbose.
+.It Fl -version
+Output version information and exit.
+.El
+.Sh EXAMPLES
+Launch two simulations for sun directions whose azimuthal and elevation
+angles are {45,70} and {50,75}.
+The solar facility is described in
+.Pa input.yaml
+and the receivers on which the integrations must be performed are declared
+in
+.Pa rcvs.yaml .
+10000 samples are used by the Monte-Carlo estimates and the results
+are written to
+.Pa output
+even though this file already exists:
+.Bd -literal -offset indent
+solstice -D45,70:50,75 -R rcvs.yaml -n 10000 -f -o output input.yaml
+.Ed
+.Pp
+Generate a mesh for each geometry described in
+.Pa input.yaml
+and save them in
+.Pa output
+with respect to the Alias Wavefront OBJ format.
+The meshes are positioned according to their orientation constraints,
+with respect to the sun direction whose azimuthal and elevation angles
+are {30,60}.
+Use
+.Xr csplit 1
+to generate one Alias Wavefront OBJ file per geometry stored in
+.Pa output .
+The generated files are named
+.Pa geom Ns Ar NUM Ns .obj
+with
+.Ar NUM
+in [0,\ N-1] where N is the number of geometries described in
+.Pa input.yaml .
+Refer to
+.Xr solstice-output 5
+for information on the regular expression
+.Qq ^---$
+used to split the output file:
+.Bd -literal -offset indent
+solstice -D30,60 -g format=obj:split=geometry -f -o output input.yaml
+csplit -f geom -b %02d.obj -z --suppress-matched output /^---$/ {*}
+.Ed
+.Pp
+Trace 100 radiative paths into the solar plant described in
+.Pa input.yaml ,
+with respect to the sun direction whose azimuthal and elevation angles
+are 0 and 90 degrees, respectively.
+Write the
+.Xr solstice-output 5
+result to standard output and postprocess it with
+.Xr sed 1
+to remove the first line that stores the sun direction.
+The remaining data listing the radiative path geometry are redirected
+into
+.Pa paths.vtk :
+.Bd -literal -offset indent
+solstice -n 100 -D0,90 -R rcvs.yaml -p default input.yaml | sed '1d' > paths.vtk
+.Ed
+.Pp
+Use the path-tracing rendering algorithm to draw the solar plant
+.Pa solplant.yaml
+with respect to the sun direction whose azimuthal and elevation angles
+are 180 and 45 degrees, respectively.
+Use 64 samples per pixel to estimate the per-pixel radiance and fix the
+camera up vector to {0,0,1}.
+Write the
+.Xr solstice-output 5
+result to standard output, use
+.Xr sed 1
+to remove the first line which stores the sun direction, and visualise
+the rendered picture by redirecting the remaining data to the
+.Xr feh 1
+image viewer:
+.Bd -literal -offset indent
+solstice -D180,45 -r up=0,0,1:rmode=pt:spp=64 solplant.yaml | sed '1d' | feh -
+.Ed
+.Sh SEE ALSO
+.Xr csplit 1 ,
+.Xr feh 1 ,
+.Xr sed 1 ,
+.Xr solstice-input 5 ,
+.Xr solstice-output 5 ,
+.Xr solstice-receiver 5
+.Sh HISTORY
+.Nm
+was initially developed with funding from the
+.Em SOLSTICE LabEx
+.Pq Laboratory of Excellence ,
+in collaboration with the PROMES Laboratory of the
+French National Centre for Scientific Research
+.Pq CNRS .
+.Sh AUTHORS
+.Nm
+was written and is maintained by
+.An |M\['e]so|Star> Aq Mt contact@meso-star.com .
diff --git a/doc/solstice.1.txt.in b/doc/solstice.1.txt.in
@@ -1,272 +0,0 @@
-// Copyright (C) 2016-2018 CNRS, 2018-2019 |Meso|Star>
-//
-// This is free documentation: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This manual is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-:toc:
-
-solstice(1)
-===========
-
-NAME
-----
-solstice - compute the power collected by a concentrated solar plant
-
-SYNOPSIS
---------
-[verse]
-*solstice*
-*solstice* [_option_]... [_file_]
-*solstice* *-g* <__sub-option__[:...]> [_option_]... [_file_]
-*solstice* *-p* <__sub-option__[:...]> [_option_]... [_file_]
-*solstice* *-r* <__sub-option__[:...]> [_option_]... [_file_]
-
-DESCRIPTION
------------
-*solstice* computes the total power collected by a concentrated solar plant, as
-described in the *solstice-input*(5) _file_. If the _file_ argument is not
-provided, the solar plant is read from standard input. To evaluate various
-efficiencies for each primary reflector, it computes losses due to cosine
-effect, shadowing and masking, orientation and surface irregularities,
-materials properties and atmospheric extinction. The efficiency for each
-one of these effects is subsequently computed for each reflector.
-
-The entities on which computations must be performed are listed in the
-*solstice-receiver*(5) file submitted through the *-R* option. The estimated
-results follow the *solstice-output*(5) format and are written to the _output_
-file or to the standard output whether the *-o* _output_ option is defined or
-not, respectively. Note that the *solstice* algorithm is based on the
-Monte-Carlo method, which means that every result is provided with its
-numerical accuracy.
-
-*solstice* is designed to efficiently handle complex solar facilities: several
-reflectors can be specified (planes, conics, cylindro-parabolic, etc.) and
-positioned in 3D space, with a possibility for 1-axis and 2-axis
-auto-orientation. Multiple materials can be used, as long as the relevant
-physical properties are provided. Spectral effects are also taken into account:
-it is possible to define the spectral distribution of any physical property,
-including the input solar spectrum and the transmissivity of the atmosphere, at
-any spectral resolution. Refer to *solstice-input*(5) for more informations.
-
-In addition of the aforementioned computations, *solstice* provides three
-other functionalities. The *-g* option can be used to convert the
-*solstice-input*(5) geometries in CAO files. The *-p* option saves the sampled
-radiative paths used by the estimates, allowing to visualise them externally
-which may be a great help to identify a design issue. Finally, the *-r* option
-is used to render an image of the submitted solar facility. Note that these
-three options are mutually exclusives, and once defined, they replace the
-default *solstice* behaviour.
-
-Please note that any coordinate-related question in Solstice must be
-considered with the right-handed convention in mind.
-
-OPTIONS
--------
-*-D* <__alpha__,__beta__[:...]>::
- List of sun directions. A direction is defined by two angles in degrees. The
- first one, here refered to as _alpha_, is an azimuthal angle in [0, 360[ and
- the second one, here refered to as _beta_, is an elevation in [0, 90].
- Each provided sun direction triggers a new computation whose results are
- concatenated to the _output_ file.
-+
-Following the right-handed convention, Solstice azimuthal rotation is
-counter-clockwise, with 0° on the X axis. Solstice elevation starts from 0° for
-directions in the XY plane, up to 90° at zenith. Thus -D0,0 -D90,0 -D180,0 and
--D270,0 will produce solar vectors {-1,0,0} {0,-1,0} {+1,0,0} and {0,+1,0}
-respectively, while -D__alpha__,90 will produce {0,0,-1} regardless of _alpha_
-value.
-
-*-f*::
- Force overwrite of the output files, i.e. the _output_ file and the file
- where the state of the random number generator is saved (see the *-G*
- option).
-
-*-G* <__sub-option__:...>::
- Save and restore the state of the random number generator. This option can be
- used to ensure the statistical independence between successive simulations
- on the same system. For instance, one can run a new simulation and
- initialising its random number generator with the final state of the
- generator as defined by the previous run. Available sub options are:
-
- **istate=**_input_rng_state_;;
- Define the file from which the initial state of the random number generator
- is read. If not defined, the random number generator is initialised with
- its default seed.
-
- **ostate=**_output_rng_state_;;
- Define the file where the final state of the random number generator is
- written. If not defined, this state is simply discarded.
-
-*-g* <__sub-option__:...>::
- Generate the shape of the geometry defined in the submitted _file_ and store
- it in _output_. Available sub-options are:
-
- *format=obj*;;
- Define the file format in which the meshes are stored. Currently, only the
- Alias Wavefront OBJ file format is supported.
-
- *split=*<**geometry**|*object*|*none*>;;
- Define how the output mesh is split in sub meshes. A sub mesh can be
- generated for each *geometry* or for each *object* as defined in the
- *solstice-input*(5) file format. The *none* option means that only one
- mesh is generated for the whole solar facility. By default, the *split*
- option is set to *none*.
-
-*-h*::
- List short help and exit.
-
-*-n* _experiments-count_::
- Number of Monte-Carlo experiments used to estimate the solar flux. By
- default _experiments-count_ is set to @SOLSTICE_ARGS_DEFAULT_NREALISATIONS@.
-
-*-o* _output_::
- Write results to _output_ with respect to the *solstice-output*(5) format. If
- not defined, write results to standard output.
-
-*-p* <__sub-option__:...>::
- Register the sampled radiative paths for each sun direction and write them to
- _output_. Available sub-options are:
-
- *default*;;
- Use default sub-options.
-
- **irlen=**_length_;;
- Length of the radiative path segments going to the infinity. By default, it
- is computed relatively to the scene size.
-
- **srlen=**_length_;;
- Length of the radiative path segments coming from the sun. By default, it
- is computed relatively to the scene size.
-
-*-q*::
- Do not print the helper message when no _file_ is submitted.
-
-*-R* _receivers_::
- *solstice-receiver*(5) file defining the scene receivers, i.e. the solar
- plant entities for which *solstice* computes Monte-Carlo estimates.
-
-*-r* <__sub-option__:...>::
- Render an image of the scene through a pinhole camera, for each submitted
- sun direction. Write the resulting images to _output_. Available sub-options
- are:
-
- **fov=**_angle_;;
- Horizontal field of view of the camera in [30, 120] degrees. By default
- _angle_ is @SOLSTICE_ARGS_DEFAULT_CAMERA_FOV@ degrees.
-
- **img=**_width_**x**_height_;;
- Definition of the rendered image in pixels. By default the image definition
- is @SOLSTICE_ARGS_DEFAULT_IMG_WIDTH@x@SOLSTICE_ARGS_DEFAULT_IMG_HEIGHT@.
-
- **pos=**_x_**,**_y_**,**_z_;;
- Position of the camera. By default it is set to
- {@SOLSTICE_ARGS_DEFAULT_CAMERA_POS@} or it is automatically computed to
- ensure that the whole scene is visible, whether *tgt* is set or not,
- respectively.
-
- **rmode=**<**draft**|**pt**>;;
- Rendering mode. In *draft* mode, images are computed by ray-casting; all
- materials are lambertian, the sun is ignored and the only light source is
- positioned at the camera position. In *pt* mode, the scene is rendered with
- the un-biased path-tracing Monte-Carlo algorithm; the materials described
- in the committed _file_ as well as the submitted sun directions are
- correctly handled and an uniform skydome is added to simulate the diffuse
- infinite lighting. By default *rmode* is set to *draft*.
-
- **spp=**_samples-count_;;
- Number of samples per pixel. If *rmode* is *draft*, the samples position
- into a pixel are the same for all pixels. With *rmode=pt* the pixel
- samples are generated independently for each pixel. By default, use 1
- sample per pixel.
-
- **tgt=**_x_**,**_y_**,**_z_;;
- Position targeted by the camera. By default, it is set to
- {@SOLSTICE_ARGS_DEFAULT_CAMERA_TGT@} or it is automatically computed to
- ensure that the whole scene is visible, whether *pos* is set or not,
- respectively.
-
- **up=**_x_**,**_y_**,**_z_;;
- Up vector of the camera. If *rmode* is *pt*, this vector also defines the
- direction toward the top of the skydome. By default, *up* is set to
- {@SOLSTICE_ARGS_DEFAULT_CAMERA_UP@}.
-
-*-t* _threads-count_::
- Hint on the number of threads to use. By default use as many threads as CPU
- cores.
-
-*-v*::
- Make solstice more verbose.
-
-*--version*::
- Output version information and exit.
-
-EXAMPLES
---------
-
-Launch two simulations for sun directions whose azimuthal and elevation angles
-are {*45*,*70*} and {*50*,*75*}. The solar facility is described in
-*input.yaml* and the receivers on which the integrations must be performed are
-declared in the *rcvs.yaml* file. *10000* experiments are used by the
-Monte-Carlo estimates and the results are written to *output* even though this
-file already exists:
-
- $ solstice -D45,70:50,75 -R rcvs.yaml -n 10000 -f -o output input.yaml
-
-Generate a mesh for each geometry described in *input.yaml*, and save them in
-the *output* file with respect to the Alias Wavefront OBJ format. The meshes
-are positioned according to their orientation constraints, with respect to the
-sun direction whose azimuthal and elevation angles are {*30*,*60*}. Use the
-*csplit*(1) Unix command to generate an Alias Wavefront OBJ file per geometry
-stored in *output*. The name of the generated Alias Wavefront OBJ files are
-*geom*<__NUM__>**.obj** with __NUM__ in [0, N-1] where N is the number of
-geometries described in *input.yaml*. Refer to *solstice-output*(5) for
-informations on the regular expression *^---$* used to split the output file:
-
- $ solstice -D30,60 -g format=obj:split=geometry -f -o output input.yaml
- $ csplit -f geom -b %02d.obj -z --suppress-matched output /^---$/ {*}
-
-Trace 100 radiative paths into the solar plant described in *input.yaml*, with
-respect to the sun direction whose azimuthal and elevations angles are *0* and
-*90* degrees, respectively. Write the *solstice-output*(5) result to the
-standard output and postprocess it with the *sed*(1) Unix command to remove the
-first line that stores the sun direction from which the radiative paths come
-from. The remaining data that list the radiative paths geometry are redirected
-into the *paths.vtk* file:
-
- $ solstice -n 100 -D0,90 -R rcvs.yaml -p default input.yaml | sed '1d'>paths.vtk
-
-Use the path-tracing rendering algorithm to draw the solar plant
-*solplant.yaml* with respect to the sun direction whose azimuthal and elevation
-angles are *180* and *45* degrees, respectively. Use *64* samples per pixel to
-estimate the per-pixel radiance and fix the up camera vector to {*0*,*0*,*1*}.
-Write the *solstice-output*(5) result to standard output and use the *sed*(1)
-Unix command to remove the first line which stores the sun direction used to
-draw the image. Finally, visualise the rendered picture by redirecting the
-remaining data to the *feh*(1) image viewer.
-
- $ solstice -D180,45 -r up=0,0,1:rmode=pt:spp=64 solplant.yaml | sed '1d' | feh -
-
-COPYRIGHT
----------
-Copyright © 2016-2018 CNRS, 2018-2019 |Meso|Star>. License GPLv3+: GNU GPL
-version 3 or later <http://gnu.org/licenses/gpl.html>. This is free software.
-You are free to change and redistribute it. There is NO WARRANTY, to the extent
-permitted by law.
-
-SEE ALSO
---------
-*csplit*(1),
-*feh*(1),
-*sed*(1),
-*solstice-input*(5),
-*solstice-output*(5),
-*solstice-receiver*(5)
diff --git a/src/solstice_args.c b/src/solstice_args.c
@@ -56,7 +56,7 @@ print_help(const char* program)
printf(
" -h display this help and exit.\n");
printf(
-" -n EXPERIMENTS number of Monte Carlo experiments. Default is %lu.\n",
+" -n SAMPLES number of Monte Carlo samples. Default is %lu.\n",
SOLSTICE_ARGS_DEFAULT.nexperiments);
printf(
" -o OUTPUT write results to OUTPUT. If not defined, write results to\n"