CArl
Code Arlequin / C++ implementation
assemble_coupling.cpp
Go to the documentation of this file.
1 #include "assemble_coupling.h"
2 
3 namespace carl
4 {
5  // Class members
7  {
8  // Clean up all systems
9  libMesh::EquationSystems *EqBIGSys = m_BIG_EquationSystem.second;
10  EqBIGSys->clear();
11  delete EqBIGSys;
12  EqBIGSys = NULL;
13  m_BIG_EquationSystem.second = NULL;
14 
15  while(!m_micro_EquationSystemMap.empty())
16  {
18 
19  libMesh::EquationSystems *EqSys = toClean->second;
20  EqSys->clear();
21  delete EqSys;
22  EqSys = NULL;
23 
24  m_micro_EquationSystemMap.erase(toClean);
25  }
26 
28  {
29  libMesh::EquationSystems *EqRBIGSys = m_R_BIG_EquationSystem.second;
30  EqRBIGSys->clear();
31  delete EqRBIGSys;
32  EqRBIGSys = NULL;
33  m_R_BIG_EquationSystem.second = NULL;
34 
35  while(!m_R_micro_EquationSystemMap.empty())
36  {
38 
39  libMesh::EquationSystems *EqSys = toClean->second;
40  EqSys->clear();
41  delete EqSys;
42  EqSys = NULL;
43 
44  m_R_micro_EquationSystemMap.erase(toClean);
45  }
46  }
47 
48  while(!m_inter_EquationSystemMap.empty())
49  {
51 
52  libMesh::EquationSystems *EqSys = toClean->second;
53  EqSys->clear();
54  delete EqSys;
55  EqSys = NULL;
56 
57  m_inter_EquationSystemMap.erase(toClean);
58  }
59 
60  while(!m_mediator_EquationSystemMap.empty())
61  {
63 
64  libMesh::EquationSystems *EqSys = toClean->second;
65  EqSys->clear();
66  delete EqSys;
67  EqSys = NULL;
68 
69  m_mediator_EquationSystemMap.erase(toClean);
70  }
71 
73  {
75 
76  libMesh::PetscMatrix<libMesh::Number> *Mat = toClean->second;
77  Mat->clear();
78  delete Mat;
79  Mat = NULL;
80 
82  }
83 
84  while(!m_couplingMatrixMap_mediator_BIG.empty())
85  {
87 
88  libMesh::PetscMatrix<libMesh::Number> *Mat = toClean->second;
89  Mat->clear();
90  delete Mat;
91  Mat = NULL;
92 
93  m_couplingMatrixMap_mediator_BIG.erase(toClean);
94  }
95 
97  {
99 
100  libMesh::PetscMatrix<libMesh::Number> *Mat = toClean->second;
101  Mat->clear();
102  delete Mat;
103  Mat = NULL;
104 
106  }
107  };
108 
109  libMesh::EquationSystems& assemble_coupling_matrices::set_BIG_EquationSystem(const std::string& name, libMesh::MeshBase& BIGMesh)
110  {
111  libMesh::EquationSystems* EqSystemPtr = new libMesh::EquationSystems(
112  BIGMesh);
113 
114  m_BIG_EquationSystem.first = name;
115  m_BIG_EquationSystem.second = EqSystemPtr;
116 
117  return *EqSystemPtr;
118  };
119 
120  libMesh::EquationSystems& assemble_coupling_matrices::set_Restricted_BIG_EquationSystem(const std::string& name, libMesh::MeshBase& R_BIGMesh)
121  {
123  libMesh::EquationSystems* EqSystemPtr = new libMesh::EquationSystems(
124  R_BIGMesh);
125 
126  m_R_BIG_EquationSystem.first = name;
127  m_R_BIG_EquationSystem.second = EqSystemPtr;
128 
129  return *EqSystemPtr;
130  };
131 
132  libMesh::EquationSystems& assemble_coupling_matrices::add_Restricted_micro_EquationSystem(const std::string& name,
133  libMesh::MeshBase& R_microMesh)
134  {
136 
137  libMesh::EquationSystems* EqSystemPtr = NULL;
138 
139  if (!m_R_micro_EquationSystemMap.count(name))
140  {
141  // Then add a new system
142  EqSystemPtr = new libMesh::EquationSystems(R_microMesh);
143 
144  m_R_micro_EquationSystemMap.insert(std::make_pair(name, EqSystemPtr));
145  }
146  else
147  {
148  // System already exits, return the system pointer
149  std::cerr << " *** Warning: restricted micro system " << name
150  << " already exists!" << std::endl;
151  EqSystemPtr = m_micro_EquationSystemMap[name];
152  }
153 
154  return *EqSystemPtr;
155  };
156 
157  libMesh::EquationSystems& assemble_coupling_matrices::add_inter_EquationSystem(const std::string& name,
158  libMesh::MeshBase& interMesh)
159  {
160  libMesh::EquationSystems* EqSystemPtr = NULL;
161 
162  if (!m_inter_EquationSystemMap.count(name))
163  {
164  // Then add a new system
165  EqSystemPtr = new libMesh::EquationSystems(interMesh);
166  m_inter_EquationSystemMap.insert(std::make_pair(name, EqSystemPtr));
167  }
168  else
169  {
170  // System already exits, return the system pointer
171  std::cerr << " *** Warning: inter system " << name
172  << " already exists!" << std::endl;
173  EqSystemPtr = m_inter_EquationSystemMap[name];
174  }
175 
176  return *EqSystemPtr;
177  };
178 
180  const std::string& name, libMesh::MeshBase& mediatorMesh)
181  {
182  libMesh::EquationSystems* EqSystemPtr = NULL;
183 
184  if (!m_mediator_EquationSystemMap.count(name))
185  {
186  // Then add a new system
187  EqSystemPtr = new libMesh::EquationSystems(mediatorMesh);
189  std::make_pair(name, EqSystemPtr));
190  }
191  else
192  {
193  // System already exits, return the system pointer
194  std::cerr << " *** Warning: mediator system " << name
195  << " already exists!" << std::endl;
196  EqSystemPtr = m_mediator_EquationSystemMap[name];
197  }
198 
199  return *EqSystemPtr;
200  };
201 
203  double coupling_rigidity, double coupling_width)
204  {
205  m_coupling_rigidityMap[name] = coupling_rigidity;
206  m_coupling_widthMap[name] = coupling_width;
207  };
208 
209  void assemble_coupling_matrices::set_corrected_shapes( const std::vector<std::vector<libMesh::Real> >& lambda_weights,
210  const std::vector<std::vector<libMesh::Real> >& phi_inter,
211  std::vector<std::vector<libMesh::Real> >& phi_corrected)
212  {
213  unsigned int lambda_corr_size = lambda_weights.size();
214  unsigned int lambda_inter_size = lambda_weights[0].size();
215 
216  unsigned int phi_inter_dof = phi_inter.size();
217  unsigned int phi_inter_qp = phi_inter[0].size();
218 
219  unsigned int phi_corrected_dof = phi_corrected.size();
220  unsigned int phi_corrected_qp = phi_corrected[0].size();
221 
222  /*
223  * lambda : [ n_dofs_corr ] x [ n_dofs_inter ]
224  * inter : [ n_dofs_inter ] x [ n_qp ]
225  * corr : [ n_dofs_corr ] x [ n_qp ]
226  */
227 
228  homemade_assert_msg(phi_inter_qp == phi_corrected_qp,
229  " Different numbers of quadrature points!");
230  homemade_assert_msg(lambda_corr_size == phi_corrected_dof,
231  " Incompatible corrected shape table and barycentric coordinates!");
232  homemade_assert_msg(lambda_inter_size == phi_inter_dof,
233  " Incompatible intersection shape table and barycentric coordinates!");
234 
235  // phi_A,i (qp) = l_i,1 * phi_I,1 (qp) + l_i,2 * phi_I,2 (qp) ...
236  // = sum [ l_i,j * phi_I,j (qp) ]
237  for(unsigned int qp = 0; qp < phi_inter_qp; ++qp)
238  {
239  for(unsigned int iii = 0; iii < phi_corrected_dof; ++iii)
240  {
241  phi_corrected[iii][qp] = 0;
242  for(unsigned int jjj = 0; jjj < phi_inter_dof; ++jjj)
243  {
244  phi_corrected[iii][qp] += lambda_weights[iii][jjj]*phi_inter[jjj][qp];
245  }
246  }
247  }
248  }
249 
250  void assemble_coupling_matrices::set_corrected_shape_gradients( const std::vector<std::vector<libMesh::Real> >& lambda_weights,
251  const std::vector<std::vector<libMesh::RealGradient> >& dphi_inter,
252  std::vector<std::vector<libMesh::RealGradient> >& dphi_corrected)
253  {
254  unsigned int lambda_corr_size = lambda_weights.size();
255  unsigned int lambda_inter_size = lambda_weights[0].size();
256 
257  unsigned int phi_inter_dof = dphi_inter.size();
258  unsigned int phi_inter_qp = dphi_inter[0].size();
259 
260  unsigned int phi_corrected_dof = dphi_corrected.size();
261  unsigned int phi_corrected_qp = dphi_corrected[0].size();
262 
263  /*
264  * lambda : [ n_dofs_corr ] x [ n_dofs_inter ]
265  * inter : [ n_dofs_inter ] x [ n_qp ]
266  * corr : [ n_dofs_corr ] x [ n_qp ]
267  */
268 
269  homemade_assert_msg(phi_inter_qp == phi_corrected_qp,
270  " Different numbers of quadrature points!");
271  homemade_assert_msg(lambda_corr_size == phi_corrected_dof,
272  " Incompatible corrected shape table and barycentric coordinates!");
273  homemade_assert_msg(lambda_inter_size == phi_inter_dof,
274  " Incompatible intersection shape table and barycentric coordinates!");
275 
276  // phi_A,i (qp) = l_i,1 * phi_I,1 (qp) + l_i,2 * phi_I,2 (qp) ...
277  // = sum [ l_i,j * phi_I,j (qp) ]
278  for(unsigned int qp = 0; qp < phi_inter_qp; ++qp)
279  {
280  for(unsigned int iii = 0; iii < phi_corrected_dof; ++iii)
281  {
282  dphi_corrected[iii][qp] = 0;
283  for(unsigned int jjj = 0; jjj < phi_inter_dof; ++jjj)
284  {
285  dphi_corrected[iii][qp] += lambda_weights[iii][jjj]*dphi_inter[jjj][qp];
286  }
287  }
288  }
289  };
290 
291  void assemble_coupling_matrices::get_lambdas( const unsigned int dim,
292  const libMesh::FEType& fe_t,
293  const libMesh::Elem* base_elem,
294  const std::vector<libMesh::Point>& phys_points,
295  std::vector<libMesh::Point>& ref_points,
296  std::vector<std::vector<libMesh::Real> >& lambda_weights)
297  {
298  // Test if we are using the correct type!
299  homemade_assert_msg(base_elem->type() == libMesh::TET4 || base_elem->type() == libMesh::HEX8,
300  " Only implemented for TET4 or HEX8 elements!");
301 
302  homemade_assert_msg(dim == 3,
303  " Only implemented for 3D!");
304 
305  unsigned int lambda_inter_size = lambda_weights[0].size();
306  unsigned int lambda_base_size = lambda_weights.size();
307 
308  // Set vectors to have same sizes
309  if(phys_points.size() != ref_points.size())
310  {
311  ref_points.resize( phys_points.size() );
312  }
313 
314  // Convert the points
315  libMesh::FEInterface::inverse_map(dim, fe_t, base_elem, phys_points, ref_points);
316 
317 
318 
319  // Calculate the lambdas
320  // -> lines : DoF from base
321  // -> cols : DoF from inter
322  for(unsigned int iii = 0; iii < lambda_base_size; ++iii)
323  {
324  for(unsigned int jjj = 0; jjj < lambda_inter_size; ++jjj)
325  {
326  lambda_weights[iii][jjj] =
327  libMesh::FE<3,libMesh::LAGRANGE>::shape(
328  base_elem->type(),
329  libMesh::FIRST,
330  iii,
331  ref_points[jjj]);
332  }
333  }
334  };
335 
336  libMesh::PetscMatrix<libMesh::Number>& assemble_coupling_matrices::get_micro_coupling_matrix(const std::string& name)
337  {
338  return * m_couplingMatrixMap_mediator_micro[name];
339  }
340 
341  libMesh::PetscMatrix<libMesh::Number>& assemble_coupling_matrices::get_BIG_coupling_matrix(const std::string& name)
342  {
343  return * m_couplingMatrixMap_mediator_BIG[name];
344  }
345 
346  libMesh::PetscMatrix<libMesh::Number>& assemble_coupling_matrices::get_mediator_coupling_matrix(const std::string& name)
347  {
349  }
350 
352  {
353  libMesh::PetscMatrix<libMesh::Number>& CouplingTestMatrix =
355  std::cout << "| Restrict - Micro matrix -> " << name << std::endl;
356  print_matrix(CouplingTestMatrix);
357  }
358 
360  {
361  libMesh::PetscMatrix<libMesh::Number>& CouplingTestMatrix =
363  std::cout << "| Restrict - Macro matrix -> " << name << std::endl;
364  print_matrix(CouplingTestMatrix);
365  }
366 
368  {
369  libMesh::PetscMatrix<libMesh::Number>& CouplingTestMatrix =
371  std::cout << "| Restrict - Restrict matrix -> " << name << std::endl;
372  print_matrix(CouplingTestMatrix);
373  }
374 
375  void assemble_coupling_matrices::print_matrices_matlab(const std::string& name, const std::string& outputRoot)
376  {
377  libMesh::PetscMatrix<libMesh::Number>& CouplingTestMatrix_BIG =
379  libMesh::PetscMatrix<libMesh::Number>& CouplingTestMatrix_micro=
381  libMesh::PetscMatrix<libMesh::Number>& CouplingTestMatrix_mediator=
383 
384 // Print MatLab debugging output? Variable defined at "carl_headers.h"
385 #ifdef PRINT_MATLAB_DEBUG
386  CouplingTestMatrix_BIG.print_matlab(outputRoot + "/coupling_matrix_macro.m");
387  CouplingTestMatrix_micro.print_matlab(outputRoot + "/coupling_matrix_micro.m");
388  CouplingTestMatrix_mediator.print_matlab(outputRoot + "/coupling_matrix_mediator.m");
389 #endif
390  }
391 
392  void assemble_coupling_matrices::print_PETSC_matrices(const std::string& name, const std::string& outputRoot)
393  {
394  libMesh::PetscMatrix<libMesh::Number>& CouplingTestMatrix_BIG =
396  libMesh::PetscMatrix<libMesh::Number>& CouplingTestMatrix_micro=
398  libMesh::PetscMatrix<libMesh::Number>& CouplingTestMatrix_mediator=
400 
401  write_PETSC_matrix(CouplingTestMatrix_BIG.mat(), outputRoot + "/coupling_matrix_macro.petscmat",m_comm->rank(),m_comm->get());
402  write_PETSC_matrix(CouplingTestMatrix_micro.mat(), outputRoot + "/coupling_matrix_micro.petscmat",m_comm->rank(),m_comm->get());
403  write_PETSC_matrix(CouplingTestMatrix_mediator.mat(), outputRoot + "/coupling_matrix_mediator.petscmat",m_comm->rank(),m_comm->get());
404  }
405 
407  {
408  m_bUseH1Coupling[name] = true;
409  };
410 
412  {
413  m_bUseH1Coupling[name] = false;
414  };
415 };
libMesh::PetscMatrix< libMesh::Number > & get_BIG_coupling_matrix(const std::string &name)
libMesh::EquationSystems & set_BIG_EquationSystem(const std::string &name, libMesh::MeshBase &BIGMesh)
const libMesh::Parallel::Communicator * m_comm
void get_lambdas(const unsigned int dim, const libMesh::FEType &fe_t, const libMesh::Elem *base_elem, const std::vector< libMesh::Point > &phys_points, std::vector< libMesh::Point > &ref_points, std::vector< std::vector< libMesh::Real > > &lambda_weights)
std::map< std::string, libMesh::EquationSystems * > m_mediator_EquationSystemMap
std::pair< std::string, libMesh::EquationSystems * > m_BIG_EquationSystem
void print_matrix_BIG_info(const std::string &name)
std::map< std::string, double > m_coupling_widthMap
std::map< std::string, double > m_coupling_rigidityMap
std::map< std::string, libMesh::EquationSystems * > m_inter_EquationSystemMap
std::map< std::string, libMesh::EquationSystems * > m_R_micro_EquationSystemMap
void set_corrected_shape_gradients(const std::vector< std::vector< libMesh::Real > > &lambda_weights, const std::vector< std::vector< libMesh::RealGradient > > &phi_inter, std::vector< std::vector< libMesh::RealGradient > > &phi_corrected)
void print_matrix_micro_info(const std::string &name)
libMesh::EquationSystems & add_inter_EquationSystem(const std::string &name, libMesh::MeshBase &interMesh)
std::map< std::string, libMesh::EquationSystems * > m_micro_EquationSystemMap
std::map< std::string, libMesh::EquationSystems * >::iterator EqSystem_iterator
std::map< std::string, libMesh::PetscMatrix< libMesh::Number > * >::iterator Matrix_iterator
void use_H1_coupling(std::string name)
void print_matrix_mediator_info(const std::string &name)
libMesh::PetscMatrix< libMesh::Number > & get_mediator_coupling_matrix(const std::string &name)
std::pair< std::string, libMesh::EquationSystems * > m_R_BIG_EquationSystem
void set_coupling_parameters(const std::string &name, double coupling_rigidity, double coupling_width)
Set physical parameters.
std::map< std::string, bool > m_bUseH1Coupling
libMesh::PetscMatrix< libMesh::Number > & get_micro_coupling_matrix(const std::string &name)
void print_matrices_matlab(const std::string &name, const std::string &outputRoot="coupling")
std::map< std::string, libMesh::PetscMatrix< libMesh::Number > * > m_couplingMatrixMap_mediator_mediator
std::map< std::string, libMesh::PetscMatrix< libMesh::Number > * > m_couplingMatrixMap_mediator_BIG
void set_corrected_shapes(const std::vector< std::vector< libMesh::Real > > &lambda_weights, const std::vector< std::vector< libMesh::Real > > &phi_inter, std::vector< std::vector< libMesh::Real > > &phi_corrected)
void print_PETSC_matrices(const std::string &name, const std::string &outputRoot="coupling")
#define homemade_assert_msg(asserted, msg)
Definition: common_header.h:63
std::map< std::string, libMesh::PetscMatrix< libMesh::Number > * > m_couplingMatrixMap_mediator_micro
void print_matrix(libMesh::PetscMatrix< libMesh::Number > &CouplingTestMatrix)
void use_L2_coupling(std::string name)
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)
void write_PETSC_matrix(Mat input_mat, const std::string &filename, int rank, MPI_Comm comm=PETSC_COMM_WORLD, int dim=1)