Esempio n. 1
0
double *update ( int id, int p, int n_global, int n_local, int nsteps,
                 double dt )

/******************************************************************************/
/*
  Purpose:

    UPDATE advances the solution a given number of time steps.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    17 November 2013

  Author:

    John Burkardt

  Parameters:

    Input, int ID, the identifier of this process.

    Input, int P, the number of processes.

    Input, int N_GLOBAL, the total number of points.

    Input, int N_LOCAL, the number of points visible to this process.

    Input, int NSTEPS, the number of time steps.

    Input, double DT, the size of the time step.

    Output, double UPDATE[N_LOCAL], the portion of the solution
    at the last time, as evaluated by this process.
*/
{
    double alpha;
    double c;
    double dx;
    int i;
    int i_global;
    int i_global_hi;
    int i_global_lo;
    int i_local;
    int i_local_hi;
    int i_local_lo;
    int j;
    int ltor = 20;
    int rtol = 10;
    MPI_Status status;
    double t;
    double *u0_local;
    double *u1_local;
    double *u2_local;
    double x;
    /*
      Determine the value of ALPHA.
    */
    c = 1.0;
    dx = 1.0 / ( double ) ( n_global - 1 );
    alpha = c * dt / dx;

    if ( 1.0 <= fabs ( alpha ) )
    {
        if ( id == 0 )
        {
            fprintf ( stderr, "\n" );
            fprintf ( stderr, "UPDATE - Warning!\n" );
            fprintf ( stderr, "  1 <= |ALPHA| = | C * dT / dX |.\n" );
            fprintf ( stderr, "  C = %g\n", c );
            fprintf ( stderr, "  dT = %g\n", dt );
            fprintf ( stderr, "  dX = %g\n", dx );
            fprintf ( stderr, "  ALPHA = %g\n", alpha );
            fprintf ( stderr, "  Computation will not be stable!\n" );
        }
        MPI_Finalize ( );
        exit ( 1 );
    }
    /*
      The global array of N_GLOBAL points must be divided up among the processes.
      Each process stores about 1/P of the total + 2 extra slots.
    */
    i_global_lo = (   id       * ( n_global - 1 ) ) / p;
    i_global_hi = ( ( id + 1 ) * ( n_global - 1 ) ) / p;
    if ( 0 < id )
    {
        i_global_lo = i_global_lo - 1;
    }

    i_local_lo = 0;
    i_local_hi = i_global_hi - i_global_lo;

    u0_local = ( double * ) malloc ( n_local * sizeof ( double ) );
    u1_local = ( double * ) malloc ( n_local * sizeof ( double ) );
    u2_local = ( double * ) malloc ( n_local * sizeof ( double ) );

    t = 0.0;
    for ( i_global = i_global_lo; i_global <= i_global_hi; i_global++ )
    {
        x = ( double ) ( i_global ) / ( double ) ( n_global - 1 );
        i_local = i_global - i_global_lo;
        u1_local[i_local] = exact ( x, t );
    }

    for ( i_local = i_local_lo; i_local <= i_local_hi; i_local++ )
    {
        u0_local[i_local] = u1_local[i_local];
    }
    /*
      Take NSTEPS time steps.
    */
    for ( i = 1; i <= nsteps; i++ )
    {
        t = dt * ( double ) i;
        /*
          For the first time step, we need to use the initial derivative information.
        */
        if ( i == 1 )
        {
            for ( i_local = i_local_lo + 1; i_local < i_local_hi; i_local++ )
            {
                i_global = i_global_lo + i_local;
                x = ( double ) ( i_global ) / ( double ) ( n_global - 1 );
                u2_local[i_local] =
                    +         0.5 * alpha * alpha   * u1_local[i_local-1]
                    + ( 1.0 -       alpha * alpha ) * u1_local[i_local]
                    +         0.5 * alpha * alpha   * u1_local[i_local+1]
                    +                            dt * dudt ( x, t );
            }
        }
        /*
          After the first time step, we can use the previous two solution estimates.
        */
        else
        {
            for ( i_local = i_local_lo + 1; i_local < i_local_hi; i_local++ )
            {
                u2_local[i_local] =
                    +               alpha * alpha   * u1_local[i_local-1]
                    + 2.0 * ( 1.0 - alpha * alpha ) * u1_local[i_local]
                    +               alpha * alpha   * u1_local[i_local+1]
                    -                                 u0_local[i_local];
            }
        }
        /*
          Exchange data with "left-hand" neighbor.
        */
        if ( 0 < id )
        {
            MPI_Send ( &u2_local[i_local_lo+1], 1, MPI_DOUBLE, id - 1, rtol,
                       MPI_COMM_WORLD );
            MPI_Recv ( &u2_local[i_local_lo],   1, MPI_DOUBLE, id - 1, ltor,
                       MPI_COMM_WORLD, &status );
        }
        else
        {
            x = 0.0;
            u2_local[i_local_lo] = exact ( x, t );
        }
        /*
          Exchange data with "right-hand" neighbor.
        */
        if ( id < p - 1 )
        {
            MPI_Send ( &u2_local[i_local_hi-1], 1, MPI_DOUBLE, id + 1, ltor,
                       MPI_COMM_WORLD );
            MPI_Recv ( &u2_local[i_local_hi],   1, MPI_DOUBLE, id + 1, rtol,
                       MPI_COMM_WORLD, &status );
        }
        else
        {
            x = 1.0;
            u2_local[i_local_hi] = exact ( x, t );
        }
        /*
          Shift data for next time step.
        */
        for ( i_local = i_local_lo; i_local <= i_local_hi; i_local++ )
        {
            u0_local[i_local] = u1_local[i_local];
            u1_local[i_local] = u2_local[i_local];
        }
    }
    /*
      Free memory.
    */
    free ( u0_local );
    free ( u2_local );

    return u1_local;
}
Esempio n. 2
0
/// Main program of uncertainty propagation of the ODE model parameters via intrusive spectral projection (ISP)
int main()
{
  // Model parameters
  Array1D<double> modelparams;
  // Model parameter names
  Array1D<string> modelparamnames;
  // Auxiliary parameters: final time and time step of integration
  Array1D<double> modelauxparams;
  
  // Read the xml tree
  RefPtr<XMLElement> xmlTree=readXMLTree("lorenz.in.xml");
  // Read the model-specific input
  readXMLModelInput(xmlTree,modelparams, modelparamnames, modelauxparams);
  // Total nuber of input parameters
  int fulldim=modelparams.XSize();
  // Read the output preferences
  dumpInfo* outPrint=new dumpInfo;
  readXMLDumpInfo( xmlTree, &(outPrint->dumpInt), &(outPrint->fdumpInt), &(outPrint->dumpfile) );

  // Output PC order
 int order;
 // PC type
 string pcType;

 // A 2d array (each row is an array of coefficients for the corresponding uncertain input parameter)
 Array2D<double> allPCcoefs;
 // The indices of the uncertain model parameters in the list of model parameters
 Array1D<int> uncParamInd;
 // Read the UQ-specific information from the xml tree
 readXMLUncInput(xmlTree,allPCcoefs,uncParamInd , &order, &pcType);

 // Stochastic dimensionality
 int dim=uncParamInd.XSize();
 
 // Instantiate a PC object for ISP computations
 PCSet myPCSet("ISP",order,dim,pcType,0.0,1.0); 
 
 // The number of PC terms
 const int nPCTerms = myPCSet.GetNumberPCTerms();
 cout << "The number of PC terms in an expansion is " << nPCTerms << endl;

  // Print the multiindices on screen
  myPCSet.PrintMultiIndex();

 // Initial time
 double t0 = 0.0;
 // Final time
 double tf = modelauxparams(0);
 // Time step
 double dTym = modelauxparams(1);
 // Number of steps
 int nStep=(int) tf / dTym;
 
  // Initial conditions of zero coverage (based on Makeev:2002)
  Array1D<double> u(nPCTerms,0.e0);
  Array1D<double> v(nPCTerms,0.e0);
  Array1D<double> w(nPCTerms,0.e0);
  Array1D<double> z(nPCTerms,0.e0);

  // Array to hold the PC representation of the number 1
  Array1D<double> one(nPCTerms,0.e0);
  one(0)=1.0;

  // The z-species is described as z=1-u-v-w
  z=one;
  myPCSet.SubtractInPlace(z,u);
  myPCSet.SubtractInPlace(z,v);
  myPCSet.SubtractInPlace(z,w);

  // Right-hand sides
  Array1D<double> dudt(nPCTerms,0.e0);
  Array1D<double> dvdt(nPCTerms,0.e0);
  Array1D<double> dwdt(nPCTerms,0.e0);

  // Array of arrays to hold the input parameter PC representations in the output PC
  // Each element is an array of coefficients for the corresponding input parameter, whether deterministic or uncertain
  // The size of the array is the total number input parameters
  
  Array1D< Array1D<double> > modelparamPCs(fulldim);
  

  printf("\nInput parameter PC coefficients are given below\n");
  for (int i=0; i<fulldim; i++){
    printf("%s: ",modelparamnames(i).c_str());
    modelparamPCs(i).Resize(nPCTerms,0.e0);
    for (int j=0; j<nPCTerms; j++){
      modelparamPCs(i)(j)=allPCcoefs(j,i);
      printf(" %lg ",modelparamPCs(i)(j));
    }
    printf("\n");
  }
  printf("\n");


  // Initial time and time step counter
  int step=0;
  double tym=t0;

  // Work arrays for integration
  Array1D<double> u_o(nPCTerms,0.e0);
  Array1D<double> v_o(nPCTerms,0.e0);
  Array1D<double> w_o(nPCTerms,0.e0);

  Array1D<double> tmp_u(nPCTerms,0.e0);
  Array1D<double> tmp_v(nPCTerms,0.e0);
  Array1D<double> tmp_w(nPCTerms,0.e0);

  // File to write the mean and stdev, name read from xml
  FILE *f_dump,*modes_dump;
  if(!(f_dump = fopen(outPrint->dumpfile.c_str(),"w"))){ 
    printf("Could not open file '%s'\n",outPrint->dumpfile.c_str()); 
    exit(1); 
  }
  
  // File to dump the PC modes, name hardwired
  string modes_dumpfile = "solution_ISP_modes.dat";
  if(!(modes_dump = fopen(modes_dumpfile.c_str(),"w"))){ 
    printf("Could not open file '%s'\n",modes_dumpfile.c_str()); 
    exit(1); 
  }

  // write time, u, v, w (all modes) to file
  WriteModesToFilePtr(tym, u.GetArrayPointer(), v.GetArrayPointer(), w.GetArrayPointer(), nPCTerms, modes_dump);
    
  // Write out initial step
  // Get standard deviations
  double uStDv = myPCSet.StDv(u);
  double vStDv = myPCSet.StDv(v);
  double wStDv = myPCSet.StDv(w);

  // write u, v, w (mean and standard deviation) to file
  WriteMeanStdDevToFilePtr(tym, u(0), v(0), w(0), uStDv, vStDv, wStDv, f_dump);
    
  // write u, v, w (mean and standard deviation) to screen
  WriteMeanStdDevToStdOut(step, tym, u(0), v(0), w(0), uStDv, vStDv, wStDv);
    
  // Forward run
  while(tym < tf) {
    // Integrate with 2nd order Runge Kutta

    // Save solution at current time step
    myPCSet.Copy(u_o,u);
    myPCSet.Copy(v_o,v);
    myPCSet.Copy(w_o,w);
    
    // Compute right hand sides
    GetRHS(myPCSet,modelparamPCs(0).GetArrayPointer(),modelparamPCs(1).GetArrayPointer(),modelparamPCs(2).GetArrayPointer(),u.GetArrayPointer(),v.GetArrayPointer(),w.GetArrayPointer(),dudt.GetArrayPointer(),dvdt.GetArrayPointer(),dwdt.GetArrayPointer());

    // Advance u, v, w to mid-point
    myPCSet.Multiply(dudt,0.5*dTym,tmp_u); // 0.5*dTym*dudt
    myPCSet.Multiply(dvdt,0.5*dTym,tmp_v); // 0.5*dTym*dvdt
    myPCSet.Multiply(dwdt,0.5*dTym,tmp_w); // 0.5*dTym*dwdt

    myPCSet.Add(u_o,tmp_u,u); // u = u_o + 0.5*dTym*dudt
    myPCSet.Add(v_o,tmp_v,v); // v = v_o + 0.5*dTym*dvdt
    myPCSet.Add(w_o,tmp_w,w); // w = w_o + 0.5*dTym*dwdt
    
    // Compute z = 1 - u - v - w
    z=one;
    myPCSet.SubtractInPlace(z,u);
    myPCSet.SubtractInPlace(z,v);
    myPCSet.SubtractInPlace(z,w);
    
    // Compute right hand sides
    GetRHS(myPCSet,modelparamPCs(0).GetArrayPointer(),modelparamPCs(1).GetArrayPointer(),modelparamPCs(2).GetArrayPointer(),u.GetArrayPointer(),v.GetArrayPointer(),w.GetArrayPointer(),dudt.GetArrayPointer(),dvdt.GetArrayPointer(),dwdt.GetArrayPointer());
    
    // Advance u, v, w to next time step
    myPCSet.Multiply(dudt,dTym,tmp_u); // dTym*dudt
    myPCSet.Multiply(dvdt,dTym,tmp_v); // dTym*dvdt
    myPCSet.Multiply(dwdt,dTym,tmp_w); // dTym*dwdt
    
    
    myPCSet.Add(u_o,tmp_u,u); // u = u_o + dTym*dudt
    myPCSet.Add(v_o,tmp_v,v); // v = v_o + dTym*dvdt
    myPCSet.Add(w_o,tmp_w,w); // w = w_o + dTym*dwdt
    
    // Compute z = 1 - u - v - w
    z=one;
    myPCSet.SubtractInPlace(z,u);
    myPCSet.SubtractInPlace(z,v);
    myPCSet.SubtractInPlace(z,w);


    // Advance time and step counter
    tym += dTym;
    step+=1;
   

    // write time, u, v, w (all modes) to file
    if(step % outPrint->fdumpInt == 0){
      WriteModesToFilePtr(tym, u.GetArrayPointer(), v.GetArrayPointer(), w.GetArrayPointer(), nPCTerms, modes_dump);
    }

    // Get standard deviations
    uStDv = myPCSet.StDv(u);
    vStDv = myPCSet.StDv(v);
    wStDv = myPCSet.StDv(w);
    
    // write u, v, w (mean and standard deviation) to file
    if(step % outPrint->fdumpInt == 0){
      WriteMeanStdDevToFilePtr(tym, u(0), v(0), w(0), uStDv, vStDv, wStDv, f_dump);
    }
    // write u, v, w (mean and standard deviation) to screen
    if(step % outPrint->dumpInt == 0){
      WriteMeanStdDevToStdOut(step, tym, u(0), v(0), w(0), uStDv, vStDv, wStDv);
    }
    
  }
  
  // Close output file
  if(fclose(f_dump)){ 
    printf("Could not close file '%s'\n",outPrint->dumpfile.c_str()); 
    exit(1); 
  }


  // Close output file
  if(fclose(modes_dump)){ 
    printf("Could not close file '%s'\n",modes_dumpfile.c_str()); 
    exit(1); 
  }
  
  return 0;
}
void convert::force(int nn,double D,double rho,double Cd,double Cm){
    // Define Pi
    //
    const double PI = 4.0*atan(1.0);


    // To cover-up for previous lazyness are we now making local
    // copies of the fields we need - sorry!
    //
    std::vector<double> tmp_;
    tmp_.resize(nt);
    for (int i=0;i<nt;i++){
        tmp_[i] = eta[i*nx*ny+nn];
    }

    // deta/dt
    //
    std::vector<double> detadt;
   detadt.resize(nt);
   gradient(detadt,tmp_,dt,nt);

    // dz/dt
    //
   Double2d dzdt(boost::extents[nz][nt]);
    for (int k=0;k<nz;k++){
        for (int i=0;i<nt;i++){
         dzdt[k][i] = detadt[i]*sigma[k];
        }
    }

    // du/dt on the sigma grid
    //
    Double2d dudt(boost::extents[nz][nt]);
    for (int k=0;k<nz;k++){
        for (int i=0;i<nt;i++){
            tmp_[i] = u[i*nx*ny*nz+nn*nz+k];
        }
        gradient(&dudt[k][0],tmp_,dt,nt); // To-do: this is super sluppy and error prone
     }



    // Acceleration
    //
    Double2d acc(boost::extents[nz][nt]);
    for (int k=0;k<nz;k++){
        for (int i=0;i<nt;i++){
            acc[k][i] = dudt[k][i]-uz[i*nx*ny*nz+nn*nz+k]*dzdt[k][i];
        }
    }

    // The inline force
    //
    double dz,Fd,Fi;
    int index;
    F.resize(nt);

    for (int i=0;i<nt;i++){
        F[i] = 0;
        for (int k=1;k<nz-1;k++){// we ignore the ghost points
            index = i*nx*ny*nz+nn*nz+k;
            dz = (sigma[k+1]-sigma[k])*(eta[i*nx*ny+nn]+h[nn]);

            Fd = 0.5*rho*Cd*D*(u[index]*std::abs(u[index])+u[index+1]*std::abs(u[index+1]))/2;
            Fi = rho*Cm*(PI/4)*pow(D,2)*(acc[k][i]+acc[k+1][i])/2;

            F[i] += (Fd+Fi)*dz;
        }

    }


    QFileInfo fileInfo =  QFileInfo(fileName);
    std::ofstream morisonForce;
    morisonForce.open(fileInfo.baseName().toLatin1() + ".force");
    morisonForce << "time F" << std::endl;
    QVector<double> QV_t,QV_F;
    QV_t.resize(nt);
    QV_F.resize(nt);
    for (int i=1;i<nt-1;i++){
        morisonForce << std::setiosflags(std::ios::fixed) << std::setprecision(10) << t[i] << " " << F[i] << std::endl;
        QV_t[i] = t[i];
        QV_F[i] = F[i];
    }
    morisonForce.close();

    // plot solution
    QCustomPlot *cPlot = new QCustomPlot;
    QWidget *plotWindow = new QWidget;
    QHBoxLayout *plotWindow_layout = new QHBoxLayout;
    plotWindow_layout->addWidget(cPlot);
    plotWindow->setLayout(plotWindow_layout);

    plotWindow->resize(800,400);

    plotWindow->show();
    cPlot->clearGraphs();

    cPlot->addGraph();
    cPlot->graph()->setData(QV_t,QV_F);
    cPlot->xAxis->setLabel("Time, t s");
    cPlot->yAxis->setLabel("Inline force, F N");
    QVector<double>::iterator Xmin = std::min_element(QV_t.begin(), QV_t.end());
    QVector<double>::iterator Xmax = std::max_element(QV_t.begin(), QV_t.end());
    QVector<double>::iterator Ymin = std::min_element(QV_F.begin(), QV_F.end());
    QVector<double>::iterator Ymax = std::max_element(QV_F.begin(), QV_F.end());
    cPlot->xAxis->setRange(*Xmin,*Xmax);
    cPlot->yAxis->setRange(*Ymin,*Ymax);
    cPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
    cPlot->replot();


}