00001
00006 #ifndef _SIMULATION_C
00007 #define _SIMULATION_C
00008
00009 #ifdef HAVE_CONFIG_H
00010 #include <tumble-conf.h>
00011 #endif
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
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
00323
00324
00325
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
00337
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
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
00365 spline->move(dp,dq, xCoord, yCoord);
00366 }
00367
00368
00369
00370 Point2D displacement;
00371
00372
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
00382
00383 v -> get_bezier() -> set_data(xCoord, displacement.x());
00384 v -> get_bezier() -> set_data(yCoord, displacement.y());
00385
00386
00387 }
00388
00389
00390
00391
00392
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
00403
00404 v -> set_data(xCoord, displacement.x());
00405 v -> set_data(yCoord, displacement.y());
00406
00407
00408 }
00409 }
00410
00411
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
00420 displacement = e->get_cp(1) + compute_displacement(e->get_dp(1), 0,
00421 vxCoord1, vyCoord1,
00422 vxCoord0, vyCoord0, dt);
00423
00424
00425
00426 e -> set_data(1, xCoord, displacement.x());
00427 e -> set_data(1, yCoord, displacement.y());
00428
00429
00430 }
00431 }
00432
00433
00434
00435 assert(bezier_mesh->check_consistency());
00436
00437
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
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
00455
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
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
00470
00471
00472 move_(time_step, vx1_pos, vy1_pos, vx0_pos, vy0_pos, XposIndex, YposIndex);
00473
00474
00475
00476
00477 data_store->swap_geo_with ( XposIndex, YposIndex);
00478
00479 return;
00480 }
00481
00482
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
00488
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