solstice

Compute collected power and efficiencies of a solar plant
git clone git://git.meso-star.com/solstice.git
Log | Files | Refs | README | LICENSE

solstice-input.5 (39495B)


      1 .\" SPDX-License-Identifier: GPL-3.0-or-later
      2 .\" Copyright (C) 2016-2018 CNRS, 2018-2019 |Méso|Star>
      3 .\"
      4 .\" This is free documentation: you can redistribute it and/or modify
      5 .\" it under the terms of the GNU General Public License as published by
      6 .\" the Free Software Foundation, either version 3 of the License, or
      7 .\" (at your option) any later version.
      8 .\"
      9 .\" This manual is distributed in the hope that it will be useful,
     10 .\" but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     12 .\" GNU General Public License for more details.
     13 .\"
     14 .\" You should have received a copy of the GNU General Public License
     15 .\" along with this program. If not, see <http://www.gnu.org/licenses/>.
     16 .Dd $Mdocdate$
     17 .Dt SOLSTICE-INPUT 5
     18 .Os
     19 .Sh NAME
     20 .Nm solstice-input
     21 .Nd solar plant description for solstice
     22 .Sh DESCRIPTION
     23 The
     24 .Nm
     25 format is used by the
     26 .Xr solstice 1
     27 program to represent a solar plant.
     28 It relies on the YAML 1.1 data serialization standard
     29 .Po
     30 see
     31 .Sx NOTES ,
     32 reference 1
     33 .Pc ;
     34 assuming that the file is compatible with the
     35 .Nm
     36 semantic, a solar plant can be described by using the whole YAML 1.1
     37 functionalities including compact notation and data tagging.
     38 .Pp
     39 A solar plant is composed of a
     40 .Em sun ,
     41 an optional
     42 .Em atmosphere
     43 and a collection of
     44 .Em geometries ,
     45 i.e.\&
     46 .Em shapes
     47 with their associated
     48 .Em material .
     49 Beside the raw description of the aforementioned data, the
     50 .Nm
     51 format provides the
     52 .Em entity
     53 item to efficiently structure the geometries in the scene.
     54 An entity is a node in a tree data structure where the position of each
     55 child entity is relative to the position of its parent.
     56 An entity can either encapsulate a
     57 .Em geometry
     58 or a
     59 .Em pivot
     60 that controls the dynamic positioning of its child entities with respect
     61 to the pivot constraints and the sun direction submitted to the
     62 .Xr solstice 1
     63 program.
     64 .Sh GRAMMAR
     65 .Bd -literal
     66 <solar-plant>         ::= - <sun>
     67                           - <item>
     68                         [ - <item> ... ]
     69                         [ - <atmosphere> ]
     70 
     71 <item>                ::= <entity>
     72                         | <geometry>
     73                         | <material>
     74                         | <medium>
     75                         | <spectrum>
     76                         | <template>
     77 .Ed
     78 .Bd -literal
     79 <geometry>            ::= geometry:
     80                           - <object>
     81                         [ - <object> ... ]
     82 
     83 <object>              ::= <shape>
     84                           <material>
     85                         [ <transform> ]
     86 
     87 <x_pivot>             ::= x_pivot:
     88                             <target>
     89                         [   ref_point: <real3> ] # Default is [0,0,0]
     90 
     91 <zx_pivot>            ::= zx_pivot:
     92                             <target>
     93                         [   spacing: REAL ] # in [0, INF). Default 0
     94                         [   ref_point: <real3> ] # Default is [0,0,0]
     95 
     96 <target>              ::= target:
     97                             anchor: <anchor-identifier>
     98                         |   direction: <real3>
     99                         |   position: <real3>
    100                         |   <sun>
    101 .Ed
    102 .Bd -literal
    103 <shape>               ::= <cuboid>
    104                         | <cylinder>
    105                         | <hemisphere>
    106                         | <hyperbol>
    107                         | <parabol>
    108                         | <parabolic-cylinder>
    109                         | <plane>
    110                         | <sphere>
    111                         | <stl>
    112 
    113 <cuboid>              ::= cuboid:
    114                             size: <real3> # in ]0, INF]^3
    115 
    116 <cylinder>            ::= cylinder:
    117                             height: REAL # in ]0, INF)
    118                             radius: REAL # in ]0, INF)
    119                         [   slices: INTEGER ] # in [4, 4096]. Default is 16
    120                         [   stacks: INTEGER ] # in [1, 4096]. Default is 1
    121 
    122 <hemisphere>          ::= hemisphere:
    123                             radius: REAL # in ]0, INF)
    124                         [   clip: <polyclip-list> ]
    125                         [   slices: INTEGER ] # in [4, 4096]
    126 
    127 <hyperbol>            ::= hyperbol:
    128                             focals: <hyperboloid-focals>
    129                             clip: <polyclip-list>
    130                         [   slices: INTEGER ] # in [4, 4096]
    131 
    132 <parabol>             ::= parabol:
    133                             focal: REAL # in ]0, INF)
    134                             clip: <polyclip-list>
    135                         [   slices: INTEGER ] # in [4, 4096]
    136 
    137 <parabolic-cylinder>  ::= parabolic-cylinder:
    138                             focal: REAL # in ]0, INF)
    139                             clip: <polyclip-list>
    140                         [   slices: INTEGER ] # in [4, 4096]
    141 
    142 <plane>               ::= plane:
    143                             clip: <polyclip-list>
    144                         [   slices: INTEGER ] # in [1, 4096]. Default is 1
    145 
    146 <sphere>              ::= sphere:
    147                             radius: REAL # in ]0, INF)
    148                         [   slices: INTEGER ] # in [4, 4096]. Default is 16
    149                         [   stacks: INTEGER ] # in [2, 4096]. Default is slices/2
    150 
    151 <stl>                 ::= stl:
    152                             path: PATH
    153 
    154 <hyperboloid-focals>  ::= real: REAL # in ]0, INF)
    155                           image: REAL # in ]0, INF)
    156 .Ed
    157 .Bd -literal
    158 <polyclip-list>       ::= - <polyclip>
    159                         [ - <polyclip> ... ]
    160 
    161 <polyclip>            ::= operation: <AND|SUB>
    162                           <contour-descriptor>
    163 
    164 <contour-descriptor>  ::= <circle-descriptor>
    165                         | <vertices-descriptor>
    166 
    167 <vertices-descriptor> ::= vertices: <vertices-list>
    168 
    169 <circle-descriptor>   ::= circle:
    170                             radius: REAL # in ]0, INF)
    171                         [   center: <real2> ] # Default is 0,0
    172                         [   segments: INTEGER ] # in [3, 4096]. Default is 64
    173 
    174 <vertices-list>       ::= - <real2>
    175                           - <real2>
    176                           - <real2>
    177                         [ - <real2> ... ]
    178 .Ed
    179 .Bd -literal
    180 <material>            ::= material:
    181                             <material-descriptor>
    182                         |   <double-sided-mtl>
    183 
    184 <double-sided-mtl>    ::= front: <material-descriptor>
    185                           back: <material-descriptor>
    186 
    187 <material-descriptor> ::= <dielectric>
    188                         | <matte>
    189                         | <mirror>
    190                         | <thin-dielectric>
    191                         | <virtual>
    192 
    193 <dielectric>          ::= dielectric:
    194                             medium_i: <medium-descriptor>
    195                             medium_t: <medium-descriptor>
    196                         [   <normal-map> ]
    197 
    198 <matte>               ::= matte:
    199                             reflectivity: <mtl-data> # in [0, 1]
    200                         [   <normal-map> ]
    201 
    202 <mirror>              ::= mirror:
    203                             reflectivity: <mtl-data> # in [0, 1]
    204                             slope_error: <mtl-data>
    205                         [   microfacet: <normal-distrib> ] # Default is BECKMANN
    206                         [   <normal-map> ]
    207 
    208 <normal-distrib>      ::= BECKMANN
    209                         | PILLBOX
    210 
    211 <virtual>             ::= virtual: EMPTY-STRING
    212 
    213 <thin-dielectric>     ::= thin_dielectric:
    214                             thickness: REAL # in [0, INF)
    215                             medium_i: <medium-descriptor>
    216                             medium_t: <medium-descriptor>
    217                         [   <normal-map> ]
    218 
    219 <normal-map>          ::= normal_map:
    220                             path: PATH
    221 .Ed
    222 .Bd -literal
    223 <medium>              ::= medium: <medium-descriptor>
    224 
    225 <medium-descriptor>   ::= refractive_index: <mtl-data> # in ]0, INF)
    226                           extinction: <mtl-data> # in [0, INF)
    227 .Ed
    228 .Bd -literal
    229 <entity>              ::= entity: <entity-data>
    230 
    231 <template>            ::= template: <entity-data>
    232 
    233 <entity-data>         ::= name: STRING
    234                         [ <geometry-data> | <x_pivot> | <zx_pivot> ]
    235                         [ <anchors> ]
    236                         [ <transform> ]
    237                         [ <children>  ]
    238 
    239 <geometry-data>       ::= primary: INTEGER # in [0, 1]
    240                           <geometry>
    241 
    242 <children>            ::= children:
    243                           - <entity-data>
    244                         [ - <entity-data> ... ]
    245 
    246 <anchors>             ::= anchors:
    247                           - <anchor-data>
    248                         [ - <anchor-data> ... ]
    249 
    250 <anchor-data>         ::= name: STRING
    251                           <position-descriptor>
    252 
    253 <position-descriptor> ::= position: <real3>
    254                         | hyperboloid_image_focals: <hyperboloid_focals>
    255 
    256 <entity-identifier>   ::= <self|STRING>[.STRING ... ]
    257 
    258 <anchor-identifier>   ::= <entity-identifier>.STRING
    259 .Ed
    260 .Bd -literal
    261 <sun>                 ::= sun:
    262                             dni: REAL # Direct Normal Irradiance in ]0, INF)
    263                         [   <spectrum> ] # Default is the smarts295 spectrum
    264                         [   <sun-shape> ]
    265 
    266 <sun-shape>           ::= <pillbox> | <gaussian> | <buie>
    267 
    268 <buie>                ::= buie:
    269                             csr: REAL # in [1e-6, 0.849]
    270 
    271 <pillbox>             ::= pillbox:
    272                             half_angle: REAL # in ]0, 90]
    273 
    274 <gaussian>            ::= gaussian:
    275                             std_dev: REAL # in ]0, INF)
    276 .Ed
    277 .Bd -literal
    278 <atmosphere>          ::= atmosphere:
    279                             extinction: <mtl-data> # in [0, 1]
    280 .Ed
    281 .Bd -literal
    282 <mtl-data>            ::= REAL
    283                         | <spectrum-data-list>
    284 
    285 <transform>           ::= transform:
    286                             translation: <real3>
    287                             rotation: <real3>
    288 
    289 <real2>               ::= - REAL
    290                           - REAL
    291 
    292 <real3>               ::= - REAL
    293                           - REAL
    294                           - REAL
    295 
    296 <spectrum>            ::= spectrum: <spectrum-data-list>
    297 
    298 <spectrum-data-list>  ::= - <spectrum-data>
    299                         [ - <spectrum-data> ... ]
    300 
    301 <spectrum-data>       ::= wavelength: REAL # in [0, INF)
    302                           data: REAL # in [0, INF)
    303 .Ed
    304 .Sh SUN
    305 The
    306 .Em sun
    307 describes the source of the solar plant.
    308 Its direction is not defined in the
    309 .Nm
    310 file but is provided by the
    311 .Xr solstice 1
    312 command.
    313 This allows the same unmodified
    314 .Nm
    315 file to be used for several simulations with different sun directions.
    316 .Pp
    317 The main
    318 .Em sun
    319 property is its direct normal irradiance, or
    320 .Em dni
    321 in W\(md m\u\s-2\-2\s0\d.
    322 Its value is a scalar defining the direct irradiance received on a plane
    323 perpendicular to the main sun direction.
    324 The optional
    325 .Em spectrum
    326 parameter describes the per-wavelength distribution of the sun
    327 .Em dni .
    328 Note that this distribution is automatically normalized by
    329 .Xr solstice 1 .
    330 If the
    331 .Em spectrum
    332 attribute is not defined,
    333 .Xr solstice 1
    334 uses a default spectrum computed with the SMARTS software
    335 .Po
    336 see
    337 .Sx NOTES ,
    338 reference 2
    339 .Pc
    340 between 0.28 and 4 micrometres.
    341 The total
    342 .Em dni
    343 (integrated over the spectral range) was set to 1000 W\(md m\u\s-2\-2\s0\d.
    344 The standard Mid-Latitude-Summer atmosphere was used with most gas
    345 concentrations set as default (CO2 concentration assumed 400 ppmv).
    346 .Pp
    347 Even if an atmosphere is provided, the atmospheric effects from the top
    348 of the atmosphere to ground level are not computed using the atmosphere
    349 description.
    350 As a result, the sun description
    351 .Pq Em dni No and optional Em spectrum
    352 is expected to include all atmospheric effects (sun irradiance available
    353 at ground level).
    354 .Pp
    355 The
    356 .Em sun-shape
    357 parameter controls the angular distribution of the sun light intensity
    358 across the sun's disk.
    359 If not defined, the distribution is assumed to be a Dirac distribution
    360 (infinite directional source).
    361 The available sun shapes are:
    362 .Bl -tag -width Ds
    363 .It Em pillbox
    364 The
    365 .Em pillbox
    366 distribution defines a uniform intensity over the sun's disk.
    367 Its single
    368 .Em half_angle
    369 parameter is the sun's disk half-angle in degrees, linked to the
    370 apparent size of the sun.
    371 A typical
    372 .Em half_angle
    373 is 0.2664.
    374 .It Em gaussian
    375 The
    376 .Em gaussian
    377 distribution defines a Gaussian distribution of the solar incoming
    378 direction.
    379 Its single
    380 .Em std_dev
    381 parameter is the standard deviation of the distribution in degrees.
    382 Values around 0.2 are typical.
    383 As the Gaussian distribution is not truncated, the resulting sun vector
    384 can theoretically be oriented away from the sun, especially with a
    385 large, non-typical
    386 .Em std_dev
    387 value.
    388 .It Em buie
    389 The
    390 .Em buie
    391 distribution, as first described in reference 3
    392 .Pq see Sx NOTES .
    393 Its single
    394 .Em csr
    395 parameter is the ratio between the circumsolar irradiance and the sum
    396 of the circumsolar and sun's disk irradiance.
    397 An analysis of typical
    398 .Em csr
    399 values can be found in reference 4
    400 .Pq see Sx NOTES .
    401 .El
    402 .Sh ATMOSPHERE
    403 The
    404 .Em atmosphere ,
    405 when provided, describes the medium surrounding the solar plant.
    406 Its only parameter is its extinction coefficient in m\u\s-2\-1\s0\d,
    407 which can either be a scalar if the extinction is constant over the
    408 spectrum, or can be spectrally described.
    409 The extinction along light paths is only computed after the first
    410 reflector, as the sun description must include all atmospheric effects
    411 before the first reflector (see
    412 .Sx SUN
    413 for more details).
    414 .Pp
    415 If no atmosphere is provided, atmospheric extinction after the first
    416 reflector is not taken into account.
    417 .Sh MATERIAL
    418 A
    419 .Em material
    420 describes the properties of an interface.
    421 These properties can be the same for both sides of the interface or may
    422 be differentiated with a
    423 .Em double-sided-mtl .
    424 The material behaviour is controlled by a
    425 .Em material-descriptor
    426 that specifies the physical properties of the interface as well as its
    427 optional normal perturbation.
    428 Note that the physical properties can be either scalars or spectral data.
    429 .Ss Material descriptors
    430 The available material descriptors are:
    431 .Bl -tag -width Ds
    432 .It Em dielectric
    433 Interface between two dielectric media.
    434 Its
    435 .Em medium_i
    436 parameter defines the current medium (the medium the ray travels in),
    437 while
    438 .Em medium_t
    439 represents the opposite medium.
    440 Incoming rays are either specularly reflected or refracted according to
    441 a Fresnel term:
    442 .Bd -literal -offset indent
    443 Fr = 1/2 * (Rs^2 + Rp^2)
    444 .Ed
    445 .Pp
    446 with Rs and Rp the reflectance for light polarized with its electric
    447 field perpendicular or parallel to the plane of incidence, respectively:
    448 .Bd -literal -offset indent
    449 Rs = (n1 * |wi.N| - n2 * |wt.N|) / (n1 * |wi.N| + n2 * |wt.N|)
    450 Rp = (n2 * |wi.N| - n1 * |wt.N|) / (n2 * |wi.N| + n1 * |wt.N|)
    451 .Ed
    452 .Pp
    453 with n1 and n2 the indices of refraction of the incident and transmitted
    454 media, and wi and wt the incident and transmitted direction.
    455 .Pp
    456 Be careful to ensure media consistency in the
    457 .Nm
    458 file: a ray travelling in a medium
    459 .Em A
    460 can only encounter a medium interface whose
    461 .Em medium_i
    462 attribute is
    463 .Em A .
    464 Consequently, a
    465 .Em dielectric
    466 material must be defined as a double-sided material whose front and back
    467 interfaces are dielectrics with inverted media:
    468 .Bd -literal -offset indent
    469 material:
    470   front:
    471     dielectric:
    472       medium_i: &vacuum { refractive_index: 1, extinction: 0 }
    473       medium_t: &glass { refractive_index: 1.5, extinction: 20 }
    474   back:
    475     dielectric:
    476       medium_i: *glass
    477       medium_t: *vacuum
    478 .Ed
    479 .Pp
    480 If media consistency is not ensured,
    481 .Xr solstice 1
    482 will fail to run simulations.
    483 Note that by default, the surrounding medium is assumed to be vacuum,
    484 i.e.\& its refractive index and extinction are scalars with values 1 and
    485 0, respectively.
    486 If an atmosphere is defined, the refractive index of the surrounding
    487 medium is still the scalar 1 but its extinction is that of the
    488 atmosphere.
    489 .It Em matte
    490 Diffuse surface.
    491 Reflects the same intensity in all directions independently of the
    492 incoming direction.
    493 .It Em mirror
    494 Specular or glossy reflection, depending on whether the
    495 .Em slope_error
    496 parameter is 0 or not.
    497 Glossy reflections are controlled by a microfacet BRDF.
    498 The microfacet normals are distributed according to the Beckmann or
    499 Pillbox distribution, as specified by the
    500 .Em normal-distrib
    501 attribute.
    502 .Pp
    503 Let S be the
    504 .Em slope_error
    505 parameter in ]0,\ 1].
    506 The Beckmann distribution is defined as:
    507 .Bd -literal -offset indent
    508 D(wh) = exp(-tan^2(a) / m^2) / (PI * m^2 * cos^4(a))
    509 .Ed
    510 .Pp
    511 with a = arccos(wh.N) and m = sqrt(2)*S, while the Pillbox distribution
    512 is defined as:
    513 .Bd -literal -offset indent
    514         | 0;                         if |wh.N| >= S
    515 D(wh) = |
    516         | 1 / (PI * (1 - cos^2(S))); if |wh.N| < S
    517 .Ed
    518 .It Em thin-dielectric
    519 The interface is assumed to be a thin slab of a dielectric material.
    520 The
    521 .Em medium_i
    522 parameter defines the outside dielectric medium while
    523 .Em medium_t
    524 is the medium of the thin slab.
    525 Incoming rays are either specularly reflected or transmitted (without
    526 deviation) according to a Fresnel term (see
    527 .Em dielectric
    528 above for the formula).
    529 The underlying scattering function correctly handles the multiple
    530 refraction effects within the thin slab.
    531 .Pp
    532 The same media consistency rules as for
    533 .Em dielectric
    534 apply: if not ensured,
    535 .Xr solstice 1
    536 will fail to run simulations.
    537 By default, the surrounding medium is vacuum (refractive index 1,
    538 extinction 0).
    539 If an atmosphere is defined, the refractive index of the surrounding
    540 medium is still 1, but its extinction is that of the atmosphere.
    541 .It Em virtual
    542 Fully transparent interface.
    543 .El
    544 .Ss Normal map
    545 All material descriptors except
    546 .Em virtual
    547 provide an optional
    548 .Em normal-map
    549 attribute that defines a path to a Portable PixMap image
    550 .Po
    551 see
    552 .Sx NOTES ,
    553 reference 5
    554 .Pc
    555 whose pixels store a normal expressed in the tangent space of the
    556 interface.
    557 By default, the unperturbed tangent space normal is {0,0,1}.
    558 The PPM image can be encoded on 8 or 16 bits per component either in
    559 ASCII or binary.
    560 The parameterization of this 2D image onto the shape surfaces depends
    561 on the type of shape.
    562 For the
    563 .Em hemisphere , hyperbol , parabol , plane
    564 and
    565 .Em parabolic-cylinder
    566 shapes, the image is mapped in the {X,Y} plane.
    567 Other shapes are not parameterized; applying a normal-mapped material to
    568 them leads to undefined behaviour.
    569 .Sh SHAPE
    570 A
    571 .Em shape
    572 describes a geometric model defined in its local coordinate system,
    573 whose origin is proper to the shape.
    574 No spatial transformation can be introduced through the declaration of
    575 a shape: it should be transformed externally through an
    576 .Em object
    577 and/or
    578 .Em entity .
    579 .Pp
    580 Two types of shape are provided: quadric and mesh.
    581 The former is used to declare parametric surfaces; the latter describes
    582 triangulated surfaces.
    583 .Ss Quadric
    584 A quadric shape is defined from a quadric equation and a set of 2D
    585 clipping operations performed in its {X,Y} plane.
    586 By convention, the front side of the quadric surface looks toward the
    587 positive Z axis.
    588 Internally, the clipped quadric surface is discretized into a triangular
    589 mesh according to the quadric's discretization parameters.
    590 This mesh is used by
    591 .Xr solstice 1
    592 as a proxy to speed up access to the quadric shape; the exact position
    593 and normal are ultimately computed from the quadric equation.
    594 .Pp
    595 The quadric surface is parameterized in the {X,Y} plane:
    596 .Bd -literal -offset indent
    597 u = (x - lowerX) / (upperX - lowerX)
    598 v = (y - lowerY) / (upperY - lowerY)
    599 .Ed
    600 .Pp
    601 with
    602 .Em u
    603 and
    604 .Em v
    605 the mapped 2D coordinates from a 3D position {x,y,z} onto the quadric,
    606 and
    607 .Em lower Ns <X|Y>
    608 and
    609 .Em upper Ns <X|Y>
    610 the lower and upper bounds of the clipped quadric along the X and Y
    611 axes.
    612 The available quadrics are:
    613 .Bl -tag -width Ds
    614 .It Em hemisphere
    615 Hemispheric shape defined along the Z axis whose minimum is at the
    616 origin.
    617 The
    618 .Em slices
    619 parameter controls the number of divisions along the Z axis.
    620 .Bd -literal -offset indent
    621 x^2 + y^2 + (z-radius)^2 = radius^2
    622 .Ed
    623 .It Em hyperbol
    624 Hyperbolic quadric defined along the Z axis whose minimum is at the
    625 origin.
    626 The
    627 .Em slices
    628 parameter controls the discretization of the hyperbol.
    629 If not defined, it is automatically computed from the hyperbol
    630 curvature.
    631 .Bd -literal -offset indent
    632 (x^2 + y^2) / a^2 - (z + z0 - g/2)^2 / b^2 + 1 = 0
    633 
    634 a^2 = g^2(f - f^2)
    635 b = g(f - 1/2)
    636 z0 = |b| + g/2
    637 g = focals.real + focals.image
    638 f = focals.real / g
    639 .Ed
    640 .It Em parabol
    641 Parabolic quadric defined along the Z axis whose minimum is at the
    642 origin.
    643 The
    644 .Em slices
    645 parameter controls the discretization of the parabol.
    646 If not defined, it is automatically computed from the parabol curvature.
    647 .Bd -literal -offset indent
    648 x^2 + y^2 - 4 * focal * z = 0
    649 .Ed
    650 .It Em parabolic-cylinder
    651 Parabolic cylinder oriented along the Z axis, with its main axis along
    652 the X axis and minimum at the origin.
    653 The
    654 .Em slices
    655 parameter controls the discretization.
    656 If not defined, it is automatically computed from the curvature.
    657 .Bd -literal -offset indent
    658 y^2 - 4 * focal * z = 0
    659 .Ed
    660 .It Em plane
    661 Plane whose normal points along the positive Z axis.
    662 The
    663 .Em slices
    664 attribute controls the discretization of the clipped plane.
    665 .El
    666 .Ss Clipping
    667 A clipping operation, or
    668 .Em polyclip ,
    669 removes parts of the quadric surface.
    670 It is defined by a 2D
    671 .Em contour-descriptor
    672 expressed in the {X,Y} plane and a clipping
    673 .Em operation .
    674 The
    675 .Em AND
    676 operand retains the portion of the quadric that intersects the
    677 contour; the
    678 .Em SUB
    679 operand removes the portion that intersects the contour.
    680 The available contour descriptors are:
    681 .Bl -tag -width Ds
    682 .It Em circle-descriptor
    683 Circular contour whose size is defined by the
    684 .Em radius
    685 parameter.
    686 .Xr solstice 1
    687 discretizes the circular contour using the
    688 .Em segments
    689 attribute as the number of segments used to approximate the circle.
    690 .It Em vertices-descriptor
    691 Polygonal contour described by a list of 2D vertices.
    692 Polygon edges connect each vertex to its predecessor; an additional
    693 edge automatically closes the polygon between the last and first vertex.
    694 Note that
    695 .Xr solstice 1
    696 assumes the polygon does not self-intersect.
    697 .El
    698 .Pp
    699 The
    700 .Em clip
    701 parameter of a quadric lists a set of
    702 .Em polyclips
    703 applied successively in declaration order.
    704 For example, the following uses 5 clipping operations on a plane to
    705 build a rectangle with a circular hole at each corner:
    706 .Bd -literal -offset indent
    707 plane:
    708   clip:
    709   - {operation: AND, vertices: [[-4,-2],[-4,2],[4,2],[4,-2]]}
    710   - {operation: SUB, circle: {radius: 0.5, center: [-3,-1]}}
    711   - {operation: SUB, circle: {radius: 0.5, center: [-3, 1]}}
    712   - {operation: SUB, circle: {radius: 0.5, center: [ 3,-1]}}
    713   - {operation: SUB, circle: {radius: 0.5, center: [ 3, 1]}}
    714 .Ed
    715 .Ss Triangular mesh
    716 Triangular meshes are generated by
    717 .Xr solstice 1
    718 from a shape description or loaded from a CAO file.
    719 Their normals are defined per triangle and are thus discontinuous even
    720 for smooth shapes.
    721 Triangular meshes are not parameterized; applying a normal-mapped
    722 material to them produces undefined behaviour.
    723 The available triangular meshes are:
    724 .Bl -tag -width Ds
    725 .It Em cuboid
    726 Axis-aligned cuboid centered at the origin, whose corner positions and
    727 dimensions along the three axes are defined by the
    728 .Em size
    729 parameter.
    730 The front side of the surface looks outside the cuboid.
    731 .It Em cylinder
    732 Cylinder centered at the origin whose
    733 .Em height
    734 is along the positive Z axis.
    735 Top and bottom are capped.
    736 The
    737 .Em stacks
    738 and
    739 .Em slices
    740 parameters control the number of divisions along and around the Z axis,
    741 respectively.
    742 The front side looks outside the cylinder.
    743 .It Em sphere
    744 Triangulated sphere centered at the origin.
    745 The
    746 .Em stacks
    747 and
    748 .Em slices
    749 parameters control the number of divisions along and around the Z axis,
    750 respectively.
    751 The front side looks outside the sphere.
    752 .It Em stl
    753 Path to an external mesh file in ASCII
    754 .Em ST Ns ereo Ns Em L Ns ithography
    755 (STL) format.
    756 The front side of each triangle is determined by the vertex ordering in
    757 the STL file: a triangle is front-facing when its vertices are
    758 clockwise-ordered.
    759 .El
    760 .Sh ENTITY
    761 An
    762 .Em entity
    763 is used to declare and position shapes in the solar plant.
    764 An entity is the only item that effectively instantiates a
    765 .Em geometry
    766 into the solar plant: a geometry declared but not referenced by an
    767 entity is ignored by
    768 .Xr solstice 1 .
    769 An entity is a hierarchical data structure whose child entities'
    770 transformation is relative to their parent.
    771 If not defined, the
    772 .Em transform
    773 of an entity is the identity (null rotation and translation).
    774 .Pp
    775 Each entity has a
    776 .Em name
    777 which must be unique per hierarchy level.
    778 The name string cannot contain dots, spaces or tabulations.
    779 A child entity is identified in the solar plant by concatenating, with
    780 the
    781 .Sq .\&
    782 character, the names of its ancestors with its own name.
    783 For instance, the identifier of a child entity named
    784 .Em level2
    785 is
    786 .Em level0.level1.level2 :
    787 .Bd -literal -offset indent
    788 entity:
    789   name: level0
    790   child:
    791   - name: level1
    792     child:
    793     - name: level2
    794 .Ed
    795 .Pp
    796 An entity encapsulates either a
    797 .Em geometry
    798 (a collection of
    799 .Em objects )
    800 or a
    801 .Em pivot .
    802 Each entity can also have a list of
    803 .Em anchors
    804 defining positions relative to the entity.
    805 .Pp
    806 For a geometric entity, one must specify whether the encapsulated
    807 geometry is a
    808 .Em primary
    809 geometry (i.e.\& directly lit by the sun and used to concentrate solar
    810 flux, such as a primary mirror).
    811 Correctly tagging primary geometries drastically improves the
    812 convergence speed of
    813 .Xr solstice 1
    814 simulations.
    815 .Ss Template
    816 A
    817 .Em template
    818 is a first-level entity with no existence in the solar plant itself.
    819 It is used to pre-declare an entity hierarchy that can then be
    820 instantiated multiple times by referencing it through common entities
    821 with YAML data tagging:
    822 .Bd -literal -offset indent
    823 - template: &my-template
    824     name: bar
    825     primary: 1
    826     geometry: ...
    827 - entity:
    828     name: foo0
    829     transform: {translation: [-10.5, 0, 0]}
    830     children: [*my-template]
    831 - entity:
    832     name: foo1
    833     transform: {translation: [0, 0, 0]}
    834     children: [*my-template]
    835 - entity:
    836     name: foo2
    837     transform: {translation: [10.5, 0, 0]}
    838     children: [*my-template]
    839 .Ed
    840 .Ss Pivot
    841 A
    842 .Em pivot
    843 is a special kind of node that automatically orients its child geometry
    844 according to the sun position and pivot parameters.
    845 It is typically (but not mandatorily) the parent of a reflector that,
    846 once pivoted, will redirect sun light toward a
    847 .Em target .
    848 A pivot cannot be the child of another pivot.
    849 .Pp
    850 The
    851 .Em target
    852 parameter is the most important pivot parameter.
    853 Four types of target are available:
    854 .Bl -tag -width Ds
    855 .It Em position
    856 The target is an absolute point in world coordinates.
    857 .It Em anchor
    858 The target is a position relative to an entity (see
    859 .Sx Anchor ) .
    860 .It Em sun
    861 The target is the center of the sun.
    862 .It Em direction
    863 The pivot reflects light in the given direction, specified in world
    864 coordinates.
    865 .El
    866 .Pp
    867 Pivots can also have an optional
    868 .Em ref_point
    869 parameter defining a 3D point in the coordinate system of the pivot's
    870 children that is used by the pointing algorithm.
    871 If not provided, it defaults to the origin.
    872 .Pp
    873 Two flavours of pivot are available:
    874 .Bl -tag -width Ds
    875 .It Em x_pivot
    876 Single-axis pivot rotating around the +X axis in its local coordinate
    877 system.
    878 Its pointing algorithm considers an incoming ray from the center of the
    879 sun and rotates its children so that a specular reflection at
    880 .Em ref_point
    881 using +Z as the local normal hits the target, or produces the specified
    882 direction.
    883 .It Em zx_pivot
    884 Two-axis pivot: first a rotation around the +Z axis in its local
    885 coordinate system, then a rotation around the +X axis in the resulting
    886 coordinate system.
    887 The optional
    888 .Em spacing
    889 parameter defines a translation along the +Y axis applied after the
    890 first rotation (default: 0).
    891 Its pointing algorithm considers an incoming ray from the center of the
    892 sun and rotates its children so that a specular reflection at
    893 .Em ref_point
    894 using +Y as the local normal hits the target, or produces the specified
    895 direction.
    896 .El
    897 .Ss Anchor
    898 An
    899 .Em anchor
    900 defines a relative position in the entity hierarchy.
    901 Anchors are particularly useful for pivots and hyperbolic shapes that
    902 must reference a position relative to an entity whose transformation may
    903 depend on its ancestors.
    904 An anchor's
    905 .Em name
    906 must be unique among all anchors in its entity and cannot contain dots,
    907 spaces or tabulations.
    908 An anchor is identified in the solar plant by concatenating its name to
    909 the
    910 .Em entity-identifier
    911 of the entity in which it is declared, using
    912 .Sq .\&
    913 as separator.
    914 For example, the identifier of an anchor named
    915 .Em anchor0
    916 declared in
    917 .Em level0.level1
    918 is
    919 .Em level0.level1.anchor0 .
    920 .Pp
    921 When the root entity name of a template is unknown (because the template
    922 has not yet been instantiated), the
    923 .Em self
    924 reserved keyword can be used to reference the unknown root entity.
    925 For example:
    926 .Bd -literal -offset indent
    927 - template: &my-template
    928     name: level0
    929     anchor: [{name: anchor0, position: [1, 2, 3]}]
    930     child:
    931     - name: level1
    932       pivot:
    933         x_pivot:
    934           ref_point: {0, 0, 0}
    935           target: {anchor: self.level0.anchor0}
    936 
    937 - entity: {name: entity0, child: [*my-template]}
    938 - entity: {name: entity1, child: [*my-template]}
    939 .Ed
    940 .Ss Transform
    941 A
    942 .Em transform
    943 moves an
    944 .Em object
    945 or an
    946 .Em entity
    947 in space.
    948 The
    949 .Em rotation
    950 parameter lists 3 angles in degrees defining rotations around the X, Y
    951 and Z axes.
    952 The
    953 .Em translation
    954 attribute describes offsets along the X, Y and Z axes.
    955 Given a local frame
    956 .Em p
    957 of an object,
    958 .Em p
    959 is transformed into
    960 .Em p'
    961 as:
    962 .Bd -literal -offset indent
    963 p' = Rx * Ry * Rz * (T + p)
    964 .Ed
    965 .Pp
    966 with
    967 .Em T
    968 the translation vector and
    969 .Em Rx , Ry , Rz
    970 the rotation matrices around the X, Y and Z axes:
    971 .Bd -literal -offset indent
    972      | 1  0   0 |        | cY  0 sY |        | cZ -sZ  0 |
    973 Rx = | 0 cX -sX |;  Ry = |  0  1  0 |;  Rz = | sZ  cZ  0 |
    974      | 0 sX  cX |        |-sY  0 cY |        |  0   0  1 |
    975 .Ed
    976 .Pp
    977 where
    978 .Em c Ns <X|Y|Z>
    979 and
    980 .Em s Ns <X|Y|Z>
    981 are the cosine and sine of the rotation angles around the X, Y and Z
    982 axes, respectively.
    983 .Sh EXAMPLES
    984 Declare 2 entities and a point-source sun.
    985 The first entity is a purely specular square of size 10 centered at the
    986 origin.
    987 The second is a purely transparent square used as a receiver; its size
    988 is 1 and its center is at {0,0,2}:
    989 .Bd -literal -offset indent
    990 - sun: {dni: 1000}
    991 
    992 - entity:
    993     name: reflector
    994     primary: 1
    995     geometry:
    996     - material:
    997         mirror:
    998           reflectivity: 1
    999           slope_error: 0
   1000       plane:
   1001         clip:
   1002         - operation: AND
   1003           vertices:
   1004           - [-5.0,-5.0]
   1005           - [-5.0, 5.0]
   1006           - [ 5.0, 5.0]
   1007           - [ 5.0,-5.0]
   1008 
   1009 - entity:
   1010     name: receiver
   1011     primary: 0
   1012     transform:
   1013       translation: [0, 0, 2]
   1014     geometry:
   1015     - material:
   1016         virtual: # No attrib
   1017       plane:
   1018         clip:
   1019         - operation: AND
   1020           vertices:
   1021           - [-0.5,-0.5]
   1022           - [-0.5, 0.5]
   1023           - [ 0.5, 0.5]
   1024           - [ 0.5,-0.5]
   1025 .Ed
   1026 .Pp
   1027 Define a circular diffuse reflector surrounded by a virtual sphere, with
   1028 a pillbox-shaped sun of
   1029 .Em half_angle
   1030 0.1 degree.
   1031 Use anchors and YAML tags to reference a pre-declared geometry, and the
   1032 YAML compact notation to reduce the number of lines:
   1033 .Bd -literal -offset indent
   1034 - sun: {dni: 1000, pillbox: {half_angle: 0.1}}
   1035 
   1036 - geometry: &small-circle
   1037   - material: {matte: {reflectivity: 1}}
   1038     plane: {clip: [{operation: AND, circle: {radius: 0.5}}]}
   1039 
   1040 - geometry: &big-sphere
   1041   - material: {virtual: ""}
   1042     sphere: {radius: 2, slices: 128}
   1043 
   1044 - entity: {name: reflector, primary: 1, geometry: *small-circle}
   1045 - entity: {name: receiver,  primary: 0, geometry: *big-sphere}
   1046 .Ed
   1047 .Pp
   1048 Declare 2 parabolic reflectors from a templated parabola whose
   1049 orientation is controlled by a
   1050 .Em zx_pivot
   1051 targeting an anchor defined relative to the receiver:
   1052 .Bd -literal -offset indent
   1053 - sun: {dni: 1000}
   1054 
   1055 - entity: # Receiver
   1056     name: square_receiver
   1057     primary: 0
   1058     transform: { rotation: [0,90,0], translation: [100,0,10] }
   1059     anchors: [{name: anchor0, position: [0,0,0]}]
   1060     geometry:
   1061     - material: {virtual: ""}
   1062       plane:
   1063         clip:
   1064         - operation: AND
   1065           vertices: [[-.5,-.5],[-.5,.5],[.5,.5],[.5,-.5]]
   1066 
   1067 - template: &self_oriented_parabol # Reflector
   1068     name: pivot
   1069     transform: {translation: [0, 0, 4], rotation: [0, 0, 90]}
   1070     zx_pivot: {target: {anchor: square_receiver.anchor0}}
   1071     children:
   1072     - name: parabol
   1073       transform: {rotation: [-90, 0, 0]}
   1074       primary: 1
   1075       geometry:
   1076       - material: {mirror: {reflectivity: 1, slope_error: 0}}
   1077         parabol:
   1078           focal: 100
   1079           clip:
   1080           - operation: AND
   1081             vertices: [[-5,-5],[-5,5],[5,5],[5,-5]]
   1082 
   1083 # Instantiate the reflector template
   1084 - entity:
   1085     name: reflector1
   1086     transform: {translation: [0,0,0]}
   1087     children: [*self_oriented_parabol]
   1088 - entity:
   1089     name: reflector2
   1090     transform: {translation: [10,43.6,0]}
   1091     children: [*self_oriented_parabol]
   1092 .Ed
   1093 .Pp
   1094 Declare a solar furnace with 9 heliostats instantiated from the same
   1095 template.
   1096 Their position is controlled by a
   1097 .Em zx_pivot
   1098 to ensure that incoming sun rays are reflected toward the negative X
   1099 axis.
   1100 Reflected rays are then concentrated by a parabola toward a purely
   1101 absorptive receiver.
   1102 The heliostats and the parabola share the same double-sided material:
   1103 front faces are purely specular, back faces are diffuse:
   1104 .Bd -literal -offset indent
   1105 - sun: {dni: 1000}
   1106 
   1107 - material: &specular
   1108     front: {mirror: {reflectivity: 1, slope_error: 0}}
   1109     back: {matte: {reflectivity: 1}}
   1110 
   1111 - template: &H # Template of a heliostat
   1112     name: heliostat
   1113     transform: {translation: [0,0,5.5]}
   1114     zx_pivot: {target: {direction: [-1,0,0]}}
   1115     children:
   1116     - name: reflector
   1117       transform: {rotation: [-90,0,0]}
   1118       primary: 1
   1119       geometry:
   1120       - material: *specular
   1121         plane:
   1122           clip: [{operation: AND, vertices: [[-5,-5],[-5,5],[5,5],[5,-5]]}]
   1123 
   1124 - entity: # Receiver entity
   1125     name: receiver
   1126     primary: 0
   1127     transform: {translation: [18,0,20], rotation: [0,90,0]}
   1128     geometry:
   1129     - material: {matte: {reflectivity: 0}}
   1130       plane:
   1131         clip:
   1132         - operation: AND
   1133           vertices: [[-.5,-.5],[-.5,.5],[.5,.5],[.5,-.5]]
   1134 
   1135 - entity: # Great parabola
   1136     name: parabola
   1137     primary: 0
   1138     transform: {translation: [0,0,20], rotation: [0,90,90]}
   1139     geometry:
   1140     - material: *specular
   1141       parabol:
   1142         focal: 18
   1143         clip: [{operation: AND, vertices: [[-30,-20],[-30,20],[30,20],[30,-20]]}]
   1144 
   1145 # Instantiate the heliostat template
   1146 - entity: {name: H1, children: [*H], transform: {translation: [40,-20, 0]}}
   1147 - entity: {name: H2, children: [*H], transform: {translation: [40,  0, 0]}}
   1148 - entity: {name: H3, children: [*H], transform: {translation: [40, 20, 0]}}
   1149 - entity: {name: H4, children: [*H], transform: {translation: [60,-20,10]}}
   1150 - entity: {name: H5, children: [*H], transform: {translation: [60,  0,10]}}
   1151 - entity: {name: H6, children: [*H], transform: {translation: [60, 20,10]}}
   1152 - entity: {name: H7, children: [*H], transform: {translation: [80,-20,20]}}
   1153 - entity: {name: H8, children: [*H], transform: {translation: [80, 0, 20]}}
   1154 - entity: {name: H9, children: [*H], transform: {translation: [80, 20,20]}}
   1155 .Ed
   1156 .Pp
   1157 Three partial parabols with various focal distances concentrate incoming
   1158 radiation at a common focal position.
   1159 A hyperbol is located between the parabols and their common focal, which
   1160 is also one of the two focals of the hyperbol.
   1161 Radiation is redirected to the second focal of the hyperbol where the
   1162 square target is located.
   1163 A cuboid using a glass material is located between the hyperbol and the
   1164 target.
   1165 This example also illustrates the use of
   1166 .Em spectrum
   1167 for refractive index and extinction:
   1168 .Bd -literal -offset indent
   1169 # Spectra
   1170 - spectrum: &solar_spectrum
   1171   - {wavelength: 0.3, data: 1.0}
   1172   - {wavelength: 0.4, data: 2.0}
   1173   - {wavelength: 0.5, data: 0.5}
   1174   - {wavelength: 0.6, data: 3.5}
   1175   - {wavelength: 0.7, data: 1.5}
   1176   - {wavelength: 0.8, data: 0.8}
   1177 
   1178 - spectrum: &air_kabs
   1179   - {wavelength: 0.3, data: 1.0e-4}
   1180   - {wavelength: 0.4, data: 1.0e-5}
   1181   - {wavelength: 0.5, data: 2.0e-5}
   1182   - {wavelength: 0.6, data: 2.0e-4}
   1183   - {wavelength: 0.7, data: 3.0e-5}
   1184   - {wavelength: 0.8, data: 1.0e-4}
   1185 
   1186 - spectrum: &glass_kabs
   1187   - {wavelength: 0.3, data: 1.0e-2}
   1188   - {wavelength: 0.4, data: 1.0e-3}
   1189   - {wavelength: 0.5, data: 2.0e-3}
   1190   - {wavelength: 0.6, data: 2.0e-2}
   1191   - {wavelength: 0.7, data: 3.0e-3}
   1192   - {wavelength: 0.8, data: 1.0e-3}
   1193 
   1194 - spectrum: &glass_ref_index
   1195   - {wavelength: 0.30, data: 1.40}
   1196   - {wavelength: 0.40, data: 1.39}
   1197   - {wavelength: 0.50, data: 1.37}
   1198   - {wavelength: 0.60, data: 1.34}
   1199   - {wavelength: 0.70, data: 1.30}
   1200   - {wavelength: 0.80, data: 1.25}
   1201 
   1202 # Media
   1203 - medium: &air_medium
   1204     refractive_index: 1
   1205     extinction: *air_kabs
   1206 
   1207 - medium: &glass_medium
   1208     refractive_index: *glass_ref_index
   1209     extinction: *glass_kabs
   1210 
   1211 # Sun & atmosphere
   1212 - sun: {dni: 1, spectrum: *solar_spectrum}
   1213 - atmosphere: {extinction: *air_kabs}
   1214 
   1215 # Materials
   1216 - material: &specular {mirror: {reflectivity: 1, slope_error: 0}}
   1217 - material: &black {matte: {reflectivity: 0}}
   1218 - material: &glass
   1219     front: {dielectric: {medium_i: *air_medium, medium_t: *glass_medium}}
   1220     back:  {dielectric: {medium_i: *glass_medium, medium_t: *air_medium}}
   1221 
   1222 # Primary reflectors
   1223 - entity:
   1224     name: "primary_reflector1"
   1225     primary: 1
   1226     transform: {translation: [0, 0, -2.0]}
   1227     geometry:
   1228     - material: *specular
   1229       parabol:
   1230         focal: 12
   1231         clip:
   1232         - {operation: AND, circle: {radius: 10}}
   1233         - {operation: SUB, circle: {radius: 5}}
   1234 
   1235 - entity:
   1236     name: "primary_reflector2"
   1237     primary: 1
   1238     transform: {translation: [0, 0, -4]}
   1239     geometry:
   1240     - material: *specular
   1241       parabol:
   1242         focal: 14
   1243         clip:
   1244         - {operation: AND, circle: {radius: 15}}
   1245         - {operation: SUB, circle: {radius: 10}}
   1246 
   1247 - entity:
   1248     name: "primary_reflector3"
   1249     primary: 1
   1250     transform: {translation: [0, 0, -6]}
   1251     geometry:
   1252     - material: *specular
   1253       parabol:
   1254         focal: 16
   1255         clip:
   1256         - {operation: AND, circle: {radius: 20}}
   1257         - {operation: SUB, circle: {radius: 15}}
   1258 
   1259 # Secondary reflector
   1260 - entity:
   1261     name: "secondary_reflector"
   1262     primary: 0
   1263     transform: {translation: [0, 0, 6]}
   1264     geometry:
   1265     - material: *specular
   1266       hyperbol:
   1267         focals: {real: 16.0, image: 4}
   1268         clip: [{operation: AND, circle: {radius: 5}}]
   1269 
   1270 # Glass box
   1271 - entity:
   1272     name: "glass_slide"
   1273     primary: 0
   1274     geometry:
   1275     - material: *glass
   1276       cuboid: {size: [10,10,0.5]}
   1277       transform: {translation: [0, 0, 0.25]}
   1278 
   1279 # Receiver
   1280 - entity:
   1281     name: "square_receiver"
   1282     primary: 0
   1283     transform: {translation: [0, 0, -10] }
   1284     geometry:
   1285     - material: *black
   1286       plane:
   1287         clip:
   1288         - operation: AND
   1289           vertices: [[-0.5,-0.5],[-0.5,0.5],[0.5,0.5],[0.5,-0.5]]
   1290 .Ed
   1291 .Sh NOTES
   1292 .Bl -enum
   1293 .It
   1294 YAML Ain't Markup Language \(em
   1295 .Lk http://yaml.org
   1296 .It
   1297 SMARTS, Simple Model of the Atmospheric Radiative Transfer of Sunshine \(em
   1298 .Lk http://www.nrel.gov/rredc/smarts/
   1299 .It
   1300 D.\& Buie, A.G.\& Monger, C.J.\& Dey.
   1301 .Dq Sunshape distributions for terrestrial solar simulations .
   1302 .Em Solar Energy ,
   1303 2003, 74, pp.\& 113\(en122.
   1304 .It
   1305 D.\& Buie, C.J.\& Dey, S.\& Bosi.
   1306 .Dq The effective size of the solar cone for solar concentrating systems .
   1307 .Em Solar Energy ,
   1308 2003, 74, pp.\& 417\(en427.
   1309 .It
   1310 Portable PixMap \(em
   1311 .Lk http://netpbm.sourceforge.net/doc/ppm.html
   1312 .El
   1313 .Sh SEE ALSO
   1314 .Xr solstice 1 ,
   1315 .Xr solstice-receiver 5
   1316 .Sh HISTORY
   1317 .Nm
   1318 was initially developed with funding from the
   1319 .Em SOLSTICE LabEx
   1320 .Pq Laboratory of Excellence ,
   1321 in collaboration with the PROMES Laboratory of the
   1322 French National Centre for Scientific Research
   1323 .Pq CNRS .
   1324 Starting in 2026, a new development effort funded by Ademe is ongoing.
   1325 .Sh AUTHORS
   1326 .Nm
   1327 was written and is maintained by
   1328 .An |M\['e]so|Star> Aq Mt contact@meso-star.com .