![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
00001 /************************************************************************ 00002 * MechSys - Open Library for Mechanical Systems * 00003 * Copyright (C) 2005 Dorival M. Pedroso, Raul Durand * 00004 * Copyright (C) 2009 Sergio Galindo * 00005 * * 00006 * This program is free software: you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation, either version 3 of the License, or * 00009 * any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License * 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> * 00018 ************************************************************************/ 00019 00020 #ifndef MECHSYS_FEM_USIGELEM_H 00021 #define MECHSYS_FEM_USIGELEM_H 00022 00023 // MechSys 00024 #include <mechsys/fem/element.h> 00025 #include <mechsys/models/equilibstate.h> 00026 #include <mechsys/models/strainupdate.h> 00027 #include <mechsys/models/stressupdate.h> 00028 00029 namespace FEM 00030 { 00031 00032 class USigElem : public Element 00033 { 00034 public: 00035 // Static 00036 static size_t NCo; 00037 static size_t NDs; 00038 static size_t NDu; 00039 00040 // Constructor 00041 USigElem (int NDim, 00042 Mesh::Cell const & Cell, 00043 Model const * Mdl, 00044 Model const * XMdl, 00045 SDPair const & Prp, 00046 SDPair const & Ini, 00047 Array<Node*> const & Nodes); 00048 00049 // Destructor 00050 ~USigElem () { if (GEs!=NULL) delete GEs; } 00051 00052 // Methods 00053 void IncNLocDOF (size_t & NEq) const { FirstEQ = NEq; NEq += NDs; } 00054 void GetLoc (Array<size_t> & Loc) const; 00055 void SetBCs (size_t IdxEdgeOrFace, SDPair const & BCs, BCFuncs * BCF); 00056 void CalcK (Mat_t & K) const; 00057 void UpdateState (Vec_t const & dU, Vec_t * F_int=NULL) const; 00058 void StateKeys (Array<String> & Keys) const; 00059 void StateAtIP (SDPair & KeysVals, int IdxIP) const; 00060 00061 // Internal methods 00062 void Matrices (Mat_t & A, Mat_t & Q) const; 00063 void Interp (Mat_t const & C, IntegPoint const & IP, Mat_t & B, Mat_t & N, Mat_t & Ns, double & detJ, double & Coef) const; 00064 00065 // Constants 00066 bool StrainResid; 00067 GeomElem * GEs; 00068 mutable long FirstEQ; 00069 }; 00070 00071 size_t USigElem::NCo = 0; 00072 size_t USigElem::NDs = 0; 00073 size_t USigElem::NDu = 0; 00074 00075 00077 00078 00079 inline USigElem::USigElem (int NDim, Mesh::Cell const & Cell, Model const * Mdl, Model const * XMdl, SDPair const & Prp, SDPair const & Ini, Array<Node*> const & Nodes) 00080 : Element(NDim,Cell,Mdl,XMdl,Prp,Ini,Nodes), StrainResid(true) 00081 { 00082 // check GE 00083 if (GE==NULL) throw new Fatal("USigElem::USigElem: GE (geometry element) must be defined"); 00084 if (GTy==pse_t) throw new Fatal("USigElem::USigElem: This element does not work for plane-stress (pse)"); 00085 if (Mdl==NULL) throw new Fatal("USigElem::USigElem: Model must be defined"); 00086 00087 // properties 00088 if (Prp.HasKey("strain_resid")) StrainResid = true; 00089 00090 // local nodes 00091 if (strcmp(GE->Name.CStr(),"Quad8")==0) GEs = AllocGeomElem ("Quad4", NDim); 00092 else throw new Fatal("USigElem::USigElem: GE must be Quad8 for the time being"); 00093 00094 // set constants of this class (just once) 00095 if (NDs==0) 00096 { 00097 NCo = 2*NDim; 00098 NDs = NCo*GEs->NN; 00099 NDu = NDim*GE->NN; 00100 } 00101 00102 // allocate and initialize state at each IP 00103 for (size_t i=0; i<GE->NIP; ++i) 00104 { 00105 Sta.Push (new EquilibState(NDim)); 00106 Mdl->InitIvs (Ini, Sta[i]); 00107 } 00108 00109 // set F in nodes due to initial stresses 00110 double detJ, coef; 00111 Mat_t C, B, N, Ns; 00112 Vec_t Fe(NDu); 00113 CoordMatrix (C); 00114 set_to_zero (Fe); 00115 for (size_t i=0; i<GE->NIP; ++i) 00116 { 00117 Interp (C, GE->IPs[i], B, N, Ns, detJ, coef); 00118 Vec_t const & sig = static_cast<EquilibState const *>(Sta[i])->Sig; 00119 Fe += (coef) * trans(B)*sig; 00120 } 00121 for (size_t i=0; i<GE->NN; ++i) 00122 { 00123 Con[i]->F("fx") += Fe(0+i*NDim); 00124 Con[i]->F("fy") += Fe(1+i*NDim); if (NDim==3) 00125 Con[i]->F("fz") += Fe(2+i*NDim); 00126 } 00127 } 00128 00129 inline void USigElem::SetBCs (size_t IdxEdgeOrFace, SDPair const & BCs, BCFuncs * BCF) 00130 { 00131 // deactivate/activate commands 00132 if (BCs.HasKey("deactivate")) throw new Fatal("USigElem::SetBCs: 'deactivate' command failed: method not implemented yet"); 00133 if (BCs.HasKey("activate")) throw new Fatal("USigElem::SetBCs: 'activate' command failed: method not implemented yet"); 00134 00135 // check 00136 if (!Active) throw new Fatal("USigElem::SetBCs: Element %d is inactive",Cell.ID); 00137 00138 bool has_bx = BCs.HasKey("bx"); // x component of body force 00139 bool has_by = BCs.HasKey("by"); // y component of body force 00140 bool has_bz = BCs.HasKey("bz"); // z component of body force 00141 bool has_cbx = BCs.HasKey("cbx"); // centrifugal body force along x (in axisymmetric problems) 00142 bool has_qx = BCs.HasKey("qx"); // x component of distributed loading 00143 bool has_qy = BCs.HasKey("qy"); // y component of distributed loading 00144 bool has_qz = BCs.HasKey("qz"); // z component of distributed loading 00145 bool has_qn = BCs.HasKey("qn"); // normal distributed loading 00146 bool has_qt = BCs.HasKey("qt"); // tangential distributed loading (2D only) 00147 bool has_ux = BCs.HasKey("ux"); // x displacement 00148 bool has_uy = BCs.HasKey("uy"); // y displacement 00149 bool has_uz = BCs.HasKey("uz"); // z displacement 00150 bool has_sup = BCs.HasKey("incsup"); // inclined support 00151 00152 // force components specified 00153 if (has_bx || has_by || has_bz || has_cbx || 00154 has_qx || has_qy || has_qz || has_qn || has_qt) 00155 { 00156 // body forces 00157 if (has_bx || has_by || has_bz || has_cbx) // prescribed body forces 00158 { 00159 // matrix of coordinates of nodes 00160 Mat_t C; 00161 CoordMatrix (C); 00162 00163 // loading 00164 double bx = (has_bx ? BCs("bx") : 0.0); 00165 double by = (has_by ? BCs("by") : 0.0); 00166 double bz = (has_bz ? BCs("bz") : 0.0); 00167 bx = (has_cbx ? BCs("cbx") : bx ); 00168 00169 // set 00170 for (size_t i=0; i<GE->NIP; ++i) 00171 { 00172 // geometric data 00173 GE->Shape (GE->IPs[i].r, GE->IPs[i].s, GE->IPs[i].t); 00174 GE->Derivs (GE->IPs[i].r, GE->IPs[i].s, GE->IPs[i].t); 00175 00176 // Jacobian and its determinant 00177 Mat_t J(GE->dNdR * C); // J = dNdR * C 00178 double detJ = Det(J); 00179 00180 // coefficient used during integration 00181 double coef = detJ*GE->IPs[i].w; 00182 if (GTy==axs_t) 00183 { 00184 // calculate radius=x at this IP 00185 double radius = 0.0; 00186 for (size_t j=0; j<GE->NN; ++j) radius += GE->N(j)*Con[j]->Vert.C[0]; 00187 00188 // correct coef 00189 if (has_cbx) coef *= radius*radius; 00190 else coef *= radius; 00191 } 00192 00193 // set boundary conditions 00194 for (size_t j=0; j<GE->NN; ++j) 00195 { 00196 Con[j]->AddToPF("fx", coef*GE->N(j)*bx, BCF); 00197 Con[j]->AddToPF("fy", coef*GE->N(j)*by, BCF); if (NDim==3) 00198 Con[j]->AddToPF("fz", coef*GE->N(j)*bz, BCF); 00199 } 00200 } 00201 } 00202 00203 // surface loading 00204 if (has_qx || has_qy || has_qz || has_qn || has_qt) 00205 { 00206 // matrix of coordinates of edge/face 00207 Mat_t Cf; 00208 FCoordMatrix (IdxEdgeOrFace, Cf); 00209 00210 // loading 00211 double qx = (has_qx ? BCs("qx") : 0.0); 00212 double qy = (has_qy ? BCs("qy") : 0.0); 00213 double qz = (has_qz ? BCs("qz") : 0.0); 00214 double qn = (has_qn ? BCs("qn") : 0.0); 00215 double qt = (has_qt ? BCs("qt") : 0.0); 00216 00217 // set 00218 for (size_t i=0; i<GE->NFIP; ++i) 00219 { 00220 // geometric data 00221 GE->FaceShape (GE->FIPs[i].r, GE->FIPs[i].s); 00222 GE->FaceDerivs (GE->FIPs[i].r, GE->FIPs[i].s); 00223 00224 // face/edge Jacobian and its determinant 00225 Mat_t J(GE->FdNdR * Cf); 00226 00227 // coefficient used during integration 00228 double coef = GE->FIPs[i].w; // *detJ is not necessary since qx,qy,qz are already multiplied by detJ (due to normal) 00229 00230 if (GTy==axs_t) 00231 { 00232 // calculate radius=x at this FIP 00233 double radius = 0.0; 00234 for (size_t j=0; j<GE->NFN; ++j) radius += GE->FN(j)*Con[GE->FNode(IdxEdgeOrFace,j)]->Vert.C[0]; 00235 coef *= radius; // correct coef 00236 } 00237 00238 // calculate qx, qy and qz from qn and qt 00239 if (has_qn || has_qt) 00240 { 00241 // normal to edge/face 00242 Vec_t n(NDim); // normal multiplied by detJ 00243 if (NDim==2) n = J(0,1), -J(0,0); 00244 else 00245 { 00246 // vectorial product 00247 Vec_t a(3); a = J(0,0), J(0,1), J(0,2); 00248 Vec_t b(3); b = J(1,0), J(1,1), J(1,2); 00249 n = a(1)*b(2) - a(2)*b(1), 00250 a(2)*b(0) - a(0)*b(2), 00251 a(0)*b(1) - a(1)*b(0); 00252 } 00253 00254 // loading 00255 if (NDim==2) 00256 { 00257 qx = n(0)*qn - n(1)*qt; 00258 qy = n(1)*qn + n(0)*qt; 00259 } 00260 else 00261 { 00262 qx = n(0)*qn; 00263 qy = n(1)*qn; 00264 qz = n(2)*qn; 00265 } 00266 } 00267 00268 // set boundary conditions 00269 for (size_t j=0; j<GE->NFN; ++j) 00270 { 00271 size_t k = GE->FNode(IdxEdgeOrFace,j); 00272 Con[k]->AddToPF("fx", coef*GE->FN(j)*qx, BCF); 00273 Con[k]->AddToPF("fy", coef*GE->FN(j)*qy, BCF); if (NDim==3) 00274 Con[k]->AddToPF("fz", coef*GE->FN(j)*qz, BCF); 00275 } 00276 } 00277 } 00278 } 00279 00280 // prescribed displacements 00281 else if (has_ux || has_uy || has_uz || has_sup) 00282 { 00283 double ux = (has_ux ? BCs("ux") : 0.0); 00284 double uy = (has_uy ? BCs("uy") : 0.0); 00285 double uz = (has_uz ? BCs("uz") : 0.0); 00286 double alpha = (has_sup ? BCs("alpha") : 0.0); 00287 for (size_t j=0; j<GE->NFN; ++j) 00288 { 00289 size_t k = GE->FNode(IdxEdgeOrFace,j); 00290 if (has_ux) Con[k]->SetPU("ux", ux, BCF); 00291 if (has_uy) Con[k]->SetPU("uy", uy, BCF); 00292 if (has_uz) Con[k]->SetPU("uz", uz, BCF); 00293 if (has_sup) Con[k]->SetIncSup (alpha); 00294 } 00295 } 00296 } 00297 00298 inline void USigElem::GetLoc (Array<size_t> & Loc) const 00299 { 00300 // Sig DOFs 00301 Loc.Resize (NDs + NDu); 00302 for (size_t i=0; i<NDs; ++i) Loc[i] = FirstEQ + i; 00303 00304 // U DOFs 00305 for (size_t i=0; i<GE->NN; ++i) 00306 { 00307 Loc[NDs+i*NDim+0] = Con[i]->Eq("ux"); 00308 Loc[NDs+i*NDim+1] = Con[i]->Eq("uy"); if (NDim==3) 00309 Loc[NDs+i*NDim+2] = Con[i]->Eq("uz"); 00310 } 00311 } 00312 00313 inline void USigElem::Matrices (Mat_t & A, Mat_t & Q) const 00314 { 00315 // submatrices 00316 A.change_dim (NDs,NDs); 00317 Q.change_dim (NDs,NDu); 00318 set_to_zero (A); 00319 set_to_zero (Q); 00320 00321 // auxiliar matrices 00322 double detJ, coef; 00323 Mat_t N, Ns, B, C, D, Di; 00324 CoordMatrix (C); 00325 00326 for (size_t i=0; i<GE->NIP; ++i) 00327 { 00328 // interpolation 00329 Interp (C, GE->IPs[i], B, N, Ns, detJ, coef); 00330 00331 // calc D 00332 Mdl->Stiffness (Sta[i], D); 00333 00334 // matrices 00335 Q += (coef) * trans(Ns)*B; 00336 if (StrainResid) 00337 { 00338 Inv (D, Di); 00339 A += (-coef) * trans(Ns)*Di*Ns; 00340 } 00341 else 00342 { 00343 A += (-coef) * trans(B)*D*B; 00344 } 00345 } 00346 } 00347 00348 inline void USigElem::CalcK (Mat_t & K) const 00349 { 00350 Mat_t A, Q; 00351 Matrices (A, Q); 00352 K.change_dim (NDs+NDu,NDs+NDu); 00353 set_to_zero (K); 00354 if (StrainResid) 00355 { 00356 for (size_t i=0; i<NDs; ++i) 00357 { 00358 for (size_t j=0; j<NDs; ++j) K(i,j) = A(i,j); 00359 for (size_t j=0; j<NDu; ++j) 00360 { 00361 K(i,NDs+j) = Q(i,j); 00362 K(NDs+j,i) = Q(i,j); 00363 } 00364 } 00365 } 00366 else 00367 { 00368 for (size_t i=0; i<NDu; ++i) 00369 { 00370 for (size_t j=0; j<NDs; ++j) 00371 { 00372 K(i, j) = Q(j,i); 00373 K(NDu+i,j) = Q(j,i); 00374 } 00375 for (size_t j=0; j<NDu; ++j) K(i,NDs+j) = A(i,j); 00376 } 00377 } 00378 } 00379 00380 inline void USigElem::Interp (Mat_t const & C, IntegPoint const & IP, Mat_t & B, Mat_t & N, Mat_t & Ns, double & detJ, double & Coef) const 00381 { 00382 // deriv of shape func w.r.t natural coordinates 00383 GE ->Shape (IP.r, IP.s, IP.t); 00384 GE ->Derivs (IP.r, IP.s, IP.t); 00385 GEs->Shape (IP.r, IP.s, IP.t); 00386 00387 // Jacobian and its determinant 00388 Mat_t J(GE->dNdR * C); // J = dNdR * C 00389 detJ = Det(J); 00390 00391 // deriv of shape func w.r.t real coordinates 00392 Mat_t Ji; 00393 Inv (J, Ji); 00394 Mat_t dNdX(Ji * GE->dNdR); // dNdX = Inv(J) * dNdR 00395 00396 // coefficient used during integration 00397 Coef = detJ*IP.w; 00398 00399 // B matrix 00400 B.change_dim (NCo,NDu); 00401 set_to_zero (B); 00402 if (NDim==2) 00403 { 00404 if (GTy==axs_t) 00405 { 00406 // correct Coef 00407 double radius = 0.0; // radius=x at this IP 00408 for (size_t j=0; j<GE->NN; ++j) radius += GE->N(j)*Con[j]->Vert.C[0]; 00409 Coef *= radius; 00410 00411 // B matrix 00412 for (size_t i=0; i<GE->NN; ++i) 00413 { 00414 B(0,0+i*NDim) = dNdX(0,i); 00415 B(1,1+i*NDim) = dNdX(1,i); 00416 B(2,0+i*NDim) = GE->N(i)/radius; 00417 B(3,0+i*NDim) = dNdX(1,i)/sqrt(2.0); 00418 B(3,1+i*NDim) = dNdX(0,i)/sqrt(2.0); 00419 } 00420 } 00421 else // pse_t, psa_t 00422 { 00423 for (size_t i=0; i<GE->NN; ++i) 00424 { 00425 B(0,0+i*NDim) = dNdX(0,i); 00426 B(1,1+i*NDim) = dNdX(1,i); 00427 B(3,0+i*NDim) = dNdX(1,i)/sqrt(2.0); 00428 B(3,1+i*NDim) = dNdX(0,i)/sqrt(2.0); 00429 } 00430 } 00431 } 00432 else // 3D 00433 { 00434 for (size_t i=0; i<GE->NN; ++i) 00435 { 00436 B(0,0+i*NDim) = dNdX(0,i); 00437 B(1,1+i*NDim) = dNdX(1,i); 00438 B(2,2+i*NDim) = dNdX(2,i); 00439 B(3,0+i*NDim) = dNdX(1,i)/sqrt(2.0); B(3,1+i*NDim) = dNdX(0,i)/sqrt(2.0); 00440 B(4,1+i*NDim) = dNdX(2,i)/sqrt(2.0); B(4,2+i*NDim) = dNdX(1,i)/sqrt(2.0); 00441 B(5,2+i*NDim) = dNdX(0,i)/sqrt(2.0); B(5,0+i*NDim) = dNdX(2,i)/sqrt(2.0); 00442 } 00443 } 00444 00445 // N matrix 00446 N.change_dim (NDim,NDu); 00447 set_to_zero (N); 00448 for (int i=0; i<NDim; ++i) 00449 for (size_t j=0; j<GE->NN; ++j) 00450 N(i,i+j*NDim) = GE->N(j); 00451 00452 // Ns matrix 00453 Ns.change_dim (NCo,NDs); 00454 set_to_zero (Ns); 00455 for (size_t i=0; i<NCo; ++i) 00456 for (size_t j=0; j<GEs->NN; ++j) 00457 Ns(i,i+j*NCo) = GEs->N(j); 00458 } 00459 00460 inline void USigElem::UpdateState (Vec_t const & dU, Vec_t * F_int) const 00461 { 00462 // stress increment 00463 Vec_t dSe(NDs); 00464 for (size_t i=0; i<NDs; ++i) dSe(i) = dU(FirstEQ+i); 00465 00466 // displacement increment 00467 Vec_t dUe(NDu); 00468 for (size_t i=0; i<GE->NN; ++i) 00469 { 00470 dUe(i*NDim+0) = dU(Con[i]->Eq("ux")); 00471 dUe(i*NDim+1) = dU(Con[i]->Eq("uy")); if (NDim==3) 00472 dUe(i*NDim+2) = dU(Con[i]->Eq("uz")); 00473 } 00474 00475 // update F_int 00476 if (F_int!=NULL) 00477 { 00478 double detJ, coef; 00479 Mat_t C, B, N, Ns; 00480 Vec_t dsig(NCo), deps(NCo), dF1(NDs), dF2(NDu); 00481 CoordMatrix (C); 00482 set_to_zero (dF1); 00483 set_to_zero (dF2); 00484 for (size_t i=0; i<GE->NIP; ++i) 00485 { 00486 // interpolation 00487 Interp (C, GE->IPs[i], B, N, Ns, detJ, coef); 00488 00489 // (external) stress and strain increment 00490 dsig = Ns * dSe; 00491 deps = B * dUe; 00492 00493 if (StrainResid) 00494 { 00495 // (internal) strain increment 00496 Vec_t deps_i(NCo); 00497 StrainUpdate staup(Mdl); 00498 staup.Update (dsig, Sta[i], deps_i); 00499 00500 // (internal) forces 00501 dF1 += (-coef) * trans(Ns)*deps_i; 00502 dF1 += (coef) * trans(Ns)*deps; 00503 dF2 += (coef) * trans(B)*dsig; 00504 } 00505 else 00506 { 00507 // (internal) stress increment 00508 Vec_t dsig_i(NCo); 00509 Mdl->SUp.Update (deps, Sta[i], dsig_i); 00510 00511 // (internal) forces 00512 dF1 += (coef) * trans(Ns)*deps; 00513 dF2 += (coef) * trans(B)*dsig; 00514 dF2 += (-coef) * trans(B)*dsig_i; 00515 } 00516 } 00517 00518 // add to F_int 00519 for (size_t i=0; i<NDs; ++i) (*F_int)(FirstEQ+i) += dF1(i); 00520 for (size_t i=0; i<GE->NN; ++i) 00521 { 00522 (*F_int)(Con[i]->Eq("ux")) += dF2(i*NDim+0); 00523 (*F_int)(Con[i]->Eq("uy")) += dF2(i*NDim+1); if (NDim==3) 00524 (*F_int)(Con[i]->Eq("uz")) += dF2(i*NDim+2); 00525 } 00526 } 00527 } 00528 00529 inline void USigElem::StateKeys (Array<String> & Keys) const 00530 { 00531 Keys = EquilibState::Keys; 00532 for (size_t i=0; i<Mdl->NIvs; ++i) Keys.Push (Mdl->IvNames[i]); 00533 } 00534 00535 inline void USigElem::StateAtIP (SDPair & KeysVals, int IdxIP) const 00536 { 00537 Vec_t const & sig = static_cast<EquilibState const *>(Sta[IdxIP])->Sig; 00538 Vec_t const & eps = static_cast<EquilibState const *>(Sta[IdxIP])->Eps; 00539 Vec_t const & ivs = static_cast<EquilibState const *>(Sta[IdxIP])->Ivs; 00540 00541 if (NDim==2) 00542 { 00543 KeysVals.Set("sx sy sz sxy ex ey ez exy pcam qcam ev ed", 00544 sig(0), sig(1), sig(2), sig(3)/Util::SQ2, 00545 eps(0), eps(1), eps(2), eps(3)/Util::SQ2, 00546 Calc_pcam(sig), Calc_qcam(sig), Calc_ev(eps), Calc_ed(eps)); 00547 } 00548 else 00549 { 00550 KeysVals.Set("sx sy sz sxy syz szx ex ey ez exy eyz ezx pcam qcam ev ed", 00551 sig(0), sig(1), sig(2), sig(3)/Util::SQ2, sig(4)/Util::SQ2, sig(5)/Util::SQ2, 00552 eps(0), eps(1), eps(2), eps(3)/Util::SQ2, eps(4)/Util::SQ2, eps(5)/Util::SQ2, 00553 Calc_pcam(sig), Calc_qcam(sig), Calc_ev(eps), Calc_ed(eps)); 00554 } 00555 for (size_t k=0; k<Mdl->NIvs; ++k) KeysVals.Set(Mdl->IvNames[k].CStr(), ivs(k)); 00556 } 00557 00558 00560 00561 00562 // Allocate a new element 00563 Element * USigElemMaker(int NDim, Mesh::Cell const & Cell, Model const * Mdl, Model const * XMdl, SDPair const & Prp, SDPair const & Ini, Array<Node*> const & Nodes) { return new USigElem(NDim,Cell,Mdl,XMdl,Prp,Ini,Nodes); } 00564 00565 // Register element 00566 int USigElemRegister() 00567 { 00568 ElementFactory["USig"] = USigElemMaker; 00569 ElementVarKeys["USig2D"] = std::make_pair ("ux uy", "fx fy"); 00570 ElementVarKeys["USig3D"] = std::make_pair ("ux uy uz", "fx fy fz"); 00571 PROB.Set ("USig", (double)PROB.Keys.Size()); 00572 return 0; 00573 } 00574 00575 // Call register 00576 int __USigElem_dummy_int = USigElemRegister(); 00577 00578 }; // namespace FEM 00579 00580 #endif // MECHSYS_FEM_USIGELEM_H