simulation.C

Go to the documentation of this file.
00001 
00006 #ifndef _SIMULATION_C
00007 #define _SIMULATION_C
00008 
00009 #ifdef HAVE_CONFIG_H
00010 #include <tumble-conf.h>
00011 #endif /* HAVE_CONFIG_H */
00012 
00013 
00014 #include <cstdio>
00015 #include <cstdlib>
00016 #include <cstring>
00017 #include <cstddef>
00018 #include <iostream>
00019 #include <list>
00020 
00021 #include "simulation.h"
00022 
00023 #include "beziermesh.h"
00024 #include "boundarymesh.h"
00025 #include "cell.h"
00026 #include "celltuple.h"
00027 #include "cleaner.h"
00028 #include "datastore.h"
00029 #include "epswrite.h"
00030 #include "globals.h"
00031 #include "meshio.h"
00032 #include "spline.h"
00033 #include "timehelp.h"
00034 #include "util.h"
00035 
00036 using namespace std;
00037 
00039 Simulation::Simulation()
00040 {
00041     initialize_structures();
00042 }
00043 
00052 Simulation::Simulation( char *filename )
00053 {
00054     initialize_structures();
00055     int len = strlen(filename);
00056     if(len>=4 && !strncmp(filename+(len-4),".geo",4))
00057         read_from_binary_file( filename );
00058     else
00059         read_from_text_file( filename );
00060 
00061 }
00062 
00068 void Simulation::initialize_structures()
00069 {
00070     persistant_store = new PersistantStore();
00071     data_store = new DataStore(*persistant_store);
00072     bdry_mesh = new BoundaryMesh(*persistant_store, data_store);
00073     bezier_mesh = new BezierMesh(*persistant_store, data_store);
00074     bdry_mesh->set_bezier_mesh(bezier_mesh);
00075     bezier_mesh->set_bdry_mesh(bdry_mesh);
00076     positions_set = false;
00077 }
00078 
00080 BezierMesh* Simulation::get_bezier_mesh()
00081 {
00082     return bezier_mesh;
00083 }
00084 
00086 BoundaryMesh* Simulation::get_boundary_mesh()
00087 {
00088     return bdry_mesh;
00089 }
00090 
00092 DataStore* Simulation::get_data_store()
00093 {
00094     return data_store;
00095 }
00096 
00097 
00109 int Simulation::read_from_text_file( char *filename )
00110 {
00111     MeshInput meshin(bezier_mesh, bdry_mesh);
00112     if(! meshin.read( filename ) ){
00113         cout<<"Error reading in mesh from file: "<<filename<<endl;
00114         exit(-1);
00115     }
00116     return 0;
00117 }
00118 
00119 
00131 int Simulation::read_from_binary_file( char *filename )
00132 {
00133     MeshBinaryInput meshin(this);
00134     if(! meshin.read( filename ) ){
00135         cout<<"Error reading in mesh from file: "<<filename<<endl;
00136         exit(-1);
00137     }
00138     return 0;
00139 }
00140 
00142 const LinearData& Simulation::get_data(const ControlPoint& cp) const
00143 {
00144   return *data_store->get_data(cp);
00145 }
00146 
00147 
00159 static Point2D compute_displacement(const LinearData& data, int fixed,
00160                                     int v1x, int v1y, int v0x, int v0y, double dt)
00161 {
00162   Point2D vel0(data.fields[v0x], data.fields[v0y] );
00163   Point2D vel1(data.fields[v1x], data.fields[v1y] );
00164 
00165   /* zero out fixed components */
00166   if (fixed == 1 || fixed == 3){
00167     vel0.coords[0] = 0.0;
00168     vel1.coords[0] = 0.0;
00169   }
00170   if (fixed == 2 || fixed == 3){
00171     vel0.coords[1] = 0.0;
00172     vel1.coords[1] = 0.0;
00173   }
00174   return ( vel0 * 0.5 + vel1 * 0.5 ) * dt;
00175 }
00176 
00189 int Simulation::to_text_file( char *filename )
00190 {
00191     int ret;
00192     MeshOutput meshout(bezier_mesh, bdry_mesh);
00193     if( !meshout.write( filename ) ){
00194         cout<<"Error writing mesh to file: "<<filename<<endl;
00195         ret = -1;
00196     } else {
00197         ret = 0;
00198     }
00199     return ret;
00200 }
00214 int Simulation::to_binary_file( char *filename )
00215 {
00216     int ret;
00217     MeshBinaryOutput meshout(this);
00218     if( !meshout.write( filename ) ){
00219         cout<<"Error writing binary mesh file: "<<filename<<endl;
00220         ret = -1;
00221     } else {
00222         ret = 0;
00223     }
00224     return ret;
00225 }
00226 
00233 int Simulation::to_eps( char *epsfile )
00234 {
00235     EPSWrite eps(bezier_mesh, bdry_mesh);
00236     if( !eps.write( epsfile ) ) {
00237         cout<<"Error writing to eps file: "<<epsfile<<endl;
00238         return -1;
00239     }
00240     return 0;
00241 }
00242 
00244 void Simulation::print()
00245 {
00246     cout<<data_store<<endl;
00247     cout<<bdry_mesh<<endl;
00248     cout<<bezier_mesh<<endl;
00249 }
00250 
00261 void Simulation::move_(double dt, unsigned vxCoord, unsigned vyCoord, unsigned xCoord, unsigned yCoord)
00262 {
00263   move_(dt, vxCoord, vyCoord, vxCoord, vyCoord, xCoord, yCoord);
00264 }
00265 
00274 void Simulation::move_(double dt, unsigned vxCoord, unsigned xCoord)
00275 {
00276   move_(dt, vxCoord, vxCoord+1, vxCoord, vxCoord+1, xCoord, xCoord+1);
00277 }
00278 
00288 void Simulation::move_(double dt, unsigned v1xCoord, unsigned v0xCoord, unsigned xCoord)
00289 {
00290   move_(dt, v1xCoord, v1xCoord+1, v0xCoord, v0xCoord+1, xCoord, xCoord+1);
00291 }
00292 
00293 
00294 
00320 void Simulation::move_(double dt, unsigned vxCoord1, unsigned vyCoord1, unsigned vxCoord0, unsigned vyCoord0, unsigned xCoord, unsigned yCoord)
00321 {
00322   //timeval start;
00323   //gettimeofday(&start,NULL);
00324   
00325   //check to make sure requested data values are here
00326   unsigned data_length = bezier_mesh->data_length();
00327   if((vxCoord1 >= data_length) || (vxCoord0 >= data_length)
00328      || (vyCoord1 >= data_length) || (vyCoord0 >= data_length) 
00329      || (xCoord >= data_length) || (yCoord >= data_length)) {
00330        cout<<"Simulation::move --- Requested velocity or position components do not exist in mesh data. Mesh Data Size:"<<data_length<<endl;
00331        cout<<"vxc1 = "<<vxCoord1<<"vyc1 = "<<vyCoord1<<"vxc0 = "<<vxCoord0<<"vyc0 = "<<vyCoord0<<"xc = "<<xCoord<<"yc = "<<yCoord<<endl;
00332        assert(0);
00333        exit(1);
00334      }
00335      
00336      /* Step 1: move BoundaryEdge's.*/
00337      /* Note spline->move will NOT move d0 vertices, we will do this seperately */
00338      for(BoundaryMesh::Edge_Hash_T::iterator be = bdry_mesh->get_edges_begin();
00339      be != bdry_mesh->get_edges_end(); ++be) {
00340        
00341        BoundaryEdge *e = (*be);
00342        QBSpline *spline = e->get_spline();
00343        int size_dp = spline->k.size();
00344        int size_dq = size_dp - 1;
00345        int fixed = e->get_fixed();
00346        Point2D dp[size_dp];
00347        Point2D dq[size_dq];
00348        
00349        //compute dp and dq
00350        for (int i = 0; i < size_dp; i++) {
00351      dp[i] = compute_displacement(get_data(spline->b[2*i]), fixed,
00352                       vxCoord1, vyCoord1,
00353                       vxCoord0, vyCoord0, dt);
00354        }
00355        for (int i = 0; i < size_dq; i++){
00356      LinearData data;
00357      data  = get_data(spline->b[2*i  ]) * 0.25;
00358      data += get_data(spline->b[2*i+1]) * 0.50;
00359      data += get_data(spline->b[2*i+2]) * 0.25;
00360      dq[i] = compute_displacement(data, fixed, vxCoord1, vyCoord1,
00361                       vxCoord0, vyCoord0, dt);
00362        }
00363 
00364        //       cout << "sim:move --> Calling spline-> move" <<endl;
00365        spline->move(dp,dq, xCoord, yCoord);
00366      }
00367 
00368      //     cout << "sim::move --> finished step 1" << endl;
00369      
00370      Point2D displacement;
00371 
00372      /* Step 2: Move d0 vertices*/
00373      for (BoundaryMesh::Vertex_Hash_T::iterator bv = bdry_mesh->get_vertices_begin();
00374       bv != bdry_mesh->get_vertices_end(); ++bv) {
00375        BoundaryVertex *v = *bv;
00376        displacement = v->get_bezier()->get_cp() + 
00377      compute_displacement(v->get_bezier()->get_dp(),v->get_fixed(), 
00378                   vxCoord1, vyCoord1,
00379                   vxCoord0, vyCoord0, dt);
00380 
00381        //cout << "v0 is cp:"<<v->get_bezier()->get_cp()<<" ld: "<<v->get_bezier()->get_dp()<<endl;
00382 
00383        v -> get_bezier() -> set_data(xCoord, displacement.x());
00384        v -> get_bezier() -> set_data(yCoord, displacement.y());
00385 
00386        //cout << "now v0 has ld: "<<v->get_bezier()->get_dp()<<endl;
00387      }
00388 
00389 
00390      //     cout << "sim::move --> finished step 2" << endl;
00391      
00392      /* Step 3: Iterate over all non-boundary vertex and non-boundary edge control points */
00393      for(BezierMesh::Vertex_Hash_T::iterator vi = bezier_mesh->get_vertices_begin();
00394      vi!=bezier_mesh->get_vertices_end(); ++vi) {
00395        
00396        BezierVertex *v = *vi;
00397        if(!v->is_boundary()) {
00398      displacement = v->get_cp() + 
00399        compute_displacement(v->get_dp(), 0, vxCoord1, vyCoord1,
00400                 vxCoord0, vyCoord0, dt);
00401 
00402      // cout << "v is cp:"<<v->get_cp()<<" ld: "<<v->get_dp()<<endl;
00403 
00404      v -> set_data(xCoord, displacement.x());
00405      v -> set_data(yCoord, displacement.y());
00406 
00407      // cout << "now v has ld: "<<v->get_dp()<<endl;
00408        }
00409      }
00410 
00411     /* Displace the edge midpoints */
00412     for(BezierMesh::Edge_Hash_T::iterator ei = bezier_mesh->get_edges_begin();
00413         ei!=bezier_mesh->get_edges_end(); ++ei){
00414         BezierEdge *e = *ei;
00415         if(!e->is_boundary()){
00416       
00417       LinearData ld = (*(e->get_data_point(0)) + *(e->get_data_point(2))) * 0.5;
00418 
00419       //displacement = Point2D(ld.get(xCoord), ld.get(yCoord));
00420           displacement = e->get_cp(1) +  compute_displacement(e->get_dp(1), 0,
00421                               vxCoord1, vyCoord1,
00422                               vxCoord0, vyCoord0, dt);
00423 
00424       // cout << "e has cp:"<<e->get_cp(1)<<" ld: "<<e->get_dp(1)<<endl;
00425 
00426       e -> set_data(1, xCoord, displacement.x());
00427       e -> set_data(1, yCoord, displacement.y());
00428 
00429       // cout << "now e has ld: "<<e->get_dp(1)<<endl;
00430         }
00431     }
00432 
00433     //    cout << "sim::move --> finished step 3" << endl;
00434 
00435     assert(bezier_mesh->check_consistency());
00436 
00437     // cout<<"Quadratic Moving complete: Time step = "<<dt<<"sec    Elapsed Time = "<<elapsed_time_ms(start)<<"ms"<<endl;
00438 
00439 }
00440 
00441 void Simulation::set_positions(unsigned xPosI, unsigned yPosI)
00442 {
00443   XposIndex = xPosI;
00444   YposIndex = yPosI;
00445   positions_set = true;
00446   return;
00447 }
00448 
00449 // 3 arguments, t, vx, vy
00450 void Simulation::move(double time_step, unsigned vx_pos, unsigned vy_pos)
00451 {
00452   move(time_step, vx_pos, vy_pos, vx_pos, vy_pos);
00453 }
00454 // Shorthand, assume y index is always x+1
00455 // 2 arguments, t, vxy
00456 void Simulation::move(double time_step, unsigned vx_pos)
00457 {
00458   move(time_step,vx_pos, vx_pos+1, vx_pos, vx_pos+1);
00459 }
00460 // 5 arguments, t, v0x, v0y, v1x, v1y
00461 void Simulation::move(double time_step, unsigned vx1_pos, unsigned vy1_pos, unsigned vx0_pos, unsigned vy0_pos)
00462 {
00463   if (!positions_set)
00464     {
00465       cout << "Positions to store the x and y data have not been set nor initialized." << endl;
00466       assert(0);
00467     }
00468 
00469   // Put new position in the data
00470   //cout << "Putting new position into the dangling data vector" << endl;
00471 
00472   move_(time_step, vx1_pos, vy1_pos, vx0_pos, vy0_pos, XposIndex, YposIndex);
00473 
00474   // Swap it into the geometry
00475   //cout << "Swapping new position into the dangling geometry" << endl;
00476 
00477   data_store->swap_geo_with ( XposIndex, YposIndex);
00478 
00479   return;
00480 }
00481 
00482 // 3 arguments, t, vx, vy
00483 double Simulation::move_safe(double time_step, unsigned vx_pos, unsigned vy_pos)
00484 {
00485   return move_safe(time_step, vx_pos, vy_pos, vx_pos, vy_pos);
00486 }
00487 // Shorthand, assume y index is always x+1
00488 // 2 arguments, t, vxy
00489 double Simulation::move_safe(double time_step, unsigned vx_pos)
00490 {
00491   return move_safe(time_step,vx_pos, vx_pos+1, vx_pos, vx_pos+1);
00492 }
00493 
00494 double Simulation::move_safe(double time_step, unsigned vx1_pos, unsigned vy1_pos, unsigned vx0_pos, unsigned vy0_pos)
00495 {
00496   move(time_step, vx1_pos, vy1_pos, vx0_pos, vy0_pos);
00497   
00498   vector<BezierTriangle*> inverted;
00499   bezier_mesh->find_inverted_triangles(inverted);
00500   if (inverted.size() != 0) {
00501     cout << "[MoveSafe] Found at least one inverting triangle:" << endl;
00502     (inverted[0]) -> print_mathematica();
00503     data_store->swap_geo_with ( XposIndex, YposIndex);
00504     return -1.0; 
00505   }
00506 
00507   return 1.0;
00508 }
00509 
00510 void Simulation::store_state(unsigned vIndexFrom, unsigned vIndexTo, unsigned xIndexTo)
00511 {
00512   data_store->copy_data_2(vIndexFrom,  vIndexTo);
00513   data_store->write_geo_into(xIndexTo);
00514 }
00515 
00516 void Simulation::restore_state(unsigned vIndexFrom, unsigned vIndexTo, unsigned xIndexFrom)
00517 {
00518   data_store->copy_data_2(vIndexFrom, vIndexTo);
00519   data_store->read_geo_from(xIndexFrom);
00520 }
00521 
00523 void Simulation::print_statistics()
00524 {
00525     cout<<"************ Simulation ****************"<<endl;
00526     cout<<"BoundaryMesh:"<<endl;
00527     bdry_mesh->print_statistics();
00528     cout<<"BezierMesh:"<<endl;
00529     bezier_mesh->print_statistics();
00530     data_store->print();
00531 }
00532 
00533 
00534 
00535 
00536 #endif /* _SIMULATION_C */

Generated on Mon May 24 09:53:30 2010 for TUMBLE by  doxygen 1.5.2