예제 #1
0
파일: Physics.cpp 프로젝트: Suttung/Jorn
Physics::Derivative Physics::evaluate(State &state, float t, float dt, const Derivative &derivative)
{
	state._position += derivative._velocity * dt;
	state._momentum += derivative._force * dt;
	state._orientation += derivative._spin * dt;
	state._angularMomentum += derivative._torque * dt;
	state.recalculate();
		
	Derivative output;
	output._velocity = state._velocity;
	output._spin = state._spin;
	forces(state, dt, output._force, output._torque);
	return output;		
}
예제 #2
0
bool BridgeVessel::applyForce( std::vector<double>& outforces ){
  bool hasforce=false; outforces.assign(outforces.size(),0.0);
  unsigned ndertot = myOutputAction->getNumberOfDerivatives();
  unsigned nextra = ndertot - getAction()->getNumberOfDerivatives();
  std::vector<double> forces( ndertot ), eforces( nextra, 0.0 );
  for(unsigned i=0;i<myOutputAction->getNumberOfVessels();++i){
     if( ( myOutputAction->getPntrToVessel(i) )->applyForce( forces ) ){
         hasforce=true;
         for(unsigned j=0;j<outforces.size();++j) outforces[j]+=forces[j];
         for(unsigned j=0;j<nextra;++j) eforces[j]+=forces[ outforces.size()+j ];
     }
  }
  if(hasforce) myOutputAction->applyBridgeForces( eforces );
  return hasforce;
}
예제 #3
0
int main(int argc, const char * argv[]) {
   int const nI = 64;               // Number of bodies in X, Y and Z directions
   int const nBod = nI*nI*nI;       // Total Number of bodies
   int const maxIter = 20;          // Total number of iterations (time steps)
   float const initDist = 1.0;      // Initial distance between the bodies
   float *rA;                       // Coordinates
   float *vA;                       // Velocities
   float *fA;                       // Forces
   int iter;
   double startTime0, endTime0;
   double startTime1, endTime1;
   char host[HOSTLEN];

   rA = (float*)malloc(3*nBod*sizeof(float));
   fA = (float*)malloc(3*nBod*sizeof(float));
   vA = (float*)malloc(3*nBod*sizeof(float));

   #pragma offload target(mic) out(numProc, host)
   {
      gethostname(host, HOSTLEN);
      numProc = omp_get_num_procs();
   }
   printf("Host name: %s\n", host);
   printf("Available number of processors: %d\n", numProc);

   // Setup initial conditions
   initCoord(rA, vA, fA, initDist, nBod, nI);

   startTime0 = omp_get_wtime();
   // Main loop
   #pragma offload target(mic) inout(rA, fA, vA:length(3*nBod)) in(nBod)
   for ( iter = 0; iter < maxIter; iter++ ) {
      forces(rA, fA, nBod);
      integration(rA, vA, fA, nBod);
   }
   endTime0 = omp_get_wtime();

   printf("\nTotal time = %10.4f [sec]\n", endTime0 - startTime0);

   free(rA);
   free(vA);
   free(fA);
	return 0;
}
예제 #4
0
void Idle()
{
  int i, j;
  float dt;
  
  present_time = glutGet(GLUT_ELAPSED_TIME);
  dt = 0.001*(present_time - last_time);

  for (i = 0; i < num_particles; i++)
  {
    for (j = 0; j < 3; j++)
    {
      particles[i].position[j] += dt*particles[i].velocity[j];
      particles[i].velocity[j] += dt*forces(i,j)/particles[i].mass;
    }
    Collision(i);
  }
  last_time = present_time;
  glutPostRedisplay();
}
예제 #5
0
void accel_calculate(cube data_vector,vec masses,int n_planets,mat &accel,int t,double G,double epsilon){
    double r2=0;
    double force=0;
    vec forces(3);
    forces.fill(0);

    /*One should find a way to capitalize on using newtons third law to minimize
     * computation time for this calculation. The current way wastes a lot of
     * computation time calculating quantities already calculated*/
    for(int i=0;i<n_planets;i++){
        for(int j=0;j<n_planets;j++){
            if(i == j) continue;
            r2 =
                    (data_vector(j,0,t)-data_vector(i,0,t))*
                    (data_vector(j,0,t)-data_vector(i,0,t))

                    + (data_vector(j,1,t)-data_vector(i,1,t))*
                    (data_vector(j,1,t)-data_vector(i,1,t))

                    + (data_vector(j,2,t)-data_vector(i,2,t))*
                    (data_vector(j,2,t)-data_vector(i,2,t))
                    ;

            force = -G*masses(j)/((r2+epsilon*epsilon)*sqrt(r2));

            forces(0) += force*(data_vector(i,0,t)-data_vector(j,0,t));
            forces(1) += force*(data_vector(i,1,t)-data_vector(j,1,t));
            forces(2) += force*(data_vector(i,2,t)-data_vector(j,2,t));

        }
        /*Note here that we dont divide with the mass of the object since
        that quantity is not multiplied with for the forces. This is done
        to save computation time.*/
        accel(i,0) = forces(0);
        accel(i,1) = forces(1);
        accel(i,2) = forces(2);
        force = 0;
        forces.fill(0);
        //cout <<accel << endl;

    }

}
예제 #6
0
void ParticleSystem::updateParticle(Particle& particle, float delta, int& index)
{
   particle.activeTime += delta;

	if ( particle.activeTime < particle.lifeTime )
   {
      Vector forces(0, mGravity);

      particle.vel += (forces * delta);
      particle.pos += (particle.vel * delta);
            
      index++;
	}
	else
   {
      // particle's time is up
		// add it to the free list
      active--;
      mParticles.swap(index, active);      
	}
}
예제 #7
0
void VTKWriter::initializeOutput(int numParticles) {
	vtkFile = new VTKFile_t("UnstructuredGrid");

	// per point, we add mass, velocity, force, type and stress
	// and in DEBUG mode the id of the molecules
	PointData pointData;
	DataArray_t mass(type::Float32, "mass", 1);
	DataArray_t velocity(type::Float32, "velocity", 3);
	DataArray_t forces(type::Float32, "force", 3);
	DataArray_t type(type::Int32, "type", 1);
	DataArray_t stress(type::Float32, "stress", 1);
	DataArray_t flag(type::Int32, "flag", 1);
	pointData.DataArray().push_back(mass);
	pointData.DataArray().push_back(velocity);
    pointData.DataArray().push_back(forces);
    pointData.DataArray().push_back(type);
    pointData.DataArray().push_back(stress);
    pointData.DataArray().push_back(flag);

#ifdef DEBUG
    DataArray_t id(type::Int32, "id", 1);
    pointData.DataArray().push_back(id);
#endif

	CellData cellData; // we don't have cell data => leave it empty

	// 3 coordinates
	Points points;
	DataArray_t pointCoordinates(type::Float32, "points", 3);
	points.DataArray().push_back(pointCoordinates);

	Cells cells; // we don't have cells, => leave it empty
	// for some reasons, we have to add a dummy entry for paraview
	DataArray_t cells_data(type::Float32, "types", 0);
	cells.DataArray().push_back(cells_data);

	PieceUnstructuredGrid_t piece(pointData, cellData, points, cells, numParticles, 0);
	UnstructuredGrid_t unstructuredGrid(piece);
	vtkFile->UnstructuredGrid(unstructuredGrid);
}
예제 #8
0
파일: graph.cpp 프로젝트: synesenom/fdeb
int Graph::iterate()
{
    int edgesNum = (int)_edges.size();
    std::vector<std::vector<meerkat::mk_vector2> > forces(
                edgesNum,
                std::vector<meerkat::mk_vector2>(
                    (int)_edges[0]._subdivs.size(), meerkat::mk_vector2(0.0, 0.0))
            );

    // spring forces
    for( int i=0; i<edgesNum; i++ )
        _edges[i].add_spring_forces(forces[i], _K);

    // electrostatic forces
    for( int i=0; i<edgesNum; i++ )
    {
        int compatibleEdgesNum = (int)_edges[i]._compatibleEdges.size();
        for( int j=0; j<compatibleEdgesNum; j++ )
            _edges[i].add_electrostatic_forces(forces[i],
                                               _edges[_edges[i]._compatibleEdges[j]],
                                               _edgeDistance);
    }

    // gravitation
    if( _gravitationIsOn )
    {
        for( int i=0; i<edgesNum; i++ )
            _edges[i].add_gravitational_forces(forces[i],
                                               _gravitationCenter,
                                               _gravitationExponent);
    }

    // update edges
    for( int i=0; i<edgesNum; i++ )
        _edges[i].update(forces[i], _S);

    _iter--;
    return _iter;
}
예제 #9
0
//------------------------------------------------------------------------------
int main( int argc, char * argv[] )
{
    //--------------------------------------------------------------------------
    const unsigned    geomDeg   = 1;
    const unsigned    dim       = 2;
    // degrees of lowest-order TH element
    const unsigned    fieldDegU = 2; 
    const unsigned    fieldDegP = 1;

    const unsigned    tiOrder   = 1;
    typedef  base::time::BDF<tiOrder> MSM;
    
    const base::Shape shape     = base::SimplexShape<dim>::value;
    const base::Shape surfShape = base::SimplexShape<dim-1>::value;

    //--------------------------------------------------------------------------
    if ( argc != 2 ) {
        std::cout << "Usage:  " << argv[0] << " input.dat \n\n";
        return -1;
    }

    const std::string inputFile = boost::lexical_cast<std::string>( argv[1] );

    //--------------------------------------------------------------------------
    std::string meshFile, surfFile;
    double viscosity, density, tolerance, penaltyFactor, stepSize;
    unsigned maxIter, numSteps;
    {    
        //Feed properties parser with the variables to be read
        base::io::PropertiesParser prop;
        prop.registerPropertiesVar( "meshFile",         meshFile );
        prop.registerPropertiesVar( "surfFile",         surfFile );
        prop.registerPropertiesVar( "viscosity",        viscosity );
        prop.registerPropertiesVar( "density",          density );
        prop.registerPropertiesVar( "maxIter",          maxIter );
        prop.registerPropertiesVar( "tolerance",        tolerance );
        prop.registerPropertiesVar( "penaltyFactor",    penaltyFactor );
        prop.registerPropertiesVar( "stepSize",         stepSize );
        prop.registerPropertiesVar( "numSteps",         numSteps );

        // Read variables from the input file
        std::ifstream inp( inputFile.c_str()  );
        VERIFY_MSG( inp.is_open(), "Cannot open input file" );
        prop.readValues( inp );
        inp.close( );

        // Make sure all variables have been found
        if ( not prop.isEverythingRead() ) {
            prop.writeUnread( std::cerr );
            VERIFY_MSG( false, "Could not find above variables" );
        }
    }

    const std::string baseName = base::io::baseName( meshFile, ".smf" );

    //--------------------------------------------------------------------------
    typedef base::Unstructured<shape,geomDeg>     Mesh;

    Mesh mesh;
    {
        std::ifstream smf( meshFile.c_str() );
        VERIFY_MSG( smf.is_open(), "Cannot open mesh file" );
        base::io::smf::readMesh( smf, mesh );
        smf.close();
    }

    //--------------------------------------------------------------------------
    // Surface mesh
    typedef base::Unstructured<surfShape,1,dim>    SurfMesh;

    SurfMesh surfMesh;
    {
        std::ifstream smf( surfFile.c_str() );
        base::io::smf::readMesh( smf, surfMesh );
        smf.close();
    }

    //--------------------------------------------------------------------------
    // Compute the level set data
    typedef base::cut::LevelSet<dim> LevelSet;
    std::vector<LevelSet> levelSet;
    const bool isSigned = true;
    base::cut::bruteForce( mesh, surfMesh, isSigned, levelSet );

    const unsigned kernelDegEstimate = 5;

    //--------------------------------------------------------------------------
    // Make cut cell structure
    typedef base::cut::Cell<shape> Cell;
    std::vector<Cell> cells;
    base::cut::generateCutCells( mesh, levelSet, cells );

    // Quadrature 
    typedef base::cut::Quadrature<kernelDegEstimate,shape> CutQuadrature;
    CutQuadrature quadrature( cells, true );

    // for surface
    typedef base::SurfaceQuadrature<kernelDegEstimate,shape> SurfaceQuadrature;
    SurfaceQuadrature surfaceQuadrature;

    //------------------------------------------------------------------------------
    // Finite element bases
    const unsigned    nHist = MSM::numSteps;
    
    const unsigned    doFSizeU = dim;
    typedef base::fe::Basis<shape,fieldDegU>                FEBasisU;
    typedef base::cut::ScaledField<FEBasisU,doFSizeU,nHist> Velocity;
    Velocity velocity;
    base::dof::generate<FEBasisU>( mesh, velocity );
    
    const unsigned    doFSizeP = 1;
    typedef base::fe::Basis<shape,fieldDegP>                FEBasisP;
    typedef base::cut::ScaledField<FEBasisP,doFSizeP,nHist> Pressure;
    Pressure pressure;
    base::dof::generate<FEBasisP>( mesh, pressure );

    const unsigned    doFSizeS = dim;
    typedef base::fe::Basis<surfShape,1>              FEBasisS;
    typedef base::Field<FEBasisS,doFSizeS>            SurfField;
    SurfField surfVelocity, surfForces;
    base::dof::generate<FEBasisS>( surfMesh, surfVelocity );
    base::dof::generate<FEBasisS>( surfMesh, surfForces   );

    // set initial condition to the identity 
    base::dof::setField( surfMesh, surfVelocity,
                         boost::bind( &surfaceVelocity<dim,
                                      SurfField::DegreeOfFreedom>, _1, _2 ) );


    // boundary datum    
    base::cut::TransferSurfaceDatum<SurfMesh,SurfField,Mesh::Element>
        s2d( surfMesh, surfVelocity, levelSet );
    
    //--------------------------------------------------------------------------
    //  surface mesh
    typedef base::mesh::BoundaryMeshBinder<Mesh>::Type BoundaryMesh;
    BoundaryMesh boundaryMesh, immersedMesh;

    // from boundary
    {
        // identify list of element boundary faces
        base::mesh::MeshBoundary meshBoundary;
        meshBoundary.create( mesh.elementsBegin(), mesh.elementsEnd() );

        // generate a mesh from that list (with a filter)
        base::mesh::generateBoundaryMesh( meshBoundary.begin(),
                                          meshBoundary.end(),
                                          mesh, boundaryMesh,
                                          boost::bind( &boundaryFilter<dim>, _1 ) );

        // make a surface mesh from the implicit surface
        base::cut::generateSurfaceMesh<Mesh,Cell>( mesh, cells, immersedMesh );
    }

    // the composite field with geometry, velocity and pressure
    typedef base::asmb::FieldBinder<Mesh,Velocity,Pressure> Field;
    Field field( mesh, velocity, pressure );

    // define the system blocks (U,U), (U,P), and (P,U)
    typedef Field::TupleBinder<1,1,1>::Type TopLeft;
    typedef Field::TupleBinder<1,2>::Type   TopRight;
    typedef Field::TupleBinder<2,1>::Type   BotLeft;


    std::vector<double> supportsU, supportsP;
    std::size_t numDoFsU = std::distance( velocity.doFsBegin(), velocity.doFsEnd() );
    supportsU.resize( numDoFsU );
    std::size_t numDoFsP = std::distance( pressure.doFsBegin(), pressure.doFsEnd() );
    supportsP.resize( numDoFsP );

    base::cut::supportComputation( mesh, velocity, quadrature, supportsU );
    base::cut::supportComputation( mesh, pressure, quadrature, supportsP );

    velocity.scaleAndTagBasis( supportsU, 1.e-8 );
    pressure.scaleAndTagBasis( supportsP, 1.e-8 ); 
    //velocity.tagBasis( supportsU, 1.e-8 );
    //pressure.tagBasis( supportsP, 1.e-8 ); 

    // Fix one pressure dof
    // Pressure::DoFPtrIter pIter = pressure.doFsBegin();
    // std::advance( pIter, std::distance( pressure.doFsBegin(), pressure.doFsEnd() )/5 );
    // (*pIter) -> constrainValue( 0, 0.0 );

    // Number of DoFs after constraint application!
    numDoFsU =
        base::dof::numberDoFsConsecutively( velocity.doFsBegin(), velocity.doFsEnd() );
    std::cout << "# Number of velocity dofs " << numDoFsU << std::endl;

    numDoFsP =
        base::dof::numberDoFsConsecutively( pressure.doFsBegin(), pressure.doFsEnd(),
            numDoFsU );
    std::cout << "# Number of pressure dofs " << numDoFsP << std::endl;

    // kernels
    typedef fluid::StressDivergence<  TopLeft::Tuple>  StressDivergence;
    typedef fluid::Convection<        TopLeft::Tuple>  Convection;
    typedef fluid::PressureGradient<  TopRight::Tuple> GradP;
    typedef fluid::VelocityDivergence<BotLeft::Tuple>  DivU;

    StressDivergence stressDivergence( viscosity );
    Convection       convection(       density );
    GradP            gradP;
    DivU             divU( true );

    // for surface fields
    typedef base::asmb::SurfaceFieldBinder<BoundaryMesh,Velocity,Pressure> SurfaceFieldBinder;
    typedef SurfaceFieldBinder::TupleBinder<1,1,1>::Type STBUU;
    typedef SurfaceFieldBinder::TupleBinder<1,2  >::Type STBUP;
    SurfaceFieldBinder   boundaryFieldBinder(  boundaryMesh, velocity, pressure );
    SurfaceFieldBinder   immersedFieldBinder(  immersedMesh, velocity, pressure );

    std::ofstream forces( "forces.dat" );

    for ( unsigned step = 0; step < numSteps; step++ ) {

        const double time = step * stepSize;
        const double factor = ( time < 1.0 ? time : 1.0 );
    
        std::cout << step << ":  time=" << time << ", factor=" << factor
                  << "\n";

        //base::dof::clearDoFs( velocity );
        //base::dof::clearDoFs( pressure );
        
        //--------------------------------------------------------------------------
        // Nonlinear iterations
        unsigned iter = 0;
        while( iter < maxIter ) {

            // Create a solver object
            typedef base::solver::Eigen3           Solver;
            Solver solver( numDoFsU + numDoFsP );

            std::cout << "* Iteration " << iter << std::flush;

            // compute inertia terms, d/dt, due to time integration
            base::time::computeInertiaTerms<TopLeft,MSM>( quadrature, solver,
                                                          field, stepSize, step,
                                                          density );
    
            // Compute system matrix
            base::asmb::stiffnessMatrixComputation<TopLeft>( quadrature, solver,
                                                             field, stressDivergence );

            base::asmb::stiffnessMatrixComputation<TopLeft>( quadrature, solver,
                                                             field, convection );

            base::asmb::stiffnessMatrixComputation<TopRight>( quadrature, solver,
                                                              field, gradP );

            base::asmb::stiffnessMatrixComputation<BotLeft>( quadrature, solver,
                                                             field, divU );
            // compute residual forces
            base::asmb::computeResidualForces<TopLeft >( quadrature, solver, field,
                                                         stressDivergence );
            base::asmb::computeResidualForces<TopLeft >( quadrature, solver, field, convection );
            base::asmb::computeResidualForces<TopRight>( quadrature, solver, field, gradP );
            base::asmb::computeResidualForces<BotLeft >( quadrature, solver, field, divU );
        
            // Parameter classes
            base::nitsche::OuterBoundary ob( viscosity );
            base::nitsche::ImmersedBoundary<Cell> ib( viscosity, cells );

            // Penalty method
            base::nitsche::penaltyLHS<STBUU>( surfaceQuadrature, solver,
                                              boundaryFieldBinder, ob, penaltyFactor );
        
            base::nitsche::penaltyRHS<STBUU>( surfaceQuadrature, solver, boundaryFieldBinder, 
                                              boost::bind( &dirichlet<dim>, _1, factor),
                                              ob, penaltyFactor );

            base::nitsche::penaltyLHS<STBUU>( surfaceQuadrature, solver,
                                              immersedFieldBinder, ib, penaltyFactor );
        
            base::nitsche::penaltyRHS2<STBUU>( surfaceQuadrature, solver, immersedFieldBinder,
                                               s2d, ib, penaltyFactor );

            // Nitsche terms
            base::nitsche::primalEnergyLHS<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                                   boundaryFieldBinder, ob );
            base::nitsche::dualEnergyLHS<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                                 boundaryFieldBinder, ob );
            base::nitsche::energyRHS<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                             boundaryFieldBinder,
                                             boost::bind( &dirichlet<dim>, _1, factor),
                                             ob );
        
            base::nitsche::primalEnergyLHS<STBUP>( gradP, surfaceQuadrature, solver,
                                                   boundaryFieldBinder, ob );
            base::nitsche::dualEnergyLHS<STBUP>( gradP, surfaceQuadrature, solver,
                                                 boundaryFieldBinder, ob );
         
            base::nitsche::energyRHS<STBUP>( gradP, surfaceQuadrature, solver,
                                             boundaryFieldBinder,
                                             boost::bind( &dirichlet<dim>, _1, factor), ob );

            base::nitsche::energyResidual<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                                  boundaryFieldBinder, ob );
            
            base::nitsche::energyResidual<STBUP>( gradP, surfaceQuadrature, solver,
                                                  boundaryFieldBinder, ob );

            base::nitsche::primalEnergyLHS<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                                   immersedFieldBinder, ib );
            base::nitsche::dualEnergyLHS<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                                 immersedFieldBinder, ib );

            base::nitsche::energyRHS2<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                              immersedFieldBinder, s2d, ib );
            
            base::nitsche::primalEnergyLHS<STBUP>( gradP, surfaceQuadrature, solver,
                                                   immersedFieldBinder, ib );
            base::nitsche::dualEnergyLHS<STBUP>( gradP, surfaceQuadrature, solver,
                                                 immersedFieldBinder, ib );

            base::nitsche::energyRHS2<STBUP>( gradP, surfaceQuadrature, solver,
                                              immersedFieldBinder, s2d, ib );

            base::nitsche::energyResidual<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                                  immersedFieldBinder, ib );

            base::nitsche::energyResidual<STBUP>( gradP, surfaceQuadrature, solver,
                                                  immersedFieldBinder, ib );
        
            // Finalise assembly
            solver.finishAssembly();

            // check convergence via solver norms
            const double residualNorm = solver.norm();
            std::cout << " |R| = " << residualNorm << std::flush;

            if ( residualNorm < tolerance * viscosity) {
                std::cout << std::endl;
                break;
            }

            // Solve
            solver.superLUSolve();

            // distribute results back to dofs
            base::dof::addToDoFsFromSolver( solver, velocity );
            base::dof::addToDoFsFromSolver( solver, pressure );
            //base::dof::setDoFsFromSolver( solver, pressure );
        
            // check convergence via solver norms
            const double incrementNorm = solver.norm(0, numDoFsU );
            std::cout << " |dU| = " << incrementNorm << std::endl;

            // push history
            base::dof::pushHistory( velocity );
            base::dof::pushHistory( pressure );
        
            if ( incrementNorm < tolerance ) break;

            iter++;

        }

        writeVTKFile( baseName, step, mesh, velocity, pressure, levelSet, viscosity );
        {
            base::Vector<dim>::Type sumOfForces = base::constantVector<dim>( 0. );
            
            typedef Field::TupleBinder<1,2>::Type UP;
            //typedef fluid::Stress<UP::Tuple> Stress;
            //Stress stress( viscosity );
            typedef fluid::Traction<UP::Tuple> Traction;
            Traction traction( viscosity );
                
            base::cut::ComputeSurfaceForces<SurfMesh,SurfField,
                                            SurfaceQuadrature,STBUP::Tuple,Traction>
                computeSurfaceForces( surfMesh, surfForces, surfaceQuadrature, levelSet, traction );

            SurfaceFieldBinder::FieldIterator first = immersedFieldBinder.elementsBegin();
            SurfaceFieldBinder::FieldIterator  last = immersedFieldBinder.elementsEnd();
            for ( ; first != last; ++first ) {
                
                sumOfForces +=
                    computeSurfaceForces( STBUP::makeTuple( *first ) );
                
            }

            writeSurfaceVTKFile( baseName, step, surfMesh, surfVelocity, surfForces );


            std::cout << "  F= " << sumOfForces.transpose() << " \n";

            forces << time << " " << sumOfForces.transpose() << std::endl;;
        }

    }

    forces.close();

    return 0;
}
예제 #10
0
파일: iteration.cpp 프로젝트: jpdarago/lio
void PointGroup<scalar_type>::solve(Timers& timers, bool compute_rmm, bool lda, bool compute_forces, bool compute_energy,
                                    double& energy, double* fort_forces_ptr)
{
  HostMatrix<scalar_type> rmm_output;
  uint group_m = total_functions();
  if (compute_rmm) { rmm_output.resize(group_m, group_m); rmm_output.zero(); }

  #if CPU_RECOMPUTE
  /** Compute functions **/
  timers.functions.start();
  compute_functions(compute_forces, !lda);
  timers.functions.pause();
  #endif

  // prepare rmm_input for this group
  timers.density.start();
  HostMatrix<scalar_type> rmm_input(group_m, group_m);
  get_rmm_input(rmm_input);
  timers.density.pause();

  HostMatrix<vec_type3> forces(total_nucleii(), 1); forces.zero();
  HostMatrix<vec_type3> dd;

  /******** each point *******/
  uint point = 0;
  for (list<Point>::const_iterator point_it = points.begin(); point_it != points.end(); ++point_it, ++point)
  {
    timers.density.start();

    /** density **/
    scalar_type partial_density = 0;
    vec_type3 dxyz(0,0,0);
    vec_type3 dd1(0,0,0);
    vec_type3 dd2(0,0,0);

    if (lda) {
      for (uint i = 0; i < group_m; i++) {
        float w = 0.0;
        float Fi = function_values(i, point);
        for (uint j = i; j < group_m; j++) {
          scalar_type Fj = function_values(j, point);
          w += rmm_input(j, i) * Fj;
        }
        partial_density += Fi * w;
      }
    }
    else {
      for (uint i = 0; i < group_m; i++) {
        float w = 0.0;
        vec_type3 w3(0,0,0);
        vec_type3 ww1(0,0,0);
        vec_type3 ww2(0,0,0);

        scalar_type Fi = function_values(i, point);
        vec_type3 Fgi(gradient_values(i, point));
        vec_type3 Fhi1(hessian_values(2 * (i + 0) + 0, point));
        vec_type3 Fhi2(hessian_values(2 * (i + 0) + 1, point));

        for (uint j = 0; j <= i; j++) {
          scalar_type rmm = rmm_input(j,i);
          scalar_type Fj = function_values(j, point);
          w += Fj * rmm;

          vec_type3 Fgj(gradient_values(j, point));
          w3 += Fgj * rmm;

          vec_type3 Fhj1(hessian_values(2 * (j + 0) + 0, point));
          vec_type3 Fhj2(hessian_values(2 * (j + 0) + 1, point));
          ww1 += Fhj1 * rmm;
          ww2 += Fhj2 * rmm;
        }
        partial_density += Fi * w;

        dxyz += Fgi * w + w3 * Fi;
        dd1 += Fgi * w3 * 2 + Fhi1 * w + ww1 * Fi;

        vec_type3 FgXXY(Fgi.x(), Fgi.x(), Fgi.y());
        vec_type3 w3YZZ(w3.y(), w3.z(), w3.z());
        vec_type3 FgiYZZ(Fgi.y(), Fgi.z(), Fgi.z());
        vec_type3 w3XXY(w3.x(), w3.x(), w3.y());

        dd2 += FgXXY * w3YZZ + FgiYZZ * w3XXY + Fhi2 * w + ww2 * Fi;
      }
    }
    timers.density.pause();

    timers.forces.start();
    /** density derivatives **/
    if (compute_forces) {
      dd.resize(total_nucleii(), 1); dd.zero();
      for (uint i = 0, ii = 0; i < total_functions_simple(); i++) {
        uint nuc = func2local_nuc(ii);
        uint inc_i = small_function_type(i);
        vec_type3 this_dd = vec_type3(0,0,0);
        for (uint k = 0; k < inc_i; k++, ii++) {
          scalar_type w = 0.0;
          for (uint j = 0; j < group_m; j++) {
            scalar_type Fj = function_values(j, point);
            w += rmm_input(j, ii) * Fj * (ii == j ? 2 : 1);
          }
          this_dd -= gradient_values(ii, point) * w;
        }
        dd(nuc) += this_dd;
      }
    }
    timers.forces.pause();

    timers.pot.start();

    timers.density.start();
    /** energy / potential **/
    scalar_type exc = 0, corr = 0, y2a = 0;
    if (lda)
      cpu_pot(partial_density, exc, corr, y2a);
    else {
      cpu_potg(partial_density, dxyz, dd1, dd2, exc, corr, y2a);
    }

    timers.pot.pause();

    if (compute_energy)
      energy += (partial_density * point_it->weight) * (exc + corr);
    timers.density.pause();


    /** forces **/
    timers.forces.start();
    if (compute_forces) {
      scalar_type factor = point_it->weight * y2a;
      for (uint i = 0; i < total_nucleii(); i++)
        forces(i) += dd(i) * factor;
    }
    timers.forces.pause();

    /** RMM **/
    timers.rmm.start();
    if (compute_rmm) {
      scalar_type factor = point_it->weight * y2a;
      HostMatrix<scalar_type>::blas_ssyr(LowerTriangle, factor, function_values, rmm_output, point);
    }
    timers.rmm.pause();
  }

  timers.forces.start();
  /* accumulate force results for this group */
  if (compute_forces) {
    FortranMatrix<double> fort_forces(fort_forces_ptr, fortran_vars.atoms, 3, fortran_vars.max_atoms); // TODO: mover esto a init.cpp
    for (uint i = 0; i < total_nucleii(); i++) {
      uint global_atom = local2global_nuc[i];
      vec_type3 this_force = forces(i);
      fort_forces(global_atom,0) += this_force.x();
      fort_forces(global_atom,1) += this_force.y();
      fort_forces(global_atom,2) += this_force.z();
    }
  }
  timers.forces.pause();

  timers.rmm.start();
  /* accumulate RMM results for this group */
  if (compute_rmm) {
    for (uint i = 0, ii = 0; i < total_functions_simple(); i++) {
      uint inc_i = small_function_type(i);
      for (uint k = 0; k < inc_i; k++, ii++) {
        uint big_i = local2global_func[i] + k;

        for (uint j = 0, jj = 0; j < total_functions_simple(); j++) {
          uint inc_j = small_function_type(j);
          for (uint l = 0; l < inc_j; l++, jj++) {
            uint big_j = local2global_func[j] + l;
            if (big_i > big_j) continue;

            uint big_index = (big_i * fortran_vars.m - (big_i * (big_i - 1)) / 2) + (big_j - big_i);
            fortran_vars.rmm_output(big_index) += rmm_output(ii, jj);
          }
        }
      }
    }
  }
  timers.rmm.pause();

  #if CPU_RECOMPUTE
  /* clear functions */
  function_values.deallocate();
  gradient_values.deallocate();
  hessian_values.deallocate();
  #endif
}
예제 #11
0
파일: main.cpp 프로젝트: astrellon/GPP
// Physics thread that controls the motion of all the spheres.
void physicsThread(int threadNum)
{
	int localFrame = 0;

	// Define the normals for each of the walls.
	static const Vector3 bottom(0, 1, 0);
	static const Vector3 left(1, 0, 0);
	static const Vector3 right(-1, 0, 0);
	static const Vector3 front(0, 0, -1);
	static const Vector3 back(0, 0, 1);

	// Initialize the starting values for the wall and sphere, spring and damping values.
	float wallSpringConst = UPPER_WALL_SPRING_CONST;
	float sphereSpringConst = UPPER_SPHERE_SPRING_CONST;

	float wallDampFactor = UPPER_WALL_DAMP_FACTOR;
	float sphereDampFactor = UPPER_SPHERE_DAMP_FACTOR;

	// The physics thread itself deals with reseting its frame counter. 
	// It will do this once a second.
	float secondCheck = 0.0f;

#if _USE_MT
	// If the physics function is being called as a thread, then we don't want it 
	// to finish after one pass.
	int threadRunning = 0;
	while(programRunning)
	{
		// If the simulation needs to be paused but the thread is running,
		// stop.
		if(pauseSimulation && threadRunning)
		{
			threadRunning = 0;
			threadStopped();
		}
		// If the simulation needs to be running but the thread is stopped,
		// start.
		else if(!pauseSimulation && !threadRunning)
		{
			threadRunning = 1;
			threadStarted();
		}

		// If the thread isn't running at this time we can't go any further and 
		// we'll just wait and check if the thread has started up next time the
		// thread is executing.
		if(!threadRunning)
		{
			boost::this_thread::yield();
			continue;
		}
#endif

		localFrame++;

		LARGE_INTEGER time;
		QueryPerformanceCounter(&time);

		// Get the time since this thread last executed and convert into
		// seconds (from milliseconds).
		float dt = (float)(((double)time.QuadPart - (double)updateTimes[threadNum].QuadPart) / freq);
		dt *= 0.001;

		// Adjust the spring and dampening values based on dt.
		// This helps when going to lower frame rates and the overlap between
		// the walls and spheres when using high frame rate values will cause
		// the spheres to gain energy.
		wallSpringConst = WALL_SPRING_GRAD * dt + WALL_SPRING_CONST;
		sphereSpringConst = SPHERE_SPRING_GRAD * dt + SPHERE_SPRING_CONST;

		wallDampFactor = WALL_DAMP_GRAD * dt + WALL_DAMP_CONST;
		sphereDampFactor = SPHERE_DAMP_GRAD * dt + SPHERE_DAMP_CONST;

		// As the gradients for the spring and dampening factors are negative,
		// we want to clamp the lower bounds of the values. Otherwise at low
		// framerates the values will be negative.
		if (wallSpringConst < LOWER_WALL_SPRING_CONST)
			wallSpringConst = LOWER_WALL_SPRING_CONST;

		if (sphereSpringConst < LOWER_SPHERE_SPRING_CONST)
			sphereSpringConst = LOWER_SPHERE_SPRING_CONST;

		if (wallDampFactor < LOWER_WALL_DAMP_FACTOR)
			wallDampFactor = LOWER_WALL_DAMP_FACTOR;

		if (sphereDampFactor < LOWER_SPHERE_DAMP_FACTOR)
			sphereDampFactor = LOWER_SPHERE_DAMP_FACTOR;

		// If this is the 1st thread, then we will deal with the user controlled
		// sphere here.
		int startSphere = threadNum;
		if(threadNum == 0)
		{
			// Skip calcuating the user sphere like a typical sphere.
			startSphere += numPhysicsThreads;

			// As the user controlled sphere only has a position and velocity
			// that is either zero or constant, we can easily calculate its new
			// position.
			if(numSpheres > 0)
			{
				spherePositions[0] += sphereData[0].m_velocity * dt;
			}
		}

		for(int i = startSphere; i < numSpheres; i += numPhysicsThreads)
		{
			// Calculate the radius of the sphere based on array index.
			float radius = (float)((i % 3) + 1) * 0.5f;
			float roomSize = ROOM_SIZE - radius;
			
			Vector3 forces(0);

			Vector3 &spherePosition = spherePositions[i];
			SphereData &sphere = sphereData[i];

			// Calculate the interim velocity.
			Vector3 halfVelo = sphere.m_velocity + (0.5f * sphere.m_acc * dt);
			spherePosition += halfVelo * dt;

			Vector3 tempVelocity = sphere.m_velocity + (sphere.m_acc * dt);

			float overlap;

			// As the % operator is fairly slow we can take advantage here
			// that we always know what the next value in the array is going
			// to be and manually determine the mod.
			int indexCounter = 0;
			
			for(int j = 0; j < numSpheres; j++)
			{
				// And since we don't want the actual mod value but mod + 1
				// we don't worry about resetting to 0.
				indexCounter++;
				if(indexCounter > 3)
					indexCounter = 1;

				// We don't want a sphere to check if it's collided with itself.
				if(i == j)
					continue;

				SphereData &otherSphere = sphereData[j];
				Vector3 toCentre = spherePosition - spherePositions[j];
				// An unfortunately slow way of checking if the radius of the
				// other sphere should be the other spheres actual radius or
				// the user controlled spheres radius.
				float otherRadius; 
				if(j == 0)
				{
					otherRadius = userSphereSize;
				}
				else
				{
					otherRadius = (float)(indexCounter) * 0.5f;
				}

				float combinedRadius = radius + otherRadius;
				float lengthSqrd = lengthSquared(toCentre);
				float combinedRadiusSqrd = combinedRadius * combinedRadius;
				
				// A check to see if the spheres have overlapped at all.
				float overlapSqrd = lengthSqrd - combinedRadiusSqrd;
				if(overlapSqrd < 0)
				{
#if _SSE
					overlap = sqrt(lengthSqrd) - combinedRadius;
					// We want to let the vector normalize itself in SSE
					// because we can take advantage of the rsqrt instruction
					// which will be quicker than loading in a float value
					// and multiplying by the reciprocal.
					Vector3 tangent = normalize(toCentre);
#else
					// Here we can take advantage that we've already calculated
					// the actual length value so that we have the overlap and
					// can use that value again to normalize the tangent.
					float len = sqrt(lengthSqrd);
					overlap = len - combinedRadius;
					Vector3 tangent = toCentre / len;
#endif
					calcForce(forces, sphereSpringConst, sphereDampFactor, overlap, tangent, tempVelocity);
				}
			}
			
			// Calculate the overlap with the walls using the normal of the wall
			// and the walls distance from the origin. Should work best for SSE
			// as it should not require any checking of individual elements of
			// the vector.
			overlap = dot3(spherePosition, bottom) + roomSize;
			if(overlap < 0)
			{
				calcForce(forces, wallSpringConst, wallDampFactor, overlap, bottom, tempVelocity);
			}

			overlap = dot3(spherePosition, left) + roomSize;
			if(overlap < 0)
			{
				calcForce(forces, wallSpringConst, wallDampFactor, overlap, left, tempVelocity);
			}
			overlap = dot3(spherePosition, right) + roomSize;
			if(overlap < 0)
			{
				calcForce(forces, wallSpringConst, wallDampFactor, overlap, right, tempVelocity);
			}

			overlap = dot3(spherePosition, front) + roomSize;
			if(overlap < 0)
			{
				calcForce(forces, wallSpringConst, wallDampFactor, overlap, front, tempVelocity);
			}
			overlap = dot3(spherePosition, back) + roomSize;
			if(overlap < 0)
			{
				calcForce(forces, wallSpringConst, wallDampFactor, overlap, back, tempVelocity);
			}

			// Apply the accumulated forces to the acceleration.
			sphere.m_acc = forces / (radius * 2.0f);
			sphere.m_acc += GRAVITY;

			// Calculate the final velocity value from the interim velocity
			// and final acceleration.
			sphere.m_velocity = halfVelo + (0.5f * sphere.m_acc * dt);
		}

		// Determin if we need to reset out physics frame counter.
		secondCheck += dt;
		if(secondCheck > 1.0f)
		{
			physicsFrames[threadNum] = 1;
			secondCheck -= 1.0f;
		}
		else
		{
			physicsFrames[threadNum]++;
		}

		updateTimes[threadNum] = time;

		// If we're running the physics function as a thread function then we
		// need to keep it running, so this is the end of the while(programRunning) loop.
#if _USE_MT
	}
#endif
}
int main (void)
{   double t0=omp_get_wtime();
    // Open I/O for business!
    ifp = fopen(INPUT, "r"); // Open input file for reading
    ofp = fopen(OUTPUT, "w"); // Open output file for writing

    // Verify that I/O files are open
    if (ifp != 0) {
         printf("Input file is open\n");
    } else {
        printf("***ERROR*** Unable to open the input file\n");
        getchar();
        return 0;
    }
    if (ofp != 0) {
        printf("Output file is open\n");
    } else {
        printf("***ERROR*** Unable to open the output file\n");
        getchar();
        return 0;
    }

    // Read in number of elements, joints from input file
    fscanf(ifp, "%d,%d\n", &ne, &nj);
    fprintf(ofp, "Control Variables:\n\tNumber of Elements: %d\n", ne);
    fprintf(ofp, "\tNumber of Joints: %d\n\n", nj);

    /*
    Associate pointers with base address of arrays in function calls: parea = area;
        Note: in this context "&" can be omitted to obtain "&area[0]"
        Note: previous remark only works for 1D arrays: px=&x[0][0]
    */

    // Define secondary variables which DO NOT depend upon neq
    double x[3][nj];							// Current joint coordinates
    int mcode[6][ne], jcode[3][nj], minc[2][ne];// Member incidence and constraint data
    double emod[ne];							// Element material properties
	double eleng[ne], deflen[ne], elong[ne];	// Element length, deformed length, and elongation
    double area[ne];							// Element cross-sectional properties
    double c1[ne], c2[ne], c3[ne];				// Direction cosines
    double qi, dqi;								// Current and incremental load proportionality factor
    double qimax;								// Maximum allowable load proportionality factor
    
	// Convergence parameters
    double tolfor, tolener;						// Tolerances on force and energy
    double intener1;							// Internal energy from first equilibrium iteration
    int inconv;									// Flag for convergence test
    int itecnt, itemax;							// Iteration counter and max number of iterations
    int errchk;									// Error check variable on user defined functions
    int i;										// Counter variable
    int csrflag=0;
    // Pass control to struc function
    errchk = struc(&jcode[0][0], &minc[0][0]);

    // Terminate program if errors encountered
    if (errchk == 1) {
        fprintf(ofp, "\n\nSolution failed\n");
        printf("Solution failed, see output file\n");

        // Close the I/O
        if (fclose(ifp) != 0) {
            printf("***ERROR*** Unable to close the input file\n");
        } else {
            printf("Input file is closed\n");
        }
        if (fclose(ofp) != 0) {
            printf("***ERROR*** Unable to close the output file\n");
        } else {
            printf("Output file is closed\n");
        }
        getchar();
        return 0;
    }

    // Pass control to codes function
    codes (&mcode[0][0], &jcode[0][0], &minc[0][0]);
    printf("number of equations: %d\n", neq);
    // Define secondary variables which DO depend upon neq
    double q[neq];						// Reference load vector
    double qtot[neq];					// Total load vector, i.e. qi * q[neq]
    double d[neq], dd[neq];				// Total and incremental nodal displacement vectors
    double f[neq];						// Internal force vector
    double fp[neq];						// Internal force vector from previous load increment
    double fpi[neq];					// Internal force vector from previous iteration
    double r[neq];						// Residual force vector, i.e. qtot - f
    int maxa[neq + 1], kht[neq], lss;	// Skyline storage parameters for stiffness matrix

    // Pass control to skylin function
    skylin (kht, maxa, &mcode[0][0], &lss);
    printf("size of stiffness matrix as a 1D element: %d\n",lss);
    // Define secondary variable which depends upon lss (the size of the stiffness marix as a 1D array)
    double *ss= (double *)malloc(lss*sizeof(double));						// Tangent stiffness matrix stored as an array

    // Pass control to prop function
    prop (&x[0][0], area, emod, eleng, c1, c2, c3, &minc[0][0]);

    // Pass control to load function
    errchk = load (q, &jcode[0][0]);

    // Terminate program if errors encountered
    if (errchk == 1) {
        fprintf(ofp, "\n\nSolution failed\n");
        printf("Solution failed, see output file\n");

        // Close the I/O
        if (fclose(ifp) != 0) {
            printf("***ERROR*** Unable to close the input file\n");
        } else {
            printf("Input file is closed\n");
        }
        if (fclose(ofp) != 0) {
            printf("***ERROR*** Unable to close the output file\n");
        } else {
            printf("Output file is closed\n");
        }
        getchar();
        return 0;
    }

    // Read in solver parameters from input file
    fscanf(ifp, "%lf,%lf,%lf\n", &qimax, &qi, &dqi);
    fscanf(ifp, "%d\n", &itemax);
    fscanf(ifp, "%lf,%lf\n", &tolfor, &tolener);

    // Print layout for output of results
    fprintf(ofp, "\nNonlinear Equilibrium Path:\n\tLambda\t");
    for (i = 0; i <= neq - 1; ++i) {
        fprintf(ofp, "\tDOF %d\t", i + 1);
    }

    // Initialize generalized nodal displacement and internal force vectors
    for (i = 0; i <= neq - 1; ++i) {
        d[i] = 0;
        f[i] = 0;
    }

    // Initialize element length and elongation variables
    for (i = 0; i <= ne - 1; ++i) {
        deflen[i] = eleng[i];
        elong[i] = 0;
    }

    /* Begin load incrementation; load will be incremented until load proportionality
       factor is equal to user specified maximum */
    do {
        /* Compute the generalized joint total load vector, store generalized internal
           force vector from previous configuration and re-initialize */
        for (i = 0; i <= neq - 1; ++i) {
            qtot[i] = q[i] * qi;
            fp[i] = f[i];
            f[i] = 0;
        }

        // Pass control to forces function
        forces (f, area, emod, c1, c2, c3, elong, eleng, &mcode[0][0]);

        itecnt = 1;  // Re-initialize iteration counter at the start of each increment
	
        /* Start of each equilibrium iteration within load increment; iterations will
           continue until convergence is reached or iteration count exceeds user
           specified maximum */
        do {
	    printf("iteration: %d\n", itecnt);
	    //printf("iteration count: %d \n", itecnt);
            // Compute residual force vector for use in evaluating displacement increment
            for (i = 0; i <= neq - 1; ++i) {
                r[i] = qtot[i] - f[i];
            }

            // Pass control to stiff function
            stiff (ss, area, emod, eleng, c1, c2, c3, elong, maxa, &mcode[0][0], &lss);
	    if (csrflag==1){
	    	write_array_double("asky", lss, ss);
	    	write_array_int("maxa", neq+1, maxa);
            	write_array_double("r", neq, r);
	    }
		// Solve the system for incremental displacements
            if (lss == 1) {
                // Carry out computation of incremental displacement directly for lss = 1
                dd[0] = r[0] / ss[0];
            } else {
                // Pass control to solve function
                errchk = solve (ss, r, dd, maxa);
	
	        if (csrflag==1){
	   		write_array_double("dd", neq, dd);    
	        }
		++csrflag;
                // Terminate program if errors encountered
                if (errchk == 1) {
                    fprintf(ofp, "\n\nSolution failed\n");
                    printf("Solution failed, see output file\n");

                    // Close the I/O
                    if (fclose(ifp) != 0) {
                        printf("***ERROR*** Unable to close the input file\n");
                    } else {
                        printf("Input file is closed\n");
                    }
                    if (fclose(ofp) != 0) {
                        printf("***ERROR*** Unable to close the output file\n");
                    } else {
                        printf("Output file is closed\n");
                    }
                    getchar();
                    return 0;
                }
            }

            /* Update generalized nodal displacement vector, store generalized internal
               force vector from previous iteration, and re-initialize generalized
               internal force vector */
            for (i = 0; i <= neq - 1; ++i) {
                d[i] += dd[i];
                fpi[i] = f[i];
                f[i] = 0;
            }

            // Pass control to forces function
            updatc (&x[0][0], dd, c1, c2, c3, elong, eleng, deflen, &minc[0][0],
                &jcode[0][0]);

            // Pass control to forces function
            forces (f, area, emod, c1, c2, c3, elong, eleng, &mcode[0][0]);

            if (itecnt == 1) {
                // Compute internal energy from first iteration
                intener1 = 0;
            	for (i = 0; i <= neq - 1; ++i) {
            		intener1 += dd[i] * (qtot[i] - fp[i]);
            	}
            }

            // Pass control to test function
            test (f, fp, qtot, dd, fpi, &intener1, &inconv, &neq, &tolfor, &tolener);

            itecnt ++; // Advance solution counter

        } while (inconv != 0 && itecnt <= itemax);

        // Store generalized internal force vector from current configuration
        for (i = 0; i <= neq - 1; ++i) {
            fp[i] = f[i];
        }

        if (inconv != 0) {
            fprintf(ofp, "\n\n***ERROR*** Convergence not reached within specified");
            fprintf(ofp, " number of iterations (INCONV = %d)", inconv);
            fprintf(ofp, "\n\nSolution failed\n");
            printf("Solution failed, see output file\n");

            // Close the I/O
            if (fclose(ifp) != 0) {
                printf("***ERROR*** Unable to close the input file\n");
            } else {
                printf("Input file is closed\n");
            }
            if (fclose(ofp) != 0) {
                printf("***ERROR*** Unable to close the output file\n");
            } else {
                printf("Output file is closed\n");
            }
            getchar();
            return 0;
        }

        // Output model response
        fprintf(ofp, "\n\t%lf", qi);
        for (i = 0; i <= neq - 1; ++i) {
            fprintf(ofp, "\t%lf", d[i]);
        }

        qi += dqi; // Increment load proportionality factor

    } while (qi <= qimax);

    if (qi >= qimax && inconv == 0) {
        fprintf(ofp, "\n\nSolution successful\n");
        printf("Solution successful\n");
    }

    // Close the I/O
    if (fclose(ifp) != 0) {
        printf("***ERROR*** Unable to close the input file\n");
    } else {
        printf("Input file is closed\n");
    }
    if (fclose(ofp) != 0) {
        printf("***ERROR*** Unable to close the output file\n");
    } else {
        printf("Output file is closed\n");
    }
    getchar(); 
    double t1 = omp_get_wtime();
    printf("Total time spent (IO+computation): %g\n",t1-t0);
    return 0;
}
예제 #13
0
파일: nbody.cpp 프로젝트: egaburov/vmath
const real iterate(
    const int n,
    real4 pos[],
    real4 vel[],
    real4 acc[],
    real4 jrk[],
    const real eta,
    const real eps2,
    const real dt) 
{
  std::vector<real4> acc0(n), jrk0(n);
  const real dt2 = dt*(1.0/2.0);
  const real dt3 = dt*(1.0/3.0);

  for (int i = 0; i < n; i++)
  {
    acc0[i] = acc[i];
    jrk0[i] = jrk[i];

    pos[i].x += dt*(vel[i].x + dt2*(acc[i].x + dt3*jrk[i].x));
    pos[i].y += dt*(vel[i].y + dt2*(acc[i].y + dt3*jrk[i].y));
    pos[i].z += dt*(vel[i].z + dt2*(acc[i].z + dt3*jrk[i].z));

    vel[i].x += dt*(acc[i].x + dt2*jrk[i].x);
    vel[i].y += dt*(acc[i].y + dt2*jrk[i].y);
    vel[i].z += dt*(acc[i].z + dt2*jrk[i].z);
  }

  forces(n, pos, vel, acc, jrk, eps2);

  if (dt > 0.0)
  {
    const real h    = dt*0.5;
    const real hinv = 1.0/h;
    const real f1   = 0.5*hinv*hinv;
    const real f2   = 3.0*hinv*f1;

    const real dt2  = dt *dt * (1.0/2.0);
    const real dt3  = dt2*dt * (1.0/3.0);
    const real dt4  = dt3*dt * (1.0/4.0);
    const real dt5  = dt4*dt * (1.0/5.0);

    for (int i = 0; i < n; i++)
    {

      /* compute snp & crk */

      const real4 Am(   acc[i].x - acc0[i].x,     acc[i].y - acc0[i].y,     acc[i].z - acc0[i].z);
      const real4 Jm(h*(jrk[i].x - jrk0[i].x), h*(jrk[i].y - jrk0[i].y), h*(jrk[i].z - jrk0[i].z));
      const real4 Jp(h*(jrk[i].x + jrk0[i].x), h*(jrk[i].y + jrk0[i].y), h*(jrk[i].z + jrk0[i].z));
      real4 snp(f1* Jm.x,         f1* Jm.y,         f1* Jm.z        );
      real4 crk(f2*(Jp.x - Am.x), f2*(Jp.y - Am.y), f2*(Jp.z - Am.z));

      snp.x -= h*crk.x;
      snp.y -= h*crk.y;
      snp.z -= h*crk.z;

      /* correct */

      pos[i].x += dt4*snp.x + dt5*crk.x;
      pos[i].y += dt4*snp.y + dt5*crk.y;
      pos[i].z += dt4*snp.z + dt5*crk.z;

      vel[i].x += dt3*snp.x + dt4*crk.x;
      vel[i].y += dt3*snp.y + dt4*crk.y;
      vel[i].z += dt3*snp.z + dt4*crk.z;
    }
  }

  return timestep(n, vel, acc, eta, eps2);
}
예제 #14
0
void Colvar::apply(){
  vector<Vector>&   f(modifyForces());
  Tensor&           v(modifyVirial());
  const unsigned    nat=getNumberOfAtoms();
  const unsigned    ncp=getNumberOfComponents();
  const unsigned    fsz=f.size();

  for(unsigned i=0;i<fsz;i++) f[i].zero();
  v.zero();

  unsigned stride=1;
  unsigned rank=0;
  if(ncp>comm.Get_size()) {
    stride=comm.Get_size();
    rank=comm.Get_rank();
  }

  unsigned nt=OpenMP::getNumThreads();
  if(nt>ncp/(2.*stride)) nt=1;

  if(!isEnergy){
    #pragma omp parallel num_threads(nt) 
    {
      vector<Vector> omp_f(fsz);
      Tensor         omp_v;
      vector<double> forces(3*nat+9);
      #pragma omp for 
      for(unsigned i=rank;i<ncp;i+=stride){
        if(getPntrToComponent(i)->applyForce(forces)){
          for(unsigned j=0;j<nat;++j){
            omp_f[j][0]+=forces[3*j+0];
            omp_f[j][1]+=forces[3*j+1];
            omp_f[j][2]+=forces[3*j+2];
          }
          omp_v(0,0)+=forces[3*nat+0];
          omp_v(0,1)+=forces[3*nat+1];
          omp_v(0,2)+=forces[3*nat+2];
          omp_v(1,0)+=forces[3*nat+3];
          omp_v(1,1)+=forces[3*nat+4];
          omp_v(1,2)+=forces[3*nat+5];
          omp_v(2,0)+=forces[3*nat+6];
          omp_v(2,1)+=forces[3*nat+7];
          omp_v(2,2)+=forces[3*nat+8];
        }
      }
      #pragma omp critical
      {
        for(unsigned j=0;j<nat;++j) f[j]+=omp_f[j]; 
        v+=omp_v;
      }
    }

    if(ncp>comm.Get_size()) {
      if(fsz>0) comm.Sum(&f[0][0],3*fsz);
      comm.Sum(&v[0][0],9);
    }

  } else if( isEnergy ){
    vector<double> forces(1);
    if(getPntrToComponent(0)->applyForce(forces)) modifyForceOnEnergy()+=forces[0];
  }
}
예제 #15
0
int fmm_stokes_solver(int ,char **)
{
    srand(0);
    typedef double value_type;
    size_t num_sources = 100;
    size_t num_targets = 100;
    size_t size_sources = 3*num_sources;
    size_t size_targets = 3*num_targets;
    std::vector<value_type> sources(size_sources), targets(size_targets), velocities(size_targets), forces(size_sources);
    value_type delta = .01;
    FmmStokesSolver<double,25,6> solver(num_sources);
    solver.setDelta(delta);

    std::generate(sources.begin(),sources.end(),random_generator<value_type>());
    std::generate(targets.begin(),targets.end(),random_generator<value_type>());
    std::generate(velocities.begin(),velocities.end(),random_generator<value_type>());
    std::generate(forces.begin(),forces.end(),random_generator<value_type>());

    solver(0,&targets[0],&velocities[0],&sources[0],&forces[0]);
    
    return 0;
}
예제 #16
0
파일: main.c 프로젝트: saifmulla/MolDyn
/*
 *  Main program : Molecular Dynamics simulation.
 */
int main(){
    int move;
    double x[npart*3], vh[npart*3], f[npart*3];
    double ekin;
    double vel;
    double sc;
    double start, time;


  /*
   *  Parameter definitions
   */

    double den    = 0.83134;
    double side   = pow((double)npart/den,0.3333333);
    double tref   = 0.722;
    double rcoff  = (double)mm/4.0;
    double h      = 0.064;
    int    irep   = 10;
    int    istop  = 20;
    int    iprint = 5;
    int    movemx = 20;

    double a      = side/(double)mm;
    double hsq    = h*h;
    double hsq2   = hsq*0.5;
    double tscale = 16.0/((double)npart-1.0);
    double vaver  = 1.13*sqrt(tref/24.0);

  /*
   *  Initial output
   */

    printf(" Molecular Dynamics Simulation example program\n");
    printf(" ---------------------------------------------\n");
    printf(" number of particles is ............ %6d\n",npart);
    printf(" side length of the box is ......... %13.6f\n",side);
    printf(" cut off is ........................ %13.6f\n",rcoff);
    printf(" reduced temperature is ............ %13.6f\n",tref);
    printf(" basic timestep is ................. %13.6f\n",h);
    printf(" temperature scale interval ........ %6d\n",irep);
    printf(" stop scaling at move .............. %6d\n",istop);
    printf(" print interval .................... %6d\n",iprint);
    printf(" total no. of steps ................ %6d\n",movemx);

  /*
   *  Generate fcc lattice for atoms inside box
   */
    fcc(x, npart, mm, a);
  /*
   *  Initialise velocities and forces (which are zero in fcc positions)
   */
    mxwell(vh, 3*npart, h, tref);
    dfill(3*npart, 0.0, f, 1);
  /*
   *  Start of md
   */
    printf("\n    i       ke         pe            e         temp   "
           "   pres      vel      rp\n  -----  ----------  ----------"
           "  ----------  --------  --------  --------  ----\n");

     start = secnds(); 


    for (move=1; move<=movemx; move++) {

    /*
     *  Move the particles and partially update velocities
     */
      domove(3*npart, x, vh, f, side);

    /*
     *  Compute forces in the new positions and accumulate the virial
     *  and potential energy.
     */
      forces(npart, x, f, side, rcoff);
	//kernelWrapper(npart,x,f,side,rcoff);

    /*
     *  Scale forces, complete update of velocities and compute k.e.
     */
      ekin=mkekin(npart, f, vh, hsq2, hsq);
    /*
     *  Average the velocity and temperature scale if desired
     */
      vel=velavg(npart, vh, vaver, h);
      if (move<istop && fmod(move, irep)==0) {
        sc=sqrt(tref/(tscale*ekin));
        dscal(3*npart, sc, vh, 1);
        ekin=tref/tscale;
      }

    /*
     *  Sum to get full potential energy and virial
     */
      if (fmod(move, iprint)==0)
        prnout(move, ekin, epot, tscale, vir, vel, count, npart, den);
      
    }

    time = secnds() - start;  

    printf("Time =  %f\n",(float) time);  

  }
    void MainWindow::applyForce( eForceType type ) {
        bool play = getSimulationThread().getSimulator().isPlaying();
        if (play) {
            pause();
        }
        getSimulationThread().wait();
        getSimulationThread().getSimulator().getLock().lockForRead();
        Creature* creature = getSimulationThread().getSimulator().currentCreature();
        if (creature) {

            if (type == FT_NONE) {
                for (int i = 0; i < creature->getNumberOfBodyParts(); ++i) {
                    creature->getBodyPart(i).getRigidBody()->clearForces();
                }
                getUiInspector().sbx_force_x->setValue(0.0);
                getUiInspector().sbx_force_y->setValue(0.0);
                getUiInspector().sbx_force_z->setValue(0.0);
            } else {
                std::vector<btRigidBody*>& bodies = getRendererThread().getRenderer().getSelectedBodyParts();
                btVector3 forces(getUiInspector().sbx_force_x->value(),
                        getUiInspector().sbx_force_y->value(),
                        getUiInspector().sbx_force_z->value());

                for (std::vector<btRigidBody*>::iterator it = bodies.begin();
                        it != bodies.end(); ++it) {
                    btRigidBody* rigid_body = *it;
                    BodyPart* body = NULL;
                    for (int i = 0; i < creature->getNumberOfBodyParts(); ++i) {
                        if (creature->getBodyPart(i).getRigidBody() == rigid_body) {
                            body = &creature->getBodyPart(i);
                            break;
                        }
                    }
                    assert(body);
                    rigid_body->activate(true);
                    switch (type) {
                        case FT_CENTRAL_FORCE: rigid_body->applyCentralForce(forces);
                            break;
                        case FT_CENTRAL_TORQUE: rigid_body->applyTorque(forces);
                            break;
                        case FT_IMPULSE_FORCE: rigid_body->applyCentralImpulse(forces);
                            break;
                        case FT_IMPULSE_TORQUE: rigid_body->applyTorqueImpulse(forces);
                            break;
                        case FT_RELATIVE_FORCE:
                            break;
                        case FT_RELATIVE_IMPULSE:
                            rigid_body->applyImpulse(forces, btVector3(0, -body->getSizeY() / 2.0, 0));
                            break;
                        case FT_EACH_STEP:
//                            creature->setTmpValueX(forces.x());
//                            creature->setTmpValueY(forces.y());
//                            creature->setTmpValueZ(forces.z());
                            break;
                        default:
                            BDEBUG(TO_STRING(type));
                            assert(0);
                    }
                }
            }

        }
        getSimulationThread().getSimulator().getLock().unlock();
        if (play) {
            this->play();
        }
    }
예제 #18
0
int main(int argc, char ** argv)
{
    cl_float4 * x = initializePositions();

    std::string* source = loadKernelSource("src/kernels.cl");

    // Get available platforms
    std::vector<cl::Platform> platforms;
    cl::Platform::get(&platforms);

    // Select the default platform and create a context using this platform and the GPU
    cl_context_properties cps[3] = { 
        CL_CONTEXT_PLATFORM, 
        (cl_context_properties)(platforms[0])(), 
        0 
    };

    cl::Context context(CL_DEVICE_TYPE_GPU, cps);

    // Get a list of devices on this platform
    std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();

    // Create a command queue and use the first device
    cl::CommandQueue queue = cl::CommandQueue(context, devices[0]);
    cl::Program::Sources sources(1, std::make_pair(source->c_str(), source->length()+1));

    // Make program of the source code in the context
    cl::Program program = cl::Program(context, sources);

    // Build program for these specific devices
    try{
        program.build(devices);
    } catch(cl::Error error) {
        std::cout << error.what() << "(" << error.err() << ")" << std::endl;

        std::string build_log;
        build_log = program.getBuildInfo<CL_PROGRAM_BUILD_STATUS>(devices[0]);
        std::cout << "Build status: " << build_log << std::endl;

        build_log = program.getBuildInfo<CL_PROGRAM_BUILD_OPTIONS>(devices[0]);
        std::cout << "Build options: " << build_log << std::endl;

        build_log = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(devices[0]);
        std::cout << "Build log: " << build_log << std::endl;
        exit(0);
    }

    // Create buffers for points, centers of mass, and bins
    
    cl::Buffer pointsBuffer = 
      cl::Buffer(context, CL_MEM_READ_ONLY, POINTS * sizeof(cl_float4));
    cl::Buffer cmBuffer =  cl::Buffer(context, CL_MEM_READ_WRITE, BINS * sizeof(cl_float4));
    cl::Buffer binsBuffer = 
      cl::Buffer(context, CL_MEM_READ_WRITE, POINTS * sizeof(unsigned int));
    cl::Buffer offsetsBuffer = 
      cl::Buffer(context, CL_MEM_READ_WRITE, BINS * sizeof(unsigned int));

    // Upload points to GPU and compute the centers of mass

    queue.enqueueWriteBuffer(pointsBuffer, CL_TRUE, 0, POINTS * sizeof(cl_float4), x);
    computeBins(context, queue, program, &pointsBuffer, &cmBuffer);

    // Generate bin offsets

    genOffsets(context, queue, program, &cmBuffer, &offsetsBuffer);

    // Sort the bins, and then compute all forces

    sortBins(context, queue, program, &pointsBuffer, &offsetsBuffer, &binsBuffer);
    cl_float4* a = 
      forces(context, queue, program, &pointsBuffer, &cmBuffer, &offsetsBuffer, &binsBuffer);

    for(int i = 0; i < POINTS; i++){
        printf("(%2.2f,%2.2f,%2.2f,%2.2f) (%2.3f,%2.3f,%2.3f)\n", 
                   x[i].x, x[i].y, x[i].z, x[i].w,
                   a[i].x, a[i].y, a[i].z);
    }

    free(x);
    return 0;
}
예제 #19
0
  bool ECPotentialBuilder::put(xmlNodePtr cur) {

    if(localPot.empty()) {
      int ng(IonConfig.getSpeciesSet().getTotalNum());
      localZeff.resize(ng,1);
      localPot.resize(ng,0);
      nonLocalPot.resize(ng,0);
    }

    string ecpFormat("table");
    string pbc("yes");
    string forces("no");
    OhmmsAttributeSet pAttrib;
    pAttrib.add(ecpFormat,"format");
    pAttrib.add(pbc,"pbc");
    pAttrib.add(forces,"forces");
    pAttrib.put(cur);
    bool doForces = (forces == "yes") || (forces == "true");

    //const xmlChar* t=xmlGetProp(cur,(const xmlChar*)"format");
    //if(t != NULL) {
    //  ecpFormat= (const char*)t;
    //} 

    if(ecpFormat == "xml")  
    {
      useXmlFormat(cur);
    } 
    else 
    {
      useSimpleTableFormat();
    } 

    ///create LocalECPotential
    bool usePBC = 
      !(IonConfig.Lattice.SuperCellEnum == SUPERCELL_OPEN || pbc =="no");
    if(hasLocalPot) {
      if(IonConfig.Lattice.SuperCellEnum == SUPERCELL_OPEN || pbc =="no") 
      {
#ifdef QMC_CUDA
        LocalECPotential_CUDA* apot = 
	  new LocalECPotential_CUDA(IonConfig,targetPtcl);
#else
        LocalECPotential* apot = new LocalECPotential(IonConfig,targetPtcl);
#endif
        for(int i=0; i<localPot.size(); i++) {
          if(localPot[i]) apot->add(i,localPot[i],localZeff[i]);
        }
        targetH.addOperator(apot,"LocalECP");
      }
      else
      {
	if (doForces) 
	  app_log() << "  Will compute forces in CoulombPBCABTemp.\n" << endl;
#ifdef QMC_CUDA
        CoulombPBCAB_CUDA* apot=
	  new CoulombPBCAB_CUDA(IonConfig,targetPtcl, doForces);
#else
	CoulombPBCABTemp* apot =
	  new CoulombPBCABTemp(IonConfig,targetPtcl, doForces);
#endif
        for(int i=0; i<localPot.size(); i++) {
          if(localPot[i]) apot->add(i,localPot[i]);
        }
        targetH.addOperator(apot,"LocalECP");
      }
      //if(IonConfig.Lattice.BoxBConds[0]) {
      //  CoulombPBCABTemp* apot=new CoulombPBCABTemp(IonConfig,targetPtcl);
      //  for(int i=0; i<localPot.size(); i++) {
      //    if(localPot[i]) apot->add(i,localPot[i]);
      //  }
      //  targetH.addOperator(apot,"LocalECP");
      //} else {
      //  LocalECPotential* apot = new LocalECPotential(IonConfig,targetPtcl);
      //  for(int i=0; i<localPot.size(); i++) {
      //    if(localPot[i]) apot->add(i,localPot[i],localZeff[i]);
      //  }
      //  targetH.addOperator(apot,"LocalECP");
      //}
    }

    if(hasNonLocalPot) {
      //resize the sphere
      targetPtcl.resizeSphere(IonConfig.getTotalNum());
      RealType rc2=0.0;
#ifdef QMC_CUDA   
      NonLocalECPotential_CUDA* apot = 
	new NonLocalECPotential_CUDA(IonConfig,targetPtcl,targetPsi,usePBC,doForces);
#else
      NonLocalECPotential* apot = 
	new NonLocalECPotential(IonConfig,targetPtcl,targetPsi, doForces);
#endif

      for(int i=0; i<nonLocalPot.size(); i++) 
      {
        if(nonLocalPot[i]) 
        {
          rc2=std::max(rc2,nonLocalPot[i]->Rmax);
          apot->add(i,nonLocalPot[i]);
        }
      }
      targetPtcl.checkBoundBox(2*rc2);
      targetH.addOperator(apot,"NonLocalECP");

      for(int ic=0; ic<IonConfig.getTotalNum(); ic++) 
      {
        int ig=IonConfig.GroupID[ic];
        if(nonLocalPot[ig]) { 
          if(nonLocalPot[ig]->nknot) targetPtcl.Sphere[ic]->resize(nonLocalPot[ig]->nknot);
        }
      }
    }
    return true;
  }
예제 #20
0
void flexionFDSimulationWithHitMap(Model& model)
{
	addFlexionController(model);
	//addExtensionController(model);
	//addTibialLoads(model, 0);

    model.setUseVisualizer(true);

	// init system
	std::time_t result = std::time(nullptr);
	std::cout << "\nBefore initSystem() " << std::asctime(std::localtime(&result)) << endl;
	SimTK::State& si = model.initSystem();
	result = std::time(nullptr);
	std::cout << "\nAfter initSystem() " << std::asctime(std::localtime(&result)) << endl;
	
	// set gravity
	//model.updGravityForce().setGravityVector(si, Vec3(-9.80665,0,0));
	//model.updGravityForce().setGravityVector(si, Vec3(0,0,0));
	
	//setHipAngle(model, si, 90);
	//setKneeAngle(model, si, 0, false, false);
	//model.equilibrateMuscles( si);

	MultibodySystem& system = model.updMultibodySystem();
	SimbodyMatterSubsystem& matter = system.updMatterSubsystem();
	GeneralForceSubsystem forces(system);
	ContactTrackerSubsystem  tracker(system);
    CompliantContactSubsystem contactForces(system, tracker);
	contactForces.setTrackDissipatedEnergy(true);
    //contactForces.setTransitionVelocity(1e-3);

	for (int i=0; i < matter.getNumBodies(); ++i) {
		MobilizedBodyIndex mbx(i);
		if (i==19 || i==20 || i==22)// || i==15 || i==16)
		{
			MobilizedBody& mobod = matter.updMobilizedBody(mbx);
			std::filebuf fb;
			//cout << mobod.updBody().
			if (i==19)
				fb.open ( "../resources/femur_lat_r.obj",std::ios::in);
			else if (i==20)
				fb.open ( "../resources/femur_med_r.obj",std::ios::in);
			else if (i==22)
				fb.open ( "../resources/tibia_upper_r.obj",std::ios::in);
			//else if (i==15)
				//fb.open ( "../resources/meniscus_lat_r.obj",std::ios::in);
			//else if (i==16)
				//fb.open ( "../resources/meniscus_med_r.obj",std::ios::in);
			std::istream is(&fb);
			PolygonalMesh polMesh;
			polMesh.loadObjFile(is);
			fb.close();
			SimTK::ContactGeometry::TriangleMesh mesh(polMesh);
			ContactSurface contSurf;//(mesh, ContactMaterial(1.0e6, 1, 1, 0.03, 0.03), 0.001);
			if (i==19 || i==20 || i==22)
				contSurf = ContactSurface(mesh, ContactMaterial(10, 1, 1, 0.03, 0.03), 0.001);
			//else if (i==15 || i==16)
				//contSurf = ContactSurface(mesh, ContactMaterial(10, 3, 1, 0.03, 0.03), 0.001);
			DecorativeMesh showMesh(mesh.createPolygonalMesh());
			showMesh.setOpacity(0.5);
			mobod.updBody().addDecoration( showMesh);
			mobod.updBody().addContactSurface(contSurf);
		}
    }

	ModelVisualizer& viz(model.updVisualizer());
	//Visualizer viz(system);
	viz.updSimbodyVisualizer().addDecorationGenerator(new HitMapGenerator(system,contactForces));
    viz.updSimbodyVisualizer().setMode(Visualizer::RealTime);
    viz.updSimbodyVisualizer().setDesiredBufferLengthInSec(1);
    viz.updSimbodyVisualizer().setDesiredFrameRate(30);
    viz.updSimbodyVisualizer().setGroundHeight(-3);
    viz.updSimbodyVisualizer().setShowShadows(true);
	
    Visualizer::InputSilo* silo = new Visualizer::InputSilo();
	viz.updSimbodyVisualizer().addInputListener(silo);
    Array_<std::pair<String,int> > runMenuItems;
    runMenuItems.push_back(std::make_pair("Go", GoItem));
    runMenuItems.push_back(std::make_pair("Replay", ReplayItem));
    runMenuItems.push_back(std::make_pair("Quit", QuitItem));
    viz.updSimbodyVisualizer().addMenu("Run", RunMenuId, runMenuItems);

    Array_<std::pair<String,int> > helpMenuItems;
    helpMenuItems.push_back(std::make_pair("TBD - Sorry!", 1));
    viz.updSimbodyVisualizer().addMenu("Help", HelpMenuId, helpMenuItems);

    system.addEventReporter(new MyReporter(system,contactForces,ReportInterval));
	//system.addEventReporter(new Visualizer::Reporter(viz.updSimbodyVisualizer(), ReportInterval));
	
    // Check for a Run->Quit menu pick every <x> second.
	system.addEventHandler(new UserInputHandler(*silo, 0.001));

	system.realizeTopology();

	//Show ContactSurfaceIndex for each contact surface
  //  for (int i=0; i < matter.getNumBodies(); ++i) {
		//MobilizedBodyIndex mbx(i);
  //      const MobilizedBody& mobod = matter.getMobilizedBody(mbx);
  //      const int nsurfs = mobod.getBody().getNumContactSurfaces();
        //printf("mobod %d has %d contact surfaces\n", (int)mbx, nsurfs);
		////cout << "mobod with mass: " << (float)mobod.getBodyMass(si) << " has " << nsurfs << " contact surfaces" << endl;
		// //for (int i=0; i<nsurfs; ++i) {
  //          //printf("%2d: index %d\n", i, 
  //                 //(int)tracker.getContactSurfaceIndex(mbx,i)); 
  //      //}
  //  }

	//cout << "tracker num of surfaces: " << tracker.getNumSurfaces() << endl;

	//State state = system.getDefaultState();
	//viz.report(state);
	State& state = model.initializeState();
	viz.updSimbodyVisualizer().report(state);

	// Add reporters
    ForceReporter* forceReporter = new ForceReporter(&model);
    model.addAnalysis(forceReporter);

	CustomAnalysis* customReporter = new CustomAnalysis(&model, "r");
	model.addAnalysis(customReporter);

	// Create the integrator and manager for the simulation.
	SimTK::RungeKuttaMersonIntegrator integrator(model.getMultibodySystem());
	//SimTK::CPodesIntegrator integrator(model.getMultibodySystem());
	//integrator.setAccuracy(.01);
	//integrator.setAccuracy(1e-3);
	//integrator.setFixedStepSize(0.001);
	Manager manager(model, integrator);

	// Define the initial and final simulation times
	double initialTime = 0.0;
	double finalTime = 0.2;

	// Integrate from initial time to final time
	manager.setInitialTime(initialTime);
	manager.setFinalTime(finalTime);
	std::cout<<"\n\nIntegrating from "<<initialTime<<" to " <<finalTime<<std::endl;

	result = std::time(nullptr);
	std::cout << "\nBefore integrate(si) " << std::asctime(std::localtime(&result)) << endl;

	manager.integrate(state);

	result = std::time(nullptr);
	std::cout << "\nAfter integrate(si) " << std::asctime(std::localtime(&result)) << endl;

	// Save the simulation results
	Storage statesDegrees(manager.getStateStorage());
	statesDegrees.print("../outputs/states_flex.sto");
	model.updSimbodyEngine().convertRadiansToDegrees(statesDegrees);
	statesDegrees.setWriteSIMMHeader(true);
	statesDegrees.print("../outputs/states_degrees_flex.mot");
	// force reporter results
	forceReporter->getForceStorage().print("../outputs/force_reporter_flex.mot");
	//customReporter->print( "../outputs/custom_reporter_flex.mot");

	//cout << "You can choose 'Replay'" << endl;
	int menuId, item;
	unsigned int frameRate = 5;
	do { 
		cout << "Please choose 'Replay' or 'Quit'" << endl;
		viz.updInputSilo().waitForMenuPick(menuId, item);

        if (item != ReplayItem && item != QuitItem) 
            cout << "\aDude... follow instructions!\n";
		if (item == ReplayItem)
		{
			cout << "Type desired frame rate (integer) for playback and press Enter (default = 1) : ";
			//frameRate = cin.get();		
			cin >> frameRate;
			if (cin.fail()) 
			{
				cout << "Not an int. Setting default frame rate." << endl;
				cin.clear();
				cin.ignore(std::numeric_limits<int>::max(),'\n');
				frameRate = 1;
			}

			//cout << "saveEm size: " << saveEm.size() << endl;
			for (unsigned int i=0; i<saveEm.size(); i++)
			{
				viz.updSimbodyVisualizer().drawFrameNow(saveEm.getElt(i));
				if (frameRate == 0)
					frameRate = 1;
				usleep(1000000/frameRate);
			}
		}
	} while (menuId != RunMenuId || item != QuitItem);
}
예제 #21
0
int hybrid_fmm_stokes_solver(int ac, char **av)
{
    srand(0);
    bool dump_tree_data = false;
    vtkSmartPointer<vtkPolyData>   poly_data = vtkSmartPointer<vtkPolyData>::New();
    vtkSmartPointer<vtkPoints>     points = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkFloatArray> data_points = vtkSmartPointer<vtkFloatArray>::New();
    vtkSmartPointer<vtkCellArray>  cells = vtkSmartPointer<vtkCellArray>::New();
    typedef float value_type;
    size_t num_sources = 1 << 8;
    size_t num_targets = 1 << 8;
    size_t size_sources = 3 * num_sources;
    size_t size_targets = 3 * num_targets;
    std::vector<value_type> sources(size_sources), targets(size_targets), velocities(size_targets), forces(size_sources);
    value_type delta = .0001;
    HybridFmmStokesSolver<value_type> fmm(num_sources);
    std::generate(sources.begin(), sources.end(), random_generator<value_type>());
    std::generate(targets.begin(), targets.end(), random_generator<value_type>());
    std::generate(forces.begin(), forces.end(), random_generator<value_type>());
    std::cout << "sources = ["; std::copy(sources.begin(), sources.end(), std::ostream_iterator<value_type>(std::cout, " ")); std::cout << "];" << std::endl;
    std::cout << "targets = ["; std::copy(targets.begin(), targets.end(), std::ostream_iterator<value_type>(std::cout, " ")); std::cout << "];" << std::endl;
    std::cout << "forces = ["; std::copy(forces.begin(), forces.end(), std::ostream_iterator<value_type>(std::cout, " ")); std::cout << "];" << std::endl;
    fmm.setDelta(delta);
    fmm(0, &sources[0], &velocities[0], &forces[0]);
    std::fill(velocities.begin(), velocities.end(), 0.0);
    fmm.allPairs();
    if (dump_tree_data)
    {
        IO::VtkWriter<vtkXMLPolyDataWriter> writer("data/points");
        data_points->SetArray(&sources[0], sources.size(), 1);
        data_points->SetNumberOfComponents(3);
        data_points->SetName("positions");
        points->SetData(data_points);
        poly_data->SetPoints(points);
        for (vtkIdType i = 0; i < num_sources; ++i)
            cells->InsertNextCell(VTK_VERTEX, &i);
        poly_data->SetVerts(cells);
        writer.write(poly_data, 0, false);
        write_vtk_octree();
    }
#ifdef USE_QT_GUI
    QApplication app(ac, av);

    if (!QGLFormat::hasOpenGL())
    {
        std::cerr << "This system has no OpenGL support" << std::endl;
        return 1;
    }
    QGL::setPreferredPaintEngine(QPaintEngine::OpenGL);
    OctreeRenderer tree_renderer;
    tree_renderer.init(octree);
    tree_renderer.setWindowTitle(QObject::tr("Quad Tree"));
    tree_renderer.setMinimumSize(200, 200);
    tree_renderer.resize(800, 600);
    tree_renderer.show();
    return app.exec();
#else
    return 0;
#endif
}
예제 #22
0
bool Simulation::assembleBogusFrictionProblem( 
        CollidingGroup& collisionGroup,
        bogus::MecheFrictionProblem& mecheProblem, 
        std::vector<unsigned> &globalIds,
        VecXx& vels, 
        VecXx& impulses,
        VecXu& startDofs, 
        VecXu& nDofs )
{

    unsigned nContacts = collisionGroup.second.size();

    std::vector<unsigned> nndofs;
    unsigned nSubsystems = collisionGroup.first.size(); 
    globalIds.reserve( nSubsystems );

    nndofs.resize( nSubsystems );
    nDofs.resize( nSubsystems );
    startDofs.resize( nSubsystems );

    unsigned dofCount = 0;
    unsigned subCount = 0;
    std::vector<unsigned> dofIndices;

    // Computes the number of DOFs per strand and the total number of contacts
    for( IndicesMap::const_iterator it = collisionGroup.first.begin();
         it != collisionGroup.first.end(); 
         ++it )
    {
        startDofs[ subCount ] = dofCount;
        dofIndices.push_back( dofCount );
        const unsigned sIdx = it->first;
        globalIds.push_back( sIdx );
        nDofs[subCount] = m_steppers[sIdx]->m_futureVelocities.rows();
        nndofs[subCount] = m_steppers[sIdx]->m_futureVelocities.rows();
        nContacts += m_externalContacts[sIdx].size();
        dofCount += m_steppers[sIdx]->m_futureVelocities.rows();
        ++subCount;
    }

    if( nContacts == 0 ){
        return false; // needs to be false to break out of solvecollidinggroup if statement
    }

    // Prepare the steppers
#pragma omp parallel for
    for ( unsigned i = 0; i < globalIds.size(); ++i )
    { // make sure steppers are ready for us to read their info/members... solve if not yet solved, reset where necessary
        m_steppers[ globalIds[i] ]->prepareForExternalSolve();
    }

    std::vector < SymmetricBandMatrixSolver<double, 10>* > MassMat;
    MassMat.resize( nSubsystems );

    VecXx forces( dofCount );

    vels.resize( dofCount );
    impulses.resize( nContacts * 3 );
    impulses.setZero();

    VecXx mu( nContacts );

    std::vector < Eigen::Matrix< double, 3, 3 > > E; E.resize( nContacts );

    VecXx u_frees( nContacts * 3 );
    u_frees.setZero();

    int ObjA[ nContacts ];
    int ObjB[ nContacts ];

    std::vector < SparseRowMatx* > H_0; H_0.resize( nContacts );
    std::vector < SparseRowMatx* > H_1; H_1.resize( nContacts );

    unsigned objectId = 0, collisionId = 0, currDof = 0;

    // Setting up objects and adding external constraints
    for ( IndicesMap::const_iterator it = collisionGroup.first.begin(); it != collisionGroup.first.end(); ++it )
    {
        const unsigned sIdx = it->first;
        ImplicitStepper& stepper = *m_steppers[sIdx];

        JacobianSolver *M = &stepper.linearSolver();
        MassMat[ objectId++ ] = M;

        if( m_params.m_alwaysUseNonLinear )
        {
            forces.segment( currDof, stepper.rhs().size() ) = -stepper.rhs();
            currDof += stepper.rhs().size();
        }
        else
        {
            forces.segment( currDof, stepper.impulse_rhs().size() ) = -stepper.impulse_rhs();
            currDof += stepper.impulse_rhs().size();
        }

        CollidingPairs & externalCollisions = m_externalContacts[sIdx];
        for ( unsigned i = 0; i < externalCollisions.size(); ++i, ++collisionId )
        {
            CollidingPair& c = externalCollisions[i];

            mu[ collisionId ] = c.m_mu;
            E [ collisionId ] = c.m_transformationMatrix;
            // u_frees.segment<3>( ( collisionId ) * 3 ) = c.objects.first.freeVel - c.objects.second.freeVel;
            ObjA[ collisionId ] = (int) it->second;
            ObjB[ collisionId ] = -1;
            H_0 [ collisionId ] = c.objects.first.defGrad;
            H_1 [ collisionId ] = NULL;
        }
    }

    // Setting up RodRod constraints
#pragma omp parallel for
    for ( unsigned i = 0; i < collisionGroup.second.size(); ++i )
    {
        CollidingPair& collision = collisionGroup.second[i];
        const int oId1 = collisionGroup.first.find( collision.objects.first.globalIndex )->second;
        const int oId2 = collisionGroup.first.find( collision.objects.second.globalIndex )->second;

        mu[ collisionId + i ] = collision.m_mu;
        E [ collisionId + i ] = collision.m_transformationMatrix;
        // u_frees.segment<3>( ( collisionId + i ) * 3 ) = collision.objects.first.freeVel - collision.objects.second.freeVel;
        ObjA[ collisionId + i ] = oId1;
        ObjB[ collisionId + i ] = oId2;
        H_0 [ collisionId + i ] = collision.objects.first.defGrad;
        H_1 [ collisionId + i ] = collision.objects.second.defGrad;
    }
    assert( collisionId + collisionGroup.second.size() == nContacts );

    mecheProblem.fromPrimal( 
                    nSubsystems,
                    nndofs,
                    MassMat, 
                    forces,
                    nContacts, 
                    mu, 
                    E, 
                    u_frees, // this is what we want the velocity to be given resting contact, set it to zero?
                    ObjA, 
                    ObjB, 
                    H_0, 
                    H_1,
                    dofIndices );

    return true;
}
예제 #23
0
void tdxedos_trans(int ibox){
	int k	  =	ibox;

	/* ---------------------------------------------------- */
	/* First, pick a random solute molecule to move along   */
	/* the reaction coordinate.  Then determine the upper   */
	/* and lower bounds for the sites to move.              */
	/* ---------------------------------------------------- */
	int lb;
	int ub;
	if(molec.Nsolute == 1){		
		lb = 0;
		ub = molec.lsite[0];
	}
	else{
		int molecule = ran_int(0, molec.Nsolute);
		lb = molec.fsite[molecule];//first site of molecule
		ub = molec.lsite[molecule];//first site of next molecule
	}
	
	int boxns = box[k].boxns;

	/* ---------------------------------------------------- */
	/* Calculate the values needed for the move.            */
	/* ---------------------------------------------------- */
	double U_initial;
	double U_final;
	double L_final;
	double L_initial;
	double x1_initial;
	double x1_final;
	double x2_initial;
	double x2_final;

	int old_bin_1;
	int new_bin_1;
	int old_bin_2;
	int new_bin_2;

	/*------------------------------------*/
	/* Call subroutines that calculate    */
	/* the properties defining the rxn-   */
	/* coordinate and assign x1 and x2    */
	/* initial values.                    */
	/*------------------------------------*/
	end_to_end(k,SITE1,SITE2);
	x1_initial = ordparam[k].d_nc;
	x2_initial = wall_angle(k,wall[k].angle_site);
	old_bin_1  = (int)((x1_initial - sim_dos[k].x1_begin)/sim_dos[k].x1_width);
	old_bin_2  = (int)((x2_initial - sim_dos[k].x2_begin)/sim_dos[k].x2_width);

	#ifdef MC
	forces_mc(lb,ub,0,k);
	#endif

	double beta_old	= 1.0/sim.kT[k];			
	double beta_new	= beta_old;

	calcvalue(k);

	/* ---------------------------------------------------- */
	/* Back up the necessary information, and calculate the */
	/* system parameters before the move.                   */
	/* ---------------------------------------------------- */
	for(int l=lb; l<ub; l++){
		atom_temp[k][l]	= atom[k][l];				/* Back up coordinates with pdb			*/
		atnopbc_temp[k][l]	= atnopbc[k][l];		/* Back up coordinates without pdb		*/
	}
	for(int l=0; l<boxns; l++){
		ff_temp[k][l]		= ff[k][l];				/* Back up all the force  components	*/
	}
	#ifdef PRESSURE
	pvir_temp[k]	= pvir[k];					/* Back up all the virial components	*/
	#endif

	en_temp[k]		= en[k];					/* Back up all the energy components	*/
		
	#ifdef MC		
	U_initial		= enmc[k].o_potens;
	#else		
	U_initial		= en[k].potens;
	#endif

	L_initial		= ordparam[k].d_nc;

	/* ---------------------------------------------------- */
	/* Perform a scaling move.                              */
	/* ---------------------------------------------------- */

	double dx	= atnopbc[k][SITE2].x -atnopbc[k][SITE1].x;
	double dy	= atnopbc[k][SITE2].y -atnopbc[k][SITE1].y;
	double dz	= atnopbc[k][SITE2].z -atnopbc[k][SITE1].z;

	double r = sqrt(dx*dx+dy*dy+dz*dz);

	double ex_dist = (ran2()-0.5)*2.0 * mc_trans.delta[k];

	double scalar = ex_dist/r;

	dx *= scalar;
	dy *= scalar;
	dz *= scalar;

	for (int i=lb; i<ub; i++){
		atnopbc[k][i].x	+=	dx;
		atnopbc[k][i].y	+=	dy;
		atnopbc[k][i].z	+=	dz;
		atom[k][i].x	=	atnopbc[k][i].x;
		atom[k][i].y	=	atnopbc[k][i].y;
		atom[k][i].z	=	atnopbc[k][i].z;
	}

	/* ----------------------------------------------- */
	/* Apply periodic boundary conditions.             */
	/* ----------------------------------------------- */
	pbc_all(k);
	#ifdef NLIST
	#ifndef DLIST
	nblist_pivot(k,ub); // call Nblist 
	#else
	nl_check(lb,ub,k);
	if(nl_flag[k] == 1) nblist_pivot(k,ub);
	#endif
	#endif

	/* ----------------------------------------------- */
	/* Update the forces and system parameters.        */
	/* ----------------------------------------------- */
	#ifdef MC
	forces_mc(lb, ub, 1,k);
	#else
	forces(k);
	#endif

	calcvalue(k);

	#ifdef MC
	U_final	= enmc[k].n_potens;
	#else
	U_final	= en[k].potens;
	#endif

	/*------------------------------------*/
	/* Call subroutines that calculate    */
	/* the properties defining the rxn-   */
	/* coordinate and assign x1 and x2    */
	/* final values.                      */
	/*------------------------------------*/
	end_to_end(k,SITE1,SITE2);
	L_final = ordparam[k].d_nc;
	x1_final = ordparam[k].d_nc;
	x2_final = wall_angle(k,wall[k].angle_site);
	new_bin_1  = (int)((x1_final - sim_dos[k].x1_begin)/sim_dos[k].x1_width);
	new_bin_2  = (int)((x2_final - sim_dos[k].x2_begin)/sim_dos[k].x2_width);		

	#ifdef WALL
	int beyond_wall_flag = 0; //flag to see if particle moved past wall
	for(int j=0; j<box[k].boxns; j++){  
		if(atom[k][j].z < wall[k].z[0]){
			beyond_wall_flag = 1;
			break;
		}
	}

	if (x1_final >= sim_dos[k].x1_begin && x1_final < sim_dos[k].x1_end &&
		x2_final >= sim_dos[k].x2_begin && x2_final < sim_dos[k].x2_end && beyond_wall_flag == 0){
	#else 
	if (x1_final >= sim_dos[k].x1_begin && x1_final < sim_dos[k].x1_end &&
		x2_final >= sim_dos[k].x2_begin && x2_final < sim_dos[k].x2_end){
	#endif

		/* ------------------------------------------------ */
		/* Determine the new and old density of states by   */
		/* 2D interpolation.                                */
		/* ------------------------------------------------ */
		double g_old; double g_new;
		
		g_old = dos_interp_2(k,x1_initial,x2_initial);
		g_new = dos_interp_2(k,x1_final,x2_final);

		double arg = g_old- g_new + (U_initial-U_final)*beta_old + 2.0*log(L_final/L_initial);

		if (arg>0.0){
			dos_hist[k][new_bin_1][new_bin_2].h_of_l ++;
			dos_hist[k][new_bin_1][new_bin_2].g_of_l += sim_dos[k].mod_f;
			flat_histogram_td(k);
			mc_trans.trans_acc[k] ++;
		}//accepted
		else if (exp(arg) > ran2()){
			dos_hist[k][new_bin_1][new_bin_2].h_of_l ++;
			dos_hist[k][new_bin_1][new_bin_2].g_of_l += sim_dos[k].mod_f;
			flat_histogram_td(k);
			mc_trans.trans_acc[k] ++;
		}//accepted
		else{
			for(int l=lb; l<ub; l++){
				atom[k][l]		= atom_temp[k][l];	 /* Back up coordinates with pdb		*/
				atnopbc[k][l]	= atnopbc_temp[k][l];/* Back up coordinates without pdb		*/
			}
			for(int l=0; l<boxns; l++){
				ff[k][l]		= ff_temp[k][l];	 /* Back up all the force  components	*/
			}
			#ifdef PRESSURE
			pvir[k]		= pvir_temp[k];				 /* Back to old  virial components		*/
			#endif

			en[k]		= en_temp[k];				 /* Back to old  energy components		*/

			#ifdef NLIST
			#ifndef DLIST
			nblist_pivot(k,ub); // call Nblist 
			#else
			nl_check(lb,ub,k);
			if(nl_flag[k] == 1) nblist_pivot(k,ub);
			#endif
			#endif

			dos_hist[k][old_bin_1][old_bin_2].h_of_l ++;
			dos_hist[k][old_bin_1][old_bin_2].g_of_l += sim_dos[k].mod_f;
			flat_histogram_td(k);
			end_to_end(k,SITE1,SITE2);				// recompute to get back to the old
			ordparam[k].x1 = ordparam[k].d_nc;
			ordparam[k].x2 = wall_angle(k,wall[k].angle_site);
		}//rejected (due to arg)
	}
	else{
		for(int l=lb; l<ub; l++){
			atom[k][l]		= atom_temp[k][l];	 /* Back up coordinates with pdb		*/
			atnopbc[k][l]	= atnopbc_temp[k][l];/* Back up coordinates without pdb		*/
		}
		for(int l=0; l<boxns; l++){
			ff[k][l]		= ff_temp[k][l];	 /* Back up all the force  components	*/
		}
		#ifdef PRESSURE
		pvir[k]		= pvir_temp[k];				 /* Back to old  virial components		*/
		#endif

		en[k]		= en_temp[k];				 /* Back to old  energy components		*/

		#ifdef NLIST
		#ifndef DLIST
		nblist_pivot(k,ub); // call Nblist 
		#endif
		#ifdef DLIST
		nl_check(lb,ub,k);
		if(nl_flag[k] == 1) nblist_pivot(k,ub);
		#endif
		#endif

		dos_hist[k][old_bin_1][old_bin_2].h_of_l ++;
		dos_hist[k][old_bin_1][old_bin_2].g_of_l += sim_dos[k].mod_f;
		flat_histogram_td(k);
		end_to_end(k,SITE1,SITE2);				// recompute to get back to the old
		ordparam[k].x1 = ordparam[k].d_nc;
		ordparam[k].x2 = wall_angle(k,wall[k].angle_site);
	}//rejected (outside range)
	calcvalue(k);
	dos_svalues(k);
}
예제 #24
0
int main(int argc, char *argv[])
{

	if (argc < 9)
	{
		printf("Usage: %s <N> <eta> <dr> <nequil> <nproduct> <binwidth>\n", argv[0]);
		printf("\t<N>        Number of particles\n");
		printf("\t<rho>      Particle density\n");
		printf("\t<T>        Temperature\n");
		printf("\t<rc>       Lennard-Jones cut-off radius\n");
		printf("\t<dt>       Length of one timestep\n");
		printf("\t<nequil>   Number of equilibration timesteps to be performed\n");
		printf("\t<nproduct> Number of production timesteps to be performed\n");
		printf("\t<binwidth> Width of a bin for correlation length histogram\n");
		exit(EXIT_SUCCESS);
	}

	outGr = fopen("outGr.txt", "w+");
	outTrajectories = fopen("outTrajectories.txt", "w+");
	outAverages = fopen("outAverages.txt", "w+");

	// Parse commandline parameters
	N = atoi(argv[1]);
	rho = atof(argv[2]);
	T = atof(argv[3]);
	rc = atof(argv[4]);
	rc2 = rc*rc;
	dt = atof(argv[5]);
	nequil = atof(argv[6]);
	nproduct = atof(argv[7]);
	nt = nequil+nproduct;
	double tequil = nequil*dt;
	double tproduct = nproduct*dt;
	tmax = nt*dt;

	// Calculate corresponding system parameters
	lx = ly = sqrt((double)N/rho);

	printf("========== PARAMETERS ==========\n");
	printf("Particles:\t\t%d\n", N);
	printf("Density:\t\t%g\n", rho);
	printf("Simulationbox lx:\t%g\n", lx);
	printf("Simulationbox ly:\t%g\n", ly);
	printf("Temperature:\t\t%g\n", T);
	printf("Timestep length:\t%g\n", dt);
	printf("Equilibration steps:\t%d\n", nequil);
	printf("Production steps:\t%d\n", nproduct);
	printf("Total steps:\t%d\n", nt);
	printf("Equilibration time:\t%g\n", tequil);
	printf("Production time:\t%g\n", tproduct);
	printf("Total time:\t\t%g\n", tmax);
	printf("================================\n\n");


	printf("======== INIT PARTICLES ========\n");
	// Initialize arrays for particle positions & velocities
	r = new TVector[N];
	r_next = new TVector[N];
	v = new TVector[N];
	v_next = new TVector[N];

	// Put all particles equally spaced in the box and assign random velocities
	int nrows = sqrt(N);
	double dlx = lx/(double)nrows;
	double dly = ly/(double)nrows;
	vsum = .0;
	vsum2 = 0;
	for (int i = 0; i < N; i++)
	{
		// Positions
		r[i].x = i%nrows*dlx+0.5;
		r[i].y = floor(i/nrows)*dly+0.5;
		// Velocities
		v[i].x = rand_value(-1., 1.);
		v[i].y = rand_value(-1., 1.);
		vsum += v[i];
		vsum2 += v[i].x*v[i].x + v[i].y*v[i].y;
	}
	printf("Center of mass velocity after initialization:\t(%g,%g)\n", vsum.x, vsum.y);
	printf("Kinetic energy after initialization:\t\t%g\n", vsum2);
	printf("Instantaneous temperature after initialization:\t%g\n", vsum2/(2.0*(double)N));
	// Calculate average velocities
	vsum = vsum/(double)N;
	// Scalefactor for velocities to match the desired temperature (we neglect the fact
	// that the whole system with constrained center of mass has only (2N - 2) degrees
	// of freedom and approximate (2N - 2) \approx 2N since we won't run the simulation
	// with less than N = 100 particles.)
	double fs = sqrt(2.0*(double)N*T/vsum2);
	printf("Scaling factor for velocities:\t\t\t%g\n", fs);
	TVector vsumcheck;
	vsumcheck = .0;
	vsum2 = 0;
	for (int i = 0; i < N; i++)
	{
		v[i] = (v[i]-vsum)*fs;
		vsumcheck += v[i];
		vsum2 += v[i].x*v[i].x + v[i].y*v[i].y;
	}
	printf("Center of mass velocity after scaling:\t\t(%g,%g)\n", vsumcheck.x, vsumcheck.y);
	printf("Kinetic energy after scaling:\t\t\t%g\n", vsum2);
	printf("Instantaneous temperature after scaling:\t%g\n", vsum2/(2.0*(double)N));
	print_coords("outCoords_start.txt");
	printf("================================\n\n");


	printf("======== INIT POTENTIAL ========\n");
	// Init the potential
	init_lj_shift();
	F = new TVector[N];
	printf("Potential initialized.\n");
	printf("U(r_c)\t\t= %g\n", u_lj_shift);
	printf("U'(r_c)\t\t= %g\n", u_lj_deriv_shift);
	printf("U_s(r_c)\t= %g\n", u_lj_shifted(rc2));
	printf("U'_s(r_c)\t= %g\n", u_lj_deriv_shifted(rc2));
	printf("================================\n\n");


	printf("======== INIT AVERAGERS ========\n");
	avg_temp.init();
	avg_epot.init();
	avg_ekin.init();
	avg_etot.init();
	avg_vir.init();
	printf("Averagers initialized!\n");

	// Histogram for pair correlation function
	binwidth = atof(argv[8]);				// Width of a histogram-bin
	nbins = ceil(grmax/binwidth);			// Maximum correlation length to be measured should be L/2 due to periodic BC
	bincount = 0;							// Number of counts done on the histogram
	hist = new int[nbins];
	for (int i = 0; i < nbins; i++) {
		hist[i] = 0;
	}
	printf("Using histogram with %d bins of width %f\n", nbins, binwidth);
	printf("================================\n\n");

	printf("======= START INTEGRATION ======\n");
	t = 0;
	fprintf(outTrajectories, "#t\tn\tr_x\t\tr_y\t\tv_x\t\tv_y\n");
	fprintf(outAverages, "#t\tT(t)\t\t<T(t)>\t\tE_tot(T)\t\t<E_tot(T)>\n");
	for (int n = 0; n <= nt; n++)
	{
		if (n == 0)
		{
			printf("Equilibration phase started.\n");
		}
		if (n == nequil)
		{
			printf("Production phase started.\n");
		}

		// Current time
		t = dt*n;
		if(debug) printf("t:\t%6.3f\t\n", t);
		// Calculate all forces
		forces();
		vsum = .0;
		vsum2 = .0;
		// update all particles
		for (int i = 0; i < N; i++)
		{
			// perform leap-frog-integration
			v_next[i] = v[i] + F[i]*dt;
			r_next[i] = r[i] + v_next[i]*dt;
			// Calculate energies
			vsum += v_next[i];
			// vsum2 += v[i].x*v[i].x + v[i].y*v[i].y; // naiv?
			vsum2 += pow(v_next[i].x+v[i].x, 2)/4.0 + pow(v_next[i].y+v[i].y, 2)/4.0; // sophisticated by Frenkel/Smit
			// update particle coordinates
			v[i] = v_next[i];
			r[i] = r_next[i];

			// Write trajectories to a file
			// fprintf(outTrajectories, "%6.3f\t%6d\t%e\t%e\t%e\t%e\n", t, i, r[i].x, r[i].y, v[i].x, v[i].y);
		}

		// Equilibration phase, scale velocities to keep temperature
		if (n < nequil)
		{
			// Rescale velocities every ?? timesteps
			if (n%10 == 0)
			{
				scale_velocities();
			}
		}
		else if (n%nsamp == 0)
		{
			double Tt = vsum2/(2.0*(double)N);
			avg_temp.add(Tt);

			avg_epot.add(epot);
			avg_vir.add(virial);

			double ekin = 0.5*vsum2;
			avg_ekin.add(ekin);

			double etot = (epot + ekin);
			avg_etot.add(etot);

			update_histogram();

			fprintf(outAverages, "%6.3f\t%e\t%e\t%e\t%e\n", t, Tt, avg_temp.average(), etot, avg_etot.average());
		}

		if ((n+1)%(nt/10) == 0 || n == 0) {
			printf("Finished %5d (t = %5.1f) out of %d (t = %g) timesteps: %3.f %% <T> = %g\n", n+1, t, nt, tmax, (double)n/(double)nt*100, avg_temp.average());
		}

		if(debug) printf("\n");
	}
	printf("================================\n\n");

	print_coords("outCoords_end.txt");

	printf("Printing histogram for g(r) & calculating pressure\n");
	fprintf(outGr, "#r\tg(r)\n");
	double p = 0; // Pressure
	for(int i = 0; i < nbins; i++) {
		double R = i*binwidth;
		double area = 2.0*PI*R*binwidth;
		// Multiply g(r) by two, since in the histogram we only counted each pair once, but each pair
		// gives two contributions to g(r)
		double gr = 2.0*(double)hist[i]/(rho*area*(double)bincount*N);
		fprintf(outGr, "%f\t%f\n", R, gr);
		// Calculate other quantities from g(r)
		if (R > 0 && R < rc) {
			double r6i = pow(1.0/R, 6);
			p += gr*2*PI*rho*rho*R*R*48*(r6i*r6i-0.5*r6i)*binwidth/2;
		}
	}
	p = p + rho*avg_temp.average();
	printf("Final pressure P(%g) = %g\n", rho, p);


	FILE *outAvgFinal;
	outAvgFinal = fopen("outAvgFinal.txt", "w+");
	fprintf(outAvgFinal, "#t\t<T(t)>\t\t<E_tot(T)>\trho\t\t1/rho\t\tp\n");
	fprintf(outAvgFinal, "%6.3f\t%e\t%e\t%e\t%e\t%e\n", t, avg_temp.average(), avg_etot.average(), rho, 1.0/rho, p);
	fclose(outAvgFinal); outAvgFinal = NULL;


	delete [] r;
	delete [] r_next;
	delete [] v;
	delete [] v_next;
	delete [] F;
	r = r_next = v = v_next = F = NULL;

	// Close filepointer
	fclose(outGr); outGr = NULL;
	fclose(outTrajectories); outTrajectories = NULL;
	fclose(outAverages); outAverages = NULL;

	exit(EXIT_SUCCESS);
}
int main( int argc , char** argv ) {

  int L_flag=0,i,j,k,l;

  if ( argc > 1 and !strcmp( "-nt" , argv[1] ) ){
    nthreads = atoi( argv[2] ) ;
    omp_set_num_threads( nthreads ) ;
    printf("\nNumber of threads set to %d!\n" , nthreads ) ;
  }
  else {
    nthreads = 1 ;
    omp_set_num_threads( nthreads ) ;
    printf("\nNumber of threads set to %d!\n" , nthreads ) ;
   }

  read_input() ;

   if(argc == 5 ) {
     flux_sp =  atoi(argv[4]);
     cout<<"new flus sp "<<flux_sp<<endl;
   }
  
  initialize() ;

  write_gro( ) ;
  write_quaternions( ) ;
   write_film_gro();
  // Save chi for pre-equilibration steps //
  double tmp_ang,chi_bkp = chiAB ;

  FILE *otp ,*otpL;
  otp = fopen( "data.dat" , "w" ) ;
  otpL = fopen("box_L.dat","w");

  printf("Entering main loop!\n") ; fflush( stdout ) ;
  for ( step = 0 ; step < nsteps ; step++ )  {

    if ( step < pre_equil_steps )
      chiAB = 0.0 ;
    else
      chiAB = chi_bkp ;
   

    forces() ;
  

    if(sigma>0){
       torque();
    }

   // if(step >0 || rst_para == 1)
   	update_positions() ;
   // else
    //	update_positions_init() ;
    
    if(sigma>0){
    update_euler();
    }
   
    if( ( flux_para == 1) and (step % flux_sp == 0)){


	 flux();

    }
    else if((flux_para == 2 ) and (step % flux_sp == 0) and (max_nC> nC ) and (nsol>Nhc)){

         flux();	
    }
    else{

    }


	 

    if ( stress_freq > 0 && step % stress_freq == 0 ) {
      calc_stress() ;

      for ( j=0 ; j<Dim ; j++ ){ 
        for ( k=0 ; k<Dim ; k++ ) {
          sts_buf[buff_ind][j][k]= Rg3*Ptens[j][k];//( j<Dim ? Stress_bonds[j][k]:0.0) ;
           sts_buf_pp[buff_ind][j][k] = Rg3*Stress_PP[j][k];
      	   sts_buf_ng[buff_ind][j][k] = Rg3*Stress_Ng[j][k];
            
	    if( ((L_fren-L_aver) < L_flag)  and (optm_L >0) and (j ==k))
	        aver_Ptens[j][j] += Rg3*Ptens[j][j];


	/*for ( k=0 ; k<nP;  k++ ){
		//euler_adot[k][j] = euler_q[k][j];	
		sts_buf[buff_ind][j][k+Dim] = euler_q[k][j];
	}*/
	}
      }
      if(((L_fren-L_aver) < L_flag) and   (optm_L >0))
      aver_Ptens[0][1] +=1;
 
      buff_ind++ ;
    }

   if(optm_L>0  ){
    	if( step > pre_equil_steps )
       		L_flag +=1 ;

    	if(L_flag == L_fren){
       		adj_L();
		L_flag = 0 ;
               
		
		
	        fprintf( otpL , "%d %lf %lf %lf \n" ,step ,L[0],L[1],L[2]);fflush( otpL ) ;
	}		
   }//optm_L

    if(step % sample_freq == 0){
	write_np();
        //write_film_gro();
        char nm[20];

	if(nsol > 0){
	   sprintf( nm , "./frame/rhosol.frame%d.dat" , step ) ;
	   write_grid_data( nm , rhosol ) ;
	}
	if(nD > 0){
	   sprintf( nm , "./frame/rhoda.frame%d.dat" , step ) ;
	    write_grid_data( nm , rhoda ) ;
	   sprintf( nm , "./frame/rhodb.frame%d.dat" , step ) ;
	               write_grid_data( nm , rhodb ) ;
	}
    }  
    
    if ( step > sample_wait && step % sample_freq == 0 ) {
     /* fftw_fwd( rho[0] , ktmp ) ;
      for ( i=0 ; i<M ; i++ ) {
        avg_sk[0][i] += ktmp[i] * conj(ktmp[i]) ;
      }

      if ( nP > 0 ) {

        fftw_fwd( rho[2] , ktmp ) ;
        for ( i=0 ; i<M ; i++ ) {
          avg_sk[2][i] += ktmp[i] * conj( ktmp[i] ) ;
        }
      }*/
     /* for ( i=0 ; i<M ; i++ ) {
        avg_rho[0][i] += rho[0][i];
	avg_rho[1][i] += rho[1][i];
        //avg_rho[3][i] += rho[3][i];
       
      }*/
	


      num_averages += 1.0 ;
    }


    if ( step % print_freq == 0 || step == nsteps-1 ) {
      printf("step %d of %d  Ubond: %lf\n" , step , nsteps , Ubond ) ;
      fflush( stdout ) ;
      write_gro() ;
      write_rst_gro();
      write_quaternions();


      if ( stress_freq > 0 )
        write_stress() ;


      write_grid_data( "rhoda.dat" , rhoda ) ;
      write_grid_data( "rhodb.dat" , rhodb ) ;
      
      if ( nA > 0.0 )
        write_grid_data( "rhoha.dat" , rhoha ) ;

      if ( nB > 0.0 )
        write_grid_data( "rhohb.dat" , rhohb ) ;
      if(  nC > 0.0 )
         write_grid_data( "rhohc.dat" , rhohb ) ;

      if ( nP > 0.0 ) 
        write_grid_data( "rhop.dat" , rhop ) ;

      if ( step > sample_wait ) {
       /* for ( i=0 ; i<M ; i++ ) 
          ktmp2[i] = avg_sk[0][i] / num_averages ;
        write_kspace_data( "avg_sk_A.dat" , ktmp2 ) ;
        
        if ( nP > 0 ) {
          for ( i=0 ; i<M ; i++ )
            ktmp2[i] = avg_sk[2][i] / num_averages ;
          write_kspace_data( "avg_sk_np.dat" , ktmp2 ) ;
        }*/
        /*	
        for ( i=0 ; i<M ; i++ )
	     tmp[i] = avg_rho[0][i]/ num_averages ;
         write_grid_data("avg_typeA.dat",tmp);	

	for ( i=0 ; i<M ; i++ )
	     tmp[i] = avg_rho[1][i]/ num_averages ;
         write_grid_data("avg_typeB.dat",tmp);	

        for ( i=0 ; i<M ; i++ )
	     tmp[i] = avg_rho[3][i]/ num_averages ;
         write_grid_data("avg_typeC.dat",tmp);	
	*/

      }

      calc_Unb() ;

      fprintf( otp , "%d %lf %lf %lf %lf %lf %lf %lf\n" , step , Ubond , U_chi_gg, U_kappa_gg,U_chi_pg,U_kappa_pg,U_kappa_pp , Utt) ;
      fflush( otp ) ;

    }// if step % print_Freq == 0

  }

  fclose( otp ) ;

  return 0 ;

}
예제 #26
0
파일: analyser.C 프로젝트: Holygitzdq/ElVis
void Analyser (Domain *omega, int step, double time)
{
  FILE     *fp[2];
  int      nfields = omega->U->fhead->dim()+1;

  int i;
  Element_List  **V;
  char      fname[FILENAME_MAX];
  double    step_length;


  dparam_set("t", time);

  V = (Element_List**) malloc(nfields*sizeof(Element_List*));

  /* ..........  Field Files   ......... */
  
  V[0]   = omega->U;
  V[1]   = omega->V;
  V[2]   = omega->W;
  V[3]   = omega->P;

  if(init){
    verbose   = option("verbose");
    iostep    = iparam("IOSTEP");
    hisstep   = option("hisstep");
    if(!hisstep) hisstep = iparam("HISSTEP");
    nsteps    = iparam("NSTEPS");
    timeavg   = option("timeavg");
    if (omega->his_list) hisHeader (omega);
    init = 0;
  }
  /* .......... General Output ......... */
  step_length = (clock()-last_time)/(double)CLOCKS_PER_SEC;
  last_time = clock();
  ROOTONLY fprintf(stdout, "Time step = %d, Time = %g Cpu-Time = %g\n", 
		   step, time, step_length);
  fflush(stdout);

  if (step == 0){                         /* Everything else is for step > 0 */
    if (omega->his_list)                  /* Do initial history point        */
      History (omega, time);
    return;
  }
  if ((step % hisstep) == 0){
    if (omega->his_list){
      History (omega, time);
      fflush(omega->his_file);
    }
    
    forces(omega,step,time);
	
	
	  if (option ("SurInflow") == 1) 
	{
	surf_inflow(omega,step,time); 
}

	
    ROOTONLY 
      fflush(omega->fce_file);
 
    /* flush stdout at step as well */
    ROOTONLY 
      fflush(stdout);
    
    
    if(option("SurForce")||option("SurInflow")){
      cnt_srf_elements(omega);
    }
    
    if(verbose){
      if(omega->soln)
	for(i=0;i<nfields;++i)
	  V[i]->Terror(omega->soln[i]);
      else
	V[0]->Terror("0.0");
    }
  }


 if(option("SurForce")||option("SurInflow")){

 int a = cnt_srf_elements(omega);
 }
 


  if (step % iostep == 0 && step < nsteps) {         
    if (option ("checkpt")) {
      DO_PARALLEL{
	if(option("SLICES")&&check_number<100){
	  sprintf (fname, "%s_%d.chk.hdr.%d", omega->name, check_number,
		   pllinfo.procid);
	  fp[0] = fopen(fname,"w");
	  
	  sprintf (fname, "%s_%d.chk.dat.%d", omega->name, check_number,
		   pllinfo.procid);
	  fp[1] = fopen(fname,"w");
	  ++check_number;
	}
	else{
	  sprintf (fname, "%s.chk.hdr.%d", omega->name, pllinfo.procid);
	  fp[0] = fopen(fname,"w");
	  
	  sprintf (fname, "%s.chk.dat.%d", omega->name, pllinfo.procid);
	  fp[1] = fopen(fname,"w");
	}

	Writefld (fp, omega->name, step, time, nfields, V);
	fclose(fp[0]);
	fclose(fp[1]);      
      }
      else{
	if(option("SLICES")&&check_number<100){
	  sprintf (fname, "%s_%d.chk",  omega->name,check_number);
	  ++check_number;
	}
	else
	  sprintf (fname, "%s.chk", omega->name);
	fp[1] = fp[0] = fopen(fname,"w");
	Writefld (fp, omega->name, step, time, nfields, V);
	fclose(fp[0]);	
      }
    }
예제 #27
0
void xedos_linear(int ibox)
{
	int k	  =	ibox;

	

	/* ---------------------------------------------------- */
	/* First, pick a random solute molecule and then a      */
	/* random site on that molecule to move.                */
	/* ---------------------------------------------------- */
	int lb;
	int ub;
	int rand_site =0;

#ifdef IONC
	/* ----------------------------------------------------	*/
	/* If IONC is defined, the random move is either done	*/
	/* on protein-Cwater system or the relevant ion (SITE2)	*/
	/* ----------------------------------------------------	*/
	double ran_num	= ran2();
	if (ran_num<0.8){
		if(molec.Nsolute == 1){		
			lb = 0;
			ub = molec.lsite[0];
			rand_site		=   ran_int(lb,ub);
		}
		else{
			int molecule = ran_int(0, molec.Nsolute);
			lb = molec.fsite[molecule];//first site of molecule
			ub = molec.lsite[molecule];//first site of next molecule
			rand_site		=   ran_int(lb,ub);
		}
	}
	else{
		rand_site	=	SITE2;
		lb = rand_site;
		ub = rand_site+1;
	}
#endif//IONC


#ifndef IONC
	if(molec.Nsolute == 1){		
		lb = 0;
		ub = molec.lsite[0];
		rand_site		=   ran_int(lb,ub);
	}
	else{
		int molecule = ran_int(0, molec.Nsolute);
		lb = molec.fsite[molecule];//first site of molecule
		ub = molec.lsite[molecule];//first site of next molecule
		rand_site		=   ran_int(lb,ub);
	}

#endif //no IONC	

	/* Move the selected site randomly in x,y,z*/

	double dx, dy,dz;
	dx = (ran2()-0.5)*mc_rand.delta[k]; 
	dy = (ran2()-0.5)*mc_rand.delta[k];
	dz = (ran2()-0.5)*mc_rand.delta[k];
	

#ifdef MC
	forces_mc(rand_site,rand_site+1,0,k);
#endif
	double L_initial;
	end_to_end(k,SITE1,SITE2);						/* Distance betweeb SITE1 and SITE2		*/
	
	L_initial		= ordparam[k].d_nc;
	double U_initial;
	double U_final;
	double L_final;
	
	int old_bin;
	int new_bin;
	double beta_old	= 1.0/sim.kT[k];			
	double beta_new	= beta_old;
	calcvalue(k);


	atom_temp[k][rand_site]		= atom[k][rand_site];				/* Back up coordinates with pdb			*/
	atnopbc_temp[k][rand_site]	= atnopbc[k][rand_site];		/* Back up coordinates without pdb		*/

	for(int l=0; l< box[k].boxns; l++){
		ff_temp[k][l]		= ff[k][l];				/* Back up all the force  components	*/
	}
#ifdef PRESSURE
		pvir_temp[k]	= pvir[k];					/* Back up all the virial components	*/
#endif
		en_temp[k]		= en[k];					/* Back up all the energy components	*/
#ifdef MC		
		U_initial		= enmc[k].o_potens;
#endif
#ifndef MC		
		U_initial		= en[k].potens;
#endif
		old_bin			= (int) ((L_initial - sim_dos[k].l_begin)/sim_dos[k].l_width);			

	  atnopbc[k][rand_site].x += dx;
	  atnopbc[k][rand_site].y += dy;
	  atnopbc[k][rand_site].z += dz;
	  atom[k][rand_site].x += dx;
	  atom[k][rand_site].y += dy;
	  atom[k][rand_site].z += dz;

		/* ----------------------------------------------- */
		/* Apply periodic boundary conditions.             */
		/* ----------------------------------------------- */
		pbc_all(k);	
	#ifdef NLIST
	#ifndef DLIST
	    nblist_pivot(k,rand_site+1); // call Nblist 
	#endif
	#ifdef DLIST
		nl_check(lb, ub, k);
		if(nl_flag[k] == 1) nblist_pivot(k,rand_site+1);
	#endif
	#endif
		/* ----------------------------------------------- */
		/* Update the forces.                              */
		/* ----------------------------------------------- */
#ifdef MC
		forces_mc(rand_site, rand_site+1, 1,k);
#endif
#ifndef MC
		forces(k);
#endif
		calcvalue(k);
#ifdef MC
		U_final	= enmc[k].n_potens;
#endif
#ifndef MC
		U_final	= en[k].potens;
#endif
		end_to_end(k,SITE1,SITE2);
		L_final = ordparam[k].d_nc;

#ifdef WALL
		int beyond_wall_flag = 0; //flag to see if particle moved past wall
		//for(int i=0; i<wall[k].n; i++){
			for(int j=0; j<box[k].boxns; j++){  
				if(atom[k][j].z < wall[k].z[0]){
					beyond_wall_flag = 1;
					break;
				}
			}
		//}

  /* ----------------------------------------------- */
	/* Check the acceptance of the move. First check   */
  /* to see if the system moved out of range, then   */
  /* check to see if it is accepted.                 */
	/* ----------------------------------------------- */

		if (L_final >= sim_dos[k].l_begin && L_final < sim_dos[k].l_end && beyond_wall_flag == 0){
#else 
		if (L_final >= sim_dos[k].l_begin && L_final < sim_dos[k].l_end){
#endif
	    new_bin	= (int) ((L_final - sim_dos[k].l_begin)/sim_dos[k].l_width);
		  double g_old = dos_interp(k,old_bin,L_initial); 
      double g_new = dos_interp(k,new_bin,L_final);
			double arg = g_old- g_new + (U_initial-U_final)*beta_old; 

			if (arg>0.0){
				dos_hist[k][new_bin].h_of_l ++;
				dos_hist[k][new_bin].g_of_l += sim_dos[k].mod_f;
				flat_histogram(k);
				mc_rand.rand_acc[k] ++;
			}//accepted
			else if (exp(arg) > ran2()){
				dos_hist[k][new_bin].h_of_l ++;
				dos_hist[k][new_bin].g_of_l += sim_dos[k].mod_f;
				flat_histogram(k);
				mc_rand.rand_acc[k] ++;
			}//accepted
			else{

				atom[k][rand_site]		= atom_temp[k][rand_site];	 /* Back up coordinates with pdb		*/
				atnopbc[k][rand_site]	= atnopbc_temp[k][rand_site];/* Back up coordinates without pdb		*/
				for(int l=0; l< box[k].boxns; l++){
					ff[k][l]		= ff_temp[k][l];	 /* Back up all the force  components	*/
				}
				#ifdef PRESSURE
				pvir[k]		= pvir_temp[k];				 /* Back to old  virial components		*/
				#endif
				en[k]		= en_temp[k];				 /* Back to old  energy components		*/
				#ifdef NLIST
				#ifndef DLIST
					nblist_pivot(k,rand_site+1); // call Nblist 
				#endif
				#ifdef DLIST
					nl_check(lb, ub, k);
					if(nl_flag[k] == 1) nblist_pivot(k,rand_site+1);
				#endif
				#endif
				dos_hist[k][old_bin].h_of_l ++;
				dos_hist[k][old_bin].g_of_l += sim_dos[k].mod_f;
				flat_histogram(k);
				end_to_end(k,SITE1,SITE2);				// recompute to get back to the old
			}//rejected (due to arg)
		}
		else{
				atom[k][rand_site]		= atom_temp[k][rand_site];	 /* Back up coordinates with pdb		*/
				atnopbc[k][rand_site]	= atnopbc_temp[k][rand_site];/* Back up coordinates without pdb		*/
			for(int l=0; l< box[k].boxns; l++){
				ff[k][l]		= ff_temp[k][l];	 /* Back up all the force  components	*/
			}
			#ifdef PRESSURE
			pvir[k]		= pvir_temp[k];				 /* Back to old  virial components		*/
			#endif
			en[k]		= en_temp[k];				 /* Back to old  energy components		*/
			#ifdef NLIST
			#ifndef DLIST
				nblist_pivot(k,rand_site+1); // call Nblist 
			#endif
			#ifdef DLIST
				nl_check(lb, ub, k);
				if(nl_flag[k] == 1) nblist_pivot(k,rand_site+1);
			#endif
			#endif
			dos_hist[k][old_bin].h_of_l ++;
			dos_hist[k][old_bin].g_of_l += sim_dos[k].mod_f;
			flat_histogram(k);
			end_to_end(k,SITE1,SITE2);				// recompute to get back to the old
		}//rejected (outside range)
		calcvalue(k);
		dos_svalues(k);
}