20 #include "discrete_problem.h"
21 #include "newton_solver_nox.h"
22 #if(defined HAVE_NOX && defined HAVE_EPETRA && defined HAVE_TEUCHOS)
28 template<
typename Scalar>
29 OGProjectionNOX<Scalar>::OGProjectionNOX() : ndof(0)
33 template<
typename Scalar>
34 void OGProjectionNOX<Scalar>::project_internal(
const Space<Scalar>* space, WeakForm<Scalar>* wf,
35 Scalar* target_vec,
double newton_tol,
int newton_max_iter)
39 throw Hermes::Exceptions::Exception(
"this->space == NULL in project_internal().");
42 int ndof = space->get_num_dofs();
45 DiscreteProblem<Scalar> dp(wf, space);
48 Scalar* coeff_vec =
new Scalar[ndof];
49 memset(coeff_vec, 0, ndof*
sizeof(Scalar));
51 const char* iterative_method =
"GMRES";
54 const char* preconditioner =
"New Ifpack";
59 unsigned message_type = NOX::Utils::Error | NOX::Utils::Warning | NOX::Utils::OuterIteration | NOX::Utils::InnerIteration | NOX::Utils::Parameters | NOX::Utils::LinearSolverDetails;
61 double ls_tolerance = 1e-5;
62 unsigned flag_absresid = 0;
63 double abs_resid = 1.0e-3;
64 unsigned flag_relresid = 1;
65 double rel_resid = newton_tol;
66 int max_iters = newton_max_iter;
69 NewtonSolverNOX<Scalar> newton_nox(&dp);
72 newton_nox.set_verbose_output(
false);
73 newton_nox.set_output_flags(message_type);
74 newton_nox.set_ls_type(iterative_method);
75 newton_nox.set_ls_tolerance(ls_tolerance);
76 newton_nox.set_conv_iters(max_iters);
78 newton_nox.set_conv_abs_resid(abs_resid);
80 newton_nox.set_conv_rel_resid(rel_resid);
81 newton_nox.set_precond(preconditioner);
82 newton_nox.set_precond_reuse(
"Rebuild");
85 newton_nox.solve(coeff_vec);
89 if(target_vec != NULL)
90 for (
int i = 0; i < ndof; i++)
91 target_vec[i] = newton_nox.get_sln_vector()[i];
94 template<
typename Scalar>
95 void OGProjectionNOX<Scalar>::project_global(
const Space<Scalar>* space,
96 MatrixFormVol<Scalar>* custom_projection_jacobian,
97 VectorFormVol<Scalar>* custom_projection_residual,
99 double newton_tol,
int newton_max_iter)
102 WeakForm<Scalar>* proj_wf =
new WeakForm<Scalar>(1);
103 proj_wf->add_matrix_form(custom_projection_jacobian);
104 proj_wf->add_vector_form(custom_projection_residual);
113 template<
typename Scalar>
114 void OGProjectionNOX<Scalar>::project_global(
const Space<Scalar>* space,
115 MeshFunction<Scalar>* source_meshfn, Scalar* target_vec,
117 double newton_tol,
int newton_max_iter)
120 if(target_vec == NULL)
throw Exceptions::NullException(3);
125 if(proj_norm == HERMES_UNSET_NORM)
127 SpaceType space_type = space->get_type();
130 case HERMES_H1_SPACE: norm = HERMES_H1_NORM;
break;
131 case HERMES_HCURL_SPACE: norm = HERMES_HCURL_NORM;
break;
132 case HERMES_HDIV_SPACE: norm = HERMES_HDIV_NORM;
break;
133 case HERMES_L2_SPACE: norm = HERMES_L2_NORM;
break;
134 default:
throw Hermes::Exceptions::Exception(
"Unknown space type in OGProjectionNOX<Scalar>::project_global().");
137 else norm = proj_norm;
140 WeakForm<Scalar>* proj_wf =
new WeakForm<Scalar>(1);
141 proj_wf->set_ext(source_meshfn);
143 proj_wf->add_matrix_form(
new ProjectionMatrixFormVol(0, 0, norm));
145 proj_wf->add_vector_form(
new ProjectionVectorFormVol(0, norm));
154 template<
typename Scalar>
155 void OGProjectionNOX<Scalar>::project_global(
const Space<Scalar>* space,
156 Solution<Scalar>* source_sln, Solution<Scalar>* target_sln,
158 double newton_tol,
int newton_max_iter)
160 if(proj_norm == HERMES_UNSET_NORM)
162 SpaceType space_type = space->get_type();
165 case HERMES_H1_SPACE: proj_norm = HERMES_H1_NORM;
break;
166 case HERMES_HCURL_SPACE: proj_norm = HERMES_HCURL_NORM;
break;
167 case HERMES_HDIV_SPACE: proj_norm = HERMES_HDIV_NORM;
break;
168 case HERMES_L2_SPACE: proj_norm = HERMES_L2_NORM;
break;
169 default:
throw Hermes::Exceptions::Exception(
"Unknown space type in OGProjectionNOX<Scalar>::project_global().");
174 int ndof = space->get_num_dofs();
175 Scalar* target_vec =
new Scalar[ndof];
176 project_global(space, source_sln, target_vec, proj_norm, newton_tol, newton_max_iter);
179 Solution<Scalar>::vector_to_solution(target_vec, space, target_sln);
182 delete [] target_vec;
185 template<
typename Scalar>
186 void OGProjectionNOX<Scalar>::project_global(Hermes::vector<
const Space<Scalar>*> spaces,
187 Hermes::vector<MeshFunction<Scalar>*> source_meshfns,
188 Scalar* target_vec, Hermes::vector<ProjNormType> proj_norms,
189 double newton_tol,
int newton_max_iter)
191 int n = spaces.size();
194 if(n != source_meshfns.size())
throw Exceptions::LengthException(1, 2, n, source_meshfns.size());
195 if(target_vec == NULL)
throw Exceptions::NullException(3);
196 if(!proj_norms.empty() && n != proj_norms.size())
throw Exceptions::LengthException(1, 5, n, proj_norms.size());
199 for (
int i = 0; i < n; i++)
201 if(proj_norms.empty())
202 project_global(spaces[i], source_meshfns[i], target_vec + start_index, HERMES_UNSET_NORM, newton_tol, newton_max_iter);
204 project_global(spaces[i], source_meshfns[i], target_vec + start_index, proj_norms[i], newton_tol, newton_max_iter);
205 spaces[i]->assign_dofs(start_index);
206 start_index += spaces[i]->get_num_dofs();
210 template<
typename Scalar>
211 void OGProjectionNOX<Scalar>::project_global(Hermes::vector<
const Space<Scalar>*> spaces, Hermes::vector<Solution<Scalar>*> source_slns,
212 Scalar* target_vec, Hermes::vector<ProjNormType> proj_norms,
213 double newton_tol,
int newton_max_iter)
215 int n = spaces.size();
218 if(n != source_slns.size())
throw Exceptions::LengthException(1, 2, n, source_slns.size());
219 if(target_vec == NULL)
throw Exceptions::NullException(3);
220 if(!proj_norms.empty() && n != proj_norms.size())
throw Exceptions::LengthException(1, 5, n, proj_norms.size());
223 for (
int i = 0; i < n; i++)
225 if(proj_norms.empty())
226 project_global(spaces[i], source_slns[i], target_vec + start_index, HERMES_UNSET_NORM, newton_tol, newton_max_iter);
228 project_global(spaces[i], source_slns[i], target_vec + start_index, proj_norms[i], newton_tol, newton_max_iter);
229 start_index += spaces[i]->get_num_dofs();
233 template<
typename Scalar>
234 void OGProjectionNOX<Scalar>::project_global(Hermes::vector<
const Space<Scalar>*> spaces, Hermes::vector<Solution<Scalar>*> source_slns,
235 Hermes::vector<Solution<Scalar>*> target_slns,
236 Hermes::vector<ProjNormType> proj_norms,
bool delete_old_meshes,
237 double newton_tol,
int newton_max_iter)
239 int n = spaces.size();
242 if(n != source_slns.size())
throw Exceptions::LengthException(1, 2, n, source_slns.size());
243 if(n != target_slns.size())
throw Exceptions::LengthException(1, 2, n, target_slns.size());
244 if(!proj_norms.empty() && n != proj_norms.size())
throw Exceptions::LengthException(1, 5, n, proj_norms.size());
247 for (
int i = 0; i < n; i++)
249 if(proj_norms.empty())
250 project_global(spaces[i], source_slns[i], target_slns[i], HERMES_UNSET_NORM, newton_tol, newton_max_iter);
252 project_global(spaces[i], source_slns[i], target_slns[i], proj_norms[i], newton_tol, newton_max_iter);
253 start_index += spaces[i]->get_num_dofs();
257 template class HERMES_API OGProjectionNOX<double>;