/** * 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); } } } }
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; }