Field3D
MACFieldUtil.h File Reference

Contains utility functions for MAC fields, such as conversion to cell-centered fields. More...

#include "MACField.h"
#include "ns.h"

Go to the source code of this file.

Functions

template<class Field_T , class Data_T >
void convertCellCenteredToMAC (typename Field_T::Ptr cc, typename MACField< Data_T >::Ptr mac)
 Converts the cell-centered field to a MAC field.
 
template<class Data_T , class Field_T >
FIELD3D_NAMESPACE_OPEN void convertMACToCellCentered (typename MACField< Data_T >::Ptr mac, typename Field_T::Ptr cc)
 Converts the MAC field to a cell-centered field.
 
template<class Data_T , class Field_T >
void convertMACToCellCentered (typename MACField< Data_T >::Ptr mac, typename Field_T::Ptr cc)
 Sets up the cell-centered target field given a MAC field.
 

Detailed Description

Contains utility functions for MAC fields, such as conversion to cell-centered fields.

Definition in file MACFieldUtil.h.

Function Documentation

◆ convertMACToCellCentered() [1/2]

template<class Data_T , class Field_T >
FIELD3D_NAMESPACE_OPEN void convertMACToCellCentered ( typename MACField< Data_T >::Ptr mac,
typename Field_T::Ptr cc )

Converts the MAC field to a cell-centered field.

Converts the MAC field to a cell-centered field.

Definition at line 78 of file MACFieldUtil.h.

80{
81 // Make sure the extents and data window match
82 if (cc->extents().min != mac->extents().min ||
83 cc->extents().max != mac->extents().max ||
84 cc->dataWindow().min != mac->dataWindow().min ||
85 cc->dataWindow().max != mac->dataWindow().max ) {
86 cc->setSize(mac->extents(), mac->dataWindow());
87 }
88
89 // Make sure mapping matches
90 if (!cc->mapping()->isIdentical(mac->mapping())) {
91 cc->setMapping(mac->mapping());
92 }
93
94 // MAC velocities are in simulation space (axis-aligned to the
95 // mapping) because the values are stored on the faces, so rotate
96 // vectors from simulation-space to world-space when transferring
97 // from MAC to cell-centered
98
99 bool rotateVector = false;
100 M44d ssToWsMtx;
103 if (mapping) {
104 M44d localToWorldMtx = mapping->localToWorld();
105 V3d scale, rot, trans, shear;
106 if (extractSHRT(localToWorldMtx, scale, shear, rot, trans, false)) {
107 ssToWsMtx.rotate(rot);
108 if (rot.length2() > FLT_EPSILON)
109 rotateVector = true;
110 }
111 }
112
113 // Loop over all the voxels in the output field ---
114
115 typename Field_T::iterator i = cc->begin();
116 typename Field_T::iterator end = cc->end();
117
118 if (rotateVector) {
119 for (; i != end; ++i) {
120 *i = mac->value(i.x, i.y, i.z) * ssToWsMtx;
121 }
122 } else {
123 for (; i != end; ++i) {
124 *i = mac->value(i.x, i.y, i.z);
125 }
126 }
127}
#define FIELD_DYNAMIC_CAST
Definition RefCount.h:271
Imath::V3d V3d
Definition SpiMathLib.h:74
Imath::M44d M44d
Definition SpiMathLib.h:82
boost::intrusive_ptr< MatrixFieldMapping > Ptr
Convenience typedef.

References FieldRes::dataWindow(), FieldRes::extents(), FIELD_DYNAMIC_CAST, FieldRes::mapping(), and MACField< Data_T >::value().

◆ convertCellCenteredToMAC()

template<class Field_T , class Data_T >
void convertCellCenteredToMAC ( typename Field_T::Ptr cc,
typename MACField< Data_T >::Ptr mac )

Converts the cell-centered field to a MAC field.

Definition at line 132 of file MACFieldUtil.h.

134{
135 // Make sure the extents and data window match
136 if (mac->extents().min != cc->extents().min ||
137 mac->extents().max != cc->extents().max ||
138 mac->dataWindow().min != cc->dataWindow().min ||
139 mac->dataWindow().max != cc->dataWindow().max ) {
140 mac->setSize(cc->extents(), cc->dataWindow());
141 }
142
143 // Make sure mapping matches
144 if (!mac->mapping()->isIdentical(cc->mapping())) {
145 mac->setMapping(cc->mapping());
146 }
147
148 Box3i data = mac->dataWindow();
149
150 // MAC velocities are in simulation space (axis-aligned to the
151 // mapping) because the values are stored on the faces, so rotate
152 // vectors from world-space to simulation-space when transferring
153 // from cell-centered to MAC
154
155 bool rotateVector = false;
156 M44d wsToSsMtx;
159 if (mapping) {
160 M44d localToWorld = mapping->localToWorld();
161 V3d scale, rot, trans, shear;
162 if (FIELD3D_EXTRACT_SHRT(localToWorld, scale, shear, rot, trans, false)) {
163 wsToSsMtx.rotate(-rot);
164 rotateVector = true;
165 }
166 }
167
168 // Use a pointer to a field below so we can substitute it out for
169 // our intermediate, rotated field if necessary, without needing to
170 // duplicate the loops. This should be more efficient CPU-wise so
171 // we don't need to do 3 matrix multiplies per cell-centered voxel
172 // because it's used in 3 separate loops (1 per MAC face).
173 typename Field_T::Ptr src = cc;
174
175 typename Field_T::Ptr ccRotated;
176 if (rotateVector) {
177 ccRotated =
178 typename Field_T::Ptr(new Field_T);
179 ccRotated->matchDefinition(cc);
180
181 typename Field_T::const_iterator iIn = cc->cbegin();
182 typename Field_T::const_iterator endIn = cc->cend();
183 typename Field_T::iterator iOut = ccRotated->begin();
184
185 for (; iIn != endIn; ++iIn, ++iOut) {
186 *iOut = *iIn * wsToSsMtx;
187 }
188 src = ccRotated;
189 }
190
191 // Set the u edge value to their closest voxel
192 for (int k = data.min.z; k <= data.max.z; k++) {
193 for (int j = data.min.y; j <= data.max.y; j++) {
194 mac->u(data.min.x, j, k) = src->value(data.min.x, j, k).x;
195 mac->u(data.max.x + 1, j, k) = src->value(data.max.x, j, k).x;
196 }
197 }
198
199 // Set the v edge value to their closest voxel
200 for (int k = data.min.z; k <= data.max.z; k++) {
201 for (int i = data.min.x; i <= data.max.x; i++) {
202 mac->v(i, data.min.y, k) = src->value(i, data.min.y, k).y;
203 mac->v(i, data.max.y + 1, k) = src->value(i, data.max.y, k).y;
204 }
205 }
206
207 // Set the w edge value to their closest voxel
208 for (int j = data.min.y; j <= data.max.y; j++) {
209 for (int i = data.min.x; i <= data.max.x; i++) {
210 mac->w(i, j, data.min.z) = src->value(i, j, data.min.z).z;
211 mac->w(i, j, data.max.z + 1) = src->value(i, j, data.max.z).z;
212 }
213 }
214
215 // Loop over internal u values
216 for (int k = data.min.z; k <= data.max.z; ++k) {
217 for (int j = data.min.y; j <= data.max.y; ++j) {
218 for (int i = data.min.x + 1; i <= data.max.x; ++i) {
219 mac->u(i, j, k) =
220 (src->value(i, j, k).x + src->value(i - 1, j, k).x) * 0.5;
221 }
222 }
223 }
224
225 // Loop over internal v values
226 for (int k = data.min.z; k <= data.max.z; ++k) {
227 for (int j = data.min.y + 1; j <= data.max.y; ++j) {
228 for (int i = data.min.x; i <= data.max.x; ++i) {
229 mac->v(i, j, k) =
230 (src->value(i, j, k).y + src->value(i, j - 1, k).y) * 0.5;
231 }
232 }
233 }
234
235 // Loop over internal w values
236 for (int k = data.min.z + 1; k <= data.max.z; ++k) {
237 for (int j = data.min.y; j <= data.max.y; ++j) {
238 for (int i = data.min.x; i <= data.max.x; ++i) {
239 mac->w(i, j, k) =
240 (src->value(i, j, k).z + src->value(i, j, k - 1).z) * 0.5;
241 }
242 }
243 }
244}
#define FIELD3D_EXTRACT_SHRT
Definition SpiMathLib.h:93
Imath::Box3i Box3i
Definition SpiMathLib.h:77

References FieldRes::dataWindow(), FieldRes::extents(), FIELD3D_EXTRACT_SHRT, FIELD_DYNAMIC_CAST, FieldRes::mapping(), FieldRes::setMapping(), ResizableField< Data_T >::setSize(), MACField< Data_T >::u(), MACField< Data_T >::v(), and MACField< Data_T >::w().

◆ convertMACToCellCentered() [2/2]

template<class Data_T , class Field_T >
void convertMACToCellCentered ( typename MACField< Data_T >::Ptr mac,
typename Field_T::Ptr cc )

Sets up the cell-centered target field given a MAC field.

Converts the MAC field to a cell-centered field.

Definition at line 78 of file MACFieldUtil.h.

80{
81 // Make sure the extents and data window match
82 if (cc->extents().min != mac->extents().min ||
83 cc->extents().max != mac->extents().max ||
84 cc->dataWindow().min != mac->dataWindow().min ||
85 cc->dataWindow().max != mac->dataWindow().max ) {
86 cc->setSize(mac->extents(), mac->dataWindow());
87 }
88
89 // Make sure mapping matches
90 if (!cc->mapping()->isIdentical(mac->mapping())) {
91 cc->setMapping(mac->mapping());
92 }
93
94 // MAC velocities are in simulation space (axis-aligned to the
95 // mapping) because the values are stored on the faces, so rotate
96 // vectors from simulation-space to world-space when transferring
97 // from MAC to cell-centered
98
99 bool rotateVector = false;
100 M44d ssToWsMtx;
103 if (mapping) {
104 M44d localToWorldMtx = mapping->localToWorld();
105 V3d scale, rot, trans, shear;
106 if (extractSHRT(localToWorldMtx, scale, shear, rot, trans, false)) {
107 ssToWsMtx.rotate(rot);
108 if (rot.length2() > FLT_EPSILON)
109 rotateVector = true;
110 }
111 }
112
113 // Loop over all the voxels in the output field ---
114
115 typename Field_T::iterator i = cc->begin();
116 typename Field_T::iterator end = cc->end();
117
118 if (rotateVector) {
119 for (; i != end; ++i) {
120 *i = mac->value(i.x, i.y, i.z) * ssToWsMtx;
121 }
122 } else {
123 for (; i != end; ++i) {
124 *i = mac->value(i.x, i.y, i.z);
125 }
126 }
127}

References FieldRes::dataWindow(), FieldRes::extents(), FIELD_DYNAMIC_CAST, FieldRes::mapping(), and MACField< Data_T >::value().