|
1 | | -use std::ops::{Add, AddAssign, Mul}; |
| 1 | +use std::ops::{Add, AddAssign, Deref, Mul}; |
2 | 2 |
|
3 | 3 | use nalgebra::allocator::Allocator; |
4 | 4 | use nalgebra::{DefaultAllocator, DimName, OPoint, Point1, Scalar, U2, U3}; |
|
47 | 47 | } |
48 | 48 | integral |
49 | 49 | } |
| 50 | + |
| 51 | + fn to_parts(&self) -> QuadratureParts<&[T], &[OPoint<T, D>], &[Self::Data]> { |
| 52 | + QuadratureParts { |
| 53 | + weights: self.weights(), |
| 54 | + points: self.points(), |
| 55 | + data: self.data(), |
| 56 | + } |
| 57 | + } |
50 | 58 | } |
51 | 59 |
|
52 | 60 | /// Trait alias for 1D quadrature rules. |
@@ -139,6 +147,77 @@ where |
139 | 147 | } |
140 | 148 | } |
141 | 149 |
|
| 150 | +/// Marker to indicate that a quadrature rule stored in [`QuadratureParts`] has no associated data. |
| 151 | +#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] |
| 152 | +pub struct NoData; |
| 153 | + |
| 154 | +#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] |
| 155 | +pub struct QuadratureParts<WeightsArray, PointsArray, DataArray> { |
| 156 | + pub weights: WeightsArray, |
| 157 | + pub points: PointsArray, |
| 158 | + pub data: DataArray, |
| 159 | +} |
| 160 | + |
| 161 | +impl<WeightsArray, PointsArray, DataArray> QuadratureParts<WeightsArray, PointsArray, DataArray> { |
| 162 | + pub fn with_data<DataArray2>(self, data: DataArray2) -> QuadratureParts<WeightsArray, PointsArray, DataArray2> { |
| 163 | + QuadratureParts { |
| 164 | + weights: self.weights, |
| 165 | + points: self.points, |
| 166 | + data, |
| 167 | + } |
| 168 | + } |
| 169 | +} |
| 170 | + |
| 171 | +impl<T, D, WeightsArray, PointsArray, DataArray, Data> Quadrature<T, D> |
| 172 | + for QuadratureParts<WeightsArray, PointsArray, DataArray> |
| 173 | +where |
| 174 | + T: Scalar, |
| 175 | + D: DimName, |
| 176 | + WeightsArray: AsRef<[T]>, |
| 177 | + PointsArray: AsRef<[OPoint<T, D>]>, |
| 178 | + DataArray: Deref<Target = [Data]>, |
| 179 | + DefaultAllocator: Allocator<T, D>, |
| 180 | +{ |
| 181 | + type Data = Data; |
| 182 | + |
| 183 | + fn weights(&self) -> &[T] { |
| 184 | + self.weights.as_ref() |
| 185 | + } |
| 186 | + |
| 187 | + fn points(&self) -> &[OPoint<T, D>] { |
| 188 | + self.points.as_ref() |
| 189 | + } |
| 190 | + |
| 191 | + fn data(&self) -> &[Self::Data] { |
| 192 | + self.data.deref() |
| 193 | + } |
| 194 | +} |
| 195 | + |
| 196 | +impl<T, D, WeightsArray, PointsArray> Quadrature<T, D> for QuadratureParts<WeightsArray, PointsArray, NoData> |
| 197 | +where |
| 198 | + T: Scalar, |
| 199 | + D: DimName, |
| 200 | + WeightsArray: AsRef<[T]>, |
| 201 | + PointsArray: AsRef<[OPoint<T, D>]>, |
| 202 | + DefaultAllocator: Allocator<T, D>, |
| 203 | +{ |
| 204 | + type Data = (); |
| 205 | + |
| 206 | + fn weights(&self) -> &[T] { |
| 207 | + self.weights.as_ref() |
| 208 | + } |
| 209 | + |
| 210 | + fn points(&self) -> &[OPoint<T, D>] { |
| 211 | + self.points.as_ref() |
| 212 | + } |
| 213 | + |
| 214 | + fn data(&self) -> &[()] { |
| 215 | + // This is a "sound" way of constructing a unit type slice of arbitrary size. |
| 216 | + // Since it's zero-sized, it won't actually allocate any memory and the leak is elided |
| 217 | + vec![(); self.weights().len()].leak() |
| 218 | + } |
| 219 | +} |
| 220 | + |
142 | 221 | fn convert_quadrature_rule_from_1d_f64<T>(quadrature: fenris_quadrature::Rule<1>) -> QuadraturePair1d<T> |
143 | 222 | where |
144 | 223 | T: RealField, |
|
0 commit comments