cellular_raza_core/backend/chili/aux_storage.rs
1use cellular_raza_concepts::CycleEvent;
2pub use circ_buffer::*;
3use serde::{Deserialize, Serialize};
4
5pub use cellular_raza_concepts::Xapy;
6
7// --------------------------------- UPDATE-MECHANICS --------------------------------
8/// Used to store intermediate information about last positions and velocities.
9/// Can store up to `N` values.
10pub trait UpdateMechanics<Pos, Vel, For, const N: usize> {
11 /// Stores the last position of the cell. May overwrite old results depending on
12 /// how many old results are being stored.
13 fn set_last_position(&mut self, pos: Pos);
14
15 /// Get all previous positions. This number maybe smaller than the maximum number of stored
16 /// positions but never exceeds it.
17 fn previous_positions<'a>(&'a self) -> RingBufferIterRef<'a, Pos, N>;
18
19 /// Stores the last velocity of the cell. Overwrites old results when stored amount
20 /// exceeds number of maximum stored values.
21 fn set_last_velocity(&mut self, vel: Vel);
22
23 /// Get all previous velocities. This number may be smaller than the maximum number of stored
24 /// velocities but never exceeds it.
25 fn previous_velocities<'a>(&'a self) -> RingBufferIterRef<'a, Vel, N>;
26
27 /// Get the number of previous values currently stored
28 ///
29 /// This number is by definition between 0 and `N`.
30 fn n_previous_values(&self) -> usize;
31
32 /// Add force to currently stored forces
33 fn add_force(&mut self, force: For);
34
35 /// Obtain current force on cell
36 fn get_current_force_and_reset(&mut self) -> For;
37}
38
39/// Stores intermediate information about the mechanics of a cell.
40#[derive(Clone, Deserialize, Serialize)]
41pub struct AuxStorageMechanics<Pos, Vel, For, const N: usize> {
42 positions: RingBuffer<Pos, N>,
43 velocities: RingBuffer<Vel, N>,
44 current_force: For,
45 zero_force: For,
46}
47
48// It is necessary to implement this trait by hand since with the current version of the Mechanics
49// concept, we need to specify next_random_mechanics_update: Some(0.0) in order for any updates to
50// be done at all.
51impl<Pos, Vel, For, const N: usize> Default for AuxStorageMechanics<Pos, Vel, For, N>
52where
53 For: num::Zero,
54{
55 fn default() -> Self {
56 Self {
57 positions: RingBuffer::<Pos, N>::default(),
58 velocities: RingBuffer::<Vel, N>::default(),
59 current_force: num::Zero::zero(),
60 zero_force: num::Zero::zero(),
61 }
62 }
63}
64
65/// Used to construct initial (empty) AuxStorage variants.
66pub trait DefaultFrom<T> {
67 /// Constructs the Type in question from a given value. This is typically a zero value.
68 /// If it can be constructed from the [num::Zero] trait, this method is not required and
69 /// `cellular_raza` will determine the initial zero-value correctly.
70 /// For other types (ie. dynamically-sized ones) additional entries may be necessary.
71 fn default_from(value: &T) -> Self;
72}
73
74impl<Pos, Vel, For, const N: usize> DefaultFrom<For> for AuxStorageMechanics<Pos, Vel, For, N>
75where
76 For: Clone,
77{
78 fn default_from(value: &For) -> Self {
79 let force: For = value.clone().into();
80 Self {
81 positions: RingBuffer::default(),
82 velocities: RingBuffer::default(),
83 current_force: force.clone(),
84 zero_force: force.clone(),
85 }
86 }
87}
88
89impl<Pos, Vel, For, const N: usize> UpdateMechanics<Pos, Vel, For, N>
90 for AuxStorageMechanics<Pos, Vel, For, N>
91where
92 For: Clone + core::ops::AddAssign<For>,
93{
94 #[inline]
95 fn previous_positions<'a>(&'a self) -> RingBufferIterRef<'a, Pos, N> {
96 self.positions.iter()
97 }
98
99 #[inline]
100 fn previous_velocities<'a>(&'a self) -> RingBufferIterRef<'a, Vel, N> {
101 self.velocities.iter()
102 }
103
104 #[inline]
105 fn n_previous_values(&self) -> usize {
106 self.positions.get_size()
107 }
108
109 #[inline]
110 fn set_last_position(&mut self, pos: Pos) {
111 self.positions.push(pos);
112 }
113
114 #[inline]
115 fn set_last_velocity(&mut self, vel: Vel) {
116 self.velocities.push(vel);
117 }
118
119 #[inline]
120 fn add_force(&mut self, force: For) {
121 self.current_force += force;
122 }
123
124 #[inline]
125 fn get_current_force_and_reset(&mut self) -> For {
126 let f = self.current_force.clone();
127 self.current_force = self.zero_force.clone();
128 f
129 }
130}
131
132// ----------------------------------- UPDATE-CYCLE ----------------------------------
133/// Trait which describes how to store intermediate
134/// information on the cell cycle.
135pub trait UpdateCycle {
136 /// Set all cycle events. This function is currently the
137 /// only way to change the contents of the stored events.
138 fn set_cycle_events(&mut self, events: Vec<CycleEvent>);
139
140 /// Get all cycle events currently stored.
141 fn get_cycle_events(&self) -> &Vec<CycleEvent>;
142
143 /// Drain all cycle events
144 fn drain_cycle_events<'a>(&'a mut self) -> std::vec::Drain<'a, CycleEvent>;
145
146 /// Add another cycle event to the storage.
147 fn add_cycle_event(&mut self, event: CycleEvent);
148}
149
150/// Stores intermediate information about the cell cycle.
151///
152/// This struct is used in the [build_aux_storage](crate::backend::chili::build_aux_storage) macro.
153/// It can in principle also be re-used on its own since it implements the [UpdateCycle] trait.
154///
155/// ```
156/// use cellular_raza_core::backend::chili::{AuxStorageCycle,UpdateCycle};
157/// use cellular_raza_concepts::CycleEvent;
158///
159/// // Construct a new empty AuxStorageCycle
160/// let mut aux_storage_cycle = AuxStorageCycle::default();
161///
162/// // Add one element
163/// aux_storage_cycle.add_cycle_event(CycleEvent::Division);
164/// assert_eq!(aux_storage_cycle.get_cycle_events().len(), 1);
165///
166/// // Drain all elements currently present
167/// let events = aux_storage_cycle.drain_cycle_events();
168/// assert_eq!(events.len(), 1);
169/// ```
170#[derive(Clone, Default, Deserialize, Serialize)]
171pub struct AuxStorageCycle {
172 cycle_events: Vec<CycleEvent>,
173}
174
175impl UpdateCycle for AuxStorageCycle {
176 #[inline]
177 fn set_cycle_events(&mut self, events: Vec<CycleEvent>) {
178 self.cycle_events = events;
179 }
180
181 #[inline]
182 fn get_cycle_events(&self) -> &Vec<CycleEvent> {
183 &self.cycle_events
184 }
185
186 #[inline]
187 fn drain_cycle_events<'a>(&'a mut self) -> std::vec::Drain<'a, CycleEvent> {
188 self.cycle_events.drain(..)
189 }
190
191 #[inline]
192 fn add_cycle_event(&mut self, event: CycleEvent) {
193 self.cycle_events.push(event);
194 }
195}
196
197// --------------------------------- UPDATE-REACTIONS --------------------------------
198/// Interface to store intermediate information about cellular reactions.
199pub trait UpdateReactions<Ri> {
200 /// Set the value of intracellular concentrations
201 fn set_conc(&mut self, conc: Ri);
202 /// Obtain the current value of intracellular concentrations
203 fn get_conc(&self) -> Ri;
204 /// Add concentrations to the current value
205 fn incr_conc(&mut self, incr: Ri);
206}
207
208/// Helper storage for values regarding intracellular concentrations for the
209/// [Reactions](cellular_raza_concepts::Reactions) trait.
210#[derive(Clone, Default, Deserialize, Serialize)]
211pub struct AuxStorageReactions<Ri> {
212 concentration: Ri,
213}
214
215impl<Ri> DefaultFrom<Ri> for AuxStorageReactions<Ri>
216where
217 Ri: Clone,
218{
219 fn default_from(value: &Ri) -> Self {
220 AuxStorageReactions {
221 concentration: value.clone(),
222 }
223 }
224}
225
226impl<R> UpdateReactions<R> for AuxStorageReactions<R>
227where
228 R: Clone + core::ops::Add<R, Output = R>,
229{
230 #[inline]
231 fn get_conc(&self) -> R {
232 self.concentration.clone()
233 }
234
235 #[inline]
236 fn incr_conc(&mut self, incr: R) {
237 self.concentration = self.concentration.clone() + incr;
238 }
239
240 #[inline]
241 fn set_conc(&mut self, conc: R) {
242 self.concentration = conc;
243 }
244}
245
246/// Used to update properties of the cell related to the
247/// [ReactionsContact](cellular_raza_concepts::ReactionsContact) trait.
248pub trait UpdateReactionsContact<Ri, const N: usize> {
249 /// Sets the current contact reactions increment
250 fn set_current_increment(&mut self, new_increment: Ri);
251 /// Adds to the current increment
252 fn incr_current_increment(&mut self, increment: Ri);
253 /// Obtains the current increment
254 fn get_current_increment(&self) -> Ri;
255 /// Obtain previous increments used for adams_bashforth integrators
256 fn previous_increments<'a>(&'a self) -> RingBufferIterRef<'a, Ri, N>;
257 /// Set the last increment in the ring buffer
258 fn set_last_increment(&mut self, increment: Ri);
259 /// Get the number of previous values to match against [circ_buffer::RingBufferIterRef]
260 fn n_previous_values(&self) -> usize;
261}
262
263/// Implementor of the [UpdateReactionsContact] trait.
264#[derive(Clone, Default, Deserialize, Serialize)]
265pub struct AuxStorageReactionsContact<Ri, const N: usize> {
266 current_increment: Ri,
267 increments: RingBuffer<Ri, N>,
268}
269
270impl<Ri, const N: usize> DefaultFrom<Ri> for AuxStorageReactionsContact<Ri, N>
271where
272 Ri: Clone,
273{
274 fn default_from(value: &Ri) -> Self {
275 AuxStorageReactionsContact {
276 current_increment: value.clone(),
277 increments: Default::default(),
278 }
279 }
280}
281
282impl<Ri, const N: usize> UpdateReactionsContact<Ri, N> for AuxStorageReactionsContact<Ri, N>
283where
284 Ri: Clone + core::ops::Add<Ri, Output = Ri>,
285{
286 #[inline]
287 fn get_current_increment(&self) -> Ri {
288 self.current_increment.clone()
289 }
290
291 #[inline]
292 fn incr_current_increment(&mut self, increment: Ri) {
293 self.current_increment = self.current_increment.clone() + increment;
294 }
295
296 #[inline]
297 fn set_current_increment(&mut self, new_increment: Ri) {
298 self.current_increment = new_increment;
299 }
300
301 #[inline]
302 fn previous_increments<'a>(&'a self) -> RingBufferIterRef<'a, Ri, N> {
303 self.increments.iter()
304 }
305
306 #[inline]
307 fn set_last_increment(&mut self, increment: Ri) {
308 self.increments.push(increment)
309 }
310
311 #[inline]
312 fn n_previous_values(&self) -> usize {
313 self.increments.get_size()
314 }
315}
316
317// -------------------------------- UPDATE-Interaction -------------------------------
318/// Interface to store intermediate information about interactions.
319pub trait UpdateInteraction {
320 /// Obtain current number of neighbors
321 fn get_current_neighbors(&self) -> usize;
322 /// Set the number of neighbors
323 fn set_current_neighbors(&mut self, neighbors: usize);
324 /// Increment the number of current neighbors by the provided value
325 fn incr_current_neighbors(&mut self, neighbors: usize);
326}
327
328/// Helper storage for number of neighbors of
329/// [Interaction](cellular_raza_concepts::Interaction) trait.
330#[derive(Clone, Default, Deserialize, Serialize)]
331pub struct AuxStorageInteraction {
332 neighbor_count: usize,
333}
334
335impl UpdateInteraction for AuxStorageInteraction {
336 #[inline]
337 fn get_current_neighbors(&self) -> usize {
338 self.neighbor_count
339 }
340
341 #[inline]
342 fn incr_current_neighbors(&mut self, neighbors: usize) {
343 self.neighbor_count += neighbors;
344 }
345
346 #[inline]
347 fn set_current_neighbors(&mut self, neighbors: usize) {
348 self.neighbor_count = neighbors;
349 }
350}
351
352#[allow(unused)]
353#[doc(hidden)]
354mod test_derive_aux_storage_compile {
355 /// ```
356 /// use cellular_raza_core::backend::chili::AuxStorage;
357 /// use cellular_raza_core::backend::chili::*;
358 ///
359 /// #[derive(AuxStorage)]
360 /// struct TestStructMechanics<Pos, Vel, For, const N: usize> {
361 /// #[UpdateMechanics(Pos, Vel, For, N)]
362 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
363 /// }
364 /// ```
365 fn mechanics_default() {}
366
367 /// ```
368 /// use cellular_raza_core::backend::chili::AuxStorage;
369 /// use cellular_raza_core::backend::chili::*;
370 ///
371 /// #[derive(AuxStorage)]
372 /// pub struct TestStructMechanics<Pos, Vel, For, const N: usize> {
373 /// #[UpdateMechanics(Pos, Vel, For, N)]
374 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
375 /// }
376 /// ```
377 fn mechanics_visibility_1() {}
378
379 /// ```
380 /// use cellular_raza_core::backend::chili::AuxStorage;
381 /// use cellular_raza_core::backend::chili::*;
382 ///
383 /// #[derive(AuxStorage)]
384 /// pub(crate) struct TestStructMechanics<Pos, Vel, For, const N: usize> {
385 /// #[UpdateMechanics(Pos, Vel, For, N)]
386 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
387 /// }
388 /// ```
389 fn mechanics_visibility_2() {}
390
391 /// ```
392 /// mod some_module {
393 /// use cellular_raza_core::backend::chili::AuxStorage;
394 /// use cellular_raza_core::backend::chili::*;
395 ///
396 /// #[derive(AuxStorage)]
397 /// pub(super) struct TestStructMechanics<Pos, Vel, For, const N: usize> {
398 /// #[UpdateMechanics(Pos, Vel, For, N)]
399 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
400 /// }
401 /// }
402 /// fn use_impl<T, Pos, Vel, For, const N: usize>(
403 /// mut aux_storage: T
404 /// ) -> For
405 /// where
406 /// T: cellular_raza_core::backend::chili::UpdateMechanics<Pos, Vel, For, N>,
407 /// {
408 /// aux_storage.get_current_force_and_reset()
409 /// }
410 /// ```
411 fn mechanics_visibility_3() {}
412
413 /// ```
414 /// use cellular_raza_core::backend::chili::AuxStorage;
415 /// use cellular_raza_core::backend::chili::*;
416 ///
417 /// #[derive(AuxStorage)]
418 /// struct TestStructMechanics<Pos, Vel, For, T, const N: usize> {
419 /// #[UpdateMechanics(Pos, Vel, For, N)]
420 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
421 /// other: T,
422 /// }
423 /// ```
424 fn mechanics_more_struct_generics() {}
425
426 /// ```
427 /// use cellular_raza_core::backend::chili::AuxStorage;
428 /// use cellular_raza_core::backend::chili::*;
429 ///
430 /// #[derive(AuxStorage)]
431 /// struct TestStructMechanics<Pos, Vel, For, const N: usize, const M: usize> {
432 /// #[UpdateMechanics(Pos, Vel, For, N)]
433 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
434 /// count: [i64; M],
435 /// }
436 /// ```
437 fn mechanics_more_struct_const_generics() {}
438
439 /// ```
440 /// use cellular_raza_core::backend::chili::AuxStorage;
441 /// use cellular_raza_core::backend::chili::*;
442 ///
443 /// #[derive(AuxStorage)]
444 /// struct TestStructMechanics<Pos, Vel, For, const N: usize>
445 /// where
446 /// Pos: Clone,
447 /// {
448 /// #[UpdateMechanics(Pos, Vel, For, N)]
449 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
450 /// }
451 /// ```
452 fn mechanics_where_clause() {}
453
454 /// ```
455 /// use cellular_raza_core::backend::chili::AuxStorage;
456 /// use cellular_raza_core::backend::chili::*;
457 ///
458 /// #[derive(AuxStorage)]
459 /// struct TestStructMechanics<Pos, Vel, For, const N: usize> {
460 /// #[UpdateMechanics(Pos, Vel, For, N)]
461 /// #[cfg(not(test))]
462 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
463 /// }
464 /// ```
465 fn mechanics_other_attributes() {}
466
467 /// ```
468 /// use cellular_raza_core::backend::chili::AuxStorage;
469 /// use cellular_raza_core::backend::chili::*;
470 /// use cellular_raza_concepts::CycleEvent;
471 ///
472 /// #[derive(AuxStorage)]
473 /// struct TestStructCycle {
474 /// #[UpdateCycle]
475 /// aux_cycle: AuxStorageCycle,
476 /// }
477 /// ```
478 fn cycle_default() {}
479
480 /// ```
481 /// use cellular_raza_core::backend::chili::AuxStorage;
482 /// use cellular_raza_core::backend::chili::*;
483 /// use cellular_raza_concepts::CycleEvent;
484 ///
485 /// #[derive(AuxStorage)]
486 /// pub struct TestStructCycle {
487 /// #[UpdateCycle]
488 /// aux_cycle: AuxStorageCycle,
489 /// }
490 /// ```
491 fn cycle_visibility_1() {}
492
493 /// ```
494 /// use cellular_raza_core::backend::chili::AuxStorage;
495 /// use cellular_raza_core::backend::chili::*;
496 /// use cellular_raza_concepts::CycleEvent;
497 ///
498 /// #[derive(AuxStorage)]
499 /// pub(crate) struct TestStructCycle {
500 /// #[UpdateCycle]
501 /// aux_cycle: AuxStorageCycle,
502 /// }
503 /// ```
504 fn cycle_visibility_2() {}
505
506 /// ```
507 /// use cellular_raza_core::backend::chili::AuxStorage;
508 /// use cellular_raza_core::backend::chili::*;
509 /// use cellular_raza_concepts::CycleEvent;
510 ///
511 /// #[derive(AuxStorage)]
512 /// pub struct TestStructCycle<T> {
513 /// #[UpdateCycle]
514 /// aux_cycle: AuxStorageCycle,
515 /// _generic: T,
516 /// }
517 /// ```
518 fn cycle_generic_param() {}
519
520 /// ```
521 /// use cellular_raza_core::backend::chili::AuxStorage;
522 /// use cellular_raza_core::backend::chili::*;
523 /// use cellular_raza_concepts::CycleEvent;
524 ///
525 /// #[derive(AuxStorage)]
526 /// pub struct TestStructCycle<const N: usize> {
527 /// #[UpdateCycle]
528 /// aux_cycle: AuxStorageCycle,
529 /// _generic: [f64; N],
530 /// }
531 /// ```
532 fn cycle_const_generic_param() {}
533
534 /// ```
535 /// use cellular_raza_core::backend::chili::AuxStorage;
536 /// use cellular_raza_core::backend::chili::*;
537 /// use cellular_raza_concepts::CycleEvent;
538 ///
539 /// #[derive(AuxStorage)]
540 /// pub struct TestStructCycle<T>
541 /// where
542 /// T: Clone,
543 /// {
544 /// #[UpdateCycle]
545 /// aux_cycle: AuxStorageCycle,
546 /// _generic: T,
547 /// }
548 /// ```
549 fn cycle_where_clause() {}
550
551 /// ```
552 /// use cellular_raza_core::backend::chili::AuxStorage;
553 /// use cellular_raza_core::backend::chili::*;
554 /// use cellular_raza_concepts::CycleEvent;
555 ///
556 /// #[derive(AuxStorage)]
557 /// struct TestStructCycle {
558 /// #[UpdateCycle]
559 /// #[cfg(not(test))]
560 /// aux_cycle: AuxStorageCycle,
561 /// }
562 /// ```
563 fn cycle_other_attributes() {}
564
565 /// ```
566 /// use cellular_raza_core::backend::chili::AuxStorage;
567 /// use cellular_raza_core::backend::chili::*;
568 ///
569 /// #[derive(AuxStorage)]
570 /// struct TestStructReactions<R> {
571 /// #[UpdateReactions(R)]
572 /// aux_cycle: AuxStorageReactions<R>,
573 /// }
574 /// ```
575 fn reactions_default() {}
576
577 /// ```
578 /// use cellular_raza_core::backend::chili::AuxStorage;
579 /// use cellular_raza_core::backend::chili::*;
580 ///
581 /// #[derive(AuxStorage)]
582 /// pub struct TestStructReactions<R> {
583 /// #[UpdateReactions(R)]
584 /// aux_cycle: AuxStorageReactions<R>,
585 /// }
586 /// ```
587 fn reactions_visibility_1() {}
588
589 /// ```
590 /// use cellular_raza_core::backend::chili::AuxStorage;
591 /// use cellular_raza_core::backend::chili::*;
592 ///
593 /// #[derive(AuxStorage)]
594 /// pub(crate) struct TestStructReactions<R> {
595 /// #[UpdateReactions(R)]
596 /// aux_cycle: AuxStorageReactions<R>,
597 /// }
598 /// ```
599 fn reactions_visibility_2() {}
600
601 /// ```
602 /// use cellular_raza_core::backend::chili::AuxStorage;
603 /// use cellular_raza_core::backend::chili::*;
604 ///
605 /// #[derive(AuxStorage)]
606 /// struct TestStructReactions<T, R> {
607 /// #[UpdateReactions(R)]
608 /// aux_cycle: AuxStorageReactions<R>,
609 /// generic: T,
610 /// }
611 /// ```
612 fn reactions_generic_param() {}
613
614 /// ```
615 /// use cellular_raza_core::backend::chili::AuxStorage;
616 /// use cellular_raza_core::backend::chili::*;
617 ///
618 /// #[derive(AuxStorage)]
619 /// struct TestStructReactions<R, const N: usize> {
620 /// #[UpdateReactions(R)]
621 /// aux_cycle: AuxStorageReactions<R>,
622 /// generic_array: [usize; N],
623 /// }
624 /// ```
625 fn reactions_const_generic_param() {}
626
627 /// ```
628 /// use cellular_raza_core::backend::chili::AuxStorage;
629 /// use cellular_raza_core::backend::chili::*;
630 ///
631 /// #[derive(AuxStorage)]
632 /// struct TestStructReactions<T, R>
633 /// where
634 /// T: Clone,
635 /// {
636 /// #[UpdateReactions(R)]
637 /// aux_cycle: AuxStorageReactions<R>,
638 /// generic: T,
639 /// }
640 /// ```
641 fn reactions_where_clause() {}
642
643 /// ```
644 /// use cellular_raza_core::backend::chili::AuxStorage;
645 /// use cellular_raza_core::backend::chili::*;
646 ///
647 /// #[derive(AuxStorage)]
648 /// struct TestStructReactions<R> {
649 /// #[cfg(not(test))]
650 /// #[UpdateReactions(R)]
651 /// aux_cycle: AuxStorageReactions<R>,
652 /// }
653 /// ```
654 fn reactions_other_attributes() {}
655
656 /// ```
657 /// use cellular_raza_core::backend::chili::AuxStorage;
658 /// use cellular_raza_core::backend::chili::*;
659 ///
660 /// #[derive(AuxStorage)]
661 /// struct TestStructInteraction {
662 /// #[UpdateInteraction]
663 /// aux_interaction: AuxStorageInteraction,
664 /// }
665 /// ```
666 fn interactions_default() {}
667
668 /// ```
669 /// use cellular_raza_core::backend::chili::AuxStorage;
670 /// use cellular_raza_core::backend::chili::*;
671 ///
672 /// #[derive(AuxStorage)]
673 /// pub struct TestStructInteraction {
674 /// #[UpdateInteraction]
675 /// aux_interaction: AuxStorageInteraction,
676 /// }
677 /// ```
678 fn interactions_visibility_1() {}
679
680 /// ```
681 /// use cellular_raza_core::backend::chili::AuxStorage;
682 /// use cellular_raza_core::backend::chili::*;
683 ///
684 /// #[derive(AuxStorage)]
685 /// pub(crate) struct TestStructInteraction {
686 /// #[UpdateInteraction]
687 /// aux_interaction: AuxStorageInteraction,
688 /// }
689 /// ```
690 fn interactions_visibility_2() {}
691
692 /// ```
693 /// use cellular_raza_core::backend::chili::AuxStorage;
694 /// use cellular_raza_core::backend::chili::*;
695 ///
696 /// #[derive(AuxStorage)]
697 /// struct TestStructInteraction<T> {
698 /// #[UpdateInteraction]
699 /// aux_interaction: AuxStorageInteraction,
700 /// generic: T,
701 /// }
702 /// ```
703 fn interactions_generic_param() {}
704
705 /// ```
706 /// use cellular_raza_core::backend::chili::AuxStorage;
707 /// use cellular_raza_core::backend::chili::*;
708 ///
709 /// #[derive(AuxStorage)]
710 /// struct TestStructInteraction<const N: usize> {
711 /// #[UpdateInteraction]
712 /// aux_interaction: AuxStorageInteraction,
713 /// generic: [f64; N],
714 /// }
715 /// ```
716 fn interactions_const_generic_param() {}
717
718 /// ```
719 /// use cellular_raza_core::backend::chili::AuxStorage;
720 /// use cellular_raza_core::backend::chili::*;
721 ///
722 /// #[derive(AuxStorage)]
723 /// struct TestStructInteraction<T>
724 /// where
725 /// T: Clone,
726 /// {
727 /// #[UpdateInteraction]
728 /// aux_interaction: AuxStorageInteraction,
729 /// generic: T,
730 /// }
731 /// ```
732 fn interactions_where_clause() {}
733
734 /// ```
735 /// use cellular_raza_core::backend::chili::AuxStorage;
736 /// use cellular_raza_core::backend::chili::*;
737 ///
738 /// #[derive(AuxStorage)]
739 /// struct TestStructInteraction {
740 /// #[UpdateInteraction]
741 /// #[cfg(not(test))]
742 /// aux_interaction: AuxStorageInteraction,
743 /// }
744 /// ```
745 fn interactions_other_attributes() {}
746}
747
748#[cfg(test)]
749mod test_derive_aux_storage {
750 use super::*;
751 use cellular_raza_core_proc_macro::AuxStorage;
752
753 #[derive(AuxStorage)]
754 struct TestStructDouble<Pos, Vel, For, const N: usize> {
755 #[UpdateCycle]
756 aux_cycle: AuxStorageCycle,
757 #[UpdateMechanics(Pos, Vel, For, N)]
758 aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
759 }
760
761 #[derive(AuxStorage)]
762 struct TestStructCycle {
763 #[UpdateCycle]
764 aux_cycle: AuxStorageCycle,
765 }
766
767 #[derive(AuxStorage)]
768 struct TestStructMechanics<Pos, Vel, For, const N: usize> {
769 #[UpdateMechanics(Pos, Vel, For, N)]
770 aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
771 }
772
773 fn add_get_events<A>(aux_storage: &mut A)
774 where
775 A: UpdateCycle,
776 {
777 aux_storage.add_cycle_event(CycleEvent::Division);
778 let events = aux_storage.get_cycle_events();
779 assert_eq!(events, &vec![CycleEvent::Division]);
780 }
781
782 fn set_get_events<A>(aux_storage: &mut A)
783 where
784 A: UpdateCycle,
785 {
786 let initial_events = vec![
787 CycleEvent::Division,
788 CycleEvent::Division,
789 CycleEvent::PhasedDeath,
790 ];
791 aux_storage.set_cycle_events(initial_events.clone());
792 let events = aux_storage.get_cycle_events();
793 assert_eq!(events.len(), 3);
794 assert_eq!(events, &initial_events);
795 }
796
797 #[test]
798 fn cycle_add_get_events() {
799 let mut aux_storage = TestStructCycle {
800 aux_cycle: AuxStorageCycle::default(),
801 };
802 add_get_events(&mut aux_storage);
803 }
804
805 #[test]
806 fn cycle_set_get_events() {
807 let mut aux_storage = TestStructCycle {
808 aux_cycle: AuxStorageCycle::default(),
809 };
810 set_get_events(&mut aux_storage);
811 }
812
813 #[test]
814 fn mechanics() {
815 let mut aux_storage = TestStructMechanics::<_, _, _, 4> {
816 aux_mechanics: AuxStorageMechanics::default(),
817 };
818 aux_storage.set_last_position(3_f64);
819 aux_storage.set_last_velocity(5_f32);
820 aux_storage.add_force(1_f32);
821 }
822
823 #[test]
824 fn cycle_mechanics_add_get_events() {
825 let mut aux_storage = TestStructDouble::<_, _, _, 4> {
826 aux_cycle: AuxStorageCycle::default(),
827 aux_mechanics: AuxStorageMechanics::default(),
828 };
829 aux_storage.set_last_position(3_f64);
830 aux_storage.set_last_velocity(5_f32);
831 aux_storage.add_force(-5_f32);
832 add_get_events(&mut aux_storage);
833 }
834
835 #[test]
836 fn cycle_mechanics_set_get_events() {
837 let mut aux_storage = TestStructDouble::<_, _, _, 4> {
838 aux_cycle: AuxStorageCycle::default(),
839 aux_mechanics: AuxStorageMechanics::default(),
840 };
841 aux_storage.set_last_position(3_f64);
842 aux_storage.set_last_velocity(5_f32);
843 aux_storage.add_force(111_i64);
844 set_get_events(&mut aux_storage);
845 }
846}
847
848#[allow(unused)]
849#[doc(hidden)]
850mod test_build_aux_storage {
851 use crate::backend::chili::proc_macro::aux_storage_constructor;
852 macro_rules! construct (
853 (name:$test_name:ident,
854 aspects:[$($asp:ident),*]) => {
855 /// ```
856 /// use serde::{Deserialize, Serialize};
857 /// use cellular_raza_core::backend::chili::*;
858 /// build_aux_storage!(
859 #[doc = concat!("aspects: [", $(stringify!($asp,),)* "],")]
860 /// aux_storage_name: __cr_AuxStorage,
861 /// core_path: cellular_raza_core
862 /// );
863 // #[doc = concat!("let mut aux_storage = __cr_AuxStorage {", init!($($asp),*) "};")]
864 // #[doc = init!{@start $($asp),* end}]
865 #[doc = concat!(
866 "let mut aux_storage = (",
867 stringify!(aux_storage_constructor!(
868 aux_storage_name: __cr_AuxStorage,
869 core_path: cellular_raza_core,
870 aspects: [$($asp),*],
871 )),
872 ")(());",
873 )]
874 /// macro_rules! test_aspect (
875 /// (Mechanics) => {
876 /// {
877 /// use cellular_raza_core::backend::chili::UpdateMechanics;
878 /// aux_storage.set_last_position(1_f32);
879 /// aux_storage.set_last_position(3_f32);
880 /// let last_positions = aux_storage
881 /// .previous_positions()
882 /// .map(|f| *f)
883 /// .collect::<Vec<f32>>();
884 /// assert_eq!(last_positions, vec![1_f32, 3_f32]);
885 /// aux_storage.set_last_velocity(10_f32);
886 /// let last_velocities: cellular_raza_core::backend::chili::RingBufferIterRef<_, 4>
887 /// = aux_storage.previous_velocities();
888 /// let last_velocities = last_velocities.map(|f| *f).collect::<Vec<f32>>();
889 /// assert_eq!(last_velocities, vec![10_f32]);
890 /// aux_storage.add_force(22_f32);
891 /// assert_eq!(aux_storage.get_current_force_and_reset(), 22_f32);
892 /// }
893 /// };
894 /// (Interaction) => {
895 /// {
896 /// use cellular_raza_core::backend::chili::UpdateInteraction;
897 /// aux_storage.incr_current_neighbors(1);
898 /// aux_storage.incr_current_neighbors(2);
899 /// aux_storage.incr_current_neighbors(1);
900 /// assert_eq!(aux_storage.get_current_neighbors(), 4);
901 /// }
902 /// };
903 /// (Cycle) => {
904 /// {
905 /// use cellular_raza_core::backend::chili::UpdateCycle;
906 /// use cellular_raza_concepts::CycleEvent;
907 /// aux_storage.add_cycle_event(CycleEvent::Division);
908 /// assert_eq!(aux_storage.get_cycle_events(), &vec![CycleEvent::Division]);
909 /// }
910 /// };
911 /// (Reactions) => {
912 /// {
913 /// use cellular_raza_core::backend::chili::UpdateReactions;
914 /// aux_storage.set_conc(0_f32);
915 /// aux_storage.incr_conc(1.44_f32);
916 /// assert_eq!(aux_storage.get_conc(), 0_f32 + 1.44_f32);
917 /// }
918 /// };
919 /// (ReactionsContact) => {
920 /// {
921 /// use cellular_raza_core::backend::chili::UpdateReactionsContact;
922 /// aux_storage.set_last_increment(0f32);
923 /// aux_storage.set_last_increment(3f32);
924 /// assert_eq!(UpdateReactionsContact::n_previous_values(&aux_storage), 2);
925 /// let last_increments =
926 /// UpdateReactionsContact::<f32, 10>::previous_increments(
927 /// &aux_storage
928 /// );
929 /// let last_increments = last_increments.map(|f| *f).collect::<Vec<_>>();
930 /// assert_eq!(last_increments, vec![0.0, 3.0]);
931 /// }
932 /// };
933 /// );
934 #[doc = concat!($(
935 concat!("test_aspect!(", stringify!($asp), ");")
936 ,)*)]
937 /// ```
938 fn $test_name() {}
939 }
940 );
941
942 cellular_raza_core_proc_macro::run_test_for_aspects!(
943 test: construct,
944 aspects: [Mechanics, Interaction, Cycle, Reactions, ReactionsContact]
945 );
946}