#include "onsolver.h"
#include "system.h"
#include "onbody.h"
#include "body.h"
#include "matrixfun.h"
#include <fstream>
using namespace std;
OnSolver::OnSolver(){
numbodies = 0;
bodyarray = 0;
q=0;u=0; qdot=0; udot=0; qdotdot=0;
type = ONSOLVER;
}
OnSolver::~OnSolver(){
DeleteModel();
}
void OnSolver::DeleteModel(){
delete [] bodyarray;
delete [] q;
delete [] u;
delete [] qdot;
delete [] udot;
delete [] qdotdot;
numbodies = 0;
}
void OnSolver::CreateModel(){
DeleteModel();
system->ClearBodyIDs();
Body* sysbasebody = system->bodies.GetHeadElement()->value;
if( sysbasebody->GetType() != INERTIALFRAME ){
cerr << "ERROR: inertial frame not at head of bodies list" << endl;
exit(1);
}
numbodies = inertialframe.RecursiveSetup( (InertialFrame*) sysbasebody );
if(!numbodies){
cerr << "ERROR: unable to create O(n) model" << endl;
exit(1);
}
bodyarray = new OnBody* [numbodies];
CreateTopologyArray(0,&inertialframe);
CreateStateMatrixMaps();
}
int OnSolver::CreateTopologyArray(int num, OnBody* body){
int i = num;
bodyarray[i] = body;
i++;
OnBody* child;
ListElement<OnBody>* ele = body->children.GetHeadElement();
while(ele){
child = ele->value;
i = CreateTopologyArray(i,child);
ele = ele->next;
}
return i;
}
void OnSolver::CreateStateMatrixMaps(){
int numstates=0;
for(int i=1;i<numbodies;i++)
numstates += bodyarray[i]->q->GetNumRows();
state.Dim(numstates);
statedot.Dim(numstates);
statedoubledot.Dim(numstates);
int count=0;
for(int i=1;i<numbodies;i++){
for(int j=0;j<bodyarray[i]->q->GetNumRows();j++){
state.SetElementPointer(count,bodyarray[i]->q->GetElementPointer(j));
statedot.SetElementPointer(count,bodyarray[i]->qdot->GetElementPointer(j));
statedoubledot.SetElementPointer(count,bodyarray[i]->qdotdot->GetElementPointer(j));
count++;
}
}
}
void OnSolver::Solve(double time, Matrix& FF){
system->SetTime(time);
for(int i=1;i<numbodies;i++)
bodyarray[i]->LocalKinematics();
Vect3 Torque; Torque.Zeros();
Vect3 Force; Force.Zeros();
for(int i=numbodies-1;i>0;i--){
Torque(1)=FF(1,i);
Torque(2)=FF(2,i);
Torque(3)=FF(3,i);
Force(1)=FF(4,i);
Force(2)=FF(5,i);
Force(3)=FF(6,i);
bodyarray[i]->LocalTriangularization(Torque,Force);
}
for(int i=1;i<numbodies;i++){
bodyarray[i]->LocalForwardSubstitution();
}
}