00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <freecloth/simulator/simSimulator.h>
00020 #include <freecloth/geom/geVector.h>
00021 #include <freecloth/geom/geMatrix3.h>
00022 #include <freecloth/base/fstream>
00023 #include <freecloth/base/iomanip>
00024 #include <freecloth/base/baMath.h>
00025 #include <freecloth/base/baStringUtil.h>
00026
00027 #ifdef NDEBUG
00028 #define DO_DEBUG(x)
00029 #else
00030 #define DO_DEBUG(x) x
00031 #endif
00032
00033
00034
00035 #define DO_NORM 0
00036
00037 #define DO_SCALE_INVARIANT 1
00038
00039 namespace {
00040 using namespace freecloth;
00041
00042 typedef Float Float_3[3];
00043 typedef Float Float_4[4];
00044 typedef GePoint GePoint_3[3];
00045 typedef GePoint GePoint_4[4];
00046 typedef GeVector GeVector_3[3];
00047 typedef GeVector GeVector_33[3][3];
00048 typedef GeVector GeVector_3333[3][3][3][3];
00049 typedef GeVector GeVector_4[4];
00050 typedef GeVector GeVector_43[4][3];
00051 typedef GeVector GeVector_443[4][4][3];
00052 typedef GeVector GeVector_4433[4][4][3][3];
00053 typedef GeMatrix3 GeMatrix3_33[3][3];
00054 typedef GeMatrix3 GeMatrix3_44[4][4];
00055
00056 const bool PRINT_STATS = false;
00057
00058 const bool DEBUG_REWIND = false;
00059 const bool DEBUG_MASS = false;
00060 const bool DEBUG_STEP = false;
00061 const bool DEBUG_COMMON = false;
00062 const bool VERIFY_COMMON = false;
00063 const bool DEBUG_STRETCH = false;
00064 const bool VERIFY_STRETCH = false;
00065 const bool DEBUG_SHEAR = false;
00066 const bool VERIFY_SHEAR = false;
00067 const bool DEBUG_BEND = false;
00068
00069
00070
00071 const bool VERIFY_BEND = false;
00072
00073 const bool DUMP_DISTS = false;
00074 const bool DUMP_FORCES = false;
00075
00076
00077
00078
00079
00080
00081 inline GeVector makeSkewRow( const GeVector& v, UInt32 row )
00082 {
00083 DGFX_ASSERT( row < 3 );
00084
00085 switch( row ) {
00086 case 0:
00087 return GeVector( 0, -v._z, v._y );
00088 case 1:
00089 return GeVector( v._z, 0, -v._x );
00090 case 2:
00091 return GeVector( -v._y, v._x, 0 );
00092 }
00093 return GeVector::ZERO;
00094 }
00095
00096
00097
00098
00099 template <class E1>
00100 bool isSymmetric( const E1& A )
00101 {
00102 DGFX_ASSERT( A.nbRows() == A.nbColumns() );
00103 for ( UInt32 i = 0; i < A.nbRows(); ++i ) {
00104 for ( UInt32 j = i + 1; j < A.nbRows(); ++j ) {
00105 if ( A( i, j ) != A( j, i ).transpose() ) {
00106 return false;
00107 }
00108 }
00109 }
00110 return true;
00111 }
00112 }
00113
00114 FREECLOTH_NAMESPACE_START
00115
00116
00117
00118
00119
00120
00121
00122
00123 class SimSimulator::CommonVars
00124 {
00125 public:
00126
00127
00128 void calc( const GePoint_3 p, const GePoint_3 tp );
00129 void debugOutput( std::ostream& os );
00130
00131
00132
00133 Float du1,dv1,du2,dv2;
00134 Float a;
00135 GeVector wu,wv;
00136 GeVector wuhat,wvhat;
00137 Float wuhim,wvhim;
00138
00139 Float_3 dwhux_dxmx, dwhvx_dxmx;
00140 #if DO_NORM
00141 GeVector_33 dwu_dxm, dwv_dxm;
00142 GeVector_3333 d2wu_dxmdxn, d2wv_dxmdxn;
00143 #endif
00144 };
00145
00146
00147
00148
00149 class SimSimulator::StretchVars {
00150 public:
00151
00152
00153 void calc(
00154 const CommonVars& cv,
00155 const GeVector v0[ 3 ],
00156 Float b_u, Float b_v
00157 );
00158 void debugOutput( std::ostream& os );
00159
00160
00161 Float Cu, Cv;
00162 GeVector_3 dCu_dxm, dCv_dxm;
00163 Float dCu_dt, dCv_dt;
00164 GeMatrix3_33 d2Cu_dxmdxn, d2Cv_dxmdxn;
00165 };
00166
00167
00168
00169
00170
00171
00172
00173 class SimSimulator::ShearVars {
00174 public:
00175
00176
00177 void calc(
00178 const CommonVars& cv,
00179 const GeVector v0[ 3 ]
00180 );
00181 void debugOutput( std::ostream& os );
00182
00183
00184 Float C;
00185 GeVector_3 dC_dxm;
00186 Float dC_dt;
00187 GeMatrix3_33 d2C_dxmdxn;
00188 };
00189
00190
00191
00192
00193
00194
00195
00196
00197 class SimSimulator::BendVars
00198 {
00199 public:
00200
00201
00202 void calc(
00203 const GePoint_4 x,
00204 const GeVector_4 v
00205 );
00206
00207 void calc(
00208 const GePoint_4 x,
00209 const GeVector_4 v,
00210 const BendVars& bv
00211 );
00212 void debugOutput( std::ostream& os );
00213
00214
00215 GeVector nA,nB,e;
00216 Float nAhim,nBhim,ehim;
00217 Float costh,sinth;
00218 Float C;
00219
00220 GeVector_4 qA, qB;
00221 Float_4 qe;
00222 GeVector_443 dqAm_dxn, dqBm_dxn;
00223
00224 GeVector_43 dnA_dxm, dnB_dxm, de_dxm;
00225 GeVector_4433 d2nA_dxmdxn, d2nB_dxmdxn;
00226 #if DO_NORM
00227 GeVector_4433 d2e_dxmdxn;
00228 #endif
00229
00230 GeVector_4 dcosth_dxm, dsinth_dxm;
00231 GeMatrix3_44 d2costh_dxmdxn, d2sinth_dxmdxn;
00232
00233 GeVector_4 dC_dxm;
00234 Float dC_dt;
00235 GeMatrix3_44 d2C_dxmdxn;
00236
00237 private:
00238
00239
00240 void mainCalc( const GePoint_4 x, const GeVector_4 v );
00241 void calcNE( const GePoint_4 x );
00242 void calcThetas();
00243 void calcQs( const GePoint_4 x );
00244 void calcDqs();
00245 void calcNEderiv();
00246 void calcD2NE();
00247 void calcCosSinDeriv();
00248 void calcD2cossinth();
00249 void calcCderivs();
00250 };
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 SimSimulator::SimSimulator( const GeMesh& initialMesh )
00306 : _initialMesh( new GeMesh( initialMesh ) ),
00307 _rho( .01f ),
00308 _h( .02f ),
00309 _time( 0.f )
00310 {
00311 rewind();
00312 setupMass();
00313 removeAllConstraints();
00314 }
00315
00316
00317
00318 void SimSimulator::rewind()
00319 {
00320 _initialMeshWingedEdge = RCShdPtr<GeMeshWingedEdge>(
00321 new GeMeshWingedEdge( _initialMesh )
00322 );
00323 if ( DEBUG_REWIND ) {
00324 std::cout << "winged edges = " << _initialMeshWingedEdge << std::endl;
00325 }
00326 _mesh = RCShdPtr<GeMesh>( new GeMesh( *_initialMesh ) );
00327
00328 const UInt32 N = _mesh->getNbVertices();
00329 _v0 = SimVector( N );
00330 _f0 = SimVector( N );
00331 _df_dx = SimMatrix( N, N );
00332 _df_dv = SimMatrix( N, N );
00333 _modPCG._b = SimVector( N );
00334 _modPCG._A = SimMatrix( N, N );
00335 UInt32 i;
00336 ForceType ftypes[] = { F_STRETCH, F_SHEAR, F_BEND };
00337 for( i = 0; i < 3; ++i ) {
00338 UInt32 f( ftypes[ i ] );
00339 _f0i[ f ] = SimVector( N );
00340 _d0i[ f ] = SimVector( N );
00341 _df_dxi[ f ] = SimMatrix( N, N );
00342 _dd_dxi[ f ] = SimMatrix( N, N );
00343 _dd_dvi[ f ] = SimMatrix( N, N );
00344
00345 _fenergy[ i ] = 0;
00346 }
00347 _f0i[ F_GRAVITY ] = SimVector( N );
00348 _f0i[ F_DRAG ] = SimVector( N );
00349
00350 for( i = 0; i < NB_FORCES; ++i ) {
00351 _trienergy[ i ].resize( _initialMesh->getNbFaces() );
00352 }
00353
00354 _venergy = 0;
00355 _energy = 0;
00356 _time = 0.f;
00357 }
00358
00359
00360
00361 void SimSimulator::setupMass()
00362 {
00363 const UInt32 N = _mesh->getNbVertices();
00364 _M = SimMatrix( N, N );
00365 _totalMass = 0;
00366
00367 GeMesh::FaceConstIterator fi;
00368 GeMesh::VertexId vid;
00369 for( fi = _initialMesh->beginFace(); fi != _initialMesh->endFace(); ++fi ) {
00370 Float m = _rho * fi->calcArea() / 3;
00371 for ( UInt32 i = 0; i < 3; ++i ) {
00372 vid = fi->getVertexId( i );
00373
00374 GeMatrix3 M( _M( vid, vid ) );
00375 M( 0, 0 ) += m;
00376 M( 1, 1 ) += m;
00377 M( 2, 2 ) += m;
00378 _M( vid, vid ) = M;
00379 _totalMass += m;
00380 }
00381 }
00382
00383 if ( DEBUG_MASS ) {
00384 std::cout << "_M = " << _M << std::endl;
00385 std::cout << "totalMass = " << _totalMass << std::endl;
00386 }
00387 }
00388
00389
00390
00391 void SimSimulator::removeAllConstraints()
00392 {
00393 const UInt32 N = _mesh->getNbVertices();
00394 GeMesh::VertexId vid;
00395 _modPCG._S.resize( N );
00396 for( vid = 0; vid < N; ++vid ) {
00397 _modPCG._S[ vid ] = GeMatrix3::IDENTITY;
00398 }
00399 _z0 = SimVector( N );
00400 _z0.clear();
00401
00402
00403
00404 _v0.clear();
00405 }
00406
00407
00408
00409 void SimSimulator::setPosConstraintPlane(
00410 GeMesh::VertexId vid,
00411 const GeVector& p
00412 ) {
00413 GeVector pu( p.getUnit() );
00414 DGFX_ASSERT( vid < _modPCG._S.size() );
00415 _modPCG._S[ vid ] =
00416 GeMatrix3::IDENTITY - GeMatrix3::outerProduct( pu, pu );
00417 }
00418
00419
00420
00421 void SimSimulator::setPosConstraintLine(
00422 GeMesh::VertexId vid,
00423 const GeVector& v
00424 ) {
00425 GeVector vu( v.getUnit() );
00426
00427
00428 GeVector p;
00429 if ( !BaMath::isEqual( vu._z, 0 ) ) {
00430 p = GeVector( 1, 1, ( vu._x + vu._y ) / vu._z );
00431 }
00432 else if ( !BaMath::isEqual( vu._y, 0 ) ) {
00433 p = GeVector( 1, ( vu._x + vu._z ) / vu._y, 1 );
00434 }
00435 else {
00436 p = GeVector( ( vu._y + vu._z ) / vu._x, 1, 1 );
00437 }
00438 GeVector pu( p.getUnit() );
00439 GeVector qu( vu.cross( pu ) );
00440
00441 DGFX_ASSERT( BaMath::isEqual( qu.length(), 1 ) );
00442 DGFX_ASSERT( BaMath::isEqual( pu.dot( vu ), 0 ) );
00443 DGFX_ASSERT( BaMath::isEqual( qu.dot( vu ), 0 ) );
00444 DGFX_ASSERT( BaMath::isEqual( pu.dot( qu ), 0 ) );
00445
00446 DGFX_ASSERT( vid < _modPCG._S.size() );
00447 _modPCG._S[ vid ] =
00448 GeMatrix3::IDENTITY - GeMatrix3::outerProduct( pu, pu ) -
00449 GeMatrix3::outerProduct( qu, qu );
00450 }
00451
00452
00453
00454 void SimSimulator::setPosConstraintFull( GeMesh::VertexId vid )
00455 {
00456 DGFX_ASSERT( vid < _modPCG._S.size() );
00457 _modPCG._S[ vid ] =
00458 GeMatrix3::ZERO;
00459 }
00460
00461
00462
00463 void SimSimulator::setVelConstraint( GeMesh::VertexId vid, const GeVector& v )
00464 {
00465 DGFX_ASSERT( vid < _z0.size() );
00466 _z0[ vid ] = v;
00467 }
00468
00469
00470
00471 void SimSimulator::step()
00472 {
00473 preSubSteps();
00474 while ( ! subStepsDone() ) {
00475 subStep();
00476 }
00477 postSubSteps();
00478 }
00479
00480
00481
00482 void SimSimulator::preSubSteps()
00483 {
00484 UInt32 i;
00485
00486 if ( PRINT_STATS ) {
00487 std::cout << "****************************************" << std::endl;
00488 std::cout << "Simulating at time " << _time << std::endl;
00489 }
00490
00491 _fenergy[ F_STRETCH ] = 0;
00492 _fenergy[ F_SHEAR ] = 0;
00493 _fenergy[ F_BEND ] = 0;
00494
00495 _venergy = .5 * _v0.dot( _M * _v0 );
00496
00497
00498 _f0.clear();
00499
00500
00501
00502
00503 _df_dx *= 0;
00504 _df_dv *= 0;
00505 for( i = 0; i < NB_FORCES; ++i ) {
00506 _f0i[ i ].clear();
00507 _d0i[ i ].clear();
00508 _df_dxi[ i ] *= 0;
00509 _dd_dxi[ i ] *= 0;
00510 _dd_dvi[ i ] *= 0;
00511 }
00512 _modPCG._A *= 0;
00513 _modPCG._b.clear();
00514
00515 GeMesh::FaceConstIterator fi;
00516 for( fi = _mesh->beginFace(); fi != _mesh->endFace(); ++fi ) {
00517 calcStretchShear( *fi );
00518 }
00519 GeMeshWingedEdge::EdgeIterator ei;
00520
00521 for(
00522 ei = _initialMeshWingedEdge->beginEdge();
00523 ei != _initialMeshWingedEdge->endEdge();
00524 ++ei
00525 ) {
00526
00527 if ( ei->hasTwin() ) {
00528 calcBend( *ei );
00529 }
00530 }
00531
00532 for( i = 0; i < _mesh->getNbVertices(); ++i ) {
00533 const GeMatrix3& M = _M( i, i );
00534 Float gravity = -M( 2, 2 ) * _params._g;
00535 _f0[ i ]._z += gravity;
00536 DO_DEBUG( _f0i[ F_GRAVITY ][ i ]._z = gravity );
00537 }
00538
00539 for ( fi = _mesh->beginFace(); fi != _mesh->endFace(); ++fi ) {
00540 Float area( fi->calcArea() );
00541 const GeVector normal( fi->calcNormal() );
00542 GeMesh::FaceVertexId fvid;
00543 for ( fvid = 0; fvid < fi->getNbVertices(); ++fvid ) {
00544 UInt32 vid( fi->getVertexId( fvid ) );
00545 Float vel( _v0[ vid ].dot( normal ) );
00546 const GeVector force( ( -_params._k_drag * vel * area ) * normal );
00547 _f0[ vid ] += force;
00548 DO_DEBUG( _f0i[ F_DRAG ][ vid ] += force );
00549 }
00550 }
00551
00552 _energy = _venergy + _fenergy[ F_STRETCH ] +
00553 _fenergy[ F_SHEAR ] + _fenergy[ F_BEND ];
00554 if ( DEBUG_STEP ) {
00555 for ( UInt32 i = 0; i < NB_FORCES; ++i ) {
00556 const char* s[] = { "stretch","shear","bend","gravity","drag" };
00557 std::cout << "f0[" << s[i] << "] = " << _f0i[ i ] << std::endl;
00558 std::cout << std::endl;
00559 std::cout << "d0[" << s[i] << "] = " << _d0i[ i ] << std::endl;
00560 std::cout << std::endl;
00561 std::cout << "df_dx[" << s[i] <<"] = " << _df_dxi[ i ] << std::endl;
00562 std::cout << std::endl;
00563 std::cout << "dd_dx[" << s[i] <<"] = " << _dd_dxi[ i ] << std::endl;
00564 std::cout << std::endl;
00565 std::cout << "dd_dv[" << s[i] <<"] = " << _dd_dvi[ i ] << std::endl;
00566 std::cout << std::endl;
00567 std::cout << std::endl;
00568 }
00569 }
00570
00571 if ( DEBUG_STEP ) {
00572 std::cout << "f0 = " << _f0 << std::endl;
00573 std::cout << "df_dx = " << _df_dx << std::endl;
00574 std::cout << "df_dv = " << _df_dv << std::endl;
00575 }
00576
00577
00578 _modPCG._A = _df_dx * (-_h * _h) + _df_dv * -_h + _M;
00579 _modPCG._b = _h * ( _h * _df_dx * _v0 + _f0 );
00580
00581 if ( DEBUG_STEP ) {
00582 std::cout << "A = " << _modPCG._A << std::endl;
00583 std::cout << "b = " << _modPCG._b << std::endl;
00584 }
00585
00586
00587
00588 _modPCG._z = _h * _z0;
00589 _modPCG.preStep();
00590 }
00591
00592
00593
00594 bool SimSimulator::subStepsDone() const
00595 {
00596 return _modPCG.done();
00597 }
00598
00599
00600
00601 void SimSimulator::subStep()
00602 {
00603 _modPCG.step();
00604 }
00605
00606
00607
00608 void SimSimulator::postSubSteps()
00609 {
00610 const SimVector& x = _modPCG.result();
00611 if ( DEBUG_STEP ) {
00612 std::cout << "deltav = " << x << std::endl;
00613 std::cout << "Ax = " << _modPCG._A * x << std::endl;
00614 }
00615
00616 _v0 += x;
00617
00618 GeMesh::VertexIterator vi;
00619 UInt32 i;
00620 for ( vi = _mesh->beginVertex(), i = 0; vi != _mesh->endVertex(); ++vi, ++i ) {
00621 (*vi) += _h * _v0[ i ];
00622 }
00623 _time += _h;
00624 if ( PRINT_STATS ) {
00625 std::cout.precision( 4 );
00626 std::cout.width( 6 );
00627 std::cout.setf( std::ios::fixed );
00628 std::cout << "Total energy: "
00629 << std::setprecision( 5 ) << std::setw( 7 )
00630 << std::setiosflags( std::ios::fixed )
00631 << _energy
00632 << "( stretch: " << _fenergy[ F_STRETCH ]
00633 << " / shear: " << _fenergy[ F_SHEAR ]
00634 << " / bend: " << _fenergy[ F_BEND ]
00635
00636 << ")" << std::resetiosflags( std::ios::fixed ) << std::endl;
00637 std::cout << std::endl;
00638 }
00639
00640 if ( DUMP_DISTS ) {
00641 static std::ofstream* fptr;
00642 if ( fptr == 0 ) {
00643 Float distance( (
00644 _initialMesh->getVertex( 1 ) - _initialMesh->getVertex( 0 )
00645 ).length() * 3 );
00646 String filename(
00647 "dists-" + BaStringUtil::fromFloat( distance, 1 ) + ".txt"
00648 );
00649 fptr = new std::ofstream( filename.c_str() );
00650 }
00651 std::ofstream& out = *fptr;
00652 GeMesh::VertexConstIterator vbi = _initialMesh->beginVertex();
00653 GeMesh::VertexConstIterator vi = _mesh->beginVertex();
00654 for ( ; vi != _mesh->endVertex(); ++vi, ++vbi ) {
00655 out << ( *vi - *vbi ).length() << " ";
00656 }
00657 out << std::endl;
00658 }
00659
00660 if ( DUMP_FORCES ) {
00661 static std::ofstream* fptr;
00662 if ( fptr == 0 ) {
00663 Float distance( (
00664 _initialMesh->getVertex( 1 ) - _initialMesh->getVertex( 0 )
00665 ).length() * 3 );
00666 String filename(
00667 "forces-" + BaStringUtil::fromFloat( distance, 2 ) + ".txt"
00668 );
00669 fptr = new std::ofstream( filename.c_str() );
00670 }
00671 std::ofstream& out = *fptr;
00672 for ( UInt32 i = 0; i < _f0i[ F_STRETCH ].size(); ++i ) {
00673 out << _f0i[ F_STRETCH ][ i ].length() << " ";
00674 out << _f0i[ F_SHEAR ][ i ].length() << " ";
00675 out << _f0i[ F_BEND ][ i ].length() << " ";
00676 out << _d0i[ F_STRETCH ][ i ].length() << " ";
00677 out << _d0i[ F_SHEAR ][ i ].length() << " ";
00678 out << _d0i[ F_BEND ][ i ].length() << " ";
00679 }
00680 out << std::endl;
00681 }
00682 }
00683
00684
00685
00686 const GeMesh& SimSimulator::getMesh() const
00687 {
00688 return *_mesh;
00689 }
00690
00691
00692
00693 const RCShdPtr<GeMesh>& SimSimulator::getMeshPtr() const
00694 {
00695 return _mesh;
00696 }
00697
00698
00699
00700 BaTime::Instant SimSimulator::getTime() const
00701 {
00702 return BaTime::floatAsInstant( _time );
00703 }
00704
00705
00706
00707 void SimSimulator::setTimestep( Float h )
00708 {
00709 _h = h;
00710 }
00711
00712
00713
00714 void SimSimulator::setDensity( Float rho )
00715 {
00716 _rho = rho;
00717 setupMass();
00718 }
00719
00720
00721
00722 void SimSimulator::setPCGTolerance( Float tolerance )
00723 {
00724 _modPCG.setTolerance( tolerance );
00725 }
00726
00727
00728
00729 void SimSimulator::setParams( const Params& params )
00730 {
00731 _params = params;
00732 }
00733
00734
00735
00736 Float SimSimulator::getTimestep() const
00737 {
00738 return _h;
00739 }
00740
00741
00742
00743 Float SimSimulator::getDensity() const
00744 {
00745 return _rho;
00746 }
00747
00748
00749
00750 Float SimSimulator::getPCGTolerance() const
00751 {
00752 return _modPCG.getTolerance();
00753 }
00754
00755
00756
00757 const SimSimulator::Params& SimSimulator::getParams() const
00758 {
00759 return _params;
00760 }
00761
00762
00763
00764 GeVector SimSimulator::getVelocity( GeMesh::VertexId vid ) const
00765 {
00766 DGFX_ASSERT( vid < _v0.size() );
00767 return _v0[ vid ];
00768 }
00769
00770
00771
00772 GeVector SimSimulator::getForce( GeMesh::VertexId vid ) const
00773 {
00774 DGFX_ASSERT( vid < _f0.size() );
00775 return _f0[ vid ];
00776 }
00777
00778
00779
00780 GeVector SimSimulator::getForce( ForceType type, GeMesh::VertexId vid ) const
00781 {
00782 DGFX_ASSERT( type < NB_FORCES );
00783 DGFX_ASSERT( vid < _f0i[ type ].size() );
00784 return _f0i[ type ][ vid ];
00785 }
00786
00787
00788
00789 GeVector SimSimulator::getDampingForce(
00790 ForceType type,
00791 GeMesh::VertexId vid
00792 ) const {
00793 DGFX_ASSERT( type < NB_FORCES );
00794 DGFX_ASSERT( vid < _d0i[ type ].size() );
00795 return _d0i[ type ][ vid ];
00796 }
00797
00798
00799
00800 Float SimSimulator::getEnergy( ForceType type ) const
00801 {
00802 DGFX_ASSERT( type < NB_FORCES );
00803 return _fenergy[ type ];
00804 }
00805
00806
00807
00808 Float SimSimulator::getTriEnergy( ForceType type, GeMesh::FaceId fid ) const
00809 {
00810 DGFX_ASSERT( type < F_GRAVITY );
00811 DGFX_ASSERT( fid < _trienergy[ type ].size() );
00812 return _trienergy[ type ][ fid ];
00813 }
00814
00815
00816
00817 void SimSimulator::setMesh( const GeMesh& mesh )
00818 {
00819 DGFX_ASSERT( mesh.getNbVertices() == _initialMesh->getNbVertices() );
00820 DGFX_ASSERT( mesh.getNbFaces() == _initialMesh->getNbFaces() );
00821 _mesh = RCShdPtr<GeMesh>( new GeMesh( mesh ) );
00822 }
00823
00824
00825
00826
00827
00828 void SimSimulator::calcStretchShear(
00829 const GeMesh::FaceWrapper& face
00830 ) {
00831 UInt32 m;
00832
00833
00834 GeMesh::VertexType x[3];
00835 GeMesh::TextureVertexType tp[3];
00836 for( m = 0; m < 3; ++m ) {
00837 x[ m ] = face.getVertex( m );
00838 tp[ m ] = _initialMesh->getTextureVertex( face.getVertexId( m ) );
00839 }
00840 if ( DEBUG_COMMON ) {
00841 std::cout << "x0 = " << x[0] << " x1 = " << x[1]
00842 << " x2 = " << x[2] << std::endl;
00843 }
00844
00845 GeVector v0[ 3 ];
00846 for( m = 0; m < 3; ++m ) {
00847 UInt32 vid = face.getVertexId( m );
00848 v0[ m ] = _v0[ vid ];
00849 }
00850
00851 CommonVars cv;
00852 cv.calc( x, tp );
00853 if ( DEBUG_COMMON ) {
00854 cv.debugOutput( std::cout );
00855 }
00856
00857 calcStretch( face, cv, x, tp, v0 );
00858 calcShear( face, cv, x, tp, v0 );
00859
00860 if ( VERIFY_COMMON ) {
00861 #if DO_NORM
00862 const Float MAX_VERIFY_ERROR = .01;
00863 const Float MAX_VERIFY_ERROR_M = MAX_VERIFY_ERROR * 3;
00864 const Float VERIFY_STEP = .001;
00865 CommonVars ver_cv[3][3];
00866 for( m = 0; m < 3; ++m ) for( UInt32 s = 0; s < 3; ++s ) {
00867 GePoint testx[3] = { x[0], x[1], x[2] };
00868 testx[ m ][ s ] += VERIFY_STEP;
00869 ver_cv[ m ][ s ].calc( testx, tp );
00870 }
00871
00872 bool DISPLAY;
00873
00874 UInt32 n,s,t;
00875 DISPLAY = false;
00876 for( m = 0; m < 3; ++m ) for( UInt32 s = 0; s < 3; ++s ) {
00877 const CommonVars& testcv = ver_cv[m][s];
00878
00879 GeVector testdwu_dxm = ( testcv.wu - cv.wu ) / VERIFY_STEP;
00880 GeVector testdwv_dxm = ( testcv.wv - cv.wv ) / VERIFY_STEP;
00881
00882 Float err;
00883
00884 if ( DISPLAY ) {
00885 std::cout << "testdwu_dxm[ " << m << " ][ " << s << " ] = "
00886 << testdwu_dxm << std::endl;
00887 }
00888 err = ( testdwu_dxm - cv.dwu_dxm[m][s] ).infinityNorm();
00889 DGFX_ASSERT( err < MAX_VERIFY_ERROR );
00890
00891 if ( DISPLAY ) {
00892 std::cout << "testdwv_dxm[ " << m << " ][ " << s << " ] = "
00893 << testdwv_dxm << std::endl;
00894 }
00895 err = ( testdwv_dxm - cv.dwv_dxm[m][s] ).infinityNorm();
00896 DGFX_ASSERT( err < MAX_VERIFY_ERROR );
00897 }
00898
00899 DISPLAY = false;
00900 for ( n = 0; n < 3; ++n ) for( m = 0; m < 3; ++m ) {
00901 for( s = 0; s < 3; ++s ) for( t = 0; t < 3; ++t ) {
00902 const CommonVars& testcv = ver_cv[n][t];
00903 GeVector testd2wu_dxmdxn =
00904 (testcv.dwu_dxm[m][s] - cv.dwu_dxm[m][s]) / VERIFY_STEP;
00905 GeVector testd2wv_dxmdxn =
00906 (testcv.dwv_dxm[m][s] - cv.dwv_dxm[m][s]) / VERIFY_STEP;
00907
00908 Float err;
00909
00910 if ( DISPLAY ) {
00911 std::cout << "testd2wu_dxmdxn[" << m << "][" << n << "]["
00912 << s << "][" << t << "] = "
00913 << testd2wu_dxmdxn << std::endl;
00914 }
00915 err = (
00916 testd2wu_dxmdxn - cv.d2wu_dxmdxn[m][n][s][t]
00917 ).infinityNorm();
00918 DGFX_ASSERT( err < MAX_VERIFY_ERROR_M );
00919
00920 if ( DISPLAY ) {
00921 std::cout << "testd2wv_dxmdxn[" << m << "][" << n << "]["
00922 << s << "][" << t << "] = "
00923 << testd2wv_dxmdxn << std::endl;
00924 }
00925 err = (
00926 testd2wv_dxmdxn - cv.d2wv_dxmdxn[m][n][s][t]
00927 ).infinityNorm();
00928 DGFX_ASSERT( err < MAX_VERIFY_ERROR_M );
00929 }
00930 }
00931 #endif
00932
00933 }
00934 }
00935
00936
00937
00938
00939 void SimSimulator::calcStretch(
00940 const GeMesh::FaceWrapper& face,
00941 const CommonVars &cv,
00942 const GePoint x[3],
00943 const GePoint tp[3],
00944 const GeVector v0[ 3 ]
00945 ) {
00946 const Float MAX_VERIFY_ERROR = .01f;
00947 const Float MAX_VERIFY_ERROR_M = MAX_VERIFY_ERROR * 3;
00948 const Float VERIFY_STEP = .001f;
00949 UInt32 m,n,s,t;
00950
00951 StretchVars stv;
00952 stv.calc( cv, v0, _params._b_u, _params._b_v );
00953
00954 if ( DEBUG_STRETCH ) {
00955 stv.debugOutput( std::cout );
00956 }
00957
00958 for ( m = 0; m < 3; ++m ) {
00959 UInt32 vid = face.getVertexId( m );
00960 GeVector val;
00961
00962
00963 val = -_params._k_stretch * (
00964 stv.dCu_dxm[ m ] * stv.Cu + stv.dCv_dxm[ m ] * stv.Cv
00965 );
00966 _f0[ vid ] += val;
00967 DO_DEBUG( _f0i[ F_STRETCH ][ vid ] += val );
00968 if ( DEBUG_STRETCH ) {
00969 std::cout << "f0[stretch][ " << m << " ] = " << val << std::endl;
00970 }
00971
00972 val = -_params._k_damp * _params._k_stretch * (
00973 stv.dCu_dxm[ m ] * stv.dCu_dt
00974 + stv.dCv_dxm[ m ] * stv.dCv_dt
00975 );
00976 _f0[ vid ] += val;
00977
00978 DO_DEBUG( _d0i[ F_STRETCH ][ vid ] += val );
00979 if ( DEBUG_STRETCH ) {
00980 std::cout << "d0[stretch][ " << m << " ] = " << val << std::endl;
00981 }
00982 }
00983 for ( m = 0; m < 3; ++m ) for ( n = 0; n < 3; ++n ) {
00984 UInt32 vidm = face.getVertexId( m );
00985 UInt32 vidn = face.getVertexId( n );
00986 GeMatrix3 val;
00987
00988
00989 val = -_params._k_stretch * (
00990 GeMatrix3::outerProduct( stv.dCu_dxm[ m ], stv.dCu_dxm[ n ] )
00991 + GeMatrix3::outerProduct( stv.dCv_dxm[ m ], stv.dCv_dxm[ n ] )
00992 + stv.d2Cu_dxmdxn[ m ][ n ] * stv.Cu
00993 + stv.d2Cv_dxmdxn[ m ][ n ] * stv.Cv
00994 );
00995 _df_dx[ vidn ][ vidm ] += val;
00996 if ( DEBUG_STRETCH ) {
00997 _df_dxi[ F_STRETCH ][ vidn ][ vidm ] += val;
00998 std::cout << "df_dx[stretch][ " << m << " ][ " << n << " ] = "
00999 << val << std::endl;
01000 }
01001
01002 val = -_params._k_damp * _params._k_stretch * (
01003 stv.d2Cu_dxmdxn[ m ][ n ] * stv.dCu_dt
01004 + stv.d2Cv_dxmdxn[ m ][ n ] * stv.dCv_dt
01005 );
01006 _df_dx[ vidn ][ vidm ] += val;
01007 if ( DEBUG_STRETCH ) {
01008 _dd_dxi[ F_STRETCH ][ vidn ][ vidm ] += val;
01009 std::cout << "dd_dx[stretch][ " << m << " ][ " << n << " ] = "
01010 << val << std::endl;
01011 }
01012
01013 val = -_params._k_damp * _params._k_stretch * (
01014 GeMatrix3::outerProduct( stv.dCu_dxm[m], stv.dCu_dxm[n] )
01015 + GeMatrix3::outerProduct( stv.dCv_dxm[m], stv.dCv_dxm[n] )
01016 );
01017 _df_dv[ vidn ][ vidm ] += val;
01018 if ( DEBUG_STRETCH ) {
01019 _dd_dvi[ F_STRETCH ][ vidn ][ vidm ] += val;
01020 std::cout << "dd_dv[stretch][ " << m << " ][ " << n << " ] = "
01021 << val << std::endl;
01022 }
01023 }
01024
01025 Float E = _params._k_stretch * .5 * ( stv.Cu * stv.Cu + stv.Cv * stv.Cv );
01026 _trienergy[ F_STRETCH ][ face.getFaceId() ] = E;
01027 _fenergy[ F_STRETCH ] += E;
01028
01029 if ( DEBUG_STRETCH ) {
01030 std::cout << std::endl;
01031 }
01032
01033 if ( VERIFY_STRETCH ) {
01034 StretchVars ver_stv[3][3];
01035 for( m = 0; m < 3; ++m ) for( UInt32 s = 0; s < 3; ++s ) {
01036 GePoint testx[3] = { x[0], x[1], x[2] };
01037 testx[ m ][ s ] += VERIFY_STEP;
01038 CommonVars ver_cv;
01039 ver_cv.calc( testx, tp );
01040 ver_stv[ m ][ s ].calc( ver_cv, v0, _params._b_u, _params._b_v );
01041 }
01042 bool DISPLAY;
01043
01044 DISPLAY = false;
01045 for( m = 0; m < 3; ++m ) {
01046 GeVector testdCu_dxm, testdCv_dxm;
01047 for( UInt32 s = 0; s < 3; ++s ) {
01048 const StretchVars& teststv = ver_stv[m][s];
01049 testdCu_dxm[ s ] = ( teststv.Cu - stv.Cu ) / VERIFY_STEP;
01050 testdCv_dxm[ s ] = ( teststv.Cv - stv.Cv ) / VERIFY_STEP;
01051 }
01052 Float err;
01053 if ( DISPLAY ) {
01054 std::cout << "testdCu_dxm[ " << m << " ] = " << testdCu_dxm << std::endl;
01055 std::cout << "testdCv_dxm[ " << m << " ] = " << testdCv_dxm << std::endl;
01056 }
01057 err = (
01058 testdCu_dxm - stv.dCu_dxm[ m ]
01059 ).infinityNorm();
01060 DGFX_ASSERT( err < MAX_VERIFY_ERROR_M );
01061 err = (
01062 testdCv_dxm - stv.dCv_dxm[ m ]
01063 ).infinityNorm();
01064 DGFX_ASSERT( err < MAX_VERIFY_ERROR_M );
01065 }
01066
01067 DISPLAY = false;
01068 for( m = 0; m < 3; ++m ) for ( n = 0; n < 3; ++n ) {
01069 GeMatrix3 testd2Cu_dxmdxn, testd2Cv_dxmdxn;
01070 for( t = 0; t < 3; ++t ) {
01071 const StretchVars& teststv = ver_stv[n][t];
01072 const GeVector diffu( teststv.dCu_dxm[ m ] - stv.dCu_dxm[ m ] );
01073 const GeVector diffv( teststv.dCv_dxm[ m ] - stv.dCv_dxm[ m ] );
01074 for( s = 0; s < 3; ++s ) {
01075 testd2Cu_dxmdxn( t, s ) = diffu[ s ] / VERIFY_STEP;
01076 testd2Cv_dxmdxn( t, s ) = diffv[ s ] / VERIFY_STEP;
01077 }
01078 }
01079
01080 Float err;
01081 if ( DISPLAY ) {
01082 std::cout << "testd2Cu_dxmdxn[ " << m << " ][ " << n
01083 << " ] = " << testd2Cu_dxmdxn << std::endl;
01084 }
01085 err = (
01086 testd2Cu_dxmdxn - stv.d2Cu_dxmdxn[ m ][ n ]
01087 ).infinityNorm();
01088 DGFX_ASSERT( err < MAX_VERIFY_ERROR_M );
01089
01090 if ( DISPLAY ) {
01091 std::cout << "testd2Cv_dxmdxn[ " << m << " ][ " << n
01092 << " ] = " << testd2Cv_dxmdxn << std::endl;
01093 }
01094 err = (
01095 testd2Cv_dxmdxn - stv.d2Cv_dxmdxn[ m ][ n ]
01096 ).infinityNorm();
01097 DGFX_ASSERT( err < MAX_VERIFY_ERROR_M );
01098 }
01099 }
01100 }
01101
01102
01103
01104 void SimSimulator::calcShear(
01105 const GeMesh::FaceWrapper& face,
01106 const CommonVars &cv,
01107 const GePoint x[4],
01108 const GePoint tp[4],
01109 const GeVector v0[ 3 ]
01110 ) {
01111 const Float MAX_VERIFY_ERROR = .01f;
01112 const Float MAX_VERIFY_ERROR_M = MAX_VERIFY_ERROR * 3;
01113 const Float VERIFY_STEP = .001f;
01114 UInt32 m,n,s,t;
01115
01116 ShearVars shv;
01117 shv.calc( cv, v0 );
01118
01119 if ( DEBUG_SHEAR ) {
01120 shv.debugOutput( std::cout );
01121 }
01122
01123 for ( m = 0; m < 3; ++m ) {
01124 UInt32 vid = face.getVertexId( m );
01125 GeVector val;
01126
01127 val = -_params._k_shear * shv.dC_dxm[ m ] * shv.C;
01128 _f0[ vid ] += val;
01129 DO_DEBUG( _f0i[ F_SHEAR ][ vid ] += val );
01130 if ( DEBUG_SHEAR ) {
01131 std::cout << "f0[shear][ " << m << " ] = " << val << std::endl;
01132 }
01133
01134 val = -_params._k_damp * _params._k_shear
01135 * shv.dC_dxm[ m ] * shv.dC_dt;
01136 _f0[ vid ] += val;
01137
01138 DO_DEBUG( _d0i[ F_SHEAR ][ vid ] += val );
01139 if ( DEBUG_SHEAR ) {
01140 std::cout << "d0[shear][ " << m << " ] = " << val << std::endl;
01141 }
01142 }
01143 for ( m = 0; m < 3; ++m ) for ( n = 0; n < 3; ++n ) {
01144 UInt32 vidm = face.getVertexId( m );
01145 UInt32 vidn = face.getVertexId( n );
01146 GeMatrix3 val;
01147 val = -_params._k_shear * (
01148 GeMatrix3::outerProduct( shv.dC_dxm[ m ], shv.dC_dxm[ n ] )
01149 + shv.d2C_dxmdxn[ m ][ n ] * shv.C
01150 );
01151 _df_dx[ vidn ][ vidm ] += val;
01152 if ( DEBUG_SHEAR ) {
01153 _df_dxi[ F_SHEAR ][ vidn ][ vidm ] += val;
01154 std::cout << "df_dx[shear][ " << m << " ][ " << n << " ] = "
01155 << val << std::endl;
01156 }
01157
01158 val = -_params._k_damp * _params._k_shear
01159 * shv.d2C_dxmdxn[ m ][ n ] * shv.dC_dt;
01160 _df_dx[ vidn ][ vidm ] += val;
01161 if ( DEBUG_SHEAR ) {
01162 _dd_dxi[ F_SHEAR ][ vidn ][ vidm ] += val;
01163 std::cout << "dd_dx[shear][ " << m << " ][ " << n << " ] = "
01164 << val << std::endl;
01165 }
01166
01167 val = -_params._k_damp * _params._k_shear
01168 * GeMatrix3::outerProduct( shv.dC_dxm[ m ], shv.dC_dxm[ n ] );
01169 _df_dv[ vidn ][ vidm ] += val;
01170
01171 if ( DEBUG_SHEAR ) {
01172 _dd_dvi[ F_SHEAR ][ vidn ][ vidm ] += val;
01173 std::cout << "dd_dv[shear][ " << m << " ][ " << n << " ] = "
01174 << val << std::endl;
01175 }
01176 }
01177
01178 Float E = _params._k_shear * .5 * shv.C * shv.C;
01179 _trienergy[ F_SHEAR ][ face.getFaceId() ] = E;
01180 _fenergy[ F_SHEAR ] += E;
01181
01182 if ( DEBUG_SHEAR ) {
01183 std::cout << std::endl;
01184 }
01185
01186 if ( VERIFY_SHEAR ) {
01187 ShearVars ver_shv[3][3];
01188 for( m = 0; m < 3; ++m ) for( UInt32 s = 0; s < 3; ++s ) {
01189 GePoint testx[3] = { x[0], x[1], x[2] };
01190 testx[ m ][ s ] += VERIFY_STEP;
01191 CommonVars ver_cv;
01192 ver_cv.calc( testx, tp );
01193 ver_shv[ m ][ s ].calc( ver_cv, v0 );
01194 }
01195 bool DISPLAY;
01196
01197 DISPLAY = false;
01198 for( m = 0; m < 3; ++m ) {
01199 GeVector testdC_dxm;
01200 for( UInt32 s = 0; s < 3; ++s ) {
01201 const ShearVars& testshv = ver_shv[m][s];
01202 testdC_dxm[ s ] = ( testshv.C - shv.C ) / VERIFY_STEP;
01203 }
01204 Float err;
01205 if ( DISPLAY ) {
01206 std::cout << "testdC_dxm[ " << m << " ] = " << testdC_dxm << std::endl;
01207 }
01208 err = (
01209 testdC_dxm - shv.dC_dxm[ m ]
01210 ).infinityNorm();
01211 DGFX_ASSERT( err < MAX_VERIFY_ERROR_M );
01212 }
01213
01214 DISPLAY = false;
01215 for( m = 0; m < 3; ++m ) for ( n = 0; n < 3; ++n ) {
01216 GeMatrix3 testd2C_dxmdxn;
01217 for( t = 0; t < 3; ++t ) {
01218 const ShearVars& testshv = ver_shv[n][t];
01219 const GeVector diff( testshv.dC_dxm[ m ] - shv.dC_dxm[ m ] );
01220 for( s = 0; s < 3; ++s ) {
01221 testd2C_dxmdxn( t, s ) = diff[ s ] / VERIFY_STEP;
01222 }
01223 }
01224
01225 Float err;
01226 if ( DISPLAY ) {
01227 std::cout << "testd2C_dxmdxn[ " << m << " ][ " << n
01228 << " ] = " << testd2C_dxmdxn << std::endl;
01229 }
01230 err = (
01231 testd2C_dxmdxn - shv.d2C_dxmdxn[ m ][ n ]
01232 ).infinityNorm();
01233 DGFX_ASSERT( err < MAX_VERIFY_ERROR_M );
01234 }
01235 }
01236 }
01237
01238
01239
01240 void SimSimulator::calcBend(
01241 const GeMeshWingedEdge::HalfEdgeWrapper& edge
01242 ) {
01243 const Float MAX_VERIFY_ERROR = .01f;
01244 const Float MAX_VERIFY_ERROR_M = MAX_VERIFY_ERROR * 3;
01245 const Float VERIFY_STEP = .001f;
01246 UInt32 m, n, s, t;
01247
01248 GeMeshWingedEdge::HalfEdgeWrapper he_next( edge.getNextHalfEdge() );
01249 GeMeshWingedEdge::HalfEdgeWrapper he_prev( edge.getPrevHalfEdge() );
01250 GeMeshWingedEdge::HalfEdgeWrapper he_twin( edge.getTwinHalfEdge() );
01251
01252 GeMesh::VertexId vid[ 4 ];
01253 vid[ 0 ] = he_prev.getOriginVertexId();
01254 vid[ 1 ] = edge.getOriginVertexId();
01255 vid[ 2 ] = he_next.getOriginVertexId();
01256 vid[ 3 ] = he_twin.getPrevHalfEdge().getOriginVertexId();
01257 GeMesh::VertexType x[ 4 ];
01258 GeMesh::TextureVertexType tv[ 4 ];
01259 GeVector v[ 4 ];
01260 for( m = 0; m < 4; ++m ) {
01261 x[ m ] = _mesh->getVertex( vid[ m ] );
01262 tv[ m ] = _initialMesh->getTextureVertex( vid[ m ] );
01263 v[ m ] = _v0[ vid[ m ] ];
01264 }
01265
01266 const Float du = tv[ 1 ]._x - tv[ 2 ]._x;
01267 const Float dv = tv[ 1 ]._y - tv[ 2 ]._y;
01268 const Float k = (
01269 _params._k_bend_u * du*du + _params._k_bend_v * dv*dv ) /
01270 (du*du + dv*dv);
01271
01272 BendVars bv;
01273 bv.calc( x, v );
01274 if ( DEBUG_BEND ) {
01275 std::cout << "x0 = " << x[0] << " x1 = " << x[1]
01276 << " x2 = " << x[2] << " x3 = " << x[3] << std::endl;
01277 std::cout << "k = " << k << std::endl;
01278 bv.debugOutput( std::cout );
01279 }
01280
01281
01282 for ( m = 0; m < 4; ++m ) {
01283 GeVector val;
01284
01285 val = -k * bv.dC_dxm[ m ] * bv.C;
01286 _f0[ vid[ m ] ] += val;
01287 DO_DEBUG( _f0i[ F_BEND ][ vid[ m ] ] += val );
01288 if ( DEBUG_BEND ) {
01289 std::cout << "f0[bend][ " << m << " ] = " << val << std::endl;
01290 }
01291
01292 val = -_params._k_damp * k * bv.dC_dxm[ m ] * bv.dC_dt;
01293 _f0[ vid[ m ] ] += val;
01294
01295 DO_DEBUG( _d0i[ F_BEND ][ vid[ m ] ] += val );
01296 if ( DEBUG_BEND ) {
01297 std::cout << "d0[bend][ " << m << " ] = " << val << std::endl;
01298 }
01299 }
01300
01301 Float E = .5 * k * bv.C * bv.C;
01302
01303 _trienergy[ F_BEND ][ edge.getFaceId() ] += E * .5;
01304 _trienergy[ F_BEND ][ he_twin.getFaceId() ] += E * .5;
01305 _fenergy[ F_BEND ] += E;
01306
01307 for ( m = 0; m < 4; ++m ) for ( n = 0; n < 4; ++n ) {
01308 GeMatrix3 val;
01309 val = -k * (
01310 GeMatrix3::outerProduct( bv.dC_dxm[ m ], bv.dC_dxm[ n ] )
01311 + bv.d2C_dxmdxn[ m ][ n ] * bv.C
01312 );
01313 _df_dx[ vid[ n ] ][ vid[ m ] ] += val;
01314 if ( DEBUG_BEND ) {
01315 _df_dxi[ F_BEND ][ vid[ n ] ][ vid[ m ] ] += val;
01316 std::cout << "df_dx[bend][ " << m << " ][ " << n << " ] = "
01317 << val << std::endl;
01318 }
01319
01320 val = -_params._k_damp * k
01321 * bv.d2C_dxmdxn[ m ][ n ] * bv.dC_dt;
01322 _df_dx[ vid[ n ] ][ vid[ m ] ] += val;
01323 if ( DEBUG_BEND ) {
01324 _dd_dxi[ F_BEND ][ vid[ n ] ][ vid[ m ] ] += val;
01325 std::cout << "dd_dx[bend][ " << m << " ][ " << n << " ] = "
01326 << val << std::endl;
01327 }
01328
01329 val = -_params._k_damp * k
01330 * GeMatrix3::outerProduct( bv.dC_dxm[ m ], bv.dC_dxm[ n ] );
01331 _df_dv[ vid[ n ] ][ vid[ m ] ] += val;
01332
01333 if ( DEBUG_BEND ) {
01334 _dd_dvi[ F_BEND ][ vid[ n ] ][ vid[ m ] ] += val;
01335 std::cout << "dd_dv[bend][ " << m << " ][ " << n << " ] = "
01336 << val << std::endl;
01337 }
01338 }
01339 if ( DEBUG_BEND ) {
01340 std::cout << std::endl << std::endl;
01341 }
01342
01343 if ( VERIFY_BEND ) {
01344 BendVars ver_bv[4][3];
01345 for( m = 0; m < 4; ++m ) for( UInt32 s = 0; s < 3; ++s ) {
01346 GePoint testx[4] = { x[0], x[1], x[2], x[3] };
01347 testx[ m ][ s ] += VERIFY_STEP;
01348 ver_bv[ m ][ s ].calc( testx, v, bv );
01349 }
01350 bool DISPLAY;
01351
01352 DISPLAY = false;
01353 for( m = 0; m < 4; ++m ) for( UInt32 s = 0; s < 3; ++s ) {
01354 const BendVars& testbv = ver_bv[m][s];
01355
01356 GeVector testdnA_dxm = ( testbv.nA - bv.nA ) / VERIFY_STEP;
01357 GeVector testdnB_dxm = ( testbv.nB - bv.nB ) / VERIFY_STEP;
01358 GeVector testde_dxm = ( testbv.e - bv.e ) / VERIFY_STEP;
01359
01360 Float err;
01361
01362 if ( DISPLAY ) {
01363 std::cout << "testdnA_dxm[ " << m << " ][ " << s << "] = "
01364 << testdnA_dxm << std::endl;
01365 }
01366 err = ( testdnA_dxm - bv.dnA_dxm[m][s] ).infinityNorm();
01367 DGFX_ASSERT( err < MAX_VERIFY_ERROR );
01368
01369 if ( DISPLAY ) {
01370 std::cout << "testdnB_dxm[ " << m << " ][ " << s << "] = "
01371 << testdnB_dxm << std::endl;
01372 }
01373 err = ( testdnB_dxm - bv.dnB_dxm[m][s] ).infinityNorm();
01374 DGFX_ASSERT( err < MAX_VERIFY_ERROR );
01375
01376 if ( DISPLAY ) {
01377 std::cout << "testde_dxm[ " << m << " ][ " << s << "] = "
01378 << testde_dxm << std::endl;
01379 }
01380 err = ( testde_dxm - bv.de_dxm[m][s] ).infinityNorm();
01381 DGFX_ASSERT( err < MAX_VERIFY_ERROR );
01382 }
01383
01384 DISPLAY = false;
01385 for( n = 0; n < 4; ++n ) {
01386 GeVector testd2nA_dxmdxn[ 4 ][ 3 ][ 3 ];
01387 GeVector testd2nB_dxmdxn[ 4 ][ 3 ][ 3 ];
01388 GeVector testd2e_dxmdxn[ 4 ][ 3 ][ 3 ];
01389 for( t = 0; t < 3; ++t ) {
01390 const BendVars& testbv = ver_bv[n][t];
01391 for( m = 0; m < 4; ++m ) for( s = 0; s < 3; ++s ) {
01392 testd2nA_dxmdxn[ m ][ s ][ t ] =
01393 ( testbv.dnA_dxm[ m ][ s ] - bv.dnA_dxm[ m ][ s ] ) /
01394 VERIFY_STEP;
01395 testd2nB_dxmdxn[ m ][ s ][ t ] =
01396 ( testbv.dnB_dxm[ m ][ s ] - bv.dnB_dxm[ m ][ s ] ) /
01397 VERIFY_STEP;
01398 testd2e_dxmdxn[ m ][ s ][ t ] =
01399 ( testbv.de_dxm[ m ][ s ] - bv.de_dxm[ m ][ s ] ) /
01400 VERIFY_STEP;
01401 }
01402 }
01403 Float err;
01404 for ( m = 0; m < 4; ++m ) {
01405 for ( s = 0; s < 3; ++s ) for ( t = 0; t < 3; ++t ) {
01406 if ( DISPLAY ) {
01407 std::cout << "testd2nA_dxmdxn[ " << m << " ][ "
01408 << n << " ][ " << s << " ][ " << t << " ] = "
01409 << testd2nA_dxmdxn[ m ][ s ][ t ] << std::endl;
01410 }
01411 testd2nA_dxmdxn[m][s][t] -= bv.d2nA_dxmdxn[m][n][s][t];
01412 err = testd2nA_dxmdxn[m][s][t].infinityNorm();
01413 DGFX_ASSERT( err < MAX_VERIFY_ERROR );
01414
01415 if ( DISPLAY ) {
01416 std::cout << "testd2nB_dxmdxn[ " << m << " ][ "
01417 << n << " ][ " << s << " ][ " << t << " ] = "
01418 << testd2nB_dxmdxn[ m ][ s ][ t ] << std::endl;
01419 }
01420 testd2nB_dxmdxn[m][s][t] -= bv.d2nB_dxmdxn[m][n][s][t];
01421 err = testd2nB_dxmdxn[m][s][t].infinityNorm();
01422 DGFX_ASSERT( err < MAX_VERIFY_ERROR );
01423
01424 if ( DISPLAY ) {
01425 std::cout << "testd2e_dxmdxn[ " << m << " ][ "
01426 << n << " ][ " << s << " ][ " << t << " ] = "
01427 << testd2e_dxmdxn[ m ][ s ][ t ] << std::endl;
01428 }
01429 #if DO_NORM
01430 testd2e_dxmdxn[m][s][t] -= bv.d2e_dxmdxn[m][n][s][t];
01431 #endif
01432 err = testd2e_dxmdxn[m][s][t].infinityNorm();
01433 DGFX_ASSERT( err < MAX_VERIFY_ERROR );
01434 }
01435 }
01436 }
01437
01438 DISPLAY = false;
01439 for( m = 0; m < 4; ++m ) {
01440 GeVector testdcosth_dxm, testdsinth_dxm;
01441 for( UInt32 s = 0; s < 3; ++s ) {
01442 const BendVars& testbv = ver_bv[m][s];
01443
01444 testdcosth_dxm[ s ] = (testbv.costh - bv.costh ) / VERIFY_STEP;
01445 testdsinth_dxm[ s ] = (testbv.sinth - bv.sinth ) / VERIFY_STEP;
01446 }
01447 Float err;
01448
01449 if ( DISPLAY ) {
01450 std::cout << "testdcosth_dxm[ " << m << " ] = "
01451 << testdcosth_dxm << std::endl;
01452 }
01453 err = (
01454 testdcosth_dxm - bv.dcosth_dxm[ m ]
01455 ).infinityNorm();
01456 DGFX_ASSERT( err < MAX_VERIFY_ERROR );
01457 if ( DISPLAY ) {
01458 std::cout << "testdsinth_dxm[ " << m << " ] = "
01459 << testdsinth_dxm << std::endl;
01460 }
01461 err = (
01462 testdsinth_dxm - bv.dsinth_dxm[ m ]
01463 ).infinityNorm();
01464 DGFX_ASSERT( err < MAX_VERIFY_ERROR );
01465 }
01466
01467 DISPLAY = false;
01468 for( n = 0; n < 4; ++n ) {
01469 for( m = 0; m < 4; ++m ) {
01470 GeMatrix3 testd2costh_dxmdxn, testd2sinth_dxmdxn;
01471 for( t = 0; t < 3; ++t ) {
01472 const BendVars& testbv = ver_bv[n][t];
01473 const GeVector diffc(
01474 ( testbv.dcosth_dxm[ m ] - bv.dcosth_dxm[ m ] ) / VERIFY_STEP
01475 );
01476 const GeVector diffs(
01477 ( testbv.dsinth_dxm[ m ] - bv.dsinth_dxm[ m ] ) / VERIFY_STEP
01478 );
01479 for ( s = 0; s < 3; ++s ) {
01480 testd2costh_dxmdxn( t, s ) = diffc[ s ];
01481 testd2sinth_dxmdxn( t, s ) = diffs[ s ];
01482 }
01483 }
01484
01485 Float err;
01486
01487 if ( DISPLAY ) {
01488 std::cout << "testd2costh_dxmdxn[ " << m << " ][ " << n << " ] = "
01489 << testd2costh_dxmdxn << std::endl;
01490 }
01491 err = (
01492 testd2costh_dxmdxn - bv.d2costh_dxmdxn[ m ][ n ]
01493 ).infinityNorm();
01494 DGFX_ASSERT( err < MAX_VERIFY_ERROR_M );
01495
01496 if ( DISPLAY ) {
01497 std::cout << "testd2sinth_dxmdxn[ " << m << " ][ " << n << " ] = "
01498 << testd2sinth_dxmdxn << std::endl;
01499 }
01500 err = (
01501 testd2sinth_dxmdxn - bv.d2sinth_dxmdxn[ m ][ n ]
01502 ).infinityNorm();
01503 DGFX_ASSERT( err < MAX_VERIFY_ERROR_M );
01504 }
01505 }
01506
01507 DISPLAY = false;
01508 for( m = 0; m < 4; ++m ) {
01509 GeVector testdC_dxm;
01510 for( UInt32 s = 0; s < 3; ++s ) {
01511 const BendVars& testbv = ver_bv[m][s];
01512 testdC_dxm[ s ] = ( testbv.C - bv.C ) / VERIFY_STEP;
01513 }
01514 Float err;
01515 if ( DISPLAY ) {
01516 std::cout << "testdC_dxm[ " << m << " ] = "
01517 << testdC_dxm << std::endl;
01518 }
01519 err = (
01520 testdC_dxm - bv.dC_dxm[ m ]
01521 ).infinityNorm();
01522 DGFX_ASSERT( err < MAX_VERIFY_ERROR_M );
01523 }
01524
01525 DISPLAY = false;
01526 for ( n = 0; n < 4; ++n ) for( m = 0; m < 4; ++m ) {
01527 GeMatrix3 testd2C_dxmdxn;
01528 for( t = 0; t < 3; ++t ) {
01529 const BendVars& testbv = ver_bv[n][t];
01530 const GeVector diff( testbv.dC_dxm[ m ] - bv.dC_dxm[ m ] );
01531 for( s = 0; s < 3; ++s ) {
01532 testd2C_dxmdxn( t, s ) = diff[ s ] / VERIFY_STEP;
01533 }
01534 }
01535
01536 Float err;
01537 if ( DISPLAY ) {
01538 std::cout << "testd2C_dxmdxn[ " << m << " ][ " << n
01539 << " ] = " << testd2C_dxmdxn << std::endl;
01540 }
01541 err = (
01542 testd2C_dxmdxn - bv.d2C_dxmdxn[ m ][ n ]
01543 ).infinityNorm();
01544 DGFX_ASSERT( err < MAX_VERIFY_ERROR_M );
01545 }
01546 }
01547 }
01548
01549
01550
01551
01552
01553
01554
01555 void SimSimulator::CommonVars::calc( const GePoint_3 p, const GePoint_3 tp )
01556 {
01557 du1 = tp[1]._x - tp[0]._x;
01558 dv1 = tp[1]._y - tp[0]._y;
01559 du2 = tp[2]._x - tp[0]._x;
01560 dv2 = tp[2]._y - tp[0]._y;
01561 const Float det = du1 * dv2 - du2 * dv1;
01562
01563 const Float det_inv = 1 / det;
01564
01565
01566
01567
01568
01569 a = .5 * ( tp[ 1 ] - tp[ 0 ] ).cross( tp[ 2 ] - tp[ 0 ] ).length();
01570
01571
01572
01573 wuhat = ((p[1]-p[0]) * dv2 + (p[2]-p[0]) * (-dv1)) * det_inv;
01574 const Float wuh_len = wuhat.length();
01575 DGFX_ASSERT( BaMath::isGreater( wuh_len, 0 ) );
01576 wuhim = 1 / wuh_len;
01577
01578 wu = wuhat * wuhim;
01579
01580
01581
01582 wvhat = (-(p[1]-p[0]) * du2 + (p[2]-p[0]) * du1) * det_inv;
01583 const Float wvh_len = wvhat.length();
01584 DGFX_ASSERT( BaMath::isGreater( wvh_len, 0 ) );
01585 wvhim = 1 / wvh_len;
01586
01587 wv = wvhat * wvhim;
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598 dwhux_dxmx[ 0 ] = (dv1 - dv2) * det_inv;
01599 dwhux_dxmx[ 1 ] = dv2 * det_inv;
01600 dwhux_dxmx[ 2 ] =-dv1 * det_inv;
01601
01602
01603
01604
01605 dwhvx_dxmx[ 0 ] = (du2 - du1) * det_inv;
01606 dwhvx_dxmx[ 1 ] =-du2 * det_inv;
01607 dwhvx_dxmx[ 2 ] = du1 * det_inv;
01608
01609 #if DO_NORM
01610 UInt32 m,n,s,t;
01611
01612 for( m = 0; m < 3; ++m ) {
01613 for ( s = 0; s < 3; ++s ) {
01614
01615
01616
01617 dwu_dxm[ m ][ s ] = wuhim * dwhux_dxmx[ m ] *
01618 ( GeVector::axis( s ) - wu[ s ] * wu );
01619
01620
01621
01622 dwv_dxm[ m ][ s ] = wvhim * dwhvx_dxmx[ m ] *
01623 ( GeVector::axis( s ) - wv[ s ] * wv );
01624 }
01625 }
01626
01627 for( m = 0; m < 3; ++m ) for ( n = 0; n < 3; ++n ) {
01628 for( s = 0; s < 3; ++s ) for ( t = 0; t < 3; ++t ) {
01629
01630
01631
01632
01633
01634
01635 d2wu_dxmdxn[m][n][s][t] =
01636 -wuhim * dwhux_dxmx[ m ] *
01637 (wu[s] * dwu_dxm[n][t] + dwu_dxm[n][t][s] * wu)
01638 - wuhim*wuhim * dwhux_dxmx[m] * dwhux_dxmx[n] *
01639 (GeVector::axis(s) - wu[s]*wu) * wu[t];
01640
01641
01642
01643
01644
01645
01646
01647 d2wv_dxmdxn[m][n][s][t] =
01648 -wvhim * dwhvx_dxmx[ m ] *
01649 (wv[s] * dwv_dxm[n][t] + dwv_dxm[n][t][s] * wv)
01650 - wvhim*wvhim * dwhvx_dxmx[m] * dwhvx_dxmx[n] *
01651 (GeVector::axis(s) - wv[s]*wv) * wv[t];
01652 }
01653 }
01654 #endif
01655 }
01656
01657
01658
01659 void SimSimulator::CommonVars::debugOutput( std::ostream& os ) {
01660 UInt32 m;
01661
01662 os << "a = " << a << std::endl;
01663 os << "wuhat = " << wuhat << " wuhim = " << wuhim << " wu = "
01664 << wu << std::endl;
01665 os << "wvhat = " << wvhat << " wvhim = " << wvhim << " wv = "
01666 << wv << std::endl;
01667 for ( m = 0; m < 3; ++m ) {
01668 os << "dwhux_dxmx[" << m << "] = " << dwhux_dxmx[ m ] << std::endl;
01669 os << "dwhvx_dxmx[" << m << "] = " << dwhvx_dxmx[ m ] << std::endl;
01670 }
01671 #if DO_NORM
01672 UInt32 n,s,t;
01673
01674 for ( m = 0; m < 3; ++m ) for ( s = 0; s < 3; ++s ) {
01675 std::cout << "dwu_dxm[" << m << "][" << s << "] = " << dwu_dxm[m][s]
01676 << std::endl;
01677 std::cout << "dwv_dxm[" << m << "][" << s << "] = " << dwv_dxm[m][s]
01678 << std::endl;
01679 }
01680 for ( m = 0; m < 3; ++m ) for ( n = 0; n < 3; ++n ) {
01681 for ( s = 0; s < 3; ++s ) for ( t = 0; t < 3; ++t ) {
01682 std::cout << "d2wu_dxmdxn[" << m << "][" << n << "][" << s << "]["
01683 << t << "] = " << d2wu_dxmdxn[m][n][s][t] << std::endl;
01684 std::cout << "d2wv_dxmdxn[" << m << "][" << n << "][" << s << "]["
01685 << t << "] = " << d2wv_dxmdxn[m][n][s][t] << std::endl;
01686 }
01687 }
01688 #endif
01689 }
01690
01691
01692
01693
01694
01695
01696
01697 void SimSimulator::StretchVars::calc(
01698 const SimSimulator::CommonVars& cv,
01699 const GeVector v0[ 3 ],
01700 Float b_u, Float b_v
01701 ) {
01702 UInt32 m,n;
01703 #if DO_SCALE_INVARIANT
01704 Float area = BaMath::sqrt( cv.a );
01705 area = area * BaMath::sqrt( area );
01706 #else
01707 const Float area = cv.a;
01708 #endif
01709
01710
01711
01712
01713
01714
01715
01716 Cu = area * ( cv.wuhat.length() - b_u );
01717 Cv = area * ( cv.wvhat.length() - b_v );
01718
01719 for ( m = 0; m < 3; ++m ) {
01720
01721 dCu_dxm[ m ] = area * cv.dwhux_dxmx[ m ] * cv.wu;
01722
01723 dCv_dxm[ m ] = area * cv.dwhvx_dxmx[ m ] * cv.wv;
01724 }
01725
01726
01727 dCu_dt = 0;
01728 dCv_dt = 0;
01729 for( m = 0; m < 3; ++m ) {
01730 dCu_dt += dCu_dxm[ m ].dot( v0[ m ] );
01731 dCv_dt += dCv_dxm[ m ].dot( v0[ m ] );
01732 }
01733
01734
01735
01736
01737 for ( m = 0; m < 3; ++m ) for ( n = 0; n < 3; ++n ) {
01738
01739
01740
01741
01742
01743 d2Cu_dxmdxn[ m ][ n ] =
01744 area * cv.wuhim * cv.dwhux_dxmx[ m ] * cv.dwhux_dxmx[ n ]
01745 * ( GeMatrix3::IDENTITY - GeMatrix3::outerProduct( cv.wu, cv.wu ) );
01746
01747
01748
01749
01750
01751
01752 d2Cv_dxmdxn[ m ][ n ] =
01753 area * cv.wvhim * cv.dwhvx_dxmx[ m ] * cv.dwhvx_dxmx[ n ]
01754 * (GeMatrix3::IDENTITY - GeMatrix3::outerProduct( cv.wv, cv.wv ) );
01755 }
01756 }
01757
01758
01759
01760 void SimSimulator::StretchVars::debugOutput( std::ostream& os )
01761 {
01762 UInt32 m,n;
01763 os << "C = ( " << Cu << ", " << Cv << " ) " << std::endl;
01764 for ( m = 0; m < 3; ++m ) {
01765 os << "dCu_dxm[ " << m << " ] = " << dCu_dxm[ m ] << std::endl;;
01766 os << "dCv_dxm[ " << m << " ] = " << dCv_dxm[ m ] << std::endl;;
01767 }
01768 os << "dCu_dt = " << dCu_dt << std::endl;;
01769 os << "dCv_dt = " << dCv_dt << std::endl;;
01770 for ( m = 0; m < 3; ++m ) for ( n = 0; n < 3; ++n ) {
01771 os << "d2Cu_dxmdxn[ " << m << "," << n << " ] = "
01772 << d2Cu_dxmdxn[ m ][ n ] << std::endl;
01773 os << "d2Cv_dxmdxn[ " << m << "," << n << " ] = "
01774 << d2Cv_dxmdxn[ m ][ n ] << std::endl;
01775 }
01776 }
01777
01778
01779
01780
01781
01782
01783
01784 void SimSimulator::ShearVars::calc(
01785 const SimSimulator::CommonVars& cv,
01786 const GeVector v0[ 3 ]
01787 ) {
01788 UInt32 m,n,s;
01789
01790 #if DO_SCALE_INVARIANT
01791 Float area = BaMath::sqrt( cv.a );
01792 area = area * BaMath::sqrt( area );
01793 #else
01794 Float area = cv.a;
01795 #endif
01796
01797
01798 #if DO_NORM
01799
01800 C = area * cv.wu.dot( cv.wv );
01801 #else
01802 C = area * cv.wuhat.dot( cv.wvhat );
01803 #endif
01804
01805
01806
01807
01808 for ( m = 0; m < 3; ++m ) {
01809 for ( s = 0; s < 3; ++s ) {
01810 dC_dxm[ m ][ s ] = area * (
01811 #if DO_NORM
01812 cv.dwu_dxm[m][s].dot( cv.wv ) +
01813 cv.wu.dot( cv.dwv_dxm[m][s] )
01814 #else
01815 cv.dwhux_dxmx[m] * cv.wvhat[s] +
01816 cv.wuhat[s] * cv.dwhvx_dxmx[m]
01817 #endif
01818 );
01819 }
01820 }
01821
01822
01823 dC_dt = 0;
01824 for( m = 0; m < 3; ++m ) {
01825 dC_dt += dC_dxm[ m ].dot( v0[ m ] );
01826 }
01827
01828 for ( m = 0; m < 3; ++m ) for ( n = 0; n < 3; ++n ) {
01829 #if DO_NORM
01830
01831
01832
01833
01834
01835 for ( s = 0; s < 3; ++s ) for ( t = 0; t < 3; ++t ) {
01836 d2C_dxmdxn[m][n]( t, s ) = area * (
01837 cv.d2wu_dxmdxn[m][n][s][t].dot( cv.wv ) +
01838 cv.dwu_dxm[m][s].dot( cv.dwv_dxm[n][t] ) +
01839 cv.dwu_dxm[n][t].dot( cv.dwv_dxm[m][s] ) +
01840 cv.wu.dot( cv.d2wv_dxmdxn[m][n][s][t] )
01841 );
01842 }
01843 #else
01844
01845
01846
01847 d2C_dxmdxn[m][n] = GeMatrix3::ZERO;
01848 for ( s = 0; s < 3; ++s ) {
01849 d2C_dxmdxn[m][n]( s, s ) = area * (
01850 cv.dwhux_dxmx[m] * cv.dwhvx_dxmx[n] +
01851 cv.dwhux_dxmx[n] * cv.dwhvx_dxmx[m]
01852 );
01853 }
01854 #endif
01855 }
01856
01857 }
01858
01859
01860
01861 void SimSimulator::ShearVars::debugOutput( std::ostream& os )
01862 {
01863 UInt32 m,n;
01864
01865 os << "C = ( " << C << " ) " << std::endl;
01866 for ( m = 0; m < 3; ++m ) {
01867 os << "dC_dxm[ " << m << " ] = " << dC_dxm[ m ] << std::endl;;
01868 }
01869 os << "dC_dt = " << dC_dt << std::endl;;
01870 for ( m = 0; m < 3; ++m ) for ( n = 0; n < 3; ++n ) {
01871 os << "d2C_dxmdxn[ " << m << "," << n << " ] = "
01872 << d2C_dxmdxn[ m ][ n ] << std::endl;
01873 }
01874 }
01875
01876
01877
01878
01879
01880
01881
01882 void SimSimulator::BendVars::calc(
01883 const GePoint_4 x,
01884 const GeVector_4 v
01885 ) {
01886
01887
01888
01889
01890
01891 calcNE( x );
01892 mainCalc( x, v );
01893 }
01894
01895
01896
01897 void SimSimulator::BendVars::calc(
01898 const GePoint_4 x,
01899 const GeVector_4 v,
01900 const BendVars& bv
01901 ) {
01902 calcNE( x );
01903 #if !DO_NORM
01904
01905
01906
01907 nA *= bv.nAhim / nAhim;
01908 nAhim = bv.nAhim;
01909 nB *= bv.nBhim / nBhim;
01910 nBhim = bv.nBhim;
01911 e *= bv.ehim / ehim;
01912 ehim = bv.ehim;
01913 #endif
01914 mainCalc( x, v );
01915 }
01916
01917
01918
01919 void SimSimulator::BendVars::mainCalc(
01920 const GePoint_4 x,
01921 const GeVector_4 v0
01922 ) {
01923 UInt32 m;
01924
01925 calcThetas();
01926 calcQs( x );
01927 calcDqs();
01928 calcNEderiv();
01929 calcD2NE();
01930 calcCosSinDeriv();
01931 calcD2cossinth();
01932 calcCderivs();
01933
01934 dC_dt = 0;
01935
01936 for( m = 0; m < 4; ++m ) {
01937 dC_dt += dC_dxm[ m ].dot( v0[ m ] );
01938 }
01939 }
01940
01941
01942
01943 void SimSimulator::BendVars::calcNE( const GePoint_4 x )
01944 {
01945
01946 const GeVector nhatA( (x[2] - x[0]).cross( x[1] - x[0] ) );
01947
01948 nAhim = 1 / nhatA.length();
01949
01950 nA = nAhim * nhatA;
01951
01952
01953 const GeVector nhatB( (x[1] - x[3]).cross( x[2] - x[3] ) );
01954 nBhim = 1 / nhatB.length();
01955
01956 nB = nBhim * nhatB;
01957
01958
01959 const GeVector ehat( x[1] - x[2] );
01960 ehim = 1 / ehat.length();
01961
01962 e = ehim * ehat;
01963 }
01964
01965
01966
01967 void SimSimulator::BendVars::calcThetas()
01968 {
01969
01970 costh = nA.dot( nB );
01971
01972 sinth = nA.cross( nB ).dot( e );
01973
01974
01975
01976 C = BaMath::arctan2( sinth, costh );
01977 }
01978
01979
01980
01981 void SimSimulator::BendVars::calcQs( const GePoint_4 x )
01982 {
01983
01984
01985
01986
01987
01988 qA[ 0 ] = x[2] - x[1];
01989 qA[ 1 ] = x[0] - x[2];
01990 qA[ 2 ] = x[1] - x[0];
01991 qA[ 3 ] = GeVector::ZERO;
01992
01993
01994
01995
01996
01997
01998 qB[ 0 ] = GeVector::ZERO;
01999 qB[ 1 ] = x[2] - x[3];
02000 qB[ 2 ] = x[3] - x[1];
02001 qB[ 3 ] = x[1] - x[2];
02002
02003
02004
02005 qe[ 0 ] = 0;
02006 qe[ 1 ] = 1;
02007 qe[ 2 ] = -1;
02008 qe[ 3 ] = 0;
02009 }
02010
02011
02012
02013 void SimSimulator::BendVars::calcDqs()
02014 {
02015
02016
02017
02018 const Int32 D1[4][4] = {
02019 { 0, -1, 1, 0 },
02020 { 1, 0, -1, 0 },
02021 { -1, 1, 0, 0 },
02022 { 0, 0, 0, 0 }
02023 };
02024 const Int32 D2[4][4] = {
02025 { 0, 0, 0, 0 },
02026 { 0, 0, 1, -1 },
02027 { 0, -1, 0, 1 },
02028 { 0, 1, -1, 0 }
02029 };
02030 for( UInt32 m = 0; m < 4; ++m ) {
02031 for( UInt32 n = 0; n < 4; ++n ) {
02032 for( UInt32 t = 0; t < 3; ++t ) {
02033 dqAm_dxn[m][n][t] = GeVector::ZERO;
02034 dqAm_dxn[m][n][t][t] = D1[m][n];
02035 dqBm_dxn[m][n][t] = GeVector::ZERO;
02036 dqBm_dxn[m][n][t][t] = D2[m][n];
02037 }
02038 }
02039 }
02040 }
02041
02042
02043
02044 void SimSimulator::BendVars::calcNEderiv()
02045 {
02046 #if DO_NORM
02047 const GeMatrix3 InAnAt =
02048 GeMatrix3::IDENTITY - GeMatrix3::outerProduct( nA,nA );
02049 const GeMatrix3 InBnBt =
02050 GeMatrix3::IDENTITY - GeMatrix3::outerProduct( nB,nB );
02051 const GeMatrix3 Ieet =
02052 GeMatrix3::IDENTITY - GeMatrix3::outerProduct( e, e );
02053
02054 for ( UInt32 m = 0; m < 4; ++m ) {
02055 for ( UInt32 s = 0; s < 3; ++s ) {
02056
02057
02058 dnA_dxm[ m ][ s ] = InAnAt * makeSkewRow( qA[ m ], s ) * nAhim;
02059
02060
02061 dnB_dxm[ m ][ s ] = InBnBt * makeSkewRow( qB[ m ], s ) * nBhim;
02062
02063
02064 de_dxm[ m ][ s ] = Ieet * GeVector::axis( s ) * qe[ m ] * ehim;
02065 }
02066 }
02067 #else
02068 for ( UInt32 m = 0; m < 4; ++m ) {
02069 for ( UInt32 s = 0; s < 3; ++s ) {
02070 dnA_dxm[ m ][ s ] = makeSkewRow( qA[ m ], s ) * nAhim;
02071 dnB_dxm[ m ][ s ] = makeSkewRow( qB[ m ], s ) * nAhim;
02072 de_dxm[ m ][ s ] = GeVector::axis( s ) * qe[ m ] * ehim;
02073 }
02074 }
02075 #endif
02076 }
02077
02078
02079
02080 void SimSimulator::BendVars::calcD2NE()
02081 {
02082 UInt32 m,n,s,t;
02083 #if DO_NORM
02084 for ( m = 0; m < 4; ++m ) for ( n = 0; n < 4; ++n ) {
02085 for ( s = 0; s < 3; ++s ) for ( t = 0; t < 3; ++t ) {
02086 GeMatrix3 tempm;
02087 GeVector tempv;
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100 GeVector SqAm = makeSkewRow( qA[ m ], s );
02101 GeVector SqAn = makeSkewRow( qA[ n ], t );
02102 tempm = GeMatrix3::outerProduct( dnA_dxm[ n ][ t ], nA );
02103 tempm += GeMatrix3::outerProduct( nA, dnA_dxm[ n ][ t ] );
02104 d2nA_dxmdxn[m][n][s][t] = tempm * SqAm * -nAhim;
02105 tempm = (GeMatrix3::IDENTITY - GeMatrix3::outerProduct( nA, nA ))
02106 * (nAhim * nAhim);
02107 tempv = makeSkewRow( dqAm_dxn[ m ][ n ][ t ], s ) / nAhim;
02108 tempv -= SqAn.dot( nA ) * SqAm;
02109 d2nA_dxmdxn[m][n][s][t] += tempm * tempv;
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122 GeVector SqBm = makeSkewRow( qB[ m ], s );
02123 GeVector SqBn = makeSkewRow( qB[ n ], t );
02124 tempm = GeMatrix3::outerProduct( dnB_dxm[ n ][ t ], nB );
02125 tempm += GeMatrix3::outerProduct( nB, dnB_dxm[ n ][ t ] );
02126 d2nB_dxmdxn[m][n][s][t] = tempm * SqBm * -nBhim;
02127 tempm = (GeMatrix3::IDENTITY - GeMatrix3::outerProduct( nB, nB ))
02128 * (nBhim * nBhim);
02129 tempv = makeSkewRow( dqBm_dxn[ m ][ n ][ t ], s ) / nBhim;
02130 tempv -= SqBn.dot( nB ) * SqBm;
02131 d2nB_dxmdxn[m][n][s][t] += tempm * tempv;
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141 tempm = GeMatrix3::outerProduct( de_dxm[ n ][ t ], e );
02142 tempm += GeMatrix3::outerProduct( e, de_dxm[ n ][ t ] );
02143 d2e_dxmdxn[m][n][s][t] = tempm * GeVector::axis( s ) *
02144 (-qe[ m ] * ehim);
02145 tempm = GeMatrix3::IDENTITY - GeMatrix3::outerProduct( e, e );
02146 tempv = ehim * ehim * qe[ n ] * qe[ m ] * e[ t ] *
02147 GeVector::axis( s );
02148 d2e_dxmdxn[m][n][s][t] -= tempm * tempv;
02149 }
02150 }
02151 #else
02152 for ( m = 0; m < 4; ++m ) for ( n = 0; n < 4; ++n ) {
02153 for ( s = 0; s < 3; ++s ) for ( t = 0; t < 3; ++t ) {
02154 d2nA_dxmdxn[m][n][s][t] =
02155 makeSkewRow( dqAm_dxn[m][n][t], s ) * nAhim;
02156 d2nB_dxmdxn[m][n][s][t] =
02157 makeSkewRow( dqBm_dxn[m][n][t], s ) * nBhim;
02158 }
02159 }
02160 #endif
02161 }
02162
02163
02164
02165 void SimSimulator::BendVars::calcCosSinDeriv()
02166 {
02167 UInt32 m,s;
02168
02169
02170
02171
02172
02173 for( m = 0; m < 4; ++m ) {
02174 for ( s = 0; s < 3; ++s ) {
02175 dcosth_dxm[m][s] = dnA_dxm[m][s].dot( nB ) + nA.dot( dnB_dxm[m][s] );
02176 }
02177 }
02178
02179
02180
02181
02182
02183
02184
02185
02186 GeVector nAxnB( nA.cross( nB ) );
02187 for( m = 0; m < 4; ++m ) {
02188 for ( s = 0; s < 3; ++s ) {
02189 dsinth_dxm[m][s] =
02190 (
02191 dnA_dxm[m][s].cross( nB ) + nA.cross( dnB_dxm[m][s] )
02192 ).dot( e ) + nAxnB.dot( de_dxm[m][s] );
02193 }
02194 }
02195 }
02196
02197
02198
02199 void SimSimulator::BendVars::calcD2cossinth()
02200 {
02201 UInt32 m,n,s,t;
02202
02203
02204
02205
02206
02207
02208 for( m = 0; m < 4; ++m ) for( n = 0; n < 4; ++n ) {
02209 for ( s = 0; s < 3; ++s ) for ( t = 0; t < 3; ++t ) {
02210 d2costh_dxmdxn[m][n](t,s) =
02211 d2nA_dxmdxn[m][n][s][t].dot( nB ) +
02212 dnA_dxm[m][s].dot( dnB_dxm[n][t] ) +
02213 dnA_dxm[n][t].dot( dnB_dxm[m][s] ) +
02214 d2nB_dxmdxn[m][n][s][t].dot( nA );
02215 }
02216 }
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234 for( m = 0; m < 4; ++m ) for( n = 0; n < 4; ++n ) {
02235 for ( s = 0; s < 3; ++s ) for ( t = 0; t < 3; ++t ) {
02236 d2sinth_dxmdxn[ m ][ n ]( t, s ) = (
02237 d2nA_dxmdxn[m][n][s][t].cross( nB ) +
02238 dnA_dxm[m][s].cross( dnB_dxm[n][t] ) +
02239 dnA_dxm[n][t].cross( dnB_dxm[m][s] ) +
02240 nA.cross( d2nB_dxmdxn[m][n][s][t] )
02241 ).dot( e );
02242 d2sinth_dxmdxn[ m ][ n ]( t, s ) += (
02243 dnA_dxm[m][s].cross( nB ) +
02244 nA.cross( dnB_dxm[m][s] )
02245 ).dot( de_dxm[n][t] );
02246 d2sinth_dxmdxn[ m ][ n ]( t, s ) += (
02247 dnA_dxm[n][t].cross( nB ) +
02248 nA.cross( dnB_dxm[n][t] )
02249 ).dot( de_dxm[m][s] );
02250 #if DO_NORM
02251 d2sinth_dxmdxn[ m ][ n ]( t, s ) +=
02252 nA.cross( nB ).dot( d2e_dxmdxn[m][n][s][t] );
02253 #endif
02254 }
02255 }
02256 }
02257
02258
02259
02260 void SimSimulator::BendVars::calcCderivs()
02261 {
02262 UInt32 m,n,s,t;
02263
02264
02265
02266
02267 for ( m = 0; m < 4; ++m ) {
02268 dC_dxm[ m ] = costh * dsinth_dxm[ m ] - sinth * dcosth_dxm[ m ];
02269 }
02270
02271
02272
02273
02274
02275 for ( m = 0; m < 4; ++m ) for ( n = 0; n < 4; ++n ) {
02276 for ( s = 0; s < 3; ++s ) for ( t = 0; t < 3; ++t ) {
02277 d2C_dxmdxn[m][n](t,s) =
02278 dcosth_dxm[n][t] * dsinth_dxm[m][s] +
02279 costh * d2sinth_dxmdxn[m][n](t,s) -
02280 dsinth_dxm[n][t] * dcosth_dxm[m][s] -
02281 sinth * d2costh_dxmdxn[m][n](t,s);
02282 }
02283 }
02284
02285 }
02286
02287
02288
02289 void SimSimulator::BendVars::debugOutput( std::ostream& os )
02290 {
02291 UInt32 m,n,s,t;
02292
02293 os << "nA = " << nA << " nAhim = " << nAhim << std::endl;
02294 os << "nB = " << nB << " nBhim = " << nBhim << std::endl;
02295 os << "e = " << e << " ehim = " << ehim << std::endl;
02296
02297 os << "cos(theta) = " << costh << " sin(theta) = " << sinth
02298 << " C = theta = " << C << " radians ("
02299 << C * 180 / M_PI << " degrees)"
02300 << std::endl;
02301
02302 for ( m = 0; m < 4; ++m ) for ( n = 0; n < 4; ++n ) {
02303 for ( s = 0; s < 3; ++s ) {
02304 os << "dqAm_dxn[ " << m << " ][ " << n << " ][ "
02305 << s << " ] = " << dqAm_dxn[m][n][s] << std::endl;
02306 os << "dqBm_dxn[ " << m << " ][ " << n << " ][ "
02307 << s << " ] = " << dqBm_dxn[m][n][s] << std::endl;
02308 }
02309 }
02310
02311 for( m = 0; m < 4; ++m ) {
02312 for( s = 0; s < 3; ++s ) {
02313 os << "dnA_dxm[ " << m << " ][ " << s << " ] = "
02314 << dnA_dxm[ m ][ s ] << std::endl;
02315 os << "dnB_dxm[ " << m << " ][ " << s << " ] = "
02316 << dnB_dxm[ m ][ s ] << std::endl;
02317 os << "de_dxm[ " << m << " ][ " << s << " ] = "
02318 << de_dxm[ m ][ s ] << std::endl;
02319 }
02320 }
02321
02322 for ( m = 0; m < 4; ++m ) for ( n = 0; n < 4; ++n ) {
02323 for ( s = 0; s < 3; ++s ) for ( t = 0; t < 3; ++t ) {
02324 os << "d2nA_dxmdxn[ " << m << " ][ " << n << " ][ "
02325 << s << " ][ " << t << " ] = " << d2nA_dxmdxn[m][n][s][t]
02326 << std::endl;
02327 os << "d2nB_dxmdxn[ " << m << " ][ " << n << " ][ "
02328 << s << " ][ " << t << " ] = " << d2nB_dxmdxn[m][n][s][t]
02329 << std::endl;
02330 #if DO_NORM
02331 os << "d2e_dxmdxn[ " << m << " ][ " << n << " ][ "
02332 << s << " ][ " << t << " ] = " << d2e_dxmdxn[m][n][s][t]
02333 << std::endl;
02334 #endif
02335 }
02336 }
02337
02338 for ( m = 0; m < 4; ++m ) {
02339 os << "dcosth_dxm[ " << m << " ] = " << dcosth_dxm[ m ] << std::endl;
02340 os << "dsinth_dxm[ " << m << " ] = " << dsinth_dxm[ m ] << std::endl;
02341 }
02342
02343 for( m = 0; m < 4; ++m ) for( n = 0; n < 4; ++n ) {
02344 os << "d2costh_dxmdxn[ " << m << " ][ " << n << " ] = "
02345 << d2costh_dxmdxn[ m ][ n ] << std::endl;
02346 os << "d2sinth_dxmdxn[ " << m << " ][ " << n << " ] = "
02347 << d2sinth_dxmdxn[ m ][ n ] << std::endl;
02348 }
02349
02350 for ( m = 0; m < 4; ++m ) {
02351 os << "dC_dxm[ " << m << " ] = " << dC_dxm[ m ] << std::endl;;
02352 }
02353 os << "dC_dt = " << dC_dt << std::endl;
02354 for ( m = 0; m < 4; ++m ) for ( n = 0; n < 4; ++n ) {
02355 os << "d2C_dxmdxn[ " << m << "," << n << " ] = "
02356 << d2C_dxmdxn[ m ][ n ] << std::endl;
02357 }
02358 }
02359
02360
02361
02362
02363
02364
02365
02366
02367 SimSimulator::ModPCGSolver::ModPCGSolver()
02368 : _tolerance( 1e-4f )
02369 {
02370 }
02371
02372
02373
02374 bool SimSimulator::ModPCGSolver::done() const
02375 {
02376 return _done;
02377 }
02378
02379
02380
02381 const SimVector& SimSimulator::ModPCGSolver::result() const
02382 {
02383 return _x;
02384 }
02385
02386
02387
02388 void SimSimulator::ModPCGSolver::setTolerance( Float tolerance )
02389 {
02390 _tolerance = tolerance;
02391 }
02392
02393
02394
02395 Float SimSimulator::ModPCGSolver::getTolerance() const
02396 {
02397 return _tolerance;
02398 }
02399
02400
02401
02402 void SimSimulator::ModPCGSolver::preStep()
02403 {
02404 setupPreconditioner();
02405 setupCG();
02406 _nbSteps = 0;
02407 _done = false;
02408 }
02409
02410
02411
02412 void SimSimulator::ModPCGSolver::setupPreconditioner()
02413 {
02414
02415
02416
02417 UInt32 N = _A.nbRows();
02418 if ( _P.nbRows() != _A.nbRows() ) {
02419 _P = SimMatrix( N, N );
02420 _Pinv = SimMatrix( N, N );
02421
02422 }
02423 for ( UInt32 i = 0; i < N; ++i ) {
02424 const GeMatrix3& a = _A( i, i );
02425 GeMatrix3& p = _P( i, i );
02426 GeMatrix3& pinv = _Pinv( i, i );
02427 p = GeMatrix3::ZERO;
02428 pinv = GeMatrix3::ZERO;
02429 for ( UInt32 j = 0; j < 3; ++j ) {
02430 DGFX_ASSERT( !BaMath::isEqual( a( j, j ), 0, 10e-12 ) );
02431
02432
02433 p( j, j ) = a( j, j );
02434 pinv( j, j ) = 1 / a( j, j );
02435 }
02436 }
02437 }
02438
02439
02440
02441 void SimSimulator::ModPCGSolver::setupCG()
02442 {
02443 _x = _z;
02444 const SimVector bf( filter( _b ) );
02445 _delta0 = ( _P * bf ).dot( bf );
02446 _r = filter( _b - _A * _x );
02447 _c = filter( _Pinv * _r );
02448 _deltaNew = _r.dot( _c );
02449 }
02450
02451
02452
02453 SimVector SimSimulator::ModPCGSolver::filter( const SimVector& a ) const
02454 {
02455 DGFX_ASSERT( _S.size() == a.size() );
02456 SimVector result( a.size() );
02457 std::vector<GeMatrix3>::const_iterator Si = _S.begin();
02458 SimVector::const_iterator ai = a.begin();
02459 SimVector::iterator ri = result.begin();
02460 for( ; Si != _S.end(); ++Si, ++ai, ++ri ) {
02461 *ri = *Si * *ai;
02462 }
02463 return result;
02464 }
02465
02466
02467
02468 void SimSimulator::ModPCGSolver::filterInPlace( SimVector& a ) const
02469 {
02470 DGFX_ASSERT( _S.size() == a.size() );
02471 std::vector<GeMatrix3>::const_iterator Si = _S.begin();
02472 SimVector::iterator ai = a.begin();
02473 for( ; Si != _S.end(); ++Si, ++ai ) {
02474 *ai = *Si * *ai;
02475 }
02476 }
02477
02478
02479
02480 void SimSimulator::ModPCGSolver::step()
02481 {
02482 if ( _deltaNew < _tolerance * _tolerance * _delta0 ) {
02483 _done = true;
02484 return;
02485 }
02486
02487 SimMatrix::multiply( _q, _A, _c );
02488 filterInPlace( _q );
02489 Float alpha = _deltaNew / _c.dot( _q );
02490 _x.plusEqualsScaled( alpha, _c );
02491 _r.plusEqualsScaled( -alpha, _q );
02492
02493 SimMatrix::multiply( _s, _Pinv, _r );
02494 Float _deltaOld = _deltaNew;
02495 _deltaNew = _r.dot( _s );
02496 _c *= _deltaNew / _deltaOld;
02497 _c += _s;
02498 filterInPlace( _c );
02499 ++_nbSteps;
02500 }
02501
02502 FREECLOTH_NAMESPACE_END