Esempio n. 1
0
/**
 * Description not yet available.
 * \param
 */
void laplace_approximation_calculator::
  do_newton_raphson_banded(function_minimizer * pfmin,double f_from_1,
  int& no_converge_flag)
{
  //quadratic_prior * tmpptr=quadratic_prior::ptr[0];
  //cout << tmpptr << endl;


  laplace_approximation_calculator::where_are_we_flag=2;
  double maxg=fabs(evaluate_function(uhat,pfmin));


  laplace_approximation_calculator::where_are_we_flag=0;
  dvector uhat_old(1,usize);
  for(int ii=1;ii<=num_nr_iters;ii++)
  {
    // test newton raphson
    switch(hesstype)
    {
    case 3:
      bHess->initialize();
      break;
    case 4:
      Hess.initialize();
      break;
    default:
      cerr << "Illegal value for hesstype here" << endl;
      ad_exit(1);
    }

    grad.initialize();
    //int check=initial_params::stddev_scale(scale,uhat);
    //check=initial_params::stddev_curvscale(curv,uhat);
    //max_separable_g=0.0;
    sparse_count = 0;

    step=get_newton_raphson_info_banded(pfmin);
    //if (bHess)
     // cout << "norm(*bHess) = " << norm(*bHess) << endl;
    //cout << "norm(Hess) = " << norm(Hess) << endl;
    //cout << grad << endl;
    //check_pool_depths();
    if (!initial_params::mc_phase)
      cout << "Newton raphson " << ii << "  ";
    if (quadratic_prior::get_num_quadratic_prior()>0)
    {
      quadratic_prior::get_cHessian_contribution(Hess,xsize);
      quadratic_prior::get_cgradient_contribution(grad,xsize);
    }

    int ierr=0;
    if (hesstype==3)
    {
      if (use_dd_nr==0)
      {
        banded_lower_triangular_dmatrix bltd=choleski_decomp(*bHess,ierr);
        if (ierr && no_converge_flag ==0)
        {
          no_converge_flag=1;
          //break;
        }
        if (ierr)
        {
          double oldval;
          evaluate_function(oldval,uhat,pfmin);
          uhat=banded_calculations_trust_region_approach(uhat,pfmin);
        }
        else
        {
          if (dd_nr_flag==0)
          {
            dvector v=solve(bltd,grad);
            step=-solve_trans(bltd,v);
            //uhat_old=uhat;
            uhat+=step;
          }
          else
          {
#if defined(USE_DD_STUFF)
            int n=grad.indexmax();
            maxg=fabs(evaluate_function(uhat,pfmin));
            uhat=dd_newton_raphson2(grad,*bHess,uhat);
#else
            cerr << "high precision Newton Raphson not implemented" << endl;
            ad_exit(1);
#endif
          }
          maxg=fabs(evaluate_function(uhat,pfmin));
          if (f_from_1< pfmin->lapprox->fmc1.fbest)
          {
            uhat=banded_calculations_trust_region_approach(uhat,pfmin);
            maxg=fabs(evaluate_function(uhat,pfmin));
          }
        }
      }
      else
      {
        cout << "error not used" << endl;
        ad_exit(1);
       /*
        banded_symmetric_ddmatrix bHessdd=banded_symmetric_ddmatrix(*bHess);
        ddvector gradd=ddvector(grad);
        //banded_lower_triangular_ddmatrix bltdd=choleski_decomp(bHessdd,ierr);
        if (ierr && no_converge_flag ==0)
        {
          no_converge_flag=1;
          break;
        }
        if (ierr)
        {
          double oldval;
          evaluate_function(oldval,uhat,pfmin);
          uhat=banded_calculations_trust_region_approach(uhat,pfmin);
          maxg=fabs(evaluate_function(uhat,pfmin));
        }
        else
        {
          ddvector v=solve(bHessdd,gradd);
          step=-make_dvector(v);
          //uhat_old=uhat;
          uhat=make_dvector(ddvector(uhat)+step);
          maxg=fabs(evaluate_function(uhat,pfmin));
          if (f_from_1< pfmin->lapprox->fmc1.fbest)
          {
            uhat=banded_calculations_trust_region_approach(uhat,pfmin);
            maxg=fabs(evaluate_function(uhat,pfmin));
          }
        }
        */
      }

      if (maxg < 1.e-13)
      {
        break;
      }
    }
    else if (hesstype==4)
    {
      dvector step;

#     if defined(USE_ATLAS)
        if (!ad_comm::no_atlas_flag)
        {
          step=-atlas_solve_spd(Hess,grad,ierr);
        }
        else
        {
          dmatrix A=choleski_decomp_positive(Hess,ierr);
          if (!ierr)
          {
            step=-solve(Hess,grad);
            //step=-solve(A*trans(A),grad);
          }
        }
        if (!ierr) break;
#     else
        if (sparse_hessian_flag)
        {
          //step=-solve(*sparse_triplet,Hess,grad,*sparse_symbolic);
          dvector temp=solve(*sparse_triplet2,grad,*sparse_symbolic2,ierr);
          if (ierr)
          {
            step=-temp;
          }
          else
          {
            cerr << "matrix not pos definite in sparse choleski"  << endl;
            pfmin->bad_step_flag=1;

            int on;
            int nopt;
            if ((on=option_match(ad_comm::argc,ad_comm::argv,"-ieigvec",nopt))
              >-1)
            {
              dmatrix M=make_dmatrix(*sparse_triplet2);

              ofstream ofs3("inner-eigvectors");
              ofs3 << "eigenvalues and eigenvectors " << endl;
              dvector v=eigenvalues(M);
              dmatrix ev=trans(eigenvectors(M));
              ofs3 << "eigenvectors" << endl;
              int i;
              for (i=1;i<=ev.indexmax();i++)
               {
                  ofs3 << setw(4) << i  << " "
                   << setshowpoint() << setw(14) << setprecision(10) << v(i)
                   << " "
                   << setshowpoint() << setw(14) << setprecision(10)
                   << ev(i) << endl;
               }
            }
          }
          //cout << norm2(step-tmpstep) << endl;
          //dvector step1=-solve(Hess,grad);
          //cout << norm2(step-step1) << endl;
        }
        else
        {
          step=-solve(Hess,grad);
        }
#     endif
      if (pmin->bad_step_flag)
        break;
      uhat_old=uhat;
      uhat+=step;

      double maxg_old=maxg;
      maxg=fabs(evaluate_function(uhat,pfmin));
      if (maxg>maxg_old)
      {
        uhat=uhat_old;
        evaluate_function(uhat,pfmin);
        break;
      }
      if (maxg < 1.e-13)
      {
        break;
      }
    }

    if (sparse_hessian_flag==0)
    {
      for (int i=1;i<=usize;i++)
      {
        y(i+xsize)=uhat(i);
      }
    }
    else
    {
      for (int i=1;i<=usize;i++)
      {
        value(y(i+xsize))=uhat(i);
      }
    }
  }
}
Esempio n. 2
0
int MAC3DTest_StationaryBubble() {
    // Set initial level set
    const double Re = 0.0, We = 0.0, Fr = 0.0;
    const double L = 1.0, U = 1.0;
    const double rhoL = 1.226, muL = 1.78e-5;
    // const double rhoH = 1000, muH = 1.137e-3;
    const double rhoH = 1000, muH = 1.137e-3, sigma = 0.0728;
    // const double rhoL = 1000, muL = 1.137e-3, sigma = 0.0;
    const double ambientPressure = 1.0;
    const double gConstant = 0.0; 
    GAXISENUM3D GAxis = GAXISENUM3D::Y;
    // # of cells
    const int nx = 128, ny = 128, nz = 128;
    // related to initialize level set
    const double baseX = 0.0, baseY = 0.0, baseZ = 0.0, lenX = 0.04, lenY = 0.04, lenZ = 0.04, cfl = 0.5;
    double radius = 0.01, x = 0.0, y = 0.0, z = 0.0, d = 0.0;

    const int maxiter = 5, niterskip = 1, num_bc_grid = 3;
    const int64_t arrSize = (nx + 2 * num_bc_grid) * (ny + 2 * num_bc_grid) * (nz + 2 * num_bc_grid);
    const double maxtime = 0.06;
    const bool writeVTK = false;
    // length of each cell
    const double dx = lenX / nx, dy = lenY / ny, dz = lenZ / nz;
    std::ostringstream outfname_stream1;
    outfname_stream1 << "testMAC3D_StationaryBubbleBubbleRisingVel_Re_"
        << std::to_string(Re) << "_"
        << static_cast<std::ostringstream*>(&(std::ostringstream() << nx))->str()
        << "x"
        << static_cast<std::ostringstream*>(&(std::ostringstream() << ny))->str()
        << "x"
        << static_cast<std::ostringstream*>(&(std::ostringstream() << nz))->str();
    const std::string fname_vel = outfname_stream1.str();

    std::ostringstream outfname_stream2;
    outfname_stream2 << "testMAC3D_StationaryBubbleBubbleRisingDiv_Re_"
        << std::to_string(Re) << "_"
        << static_cast<std::ostringstream*>(&(std::ostringstream() << nx))->str()
        << "x"
        << static_cast<std::ostringstream*>(&(std::ostringstream() << ny))->str()
        << "x"
        << static_cast<std::ostringstream*>(&(std::ostringstream() << nz))->str();
    const std::string fname_div = outfname_stream2.str();
    const int iterskip = 1;
    int stat = 0;

    std::unique_ptr<MACSolver3D> MSolver;
    MSolver = std::make_unique<MACSolver3D>(rhoH, rhoL, muH, muL, gConstant, GAxis,
        L, U, sigma, nx, ny, nz, baseX, baseY, baseY, lenX, lenY, lenZ,
        cfl, maxtime, maxiter, niterskip, num_bc_grid, writeVTK);
    MSolver->SetBC_U_3D("wall", "wall", "wall", "wall", "wall", "wall");
    MSolver->SetBC_V_3D("wall", "wall", "wall", "wall", "wall", "wall");
    MSolver->SetBC_W_3D("wall", "wall", "wall", "wall", "wall", "wall");
    MSolver->SetBC_P_3D("wall", "wall", "wall", "wall", "wall", "wall");
    MSolver->SetBCConstantUW(0.0);
    MSolver->SetBCConstantUE(0.0);
    MSolver->SetBCConstantUS(0.0);
    MSolver->SetBCConstantUN(0.0);
    MSolver->SetBCConstantUB(0.0);
    MSolver->SetBCConstantUT(0.0);
    MSolver->SetBCConstantVW(0.0);
    MSolver->SetBCConstantVE(0.0);
    MSolver->SetBCConstantVS(0.0);
    MSolver->SetBCConstantVN(0.0);
    MSolver->SetBCConstantVB(0.0);
    MSolver->SetBCConstantVT(0.0);
    MSolver->SetBCConstantWW(0.0);
    MSolver->SetBCConstantWE(0.0);
    MSolver->SetBCConstantWS(0.0);
    MSolver->SetBCConstantWN(0.0);
    MSolver->SetBCConstantWB(0.0);
    MSolver->SetBCConstantWT(0.0);
    MSolver->UpdateAmbientPressure(MSolver->m_dt * ambientPressure);
    MSolver->SetPLTType(PLTTYPE::BINARY);

    MSolver->SetPoissonSolver(POISSONTYPE::CG);
    MSolver->SetImplicitSolver(POISSONTYPE::CG);
    const int poissonMaxIter = 2500;

    std::shared_ptr<LevelSetSolver3D> LSolver;
    LSolver = std::make_shared<LevelSetSolver3D>(nx, ny, nz, num_bc_grid, baseX, baseY, baseZ, dx, dy, dz);
    // \phi^n
    std::vector<double> lsB(arrSize, 0.0);
    // \phi^{n + 1}
    std::vector<double> ls(arrSize, 0.0);
    // inside value must be positive levelset, otherwise, negative
    
    std::vector<double> H(arrSize, 0.0), 
        HSmooth(arrSize, 0.0);
    // init velocity and pseudo-pressure
    MSolver->AllocateVariables();

    MSolver->ApplyBC_U_3D(MSolver->m_u);
    MSolver->ApplyBC_V_3D(MSolver->m_v);
    MSolver->ApplyBC_W_3D(MSolver->m_w);
    MSolver->ApplyBC_P_3D(MSolver->m_ps);
    MSolver->ApplyBC_P_3D(MSolver->m_p);
    LSolver->SetBC_P_3D("neumann", "neumann", "neumann", "neumann", "neumann", "neumann");
    LSolver->SetBCConstantPW(0.0);
    LSolver->SetBCConstantPE(0.0);
    LSolver->SetBCConstantPS(0.0);
    LSolver->SetBCConstantPN(0.0);
    LSolver->SetBCConstantPB(0.0);
    LSolver->SetBCConstantPT(0.0);
    
    for (int k = 0; k < nz + 2 * num_bc_grid; k++)
    for (int j = 0; j < ny + 2 * num_bc_grid; j++)
    for (int i = 0; i < nx + 2 * num_bc_grid; i++) {
        // positive : inside & gas, negative : outside & liquid 
        x = baseX + (i + 0.5 - num_bc_grid) * dx;
        y = baseY + (j + 0.5 - num_bc_grid) * dy;
        z = baseZ + (k + 0.5 - num_bc_grid) * dz;

        // d - inside : -, outside : +
        d = std::sqrt(std::pow(x - 0.02, 2.0) + std::pow(y - 0.02, 2.0) + std::pow(z - 0.02, 2.0)) - radius;

        // ls - inside : -(gas), outside : +(liquid)
        ls[idx3_3D(ny, nz, i, j, k)] = d;
    }
    LSolver->ApplyBC_P_3D(ls);
    LSolver->Reinit_MinRK2_3D(ls);
    
    LSolver->ApplyBC_P_3D(ls);

    // prevent dt == 0.0
    MSolver->m_dt = cfl * std::min(dx, dy) / U;
    std::cout << " dt : " << MSolver->m_dt << std::endl;

    std::vector<double> rhsU(arrSize), rhsV(arrSize), rhsW(arrSize);
    std::vector<double> uhat(arrSize), vhat(arrSize), what(arrSize);
    std::vector<double> div(arrSize);
    MSolver->OutRes(MSolver->m_iter, MSolver->m_curTime, fname_vel, fname_div,
        MSolver->m_u, MSolver->m_v, MSolver->m_w, MSolver->m_ps, ls);

    while (MSolver->m_curTime < MSolver->kMaxTime && MSolver->m_iter < MSolver->kMaxIter) {
        // Solver Level set part first
        // Have to use \phi^{n+1} for rho, mu, kappa
        MSolver->m_iter++;

        lsB = ls;
        LSolver->Solve_LevelSet_3D(ls, MSolver->m_u, MSolver->m_v, MSolver->m_w, MSolver->m_dt);
        LSolver->ApplyBC_P_3D(ls);
        LSolver->Reinit_MinRK2_3D(ls);
        
        LSolver->ApplyBC_P_3D(ls);
        
        // Solve Momentum Part
        MSolver->UpdateKappa(ls);
        H = MSolver->UpdateHeavisideFunc(ls);
        HSmooth = MSolver->UpdateSmoothHeavisideFunc(ls);

        rhsU = MSolver->GetRHSU(LSolver, ls, MSolver->m_u, MSolver->m_v, MSolver->m_w, H);
        rhsV = MSolver->GetRHSV(LSolver, ls, MSolver->m_u, MSolver->m_v, MSolver->m_w, H);
        rhsW = MSolver->GetRHSW(LSolver, ls, MSolver->m_u, MSolver->m_v, MSolver->m_w, H);

        uhat = MSolver->GetUHat(ls, rhsU, H, poissonMaxIter);
        vhat = MSolver->GetVHat(ls, rhsV, H, poissonMaxIter);
        what = MSolver->GetWHat(ls, rhsW, H, poissonMaxIter);

        MSolver->ApplyBC_U_3D(uhat);
        MSolver->ApplyBC_V_3D(vhat);
        MSolver->ApplyBC_W_3D(what);
        
        // From intermediate velocity, get divergence
        div = MSolver->GetDivergence(uhat, vhat, what);
        MSolver->ApplyBC_P_3D(MSolver->m_ps);
        LSolver->ApplyBC_P_3D(ls);

        // Solve Poisson equation
        // m_phi = pressure * dt
        stat = MSolver->SolvePoisson(MSolver->m_ps, div, ls, lsB, MSolver->m_u, MSolver->m_v, MSolver->m_w, H, poissonMaxIter);
        MSolver->ApplyBC_P_3D(MSolver->m_ps);

        stat = MSolver->UpdateVel(MSolver->m_u, MSolver->m_v, MSolver->m_w,
            uhat, vhat, what, MSolver->m_ps, ls, lsB, H);

        MSolver->ApplyBC_U_3D(MSolver->m_u);
        MSolver->ApplyBC_V_3D(MSolver->m_v);
        MSolver->ApplyBC_W_3D(MSolver->m_w);

        MSolver->m_dt = MSolver->UpdateDt(MSolver->m_u, MSolver->m_v, MSolver->m_w);
        MSolver->m_curTime += MSolver->m_dt;

        if ((MSolver->m_iter % MSolver->kNIterSkip) == 0) {
            std::chrono::high_resolution_clock::time_point p = std::chrono::high_resolution_clock::now();
            std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(p.time_since_epoch());

            std::chrono::seconds s = std::chrono::duration_cast<std::chrono::seconds>(ms);
            std::time_t t = s.count();
            std::size_t fractional_seconds = ms.count() % 1000;

            std::cout << "Stationary Bubble : " << std::ctime(&t) << " " << MSolver->m_iter << " " << MSolver->m_curTime << " " << MSolver->m_dt << " " << std::endl;

            MSolver->OutRes(MSolver->m_iter, MSolver->m_curTime, fname_vel, fname_div,
                MSolver->m_u, MSolver->m_v, MSolver->m_w, MSolver->m_ps, ls);
        }
        std::fill(uhat.begin(), uhat.end(), 0.0);
        std::fill(vhat.begin(), vhat.end(), 0.0);
    }
    // http://stackoverflow.com/a/12836048/743078
    std::chrono::high_resolution_clock::time_point p = std::chrono::high_resolution_clock::now();
    std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(p.time_since_epoch());

    std::chrono::seconds s = std::chrono::duration_cast<std::chrono::seconds>(ms);
    std::time_t t = s.count();
    std::size_t fractional_seconds = ms.count() % 1000;

    std::cout << "(Final) Stationary Bubble : " << std::ctime(&t) << " " << MSolver->m_iter << " " << MSolver->m_curTime << " " << MSolver->m_dt << " " << std::endl;
    MSolver->OutRes(MSolver->m_iter, MSolver->m_curTime, fname_vel, fname_div,
        MSolver->m_u, MSolver->m_v, MSolver->m_w, MSolver->m_ps, ls);
    MSolver->OutResClose();

    MSolver.reset();
    LSolver.reset();

    return 0;
}