Trilinos based (stochastic) FEM solvers
dirichletInletOutlet_PolyconvexHGO.hpp
Go to the documentation of this file.
1 /*
2 Brian Staber (brian.staber@gmail.com)
3 */
4 
5 #ifndef DIRICHLETINLETOUTLET_POLYCONVEXHGO_HPP
6 #define DIRICHLETINLETOUTLET_POLYCONVEXHGO_HPP
7 
8 #include "tensor_calculus.hpp"
9 #include "laplacepp.hpp"
11 
13 {
14 public:
15 
17 
18  double mu1, mu2, mu3, mu4, beta3, beta4, theta, xxmax;
19  int fixed = 2;
20  int moved = 3;
21 
22  Epetra_SerialDenseVector a, b;
23 
24  dirichletInletOutlet_PolyconvexHGO(Epetra_Comm & comm, Teuchos::ParameterList & Parameters){
25 
26  std::string mesh_file = Teuchos::getParameter<std::string>(Parameters.sublist("Mesh"), "mesh_file");
27  std::string boundary_file = Teuchos::getParameter<std::string>(Parameters.sublist("Mesh"), "boundary_file");
28  unsigned int number_physical_groups = Teuchos::getParameter<unsigned int>(Parameters.sublist("Mesh"), "nb_phys_groups");
29 
30  Mesh = new mesh(comm, mesh_file, 1);
31  Mesh->read_boundary_file(boundary_file,number_physical_groups);
32  Comm = Mesh->Comm;
33 
34  Laplace = new laplace(*Mesh);
35 
36  //$$Laplace
37  Epetra_FECrsMatrix matrix(Copy,*Laplace->FEGraph);
38  Epetra_Vector psi(*Laplace->StandardMap);
39  Epetra_Vector phi(*Laplace->StandardMap);
40  Epetra_FEVector rhs(*Laplace->StandardMap);
41  int bc_indx[2];
42  double bc_val[2];
43  bc_val[0] = 0.0; bc_val[1] = 1.0;
44  //Problem number one with aztec
45  bc_indx[0] = 2; bc_indx[1] = 3;
46  Laplace->solve_aztec(Parameters.sublist("Laplace"), matrix, phi, rhs, &bc_indx[0], &bc_val[0]);
47  Laplace->print_solution(phi, "laplace_inlet_to_outlet_aztec.mtx");
48  //Problem number one with aztec
49  bc_indx[0] = 0; bc_indx[1] = 1;
50  Laplace->solve_aztec(Parameters.sublist("Laplace"), matrix, psi, rhs, &bc_indx[0], &bc_val[0]);
51  Laplace->print_solution(psi, "laplace_inner_to_outer_aztec.mtx");
52  //Get local directions
53  Laplace->compute_local_directions(phi, psi);
54  //$$End
55 
56  StandardMap = new Epetra_Map(-1,3*Mesh->n_local_nodes_without_ghosts,&Mesh->local_dof_without_ghosts[0],0,*Comm);
57  OverlapMap = new Epetra_Map(-1,3*Mesh->n_local_nodes,&Mesh->local_dof[0],0,*Comm);
58  ImportToOverlapMap = new Epetra_Import(*OverlapMap,*StandardMap);
60 
61  a.Resize(3);
62  b.Resize(3);
64 
65  }
66 
68  }
69 
70  void get_matrix_and_rhs(Epetra_Vector & x, Epetra_FECrsMatrix & K, Epetra_FEVector & F){
72  }
73 
75  n_bc_dof = 0;
76  for (unsigned int i=0; i<Mesh->n_local_nodes_without_ghosts; ++i){
77  if (Mesh->nodes_to_boundaries(i,fixed)==1){
78  n_bc_dof+=3;
79  }
80  if (Mesh->nodes_to_boundaries(i,moved)==1){
81  n_bc_dof+=1;
82  }
83  }
84 
85  int indbc = 0;
86  dof_on_boundary = new int [n_bc_dof];
87  for (unsigned int inode=0; inode<Mesh->n_local_nodes_without_ghosts; ++inode){
88  if (Mesh->nodes_to_boundaries(inode,fixed)==1){
89  dof_on_boundary[indbc+0] = 3*inode+0;
90  dof_on_boundary[indbc+1] = 3*inode+1;
91  dof_on_boundary[indbc+2] = 3*inode+2;
92  indbc+=3;
93  }
94  if (Mesh->nodes_to_boundaries(inode,moved)==1){
95  dof_on_boundary[indbc+0] = 3*inode+0;
96  indbc+=1;
97  }
98  }
99  }
100 
101  void apply_dirichlet_conditions(Epetra_FECrsMatrix & K, Epetra_FEVector & F, double & displacement){
102  int node;
103  Epetra_MultiVector v(*StandardMap,true);
104  v.PutScalar(0.0);
105  if (n_bc_dof>0){
106  double xx;
107  for (unsigned int inode=0; inode<Mesh->n_local_nodes_without_ghosts; ++inode){
108  node = Mesh->local_nodes[inode];
109  if (Mesh->nodes_to_boundaries(inode,fixed)==1){
110  v[0][StandardMap->LID(3*node+0)] = 0.0;
111  v[0][StandardMap->LID(3*node+1)] = 0.0;
112  v[0][StandardMap->LID(3*node+2)] = 0.0;
113  }
114  if (Mesh->nodes_to_boundaries(inode,moved)==1){
115  xx = Mesh->nodes_coord[3*node];
116  v[0][StandardMap->LID(3*node+0)] = displacement*(xxmax-xx); //warning, displacement shouldn't be used this way but I fucked up: displacement should be a pointer or an Epetra_SDV; In this case displacement is used as the "step increment".
117  }
118  }
119  }
120 
121  Epetra_MultiVector rhsDir(*StandardMap,true);
122  K.Apply(v,rhsDir);
123  F.Update(-1.0,rhsDir,1.0);
124 
125  for (int inode=0; inode<Mesh->n_local_nodes_without_ghosts; ++inode){
126  node = Mesh->local_nodes[inode];
127  if (Mesh->nodes_to_boundaries(inode,fixed)==1){
128  F[0][StandardMap->LID(3*node+0)] = 0.0;
129  F[0][StandardMap->LID(3*node+1)] = 0.0;
130  F[0][StandardMap->LID(3*node+2)] = 0.0;
131  }
132  if (Mesh->nodes_to_boundaries(inode,moved)==1){
133  F[0][StandardMap->LID(3*node+0)] = v[0][StandardMap->LID(3*node)];
134  }
135  }
136 
137  ML_Epetra::Apply_OAZToMatrix(dof_on_boundary,n_bc_dof,K);
138  }
139 
140  void get_material_parameters(unsigned int & e_lid, unsigned int & gp){
141 
142  int n_gauss_points = Mesh->n_gauss_cells;
143  int e_gid = Mesh->local_cells[e_lid];
144 
145  mu1 = 4.1543/1000.0;
146  mu2 = 2.5084/1000.0;
147  mu3 = 9.7227/1000.0;
148  mu4 = 19.285/1000.0;
149  beta3 = 3.6537;
150  beta4 = 500.02;
151  theta = 0.80764;
152 
153  for (int i=0; i<3; ++i){
154  a(i) = cos(theta)*Laplace->laplace_direction_one(n_gauss_points*e_lid+gp,i) + sin(theta)*Laplace->laplace_direction_two_cross_one(n_gauss_points*e_lid+gp,i);
155  b(i) = cos(theta)*Laplace->laplace_direction_one(n_gauss_points*e_lid+gp,i) - sin(theta)*Laplace->laplace_direction_two_cross_one(n_gauss_points*e_lid+gp,i);
156  }
157 
158  }
159 
160  void get_constitutive_tensors_static_condensation(Epetra_SerialDenseMatrix & deformation_gradient, double & det, Epetra_SerialDenseVector & L, Epetra_SerialDenseVector & piola_isc, Epetra_SerialDenseVector & piola_vol, Epetra_SerialDenseMatrix & tangent_piola_isc, Epetra_SerialDenseMatrix & tangent_piola_vol){
161 
162  det = deformation_gradient(0,0)*deformation_gradient(1,1)*deformation_gradient(2,2)-deformation_gradient(0,0)*deformation_gradient(1,2)*deformation_gradient(2,1)-deformation_gradient(0,1)*deformation_gradient(1,0)*deformation_gradient(2,2)+deformation_gradient(0,1)*deformation_gradient(1,2)*deformation_gradient(2,0)+deformation_gradient(0,2)*deformation_gradient(1,0)*deformation_gradient(2,1)-deformation_gradient(0,2)*deformation_gradient(1,1)*deformation_gradient(2,0);
163 
164  double alpha = std::pow(det,-2.0/3.0);
165 
166  Epetra_SerialDenseMatrix rightCauchy(3,3);
167  Epetra_SerialDenseVector M1(6), M2(6);
168  Epetra_SerialDenseVector eye(6);
169  Epetra_SerialDenseVector C(6);
170  Epetra_SerialDenseVector D(6);
171  //Epetra_SerialDenseVector L(6);
172  Epetra_SerialDenseVector piola_nh(6);
173 
174  M1(0) = a(0)*a(0);
175  M1(1) = a(1)*a(1);
176  M1(2) = a(2)*a(2);
177  M1(3) = a(1)*a(2);
178  M1(4) = a(0)*a(2);
179  M1(5) = a(0)*a(1);
180 
181  M2(0) = b(0)*b(0);
182  M2(1) = b(1)*b(1);
183  M2(2) = b(2)*b(2);
184  M2(3) = b(1)*b(2);
185  M2(4) = b(0)*b(2);
186  M2(5) = b(0)*b(1);
187 
188  rightCauchy.Multiply('T','N',1.0,deformation_gradient,deformation_gradient,0.0);
189 
190  eye(0) = 1.0; eye(1) = 1.0; eye(2) = 1.0; eye(3) = 0.0; eye(4) = 0.0; eye(5) = 0.0;
191 
192  C(0) = rightCauchy(0,0); C(1) = rightCauchy(1,1); C(2) = rightCauchy(2,2);
193  C(3) = rightCauchy(1,2); C(4) = rightCauchy(0,2); C(5) = rightCauchy(0,1);
194 
195  L(0) = (1.0/(det*det))*(rightCauchy(1,1)*rightCauchy(2,2)-rightCauchy(1,2)*rightCauchy(2,1));
196  L(1) = (1.0/(det*det))*(rightCauchy(0,0)*rightCauchy(2,2)-rightCauchy(0,2)*rightCauchy(2,0));
197  L(2) = (1.0/(det*det))*(rightCauchy(0,0)*rightCauchy(1,1)-rightCauchy(0,1)*rightCauchy(1,0));
198  L(3) = (1.0/(det*det))*(rightCauchy(0,2)*rightCauchy(1,0)-rightCauchy(0,0)*rightCauchy(1,2));
199  L(4) = (1.0/(det*det))*(rightCauchy(0,1)*rightCauchy(1,2)-rightCauchy(0,2)*rightCauchy(1,1));
200  L(5) = (1.0/(det*det))*(rightCauchy(0,2)*rightCauchy(2,1)-rightCauchy(0,1)*rightCauchy(2,2));
201 
202  double I1 = C(0) + C(1) + C(2);
203  double II1 = C(0)*C(0) + C(1)*C(1) + C(2)*C(2) + 2.0*C(3)*C(3) + 2.0*C(4)*C(4) + 2.0*C(5)*C(5);
204  double I2 = (1.0/2.0)*(I1*I1-II1);
205  double I4_1 = C(0)*M1(0) + C(1)*M1(1) + C(2)*M1(2) + 2.0*C(5)*M1(5) + 2.0*C(4)*M1(4) + 2.0*C(3)*M1(3);
206  double I4_2 = C(0)*M2(0) + C(1)*M2(1) + C(2)*M2(2) + 2.0*C(5)*M2(5) + 2.0*C(4)*M2(4) + 2.0*C(3)*M2(3);
207  double pI2 = std::sqrt(I2);
208 
209  double S4_1 = 0.0;
210  double T4_1 = 0.0;
211  double U4_1 = 0.0;
212  if (I4_1>1.0){
213  U4_1 = 1.0;
214  T4_1 = I4_1-1.0;
215  S4_1 = T4_1*T4_1;
216  }
217  double S4_2 = 0.0;
218  double T4_2 = 0.0;
219  double U4_2 = 0.0;
220  if (I4_2>1.0){
221  U4_2 = 1.0;
222  T4_2 = I4_2-1.0;
223  S4_2 = T4_2*T4_2;
224  }
225 
226  for (unsigned int i=0; i<6; ++i){
227  D(i) = I1*eye(i) - C(i);
228  piola_nh(i) = 2.0*alpha*mu1*(eye(i)-(1.0/3.0)*I1*L(i));
229  piola_isc(i) = piola_nh(i) + (mu2/(det*det))*( 3.0*pI2*D(i) - 2.0*pI2*I2*L(i) ) + 4.0*mu4*T4_1*exp(beta4*S4_1)*M1(i) + 4.0*mu4*T4_2*exp(beta4*S4_2)*M2(i);
230  piola_vol(i) = det*L(i);
231  }
232 
233  double scalarAB;
234 
235  scalarAB = det;
236  tensor_product(det,L,L,tangent_piola_vol,0.0);
237  scalarAB = -2.0*det;
238  sym_tensor_product(scalarAB,L,L,tangent_piola_vol,1.0);
239 
240  scalarAB = -2.0/3.0;
241  tensor_product(scalarAB,piola_nh,L,tangent_piola_isc,0.0);
242  tensor_product(scalarAB,L,piola_nh,tangent_piola_isc,1.0);
243 
244  scalarAB = -6.0*mu2*pI2/(det*det);
245  tensor_product(scalarAB,D,eye,tangent_piola_isc,1.0);
246  tensor_product(scalarAB,eye,D,tangent_piola_isc,1.0);
247 
248  scalarAB = (-4.0/9.0)*mu1*alpha*I1 + 4.0*mu2*pI2*I2/(det*det);
249  tensor_product(scalarAB,L,L,tangent_piola_isc,1.0);
250 
251  scalarAB = (4.0/3.0)*mu1*alpha*I1 + 4.0*mu2*pI2*I2/(det*det);
252  sym_tensor_product(scalarAB,L,L,tangent_piola_isc,1.0);
253 
254  scalarAB = 3.0*mu2/(det*det*pI2);
255  tensor_product(scalarAB,D,D,tangent_piola_isc,1.0);
256 
257  scalarAB = 6.0*mu2*pI2/(det*det);
258  tensor_product(scalarAB,eye,eye,tangent_piola_isc,1.0);
259 
260  scalarAB = -scalarAB;
261  sym_tensor_product(scalarAB,eye,eye,tangent_piola_isc,1.0);
262 
263  scalarAB = (8.0*mu4*U4_1 + 16.0*mu4*beta4*S4_1)*exp(beta4*S4_1);
264  tensor_product(scalarAB,M1,M1,tangent_piola_isc,1.0);
265 
266  scalarAB = (8.0*mu4*U4_2 + 16.0*mu4*beta4*S4_2)*exp(beta4*S4_2);
267  tensor_product(scalarAB,M2,M2,tangent_piola_isc,1.0);
268 
269  }
270 
271  void get_internal_pressure(double & theta, double & pressure, double & dpressure){
272  double ptheta = std::pow(theta,beta3);
273  pressure = mu3*beta3*( (ptheta/theta) - (1.0/(ptheta*theta)) );
274  dpressure = mu3*beta3*( (beta3-1.0)*(ptheta/(theta*theta)) + (beta3+1.0)/(ptheta*theta*theta) );
275  }
276 
277  void get_material_parameters_for_recover(unsigned int & e_lid){
278  }
279 
280  void get_stress_for_recover(Epetra_SerialDenseMatrix & deformation_gradient, double & det, Epetra_SerialDenseMatrix & piola_stress){
281  }
282 
283 };
284 
285 #endif
dirichletInletOutlet_PolyconvexHGO(Epetra_Comm &comm, Teuchos::ParameterList &Parameters)
Epetra_Comm * Comm
void get_material_parameters(unsigned int &e_lid, unsigned int &gp)
std::vector< int > local_nodes
Definition: meshpp.hpp:80
void tensor_product(double scalarAB, Epetra_SerialDenseVector &A, Epetra_SerialDenseVector &B, Epetra_SerialDenseMatrix &AoB, double scalarThis)
void apply_dirichlet_conditions(Epetra_FECrsMatrix &K, Epetra_FEVector &F, double &displacement)
std::vector< double > nodes_coord
Definition: meshpp.hpp:77
unsigned int n_bc_dof
int print_solution(Epetra_Vector &lhs, std::string fileName)
Definition: laplacepp.cpp:399
void get_internal_pressure(double &theta, double &pressure, double &dpressure)
Epetra_FECrsGraph * FEGraph
Epetra_IntSerialDenseMatrix nodes_to_boundaries
Definition: meshpp.hpp:75
std::vector< int > local_cells
Definition: meshpp.hpp:81
clc clear all close all mesh
Definition: run.m:5
int n_local_nodes_without_ghosts
Definition: meshpp.hpp:92
L
Definition: costFunction.m:66
Epetra_SerialDenseMatrix laplace_direction_one
Definition: laplacepp.hpp:28
Epetra_Import * ImportToOverlapMap
Epetra_Map * StandardMap
unsigned int n_gauss_cells
Definition: meshpp.hpp:98
void sym_tensor_product(double scalarAB, Epetra_SerialDenseVector &A, Epetra_SerialDenseVector &B, Epetra_SerialDenseMatrix &AoB, double scalarThis)
Epetra_SerialDenseMatrix laplace_direction_two_cross_one
Definition: laplacepp.hpp:30
void compute_local_directions(Epetra_Vector &laplace_one, Epetra_Vector &laplace_two)
Definition: laplacepp.cpp:229
void get_constitutive_tensors_static_condensation(Epetra_SerialDenseMatrix &deformation_gradient, double &det, Epetra_SerialDenseVector &L, Epetra_SerialDenseVector &piola_isc, Epetra_SerialDenseVector &piola_vol, Epetra_SerialDenseMatrix &tangent_piola_isc, Epetra_SerialDenseMatrix &tangent_piola_vol)
for i
Definition: costFunction.m:38
Epetra_Map * OverlapMap
void assemblePureDirichlet_homogeneousForcing(Epetra_Vector &x, Epetra_FECrsMatrix &K, Epetra_FEVector &F)
void get_matrix_and_rhs(Epetra_Vector &x, Epetra_FECrsMatrix &K, Epetra_FEVector &F)
void get_stress_for_recover(Epetra_SerialDenseMatrix &deformation_gradient, double &det, Epetra_SerialDenseMatrix &piola_stress)
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