muMECH  1.0
melement.cpp
Go to the documentation of this file.
1 //********************************************************************************************************
2 // code: ### ### ##### #### ## ##
3 // ## ## ######## ## ## ## ## ##
4 // ## ## ## ## ## ### ## ######
5 // ## ## ## ## ## ## ## ## ##
6 // ##### ## ## ##### #### ## ##
7 // ##
8 //
9 // name: element.cpp
10 // author(s): Ladislav Svoboda
11 // language: C, C++
12 // license: This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU Lesser General Public License as published by
14 // the Free Software Foundation; either version 2 of the License, or
15 // (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 //********************************************************************************************************
26 
27 #include "melement.h"
28 
29 #include "problem.h"
30 #include "mesh.h"
31 #include "mnode.h"
32 #include "matrixOperations.h"
33 
34 #include "arrays.h"
35 
36 
37 namespace mumech {
38 
40 mElement :: mElement (long i, const Mesh *m)
41 {
42  id = i;
43  M = m;
44 
45  nnodes = 0;
46  nodes = NULL;
47  type = 0;
48  region = -3;
49  volume = -1;
50 
51  displc = strain = stress = NULL;
52  energy = NULL;
53  eqstress = NULL;
54 
55  error = NULL;
56 }
58 mElement :: mElement (long i, const Mesh *m, const mElement *src)
59 {
60  id = i;
61  M = m;
62 
63  type = 0;
64  this->set_type(src->type);
65  CopyVector(src->nodes, this->nodes, this->nnodes);
66 
67  region = -3;
68  volume = -1;
69 
70  displc = strain = stress = NULL;
71  if (src->displc != NULL || src->strain != NULL || src->stress != NULL) _errorr("results data not supported in copy constructor");
72  energy = NULL;
73  if (src->energy != NULL) _errorr("results data not supported in copy constructor");
74  eqstress = NULL;
75  if (src->eqstress != NULL) _errorr("results data not supported in copy constructor");
76 
77  error = NULL;
78  if (src->error != NULL) _errorr("results data not supported in copy constructor");
79 
80 }
81 
82 
85 {
86  delete [] nodes;
87 
88  int nP = M->npa;
89  int nLC = M->nLC;
90 
91  DeleteArray3D (displc, nP, nLC);
92  DeleteArray3D (strain, nP, nLC);
93  DeleteArray3D (stress, nP, nLC);
94 
95  DeleteArray2D (energy, nP);
96  DeleteArray2D (eqstress, nP);
97  DeleteArray2D (error, nP);
98 }
99 
101 void mElement :: set_type (long t)
102 {
103  if (type != 0) _errorr("");
104  type = t;
105 
106  if (type == 5) nnodes = 3;
107  else if (type == 9) nnodes = 4;
108  else if (type == 10) nnodes = 4;
109  else if (type == 12) nnodes = 8;
110  else _errorr("");
111 
112  nodes = new long[nnodes];
113 }
114 
117 {
118  if (nodes==NULL) errol;
119 
120  if (M->coll) { //2D
121  if (nnodes == 3) {
122  for (int i=0; i<3; i++)
123  centroids[i] = ( M->Nodes[nodes[0]]->coords[i] +
124  M->Nodes[nodes[1]]->coords[i] +
125  M->Nodes[nodes[2]]->coords[i] ) / 3.0;
126  }
127  else if (nnodes == 4) {
128  for (int i=0; i<3; i++)
129  centroids[i] = ( M->Nodes[nodes[0]]->coords[i] +
130  M->Nodes[nodes[1]]->coords[i] +
131  M->Nodes[nodes[2]]->coords[i] +
132  M->Nodes[nodes[3]]->coords[i] ) / 4.0;
133  }
134  else errol;
135  }
136  else { // 3D
137  if (nnodes == 8) {
138  for (int i=0; i<3; i++)
139  centroids[i] = ( M->Nodes[nodes[0]]->coords[i] + M->Nodes[nodes[4]]->coords[i] +
140  M->Nodes[nodes[1]]->coords[i] + M->Nodes[nodes[5]]->coords[i] +
141  M->Nodes[nodes[2]]->coords[i] + M->Nodes[nodes[6]]->coords[i] +
142  M->Nodes[nodes[3]]->coords[i] + M->Nodes[nodes[7]]->coords[i] ) / 8.0;
143  }
144  else errol;
145  }
146 }
147 
148 
151 {
152  int nLC = M->nLC;
153 
154  if (M->el_dspl_rf) { if (!displc) displc = Allocate1Ddpp (M->npa); if (M->el_dspl_rf[pid]) { if (!displc[pid]) displc[pid] = Allocate1Ddp(nLC); for (int i=0; i<nLC; i++) { if (M->el_dspl_rf[pid][i] && displc[pid][i] == NULL) displc[pid][i] = new double[M->P[pid]->ndisplc_one()]; } } }
155  if (M->el_strn_rf) { if (!strain) strain = Allocate1Ddpp (M->npa); if (M->el_strn_rf[pid]) { if (!strain[pid]) strain[pid] = Allocate1Ddp(nLC); for (int i=0; i<nLC; i++) { if (M->el_strn_rf[pid][i] && strain[pid][i] == NULL) strain[pid][i] = new double[M->P[pid]->nstrain_one()]; } } }
156  if (M->el_strs_rf) { if (!stress) stress = Allocate1Ddpp (M->npa); if (M->el_strs_rf[pid]) { if (!stress[pid]) stress[pid] = Allocate1Ddp(nLC); for (int i=0; i<nLC; i++) { if (M->el_strs_rf[pid][i] && stress[pid][i] == NULL) stress[pid][i] = new double[M->P[pid]->nstrain_one()]; } } }
157 }
158 
161 {
162  if (nodes==NULL) errol;
163 
165 
166  // compute volume
167  if (volume <= 0.0) {
168  if (M->coll) { //2D
169  if (nnodes!=3) errol;
170  VectoR normal;
171 
172  normal.beVectProduct (&M->Nodes[nodes[0]]->coords,
173  &M->Nodes[nodes[1]]->coords,
174  &M->Nodes[nodes[2]]->coords);
175 
176  volume = 0.5 * normal.give_length();
177  }
178  else { // 3D
179  if (nnodes!=3) errol;
180  errol;
181  }
182  }
183 
184  return volume;
185 }
186 
188 double mElement :: give_energy (int pid, int lc)
189 {
190  if (energy == NULL) energy = Allocate1Ddp(M->npa);
191  if (energy[pid] == NULL) energy[pid] = Allocate1Ddz(M->nLC);
192 
193  // compute energy
194  if (energy[pid][lc] == 0.0) {
195 
196  bool twodim = M->give_twodim();
197 
198  // mesh and problem dimension is same
199  if ((M->coll == 0 && M->P[pid]->give_dimension() == 3) ||
200  (M->coll == 3 && M->P[pid]->give_dimension() == 2)) {
201 
202  if (twodim) energy[pid][lc] = MatrixOperations::giveTTproduct_1is2x2to3and2x2to3_SS(stress[pid][lc], strain[pid][lc]);
203  else errol;
204  }
205  // problem is 3d, mesh is 2d => planestrain is supposed
206  else if ((M->coll == 3 && M->P[0]->give_dimension() == 3)) {
207  errol;
208  // double strain2d[3], stress2d[3];
209  // copy3Dto2Dtensors_FEEPreduced (strain[lc], strain2d);
210  // copy3Dto2Dtensors_FEEPreduced (stress[lc], stress2d);
211  //
212  // energy[lc] = give_VectorVectorProduct (strain2d, stress2d, 3);
213  }
214  else errol;
215 
216  //
217  energy[pid][lc] *= this->give_volume();
218  }
219 
220  return energy[pid][lc];
221 }
222 
223 
225 void mElement :: save_error (double val, int pid, int lc)
226 {
227  if (error == NULL) error = Allocate1Ddp (M->npa);
228  if (error[pid] == NULL) error[pid] = Allocate1Ddz (M->nLC);
229 
230  error[pid][lc] = val;
231 }
232 
234 void mElement :: giveReducedStiffMatrix (double *C, int pid) const
235 {
236  const Problem *prob = dynamic_cast <const Problem*>(M->P[pid]);
237  if (prob == NULL) errol;
238 
239  if (this->region < -1) errol;
240  else if (this->region == -1) prob->matrix_giveReducedStiffMatrix(C);
242 }
243 
244 
246 void mElement :: give_strain (double *strain, int pid, int lc) const
247 {
248  if (this->strain == NULL || this->strain[pid] == NULL || this->strain[pid][lc] == NULL) errol;
249  if (strain == NULL) errol;
250 
251  // mesh and problem dimension is same
252  if ( M->equal_dimensions(pid) ) {
253  CopyVector (this->strain[pid][lc], strain, M->P[pid]->nstrain_one());
254  }
255  // mesh is 2d and problem is 3d => planestrain is supposed
256  else if ((M->coll == 3 && M->P[pid]->give_dimension() == 3)) {
257  MatrixOperations::copy3Dto2Dtensors_FEEPreduced (this->strain[pid][lc], strain);
258  }
259  else errol;
260 }
262 void mElement :: give_stress (double *stress, int pid, int lc) const
263 {
264  if (this->stress == NULL || this->stress[pid] == NULL || this->stress[pid][lc] == NULL) errol;
265  if (stress == NULL) errol;
266 
267  // mesh and problem dimension is same
268  if ( M->equal_dimensions(pid) ) {
269  CopyVector(this->stress[pid][lc], stress, M->P[pid]->nstrain_one());
270  }
271  // mesh is 2d and problem is 3d => planestrain is supposed
272  else if ((M->coll == 3 && M->P[pid]->give_dimension() == 3)) {
273  MatrixOperations::copy3Dto2Dtensors_FEEPreduced (this->stress[pid][lc], stress);
274  }
275  else errol;
276 }
277 
278 
279 // ///
280 // double mElement :: give_equiv_stress (int lc)
281 // {
282 // if (eqstress == NULL) {
283 // int nLC = M->P[0]->give_nLC();
284 // eqstress = new double[nLC];
285 // memset (eqstress, 0, nLC*sizeof(double));
286 // }
287 //
288 // // compute eqstress
289 // if (eqstress[lc] == 0.0) {
290 // // mesh and problem dimension is same
291 // if ((M->coll == 0 && M->P[0]->give_dimension() == 3) ||
292 // (M->coll == 3 && M->P[0]->give_dimension() == 2)) {
293 // errol;
294 // //eqstress[lc] = give_VectorVectorProduct (strain[lc], stress[lc], M->P->nstrain());
295 // }
296 // // problem is 3d, mesh is 2d => planestrain is supposed
297 // else if ((M->coll == 3 && M->P[0]->give_dimension() == 3)) {
298 // double stress2d[3];
299 // copy3Dto2Dtensors_FEEPreduced (stress[lc], stress2d);
300 // errol;
301 // //eqstress[lc] = sqrt( 0.5 * (stress2d));
302 // }
303 // else errol;
304 //
305 // //
306 // eqstress[lc] *= this->give_volume();
307 // }
308 //
309 // return eqstress[lc];
310 // }
311 
312 
313 } // end of namespace mumech
314 
315 /*end of file*/
double ** Allocate1Ddp(long d1)
Function allocates (&#39;new&#39; command) a 1d array of double* pointers set to NULL.
int give_dimension(void) const
Definition: problem.h:86
mElement(long i, const Mesh *m)
Constructor.
Definition: melement.cpp:40
double giveTTproduct_1is2x2to3and2x2to3_SS(const double *T1, const double *T2)
Function gives scalar left-right product of tensor and tensor.
double *** Allocate1Ddpp(long d1)
Function allocates (&#39;new&#39; command) a 1d array of double** pointers set to NULL.
double ** energy
energy = INTEGRAL Strain * Stress *dVolume
Definition: melement.h:63
void matrix_giveReducedStiffMatrix(double *m) const
Definition: problem.h:329
Problem description.
Definition: problem.h:154
double *** strain
computed fields - strain in TVRN_THEORETICAL_FEEP notation
Definition: melement.h:60
long * nodes
Element nodes.
Definition: melement.h:49
int nstrain_one(void) const
Definition: problem.h:89
Namespace MatrixOperations.
double give_length(void) const
Definition: arrays.h:193
Class Mesh.
double ** eqstress
equivalent stress = SQRT(3*J2)
Definition: melement.h:64
void CopyVector(const double *src, double *dest, long n)
Function copy given number of components from vector, &#39;a&#39; to vector &#39;b&#39;.
Inclusion * give_inclusion(long i) const
debug, for one function in tools
Definition: problem.h:402
Class mElement, mesh element.
double *** displc
computed fields - displacement
Definition: melement.h:59
void give_stress(double *stress, int pid, int lc) const
Definition: melement.cpp:262
int ndisplc_one(void) const
Definition: problem.h:88
mNode ** Nodes
1d array of pointers to Node.
Definition: mesh.h:84
#define errol
Definition: gelib.h:151
void set_type(long t)
Definition: melement.cpp:101
void give_strain(double *strain, int pid, int lc) const
Definition: melement.cpp:246
const Mesh * M
mesh
Definition: melement.h:46
VectoR * beVectProduct(const VectoR *v1, const VectoR *v2)
vector product v1 x v2 (cross product)
Definition: arrays.h:165
long region
-2 - not set, -1 - matrix, <0;nIncl) id of inclusion
Definition: melement.h:55
double * Allocate1Ddz(long d1)
Function allocates (&#39;new&#39; command) a 1d array of double set to zero.
double *** stress
computed fields - stress in TVRN_THEORETICAL_FEEP notation
Definition: melement.h:61
int nLC
number of load cases
Definition: mesh.h:92
PoinT coords
coordinates
Definition: mnode.h:49
void DeleteArray3D(double ***array, long d1, long d2)
Function deletes a 3D &#39;double&#39; array of dimension d1 x d2 x ??, allocated by new. ...
bool ** el_strs_rf
Definition: mesh.h:100
Structs Elem3D, PoinT and VectoR; classes Array, Array1d, Xscal, Dscal, Xvctr, Lvctr, Dvctr, Xmtrx, Lmtrx and Dmtrx.
double give_energy(int pid, int lc)
Definition: melement.cpp:188
int npa
number of allocated pointers
Definition: mesh.h:57
void compute_centroids(void)
Definition: melement.cpp:116
bool equal_dimensions(int pid) const
Returns true when mesh and problem dimensions are same.
Definition: mesh.cpp:180
bool give_twodim(void) const
Definition: mesh.h:123
bool ** el_dspl_rf
pid x nlc
Definition: mesh.h:98
int coll
Definition: mesh.h:68
double give_volume(void)
Definition: melement.cpp:160
#define _errorr(_1)
Definition: gelib.h:160
Class mNode, mesh node.
void giveReducedStiffMatrix(double *C, int pid) const
Definition: melement.cpp:234
double ** error
docasne, energeticka chyba reseni v porovnani s FEM resenim = (eps_mM - eps_FEM)
Definition: melement.h:70
double volume
Volume/Area.
Definition: melement.h:52
long type
Element type.
Definition: melement.h:51
void DeleteArray2D(bool **array, long d1)
Function deletes a 2D &#39;bool&#39; array of dimension d1 x ??, allocated by new.
void copy3Dto2Dtensors_FEEPreduced(const double *a, double *b)
Function copy the symmetric double 3D tensor &#39;a&#39; to 2D tensor &#39;b&#39;.
const Problems ** P
set of pointers to solved problems
Definition: mesh.h:59
void save_error(double val, int pid, int lc)
Definition: melement.cpp:225
Class Mesh contains and handles all mesh data.
Definition: mesh.h:52
long nnodes
Number of nodes at elements.
Definition: melement.h:48
double give_regular_element_volume(void) const
Definition: mesh.cpp:1190
virtual ~mElement()
Destructor.
Definition: melement.cpp:84
Class Problem.
Class mElement contains and handles all mesh element data.
Definition: melement.h:42
void give_StiffnessMatrixReduced(double *answer) const
Copy stiffness tensor into reduced vector answer.
Definition: inclusion.cpp:810
void allocate_fields(int pid)
Definition: melement.cpp:150
bool ** el_strn_rf
Definition: mesh.h:99
double centroids[3]
Centroid coordinates.
Definition: melement.h:57