00001 
00002 
00003 #ifndef MOTION_SOLVER_H
00004 #define MOTION_SOLVER_H
00005 
00013 #include "Solver.h"
00014 
00015 template <class DataType, int dim>
00016 class MotionSolver : public Solver {
00017 public:
00018   typedef Solver base;
00019   typedef ads::FixedArray<dim,DataType> point_type;
00020   typedef ads::FixedArray<dim,int> multi_index_type;
00021 
00022   MotionSolver() : base(), Tr(0.), scale(1.), dtret(0.), brep_filetype(0), num_vertices(0), num_connections(0), steps(0), 
00023                    initial_vertices(0), vertices(0), velocities(0), connections(0), nodeids(0), pressures(0) {
00024     OutputName="-";
00025     CheckpointName="motion";
00026     for (int i=0; i<dim; i++) xs[i]=0.; 
00027     pi=4.0*std::atan(1.);
00028   }  
00029 
00030   ~MotionSolver() {
00031     if (initial_vertices) delete[] initial_vertices;
00032     if (vertices) delete[] vertices;
00033     if (velocities) delete [] velocities;
00034     if (connections) delete[] connections;
00035     if (nodeids) delete [] nodeids;
00036     if (pressures) delete [] pressures;
00037   }
00038   
00039   virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00040     LocCtrl = Ctrl.getSubDevice(prefix+"MotionSolver");
00041     RegisterAt(LocCtrl,"FileType",brep_filetype);
00042     RegisterAt(LocCtrl,"InputBrep",brep_filename);
00043     RegisterAt(LocCtrl,"OutputName",OutputName);
00044     RegisterAt(LocCtrl,"CheckpointName",CheckpointName);
00045 
00046     RegisterAt(LocCtrl,"Scale",scale);
00047     RegisterAt(LocCtrl,"Center(1)",xs[0]);
00048     RegisterAt(LocCtrl,"Center(2)",xs[1]);
00049     RegisterAt(LocCtrl,"Center(3)",xs[2]);
00050     RegisterAt(LocCtrl,"RotationDuration",Tr);
00051     RegisterAt(LocCtrl,"dt",dtret);    
00052   }
00053   virtual void register_at(ControlDevice& Ctrl) {
00054     register_at(Ctrl, "");
00055   }
00056 
00057   virtual bool setup() {
00058     std::ifstream brep_file( brep_filename.c_str() );
00059     if ( ! brep_file ) {
00060       std::cerr << "Could not read the b-rep file.  Exiting...\n";
00061       std::exit( 1 );
00062     }
00063 
00064     
00065     if (brep_filetype==1) {
00066       int fdim, mdim;
00067       brep_file >> fdim >> mdim;
00068       if ( fdim!=dim || mdim!=dim-1 ) {
00069         std::cerr << "Mesh in b-rep file has wrong dimension.  Exiting...\n";
00070         std::exit( 1 );
00071       }
00072       brep_file >> num_vertices;
00073       initial_vertices = new point_type[ num_vertices ];
00074       const point_type* point_iter_end = initial_vertices + num_vertices;
00075       for ( point_type* piter = initial_vertices; piter != point_iter_end; ++piter ) {
00076         brep_file >> *piter; 
00077         *piter *= scale;
00078       }
00079       brep_file >> num_connections;
00080     }
00081     else {
00082       brep_file >> num_vertices >> num_connections;
00083       initial_vertices = new point_type[ num_vertices ];
00084       const point_type* point_iter_end = initial_vertices + num_vertices;
00085       for ( point_type* piter = initial_vertices; piter != point_iter_end; ++piter ) {
00086         brep_file >> *piter;
00087         *piter *= scale;
00088       }
00089     }
00090       
00091     connections = new multi_index_type[ num_connections ];
00092     const multi_index_type* connections_iter_end = connections + num_connections;
00093     for ( multi_index_type* eiter = connections; eiter != connections_iter_end; ++eiter ) 
00094       brep_file >> *eiter;
00095     brep_file.close();
00096 
00097     velocities = new point_type[ num_vertices ];
00098     vertices = new point_type[ num_vertices ];
00099     pressures = new DataType[ num_vertices ];  
00100     nodeids = new int[ num_vertices ];
00101     for (register int j=0; j<num_vertices; j++)
00102       nodeids[j] = j;
00103   
00104     return true;
00105   }    
00106   
00107   virtual void finish() {} 
00108 
00109   virtual void SetVertices(double& t) {
00110     for (int i=0; i<num_vertices; i++) {
00111       DataType x = initial_vertices[i](0)-xs[0];
00112       DataType y = initial_vertices[i](1)-xs[1];
00113       DataType rs = std::sqrt(x*x+y*y);
00114       DataType alpha = std::atan2(y,x);
00115 
00116       vertices[i](0) = xs[0]+rs*std::cos(2.*pi/Tr*t+alpha);
00117       vertices[i](1) = xs[1]+rs*std::sin(2.*pi/Tr*t+alpha);
00118       vertices[i](2) = initial_vertices[i](2);
00119     }
00120   }
00121 
00122   virtual void SetVelocities(double& t) {
00123     for (int i=0; i<num_vertices; i++) {
00124       DataType x = vertices[i](0)-xs[0];
00125       DataType y = vertices[i](1)-xs[1];
00126       DataType rs = std::sqrt(x*x+y*y);
00127       DataType alpha = std::atan2(y,x);
00128       if (Tr!=0.) {
00129         DataType vr = 2.*pi/Tr*rs;
00130         velocities[i](0) = -vr*std::sin(alpha);
00131         velocities[i](1) =  vr*std::cos(alpha);
00132         velocities[i](2) = 0.;
00133       }
00134       else 
00135         velocities[i] = 0.;
00136     }
00137   }
00138 
00139   virtual void Initialize(double& t, double& dt) {
00140     t=0.; time=t; dt=dtret;
00141     SetVertices(t);
00142     SetVelocities(t);
00143   }
00144 
00145   virtual void Advance(double& t, double& dt) {
00146     t+=dt;
00147     SetVertices(t);
00148     SetVelocities(t);
00149     time=t;
00150     steps++;
00151     dt=dtret;
00152   }
00153 
00154   virtual void Output() {
00155     if (OutputName.c_str()[0] == '-') 
00156       return;
00157     char ioname[256];
00158     sprintf(ioname,"%s_%d.tec",OutputName.c_str(),NSteps());
00159     std::ofstream outfile(ioname, std::ios::out);
00160 
00161     std::ostream* out;
00162     outfile.open(ioname, std::ios::out);
00163     out = new std::ostream(outfile.rdbuf());
00164 
00165     *out << "title = mesh" << std::endl;
00166     *out << "variables = x y z Pressures Velocity_u Velocity_v Velocity_w VelocityVec" << std::endl;
00167     *out << "zone t=\"zone 1\", I=" << num_vertices << ", J="
00168          << num_connections << ", F=FEPOINT, ET=TRIANGLE" << std::endl;
00169     for (register int j=0;j<num_vertices; j++)
00170       *out << vertices[j](0) << " " << vertices[j](1) << " " << vertices[j](2) << " " 
00171            << pressures[j] << " " << velocities[j](0) << " " << velocities[j](1) << " " << velocities[j](2) << " "
00172            << std::sqrt(velocities[j](0)*velocities[j](0)+velocities[j](1)*velocities[j](1)+velocities[j](2)*velocities[j](2)) 
00173            << std::endl;
00174     for (register int j=0;j<num_connections; j++)
00175       *out << connections[j](0)+1 << " " << connections[j](1)+1 << " " << connections[j](2)+1 << std::endl; 
00176 
00177     outfile.close();
00178     delete out; 
00179   }    
00180 
00181   virtual void Restart(double& t, double& dt) {
00182     char fname[256];
00183     sprintf(fname,"%s.cp",CheckpointName.c_str());
00184     std::ifstream ifs(fname, std::ios::in);
00185     ifs.read((char*)&time,sizeof(double));
00186     ifs.read((char*)&steps,sizeof(int));
00187     ifs.close();
00188     dt=dtret;
00189   }
00190 
00191   virtual void Checkpointing() {
00192     char fname[256];
00193     sprintf(fname,"%s.cp",CheckpointName.c_str());
00194     std::ofstream ofs(fname, std::ios::out);
00195     ofs.write((char*)&time,sizeof(double));
00196     ofs.write((char*)&steps,sizeof(int));
00197     ofs.close();
00198   }
00199 
00200   inline double CurrentTime() const { return time; }
00201   virtual  int NSteps() { return steps; }
00202  
00203 protected:
00204   DataType xs[dim], Tr, pi, scale;
00205   double dtret, time;
00206   std::string brep_filename;
00207   std::string OutputName;
00208   std::string CheckpointName;
00209   int brep_filetype, num_vertices, num_connections, steps;
00210   point_type *initial_vertices, *vertices, *velocities;
00211   multi_index_type* connections;
00212   int *nodeids;
00213   DataType *pressures;
00214   ControlDevice LocCtrl;
00215 };
00216 
00217 
00218 #endif