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