1
// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
3
// See the LICENSE.txt file for license information. Please report all
4
// bugs and problems to <gmsh@geuz.org>.
7
#include "elasticityTerm.h"
9
#include "MTetrahedron.h"
10
#include "elasticitySolver.h"
11
#include "linearSystemTAUCS.h"
14
static double vonMises(dofManager<double,double> *a, MElement *e,
15
double u, double v, double w,
16
double E, double nu, int _tag)
21
for (int k = 0; k < e->getNumVertices(); k++){
22
valx[k] = a->getDofValue(e->getVertex(k), 0, _tag);
23
valy[k] = a->getDofValue(e->getVertex(k), 1, _tag);
24
valz[k] = a->getDofValue(e->getVertex(k), 2, _tag);
29
e->interpolateGrad(valx, u, v, w, gradux);
30
e->interpolateGrad(valy, u, v, w, graduy);
31
e->interpolateGrad(valz, u, v, w, graduz);
33
double eps[6] = {gradux[0], graduy[1], graduz[2],
34
0.5 * (gradux[1] + graduy[0]),
35
0.5 * (gradux[2] + graduz[0]),
36
0.5 * (graduy[2] + graduz[1])};
37
double A = E / (1. + nu);
38
double B = A * (nu / (1. - 2 * nu));
39
double trace = eps[0] + eps[1] + eps[2] ;
40
double sxx = A * eps[0] + B * trace;
41
double syy = A * eps[1] + B * trace;
42
double szz = A * eps[2] + B * trace;
43
double sxy = A * eps[3];
44
double sxz = A * eps[4];
45
double syz = A * eps[5];
47
double s[9] = {sxx, sxy, sxz,
51
return ComputeVonMises(s);
54
void elasticitySolver::setMesh(const std::string &meshFileName)
56
pModel = new GModel();
57
pModel->readMSH(meshFileName.c_str());
58
_dim = pModel->getNumRegions() ? 3 : 2;
61
void elasticitySolver::readInputFile(const std::string &fn)
63
FILE *f = fopen(fn.c_str(), "r");
66
if(fscanf(f, "%s", what) != 1) return;
67
// printf("%s\n", what);
68
if (!strcmp(what,"ElasticMaterial")){
71
if(fscanf(f, "%d %lf %lf", &physical, &E, &nu) != 3) return;
72
elasticConstants[physical] = std::make_pair(E, nu);
74
else if (!strcmp(what, "NodalDisplacement")){
77
if(fscanf(f, "%d %d %lf", &node, &comp, &val) != 3) return;
78
nodalDisplacements[ std::make_pair(node, comp) ] = val;
80
else if (!strcmp(what, "EdgeDisplacement")){
83
if(fscanf(f, "%d %d %lf", &edge, &comp, &val) != 3) return;
84
edgeDisplacements[ std::make_pair(edge, comp) ] = val;
86
else if (!strcmp(what, "FaceDisplacement")){
89
if(fscanf(f, "%d %d %lf", &face, &comp, &val) != 3) return;
90
faceDisplacements[ std::make_pair(face, comp) ] = val;
92
else if (!strcmp(what, "NodalForce")){
93
double val1, val2, val3;
95
if(fscanf(f, "%d %lf %lf %lf", &node, &val1, &val2, &val3) != 4) return;
96
nodalForces[node] = SVector3(val1, val2, val3);
98
else if (!strcmp(what, "LineForce")){
99
double val1, val2, val3;
101
if(fscanf(f, "%d %lf %lf %lf", &node, &val1, &val2, &val3) != 4) return;
102
//printf("%d %lf %lf %lf\n", node, val1, val2, val3);
103
lineForces[node] = SVector3(val1, val2, val3);
105
else if (!strcmp(what, "FaceForce")){
106
double val1, val2, val3;
108
if(fscanf(f, "%d %lf %lf %lf", &face, &val1, &val2, &val3) != 4) return;
109
faceForces[face] = SVector3(val1, val2, val3);
111
else if (!strcmp(what, "VolumeForce")){
112
double val1, val2, val3;
114
if(fscanf(f, "%d %lf %lf %lf", &volume, &val1, &val2, &val3) != 4) return;
115
volumeForces[volume] = SVector3(val1, val2, val3);
117
else if (!strcmp(what, "MeshFile")){
119
if(fscanf(f, "%s", name) != 1) return;
126
void elasticitySolver::solve()
129
linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>;
131
linearSystemCSRGmm<double> *lsys = new linearSystemCSRGmm<double>;
133
pAssembler = new dofManager<double, double>(lsys);
135
std::map<int, std::vector<GEntity*> > groups[4];
136
pModel->getPhysicalGroups(groups);
138
// we first do all fixations. the behavior of the dofManager is to
139
// give priority to fixations : when a dof is fixed, it cannot be
140
// numbered afterwards
142
for (std::map<std::pair<int, int>, double>::iterator it = nodalDisplacements.begin();
143
it != nodalDisplacements.end(); ++it){
144
MVertex *v = pModel->getMeshVertexByTag(it->first.first);
145
pAssembler->fixVertex(v , it->first.second, _tag, it->second);
146
printf("-- Fixing node %3d comp %1d to %8.5f\n",
147
it->first.first, it->first.second, it->second);
150
for (std::map<std::pair<int, int>, double>::iterator it = edgeDisplacements.begin();
151
it != edgeDisplacements.end(); ++it){
152
elasticityTerm El(pModel, 1, 1, _tag);
153
El.dirichletNodalBC(it->first.first, 1, it->first.second, _tag,
154
simpleFunction<double>(it->second), *pAssembler);
155
printf("-- Fixing edge %3d comp %1d to %8.5f\n",
156
it->first.first, it->first.second, it->second);
159
for (std::map<std::pair<int, int>, double>::iterator it = faceDisplacements.begin();
160
it != faceDisplacements.end(); ++it){
161
elasticityTerm El(pModel, 1, 1, _tag);
162
El.dirichletNodalBC(it->first.first, 2, it->first.second, _tag,
163
simpleFunction<double>(it->second), *pAssembler);
164
printf("-- Fixing face %3d comp %1d to %8.5f\n",
165
it->first.first, it->first.second, it->second);
168
// we number the nodes : when a node is numbered, it cannot be numbered
169
// again with another number. so we loop over elements
170
for (std::map<int, std::pair<double, double> >::iterator it = elasticConstants.begin();
171
it != elasticConstants.end() ; it++){
172
int physical = it->first;
173
std::vector<MVertex *> v;
174
pModel->getMeshVerticesForPhysicalGroup(_dim, physical, v);
175
printf("Physical %d, dim: %d, nb vert: %d\n", physical, _dim, (int)v.size());
176
for (unsigned int i = 0; i < v.size(); i++){
177
pAssembler->numberVertex(v[i], 0, _tag);
178
pAssembler->numberVertex(v[i], 1, _tag);
179
pAssembler->numberVertex(v[i], 2, _tag);
183
// Now we start the assembly process
184
// First build the force vector
185
// Nodes at geometrical vertices
186
for (std::map<int, SVector3 >::iterator it = nodalForces.begin();
187
it != nodalForces.end(); ++it){
188
int iVertex = it->first;
189
SVector3 f = it->second;
190
std::vector<GEntity*> ent = groups[0][iVertex];
191
for (unsigned int i = 0; i < ent.size(); i++){
192
pAssembler->assemble(ent[i]->mesh_vertices[0], 0, _tag, f.x());
193
pAssembler->assemble(ent[i]->mesh_vertices[0], 1, _tag, f.y());
194
pAssembler->assemble(ent[i]->mesh_vertices[0], 2, _tag, f.z());
195
printf("-- Force on node %3d(%3d) : %8.5f %8.5f %8.5f\n",
196
ent[i]->mesh_vertices[0]->getNum(), iVertex, f.x(), f.y(), f.z());
201
for (std::map<int, SVector3 >::iterator it = lineForces.begin();
202
it != lineForces.end(); ++it){
203
elasticityTerm El(pModel, 1, 1, _tag);
204
int iEdge = it->first;
205
SVector3 f = it->second;
206
El.neumannNodalBC(iEdge, 1, 0, _tag, simpleFunction<double>(f.x()), *pAssembler);
207
El.neumannNodalBC(iEdge, 1, 1, _tag, simpleFunction<double>(f.y()), *pAssembler);
208
El.neumannNodalBC(iEdge, 1, 2, _tag, simpleFunction<double>(f.z()), *pAssembler);
209
printf("-- Force on edge %3d : %8.5f %8.5f %8.5f\n", iEdge, f.x(), f.y(), f.z());
213
for (std::map<int, SVector3 >::iterator it = faceForces.begin();
214
it != faceForces.end(); ++it){
215
elasticityTerm El(pModel, 1, 1, _tag);
216
int iFace = it->first;
217
SVector3 f = it->second;
218
El.neumannNodalBC(iFace, 2, 0, _tag, simpleFunction<double>(f.x()), *pAssembler);
219
El.neumannNodalBC(iFace, 2, 1, _tag, simpleFunction<double>(f.y()), *pAssembler);
220
El.neumannNodalBC(iFace, 2, 2, _tag, simpleFunction<double>(f.z()), *pAssembler);
221
printf("-- Force on face %3d : %8.5f %8.5f %8.5f\n", iFace, f.x(), f.y(), f.z());
225
for (std::map<int, SVector3 >::iterator it = volumeForces.begin();
226
it != volumeForces.end(); ++it){
227
elasticityTerm El(pModel, 1, 1, _tag);
228
int iVolume = it->first;
229
SVector3 f = it->second;
231
printf("-- Force on volume %3d : %8.5f %8.5f %8.5f\n", iVolume, f.x(), f.y(), f.z());
232
std::vector<GEntity*> ent = groups[_dim][iVolume];
233
for (unsigned int i = 0; i < ent.size(); i++){
234
El.addToRightHandSide(*pAssembler, ent[i]);
238
// assembling the stifness matrix
239
for (std::map<int, std::pair<double, double> >::iterator it = elasticConstants.begin();
240
it != elasticConstants.end() ; it++){
241
int physical = it->first;
242
double E = it->second.first;
243
double nu = it->second.second;
244
elasticityTerm El(0, E, nu, _tag);
245
std::vector<GEntity*> ent = groups[_dim][physical];
246
for (unsigned int i = 0; i < ent.size(); i++){
247
El.addToMatrix(*pAssembler, ent[i]);