Trilinos based (stochastic) FEM solvers
manufacturedSolution.hpp
Go to the documentation of this file.
1 /*
2 Brian Staber (brian.staber@gmail.com)
3 */
4 
5 #ifndef manufactured_HPP
6 #define manufactured_HPP
7 
8 #include "tensor_calculus.hpp"
10 
12 {
13 public:
14 
15  Teuchos::ParameterList * Krylov;
16  Epetra_Vector * uh;
17 
18  manufactured(Epetra_Comm & comm, Teuchos::ParameterList & Parameters, std::string & mesh_file){
19 
20  Krylov = &Parameters.sublist("Krylov");
21 
22  Mesh = new mesh(comm, mesh_file, 1.0);
23  Comm = Mesh->Comm;
24 
26  OverlapMap = new Epetra_Map(-1,3*Mesh->n_local_nodes,&Mesh->local_dof[0],0,*Comm);
27  ImportToOverlapMap = new Epetra_Import(*OverlapMap,*StandardMap);
29 
31  uh = new Epetra_Vector(*StandardMap);
32  }
33 
35  }
36 
37  Epetra_SerialDenseVector manufacturedSolution(double & x1, double & x2, double & x3){
38  Epetra_SerialDenseVector u(3);
39  double c1 = 2.0e-5; double c2 = 1.0e-5; double c3 = 2.0e-5; double topcoord = 25.0;
40  u(0) = -c1*x2*(topcoord-x1)*(topcoord - x2);
41  u(1) = c2*x2*(topcoord/2.0-x2);
42  u(2) = std::sin(c1*x3);
43  return u;
44  }
45 
46  Epetra_SerialDenseMatrix manufacturedDeformation(double & x1, double & x2, double & x3){
47  Epetra_SerialDenseMatrix epsilon(3,3);
48  double c1 = 2.0e-5; double c2 = 1.0e-5; double c3 = 2.0e-5; double topcoord = 25.0;
49  epsilon(0,0) = c1*x2*(topcoord - x2);
50  epsilon(1,1) = c2*(topcoord/2 - x2) - c2*x2;
51  epsilon(2,2) = c1*std::cos(c1*x3);
52  epsilon(1,2) = 0.0; epsilon(2,1) = 0.0;
53  epsilon(0,2) = 0.0; epsilon(2,0) = 0.0;
54  epsilon(0,1) = (c1*x2*(topcoord-x1))/2.0 - (c1*(topcoord-x1)*(topcoord-x2))/2.0; epsilon(1,0) = epsilon(0,1);
55  return epsilon;
56  }
57 
58  Epetra_SerialDenseMatrix manufacturedStress(double & x1, double & x2, double & x3){
59  Epetra_SerialDenseMatrix sigma(3,3), epsilon(3,3), elasticity(6,6);
60  Epetra_SerialDenseVector sigma_voigt(6), epsilon_voigt(6);
61  epsilon = manufacturedDeformation(x1,x2,x3);
62  epsilon_voigt(0) = epsilon(0,0); epsilon_voigt(1) = epsilon(1,1); epsilon_voigt(2) = epsilon(2,2);
63  epsilon_voigt(3) = std::sqrt(2.0)*epsilon(1,2); epsilon_voigt(4) = std::sqrt(2.0)*epsilon(0,2); epsilon_voigt(5) = std::sqrt(2.0)*epsilon(0,1);
64  unsigned int e_lid = 0;
65  unsigned int gp = 0;
66  get_elasticity_tensor(e_lid,gp,elasticity);
67  sigma_voigt.Multiply('N','N',1.0,elasticity,epsilon_voigt,0.0);
68  sigma(0,0) = sigma_voigt(0); sigma(0,1) = sigma_voigt(5)/std::sqrt(2.0); sigma(0,2) = sigma_voigt(4)/std::sqrt(2.0);
69  sigma(1,0) = sigma_voigt(5)/std::sqrt(2.0); sigma(1,1) = sigma_voigt(1); sigma(1,2) = sigma_voigt(3)/std::sqrt(2.0);
70  sigma(2,0) = sigma_voigt(4)/std::sqrt(2.0); sigma(2,1) = sigma_voigt(3)/std::sqrt(2.0); sigma(2,2) = sigma_voigt(2);
71  return sigma;
72  }
73 
74  Epetra_SerialDenseVector get_neumannBc(Epetra_SerialDenseMatrix & matrix_X, Epetra_SerialDenseMatrix & xg, unsigned int & gp){
75  Epetra_SerialDenseVector t(3), normal(3);
76  Epetra_SerialDenseMatrix sigma(3,3), d_shape_functions(Mesh->face_type,2), dxi_matrix_x(3,2);
77  sigma = manufacturedStress(xg(0,gp),xg(1,gp),xg(2,gp));
78  for (unsigned int inode=0; inode<Mesh->face_type; ++inode){
79  d_shape_functions(inode,0) = Mesh->D1_N_faces(gp,inode);
80  d_shape_functions(inode,1) = Mesh->D2_N_faces(gp,inode);
81  }
82  dxi_matrix_x.Multiply('N','N',1.0,matrix_X,d_shape_functions,0.0);
83  normal(0) = dxi_matrix_x(1,0)*dxi_matrix_x(2,1) - dxi_matrix_x(2,0)*dxi_matrix_x(1,1);
84  normal(1) = dxi_matrix_x(2,0)*dxi_matrix_x(0,1) - dxi_matrix_x(0,0)*dxi_matrix_x(2,1);
85  normal(2) = dxi_matrix_x(0,0)*dxi_matrix_x(1,1) - dxi_matrix_x(1,0)*dxi_matrix_x(0,1);
86  if (xg(2,gp)==0.0){
87  normal.Scale(-1.0);
88  }
89  t.Multiply('N','N',1.0,sigma,normal,0.0);
90  return t;
91  }
92  Epetra_SerialDenseVector get_forcing(double & x1, double & x2, double & x3, unsigned int & e_lid, unsigned int & gp){
93  Epetra_SerialDenseVector f(3);
94  Epetra_SerialDenseMatrix C(6,6);
95  get_elasticity_tensor(e_lid,gp,C);
96  double k = std::sqrt(2.0);
97  double C11 = C(0,0); double C12 = C(0,1); double C13 = C(0,2); double C14 = C(0,3); double C15 = C(0,4); double C16 = C(0,5);
98  double C22 = C(1,1); double C23 = C(1,2); double C24 = C(1,3); double C25 = C(1,4); double C26 = C(1,5);
99  double C33 = C(2,2); double C34 = C(2,3); double C35 = C(2,4); double C36 = C(2,5);
100  double C44 = C(3,3); double C45 = C(3,4); double C46 = C(3,5);
101  double C55 = C(4,4); double C56 = C(4,5);
102  double C66 = C(5,5);
103  double c1 = 2.0e-5; double c2 = 1.0e-5; double c3 = 2.0e-5; double topcoord = 25.0;
104  f(0) = C66*c1*topcoord - k*C26*c2 - C66*c1*x1 - (k*C35*c1*c1*std::sin(c1*x3))/2 + k*C16*c1*topcoord - 2*k*C16*c1*x2;
105  f(1) = C12*c1*(topcoord - x2) - C66*((c1*x2)/2 - (c1*(topcoord - x2))/2) - C12*c1*x2 - 2*C22*c2 + k*C26*c1*(topcoord - x1) - (k*C34*c1*c1*std::sin(c1*x3))/2;
106  f(2) = - (k*(2*C24*c2 + C14*c1*x2 - C14*c1*(topcoord - x2) - k*C46*c1*(topcoord - x1)))/2 - C56*((c1*x2)/2 - (c1*(topcoord - x2))/2) - C33*c1*c1*std::sin(c1*x3);
107  f.Scale(-1.0);
108  return f;
109  }
110 
111  double solve(std::string & outPath){
112  Epetra_FECrsMatrix linearOperator(Copy,*FEGraph);
113  Epetra_FEVector rhs(*StandardMap);
114  rhs.PutScalar(0.0);
115  double dummy = 0.0;
117  apply_dirichlet_conditions(linearOperator,rhs,dummy);
118  aztecSolver(linearOperator,rhs,*uh,*Krylov);
119  print_solution(*uh,outPath);
120 
121  double totalError = errorL2(*uh);
122  return totalError;
123  }
124 
125  double errorL2(Epetra_Vector & uStandardMap){
126 
127  Epetra_Vector u(*OverlapMap);
128  u.Import(uStandardMap, *ImportToOverlapMap, Insert);
129  double totalError;
130  double error = 0.0;
131  double normVH;
132  double gauss_weight;
133  int n_gauss_points = Mesh->n_gauss_cells;
134  int e_gid, node;
135 
136  //Epetra_SerialDenseVector epsilon(6);
137  //Epetra_SerialDenseMatrix matrix_B(6,3*Mesh->el_type);
138  Epetra_SerialDenseVector uExact(3), vH(3);
139  Epetra_SerialDenseMatrix dx_shape_functions(Mesh->el_type,3), X_I(3,Mesh->el_type), u_I(3,Mesh->el_type);
140  Epetra_SerialDenseMatrix u_G(3,n_gauss_points), x_G(3,n_gauss_points);
141 
142  for (unsigned int e_lid=0; e_lid<Mesh->n_local_cells; ++e_lid){
143  e_gid = Mesh->local_cells[e_lid];
144  for (unsigned int inode=0; inode<Mesh->el_type; ++inode){
145  node = Mesh->cells_nodes[Mesh->el_type*e_gid+inode];
146  X_I(0,inode) = Mesh->nodes_coord[3*node+0];
147  X_I(1,inode) = Mesh->nodes_coord[3*node+1];
148  X_I(2,inode) = Mesh->nodes_coord[3*node+2];
149  u_I(0,inode) = u[OverlapMap->LID(3*node+0)];
150  u_I(1,inode) = u[OverlapMap->LID(3*node+1)];
151  u_I(2,inode) = u[OverlapMap->LID(3*node+2)];
152  }
153  x_G.Multiply('N','N',1.0,X_I,Mesh->N_cells,0.0);
154  u_G.Multiply('N','N',1.0,u_I,Mesh->N_cells,0.0);
155  for (unsigned int gp=0; gp<n_gauss_points; ++gp){
156  gauss_weight = Mesh->gauss_weight_cells(gp);
157  uExact = manufacturedSolution(x_G(0,gp),x_G(1,gp),x_G(2,gp));
158  vH(0) = uExact(0) - u_G(0,gp);
159  vH(1) = uExact(1) - u_G(1,gp);
160  vH(2) = uExact(2) - u_G(2,gp);
161  normVH = vH.Norm2();
162  /*for (unsigned int inode=0; inode<Mesh->el_type; ++inode){
163  dx_shape_functions(inode,0) = Mesh->DX_N_cells(gp+n_gauss_points*inode,e_lid);
164  dx_shape_functions(inode,1) = Mesh->DY_N_cells(gp+n_gauss_points*inode,e_lid);
165  dx_shape_functions(inode,2) = Mesh->DZ_N_cells(gp+n_gauss_points*inode,e_lid);
166  }
167  compute_B_matrices(dx_shape_functions,matrix_B);
168  epsilon.Multiply('N','N',1.0,matrix_B,vector_u,0.0);*/
169  error += gauss_weight*normVH*normVH*Mesh->detJac_cells(e_lid,gp);
170  }
171  }
172  Comm->SumAll(&error,&totalError,1);
173  totalError = std::sqrt(totalError);
174  return totalError;
175  }
176 
178  n_bc_dof = 0;
179  double x;
180  unsigned int node;
181  for (unsigned int i=0; i<Mesh->n_local_nodes_without_ghosts; ++i){
182  node = Mesh->local_nodes[i];
183  x = Mesh->nodes_coord[3*node+1];
184  if(x==0.0 || x==25.0){
185  n_bc_dof+=3;
186  }
187  }
188 
189  int indbc = 0;
190  dof_on_boundary = new int [n_bc_dof];
191  for (unsigned int inode=0; inode<Mesh->n_local_nodes_without_ghosts; ++inode){
192  node = Mesh->local_nodes[inode];
193  x = Mesh->nodes_coord[3*node+1];
194  if(x==0.0 || x==25.0){
195  dof_on_boundary[indbc+0] = 3*inode+0;
196  dof_on_boundary[indbc+1] = 3*inode+1;
197  dof_on_boundary[indbc+2] = 3*inode+2;
198  indbc+=3;
199  }
200  }
201  }
202 
203  void apply_dirichlet_conditions(Epetra_FECrsMatrix & K, Epetra_FEVector & F, double & displacement){
204  Epetra_MultiVector v(*StandardMap,true);
205  v.PutScalar(0.0);
206 
207  int node;
208  double x, y, z;
209  Epetra_SerialDenseVector u(3);
210  for (unsigned int inode=0; inode<Mesh->n_local_nodes_without_ghosts; ++inode){
211  node = Mesh->local_nodes[inode];
212  x = Mesh->nodes_coord[3*node+0];
213  y = Mesh->nodes_coord[3*node+1];
214  z = Mesh->nodes_coord[3*node+2];
215  if(y==0.0 || y==25.0){
216  u = manufacturedSolution(x,y,z);
217  v[0][StandardMap->LID(3*node+0)] = u(0);
218  v[0][StandardMap->LID(3*node+1)] = u(1);
219  v[0][StandardMap->LID(3*node+2)] = u(2);
220  }
221  }
222 
223  Epetra_MultiVector rhs_dir(*StandardMap,true);
224  K.Apply(v,rhs_dir);
225  F.Update(-1.0,rhs_dir,1.0);
226 
227  for (unsigned int inode=0; inode<Mesh->n_local_nodes_without_ghosts; ++inode){
228  node = Mesh->local_nodes[inode];
229  x = Mesh->nodes_coord[3*node+0];
230  y = Mesh->nodes_coord[3*node+1];
231  z = Mesh->nodes_coord[3*node+2];
232  if(y==0.0 || y==25.0){
233  F[0][StandardMap->LID(3*node+0)] = v[0][StandardMap->LID(3*node+0)];
234  F[0][StandardMap->LID(3*node+1)] = v[0][StandardMap->LID(3*node+1)];
235  F[0][StandardMap->LID(3*node+2)] = v[0][StandardMap->LID(3*node+2)];
236  }
237  }
238  ML_Epetra::Apply_OAZToMatrix(dof_on_boundary,n_bc_dof,K);
239  }
240 
241  void get_elasticity_tensor(unsigned int & e_lid, unsigned int & gp, Epetra_SerialDenseMatrix & tangent_matrix){
242  int e_gid = Mesh->local_cells[e_lid];
243  int n_gauss_cells = Mesh->n_gauss_cells;
244  double c1 = 144.8969e3;
245  double c2 = 14.2500e3;
246  double c3 = 5.8442e3;
247  double c4 = 7.5462e3;
248  double c5 = 12.5580e3;
249  transverse_isotropic_matrix(tangent_matrix,c1,c2,c3,c4,c5);
250  }
251 
252  void transverse_isotropic_matrix(Epetra_SerialDenseMatrix & C, double & c1, double & c2, double & c3, double & c4, double & c5){
253  C(0,0) = c1/16.0 + (9.0*c2)/32.0 + (9.0*c4)/32.0 + (3.0*c5)/8.0 + (3.0*std::sqrt(2.0)*c3)/16.0;
254  C(0,1) = (3.0*c1)/16.0 + (3.0*c2)/32.0 + (3.0*c4)/32.0 - (3.0*c5)/8.0 + (5.0*std::sqrt(2.0)*c3)/16.0;
255  C(0,2) = (3.0*c2)/8.0 - (3.0*c4)/8.0 + (std::sqrt(2.0)*c3)/8.0;
256  C(0,3) = 0.0;
257  C(0,4) = 0.0;
258  C(0,5) = std::sqrt(6)*(c1/16.0 - (3.0*c2)/32.0 - (3.0*c4)/32.0 + c5/8.0 + (std::sqrt(2.0)*c3)/16.0);
259 
260  C(1,0) = (3.0*c1)/16.0 + (3.0*c2)/32.0 + (3.0*c4)/32.0 - (3.0*c5)/8.0 + (5*std::sqrt(2.0)*c3)/16.0;
261  C(1,1) = (9.0*c1)/16.0 + c2/32.0 + c4/32.0 + (3.0*c5)/8.0 + (3.0*std::sqrt(2.0)*c3)/16.0;
262  C(1,2) = c2/8.0 - c4/8.0 + (3.0*std::sqrt(2.0)*c3)/8.0;
263  C(1,3) = 0.0;
264  C(1,4) = 0.0;
265  C(1,5) = -std::sqrt(6.0)*(c2/32.0 - (3.0*c1)/16.0 + c4/32.0 + c5/8.0 + (std::sqrt(2.0)*c3)/16.0);
266 
267  C(2,0) = (3.0*c2)/8.0 - (3.0*c4)/8.0 + std::sqrt(2.0)*c3/8.0;
268  C(2,1) = c2/8.0 - c4/8.0 + (3.0*std::sqrt(2.0)*c3)/8.0;
269  C(2,2) = c2/2.0 + c4/2.0;
270  C(2,3) = 0.0;
271  C(2,4) = 0.0;
272  C(2,5) = (std::sqrt(3.0)*(2.0*c3 - std::sqrt(2.0)*c2 + std::sqrt(2.0)*c4))/8.0;
273 
274  C(3,0) = 0.0;
275  C(3,1) = 0.0;
276  C(3,2) = 0.0;
277  C(3,3) = c4/4.0 + (3.0*c5)/4.0;
278  C(3,4) = -(std::sqrt(3.0)*(c4 - c5))/4.0;
279  C(3,5) = 0.0;
280 
281  C(4,0) = 0.0;
282  C(4,1) = 0.0;
283  C(4,2) = 0.0;
284  C(4,3) = -(std::sqrt(3.0)*(c4 - c5))/4.0;
285  C(4,4) = (3.0*c4)/4.0 + c5/4.0;
286  C(4,5) = 0.0;
287 
288  C(5,0) = std::sqrt(6.0)*(c1/16.0 - (3.0*c2)/32.0 - (3.0*c4)/32.0 + c5/8.0 + std::sqrt(2.0)*c3/16.0);
289  C(5,1) = -std::sqrt(6.0)*(c2/32.0 - (3.0*c1)/16.0 + c4/32.0 + c5/8.0 + (std::sqrt(2.0)*c3)/16.0);
290  C(5,2) = (std::sqrt(3.0)*(2.0*c3 - std::sqrt(2.0)*c2 + std::sqrt(2.0)*c4))/8.0;
291  C(5,3) = 0.0;
292  C(5,4) = 0.0;
293  C(5,5) = (3.0*c1)/8.0 + (3.0*c2)/16.0 + (3.0*c4)/16.0 + c5/4.0 - (3.0*std::sqrt(2.0)*c3)/8.0;
294  }
295 
296  void get_elasticity_tensor_for_recovery(unsigned int & e_lid, Epetra_SerialDenseMatrix & tangent_matrix){
297  }
298 };
299 
300 
301 #endif
Epetra_Comm * Comm
u
Definition: run.m:9
int print_solution(Epetra_Vector &solution, std::string fileName)
void assembleMixedDirichletNeumann_inhomogeneousForcing(Epetra_FECrsMatrix &K, Epetra_FEVector &F)
std::vector< int > local_nodes
Definition: meshpp.hpp:80
double solve(std::string &outPath)
std::vector< double > nodes_coord
Definition: meshpp.hpp:77
std::vector< int > local_dof
Definition: meshpp.hpp:80
Epetra_SerialDenseMatrix D2_N_faces
Definition: meshpp.hpp:71
Epetra_SerialDenseVector N_cells
Definition: meshpp.hpp:73
Epetra_Comm * Comm
Definition: meshpp.hpp:69
int n_local_cells
Definition: meshpp.hpp:94
Epetra_SerialDenseMatrix manufacturedStress(double &x1, double &x2, double &x3)
Epetra_SerialDenseVector get_neumannBc(Epetra_SerialDenseMatrix &matrix_X, Epetra_SerialDenseMatrix &xg, unsigned int &gp)
int face_type
Definition: meshpp.hpp:91
Epetra_SerialDenseVector detJac_cells
Definition: meshpp.hpp:73
Epetra_FECrsGraph * FEGraph
void get_elasticity_tensor_for_recovery(unsigned int &e_lid, Epetra_SerialDenseMatrix &tangent_matrix)
std::vector< int > local_cells
Definition: meshpp.hpp:81
for k
Definition: costFunction.m:51
clc clear all close all mesh
Definition: run.m:5
Epetra_SerialDenseVector get_forcing(double &x1, double &x2, double &x3, unsigned int &e_lid, unsigned int &gp)
Teuchos::ParameterList * Krylov
Epetra_Vector * uh
int n_local_nodes_without_ghosts
Definition: meshpp.hpp:92
int n_local_nodes
Definition: meshpp.hpp:93
int el_type
Definition: meshpp.hpp:90
std::vector< int > cells_nodes
Definition: meshpp.hpp:78
Epetra_Import * ImportToOverlapMap
Epetra_Map * StandardMap
Epetra_SerialDenseMatrix D1_N_faces
Definition: meshpp.hpp:71
unsigned int n_gauss_cells
Definition: meshpp.hpp:98
manufactured(Epetra_Comm &comm, Teuchos::ParameterList &Parameters, std::string &mesh_file)
Epetra_SerialDenseMatrix manufacturedDeformation(double &x1, double &x2, double &x3)
std::vector< int > local_dof_without_ghosts
Definition: meshpp.hpp:79
void d_shape_functions(Epetra_SerialDenseMatrix &D, double &xi, double &eta)
Definition: fepp.cpp:12
for i
Definition: costFunction.m:38
Epetra_Map * OverlapMap
Epetra_SerialDenseVector manufacturedSolution(double &x1, double &x2, double &x3)
void get_elasticity_tensor(unsigned int &e_lid, unsigned int &gp, Epetra_SerialDenseMatrix &tangent_matrix)
void aztecSolver(Epetra_FECrsMatrix &A, Epetra_FEVector &b, Epetra_Vector &u, Teuchos::ParameterList &paramList)
t
Definition: run.m:7
double errorL2(Epetra_Vector &uStandardMap)
void transverse_isotropic_matrix(Epetra_SerialDenseMatrix &C, double &c1, double &c2, double &c3, double &c4, double &c5)
Epetra_SerialDenseVector gauss_weight_cells
Definition: meshpp.hpp:99
void apply_dirichlet_conditions(Epetra_FECrsMatrix &K, Epetra_FEVector &F, double &displacement)