FiberVISH 0.2
Fish - The Fiber Bundle API for the Vish Visualization Shell
GridEvaluator_impl.hpp
1#ifndef __FIBER_BASEOPERATIONS_GRIDEVALUATOR_IMPL_HPP
2#define __FIBER_BASEOPERATIONS_GRIDEVALUATOR_IMPL_HPP
3
4#include "GridEvaluator.hpp"
5#include <field/DirectProductArray.hpp>
6#include <field/ArrayRef.hpp>
7
8#include <grid/types/FEM.hpp>
9
10#include <vector/Interpolate.hpp>
11#include <vector/LinearIpol.hpp>
12
13#include "LocalFromWorldPoint.hpp"
14
15#include <aerie/KDTree.hpp>
16
17#include <field/FragmentIDContainer.hpp>
18
19namespace Fiber
20{
21
28{
29 GridEvaluator::Context&myContext;
30 RefPtr<Field> SourceCoordinates;
31
32 RefPtr<LocalFromWorldPoint> myLocalFromWorldPoint;
33
34
37
39 : myContext(theContext)
40 {}
41
42 LocalFromWorldPoint&getLocalFromWorldPoint()
43 {
44 if (!myLocalFromWorldPoint)
45 {
46 myLocalFromWorldPoint = new LocalFromWorldPoint(myContext.mySlice, myContext.mySourceGrid, myContext.Gridname
47// , SourceCoordinates
48 , myContext.Res_scale, myContext.Prec_scale);
49 }
50 return *myLocalFromWorldPoint;
51 }
52
53
54};
55
56template <class PointType>
58{
59
60template <class FloatIndexType>
61static bool getPoint(FragmentSearchBase&FSB ,
62 const PointType&P,
64 RefPtr<FragmentID>&FragID)
65 {
66 return false;
67 }
68};
69
70template <>
72{
74
75static bool getPoint(FragmentSearchBase&FSB,
78 RefPtr<FragmentID>&FragID)
79 {
80 LocalFromWorldPoint&findLocal = FSB.getLocalFromWorldPoint();
81
82// pair<Eagle::PhysicalSpace::point, RefPtr<FragmentID> > MultiblockFloatingIndex;
85
87 FragID = MultiblockFloatingIndex.frag_id;
89 }
90};
91
92
93// some structure for KD search, maybe
95{
97 std::vector<double> weight;
98};
99
100template <class PointType, class FloatIndexType>
102{
103
104
105 static bool getPoint( RefPtr<MemArray<1, PointType> >&VertexSet,
106 const PointType&P,
108 RefPtr<FragmentID>&FragID)
109 {
110 puts("KDTreeCloudSearch: wrong weight type requested!!\n");
111 return false;
112 }
113};
114
115template <class PointType>
117{
118enum { N = PointType::SIZE };
119
120 static bool getPoint( RefPtr<MemArray<1, PointType> >&VertexSet,
121 const PointType&P,
123 RefPtr<FragmentID>&FragID)
124 {
125 // Do the search here ...
126
129 // check for a cached tree on the vertexset. fill and cache tree if not found
130 if( !TreeInt )
131 {
132#ifdef VERBOSE
133 puts("GridEvaluator::creating new tree");
134#endif
136 TreeInt = new Eagle::KDInterface <N, index_t >( myTree ) ;
137
139 MultiIndex<1> max = Vertices.Size();
140 MultiIndex<1> mi(0);
141
142 do
143 {
144 myTree->insert( Vertices[mi], mi[0] );
145 }while ( mi.inc(max) );
146
147 VertexSet->addInterface( TreeInt ) ;
148 }
149 else // tree found -> assign it to local tree pointer
150 {
151#ifdef VERBOSE
152 puts("GridEvaluator::found cached tree");
153#endif
154 myTree = TreeInt->Tree ;
155 }
156
157 // data container for result query poitns
159
160 // somehow a radius for the query must be controlled, or also be adjustable paramter..
161 double r = 1.0;
162
163 // check for the certain poitn P
164 myTree->getEuclideanRange(P, r, verts );
165
166 // no candidates found in range
167 if( verts.size() < 0 )
168 return GridEvaluator::Nope;
169
170 // copy weights into VertexWeightstructure
171 // maybe better implement container filling directly in KDTree
172 // (but then it would be unsorted ... )
173 index_t i = 0;
174 InterpolationWeights.weight.resize( verts.size() );
175 InterpolationWeights.index.resize( verts.size() );
176
177 for ( std::multimap<double, index_t>::iterator it = verts.begin(); it != verts.end(); it++ )
178 {
179 InterpolationWeights.weight[i] = (*it).first;
180 InterpolationWeights.index[i] = (*it).second;
181 i++;
182 }
183
184 return true;
185 }
186};
187
188
189
190// mr: floatindex_t should become a template parameter, such it can be exchanged be a more general type?
191template <class PointType>
193{
194 enum { N = PointType::SIZE };
195
197
198
200 : FragmentSearchBase(theContext)
201 {}
202
203
207 {
208 // try to get data, if loaded.
210
211 // TODO: Check for Min/Max Interface stored at DC
212
213 RefPtr<MemBase> FragmentCoordinates = DC->create(); // possibly slow call!
215 {
216 assert( 0 && "bah!");
217 return GridEvaluator::Nope;
218 }
219
222 UniformCoordinates = FragmentCoordinates)
223 {
224 FloatIndex = UniformCoordinates->getIndex( P );
225/*
226 for(int i=0; i<N; i++)
227 {
228 if (FloatIndex[i]<0.0 || FloatIndex[i]>1.0)
229 return GridEvaluator::Nope;
230 }
231*/
232 return GridEvaluator::YesWithLocationAlreadyFound;
233 }
234
237 UniformCoordinates = FragmentCoordinates)
238 {
239 FloatIndex = UniformCoordinates->getIndex( P );
240
241 for(int i=0; i<N; i++)
242 {
243 if (FloatIndex[i]<0.0 || FloatIndex[i]>1.0)
244 return GridEvaluator::Nope;
245 }
246
247 return GridEvaluator::YesWithLocationAlreadyFound;
248 }
249
250 if( RefPtr<MemArray<1, PointType> > VertexSet = FragmentCoordinates ) // 1D explicit vertices
251 {
252// if( (*myContext.mySourceGrid)(FEM::cellID())
253// && (*(*myContext.mySourceGrid)(FEM::cellID() ))( myContext.mySourceGrid->findVertices() ) // have a relative representation cells as vertices
254// && ((*(*myContext.mySourceGrid)(FEM::cellID() ))( myContext.mySourceGrid->findVertices() ))->Positions() // have cell positions field
255// && ((*(*myContext.mySourceGrid)(FEM::cellID() ))( myContext.mySourceGrid->findVertices() ))->Positions()->getData( FoundFragID ) // have data
256// // support for fragmented data? same frags in cells as in verts
257// )
258// {
259// // build/check for search structures: vertices as cells -> converter? cell neighborhood? -> converter?
260// // max cell size, cell midpoints? KD query?
261// // maybe remove mixed type meshes and assume one element type per part (which is correct for abaqus) -> converter?
262// // weight would be similar to the point cloud case with indices and weights... but maybe not vlens but fixed sizes
263
264// RefPtr<MemArray<1, CellIndices_t> > cell_set = ((*(*myContext.mySourceGrid)(FEM::cellID() ))( myContext.mySourceGrid->findVertices() ))->Positions()->getData( FoundFragID );
265
266// // RefPtr<Eagle::KDTree<PointType::SIZE, index_t> > tree = FEM::getCellMidPointTree<PointType>( cell_set, VertexSet );
267// // double max_cell_size = 1.0; //FEM::maxCellSize( cell_set );
268
269// // std::list<index_t> candidates;
270// // tree->nearest_range(P, max_cell_size, candidates );
271
272// // std::list<index_t>::const_iterator it;
273// // for( it = candidates.begin(); it != candidates.end(); it++ )
274// // {
275// // do some check to find local coords
276// // }
277// }
278// // else ifs: check other special 1D explicit point3D types
279// else // point cloud
280// {
281 puts("GridEvaluator: Evaluating set of Vertices not yet fully implemented!!!\n");
282 fflush(stdout);
283
284 // mr: so what to come to the VertexWeighting type here?
286 {
287// return GridEvaluator::YesWithLocationAlreadyFound;
288 return GridEvaluator::Nope;
289 }
290
291
292 Verbose(0) << "###### GridEvaluator: Evaluating set of Vertices not yet implemented!!! ####";
293 return GridEvaluator::Nope;
294// }
295
296 }
297
298 /*TODO: Marcel, this is the place where you use the KD-tree lookup to find
299 all points in the VertexSet which are close to the provided point "P".
300 Currently the result is expected to be returned in a FloatIndex_t .
301 This will NOT be appropriate for an evaluation of a point set and
302 we will need to extend this API for a more general evaluation weight,
303 but need careful to not impact performance. In the most general case
304 the interpolation weight will be an index_t (integer) with a distance
305 weight (double), thus replacing FloatIndex_t with
306 struct { vector<index_t> index; vector<double> weight; };
307 but this semantic structure is not very efficient due to the
308 dynamic allocation of vector's. Need to think about a more efficient
309 scheme.
310 */
311/*
312 // mr: Couldnt this also be a line instead of a pointcloud?
313 if (RefPtr<MemArray<1, PointType> > VertexSet = FragmentCoordinates)
314 {
315 puts("GridEvaluator: Evaluating set of Vertices not yet fullly implemented!!!\n");
316 fflush(stdout);
317
318 // mr: to be adjusted to apropriate weight type
319 if (KDTreeCloudSearch<PointType, FloatIndex_t >::getPoint( VertexSet, P, FloatIndex, FoundFragID) )
320 {
321// return GridEvaluator::YesWithLocationAlreadyFound;
322 return GridEvaluator::Nope;
323 }
324
325
326 assert( 0 && "GridEvaluator: Evaluating set of Vertices not yet implemented!!!\n");
327 return GridEvaluator::Nope;
328 }
329*/
331 {
332
334 {
335 puts("yayy, curvigrid found!");
336 return GridEvaluator::YesWithLocationAlreadyFound;
337 }
338
339 puts("GridEvaluator: NO curvilinear 3D location found!\n");
340// fflush(stdout);
341// assert( 0 && "GridEvaluator: Evaluating curvilinear 3D not yet implemented!!!\n");
342 return GridEvaluator::Nope;
343 }
344
345
346 // curvilinear? do coarse bounding box check.
348
349 assert( 0 && "GridEvaluator: Provided Coordinate type not supported!!!\n");
350 return GridEvaluator::Nope;
351 }
352};
353
354
355
356
357
358template <class PositionsFieldType>
360 const Field&SourcePositions,
362{
363 typedef typename PositionsFieldType::value_type point_t;
364
365 // the dimensionality of the destination manifold, for instance 2 for a plane
366 enum { DestManifoldDims = PositionsFieldType::Dims };
367
368 // the dimensionality of the manifold where this plane is embedded, for instance
369 // 3 for a plane in a 3D space.
370 enum { EmbeddingManifoldDims = point_t::SIZE };
371
373
376
378
379 if (NumberOfEvalPositions.size()<1)
380 return;
381
384
387
388
389 /*
390 Iterate over all fragments of the source field
391 to collect all possible fragment ID's for a given
392 destination point.
393 */
395 {
397
398 const point_t &DestPoint;
400 int &SearchStatus;
402
404 const point_t &theDestPoint,
406 int &theSearchStatus,
411 , SearchStatus ( theSearchStatus )
413 {
414 SearchStatus = Nope;
415 }
416
418 {
419 if (!DC) return true;
420
422
423 SearchStatus = GotIt;
424
425 switch( GotIt )
426 {
427 case Possibly:
428 case Certainly:
429 case YesWithLocationAlreadyFound:
430
431 if (FragmentSearcher.FoundFragID)
432 {
433 SourceFragments.insert(FragmentSearcher.FoundFragID);
434 return false; // stop iteration over fragments for the destination point
435 }
436
437 SourceFragments.insert( f );
438 break;
439
440 default: ;
441 }
442
443 return true;
444 }
445 };
446
447// Iteration over all *destination* points
448// @TODO should be done in parallel!
449// @TODO need to optimize to move out of this loop as much as posisble
451 do
452 {
453 int &theSearchStatus = FragmentSearchStatus[ Index ];
455
456 // we want to know the fragment ID's at this point
458 DestinationPositions[ Index ],
459 FragmentArray[ Index ],
460
463
464 GetFragmentsForPoint.FragmentSearcher.SourceCoordinates = SourcePositions.self();
465
466 SourcePositions.iterate( GetFragmentsForPoint );
467
469
470// printf("handled index [%d,%d] stat %d\n", Index[0], Index[1], theSearchStatus);
471 }
472 while( Index.inc( NumberOfEvalPositions ) );
473
474
478}
479
480
481template <int SourceDims, class ValueType>
484 const Field&SourceField) const
485{
486typedef FixedArray<double, SourceDims> FloatIndex_t;
487
489
491
493 {
495 const Iterator<int>&It = SR;
496
498
499/*
500 A different strategy would be to first collect all destination points
501 that belong to the same source fragment and then evaluate all those
502 points from the same source fragment. This might be more performant
503 because the fragment needs to be retrieved only once instead of for
504 each point. It would also be more memory-efficient if only
505 one fragment can be kept in memory.
506 */
507
508 for(index_t i=0; i<It.count(); i++)
509 {
510 switch( FragmentSearchResult(It[ i ] ) )
511 {
512 case YesWithLocationAlreadyFound:
513 {
514 const FloatIndex_t &PointIndex = InterpolationWeightsPerDestPoint[ i ];
516
517 // TODO: reverse loop such that this can be outside, then do in parallel
518 if (SourceFragment.nFragments()==1)
519 {
520 RefPtr<FragmentID> fID = SourceFragment.getFirst();
521 // note: fID can be a NullPtr, this is valid, and indicates
522 // an unfragmented source field.
524 SourceMemArray = SourceField.getData( fID );
525 if (!SourceMemArray) return false;
526
528
529// Interpolate<SourceDims, ValueType, LinearIpol<ValueType>, ValueType>
532
535
536 }
537 assert( SourceFragment.nFragments() == 1);
538 break;
539 }
540
541 default:
542 // assert(0 && "Uncertain fragment not handled yet");
543 break;
544 ;
545 }
546 }
547
548 return true;
549 }
550
551 assert( 0 && "No point fragment location per point available, not good.");
552
554 {
555 }
556
557 // type: FixedArray<double, int CoordinateDims>
558// RefPtr<MemBase> PointLocation;
559
560 return false;
561}
562
563
564
568template <class ValueType>
570{
571 if (!PointLocation)
572 return false;
573
575 {
577 }
579 {
581 }
582
583 return false;
584}
585
586
587
588} // namespace Fiber
589
590
591#endif // __FIBER_BASEOPERATIONS_GRIDEVALUATOR_IMPL_HPP
_Tp max() const
_Expr< _ValFunClos< _ValArray, _Tp >, _Tp > apply(_Tp __func(_Tp)) const
An iterator with an optional DataCreator, which is just a class to intercept creation of data along a...
Definition CreativeIterator.hpp:34
A Field is a collection of CreativeArrayBase reference pointers which are accessed via FragmentID obj...
Definition Field.hpp:245
RefPtr< MemBase > getData(const RefPtr< FragmentID > &FID=nullptr) const
Get the data of a contigous field.
Definition Field.cpp:665
Definition FragmentIDContainer.hpp:40
Base class for iterators over the fragments of a field.
Definition FragmentID.hpp:249
index_t getIndex(index_t i, int c) const
Given a major and a minor index, compute the overall index in the dataset according to.
Definition HyperslabParameters.hpp:176
index_t count() const
Return the number of steps which can be traversed through this ElementIterator.
Definition HyperslabParameters.hpp:147
Use this class to compute a local cell index and fragment ID (if neccessary) of any coordinate field ...
Definition LocalFromWorldPoint.hpp:71
Definition TypedArray.hpp:544
Given a fragmented field of curvilinear coordinates, (3D array of coordinates), build a uniform Grid ...
Definition FAQ.dox:2
Definition GridEvaluator_impl.hpp:58
Definition FragmentSkeleton.hpp:155
Definition GridEvaluator_impl.hpp:28
RefPtr< FragmentID > FoundFragID
result
Definition GridEvaluator_impl.hpp:36
Definition GridEvaluator_impl.hpp:193
GridEvaluator::FragmentSearchResult Contains(const PointType &P, const MemCore::StrongPtr< Fiber::CreativeArrayBase > &DC, FloatIndex_t &FloatIndex)
Definition GridEvaluator_impl.hpp:204
Definition GridEvaluator.hpp:59
RefPtr< MemBase > PointLocation
Will be of type: FixedArray<double, int CoordinateDims>
Definition GridEvaluator.hpp:55
bool evalFloatIndices(std::vector< ValueType > &ResultData, const CreativeIterator< FixedArray< double, SourceDims > > &InterpolationWeightsPerDestPoint, const Field &SourceField) const
The type must match as stored in the SourceField.
Definition GridEvaluator_impl.hpp:482
RefPtr< MemBase > FragmentIDs
Fragment ID's per evaluation point.
Definition GridEvaluator.hpp:35
void findForSpecificDestinationPositions(const PositionsFieldType &DestinationPositions, const Field &SourcePositions, GridEvaluator::Context &theEvaluationContext)
Given a specific type for the positions in the destination coordinates, find the evaluation weights f...
Definition GridEvaluator_impl.hpp:359
RefPtr< MemBase > SearchStatus
An integer field of search result enums (FragmentSearchResult)
Definition GridEvaluator.hpp:50
bool evalType(std::vector< ValueType > &ResultData, const Field &SourceField) const
Evaluate a source field on a pre-allocated std::vector<> of destination types.
Definition GridEvaluator_impl.hpp:569
FragmentSearchResult
Status of first-pass point search in multiblock source Grids.
Definition GridEvaluator.hpp:42
Definition GridEvaluator_impl.hpp:102
Definition LocalFromWorldPoint.hpp:39
Definition GridEvaluator_impl.hpp:95