v0.15.0
Loading...
Searching...
No Matches
BCs_RVELagrange_Trac.hpp
Go to the documentation of this file.
1/* Copyright (C) 2014, Zahur Ullah (Zahur.Ullah AT glasgow.ac.uk)
2 * --------------------------------------------------------------
3 */
4
5/* This file is part of MoFEM.
6 * MoFEM is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * MoFEM is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with MoFEM. If not, see <http://www.gnu.org/licenses/>. */
18
19#ifndef __BCS_RVELAGRANGE_TRAC_HPP
20#define __BCS_RVELAGRANGE_TRAC_HPP
21
23
25
26 struct CommonData {
27 MatrixDouble D_mat;
28 };
30
32
33 PetscErrorCode shapeMat(
34 int rank,unsigned int gg,DataForcesAndSurcesCore::EntData &col_data,MatrixDouble &n
35 ) {
36 PetscFunctionBegin;
37
38 int shape_size = col_data.getN().size2();
39
40 n.resize(rank,shape_size*rank);
41 n.clear();
42
43 int kk = 0;
44 for(int ii=0; ii<shape_size; ii++){
45 double val = col_data.getN()(gg,ii);
46 for(int jj=0; jj<rank; jj++){
47 n(jj,kk) = val;
48 kk++;
49 }
50 }
51
52 PetscFunctionReturn(0);
53 }
54
55
56 MatrixDouble H_mat_1Node;
57
58 PetscErrorCode hMat(
59 VectorDouble face_normal,
60 int rank,
61 MatrixDouble &n_mat,
62 MatrixDouble &h_mat
63 ) {
64 PetscFunctionBegin;
65
66 switch(rank) {
67 //Mechanical problem
68 case 3: {
69 H_mat_1Node.resize(6,3);
70 H_mat_1Node.clear(); //for one node
71 if(face_normal[0]>0) { //+X face of the RVE
72 H_mat_1Node(0,0) = 1.0;
73 H_mat_1Node(3,1) = 1.0;
74 H_mat_1Node(5,2) = 1.0;
75 } else if(face_normal[0]<0) { //-X face of the RVE
76 H_mat_1Node(0,0) = -1.0;
77 H_mat_1Node(3,1) = -1.0;
78 H_mat_1Node(5,2) = -1.0;
79 } else if(face_normal[1]>0) { //+Y face of the RVE
80 H_mat_1Node(1,1) = 1.0;
81 H_mat_1Node(3,0) = 1.0;
82 H_mat_1Node(4,2) = 1.0;
83 } else if(face_normal[1]<0) { //-Y face of the RVE
84 H_mat_1Node(1,1) = -1.0;
85 H_mat_1Node(3,0) = -1.0;
86 H_mat_1Node(4,2) = -1.0;
87 } else if(face_normal[2]>0) { //+Z face of the RVE
88 H_mat_1Node(2,2) = 1.0;
89 H_mat_1Node(4,1) = 1.0;
90 H_mat_1Node(5,0) = 1.0;
91 } else if(face_normal[2]<0) { //-Z face of the RVE
92 H_mat_1Node(2,2) = -1.0;
93 H_mat_1Node(4,1) = -1.0;
94 H_mat_1Node(5,0) = -1.0;
95 } else {
96 SETERRQ(PETSC_COMM_SELF,MOFEM_IMPOSIBLE_CASE,"Can not be ?!");
97 }
98
99 int num_col = n_mat.size2();
100 h_mat.resize(6,num_col);
101
102 int cc1 = 0;
103 for(int bb = 0; bb<num_col/3; bb++) {
104 //blocks of 6x3
105 for(int rr = 0; rr<6; rr++) {
106 for(int cc = 0; cc<3; cc++) {
107 h_mat(rr,(cc+cc1)) = H_mat_1Node(rr,cc);
108 }
109 }
110 cc1+=3;
111 }
112
113 }
114 break;
115 case 1: //Moisture transport or thermal problem
116 {
117 H_mat_1Node.resize(3,1);
118 H_mat_1Node.clear();
119 if(face_normal[0]>0) { //+X face of the RVE
120 H_mat_1Node(0,0) = 1.0;
121 }
122 if(face_normal[0]<0) { //-X face of the RVE
123 H_mat_1Node(0,0) = -1.0;
124 }
125 if(face_normal[1]>0) { //+Y face of the RVE
126 H_mat_1Node(1,0) = 1.0;
127 }
128 if(face_normal[1]<0) { //-Y face of the RVE
129 H_mat_1Node(1,0) = -1.0;
130 }
131 if(face_normal[2]>0) { //+Z face of the RVE
132 H_mat_1Node(2,0) = 1.0;
133 }
134 if(face_normal[2]<0) { //-Z face of the RVE
135 H_mat_1Node(2,0) = -1.0;
136 }
137
138 int num_col = n_mat.size2();
139 h_mat.resize(3,num_col);
140
141 int cc1 = 0;
142 for(int bb = 0; bb<num_col; bb++) {
143 //blocks of 3x1
144 for(int rr = 0; rr<3; rr++) {
145 for(int cc = 0; cc<1; cc++) {
146 h_mat(rr,(cc+cc1))=H_mat_1Node(rr,cc);
147 }
148 }
149 cc1+=1;
150 }
151
152 }
153 break;
154 default:
155 SETERRQ(PETSC_COMM_SELF,MOFEM_NOT_IMPLEMENTED,"not implemented");
156 }
157 PetscFunctionReturn(0);
158 }
159 };
160
162
163 /// \biref operator to calculate the LHS for the RVE bounary conditions
164 struct OpRVEBCsLhs:public FaceElementForcesAndSourcesCore::UserDataOperator {
165
169 Mat Aij;
170
171 OpRVEBCsLhs(const string field_name, const string lagrang_field_name,Mat aij,
172 RVEBC_Data &data, CommonFunctions &common_functions, bool ho_geometry = false
173 ):
175 dAta(data),commonFunctions(common_functions),hoGeometry(ho_geometry),Aij(aij) {
176 //This will make sure to loop over all entities
177 // (e.g. for order=2 it will make doWork to loop 16 time)
178 sYmm = false;
179 }
180
181 MatrixDouble K,transK, NTN;
182 ublas::vector<MatrixDouble > N_mat_row;
183 MatrixDouble N_mat_col,H_mat;
184
185 PetscErrorCode doWork(
186 int row_side,int col_side,
187 EntityType row_type,EntityType col_type,
188 DataForcesAndSurcesCore::EntData &row_data,
189 DataForcesAndSurcesCore::EntData &col_data
190 ) {
191 PetscFunctionBegin;
192
193 try {
194 if(row_data.getIndices().size()==0) PetscFunctionReturn(0);
195 if(col_data.getIndices().size()==0) PetscFunctionReturn(0);
196
197 int nb_row = row_data.getIndices().size();
198 int nb_col = col_data.getIndices().size();
199
200
201 const FENumeredDofEntity *dof_ptr;
202 ierr = getNumeredEntFiniteElementPtr()->getColDofsByPetscGlobalDofIdx(col_data.getIndices()[0],&dof_ptr); CHKERRQ(ierr);
203 int rank = dof_ptr->getNbOfCoeffs();
204
205 K.resize(nb_row,nb_col);
206 K.clear();
207
208 N_mat_row.resize(col_data.getN().size1());
209 for(unsigned int gg = 0;gg<col_data.getN().size1();gg++) {
210 double area;
211 if(hoGeometry) {
212 area = norm_2(getNormalsAtGaussPt(gg))*0.5;
213 } else {
214 area = getArea();
215 }
216 double val = getGaussPts()(2,gg)*area;
217
218 if(col_type==MBVERTEX) {
219 ierr = commonFunctions.shapeMat(rank,gg,col_data,N_mat_row[gg]); CHKERRQ(ierr);
220 }
221 ierr = commonFunctions.shapeMat(rank,gg,col_data,N_mat_col); CHKERRQ(ierr);
222 ierr = commonFunctions.hMat(getNormalsAtGaussPt(gg),rank,N_mat_row(gg),H_mat); CHKERRQ(ierr);
223
224 if(gg==0){
225 NTN = prod(trans(N_mat_row(gg)),N_mat_col); //we don't need to define size NTN
226 K = val*prod(H_mat,NTN); //we don't need to defiend size of K
227 } else {
228 noalias(NTN) = prod(trans(N_mat_row(gg)),N_mat_col);
229 K += val*prod(H_mat, NTN);
230 }
231 }
232
233 // Matrix C
234 int nb_rows=row_data.getIndices().size();
235 int nb_cols=col_data.getIndices().size();
236 ierr = MatSetValues(
237 Aij,nb_rows,&row_data.getIndices()[0],nb_cols,&col_data.getIndices()[0],&K(0,0),ADD_VALUES
238 ); CHKERRQ(ierr);
239
240 // Matrix CT
241 transK = trans(K);
242 ierr = MatSetValues(
243 Aij,nb_cols,&col_data.getIndices()[0],nb_rows,&row_data.getIndices()[0],&transK(0,0),ADD_VALUES
244 ); CHKERRQ(ierr);
245
246 } catch (const std::exception& ex) {
247 ostringstream ss;
248 ss << "throw in method: " << ex.what() << endl;
249 SETERRQ(PETSC_COMM_SELF,MOFEM_NOT_IMPLEMENTED,ss.str().c_str());
250 }
251 PetscFunctionReturn(0);
252 }
253
254 };
255
256 /// \biref operator to calculate the RHS of the constrain for the RVE boundary conditions
257 struct OpRVEBCsRhs_Cal:public FaceElementForcesAndSourcesCore::UserDataOperator {
258
263
265 const string field_name, RVEBC_Data &data,CommonData &common_data,CommonFunctions &common_functions,bool ho_geometry = false
266 ):
268 dAta(data),
269 hoGeometry(ho_geometry),
270 commonData(common_data),
272 }
273
274 MatrixDouble X_mat, N_mat, NTX, H_mat;
275
276 PetscErrorCode doWork(int side,EntityType type,DataForcesAndSurcesCore::EntData &data) {
277 PetscFunctionBegin;
278
279 if(type!=MBVERTEX) PetscFunctionReturn(0);
280 if(data.getIndices().size()==0) PetscFunctionReturn(0);
281
282
283 const FENumeredDofEntity *dof_ptr;
284 ierr = getNumeredEntFiniteElementPtr()->getColDofsByPetscGlobalDofIdx(data.getIndices()[0],&dof_ptr); CHKERRQ(ierr);
285 int rank = dof_ptr->getNbOfCoeffs();
286
287 double x,y,z;
288 for(unsigned int gg = 0;gg<data.getN().size1();gg++) {
289 double area;
290 if(hoGeometry) {
291 area = norm_2(getNormalsAtGaussPt(gg))*0.5;
292 } else {
293 area = getArea();
294 }
295 double val = getGaussPts()(2,gg)*area;
296
297 x = getHoCoordsAtGaussPts()(gg,0);
298 y = getHoCoordsAtGaussPts()(gg,1);
299 z = getHoCoordsAtGaussPts()(gg,2);
300
301 switch(rank) {
302 case 3: //mech problem
303 X_mat.resize(rank,6,false);
304 X_mat.clear();
305 X_mat(0,0) = 2.0*x; X_mat(0,3) = y; X_mat(0,5) = z;
306 X_mat(1,1) = 2.0*y; X_mat(1,3) = x; X_mat(1,4) = z;
307 X_mat(2,2) = 2.0*z; X_mat(2,4) = y; X_mat(2,5) = x;
308 X_mat=0.5*X_mat;
309 break;
310 case 1: //moisture transport or thermal problem
311 X_mat.resize(rank,3,false);
312 X_mat.clear();
313 X_mat(0,0) = x;
314 X_mat(0,1) = y;
315 X_mat(0,2) = z;
316 break;
317 default:
318 SETERRQ(PETSC_COMM_SELF,MOFEM_NOT_IMPLEMENTED,"not implemented");
319 }
320 ierr = commonFunctions.shapeMat(rank, gg, data, N_mat); CHKERRQ(ierr);
321 ierr = commonFunctions.hMat(getNormalsAtGaussPt(gg), rank, N_mat, H_mat); CHKERRQ(ierr);
322
323 if(gg==0) {
324 NTX = val*prod(trans(N_mat),X_mat);
325 commonData.D_mat = prod(H_mat, NTX);
326 } else {
327 noalias(NTX) = val*prod(trans(N_mat),X_mat);
328 commonData.D_mat += prod(H_mat, NTX);
329 }
330 }
331
332 PetscFunctionReturn(0);
333 }
334 };
335
336 /// \biref operator to calculate the RHS of the constrain for the RVE boundary conditions
337 struct OpRVEBCsRhs_Assemble: public FaceElementForcesAndSourcesCore::UserDataOperator {
338
341 vector<Vec> &F;
342
343 OpRVEBCsRhs_Assemble(const string lagrang_field_name,vector<Vec> &f,RVEBC_Data &data,CommonData &common_data):
345 dAta(data),commonData(common_data),F(f) {
346 }
347
348
349 VectorDouble applied_strain,f;
350
351 PetscErrorCode doWork(int side,EntityType type,DataForcesAndSurcesCore::EntData &data) {
352 PetscFunctionBegin;
353
354 if(data.getIndices().size()==0) PetscFunctionReturn(0);
355
356 MatrixDouble &D_mat=commonData.D_mat;
357 applied_strain.resize(D_mat.size2(),false);
358
359 for(int ii = 0;ii<F.size();ii++) {
360 applied_strain.clear();
361 applied_strain(ii) = 1.0;
362 f.resize(D_mat.size1(),false);
363 noalias(f) = prod(D_mat,applied_strain);
364 ierr = VecSetValues(F[ii],data.getIndices().size(),&data.getIndices()[0],&f[0],ADD_VALUES); CHKERRQ(ierr);
365 }
366
367 PetscFunctionReturn(0);
368 }
369 };
370
371 PetscErrorCode setRVEBCsOperators(
372 string field_name,string lagrang_field_name,string mesh_nodals_positions,Mat aij,vector<Vec> &f
373 ) {
374 PetscFunctionBegin;
375 bool ho_geometry = false;
376 if(mField.check_field(mesh_nodals_positions)) {
377 ho_geometry = true;
378 }
379 map<int,RVEBC_Data>::iterator sit = setOfRVEBC.begin();
380 for(;sit!=setOfRVEBC.end();sit++) {
381 //LHS
382 feRVEBCLhs.getOpPtrVector().push_back(
383 new OpRVEBCsLhs(field_name,lagrang_field_name,aij,sit->second,commonFunctions,ho_geometry)
384 );
385 //RHS
386 feRVEBCRhs.getOpPtrVector().push_back(
387 new OpRVEBCsRhs_Cal(field_name,sit->second,commonData,commonFunctions,ho_geometry)
388 );
389 feRVEBCRhs.getOpPtrVector().push_back(
390 new OpRVEBCsRhs_Assemble(lagrang_field_name,f,sit->second,commonData)
391 );
392 }
393 PetscFunctionReturn(0);
394 }
395
396 struct OpRVEHomoStress_Assemble:public FaceElementForcesAndSourcesCore::UserDataOperator {
397
401
403 const string lagrang_field_name,Vec stress_homo,RVEBC_Data &data,CommonData &common_data
404 ):
406 dAta(data),commonData(common_data),stressHomo(stress_homo) {
407 }
408
409
410 VectorDouble stressVector;
411
412 PetscErrorCode doWork(int side,EntityType type,DataForcesAndSurcesCore::EntData &data) {
413 PetscFunctionBegin;
414 if(data.getIndices().size()==0) PetscFunctionReturn(0);
415 if(dAta.tRis.find(getNumeredEntFiniteElementPtr()->getEnt())==dAta.tRis.end()) PetscFunctionReturn(0);
416 stressVector.resize(commonData.D_mat.size2());
417 //Lamda=data.getFieldData() is reaction force (so multiply for -1 to get the force)
418 noalias(stressVector) = prod(trans(commonData.D_mat),-data.getFieldData());
419 const int indices_6[6] = {0, 1, 2, 3, 4, 5};
420 const int indices_3[3] = {0, 1, 2};
421 switch(stressVector.size()) {
422 case 6:
423 ierr = VecSetValues(stressHomo,6,indices_6,&stressVector[0],ADD_VALUES); CHKERRQ(ierr);
424 break;
425 case 3:
426 ierr = VecSetValues(stressHomo,3,indices_3,&stressVector[0],ADD_VALUES); CHKERRQ(ierr);
427 break;
428 default:
429 SETERRQ(PETSC_COMM_SELF,MOFEM_NOT_IMPLEMENTED,"not implemented");
430 }
431 PetscFunctionReturn(0);
432 }
433
434 };
435
437 string field_name,string lagrang_field_name,string mesh_nodals_positions,Vec stress_homo
438 ) {
439 PetscFunctionBegin;
440 bool ho_geometry = false;
441 if(mField.check_field(mesh_nodals_positions)) {
442 ho_geometry = true;
443 }
444 map<int,RVEBC_Data>::iterator sit = setOfRVEBC.begin();
445 for(;sit!=setOfRVEBC.end();sit++) {
446 feRVEBCStress.getOpPtrVector().push_back(
448 );
449 feRVEBCStress.getOpPtrVector().push_back(
450 new OpRVEHomoStress_Assemble(lagrang_field_name,stress_homo,sit->second,commonData)
451 );
452 }
453 PetscFunctionReturn(0);
454 }
455
456};
457
458#endif
static PetscErrorCode ierr
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
virtual bool check_field(const std::string &name) const =0
check if field is in database
const double n
refractive index of diffusive medium
constexpr auto field_name
map< int, RVEBC_Data > setOfRVEBC
maps side set id with appropriate FluxData
PetscErrorCode shapeMat(int rank, unsigned int gg, DataForcesAndSurcesCore::EntData &col_data, MatrixDouble &n)
PetscErrorCode hMat(VectorDouble face_normal, int rank, MatrixDouble &n_mat, MatrixDouble &h_mat)
\biref operator to calculate the LHS for the RVE bounary conditions
PetscErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, DataForcesAndSurcesCore::EntData &row_data, DataForcesAndSurcesCore::EntData &col_data)
ublas::vector< MatrixDouble > N_mat_row
OpRVEBCsLhs(const string field_name, const string lagrang_field_name, Mat aij, RVEBC_Data &data, CommonFunctions &common_functions, bool ho_geometry=false)
\biref operator to calculate the RHS of the constrain for the RVE boundary conditions
PetscErrorCode doWork(int side, EntityType type, DataForcesAndSurcesCore::EntData &data)
OpRVEBCsRhs_Assemble(const string lagrang_field_name, vector< Vec > &f, RVEBC_Data &data, CommonData &common_data)
\biref operator to calculate the RHS of the constrain for the RVE boundary conditions
OpRVEBCsRhs_Cal(const string field_name, RVEBC_Data &data, CommonData &common_data, CommonFunctions &common_functions, bool ho_geometry=false)
PetscErrorCode doWork(int side, EntityType type, DataForcesAndSurcesCore::EntData &data)
PetscErrorCode doWork(int side, EntityType type, DataForcesAndSurcesCore::EntData &data)
OpRVEHomoStress_Assemble(const string lagrang_field_name, Vec stress_homo, RVEBC_Data &data, CommonData &common_data)
BCs_RVELagrange_Trac(MoFEM::Interface &m_field)
PetscErrorCode setRVEBCsOperators(string field_name, string lagrang_field_name, string mesh_nodals_positions, Mat aij, vector< Vec > &f)
PetscErrorCode setRVEBCsHomoStressOperators(string field_name, string lagrang_field_name, string mesh_nodals_positions, Vec stress_homo)
Deprecated interface functions.