CArl
Code Arlequin / C++ implementation
CArl_FETI_iterate.cpp
Go to the documentation of this file.
1 #include "CArl_FETI_iterate.h"
79 int main(int argc, char** argv) {
80 
81  // --- Initialize libMesh
82  libMesh::LibMeshInit init(argc, argv);
83 
84  // Do performance log?
85  libMesh::PerfLog perf_log("Main program");
86 
87  // libMesh's C++ / MPI communicator wrapper
88  libMesh::Parallel::Communicator& WorldComm = init.comm();
89 
90  // Number of processors and processor rank.
91  int rank = WorldComm.rank();
92  int nodes = WorldComm.size();
93 
94  // --- Set up inputs
95 
96  // Command line parser
97  GetPot command_line(argc, argv);
98 
99  // File parser
100  GetPot field_parser;
101 
102  // If there is an input file, parse it to get the parameters. Else, parse the command line
103  std::string input_filename;
104  if (command_line.search(2, "--inputfile", "-i")) {
105  input_filename = command_line.next(input_filename);
106  field_parser.parse_input_file(input_filename, "#", "\n", " \t\n");
107  } else {
108  field_parser = command_line;
109  }
110 
111  carl::feti_iterate_params input_params;
112  get_input_params(field_parser, input_params);
113 
114  // Object containing the FETI operations
115  carl::FETI_Operations feti_op(WorldComm,input_params.scratch_folder_path,input_params.coupling_folder_path);
116 
117  // --- Define if the rb modes will be used or not
118  feti_op.using_rb_modes(input_params.bUseRigidBodyModes);
119 
120  // --- Read the common files: coupling matrices, null space vectors ...
121  // Read up the coupling matricesconst std::string& filename)
122  feti_op.set_coupling_matrix_R_micro();
123  feti_op.set_coupling_matrix_R_BIG();
124 
125  // --- Set up any matrices or vectors needed before calculating the outputs
126  // Set up the preconditioner
127  feti_op.set_preconditioner(input_params.CG_precond_type, /* initial_set = */ false);
128 
129  // Read operations needed if we are using the rigid body modes
130  if(input_params.bUseRigidBodyModes)
131  {
132  // Read the RB-related vectors and matrices
133  feti_op.read_null_space_vecs(input_params.RB_vectors_base,input_params.nb_of_rb_vectors);
135  }
136 
137  // --- Read the previous iteration files: scalar data, iteration vectors ...
138  /* Read the scalar data from the previous iterations '0 ... kkk'
139  * We now have: 'kkk'
140  * 'rho(0)'
141  * 'rho(kkk)'
142  * '| RB_corr(kkk) |'
143  * 'p(0 ... kkk - 1).q(0 ... kkk - 1)'
144  */
145  feti_op.read_scalar_data();
146 
147  // Read the vector data from the previous iterations '0 ... kkk'
148  /* We now have: 'r(kkk)'
149  * 'phi(kkk)'
150  * 'p(0 ... kkk)'
151  * 'q(0 ... kkk - 1)'
152  */
153  feti_op.read_vector_data();
154 
155  // Read the previous iteration 'kkk' external solver output, 'x_i(kkk)'
156  feti_op.read_ext_solver_output();
157 
158  // --- Iterate!
159  // Calculate 'q(kkk) = C_1 * x_1(kkk) + C_2 * x_2(kkk)' and 'p(kkk).q(kkk)'
160  feti_op.calculate_q();
161 
162  // Calculate 'phi(kkk + 1) = phi(kkk) + gamma * p(kkk)'
163  // gamma = rho(kkk) / ( p(kkk).q(kkk) )
164  feti_op.calculate_phi();
165 
166  // Calculate 'r(kkk + 1) = r(kkk) - gamma * q(kkk)'
167  feti_op.calculate_r();
168 
169  // Calculate 'z(kkk + 1)' (formula depends on preconditioner and projection settings)
170  feti_op.calculate_z();
171 
172  // Calculate 'p(kkk + 1)'
173  feti_op.calculate_p();
174 
175  // Calculate 'RB_corr(kkk+1)'
176  if(input_params.bUseRigidBodyModes)
177  {
178  feti_op.calculate_rb_correction();
179  }
180 
181  // Calculate the scalar data, 'rho(kkk+1)' and '| RB_corr(kkk+1) |'
182  feti_op.calculate_scalar_data();
183 
184  /* Export scalar data
185  * Data to export: 'kkk+1'
186  * 'rho(0)'
187  * 'rho(kkk+1)'
188  * '| RB_corr(kkk+1) |'
189  * 'p(kkk).q(kkk)'
190  */
191  feti_op.export_scalar_data();
192 
193  /* Export the iteration vectors
194  * Vectors to export: 'r(kkk+1)'
195  * 'phi(kkk+1)'
196  * 'p(kkk+1)'
197  * 'q(kkk)'
198  */
199  feti_op.export_iter_vecs();
200 
201  // // --- Check the convergence
202  carl::IterationStatus current_iteration_status = carl::IterationStatus::ITERATING;
203 
204  if(input_params.bUseRigidBodyModes)
205  {
206  current_iteration_status = feti_op.check_convergence(input_params.CG_coupled_conv_rel, input_params.CG_coupled_conv_abs, input_params.CG_coupled_conv_max, input_params.CG_coupled_div, input_params.CG_coupled_conv_corr);
207  } else {
208  current_iteration_status = feti_op.check_convergence(input_params.CG_coupled_conv_rel, input_params.CG_coupled_conv_abs, input_params.CG_coupled_conv_max, input_params.CG_coupled_div);
209  }
210 
211  // Print the current values of the convergence parameters
212  feti_op.print_previous_iters_conv( /* nb. of iterations = 5 */);
213 
214  switch (current_iteration_status)
215  {
217  // --- Continue the iteration
218 
219  // Export the Ct_i * p(kkk+1) vectors
220  feti_op.export_ext_solver_rhs_Ct_p();
221 
222  // --- Launch the "iter_script.sh" script --- ONLY ON THE FIRST PROC!
223  if(WorldComm.rank() == 0)
224  {
225  std::string iter_script_command = ". " + input_params.scratch_folder_path + "/FETI_iter_script.sh";
226  if(input_params.scheduler == carl::ClusterSchedulerType::LOCAL)
227  {
228  std::cout << " !!! LOCAL job 'scheduler: Run the following script manually: " << std::endl;
229  std::cout << iter_script_command << std::endl << std::endl;
230  } else {
231  carl::exec_command(iter_script_command);
232  }
233  }
234  break;
236  // --- Well ... converged!
237 
238  // Export the Ct_i * phi(kkk+1) vectors
240 
241  // Export the rigid body modes correction vector
242  feti_op.export_rb_correction_vector();
243 
244  // --- Launch the "sol_script.sh" script --- ONLY ON THE FIRST PROC!
245  if(WorldComm.rank() == 0)
246  {
247  std::string sol_script_command = ". " + input_params.scratch_folder_path + "/FETI_sol_script.sh";
248  if(input_params.scheduler == carl::ClusterSchedulerType::LOCAL)
249  {
250  std::cout << " !!! LOCAL job 'scheduler: Run the following script manually: " << std::endl;
251  std::cout << sol_script_command << std::endl << std::endl;
252  } else {
253  carl::exec_command(sol_script_command);
254  }
255  }
256  break;
258  // --- Well, we have to stop here ...
259  break;
260  }
261 
262  return 0;
263 }
double CG_coupled_conv_rel
[CG] Relative residual convergence.
void get_input_params(GetPot &field_parser, feti_iterate_params &input_params)
Parser function for the coupled solver test programs.
int CG_coupled_conv_max
[CG] Maximum number of iterations.
double CG_coupled_div
[CG] Residual divergence.
void read_scalar_data()
Read the scalar data, rho(0 ... kkk), | RB_corr(0 ... kkk) | and p(0 ... kkk - 1).q(0 ... kkk - 1)
void calculate_q()
Calculate the current q(kkk) vector.
bool bUseRigidBodyModes
[RB] Use the rigid body modes for the micro system?
void export_rb_correction_vector()
Export the rigid body modes correction.
std::string exec_command(const std::string &cmd)
void export_ext_solver_rhs_Ct_phi()
Calculate and export the external solver RHS's for the decoupled problem.
void set_coupling_matrix_R_micro()
Read the mediator - micro system coupling matrix.
carl::BaseCGPrecondType CG_precond_type
[CG] Type of preconditionner.
void calculate_z()
Calculate the current z(kkk+1) vector.
double CG_coupled_conv_abs
[CG] Absolute residual convergence.
void calculate_phi()
Calculate the current phi(kkk+1) solution vector.
void calculate_scalar_data()
Calculate the scalar quantities.
Class containing the operations needed for the FETI solver.
void read_null_space_vecs(const std::string &RB_vectors_base, int nb_of_rb_vectors)
Read the null space vectors.
void read_vector_data()
Read the vector data - essentially calls the "read_previous" and "read_all_previous" methods...
void calculate_rb_correction()
Calculate the rigid body modes corrections.
std::string scratch_folder_path
Path to the folder which will be used to save the temporary files during the solve operation...
void calculate_r()
Calculate the current r(kkk+1) residual vector.
IterationStatus check_convergence(double rel_residual_conv, double abs_residual_conv, int max_iter_div, double rel_residual_div, double rb_modes_conv=-1)
Check the convergence.
void calculate_p()
Calculate the current p(kkk+1) vector.
int main(int argc, char **argv)
void set_coupling_matrix_R_BIG()
Read the mediator - macro system coupling matrix.
std::string coupling_folder_path
Folder containing the coupling matrices.
IterationStatus
Definition: common_enums.h:41
void read_null_space_inv_RITRI_mat()
Read the matrix.
void using_rb_modes(bool bUseRigidBodyModes)
Set up the.
Structure containing the parameters for the setup initialization of the FETI solver.
void read_ext_solver_output()
Read the latest external solver output.
std::string RB_vectors_base
[RB] Common path base for the micro system's rigid body mode vectors.
double CG_coupled_conv_corr
[CG] Relative rigid body mode convergence.
void print_previous_iters_conv(int nb_of_iters=5)
void export_scalar_data()
Export the iteration scalar data, rho(kkk+1), | RB_corr(kkk+1) | and p(kkk).q(kkk) ...
void export_ext_solver_rhs_Ct_p()
Calculate and export the external solver RHS's for the next iteration.
ClusterSchedulerType scheduler
Cluster scheduler software type. Values: PBS, SLURM (code not implemented for the later yet)...
void set_preconditioner(BaseCGPrecondType CG_precond_type, bool bInitialSet=true)
int nb_of_rb_vectors
[RB] Number of RB mode vectors.