1 /*   EXTRAITS DE LA LICENCE
2 	Copyright CEA, contributeurs : Damien
3 	CALISTE, laboratoire L_Sim, (2018)
4 
5 	Adresse mèl :
6 	CALISTE, damien P caliste AT cea P fr.
7 
8 	Ce logiciel est un programme informatique servant à visualiser des
9 	structures atomiques dans un rendu pseudo-3D.
10 
11 	Ce logiciel est régi par la licence CeCILL soumise au droit français et
12 	respectant les principes de diffusion des logiciels libres. Vous pouvez
13 	utiliser, modifier et/ou redistribuer ce programme sous les conditions
14 	de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
15 	sur le site "http://www.cecill.info".
16 
17 	Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
18 	pris connaissance de la licence CeCILL, et que vous en avez accepté les
19 	termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
20 */
21 
22 /*   LICENCE SUM UP
23 	Copyright CEA, contributors : Damien
24 	CALISTE, laboratoire L_Sim, (2018)
25 
26 	E-mail address:
27 	CALISTE, damien P caliste AT cea P fr.
28 
29 	This software is a computer program whose purpose is to visualize atomic
30 	configurations in 3D.
31 
32 	This software is governed by the CeCILL  license under French law and
33 	abiding by the rules of distribution of free software.  You can  use,
34 	modify and/ or redistribute the software under the terms of the CeCILL
35 	license as circulated by CEA, CNRS and INRIA at the following URL
36 	"http://www.cecill.info".
37 
38 	The fact that you are presently reading this means that you have had
39 	knowledge of the CeCILL license and that you accept its terms. You can
40 	find a copy of this licence shipped with this software at Documentation/licence.en.txt.
41 */
42 
43 #include "poleProp.h"
44 #include <coreTools/toolMatrix.h>
45 #include <coreTools/toolPhysic.h>
46 #include <coreTools/atoms_yaml.h>
47 
48 #include <string.h>
49 
50 /**
51  * SECTION:poleProp
52  * @short_description: define a #VisuNodeValues object to handle
53  * multipole node information.
54  *
55  * <para>Defines a #VisuNodeValues object to store a pole
56  * information on nodes.</para>
57  */
58 
59 static gboolean _parse(VisuNodeValues *vals, VisuNode *node, const gchar *from);
60 static gchar* _serialize(const VisuNodeValues *vals, const VisuNode *node);
61 
62 
G_DEFINE_TYPE(VisuNodeValuesPole,visu_node_values_pole,VISU_TYPE_NODE_VALUES_FARRAY)63 G_DEFINE_TYPE(VisuNodeValuesPole, visu_node_values_pole, VISU_TYPE_NODE_VALUES_FARRAY)
64 
65 static void visu_node_values_pole_class_init(VisuNodeValuesPoleClass *klass)
66 {
67   /* Connect the overloading methods. */
68   VISU_NODE_VALUES_CLASS(klass)->parse = _parse;
69   VISU_NODE_VALUES_CLASS(klass)->serialize = _serialize;
70 }
71 
visu_node_values_pole_init(VisuNodeValuesPole * self _U_)72 static void visu_node_values_pole_init(VisuNodeValuesPole *self _U_)
73 {
74 }
75 
_parse(VisuNodeValues * vals,VisuNode * node,const gchar * from)76 static gboolean _parse(VisuNodeValues *vals, VisuNode *node, const gchar *from)
77 {
78   gfloat data[9];
79   GValue value = G_VALUE_INIT;
80   PosinpDict *dict;
81   guint i;
82 
83   g_return_val_if_fail(from, FALSE);
84 
85   dict = posinp_yaml_parse_properties(from, NULL);
86   if (!dict)
87     return FALSE;
88   memset(vals, '\0', sizeof(gfloat) * 9);
89   for (i = 0; i < dict->len && dict->items[i].key; i++)
90     if (!strcmp(dict->items[i].key, "q0") &&
91         dict->items[i].type == POSINP_TYPE_DBL_ARR &&
92         dict->items[i].value.darr.len == 1)
93       data[0] = dict->items[i].value.darr.arr[0];
94     else if (!strcmp(dict->items[i].key, "q1") &&
95              dict->items[i].type == POSINP_TYPE_DBL_ARR &&
96              dict->items[i].value.darr.len == 3)
97       {
98         data[1] = dict->items[i].value.darr.arr[0];
99         data[2] = dict->items[i].value.darr.arr[1];
100         data[3] = dict->items[i].value.darr.arr[2];
101       }
102     else if (!strcmp(dict->items[i].key, "q2") &&
103              dict->items[i].type == POSINP_TYPE_DBL_ARR &&
104              dict->items[i].value.darr.len == 5)
105       {
106         data[4] = dict->items[i].value.darr.arr[0];
107         data[5] = dict->items[i].value.darr.arr[1];
108         data[6] = dict->items[i].value.darr.arr[2];
109         data[7] = dict->items[i].value.darr.arr[3];
110         data[8] = dict->items[i].value.darr.arr[4];
111       }
112   posinp_yaml_free_properties(dict);
113   g_value_set_pointer(&value, data);
114   return visu_node_values_setAt(vals, node, &value);
115 }
_serialize(const VisuNodeValues * vals,const VisuNode * node)116 static gchar* _serialize(const VisuNodeValues *vals, const VisuNode *node)
117 {
118   GValue value = G_VALUE_INIT;
119   gfloat *fvals;
120 
121   if (!visu_node_values_getAt(vals, node, &value))
122     return (gchar*)0;
123 
124   fvals = (float*)g_value_get_pointer(&value);
125   if (fvals)
126     return g_strdup_printf("q0: [%#.3g]\nq1: [%#.3g, %#.3g, %#.3g]\nq2: [%#.3g, %#.3g, %#.3g, %#.3g, %#.3g]", fvals[0], fvals[1], fvals[2], fvals[3], fvals[4], fvals[5], fvals[6], fvals[7], fvals[8]);
127   else
128     return (gchar*)0;
129 }
130 
131 /**
132  * visu_node_values_pole_new:
133  * @arr: a #VisuNodeArray object.
134  * @label: a translatable label.
135  *
136  * Create a new pole field located on nodes.
137  *
138  * Since: 3.8
139  *
140  * Returns: (transfer full): a newly created #VisuNodeValuesPole object.
141  **/
visu_node_values_pole_new(VisuNodeArray * arr,const gchar * label)142 VisuNodeValuesPole* visu_node_values_pole_new(VisuNodeArray *arr,
143                                                   const gchar *label)
144 {
145   VisuNodeValuesPole *vals;
146 
147   vals = VISU_NODE_VALUES_POLE(g_object_new(VISU_TYPE_NODE_VALUES_POLE,
148                                             "nodes", arr, "label", label,
149                                             "type", G_TYPE_FLOAT,
150                                             "n-elements", 9, NULL));
151   return vals;
152 }
153 
154 static const gfloat zmono[1] = {0.f};
155 static const gfloat zdi[3]   = {0.f, 0.f, 0.f};
156 static const gfloat zquad[5] = {0.f, 0.f, 0.f, 0.f, 0.f};
157 /**
158  * visu_node_values_pole_getAt:
159  * @pole: a #VisuNodeValuesPole object.
160  * @node: a #VisuNode object.
161  * @order: a #VisuPoleOrder value.
162  *
163  * Retrieves the pole hosted on @node.
164  *
165  * Since: 3.8
166  *
167  * Returns: (array fixed-size=3) (transfer none): the coordinates of
168  * pole for @node.
169  **/
visu_node_values_pole_getAt(const VisuNodeValuesPole * pole,const VisuNode * node,VisuPoleOrder order)170 const gfloat* visu_node_values_pole_getAt(const VisuNodeValuesPole *pole,
171                                           const VisuNode *node,
172                                           VisuPoleOrder order)
173 {
174   GValue diffValue = G_VALUE_INIT;
175   const gfloat *diff;
176 
177   diff = (const gfloat*)0;
178   if (visu_node_values_getAt(VISU_NODE_VALUES(pole), node, &diffValue))
179     diff = (const gfloat*)g_value_get_pointer(&diffValue);
180   switch (order)
181     {
182     case VISU_MONOPOLE:
183       return (diff) ? diff : zmono;
184     case VISU_DIPOLE:
185       return (diff) ? diff + 1: zdi;
186     case VISU_QUADRUPOLE:
187       return (diff) ? diff + 4: zquad;
188     default:
189       return (const gfloat*)0;
190     }
191 }
192 
193 /**
194  * visu_node_values_pole_setMonoAt:
195  * @pole: a #VisuNodeValuesPole object.
196  * @node: a #VisuNode object.
197  * @val: a mono-pole value.
198  *
199  * Changes the mono-pole hosted at @node.
200  *
201  * Since: 3.8
202  *
203  * Returns: TRUE if pole for @node is indeed changed.
204  **/
visu_node_values_pole_setMonoAt(VisuNodeValuesPole * pole,const VisuNode * node,gfloat val)205 gboolean visu_node_values_pole_setMonoAt(VisuNodeValuesPole *pole,
206                                          const VisuNode *node, gfloat val)
207 {
208   gfloat *vals, poles[9];
209   GValue gval = G_VALUE_INIT;
210 
211   visu_node_values_getAt(VISU_NODE_VALUES(pole), node, &gval);
212   vals = (gfloat*)g_value_get_pointer(&gval);
213   if (vals && vals[0] == val)
214     return FALSE;
215 
216   if (!vals)
217     {
218       vals = poles;
219       memset(poles, '\0', sizeof(gfloat) * 9);
220     }
221   vals[0] = val;
222   g_value_set_pointer(&gval, vals);
223   return visu_node_values_setAt(VISU_NODE_VALUES(pole), node, &gval);
224 }
225 /**
226  * visu_node_values_pole_setMonoAtDbl:
227  * @pole: a #VisuNodeValuesPole object.
228  * @node: a #VisuNode object.
229  * @val: a mono-pole value.
230  *
231  * Changes the mono-pole hosted at @node.
232  *
233  * Since: 3.8
234  *
235  * Returns: TRUE if pole for @node is indeed changed.
236  **/
visu_node_values_pole_setMonoAtDbl(VisuNodeValuesPole * pole,const VisuNode * node,gdouble val)237 gboolean visu_node_values_pole_setMonoAtDbl(VisuNodeValuesPole *pole,
238                                             const VisuNode *node, gdouble val)
239 {
240   return visu_node_values_pole_setMonoAt(pole, node, val);
241 }
242 
243 /**
244  * visu_node_values_pole_setDiAt:
245  * @pole: a #VisuNodeValuesPole object.
246  * @node: a #VisuNode object.
247  * @val: a di-pole value.
248  *
249  * Changes the di-pole hosted at @node.
250  *
251  * Since: 3.8
252  *
253  * Returns: TRUE if pole for @node is indeed changed.
254  **/
visu_node_values_pole_setDiAt(VisuNodeValuesPole * pole,const VisuNode * node,const gfloat val[3])255 gboolean visu_node_values_pole_setDiAt(VisuNodeValuesPole *pole,
256                                        const VisuNode *node, const gfloat val[3])
257 {
258   gfloat *vals, poles[9];
259   GValue gval = G_VALUE_INIT;
260 
261   visu_node_values_getAt(VISU_NODE_VALUES(pole), node, &gval);
262   vals = (gfloat*)g_value_get_pointer(&gval);
263   if (vals && vals[1] == val[0] && vals[2] == val[1] && vals[3] == val[2])
264     return FALSE;
265 
266   if (!vals)
267     {
268       vals = poles;
269       memset(poles, '\0', sizeof(gfloat) * 9);
270     }
271   vals[1] = val[0];
272   vals[2] = val[1];
273   vals[3] = val[2];
274   g_value_set_pointer(&gval, vals);
275   return visu_node_values_setAt(VISU_NODE_VALUES(pole), node, &gval);
276 }
277 /**
278  * visu_node_values_pole_setDiAtDbl:
279  * @pole: a #VisuNodeValuesPole object.
280  * @node: a #VisuNode object.
281  * @val: a di-pole value.
282  *
283  * Changes the di-pole hosted at @node.
284  *
285  * Since: 3.8
286  *
287  * Returns: TRUE if pole for @node is indeed changed.
288  **/
visu_node_values_pole_setDiAtDbl(VisuNodeValuesPole * pole,const VisuNode * node,const gdouble val[3])289 gboolean visu_node_values_pole_setDiAtDbl(VisuNodeValuesPole *pole,
290                                           const VisuNode *node, const gdouble val[3])
291 {
292   gfloat fval[3];
293   fval[0] = val[0];
294   fval[1] = val[1];
295   fval[2] = val[2];
296   return visu_node_values_pole_setDiAt(pole, node, fval);
297 }
298 
299 /**
300  * visu_node_values_pole_setQuadAt:
301  * @pole: a #VisuNodeValuesPole object.
302  * @node: a #VisuNode object.
303  * @val: a quadru-pole value.
304  *
305  * Changes the quadru-pole hosted at @node.
306  *
307  * Since: 3.8
308  *
309  * Returns: TRUE if pole for @node is indeed changed.
310  **/
visu_node_values_pole_setQuadAt(VisuNodeValuesPole * pole,const VisuNode * node,const gfloat val[5])311 gboolean visu_node_values_pole_setQuadAt(VisuNodeValuesPole *pole,
312                                          const VisuNode *node, const gfloat val[5])
313 {
314   gfloat *vals, poles[9];
315   GValue gval = G_VALUE_INIT;
316 
317   visu_node_values_getAt(VISU_NODE_VALUES(pole), node, &gval);
318   vals = (gfloat*)g_value_get_pointer(&gval);
319   if (vals && vals[4] == val[0] && vals[5] == val[1] && vals[6] == val[2] && vals[7] == val[3] && vals[8] == val[4])
320     return FALSE;
321 
322   if (!vals)
323     {
324       vals = poles;
325       memset(poles, '\0', sizeof(gfloat) * 9);
326     }
327   vals[4] = val[0];
328   vals[5] = val[1];
329   vals[6] = val[2];
330   vals[7] = val[3];
331   vals[8] = val[4];
332   g_value_set_pointer(&gval, vals);
333   return visu_node_values_setAt(VISU_NODE_VALUES(pole), node, &gval);
334 }
335 /**
336  * visu_node_values_pole_setQuadAtDbl:
337  * @pole: a #VisuNodeValuesPole object.
338  * @node: a #VisuNode object.
339  * @val: a quadru-pole value.
340  *
341  * Changes the quadru-pole hosted at @node.
342  *
343  * Since: 3.8
344  *
345  * Returns: TRUE if pole for @node is indeed changed.
346  **/
visu_node_values_pole_setQuadAtDbl(VisuNodeValuesPole * pole,const VisuNode * node,const gdouble val[5])347 gboolean visu_node_values_pole_setQuadAtDbl(VisuNodeValuesPole *pole,
348                                             const VisuNode *node, const gdouble val[5])
349 {
350   gfloat fval[5];
351   fval[0] = val[0];
352   fval[1] = val[1];
353   fval[2] = val[2];
354   fval[3] = val[3];
355   fval[4] = val[4];
356   return visu_node_values_pole_setQuadAt(pole, node, fval);
357 }
358