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