27 #ifdef MANGO_PETSC_AVAILABLE
34 #ifdef MANGO_PETSC_AVAILABLE
40 PETSC_COMM_WORLD = MPI_COMM_SELF;
43 ierr = PetscInitialize(&(solver->
argc),&(solver->
argv),(
char *)0,
help);
44 if (ierr)
throw std::runtime_error(
"Error in PetscInitialize in mango::Package_petsc::optimize_least_squares().");
45 ierr = PetscInitializeFortran();
48 TaoCreate(PETSC_COMM_SELF, &my_tao);
51 VecCreateSeq(PETSC_COMM_SELF, N_parameters, &tao_state_vec);
53 VecCreateSeq(PETSC_COMM_SELF, N_terms, &tao_residual_vec);
55 MatCreateSeqDense(MPI_COMM_SELF,N_terms,N_parameters,NULL,&petsc_Jacobian);
59 VecGetArray(tao_state_vec, &temp_array);
60 memcpy(temp_array, solver->
state_vector, N_parameters *
sizeof(
double));
61 VecRestoreArray(tao_state_vec, &temp_array);
63 std::cout <<
"Here comes petsc vec for initial condition:" << std::endl;
64 VecView(tao_state_vec, PETSC_VIEWER_STDOUT_SELF);
66 TaoSetInitialVector(my_tao, tao_state_vec);
68 if (solver->
verbose > 0) std::cout <<
"PETSc has been initialized." << std::endl;
70 #if (PETSC_VERSION_MAJOR < 3 || (PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR < 11))
71 TaoSetSeparableObjectiveRoutine(my_tao, tao_residual_vec, &mango_petsc_residual_function, (
void*)solver);
73 TaoSetResidualRoutine(my_tao, tao_residual_vec, &mango_petsc_residual_function, (
void*)solver);
76 switch (solver->algorithm) {
78 TaoSetType(my_tao, TAOPOUNDERS);
81 #if (PETSC_VERSION_MAJOR < 3 || (PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR < 11))
82 throw std::runtime_error(
"The petsc_brgn algorithm requires PETSc version 3.11 or newer.");
84 TaoSetJacobianResidualRoutine(my_tao, petsc_Jacobian, petsc_Jacobian, &mango_petsc_Jacobian_function, (
void*)solver);
85 TaoSetType(my_tao, TAOBRGN);
89 std::cerr <<
"Should not get here! algorithm = " << solver->algorithm <<
" i.e. " <<
algorithms[solver->algorithm].
name << std::endl;
90 throw std::runtime_error(
"Error in mango::problem::optimize_least_squares_petsc()");
93 TaoSetMaximumFunctionEvaluations(my_tao, (PetscInt) solver->max_function_and_gradient_evaluations);
95 Vec lower_bounds_vec, upper_bounds_vec;
96 if (solver->bound_constraints_set) {
97 VecCreateSeq(PETSC_COMM_SELF, N_parameters, &lower_bounds_vec);
98 VecCreateSeq(PETSC_COMM_SELF, N_parameters, &upper_bounds_vec);
100 for (
int j=0; j<N_parameters; j++) {
101 VecSetValue(lower_bounds_vec, j, solver->lower_bounds[j], INSERT_VALUES);
102 VecSetValue(upper_bounds_vec, j, solver->upper_bounds[j], INSERT_VALUES);
104 VecAssemblyBegin(lower_bounds_vec);
105 VecAssemblyBegin(upper_bounds_vec);
106 VecAssemblyEnd(lower_bounds_vec);
107 VecAssemblyEnd(upper_bounds_vec);
109 TaoSetVariableBounds(my_tao, lower_bounds_vec, upper_bounds_vec);
113 TaoSetFromOptions(my_tao);
115 if (solver->verbose > 0) TaoView(my_tao, PETSC_VIEWER_STDOUT_SELF);
119 VecGetArray(tao_state_vec, &temp_array);
120 memcpy(solver->state_vector, temp_array, N_parameters *
sizeof(
double));
121 VecRestoreArray(tao_state_vec, &temp_array);
125 VecDestroy(&tao_state_vec);
130 throw std::runtime_error(
"Error! A PETSc algorithm was requested, but Mango was compiled without PETSc support.");
138 #ifdef MANGO_PETSC_AVAILABLE
139 PetscErrorCode mango::Package_petsc::mango_petsc_residual_function(Tao my_tao, Vec x, Vec f,
void* user_context) {
142 const double* x_array;
144 VecGetArrayRead(x, &x_array);
145 VecGetArray(f, &f_array);
155 std::cout <<
"mango_petsc_residual_function before sigma shift. state_vector:";
157 std::cout << std::setw(24) << std::setprecision(15) << x_array[j];
159 std::cout << std::endl;
160 std::cout <<
"residual:";
161 for (j=0; j < solver->
N_terms; j++) {
162 std::cout << std::setw(24) << std::setprecision(15) << f_array[j];
164 std::cout << std::endl << std::flush;
168 for (j=0; j<solver->
N_terms; j++) {
169 f_array[j] = (f_array[j] - solver->
targets[j]) / solver->
sigmas[j];
174 std::cout <<
"mango_petsc_residual_function after sigma shift. state_vector:";
176 std::cout << std::setw(24) << std::setprecision(15) << x_array[j];
178 std::cout << std::endl;
179 std::cout <<
"residual:";
180 for (j=0; j < solver->
N_terms; j++) {
181 std::cout << std::setw(24) << std::setprecision(15) << f_array[j];
183 std::cout << std::endl << std::flush;
186 VecRestoreArrayRead(x, &x_array);
187 VecRestoreArray(f, &f_array);
195 PetscErrorCode mango::Package_petsc::mango_petsc_Jacobian_function(Tao my_tao, Vec x, Mat Jacobian, Mat preconditioner,
void* user_context) {
197 const double* x_array;
198 double* Jacobian_array;
199 VecGetArrayRead(x, &x_array);
200 MatDenseGetArray(Jacobian, &Jacobian_array);
202 Least_squares_solver* solver = (Least_squares_solver*) user_context;
205 int N_terms = solver->N_terms;
207 assert(solver->mpi_partition->get_proc0_world());
209 if (solver->verbose > 0) {
210 std::cout <<
"mango_petsc_Jacobian_function before sigma shift. state_vector:";
211 for (j=0; j < N_parameters; j++) {
212 std::cout << std::setw(24) << std::setprecision(15) << x_array[j];
214 std::cout << std::endl << std::flush;
217 solver->finite_difference_Jacobian(x_array, solver->residuals, Jacobian_array);
223 for (
int j_parameter = 0; j_parameter < N_parameters; j_parameter++) {
224 for (
int j_term = 0; j_term < N_terms; j_term++) {
228 Jacobian_array[j_parameter*N_terms+j_term] /= solver->sigmas[j_term];
232 VecRestoreArrayRead(x, &x_array);
233 MatDenseRestoreArray(Jacobian, &Jacobian_array);