static void explicit_time_strategy(MESH *mesh, ADAPT_INSTAT *adapt) { FUNCNAME("explicit_time_strategy"); ADAPT_STAT *adapt_s = adapt->adapt_space; /* first estimate must be computed before adapt_mesh() is called */ if (adapt->time <= adapt->start_time) { if (adapt_s->estimate) adapt_s->estimate(mesh, adapt_s); } adapt->time += adapt->timestep; if (adapt->set_time) adapt->set_time(mesh, adapt); INFO(adapt->info,6,"time = %.4le, timestep = %.4le\n", adapt->time, adapt->timestep); adapt_mesh(mesh, adapt_s); if (adapt_s->solve) adapt_s->solve(mesh); if (adapt_s->estimate) adapt_s->estimate(mesh, adapt_s); /* return value is not used */ return; }
void App::initial_load() { build_femspace(); //autoSetGrainInfo(); readGrainInfo(); Operator::L2Project(&phi_0, *phi_h, Operator::LOCAL_LEAST_SQUARE, 5); Operator::L2Project(&c_0, *c_h, Operator::LOCAL_LEAST_SQUARE, 5); for (int i=0;i<3;++i) { adapt_mesh(); initOrientation(); // Operator::L2Interpolate(&phi_0, *phi_h); // Operator::L2Interpolate(&c_0, *c_h); } Operator::L2Project(&u_0, *u_h, Operator::LOCAL_LEAST_SQUARE, 5); Operator::L2Project(&v_0, *v_h, Operator::LOCAL_LEAST_SQUARE, 5); Operator::L2Project(&p_0, *p_h, Operator::LOCAL_LEAST_SQUARE, 5); Operator::L2Project(&p_0, *last_p_h, Operator::LOCAL_LEAST_SQUARE, 5); save_data(); load_balance(); }
void SCL::run() { std::cout.precision(6); std::cout.setf(std::ios::scientific, std::ios::floatfield); double start_time = MPI_Wtime(); double last_time = start_time; double this_time; initialize(); do { step_forward(); adapt_mesh(); load_balance(); /// 完成负载平衡 getControl(); if (htree.rank() == 0) { last_time = this_time; this_time = MPI_Wtime(); std::cout << "t = " << t << ", dt = " << dt << ", wall time = " << this_time - start_time << ", step time = " << this_time - last_time << std::endl; } } while(end_t - t > 2.0e-16); }
static void implicit_time_strategy(MESH *mesh, ADAPT_INSTAT *adapt) { FUNCNAME("implicit_time_strategy"); int iter, iter_s; ADAPT_STAT *adapt_s = adapt->adapt_space; REAL err_space, err_time, space_err_limit, time_err_limit, time_err_low; space_err_limit = adapt->tolerance * adapt->rel_space_error; time_err_limit = adapt->tolerance * adapt->rel_time_error; time_err_low = adapt->tolerance * adapt->rel_time_error * adapt->time_theta_2; iter = iter_s = 0; err_time = 0.0; do { adapt->time += adapt->timestep; if (adapt->set_time) adapt->set_time(mesh, adapt); INFO(adapt->info,6,"time = %.4le, try timestep = %.4le\n", adapt->time, adapt->timestep); if (adapt_s->build_before_refine) adapt_s->build_before_refine(mesh, 0); if (adapt_s->build_before_coarsen) adapt_s->build_before_coarsen(mesh, 0); if (adapt_s->build_after_coarsen) adapt_s->build_after_coarsen(mesh, 0); if (adapt_s->solve) adapt_s->solve(mesh); err_space = adapt_s->estimate ? adapt_s->estimate(mesh, adapt_s) : 0.0; if (adapt->get_time_est) err_time = adapt->get_time_est(mesh, adapt); iter++; if (iter > adapt->max_iteration) break; if (err_time > time_err_limit) { adapt->time -= adapt->timestep; adapt->timestep *= adapt->time_delta_1; continue; } do { if (adapt_mesh(mesh, adapt_s)) { adapt_s->solve(mesh); err_space = adapt_s->estimate ? adapt_s->estimate(mesh, adapt_s) : 0.0; if (adapt->get_time_est) { err_time = adapt->get_time_est(mesh, adapt); if (err_time > time_err_limit) { adapt->time -= adapt->timestep; adapt->timestep *= adapt->time_delta_1; break; } } } iter_s++; if (iter_s > adapt_s->max_iteration) break; } while (err_space > space_err_limit); } while (err_time > time_err_limit); if (adapt->get_time_est) if (err_time <= time_err_low) { adapt->timestep *= adapt->time_delta_2; } return; }
void adapt_method_stat(MESH *mesh, ADAPT_STAT *adapt) { FUNCNAME("adapt_method_stat"); int iter; REAL est; clock_t first; TEST_EXIT(mesh, "no MESH\n"); TEST_EXIT(adapt, "no ADAPT_STAT\n"); /* get solution on initial mesh */ if (adapt->build_before_refine) adapt->build_before_refine(mesh, 0); if (adapt->build_before_coarsen) adapt->build_before_coarsen(mesh, 0); if (adapt->build_after_coarsen) adapt->build_after_coarsen(mesh, 0); if (adapt->solve) { first = clock(); adapt->solve(mesh); INFO(adapt->info,8,"solution of discrete system needed %.5lg seconds\n", TIME_USED(first,clock())); } first = clock(); est = adapt->estimate ? adapt->estimate(mesh, adapt) : 0.0; INFO(adapt->info,8,"estimation of the error needed %.5lg seconds\n", TIME_USED(first,clock())); for (iter = 0; (est > adapt->tolerance) && ((adapt->max_iteration <= 0) || (iter < adapt->max_iteration)); iter++) { if (adapt_mesh(mesh, adapt)) { if (adapt->solve) { first = clock(); adapt->solve(mesh); INFO(adapt->info,8, "solution of discrete system needed %.5lg seconds\n", TIME_USED(first,clock())); } first = clock(); est = adapt->estimate ? adapt->estimate(mesh, adapt) : 0.0; INFO(adapt->info,8,"estimation of the error needed %.5lg seconds\n", TIME_USED(first,clock())); } else { WARNING("no mesh adaption, but estimate above tolerance ???\n"); //ERROR("no mesh adaption, but estimate above tolerance ???\n"); //break; } INFO(adapt->info, 4,"iter: %d", iter); PRINT_INFO(adapt->info, 4,", tol = %.4le", adapt->tolerance); PRINT_INFO(adapt->info, 4,", estimate = %.4le\n", est); } if (est > adapt->tolerance) { MSG("max_iterations REACHED: %d\n", adapt->max_iteration); MSG("prescribed tolerance %le\n", adapt->tolerance); MSG("finished with estimate %le\n", est); } else { INFO(adapt->info, 2,"no of iterations: %d\n", iter); INFO(adapt->info, 2,"prescribed tolerance %.4le\n", adapt->tolerance); INFO(adapt->info, 2,"finished with estimate %.4le\n", est); } return; }
/* Main Program */ int main() { /* general problem parameters */ realtype T0 = RCONST(0.0); /* initial time */ realtype Tf = RCONST(1.0); /* final time */ realtype rtol = 1.e-3; /* relative tolerance */ realtype atol = 1.e-10; /* absolute tolerance */ realtype hscale = 1.0; /* time step change factor on resizes */ UserData udata = NULL; realtype *data; long int N = 21; /* initial spatial mesh size */ realtype refine = 3.e-3; /* adaptivity refinement tolerance */ realtype k = 0.5; /* heat conductivity */ long int i, nni, nni_cur=0, nni_tot=0, nli, nli_tot=0; int iout=0; /* general problem variables */ int flag; /* reusable error-checking flag */ N_Vector y = NULL; /* empty vector for storing solution */ N_Vector y2 = NULL; /* empty vector for storing solution */ N_Vector yt = NULL; /* empty vector for swapping */ void *arkode_mem = NULL; /* empty ARKode memory structure */ FILE *XFID, *UFID; realtype t, olddt, newdt; realtype *xnew = NULL; long int Nnew; /* allocate and fill initial udata structure */ udata = (UserData) malloc(sizeof(*udata)); udata->N = N; udata->k = k; udata->refine_tol = refine; udata->x = malloc(N * sizeof(realtype)); for (i=0; i<N; i++) udata->x[i] = 1.0*i/(N-1); /* Initial problem output */ printf("\n1D adaptive Heat PDE test problem:\n"); printf(" diffusion coefficient: k = %g\n", udata->k); printf(" initial N = %li\n", udata->N); /* Initialize data structures */ y = N_VNew_Serial(N); /* Create initial serial vector for solution */ if (check_flag((void *) y, "N_VNew_Serial", 0)) return 1; N_VConst(0.0, y); /* Set initial conditions */ /* output mesh to disk */ XFID=fopen("heat_mesh.txt","w"); /* output initial mesh to disk */ for (i=0; i<udata->N; i++) fprintf(XFID," %.16e", udata->x[i]); fprintf(XFID,"\n"); /* Open output stream for results, access data array */ UFID=fopen("heat1D.txt","w"); /* output initial condition to disk */ data = N_VGetArrayPointer(y); for (i=0; i<udata->N; i++) fprintf(UFID," %.16e", data[i]); fprintf(UFID,"\n"); /* Create the solver memory */ arkode_mem = ARKodeCreate(); if (check_flag((void *) arkode_mem, "ARKodeCreate", 0)) return 1; /* Initialize the integrator memory */ flag = ARKodeInit(arkode_mem, NULL, f, T0, y); if (check_flag(&flag, "ARKodeInit", 1)) return 1; /* Set routines */ flag = ARKodeSetUserData(arkode_mem, (void *) udata); /* Pass udata to user functions */ if (check_flag(&flag, "ARKodeSetUserData", 1)) return 1; flag = ARKodeSetMaxNumSteps(arkode_mem, 10000); /* Increase max num steps */ if (check_flag(&flag, "ARKodeSetMaxNumSteps", 1)) return 1; flag = ARKodeSStolerances(arkode_mem, rtol, atol); /* Specify tolerances */ if (check_flag(&flag, "ARKodeSStolerances", 1)) return 1; flag = ARKodeSetAdaptivityMethod(arkode_mem, 2, 1, 0, NULL); /* Set adaptivity method */ if (check_flag(&flag, "ARKodeSetAdaptivityMethod", 1)) return 1; flag = ARKodeSetPredictorMethod(arkode_mem, 0); /* Set predictor method */ if (check_flag(&flag, "ARKodeSetPredictorMethod", 1)) return 1; /* Linear solver specification */ flag = ARKPcg(arkode_mem, 0, N); if (check_flag(&flag, "ARKPcg", 1)) return 1; flag = ARKSpilsSetJacTimesVecFn(arkode_mem, Jac); if (check_flag(&flag, "ARKSpilsSetJacTimesVecFn", 1)) return 1; /* Main time-stepping loop: calls ARKode to perform the integration, then prints results. Stops when the final time has been reached */ t = T0; olddt = 0.0; newdt = 0.0; printf(" iout dt_old dt_new ||u||_rms N NNI NLI\n"); printf(" ----------------------------------------------------------------------------------------\n"); printf(" %4i %19.15e %19.15e %19.15e %li %2i %3i\n", iout, olddt, newdt, sqrt(N_VDotProd(y,y)/udata->N), udata->N, 0, 0); while (t < Tf) { /* "set" routines */ flag = ARKodeSetStopTime(arkode_mem, Tf); if (check_flag(&flag, "ARKodeSetStopTime", 1)) return 1; flag = ARKodeSetInitStep(arkode_mem, newdt); if (check_flag(&flag, "ARKodeSetInitStep", 1)) return 1; /* call integrator */ flag = ARKode(arkode_mem, Tf, y, &t, ARK_ONE_STEP); if (check_flag(&flag, "ARKode", 1)) return 1; /* "get" routines */ flag = ARKodeGetLastStep(arkode_mem, &olddt); if (check_flag(&flag, "ARKodeGetLastStep", 1)) return 1; flag = ARKodeGetCurrentStep(arkode_mem, &newdt); if (check_flag(&flag, "ARKodeGetCurrentStep", 1)) return 1; flag = ARKodeGetNumNonlinSolvIters(arkode_mem, &nni); if (check_flag(&flag, "ARKodeGetNumNonlinSolvIters", 1)) return 1; flag = ARKSpilsGetNumLinIters(arkode_mem, &nli); if (check_flag(&flag, "ARKSpilsGetNumLinIters", 1)) return 1; /* print current solution stats */ iout++; printf(" %4i %19.15e %19.15e %19.15e %li %2li %3li\n", iout, olddt, newdt, sqrt(N_VDotProd(y,y)/udata->N), udata->N, nni-nni_cur, nli); nni_cur = nni; nni_tot = nni; nli_tot += nli; /* output results and current mesh to disk */ data = N_VGetArrayPointer(y); for (i=0; i<udata->N; i++) fprintf(UFID," %.16e", data[i]); fprintf(UFID,"\n"); for (i=0; i<udata->N; i++) fprintf(XFID," %.16e", udata->x[i]); fprintf(XFID,"\n"); /* adapt the spatial mesh */ xnew = adapt_mesh(y, &Nnew, udata); if (check_flag(xnew, "ark_adapt", 0)) return 1; /* create N_Vector of new length */ y2 = N_VNew_Serial(Nnew); if (check_flag((void *) y2, "N_VNew_Serial", 0)) return 1; /* project solution onto new mesh */ flag = project(udata->N, udata->x, y, Nnew, xnew, y2); if (check_flag(&flag, "project", 1)) return 1; /* delete old vector, old mesh */ N_VDestroy_Serial(y); free(udata->x); /* swap x and xnew so that new mesh is stored in udata structure */ udata->x = xnew; xnew = NULL; udata->N = Nnew; /* store size of new mesh */ /* swap y and y2 so that y holds new solution */ yt = y; y = y2; y2 = yt; /* call ARKodeResize to notify integrator of change in mesh */ flag = ARKodeResize(arkode_mem, y, hscale, t, NULL, NULL); if (check_flag(&flag, "ARKodeResize", 1)) return 1; /* destroy and re-allocate linear solver memory */ flag = ARKPcg(arkode_mem, 0, udata->N); if (check_flag(&flag, "ARKPcg", 1)) return 1; flag = ARKSpilsSetJacTimesVecFn(arkode_mem, Jac); if (check_flag(&flag, "ARKSpilsSetJacTimesVecFn", 1)) return 1; } printf(" ----------------------------------------------------------------------------------------\n"); /* Free integrator memory */ ARKodeFree(&arkode_mem); /* print some final statistics */ printf(" Final solver statistics:\n"); printf(" Total number of time steps = %i\n", iout); printf(" Total nonlinear iterations = %li\n", nni_tot); printf(" Total linear iterations = %li\n\n", nli_tot); /* Clean up and return with successful completion */ fclose(UFID); fclose(XFID); N_VDestroy_Serial(y); /* Free vectors */ free(udata->x); /* Free user data */ free(udata); return 0; }
void SCL::initialize() { htree.set_communicator(MPI_COMM_WORLD); syncer.set_forest(htree); /// 设置数据交换器所依赖的森林 /**< 对数据迁移全局环境进行初始化 */ Migration::initialize(htree.communicator()); htree.readMesh(meshfile); ir_mesh = new ir_mesh_t(htree); ir_mesh->semiregularize(); ir_mesh->regularize(false); triangle_template_geometry.readData("triangle.tmp_geo"); triangle_coord_transform.readData("triangle.crd_trs"); triangle_unit_out_normal.readData("triangle.out_nrm"); triangle_template_dof.reinit(triangle_template_geometry); triangle_template_dof.readData("triangle.0.tmp_dof"); triangle_basis_function.reinit(triangle_template_dof); triangle_basis_function.readData("triangle.0.bas_fun"); twin_triangle_template_geometry.readData("twin_triangle.tmp_geo"); twin_triangle_coord_transform.readData("twin_triangle.crd_trs"); twin_triangle_unit_out_normal.readData("twin_triangle.out_nrm"); twin_triangle_template_dof.reinit(twin_triangle_template_geometry); twin_triangle_template_dof.readData("twin_triangle.0.tmp_dof"); twin_triangle_basis_function.reinit(twin_triangle_template_dof); twin_triangle_basis_function.readData("twin_triangle.0.bas_fun"); template_element.resize(2); template_element[0].reinit(triangle_template_geometry, triangle_template_dof, triangle_coord_transform, triangle_basis_function, triangle_unit_out_normal); template_element[1].reinit(twin_triangle_template_geometry, twin_triangle_template_dof, twin_triangle_coord_transform, twin_triangle_basis_function, twin_triangle_unit_out_normal); interval_template_geometry.readData("interval.tmp_geo"); interval_to2d_coord_transform.readData("interval.to2d.crd_trs"); dg_template_element.resize(1); dg_template_element[0].reinit(interval_template_geometry, interval_to2d_coord_transform); build_fe_space(); u_h = new fe_func_t(*fem_space); TimeFunction u(t, _u_0_); Operator::L2Project(u, *u_h, Operator::LOCAL_LEAST_SQUARE, 3); update_edge_cache(*u_h); for (u_int i = 0;i < 5;++ i) { adapt_mesh(); Operator::L2Project(u, *u_h, Operator::LOCAL_LEAST_SQUARE, 3); } }