00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef MECHSYS_FEM_EQUILIB_H
00023 #define MECHSYS_FEM_EQUILIB_H
00024
00025 #ifdef HAVE_CONFIG_H
00026 #include "config.h"
00027 #else
00028 #ifndef REAL
00029 #define REAL double
00030 #endif
00031 #endif
00032
00033 #include "util/string.h"
00034 #include "models/equilibmodel.h"
00035 #include "fem/ele/element.h"
00036 #include "tensors/tensors.h"
00037 #include "tensors/functions.h"
00038 #include "util/numstreams.h"
00039 #include "linalg/laexpr.h"
00040
00041 using Tensors::Stress_p_q_S_sin3th;
00042 using Tensors::Strain_Ev_Ed;
00043
00044 namespace FEM
00045 {
00046
00047 class EquilibElem : public virtual Element
00048 {
00049
00050 public:
00051
00052 static int NDIM;
00053 static int NSTRESSCOMPS;
00054 static String DUX;
00055 static String DUY;
00056 static String DUZ;
00057 static String DFX;
00058 static String DFY;
00059 static String DFZ;
00060 static String DTX;
00061 static String DTY;
00062 static String DTZ;
00063
00064
00065
00066 virtual ~EquilibElem() {}
00067
00068
00069 virtual void ReAllocateModel (String const & ModelName, Array<REAL> const & ModelPrms, Array<Array<REAL> > const & AIniData);
00070 virtual bool IsEssential (String const & DOFName) const;
00071 virtual void Stiffness (LinAlg::Matrix<REAL> & Ke, Array<size_t> & EqMap) const;
00072 virtual void B_Matrix (LinAlg::Matrix<REAL> const & derivs, LinAlg::Matrix<REAL> const & J, LinAlg::Matrix<REAL> & B) const;
00073 virtual void NodalDOFs (int iNode, Array<FEM::Node::DOFVarsStruct*> & DOFs) const;
00074 virtual void SetProperties (Array<REAL> const & EleProps) { _unit_weight=EleProps[0]; }
00075 virtual String OutCenter (bool PrintCaptionOnly) const;
00076 void OutNodes (LinAlg::Matrix<REAL> & Values, Array<String> & Labels) const;
00077 virtual void UpdateState (REAL TimeInc);
00078 virtual void CalcFaceNodalValues (String const & FaceDOFName ,
00079 REAL const FaceDOFValue ,
00080 Array<FEM::Node*> const & APtrFaceNodes,
00081 String & NodalDOFName ,
00082 LinAlg::Vector<REAL> & NodalValues ) const;
00083 virtual void Deactivate();
00084
00085
00086 void BackupState();
00087 void RestoreState();
00088
00089 virtual size_t nOrder1Matrices() const { return 1; };
00090 virtual void Order1Matrix(size_t index, LinAlg::Matrix<REAL> & M, Array<size_t> & RowsMap, Array<size_t> & ColsMap) const;
00091
00092 void OutTensor1 (String & Str) const;
00093 void OutTensor2 (String & Str) const;
00094 REAL OutScalar2 () const;
00095
00096 private:
00097
00098 Array<EquilibModel*> _a_model;
00099 REAL _unit_weight;
00100
00101
00102 void _set_node_vars (int iNode);
00103 void _calc_initial_internal_forces ();
00104
00105 };
00106
00107
00108 int EquilibElem::NDIM = 3;
00109 int EquilibElem::NSTRESSCOMPS = 6;
00110 String EquilibElem::DUX = _T("Dux");
00111 String EquilibElem::DUY = _T("Duy");
00112 String EquilibElem::DUZ = _T("Duz");
00113 String EquilibElem::DFX = _T("Dfx");
00114 String EquilibElem::DFY = _T("Dfy");
00115 String EquilibElem::DFZ = _T("Dfz");
00116 String EquilibElem::DTX = _T("Dtx");
00117 String EquilibElem::DTY = _T("Dty");
00118 String EquilibElem::DTZ = _T("Dtz");
00119
00120
00121
00123
00124
00125 inline void EquilibElem::_set_node_vars(int iNode)
00126 {
00127
00128 _connects[iNode]->AddDOF(DUX, DFX);
00129 _connects[iNode]->AddDOF(DUY, DFY);
00130 _connects[iNode]->AddDOF(DUZ, DFZ);
00131
00132
00133 _connects[iNode]->SetEssentialVector(DUX, DUY, DUZ);
00134 _connects[iNode]->SetNaturalVector (DFX, DFY, DFZ);
00135 }
00136
00137 inline void EquilibElem::Deactivate()
00138 {
00139 if (_is_active==false) return;
00140 _is_active = false;
00141
00142 for (int i_node=0; i_node<_n_nodes; i_node++)
00143 {
00144 _connects[i_node]->Refs()--;
00145 }
00146
00147 bool in_boundary = false;
00148 for (int i_node=0; i_node<_n_nodes; i_node++)
00149 if (_connects[i_node]->Refs()>0)
00150 {
00151 in_boundary=true;
00152 break;
00153 }
00154
00155 if (in_boundary)
00156 {
00157 LinAlg::Vector<REAL> F(NDIM*_n_nodes);
00158 F.SetValues(0.0);
00159
00160 for (int i_ip=0; i_ip<_n_int_pts; ++i_ip)
00161 {
00162
00163 REAL r = _a_int_pts[i_ip].r;
00164 REAL s = _a_int_pts[i_ip].s;
00165 REAL t = _a_int_pts[i_ip].t;
00166 REAL w = _a_int_pts[i_ip].w;
00167
00168 LinAlg::Matrix<REAL> derivs;
00169 Derivs(r,s,t, derivs);
00170
00171
00172 LinAlg::Matrix<REAL> J;
00173 Jacobian(derivs, J);
00174 REAL det_J = J.Det();
00175
00176
00177 LinAlg::Matrix<REAL> B;
00178 B_Matrix(derivs,J, B);
00179
00180
00181 Tensors::Tensor2 sig;
00182 sig = _a_model[i_ip]->Sig();
00183
00184
00185 for (int i=0; i<F.Size(); ++i)
00186 for (int j=0; j<B.Rows(); ++j)
00187 F(i) += B(j,i)*sig(j)*det_J*w;
00188 }
00189
00190
00191 for (int i_node=0; i_node<_n_nodes; i_node++)
00192 if (_connects[i_node]->Refs()>0)
00193 {
00194 _connects[i_node]->DOFVar(DFX).NaturalBry += F(i_node*NDIM );
00195 _connects[i_node]->DOFVar(DFY).NaturalBry += F(i_node*NDIM+1);
00196 _connects[i_node]->DOFVar(DFZ).NaturalBry += F(i_node*NDIM+2);
00197 }
00198 else
00199 {
00200 _connects[i_node]->ClearDOF();
00201
00202 }
00203
00204 }
00205 }
00206
00207 inline void EquilibElem::ReAllocateModel(String const & ModelName, Array<REAL> const & ModelPrms, Array<Array<REAL> > const & AIniData)
00208 {
00209
00210 if (!(AIniData.size()==1 || static_cast<int>(AIniData.size())==_n_int_pts))
00211 throw new Fatal(_("EquilibElem::ReAllocateModel: Array of array of initial data must have size==1 or size==%d"),_n_int_pts);
00212
00213
00214 if (_a_model.size()==0)
00215 {
00216
00217 _a_model.resize(_n_int_pts);
00218
00219
00220 for (int i=0; i<_n_int_pts; ++i)
00221 {
00222
00223 if (AIniData.size()==1) _a_model[i] = AllocEquilibModel(ModelName, ModelPrms, AIniData[0]);
00224 else _a_model[i] = AllocEquilibModel(ModelName, ModelPrms, AIniData[i]);
00225 }
00226
00227
00228 _calc_initial_internal_forces();
00229 }
00230 else
00231 {
00232
00233 for (int i=0; i<_n_int_pts; ++i)
00234 {
00235 if (_a_model[i]->Name()!=ModelName)
00236 {
00237
00238 delete _a_model[i];
00239
00240
00241 if (AIniData.size()==1) _a_model[i] = AllocEquilibModel(ModelName, ModelPrms, AIniData[0]);
00242 else _a_model[i] = AllocEquilibModel(ModelName, ModelPrms, AIniData[i]);
00243 }
00244
00245 }
00246 }
00247 }
00248
00249 inline bool EquilibElem::IsEssential(String const & DOFName) const
00250 {
00251 if (DOFName==DUX || DOFName==DUY || DOFName==DUZ) return true;
00252 else return false;
00253 }
00254
00255 inline void EquilibElem::CalcFaceNodalValues(String const & FaceDOFName ,
00256 REAL const FaceDOFValue ,
00257 Array<FEM::Node*> const & APtrFaceNodes,
00258 String & NodalDOFName ,
00259 LinAlg::Vector<REAL> & NodalValues ) const
00260 {
00261 if (FaceDOFName==DTX || FaceDOFName==DTY || FaceDOFName==DTZ)
00262 {
00263 if (FaceDOFName==DTX) NodalDOFName=DFX;
00264 if (FaceDOFName==DTY) NodalDOFName=DFY;
00265 if (FaceDOFName==DTZ) NodalDOFName=DFZ;
00266 _distrib_val_to_face_nodal_vals(APtrFaceNodes, FaceDOFValue, NodalValues);
00267 }
00268 else
00269 {
00270 std::ostringstream oss; oss << "Face nodes coordinates:\n";
00271 for (size_t i_node=0; i_node<APtrFaceNodes.size(); ++i_node)
00272 oss << "X=" << APtrFaceNodes[i_node]->X() << ", Y=" << APtrFaceNodes[i_node]->Y() << ", Z=" << APtrFaceNodes[i_node]->Z() << std::endl;
00273 throw new Fatal(_("EquilibElem::CalcFaceNodalValues: This method must only be called for FaceDOFName< %s > equal to Dtx, Dty or Dtz.\n %s"),
00274 FaceDOFName.c_str(), oss.str().c_str());
00275 }
00276 }
00277
00278 inline void EquilibElem::Stiffness(LinAlg::Matrix<REAL> & Ke, Array<size_t> & EqMap) const
00279 {
00280
00281 Ke.Resize(NDIM*_n_nodes, NDIM*_n_nodes);
00282 Ke.SetValues(0.0);
00283
00284
00285 LinAlg::Matrix<REAL> derivs;
00286 LinAlg::Matrix<REAL> J;
00287 LinAlg::Matrix<REAL> B;
00288 Tensors::Tensor4 tsrD;
00289 LinAlg::Matrix<REAL> D;
00290
00291
00292 for (int i_ip=0; i_ip<_n_int_pts; ++i_ip)
00293 {
00294
00295 REAL r = _a_int_pts[i_ip].r;
00296 REAL s = _a_int_pts[i_ip].s;
00297 REAL t = _a_int_pts[i_ip].t;
00298 REAL w = _a_int_pts[i_ip].w;
00299
00300 Derivs(r,s,t, derivs);
00301 Jacobian(derivs, J);
00302 B_Matrix(derivs,J, B);
00303
00304
00305 _a_model[i_ip]->TgStiffness(tsrD); Copy(tsrD, D);
00306
00307
00308 Ke += trn(B)*D*B*det(J)*w;
00309 }
00310
00311
00312 int idx_Ke=0;
00313 EqMap.resize(Ke.Rows());
00314 for (int i_node=0; i_node<_n_nodes; ++i_node)
00315 {
00316
00317 EqMap[idx_Ke++] = _connects[i_node]->DOFVar(DUX).EqID;
00318 EqMap[idx_Ke++] = _connects[i_node]->DOFVar(DUY).EqID;
00319 EqMap[idx_Ke++] = _connects[i_node]->DOFVar(DUZ).EqID;
00320 }
00321 }
00322
00323 inline void EquilibElem::NodalDOFs(int iNode, Array<FEM::Node::DOFVarsStruct*> & DOFs) const
00324 {
00325
00326
00327
00328
00329 DOFs.resize(3);
00330
00331
00332 DOFs[0] = &_connects[iNode]->DOFVar(DUX);
00333 DOFs[1] = &_connects[iNode]->DOFVar(DUY);
00334 DOFs[2] = &_connects[iNode]->DOFVar(DUZ);
00335
00336 }
00337
00338 inline void EquilibElem::B_Matrix(LinAlg::Matrix<REAL> const & derivs, LinAlg::Matrix<REAL> const & J, LinAlg::Matrix<REAL> & B) const
00339 {
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 B.Resize(NSTRESSCOMPS,NDIM*_n_nodes);
00351
00352
00353 LinAlg::Matrix<REAL> inv_J(J.Rows(),J.Cols());
00354 J.Inv(inv_J);
00355
00356
00357 LinAlg::Matrix<REAL> cart_derivs;
00358 cart_derivs.Resize(J.Rows(), derivs.Cols());
00359 LinAlg::Gemm(1.0,inv_J,derivs, 0.0,cart_derivs);
00360
00361
00362 REAL sq2 = sqrt(2.0);
00363 REAL dNdX,dNdY,dNdZ;
00364 int j=0;
00365 for (int i=0; i<_n_nodes; ++i)
00366 {
00367
00368 j=i*NDIM;
00369 dNdX=-cart_derivs(0,i); dNdY=-cart_derivs(1,i); dNdZ=-cart_derivs(2,i);
00370 B(0,0+j) = dNdX; B(0,1+j) = 0.0; B(0,2+j) = 0.0;
00371 B(1,0+j) = 0.0; B(1,1+j) = dNdY; B(1,2+j) = 0.0;
00372 B(2,0+j) = 0.0; B(2,1+j) = 0.0; B(2,2+j) = dNdZ;
00373 B(3,0+j) = dNdY/sq2; B(3,1+j) = dNdX/sq2; B(3,2+j) = 0.0;
00374 B(4,0+j) = 0.0; B(4,1+j) = dNdZ/sq2; B(4,2+j) = dNdY/sq2;
00375 B(5,0+j) = dNdZ/sq2; B(5,1+j) = 0.0; B(5,2+j) = dNdX/sq2;
00376 }
00377 }
00378
00379 inline void EquilibElem::BackupState()
00380 {
00381 for (int i=0; i<_n_int_pts; ++i)
00382 _a_model[i]->BackupState();
00383 }
00384
00385 inline void EquilibElem::UpdateState(REAL TimeInc)
00386 {
00387
00388
00389
00390 LinAlg::Vector<REAL> dU(NDIM*_n_nodes);
00391
00392
00393 for (int i_node=0; i_node<_n_nodes; ++i_node)
00394 {
00395
00396 dU(i_node*NDIM ) = _connects[i_node]->DOFVar(DUX)._IncEssenVal;
00397 dU(i_node*NDIM+1) = _connects[i_node]->DOFVar(DUY)._IncEssenVal;
00398 dU(i_node*NDIM+2) = _connects[i_node]->DOFVar(DUZ)._IncEssenVal;
00399 }
00400
00401
00402 LinAlg::Vector<REAL> dF(NDIM*_n_nodes);
00403 dF.SetValues(0.0);
00404
00405
00406 LinAlg::Matrix<REAL> derivs;
00407 LinAlg::Matrix<REAL> J;
00408 LinAlg::Matrix<REAL> B;
00409 Tensors::Tensor2 tsrDEps;
00410 Tensors::Tensor2 tsrDSig;
00411 LinAlg::Vector<REAL> DEps;
00412 LinAlg::Vector<REAL> DSig;
00413
00414
00415 for (int i_ip=0; i_ip<_n_int_pts; ++i_ip)
00416 {
00417
00418 REAL r = _a_int_pts[i_ip].r;
00419 REAL s = _a_int_pts[i_ip].s;
00420 REAL t = _a_int_pts[i_ip].t;
00421 REAL w = _a_int_pts[i_ip].w;
00422
00423 Derivs(r,s,t, derivs);
00424 Jacobian(derivs, J);
00425 B_Matrix(derivs, J, B);
00426
00427
00428 DEps = B*dU;
00429 Copy(DEps, tsrDEps);
00430
00431
00432 _a_model[i_ip]->StressUpdate(tsrDEps, tsrDSig);
00433 Copy(tsrDSig, DSig);
00434
00435
00436 dF += trn(B)*DSig*det(J)*w;
00437 }
00438
00439
00440 for (int i_node=0; i_node<_n_nodes; ++i_node)
00441 {
00442
00443 _connects[i_node]->DOFVar(DFX)._IncNaturVal += dF(i_node*NDIM );
00444 _connects[i_node]->DOFVar(DFY)._IncNaturVal += dF(i_node*NDIM+1);
00445 _connects[i_node]->DOFVar(DFZ)._IncNaturVal += dF(i_node*NDIM+2);
00446
00447
00448 _connects[i_node]->DOFVar(DFX).NaturalVal += dF(i_node*NDIM );
00449 _connects[i_node]->DOFVar(DFY).NaturalVal += dF(i_node*NDIM+1);
00450 _connects[i_node]->DOFVar(DFZ).NaturalVal += dF(i_node*NDIM+2);
00451 }
00452 }
00453
00454 inline void EquilibElem::RestoreState()
00455 {
00456 for (int i=0; i<_n_int_pts; ++i)
00457 _a_model[i]->RestoreState();
00458 }
00459
00460 inline String EquilibElem::OutCenter(bool PrintCaptionOnly=false) const
00461 {
00462
00463 std::ostringstream oss;
00464
00465
00466 int n_int_state_vals = _a_model[0]->nInternalStateValues();
00467
00468
00469 if (PrintCaptionOnly)
00470 {
00471
00472 oss << _8s()<< "p" << _8s()<< "q" << _8s()<< "sin3th" << _8s()<< "Ev" << _8s()<< "Ed";
00473 oss << _8s()<< "Sx" << _8s()<< "Sy" << _8s()<< "Sz" << _8s()<< "Sxy" << _8s()<< "Syz" << _8s()<< "Sxz";
00474 oss << _8s()<< "Ex" << _8s()<< "Ey" << _8s()<< "Ez" << _8s()<< "Exy" << _8s()<< "Eyz" << _8s()<< "Exz";
00475
00476
00477 Array<String> str_state_names; _a_model[0]->InternalStateNames(str_state_names);
00478 for (int i=0; i<n_int_state_vals; ++i)
00479 oss << _8s()<< str_state_names[i];
00480 oss << std::endl;
00481 }
00482 else
00483 {
00484
00485 Tensors::Tensor2 sig_cen(0.0);
00486 Tensors::Tensor2 eps_cen(0.0);
00487 Array<REAL> int_state_vals_cen; int_state_vals_cen.assign(n_int_state_vals,0.0);
00488
00489
00490 for (int i_ip=0; i_ip<_n_int_pts; ++i_ip)
00491 {
00492
00493 sig_cen += _a_model[i_ip]->Sig();
00494 eps_cen += _a_model[i_ip]->Eps();
00495
00496
00497 Array<REAL> int_state_vals; _a_model[i_ip]->InternalStateValues(int_state_vals);
00498 for (int j=0; j<n_int_state_vals; ++j)
00499 int_state_vals_cen[j] += int_state_vals[j];
00500 }
00501
00502
00503 sig_cen = sig_cen / _n_int_pts;
00504 eps_cen = eps_cen / _n_int_pts;
00505
00506
00507 for (int j=0; j<n_int_state_vals; ++j)
00508 int_state_vals_cen[j] = int_state_vals_cen[j] / _n_int_pts;;
00509
00510
00511 REAL p,q,sin3th;
00512 Tensors::Tensor2 S;
00513 Stress_p_q_S_sin3th(sig_cen,p,q,S,sin3th);
00514
00515
00516 REAL Ev,Ed;
00517 Strain_Ev_Ed(eps_cen,Ev,Ed);
00518
00519
00520 REAL sq2 = sqrt(2.0);
00521 oss << _8s()<< p << _8s()<< q << _8s()<< sin3th << _8s()<< Ev*100.0 << _8s()<< Ed*100.0;
00522 oss << _8s()<< sig_cen(0) << _8s()<< sig_cen(1) << _8s()<< sig_cen(2) << _8s()<< sig_cen(3)/sq2 << _8s()<< sig_cen(4)/sq2 << _8s()<< sig_cen(5)/sq2;
00523 oss << _8s()<< eps_cen(0) << _8s()<< eps_cen(1) << _8s()<< eps_cen(2) << _8s()<< eps_cen(3)/sq2 << _8s()<< eps_cen(4)/sq2 << _8s()<< eps_cen(5)/sq2;
00524 for (int j=0; j<n_int_state_vals; ++j)
00525 oss << _8s()<< int_state_vals_cen[j];
00526 oss << std::endl;
00527 }
00528
00529 return oss.str();
00530 }
00531
00532 inline void EquilibElem::OutNodes(LinAlg::Matrix<REAL> & Values, Array<String> & Labels) const
00533 {
00534 int const DATA_COMPS=18;
00535 Values.Resize(_n_nodes,DATA_COMPS);
00536 Labels.resize(DATA_COMPS);
00537 Labels[ 0] = DUX ; Labels[ 1] = DUY ; Labels[ 2] = DUZ;
00538 Labels[ 3] = DFX ; Labels[ 4] = DFY ; Labels[ 5] = DFZ;
00539 Labels[ 6] = "Ex"; Labels[ 7] = "Ey"; Labels[ 8] = "Ez"; Labels[ 9] = "Exy"; Labels[10] = "Eyz"; Labels[11] = "Exz";
00540 Labels[12] = "Sx"; Labels[13] = "Sy"; Labels[14] = "Sz"; Labels[15] = "Sxy"; Labels[16] = "Syz"; Labels[17] = "Sxz";
00541 for (int i_node=0; i_node<_n_nodes; i_node++)
00542 {
00543 Values(i_node,0) = _connects[i_node]->DOFVar(DUX).EssentialVal;
00544 Values(i_node,1) = _connects[i_node]->DOFVar(DUY).EssentialVal;
00545 Values(i_node,2) = _connects[i_node]->DOFVar(DUZ).EssentialVal;
00546 Values(i_node,3) = _connects[i_node]->DOFVar(DFX).NaturalVal;
00547 Values(i_node,4) = _connects[i_node]->DOFVar(DFY).NaturalVal;
00548 Values(i_node,5) = _connects[i_node]->DOFVar(DFZ).NaturalVal;
00549 }
00550
00551
00552 LinAlg::Vector<REAL> ip_values(_n_int_pts);
00553 LinAlg::Vector<REAL> nodal_values(_n_nodes);
00554
00555
00556 for (int i_comp=0; i_comp<NSTRESSCOMPS; i_comp++)
00557 {
00558 for (int j_ip=0; j_ip<_n_int_pts; j_ip++)
00559 {
00560 Tensors::Tensor2 const & eps = _a_model[j_ip]->Eps();
00561 ip_values(j_ip) = eps(i_comp);
00562 }
00563 _extrapolate(ip_values, nodal_values);
00564 for (int j_node=0; j_node<_n_nodes; j_node++)
00565 Values(j_node,i_comp+6) = nodal_values(j_node);
00566 }
00567
00568
00569 for (int i_comp=0; i_comp<NSTRESSCOMPS; i_comp++)
00570 {
00571 for (int j_ip=0; j_ip<_n_int_pts; j_ip++)
00572 {
00573 Tensors::Tensor2 const & sig = _a_model[j_ip]->Sig();
00574 ip_values(j_ip) = sig(i_comp);
00575 }
00576 _extrapolate(ip_values, nodal_values);
00577 for (int j_node=0; j_node<_n_nodes; j_node++)
00578 Values(j_node,i_comp+12) = nodal_values(j_node);
00579 }
00580 }
00581
00582 inline void EquilibElem::_calc_initial_internal_forces()
00583 {
00584
00585 LinAlg::Vector<REAL> F(NDIM*_n_nodes);
00586 F.SetValues(0.0);
00587
00588
00589 LinAlg::Matrix<REAL> derivs;
00590 LinAlg::Matrix<REAL> J;
00591 LinAlg::Matrix<REAL> B;
00592 LinAlg::Vector<REAL> Sig;
00593
00594
00595 for (int i_ip=0; i_ip<_n_int_pts; ++i_ip)
00596 {
00597
00598 REAL r = _a_int_pts[i_ip].r;
00599 REAL s = _a_int_pts[i_ip].s;
00600 REAL t = _a_int_pts[i_ip].t;
00601 REAL w = _a_int_pts[i_ip].w;
00602
00603 Derivs(r,s,t, derivs);
00604 Jacobian(derivs, J);
00605 B_Matrix(derivs, J, B);
00606
00607 Tensors::Tensor2 const & tsrSig = _a_model[i_ip]->Sig();
00608 Copy(tsrSig, Sig);
00609
00610
00611 F += trn(B)*Sig*det(J)*w;
00612 }
00613
00614
00615 for (int i_node=0; i_node<_n_nodes; ++i_node)
00616 {
00617
00618 _connects[i_node]->DOFVar(DFX).NaturalVal += F(i_node*NDIM );
00619 _connects[i_node]->DOFVar(DFY).NaturalVal += F(i_node*NDIM+1);
00620 _connects[i_node]->DOFVar(DFZ).NaturalVal += F(i_node*NDIM+2);
00621 }
00622 }
00623
00624 inline void EquilibElem::Order1Matrix(size_t index, LinAlg::Matrix<REAL> & M, Array<size_t> & RowsMap, Array<size_t> & ColsMap) const
00625 {
00626 assert(index == 0);
00627 Stiffness(M, RowsMap);
00628 ColsMap.resize(RowsMap.size());
00629 for (size_t i=0; i<RowsMap.size(); i++) ColsMap[i] = RowsMap[i];
00630 }
00631
00632 inline void EquilibElem::OutTensor1(String & Str) const
00633 {
00634
00635 Tensors::Tensor2 s(0.0);
00636
00637
00638 for (int i_ip=0; i_ip<_n_int_pts; ++i_ip)
00639 s += _a_model[i_ip]->Sig();
00640
00641
00642 s = s / _n_int_pts;
00643
00644
00645 REAL sq2 = sqrt(2.0);
00646 Str.Printf(_(" %e %e %e %e %e %e %e %e %e "), s(0),s(3)/sq2,s(5)/sq2, s(3)/sq2,s(1),s(4)/sq2, s(5)/sq2,s(4)/sq2,s(2));
00647
00648 }
00649
00650 inline void EquilibElem::OutTensor2(String & Str) const
00651 {
00652
00653 Tensors::Tensor2 e(0.0);
00654
00655
00656 for (int i_ip=0; i_ip<_n_int_pts; ++i_ip)
00657 e += 100.0*_a_model[i_ip]->Eps();
00658
00659
00660 e = e / _n_int_pts;
00661
00662
00663 REAL sq2 = sqrt(2.0);
00664 Str.Printf(_(" %e %e %e %e %e %e %e %e %e "), e(0),e(3)/sq2,e(5)/sq2, e(3)/sq2,e(1),e(4)/sq2, e(5)/sq2,e(4)/sq2,e(2));
00665
00666 }
00667
00668 inline REAL EquilibElem::OutScalar2() const
00669 {
00670
00671 Tensors::Tensor2 e(0.0);
00672
00673
00674 for (int i_ip=0; i_ip<_n_int_pts; ++i_ip)
00675 e += 100.0*_a_model[i_ip]->Eps();
00676
00677
00678 e = e / _n_int_pts;
00679
00680
00681 REAL Ev,Ed;
00682 Strain_Ev_Ed(e,Ev,Ed);
00683
00684
00685 return Ed;
00686
00687 }
00688
00689
00691
00692
00693
00694 int EquilibDOFInfoRegister()
00695 {
00696
00697 DOFInfo D;
00698
00699
00700 D.NodeEssential.push_back(EquilibElem::DUX + _("@Nodal displacement increment in x direction"));
00701 D.NodeEssential.push_back(EquilibElem::DUY + _("@Nodal displacement increment in y direction"));
00702 D.NodeEssential.push_back(EquilibElem::DUZ + _("@Nodal displacement increment in z direction"));
00703 D.NodeNatural .push_back(EquilibElem::DFX + _("@Nodal force increment in x direction"));
00704 D.NodeNatural .push_back(EquilibElem::DFY + _("@Nodal force increment in y direction"));
00705 D.NodeNatural .push_back(EquilibElem::DFZ + _("@Nodal force increment in z direction"));
00706
00707
00708 D.FaceEssential.push_back(EquilibElem::DUX + _("@Displacement increment in x direction on face"));
00709 D.FaceEssential.push_back(EquilibElem::DUY + _("@Displacement increment in y direction on face"));
00710 D.FaceEssential.push_back(EquilibElem::DUZ + _("@Displacement increment in z direction on face"));
00711 D.FaceNatural .push_back(EquilibElem::DTX + _("@Traction increment in x direction on face"));
00712 D.FaceNatural .push_back(EquilibElem::DTY + _("@Traction increment in y direction on face"));
00713 D.FaceNatural .push_back(EquilibElem::DTZ + _("@Traction increment in z direction on face"));
00714
00715
00716 DOFInfoMap["Equilibrium"] = D;
00717
00718 return 0;
00719 }
00720
00721
00722 int __EquilibElemDOFInfo_dummy_int = EquilibDOFInfoRegister();
00723
00724 };
00725
00726 #endif // MECHSYS_FEM_EQUILIB_H
00727
00728