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