void OGProjectionNOX<Scalar>::project_global(SpaceSharedPtr<Scalar> space, MeshFunctionSharedPtr<Scalar> source_sln, MeshFunctionSharedPtr<Scalar> target_sln, NormType proj_norm, double newton_tol, int newton_max_iter) { if(proj_norm == HERMES_UNSET_NORM) { SpaceType space_type = space->get_type(); switch (space_type) { case HERMES_H1_SPACE: proj_norm = HERMES_H1_NORM; break; case HERMES_HCURL_SPACE: proj_norm = HERMES_HCURL_NORM; break; case HERMES_HDIV_SPACE: proj_norm = HERMES_HDIV_NORM; break; case HERMES_L2_SPACE: proj_norm = HERMES_L2_NORM; break; case HERMES_L2_MARKERWISE_CONST_SPACE: proj_norm = HERMES_L2_NORM; break; default: throw Hermes::Exceptions::Exception("Unknown space type in OGProjectionNOX<Scalar>::project_global()."); } } // Calculate the coefficient vector. int ndof = space->get_num_dofs(); Scalar* target_vec = new Scalar[ndof]; project_global(space, source_sln, target_vec, proj_norm, newton_tol, newton_max_iter); // Translate coefficient vector into a Solution. Solution<Scalar>::vector_to_solution(target_vec, space, target_sln); // Clean up. delete [] target_vec; }
void OGProjectionNOX<Scalar>::project_global(SpaceSharedPtr<Scalar> space, MeshFunctionSharedPtr<Scalar> source_meshfn, Scalar* target_vec, NormType proj_norm, double newton_tol, int newton_max_iter) { project_global(space, source_meshfn.get(), target_vec, proj_norm, newton_tol, newton_max_iter); }
void OGProjection<Scalar>::project_global(Hermes::vector<Space<Scalar>*> spaces, Hermes::vector<Solution<Scalar>*> source_sols, Scalar* target_vec, Hermes::MatrixSolverType matrix_solver_type, Hermes::vector<ProjNormType> proj_norms) { Hermes::vector<MeshFunction<Scalar>*> mesh_fns; for(unsigned int i = 0; i < source_sols.size(); i++) mesh_fns.push_back(source_sols[i]); project_global(spaces, mesh_fns, target_vec, matrix_solver_type, proj_norms); }
void OGProjection<Scalar>::project_global(Hermes::vector<SpaceSharedPtr<Scalar> > spaces, Hermes::vector<MeshFunctionSharedPtr<Scalar> > source_slns, Hermes::Algebra::Vector<Scalar>* target_vec, Hermes::vector<NormType> proj_norms) { if(target_vec->get_size() != Space<Scalar>::get_num_dofs(spaces)) throw Exceptions::ValueException("target_vec->size", target_vec->get_size(), Space<Scalar>::get_num_dofs(spaces)); Scalar* vec = new Scalar[target_vec->get_size()]; project_global(spaces, source_slns, vec, proj_norms); target_vec->set_vector(vec); delete [] vec; }
void OGProjectionNOX<Scalar>::project_global(Hermes::vector<SpaceSharedPtr<Scalar> > spaces, Hermes::vector<MeshFunctionSharedPtr<Scalar> > source_slns, Scalar* target_vec, Hermes::vector<NormType> proj_norms, double newton_tol, int newton_max_iter) { int n = spaces.size(); // Sanity checks. if(n != source_slns.size()) throw Exceptions::LengthException(1, 2, n, source_slns.size()); if(target_vec == nullptr) throw Exceptions::NullException(3); if(!proj_norms.empty() && n != proj_norms.size()) throw Exceptions::LengthException(1, 5, n, proj_norms.size()); int start_index = 0; for (int i = 0; i < n; i++) { if(proj_norms.empty()) project_global(spaces[i], source_slns[i], target_vec + start_index, HERMES_UNSET_NORM, newton_tol, newton_max_iter); else project_global(spaces[i], source_slns[i], target_vec + start_index, proj_norms[i], newton_tol, newton_max_iter); start_index += spaces[i]->get_num_dofs(); } }
void OGProjection<Scalar>::project_global(SpaceSharedPtr<Scalar> space, MeshFunctionSharedPtr<Scalar> source_meshfn, Hermes::Algebra::Vector<Scalar>* target_vec, NormType proj_norm) { if(target_vec->get_size() != space->get_num_dofs()) throw Exceptions::ValueException("target_vec->size", target_vec->get_size(), space->get_num_dofs()); Scalar* vec = new Scalar[target_vec->get_size()]; project_global(space, source_meshfn, vec, proj_norm); target_vec->set_vector(vec); delete [] vec; }
void OGProjection<Scalar>::project_global(Space<Scalar>* space, MeshFunction<Scalar>* source_meshfn, Scalar* target_vec, Hermes::MatrixSolverType matrix_solver_type, ProjNormType proj_norm) { Hermes::vector<Space<Scalar>*> spaces; spaces.push_back(space); Hermes::vector<MeshFunction<Scalar>*> source_meshfns; source_meshfns.push_back(source_meshfn); Hermes::vector<ProjNormType> proj_norms; proj_norms.push_back(proj_norm); project_global(spaces, source_meshfns, target_vec, matrix_solver_type, proj_norms); }
void OGProjection<Scalar>::project_global(Hermes::vector<SpaceSharedPtr<Scalar> > spaces, Hermes::vector<MeshFunctionSharedPtr<Scalar> > source_slns, Hermes::vector<MeshFunctionSharedPtr<Scalar> > target_slns, Hermes::vector<NormType> proj_norms, bool delete_old_meshes) { int n = spaces.size(); // Sanity checks. if(n != source_slns.size()) throw Exceptions::LengthException(1, 2, n, source_slns.size()); if(n != target_slns.size()) throw Exceptions::LengthException(1, 2, n, target_slns.size()); if(!proj_norms.empty() && n != proj_norms.size()) throw Exceptions::LengthException(1, 5, n, proj_norms.size()); int start_index = 0; for (int i = 0; i < n; i++) { if(proj_norms.empty()) project_global(spaces[i], source_slns[i], target_slns[i], HERMES_UNSET_NORM); else project_global(spaces[i], source_slns[i], target_slns[i], proj_norms[i]); start_index += spaces[i]->get_num_dofs(); } }
void OGProjection<Scalar>::project_global(SpaceSharedPtr<Scalar> space, MatrixFormVol<Scalar>* custom_projection_jacobian, VectorFormVol<Scalar>* custom_projection_residual, MeshFunctionSharedPtr<Scalar> target_sln) { // Calculate the coefficient vector. Scalar* target_vec = new Scalar[space->get_num_dofs()]; project_global(space, custom_projection_jacobian, custom_projection_residual, target_vec); // Translate coefficient vector into a Solution. Solution<Scalar>::vector_to_solution(target_vec, space, target_sln); // Clean up. delete [] target_vec; }
void OGProjection<Scalar>::project_global(const Hermes::vector<SpaceSharedPtr<Scalar> >& spaces, const Hermes::vector<MatrixFormVol<Scalar>*>& custom_projection_jacobians, const Hermes::vector<VectorFormVol<Scalar>*>& custom_projection_residuals, const Hermes::vector<MeshFunctionSharedPtr<Scalar> >& target_slns) { int n = spaces.size(); // Sanity checks. if (n != target_slns.size()) throw Exceptions::LengthException(1, 2, n, target_slns.size()); if (n != custom_projection_jacobians.size()) throw Exceptions::LengthException(1, 2, n, custom_projection_residuals.size()); if (n != custom_projection_residuals.size()) throw Exceptions::LengthException(1, 2, n, custom_projection_residuals.size()); for (int i = 0; i < n; i++) { project_global(spaces[i], custom_projection_jacobians[i], custom_projection_residuals[i], target_slns[i]); } }
void OGProjection<Scalar>::project_global(Space<Scalar>* space, Solution<Scalar>* sol_src, Solution<Scalar>* sol_dest, Hermes::MatrixSolverType matrix_solver_type, ProjNormType proj_norm) { Hermes::vector<Space<Scalar>*> spaces; spaces.push_back(space); Hermes::vector<Solution<Scalar>*> sols_src; sols_src.push_back(sol_src); Hermes::vector<Solution<Scalar>*> sols_dest; sols_dest.push_back(sol_dest); Hermes::vector<ProjNormType> proj_norms; if(proj_norm != HERMES_UNSET_NORM) proj_norms.push_back(proj_norm); project_global(spaces, sols_src, sols_dest, matrix_solver_type, proj_norms); }
void OGProjection<Scalar>::project_global(const Hermes::vector<SpaceSharedPtr<Scalar> >& spaces, const Hermes::vector<MatrixFormVol<Scalar>*>& custom_projection_jacobians, const Hermes::vector<VectorFormVol<Scalar>*>& custom_projection_residuals, Scalar* target_vec) { int n = spaces.size(); // Sanity checks. if(target_vec == nullptr) throw Exceptions::NullException(3); if (n != custom_projection_jacobians.size()) throw Exceptions::LengthException(1, 2, n, custom_projection_residuals.size()); if (n != custom_projection_residuals.size()) throw Exceptions::LengthException(1, 2, n, custom_projection_residuals.size()); int start_index = 0; for (int i = 0; i < n; i++) { project_global(spaces[i], custom_projection_jacobians[i], custom_projection_residuals[i], target_vec + start_index); start_index += spaces[i]->get_num_dofs(); } }
void OGProjection::project_global(Space *space, ExactFunction2 source_fn, scalar* target_vec, MatrixSolverType matrix_solver) { _F_ ProjNormType norm; ESpaceType space_type = space->get_type(); switch (space_type) { case HERMES_H1_SPACE: norm = HERMES_H1_NORM; break; case HERMES_HCURL_SPACE: norm = HERMES_HCURL_NORM; break; case HERMES_HDIV_SPACE: norm = HERMES_HDIV_NORM; break; case HERMES_L2_SPACE: norm = HERMES_L2_NORM; break; default: error("Unknown space type in OGProjection::project_global()."); } // Since the projected function is vector-valued, H1 and L2 spaces are not admissible. if (space_type == HERMES_H1_SPACE) error("Mismatched space and projection norm in OGProjection::project_global()."); if (space_type == HERMES_L2_SPACE) error("Mismatched space and projection norm in OGProjection::project_global()."); Mesh *mesh = space->get_mesh(); if (mesh == NULL) error("Mesh is NULL in project_global()."); Solution source_sln; source_sln.set_exact(mesh, source_fn); project_global(space, (MeshFunction*)&source_sln, target_vec, matrix_solver, norm); };
int main(int argc, char* argv[]) { // Read the command-line arguments. if (argc != 10) error("You must provide 5 real numbers (mesh vertices) and 4 integers (poly degrees)."); double x0 = atof(argv[1]); double x1 = atof(argv[2]); double x2 = atof(argv[3]); double x3 = atof(argv[4]); double x4 = atof(argv[5]); int o0 = atoi(argv[6]); int o1 = atoi(argv[7]); int o2 = atoi(argv[8]); int o3 = atoi(argv[9]); // Prepare mesh geometry. int nv = 10; double2 verts[10]; verts[0][0] = x0; verts[0][1] = 0; verts[1][0] = x1; verts[1][1] = 0; verts[2][0] = x2; verts[2][1] = 0; verts[3][0] = x3; verts[3][1] = 0; verts[4][0] = x4; verts[4][1] = 0; verts[5][0] = x0; verts[5][1] = 1; verts[6][0] = x1; verts[6][1] = 1; verts[7][0] = x2; verts[7][1] = 1; verts[8][0] = x3; verts[8][1] = 1; verts[9][0] = x4; verts[9][1] = 1; int nt = 0; int4* tris = NULL; int nq = 4; int5 quads[4]; quads[0][0] = 0; quads[0][1] = 1; quads[0][2] = 6; quads[0][3] = 5; quads[0][4] = 0; quads[1][0] = 1; quads[1][1] = 2; quads[1][2] = 7; quads[1][3] = 6; quads[1][4] = 0; quads[2][0] = 2; quads[2][1] = 3; quads[2][2] = 8; quads[2][3] = 7; quads[2][4] = 0; quads[3][0] = 3; quads[3][1] = 4; quads[3][2] = 9; quads[3][3] = 8; quads[3][4] = 0; int nm = 10; int3 mark[10]; mark[0][0] = 0; mark[0][1] = 1; mark[0][2] = 1; mark[1][0] = 1; mark[1][1] = 2; mark[1][2] = 1; mark[2][0] = 2; mark[2][1] = 3; mark[2][2] = 1; mark[3][0] = 3; mark[3][1] = 4; mark[3][2] = 1; mark[4][0] = 4; mark[4][1] = 9; mark[4][2] = 1; mark[5][0] = 9; mark[5][1] = 8; mark[5][2] = 1; mark[6][0] = 8; mark[6][1] = 7; mark[6][2] = 1; mark[7][0] = 7; mark[7][1] = 6; mark[7][2] = 1; mark[8][0] = 6; mark[8][1] = 5; mark[8][2] = 1; mark[9][0] = 5; mark[9][1] = 0; mark[9][2] = 1; // Create a mesh with 10 vertices, 4 elements and 10 boundary // edges from the above data. Mesh mesh; mesh.create(nv, verts, nt, tris, nq, quads, nm, mark); // Create an H1 space with default shapeset. H1Space space(&mesh, NULL, NULL, P_INIT); // Set element poly orders. space.set_element_order(0, H2D_MAKE_QUAD_ORDER(o0, 1)); space.set_element_order(1, H2D_MAKE_QUAD_ORDER(o1, 1)); space.set_element_order(2, H2D_MAKE_QUAD_ORDER(o2, 1)); space.set_element_order(3, H2D_MAKE_QUAD_ORDER(o3, 1)); // Perform orthogonal projection in the H1 norm. Solution sln_approx; ExactSolution sln_exact(&mesh, init_cond); project_global(&space, H2D_H1_NORM, &sln_exact, &sln_approx); // Calculate the error. double err = calc_abs_error(&sln_approx, &sln_exact, H2D_H1_NORM); printf("\nMesh: %g, %g, %g, %g, %g\n", x0, x1, x2, x3, x4); printf("Poly degrees: %d, %d, %d, %d\n", o0, o1, o2, o3); printf("err = %g, err_squared = %g\n\n", err, err*err); /* // Visualise the solution and mesh. WinGeom* sln_win_geom = new WinGeom(0, 0, 440, 350); ScalarView sview("Solution", sln_win_geom); sview.show(&sln_approx); WinGeom* mesh_win_geom = new WinGeom(450, 0, 400, 350); OrderView oview("Mesh", mesh_win_geom); oview.show(&space); // Wait for all views to be closed. View::wait(); return 0; */ }
int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinemets. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Create H1 spaces with default shapesets. H1Space* t_space = new H1Space(&mesh, bc_types, essential_bc_values_t, P_INIT); H1Space* c_space = new H1Space(&mesh, bc_types, essential_bc_values_c, P_INIT); int ndof = get_num_dofs(Tuple<Space *>(t_space, c_space)); info("ndof = %d.", ndof); // Define initial conditions. Solution t_prev_time_1, c_prev_time_1, t_prev_time_2, c_prev_time_2, t_iter, c_iter, t_prev_newton, c_prev_newton; t_prev_time_1.set_exact(&mesh, temp_ic); c_prev_time_1.set_exact(&mesh, conc_ic); t_prev_time_2.set_exact(&mesh, temp_ic); c_prev_time_2.set_exact(&mesh, conc_ic); t_iter.set_exact(&mesh, temp_ic); c_iter.set_exact(&mesh, conc_ic); // Filters for the reaction rate omega and its derivatives. DXDYFilter omega(omega_fn, Tuple<MeshFunction*>(&t_prev_time_1, &c_prev_time_1)); DXDYFilter omega_dt(omega_dt_fn, Tuple<MeshFunction*>(&t_prev_time_1, &c_prev_time_1)); DXDYFilter omega_dc(omega_dc_fn, Tuple<MeshFunction*>(&t_prev_time_1, &c_prev_time_1)); // Initialize visualization. ScalarView rview("Reaction rate", new WinGeom(0, 0, 800, 230)); // Initialize weak formulation. WeakForm wf(2, JFNK ? true : false); if (!JFNK || (JFNK && PRECOND == 1)) { wf.add_matrix_form(callback(newton_bilinear_form_0_0), H2D_UNSYM, H2D_ANY, &omega_dt); wf.add_matrix_form_surf(0, 0, callback(newton_bilinear_form_0_0_surf), 3); wf.add_matrix_form(1, 1, callback(newton_bilinear_form_1_1), H2D_UNSYM, H2D_ANY, &omega_dc); wf.add_matrix_form(0, 1, callback(newton_bilinear_form_0_1), H2D_UNSYM, H2D_ANY, &omega_dc); wf.add_matrix_form(1, 0, callback(newton_bilinear_form_1_0), H2D_UNSYM, H2D_ANY, &omega_dt); } else if (PRECOND == 2) { wf.add_matrix_form(0, 0, callback(precond_0_0)); wf.add_matrix_form(1, 1, callback(precond_1_1)); } wf.add_vector_form(0, callback(newton_linear_form_0), H2D_ANY, Tuple<MeshFunction*>(&t_prev_time_1, &t_prev_time_2, &omega)); wf.add_vector_form_surf(0, callback(newton_linear_form_0_surf), 3); wf.add_vector_form(1, callback(newton_linear_form_1), H2D_ANY, Tuple<MeshFunction*>(&c_prev_time_1, &c_prev_time_2, &omega)); // Project the functions "t_iter" and "c_iter" on the FE space // in order to obtain initial vector for NOX. info("Projecting initial solutions on the FE meshes."); Vector* coeff_vec = new AVector(ndof); project_global(Tuple<Space *>(t_space, c_space), Tuple<int>(H2D_H1_NORM, H2D_H1_NORM), Tuple<MeshFunction*>(&t_prev_time_1, &c_prev_time_1), Tuple<Solution*>(&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. FeProblem fep(&wf, Tuple<Space*>(t_space, c_space)); // Initialize NOX solver and preconditioner. NoxSolver solver(&fep); MlPrecond pc("sa"); if (PRECOND) { if (JFNK) solver.set_precond(&pc); else solver.set_precond("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 <= 60.0; ts++) { info("---- Time step %d, t = %g s", ts, total_time + TAU); cpu_time.tick(HERMES_SKIP); solver.set_init_sln(coeff_vec->get_c_array()); bool solved = solver.solve(); if (solved) { double* s = solver.get_solution_vector(); AVector *tmp_vector = new AVector(ndof); tmp_vector->set_c_array(s, ndof); t_prev_newton.set_fe_solution(t_space, tmp_vector); c_prev_newton.set_fe_solution(c_space, tmp_vector); delete tmp_vector; cpu_time.tick(); info("Number of nonlin iterations: %d (norm of residual: %g)", solver.get_num_iters(), solver.get_residual()); 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(HERMES_SKIP); // Visualization. DXDYFilter omega_view(omega_fn, Tuple<MeshFunction*>(&t_prev_newton, &c_prev_newton)); rview.set_min_max_range(0.0,2.0); cpu_time.tick(HERMES_SKIP); // Skip visualization time. cpu_time.tick(HERMES_SKIP); // Update global time. total_time += TAU; // Saving solutions for the next time step. t_prev_time_2.copy(&t_prev_time_1); c_prev_time_2.copy(&c_prev_time_1); t_prev_time_1 = t_prev_newton; c_prev_time_1 = c_prev_newton; } else error("NOX failed."); 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; }