AnalyticCreator.hpp

00001 #ifndef __ANALYTIC_CREATOR_HPP
00002 #define __ANALYTIC_CREATOR_HPP
00003 
00004 #include <grid/CartesianChart.hpp>
00005 #include <field/DirectProductArray.hpp>
00006 #include <bone/AsynchronCreator.hpp>
00007 #include <bone/FishField.hpp>
00008 
00009 #include <ocean/eagle/PhysicalSpace.hpp>
00010 #include <bundle/FieldSelector.hpp>
00011 
00012 using namespace MemCore;
00013 using namespace Fiber;
00014 
00015 
00019 template <class Formula>
00020 struct  AnalyticCreator : Wizt::AsynchronCreator
00021 {
00022         typedef typename Formula::value_type    value_type;
00023         enum { FieldDims = Formula::Dims };
00024         typedef typename Formula::point_type    point_type;
00025 
00026         typedef typename Formula::Parameters    Param_t;
00027 
00028         typedef Fiber::MemArray<FieldDims,  value_type> Array_t; 
00029 
00030         typedef Fiber::DirectProductMemArray<point_type>        ProcArray_t;
00031 
00032 
00033         double                          time;
00034         Param_t                         Params;
00035 
00036         RefPtr<Array_t>                 myArray;
00037         RefPtr<CreativeArrayBase>       myCoords;
00038 
00039         AnalyticCreator(double t, const RefPtr<CreativeArrayBase>&Coords, Wizt::VCotask*CoTask,
00040                         const Param_t&P)
00041         : AsynchronCreator(CoTask)
00042         , time(t)
00043         , Params(P)
00044         , myCoords(Coords)
00045         {
00046                 assert( myCoords );
00047 
00048                 addInterface( new MemArrayProperties(FieldDims, FiberType<value_type>::getFiberType() ) );
00049         }
00050 
00051         ~AnalyticCreator()
00052         {}
00053 
00054         override bool release()
00055         {
00056                 myArray = NullPtr(); 
00057                 return true;
00058         }
00059 
00060         override bool hasData() const
00061         {
00062                 if (myArray)
00063                         return true;
00064 
00065                 return false;
00066         }
00067 
00068         const type_info&getType()
00069         {
00070                 return typeid(value_type);
00071         }
00072 
00073         override RefPtr<Fiber::MemBase> compute()
00074         {
00075                 assert( myCoords );
00076         RefPtr<ProcArray_t> Coords = myCoords->create();
00077                 assert(Coords);
00078         ProcArray_t&P = *Coords;
00079 
00080         RefPtr<Array_t> A = new Array_t( Coords->Size() );
00081         Array_t&MyField = *A; 
00082 
00083                 Wizt::VActionNotifier::BusyInfo("Computing Analytic field..."); 
00084         MultiIndex<FieldDims> M = MIndex(0,0,0);
00085                 do
00086                 {
00087                 const Eagle::point3&Pt = P[ M ]; 
00088 
00089                         Formula::eval( MyField[M], Pt, time, Params);
00090                 }
00091                 while( M.inc( Coords->Size() ) ); 
00092 
00093                 return A;
00094         }
00095 
00096 static  void    setFieldType(Fiber::FieldSelector&FS)
00097         {
00098                 FS.accept<value_type>();
00099         }
00100 
00101 
00102 static  bool    set(Wizt::VCotask*where,
00103                     double time, const Param_t&P, 
00104                     Grid&G, const string&fieldname)
00105         {
00106         RefPtr<Field>&myField = G[ fieldname ];
00107                 if (!myField)
00108                         myField = new Field(); 
00109 
00110         RefPtr<AnalyticCreator<Formula> > AC = myField->getCreator(); 
00111                 if (AC)
00112                 {
00113                         if (AC->Params == P)
00114                         {
00115                                 if (AC->isRunning() )
00116                                         return false;
00117                                 return true;
00118                         }
00119                 } 
00120                 myField->setCreator( new AnalyticCreator<Formula>(time, G.CartesianPositions()->getCreator(), where, P ) );
00121                 if (AC)
00122                 {
00123                         if (AC->isRunning() )
00124                                 return false;
00125                 }
00126                 return true;
00127         }
00128 };
00129 
00130 #endif