00001
00002
00003 #ifndef ASSEMBLY_H
00004 #define ASSEMBLY_H
00005
00013 #include <iostream>
00014 #include <fstream>
00015 #include <string>
00016 #include <vector>
00017 #include <set>
00018 #include <map>
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021
00022 #include "Part.h"
00023
00024 #define averbose 0
00025
00427
00428
00429 template <class DataType, int dim>
00430 class Assembly {
00431 typedef Assembly<DataType,dim> base;
00432 public:
00433 typedef Part<DataType,dim> PartType;
00434 typedef ads::FixedArray<dim,DataType> point_type;
00435 typedef ads::FixedArray<dim,int> multi_index_type;
00436
00437
00438 Assembly()
00439 {
00440 idTag.clear();
00441 edges.resize(0);
00442 component = -1;
00443 backedge = -1;
00444 gdistance = -1;
00445
00446 parts.clear();
00447 subAssemblies.clear();
00448
00449 AssemblyTmatrix.resize(dim+1,dim+1);
00450 AssemblyTmatrix.assign(imatrix(dim+1));
00451 MotionTmatrix.resize(dim+1,dim+1);
00452 MotionTmatrix.assign(imatrix(dim+1));
00453 DHMat.resize(dim+1,dim+1);
00454 DHMat.assign(imatrix(dim+1));
00455 DHMat_old.resize(dim+1,dim+1);
00456 DHMat_old.assign(imatrix(dim+1));
00457 }
00458
00459 Assembly(const base& v)
00460 {
00461 base();
00462 idTag = v.idTag;
00463
00464 component = v.component;
00465 backedge = v.backedge;
00466 gdistance = v.gdistance;
00467 edges = v.edges;
00468 parent = v.parent;
00469
00470 AssemblyTmatrix = v.AssemblyTmatrix;
00471 MotionTmatrix = v.MotionTmatrix;
00472
00473 parts = v.parts;
00474 subAssemblies = v.subAssemblies;
00475
00476 name = v.name;
00477 mobile = v.mobile;
00478
00479
00480 DHMat = v.DHMat;
00481 DHMat_old = v.DHMat_old;
00482
00483 }
00484
00485
00486 ~Assembly() {}
00487
00488 virtual void setDim() {
00489 if (dim == 2) {
00490
00491 }
00492 }
00493
00494 virtual std::vector<int>& IdTag() { return idTag; }
00495 virtual void setIdTag(std::vector<int> val) {
00496 idTag = val;
00497 }
00498
00499 virtual std::string Name() { return name; }
00500 virtual void setName(std::string val) {
00501 name = val;
00502 }
00503
00504 virtual base * GetWorld() { return parent; }
00505
00506 virtual void setDHMat( MType val ) { DHMat = val; }
00507 virtual MType GetDHMat() { return DHMat; }
00508
00509
00510 virtual void AddPart( PartType * v) {
00511 std::vector<int> tmpId;
00512 tmpId = idTag;
00513 ( mklog() << " Adding Part to assembly " << Name() << " that has idTag " << stringID(tmpId) ).flush();
00514 tmpId.push_back( -(parts.size()+1) );
00515 v->setIdTag(tmpId);
00516 printID(v->IdTag());
00517 ( mklog() << " Part added to " << Name() << ". Part has " << v->Name() << " and idTag " << stringID(tmpId) ).flush();
00518 base::parts.push_back(v);
00519 }
00520 virtual void AddPart( PartType& v) { AddPart(&v); }
00521 virtual int GetNumParts() {
00522 return ((int) parts.size());
00523 }
00524 virtual PartType * GetNthPart(int n) {
00525 return (parts[n]);
00526 }
00527
00528 virtual void AddSubAssembly( base * v) {
00529 ( mklog() << base::Name() << " adding subassembly "<< v->Name() <<std::endl
00530 << Name() << " " << stringID(idTag) << std::endl ).flush();
00531 std::vector<int> tmpId;
00532 tmpId = idTag;
00533 tmpId.push_back( subAssemblies.size() );
00534 v->setIdTag(tmpId);
00535 printID(v->IdTag());
00536 base::subAssemblies.push_back(*v);
00537 }
00538 virtual void AddSubAssembly( base& v) { AddSubAssembly(&v); }
00539
00540 virtual int GetNumSubAssemblies() {
00541 return ((int) subAssemblies.size());
00542 }
00543 virtual base * GetNthSubAssembly(int n) {
00544 return (&subAssemblies[n]);
00545 }
00546
00547 virtual void setAssemblyTmatrix() {
00548 AssemblyTmatrix.assign(imatrix(dim));
00549 }
00550
00551 virtual void setAssemblyTmatrix( const MType ttemp) {
00552 AssemblyTmatrix = ttemp;
00553 }
00554
00555 virtual MType * getAssemblyTmatrix() {
00556 return &AssemblyTmatrix;
00557 }
00558
00559 void setAssemblyMotion(MType &Tmatrix) {
00560 MotionTmatrix = Tmatrix;
00561 }
00562
00563 void updateAssembly(DataType dt, DataType time, MType transform, int level) {
00564 level++;
00565 #ifdef ASSEMBLY_DEBUG_ON
00566 ( mklog() <<"Updating Assembly "<<Name()<<" :::: NumParts "<<GetNumParts()<<std::endl ).flush();
00567 #endif
00568 MType tTmp;
00569 PType otemp(0.), otemp2(0.), atemp(0.);
00570
00571 for (register int p = 0; p < GetNumParts(); p++) {
00572 #ifdef ASSEMBLY_DEBUG_ON
00573 ( mklog() <<" _Part "<<p<<" "<<GetNthPart(p)->Name()
00574 <<" numConnections "<<GetNthPart(p)->GetNumConnections()<<std::endl ).flush();
00575 #endif
00576 GetNthPart(p)->updatePart(dt,time);
00577 }
00578
00579 for (register int sa = 0; sa < GetNumSubAssemblies(); sa++) {
00580 #ifdef ASSEMBLY_DEBUG_ON
00581 ( mklog() <<"Sub-Assembly "<<sa<<" "<<GetNthSubAssembly(sa)->Name()
00582 <<" NumParts "<<GetNthSubAssembly(sa)->GetNumParts()<<std::endl ).flush();
00583 #endif
00584 GetNthSubAssembly(sa)->updateAssembly(dt,time,tTmp,level);
00585 }
00586 }
00587
00588 void resetAssembly() {
00589 #ifdef ASSEMBLY_DEBUG_ON
00590 ( mklog() <<"Reseting Assembly "<<Name()<<" :::: NumParts "<<GetNumParts()<<std::endl).flush();
00591 #endif
00592 for (register int p = 0; p < GetNumParts(); p++) {
00593 GetNthPart(p)->resetPart();
00594 }
00595 for (register int sa = 0; sa < GetNumSubAssemblies(); sa++) {
00596 GetNthSubAssembly(sa)->resetAssembly();
00597 }
00598 }
00599
00600 void partPressureForces( multi_index_type* cons, DataType* press, DataType scale ) {
00601 #ifdef ASSEMBLY_DEBUG_ON
00602 ( mklog() <<"Calculating part pressure forces in Assembly "<<Name()
00603 <<" :::: NumParts "<<GetNumParts()<<std::endl).flush();
00604 #endif
00605 for (register int p = 0; p < GetNumParts(); p++) {
00606 GetNthPart(p)->pressureForce( cons, press, scale );
00607 }
00608 for (register int sa = 0; sa < GetNumSubAssemblies(); sa++) {
00609 GetNthSubAssembly(sa)->partPressureForces( cons, press, scale );
00610 }
00611 }
00612
00613 virtual void logPartLoads( std::ofstream& ofs, DataType time_, int steps ) {
00614 #ifdef SCENE_DEBUG_ON
00615 ( mklog() <<"SCENE: logPartLoads()\n").flush();
00616 #endif
00617 for (register int p = 0; p < GetNumParts(); p++) {
00618 GetNthPart(p)->logLoad( ofs, time_, steps );
00619 }
00620 for (register int a = 0; a < GetNumSubAssemblies(); a++) {
00621 GetNthSubAssembly(a)->logPartLoads( ofs, time_, steps );
00622 }
00623 }
00624
00625 void send2CPT(int& nump, int& numc, point_type* vertices, multi_index_type* connections, DataType scale) {
00626 point_type * ptmp;
00627 Facet<DataType> * ctmp;
00628 PartType * partTmp;
00629 int it = 0, it2 = nump, it1 = numc, it0 = numc;
00630 for (register int p = 0; p < GetNumParts(); p++) {
00631 partTmp = GetNthPart(p);
00632 partTmp->setCGS(numc);
00633
00634 for ( register int ii=0; ii < partTmp->GetNumPoints(); ii++ ) {
00635 ptmp = partTmp->GetNthPointAddress(ii);
00636 vertices[it2](0) = (*ptmp)(0)*scale;
00637 vertices[it2](1) = (*ptmp)(1)*scale;
00638 vertices[it2](2) = (*ptmp)(2)*scale;
00639 it2++;
00640 }
00641 it1 += partTmp->GetNumConnections();
00642
00643 for (register int c=0; c < partTmp->GetNumConnections(); c++) {
00644 ctmp = (Facet<DataType> *) partTmp->GetNthConnection(c);
00645 connections[it0+c](0) = ctmp->getNthCon(0);
00646 connections[it0+c](1) = ctmp->getNthCon(1);
00647 connections[it0+c](2) = ctmp->getNthCon(2);
00648 }
00649 for (it = it0; it < it1; it++) {
00650 connections[it](0) += nump;
00651 connections[it](1) += nump;
00652 connections[it](2) += nump;
00653 }
00654 it0 += partTmp->GetNumConnections();
00655 numc += partTmp->GetNumConnections();
00656 nump += partTmp->GetNumPoints();
00657 }
00658 for (register int sa = 0; sa < GetNumSubAssemblies(); sa++) {
00659 GetNthSubAssembly(sa)->send2CPT(nump,numc,vertices,connections,scale);
00660 }
00661 }
00662
00663 void vel2CPT(int& totPoints, point_type* velocities, DataType scale) {
00664 point_type * ptmp;
00665 PartType * partTmp;
00666 int it2 = totPoints;
00667 for (register int p = 0; p < GetNumParts(); p++) {
00668 partTmp = GetNthPart(p);
00669
00670 for ( register int ii=0; ii < partTmp->GetNumPoints(); ii++ ) {
00671 ptmp = partTmp->GetNthVelocityAddress(ii);
00672 velocities[it2](0) = (*ptmp)(0)*scale;
00673 velocities[it2](1) = (*ptmp)(1)*scale;
00674 velocities[it2](2) = (*ptmp)(2)*scale;
00675 it2++;
00676 }
00677 totPoints = it2;
00678 }
00679 for (register int sa = 0.; sa < GetNumSubAssemblies(); sa++) {
00680 GetNthSubAssembly(sa)->vel2CPT(totPoints, velocities, scale);
00681 }
00682 }
00683
00684 int GetNumPoints() {
00685 int acount = 0;
00686
00687 for (register int p = 0; p < GetNumParts(); p++) {
00688 acount += GetNthPart(p)->GetNumPoints();
00689 }
00690 for (register int sa = 0; sa < GetNumSubAssemblies(); sa++) {
00691 acount += GetNthSubAssembly(sa)->GetNumPoints();
00692 }
00693 return acount;
00694 }
00695
00696 void GetNumPC(int& pcount, int& ccount) {
00697 for (register int p = 0; p < GetNumParts(); p++) {
00698 pcount += GetNthPart(p)->GetNumPoints();
00699 ccount += GetNthPart(p)->GetNumConnections();
00700 }
00701 for (register int sa = 0; sa < GetNumSubAssemblies(); sa++) {
00702 GetNthSubAssembly(sa)->GetNumPC(pcount,ccount);
00703 }
00704 }
00705
00706 void print(int level) {
00707 ( mklog() << std::endl << std::string(level, '\t') << "Assembly " << Name() << " :::: NumParts " << GetNumParts() << "\n"
00708 << std::string(level, '\t') << "AssemblyTmatrix = " << AssemblyTmatrix << std::endl ).flush();
00709 level++;
00710 for (register int p = 0; p < GetNumParts(); p++) {
00711 ( mklog() << std::string(level, '\t') << "Part " << GetNthPart(p)->Name()
00712 << " idTag " << stringID(GetNthPart(p)->IdTag())
00713 << " numConnections " << GetNthPart(p)->GetNumConnections() << std::endl
00714 << std::string(level, '\t') << " DHMat " << GetNthPart(p)->GetDHMat() <<std::endl ).flush();
00715 if ( GetNthPart(p)->GetMobility() == 1 ) {
00716 ( mklog() << std::string(level, '\t') << " mobile ").flush();
00717 }
00718 else {
00719 ( mklog() << std::string(level, '\t') << " stationary ").flush();
00720 }
00721 if ( GetNthPart(p)->GetDeformation() == 1 ) {
00722 ( mklog() << " deformable\n").flush();
00723 }
00724 else {
00725 ( mklog() << " rigid\n").flush();
00726 }
00727 }
00728
00729 if ( GetNumSubAssemblies() > 0)
00730 ( mklog() << std::endl<< std::string(level, '\t') << "GetNumSubAssemblies() " << GetNumSubAssemblies() << std::endl ).flush();
00731 for (register int sa = 0; sa < GetNumSubAssemblies(); sa++) {
00732 GetNthSubAssembly(sa)->print(level);
00733 }
00734
00735 }
00736
00737 void printSummary(int level) {
00738 ( mklog() << std::endl << std::string(level, '\t') << "Assembly " << Name()
00739 << " :::: NumParts " << GetNumParts() << std::endl ).flush();
00740 std::cout << std::endl << std::string(level, '\t') << "Assembly " << Name()
00741 << " :::: NumParts " << GetNumParts() << std::endl;
00742 level++;
00743 for (register int p = 0; p < GetNumParts(); p++) {
00744 ( mklog() << std::string(level, '\t') << "Part " << GetNthPart(p)->Name()
00745 << " idTag " << stringID(GetNthPart(p)->IdTag()) <<std::endl ).flush();
00746 std::cout << std::string(level, '\t') << "Part " << GetNthPart(p)->Name()
00747 << " idTag " << stringID(GetNthPart(p)->IdTag()) <<std::endl;
00748 if ( GetNthPart(p)->GetMobility() == 1 ) {
00749 ( mklog() << std::string(level, '\t') << " mobile ").flush();
00750 std::cout << std::string(level, '\t') << " mobile ";
00751 }
00752 else {
00753 ( mklog() << std::string(level, '\t') << " stationary ").flush();
00754 std::cout << std::string(level, '\t') << " stationary ";
00755 }
00756 if ( GetNthPart(p)->GetDeformation() == 1 ) {
00757 ( mklog() << " deformable\n").flush();
00758 std::cout << " deformable\n";
00759 }
00760 else {
00761 ( mklog() << " rigid\n").flush();
00762 std::cout << " rigid\n";
00763 }
00764 }
00765 if ( GetNumSubAssemblies() > 0) {
00766 ( mklog() << std::endl<< std::string(level, '\t') << "GetNumSubAssemblies() " << GetNumSubAssemblies() << std::endl ).flush();
00767 std::cout << std::endl<< std::string(level, '\t') << "GetNumSubAssemblies() " << GetNumSubAssemblies() << std::endl;
00768 }
00769 for (register int sa = 0; sa < GetNumSubAssemblies(); sa++) {
00770 GetNthSubAssembly(sa)->printSummary(level);
00771 }
00772 }
00773
00774 virtual void outputAssembly_Brep3D(DataType time, int pc, int pointCount[], int& pp, FILE * fout) {
00775
00776 const Facet<DataType> * facetTmp;
00777 const PartType * partTmp;
00778
00779 if (pc == 0) {
00780 for (register int p = 0; p < GetNumParts(); p++) {
00781 ( mklog() <<"Part "<<p<<" "<<GetNthPart(p)->Name() <<" numPoints "<< GetNthPart(p)->GetNumPoints()<<std::endl ).flush();
00782 partTmp = GetNthPart(p);
00783 for (register int j=0; j < partTmp->GetNumPoints(); j ++) {
00784 fprintf(fout,"%10d %8.5e %8.5e %8.5e\n",j,
00785 partTmp->GetNthPoint(j)(0),partTmp->GetNthPoint(j)(1),partTmp->GetNthPoint(j)(2) );
00786 }
00787 }
00788 for (register int sa = 0; sa < GetNumSubAssemblies(); sa++) {
00789 GetNthSubAssembly(sa)->outputAssembly_Brep3D(time,1,pointCount,pp,fout);
00790 }
00791 }
00792
00793 if (pc == 1) {
00794 for (register int p = 0; p < GetNumParts(); p++) {
00795 partTmp = GetNthPart(p);
00796 for (register int j = 0; j < partTmp->GetNumConnections(); j++) {
00797 facetTmp = (partTmp->GetNthFacet(j));
00798 fprintf(fout,"%d\t%d\t%d\n",
00799 facetTmp->getNthCon(0)+pointCount[pp],facetTmp->getNthCon(1)+pointCount[pp],
00800 facetTmp->getNthCon(2)+pointCount[pp] );
00801 }
00802 pp++;
00803 }
00804 for (register int sa = 0; sa < GetNumSubAssemblies(); sa++) {
00805 GetNthSubAssembly(sa)->outputAssembly_Brep3D(time,1,pointCount,pp,fout);
00806 }
00807 }
00808
00809 }
00810
00811 virtual void outputAssembly_STL(DataType time, FILE * fout) {
00812
00813 for (register int p = 0; p < GetNumParts(); p++) {
00814 ( mklog() <<"Asssembly "<<Name()<<" contains Part "<<GetNthPart(p)->Name()
00815 <<" with "<< GetNthPart(p)->GetNumConnections()<<" numConnections "<< std::endl ).flush();
00816 GetNthPart(p)->output(PartType::STL,time,fout);
00817 }
00818 ( mklog() <<"Assembly "<<Name()<<" has "<< GetNumSubAssemblies() <<" SubAssemblies\n").flush();
00819 for (register int sa = 0; sa < GetNumSubAssemblies(); sa++) {
00820 ( mklog() <<"Calling output on Subassembly "<<sa<<" : "<<GetNthSubAssembly(sa)->Name()<<std::endl).flush();
00821 GetNthSubAssembly(sa)->outputAssembly_STL(time,fout);
00822 }
00823
00824 }
00825
00826 virtual void Restart(std::ifstream& ifs, int& pos, double& t, double& dt) {
00827 #ifdef CHECKRESTART_DEBUG_ON
00828 (mklog() << "\nRestarting Assembly " << Name() << " t = " << t << " dt = " << dt << " pos = " << pos << std::endl).flush();
00829 #endif
00830 ifs.read((char*)&num_parts,sizeof(int));
00831 ifs.read((char*)&num_subAssemblies,sizeof(int));
00832 pos = ifs.tellg();
00833
00834 for (register int i=0; i<num_parts; i++) {
00835 ( mklog() << stringID(GetNthPart(i)->IdTag()) << " " << parts[i]->Name() << std::endl ).flush();
00836 parts[i]->Restart(ifs,pos,t,dt);
00837 pos = ifs.tellg();
00838 }
00839
00840 for (register int i=0; i<num_subAssemblies; i++) {
00841 subAssemblies[i].Restart(ifs,pos,t,dt);
00842 pos = ifs.tellg();
00843 }
00844 #ifdef CHECKRESTART_DEBUG_ON
00845 ( mklog() << "\nDone Restarting Assembly " << Name() << " t = " << t << " dt = " << dt << " pos = " << pos << std::endl ).flush();
00846 #endif
00847 }
00848
00849 virtual void Checkpointing(std::ofstream& ofs) {
00850 #ifdef CHECKRESTART_DEBUG_ON
00851 ( mklog() << "\nCHECKPOINTING Assembly " << Name() << std::endl ).flush();
00852 #endif
00853 ( mklog() << "\nCHECKPOINTING Assembly " << Name() << std::endl ).flush();
00854 num_parts = parts.size();
00855 ( mklog() << "num_parts " << num_parts << std::endl ).flush();
00856 num_subAssemblies = subAssemblies.size();
00857 ( mklog() << "num_subAssemblies " << num_subAssemblies << std::endl ).flush();
00858 ofs.write((char*)&num_parts,sizeof(int));
00859 ofs.write((char*)&num_subAssemblies,sizeof(int));
00860
00861 for (register int i=0; i<num_parts; i++) {
00862 ( mklog() << stringID(GetNthPart(i)->IdTag()) << " " << parts[i]->Name() << std::endl ).flush();
00863 parts[i]->Checkpointing(ofs);
00864 }
00865
00866 for (register int i=0; i<num_subAssemblies; i++) {
00867 subAssemblies[i].Checkpointing(ofs);
00868 }
00869
00870 }
00871
00872 virtual PType * GetVerticies() { return verticies; }
00873 virtual multi_index_type * GetConnections() { return connections; }
00874 virtual void makeVerticies(int n) { verticies = new PType[n]; }
00875 virtual void makeConnections(int n) { connections = new multi_index_type[n]; }
00876
00877 virtual PType surfacePoint(PType I_A, DataType zmin, int flag) {
00878 PType I_B(I_A);
00879 I_B(2) = zmin;
00880 int nump = 0, numc = 0;
00881 GetNumPC(nump,numc);
00882
00883 ( mklog() << " I_A " << I_A << " I_B " << I_B << std::endl
00884 << "SurfacePoint nump = " << nump << " numc = " << numc << std::endl ).flush();
00885 makeVerticies(nump);
00886 makeConnections(numc);
00887
00888 DataType scale = 1.;
00889 nump = 0;
00890 numc = 0;
00891 send2CPT(nump, numc, GetVerticies(), GetConnections(), scale);
00892 I_B = intersection_line2facet(I_A, I_B, nump, numc, GetVerticies(), GetConnections(), flag );
00893 return I_B;
00894 }
00895
00896 virtual PType surfacePoint(PType I_A, DataType zmin, int flag, DataType off ) {
00897 PType I_B(I_A), normal;
00898 I_B(2) = zmin;
00899 int nump = 0, numc = 0;
00900 GetNumPC(nump,numc);
00901 normal(0) = 0; normal(1) = 0; normal(2) = 1;
00902
00903 ( mklog() << Name() << " I_A " << I_A << " I_B " << I_B << std::endl
00904 << "SurfacePoint nump = " << nump << " numc = " << numc << std::endl ).flush();
00905 makeVerticies(nump);
00906 makeConnections(numc);
00907
00908 DataType scale = 1.;
00909 nump = 0;
00910 numc = 0;
00911 send2CPT(nump, numc, GetVerticies(), GetConnections(), scale);
00912 ( mklog() << "SurfacePoint after sed2CPT() nump = " << nump << " numc = " << numc << std::endl ).flush();
00913 I_B = intersection_line2facet(I_A, I_B, nump, numc, GetVerticies(), GetConnections(), flag );
00914 I_A =(I_A-I_B);
00915 ( mklog() << " normalize(I_A) " << normalize(I_A) << std::endl ).flush();
00916
00917 I_B = I_B + off*normal;
00918
00919 return I_B;
00920 }
00921
00922 protected:
00923 std::vector<int> idTag;
00928 std::string name;
00929 bool mobile;
00930 MType AssemblyTmatrix;
00931 MType MotionTmatrix;
00932 std::vector<base > subAssemblies;
00933 std::vector<PartType *> parts;
00934
00935 int num_subAssemblies, num_parts;
00936
00937
00938 MType DHMat;
00939 MType DHMat_old;
00940
00941
00942 base * parent;
00943 std::vector<int> edges;
00944 int component;
00945 int backedge;
00946 int gdistance;
00947
00948
00949 PType * verticies;
00950 multi_index_type * connections;
00951
00952
00953 };
00954
00955 #endif // ASSEMBLY_H