20 #include "discrete_problem/discrete_problem.h"
21 #include "solver/nox_solver.h"
22 #if(defined HAVE_NOX && defined HAVE_EPETRA && defined HAVE_TEUCHOS)
28 template<
typename Scalar>
29 void OGProjectionNOX<Scalar>::project_internal(SpaceSharedPtr<Scalar> space, WeakForm<Scalar>* wf,
30 Scalar* target_vec,
double newton_tol,
int newton_max_iter)
34 throw Hermes::Exceptions::Exception(
"this->space == nullptr in project_internal().");
37 int ndof = space->get_num_dofs();
40 DiscreteProblemNOX<Scalar> dp(wf, space);
43 Scalar* coeff_vec = calloc_with_check<Scalar>(ndof);
46 const char* iterative_method =
"GMRES";
50 const char* preconditioner =
"New Ifpack";
55 unsigned message_type = NOX::Utils::Error | NOX::Utils::Warning | NOX::Utils::OuterIteration | NOX::Utils::InnerIteration | NOX::Utils::Parameters | NOX::Utils::LinearSolverDetails;
58 double ls_tolerance = 1e-5;
60 unsigned flag_absresid = 0;
62 double abs_resid = 1.0e-3;
64 unsigned flag_relresid = 1;
66 double rel_resid = newton_tol;
68 int max_iters = newton_max_iter;
71 NewtonSolverNOX<Scalar> newton_nox(&dp);
74 newton_nox.set_verbose_output(
false);
75 newton_nox.set_output_flags(message_type);
76 newton_nox.set_ls_type(iterative_method);
77 newton_nox.set_ls_tolerance(ls_tolerance);
78 newton_nox.set_conv_iters(max_iters);
80 newton_nox.set_conv_abs_resid(abs_resid);
82 newton_nox.set_conv_rel_resid(rel_resid);
83 newton_nox.set_precond(preconditioner);
84 newton_nox.set_precond_reuse(
"Rebuild");
87 newton_nox.solve(coeff_vec);
89 free_with_check(coeff_vec);
91 if (target_vec !=
nullptr)
92 for (
int i = 0; i < ndof; i++)
93 target_vec[i] = newton_nox.get_sln_vector()[i];
96 template<
typename Scalar>
97 void OGProjectionNOX<Scalar>::project_global(SpaceSharedPtr<Scalar> space,
98 MatrixFormVol<Scalar>* custom_projection_jacobian,
99 VectorFormVol<Scalar>* custom_projection_residual,
101 double newton_tol,
int newton_max_iter)
104 WeakForm<Scalar>* proj_wf =
new WeakForm<Scalar>(1);
105 proj_wf->add_matrix_form(custom_projection_jacobian);
106 proj_wf->add_vector_form(custom_projection_residual);
109 project_internal(space, proj_wf, target_vec, newton_tol, newton_max_iter);
115 template<
typename Scalar>
116 void OGProjectionNOX<Scalar>::project_global(SpaceSharedPtr<Scalar> space,
117 MeshFunction<Scalar>* source_meshfn, Scalar* target_vec,
119 double newton_tol,
int newton_max_iter)
122 if (target_vec ==
nullptr)
throw Exceptions::NullException(3);
127 if (proj_norm == HERMES_UNSET_NORM)
129 SpaceType space_type = space->get_type();
132 case HERMES_H1_SPACE: norm = HERMES_H1_NORM;
break;
133 case HERMES_HCURL_SPACE: norm = HERMES_HCURL_NORM;
break;
134 case HERMES_HDIV_SPACE: norm = HERMES_HDIV_NORM;
break;
135 case HERMES_L2_SPACE: norm = HERMES_L2_NORM;
break;
136 case HERMES_L2_MARKERWISE_CONST_SPACE: norm = HERMES_L2_NORM;
break;
137 default:
throw Hermes::Exceptions::Exception(
"Unknown space type in OGProjectionNOX<Scalar>::project_global().");
140 else norm = proj_norm;
143 WeakForm<Scalar>* proj_wf =
new WeakForm<Scalar>(1);
144 proj_wf->set_ext(source_meshfn);
146 proj_wf->add_matrix_form(
new ProjectionMatrixFormVol(0, 0, norm));
148 proj_wf->add_vector_form(
new ProjectionVectorFormVol(0, norm));
151 project_internal(space, proj_wf, target_vec, newton_tol, newton_max_iter);
157 template<
typename Scalar>
158 void OGProjectionNOX<Scalar>::project_global(SpaceSharedPtr<Scalar> space,
159 MeshFunctionSharedPtr<Scalar> source_meshfn, Scalar* target_vec,
161 double newton_tol,
int newton_max_iter)
163 project_global(space, source_meshfn.get(), target_vec, proj_norm, newton_tol, newton_max_iter);
166 template<
typename Scalar>
167 void OGProjectionNOX<Scalar>::project_global(SpaceSharedPtr<Scalar> space,
168 MeshFunctionSharedPtr<Scalar> source_sln, MeshFunctionSharedPtr<Scalar> target_sln,
170 double newton_tol,
int newton_max_iter)
172 if (proj_norm == HERMES_UNSET_NORM)
174 SpaceType space_type = space->get_type();
177 case HERMES_H1_SPACE: proj_norm = HERMES_H1_NORM;
break;
178 case HERMES_HCURL_SPACE: proj_norm = HERMES_HCURL_NORM;
break;
179 case HERMES_HDIV_SPACE: proj_norm = HERMES_HDIV_NORM;
break;
180 case HERMES_L2_SPACE: proj_norm = HERMES_L2_NORM;
break;
181 case HERMES_L2_MARKERWISE_CONST_SPACE: proj_norm = HERMES_L2_NORM;
break;
182 default:
throw Hermes::Exceptions::Exception(
"Unknown space type in OGProjectionNOX<Scalar>::project_global().");
187 int ndof = space->get_num_dofs();
188 Scalar* target_vec = malloc_with_check<Scalar>(ndof);
189 project_global(space, source_sln, target_vec, proj_norm, newton_tol, newton_max_iter);
192 Solution<Scalar>::vector_to_solution(target_vec, space, target_sln);
195 free_with_check(target_vec);
198 template<
typename Scalar>
199 void OGProjectionNOX<Scalar>::project_global(std::vector<SpaceSharedPtr<Scalar> > spaces,
200 std::vector<MeshFunction<Scalar>* > source_meshfns,
201 Scalar* target_vec, std::vector<NormType> proj_norms,
202 double newton_tol,
int newton_max_iter)
204 int n = spaces.size();
207 if (n != source_meshfns.size())
throw Exceptions::LengthException(1, 2, n, source_meshfns.size());
208 if (target_vec ==
nullptr)
throw Exceptions::NullException(3);
209 if (!proj_norms.empty() && n != proj_norms.size())
throw Exceptions::LengthException(1, 5, n, proj_norms.size());
212 for (
int i = 0; i < n; i++)
214 if (proj_norms.empty())
215 project_global(spaces[i], source_meshfns[i], target_vec + start_index, HERMES_UNSET_NORM, newton_tol, newton_max_iter);
217 project_global(spaces[i], source_meshfns[i], target_vec + start_index, proj_norms[i], newton_tol, newton_max_iter);
218 spaces[i]->assign_dofs(start_index);
219 start_index += spaces[i]->get_num_dofs();
223 template<
typename Scalar>
224 void OGProjectionNOX<Scalar>::project_global(std::vector<SpaceSharedPtr<Scalar> > spaces, std::vector<MeshFunctionSharedPtr<Scalar> > source_slns,
225 Scalar* target_vec, std::vector<NormType> proj_norms,
226 double newton_tol,
int newton_max_iter)
228 int n = spaces.size();
231 if (n != source_slns.size())
throw Exceptions::LengthException(1, 2, n, source_slns.size());
232 if (target_vec ==
nullptr)
throw Exceptions::NullException(3);
233 if (!proj_norms.empty() && n != proj_norms.size())
throw Exceptions::LengthException(1, 5, n, proj_norms.size());
236 for (
int i = 0; i < n; i++)
238 if (proj_norms.empty())
239 project_global(spaces[i], source_slns[i], target_vec + start_index, HERMES_UNSET_NORM, newton_tol, newton_max_iter);
241 project_global(spaces[i], source_slns[i], target_vec + start_index, proj_norms[i], newton_tol, newton_max_iter);
242 start_index += spaces[i]->get_num_dofs();
246 template<
typename Scalar>
247 void OGProjectionNOX<Scalar>::project_global(std::vector<SpaceSharedPtr<Scalar> > spaces, std::vector<MeshFunctionSharedPtr<Scalar> > source_slns,
248 std::vector<MeshFunctionSharedPtr<Scalar> > target_slns,
249 std::vector<NormType> proj_norms,
bool delete_old_meshes,
250 double newton_tol,
int newton_max_iter)
252 int n = spaces.size();
255 if (n != source_slns.size())
throw Exceptions::LengthException(1, 2, n, source_slns.size());
256 if (n != target_slns.size())
throw Exceptions::LengthException(1, 2, n, target_slns.size());
257 if (!proj_norms.empty() && n != proj_norms.size())
throw Exceptions::LengthException(1, 5, n, proj_norms.size());
260 for (
int i = 0; i < n; i++)
262 if (proj_norms.empty())
263 project_global(spaces[i], source_slns[i], target_slns[i], HERMES_UNSET_NORM, newton_tol, newton_max_iter);
265 project_global(spaces[i], source_slns[i], target_slns[i], proj_norms[i], newton_tol, newton_max_iter);
266 start_index += spaces[i]->get_num_dofs();
270 template class HERMES_API OGProjectionNOX < double > ;
Orthogonal projection via NOX (matrix-free).