CArl
Code Arlequin / C++ implementation
FETI_operations_setup.cpp
Go to the documentation of this file.
1 #include "FETI_operations.h"
2 
3 namespace carl
4 {
5 // --- Protected methods
7 {
8  homemade_assert_msg(m_bC_RR_MatrixSet,"Preconditioner matrix not set yet!");
9 
10  KSPCreate(m_comm.get(), &m_coupling_precond_solver);
11  KSPSetOperators(m_coupling_precond_solver, m_C_RR, m_C_RR);
12  KSPSetFromOptions(m_coupling_precond_solver);
13 
15 }
16 
18 {
19  homemade_assert_msg(m_bC_RR_MatrixSet,"Preconditioner matrix not set yet!");
20 
21  // Create and set the vector
22  VecCreate(m_comm.get(),&m_coupling_jacobi_precond_vec);
24  VecSetFromOptions(m_coupling_jacobi_precond_vec);
25 
26  // Get the diagonal
27  MatGetDiagonal(m_C_RR,m_coupling_jacobi_precond_vec);
28 
29  // Calculate the reciprocal
30  VecReciprocal(m_coupling_jacobi_precond_vec);
31 
32  // Export it
33  write_PETSC_vector(m_coupling_jacobi_precond_vec,m_scratch_folder_path + "/precond_Jacobi_vector.petscvec",m_comm.rank(),m_comm.get());
34 
35 // Print MatLab debugging output? Variable defined at "carl_headers.h"
36 #ifdef PRINT_MATLAB_DEBUG
38 #endif
39 
40  // Set flag
42 }
43 
45 {
46  // Create and set the vector
47  VecCreate(m_comm.get(),&m_coupling_jacobi_precond_vec);
49 
50  // Read it
51  read_PETSC_vector(m_coupling_jacobi_precond_vec,m_scratch_folder_path + "/precond_Jacobi_vector.petscvec", m_comm.get());
52 
53  // Set flag
55 }
56 
58 {
59  homemade_assert_msg(m_bCreatedPrecondSolver,"Preconditioner system not set yet!");
60  KSPSolve(m_coupling_precond_solver, vec_in, vec_out);
61 }
62 
64 {
65  homemade_assert_msg(m_bCreatedPrecondJacobiVec,"Preconditioner vector not set yet!");
66  VecPointwiseMult(vec_out, m_coupling_jacobi_precond_vec, vec_in);
67 }
68 
69 void FETI_Operations::apply_precond(Vec vec_in, Vec vec_out)
70 {
71  switch (m_precond_type)
72  {
74  // Shouldn't call this function in this case
75  homemade_error_msg("No preconditioner to be applied!");
76  break;
77 
79  this->apply_inverse_coupling_precond(vec_in, vec_out);
80  break;
81 
83  this->apply_jacobi_coupling_precond(vec_in, vec_out);
84  break;
85  default :
86  // Undefined preconditioner
87  homemade_error_msg("Undefined preconditioner");
88  }
89 }
90 
91 void FETI_Operations::apply_RB_projection(Vec vec_in, Vec vec_out)
92 {
93  homemade_assert_msg(m_bNullVecsSet,"Null space vectors not set yet!");
94  homemade_assert_msg(m_binvRITRIMatSet,"Null space matrices not set yet!");
95 
96  // vec_out = [ I - RC * (inv_RITRI_mat) * RC^t ] * vec_in
97 
98  // Declaration of Vecs with size 'm_null_nb_vecs'
99  Vec dummy_seq_vec;
100  Vec dummy_seq_vec_bis;
101  VecCreateSeq(PETSC_COMM_SELF,m_null_nb_vecs,&dummy_seq_vec);
102  VecZeroEntries(dummy_seq_vec);
103  VecDuplicate(dummy_seq_vec,&dummy_seq_vec_bis);
104 
105  // dummy_seq_vec = RC^t * vec_in
106  // -> All the communications are done here!
107  PetscScalar *dummy_seq_array;
108  VecGetArray(dummy_seq_vec,&dummy_seq_array);
109  VecMDot(vec_in,m_null_nb_vecs,m_null_coupled_vecs,dummy_seq_array);
110  VecRestoreArray(dummy_seq_vec,&dummy_seq_array);
111 
112  // dummy_seq_vec_bis = - inv_RITRI_mat * dummy_seq_vec
113  // -> Calculate dummy_seq_vec_bis on the first proc, and then broadcast the value
114 
115  /*
116  * Originally, this operation was done locally, but due to a syncing issue,
117  * we have to do it this way to avoid a "Value must the same in all processors" error
118  * when calling VecMAXPY below.
119  */
120  PETSC_MatMultScale_Bcast(m_inv_RITRI_mat,dummy_seq_vec,dummy_seq_vec_bis,-1);
121 
122  m_comm.barrier();
123 
124  // vec_out = vec_in + sum ( dummy_seq_vec_bis[i] * vec_RC[i])
125  // -> This should have no communications at all!
126  VecCopy(vec_in,vec_out);
127 
128  VecGetArray(dummy_seq_vec_bis,&dummy_seq_array);
129  VecMAXPY(vec_out,m_null_nb_vecs,dummy_seq_array,m_null_coupled_vecs);
130  VecRestoreArray(dummy_seq_vec_bis,&dummy_seq_array);
131 
132  // Cleanup
133  VecDestroy(&dummy_seq_vec);
134  VecDestroy(&dummy_seq_vec_bis);
135 }
136 
138 {
139  homemade_assert_msg(m_bScratchFolderSet,"Scratch folder not set yet!");
140 
141  Vec vec_C_micro_t_p_kkk_PETSc;
142  VecCreate(m_comm.get(),&vec_C_micro_t_p_kkk_PETSc);
143  VecSetSizes(vec_C_micro_t_p_kkk_PETSc,m_C_R_micro_N_local,m_C_R_micro_N);
144  VecSetFromOptions(vec_C_micro_t_p_kkk_PETSc);
145 
146  Vec vec_C_BIG_t_p_kkk_PETSc;
147  VecCreate(m_comm.get(),&vec_C_BIG_t_p_kkk_PETSc);
148  VecSetSizes(vec_C_BIG_t_p_kkk_PETSc,m_C_R_BIG_N_local,m_C_R_BIG_N);
149  VecSetFromOptions(vec_C_BIG_t_p_kkk_PETSc);
150 
151  MatMultTranspose(m_C_R_micro,vec_in,vec_C_micro_t_p_kkk_PETSc);
152  MatMultTranspose(m_C_R_BIG,vec_in,vec_C_BIG_t_p_kkk_PETSc);
153 
154  write_PETSC_vector(vec_C_BIG_t_p_kkk_PETSc,m_scratch_folder_path + "/ext_solver_A_rhs.petscvec",m_comm.rank(),m_comm.get());
155  write_PETSC_vector(vec_C_micro_t_p_kkk_PETSc,m_scratch_folder_path + "/ext_solver_B_rhs.petscvec",m_comm.rank(),m_comm.get());
156 
157 // Print MatLab debugging output? Variable defined at "carl_headers.h"
158 #ifdef PRINT_MATLAB_DEBUG
159  write_PETSC_vector_MATLAB(vec_C_micro_t_p_kkk_PETSc,m_scratch_folder_path + "/ext_solver_B_rhs.m",m_comm.get());
160  write_PETSC_vector_MATLAB(vec_C_BIG_t_p_kkk_PETSc,m_scratch_folder_path + "/ext_solver_A_rhs.m",m_comm.get());
161 #endif
162 
163  VecDestroy(&vec_C_micro_t_p_kkk_PETSc);
164  VecDestroy(&vec_C_BIG_t_p_kkk_PETSc);
165 }
166 
168 {
170  MatDestroy(&m_C_R_BIG);
172  MatDestroy(&m_C_R_micro);
174  MatDestroy(&m_C_RR);
175  if(m_bNullVecsSet)
176  {
177  for(int iii = 0; iii < m_null_nb_vecs; ++iii)
178  VecDestroy(&m_null_vecs[iii]);
179  }
181  {
182  MatDestroy(&m_inv_RITRI_mat);
183  }
184  if(m_bSet_u_0)
185  {
186  VecDestroy(&m_u_0_BIG);
187  VecDestroy(&m_u_0_micro);
188  }
190  {
191  VecDestroy(&m_ext_solver_sol_BIG);
192  VecDestroy(&m_ext_solver_sol_micro);
193  }
195  {
196  VecDestroy(&m_current_phi);
197  }
199  {
200  VecDestroy(&m_current_residual);
201  }
203  {
204  KSPDestroy(&m_coupling_precond_solver);
205  }
207  {
208  VecDestroy(&m_coupling_jacobi_precond_vec);
209  }
211  {
212  VecDestroy(&m_current_rb_correction);
213  }
215  {
216  VecDestroy(&m_previous_residual);
217  }
219  {
220  VecDestroy(&m_previous_phi);
221  }
223  {
224  VecDestroyVecs(m_kkk+1,&m_previous_p_ptr);
225  delete[] m_previous_p_ptr;
226  }
228  {
229  VecDestroyVecs(m_kkk+1,&m_previous_q_ptr);
230  delete[] m_previous_q_ptr;
231  }
233  {
234  VecDestroy(&m_coupled_sol_micro);
235  VecDestroy(&m_coupled_sol_BIG);
236  }
237 }
238 
239 // --- Public methods
240 // --- Coupling matrix and preconditioner methods
241 void FETI_Operations::set_preconditioner(BaseCGPrecondType CG_precond_type, bool bInitialSet)
242 {
243  m_precond_type = CG_precond_type;
244 
245  switch (m_precond_type)
246  {
248  // Well ... nothing to do ...
249  break;
250 
252  // Read the mediator - mediator coupling matrix and set the solver
253  this->set_coupling_matrix_RR();
255  m_bC_RR_MatrixSet = true;
256  break;
257 
259  if(bInitialSet)
260  {
261  // Read the mediator - mediator coupling matrix and build the Jacobi coupling preconditioner vector
262  this->set_coupling_matrix_RR();
264  m_bC_RR_MatrixSet = true;
265  } else {
266  // Just read the Jacobi coupling preconditioner vector
268  m_bC_RR_MatrixSet = true;
269  }
270  break;
271  }
272 }
273 
274 // --- Null space / rigid body modes methods
275 void FETI_Operations::using_rb_modes(bool bUseRigidBodyModes)
276 {
277  m_bUsingNullVecs = bUseRigidBodyModes;
278 }
279 
280 void FETI_Operations::set_null_space(const std::string& input_filename_base, int nb_of_vecs)
281 {
282  homemade_assert_msg(m_bNullVecsDimensionsSet,"Null vectors sizes not set yet!");
283  homemade_assert_msg(m_bScratchFolderSet,"Scratch folder not set yet!");
284 
285  // Set the null vec arrays
286  m_null_nb_vecs = nb_of_vecs;
287 
288  // Set the (dummy) coupling matrix pointer
289  Mat * coupling_matrix;
290 
291  switch (m_RB_modes_system)
292  {
293  case RBModesSystem::MICRO :
294  coupling_matrix = &m_C_R_micro;
295  break;
296 
297  case RBModesSystem::MACRO :
298  // TODO: Remove the error message below after the more general code was implemented
299  homemade_error_msg("Option not implemented yet!");
300  coupling_matrix = &m_C_R_BIG;
301  break;
302  }
303 
304  // Matrix dimensions
305  // M x N
306  // coupling_matrix : n_med x n_sys
307  // m_null_vecs : n_sys x nb_of_vecs ( R ) -> nb_of_vecs vectors of dim n_sys
308  // m_null_coupled_vecs : n_med x nb_of_vecs ( RC ) -> nb_of_vecs vectors of dim n_coupl
309 
310  // Set the first nullspace vectors
311  std::string input_filename = input_filename_base + "_0_n_" + std::to_string(m_null_nb_vecs) + ".petscvec";
312  VecCreate(m_comm.get(),&m_null_vecs[0]);
314  read_PETSC_vector(m_null_vecs[0],input_filename, m_comm.get());
315 
316  std::string output_filename = m_scratch_folder_path + "/rb_coupl_vector_0_n_" + std::to_string(m_null_nb_vecs) + ".petscvec";
317  VecCreate(m_comm.get(),&m_null_coupled_vecs[0]);
319  VecSetFromOptions(m_null_coupled_vecs[0]);
320  MatMult(*coupling_matrix,m_null_vecs[0],m_null_coupled_vecs[0]);
321  write_PETSC_vector(m_null_coupled_vecs[0],output_filename,m_comm.rank(),m_comm.get());
322 
323  // Read and calculate the rest of the nullspace vectors
324  for(int iii = 1; iii < m_null_nb_vecs; ++iii)
325  {
326  input_filename = input_filename_base + "_" + std::to_string(iii) + "_n_" + std::to_string(m_null_nb_vecs) + ".petscvec";
327  VecDuplicate(m_null_vecs[0],&m_null_vecs[iii]);
328  read_PETSC_vector(m_null_vecs[iii],input_filename, m_comm.get());
329 
330  std::string output_filename = m_scratch_folder_path + "/rb_coupl_vector_" + std::to_string(iii) + "_n_" + std::to_string(m_null_nb_vecs) + ".petscvec";
331  VecDuplicate(m_null_coupled_vecs[0],&m_null_coupled_vecs[iii]);
332  MatMult(*coupling_matrix,m_null_vecs[iii],m_null_coupled_vecs[iii]);
333 
334  write_PETSC_vector(m_null_coupled_vecs[iii],output_filename,m_comm.rank(),m_comm.get());
335  }
336 
337  // Build the LOCAL dense matrix
338  std::vector<PetscScalar> dummy_vec_val(m_null_nb_vecs,0);
339  std::vector<PetscInt> dummy_vec_row(m_null_nb_vecs,0);
340 
341  for(PetscInt iii = 0; iii < m_null_nb_vecs; ++iii)
342  {
343  dummy_vec_row[iii] = iii;
344  }
345 
346  MatCreateSeqDense(PETSC_COMM_SELF,m_null_nb_vecs,m_null_nb_vecs,NULL,&m_RITRI_mat);
347 
348  for(PetscInt iii = 0; iii < m_null_nb_vecs; ++iii)
349  {
350  VecMDot(m_null_coupled_vecs[iii],m_null_nb_vecs,m_null_coupled_vecs,dummy_vec_val.data());
351  MatSetValues(m_RITRI_mat,m_null_nb_vecs,dummy_vec_row.data(),1,&iii,dummy_vec_val.data(),INSERT_VALUES);
352  }
353  MatAssemblyBegin(m_RITRI_mat,MAT_FINAL_ASSEMBLY);
354  MatAssemblyEnd(m_RITRI_mat,MAT_FINAL_ASSEMBLY);
355 
357 
358  if(m_comm.rank() == 0)
359  {
360  write_PETSC_matrix(m_inv_RITRI_mat,m_scratch_folder_path + "/rb_inv_RITRI.petscmat",0,PETSC_COMM_SELF);
361  }
362 
363  // Set up flag
364  m_bNullVecsSet = true;
365  m_binvRITRIMatSet = true;
366 
367  // Cleanup
368  MatDestroy(&m_RITRI_mat);
369 }
370 
371 }
Vec m_current_residual
Current residual vector, r(kkk+1) (r(0) for the initialization)
bool m_bC_RR_MatrixSet
Mediator - mediator coupling matrix has been set?
PetscInt m_null_nb_vecs
Number of null space vectors.
void set_null_space(const std::string &input_filename_base, int nb_of_vecs)
Set and print the null space vectors and matrices.
bool m_bSet_u_0
Have the u_0 vectors been set?
bool m_bNullVecsDimensionsSet
Have the null space vectors' dimensions been set?
#define homemade_error_msg(msg)
Definition: common_header.h:73
bool m_bSet_previous_residual
Have the previous r(kkk) vector been set?
Vec m_previous_phi
Previous Lagrange multipliers / solution, phi(kkk)
Mat m_C_RR
Mediator - mediator system coupling matrix.
bool m_binvRITRIMatSet
Have the inv(RI^T * RI) matrix been set?
void export_ext_solver_rhs(Vec vec_in)
Calculate and export the external solver RHS's.
KSP m_coupling_precond_solver
Preconditioner system solver.
Mat m_C_R_BIG
Mediator - macro system coupling matrix.
void write_PETSC_vector(libMesh::PetscVector< libMesh::Number > &input_vec, const std::string &filename, int dim=1)
Vec m_ext_solver_sol_micro
Micro model external solver solution.
Vec m_u_0_BIG
Solution of the decoupled macro model.
std::string m_scratch_folder_path
Scratch folder path.
Vec m_coupled_sol_micro
Coupled system solution for the micro model.
bool m_bC_R_BIG_MatrixSet
Mediator - macro coupling matrix has been set?
Vec * m_previous_p_ptr
Pointer to the previous p vectors, p(0 ... kkk)
Mat m_inv_RITRI_mat
Matrix , used in some projectors.
bool m_bSet_current_RB_correction
Have the RB modes correction RB_corr(kkk+1) vector been set?
void read_jacobi_precond_vector()
Read the Jacobi coupling matrix preconditioner vector.
Vec m_u_0_micro
Solution of the decoupled micro model.
void set_coupling_matrix_RR()
Read the mediator - mediator system coupling matrix.
Vec m_current_rb_correction
Current rigid body modes correction, RB_corr(kkk+1) (RB_corr(0) for the initialization) ...
void clear_PETSc()
PETSc Vec and Mat deallocation, called by the destructor.
bool m_bScratchFolderSet
Have the scratch folder been set?
Mat m_C_R_micro
Mediator - micro system coupling matrix.
bool m_bSet_previous_p_ptr
Have the previous p vectors, p(0 ... kkk), been set?
bool m_bCreatedPrecondSolver
Have the preconditioner system solver been set?
Vec * m_previous_q_ptr
Pointer to the previous q vectors, q(0 ... kkk)
void PETSC_MatMultScale_Bcast(Mat mat_seq, Vec vec_seq_in, Vec vec_seq_out, double a_const)
bool m_bSet_current_residual
Have the current r(kkk+1) vector been set?
void PETSC_invert_dense_matrix(Mat &matrix_in, Mat &matrix_out)
void set_jacobi_precond_vector()
Set up the Jacobi coupling matrix preconditioner vector.
void apply_inverse_coupling_precond(Vec vec_in, Vec vec_out)
Apply the full inversed coupling matrix preconditioner.
Vec m_coupled_sol_BIG
Coupled system solution for the macro model.
RBModesSystem m_RB_modes_system
Which model is associated to the RB modes? Default: RBModesSystem::MICRO.
bool m_bSet_previous_q_ptr
Have the previous q vectors, q(0 ... kkk), been set?
Vec m_coupling_jacobi_precond_vec
Preconditioner Jacobi vector.
libMesh::Parallel::Communicator & m_comm
Communicator.
Vec m_ext_solver_sol_BIG
Macro model external solver solution.
void using_rb_modes(bool bUseRigidBodyModes)
Set up the.
bool m_bCreatedPrecondJacobiVec
Have the preconditioner system solver been set?
bool m_bSet_ext_solver_sol
Have the external solvers solutions been set vectors been set?
bool m_bC_R_micro_MatrixSet
Mediator - micro coupling matrix has been set?
Vec m_current_phi
Current Lagrange multipliers / solution, phi(kkk+1) (phi(0) for the initialization) ...
#define homemade_assert_msg(asserted, msg)
Definition: common_header.h:63
BaseCGPrecondType m_precond_type
Preconditioner type. Default: BaseCGPrecondType::NO_PRECONDITIONER.
bool m_bSet_previous_phi
Have the previous Lagrange multipliers / solution phi(kkk) been set?
void apply_RB_projection(Vec vec_in, Vec vec_out)
Apply the rigid body modes projection operation.
BaseCGPrecondType
Definition: common_enums.h:35
bool m_bCoupled_sols_set
Have the coupled solutions been set yet?
Vec m_null_coupled_vecs[maxVecLimit]
Null space vectors times the coupling matrix.
Vec m_previous_residual
Previous residual vector, r(kkk)
void apply_jacobi_coupling_precond(Vec vec_in, Vec vec_out)
Apply the Jacobi coupling matrix preconditioner vector.
int m_kkk
Current iteration index.
void read_PETSC_vector(libMesh::PetscVector< libMesh::Number > &input_vec, const std::string &filename)
bool m_bSet_current_phi
Have the current Lagrange multipliers / solution phi(kkk+1) been set?
void write_PETSC_vector_MATLAB(Vec input_vec, const std::string &filename, MPI_Comm comm=PETSC_COMM_WORLD)
void apply_precond(Vec vec_in, Vec vec_out)
Common interface to the preconditionners.
Vec m_null_vecs[maxVecLimit]
Null space vectors.
void set_preconditioner(BaseCGPrecondType CG_precond_type, bool bInitialSet=true)
void set_inverse_precond_solver()
Set up the full inversed coupling matrix preconditioner.
bool m_bUsingNullVecs
Do we need to use the null space vectors?
void write_PETSC_matrix(Mat input_mat, const std::string &filename, int rank, MPI_Comm comm=PETSC_COMM_WORLD, int dim=1)
bool m_bNullVecsSet
Have the null space vectors been set?