IntegralHeart.hpp

00001 #include "IntegralFace.hpp"
00002 
00003 #include <fish/lakeview/base/FieldInterpolator.hpp>
00004 
00005 #include <ocean/plankton/VCreator.hpp>
00006 #include <ocean/eagle/PhysicalSpace.hpp>
00007 #include <ocean/eagle/STA.hpp>
00008 #include <ocean/shrimp/VEnum.hpp>
00009 #include <ocean/shrimp/PhysicalSpace.hpp>
00010 
00011 #include <ocean/plankton/VTimer.hpp>
00012  
00013 #include <fish/fiber/vector/Interpolate.hpp>
00014 #include <fish/fiber/vector/LinearIpol.hpp>
00015 #include <bone/FishField.hpp>
00016 #include <bone/FishSlice.hpp>
00017 
00018 #include <ocean/shrimp/VObjectStatus.hpp>
00019 #include <fish/fiber/baseop/LocalFromWorldPoint.hpp>
00020 #include <fish/fiber/baseop/ExpandBBox.hpp>
00021 #include <fish/fiber/baseop/CopySkeletons.hpp>
00022 //#include <fish/fiber/baseop/AMRFieldFinder.hpp>
00023 
00024 #include <ode/dop853def.hpp>
00025 #include <baseop/TangentialVectors.hpp>
00026 
00027 #include <ocean/plankton/VTimer.hpp>
00028 
00029 #include <grid/types/LineSet.hpp>
00030 
00031 //#define VERBOSE
00032 
00033 #define TIMEIT
00034 
00035 
00036 namespace Fiber
00037 {
00038         // convinience function, to be placed somewhere else
00039         template<int N, typename T>
00040         RefPtr<MemArray<N, T> > getMemArrayViaMBase( RefPtr<Field>& myField, RefPtr<FragmentID> FragID = MemCore::NullPtr() )
00041         {
00042                 RefPtr<CreativeArrayBase> cBase = myField->getCreator(); 
00043                 if(!cBase)
00044                 {
00045                         puts("getMemArrayViaMBase() No cBase for FIELD found in field");fflush(stdout); 
00046                         return MemCore::NullPtr(); 
00047                 }       
00048 
00049                 RefPtr<MemBase> mBase = cBase->create(); 
00050                 if(!mBase)
00051                 {
00052                         puts("getMemArrayViaMBase() No mBase for FIELD found in field");fflush(stdout); 
00053                         return MemCore::NullPtr(); 
00054                 } 
00055 
00056                 RefPtr<MemArray<N, T> > ret = mBase; 
00057                 ret = myField->getCreator(FragID)->create(); 
00058                 if(!ret)
00059                 {
00060                                 mBase.speak("MBase Inforation ------>"); 
00061                                 puts("getMemArrayViaMBase() ERROR retrieving matching field."); 
00062 
00063                                 return MemCore::NullPtr();
00064                 } 
00065 
00066                 return ret;
00067         }
00068 
00069         template<typename T>
00070         RefPtr<MemCore::TypedChunk<T> > getChunkOfField( RefPtr<Field>& myField, RefPtr<FragmentID> FragID = MemCore::NullPtr() )
00071         {
00072                 RefPtr<MemArray<1, T> > DataArr = getMemArrayViaMBase<1, T>( myField ); 
00073                 assert(DataArr); 
00074 
00075                 return DataArr->myChunk();
00076         }
00077 }
00078 
00079 namespace FieldLines
00080 {
00081 typedef std::string FragmentID_t;
00082 
00083 // This class iterates over the input grid object and
00084 // maps Field with time value for time dependent fields.
00085 //template<typename FieldType, typename LineType>
00086 class GridIterator : public EvolutionIterator<Grid>
00087                    , public MemCore::ReferenceBase<GridIterator>
00088 {
00089         typedef std::map<double, RefPtr<Field> > MapFieldObject_t;      
00090         std::string theFieldName;
00091 public:
00092         MapFieldObject_t fieldObjectCollection;
00093         std::map<double, double> timeDifferenceMap;
00094         double t0, t1;
00095 
00096         // Constructor
00097         GridIterator(const string fieldName)
00098         : MemCore::ReferenceBase<GridIterator>(this)
00099         , theFieldName(fieldName)
00100         , t0(0.0)
00101         , t1(0.0)
00102         {}
00103         
00104         // Define the apply function here.
00105         bool apply(double t, GridID&id, Grid&g)
00106         {       
00107                 t1 = t;
00108                 if(t1 != t0)
00109                 {
00110                         double stepTime = t1-t0;
00111                         timeDifferenceMap[t1] = timeDifferenceMap[t0] = stepTime;
00112                 }
00113                 else 
00114                         timeDifferenceMap[t0] = 0.0;
00115                         
00116                 t0 = t;
00117                 
00118                 // Get the Field object with corresponding fieldName
00119                 RefPtr<Field> fieldObj = g(theFieldName); 
00120 
00121                 if(!fieldObj)
00122                 {
00123                         printf("GridIterator::apply() Null to field retrieved. Abording at t=%f!", t); 
00124                         return true;
00125                 }
00126 
00127 //              assert(fieldObj);
00128                 
00129                 fieldObjectCollection[t] = fieldObj; 
00130 
00131 #ifdef VERBOSE
00132                 printf("GridIterator::apply() inserted %s st %.18f --> map size:%d\n", theFieldName.c_str(), t, (int)fieldObjectCollection.size() ); 
00133                 fflush(stdout);
00134 #endif
00135                 return true;    
00136         }               
00137 };
00138 
00139 
00140 class FieldCollectionDataBase1D
00141 {
00142 protected:
00143         RefPtr<Grid> myGrid;
00144         RefPtr<MemArray<1, Eagle::point3> > Positions;
00145 
00146         unsigned size;
00147 
00148 //      RefPtr<MemArray<1, Eagle::point3> > LocalPositions;
00149 //      RefPtr<MemArray<1, std::string> >   FragmentNames;
00150 public:
00151         FieldCollectionDataBase1D( const RefPtr<Grid>& myGridP )
00152         : myGrid(myGridP)
00153         , size(0)
00154         {
00155                 RefPtr<Field> PosField = myGrid->getCartesianPositions(); 
00156 
00157                 if( !PosField ) 
00158                         puts("FieldCollectionDataBase1D::FieldCollectionDataBase1D() ERROR No Field in Grid"); 
00159                 else
00160                 {
00161                         Positions = getMemArrayViaMBase<1, Eagle::point3>( PosField ); 
00162 
00163                         if( Positions )
00164                                 size = Positions->Size()[0];
00165                 }
00166         }
00167 
00168 };
00169 
00170 template <class FieldType, typename LineType>
00171 struct FieldCollection : public MemCore::ReferenceBase<FieldCollection<FieldType,LineType> >
00172 {
00173         FieldCollection( const RefPtr<Grid>& myFieldP)
00174         : MemCore::ReferenceBase<FieldCollection<FieldType,LineType> >(this)
00175         {}
00176         
00177         unsigned getVertexSize()
00178         {
00179                 puts("FieldCollection::getVertexSize() not implemented, returning ZERO"); 
00180                 return 0;
00181         }
00182         
00183         unsigned getDataSize()
00184         {
00185                 puts("FieldCollection::getDataSize() not implemented, returning ZERO"); 
00186                 return 0;
00187         }
00188 };
00189 
00190 struct AtomicDataBase
00191 {
00192         RefPtr<LocalFromWorldPoint> LocalPointFinder;
00193         FieldSelector FieldSelection;
00194         RefPtr<BoundingBox> BB;
00195         RefPtr<GridIterator> GI;
00196         double step_size; 
00197         double scale;
00198         double nextTime;
00199 
00200         AtomicDataBase( const RefPtr<LocalFromWorldPoint>&LocalPointFinderP, 
00201                         const FieldSelector&FieldSelectionP, const RefPtr<BoundingBox>&BBP, const RefPtr<GridIterator>&GridIteratorP,
00202                         const double step_sizeP , const double scale_facP )
00203         : LocalPointFinder(LocalPointFinderP)
00204         , FieldSelection(FieldSelectionP)
00205         , BB(BBP)
00206         , GI(GridIteratorP)
00207         , step_size(step_sizeP)
00208         , scale(scale_facP)
00209         {}
00210 
00211         ~AtomicDataBase()
00212         {
00213 #ifdef VERBOSE          
00214                 puts("~AtomicDataBase()");fflush(stdout);
00215                 LocalPointFinder.speak("--------------------------------------------------------------~AtomicDataBase() LocalPointFinder"); fflush(stdout);
00216                 BB.speak("--------------------------------------------------------------~AtomicDataBase() BB"); fflush(stdout);
00217                 GI.speak("--------------------------------------------------------------~AtomicDataBase() GI"); fflush(stdout);
00218 #endif
00219         }
00220 };
00221 
00222 // type trait for atomic integration requires Euler and Dop853 functions
00223 // the interpolation type is defined at compile time via the last template paramter.
00224 template<typename FieldType, typename LineType, int InterpolType>
00225 class AtomicIntegrator
00226 {
00227         typedef MemArray<3, FieldType> ToIntegrateArray_t; 
00228 public:
00229         
00230         virtual ~AtomicIntegrator()
00231         {
00232 #ifdef VERBOSE  
00233                 puts("~AtomicIntegrator() base");fflush(stdout);
00234 #endif
00235         }
00236 
00237         unsigned long nextStartIndexPerCoarseCall( unsigned long start, unsigned long size )
00238         {
00239                 puts("FieldLines::AtomicIntegrator<FieldType>.nextStartIndexPerCoarseCall() ERROR: Unsupported type Field/Line Type doing nothing!");fflush(stdout); 
00240                 return 0;
00241         }
00242 
00243         // does the local data extraction from using the positions field of the front to comput local coords, fragmentIds
00244         // and interpolated field data.
00245         bool extractLocalData( FieldCollection<FieldType, LineType>& CurrentFront,
00246                                const unsigned index, const double time  )
00247         {
00248                 puts("FieldLines::AtomicIntegrator<FieldType>.extractLocalData() ERROR: Unsupported type Field/Line Type doing nothing!");fflush(stdout); 
00249                 return true;
00250         }
00251 
00254         bool doEuler( FieldCollection<FieldType, LineType>& lastFront,
00255                       unsigned index, 
00256                       FieldCollection<FieldType, LineType>& newFront,
00257                       double time,
00258                       unsigned integration_width)
00259         {
00260                 puts("FieldLines::AtomicIntegrator<FieldType>.doEuler (Fronts) () ERROR: Unsupported type Field/Line Type doing nothing!");fflush(stdout); 
00261                 return false;   
00262         }
00263 
00264         bool doDop853( FieldCollection<FieldType, LineType>& lastFront,
00265                        unsigned index, 
00266                        FieldCollection<FieldType, LineType>& newFront,
00267                        double time,
00268                        unsigned integration_width )
00269         {
00270                 puts("FieldLines::AtomicIntegrator<FieldType>.doDop853() ERROR: Unsupported type FieldType doing nothing!");fflush(stdout); 
00271                 return false;   
00272         }
00273 
00274         bool initDop853( const int number_of_lines )
00275         {
00276                 puts("FieldLines::AtomicIntegrator<FieldType>.initDop853() ERROR: Unsupported type FieldType doing nothing!");fflush(stdout); 
00277                 return false;
00278         }       
00279         
00280         double getNextTime()
00281         {
00282                 return 0.0;
00283         }
00284 };
00285 
00286         
00287 template <class FieldType, typename LineType>
00288 class GridOperator
00289 {
00290         RefPtr<Bundle>& myBundle;
00291         
00292 public:
00293         GridOperator( RefPtr<Bundle> myBundleP = MemCore::NullPtr() )
00294         :myBundle( myBundleP )
00295         {}
00296 
00297         RefPtr<Grid> getPreparedGrid( const RefPtr<Grid>& EmitterGrid, unsigned long steps_estimate = 500 )
00298         {
00299                 puts("GridOperator::getpreparedGrid() WARNING: Using default base implementation, returning new Grid"); 
00300                 return myBundle->newGrid();
00301         }
00302 
00303         RefPtr<Grid> advanceGrid(const RefPtr<Grid>& gridP )
00304         {
00305                 puts("GridOperator::advanceGrid() WARNING: Using default implementation, returning new Grid"); 
00306                 return myBundle->newGrid();
00307         }
00308 
00309         RefPtr<Grid> refineGrid(const RefPtr<Grid>& gridP )
00310         {
00311                 puts("GridOperator::advanceGrid() WARNING: Using default implementation, returning new Grid"); 
00312                 return gridP;
00313         }
00314 
00315         void storeGrid( const std::string& grid_name, const RefPtr<Grid>& gridP, double time )
00316         {
00317                 puts("GridOperator::storeGrid() WARNING: Using default implementation, doing Nothing"); 
00318         }
00319 
00320         void finalizeGrid( const std::string& grid_name, const RefPtr<Grid>& gridP, double slice )
00321         {
00322                 puts("GridOperator::finalizeGrid() WARNING: Using default implementation, doing Nothing"); 
00323         }
00324         
00325         unsigned getIntegrationSize(  const RefPtr<Grid>& gridP )
00326         {
00327                 puts("GridOperator::getIntegrationSize() WARNING: Using default implementation, returning ZERO"); 
00328                 return 0;
00329         }
00330 
00331         RefPtr<Bundle> getBundle()
00332         {
00333                 return myBundle;
00334         }
00335 };
00336 
00337 
00338 
00339 template <class FieldType, typename LineType, int InterpolType>
00340 class  CoarseIntegrator
00341 {
00342 typedef MemArray<3, FieldType> ToIntegrateArray_t; 
00343 
00344         AtomicIntegrator<FieldType, LineType, InterpolType> AI;
00345 
00346         bool dop;
00347         size_t nPoints;
00348         double line_length;
00349         double start_time;
00350         double time;
00351         int number_lines;
00352 
00353 public:
00354         CoarseIntegrator( const FieldSelector&FieldSelectionP, const RefPtr<LocalFromWorldPoint>&LocalPointFinderP,
00355                        const RefPtr<BoundingBox>&BBP, const RefPtr<GridIterator>&GridIteratorP, 
00356                        const double step_sizeP, const bool dopP, const size_t nPointsP,
00357                        const double line_lengthP, const double start_timeP, const double scale_facP )
00358         : AI( LocalPointFinderP, FieldSelectionP, BBP, GridIteratorP, step_sizeP, scale_facP )
00359         , dop(dopP)
00360         , nPoints(nPointsP)
00361         , line_length(line_lengthP)
00362         , start_time(start_timeP)
00363         , time(start_timeP)
00364         {}
00365 
00366         virtual ~CoarseIntegrator()
00367         {
00368 #ifdef VERBOSE  
00369                 puts("~FronAdvancer()");fflush(stdout);
00370 #endif
00371         }
00372 
00373 //      LineIntegrator::LineIntegrator(){}
00374 
00375 
00376         size_t getNPoints() { return nPoints;}
00377 
00378         bool advance( RefPtr<Grid>&CurrentGrid, RefPtr<Grid>&NewGrid,
00379                       double&time, unsigned long&start, unsigned long&size)
00380         {
00381 //              puts("CoarseIntegrator::advance() enter" );fflush(stdout);
00382                 FieldCollection<FieldType, LineType> CurrentFields( CurrentGrid ); 
00383 //              puts("CoarseIntegrator::advance() 1" );fflush(stdout);
00384                 FieldCollection<FieldType, LineType> NewFields( NewGrid ); 
00385 //              puts("CoarseIntegrator::advance() 2" );fflush(stdout); 
00386                 
00387                 unsigned end_counter = 0; 
00388                 
00389                 if(dop)
00390                         AI.initDop853( size ); 
00391                         
00392                 //printf("CoarseIntegrator::Time at the start of advnace = %.18f\n", time); 
00393                 //printf("About to get into Euler...start = %d, size = %d\n", int(start), int(size) );
00394 
00395                 // add a omp pragma here maybe
00396                 for(unsigned p = start; p < start + size; p++)
00397                 {
00398 #ifdef VERBOSE
00399                         printf("\n WORKING ON LINE %d out of %d\n", p, Lines.size() ); 
00400                         VActionNotifier::ProgressInfo("Working on line " + String(int(p)) + " out of " + String(int(size)) ); 
00401                         printf("Working on point %d, about to get into Euler...start = %d, size = %d\n", p, int(start), int(size)); 
00402 #endif
00403                         
00404                         bool test; 
00405                                 
00406                         // could this condition also be pulled out to one condition in the update, like the integration type?
00407                         if( !dop )
00408                                 test = AI.doEuler( CurrentFields, p, NewFields, time, size ); 
00409                         else
00410                                 //      test = AI.doDop853( CurrentFields, p, NewFields, time, size ); 
00411 
00412 
00413                         if( test == false ) 
00414                                 end_counter++;
00415                         else
00416                                 nPoints++;
00417                 } 
00418                 // change the time value here ...MAY BE!!!
00419                 time = AI.getNextTime();
00420                 
00421 #ifdef VERBOSE  
00422                 printf("CoarseIntegrator::Time at the end of advance = %.18f\n", time);
00423 #endif          
00424                 // change the start index in the needs of the Atomic Integrator
00425                 start = AI.nextStartIndexPerCoarseCall( start, size );
00426 
00427                 VActionNotifier::ProgressInfo("Integration of " + String(int(size)) + " lines done."  );
00428 
00429 //      printf("end_counter %d, Lines.size() %d\n", end_counter, Lines.size() ); 
00430 
00431 //      bool check =  ( end_counter == size ) ? true : false; 
00432 
00433 //      printf("CoarseIntegrator::advance() exit, check: %d\n", check);fflush(stdout); 
00434 
00435                 return true;
00436         }
00437 
00438         // should be implementable by filling the data arrays up to the size of the vertices
00439         bool extractLocalGridData( RefPtr<Grid > & CurrentGrid, double time )
00440         {
00441 #ifdef VERBOSE  
00442                 puts("CoarseIntegrator::extractLocalGridData() enter");fflush(stdout);
00443 #endif
00444                 FieldCollection<FieldType, LineType>CurrentFields( CurrentGrid ); 
00445 
00446 #ifdef VERBOSE  
00447                 puts("CoarseIntegrator::extractLocalGridData() 1");fflush(stdout);
00448 #endif
00449 
00450                 bool check = true; 
00451 
00452                 for( unsigned p = CurrentFields.getDataSize(); p < CurrentFields.getVertexSize(); p++ )
00453                 {
00454                         check = check && AI.extractLocalData( CurrentFields, p, time );
00455                 }
00456  
00457 #ifdef VERBOSE  
00458                 printf("CoarseIntegrator::extractLocalGridData() exit, check: %d\n", check);fflush(stdout);
00459 #endif
00460 
00461                 return check;
00462         }
00463 
00464 };
00465 
00466 
00467 // type trait to convert the integration line type to a string used for naming in the fiber bundle
00468 // must be provided in the specializations
00469 template<typename FieldType, typename LineType>
00470 struct LineTypeString
00471 {
00472         string name() { return "Unknown"; }
00473 };
00474 
00475 
00476 template <typename FieldType, typename LineType>
00477 class   IntegralHeart : public IntegralFace
00478 {
00479 public:
00480         typedef MemArray<3, double>                    ScalarArray_t;
00481         typedef MemArray<3, Eagle::point3>             CoordsArray_t;
00482         typedef MemArray<1, Eagle::point3>             CoordsArray1D_t;
00483         typedef MemArray<1, Eagle::tvector3>           VecsArray1D_t;
00484         typedef MemArray<1, std::string>               FragmentIDs_t;
00485         typedef MemArray<1, BoundingBox>               FragmentBounds_t;
00486         
00487         struct FieldState : State
00488         {
00489                 WeakPtr<GridIterator> flowIterator;
00490                 double time;
00491                 
00492                 FieldState()
00493                 : time(0.0)
00494                 {}
00495         };
00496         
00497         override RefPtr<State> newState() const
00498         {
00499                 return new FieldState();
00500         }
00501 
00502 
00503         IntegralHeart(const string&name, int p, const RefPtr<VCreationPreferences>&VP)
00504         : VObject(name, p, VP)
00505         , Fish<VObject>(this)
00506         , Fish<Field>("inputfield")
00507         , IntegralFace(name, p, VP)
00508         {}
00509 
00510         typedef typename FieldType::Chart_t Chart_t;
00511         typedef typename Coordinates<Chart_t>::point point;     
00512         typedef typename Coordinates<Chart_t>::vector tvector4; 
00513         
00514         override bool update(VRequest&R, double precision);
00515 
00516                 
00522         struct  AMRLevelExtractor : public LevelIterator
00523         {
00524                 double          currenttime;
00525                 std::string     AMRfieldname;
00526                 
00527                 // store available refinement levels of Field in map (at current time)
00528 //              std::map<unsigned, MemCore::RefPtr<Fiber::Field> > collect;
00529                 std::map<double, std::map<unsigned, RefPtr<Fiber::Field> > > collect;
00530 
00531                 AMRLevelExtractor(std::string& fieldnameP, double currenttimeP, std::map<double, std::map<unsigned, RefPtr<Fiber::Field> > >& collectP)
00532                 : currenttime(currenttimeP)
00533                 , AMRfieldname(fieldnameP)
00534                 , collect(collectP)  
00535                 {}
00536 
00537                 // collect time, levelnr and field in map
00538                 override bool apply(const RefPtr<Fiber::Representation>&CartesianLevelRep,
00539                                     double time, int Level,
00540                                     const RefPtr<Fiber::Grid>&GridWithCoarsetRefinementLevel, 
00541                                     const RefPtr<ValuePool>&Context)
00542                 {
00543                 RefPtr<Field> Coords     = CartesianLevelRep->Positions(); 
00544                 RefPtr<Field> DataField  = (*CartesianLevelRep)(AMRfieldname); 
00545 
00546                         collect.insert( pair<unsigned, RefPtr<Fiber::Field> >( Level, DataField ) );
00547                         
00548                         return true;
00549                 }
00550 
00551         }; 
00552         
00553 
00554         class AMRFieldFinder
00555         {
00556                 Fiber::BundlePtr bundle;
00557                 std::map<double, std::map<unsigned, RefPtr<Fiber::Field> > > AMRField;
00558                 std::string fieldname;
00559                 
00560                 // iterate over grids in time
00561                 struct AMRGridEvolution : EvolutionIterator<Fiber::Grid>
00562                 {
00563                         std::string fieldname;
00564 //                      std::map<double, std::map<unsigned, RefPtr<Fiber::Field> > > myAMRField;
00565 
00566                         AMRGridEvolution( std::string& fieldnameP) //, std::map<double, std::map<unsigned, RefPtr<Fiber::Field> > >&myAMRFieldP )
00567                         : fieldname(fieldnameP)
00568 //                      , myAMRField(myAMRFieldP)
00569                                 {};
00570                         
00571                         // first collect level data in map by using the level iterator. then store available field ptr and level nr 
00572                         // in time-map of Field finder
00573                         override bool apply (double t, GridID&id, Grid&g)
00574                                 {
00575                                         std::map<unsigned, MemCore::RefPtr<Fiber::Field> > collect; 
00576 
00577                                         AMRLevelExtractor refIt(fieldname, t, collect); 
00578 
00579                                                 g.iterate( refIt ); 
00580 
00581                                                 AMRField.insert( pair<double, RefPtr<Field> >(t, collect) );
00582                                         
00583                                         return true;
00584                                 }
00585                 };
00586                 
00587                 
00588                 
00589         public:
00590         
00591                 AMRFieldFinder(const string& fieldnameP)
00592                 : fieldname(fieldnameP)
00593                         {}
00594                 
00595                 // collect all time and field data into a the map structure
00596                 void precompute()
00597                         {
00598                         }
00599                 
00600                 /* also provide a function to find field on demand without pre-iterations
00601                    pre evaluation might be not too efficient in huge time dependent data sets
00602                 RefPtr<Fiber::Field> getFinestField(double time)
00603                 {
00604                 return MemCore::NullPtr();
00605                 }
00606                 */
00607                 
00608         };
00609         
00610         static  string createChildname(const string&inputfield)
00611         {
00612                 LineTypeString<FieldType,LineType> tmp;
00613                 return tmp.name() +"(" + inputfield + ")";
00614         }
00615 
00616         // print progress of iteration as status and stdout
00617         void printProgress( unsigned long&old_nPoints, const unsigned long nPoints, const unsigned long nPointsEst, VRequest&Context)
00618         {
00619                 if( old_nPoints + 100 < nPoints )
00620                 {
00621                         old_nPoints = nPoints;
00622                  char buf[64]; 
00623                         float percent = (double)nPoints / nPointsEst * 100; 
00624                         sprintf(buf, "Integrating %.1f %% #%d", percent, (int)nPoints); 
00625                         VActionNotifier::ProgressInfo (string(buf)); 
00626                         printf("IntegralHeart::printProgress(): %s\n", buf);fflush(stdout);
00627                         setStatusInfo( Context, buf); 
00628                  } 
00629                 
00630         }
00631 
00632         
00633         // Function to simplify main iteration loop in update.
00634         template<class IntegratorType>
00635         int doMainLoop(IntegratorType&IntT, 
00636                        RefPtr<Grid>& StartGrid,
00637                        GridOperator<FieldType, LineType>& GridOperator,
00638                        const string& grid_name, 
00639                        FieldSelector& FieldSelection,
00640                        double time, 
00641                        unsigned long max_steps, int nPointsEst, size_t nPoints, VRequest&Context)
00642         {
00643 //              puts("IntegralHeart::doMainLoop() enter");fflush(stdout);
00644                 
00645         unsigned long step_counter = 0; 
00646         unsigned long integration_width = GridOperator.getIntegrationSize( StartGrid ); 
00647         unsigned long start_count = 0;
00648         bool hasfinished = false; 
00649         unsigned long old_nPoints = 0; 
00650 
00651         RefPtr<Grid> CurrentGrid = StartGrid; 
00652         RefPtr<Grid> NewGrid;
00653 
00654                 while( hasfinished == false && step_counter < max_steps )
00655                 {
00656                         printProgress(old_nPoints, nPoints, nPointsEst, Context ); 
00657 #ifdef VERBOSE  
00658                         puts("fill local data and store grid  in case of being the initial front");
00659 #endif
00660                         if( step_counter == 0)
00661                         {                 
00662                                 printf("Emitter Grid:: Time at which emitter grid is stored %.18f\n", time);                    
00663                                 hasfinished = hasfinished || 
00664                                               !IntT.extractLocalGridData( CurrentGrid, time ); 
00665                                 GridOperator.storeGrid( grid_name, CurrentGrid, time );
00666                         } 
00667 #ifdef VERBOSE  
00668                         puts("maybe create a copy for the new grid");
00669 #endif
00670                         NewGrid = GridOperator.advanceGrid( CurrentGrid ); 
00671 #ifdef VERBOSE  
00672                         puts("do one integration step of the whole front"); 
00673 #endif
00674                         hasfinished = hasfinished || 
00675                                       !IntT.advance( CurrentGrid, NewGrid, time, start_count, integration_width ); 
00676 #ifdef VERBOSE                          
00677                         puts("refine the grid");
00678 #endif
00679                         NewGrid = GridOperator.refineGrid( NewGrid ); 
00680 
00681 #ifdef VERBOSE
00682                         puts("fill local data in front"); 
00683 #endif                  
00684                         hasfinished = hasfinished || 
00685                                       !IntT.extractLocalGridData( NewGrid, time ); 
00686 #ifdef VERBOSE                  
00687                         puts("store grid");
00688 #endif
00689                         GridOperator.storeGrid( grid_name, NewGrid, time ); 
00690 
00691                         CurrentGrid = NewGrid; 
00692 
00693                         step_counter++; 
00694 #ifdef VERBOSE
00695                         printf("hasfinished: %d, step_counter: %ld, max_steps: %ld \n\n", hasfinished, step_counter,  max_steps); fflush(stdout);
00696 #endif
00697                 } 
00698 
00699 #ifdef VERBOSE
00700                 puts("do a final operation on the grid");
00701 #endif
00702                 GridOperator.finalizeGrid( grid_name, NewGrid, time ); 
00703 
00704 #ifdef VERBOSE
00705                 puts("exit main loop");
00706 #endif
00707                 return IntT.getNPoints(); 
00708         }
00709 
00710 };
00711 
00712 template<typename FieldType, typename LineType>
00713 bool IntegralHeart<FieldType,LineType>::update(VRequest&Context, double precision)
00714 {
00715 double sec = 0.0;
00716 VTimer Tim_update; 
00717 
00718         printf("IntegralLines::update()  -->%s<--: enter\n", Name().c_str() );fflush(stdout); 
00719  
00720 // 1. Get input field information 
00721 // 
00722         puts("IntegralLines::update() 1. Get input field information");fflush(stdout); 
00723 FieldSelector   FieldSelection = getFieldSelector(Context); 
00724 RefPtr<Field>   InputToIntegrateField = FieldSelection.getField(); 
00725 
00726         if(!FieldSelection.theSourceBundle) { return errorMsg(Context, "No bundle found in integrate field");    }
00727         if(!InputToIntegrateField)          { return errorMsg(Context, "No integratable field in input bundle"); }
00728 
00729 double time      = FieldSelection.getTime(); 
00730 string fieldName = FieldSelection.getFieldName();
00731 
00732 // Get the State Variable
00733 RefPtr<FieldState> state = newState();
00734 
00735 
00736 // 2. Get emitter info
00737 // 
00738 GridSelector EmitterGS; 
00739 FieldSelector EmitterFS; 
00740         StartGrid << Context >> EmitterGS; 
00741         StartField << Context >> EmitterFS; 
00742 
00743         EmitterFieldData EFD( EmitterGS, EmitterFS ); 
00744 
00745         RefPtr<Field> EmitterCoordinates = getEmitterField( Context, EFD );
00746         
00747 //
00748 // 3. Construct name for the output grid (the integral lines) and check if it already exists. And if so, if not the 
00749 //    input is newer, such that it would require re-creation.
00750 // 
00751 string grid_name = FieldSelection.Gridname() + "_" + Name(); 
00752 
00753 GridSelector GS; 
00754         myIntegralLines << Context >> GS; 
00755 
00756 UpdateCheckData UCD( EmitterCoordinates, FieldSelection, GS, InputToIntegrateField, time, grid_name); 
00757 
00758         if( !needUpdate( Context, UCD) )
00759         {
00760                 puts("IntegralLines::update() 3.5 no update needed");
00761                 return true;
00762         }
00763 // 
00764 // 4. Make sure we have some seed points 
00765 // 
00766         puts("IntegralLines::update() 4. Make sure we have seeding points");fflush(stdout); 
00767 
00768 RefPtr<BoundingBox> ToIntegratefieldBBox = getBoundingBox( *FieldSelection.getGrid() ); 
00769         if (!ToIntegratefieldBBox) return setStatusError(Context, "No bounding box available.\n"); 
00770 
00771 int     NumberOfInternalSeedPoints = 23; 
00772         InternalEmissionSeedPoints << Context >> NumberOfInternalSeedPoints;
00773         AutoEmitterData AED( EmitterCoordinates, ToIntegratefieldBBox,  NumberOfInternalSeedPoints); 
00774         setDefaultEmissionPoints(Context, AED);
00775 
00776 
00777         //
00778         // Note: the emitter coordinate field could also be fragmented.
00779         // In this case, the getData() call will return a NullPtr().
00780         // In general, we need to rather iterate here over all field
00781         // fragments of the emitter coordinates.
00782         //
00783 RefPtr<CoordsArray1D_t > EmitterVerts = EmitterCoordinates->getData();
00784         if (!EmitterVerts)
00785                 return setStatusError( Context, "Emitter points not in a supported format."); 
00786 
00787         MultiArray<1, Eagle::point3>&EmitterCrds = *EmitterVerts; 
00788 
00789 //
00790 RefPtr<Field> EmitterVecField = EmitterFS.getField(); 
00791 RefPtr<VecsArray1D_t > EmitterVecs;
00792  
00793         if(EmitterVecField)
00794                 EmitterVecs = EmitterVecField->getData(); 
00795 
00796 // 
00797 // 5. Prepare data structs for integration 
00798 // 
00799 // 
00800         puts("IntegralLines::update() 5. Prepare data");fflush(stdout); 
00801 BundlePtr   bundlePtr = FieldSelection.BundleSource(); // Was named as outBPtr. Modified by Bidur
00802 Info<Slice> currentSlice = FieldSelection.FieldSource; 
00803 
00804         assert( FieldSelection.getGrid() );
00805 
00806         setStatusInfo(Context, "Setting up index search"); 
00807 double  UnimapperScale = 1.0; 
00808         UniMapperScalator << Context >> UnimapperScale;
00809 
00810 RefPtr<LocalFromWorldPoint>
00811         LocalPointFinder = new LocalFromWorldPoint(*currentSlice.getSlice(), FieldSelection.getGrid(),
00812                                                    FieldSelection.getGridname(),
00813                                                    FieldSelection.getGrid()->getCartesianPositions(), 
00814                                                    UnimapperScale );
00815 
00816 double  step_size;
00817 double  min_line_length = 0.0; 
00818 double  max_steps = 0.0; 
00819 double  scale_fac = 1.0;
00820 
00821         MinLineLength  << Context >> min_line_length; 
00822         MaxSteps       << Context >> max_steps;
00823         StepSize       << Context >> step_size; 
00824         ScaleFac       << Context >> scale_fac;
00825 
00826         step_size *= ToIntegratefieldBBox->radius();
00827         step_size /= 33.0; 
00828 
00829         if( max_steps < 2)         max_steps = 2; 
00830         if( min_line_length < 0.0) min_line_length = 0.0; 
00831 
00832 unsigned long max_steps_l = (unsigned long)std::floor(max_steps);
00833 
00834 Enum AddData, AddMagnitude; 
00835         IncludeData << Context >> AddData; 
00836         IncludeMagnitude << Context >> AddMagnitude; 
00837 
00838 unsigned nEmPoints = EmitterCrds.Size()[0]; 
00839 unsigned nPointsEst = nEmPoints * (int)max_steps; 
00840 
00841         printf("IntegralHeart::update() nEmPoints: %d, nPointsEst: %d\n",nEmPoints,  nPointsEst);
00842 
00843 typedef CoarseIntegrator<FieldType, LineType, FieldInterpolatorBase::LINEAR   > AdvancerLinear;  
00844 typedef CoarseIntegrator<FieldType, LineType, FieldInterpolatorBase::CUBIC    > AdvancerCubic; 
00845 typedef CoarseIntegrator<FieldType, LineType, FieldInterpolatorBase::ANALYTIC > AdvancerAnalytic; 
00846 
00847 size_t nPoints = 0; 
00848 
00849         GridOperator<FieldType, LineType> integrationGridOperator( FieldSelection.getBundle() ); 
00850 
00851 // TODO make sure emitter grid is there. overrides current version of emitter-grid-point-creation! 
00852 RefPtr<Grid> IntegrationGeometry = integrationGridOperator.getPreparedGrid( EmitterGS(time, EmitterGS.getBundle() ), (unsigned long) max_steps );
00853 
00854 // 
00855 // 6. Do the actual integration
00856 // 
00857         puts("IntegralLines::update() 6. Do the actual Integration");fflush(stdout);    
00858         setStatusInfo(Context, "Integrating ...");
00859 
00860 // Define new GridIterator and assign it the Iterator from State variable 
00861 RefPtr<GridIterator> flowIterator = state->flowIterator;
00862 
00863 int totalSteps;
00864 double gridTime; 
00865 
00866         // Declare and initialize Grid Iterator 
00867         flowIterator = new GridIterator( fieldName );
00868         gridTime = time;
00869 
00870         // This iterates over Grid objects of input Bundle.
00871         // FlowIterator then maps the time of Grid with the Field(vector field) object of Grid. 
00872         totalSteps = bundlePtr->iterateForward(gridTime, FieldSelection.Gridname(), *flowIterator, false); 
00873         printf("\nTotal time slices = %d and Time value = %f %f\n", totalSteps, time, gridTime); 
00874 
00875 
00876 Enum Interpol; 
00877         Ipol << Context >> Interpol; 
00878 Enum Dop;
00879         UseDop853 << Context >> Dop; 
00880 
00881         puts("2");
00882 
00883         ________________________________________________getTime(sec , Tim_update ); 
00884 
00885         if( Interpol("linear") ) 
00886         {
00887 
00888         AdvancerLinear  MyAdvancerLinear( FieldSelection, LocalPointFinder, ToIntegratefieldBBox, flowIterator,
00889                                           step_size, Dop("yes"), nPoints, min_line_length, time, scale_fac ); 
00890 
00891                 nPoints = doMainLoop<AdvancerLinear>( MyAdvancerLinear, IntegrationGeometry, integrationGridOperator, grid_name,
00892                                                       FieldSelection, time, max_steps_l, nPointsEst, nPoints, Context); 
00893         
00894                 nPoints = MyAdvancerLinear.getNPoints(); 
00895         } 
00896         else if( Interpol("cubic") )
00897         {
00898         AdvancerCubic  MyAdvancerCubic( FieldSelection, LocalPointFinder, ToIntegratefieldBBox, flowIterator,
00899                                           step_size, Dop("yes"), nPoints, min_line_length, time, scale_fac ); 
00900 
00901                 nPoints = doMainLoop<AdvancerCubic>( MyAdvancerCubic, IntegrationGeometry, integrationGridOperator, grid_name, 
00902                                                      FieldSelection, time, max_steps_l, nPointsEst, nPoints, Context); 
00903                 nPoints = MyAdvancerCubic.getNPoints(); 
00904         } 
00905         else
00906         {
00907         AdvancerAnalytic  MyAdvancerAnalytic( FieldSelection, LocalPointFinder, ToIntegratefieldBBox, flowIterator,
00908                                               step_size, Dop("yes"), nPoints, min_line_length, time, scale_fac ); 
00909 
00910                 nPoints = doMainLoop<AdvancerAnalytic>( MyAdvancerAnalytic, IntegrationGeometry, integrationGridOperator, grid_name, 
00911                                                         FieldSelection, time, max_steps_l, nPointsEst, nPoints, Context ); 
00912                 nPoints = MyAdvancerAnalytic.getNPoints(); 
00913         } 
00914 
00915 #ifdef VERBOSE  
00916         puts("3");fflush(stdout);
00917 #endif
00918 
00919         double overall_int_time = Tim_update.secs() - sec; 
00920 
00921 //      ________________________________________________printTime("IntegralLines::update(): Compute Time:", Tim_update.secs() - sec); 
00922 
00923         printf("IntegralLines::update(): ComputeTime: %f\n",overall_int_time  ); 
00924         printf("IntegralLines::update(): Time per integration %d points: %f\n", (int)nPointsEst, overall_int_time / nPointsEst ); 
00925 
00926         CurviCellsPerUniCell << Context << LocalPointFinder->MaxListSize; 
00927 
00928 #ifdef VERBOSE  
00929         puts("4");fflush(stdout);
00930 #endif
00931 
00932         {
00933         GridSelector GS( grid_name, integrationGridOperator.getBundle() ); 
00934                 myIntegralLines << Context << GS; 
00935 
00936                 printf("time: %f\n", time);
00937 
00938 /*
00939         Grid& myGrid = *GS(time); 
00940 
00941         puts("5");fflush(stdout);
00942 
00943         RefPtr<Field> myField = myGrid.CartesianPositions(); 
00944 
00945         if(!myField)
00946         {
00947                 puts("No FIELD!"); return true;
00948         }
00949 
00950         RefPtr<MemArray<1, Eagle::point3> > myArr = getMemArrayViaMBase<1, Eagle::point3>( myField ); 
00951         if(!myArr)
00952         {
00953                 puts("No ARR!"); return true;
00954         }
00955 
00956         MultiArray<1, Eagle::point3>&multArr = *myArr; 
00957 
00958         
00959 
00960         MultiIndex<1> mx = multArr.Size(); 
00961         printf("MultiArray: Size(): %ld\n", mx[0] ); 
00962         
00963         MultiIndex<1> mi; 
00964 
00965         unsigned long hyperlen = multArr.getLength(); 
00966         printf("MultiArray: hyper size: %ld\n", hyperlen ); 
00967 
00968         unsigned long hypercount = multArr.maxcount(); 
00969         printf("MultiArray: hyper size: %ld\n", hyperlen ); 
00970         printf("MultiArray: hyper count: %ld\n", hypercount ); 
00971 
00972         printf("MultiArray: multidim size: %ld\n", mx[0]); 
00973 
00974         for(unsigned i = 0; i < mx[0]; i++)
00975         {
00976                 mi[0] = i;
00977                 std::cout << multArr[mi] << endl;
00978         }
00979         printf("ArraySize: %ld\n", mx[0]); 
00980 
00981         RefPtr<Chunk<Eagle::point3> >PositionsChunk = getChunkOfField<Eagle::point3>( myField ); 
00982         if(!PositionsChunk)
00983         {
00984                 puts("No CHUNK!"); return true;
00985         }
00986 
00987                 for(unsigned i = 0; i < PositionsChunk->size(); i++)
00988                         std::cout << (*PositionsChunk)[i] << endl;
00989 */
00990         }
00991 
00992         infoMsg(Context, "Done, output at: " + grid_name);fflush(stdout);
00993 
00994 //      printf("ComputMultipleStreamLines::update() Written into Bundle, setPersitentData and touched Spacetimeslot()\n");
00995         VActionNotifier::ProgressInfo (string("Integration computation complete"));
00996 
00997 
00998         return true;
00999 }
01000 
01001 }