CArl
Code Arlequin / C++ implementation
CArl_assemble_coupling.cpp
Go to the documentation of this file.
1 
31 #include "CArl_assemble_coupling.h"
32 
33 libMesh::ExplicitSystem& add_explicit_elasticity( libMesh::EquationSystems& input_systems,
34  libMesh::Order order = libMesh::FIRST,
35  libMesh::FEFamily family = libMesh::LAGRANGE)
36 {
37  libMesh::ExplicitSystem& elasticity_system =
38  input_systems.add_system<libMesh::ExplicitSystem> ("Elasticity");
39 
40  elasticity_system.add_variable("u", order, family);
41  elasticity_system.add_variable("v", order, family);
42  elasticity_system.add_variable("w", order, family);
43 
44  return elasticity_system;
45 }
46 
47 libMesh::ImplicitSystem& add_elasticity( libMesh::EquationSystems& input_systems,
48  libMesh::Order order = libMesh::FIRST,
49  libMesh::FEFamily family = libMesh::LAGRANGE)
50 {
51  libMesh::ImplicitSystem& elasticity_system =
52  input_systems.add_system<libMesh::ImplicitSystem> ("Elasticity");
53 
54  elasticity_system.add_variable("u", order, family);
55  elasticity_system.add_variable("v", order, family);
56  elasticity_system.add_variable("w", order, family);
57 
58  return elasticity_system;
59 }
60 
61 int main(int argc, char** argv) {
62 
63  // --- Initialize libMesh
64  libMesh::LibMeshInit init(argc, argv);
65 
66  // Do performance log?
67  const bool MASTER_bPerfLog_carl_libmesh = true;
68  libMesh::PerfLog perf_log("Main program", MASTER_bPerfLog_carl_libmesh);
69 
70  // libMesh's C++ / MPI communicator wrapper
71  libMesh::Parallel::Communicator& WorldComm = init.comm();
72 
73  // Number of processors and processor rank.
74  int rank = WorldComm.rank();
75  int nodes = WorldComm.size();
76 
77  // Create local communicator
78  libMesh::Parallel::Communicator LocalComm;
79  WorldComm.split(rank,rank,LocalComm);
80 
81  // --- Set up inputs
82 
83  // Command line parser
84  GetPot command_line(argc, argv);
85 
86  // File parser
87  GetPot field_parser;
88 
89  // If there is an input file, parse it to get the parameters. Else, parse the command line
90  std::string input_filename;
91  if (command_line.search(2, "--inputfile", "-i")) {
92  input_filename = command_line.next(input_filename);
93  field_parser.parse_input_file(input_filename, "#", "\n", " \t\n");
94  } else {
95  field_parser = command_line;
96  }
97 
99  carl::get_assemble_coupling_input_params(field_parser, input_params);
100 
101  // Check libMesh installation dimension
102  const unsigned int dim = 3;
103 
104  libmesh_example_requires(dim == LIBMESH_DIM, "3D support");
105 
106  // --- Set up the meshes
107 
108  // - Parallelized meshes: A, B, mediator and weight
109  perf_log.push("Meshes - Parallel","Read files:");
110  libMesh::Mesh mesh_BIG(WorldComm, dim);
111  mesh_BIG.read(input_params.mesh_BIG_file);
112  mesh_BIG.prepare_for_use();
113 
114  libMesh::Mesh mesh_micro(WorldComm, dim);
115  mesh_micro.read(input_params.mesh_micro_file);
116  mesh_micro.prepare_for_use();
117 
118  libMesh::Mesh mesh_mediator(WorldComm, dim);
119  mesh_mediator.allow_renumbering(false);
120  mesh_mediator.read(input_params.mesh_mediator_file);
121  mesh_mediator.prepare_for_use();
122 
123  perf_log.pop("Meshes - Parallel","Read files:");
124 
125  // - Local meshes: restrict A and restrict B
126 
127  // -> libMesh's default mesh IS the ReplicatedMesh, which creates a copy of
128  // itself on each processor, but partitions the iterators over each
129  // processor to allow the parallelization of the code. The usage of
130  // ParallelMesh is still a bit risky, and, performance-wise, is worse
131  // than ReplicatedMesh for less than a few thousand processors.
132 
133  perf_log.push("Meshes - Serial","Read files:");
134  libMesh::ReplicatedMesh mesh_R_BIG(WorldComm, dim);
135  mesh_R_BIG.allow_renumbering(false);
136  mesh_R_BIG.read(input_params.mesh_restrict_BIG_file);
137  mesh_R_BIG.prepare_for_use();
138 
139  libMesh::ReplicatedMesh mesh_R_micro(WorldComm, dim);
140  mesh_R_micro.allow_renumbering(false);
141  mesh_R_micro.read(input_params.mesh_restrict_micro_file);
142  mesh_R_micro.prepare_for_use();
143 
144  // - Local mesh: intersection mesh
145  libMesh::Mesh mesh_inter(LocalComm, dim);
146  mesh_inter.allow_renumbering(false);
147  std::string local_inter_mesh_filename = input_params.common_inter_file + "_r_"
148  + std::to_string(rank) + "_n_" + std::to_string(nodes) + ".e";
149  std::string local_inter_table_filename = input_params.common_inter_file + "_r_"
150  + std::to_string(rank) + "_n_" + std::to_string(nodes) + "_inter_table.dat";
151  std::string global_inter_table_filename = input_params.common_inter_file + "_global_inter_pairs.dat";
152 
153  mesh_inter.read(local_inter_mesh_filename);
154  mesh_inter.prepare_for_use();
155 
156  perf_log.pop("Meshes - Serial","Read files:");
157 
158  // --- Prepare the equivalence tables and the intersection mappings
159  perf_log.push("Equivalence / intersection tables","Read files:");
160 
161  // Local intersection pairs (system meshes)
162  std::unordered_map<int,std::pair<int,int> > local_intersection_pairs_map;
163 
164  // Local intersection pairs (restricted meshes)
165  std::unordered_map<int,std::pair<int,int> > local_intersection_restricted_pairs_map;
166 
167  // Intersection elements to be treated by this processor
168  std::unordered_map<int,int> local_intersection_meshI_to_inter_map;
169 
170  // Equivalence tables between system and restricted meshes (and vice-versa)
171  std::unordered_map<int,int> equivalence_table_BIG_to_R_BIG;
172  std::unordered_map<int,int> equivalence_table_micro_to_R_micro;
173  std::unordered_map<int,int> equivalence_table_R_BIG_to_BIG;
174  std::unordered_map<int,int> equivalence_table_R_micro_to_micro;
175 
176  // Start by reading and broadcasting the equivalence tables
178  WorldComm,
181 
182  equivalence_table_BIG_to_R_BIG,
183  equivalence_table_micro_to_R_micro,
184  equivalence_table_R_BIG_to_BIG,
185  equivalence_table_R_micro_to_micro);
186 
187  // Set the local intersection tables
188  if(input_params.mediator_type == carl::MediatorType::USE_MACRO)
189  {
191  WorldComm,
192  mesh_inter,
193  local_inter_table_filename,
196 
197  equivalence_table_BIG_to_R_BIG,
198  equivalence_table_micro_to_R_micro,
199 
200  local_intersection_pairs_map,
201  local_intersection_restricted_pairs_map,
202  local_intersection_meshI_to_inter_map);
203  }
204  else if(input_params.mediator_type == carl::MediatorType::USE_MICRO)
205  {
207  WorldComm,
208  mesh_inter,
209  local_inter_table_filename,
212 
213  equivalence_table_micro_to_R_micro,
214  equivalence_table_BIG_to_R_BIG,
215 
216  local_intersection_pairs_map,
217  local_intersection_restricted_pairs_map,
218  local_intersection_meshI_to_inter_map);
219  }
220 
221  // Build mappings with the intersections of the mediator mesh with the micro and macro meshes - used to preallocate the coupling matrices
222  std::unordered_multimap<int,int> inter_mediator_BIG;
223  std::unordered_multimap<int,int> inter_mediator_micro;
225  WorldComm,
226  global_inter_table_filename,
227  equivalence_table_BIG_to_R_BIG,
228  equivalence_table_R_BIG_to_BIG,
229  inter_mediator_BIG,
230  inter_mediator_micro);
231  perf_log.pop("Equivalence / intersection tables","Read files:");
232 
233  // --- Generate the equation systems
234  perf_log.push("Initialization","System initialization:");
235  carl::assemble_coupling_matrices CoupledMatrices(WorldComm);
236 
237  libMesh::EquationSystems& equation_systems_inter =
238  CoupledMatrices.add_inter_EquationSystem("InterSys", mesh_inter);
239 
240  libMesh::ExplicitSystem& elasticity_system_inter
241  = add_explicit_elasticity(equation_systems_inter);
242 
243  carl::reduced_system_init(elasticity_system_inter);
244 
245  perf_log.pop("Initialization","System initialization:");
246 
247  // - Build the MACRO system
248 
249  perf_log.push("Macro system","System initialization:");
250  libMesh::EquationSystems& equation_systems_BIG =
251  CoupledMatrices.set_BIG_EquationSystem("BigSys", mesh_BIG);
252 
253  // [MACRO] Set up the physical properties
254  libMesh::ExplicitSystem& elasticity_system_BIG
255  = add_explicit_elasticity(equation_systems_BIG);
256 
257  carl::reduced_system_init(elasticity_system_BIG);
258  perf_log.pop("Macro system","System initialization:");
259 
260  // - Build the micro system
261 
262  perf_log.push("Micro system","System initialization:");
263  libMesh::EquationSystems& equation_systems_micro =
264  CoupledMatrices.add_micro_EquationSystem<libMesh::PetscMatrix<libMesh::Number> >("MicroSys", mesh_micro);
265 
266  // [MICRO] Set up the physical properties
267  libMesh::ExplicitSystem& elasticity_system_micro
268  = add_explicit_elasticity(equation_systems_micro);
269 
270  carl::reduced_system_init(elasticity_system_micro);
271  perf_log.pop("Micro system","System initialization:");
272 
273  // - Build the RESTRICTED BIG system
274  perf_log.push("RESTRICTED macro system","System initialization:");
275  libMesh::EquationSystems& equation_systems_R_BIG =
276  CoupledMatrices.set_Restricted_BIG_EquationSystem("BigSys", mesh_R_BIG);
277 
278  // [R. MACRO] Set up the physical properties
279  libMesh::ExplicitSystem& elasticity_system_R_BIG
280  = add_explicit_elasticity(equation_systems_R_BIG);
281 
282  carl::reduced_system_init(elasticity_system_R_BIG);
283 
284  perf_log.pop("RESTRICTED macro system","System initialization:");
285 
286  // - Build the RESTRICTED micro system
287 
288  perf_log.push("RESTRICTED micro system","System initialization:");
289  libMesh::EquationSystems& equation_systems_R_micro =
290  CoupledMatrices.add_Restricted_micro_EquationSystem("MicroSys", mesh_R_micro);
291 
292  // [R. MICRO] Set up the physical properties
293  libMesh::ExplicitSystem& elasticity_system_R_micro
294  = add_explicit_elasticity(equation_systems_R_micro);
295 
296  carl::reduced_system_init(elasticity_system_R_micro);
297  perf_log.pop("RESTRICTED micro system","System initialization:");
298 
299  // - Build the mediator system
300 
301  perf_log.push("Mediator system","System initialization:");
302  libMesh::EquationSystems& equation_systems_mediator =
303  CoupledMatrices.add_mediator_EquationSystem("MediatorSys", mesh_mediator);
304 
305  libMesh::ExplicitSystem& elasticity_system_mediator
306  = add_explicit_elasticity(equation_systems_mediator);
307 
308  carl::reduced_system_init(elasticity_system_mediator);
309 
310  perf_log.pop("Mediator system","System initialization:");
311 
312  // Set parameters
313  CoupledMatrices.set_coupling_parameters("MicroSys",input_params.coupling_rigidity,input_params.coupling_width);
314 
315  // Use H1 norm
316  CoupledMatrices.use_H1_coupling("MicroSys");
317 
318  // Assemble!
319  CoupledMatrices.assemble_coupling_elasticity_3D_parallel("BigSys","MicroSys",
320  "InterSys","MediatorSys",
321  mesh_R_BIG, mesh_R_micro,
322  local_intersection_pairs_map,
323  local_intersection_restricted_pairs_map,
324  local_intersection_meshI_to_inter_map,
325  inter_mediator_BIG,
326  inter_mediator_micro);
327 
328  // Print matrices!
329  if(rank == 0)
330  {
331  std::string command_string = "mkdir -p " + input_params.output_folder;
332  carl::exec_command(command_string.c_str());
333  }
334  WorldComm.barrier();
335 
336 // Print MatLab debugging output? Variable defined at "carl_headers.h"
337 #ifdef PRINT_MATLAB_DEBUG
338  CoupledMatrices.print_matrices_matlab("MicroSys",input_params.output_folder);
339 #endif
340  CoupledMatrices.print_PETSC_matrices("MicroSys",input_params.output_folder);
341 
342  return 0;
343 }
Structure containing the parameters for the construction of the coupling matrices.
libMesh::EquationSystems & set_BIG_EquationSystem(const std::string &name, libMesh::MeshBase &BIGMesh)
void set_local_intersection_tables(const libMesh::Parallel::Communicator &WorldComm, const libMesh::Mesh &mesh_intersection, const std::string &intersection_local_table_Filename, const std::string &equivalence_table_A_Filename, const std::string &equivalence_table_B_Filename, const std::unordered_map< int, int > &equivalence_table_A_to_R_A, const std::unordered_map< int, int > &equivalence_table_B_to_R_B, std::unordered_map< int, std::pair< int, int > > &local_intersection_pairs_map, std::unordered_map< int, std::pair< int, int > > &local_intersection_restricted_pairs_map, std::unordered_map< int, int > &local_intersection_meshI_to_inter_map)
libMesh::ExplicitSystem & add_explicit_elasticity(libMesh::EquationSystems &input_systems, libMesh::Order order=libMesh::FIRST, libMesh::FEFamily family=libMesh::LAGRANGE)
std::string exec_command(const std::string &cmd)
int main(int argc, char **argv)
libMesh::EquationSystems & add_inter_EquationSystem(const std::string &name, libMesh::MeshBase &interMesh)
void reduced_system_init(Sys &system_input)
std::string equivalence_table_restrict_BIG_file
Equivalence table between the macro (BIG) system mesh and its restriction mesh.
void set_equivalence_tables(const libMesh::Parallel::Communicator &WorldComm, const std::string &equivalence_table_A_Filename, const std::string &equivalence_table_B_Filename, std::unordered_map< int, int > &equivalence_table_A_to_R_A, std::unordered_map< int, int > &equivalence_table_B_to_R_B, std::unordered_map< int, int > &equivalence_table_R_A_to_A, std::unordered_map< int, int > &equivalence_table_R_B_to_B)
libMesh::EquationSystems & add_micro_EquationSystem(const std::string &name, libMesh::MeshBase &microMesh)
void assemble_coupling_elasticity_3D_parallel(const std::string BIG_name, const std::string micro_name, const std::string inter_name, const std::string mediator_name, const libMesh::MeshBase &mesh_R_BIG, const libMesh::MeshBase &mesh_R_micro, const std::unordered_map< int, std::pair< int, int > > &full_intersection_pairs_map, const std::unordered_map< int, std::pair< int, int > > &full_intersection_restricted_pairs_map, const std::unordered_map< int, int > &local_intersection_meshI_to_inter_map, const std::unordered_multimap< int, int > &inter_table_mediator_BIG, const std::unordered_multimap< int, int > &inter_table_mediator_micro, const std::string BIG_type="Elasticity", const std::string micro_type="Elasticity", bool bSameElemsType=true)
std::string equivalence_table_restrict_micro_file
Equivalence table between the micro system mesh and its restriction mesh.
void use_H1_coupling(std::string name)
libMesh::ImplicitSystem & add_elasticity(libMesh::EquationSystems &input_systems, libMesh::Order order=libMesh::FIRST, libMesh::FEFamily family=libMesh::LAGRANGE)
Add a linear elasticity libMesh::LinearImplicitSystem to the input libMesh::EquationSystems& input_sy...
void get_assemble_coupling_input_params(GetPot &field_parser, coupling_assemble_coupling_input_params &input_params)
Parser function for the construction of the coupling matrices.
carl::MediatorType mediator_type
Use which mesh as the mediator mesh? Values: carl::MediatorType::USE_MACRO, carl::MediatorType::USE_M...
void set_coupling_parameters(const std::string &name, double coupling_rigidity, double coupling_width)
Set physical parameters.
double coupling_rigidity
Rigidity used for the coupling matrix.
std::string mesh_micro_file
Path to the micro system mesh.
std::string common_inter_file
Common path to the intersection meshes and tables.
void print_matrices_matlab(const std::string &name, const std::string &outputRoot="coupling")
std::string mesh_restrict_micro_file
Path to the restricted micro system mesh.
void print_PETSC_matrices(const std::string &name, const std::string &outputRoot="coupling")
std::string mesh_BIG_file
Path to the macro (BIG) system mesh.
std::string mesh_restrict_BIG_file
Path to the restricted macro (BIG) system mesh.
void set_global_mediator_system_intersection_lists(const libMesh::Parallel::Communicator &WorldComm, const std::string &intersection_global_table_Filename, const std::unordered_map< int, int > &equivalence_table_system_to_mediator, const std::unordered_map< int, int > &equivalence_table_mediator_to_system, std::unordered_multimap< int, int > &inter_mediator_A, std::unordered_multimap< int, int > &inter_mediator_B)
libMesh::EquationSystems & add_mediator_EquationSystem(const std::string &name, libMesh::MeshBase &mediatorMesh)
libMesh::EquationSystems & set_Restricted_BIG_EquationSystem(const std::string &name, libMesh::MeshBase &R_BIGMesh)
libMesh::EquationSystems & add_Restricted_micro_EquationSystem(const std::string &name, libMesh::MeshBase &R_microMesh)
std::string mesh_mediator_file
Path to the mediator system mesh.