SEXP predkda(SEXP s_test, SEXP s_learn, SEXP s_grouping, SEXP s_wf, SEXP s_bw, SEXP s_k, SEXP s_env) { const R_len_t p = ncols(s_test); // dimensionality const R_len_t N_learn = nrows(s_learn); // # training observations const R_len_t N_test = nrows(s_test); // # test observations const R_len_t K = nlevels(s_grouping); // # classes double *test = REAL(s_test); // pointer to test data set double *learn = REAL(s_learn); // pointer to training data set int *g = INTEGER(s_grouping); // pointer to class labels const int k = INTEGER(s_k)[0]; // number of nearest neighbors double *bw = REAL(s_bw); // bandwidth /*Rprintf("k %u\n", k); Rprintf("bw %f\n", *bw); */ SEXP s_posterior; // initialize posteriors PROTECT(s_posterior = allocMatrix(REALSXP, N_test, K)); double *posterior = REAL(s_posterior); SEXP s_dist; // initialize distances to test observation PROTECT(s_dist = allocVector(REALSXP, N_learn)); double *dist = REAL(s_dist); SEXP s_weights; // initialize weight vector PROTECT(s_weights = allocVector(REALSXP, N_learn)); double *weights = REAL(s_weights); int nas = 0; int i, j, l, n; // indices // select weight function typedef void (*wf_ptr_t) (double*, double*, int, double*, int);// *weights, *dist, N, *bw, k wf_ptr_t wf = NULL; if (isInteger(s_wf)) { const int wf_nr = INTEGER(s_wf)[0]; //Rprintf("wf_nr %u\n", wf_nr); wf_ptr_t wfs[] = {biweight1, cauchy1, cosine1, epanechnikov1, exponential1, gaussian1, optcosine1, rectangular1, triangular1, biweight2, cauchy2, cosine2, epanechnikov2, exponential2, gaussian2, optcosine2, rectangular2, triangular2, biweight3, cauchy3, cosine3, epanechnikov3, exponential3, gaussian3, optcosine3, rectangular3, triangular3, cauchy4, exponential4, gaussian4}; wf = wfs[wf_nr - 1]; } // loop over all test observations for(n = 0; n < N_test; n++) { // 0. check for NAs in test nas = 0; for (j = 0; j < p; j++) { nas += ISNA(test[n + N_test * j]); } if (nas > 0) { // NAs in n-th test observation warning("NAs in test observation %u", n+1); // set posterior to NA for (l = 0; l < K; l++) { posterior[n + N_test * l] = NA_REAL; } } else { // 1. calculate distances to n-th test observation for (i = 0; i < N_learn; i++) { dist[i] = 0; for (j = 0; j < p; j++) { dist[i] += pow(learn[i + N_learn * j] - test[n + N_test * j], 2); } dist[i] = sqrt(dist[i]); weights[i] = 0; // important because some weights are 0 //Rprintf("dist %f\n", dist[i]); } // 2. calculate observation weights if (isInteger(s_wf)) { // case 1: wf is integer // calculate weights by reading number and calling corresponding C function wf(weights, dist, N_learn, bw, k); } else if (isFunction(s_wf)) { // case 2: wf is R function // calculate weights by calling R function SEXP R_fcall; PROTECT(R_fcall = lang2(s_wf, R_NilValue)); //R_NilValue = NULL??? NILSXP = NULL SETCADR(R_fcall, s_dist); // SETCADR: cadr list = (car (cdr list)) weights = REAL(eval(R_fcall, s_env)); UNPROTECT(1); // R_fcall } /*for(i = 0; i < N_learn; i++) { Rprintf("weights %f\n", weights[i]); }*/ // 3. calculate posterior probabilities as class wise sum of weights for (l = 0; l < K; l++) { posterior[n + N_test * l] = 0; for (i = 0; i < N_learn; i++) { if (g[i] == l + 1) { posterior[n + N_test * l] += weights[i]; } } } } } // end loop over test observations // 4. set dimnames of s_posterior SEXP dimnames; PROTECT(dimnames = allocVector(VECSXP, 2)); SET_VECTOR_ELT(dimnames, 0, VECTOR_ELT(getAttrib(s_test, R_DimNamesSymbol), 0)); SET_VECTOR_ELT(dimnames, 1, getAttrib(s_grouping, R_LevelsSymbol)); setAttrib(s_posterior, R_DimNamesSymbol, dimnames); //void R_max_col (double* matrix, int* nr, int* nc, int* maxes) // maxes initialisieren //R_max_col (posterior, &N_test, &K, int* maxes) UNPROTECT(4); // dimnames, s_dist, s_weights, s_posterior return(s_posterior); }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("../domain.mesh", &mesh); // Perform uniform mesh refinement. mesh.refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst zero_disp("Bottom", 0.0); EssentialBCs bcs(&zero_disp); // Create x- and y- displacement space using the default H1 shapeset. H1Space u1_space(&mesh, &bcs, P_INIT); H1Space u2_space(&mesh, &bcs, P_INIT); info("ndof = %d.", Space::get_num_dofs(Hermes::vector<Space *>(&u1_space, &u2_space))); // Initialize the weak formulation. CustomWeakFormLinearElasticity wf(E, nu, rho*g1, "Top", f0, f1); // Testing n_dof and correctness of solution vector // for p_init = 1, 2, ..., 10 int success = 1; Solution xsln, ysln; for (int p_init = 1; p_init <= 6; p_init++) { printf("********* p_init = %d *********\n", p_init); u1_space.set_uniform_order(p_init); u2_space.set_uniform_order(p_init); int ndof = Space::get_num_dofs(Hermes::vector<Space *>(&u1_space, &u2_space)); info("ndof = %d", ndof); // Initialize the FE problem. DiscreteProblem dp(&wf, Hermes::vector<Space *>(&u1_space, &u2_space)); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof]; memset(coeff_vec, 0, ndof*sizeof(scalar)); // Perform Newton's iteration. bool verbose = true; bool jacobian_changed = true; if (!hermes2d.solve_newton(coeff_vec, &dp, solver, matrix, rhs, jacobian_changed, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution u1_sln, u2_sln; Solution::vector_to_solutions(coeff_vec, Hermes::vector<Space *>(&u1_space, &u2_space), Hermes::vector<Solution *>(&u1_sln, &u2_sln)); double sum = 0; for (int i=0; i < ndof; i++) sum += coeff_vec[i]; printf("coefficient sum = %g\n", sum); // Actual test. The values of 'sum' depend on the // current shapeset. If you change the shapeset, // you need to correct these numbers. if (p_init == 1 && fabs(sum - 1.41886e-05) > 1e-5) success = 0; if (p_init == 2 && fabs(sum - 1.60006e-05) > 1e-5) success = 0; if (p_init == 3 && fabs(sum - 1.60810e-05) > 1e-5) success = 0; if (p_init == 4 && fabs(sum - 1.61106e-05) > 1e-5) success = 0; if (p_init == 5 && fabs(sum - 1.61065e-05) > 1e-5) success = 0; if (p_init == 6 && fabs(sum - 1.61112e-05) > 1e-5) success = 0; delete [] coeff_vec; delete solver; delete matrix; delete rhs; } if (success == 1) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // load the mesh file Mesh mesh; H2DReader mloader; mloader.load("sample.mesh", &mesh); // initialize the shapeset and the cache H1Shapeset shapeset; PrecalcShapeset pss(&shapeset); // create the x displacement space H1Space xdisp(&mesh, &shapeset); xdisp.set_bc_types(bc_types); xdisp.set_bc_values(bc_values); // create the y displacement space H1Space ydisp(&mesh, &shapeset); ydisp.set_bc_types(bc_types); ydisp.set_bc_values(bc_values); // initialize the weak formulation WeakForm wf(2); wf.add_biform(0, 0, callback(bilinear_form_0_0), SYM); // Note that only one symmetric part is wf.add_biform(0, 1, callback(bilinear_form_0_1), SYM); // added in the case of symmetric bilinear wf.add_biform(1, 1, callback(bilinear_form_1_1), SYM); // forms. wf.add_liform_surf(0, callback(linear_form_surf_0), 3); wf.add_liform_surf(1, callback(linear_form_surf_1), 3); // initialize the linear system and solver UmfpackSolver umfpack; LinSystem sys(&wf, &umfpack); sys.set_spaces(2, &xdisp, &ydisp); sys.set_pss(1, &pss); // testing n_dof and correctness of solution vector // for p_init = 1, 2, ..., 10 int success = 1; for (int p_init = 1; p_init <= 10; p_init++) { printf("********* p_init = %d *********\n", p_init); xdisp.set_uniform_order(p_init); int ndofs = xdisp.assign_dofs(0); ydisp.set_uniform_order(p_init); ndofs += ydisp.assign_dofs(ndofs); // assemble the stiffness matrix and solve the system Solution xsln, ysln; sys.assemble(); sys.solve(2, &xsln, &ysln); scalar *sol_vector; int n_dof; sys.get_solution_vector(sol_vector, n_dof); printf("n_dof = %d\n", n_dof); double sum = 0; for (int i=0; i < n_dof; i++) sum += sol_vector[i]; printf("coefficient sum = %g\n", sum); // Actual test. The values of 'sum' depend on the // current shapeset. If you change the shapeset, // you need to correct these numbers. if (p_init == 1 && fabs(sum - 3.50185e-06) > 1e-3) success = 0; if (p_init == 2 && fabs(sum - 4.34916e-06) > 1e-3) success = 0; if (p_init == 3 && fabs(sum - 4.60553e-06) > 1e-3) success = 0; if (p_init == 4 && fabs(sum - 4.65616e-06) > 1e-3) success = 0; if (p_init == 5 && fabs(sum - 4.62893e-06) > 1e-3) success = 0; if (p_init == 6 && fabs(sum - 4.64336e-06) > 1e-3) success = 0; if (p_init == 7 && fabs(sum - 4.63724e-06) > 1e-3) success = 0; if (p_init == 8 && fabs(sum - 4.64491e-06) > 1e-3) success = 0; if (p_init == 9 && fabs(sum - 4.64582e-06) > 1e-3) success = 0; if (p_init == 10 && fabs(sum - 4.65028e-06) > 1e-3) success = 0; } #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 if (success == 1) { printf("Success!\n"); return ERROR_SUCCESS; } else { printf("Failure!\n"); return ERROR_FAILURE; } }
int main() { // Create space. // Transform input data to the format used by the "Space" constructor. SpaceData *md = new SpaceData(verbose); Space* space = new Space(md->N_macroel, md->interfaces, md->poly_orders, md->material_markers, md->subdivisions, N_GRP, N_SLN); delete md; // Enumerate basis functions, info for user. info("N_dof = %d", Space::get_num_dofs(space)); // Plot the space. space->plot("space.gp"); // Initial approximation of the dominant eigenvalue. double K_EFF = 1.0; // Initial approximation of the dominant eigenvector. double init_val = 1.0; for (int g = 0; g < N_GRP; g++) { set_vertex_dofs_constant(space, init_val, g); space->set_bc_right_dirichlet(g, flux_right_surf[g]); } // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, jacobian_fuel_0_0, NULL, fuel); wf.add_matrix_form(0, 0, jacobian_water_0_0, NULL, water); wf.add_matrix_form(0, 1, jacobian_fuel_0_1, NULL, fuel); wf.add_matrix_form(0, 1, jacobian_water_0_1, NULL, water); wf.add_matrix_form(1, 0, jacobian_fuel_1_0, NULL, fuel); wf.add_matrix_form(1, 0, jacobian_water_1_0, NULL, water); wf.add_matrix_form(1, 1, jacobian_fuel_1_1, NULL, fuel); wf.add_matrix_form(1, 1, jacobian_water_1_1, NULL, water); wf.add_vector_form(0, residual_fuel_0, NULL, fuel); wf.add_vector_form(0, residual_water_0, NULL, water); wf.add_vector_form(1, residual_fuel_1, NULL, fuel); wf.add_vector_form(1, residual_water_1, NULL, water); wf.add_vector_form_surf(0, residual_surf_left_0, BOUNDARY_LEFT); wf.add_vector_form_surf(1, residual_surf_left_1, BOUNDARY_LEFT); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear); Linearizer l(space); char solution_file[32]; // Source iteration int i; int current_solution = 0, previous_solution = 1; double K_EFF_old; for (i = 0; i < Max_SI; i++) { // Plot the critical (i.e. steady-state) flux in the actual iteration. sprintf(solution_file, "solution_%d.gp", i); l.plot_solution(solution_file); // Store the previous solution (used at the right-hand side). for (int g = 0; g < N_GRP; g++) copy_dofs(current_solution, previous_solution, space, g); // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(space)]; get_coeff_vector(space, coeff_vec); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp->assemble(matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec, space); it++; } // Cleanup. delete matrix; delete rhs; delete solver; delete [] coeff_vec; // Update the eigenvalue. K_EFF_old = K_EFF; K_EFF = calc_total_reaction_rate(space, nSf, 0., 40.); // Convergence test. if (fabs(K_EFF - K_EFF_old)/K_EFF < TOL_SI) break; // Normalize total neutron flux to one fission neutron. multiply_dofs_with_constant(space, 1./K_EFF, current_solution); if (verbose) info("K_EFF_%d = %.8f", i+1, K_EFF); } // Print the converged eigenvalue. info("K_EFF = %.8f, err= %.8f%%", K_EFF, 100*(K_EFF-1)); // Plot the converged critical neutron flux. sprintf(solution_file, "solution.gp"); l.plot_solution(solution_file); // Comparison with analytical results (see the reference above). double flux[N_GRP], J[N_GRP], R; get_solution_at_point(space, 0.0, flux, J); R = flux[0]/flux[1]; info("phi_fast/phi_therm at x=0 : %.4f, err = %.2f%%", R, 100*(R-2.5332)/2.5332); get_solution_at_point(space, 40.0, flux, J); R = flux[0]/flux[1]; info("phi_fast/phi_therm at x=40 : %.4f, err = %.2f%%", R, 100*(R-1.5162)/1.5162); info("Done."); return 0; }
void GameUpdateDraw( NimblePixMap& map, NimbleRequest request ) { #if WRITING_DOCUMENTATION new(&TheMap) NimblePixMap( map ); #endif /* WRITING_DOCUMENTATION */ WavefieldRect = NimbleRect(PanelWidth,map.height()/2,map.width(),map.height()); NimblePixMap subsurface(map,WavefieldRect); NimblePixMap seismogramClip( map,NimbleRect(PanelWidth,0,map.width(),map.height()/2) ); if( request & NimbleUpdate ) { ShowGeology.update(); ShowSeismic.update(); } const NimbleRequest pausedRequest = IsPaused ? request-NimbleUpdate : request; SeismogramUpdateDraw( seismogramClip, pausedRequest&NimbleUpdate, TheColorFunc, IsAutoGainOn ); WavefieldFunctor wf(subsurface, pausedRequest); SeismogramFunctor sf( seismogramClip, pausedRequest&NimbleDraw ); ReservoirFunctor rf( pausedRequest ); #if PARALLEL tbb::parallel_invoke( wf, sf, rf ); #else wf(); sf(); rf(); #endif if( pausedRequest & NimbleUpdate ) { DrillBit.update(); UpdateDuckAndRig(); } if( request & NimbleDraw ) { ClickableSetEnd = ClickableSet; const int wavefieldWidth = map.width()-PanelWidth; Assert(wavefieldWidth%4==0); const int wavefieldHeight = map.height()/2; ReservoirDrawHoles( subsurface ); if( DrillY>0 ) DrillBit.drawOn( subsurface, RigX-DrillBit.width()/2, DrillY-5 ); if( ShowReservoir ) ReservoirDraw( subsurface ); NimblePixMap spriteClip( map, NimbleRect( PanelWidth, 0, map.width(), map.height() ));\ NimblePixel greenPixel = map.pixel( NimbleColor( 0, NimbleColor::FULL, 0 )); NimblePixel redPixel = map.pixel( NimbleColor( NimbleColor::FULL, 0, 0 )); const int lineHeight = map.height()/2-1; if( CultureBeginX<CultureEndX ) { spriteClip.draw( NimbleRect( 0, lineHeight, CultureBeginX, lineHeight+1 ), greenPixel ); spriteClip.draw( NimbleRect( CultureBeginX, lineHeight-1, CultureEndX, lineHeight+2 ), redPixel ); spriteClip.draw( NimbleRect( CultureEndX, lineHeight, spriteClip.width(), lineHeight+1 ), greenPixel ); Culture.drawOn( spriteClip, CultureBeginX+(CultureEndX-CultureBeginX)/2-Culture.width()/2, map.height()/2-Culture.height() ); } else { spriteClip.draw( NimbleRect( 0, lineHeight, spriteClip.width(), lineHeight+1 ), greenPixel ); } OilRig->drawOn( spriteClip, RigX-OilRig->width()/2, OilRigVerticalOffset ); if( DuckGoingLeft ) DuckLeft.drawOn( spriteClip, DuckX-50, map.height()/2-DuckLeft.height()+12 ); else DuckRight.drawOn( spriteClip, DuckX-(DuckRight.width()-50), map.height()/2-DuckLeft.height()+12 ); NimblePixMap panelClip( map, NimbleRect( 0, 0, PanelWidth, map.height() )); PanelBackground.drawOn( panelClip ); int cashMeterY = map.height()- 50 -CashMeter.height(); int levelMeterY = cashMeterY - 10 - LevelMeter.height(); // The Min is there so that if there is room, the green line artistically lines up // with the top of the fluid meters. int fluidMeterY = Min(levelMeterY - 10 - WaterMeter.height(), map.height()/2 ); if( ScoreState.isDisplayingScore() ) { LevelMeter.drawOn( map, PanelWidth/2-LevelMeter.width()/2, levelMeterY ); CashMeter.drawOn( map, PanelWidth/2-CashMeter.width()/2, cashMeterY ); } int meterMarginX = (PanelWidth-WaterMeter.width()-OilMeter.width()-GasMeter.width())/4; WaterMeter.drawOn( map, meterMarginX, fluidMeterY ); OilMeter.drawOn( map, PanelWidth/2-OilMeter.width()/2, fluidMeterY ); GasMeter.drawOn( map, PanelWidth-meterMarginX-GasMeter.width(), fluidMeterY ); if( VisibleDialog ) { if( VisibleDialog==&TheAboutTheAuthorDialog || VisibleDialog==&TheLevelContinueDialog ) // Center it on screen VisibleDialog->drawOn( map, map.width()/2-VisibleDialog->width()/2, map.height()/2-VisibleDialog->height()/2 ); else if( VisibleDialog==&TheKeyboardHelpDialog ) // Put in upper right corner VisibleDialog->drawOn( map, map.width()*.95f-VisibleDialog->width(), map.height()*.05f ); else // Put it in upper left portion of seismogram VisibleDialog->drawOn( map, PanelWidth+24, 24 ); } int tabTop1 = 50; int tabTop2 = tabTop1+2*TheFont.height(); int tabLeft1 = PanelWidth/8; int tabLeft2 = PanelWidth*5/8; int airGunTop = tabTop2+2*TheFont.height();; AirgunMeter.drawOn( map, PanelWidth/2-AirgunMeter.width()/2, airGunTop ); if( ShowFrameRate ) { FrameRateMeter.setValue( EstimateFrameRate() ); FrameRateMeter.drawOn( map, PanelWidth/2-FrameRateMeter.width()/2, fluidMeterY-FrameRateMeter.height()-15 ); } const int tabSpacing = PanelWidth/4; DrawClickable( TheFileMenu, map, tabLeft1, tabTop1 ); DrawClickable( TheHelpMenu, map, tabLeft2, tabTop1 ); // The "isTabbed" tests below do some ad-hoc occlusion testing. if( TheFileMenu.isTabbed() ) DrawClickable( TheModelMenu, map, tabLeft1, tabTop2 ); if( TheFileMenu.isTabbed() && TheHelpMenu.isTabbed() ) DrawClickable( TheViewMenu, map, tabLeft2, tabTop2 ); } ScoreState.update(); }
int main(int argc, char* argv[]) { // load the mesh file Mesh mesh; H2DReader mloader; mloader.load("domain-quad.mesh", &mesh); // unstructured triangular mesh available in domain-tri.mesh // a-priori mesh refinements mesh.refine_all_elements(); mesh.refine_towards_boundary(5, 4, false); mesh.refine_towards_boundary(1, 4); mesh.refine_towards_boundary(3, 4); // display the mesh //MeshView mview("Navier-Stokes Example - Mesh", 100, 100, 1100, 400); //mview.show(&mesh); //mview.wait_for_keypress(); // initialize the shapesets and the cache H1Shapeset shapeset_h1; PrecalcShapeset pss_h1(&shapeset_h1); L2Shapeset shapeset_l2; PrecalcShapeset pss_l2(&shapeset_l2); // H1 spaces for velocities and L2 for pressure H1Space xvel(&mesh, &shapeset_h1); H1Space yvel(&mesh, &shapeset_h1); L2Space press(&mesh, &shapeset_l2); // initialize boundary conditions xvel.set_bc_types(xvel_bc_type); xvel.set_bc_values(xvel_bc_value); yvel.set_bc_types(yvel_bc_type); press.set_bc_types(press_bc_type); // set velocity and pressure polynomial degrees xvel.set_uniform_order(P_INIT_VEL); yvel.set_uniform_order(P_INIT_VEL); press.set_uniform_order(P_INIT_PRESSURE); // assign degrees of freedom int ndofs = 0; ndofs += xvel.assign_dofs(ndofs); ndofs += yvel.assign_dofs(ndofs); ndofs += press.assign_dofs(ndofs); // initial condition: xprev and yprev are zero Solution xprev, yprev; xprev.set_zero(&mesh); yprev.set_zero(&mesh); // set up weak formulation WeakForm wf(3); wf.add_biform(0, 0, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(0, 0, callback(bilinear_form_unsym_0_0_1_1), UNSYM, ANY, 2, &xprev, &yprev); wf.add_biform(1, 1, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(1, 1, callback(bilinear_form_unsym_0_0_1_1), UNSYM, ANY, 2, &xprev, &yprev); wf.add_biform(0, 2, callback(bilinear_form_unsym_0_2), ANTISYM); wf.add_biform(1, 2, callback(bilinear_form_unsym_1_2), ANTISYM); wf.add_liform(0, callback(linear_form), ANY, 1, &xprev); wf.add_liform(1, callback(linear_form), ANY, 1, &yprev); // visualization VectorView vview("velocity [m/s]", 0, 0, 1500, 470); ScalarView pview("pressure [Pa]", 0, 530, 1500, 470); vview.set_min_max_range(0, 1.6); vview.fix_scale_width(80); pview.show_mesh(false); pview.fix_scale_width(80); // fixing scale width (for nicer videos). Note: creation of videos is // discussed in a separate example vview.fix_scale_width(5); pview.fix_scale_width(5); // set up the linear system UmfpackSolver umfpack; LinSystem sys(&wf, &umfpack); sys.set_spaces(3, &xvel, &yvel, &press); sys.set_pss(3, &pss_h1, &pss_h1, &pss_l2); // main loop char title[100]; int num_time_steps = FINAL_TIME / TAU; for (int i = 1; i <= num_time_steps; i++) { TIME += TAU; info("\n---- Time step %d, time = %g -----------------------------------", i, TIME); // this is needed to update the time-dependent boundary conditions ndofs = 0; ndofs += xvel.assign_dofs(ndofs); ndofs += yvel.assign_dofs(ndofs); ndofs += press.assign_dofs(ndofs); // assemble and solve Solution xsln, ysln, psln; sys.assemble(); sys.solve(3, &xsln, &ysln, &psln); // visualization sprintf(title, "Velocity, time %g", TIME); vview.set_title(title); vview.show(&xprev, &yprev, EPS_LOW); sprintf(title, "Pressure, time %g", TIME); pview.set_title(title); pview.show(&psln); xprev = xsln; yprev = ysln; } // wait for keyboard or mouse input View::wait("Waiting for all views to be closed."); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("sample.mesh", &mesh); // Perform uniform mesh refinement. mesh.refine_all_elements(); // Create x- and y- displacement space using the default H1 shapeset. H1Space u_space(&mesh, bc_types, essential_bc_values, P_INIT); H1Space v_space(&mesh, bc_types, essential_bc_values, P_INIT); info("ndof = %d.", Space::get_num_dofs(Tuple<Space *>(&u_space, &v_space))); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, callback(bilinear_form_0_0), HERMES_SYM); // Note that only one symmetric part is wf.add_matrix_form(0, 1, callback(bilinear_form_0_1), HERMES_SYM); // added in the case of symmetric bilinear wf.add_matrix_form(1, 1, callback(bilinear_form_1_1), HERMES_SYM); // forms. wf.add_vector_form_surf(0, callback(linear_form_surf_0), GAMMA_3_BDY); wf.add_vector_form_surf(1, callback(linear_form_surf_1), GAMMA_3_BDY); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, Tuple<Space *>(&u_space, &v_space), is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the solutions. Solution u_sln, v_sln; // Assemble the stiffness matrix and right-hand side vector. info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); // Solve the linear system and if successful, obtain the solutions. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), Tuple<Space *>(&u_space, &v_space), Tuple<Solution *>(&u_sln, &v_sln)); else error ("Matrix solver failed.\n"); // Visualize the solution. ScalarView view("Von Mises stress [Pa]", new WinGeom(0, 0, 800, 400)); VonMisesFilter stress(Tuple<MeshFunction *>(&u_sln, &v_sln), lambda, mu); view.show_mesh(false); view.show(&stress, HERMES_EPS_HIGH, H2D_FN_VAL_0, &u_sln, &v_sln, 1.5e5); // Wait for the view to be closed. View::wait(); // Clean up. delete solver; delete matrix; delete rhs; return 0; }
int main() { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Create coarse mesh, set Dirichlet BC, enumerate basis functions. Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ, NEQ); // Enumerate basis functions, info for user. int ndof = Space::get_num_dofs(space); info("ndof: %d", ndof); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, jacobian_0_0); wf.add_matrix_form(0, 1, jacobian_0_1); wf.add_matrix_form(1, 0, jacobian_1_0); wf.add_matrix_form(1, 1, jacobian_1_1); wf.add_vector_form(0, residual_0); wf.add_vector_form(1, residual_1); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp_coarse = new DiscreteProblem(&wf, space, is_linear); // Set zero initial condition. double *coeff_vec_coarse = new double[Space::get_num_dofs(space)]; set_zero(coeff_vec_coarse, Space::get_num_dofs(space)); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix_coarse = create_matrix(matrix_solver); Vector* rhs_coarse = create_vector(matrix_solver); Solver* solver_coarse = create_linear_solver(matrix_solver, matrix_coarse, rhs_coarse); // Newton's loop on coarse mesh. int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof_coarse = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp_coarse->assemble(coeff_vec_coarse, matrix_coarse, rhs_coarse); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs_coarse); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced here because sometimes the initial // residual on fine mesh is already too small. if(res_l2_norm < NEWTON_TOL_COARSE && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i = 0; i < ndof_coarse; i++) rhs_coarse->set(i, -rhs_coarse->get(i)); // Solve the linear system. if(!solver_coarse->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof_coarse; i++) coeff_vec_coarse[i] += solver_coarse->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); it++; } // Cleanup. delete matrix_coarse; delete rhs_coarse; delete solver_coarse; delete [] coeff_vec_coarse; delete dp_coarse; // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est; SimpleGraph graph_dof_exact, graph_cpu_exact; // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh, create reference space on it, // and transfer the coarse mesh solution there. Space* ref_space = construct_refined_space(space); // Initialize the FE problem. bool is_linear = false; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(ref_space)]; get_coeff_vector(ref_space, coeff_vec); // Newton's loop on the fine mesh. info("Solving on fine mesh:"); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(ref_space); // Assemble the Jacobian matrix and residual vector. dp->assemble(coeff_vec, matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(ref_space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced here because sometimes the initial // residual on fine mesh is already too small. if(res_l2_norm < NEWTON_TOL_REF && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); it++; } // Starting with second adaptivity step, obtain new coarse // mesh solution via projecting the fine mesh solution. if(as > 1) { info("Projecting the fine mesh solution onto the coarse mesh."); // Project the fine mesh solution (defined on space_ref) onto the coarse mesh (defined on space). OGProjection::project_global(space, ref_space, matrix_solver); } // Calculate element errors and total error estimate. info("Calculating error estimate."); double err_est_array[MAX_ELEM_NUM]; double err_est_rel = calc_err_est(NORM, space, ref_space, err_est_array) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space::get_num_dofs(space), Space::get_num_dofs(ref_space), err_est_rel); // Time measurement. cpu_time.tick(); // If exact solution available, also calculate exact error. if (EXACT_SOL_PROVIDED) { // Calculate element errors wrt. exact solution. double err_exact_rel = calc_err_exact(NORM, space, exact_sol, NEQ, A, B) * 100; // Info for user. info("Relative error (exact) = %g %%", err_exact_rel); // Add entry to DOF and CPU convergence graphs. graph_dof_exact.add_values(Space::get_num_dofs(space), err_exact_rel); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel); } // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space::get_num_dofs(space), err_est_rel); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel); // If err_est_rel too large, adapt the mesh. if (err_est_rel < NEWTON_TOL_REF) done = true; else { info("Adapting the coarse mesh."); adapt(NORM, ADAPT_TYPE, THRESHOLD, err_est_array, space, ref_space); } as++; // Plot meshes, results, and errors. adapt_plotting(space, ref_space, NORM, EXACT_SOL_PROVIDED, exact_sol); // Cleanup. delete solver; delete matrix; delete rhs; delete ref_space; delete dp; delete [] coeff_vec; } while (done == false); info("Total running time: %g s", cpu_time.accumulated()); // Save convergence graphs. graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.save("conv_cpu_est.dat"); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.save("conv_cpu_exact.dat"); return 0; }
int main(int argc, char* argv[]) { // Load the mesh Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // initial uniform mesh refinement for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize the shapeset and the cache H1Shapeset shapeset; PrecalcShapeset pss(&shapeset); // Create finite element space H1Space space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_bc_values(bc_values); space.set_uniform_order(P_INIT); // Enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, bilinear_form_1, bilinear_form_ord, SYM, 1); wf.add_biform(0, 0, bilinear_form_2, bilinear_form_ord, SYM, 2); wf.add_biform(0, 0, bilinear_form_3, bilinear_form_ord, SYM, 3); wf.add_biform(0, 0, bilinear_form_4, bilinear_form_ord, SYM, 4); wf.add_biform(0, 0, bilinear_form_5, bilinear_form_ord, SYM, 5); wf.add_liform(0, linear_form_1, linear_form_ord, 1); wf.add_liform(0, linear_form_3, linear_form_ord, 3); // Visualize solution and mesh ScalarView sview("Coarse solution", 0, 100, 798, 700); OrderView oview("Polynomial orders", 800, 100, 798, 700); // Matrix solver UmfpackSolver solver; // DOF and CPU convergence graphs SimpleGraph graph_dof, graph_cpu; // prepare selector RefinementSelectors::H1NonUniformHP selector(ISO_ONLY, ADAPT_TYPE, 1.0, H2DRS_DEFAULT_ORDER, &shapeset); // Adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // Time measurement begin_time(); // Solve the coarse mesh problem LinSystem ls(&wf, &solver); ls.set_spaces(1, &space); ls.set_pss(1, &pss); ls.assemble(); ls.solve(1, &sln_coarse); // Time measurement cpu += end_time(); // View the solution and mesh sview.show(&sln_coarse); oview.show(&space); // Time measurement begin_time(); // Solve the fine mesh problem RefSystem rs(&ls); rs.assemble(); rs.solve(1, &sln_fine); // Calculate error estimate wrt. fine mesh solution H1AdaptHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Estimate of error: %g%%", err_est); // add entry to DOF convergence graph graph_dof.add_values(space.get_num_dofs(), err_est); graph_dof.save("conv_dof.dat"); // add entry to CPU convergence graph graph_cpu.add_values(cpu, err_est); graph_cpu.save("conv_cpu.dat"); // If err_est too large, adapt the mesh if (err_est < ERR_STOP) done = true; else { hp.adapt(THRESHOLD, STRATEGY, &selector, MESH_REGULARITY); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // Time measurement cpu += end_time(); } while (done == false); verbose("Total running time: %g sec", cpu); // Show the fine solution - this is the final result sview.set_title("Final solution"); sview.show(&sln_fine); oview.set_title("Final orders"); oview.show(&space); // Wait for keyboard or mouse input View::wait(); return 0; }
int main(int argc, char* argv[]) { #ifdef WITH_PARALUTION HermesCommonApi.set_integral_param_value(matrixSolverType, SOLVER_PARALUTION_ITERATIVE); // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("square.mesh", mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh->refine_all_elements(); mesh->refine_towards_boundary("Bdy", INIT_BDY_REF_NUM); // Initialize boundary conditions. CustomEssentialBCNonConst bc_essential("Bdy"); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); int ndof = space->get_num_dofs(); // Initialize the weak formulation CustomNonlinearity lambda(alpha); Hermes2DFunction<double> src(-heat_src); DefaultWeakFormPoisson<double> wf(HERMES_ANY, &lambda, &src); #ifdef SHOW_OUTPUT ScalarView s_view("Solution"); #endif double* coeff_vec = new double[ndof]; MeshFunctionSharedPtr<double> init_sln(new CustomInitialCondition(mesh)); OGProjection<double> ogProjection; ogProjection.project_global(space, init_sln, coeff_vec); MeshFunctionSharedPtr<double> sln(new Solution<double>); // Testing is happening here. Hermes::vector<int> numbers_of_nonlinear_iterations; Hermes::vector<int> numbers_of_linear_iterations_in_last_nonlinear_step; // Iterative - original initial guess. HermesCommonApi.set_integral_param_value(matrixSolverType, SOLVER_PARALUTION_ITERATIVE); { // Initialize Newton solver. NewtonSolver<double> newton(&wf, space); newton.set_tolerance(NEWTON_TOL, ResidualNormAbsolute); newton.set_max_steps_with_reused_jacobian(0); newton.get_linear_matrix_solver()->as_IterSolver()->set_solver_type(Solvers::GMRES); newton.get_linear_matrix_solver()->as_IterSolver()->set_tolerance(1e-5); // Perform Newton's iteration. newton.solve(coeff_vec); numbers_of_nonlinear_iterations.push_back(newton.get_num_iters()); numbers_of_linear_iterations_in_last_nonlinear_step.push_back(newton.get_linear_matrix_solver()->as_IterSolver()->get_num_iters()); // Translate the resulting coefficient vector into a Solution. Solution<double>::vector_to_solution(newton.get_sln_vector(), space, sln); #ifdef SHOW_OUTPUT s_view.show(sln); #endif } // Iterative - "exact" initial guess. { // Initialize Newton solver. NewtonSolver<double> newton(&wf, space); newton.set_tolerance(NEWTON_TOL, ResidualNormAbsolute); newton.get_linear_matrix_solver()->as_IterSolver()->set_solver_type(Solvers::GMRES); // Perform Newton's iteration. newton.solve(sln); numbers_of_nonlinear_iterations.push_back(newton.get_num_iters()); numbers_of_linear_iterations_in_last_nonlinear_step.push_back(newton.get_linear_matrix_solver()->as_IterSolver()->get_num_iters()); // Translate the resulting coefficient vector into a Solution. Solution<double>::vector_to_solution(newton.get_sln_vector(), space, sln); #ifdef SHOW_OUTPUT s_view.show(sln); #endif } bool success = true; success = Hermes::Testing::test_value(numbers_of_nonlinear_iterations[0], 10, "Nonlinear iterations[0]", 1) && success; success = Hermes::Testing::test_value(numbers_of_nonlinear_iterations[1], 1, "Nonlinear iterations[1]", 1) && success; success = Hermes::Testing::test_value(numbers_of_linear_iterations_in_last_nonlinear_step[0], 5, "Linear iterations[0]", 1) && success; success = Hermes::Testing::test_value(numbers_of_linear_iterations_in_last_nonlinear_step[1], 7, "Linear iterations[1]", 1) && success; if(success == true) { printf("Success!\n"); return 0; } else { printf("Failure!\n"); return -1; } #endif return 0; }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; H2DReader mloader; mloader.load("square_quad.mesh", &mesh); // mloader.load("square_tri.mesh", &mesh); for (int i=0; i<INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(2, INIT_REF_NUM_BDY); // initialize the shapeset and the cache H1Shapeset shapeset; PrecalcShapeset pss(&shapeset); // create finite element space H1Space space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_bc_values(bc_values); space.set_uniform_order(P_INIT); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form)); if (STABILIZATION_ON == true) { wf.add_biform(0, 0, bilinear_form_stabilization, bilinear_form_stabilization_order); } if (SHOCK_CAPTURING_ON == true) { wf.add_biform(0, 0, bilinear_form_shock_capturing, bilinear_form_shock_capturing_order); } // visualize solution and mesh OrderView oview("Coarse mesh", 0, 0, 500, 400); ScalarView sview("Coarse mesh solution", 510, 0, 500, 400); ScalarView sview2("Fine mesh solution", 1020, 0, 500, 400); // matrix solver UmfpackSolver solver; // DOF convergence graph SimpleGraph graph_dof_est, graph_cpu_est; // prepare selector RefinementSelectors::H1NonUniformHP selector(ISO_ONLY, ADAPT_TYPE, CONV_EXP, H2DRS_DEFAULT_ORDER, &shapeset); // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem ls(&wf, &solver); ls.set_spaces(1, &space); ls.set_pss(1, &pss); ls.assemble(); ls.solve(1, &sln_coarse); // solve the fine mesh problem int p_increase; if (ADAPT_TYPE == RefinementSelectors::H2DRS_CAND_HP) p_increase = 1; else p_increase = 0; RefSystem rs(&ls, p_increase, 1); // the '1' is for one level of global refinement in space rs.assemble(); rs.solve(1, &sln_fine); // time measurement cpu += end_time(); // show fine mesh solution // view the solution and mesh oview.show(&space); sview.show(&sln_coarse); sview2.show(&sln_fine); //sview.wait_for_keypress(); // time measurement begin_time(); // calculate error estimate wrt. fine mesh solution H1AdaptHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Estimate of error: %g%%", err_est); // add entries to DOF and CPU convergence graphs graph_dof_est.add_values(space.get_num_dofs(), err_est); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu, err_est); graph_cpu_est.save("conv_cpu_est.dat"); // if err_est too large, adapt the mesh if (err_est < ERR_STOP) done = true; else { hp.adapt(THRESHOLD, STRATEGY, &selector, MESH_REGULARITY); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); } while (done == false); verbose("Total running time: %g sec", cpu); // show the fine solution - this is the final result sview.set_title("Final solution"); sview.show(&sln_fine); // wait for keyboard or mouse input View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh basemesh; H2DReader mloader; mloader.load("domain.mesh", &basemesh); // Initialize the meshes. Mesh mesh_flow, mesh_concentration; mesh_flow.copy(&basemesh); mesh_concentration.copy(&basemesh); for(unsigned int i = 0; i < INIT_REF_NUM_CONCENTRATION; i++) mesh_concentration.refine_all_elements(0); mesh_concentration.refine_towards_boundary(BDY_DIRICHLET_CONCENTRATION, INIT_REF_NUM_CONCENTRATION_BDY); for(unsigned int i = 0; i < INIT_REF_NUM_FLOW; i++) mesh_flow.refine_all_elements(); // Initialize boundary condition types and spaces with default shapesets. // For the concentration. EssentialBCs bcs_concentration; bcs_concentration.add_boundary_condition(new DefaultEssentialBCConst(BDY_DIRICHLET_CONCENTRATION, CONCENTRATION_EXT)); L2Space space_rho(&mesh_flow, P_INIT_FLOW); L2Space space_rho_v_x(&mesh_flow, P_INIT_FLOW); L2Space space_rho_v_y(&mesh_flow, P_INIT_FLOW); L2Space space_e(&mesh_flow, P_INIT_FLOW); // Space for concentration. H1Space space_c(&mesh_concentration, &bcs_concentration, P_INIT_CONCENTRATION); int ndof = Space::get_num_dofs(Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c)); info("ndof: %d", ndof); // Initialize solutions, set initial conditions. InitialSolutionEulerDensity prev_rho(&mesh_flow, RHO_EXT); InitialSolutionEulerDensityVelX prev_rho_v_x(&mesh_flow, RHO_EXT * V1_EXT); InitialSolutionEulerDensityVelY prev_rho_v_y(&mesh_flow, RHO_EXT * V2_EXT); InitialSolutionEulerDensityEnergy prev_e(&mesh_flow, QuantityCalculator:: calc_energy(RHO_EXT, RHO_EXT * V1_EXT, RHO_EXT * V2_EXT, P_EXT, KAPPA)); InitialSolutionConcentration prev_c(&mesh_concentration, 0.0); // Numerical flux. OsherSolomonNumericalFlux num_flux(KAPPA); // Initialize weak formulation. EulerEquationsWeakFormExplicitCoupled wf(&num_flux, KAPPA, RHO_EXT, V1_EXT, V2_EXT, P_EXT, BDY_SOLID_WALL, BDY_INLET, BDY_OUTLET, BDY_NATURAL_CONCENTRATION, &prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, &prev_c, EPSILON); wf.set_time_step(time_step); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c), is_linear); // If the FE problem is in fact a FV problem. //if(P_INIT == 0) dp.set_fvm(); // Filters for visualization of Mach number, pressure and entropy. MachNumberFilter Mach_number(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); PressureFilter pressure(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); EntropyFilter entropy(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA, RHO_EXT, P_EXT); /* ScalarView pressure_view("Pressure", new WinGeom(0, 0, 600, 300)); ScalarView Mach_number_view("Mach number", new WinGeom(700, 0, 600, 300)); ScalarView entropy_production_view("Entropy estimate", new WinGeom(0, 400, 600, 300)); ScalarView s5("Concentration", new WinGeom(700, 400, 600, 300)); */ ScalarView s1("1", new WinGeom(0, 0, 600, 300)); ScalarView s2("2", new WinGeom(700, 0, 600, 300)); ScalarView s3("3", new WinGeom(0, 400, 600, 300)); ScalarView s4("4", new WinGeom(700, 400, 600, 300)); ScalarView s5("Concentration", new WinGeom(350, 200, 600, 300)); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Set up CFL calculation class. CFLCalculation CFL(CFL_NUMBER, KAPPA); // Set up Advection-Diffusion-Equation stability calculation class. ADEStabilityCalculation ADES(ADVECTION_STABILITY_CONSTANT, DIFFUSION_STABILITY_CONSTANT, EPSILON); int iteration = 0; double t = 0; for(t = 0.0; t < 83.0; t += time_step) { info("---- Time step %d, time %3.5f.", iteration++, t); // Set the current time step. wf.set_time_step(time_step); bool rhs_only = (iteration == 1 ? false : true); // Assemble stiffness matrix and rhs or just rhs. if (rhs_only == false) { info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); } else { info("Assembling the right-hand side vector (only)."); dp.assemble(NULL, rhs); } // Solve the matrix problem. info("Solving the matrix problem."); scalar* solution_vector = NULL; if(solver->solve()) { solution_vector = solver->get_solution(); Solution::vector_to_solutions(solution_vector, Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, &prev_c)); } else error ("Matrix solver failed.\n"); if(SHOCK_CAPTURING) { DiscontinuityDetector discontinuity_detector(Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); std::set<int> discontinuous_elements = discontinuity_detector.get_discontinuous_element_ids(DISCONTINUITY_DETECTOR_PARAM); FluxLimiter flux_limiter(solution_vector, Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); flux_limiter.limit_according_to_detector(discontinuous_elements); } util_time_step = time_step; if((iteration - 1) % CFL_CALC_FREQ == 0) CFL.calculate(Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), &mesh_flow, util_time_step); time_step = util_time_step; ADES.calculate(Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y), &mesh_concentration, util_time_step); if(util_time_step < time_step) time_step = util_time_step; // Visualization. if((iteration - 1) % EVERY_NTH_STEP == 0) { // Hermes visualization. if(HERMES_VISUALIZATION) { /* Mach_number.reinit(); pressure.reinit(); entropy.reinit(); pressure_view.show(&pressure); entropy_production_view.show(&entropy); Mach_number_view.show(&Mach_number); s5.show(&prev_c); */ s1.show(&prev_rho); s2.show(&prev_rho_v_x); s3.show(&prev_rho_v_y); s4.show(&prev_e); s5.show(&prev_c); //s5.wait_for_close(); } // Output solution in VTK format. if(VTK_VISUALIZATION) { pressure.reinit(); Mach_number.reinit(); Linearizer lin; char filename[40]; sprintf(filename, "pressure-%i.vtk", iteration - 1); lin.save_solution_vtk(&pressure, filename, "Pressure", false); sprintf(filename, "pressure-3D-%i.vtk", iteration - 1); lin.save_solution_vtk(&pressure, filename, "Pressure", true); sprintf(filename, "Mach number-%i.vtk", iteration - 1); lin.save_solution_vtk(&Mach_number, filename, "MachNumber", false); sprintf(filename, "Mach number-3D-%i.vtk", iteration - 1); lin.save_solution_vtk(&Mach_number, filename, "MachNumber", true); sprintf(filename, "Concentration-%i.vtk", iteration - 1); lin.save_solution_vtk(&prev_c, filename, "Concentration", true); sprintf(filename, "Concentration-3D-%i.vtk", iteration - 1); lin.save_solution_vtk(&prev_c, filename, "Concentration", true); } } } /* pressure_view.close(); entropy_production_view.close(); Mach_number_view.close(); s5.close(); */ s1.close(); s2.close(); s3.close(); s4.close(); s5.close(); return 0; }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial uniform mesh refinement. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Set essential boundary conditions. DefaultEssentialBCConst bc_essential(Hermes::vector<std::string>("right", "top"), 0.0); EssentialBCs bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space space(&mesh, &bcs, P_INIT); // Associate element markers (corresponding to physical regions) // with material properties (diffusion coefficient, absorption // cross-section, external sources). Hermes::vector<std::string> regions("e1", "e2", "e3", "e4", "e5"); Hermes::vector<double> D_map(D_1, D_2, D_3, D_4, D_5); Hermes::vector<double> Sigma_a_map(SIGMA_A_1, SIGMA_A_2, SIGMA_A_3, SIGMA_A_4, SIGMA_A_5); Hermes::vector<double> Sources_map(Q_EXT_1, 0.0, Q_EXT_3, 0.0, 0.0); // Initialize the weak formulation. WeakFormsNeutronics::Monoenergetic::Diffusion::DefaultWeakFormFixedSource wf(regions, D_map, Sigma_a_map, Sources_map); // Initialize coarse and reference mesh solution. Solution sln, ref_sln; // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. ScalarView sview("Solution", new WinGeom(0, 0, 440, 350)); sview.fix_scale_width(50); sview.show_mesh(false); OrderView oview("Polynomial orders", new WinGeom(450, 0, 400, 350)); // DOF and CPU convergence graphs initialization. SimpleGraph graph_dof, graph_cpu; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = Space::construct_refined_space(&space); int ndof_ref = Space::get_num_dofs(ref_space); // Initialize the FE problem. DiscreteProblem dp(&wf, ref_space); // Initialize the FE problem. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof_ref]; memset(coeff_vec, 0, ndof_ref*sizeof(scalar)); // Perform Newton's iteration on reference emesh. info("Solving on reference mesh."); if (!hermes2d.solve_newton(coeff_vec, &dp, solver, matrix, rhs)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solution(coeff_vec, ref_space, &ref_sln); // Project the fine mesh solution onto the coarse mesh. Solution sln; info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Time measurement. cpu_time.tick(); // View the coarse mesh solution and polynomial orders. sview.show(&sln); oview.show(&space); // Skip visualization time. cpu_time.tick(HERMES_SKIP); // Calculate element errors and total error estimate. info("Calculating error estimate."); Adapt* adaptivity = new Adapt(&space); double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space), err_est_rel); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof.save("conv_dof_est.dat"); graph_cpu.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu.save("conv_cpu_est.dat"); // If err_est too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if (done == false) as++; } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete [] coeff_vec; delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); // Show the reference solution - the final result. sview.set_title("Fine mesh solution"); sview.show_mesh(false); sview.show(&ref_sln); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes_2D; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst left_t("Left", 1.0); EssentialBCs bcs_t(&left_t); DefaultEssentialBCConst left_c("Left", 0.0); EssentialBCs bcs_c(&left_c); // Create H1 spaces with default shapesets. H1Space* t_space = new H1Space(&mesh, &bcs_t, P_INIT); H1Space* c_space = new H1Space(&mesh, &bcs_c, P_INIT); int ndof = Space::get_num_dofs(Hermes::vector<Space*>(t_space, c_space)); info("ndof = %d.", ndof); // Define initial conditions. InitialSolutionTemperature t_prev_time_1(&mesh, x1); InitialSolutionConcentration c_prev_time_1(&mesh, x1, Le); InitialSolutionTemperature t_prev_time_2(&mesh, x1); InitialSolutionConcentration c_prev_time_2(&mesh, x1, Le); Solution t_prev_newton; Solution c_prev_newton; // Filters for the reaction rate omega and its derivatives. CustomFilter omega(Hermes::vector<MeshFunction*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); CustomFilterDt omega_dt(Hermes::vector<MeshFunction*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); CustomFilterDc omega_dc(Hermes::vector<MeshFunction*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); // Initialize visualization. ScalarView rview("Reaction rate", new WinGeom(0, 0, 800, 230)); scalar* coeff_vec = new scalar[Space::get_num_dofs(Hermes::vector<Space*>(t_space, c_space))]; memset(coeff_vec, 0, ndof * sizeof(double)); Solution::vector_to_solutions(coeff_vec, Hermes::vector<Space*>(t_space, c_space), Hermes::vector<Solution *>(&t_prev_time_1, &c_prev_time_1)); // Initialize the weak formulation. double current_time = 0; CustomWeakForm wf(Le, alpha, beta, kappa, x1, TAU, false, PRECOND, &omega, &omega_dt, &omega_dc, &t_prev_time_1, &c_prev_time_1, &t_prev_time_2, &c_prev_time_2); // Initialize the FE problem. DiscreteProblem dp(&wf, Hermes::vector<Space*>(t_space, c_space)); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Time stepping: int ts = 1; bool jacobian_changed = true; do { info("---- Time step %d, time %3.5f s", ts, current_time); if (NEWTON) { // Perform Newton's iteration. info("Solving nonlinear problem:"); bool verbose = true; bool jacobian_changed = true; if (!hermes_2D.solve_newton(coeff_vec, &dp, solver, matrix, rhs, jacobian_changed, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); Solution::vector_to_solutions(coeff_vec, Hermes::vector<Space*>(t_space, c_space), Hermes::vector<Solution*>(&t_prev_newton, &c_prev_newton)); // Saving solutions for the next time step. if(ts > 1) { t_prev_time_2.copy(&t_prev_time_1); c_prev_time_2.copy(&c_prev_time_1); } t_prev_time_1.copy(&t_prev_newton); c_prev_time_1.copy(&c_prev_newton); } // Visualization. rview.set_min_max_range(0.0,2.0); rview.show(&omega); // Increase current time and time step counter. current_time += TAU; ts++; } while (current_time < T_FINAL); // Clean up. delete [] coeff_vec; delete matrix; delete rhs; delete solver; // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Define problem parameters: (x_loc, y_loc) is the center of the circular wave front, R_ZERO is the distance from the // wave front to the center of the circle, and alpha gives the steepness of the wave front. double alpha, x_loc, y_loc, r_zero; switch(PARAM) { case 0: alpha = 20; x_loc = -0.05; y_loc = -0.05; r_zero = 0.7; break; case 1: alpha = 1000; x_loc = -0.05; y_loc = -0.05; r_zero = 0.7; break; case 2: alpha = 1000; x_loc = 1.5; y_loc = 0.25; r_zero = 0.92; break; case 3: alpha = 50; x_loc = 0.5; y_loc = 0.5; r_zero = 0.25; break; default: // The same as 0. alpha = 20; x_loc = -0.05; y_loc = -0.05; r_zero = 0.7; break; } // Set adaptivity options according to the command line argument. int refinement_mode; if (argc != 2) refinement_mode = 0; else { refinement_mode = atoi(argv[1]); if (refinement_mode < 1 || refinement_mode > 12) throw Hermes::Exceptions::Exception("Invalid run case: %d (valid range is [1,12])", refinement_mode); } double threshold = 0.3; // strategy = 0 ... Refine elements until sqrt(threshold) times total error is processed. // If more elements have similar errors, refine all to keep the mesh symmetric. int strategy = 0; // strategy = 1 ... Refine all elements whose error is larger than threshold times max. element error. // Add also the norm of the residual to the error estimate of each element. bool use_residual_estimator = false; // Use energy norm for error estimate normalization and measuring of exact error. bool use_energy_norm_normalization = false; switch (refinement_mode) { case 1: case 2: case 3: case 4: case 5: case 6: { strategy = 0; break; } case 7 : case 8 : case 9 : case 10: case 11: case 12: { strategy = 1; break; } } switch (refinement_mode) { case 1: case 2: case 3: case 7: case 8: case 9: { threshold = 0.3; break; } case 4: case 5: case 6: case 10: case 11: case 12: { threshold = 0.3*0.3; break; } } switch (refinement_mode) { case 2: case 3: case 5: case 6: case 8: case 9: case 11: case 12: { use_residual_estimator = true; break; } } switch (refinement_mode) { case 3: case 6: case 9: case 12: { use_energy_norm_normalization = true; break; } } double setup_time = 0, assemble_time = 0, solve_time = 0, adapt_time = 0; // Time measurement. Hermes::Mixins::TimeMeasurable wall_clock; // Stop counting time for adaptation. wall_clock.tick(); // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("square_quad.mesh", &mesh); // Perform initial mesh refinement. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Stop counting time for adaptation. wall_clock.tick(); adapt_time += wall_clock.last(); // Set exact solution. CustomExactSolution exact(&mesh, alpha, x_loc, y_loc, r_zero); // Define right-hand side. CustomRightHandSide rhs(alpha, x_loc, y_loc, r_zero); // Initialize the weak formulation. CustomWeakForm wf(&rhs); // Equivalent, but slower: // DefaultWeakFormPoisson<double> wf(Hermes::HERMES_ANY, HERMES_ONE, &rhs); // Initialize boundary conditions. DefaultEssentialBCNonConst<double> bc("Bdy", &exact); EssentialBCs<double> bcs(&bc); SpaceSharedPtr<double> space(new // Create an H1 space with default shapeset. H1Space<double>(&mesh, &bcs, P_INIT)); // Initialize approximate solution. Solution<double> sln; // Initialize views. Views::ScalarView sview("Solution", new Views::WinGeom(800, 0, 400, 400)); sview.show_mesh(false); sview.set_3d_mode(); sview.set_palette(Views::H2DV_PT_HUESCALE); sview.fix_scale_width(50); Views::OrderView oview("Mesh", new Views::WinGeom(0, 0, 800, 800)); oview.set_palette(Views::H2DV_PT_INVGRAYSCALE); // DOF and CPU convergence graphs. ConvergenceTable conv_table; conv_table.add_column(" cycle ", "%6d "); conv_table.add_column(" H1 error ", " %.4e "); conv_table.add_column(" ndof ", " %6d "); conv_table.add_column(" total time ", " %8.3f "); conv_table.add_column(" setup time ", " %8.3f "); conv_table.add_column(" assem time ", " %8.3f "); conv_table.add_column(" solve time ", " %8.3f "); conv_table.add_column(" adapt time ", " %8.3f "); wall_clock.tick(Hermes::Mixins::TimeMeasurable::HERMES_SKIP); // Adaptivity loop: int as = 0; bool done = false; do { // Start counting setup time. wall_clock.tick(); // Assemble the discrete problem. DiscreteProblem<double> dp(&wf, &space); // Actual ndof. int ndof = space.get_num_dofs(); NewtonSolver<double> newton(&dp); //newton.set_verbose_output(false); // Setup time continues in NewtonSolver::solve(). try { newton.solve(); } catch(Hermes::Exceptions::Exception e) { e.print_msg(); throw Hermes::Exceptions::Exception("Newton's iteration failed."); }; // Start counting time for adaptation. wall_clock.tick(); Solution<double>::vector_to_solution(newton.get_sln_vector(), &space, &sln); double err_exact = Global<double>::calc_abs_error(&sln, &exact, HERMES_H1_NORM); // Report results. Hermes::Mixins::Loggable::Static::info(" Cycle %d:", as); Hermes::Mixins::Loggable::Static::info(" Number of degrees of freedom: %d", ndof); Hermes::Mixins::Loggable::Static::info(" H1 error w.r.t. exact soln.: %g", err_exact); // Stop counting time for adaptation. wall_clock.tick(); double accum_time = wall_clock.accumulated(); adapt_time += wall_clock.last(); // View the approximate solution and polynomial orders. //sview.show(&sln); //oview.show(&space); //Views::View::wait(Views::HERMES_WAIT_KEYPRESS); conv_table.add_value(0, as); conv_table.add_value(1, err_exact); conv_table.add_value(2, ndof); conv_table.add_value(3, accum_time); conv_table.add_value(4, setup_time); conv_table.add_value(5, assemble_time); conv_table.add_value(6, solve_time); conv_table.add_value(7, adapt_time); // Start counting time for adaptation. wall_clock.tick(); if (err_exact < ERR_STOP) done = true; else { // Calculate element errors and total error estimate. Hermes::Hermes2D::BasicKellyAdapt<double> adaptivity(&space); unsigned int error_flags = HERMES_TOTAL_ERROR_ABS; if (use_energy_norm_normalization) { error_flags |= HERMES_ELEMENT_ERROR_REL; adaptivity.set_error_form(new EnergyErrorForm(&wf)); } else error_flags |= HERMES_ELEMENT_ERROR_ABS; if (use_residual_estimator) adaptivity.add_error_estimator_vol(new ResidualErrorForm(&rhs)); double err_est_rel = adaptivity.calc_err_est(&sln, error_flags); done = adaptivity.adapt(threshold, strategy, MESH_REGULARITY); // Stop counting time for adaptation. wall_clock.tick(); adapt_time += wall_clock.last(); } // Increase the counter of performed adaptivity steps. if (done == false) as++; else { Hermes::Mixins::Loggable::Static::info("Total running time: %g s", wall_clock.accumulated()); Hermes::Mixins::Loggable::Static::info(" Setup: %g s", setup_time); Hermes::Mixins::Loggable::Static::info(" Assemble: %g s", assemble_time); Hermes::Mixins::Loggable::Static::info(" Solve: %g s", solve_time); Hermes::Mixins::Loggable::Static::info(" Adapt: %g s", adapt_time); //sview.show(&sln); oview.show(&space); oview.save_screenshot(("final_mesh-"+itos(refinement_mode)+".bmp").c_str()); oview.close(); conv_table.save(("conv_table-"+itos(refinement_mode)+".dat").c_str()); } } while (done == false); // Wait for all views to be closed. //Views::View::wait(); return 0; }
int main(int argc, char* argv[]) { // Choose a Butcher's table or define your own. ButcherTable bt(butcher_table_type); if (bt.is_explicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage explicit R-K method.", bt.get_size()); if (bt.is_diagonally_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage diagonally implicit R-K method.", bt.get_size()); if (bt.is_fully_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage fully implicit R-K method.", bt.get_size()); // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("square.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Convert initial condition into a Solution<std::complex<double> >. CustomInitialCondition psi_time_prev(&mesh); Solution<std::complex<double> > psi_time_new(&mesh); // Initialize the weak formulation. double current_time = 0; CustomWeakFormGPRK wf(h, m, g, omega); // Initialize boundary conditions. DefaultEssentialBCConst<std::complex<double> > bc_essential("Bdy", 0.0); EssentialBCs<std::complex<double> > bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<std::complex<double> > space(&mesh, &bcs, P_INIT); int ndof = space.get_num_dofs(); Hermes::Mixins::Loggable::Static::info("ndof = %d", ndof); // Initialize the FE problem. DiscreteProblem<std::complex<double> > dp(&wf, &space); // Initialize views. ScalarView sview_real("Solution - real part", new WinGeom(0, 0, 600, 500)); ScalarView sview_imag("Solution - imaginary part", new WinGeom(610, 0, 600, 500)); sview_real.fix_scale_width(80); sview_imag.fix_scale_width(80); // Initialize Runge-Kutta time stepping. RungeKutta<std::complex<double> > runge_kutta(&wf, &space, &bt); // Time stepping: int ts = 1; int nstep = (int)(T_FINAL/time_step + 0.5); for(int ts = 1; ts <= nstep; ts++) { // Perform one Runge-Kutta time step according to the selected Butcher's table. Hermes::Mixins::Loggable::Static::info("Runge-Kutta time step (t = %g s, time step = %g s, stages: %d).", current_time, time_step, bt.get_size()); try { runge_kutta.setTime(current_time); runge_kutta.setTimeStep(time_step); runge_kutta.rk_time_step_newton(&psi_time_prev, &psi_time_new); } catch(Exceptions::Exception& e) { e.printMsg(); throw Hermes::Exceptions::Exception("Runge-Kutta time step failed"); } // Show the new time level solution. char title[100]; sprintf(title, "Solution - real part, Time %3.2f s", current_time); sview_real.set_title(title); sprintf(title, "Solution - imaginary part, Time %3.2f s", current_time); sview_imag.set_title(title); RealFilter real(&psi_time_new); ImagFilter imag(&psi_time_new); sview_real.show(&real); sview_imag.show(&imag); // Copy solution for the new time step. psi_time_prev.copy(&psi_time_new); // Increase current time and time step counter. current_time += time_step; ts++; } // Wait for the view to be closed. View::wait(); return 0; }
int main() { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Create space, set Dirichlet BC, enumerate basis functions. Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ, NEQ); // Enumerate basis functions, info for user. int ndof = Space::get_num_dofs(space); info("ndof: %d", ndof); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, jacobian_0_0); wf.add_matrix_form(0, 1, jacobian_0_1); wf.add_matrix_form(1, 0, jacobian_1_0); wf.add_matrix_form(1, 1, jacobian_1_1); wf.add_vector_form(0, residual_0); wf.add_vector_form(1, residual_1); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear); // Newton's loop. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(space)]; get_coeff_vector(space, coeff_vec); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); int it = 1; bool success = false; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp->assemble(coeff_vec, matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!(success = solver->solve())) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec, space); it++; } info("Total running time: %g s", cpu_time.accumulated()); // Test variable. info("ndof = %d.", Space::get_num_dofs(space)); // Cleanup. for(unsigned i = 0; i < DIR_BC_LEFT.size(); i++) delete DIR_BC_LEFT[i]; DIR_BC_LEFT.clear(); for(unsigned i = 0; i < DIR_BC_RIGHT.size(); i++) delete DIR_BC_RIGHT[i]; DIR_BC_RIGHT.clear(); delete matrix; delete rhs; delete solver; delete[] coeff_vec; delete dp; delete space; if (success) { info("Success!"); return ERROR_SUCCESS; } else { info("Failure!"); return ERROR_FAILURE; } }
int main(int argc, char **args) { // Test variable. int success_test = 1; if (argc < 2) error("Not enough parameters."); // Load the mesh. Mesh mesh; H3DReader mloader; if (!mloader.load(args[1], &mesh)) error("Loading mesh file '%s'.", args[1]); // Initialize the space. #if defined NONLIN1 Ord3 order(1, 1, 1); #else Ord3 order(2, 2, 2); #endif H1Space space(&mesh, bc_types, essential_bc_values, order); #if defined NONLIN2 // Do L2 projection of zero function. WeakForm proj_wf; proj_wf.add_matrix_form(biproj_form<double, scalar>, biproj_form<Ord, Ord>, HERMES_SYM); proj_wf.add_vector_form(liproj_form<double, scalar>, liproj_form<Ord, Ord>); bool is_linear = true; DiscreteProblem lp(&proj_wf, &space, is_linear); // Initialize the solver in the case of SOLVER_PETSC or SOLVER_MUMPS. initialize_solution_environment(matrix_solver, argc, args); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver_proj = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the preconditioner in the case of SOLVER_AZTECOO. if (matrix_solver == SOLVER_AZTECOO) { ((AztecOOSolver*) solver_proj)->set_solver(iterative_method); ((AztecOOSolver*) solver_proj)->set_precond(preconditioner); // Using default iteration parameters (see solver/aztecoo.h). } // Assemble the linear problem. info("Assembling (ndof: %d).", Space::get_num_dofs(&space)); lp.assemble(matrix, rhs); // Solve the linear system. info("Solving."); if(!solver_proj->solve()); error ("Matrix solver failed.\n"); delete matrix; delete rhs; #endif // Initialize the weak formulation. WeakForm wf(1); wf.add_matrix_form(0, 0, jacobi_form<double, scalar>, jacobi_form<Ord, Ord>, HERMES_UNSYM); wf.add_vector_form(0, resid_form<double, scalar>, resid_form<Ord, Ord>); // Initialize the FE problem. #if defined NONLIN2 is_linear = false; #else bool is_linear = false; #endif DiscreteProblem dp(&wf, &space, is_linear); NoxSolver solver(&dp); #if defined NONLIN2 solver.set_init_sln(solver_proj->get_solution()); delete solver_proj; #endif solver.set_conv_iters(10); info("Solving."); Solution sln(&mesh); if(solver.solve()) Solution::vector_to_solution(solver.get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); Solution ex_sln(&mesh); #ifdef NONLIN1 ex_sln.set_const(100.0); #else ex_sln.set_exact(exact_solution); #endif // Calculate exact error. info("Calculating exact error."); Adapt *adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = false; double err_exact = adaptivity->calc_err_exact(&sln, &ex_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_ABS); if (err_exact > EPS) // Calculated solution is not precise enough. success_test = 0; if (success_test) { info("Success!"); return ERR_SUCCESS; } else { info("Failure!"); return ERR_FAILURE; } }
int main() { // Create space, set Dirichlet BC, enumerate basis functions. Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ); info("N_dof = %d.", Space::get_num_dofs(space)); // Initialize the weak formulation. WeakForm wf(4); wf.add_matrix_form(0, 0, jacobian_1_1); wf.add_matrix_form(0, 1, jacobian_1_2); wf.add_matrix_form(1, 0, jacobian_2_1); wf.add_matrix_form(1, 1, jacobian_2_2); wf.add_matrix_form(1, 2, jacobian_2_3); wf.add_matrix_form(2, 1, jacobian_3_2); wf.add_matrix_form(2, 2, jacobian_3_3); wf.add_matrix_form(2, 3, jacobian_3_4); wf.add_matrix_form(3, 2, jacobian_4_3); wf.add_matrix_form(3, 3, jacobian_4_4); wf.add_vector_form(0, residual_1); wf.add_vector_form(1, residual_2); wf.add_vector_form(2, residual_3); wf.add_vector_form(3, residual_4); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear); // Newton's loop. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(space)]; get_coeff_vector(space, coeff_vec); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp->assemble(matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec, space); it++; } // Plot the solution. Linearizer l(space); l.plot_solution("solution.gp"); // Plot the resulting space. space->plot("space.gp"); info("Done."); return 0; }
int main(int argc, char* argv[]) { // Choose a Butcher's table or define your own. ButcherTable bt(butcher_table_type); if (bt.is_explicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage explicit R-K method.", bt.get_size()); if (bt.is_diagonally_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage diagonally implicit R-K method.", bt.get_size()); if (bt.is_fully_implicit()) Hermes::Mixins::Loggable::Static::info("Using a %d-stage fully implicit R-K method.", bt.get_size()); // Turn off adaptive time stepping if R-K method is not embedded. if (bt.is_embedded() == false && ADAPTIVE_TIME_STEP_ON == true) { Hermes::Mixins::Loggable::Static::warn("R-K method not embedded, turning off adaptive time stepping."); ADAPTIVE_TIME_STEP_ON = false; } // Load the mesh. MeshSharedPtr mesh(new Mesh), basemesh(new Mesh); MeshReaderH2D mloader; mloader.load("square.mesh", basemesh); mesh->copy(basemesh); // Initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh->refine_all_elements(); // Convert initial condition into a Solution<complex>. MeshFunctionSharedPtr<complex> psi_time_prev(new CustomInitialCondition(mesh)); // Initialize the weak formulation. double current_time = 0; // Initialize weak formulation. CustomWeakFormGPRK wf(h, m, g, omega); // Initialize boundary conditions. DefaultEssentialBCConst<complex> bc_essential("Bdy", 0.0); EssentialBCs<complex> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<complex> space(new H1Space<complex> (mesh, &bcs, P_INIT)); int ndof = space->get_num_dofs(); Hermes::Mixins::Loggable::Static::info("ndof = %d", ndof); // Initialize the FE problem. DiscreteProblem<complex> dp(&wf, space); // Create a refinement selector. H1ProjBasedSelector<complex> selector(CAND_LIST); // Visualize initial condition. char title[100]; ScalarView sview_real("Initial condition - real part", new WinGeom(0, 0, 600, 500)); ScalarView sview_imag("Initial condition - imaginary part", new WinGeom(610, 0, 600, 500)); sview_real.show_mesh(false); sview_imag.show_mesh(false); sview_real.fix_scale_width(50); sview_imag.fix_scale_width(50); OrderView ord_view("Initial mesh", new WinGeom(445, 0, 440, 350)); ord_view.fix_scale_width(50); ScalarView time_error_view("Temporal error", new WinGeom(0, 400, 440, 350)); time_error_view.fix_scale_width(50); time_error_view.fix_scale_width(60); ScalarView space_error_view("Spatial error", new WinGeom(445, 400, 440, 350)); space_error_view.fix_scale_width(50); MeshFunctionSharedPtr<double> real(new RealFilter(psi_time_prev)); MeshFunctionSharedPtr<double> imag(new ImagFilter(psi_time_prev)); sview_real.show(real); sview_imag.show(imag); ord_view.show(space); // Graph for time step history. SimpleGraph time_step_graph; if (ADAPTIVE_TIME_STEP_ON) Hermes::Mixins::Loggable::Static::info("Time step history will be saved to file time_step_history.dat."); // Time stepping: int num_time_steps = (int)(T_FINAL/time_step + 0.5); for(int ts = 1; ts <= num_time_steps; ts++) // Time stepping loop. double current_time = 0.0; int ts = 1; do { Hermes::Mixins::Loggable::Static::info("Begin time step %d.", ts); // Periodic global derefinement. if (ts > 1 && ts % UNREF_FREQ == 0) { Hermes::Mixins::Loggable::Static::info("Global mesh derefinement."); switch (UNREF_METHOD) { case 1: mesh->copy(basemesh); space->set_uniform_order(P_INIT); break; case 2: space->unrefine_all_mesh_elements(); space->set_uniform_order(P_INIT); break; case 3: space->unrefine_all_mesh_elements(); space->adjust_element_order(-1, -1, P_INIT, P_INIT); break; default: throw Hermes::Exceptions::Exception("Wrong global derefinement method."); } ndof = Space<complex>::get_num_dofs(space); } Hermes::Mixins::Loggable::Static::info("ndof: %d", ndof); // Spatial adaptivity loop. Note: psi_time_prev must not be // changed during spatial adaptivity. MeshFunctionSharedPtr<complex> ref_sln(new Solution<complex>()); MeshFunctionSharedPtr<complex> time_error_fn(new Solution<complex>); bool done = false; int as = 1; double err_est; do { // Construct globally refined reference mesh and setup reference space. Mesh::ReferenceMeshCreator refMeshCreator(mesh); MeshSharedPtr ref_mesh = refMeshCreator.create_ref_mesh(); Space<complex>::ReferenceSpaceCreator refSpaceCreator(space, ref_mesh); SpaceSharedPtr<complex> ref_space = refSpaceCreator.create_ref_space(); // Initialize discrete problem on reference mesh. DiscreteProblem<complex>* ref_dp = new DiscreteProblem<complex>(&wf, ref_space); RungeKutta<complex> runge_kutta(&wf, ref_space, &bt); // Runge-Kutta step on the fine mesh-> Hermes::Mixins::Loggable::Static::info("Runge-Kutta time step on fine mesh (t = %g s, time step = %g s, stages: %d).", current_time, time_step, bt.get_size()); bool verbose = true; try { runge_kutta.set_time(current_time); runge_kutta.set_time_step(time_step); runge_kutta.set_max_allowed_iterations(NEWTON_MAX_ITER); runge_kutta.set_tolerance(NEWTON_TOL_FINE); runge_kutta.rk_time_step_newton(psi_time_prev, ref_sln, time_error_fn); } catch(Exceptions::Exception& e) { e.print_msg(); throw Hermes::Exceptions::Exception("Runge-Kutta time step failed"); } /* If ADAPTIVE_TIME_STEP_ON == true, estimate temporal error. If too large or too small, then adjust it and restart the time step. */ double rel_err_time = 0; if (bt.is_embedded() == true) { Hermes::Mixins::Loggable::Static::info("Calculating temporal error estimate."); // Show temporal error. char title[100]; sprintf(title, "Temporal error est, spatial adaptivity step %d", as); time_error_view.set_title(title); time_error_view.show_mesh(false); MeshFunctionSharedPtr<double> abs_time(new RealFilter(time_error_fn)); MeshFunctionSharedPtr<double> abs_tef(new AbsFilter(abs_time)); time_error_view.show(abs_tef); rel_err_time = Global<complex>::calc_norm(time_error_fn.get(), HERMES_H1_NORM) / Global<complex>::calc_norm(ref_sln.get(), HERMES_H1_NORM) * 100; if (ADAPTIVE_TIME_STEP_ON == false) Hermes::Mixins::Loggable::Static::info("rel_err_time: %g%%", rel_err_time); } if (ADAPTIVE_TIME_STEP_ON) { if (rel_err_time > TIME_ERR_TOL_UPPER) { Hermes::Mixins::Loggable::Static::info("rel_err_time %g%% is above upper limit %g%%", rel_err_time, TIME_ERR_TOL_UPPER); Hermes::Mixins::Loggable::Static::info("Decreasing time step from %g to %g s and restarting time step.", time_step, time_step * TIME_STEP_DEC_RATIO); time_step *= TIME_STEP_DEC_RATIO; delete ref_dp; continue; } else if (rel_err_time < TIME_ERR_TOL_LOWER) { Hermes::Mixins::Loggable::Static::info("rel_err_time = %g%% is below lower limit %g%%", rel_err_time, TIME_ERR_TOL_LOWER); Hermes::Mixins::Loggable::Static::info("Increasing time step from %g to %g s.", time_step, time_step * TIME_STEP_INC_RATIO); time_step *= TIME_STEP_INC_RATIO; delete ref_dp; continue; } else { Hermes::Mixins::Loggable::Static::info("rel_err_time = %g%% is in acceptable interval (%g%%, %g%%)", rel_err_time, TIME_ERR_TOL_LOWER, TIME_ERR_TOL_UPPER); } // Add entry to time step history graph. time_step_graph.add_values(current_time, time_step); time_step_graph.save("time_step_history.dat"); } /* Estimate spatial errors and perform mesh refinement */ Hermes::Mixins::Loggable::Static::info("Spatial adaptivity step %d.", as); // Project the fine mesh solution onto the coarse mesh. MeshFunctionSharedPtr<complex> sln(new Solution<complex>); Hermes::Mixins::Loggable::Static::info("Projecting fine mesh solution on coarse mesh for error estimation."); OGProjection<complex> ogProjection; ogProjection.project_global(space, ref_sln, sln); // Show spatial error. sprintf(title, "Spatial error est, spatial adaptivity step %d", as); MeshFunctionSharedPtr<complex> space_error_fn(new DiffFilter<complex>(Hermes::vector<MeshFunctionSharedPtr<complex> >(ref_sln, sln))); space_error_view.set_title(title); space_error_view.show_mesh(false); MeshFunctionSharedPtr<double> abs_space(new RealFilter(space_error_fn)); MeshFunctionSharedPtr<double> abs_sef(new AbsFilter(abs_space)); space_error_view.show(abs_sef); // Calculate element errors and spatial error estimate. Hermes::Mixins::Loggable::Static::info("Calculating spatial error estimate."); Adapt<complex> adaptivity(space); double err_rel_space = errorCalculator.get_total_error_squared() * 100; // Report results. Hermes::Mixins::Loggable::Static::info("ndof: %d, ref_ndof: %d, err_rel_space: %g%%", Space<complex>::get_num_dofs(space), Space<complex>::get_num_dofs(ref_space), err_rel_space); // If err_est too large, adapt the mesh. if (err_rel_space < SPACE_ERR_TOL) done = true; else { Hermes::Mixins::Loggable::Static::info("Adapting the coarse mesh."); done = adaptivity.adapt(&selector); // Increase the counter of performed adaptivity steps. as++; } // Clean up. delete ref_dp; } while (done == false); // Visualize the solution and mesh-> char title[100]; sprintf(title, "Solution - real part, Time %3.2f s", current_time); sview_real.set_title(title); sprintf(title, "Solution - imaginary part, Time %3.2f s", current_time); sview_imag.set_title(title); MeshFunctionSharedPtr<double> real(new RealFilter(ref_sln)); MeshFunctionSharedPtr<double> imag(new ImagFilter(ref_sln)); sview_real.show(real); sview_imag.show(imag); sprintf(title, "Mesh, time %g s", current_time); ord_view.set_title(title); ord_view.show(space); // Copy last reference solution into psi_time_prev. psi_time_prev->copy(ref_sln); // Increase current time and counter of time steps. current_time += time_step; ts++; } while (current_time < T_FINAL); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements (optional). for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize the weak formulation. CustomWeakFormPoissonNeumann wf("Aluminum", LAMBDA_AL, "Copper", LAMBDA_CU, VOLUME_HEAT_SRC, "Outer", HEAT_FLUX); // Initialize boundary conditions. CustomDirichletCondition bc_essential(Hermes::vector<std::string>("Bottom", "Inner", "Left"), BDY_A_PARAM, BDY_B_PARAM, BDY_C_PARAM); EssentialBCs bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space space(&mesh, &bcs, P_INIT); int ndof = space.get_num_dofs(); info("ndof = %d", ndof); // Initialize the FE problem. DiscreteProblem dp(&wf, &space); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof]; memset(coeff_vec, 0, ndof*sizeof(scalar)); // Perform Newton's iteration. if (!hermes2d.solve_newton(coeff_vec, &dp, solver, matrix, rhs)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution sln; Solution::vector_to_solution(coeff_vec, &space, &sln); // VTK output. if (VTK_VISUALIZATION) { // Output solution in VTK format. Linearizer lin; bool mode_3D = true; lin.save_solution_vtk(&sln, "sln.vtk", "Temperature", mode_3D); info("Solution in VTK format saved to file %s.", "sln.vtk"); // Output mesh and element orders in VTK format. Orderizer ord; ord.save_orders_vtk(&space, "ord.vtk"); info("Element orders in VTK format saved to file %s.", "ord.vtk"); } // Visualize the solution. if (HERMES_VISUALIZATION) { ScalarView view("Solution", new WinGeom(0, 0, 440, 350)); view.show(&sln, HERMES_EPS_HIGH); View::wait(); } // Clean up. delete solver; delete matrix; delete rhs; delete [] coeff_vec; return 0; }
int main(int argc, char* argv[]) { // Time measurement. Hermes::Mixins::TimeMeasurable cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinemets. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst<double> left_t("Left", 1.0); EssentialBCs<double> bcs_t(&left_t); DefaultEssentialBCConst<double> left_c("Left", 0.0); EssentialBCs<double> bcs_c(&left_c); // Create H1 spaces with default shapesets. H1Space<double>* t_space = new H1Space<double>(&mesh, &bcs_t, P_INIT); H1Space<double>* c_space = new H1Space<double>(&mesh, &bcs_c, P_INIT); int ndof = Space<double>::get_num_dofs(Hermes::vector<const Space<double>*>(t_space, c_space)); Hermes::Mixins::Loggable::Static::info("ndof = %d.", ndof); // Define initial conditions. InitialSolutionTemperature t_prev_time_1(&mesh, x1); InitialSolutionConcentration c_prev_time_1(&mesh, x1, Le); InitialSolutionTemperature t_prev_time_2(&mesh, x1); InitialSolutionConcentration c_prev_time_2(&mesh, x1, Le); Solution<double> t_prev_newton; Solution<double> c_prev_newton; // Filters for the reaction rate omega and its derivatives. CustomFilter omega(Hermes::vector<Solution<double>*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); CustomFilterDt omega_dt(Hermes::vector<Solution<double>*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); CustomFilterDc omega_dc(Hermes::vector<Solution<double>*>(&t_prev_time_1, &c_prev_time_1), Le, alpha, beta, kappa, x1, TAU); // Initialize visualization. ScalarView rview("Reaction rate", new WinGeom(0, 0, 800, 230)); // Initialize weak formulation. CustomWeakForm wf(Le, alpha, beta, kappa, x1, TAU, TRILINOS_JFNK, PRECOND, &omega, &omega_dt, &omega_dc, &t_prev_time_1, &c_prev_time_1, &t_prev_time_2, &c_prev_time_2); // Project the functions "t_prev_time_1" and "c_prev_time_1" on the FE space // in order to obtain initial vector for NOX. Hermes::Mixins::Loggable::Static::info("Projecting initial solutions on the FE meshes."); double* coeff_vec = new double[ndof]; OGProjection<double> ogProjection; ogProjection.project_global(Hermes::vector<const Space<double> *>(t_space, c_space), Hermes::vector<MeshFunction<double>*>(&t_prev_time_1, &c_prev_time_1), coeff_vec); // Measure the projection time. double proj_time = cpu_time.tick().last(); // Initialize finite element problem. DiscreteProblem<double> dp(&wf, Hermes::vector<const Space<double>*>(t_space, c_space)); // Initialize NOX solver and preconditioner. NewtonSolverNOX<double> solver(&dp); MlPrecond<double> pc("sa"); if (PRECOND) { if (TRILINOS_JFNK) solver.set_precond(pc); else solver.set_precond("New Ifpack"); } if (TRILINOS_OUTPUT) solver.set_output_flags(NOX::Utils::Error | NOX::Utils::OuterIteration | NOX::Utils::OuterIterationStatusTest | NOX::Utils::LinearSolverDetails); // Time stepping loop: double total_time = 0.0; cpu_time.tick_reset(); for (int ts = 1; total_time <= T_FINAL; ts++) { Hermes::Mixins::Loggable::Static::info("---- Time step %d, t = %g s", ts, total_time + TAU); cpu_time.tick(); try { solver.solve(coeff_vec); } catch(std::exception& e) { std::cout << e.what(); } Solution<double>::vector_to_solutions(solver.get_sln_vector(), Hermes::vector<const Space<double> *>(t_space, c_space), Hermes::vector<Solution<double> *>(&t_prev_newton, &c_prev_newton)); cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Number of nonlin iterations: %d (norm of residual: %g)", solver.get_num_iters(), solver.get_residual()); Hermes::Mixins::Loggable::Static::info("Total number of iterations in linsolver: %d (achieved tolerance in the last step: %g)", solver.get_num_lin_iters(), solver.get_achieved_tol()); // Time measurement. cpu_time.tick(); // Skip visualization time. cpu_time.tick(); // Update global time. total_time += TAU; // Saving solutions for the next time step. if(ts > 1) { t_prev_time_2.copy(&t_prev_time_1); c_prev_time_2.copy(&c_prev_time_1); } t_prev_time_1.copy(&t_prev_newton); c_prev_time_1.copy(&c_prev_newton); // Visualization. rview.set_min_max_range(0.0,2.0); rview.show(&omega); cpu_time.tick(); Hermes::Mixins::Loggable::Static::info("Total running time for time level %d: %g s.", ts, cpu_time.tick().last()); } // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("domain.mesh", &mesh); // Perform uniform mesh refinement. // 2 is for vertical split. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(2); // Initialize boundary conditions DefaultEssentialBCConst<double> bc1("Bdy_perfect", 0.0); EssentialBCNonConst bc2("Bdy_left"); DefaultEssentialBCConst<double> bc3("Bdy_left", 0.0); EssentialBCs<double> bcs(Hermes::vector<EssentialBoundaryCondition<double> *>(&bc1, &bc2)); EssentialBCs<double> bcs_im(Hermes::vector<EssentialBoundaryCondition<double> *>(&bc1, &bc3)); // Create an H1 space with default shapeset. H1Space<double> e_r_space(&mesh, &bcs, P_INIT); H1Space<double> e_i_space(&mesh, &bcs_im, P_INIT); int ndof = Space<double>::get_num_dofs(&e_r_space); info("ndof = %d", ndof); // Initialize the weak formulation. WeakFormHelmholtz wf(eps, mu, omega, sigma, beta, E0, h); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, Hermes::vector<const Space<double>*>(&e_r_space, &e_i_space)); // Initialize the solutions. Solution<double> e_r_sln, e_i_sln; // Initial coefficient vector for the Newton's method. ndof = Space<double>::get_num_dofs(Hermes::vector<const Space<double>*>(&e_r_space, &e_i_space)); Hermes::Hermes2D::NewtonSolver<double> newton(&dp, matrix_solver); try { newton.solve(NULL, NEWTON_TOL, NEWTON_MAX_ITER); } catch(Hermes::Exceptions::Exception e) { e.printMsg(); error("Newton's iteration failed."); }; // Translate the resulting coefficient vector into Solutions. Solution<double>::vector_to_solutions(newton.get_sln_vector(), Hermes::vector<const Space<double>*>(&e_r_space, &e_i_space), Hermes::vector<Solution<double>*>(&e_r_sln, &e_i_sln)); // Visualize the solution. ScalarView viewEr("Er [V/m]", new WinGeom(0, 0, 800, 400)); viewEr.show(&e_r_sln); // viewEr.save_screenshot("real_part.bmp"); ScalarView viewEi("Ei [V/m]", new WinGeom(0, 450, 800, 400)); viewEi.show(&e_i_sln); // viewEi.save_screenshot("imaginary_part.bmp"); // Wait for the view to be closed. View::wait(); return 0; }
int main() { // Create space. // Transform input data to the format used by the "Space" constructor. SpaceData *md = new SpaceData(); Space* space = new Space(md->N_macroel, md->interfaces, md->poly_orders, md->material_markers, md->subdivisions, N_GRP, N_SLN); delete md; // Enumerate basis functions, info for user. int ndof = Space::get_num_dofs(space); info("ndof: %d", ndof); // Plot the space. space->plot("space.gp"); for (int g = 0; g < N_GRP; g++) { space->set_bc_left_dirichlet(g, flux_left_surf[g]); space->set_bc_right_dirichlet(g, flux_right_surf[g]); } // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, jacobian_mat1_0_0, NULL, mat1); wf.add_matrix_form(0, 0, jacobian_mat2_0_0, NULL, mat2); wf.add_matrix_form(0, 0, jacobian_mat3_0_0, NULL, mat3); wf.add_matrix_form(0, 1, jacobian_mat1_0_1, NULL, mat1); wf.add_matrix_form(0, 1, jacobian_mat2_0_1, NULL, mat2); wf.add_matrix_form(0, 1, jacobian_mat3_0_1, NULL, mat3); wf.add_matrix_form(1, 0, jacobian_mat1_1_0, NULL, mat1); wf.add_matrix_form(1, 0, jacobian_mat2_1_0, NULL, mat2); wf.add_matrix_form(1, 0, jacobian_mat3_1_0, NULL, mat3); wf.add_matrix_form(1, 1, jacobian_mat1_1_1, NULL, mat1); wf.add_matrix_form(1, 1, jacobian_mat2_1_1, NULL, mat2); wf.add_matrix_form(1, 1, jacobian_mat3_1_1, NULL, mat3); wf.add_vector_form(0, residual_mat1_0, NULL, mat1); wf.add_vector_form(0, residual_mat2_0, NULL, mat2); wf.add_vector_form(0, residual_mat3_0, NULL, mat3); wf.add_vector_form(1, residual_mat1_1, NULL, mat1); wf.add_vector_form(1, residual_mat2_1, NULL, mat2); wf.add_vector_form(1, residual_mat3_1, NULL, mat3); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear); // Newton's loop. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(space)]; get_coeff_vector(space, coeff_vec); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp->assemble(coeff_vec, matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec, space); it++; } // Plot the solution. Linearizer l(space); l.plot_solution("solution.gp"); info("Done."); return 0; }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("../domain.mesh", &mesh); // Perform initial mesh refinements (optional). for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize the weak formulation. CustomWeakFormPoissonDirichlet wf("Aluminum", LAMBDA_AL, "Copper", LAMBDA_CU, VOLUME_HEAT_SRC); // Initialize boundary conditions. CustomDirichletCondition bc_essential(Hermes::vector<std::string>("Bottom", "Inner", "Outer", "Left"), BDY_A_PARAM, BDY_B_PARAM, BDY_C_PARAM); EssentialBCs bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space space(&mesh, &bcs, P_INIT); int ndof = space.get_num_dofs(); info("ndof = %d", ndof); // Initialize the FE problem. DiscreteProblem dp(&wf, &space); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof]; memset(coeff_vec, 0, ndof*sizeof(scalar)); // Perform Newton's iteration. if (!hermes2d.solve_newton(coeff_vec, &dp, solver, matrix, rhs)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution sln; Solution::vector_to_solution(coeff_vec, &space, &sln); // VTK output. if (VTK_VISUALIZATION) { // Output solution in VTK format. Linearizer lin; bool mode_3D = true; lin.save_solution_vtk(&sln, "sln.vtk", "Temperature", mode_3D); info("Solution in VTK format saved to file %s.", "sln.vtk"); // Output mesh and element orders in VTK format. Orderizer ord; ord.save_orders_vtk(&space, "ord.vtk"); info("Element orders in VTK format saved to file %s.", "ord.vtk"); } ndof = Space::get_num_dofs(&space); printf("ndof = %d\n", ndof); double sum = 0; for (int i=0; i < ndof; i++) sum += coeff_vec[i]; printf("coefficient sum = %g\n", sum); bool success = true; if (fabs(sum + 4.2471) > 1e-3) success = 0; if (success == 1) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Load the mesh. Hermes::Hermes2D::Mesh mesh; Hermes::Hermes2D::MeshReaderH2D mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements (optional). for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize the weak formulation. CustomWeakFormPoissonNewton wf("Aluminum", new Hermes::Hermes1DFunction<double>(LAMBDA_AL), "Copper", new Hermes::Hermes1DFunction<double>(LAMBDA_CU), new Hermes::Hermes2DFunction<double>(-VOLUME_HEAT_SRC), "Outer", ALPHA, T_EXTERIOR); // Initialize boundary conditions. CustomDirichletCondition bc_essential(Hermes::vector<std::string>("Bottom", "Inner", "Left"), BDY_A_PARAM, BDY_B_PARAM, BDY_C_PARAM); Hermes::Hermes2D::EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. Hermes::Hermes2D::H1Space<double> space(&mesh, &bcs, P_INIT); int ndof = space.get_num_dofs(); info("ndof = %d", ndof); // Initialize the FE problem. Hermes::Hermes2D::DiscreteProblem<double> dp(&wf, &space); // Initial coefficient vector for the Newton's method. double* coeff_vec = new double[ndof]; memset(coeff_vec, 0, ndof*sizeof(double)); // Initialize the Newton solver. Hermes::Hermes2D::NewtonSolver<double> newton(&dp, matrix_solver_type); // Perform Newton's iteration and translate the resulting coefficient vector into a Solution. Hermes::Hermes2D::Solution<double> sln; if (!newton.solve(coeff_vec)) error("Newton's iteration failed."); else Hermes::Hermes2D::Solution<double>::vector_to_solution(newton.get_sln_vector(), &space, &sln); // VTK output. if (VTK_VISUALIZATION) { // Output solution in VTK format. Hermes::Hermes2D::Views::Linearizer lin(&sln); bool mode_3D = true; lin.save_solution_vtk("sln.vtk", "Temperature", mode_3D); info("Solution in VTK format saved to file %s.", "sln.vtk"); // Output mesh and element orders in VTK format. Hermes::Hermes2D::Views::Orderizer ord; ord.save_orders_vtk(&space, "ord.vtk"); info("Element orders in VTK format saved to file %s.", "ord.vtk"); } // Visualize the solution. if (HERMES_VISUALIZATION) { Hermes::Hermes2D::Views::ScalarView view("Solution", new Hermes::Hermes2D::Views::WinGeom(0, 0, 440, 350)); view.show(&sln, Hermes::Hermes2D::Views::HERMES_EPS_VERYHIGH); Hermes::Hermes2D::Views::View::wait(); } // Clean up. delete [] coeff_vec; return 0; }
int main(int argc, char* argv[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh), mesh1(new Mesh); if (USE_XML_FORMAT == true) { MeshReaderH2DXML mloader; Hermes::Mixins::Loggable::Static::info("Reading mesh in XML format."); mloader.load("domain.xml", mesh); } else { MeshReaderH2D mloader; Hermes::Mixins::Loggable::Static::info("Reading mesh in original format."); mloader.load("domain.mesh", mesh); } // Perform uniform mesh refinement. mesh->refine_all_elements(); // Show mesh. MeshView mv("Mesh", new WinGeom(0, 0, 580, 400)); mv.show(mesh); // Initialize boundary conditions. DefaultEssentialBCConst<double> zero_disp("Bottom", 0.0); EssentialBCs<double> bcs(&zero_disp); // Create x- and y- displacement space using the default H1 shapeset. SpaceSharedPtr<double> u1_space(new H1Space<double>(mesh, &bcs, P_INIT)); SpaceSharedPtr<double> u2_space(new H1Space<double>(mesh, &bcs, P_INIT)); Hermes::vector<SpaceSharedPtr<double> > spaces(u1_space, u2_space); int ndof = Space<double>::get_num_dofs(spaces); Hermes::Mixins::Loggable::Static::info("ndof = %d", ndof); // Initialize the weak formulation. CustomWeakFormLinearElasticity wf(E, nu, rho*g1, "Top", f0, f1); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, spaces); // Initialize Newton solver. NewtonSolver<double> newton(&dp); newton.set_verbose_output(true); // Perform Newton's iteration. try { newton.solve(); } catch(std::exception& e) { std::cout << e.what(); } // Translate the resulting coefficient vector into the Solution sln. MeshFunctionSharedPtr<double> u1_sln(new Solution<double>), u2_sln(new Solution<double>); Solution<double>::vector_to_solutions(newton.get_sln_vector(), spaces, Hermes::vector<MeshFunctionSharedPtr<double> >(u1_sln, u2_sln)); // Visualize the solution. ScalarView view("Von Mises stress [Pa]", new WinGeom(590, 0, 700, 400)); // First Lame constant. double lambda = (E * nu) / ((1 + nu) * (1 - 2*nu)); // Second Lame constant. double mu = E / (2*(1 + nu)); MeshFunctionSharedPtr<double> stress(new VonMisesFilter(Hermes::vector<MeshFunctionSharedPtr<double> >(u1_sln, u2_sln), lambda, mu)); view.show_mesh(false); view.show(stress, HERMES_EPS_HIGH, H2D_FN_VAL_0, u1_sln, u2_sln, 1.5e5); // Wait for the view to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; H2DReader mloader; if (ALIGN_MESH) mloader.load("oven_load_circle.mesh", &mesh); else mloader.load("oven_load_square.mesh", &mesh); //mesh.refine_all_elements(); // initialize the shapeset and the cache HcurlShapeset shapeset; PrecalcShapeset pss(&shapeset); // create finite element space HcurlSpace space(&mesh, &shapeset); space.set_bc_types(e_bc_types); space.set_uniform_order(P_INIT); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form)); wf.add_liform_surf(0, callback(linear_form_surf)); // visualize solution and mesh VectorView eview("Electric field",0,0,800, 590); OrderView ord("Order", 800, 0, 700, 590); /* // view the basis functions VectorBaseView bview; vbview.show(&space); vbview.wait_for_keypress(); */ // matrix solver UmfpackSolver solver; // DOF and CPU convergence graphs SimpleGraph graph_dof_est, graph_cpu_est; // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // coarse problem LinSystem sys(&wf, &solver); sys.set_spaces(1, &space); sys.set_pss(1, &pss); sys.assemble(); sys.solve(1, &sln_coarse); // time measurement cpu += end_time(); // show real part of the solution AbsFilter abs(&sln_coarse); eview.set_min_max_range(0, 4e3); eview.show(&abs); ord.show(&space); // time measurement begin_time(); // solve the fine mesh problem RefSystem ref(&sys); ref.assemble(); ref.solve(1, &sln_fine); // calculate error estimate wrt. fine mesh solution HcurlOrthoHP hp(1, &space); hp.set_biform(0, 0, callback(hcurl_form_kappa)); double err_est_adapt = hp.calc_error(&sln_coarse, &sln_fine) * 100; double err_est_hcurl = hcurl_error(&sln_coarse, &sln_fine) * 100; info("Error estimate (adapt): %g%%", err_est_adapt); info("Error estimate (hcurl): %g%%", err_est_hcurl); // add entries to DOF convergence graphs graph_dof_est.add_values(space.get_num_dofs(), err_est_hcurl); graph_dof_est.save("conv_dof_est.dat"); // add entries to CPU convergence graphs graph_cpu_est.add_values(cpu, err_est_hcurl); graph_cpu_est.save("conv_cpu_est.dat"); // if err_est_adapt too large, adapt the mesh if (err_est_adapt < ERR_STOP) done = true; else { hp.adapt(THRESHOLD, STRATEGY, ADAPT_TYPE, ISO_ONLY, MESH_REGULARITY); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); } while (done == false); verbose("Total running time: %g sec", cpu); // wait for keyboard or mouse input View::wait("Waiting for all views to be closed."); return 0; }
int main(int argc, char* argv[]) { // Time measurement. Hermes::Mixins::TimeMeasurable cpu_time; cpu_time.tick(); // Load the mesh. MeshSharedPtr u_mesh(new Mesh), v_mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", u_mesh); if (MULTI == false) u_mesh->refine_towards_boundary("Bdy", INIT_REF_BDY); // Create initial mesh (master mesh). v_mesh->copy(u_mesh); // Initial mesh refinements in the v_mesh towards the boundary. if (MULTI == true) v_mesh->refine_towards_boundary("Bdy", INIT_REF_BDY); // Set exact solutions. MeshFunctionSharedPtr<double> exact_u(new ExactSolutionFitzHughNagumo1(u_mesh)); MeshFunctionSharedPtr<double> exact_v(new ExactSolutionFitzHughNagumo2(v_mesh, K)); // Define right-hand sides. CustomRightHandSide1 g1(K, D_u, SIGMA); CustomRightHandSide2 g2(K, D_v); // Initialize the weak formulation. CustomWeakForm wf(&g1, &g2); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_u("Bdy", 0.0); EssentialBCs<double> bcs_u(&bc_u); DefaultEssentialBCConst<double> bc_v("Bdy", 0.0); EssentialBCs<double> bcs_v(&bc_v); // Create H1 spaces with default shapeset for both displacement components. SpaceSharedPtr<double> u_space(new H1Space<double>(u_mesh, &bcs_u, P_INIT_U)); SpaceSharedPtr<double> v_space(new H1Space<double>(MULTI ? v_mesh : u_mesh, &bcs_v, P_INIT_V)); Hermes::vector<SpaceSharedPtr<double> > spaces(u_space, v_space); // Set the spaces to adaptivity. adaptivity.set_spaces(spaces); // Initialize coarse and reference mesh solutions. MeshFunctionSharedPtr<double> u_sln(new Solution<double>), v_sln(new Solution<double>), u_ref_sln(new Solution<double>), v_ref_sln(new Solution<double>); // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, H2DRS_DEFAULT_ORDER); // Initialize views. Views::ScalarView s_view_0("Solution[0]", new Views::WinGeom(0, 0, 440, 350)); s_view_0.show_mesh(false); Views::OrderView o_view_0("Mesh[0]", new Views::WinGeom(450, 0, 420, 350)); Views::ScalarView s_view_1("Solution[1]", new Views::WinGeom(880, 0, 440, 350)); s_view_1.show_mesh(false); Views::OrderView o_view_1("Mesh[1]", new Views::WinGeom(1330, 0, 420, 350)); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est; SimpleGraph graph_dof_exact, graph_cpu_exact; // Newton NewtonSolver<double> newton(&wf, spaces); newton.set_tolerance(1e-1, Hermes::Solvers::ResidualNormAbsolute); // Adaptivity loop: int as = 1; bool done = false; do { Hermes::Mixins::Loggable::Static::info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Mesh::ReferenceMeshCreator u_ref_mesh_creator(u_mesh); MeshSharedPtr u_ref_mesh = u_ref_mesh_creator.create_ref_mesh(); Mesh::ReferenceMeshCreator v_ref_mesh_creator(v_mesh); MeshSharedPtr v_ref_mesh = v_ref_mesh_creator.create_ref_mesh(); Space<double>::ReferenceSpaceCreator u_ref_space_creator(u_space, u_ref_mesh); SpaceSharedPtr<double> u_ref_space = u_ref_space_creator.create_ref_space(); Space<double>::ReferenceSpaceCreator v_ref_space_creator(v_space, v_ref_mesh); SpaceSharedPtr<double> v_ref_space = v_ref_space_creator.create_ref_space(); Hermes::vector<SpaceSharedPtr<double> > ref_spaces(u_ref_space, v_ref_space); int ndof_ref = Space<double>::get_num_dofs(ref_spaces); // Initialize reference problem. Hermes::Mixins::Loggable::Static::info("Solving on reference mesh."); // Time measurement. cpu_time.tick(); // Perform Newton's iteration. try { newton.set_spaces(ref_spaces); newton.solve(); } catch(std::exception& e) { std::cout << e.what(); } // Translate the resulting coefficient vector into the instance of Solution. Solution<double>::vector_to_solutions(newton.get_sln_vector(), ref_spaces, Hermes::vector<MeshFunctionSharedPtr<double> >(u_ref_sln, v_ref_sln)); // Project the fine mesh solution onto the coarse mesh. Hermes::Mixins::Loggable::Static::info("Projecting reference solution on coarse mesh."); OGProjection<double>::project_global(spaces, Hermes::vector<MeshFunctionSharedPtr<double> >(u_ref_sln, v_ref_sln), Hermes::vector<MeshFunctionSharedPtr<double> >(u_sln, v_sln)); cpu_time.tick(); // View the coarse mesh solution and polynomial orders. s_view_0.show(u_sln); o_view_0.show(u_space); s_view_1.show(v_sln); o_view_1.show(v_space); // Calculate element errors and total error estimate. errorCalculator.calculate_errors(Hermes::vector<MeshFunctionSharedPtr<double> >(u_sln, v_sln), Hermes::vector<MeshFunctionSharedPtr<double> >(exact_u, exact_v), false); double err_exact_rel = errorCalculator.get_total_error_squared() * 100; // Calculate exact error. errorCalculator.calculate_errors(Hermes::vector<MeshFunctionSharedPtr<double> >(u_sln, v_sln), Hermes::vector<MeshFunctionSharedPtr<double> >(u_ref_sln, v_ref_sln)); double err_est_rel = errorCalculator.get_total_error_squared() * 100; // Time measurement. cpu_time.tick(); // Report results. Hermes::Mixins::Loggable::Static::info("ndof_coarse[0]: %d, ndof_fine[0]: %d", u_space->get_num_dofs(), u_ref_space->get_num_dofs()); Hermes::Mixins::Loggable::Static::info("ndof_coarse[1]: %d, ndof_fine[1]: %d", v_space->get_num_dofs(), v_ref_space->get_num_dofs()); Hermes::Mixins::Loggable::Static::info("ndof_coarse_total: %d, ndof_fine_total: %d", Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space)), Space<double>::get_num_dofs(ref_spaces)); Hermes::Mixins::Loggable::Static::info("err_est_rel_total: %g%%, err_est_exact_total: %g%%", err_est_rel, err_exact_rel); // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space)), err_est_rel); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu_est.save("conv_cpu_est.dat"); graph_dof_exact.add_values(Space<double>::get_num_dofs(Hermes::vector<SpaceSharedPtr<double> >(u_space, v_space)), err_exact_rel); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel); graph_cpu_exact.save("conv_cpu_exact.dat"); // If err_est too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { Hermes::Mixins::Loggable::Static::info("Adapting coarse mesh."); done = adaptivity.adapt(Hermes::vector<RefinementSelectors::Selector<double> *>(&selector, &selector)); } // Increase counter. as++; } while (done == false); Hermes::Mixins::Loggable::Static::info("Total running time: %g s", cpu_time.accumulated()); // Wait for all views to be closed. Views::View::wait(); return 0; }
int main(int argc, char* argv[]) { // Choose a Butcher's table or define your own. ButcherTable bt(butcher_table_type); if (bt.is_explicit()) info("Using a %d-stage explicit R-K method.", bt.get_size()); if (bt.is_diagonally_implicit()) info("Using a %d-stage diagonally implicit R-K method.", bt.get_size()); if (bt.is_fully_implicit()) info("Using a %d-stage fully implicit R-K method.", bt.get_size()); // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinemets. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize solutions. CustomInitialConditionWave E_sln(&mesh); ZeroSolution B_sln(&mesh); Hermes::vector<Solution<double>*> slns(&E_sln, &B_sln); // Initialize the weak formulation. CustomWeakFormWave wf(C_SQUARED); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_essential("Perfect conductor", 0.0); EssentialBCs<double> bcs_E(&bc_essential); EssentialBCs<double> bcs_B; // Create x- and y- displacement space using the default H1 shapeset. HcurlSpace<double> E_space(&mesh, &bcs_E, P_INIT); H1Space<double> B_space(&mesh, &bcs_B, P_INIT); Hermes::vector<const Space<double> *> spaces(&E_space, &B_space); Hermes::vector<Space<double> *> spaces_mutable(&E_space, &B_space); info("ndof = %d.", Space<double>::get_num_dofs(spaces)); // Initialize views. ScalarView E1_view("Solution E1", new WinGeom(0, 0, 400, 350)); E1_view.fix_scale_width(50); ScalarView E2_view("Solution E2", new WinGeom(410, 0, 400, 350)); E2_view.fix_scale_width(50); ScalarView B_view("Solution B", new WinGeom(0, 405, 400, 350)); B_view.fix_scale_width(50); // Initialize Runge-Kutta time stepping. RungeKutta<double> runge_kutta(&wf, spaces_mutable, &bt, matrix_solver); // Time stepping loop. double current_time = time_step; int ts = 1; do { // Perform one Runge-Kutta time step according to the selected Butcher's table. info("Runge-Kutta time step (t = %g s, time_step = %g s, stages: %d).", current_time, time_step, bt.get_size()); bool jacobian_changed = false; bool verbose = true; try { runge_kutta.rk_time_step_newton(current_time, time_step, slns, slns, jacobian_changed, verbose); } catch(Exceptions::Exception& e) { e.printMsg(); error("Runge-Kutta time step failed"); } // Visualize the solutions. char title[100]; sprintf(title, "E1, t = %g", current_time); E1_view.set_title(title); E1_view.show(&E_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_0); sprintf(title, "E2, t = %g", current_time); E2_view.set_title(title); E2_view.show(&E_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_1); sprintf(title, "B, t = %g", current_time); B_view.set_title(title); B_view.show(&B_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_0); // Update time. current_time += time_step; } while (current_time < T_FINAL); // Wait for the view to be closed. View::wait(); return 0; }