1 \input texinfo @c -*-texinfo-*-
2 @comment %**start of header
5 @settitle Hkl Diffraction Library @value{VERSION}
7 @comment %**end of header
9 This manual is for hkl Library (version @value{VERSION}, @value{UPDATED}).
11 Copyright @copyright{} 2003-2010 Synchrotron SOLEIL
12 L'Orme des Merisiers Saint-Aubin
13 BP 48 91192 GIF-sur-YVETTE CEDEX
16 The hkl library is free software: you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation, either version 3 of the License, or
19 (at your option) any later version.
21 The hkl library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with the hkl library. If not, see <http://www.gnu.org/licenses/>.
31 @dircategory Software libraries
33 * hkl: (hkl). Library for hkl diffraction computation.
38 @subtitle for version @value{VERSION}, @value{UPDATED}
39 @author F-E. Picca (@email{picca@@synchrotorn-soleil.fr})
41 @vskip 0pt plus 1filll
48 @node Top, Introduction, (dir), (dir)
49 @top hkl Diffraction Library
51 This manual is for Hkl Diffraction Library (version @value{VERSION}, @value{UPDATED}).
61 --- The Detailed Node Listing ---
65 * Eulerian 4 circles::
66 * Eulerian 6 circles::
67 * Kappa 4 circles vertical::
70 * SOLEIL SIXS MED2+2::
75 @node Introduction, Diffractometer, Top, Top
78 The purpose of the library is to factories diffraction angles computation for
79 different kind of diffractometers geometries. It is used at the SOLEIL, Desy
80 and Alba synchrotron with the Tango control system to pilot diffractometers.
85 @item mode computation (aka PseudoAxis)
87 @item for different diffractometer geometries.
89 @item UB matrix computation.
91 @item busing & Levy with 2 reflections
92 @item simplex computation with more than 2 reflections using the GSL library.
93 @item Eulerians angles to pre-orientate your sample.
95 @item Crystal lattice affinement
97 @item with more than 2 reflections you can select which parameter must be fitted.
101 @item psi, eulerians, q, ...
105 @section Conventions.
107 In all this document the next convention will be used to describe the diffractometers
110 @item right handed convention for all the angles.
111 @item direct space orthogonal base.
112 @item description of the diffractometer geometries is done with all axes values set to zero.
115 @node Diffractometer, Developpement, Introduction, Top
116 @chapter Diffractometer
119 * Eulerian 4 circles::
120 * Eulerian 6 circles::
121 * Kappa 4 circles vertical::
124 * SOLEIL SIXS MED2+2::
127 @node Eulerian 4 circles, Eulerian 6 circles, Diffractometer, Diffractometer
128 @section Eulerian 4 circles
130 @subsection Geometries
132 @subsubsection Vertical
134 @item xrays source fix allong the @math{\vec{x}} direction (1, 0, 0)
135 @item 3 axes for the sample
137 @item @samp{omega} : rotating around the @math{-\vec{y}} direction (0, -1, 0)
138 @item @samp{chi} : rotating around the @math{\vec{x}} direction (1, 0, 0)
139 @item @samp{phi} : rotating around the @math{-\vec{y}} direction (0, -1, 0)
141 @item 1 axis for the detector
143 @item @samp{tth} : rotation around the @math{-\vec{y}} direction (0, -1, 0)
147 @subsubsection Horizontal
150 @item xrays source fix allong the @math{\vec{x}} direction (1, 0, 0)
151 @item 3 axes for the sample
153 @item @samp{omega} : rotating around the @math{\vec{z}} direction (0, 0, 1)
154 @item @samp{chi} : rotating around the @math{\vec{x}} direction (1, 0, 0)
155 @item @samp{phi} : rotating around the @math{\vec{z}} direction (0, 0, 1)
157 @item 1 axis for the detector
159 @item @samp{tth} : rotation around the @math{\vec{z}} direction (0, 0, 1)
163 @subsubsection Soleil Mars Beamline
166 @item xrays source fix allong the @math{\vec{x}} direction (1, 0, 0)
167 @item 3 axes for the sample
169 @item @samp{omega} : rotating around the @math{\vec{z}} direction (0, -1, 0)
170 @item @samp{chi} : rotating around the @math{\vec{x}} direction (-1, 0, 0)
171 @item @samp{phi} : rotating around the @math{\vec{z}} direction (0, 0, 1)
173 @item 1 axis for the detector
175 @item @samp{tth} : rotation around the @math{\vec{z}} direction (0, -1, 0)
179 @subsection Pseudo axis @samp{hkl}
181 PseudoAxes provided : @samp{h}, @samp{k} and @samp{l}
183 @subsubsection mode @samp{bissector}
186 @item Axes : @samp{omega}, @samp{chi}, @samp{phi}, @samp{tth}
187 @item Parameters : No parameter
190 This mode add the bissector constrain @code{tth = 2 * omega}. In this mode the @samp{chi}
191 circle containt the vector of diffusion @math{\vec{Q}}. So it is easy to know the orientation
194 @subsubsection mode @samp{constant_omega}
197 @item Axes : @samp{chi}, @samp{phi}, @samp{tth}
198 @item Parameters : No parameter
201 This mode do not move the current @samp{omega} axis.
203 @subsubsection mode @samp{constant_chi}
206 @item Axes : @samp{omega}, @samp{phi}, @samp{tth}
207 @item Parameters : No parameter
210 This mode do not move the current @samp{chi} axis.
212 @subsubsection mode @samp{constant_phi}
215 @item Axes related : @samp{omega}, @samp{chi}, @samp{tth}
216 @item Parameters : No parameter
218 This mode do not move the current @samp{phi} axis.
220 @subsubsection mode @samp{double_diffraction}
223 @item Axes : @samp{omega}, @samp{chi}, @samp{phi}, @samp{tth}
224 @item Parameters : @samp{h2}, @samp{k2}, @samp{l2}
227 This mode put a second hkl vector (@samp{h2}, @samp{k2}, @samp{l2}) in Bragg condition.
228 This is usefull sometimes when you want to explore two bragg peaks without moving your sample.
230 @subsubsection mode @samp{psi_constant}
233 @item Axes : @samp{omega}, @samp{chi}, @samp{phi}, @samp{tth}
234 @item Parameters : @samp{h2}, @samp{k2}, @samp{l2}, @samp{psi}
237 This mode allow to fix the value of the pseudo axis @samp{psi} at a constant value when you move
238 around an @samp{h}, @samp{k} ,@samp{l} position. The (@samp{h2}, @samp{k2}, @samp{l2}) vector is
239 used as a reference for the computation of the @samp{psi} pseudo axis value.
241 You can retrive and ``freeze'' the current value of the @samp{psi} pseudo axis value into the
242 @samp{psi} parameter when you initialize the mode. But you can also write directly the value
243 of the desired @samp{psi} parameter.
245 @subsection PseudoAxis @samp{psi}
247 PseudoAxis provided : @samp{psi}
249 @subsubsection mode @samp{psi}
252 @item Axes : @samp{omega}, @samp{chi}, @samp{phi}, @samp{tth}
253 @item Parameters : @samp{h1}, @samp{k1},@samp{l1}
256 @node Eulerian 6 circles, Kappa 4 circles vertical, Eulerian 4 circles, Diffractometer
257 @section Eulerian 6 circles
262 @item xrays source fix allong the @math{\vec{x}} direction (1, 0, 0)
263 @item 4 axes for the sample
265 @item @samp{mu} : rotating around the @math{\vec{z}} direction (0, 0, 1)
266 @item @samp{omega} : rotating around the @math{-\vec{y}} direction (0, -1, 0)
267 @item @samp{chi} : rotating around the @math{\vec{x}} direction (1, 0, 0)
268 @item @samp{phi} : rotating around the @math{-\vec{y}} direction (0, -1, 0)
270 @item 2 axes for the detector
272 @item @samp{gamma} : rotation around the @math{\vec{z}} direction (0, 0, 1)
273 @item @samp{delta} : rotation around the @math{-\vec{y}} direction (0, -1, 0)
277 @subsection PseudoAxes
279 @node Kappa 4 circles vertical, Kappa 6 circles, Eulerian 6 circles, Diffractometer
280 @section Kappa 4 circles vertical
284 For this geometry there is a special parameters called @math{\alpha} which is the
285 angle between the kappa rotation axis and the @math{\vec{y}} direction.
288 @item xrays source fix allong the @math{\vec{x}} direction (1, 0, 0)
289 @item 3 axes for the sample
291 @item @samp{komega} : rotating around the @math{-\vec{y}} direction (0, -1, 0)
292 @item @samp{kappa} : rotating around the @math{\vec{x}} direction (0, @math{-\cos\alpha}, @math{-\sin\alpha})
293 @item @samp{kphi} : rotating around the @math{-\vec{y}} direction (0, -1, 0)
295 @item 1 axis for the detector
297 @item @samp{tth} : rotation around the @math{-\vec{y}} direction (0, -1, 0)
301 @subsection PseudoAxes
303 @node Kappa 6 circles, Z-axis, Kappa 4 circles vertical, Diffractometer
304 @section Kappa 6 circles
308 For this geometry there is a special parameters called @math{\alpha} which is the
309 angle between the kappa rotation axis and the @math{\vec{y}} direction.
312 @item xrays source fix allong the @math{\vec{x}} direction (1, 0, 0)
313 @item 4 axes for the sample
315 @item @samp{mu} : rotating around the @math{\vec{z}} direction (0, 0, 1)
316 @item @samp{komega} : rotating around the @math{-\vec{y}} direction (0, -1, 0)
317 @item @samp{kappa} : rotating around the @math{\vec{x}} direction (0, @math{-\cos\alpha}, @math{-\sin\alpha})
318 @item @samp{kphi} : rotating around the @math{-\vec{y}} direction (0, -1, 0)
320 @item 2 axes for the detector
322 @item @samp{gamma} : rotation around the @math{\vec{z}} direction (0, 0, 1)
323 @item @samp{delta} : rotation around the @math{-\vec{y}} direction (0, -1, 0)
327 @subsection PseudoAxes
329 @node Z-axis, SOLEIL SIXS MED2+2, Kappa 6 circles, Diffractometer
334 For this geometry the @samp{mu} axis is common to the sample and the detector.
337 @item xrays source fix allong the @math{\vec{x}} direction (1, 0, 0)
338 @item 2 axes for the sample
340 @item @samp{mu} : rotation around the @math{\vec{z}} direction (0, 0, 1)
341 @item @samp{omega} : rotating around the @math{-\vec{y}} direction (0, -1, 0)
343 @item 3 axis for the detector
345 @item @samp{mu} : rotation around the @math{\vec{z}} direction (0, 0, 1)
346 @item @samp{delta} : rotation around the @math{-\vec{y}} direction (0, -1, 0)
347 @item @samp{gamma} : rotation around the @math{\vec{z}} direction (0, 0, 1)
351 @subsection PseudoAxes
353 PseudoAxes provided : @samp{h}, @samp{k} and @samp{l}
355 @subsubsection mode @samp{zaxis}
358 @item Axes : @samp{omega}, @samp{delta}, @samp{gamma}
359 @item Parameters : No parameter
362 @subsubsection mode @samp{reflectivity}
365 @item Axes : @samp{mu}, @samp{omega}, @samp{delta}, @samp{gamma}
366 @item Parameters : No parameter
369 This mode add the reflectivity constraint @code{mu = gamma}. The
370 incomming beam angle and the outgoing beam angle are equals.
372 @node SOLEIL SIXS MED2+2, , Z-axis, Diffractometer
373 @section SOLEIL SIXS MED2+2
378 @item xrays source fix allong the @math{\vec{x}} direction (1, 0, 0)
379 @item 2 axes for the sample
381 @item @samp{mu} : rotation around the @math{\vec{z}} direction (0, 0, 1)
382 @item @samp{omega} : rotating around the @math{-\vec{y}} direction (0, -1, 0)
384 @item 3 axis for the detector
386 @item @samp{gamma} : rotation around the @math{\vec{z}} direction (0, 0, 1)
387 @item @samp{delta} : rotation around the @math{-\vec{y}} direction (0, -1, 0)
391 @subsection Pseudo axis @samp{hkl}
393 PseudoAxes provided : @samp{h}, @samp{k} and @samp{l}
395 @subsubsection mode @samp{mu_fixed}
398 @item Axes : @samp{omega}, @samp{gamma}, @samp{delta}
399 @item Parameters : No parameter
402 @node Developpement, Index, Diffractometer, Top
403 @chapter Developpement
407 To get hkl, you can download the last stable version from sourceforge or if you
408 want the latest development version use @uref{http://git.or.cz/, git} or
409 @uref{http://code.google.com/p/msysgit/downloads/list, msysgit} on windows system and
412 $ git clone git://repo.or.cz/hkl.git
416 $ git clone http://repo.or.cz/r/hkl.git (slower)
418 then checkout the next branch like this.
421 $ git checkout -b next origin/next
424 @section Building hkl
426 To build hkl you need @uref{http://www.python.org, Python 2.3+} and the
427 @uref{http://www.gnu.org/software/gsl/, GNU Scientific Library 1.12+}
431 $ ./waf install (as root)
434 This command compile the library and the test suit if everythings goes fine you
435 must have a @file{libhkl.so.@value{VERSION}} or @file{libhkl.lib} depending on your
436 platform in the @file{build/default/src} directory. If your platform is not supported yet please
437 contact the @email{picca@@synchrotron-soleil.fr}.
441 you can send your patch to the @email{picca@@synchrotron-soleil.fr} using
444 The developpement process is like this. suppose you wan to add a new feature to
445 hkl create first a new branch from the next one
447 $ git checkout -b my-next next
457 now that your great feature is ready for publication, you can send by mail your
458 patches process like this:
460 $ git format-patch origin/next
462 and send files @file{0001_xxx} and @file{0002_xxx} created to the author.
464 @subsection Howto add a diffractometer
466 In this section we will describe all steps needed to add a diffractometer. We
467 will use the kappa 4 circles exemple.
469 @subsection Adding Geometry
471 The first thing to do is to add the Geometry of this diffractometer. you need
472 to edit the @file{hkl/hkl-geometry.h} file
474 add a new @code{HKL_GEOMETRY_KAPPA4C_VERTICAL} const to the @code{_HklGeometryType}
477 enum _HklGeometryType
480 HKL_GEOMETRY_KAPPA4C_VERTICAL
484 Then you need to add it to the static hkl_geometry_factory_configs constant in the
485 @file{hkl/hkl-geometry-factory.h}
488 static const HklGeometryConfig hkl_geometry_factory_configs[] =
491 {"K4CV", HKL_GEOMETRY_TYPE_KAPPA4C_VERTICAL},
495 Now you must describe the diffractometer axes and the way they are connected
496 all togethers. This diffractometer have one sample holder and one detecter
497 holder and four axes ("komega", "kappa", "kphi" and "tth") So you need to add a
498 new init method for this diffractometer.
501 static void hkl_geometry_init_kappa4C_vertical(HklGeometry *self, double alpha)
506 h = hkl_geometry_add_holder(self);
507 hkl_holder_add_rotation_axis(h, "komega", 0, -1, 0);
508 hkl_holder_add_rotation_axis(h, "kappa", 0, -cos(alpha), -sin(alpha));
509 hkl_holder_add_rotation_axis(h, "kphi", 0, -1, 0);
511 h = hkl_geometry_add_holder(self);
512 hkl_holder_add_rotation_axis(h, "tth", 0, -1, 0);
516 first we set the diffractometer name by
523 This name is used in the Tango diffractometer device to refer this diffractometer.
525 Then you can create the first holder with it's three axes. The order of the axis is from
526 the farest to the closest of the sample. In this case, komega -> kappa -> kphi.
529 h = hkl_geometry_add_holder(self);
530 hkl_holder_add_rotation_axis(h, "komega", 0, -1, 0);
531 hkl_holder_add_rotation_axis(h, "kappa", 0, -cos(alpha), -sin(alpha));
532 hkl_holder_add_rotation_axis(h, "kphi", 0, -1, 0);
535 Same thing for the other holder holding the detector.
538 h = hkl_geometry_add_holder(self);
539 hkl_holder_add_rotation_axis(h, "tth", 0, -1, 0);
542 now it is almost finish for the geometry part. you just need to add it in the factory
545 Hklgeometry *hkl_geometry_factory_new(HklGeometryType type, ...)
550 case HKL_GEOMETRY_KAPPA4C_VERTICAL:
552 alpha = va_arg(ap, double);
554 hkl_geometry_init_kappa4C_vertical(geom, alpha);
561 in this exemple the geometry take one parameter. The fatory can have a variable
562 number of parameters you just need to take care of this with the va_arg
565 @subsection Adding PseudoAxis mode
567 Suppose you want to add a new mode to the hkl pseudo axes.
568 lets call it "psi constant vertical" to the eulerian 6 circle geometry.
570 The starting point is to look in the @file{src/hkl-pseudoaxis-factory.c} for
573 HklEngineList *hkl_engine_list_factory(HklGeometryType type)
576 in that method you can see this in the eulerian 6 circle part
579 case HKL_GEOMETRY_EULERIAN6C:
580 hkl_engine_list_add(self, hkl_engine_e6c_hkl_new());
581 hkl_engine_list_add(self, hkl_engine_e6c_psi_new());
582 hkl_engine_list_add(self, hkl_engine_q2_new());
586 so as you can see there is three pseudo axis engine for this geometry. Your mode if for
587 the hkl pseudo axis. so let look in the @code{hkl_engine_e6c_hkl_new()} method.
588 You can find it in the @file{include/hkl/hkl-pseudoaxis-e6c.h} which contain this:
591 #ifndef __HKL_PSEUDOAXIS_E6C_H__
592 #define __HKL_PSEUDOAXIS_E6C_H__
594 #include <hkl/hkl-pseudoaxis-auto.h>
598 extern HklEngine *hkl_engine_e6c_hkl_new(void);
599 extern HklEngine *hkl_engine_e6c_psi_new(void);
603 #endif /* __HKL_PSEUDOAXIS_E6C_H__ */
606 strange only 2 methods nothing about @code{hkl_engine_q2_new()}. This is because
607 the implementation of this method is common to more than one geometry. So you can find it in
608 @file{hkl/hkl-pseudoaxis-common-q.h}
610 now you need to change the code of @code{hkl_engine_e6c_hkl_new(void)}. Lets
611 look about it in @file{src/hkl-pseudoaxis-e6c-hkl.c}
614 HklEngine *hkl_engine_e6c_hkl_new(void)
619 self = hkl_engine_hkl_new();
621 /* bissector_vertical */
623 "bissector_vertical",
625 hkl_mode_get_hkl_real,
626 hkl_engine_setter_func_bissector_vertical,
628 4, "omega", "chi", "phi", "delta");
629 hkl_engine_add_mode(self, mode);
631 /* constant_omega_vertical */
633 "constant_omega_vertical",
635 hkl_mode_get_hkl_real,
636 hkl_mode_set_hkl_real,
638 3, "chi", "phi", "delta");
639 hkl_engine_add_mode(self, mode);
641 /* constant_chi_vertical */
643 "constant_chi_vertical",
645 hkl_mode_get_hkl_real,
646 hkl_mode_set_hkl_real,
648 3, "omega", "phi", "delta");
649 hkl_engine_add_mode(self, mode);
651 /* constant_phi_vertical */
653 "constant_phi_vertical",
655 hkl_mode_get_hkl_real,
656 hkl_mode_set_hkl_real,
658 3, "omega", "chi", "delta");
659 hkl_engine_add_mode(self, mode);
661 /* lifting_detector_phi */
663 "lifting_detector_phi",
665 hkl_mode_get_hkl_real,
666 hkl_mode_set_hkl_real,
668 3, "phi", "gamma", "delta");
669 hkl_engine_add_mode(self, mode);
671 /* lifting_detector_omega */
673 "lifting_detector_omega",
675 hkl_mode_get_hkl_real,
676 hkl_mode_set_hkl_real,
678 3, "omega", "gamma", "delta");
679 hkl_engine_add_mode(self, mode);
681 /* lifting_detector_mu */
683 "lifting_detector_mu",
685 hkl_mode_get_hkl_real,
686 hkl_mode_set_hkl_real,
688 3, "mu", "gamma", "delta");
689 hkl_engine_add_mode(self, mode);
691 /* double_diffraction vertical*/
696 hkl_parameter_init(&h2, "h2", -1, 1, 1,
699 hkl_parameter_init(&k2, "k2", -1, 1, 1,
702 hkl_parameter_init(&l2, "l2", -1, 1, 1,
707 "double_diffraction_vertical",
709 hkl_mode_get_hkl_real,
710 hkl_mode_set_double_diffraction_real,
712 4, "omega", "chi", "phi", "delta");
713 hkl_engine_add_mode(self, mode);
715 /* bissector_horizontal */
717 "bissector_horizontal",
719 hkl_mode_get_hkl_real,
720 hkl_engine_setter_func_bissector_horizontal,
722 5, "mu", "omega", "chi", "phi", "gamma");
723 hkl_engine_add_mode(self, mode);
725 /* double_diffraction_horizontal */
727 "double_diffraction_horizontal",
729 hkl_mode_get_hkl_real,
730 hkl_mode_set_double_diffraction_real,
732 4, "mu", "chi", "phi", "gamma");
733 hkl_engine_add_mode(self, mode);
735 hkl_engine_select_mode(self, 0);
741 so you "just" need to add a new mode like this
744 /* double_diffraction_horizontal */
746 "psi_constant_vertical",
748 hkl_mode_get_hkl_real,
749 hkl_mode_set_psi_constant_vertical,
751 4, "omega", "chi", "phi", "delta");
752 hkl_engine_add_mode(self, mode);
755 So the first parameter of the hkl_mode_new method
757 @item name is the name of the mode
758 @item then the init functions (usually you need to store the current state of the geometry
759 to be able to use the pseudo axis). Here no need for this init method
760 so we put @code{NULL}.
761 @item then the get method which compute for a given geometry the pseudo axis value.
762 the hkl get method @code{hkl_mode_get_hkl_real} is completely generic
763 and do not depend of the geometry. No need to write it.
764 @item then the set method which compute a geometry for the given pseudo axis values.
765 Now you need to work a little bit and write the set method.
766 @item the parameters of your mode
767 @item * first the number of parameters : 3
768 @item * then each parameters (pointer on the right parameters)
769 for this mode we have 3 parameters h2, k2, l2 which are the coordinates of a
770 sample reference direction use to compute the psi value.
771 @item the name of axes used by the set method.
772 @item * first the number of axes used by the set method : 4
773 @item * then all axes names.
776 In fact the "set" method know nothing about the axes names.
777 so you can use a set method with different kind of geometries.
778 the association is only done during the mode creation.
780 At the end you need to add this mode to the pseudo axis engine with
781 @code{hkl_engine_add_mode(self, mode)};
785 Now let see how this "set" method could be written. In our case we want
786 to compute the geometry angles for a given h, k, l pseudo axis values keeping the
787 angle between the reference reciprocal space vector (h2, k2, l2) and the
788 diffraction plane defined by the incomming beam and the outgoing beam.
791 static int hkl_mode_set_psi_constant_vertical(HklEngine *engine,
792 HklGeometry *geometry,
793 HklDetector *detector,
796 hkl_engine_prepare_internal(engine, geometry, detector,
799 return hkl_engine_solve_function(engine, psi_constant_vertical);
803 the prepare internal part is about initializing the solver with the given
804 geometry, detector and sample. Then comes the hkl_engine_solve_function
805 which need the psi_constant_vertical function to work. This method use the GSL library
806 to find the given function roots (where f(x) = 0).
807 Lets see how it works for the "bissector_horizontal" mode.
810 static int bissector_horizontal(const gsl_vector *x, void *params, gsl_vector *f)
812 double mu, omega, gamma;
813 double const *x_data = gsl_vector_const_ptr(x, 0);
814 double *f_data = gsl_vector_ptr(f, 0);
816 RUBh_minus_Q(x_data, params, f_data);
823 f_data[4] = gamma - 2 * fmod(mu, M_PI);
829 The bissector_horizotal method is used by the setter method of the mode to
830 compute the right set of axes angles corresponding to the pseudo axes values
831 you want to reach. This method compute the difference between these pseudo axes
832 values and the ones computed from the axes angles. It can be decompose in three
835 The first three of these equations are given for the function @code{RUBH_minus_Q}:
836 they are the diference between the h,k,l values that want to be set and the h,k,l
837 values computed for a possible combination of angles:
845 As the bissector_horizontal mode use 5 axes you need to find 2 other
846 equations to be able to solve your mode. The first one
847 is @math{omega = 0} for an horizontal mode:
853 and the last one is for the bissector parameter @math{gamma = 2 * mu}.
856 f_data[4] = gamma - 2 * fmod(mu, M_PI)
859 One question could be why this complicate @code{f4 = gamma - 2 * fmod(mu, M_PI)}
860 equation instead of a simpler @code{f4 = gamma - 2 * mu} ?
861 this is because the bissector_horizontal method is also called by a solution
862 multiplicator to gives the user plenty of equivalent solutions. This multiplicator
863 do some operations like @code{omega = pi - omega} or @code{omega = - omega} on the axes.
864 Then it check that the new angles combination gives also @math{f(x) = 0}. This is the
865 explaination of this more complicate equation.
867 So in our case we need to build something like
870 static int psi_constant_vertical(const gsl_vector *x, void *params, gsl_vector *f)
872 double mu, omega, gamma;
873 double const *x_data = gsl_vector_const_ptr(x, 0);
874 double *f_data = gsl_vector_ptr(f, 0);
876 RUBh_minus_Q(x_data, params, f_data);
884 The missing part is about the psi computation. f3 = psi (target) - psi(x).
885 Calculation psi is done in the psi pseudo axis common part.
888 static int psi(const gsl_vector *x, void *params, gsl_vector *f)
891 This psi method is the equivalent of psi_constant_vertical. So you need
892 to factorize the psi calculation in between psi_constant_vertical and
895 @node Index, , Developpement, Top