forked from lijiext/lammps
490 lines
14 KiB
C++
490 lines
14 KiB
C++
/*
|
|
*_________________________________________________________________________*
|
|
* POEMS: PARALLELIZABLE OPEN SOURCE EFFICIENT MULTIBODY SOFTWARE *
|
|
* DESCRIPTION: SEE READ-ME *
|
|
* FILE NAME: workspace.cpp *
|
|
* AUTHORS: See Author List *
|
|
* GRANTS: See Grants List *
|
|
* COPYRIGHT: (C) 2005 by Authors as listed in Author's List *
|
|
* LICENSE: Please see License Agreement *
|
|
* DOWNLOAD: Free at www.rpi.edu/~anderk5 *
|
|
* ADMINISTRATOR: Prof. Kurt Anderson *
|
|
* Computational Dynamics Lab *
|
|
* Rensselaer Polytechnic Institute *
|
|
* 110 8th St. Troy NY 12180 *
|
|
* CONTACT: anderk5@rpi.edu *
|
|
*_________________________________________________________________________*/
|
|
|
|
|
|
#include "workspace.h"
|
|
#include "system.h"
|
|
#include "solver.h"
|
|
#include "SystemProcessor.h"
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <iomanip>
|
|
#include <cmath>
|
|
|
|
|
|
using namespace std;
|
|
|
|
void Workspace::allocateNewSystem() {
|
|
currentIndex++;
|
|
if(currentIndex < maxAlloc)
|
|
{
|
|
system[currentIndex].system = new System;
|
|
}
|
|
else
|
|
{
|
|
maxAlloc = (maxAlloc + 1) * 2;
|
|
|
|
SysData * tempPtrSys = new SysData[maxAlloc];
|
|
for(int i = 0; i < currentIndex; i++)
|
|
{
|
|
tempPtrSys[i] = system[i];
|
|
}
|
|
delete [] system;
|
|
system = tempPtrSys;
|
|
system[currentIndex].system = new System;
|
|
}
|
|
}
|
|
|
|
Workspace::Workspace(){
|
|
currentIndex = -1;
|
|
maxAlloc = 0;
|
|
system = NULL;
|
|
}
|
|
|
|
Workspace::~Workspace(){
|
|
for(int i = 0; i <= currentIndex; i++){
|
|
delete system[i].system;
|
|
}
|
|
delete [] system;
|
|
}
|
|
|
|
|
|
bool Workspace::LoadFile(char* filename){
|
|
bool ans;
|
|
ifstream file;
|
|
file.open(filename, ifstream::in);
|
|
if( !file.is_open() ){
|
|
cerr << "File '" << filename << "' not found." << endl;
|
|
return false;
|
|
}
|
|
allocateNewSystem();
|
|
ans = system[currentIndex].system->ReadIn(file);
|
|
file.close();
|
|
|
|
return ans;
|
|
}
|
|
|
|
void Workspace::SetLammpsValues(double dtv, double dthalf, double tempcon){
|
|
Thalf = dthalf;
|
|
Tfull = dtv;
|
|
ConFac = tempcon;
|
|
}
|
|
|
|
|
|
bool Workspace::MakeSystem(int& nbody, double *&masstotal, double **&inertia, double **&xcm, double **&vcm, double **&omega, double **&ex_space, double **&ey_space, double **&ez_space, int &njoint, int **&jointbody, double **&xjoint, int& nfree, int*freelist, double dthalf, double dtv, double tempcon, double KE){
|
|
|
|
SetLammpsValues(dtv, dthalf, tempcon);
|
|
|
|
if(njoint){
|
|
SystemProcessor sys;
|
|
sys.processArray(jointbody, njoint);
|
|
List<POEMSChain> * results = sys.getSystemData();
|
|
|
|
int numsyschains = results->GetNumElements();
|
|
int headvalue = 0;
|
|
List<POEMSChain> * newresults = results;
|
|
ListElement<POEMSChain> * tempNode = results->GetHeadElement();
|
|
int stop = 1;
|
|
int counter = 1;
|
|
for(int n = 1; n<=numsyschains; n++){
|
|
while(stop){
|
|
if ( (*(tempNode->value->listOfNodes.GetHeadElement()->value) == (headvalue+1) ) || (*(tempNode->value->listOfNodes.GetTailElement()->value) == (headvalue+1) ) ) {
|
|
newresults->Append(tempNode->value);
|
|
headvalue = headvalue + tempNode->value->listOfNodes.GetNumElements();
|
|
tempNode = results->GetHeadElement();
|
|
stop = 0;
|
|
counter ++;
|
|
}
|
|
else{
|
|
tempNode = tempNode->next;
|
|
}
|
|
}
|
|
stop=1;
|
|
}
|
|
|
|
ListElement<POEMSChain> * TNode = newresults->GetHeadElement();
|
|
ListElement<POEMSChain> * TTNode = newresults->GetHeadElement();
|
|
for(int kk=1; kk<=numsyschains; kk++){
|
|
if(kk!=numsyschains)
|
|
TTNode = TNode->next;
|
|
newresults->Remove(TNode);
|
|
if(kk!=numsyschains)
|
|
TNode = TTNode;
|
|
}
|
|
ListElement<POEMSChain> * NodeValue = newresults->GetHeadElement();
|
|
int count = 0;
|
|
int * array;
|
|
int ** arrayFromChain;
|
|
int numElementsInSystem;
|
|
int ttk = 0;
|
|
|
|
|
|
while(NodeValue != NULL) {
|
|
array = new int[NodeValue->value->listOfNodes.GetNumElements()];
|
|
arrayFromChain = NodeValue->value->listOfNodes.CreateArray();
|
|
numElementsInSystem = NodeValue->value->listOfNodes.GetNumElements();
|
|
for(int counter = 0; counter < numElementsInSystem; counter++){
|
|
array[counter] = *arrayFromChain[counter];
|
|
}
|
|
|
|
SetKE(1,KE);
|
|
allocateNewSystem();
|
|
system[currentIndex].system->Create_System_LAMMPS(nbody,masstotal,inertia,xcm,xjoint,vcm,omega,ex_space,ey_space,ez_space, numElementsInSystem, array, count);
|
|
|
|
system[currentIndex].solver = ONSOLVER;
|
|
ttk = ttk + 1;
|
|
count = ttk;
|
|
delete [] array;
|
|
delete [] arrayFromChain;
|
|
NodeValue= NodeValue->next;
|
|
}
|
|
}
|
|
if(nfree){
|
|
MakeDegenerateSystem(nfree,freelist,masstotal,inertia,xcm,vcm,omega,ex_space,ey_space,ez_space);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
bool Workspace::MakeDegenerateSystem(int& nfree, int*freelist, double *&masstotal, double **&inertia, double **&xcm, double **&vcm, double **&omega, double **&ex_space, double **&ey_space, double **&ez_space){
|
|
allocateNewSystem();
|
|
system[currentIndex].system->Create_DegenerateSystem(nfree,freelist,masstotal,inertia,xcm,vcm,omega,ex_space,ey_space,ez_space);
|
|
system[currentIndex].solver = ONSOLVER;
|
|
return true;
|
|
}
|
|
|
|
bool Workspace::SaveFile(char* filename, int index){
|
|
if(index < 0){
|
|
index = currentIndex;
|
|
}
|
|
ofstream file;
|
|
|
|
file.open(filename, ofstream::out);
|
|
|
|
if( !file.is_open() ){
|
|
cerr << "File '" << filename << "' could not be opened." << endl;
|
|
return false;
|
|
}
|
|
if(index >= 0 && index <= currentIndex){
|
|
system[index].system->WriteOut(file);
|
|
}
|
|
else {
|
|
cerr << "Error, requested system index " << index << ", minimum index 0 and maximum index " << currentIndex << endl;
|
|
}
|
|
file.close();
|
|
return true;
|
|
}
|
|
|
|
|
|
System* Workspace::GetSystem(int index){
|
|
if(index <= currentIndex){
|
|
if(index >= 0){
|
|
return system[index].system;
|
|
}
|
|
else{
|
|
return system[currentIndex].system;
|
|
}
|
|
}
|
|
else{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
void Workspace::AddSolver(Solver* s, int index){
|
|
if(currentIndex >= index){
|
|
if(index >= 0){
|
|
system[index].solver = (int)s->GetSolverType();
|
|
}
|
|
else{
|
|
system[currentIndex].solver = (int)s->GetSolverType();
|
|
}
|
|
}
|
|
else{
|
|
cout << "Error adding solver to index " << index << endl;
|
|
}
|
|
}
|
|
|
|
int Workspace::getNumberOfSystems(){
|
|
return currentIndex + 1;
|
|
}
|
|
|
|
|
|
|
|
void Workspace::SetKE(int temp, double SysKE){
|
|
KE_val = SysKE;
|
|
FirstTime =temp;
|
|
}
|
|
|
|
|
|
void Workspace::LobattoOne(double **&xcm, double **&vcm,double **&omega,double **&torque, double **&fcm, double **&ex_space, double **&ey_space, double **&ez_space){
|
|
|
|
int numsys = currentIndex;
|
|
int numbodies;
|
|
double time = 0.0;
|
|
int * mappings;
|
|
double SysKE=0.0;
|
|
|
|
for (int i = 0; i <= numsys; i++){
|
|
mappings = system[i].system->GetMappings();
|
|
numbodies = system[i].system->GetNumBodies() - 1;
|
|
Matrix FF(6,numbodies);
|
|
FF.Zeros();
|
|
for (int j=1; j<=numbodies; j++){
|
|
FF(1,j) = torque[mappings[j - 1]-1][0]*ConFac;
|
|
FF(2,j) = torque[mappings[j - 1]-1][1]*ConFac;
|
|
FF(3,j) = torque[mappings[j - 1]-1][2]*ConFac;
|
|
|
|
FF(4,j) = fcm[mappings[j - 1]-1][0]*ConFac;
|
|
FF(5,j) = fcm[mappings[j - 1]-1][1]*ConFac;
|
|
FF(6,j) = fcm[mappings[j - 1]-1][2]*ConFac;
|
|
}
|
|
|
|
//------------------------------------//
|
|
// Get a solver and solve that system.
|
|
Solver * theSolver = Solver::GetSolver((SolverType)system[i].solver);
|
|
theSolver->SetSystem(system[i].system);
|
|
theSolver->Solve(time, FF);
|
|
|
|
|
|
theSolver->Solve(time, FF);
|
|
ColMatrix tempx = *((*theSolver).GetState());
|
|
ColMatrix tempv = *((*theSolver).GetStateDerivative());
|
|
ColMatrix tempa = *((*theSolver).GetStateDerivativeDerivative());
|
|
|
|
|
|
for(int numint =0 ; numint<3; numint++){
|
|
theSolver->Solve(time, FF);
|
|
tempa = *((*theSolver).GetStateDerivativeDerivative());
|
|
*((*theSolver).GetStateDerivative())= tempv + Thalf*tempa;
|
|
}
|
|
|
|
ColMatrix TempV= *((*theSolver).GetStateDerivative());
|
|
*((*theSolver).GetState())= tempx + Tfull*TempV;
|
|
|
|
int numjoints = system[i].system->joints.GetNumElements();
|
|
for(int k = 0; k < numjoints; k++){
|
|
system[i].system->joints(k)->ForwardKinematics();
|
|
}
|
|
|
|
for(int k = 0; k < numbodies; k++){
|
|
Vect3 temp1 =system[i].system->bodies(k+1)->r;
|
|
Vect3 temp2 =system[i].system->bodies(k+1)->v;
|
|
Vect3 temp3 =system[i].system->bodies(k+1)->omega;
|
|
Mat3x3 temp4 =system[i].system->bodies(k+1)->n_C_k;
|
|
for(int m = 0; m < 3; m++){
|
|
xcm[mappings[k]-1][m] = temp1(m+1);
|
|
vcm[mappings[k]-1][m] = temp2(m+1);
|
|
omega[mappings[k]-1][m] = temp3(m+1);
|
|
ex_space[mappings[k]-1][m] = temp4(m+1,1);
|
|
ey_space[mappings[k]-1][m] = temp4(m+1,2);
|
|
ez_space[mappings[k]-1][m] = temp4(m+1,3);
|
|
}
|
|
SysKE = SysKE + system[i].system->bodies(k+1)->KE;
|
|
}
|
|
delete theSolver;
|
|
}
|
|
}
|
|
|
|
void Workspace::LobattoTwo(double **&vcm,double **&omega,double **&torque, double **&fcm){
|
|
int numsys = currentIndex;
|
|
int numbodies;
|
|
double time = 0.0;
|
|
int * mappings;
|
|
double SysKE =0.0;
|
|
for (int i = 0; i <= numsys; i++){
|
|
mappings = system[i].system->GetMappings();
|
|
numbodies = system[i].system->GetNumBodies() - 1;
|
|
Matrix FF(6,numbodies);
|
|
|
|
for (int j=1; j<=numbodies; j++){
|
|
FF(1,j) = torque[mappings[j - 1]-1][0]*ConFac;
|
|
FF(2,j) = torque[mappings[j - 1]-1][1]*ConFac;
|
|
FF(3,j) = torque[mappings[j - 1]-1][2]*ConFac;
|
|
FF(4,j) = fcm[mappings[j - 1]-1][0]*ConFac;
|
|
FF(5,j) = fcm[mappings[j - 1]-1][1]*ConFac;
|
|
FF(6,j) = fcm[mappings[j - 1]-1][2]*ConFac;
|
|
}
|
|
|
|
//------------------------------------//
|
|
// Get a solver and solve that system.
|
|
Solver * theSolver = Solver::GetSolver((SolverType)system[i].solver);
|
|
theSolver->SetSystem(system[i].system);
|
|
theSolver->Solve(time, FF);
|
|
ColMatrix tempv = *((*theSolver).GetStateDerivative());
|
|
ColMatrix tempa = *((*theSolver).GetStateDerivativeDerivative());
|
|
*((*theSolver).GetStateDerivative()) = tempv + Thalf*tempa;
|
|
|
|
|
|
int numjoints = system[i].system->joints.GetNumElements();
|
|
for(int k = 0; k < numjoints; k++){
|
|
system[i].system->joints(k)->ForwardKinematics();
|
|
}
|
|
|
|
for(int k = 0; k < numbodies; k++){
|
|
Vect3 temp1 =system[i].system->bodies(k+1)->r;
|
|
Vect3 temp2 =system[i].system->bodies(k+1)->v;
|
|
Vect3 temp3 =system[i].system->bodies(k+1)->omega;
|
|
SysKE = SysKE + system[i].system->bodies(k+1)->KE;
|
|
for(int m = 0; m < 3; m++){
|
|
vcm[mappings[k]-1][m] = temp2(m+1);
|
|
omega[mappings[k]-1][m] = temp3(m+1);
|
|
}
|
|
}
|
|
delete theSolver;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Workspace::RKStep(double **&xcm, double **&vcm,double **&omega,double **&torque, double **&fcm, double **&ex_space, double **&ey_space, double **&ez_space){
|
|
|
|
double a[6];
|
|
double b[6][6];
|
|
double c[6];
|
|
//double e[6];
|
|
|
|
a[1] = 0.2;
|
|
a[2] = 0.3;
|
|
a[3] = 0.6;
|
|
a[4] = 1.0;
|
|
a[5] = 0.875;
|
|
|
|
b[1][0] = 0.2;
|
|
b[2][0] = 0.075; b[2][1] = 0.225;
|
|
b[3][0] = 0.3; b[3][1] = -0.9; b[3][2] = 1.2;
|
|
b[4][0] = -11.0/54.0; b[4][1] = 2.5; b[4][2] = -70.0/27.0; b[4][3] = 35.0/27.0;
|
|
b[5][0] = 1631.0/55296.0; b[5][1] = 175.0/512.0; b[5][2] = 575.0/13824.0; b[5][3] = 44275.0/110592.0; b[5][4] = 253.0/4096.0;
|
|
|
|
c[0] = 37.0/378.0;
|
|
c[1] = 0.0;
|
|
c[2] = 250.0/621.0;
|
|
c[3] = 125.0/594.0;
|
|
c[4] = 0.0;
|
|
c[5] = 512.0/1771.0;
|
|
|
|
int numsys = currentIndex;
|
|
int numbodies;
|
|
double time = 0.0;
|
|
int * mappings;
|
|
double SysKE =0.0;
|
|
|
|
|
|
for (int i = 0; i <= numsys; i++){
|
|
mappings = system[i].system->GetMappings();
|
|
|
|
numbodies = system[i].system->GetNumBodies() - 1;
|
|
Matrix FF(6,numbodies);
|
|
for (int j=1; j<=numbodies; j++){
|
|
FF(1,j) = ConFac*torque[mappings[j - 1]-1][0];
|
|
FF(2,j) = ConFac*torque[mappings[j - 1]-1][1];
|
|
FF(3,j) = ConFac*torque[mappings[j - 1]-1][2];
|
|
|
|
FF(4,j) = ConFac*fcm[mappings[j - 1]-1][0];
|
|
FF(5,j) = ConFac*fcm[mappings[j - 1]-1][1];
|
|
FF(6,j) = ConFac*fcm[mappings[j - 1]-1][2];
|
|
}
|
|
|
|
|
|
//------------------------------------//
|
|
// Get a solver and solve that system.
|
|
Solver * theSolver = Solver::GetSolver((SolverType)system[i].solver);
|
|
theSolver->SetSystem(system[i].system);
|
|
theSolver->Solve(time, FF);
|
|
|
|
ColMatrix initial_x;
|
|
ColMatrix initial_xdot;
|
|
ColMatMap* x;
|
|
ColMatMap* xdot;
|
|
ColMatMap* xdotdot;
|
|
|
|
x = theSolver->GetState();
|
|
xdot = theSolver->GetStateDerivative();
|
|
xdotdot=theSolver->GetStateDerivativeDerivative();
|
|
|
|
initial_x = *x;
|
|
initial_xdot = *xdot;
|
|
ColMatrix f[6];
|
|
ColMatrix ff[6];
|
|
|
|
ff[0] = initial_xdot;
|
|
f[0] = *xdotdot;
|
|
|
|
for(int ii=1;ii<6;ii++){
|
|
time = a[ii] * Tfull;
|
|
(*x) = initial_x;
|
|
(*xdot) = initial_xdot;
|
|
for(int j=0;j<ii;j++){
|
|
(*x) = (*x) + (b[ii][j]*Tfull)*ff[j];
|
|
(*xdot) = (*xdot) + (b[ii][j]*Tfull)*f[j];
|
|
}
|
|
theSolver->Solve(time,FF);
|
|
f[ii] = (*xdotdot);
|
|
ff[ii] = (*xdot);
|
|
}
|
|
|
|
|
|
(*x) = initial_x + (c[0]*Tfull)*ff[0] + (c[2]*Tfull)*ff[2] + (c[3]*Tfull)*ff[3] + (c[5]*Tfull)*ff[5];
|
|
|
|
(*xdot) = initial_xdot + (c[0]*Tfull)*f[0] + (c[2]*Tfull)*f[2] + (c[3]*Tfull)*f[3] + (c[5]*Tfull)*f[5];
|
|
|
|
|
|
int numjoints = system[i].system->joints.GetNumElements();
|
|
for(int k = 0; k < numjoints; k++){
|
|
system[i].system->joints(k)->ForwardKinematics();
|
|
}
|
|
|
|
|
|
for(int k = 0; k < numbodies; k++){
|
|
Vect3 temp1 =system[i].system->bodies(k+1)->r;
|
|
Vect3 temp2 =system[i].system->bodies(k+1)->v;
|
|
Vect3 temp3 =system[i].system->bodies(k+1)->omega;
|
|
Mat3x3 temp4 =system[i].system->bodies(k+1)->n_C_k;
|
|
SysKE = SysKE + system[i].system->bodies(k+1)->KE;
|
|
for(int m = 0; m < 3; m++){
|
|
xcm[mappings[k]-1][m] = temp1(m+1);
|
|
vcm[mappings[k]-1][m] = temp2(m+1);
|
|
omega[mappings[k]-1][m] = temp3(m+1);
|
|
|
|
ex_space[mappings[k]-1][m] = temp4(m+1,1);
|
|
ey_space[mappings[k]-1][m] = temp4(m+1,2);
|
|
ez_space[mappings[k]-1][m] = temp4(m+1,3);
|
|
}
|
|
}
|
|
delete theSolver;
|
|
}
|
|
}
|
|
|
|
|
|
void Workspace::WriteFile(char * filename){
|
|
int numsys = currentIndex;
|
|
int numbodies;
|
|
|
|
|
|
for (int i = 0; i <= numsys; i++){
|
|
numbodies = system[i].system->GetNumBodies() - 1;
|
|
ofstream outfile;
|
|
outfile.open(filename,ofstream::out | ios::app);
|
|
outfile << numbodies<<endl;
|
|
outfile << "Atoms "<<endl;
|
|
for(int k = 0; k < numbodies; k++){
|
|
Vect3 temp1 =system[i].system->bodies(k+1)->r;
|
|
outfile<<1<<"\t"<<temp1(1)<<"\t"<<temp1(2)<<"\t"<<temp1(3)<<endl;
|
|
}
|
|
outfile.close();
|
|
}
|
|
}
|