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