Trilinos based (stochastic) FEM solvers
laplacepp.cpp
Go to the documentation of this file.
1 /*
2 Brian Staber (brian.staber@gmail.com)
3 */
4 
5 #include "laplacepp.hpp"
6 
8 }
9 
11  Mesh = &mesh;
12  Comm = Mesh->Comm;
14  OverlapMap = new Epetra_Map(-1,Mesh->n_local_nodes,&Mesh->local_nodes[0],0,*Comm);
15  ImportToOverlapMap = new Epetra_Import(*OverlapMap, *StandardMap);
17 }
18 
19 laplace::laplace(mesh & mesh, Teuchos::ParameterList & Parameters){
20  Mesh = &mesh;
21  Comm = Mesh->Comm;
22  std::string boundary_file = Teuchos::getParameter<std::string>(Parameters, "boundary_file");
23  unsigned int number_physical_groups = Teuchos::getParameter<unsigned int>(Parameters, "nb_phys_groups");
24 
25  Mesh->read_boundary_file(boundary_file,number_physical_groups);
26 
28  OverlapMap = new Epetra_Map(-1,Mesh->n_local_nodes,&Mesh->local_nodes[0],0,*Comm);
29  ImportToOverlapMap = new Epetra_Import(*OverlapMap, *StandardMap);
31 }
32 
33 laplace::laplace(Epetra_Comm & comm, Teuchos::ParameterList & Parameters){
34  std::string mesh_file = Teuchos::getParameter<std::string>(Parameters, "mesh_file");
35  std::string boundary_file = Teuchos::getParameter<std::string>(Parameters, "boundary_file");
36  unsigned int number_physical_groups = Teuchos::getParameter<unsigned int>(Parameters, "nb_phys_groups");
37 
38  Mesh = new mesh(comm, mesh_file, 1.0);
39  Mesh->read_boundary_file(boundary_file,number_physical_groups);
40  Comm = Mesh->Comm;
41 
42  StandardMap = new Epetra_Map(-1,Mesh->n_local_nodes_without_ghosts,&Mesh->local_nodes_without_ghosts[0],0,*Comm);
43  OverlapMap = new Epetra_Map(-1,Mesh->n_local_nodes,&Mesh->local_nodes[0],0,*Comm);
44  ImportToOverlapMap = new Epetra_Import(*OverlapMap, *StandardMap);
46 }
47 
49  //delete Comm;
50  //delete StandardMap;
51  //delete OverlapMap;
52  //delete ImportToOverlapMap;
53  //delete FEGraph;
54 }
55 
57  FEGraph = new Epetra_FECrsGraph(Copy,*StandardMap,100);
58  int eglob, node;
59  int *index;
60  index = new int [Mesh->el_type];
61 
62  for (int eloc=0; eloc<Mesh->n_local_cells; ++eloc){
63  eglob = Mesh->local_cells[eloc];
64  for (int inode=0; inode<Mesh->el_type; ++inode){
65  node = Mesh->cells_nodes[Mesh->el_type*eglob+inode];
66  index[inode] = node;
67  }
68 
69  for (int i=0; i<Mesh->el_type; ++i){
70  for (int j=0; j<Mesh->el_type; ++j){
71  FEGraph->InsertGlobalIndices(1, &index[i], 1, &index[j]);
72  }
73  }
74 
75  }
76  Comm->Barrier();
77  FEGraph->GlobalAssemble();
78  delete[] index;
79 }
80 
81 void laplace::solve_aztec(Teuchos::ParameterList & Parameters, Epetra_FECrsMatrix & matrix, Epetra_Vector & lhs, Epetra_FEVector & rhs, int * bc_indx, double * bc_val){
82 
83  assembling_OAZ(matrix, rhs, bc_indx, bc_val);
84  lhs.PutScalar(0.0);
85 
86  Epetra_LinearProblem problem(&matrix, &lhs, &rhs);
87  AztecOO solver(problem);
88 
89  solver.SetParameters(Parameters);
90 
91  solver.Iterate(2000,1e-6);
92 
93  if (Comm->MyPID()==0){
94  std::cout << "laplace problem. \n";
95  std::cout << "AZTEC_its \t AZTEC_res \t\t AZTEC_time \n";
96  std::cout << solver.NumIters() << "\t\t" << solver.TrueResidual() << "\t\t" << solver.SolveTime() << "\n";
97  }
98 }
99 
100 void laplace::solve_amesos(Teuchos::ParameterList & Parameters, Epetra_FECrsMatrix & matrix, Epetra_Vector & lhs, Epetra_FEVector & rhs, int * bc_indx, double * bc_val){
101 
102  bool display = Teuchos::getParameter<bool>(Parameters,"display");
103  std::string solver_type = Teuchos::getParameter<std::string>(Parameters, "solver_type");
104 
105  /*if (Comm->MyPID()==0 && display){
106  display_amesos_solvers();
107  }*/
108 
109  assembling_OAZ(matrix, rhs, bc_indx, bc_val);
110  lhs.PutScalar(0.0);
111 
112  Epetra_LinearProblem problem(&matrix, &lhs, &rhs);
113 
114  Amesos_BaseSolver* Solver;
115  Amesos Factory;
116  Solver = Factory.Create(solver_type, problem);
117  Solver->SymbolicFactorization();
118  Solver->NumericFactorization();
119  Solver->Solve();
120 }
121 
122 void laplace::assembling_OAZ(Epetra_FECrsMatrix & matrix, Epetra_FEVector & rhs, int * bc_indx, double * bc_val){
123 
124  assembling(matrix,rhs);
125 
126  int ind_bc1 = bc_indx[0];
127  int ind_bc2 = bc_indx[1];
128  double val_bc1 = bc_val[0];
129  double val_bc2 = bc_val[1];
130 
131  Epetra_MultiVector v(*StandardMap,true);
132  v.PutScalar(0.0);
133 
134  int n_BCDof = 0;
135  int node;
136  for (unsigned int i=0; i<Mesh->n_local_nodes_without_ghosts; ++i){
137  if(Mesh->nodes_to_boundaries(i,ind_bc1)==1 || Mesh->nodes_to_boundaries(i,ind_bc2)==1){
138  n_BCDof+=1;
139  }
140  }
141 
142  int indbc = 0;
143  int * dofOnBoundary = new int [n_BCDof];
144 
145  for (unsigned int inode=0; inode<Mesh->n_local_nodes_without_ghosts; ++inode){
146  node = Mesh->local_nodes_without_ghosts[inode];
147  if (Mesh->nodes_to_boundaries(inode,ind_bc1)==1){
148  dofOnBoundary[indbc] = inode;
149  v[0][StandardMap->LID(node)] = val_bc1;
150  indbc++;
151  }
152 
153  if (Mesh->nodes_to_boundaries(inode,ind_bc2)==1){
154  dofOnBoundary[indbc] = inode;
155  v[0][StandardMap->LID(node)] = val_bc2;
156  indbc++;
157  }
158  }
159 
160 
161  Epetra_MultiVector rhsDir(*StandardMap,true);
162  matrix.Apply(v,rhsDir);
163  rhs.Update(-1.0,rhsDir,1.0);
164 
165  for (int inode=0; inode<Mesh->n_local_nodes_without_ghosts; ++inode){
166  node = Mesh->local_nodes_without_ghosts[inode];
167  if (Mesh->nodes_to_boundaries(inode,ind_bc1)==1){
168  rhs[0][StandardMap->LID(node)] = v[0][StandardMap->LID(node)];
169  }
170  if (Mesh->nodes_to_boundaries(inode,ind_bc2)==1){
171  rhs[0][StandardMap->LID(node)] = v[0][StandardMap->LID(node)];
172  }
173  }
174 
175  ML_Epetra::Apply_OAZToMatrix(dofOnBoundary,n_BCDof,matrix);
176  delete[] dofOnBoundary;
177 }
178 
179 void laplace::assembling(Epetra_FECrsMatrix & matrix, Epetra_FEVector & rhs){
180 
181  matrix.PutScalar(0.0);
182  rhs.PutScalar(0.0);
183 
184  Epetra_SerialDenseMatrix B(3,Mesh->el_type);
185  Epetra_SerialDenseMatrix Ke(Mesh->el_type,Mesh->el_type);
186 
187  double gaussWeight; // = 1.0/24.0;
188  int n_gauss_points = Mesh->n_gauss_cells;
189  unsigned int eglob;
190  int *index = new int [Mesh->el_type];
191  int error;
192 
193  for (unsigned int eloc=0; eloc<Mesh->n_local_cells; ++eloc){
194  eglob = Mesh->local_cells[eloc];
195  for (unsigned int inode=0; inode<Mesh->el_type; ++inode){
196  index[inode] = Mesh->cells_nodes[Mesh->el_type*eglob+inode];
197  for (unsigned int jnode=0; jnode<Mesh->el_type; ++jnode){
198  Ke(inode,jnode) = 0.0;
199  }
200  }
201 
202  for (unsigned int gp=0; gp<Mesh->n_gauss_cells; ++gp){
203  gaussWeight = Mesh->gauss_weight_cells(gp);
204  for (unsigned int inode=0; inode<Mesh->el_type; ++inode){
205  B(0,inode) = Mesh->DX_N_cells(gp+n_gauss_points*inode,eloc);
206  B(1,inode) = Mesh->DY_N_cells(gp+n_gauss_points*inode,eloc);
207  B(2,inode) = Mesh->DZ_N_cells(gp+n_gauss_points*inode,eloc);
208  }
209  Ke.Multiply('T','N',gaussWeight*Mesh->detJac_cells(eloc,gp),B,B,1.0);
210  }
211 
212  for (unsigned int inode=0; inode<Mesh->el_type; ++inode){
213  for (unsigned int jnode=0; jnode<Mesh->el_type; ++jnode){
214  error = matrix.SumIntoGlobalValues(1, &index[inode], 1, &index[jnode], &Ke(inode,jnode));
215  }
216  }
217 
218  }
219 
220  Comm->Barrier();
221 
222  matrix.GlobalAssemble();
223  matrix.FillComplete();
224  rhs.GlobalAssemble();
225 
226  delete[] index;
227 }
228 
229 void laplace::compute_local_directions(Epetra_Vector & laplace_one, Epetra_Vector & laplace_two){
230 
231  Epetra_Vector u_phi(*OverlapMap);
232  u_phi.Import(laplace_one, *ImportToOverlapMap, Insert);
233 
234  Epetra_Vector u_psi(*OverlapMap);
235  u_psi.Import(laplace_two, *ImportToOverlapMap, Insert);
236 
237  int node;
238  unsigned int e_gid;
239  double norm_phi, norm_psi;
240  Epetra_SerialDenseMatrix matrix_B(3,Mesh->el_type);
241  Epetra_SerialDenseVector phi_nodes(Mesh->el_type);
242  Epetra_SerialDenseVector psi_nodes(Mesh->el_type);
243  Epetra_SerialDenseVector grad_psi(3);
244  Epetra_SerialDenseVector grad_phi(3);
245  Epetra_SerialDenseMatrix matrix_X(3,Mesh->el_type);
246 
247  Epetra_SerialDenseVector e0(3);
248  Epetra_SerialDenseVector e1(3);
249  Epetra_SerialDenseVector e2(3);
250 
251  int n_gauss_points = Mesh->n_gauss_cells;
252  laplace_direction_one.Reshape(n_gauss_points*Mesh->n_local_cells,3);
253  laplace_direction_two.Reshape(n_gauss_points*Mesh->n_local_cells,3);
254  laplace_direction_two_cross_one.Reshape(n_gauss_points*Mesh->n_local_cells,3);
255 
256  for (unsigned int e_lid=0; e_lid<Mesh->n_local_cells; ++e_lid){
257  e_gid = Mesh->local_cells[e_lid];
258  for (unsigned int inode=0; inode<Mesh->el_type; ++inode){
259  node = Mesh->cells_nodes[Mesh->el_type*e_gid+inode];
260  phi_nodes(inode) = u_phi[OverlapMap->LID(node)];
261  psi_nodes(inode) = u_psi[OverlapMap->LID(node)];
262  matrix_X(0,inode) = Mesh->nodes_coord[3*node+0];
263  matrix_X(1,inode) = Mesh->nodes_coord[3*node+1];
264  matrix_X(2,inode) = Mesh->nodes_coord[3*node+2];
265  }
266 
267  for (unsigned int gp=0; gp<n_gauss_points; ++gp){
268  for (unsigned int inode=0; inode<Mesh->el_type; ++inode){
269  matrix_B(0,inode) = Mesh->DX_N_cells(gp+n_gauss_points*inode,e_lid);
270  matrix_B(1,inode) = Mesh->DY_N_cells(gp+n_gauss_points*inode,e_lid);
271  matrix_B(2,inode) = Mesh->DZ_N_cells(gp+n_gauss_points*inode,e_lid);
272  }
273 
274  grad_phi.Multiply('N','N',1.0,matrix_B,phi_nodes,0.0);
275  grad_psi.Multiply('N','N',1.0,matrix_B,psi_nodes,0.0);
276 
277  norm_phi = grad_phi.Norm2();
278  norm_psi = grad_psi.Norm2();
279 
280  e0(0) = grad_phi(0)/norm_phi;
281  e0(1) = grad_phi(1)/norm_phi;
282  e0(2) = grad_phi(2)/norm_phi;
283 
284  e2(0) = grad_psi(0)/norm_psi;
285  e2(1) = grad_psi(1)/norm_psi;
286  e2(2) = grad_psi(2)/norm_psi;
287 
288  e1(0) = e2(1)*e0(2) - e2(2)*e0(1);
289  e1(1) = e2(2)*e0(0) - e2(0)*e0(2);
290  e1(2) = e2(0)*e0(1) - e2(1)*e0(0);
291 
292  laplace_direction_one(n_gauss_points*e_lid+gp,0) = e0(0);
293  laplace_direction_one(n_gauss_points*e_lid+gp,1) = e0(1);
294  laplace_direction_one(n_gauss_points*e_lid+gp,2) = e0(2);
295 
296  laplace_direction_two(n_gauss_points*e_lid+gp,0) = e2(0);
297  laplace_direction_two(n_gauss_points*e_lid+gp,1) = e2(1);
298  laplace_direction_two(n_gauss_points*e_lid+gp,2) = e2(2);
299 
300  laplace_direction_two_cross_one(n_gauss_points*e_lid+gp,0) = e1(0);
301  laplace_direction_two_cross_one(n_gauss_points*e_lid+gp,1) = e1(1);
302  laplace_direction_two_cross_one(n_gauss_points*e_lid+gp,2) = e1(2);
303  }
304  }
305 }
306 
307 void laplace::compute_center_local_directions(Epetra_Vector & laplace_one, Epetra_Vector & laplace_two){
308 
309  Epetra_Vector u_phi(*OverlapMap);
310  u_phi.Import(laplace_one, *ImportToOverlapMap, Insert);
311 
312  Epetra_Vector u_psi(*OverlapMap);
313  u_psi.Import(laplace_two, *ImportToOverlapMap, Insert);
314 
315  int node;
316  unsigned int e_gid;
317  double norm_phi, norm_psi;
318  Epetra_SerialDenseVector phi_nodes(Mesh->el_type);
319  Epetra_SerialDenseVector psi_nodes(Mesh->el_type);
320  Epetra_SerialDenseVector grad_psi(3);
321  Epetra_SerialDenseVector grad_phi(3);
322  Epetra_SerialDenseMatrix matrix_X(3,Mesh->el_type);
323  Epetra_SerialDenseMatrix dx_shape_functions(Mesh->el_type,3), D(Mesh->el_type,3);
324  Epetra_SerialDenseMatrix JacobianMatrix(3,3);
325 
326  Epetra_SerialDenseVector e0(3);
327  Epetra_SerialDenseVector e1(3);
328  Epetra_SerialDenseVector e2(3);
329 
330  int n_gauss_points = Mesh->n_gauss_cells;
334 
335  double det_jac_cells;
336  switch (Mesh->el_type){
337  double xi;
338  case 4:
339  xi = 1.0/3.0;
340  tetra4::d_shape_functions(D, xi, xi, xi);
341  break;
342  case 8:
343  xi = 0.0;
344  hexa8::d_shape_functions(D, xi, xi, xi);
345  break;
346  case 10:
347  xi = 1.0/3.0;
348  tetra10::d_shape_functions(D, xi, xi, xi);
349  break;
350  };
351  for (unsigned int e_lid=0; e_lid<Mesh->n_local_cells; ++e_lid){
352  e_gid = Mesh->local_cells[e_lid];
353  for (unsigned int inode=0; inode<Mesh->el_type; ++inode){
354  node = Mesh->cells_nodes[Mesh->el_type*e_gid+inode];
355  phi_nodes(inode) = u_phi[OverlapMap->LID(node)];
356  psi_nodes(inode) = u_psi[OverlapMap->LID(node)];
357  matrix_X(0,inode) = Mesh->nodes_coord[3*node+0];
358  matrix_X(1,inode) = Mesh->nodes_coord[3*node+1];
359  matrix_X(2,inode) = Mesh->nodes_coord[3*node+2];
360  }
361 
362  jacobian_matrix(matrix_X,D,JacobianMatrix);
363  jacobian_det(JacobianMatrix,det_jac_cells);
364  dX_shape_functions(D,JacobianMatrix,det_jac_cells,dx_shape_functions);
365 
366  grad_phi.Multiply('T','N',1.0,dx_shape_functions,phi_nodes,0.0);
367  grad_psi.Multiply('T','N',1.0,dx_shape_functions,psi_nodes,0.0);
368 
369  norm_phi = grad_phi.Norm2();
370  norm_psi = grad_psi.Norm2();
371 
372  e0(0) = grad_phi(0)/norm_phi;
373  e0(1) = grad_phi(1)/norm_phi;
374  e0(2) = grad_phi(2)/norm_phi;
375 
376  e2(0) = grad_psi(0)/norm_psi;
377  e2(1) = grad_psi(1)/norm_psi;
378  e2(2) = grad_psi(2)/norm_psi;
379 
380  e1(0) = e2(1)*e0(2) - e2(2)*e0(1);
381  e1(1) = e2(2)*e0(0) - e2(0)*e0(2);
382  e1(2) = e2(0)*e0(1) - e2(1)*e0(0);
383 
384  laplace_direction_one_center(e_lid,0) = e0(0);
385  laplace_direction_one_center(e_lid,1) = e0(1);
386  laplace_direction_one_center(e_lid,2) = e0(2);
387 
388  laplace_direction_two_center(e_lid,0) = e2(0);
389  laplace_direction_two_center(e_lid,1) = e2(1);
390  laplace_direction_two_center(e_lid,2) = e2(2);
391 
395  }
396 
397 }
398 
399 int laplace::print_solution(Epetra_Vector & lhs, std::string fileName){
400  int NumTargetElements = 0;
401  if (Comm->MyPID()==0){
402  NumTargetElements = Mesh->n_nodes;
403  }
404  Epetra_Map MapOnRoot(-1,NumTargetElements,0,*Comm);
405  Epetra_Export ExportOnRoot(*StandardMap,MapOnRoot);
406  Epetra_MultiVector lhs_root(MapOnRoot,true);
407  lhs_root.Export(lhs,ExportOnRoot,Insert);
408  int error = EpetraExt::MultiVectorToMatrixMarketFile(fileName.c_str(),lhs_root,0,0,false);
409  return error;
410 }
Epetra_Comm * Comm
for j
Definition: costFunction.m:42
void assembling_OAZ(Epetra_FECrsMatrix &matrix, Epetra_FEVector &rhs, int *bc_indx, double *bc_val)
Definition: laplacepp.cpp:122
std::vector< int > local_nodes
Definition: meshpp.hpp:80
Epetra_SerialDenseVector DZ_N_cells
Definition: meshpp.hpp:73
std::vector< double > nodes_coord
Definition: meshpp.hpp:77
~laplace()
Definition: laplacepp.cpp:48
void assembling(Epetra_FECrsMatrix &matrix, Epetra_FEVector &rhs)
Definition: laplacepp.cpp:179
int print_solution(Epetra_Vector &lhs, std::string fileName)
Definition: laplacepp.cpp:399
void compute_center_local_directions(Epetra_Vector &laplace_one, Epetra_Vector &laplace_two)
Definition: laplacepp.cpp:307
Epetra_Comm * Comm
Definition: meshpp.hpp:69
int n_local_cells
Definition: meshpp.hpp:94
void d_shape_functions(Epetra_SerialDenseMatrix &D, double &xi, double &eta, double &zeta)
Definition: fepp.cpp:99
int read_boundary_file(std::string &fileName_bc, unsigned int &number_physical_groups)
Definition: meshpp.cpp:270
void dX_shape_functions(Epetra_SerialDenseMatrix &D, Epetra_SerialDenseMatrix JacobianMatrix, double &jac, Epetra_SerialDenseMatrix &DX)
Definition: fepp.cpp:152
Epetra_SerialDenseVector DX_N_cells
Definition: meshpp.hpp:73
Epetra_SerialDenseVector detJac_cells
Definition: meshpp.hpp:73
Epetra_FECrsGraph * FEGraph
Definition: meshpp.hpp:49
Epetra_IntSerialDenseMatrix nodes_to_boundaries
Definition: meshpp.hpp:75
Epetra_SerialDenseMatrix laplace_direction_two_center
Definition: laplacepp.hpp:29
std::vector< int > local_cells
Definition: meshpp.hpp:81
clc clear all close all mesh
Definition: run.m:5
void d_shape_functions(Epetra_SerialDenseMatrix &D, double &xi, double &eta, double &zeta)
Definition: fepp.cpp:139
int n_local_nodes_without_ghosts
Definition: meshpp.hpp:92
int n_local_nodes
Definition: meshpp.hpp:93
void jacobian_det(Epetra_SerialDenseMatrix &JacobianMatrix, double &jac)
Definition: fepp.cpp:175
int el_type
Definition: meshpp.hpp:90
Epetra_SerialDenseVector DY_N_cells
Definition: meshpp.hpp:73
std::vector< int > cells_nodes
Definition: meshpp.hpp:78
Epetra_SerialDenseMatrix laplace_direction_two
Definition: laplacepp.hpp:29
void create_FECrsGraph()
Definition: laplacepp.cpp:56
Epetra_SerialDenseMatrix laplace_direction_one
Definition: laplacepp.hpp:28
Epetra_Import * ImportToOverlapMap
Epetra_Map * StandardMap
laplace()
Definition: laplacepp.cpp:7
unsigned int n_gauss_cells
Definition: meshpp.hpp:98
Epetra_SerialDenseMatrix laplace_direction_two_cross_one
Definition: laplacepp.hpp:30
Epetra_SerialDenseMatrix laplace_direction_one_center
Definition: laplacepp.hpp:28
std::vector< int > local_nodes_without_ghosts
Definition: meshpp.hpp:79
Epetra_SerialDenseMatrix laplace_direction_two_cross_one_center
Definition: laplacepp.hpp:30
int n_nodes
Definition: meshpp.hpp:87
void compute_local_directions(Epetra_Vector &laplace_one, Epetra_Vector &laplace_two)
Definition: laplacepp.cpp:229
void solve_amesos(Teuchos::ParameterList &Parameters, Epetra_FECrsMatrix &matrix, Epetra_Vector &lhs, Epetra_FEVector &rhs, int *bc_indx, double *bc_val)
Definition: laplacepp.cpp:100
void d_shape_functions(Epetra_SerialDenseMatrix &D, double &xi, double &eta, double &zeta)
Definition: fepp.cpp:118
for i
Definition: costFunction.m:38
Epetra_Map * OverlapMap
e
Definition: run.m:10
Epetra_SerialDenseVector gauss_weight_cells
Definition: meshpp.hpp:99
void jacobian_matrix(Epetra_SerialDenseMatrix &X, Epetra_SerialDenseMatrix &D, Epetra_SerialDenseMatrix &JacobianMatrix)
Definition: fepp.cpp:171
void solve_aztec(Teuchos::ParameterList &Parameters, Epetra_FECrsMatrix &matrix, Epetra_Vector &lhs, Epetra_FEVector &rhs, int *bc_indx, double *bc_val)
Definition: laplacepp.cpp:81